Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mumble-voip/mumble.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThorvald Natvig <slicer@users.sourceforge.net>2005-09-17 03:03:53 +0400
committerThorvald Natvig <slicer@users.sourceforge.net>2005-09-17 03:03:53 +0400
commit67e3d8533edaa62fca61ebd9ca3e72421843c2fe (patch)
tree7aeec2b1d54c0c4f5b1bb7aeb6fff95138fdb9b3
parent3d9e12b8baad26f8c194f85c4344cf3210305647 (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.cpp4
-rw-r--r--AudioInput.h1
-rw-r--r--AudioOutput.cpp17
-rw-r--r--AudioOutput.h3
-rw-r--r--DXAudioOutput.cpp385
-rw-r--r--DXAudioOutput.h13
-rw-r--r--main.cpp1
-rw-r--r--mumble.pro1
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
diff --git a/main.cpp b/main.cpp
index edaee72c1..837d068ec 100644
--- a/main.cpp
+++ b/main.cpp
@@ -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
}