DirectSound - FullDuplex



  • Hallo,

    ich bin gerade dabei DirectSoundFullDuplex zu initialisieren und zum Laufen zu bringen. Wenn ich mein Projekt compiliere, bringt er mir auch keinen Fehler und so, jedoch weiß ich nicht, ob ich es bisher richtig gemacht habe.

    Woran erkenne ich, ob die Aufnahme und Ausgabe funktioniert? Also mein Vorhaben ist folgendes:

    Ich will mittels DirectSound einen Sound beliebiger Quellen aufnehmen und direkt an die Soundkarte weiterleiten. Das Programm soll dabei später eine Schnittstelle zwischen zwei Programmen sein. Aber, um die Lösung des Problems erst einmal in der Funktionalität zu begreifen, wollte ich eben erst einmal eine solche FullDuplex Methode probieren.

    Könntet ihr mir Tipps geben, die mich an mein Ziel bringen?

    Danke euch schonmal dafür! 🙂

    Hier der Quellcode (Visual Studio 2008 Prof. - MFC):

    // dsCaptureWavDlg.cpp : implementation file
    //
    
    #include "stdafx.h"
    #include "dsCaptureWav.h"
    #include "dsCaptureWavDlg.h"
    #include <windows.h>
    #include <mmsystem.h>
    #include <dsound.h>
    #include <iostream>
    #include <stdio.h>
    #include <string>
    #include <vector>
    
    #pragma comment(lib, "winmm.lib")
    #pragma comment(lib, "dsound.lib")
    
    using namespace std;
    
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #endif
    #define SAMPLERATE                44100      ///< [Hz]
    #define NOTIFY_SIZE					(SAMPLERATE/50*2)  ///< 1920 [Bytes] = 960 Samples (16bit)
    #define NUM_CAPTURE_NOTIFICATIONS   4
    #define NUM_BUFFER_SEGMENTS         4        ///< 4 Buffer Segments in the ring buffer
    
    //directsound variablen
    
    HRESULT	hr;
    LPDIRECTSOUND8 directSound;
    LPDIRECTSOUNDFULLDUPLEX dsFD;
    WAVEFORMATEX wfx;
    
    //Input
    LPDIRECTSOUNDCAPTURE8 dsCapture;
    LPDIRECTSOUNDCAPTUREBUFFER8 dsbCapture;
    DSCBUFFERDESC dsCBufferDesc;
    
    //Output
    LPDIRECTSOUNDBUFFER8 dsbSound;
    DSBUFFERDESC dsBufferDesc;
    
    //Buffer Notifications
    DWORD dwCapturePos;
    DWORD dwReadPos;
    
    //Lock Parameter
    DWORD dwOffset;
    DWORD dwBytes;
    DWORD dwNotifySize;
    DWORD dwBufferSize;
    
    VOID* lockedBufferPointer = NULL;
    DWORD lockedBufferSize;
    
    VOID* lockedBufferPointer2 = NULL;
    DWORD lockedBufferSize2;
    
    DSCCAPS caps;
    
    // CdsCaptureWavDlg dialog
    
    CdsCaptureWavDlg::CdsCaptureWavDlg(CWnd* pParent /*=NULL*/)
    	: CDialog(CdsCaptureWavDlg::IDD, pParent)
    {
    	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
    }
    
    void CdsCaptureWavDlg::DoDataExchange(CDataExchange* pDX)
    {
    	CDialog::DoDataExchange(pDX);
    }
    
    BEGIN_MESSAGE_MAP(CdsCaptureWavDlg, CDialog)
    	ON_WM_PAINT()
    	ON_WM_QUERYDRAGICON()
    	//}}AFX_MSG_MAP
    	ON_BN_CLICKED(IDOK, &CdsCaptureWavDlg::OnBnClickedOk)
    	ON_BN_CLICKED(IDCANCEL, &CdsCaptureWavDlg::OnBnClickedCancel)
    END_MESSAGE_MAP()
    
    // CdsCaptureWavDlg message handlers
    
    BOOL CdsCaptureWavDlg::OnInitDialog()
    {
    	CDialog::OnInitDialog();
    
    	// Set the icon for this dialog.  The framework does this automatically
    	//  when the application's main window is not a dialog
    	SetIcon(m_hIcon, TRUE);			// Set big icon
    	SetIcon(m_hIcon, FALSE);		// Set small icon
    
    	// TODO: Add extra initialization here
    
    	//Waveformatex
    	wfx.cbSize = 0;
    	wfx.nAvgBytesPerSec = 176400;
    	wfx.nBlockAlign = 4;
    	wfx.nChannels = 2;
    	wfx.nSamplesPerSec = 44100;
    	wfx.wBitsPerSample = 16;
    	wfx.wFormatTag = WAVE_FORMAT_PCM;
    
    	//directsoundCaptureBuffer
    	ZeroMemory(&dsCBufferDesc, sizeof(DSCBUFFERDESC));
    	dsCBufferDesc.dwSize = sizeof(DSCBUFFERDESC);
    	dsCBufferDesc.dwFlags = 0;
    	dsCBufferDesc.dwBufferBytes = wfx.nAvgBytesPerSec;
    	dsCBufferDesc.dwReserved = 0;
    	dsCBufferDesc.lpwfxFormat = &wfx;
    	dsCBufferDesc.dwFXCount = 0;
    	dsCBufferDesc.lpDSCFXDesc = NULL;
    
    	//directSoundBuffer
    	ZeroMemory(&dsBufferDesc, sizeof(DSBUFFERDESC)); 
    	dsBufferDesc.dwSize = sizeof(DSBUFFERDESC); 
    	dsBufferDesc.dwFlags = DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLFREQUENCY | DSBCAPS_GLOBALFOCUS; 
    	dsBufferDesc.dwBufferBytes = 3 * wfx.nAvgBytesPerSec; 
    	dsBufferDesc.lpwfxFormat = &wfx; 
    
    	//directsound init
    	if(DirectSoundCreate8(NULL, &directSound, NULL)!=DS_OK)
    		return FALSE;
    
    	if(DirectSoundCaptureCreate8(NULL, &dsCapture, NULL)!=DS_OK)
    		return FALSE;
    
    	//if(dsCapture->GetCaps(::TODO::)!=DS_OK)
    	//	return FALSE;
    
    	if(DirectSoundFullDuplexCreate8(NULL, NULL, &dsCBufferDesc, &dsBufferDesc, (HWND)this->GetForegroundWindow(), DSSCL_NORMAL, &dsFD, &dsbCapture, &dsbSound, NULL)!=DS_OK)
    		return FALSE;
    
    	if(dsFD->Initialize(NULL, NULL, &dsCBufferDesc, &dsBufferDesc, (HWND)this->GetForegroundWindow(), DSSCL_NORMAL, &dsbCapture, &dsbSound)!=DS_OK)
    		return FALSE;
    
    	return TRUE;  // return TRUE  unless you set the focus to a control
    }
    
    // If you add a minimize button to your dialog, you will need the code below
    //  to draw the icon.  For MFC applications using the document/view model,
    //  this is automatically done for you by the framework.
    
    void CdsCaptureWavDlg::OnPaint()
    {
    	if (IsIconic())
    	{
    		CPaintDC dc(this); // device context for painting
    
    		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
    
    		// Center icon in client rectangle
    		int cxIcon = GetSystemMetrics(SM_CXICON);
    		int cyIcon = GetSystemMetrics(SM_CYICON);
    		CRect rect;
    		GetClientRect(&rect);
    		int x = (rect.Width() - cxIcon + 1) / 2;
    		int y = (rect.Height() - cyIcon + 1) / 2;
    
    		// Draw the icon
    		dc.DrawIcon(x, y, m_hIcon);
    	}
    	else
    	{
    		CDialog::OnPaint();
    	}
    }
    
    // The system calls this function to obtain the cursor to display while the user drags
    //  the minimized window.
    HCURSOR CdsCaptureWavDlg::OnQueryDragIcon()
    {
    	return static_cast<HCURSOR>(m_hIcon);
    }
    
    void CdsCaptureWavDlg::OnBnClickedOk()
    {
    	// TODO: Add your control notification handler code here
    	string capPos, readPos;
    
    	caps.dwSize=sizeof(caps);
    	dsCapture->GetCaps(&caps);
    	dsbCapture->Start(DSCBSTART_LOOPING);
    
    	dsbCapture->GetCurrentPosition(&dwCapturePos, &dwReadPos);
    
    	//Create the capture buffer
    	dwNotifySize  = NOTIFY_SIZE;
    	dwNotifySize -= dwNotifySize % wfx.nBlockAlign;	
    	dwBufferSize  = dwNotifySize * NUM_BUFFER_SEGMENTS;
    
    	dsbCapture->Lock(dwCapturePos, dwNotifySize, &lockedBufferPointer, &lockedBufferSize, &lockedBufferPointer2, &lockedBufferSize2, 0L ); 
    	//dsbCapture->Unlock(...);
    
    }
    
    void CdsCaptureWavDlg::OnBnClickedCancel()
    {
    	// TODO: Add your control notification handler code here
    
    	//dsbCapture->Stop();
    	OnCancel();
    }
    

Anmelden zum Antworten