diff options
author | Thorvald Natvig <slicer@users.sourceforge.net> | 2005-09-17 03:03:53 +0400 |
---|---|---|
committer | Thorvald Natvig <slicer@users.sourceforge.net> | 2005-09-17 03:03:53 +0400 |
commit | 67e3d8533edaa62fca61ebd9ca3e72421843c2fe (patch) | |
tree | 7aeec2b1d54c0c4f5b1bb7aeb6fff95138fdb9b3 | |
parent | 3d9e12b8baad26f8c194f85c4344cf3210305647 (diff) |
Single-threaded directsound output
git-svn-id: https://mumble.svn.sourceforge.net/svnroot/mumble/trunk@151 05730e5d-ab1b-0410-a4ac-84af385074fa
-rw-r--r-- | AudioInput.cpp | 4 | ||||
-rw-r--r-- | AudioInput.h | 1 | ||||
-rw-r--r-- | AudioOutput.cpp | 17 | ||||
-rw-r--r-- | AudioOutput.h | 3 | ||||
-rw-r--r-- | DXAudioOutput.cpp | 385 | ||||
-rw-r--r-- | DXAudioOutput.h | 13 | ||||
-rw-r--r-- | main.cpp | 1 | ||||
-rw-r--r-- | mumble.pro | 1 |
8 files changed, 257 insertions, 168 deletions
diff --git a/AudioInput.cpp b/AudioInput.cpp index 389baf133..d02c50d24 100644 --- a/AudioInput.cpp +++ b/AudioInput.cpp @@ -120,10 +120,6 @@ AudioInput::~AudioInput() delete [] psMic; } -bool AudioInput::isRunning() const { - return bRunning; -} - void AudioInput::encodeAudioFrame() { int iArg; float fArg; diff --git a/AudioInput.h b/AudioInput.h index 2312c9e8b..828d6c431 100644 --- a/AudioInput.h +++ b/AudioInput.h @@ -81,7 +81,6 @@ class AudioInput : public QThread { AudioInput(); ~AudioInput(); void run() = 0; - bool isRunning() const; }; #else diff --git a/AudioOutput.cpp b/AudioOutput.cpp index 81eb60e61..869f07232 100644 --- a/AudioOutput.cpp +++ b/AudioOutput.cpp @@ -95,9 +95,9 @@ AudioOutputPlayer::AudioOutputPlayer(AudioOutput *ao, Player *player) { } AudioOutputPlayer::~AudioOutputPlayer() { - speex_decoder_destroy(dsDecState); - speex_jitter_destroy(&sjJitter); - delete [] psBuffer; + speex_decoder_destroy(dsDecState); + speex_jitter_destroy(&sjJitter); + delete [] psBuffer; } void AudioOutputPlayer::addFrameToBuffer(QByteArray &qbaPacket, int iSeq) { @@ -123,6 +123,7 @@ bool AudioOutputPlayer::decodeNextFrame() { iSpeech = speex_bits_unpack_unsigned(&sjJitter.current_packet, 1); if (! iSpeech) { sjJitter.reset_state = 1; + sjJitter.valid_bits = 0; speex_decoder_ctl(dsDecState, SPEEX_RESET_STATE, NULL); } left = speex_bits_remaining(&sjJitter.current_packet) / 8; @@ -168,6 +169,7 @@ AudioOutput::AudioOutput() { AudioOutput::~AudioOutput() { bRunning = false; + wait(); wipe(); } @@ -181,13 +183,20 @@ void AudioOutput::wipe() { } void AudioOutput::addFrameToBuffer(Player *player, QByteArray &qbaPacket, int iSeq) { - QReadLocker locker(&qrwlOutputs); + qrwlOutputs.lockForRead(); AudioOutputPlayer *aop = qmOutputs.value(player); if (! aop) { + qrwlOutputs.unlock(); + qrwlOutputs.lockForWrite(); aop = getPlayer(player); qmOutputs[player]=aop; } + aop->addFrameToBuffer(qbaPacket, iSeq); + + if (! isRunning()) + start(QThread::HighPriority); + qrwlOutputs.unlock(); } void AudioOutput::removeBuffer(Player *player) { diff --git a/AudioOutput.h b/AudioOutput.h index 51bf48f2b..5885d5f9d 100644 --- a/AudioOutput.h +++ b/AudioOutput.h @@ -88,7 +88,7 @@ class AudioOutputPlayer : public QObject { ~AudioOutputPlayer(); }; -class AudioOutput : public QObject { +class AudioOutput : public QThread { Q_OBJECT protected: bool bRunning; @@ -102,6 +102,7 @@ class AudioOutput : public QObject { ~AudioOutput(); void addFrameToBuffer(Player *, QByteArray &, int iSeq); void removeBuffer(Player *); + void run() = 0; }; #else diff --git a/DXAudioOutput.cpp b/DXAudioOutput.cpp index 23c174fd1..c8bd94b2e 100644 --- a/DXAudioOutput.cpp +++ b/DXAudioOutput.cpp @@ -52,6 +52,184 @@ static ConfigWidget *DXAudioOutputConfig(QWidget *parent) { AudioOutputRegistrar aorDX("DirectSound", DXAudioOutputNew, DXAudioOutputConfig); +DXAudioOutputPlayer::DXAudioOutputPlayer(DXAudioOutput *ao, Player *player) : AudioOutputPlayer(ao, player) { + dxAudio = static_cast<DXAudioOutput *>(aoOutput); + + DSBUFFERDESC dsbd; + WAVEFORMATEX wfx; + HRESULT hr; + + bPlaying = false; + + ZeroMemory( &wfx, sizeof(wfx) ); + wfx.wFormatTag = WAVE_FORMAT_PCM; + wfx.nChannels = 1; + wfx.nBlockAlign = 2; + wfx.nSamplesPerSec = SAMPLE_RATE; + wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; + wfx.wBitsPerSample = 16; + + ZeroMemory( &dsbd, sizeof(DSBUFFERDESC) ); + dsbd.dwSize = sizeof(DSBUFFERDESC); + dsbd.dwFlags = DSBCAPS_GLOBALFOCUS|DSBCAPS_GETCURRENTPOSITION2; + dsbd.dwFlags |= DSBCAPS_CTRLPOSITIONNOTIFY; + if (dxAudio->p3DListener) + dsbd.dwFlags |= DSBCAPS_CTRL3D; + dsbd.dwBufferBytes = iFrameSize * 2 * NBLOCKS; + dsbd.lpwfxFormat = &wfx; + if (dxAudio->p3DListener) { + switch (g.s.a3dModel) { + case Settings::None: + case Settings::Panning: + dsbd.guid3DAlgorithm = DS3DALG_NO_VIRTUALIZATION; + break; + case Settings::Light: + dsbd.guid3DAlgorithm = DS3DALG_HRTF_LIGHT; + break; + case Settings::Full: + dsbd.guid3DAlgorithm = DS3DALG_HRTF_FULL; + break; + } + } + + hNotificationEvent = CreateEvent( NULL, FALSE, FALSE, NULL ); + + // Create the DirectSound buffer + if( FAILED( hr = dxAudio->pDS->CreateSoundBuffer( &dsbd, &pDSBOutput, NULL ) ) ) + qFatal("DXAudioOutputPlayer: CreateSoundBuffer (Secondary): 0x%08lx", hr); + + DSBPOSITIONNOTIFY aPosNotify[NBLOCKS]; + + for(int i=0;i<NBLOCKS;i++) { + aPosNotify[i].dwOffset = iFrameSize * 2 * i; + aPosNotify[i].hEventNotify = hNotificationEvent; + } + + if( FAILED( hr = pDSBOutput->QueryInterface( IID_IDirectSoundNotify, reinterpret_cast<VOID**>(&pDSNotify) ) ) ) + qFatal("DXAudioOutputPlayer: QueryInterface (Notify)"); + + if( FAILED( hr = pDSNotify->SetNotificationPositions( NBLOCKS, aPosNotify ) ) ) + qFatal("DXAudioOutputPlayer: SetNotificationPositions"); + + pDS3dBuffer = NULL; + if (dxAudio->p3DListener) { + if (FAILED(pDSBOutput->QueryInterface(IID_IDirectSound3DBuffer8, reinterpret_cast<void **>(&pDS3dBuffer)))) + qFatal("DXAudioOutputPlayer: QueryInterface (DirectSound3DBuffer)"); + + pDS3dBuffer->SetMinDistance(g.s.fDXMinDistance, DS3D_DEFERRED); + pDS3dBuffer->SetMaxDistance(g.s.fDXMaxDistance, DS3D_DEFERRED); + } + + qWarning("DXAudioOutputPlayer: %s: New %dHz output buffer of %ld bytes", p->qsName.toLatin1().constData(), SAMPLE_RATE, dsbd.dwBufferBytes); +} + +DXAudioOutputPlayer::~DXAudioOutputPlayer() { + qWarning("DXAudioOutputPlayer: %s: Removed", p->qsName.toLatin1().constData()); + if (pDSNotify) + pDSNotify->Release(); + if (pDSBOutput) { + pDSBOutput->Stop(); + pDSBOutput->Release(); + } + CloseHandle(hNotificationEvent); +} + +bool DXAudioOutputPlayer::playFrames() { + int playblock; + int nowriteblock; + DWORD dwPlayPosition, dwWritePosition; + HRESULT hr; + + LPVOID aptr1, aptr2; + DWORD nbytes1, nbytes2; + + bool alive = true; + + if (! bPlaying) { + if (FAILED( hr = pDSBOutput->Lock(0, 0, &aptr1, &nbytes1, &aptr2, &nbytes2, DSBLOCK_ENTIREBUFFER))) + qFatal("DXAudioOutputPlayer: Initial Lock"); + + dwBufferSize = nbytes1 + nbytes2; + if (aptr1) + ZeroMemory(aptr1, nbytes1); + if (aptr2) + ZeroMemory(aptr2, nbytes2); + + if (FAILED( hr = pDSBOutput->Unlock(aptr1, nbytes1, aptr2, nbytes2))) + qFatal("DXAudioOutputPlayer: Initial Unlock"); + + if (FAILED( hr = pDSBOutput->Play(0, 0, DSBPLAY_LOOPING))) + qFatal("DXAUdioOutputPlayer: Play"); + + dwLastWritePos = 0; + dwLastPlayPos = 0; + dwTotalPlayPos = 0; + + iLastwriteblock = NBLOCKS - 1; + + bPlaying = true; + } + + if( FAILED( hr = pDSBOutput->GetCurrentPosition(&dwPlayPosition, &dwWritePosition ) ) ) + qFatal("DXAudioOutputPlayer: GetCurrentPosition"); + + playblock = dwWritePosition / iByteSize; + nowriteblock = (playblock + g.s.iDXOutputDelay + 1) % NBLOCKS; + + for(int block=(iLastwriteblock + 1) % NBLOCKS;alive && (block!=nowriteblock);block=(block + 1) % NBLOCKS) { + iLastwriteblock = block; + + alive = decodeNextFrame(); + if (! alive) { + pDSBOutput->Stop(); + bPlaying = false; + return false; + } + + if (pDS3dBuffer) { + bool center = g.bCenterPosition; + DWORD mode; + + pDS3dBuffer->GetMode(&mode); + if (! center) { + if ((fabs(fPos[0]) < 0.1) && (fabs(fPos[1]) < 0.1) && (fabs(fPos[2]) < 0.1)) + center = true; + else if (! g.p->bValid) + center = true; + } + if (center) { + if (mode != DS3DMODE_DISABLE) + pDS3dBuffer->SetMode(DS3DMODE_DISABLE, DS3D_DEFERRED); + } else { + if (mode != DS3DMODE_NORMAL) + pDS3dBuffer->SetMode(DS3DMODE_NORMAL, DS3D_DEFERRED); + pDS3dBuffer->SetPosition(fPos[0], fPos[1], fPos[2], DS3D_DEFERRED); + pDS3dBuffer->SetVelocity(fVel[0], fVel[1], fVel[2], DS3D_DEFERRED); + } + } + + if (FAILED( hr = pDSBOutput->Lock(block * iByteSize, iByteSize, &aptr1, &nbytes1, &aptr2, &nbytes2, 0))) + qFatal("DXAudioOutput: Lock block %d (%d bytes)",block, iByteSize); + if (aptr1 && nbytes1) + CopyMemory(aptr1, psBuffer, MIN(iByteSize, nbytes1)); + if (aptr2 && nbytes2) + CopyMemory(aptr2, psBuffer+(nbytes1/2), MIN(iByteSize-nbytes1, nbytes2)); + if (FAILED( hr = pDSBOutput->Unlock(aptr1, nbytes1, aptr2, nbytes2))) + qFatal("DXAudioOutput: Unlock"); + + // If we get another while we're working, we're already taking care of it. + ResetEvent(hNotificationEvent); + + if( FAILED( hr = pDSBOutput->GetCurrentPosition(&dwPlayPosition, &dwWritePosition ) ) ) + qFatal("DXAudioOutputPlayer: GetCurrentPosition"); + + playblock = dwWritePosition / iByteSize; + nowriteblock = (playblock + g.s.iDXOutputDelay + 1) % NBLOCKS; + } + return alive; +} + + DXAudioOutput::DXAudioOutput() { HRESULT hr; DSBUFFERDESC dsbdesc; @@ -86,6 +264,8 @@ DXAudioOutput::DXAudioOutput() { pDSBPrimary = NULL; p3DListener = NULL; + hNotificationEvent = CreateEvent( NULL, FALSE, FALSE, NULL ); + if (! g.s.qbaDXOutput.isEmpty()) { LPGUID lpguid = reinterpret_cast<LPGUID>(g.s.qbaDXOutput.data()); if( FAILED( hr = DirectSoundCreate8(lpguid, &pDS, NULL))) { @@ -132,6 +312,8 @@ DXAudioOutput::DXAudioOutput() { DXAudioOutput::~DXAudioOutput() { bRunning = false; wipe(); + SetEvent(hNotificationEvent); + wait(); if (p3DListener) p3DListener->Release(); @@ -139,12 +321,12 @@ DXAudioOutput::~DXAudioOutput() { pDSBPrimary->Release(); if (pDS) pDS->Release(); + CloseHandle(hNotificationEvent); } AudioOutputPlayer *DXAudioOutput::getPlayer(Player *player) { DXAudioOutputPlayer *daopPlayer = new DXAudioOutputPlayer(this, player); - if (bOk) - daopPlayer->start(QThread::HighPriority); + SetEvent(daopPlayer->hNotificationEvent); return daopPlayer; } @@ -168,171 +350,66 @@ void DXAudioOutput::updateListener() { qWarning("DXAudioOutputPlayer: CommitDeferrredSettings failed 0x%08lx", hr); } -DXAudioOutputPlayer::DXAudioOutputPlayer(DXAudioOutput *ao, Player *player) : AudioOutputPlayer(ao, player) { - dxAudio = static_cast<DXAudioOutput *>(aoOutput); - DSBUFFERDESC dsbd; - WAVEFORMATEX wfx; - HRESULT hr; +void DXAudioOutput::run() { + DXAudioOutputPlayer *dxaop; + AudioOutputPlayer *aop; + HANDLE handles[MAXIMUM_WAIT_OBJECTS]; + DWORD count = 0; + DWORD hit; - ZeroMemory( &dsbd, sizeof(DSBUFFERDESC) ); + LARGE_INTEGER ticksPerSecond; + LARGE_INTEGER ticksPerFrame; + LARGE_INTEGER ticksNow; + LARGE_INTEGER ticksNext = {QuadPart: 0L}; - ZeroMemory( &wfx, sizeof(wfx) ); - wfx.wFormatTag = WAVE_FORMAT_PCM; - wfx.nChannels = 1; - wfx.nBlockAlign = 2; - wfx.nSamplesPerSec = SAMPLE_RATE; - wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; - wfx.wBitsPerSample = 16; + bool found; + bool alive; - dsbd.dwSize = sizeof(DSBUFFERDESC); - dsbd.dwFlags = DSBCAPS_GLOBALFOCUS|DSBCAPS_GETCURRENTPOSITION2; - dsbd.dwFlags |= DSBCAPS_CTRLPOSITIONNOTIFY; - if (dxAudio->p3DListener) - dsbd.dwFlags |= DSBCAPS_CTRL3D; - dsbd.dwBufferBytes = iFrameSize * 2 * NBLOCKS; - dsbd.lpwfxFormat = &wfx; - if (dxAudio->p3DListener) { - switch (g.s.a3dModel) { - case Settings::None: - case Settings::Panning: - dsbd.guid3DAlgorithm = DS3DALG_NO_VIRTUALIZATION; - break; - case Settings::Light: - dsbd.guid3DAlgorithm = DS3DALG_HRTF_LIGHT; - break; - case Settings::Full: - dsbd.guid3DAlgorithm = DS3DALG_HRTF_FULL; - break; - } - } - - hNotificationEvent = CreateEvent( NULL, FALSE, FALSE, NULL ); + QueryPerformanceFrequency(&ticksPerSecond); + ticksPerFrame.QuadPart = ticksPerSecond.QuadPart / 50; - // Create the DirectSound buffer - if( FAILED( hr = dxAudio->pDS->CreateSoundBuffer( &dsbd, &pDSBOutput, NULL ) ) ) - qFatal("DXAudioOutputPlayer: CreateSoundBuffer (Secondary): 0x%08lx", hr); + while (bRunning) { + // Ok, so I thought about it.. + // We might optimize this by having a QHash<hEvent, AOP *>, but.. + // .. most of the time, there will be one or maybe two AOPs active. + // The overhead of updating the cache is likely to outstrip the + // benefit. - DSBPOSITIONNOTIFY aPosNotify[NBLOCKS]; - - for(int i=0;i<NBLOCKS;i++) { - aPosNotify[i].dwOffset = iFrameSize * 2 * i; - aPosNotify[i].hEventNotify = hNotificationEvent; - } + count = 0; - if( FAILED( hr = pDSBOutput->QueryInterface( IID_IDirectSoundNotify, reinterpret_cast<VOID**>(&pDSNotify) ) ) ) - qFatal("DXAudioOutputPlayer: QueryInterface (Notify)"); - - if( FAILED( hr = pDSNotify->SetNotificationPositions( NBLOCKS, aPosNotify ) ) ) - qFatal("DXAudioOutputPlayer: SetNotificationPositions"); - - pDS3dBuffer = NULL; - if (dxAudio->p3DListener) { - if (FAILED(pDSBOutput->QueryInterface(IID_IDirectSound3DBuffer8, reinterpret_cast<void **>(&pDS3dBuffer)))) - qFatal("DXAudioOutputPlayer: QueryInterface (DirectSound3DBuffer)"); - - pDS3dBuffer->SetMinDistance(g.s.fDXMinDistance, DS3D_DEFERRED); - pDS3dBuffer->SetMaxDistance(g.s.fDXMaxDistance, DS3D_DEFERRED); - } - - LPVOID aptr1, aptr2; - DWORD nbytes1, nbytes2; - - if (FAILED( hr = pDSBOutput->Lock(0, 0, &aptr1, &nbytes1, &aptr2, &nbytes2, DSBLOCK_ENTIREBUFFER))) - qFatal("DXAudioOutputPlayer: Initial Lock"); - - dwBufferSize = nbytes1 + nbytes2; - if (aptr1) - ZeroMemory(aptr1, nbytes1); - if (aptr2) - ZeroMemory(aptr2, nbytes2); - - if (FAILED( hr = pDSBOutput->Unlock(aptr1, nbytes1, aptr2, nbytes2))) - qFatal("DXAudioOutputPlayer: Initial Unlock"); - - dwLastWritePos = 0; - dwLastPlayPos = 0; - dwTotalPlayPos = 0; - - qWarning("DXAudioOutputPlayer: New %dHz output buffer of %ld bytes", SAMPLE_RATE, dwBufferSize); -} - -DXAudioOutputPlayer::~DXAudioOutputPlayer() { - bRunning = false; - SetEvent(hNotificationEvent); - wait(); - if (pDSNotify) - pDSNotify->Release(); - if (pDSBOutput) - pDSBOutput->Release(); - CloseHandle(hNotificationEvent); -} - -void DXAudioOutputPlayer::run() { - int playblock; - int nowriteblock; - int lastwriteblock = NBLOCKS-1; - DWORD dwPlayPosition, dwWritePosition; - HRESULT hr; - - if (FAILED( hr = pDSBOutput->Play(0, 0, DSBPLAY_LOOPING))) - qFatal("DXAUdioOutputPlayer: Play"); - - bRunning = true; - - while (bRunning && dxAudio->bRunning) { - if( FAILED( hr = pDSBOutput->GetCurrentPosition(&dwPlayPosition, &dwWritePosition ) ) ) - qFatal("DXAudioOutputPlayer: GetCurrentPosition"); - - playblock = dwWritePosition / iByteSize; - nowriteblock = (playblock + g.s.iDXOutputDelay + 1) % NBLOCKS; + qrwlOutputs.lockForRead(); + foreach(aop, qmOutputs) { + dxaop=static_cast<DXAudioOutputPlayer *>(aop); + handles[count++] = dxaop->hNotificationEvent; + } + handles[count++] = hNotificationEvent; + qrwlOutputs.unlock(); - for(int block=(lastwriteblock + 1) % NBLOCKS;block!=nowriteblock;block=(block + 1) % NBLOCKS) { - lastwriteblock = block; + hit = WaitForMultipleObjects(count, handles, false, 20); - decodeNextFrame(); - dxAudio->updateListener(); + found = false; - if (pDS3dBuffer) { - bool center = g.bCenterPosition; - DWORD mode; + QueryPerformanceCounter(&ticksNow); + if (ticksNow.QuadPart > ticksNext.QuadPart) { + ticksNext.QuadPart = ticksNow.QuadPart + ticksPerFrame.QuadPart; + updateListener(); + } - pDS3dBuffer->GetMode(&mode); - if (! center) { - if ((fabs(fPos[0]) < 0.1) && (fabs(fPos[1]) < 0.1) && (fabs(fPos[2]) < 0.1)) - center = true; - else if (! g.p->bValid) - center = true; - } - if (center) { - if (mode != DS3DMODE_DISABLE) - pDS3dBuffer->SetMode(DS3DMODE_DISABLE, DS3D_DEFERRED); - } else { - if (mode != DS3DMODE_NORMAL) - pDS3dBuffer->SetMode(DS3DMODE_NORMAL, DS3D_DEFERRED); - pDS3dBuffer->SetPosition(fPos[0], fPos[1], fPos[2], DS3D_DEFERRED); - pDS3dBuffer->SetVelocity(fVel[0], fVel[1], fVel[2], DS3D_DEFERRED); + qrwlOutputs.lockForRead(); + if (hit >= WAIT_OBJECT_0 && hit < WAIT_OBJECT_0 + count - 1) { + foreach(aop, qmOutputs) { + dxaop=static_cast<DXAudioOutputPlayer *>(aop); + if (handles[hit - WAIT_OBJECT_0] == dxaop->hNotificationEvent) { + found = true; + alive = dxaop->playFrames(); + break; } } - - LPVOID aptr1, aptr2; - DWORD nbytes1, nbytes2; - - if (FAILED( hr = pDSBOutput->Lock(block * iByteSize, iByteSize, &aptr1, &nbytes1, &aptr2, &nbytes2, 0))) - qFatal("DXAudioOutput: Lock block %d (%d bytes)",block, iByteSize); - if (aptr1 && nbytes1) - CopyMemory(aptr1, psBuffer, MIN(iByteSize, nbytes1)); - if (aptr2 && nbytes2) - CopyMemory(aptr2, psBuffer+(nbytes1/2), MIN(iByteSize-nbytes1, nbytes2)); - if (FAILED( hr = pDSBOutput->Unlock(aptr1, nbytes1, aptr2, nbytes2))) - qFatal("DXAudioOutput: Unlock"); - - if( FAILED( hr = pDSBOutput->GetCurrentPosition(&dwPlayPosition, &dwWritePosition ) ) ) - qFatal("DXAudioOutputPlayer: GetCurrentPosition"); - - playblock = dwWritePosition / iByteSize; - nowriteblock = (playblock + g.s.iDXOutputDelay + 1) % NBLOCKS; } - WaitForSingleObject(hNotificationEvent, INFINITE); + qrwlOutputs.unlock(); + + if (found && ! alive) + removeBuffer(dxaop->p); } } diff --git a/DXAudioOutput.h b/DXAudioOutput.h index 3c1902d19..4a524e138 100644 --- a/DXAudioOutput.h +++ b/DXAudioOutput.h @@ -36,7 +36,8 @@ class DXAudioOutput; -class DXAudioOutputPlayer : public AudioOutputPlayer, public QThread { +class DXAudioOutputPlayer : public AudioOutputPlayer { + friend class DXAudioOutput; Q_OBJECT protected: LPDIRECTSOUNDBUFFER pDSBOutput; @@ -48,14 +49,15 @@ class DXAudioOutputPlayer : public AudioOutputPlayer, public QThread { DWORD dwLastWritePos; DWORD dwLastPlayPos; DWORD dwTotalPlayPos; - - bool bRunning; + int iLastwriteblock; DXAudioOutput *dxAudio; + + bool bPlaying; public: DXAudioOutputPlayer(DXAudioOutput *, Player *); ~DXAudioOutputPlayer(); - void run(); + bool playFrames(); }; @@ -66,14 +68,17 @@ class DXAudioOutput : public AudioOutput { LPDIRECTSOUND8 pDS; LPDIRECTSOUNDBUFFER pDSBPrimary; LPDIRECTSOUND3DLISTENER8 p3DListener; + HANDLE hNotificationEvent; virtual AudioOutputPlayer *getPlayer(Player *); void updateListener(); + bool bRebuild; bool bOk; public: DXAudioOutput(); ~DXAudioOutput(); + void run(); }; #else @@ -94,6 +94,7 @@ int main(int argc, char **argv) g.ai = AudioInputRegistrar::newFromChoice(); g.ai->start(QThread::HighestPriority); g.ao = AudioOutputRegistrar::newFromChoice(); + g.ao->start(QThread::HighPriority); } // Increase our priority class to live alongside games. diff --git a/mumble.pro b/mumble.pro index 382ffe907..d068d2c3f 100644 --- a/mumble.pro +++ b/mumble.pro @@ -18,4 +18,5 @@ win32 { SOURCES += DXAudioInput.cpp DXAudioOutput.cpp DXConfigDialog.cpp GlobalShortcut_win.cpp TextToSpeech_win.cpp Plugins.cpp INCLUDEPATH += /dx90sdk/include "/Program Files/Microsoft Speech SDK 5.1/Include" LIBS += -L\\dx90sdk\\lib -L"/Program Files/Microsoft Speech SDK 5.1/Lib/i386" -ldsound -ldxguid -ldinput8 -lsapi -lole32 + INCLUDEPATH += /boost/include/boost-1_33 } |