int audioStreamer_ds::Open(int iswrite, int srate, int nch, int bps, int sleep, int nbufs, int bufsize, GUID *device) { // todo: use device m_sleep = sleep >= 0 ? sleep : 0; GUID zero={0,}; if (!memcmp(device,&zero,sizeof(zero))) device=NULL; m_nch = nch; m_srate=srate; m_bps=bps; int fmt_align=(bps>>3)*nch; int fmt_mul=fmt_align*srate; WAVEFORMATEX wfx={ WAVE_FORMAT_PCM, nch, srate, fmt_mul, fmt_align, bps, 0 }; m_totalbufsize=nbufs*bufsize; if (iswrite) { DirectSoundCreate(device,&m_lpds,NULL); if (m_lpds) { HWND hWnd = GetForegroundWindow(); if (hWnd == NULL) hWnd = GetDesktopWindow(); m_lpds->SetCooperativeLevel(hWnd,DSSCL_PRIORITY); // create a secondary buffer for now DSBUFFERDESC ds={sizeof(ds),DSBCAPS_GETCURRENTPOSITION2|DSBCAPS_GLOBALFOCUS,m_totalbufsize,0,&wfx, }; m_lpds->CreateSoundBuffer(&ds,&m_outbuf,NULL); } } else { DirectSoundCaptureCreate(device,&m_lpcap,NULL); if (m_lpcap) { DSCBUFFERDESC ds={sizeof(ds),0,m_totalbufsize,0,&wfx, }; m_lpcap->CreateCaptureBuffer(&ds,&m_inbuf,NULL); } } m_bufsize=bufsize; return 0; }
static int capture_init (void) { HRESULT hr; DSCBUFFERDESC sound_buffer_rec; WAVEFORMATEX wavfmt; TCHAR *name; int samplerate = 44100; if (currprefs.sampler_freq) samplerate = currprefs.sampler_freq; name = record_devices[currprefs.win32_samplersoundcard]->name; wavfmt.wFormatTag = WAVE_FORMAT_PCM; wavfmt.nChannels = 2; wavfmt.nSamplesPerSec = samplerate; wavfmt.wBitsPerSample = 16; wavfmt.nBlockAlign = wavfmt.wBitsPerSample / 8 * wavfmt.nChannels; wavfmt.nAvgBytesPerSec = wavfmt.nBlockAlign * wavfmt.nSamplesPerSec; wavfmt.cbSize = 0; clockspersample = sampler_evtime / samplerate; sampleframes = (samplerate + 49) / 50; recordbufferframes = 16384; if (currprefs.sampler_buffer) recordbufferframes = currprefs.sampler_buffer; hr = DirectSoundCaptureCreate (&record_devices[currprefs.win32_samplersoundcard]->guid, &lpDS2r, NULL); if (FAILED (hr)) { write_log (_T("SAMPLER: DirectSoundCaptureCreate('%s') failure: %s\n"), name, DXError (hr)); return 0; } memset (&sound_buffer_rec, 0, sizeof (DSCBUFFERDESC)); sound_buffer_rec.dwSize = sizeof (DSCBUFFERDESC); sound_buffer_rec.dwBufferBytes = recordbufferframes * SAMPLESIZE; sound_buffer_rec.lpwfxFormat = &wavfmt; sound_buffer_rec.dwFlags = 0 ; hr = lpDS2r->CreateCaptureBuffer (&sound_buffer_rec, &lpDSB2r, NULL); if (FAILED (hr)) { write_log (_T("SAMPLER: CreateCaptureSoundBuffer('%s') failure: %s\n"), name, DXError(hr)); return 0; } hr = lpDSB2r->Start (DSCBSTART_LOOPING); if (FAILED (hr)) { write_log (_T("SAMPLER: DirectSoundCaptureBuffer_Start('%s') failed: %s\n"), name, DXError (hr)); return 0; } samplebuffer = xcalloc (uae_u8, sampleframes * SAMPLESIZE); write_log (_T("SAMPLER: Parallel port sampler initialized, CPS=%f, '%s'\n"), clockspersample, name); return 1; }
static void capture_free (void) { if (lpDSB2r) { lpDSB2r->Stop (); lpDSB2r->Release (); write_log (_T("SAMPLER: Parallel port sampler freed\n")); } lpDSB2r = NULL; if (lpDS2r) lpDS2r->Release (); lpDS2r = NULL; xfree (samplebuffer); samplebuffer = NULL; }
void VoiceRecord_DSound::Term() { if(m_pCaptureBuffer) m_pCaptureBuffer->Release(); if(m_pCapture) m_pCapture->Release(); if(m_hWrapEvent) DeleteObject(m_hWrapEvent); if(m_hInstDS) { FreeLibrary(m_hInstDS); m_hInstDS = NULL; } Clear(); }
bool nuiAudioDevice_DirectSound::Open(std::vector<uint32>& rInputChannels, std::vector<uint32>& rOutputChannels, double SampleRate, uint32 BufferSize, nuiAudioProcessFn pProcessFunction) { if (!mpDirectSound) return false; HRESULT hr = S_OK; mAudioProcessFn = pProcessFunction; mBufferSize = BufferSize; hr = mpDirectSound->SetCooperativeLevel(GetDesktopWindow(), DSSCL_EXCLUSIVE); mHasInput = (rInputChannels.size() > 0) && (mInputChannels.size() > 0); mHasOutput = (rOutputChannels.size() > 0) && (mOutputChannels.size() > 0); mpInputBuffer = NULL; mpOutputBuffer = NULL; if (!mHasInput && !mHasOutput) return false; // init ringbuffer mpRingBuffer = new nglRingBuffer(BufferSize*4, sizeof(float), rOutputChannels.size()); mpRingBuffer->AdvanceWriteIndex(BufferSize); // init input buffers if (mHasInput) { { mActiveInputChannels = rInputChannels; } WAVEFORMATEX IFormat; IFormat.wFormatTag = WAVE_FORMAT_PCM; IFormat.nChannels = (WORD)mInputChannels.size(); IFormat.nSamplesPerSec = ToNearest(SampleRate); IFormat.wBitsPerSample = 16; IFormat.nAvgBytesPerSec = IFormat.nChannels * IFormat.nSamplesPerSec * (IFormat.wBitsPerSample / 8); IFormat.nBlockAlign = IFormat.nChannels * (IFormat.wBitsPerSample / 8); IFormat.cbSize = 0; DSCBUFFERDESC IBufferDesc; memset(&IBufferDesc, 0, sizeof(IBufferDesc)); IBufferDesc.dwSize = sizeof(DSCBUFFERDESC); IBufferDesc.dwFlags = DSCBCAPS_WAVEMAPPED; IBufferDesc.dwBufferBytes = (IFormat.wBitsPerSample / 8) * IFormat.nChannels * BufferSize * 2; IBufferDesc.dwReserved = 0; IBufferDesc.lpwfxFormat = &IFormat; IBufferDesc.dwFXCount = 0; IBufferDesc.lpDSCFXDesc = NULL; NGL_ASSERT(mpDirectSoundCapture); hr = mpDirectSoundCapture->CreateCaptureBuffer(&IBufferDesc, &mpInputBuffer, NULL); } // init output buffers if (mHasOutput) { { mActiveOutputChannels = rOutputChannels; } WAVEFORMATEX OFormat; OFormat.wFormatTag = WAVE_FORMAT_PCM; OFormat.nChannels = (WORD)mOutputChannels.size(); OFormat.nSamplesPerSec = ToNearest(SampleRate); OFormat.wBitsPerSample = 16; OFormat.nAvgBytesPerSec = OFormat.nChannels * OFormat.nSamplesPerSec * (OFormat.wBitsPerSample / 8); OFormat.nBlockAlign = OFormat.nChannels * OFormat.wBitsPerSample / 8; OFormat.cbSize = 0; DSBUFFERDESC OBufferDesc; memset(&OBufferDesc, 0, sizeof(OBufferDesc)); OBufferDesc.dwSize = sizeof(OBufferDesc); OBufferDesc.dwFlags = DSBCAPS_GLOBALFOCUS | DSBCAPS_CTRLPOSITIONNOTIFY; OBufferDesc.dwBufferBytes = (OFormat.wBitsPerSample / 8) * OFormat.nChannels * BufferSize * 2; OBufferDesc.dwReserved = 0; OBufferDesc.lpwfxFormat = &OFormat; hr = mpDirectSound->CreateSoundBuffer(&OBufferDesc, &mpOutputBuffer, NULL); } // create event for notifications mNotifInputEvent[0] = CreateEvent(NULL, FALSE, FALSE, _T("NUI_DSoundInputEvent0")); mNotifInputEvent[1] = CreateEvent(NULL, FALSE, FALSE, _T("NUI_DSoundInputEvent1")); mNotifOutputEvent[0] = CreateEvent(NULL, FALSE, FALSE, _T("NUI_DSoundOutputEvent0")); mNotifOutputEvent[1] = CreateEvent(NULL, FALSE, FALSE, _T("NUI_DSoundOutputEvent1")); // set the notification for the input buffer if (mHasInput) { // Setup the notification positions ZeroMemory( &mInputPosNotify, sizeof(DSBPOSITIONNOTIFY) * 2); mInputPosNotify[0].dwOffset = BufferSize * sizeof(int16) * mInputChannels.size() - 1; mInputPosNotify[0].hEventNotify = mNotifInputEvent[0]; mInputPosNotify[1].dwOffset = BufferSize * sizeof(int16) * mInputChannels.size() * 2 - 1; mInputPosNotify[1].hEventNotify = mNotifInputEvent[1]; LPDIRECTSOUNDNOTIFY pInputNotify = NULL; if( FAILED( hr = mpInputBuffer->QueryInterface( IID_IDirectSoundNotify, (VOID**)&pInputNotify ) ) ) { NGL_LOG(_T("nuiAudioDevice_DirectSound"), NGL_LOG_ERROR, _T("Open ERROR : failed in querying interface for input notifications.\n")); return false; } // Tell DirectSound when to notify us. the notification will come in the from // of signaled events that are handled in WinMain() if( FAILED( hr = pInputNotify->SetNotificationPositions( 2, mInputPosNotify ) ) ) { NGL_LOG(_T("nuiAudioDevice_DirectSound"), NGL_LOG_ERROR, _T("Open ERROR : failed in setting notifications for input\n")); return false; } pInputNotify->Release(); } // set the notification events for the output buffer if (mHasOutput) { // Setup the notification positions ZeroMemory( &mOutputPosNotify, sizeof(DSBPOSITIONNOTIFY) * 2); mOutputPosNotify[0].dwOffset = BufferSize * sizeof(int16) * mOutputChannels.size() - 1; mOutputPosNotify[0].hEventNotify = mNotifOutputEvent[0]; mOutputPosNotify[1].dwOffset = BufferSize * sizeof(int16) * mOutputChannels.size() * 2 - 1; mOutputPosNotify[1].hEventNotify = mNotifOutputEvent[1]; LPDIRECTSOUNDNOTIFY pOutputNotify = NULL; if( FAILED( hr = mpOutputBuffer->QueryInterface( IID_IDirectSoundNotify, (VOID**)&pOutputNotify ) ) ) { NGL_LOG(_T("nuiAudioDevice_DirectSound"), NGL_LOG_ERROR, _T("Open ERROR : failed in querying interface for output notifications.\n")); return false; } // Tell DirectSound when to notify us. the notification will come in the from // of signaled events that are handled in WinMain() if( FAILED( hr = pOutputNotify->SetNotificationPositions( 2, mOutputPosNotify ) ) ) { NGL_LOG(_T("nuiAudioDevice_DirectSound"), NGL_LOG_ERROR, _T("Open ERROR : failed in setting notifications for output\n")); return false; } pOutputNotify->Release(); } // start input processing thread mpProcessingTh = new nuiAudioDevice_DS_ProcessingTh(this, mNotifInputEvent[0], mNotifInputEvent[1], mAudioProcessFn); mpProcessingTh->Start(); // start output thread if (mHasOutput) { mpOutputTh = new nuiAudioDevice_DS_OutputTh(this, mNotifInputEvent[0], mNotifInputEvent[1], mNotifOutputEvent[0], mNotifOutputEvent[1]); mpOutputTh->Start(); hr = mpOutputBuffer->Play(0,0,DSCBSTART_LOOPING); if (FAILED(hr)) NGL_LOG(_T("nuiAudioDevice_DirectSound"), NGL_LOG_ERROR, _T("OutputBuffer->Play ERROR!\n")); } // start input capture if (mHasInput) { hr = mpInputBuffer->Start(DSCBSTART_LOOPING); if (FAILED(hr)) NGL_LOG(_T("nuiAudioDevice_DirectSound"), NGL_LOG_ERROR, _T("InputBuffer->Start ERROR!\n")); } return true; }
void nuiAudioDevice_DirectSound::Init() { DSCCAPS icaps; icaps.dwSize = sizeof(DSCCAPS); if (mpDirectSoundCapture) mpDirectSoundCapture->GetCaps(&icaps); else { icaps.dwChannels = 0; icaps.dwFormats = 0; icaps.dwFlags = 0; } DSCAPS ocaps; ocaps.dwSize = sizeof(DSCAPS); mpDirectSound->GetCaps(&ocaps); // Input channels: if (icaps.dwChannels == 1) { nglString str(mInName); str.Add(_T(" (Input)")); mInputChannels.push_back(str); } else if (icaps.dwChannels > 1) { { nglString str(mInName); str.Add(_T(" (Left input)")); mInputChannels.push_back(str); } { nglString str(mInName); str.Add(_T(" (Right input)")); mInputChannels.push_back(str); } } // Output channels: { nglString str(mOutName); str.Add(_T(" (Left output)")); mOutputChannels.push_back(str); } { nglString str(mOutName); str.Add(_T(" (Right output)")); mOutputChannels.push_back(str); } mSampleRates.clear(); mBufferSizes.clear(); if ( ( ( icaps.dwFormats & WAVE_FORMAT_1M16 ) || ( icaps.dwFormats & WAVE_FORMAT_1S16 ) ) && ocaps.dwMinSecondarySampleRate <= 11025 && ocaps.dwMaxSecondarySampleRate >= 11025 ) mSampleRates.push_back(11025); if ( ( ( icaps.dwFormats & WAVE_FORMAT_2M16 ) || ( icaps.dwFormats & WAVE_FORMAT_2S16 ) ) && ocaps.dwMinSecondarySampleRate <= 22050 && ocaps.dwMaxSecondarySampleRate >= 22050 ) mSampleRates.push_back(22050); if ( ( ( icaps.dwFormats & WAVE_FORMAT_4M16 ) || ( icaps.dwFormats & WAVE_FORMAT_4S16 ) ) && ocaps.dwMinSecondarySampleRate <= 44100 && ocaps.dwMaxSecondarySampleRate >= 44100 ) mSampleRates.push_back(44100); if ( ( ( icaps.dwFormats & WAVE_FORMAT_48M16 ) || ( icaps.dwFormats & WAVE_FORMAT_48S16 ) ) && ocaps.dwMinSecondarySampleRate <= 48000 && ocaps.dwMaxSecondarySampleRate >= 48000 ) mSampleRates.push_back(48000); if ( ( ( icaps.dwFormats & WAVE_FORMAT_96M16 ) || ( icaps.dwFormats & WAVE_FORMAT_96S16 ) ) && ocaps.dwMinSecondarySampleRate <= 96000 && ocaps.dwMaxSecondarySampleRate >= 96000 ) mSampleRates.push_back(96000); if (mSampleRates.empty()) { mInputChannels.clear(); if (ocaps.dwMinSecondarySampleRate <= 11025 && ocaps.dwMaxSecondarySampleRate >= 11025 ) mSampleRates.push_back(11025); if (ocaps.dwMinSecondarySampleRate <= 22050 && ocaps.dwMaxSecondarySampleRate >= 22050 ) mSampleRates.push_back(22050); if (ocaps.dwMinSecondarySampleRate <= 44100 && ocaps.dwMaxSecondarySampleRate >= 44100 ) mSampleRates.push_back(44100); if (ocaps.dwMinSecondarySampleRate <= 48000 && ocaps.dwMaxSecondarySampleRate >= 48000 ) mSampleRates.push_back(48000); if (ocaps.dwMinSecondarySampleRate <= 96000 && ocaps.dwMaxSecondarySampleRate >= 96000 ) mSampleRates.push_back(96000); } mIsPresent = true; uint i = 0; int sizes[] = { 64, 128, 256, 384, 512, 768, 1024, 2048, 4096, 8192, 16384, 32768 ,0 }; while (sizes[i]) mBufferSizes.push_back(sizes[i++]); }
bool VoiceRecord_DSound::Init(int sampleRate) { HRESULT hr; DSCBUFFERDESC dscDesc; DirectSoundCaptureCreateFn createFn; Term(); WAVEFORMATEX recordFormat = { WAVE_FORMAT_PCM, // wFormatTag 1, // nChannels sampleRate, // nSamplesPerSec sampleRate*2, // nAvgBytesPerSec 2, // nBlockAlign 16, // wBitsPerSample sizeof(WAVEFORMATEX) // cbSize }; // Load the DSound DLL. m_hInstDS = LoadLibrary("dsound.dll"); if(!m_hInstDS) goto HandleError; createFn = (DirectSoundCaptureCreateFn)GetProcAddress(m_hInstDS, "DirectSoundCaptureCreate"); if(!createFn) goto HandleError; hr = createFn(NULL, &m_pCapture, NULL); if(FAILED(hr)) goto HandleError; // Create the capture buffer. memset(&dscDesc, 0, sizeof(dscDesc)); dscDesc.dwSize = sizeof(dscDesc); dscDesc.dwFlags = 0; dscDesc.dwBufferBytes = recordFormat.nAvgBytesPerSec; dscDesc.lpwfxFormat = &recordFormat; hr = m_pCapture->CreateCaptureBuffer(&dscDesc, &m_pCaptureBuffer, NULL); if(FAILED(hr)) goto HandleError; // Figure out how many bytes we got in our capture buffer. DSCBCAPS caps; memset(&caps, 0, sizeof(caps)); caps.dwSize = sizeof(caps); hr = m_pCaptureBuffer->GetCaps(&caps); if(FAILED(hr)) goto HandleError; m_nCaptureBufferBytes = caps.dwBufferBytes; // Set it up so we get notification when the buffer wraps. m_hWrapEvent = CreateEvent(NULL, FALSE, FALSE, NULL); if(!m_hWrapEvent) goto HandleError; DSBPOSITIONNOTIFY dsbNotify; dsbNotify.dwOffset = dscDesc.dwBufferBytes - 1; dsbNotify.hEventNotify = m_hWrapEvent; // Get the IDirectSoundNotify interface. LPDIRECTSOUNDNOTIFY pNotify; hr = m_pCaptureBuffer->QueryInterface(IID_IDirectSoundNotify, (void**)&pNotify); if(FAILED(hr)) goto HandleError; hr = pNotify->SetNotificationPositions(1, &dsbNotify); pNotify->Release(); if(FAILED(hr)) goto HandleError; // Start capturing. hr = m_pCaptureBuffer->Start(DSCBSTART_LOOPING); if(FAILED(hr)) return false; return true; HandleError:; Term(); return false; }