Browse Source

Minor code review + spring-cleaning for DSound code (no functionality changes)

tags/2021-05-28
jules 12 years ago
parent
commit
5d52b0e071
1 changed files with 109 additions and 187 deletions
  1. +109
    -187
      modules/juce_audio_devices/native/juce_win32_DirectSound.cpp

+ 109
- 187
modules/juce_audio_devices/native/juce_win32_DirectSound.cpp View File

@@ -165,36 +165,36 @@ namespace
//==============================================================================
#define DS_DEBUGGING 1
#ifdef DS_DEBUGGING
#define CATCH JUCE_CATCH_EXCEPTION
#undef log
#define log(a) Logger::writeToLog(a);
#undef logError
#define logError(a) logDSError(a, __LINE__);
static void logDSError (HRESULT hr, int lineNum)
#ifdef DS_DEBUGGING
#define CATCH JUCE_CATCH_EXCEPTION
#undef log
#define log(a) Logger::writeToLog(a);
#undef logError
#define logError(a) logDSError(a, __LINE__);
static void logDSError (HRESULT hr, int lineNum)
{
if (FAILED (hr))
{
if (hr != S_OK)
{
String error ("DS error at line ");
error << lineNum << " - " << getDSErrorMessage (hr);
log (error);
}
String error ("DS error at line ");
error << lineNum << " - " << getDSErrorMessage (hr);
log (error);
}
#else
#define CATCH JUCE_CATCH_ALL
#define log(a)
#define logError(a)
#endif
}
#else
#define CATCH JUCE_CATCH_ALL
#define log(a)
#define logError(a)
#endif
//==============================================================================
#define DSOUND_FUNCTION(functionName, params) \
typedef HRESULT (WINAPI *type##functionName) params; \
static type##functionName ds##functionName = 0;
static type##functionName ds##functionName = nullptr;
#define DSOUND_FUNCTION_LOAD(functionName) \
ds##functionName = (type##functionName) GetProcAddress (h, #functionName); \
jassert (ds##functionName != 0);
jassert (ds##functionName != nullptr);
typedef BOOL (CALLBACK *LPDSENUMCALLBACKW) (LPGUID, LPCWSTR, LPCWSTR, LPVOID);
typedef BOOL (CALLBACK *LPDSENUMCALLBACKA) (LPGUID, LPCSTR, LPCSTR, LPVOID);
@@ -206,7 +206,7 @@ namespace
void initialiseDSoundFunctions()
{
if (dsDirectSoundCreate == 0)
if (dsDirectSoundCreate == nullptr)
{
HMODULE h = LoadLibraryA ("dsound.dll");
@@ -237,12 +237,10 @@ public:
void close()
{
HRESULT hr;
if (pOutputBuffer != nullptr)
{
log ("closing dsound out: " + name);
hr = pOutputBuffer->Stop();
HRESULT hr = pOutputBuffer->Stop();
logError (hr);
pOutputBuffer->Release();
@@ -268,10 +266,10 @@ public:
String error;
HRESULT hr = E_NOINTERFACE;
if (dsDirectSoundCreate != 0)
hr = dsDirectSoundCreate (&guid, &pDirectSound, 0);
if (dsDirectSoundCreate != nullptr)
hr = dsDirectSoundCreate (&guid, &pDirectSound, nullptr);
if (hr == S_OK)
if (SUCCEEDED (hr))
{
bytesPerBuffer = (bufferSizeSamples * (bitDepth >> 2)) & ~15;
totalBytesPerBuffer = (3 * bytesPerBuffer) & ~15;
@@ -280,7 +278,7 @@ public:
hr = pDirectSound->SetCooperativeLevel (GetDesktopWindow(), 2 /* DSSCL_PRIORITY */);
logError (hr);
if (hr == S_OK)
if (SUCCEEDED (hr))
{
IDirectSoundBuffer* pPrimaryBuffer;
@@ -294,21 +292,21 @@ public:
hr = pDirectSound->CreateSoundBuffer (&primaryDesc, &pPrimaryBuffer, 0);
logError (hr);
if (hr == S_OK)
if (SUCCEEDED (hr))
{
WAVEFORMATEX wfFormat;
wfFormat.wFormatTag = WAVE_FORMAT_PCM;
wfFormat.nChannels = (unsigned short) numChannels;
wfFormat.nSamplesPerSec = (DWORD) sampleRate;
wfFormat.wBitsPerSample = (unsigned short) bitDepth;
wfFormat.nBlockAlign = (unsigned short) (wfFormat.nChannels * wfFormat.wBitsPerSample / 8);
wfFormat.nAvgBytesPerSec = wfFormat.nSamplesPerSec * wfFormat.nBlockAlign;
wfFormat.wFormatTag = WAVE_FORMAT_PCM;
wfFormat.nChannels = (unsigned short) numChannels;
wfFormat.nSamplesPerSec = (DWORD) sampleRate;
wfFormat.wBitsPerSample = (unsigned short) bitDepth;
wfFormat.nBlockAlign = (unsigned short) (wfFormat.nChannels * wfFormat.wBitsPerSample / 8);
wfFormat.nAvgBytesPerSec = wfFormat.nSamplesPerSec * wfFormat.nBlockAlign;
wfFormat.cbSize = 0;
hr = pPrimaryBuffer->SetFormat (&wfFormat);
logError (hr);
if (hr == S_OK)
if (SUCCEEDED (hr))
{
DSBUFFERDESC secondaryDesc = { 0 };
secondaryDesc.dwSize = sizeof (DSBUFFERDESC);
@@ -320,7 +318,7 @@ public:
hr = pDirectSound->CreateSoundBuffer (&secondaryDesc, &pOutputBuffer, 0);
logError (hr);
if (hr == S_OK)
if (SUCCEEDED (hr))
{
log ("opening dsound out step 3");
@@ -331,21 +329,21 @@ public:
(LPVOID*) &pDSBuffData, &dwDataLen, 0, 0, 0);
logError (hr);
if (hr == S_OK)
if (SUCCEEDED (hr))
{
zeromem (pDSBuffData, dwDataLen);
hr = pOutputBuffer->Unlock (pDSBuffData, dwDataLen, 0, 0);
if (hr == S_OK)
if (SUCCEEDED (hr))
{
hr = pOutputBuffer->SetCurrentPosition (0);
if (hr == S_OK)
if (SUCCEEDED (hr))
{
hr = pOutputBuffer->Play (0, 0, 1 /* DSBPLAY_LOOPING */);
if (hr == S_OK)
if (SUCCEEDED (hr))
return String::empty;
}
}
@@ -387,7 +385,7 @@ public:
continue;
}
if (hr == S_OK)
if (SUCCEEDED (hr))
break;
logError (hr);
@@ -400,7 +398,6 @@ public:
playWriteGap += totalBytesPerBuffer;
int bytesEmpty = (int) (playCursor - writeOffset);
if (bytesEmpty < 0)
bytesEmpty += totalBytesPerBuffer;
@@ -412,71 +409,47 @@ public:
if (bytesEmpty >= bytesPerBuffer)
{
void* lpbuf1 = nullptr;
void* lpbuf2 = nullptr;
int* buf1 = nullptr;
int* buf2 = nullptr;
DWORD dwSize1 = 0;
DWORD dwSize2 = 0;
HRESULT hr = pOutputBuffer->Lock ((DWORD) writeOffset, (DWORD) bytesPerBuffer,
&lpbuf1, &dwSize1,
&lpbuf2, &dwSize2, 0);
HRESULT hr = pOutputBuffer->Lock (writeOffset, (DWORD) bytesPerBuffer,
(void**) &buf1, &dwSize1,
(void**) &buf2, &dwSize2, 0);
if (hr == MAKE_HRESULT (1, 0x878, 150)) // DSERR_BUFFERLOST
{
pOutputBuffer->Restore();
hr = pOutputBuffer->Lock ((DWORD) writeOffset, (DWORD) bytesPerBuffer,
&lpbuf1, &dwSize1,
&lpbuf2, &dwSize2, 0);
hr = pOutputBuffer->Lock (writeOffset, (DWORD) bytesPerBuffer,
(void**) &buf1, &dwSize1,
(void**) &buf2, &dwSize2, 0);
}
if (hr == S_OK)
if (SUCCEEDED (hr))
{
if (bitDepth == 16)
{
int* dest = static_cast<int*> (lpbuf1);
const float* left = leftBuffer;
const float* right = rightBuffer;
int samples1 = (int) (dwSize1 >> 2);
int samples2 = (int) (dwSize2 >> 2);
if (left == 0)
if (left == nullptr)
{
while (--samples1 >= 0)
*dest++ = (convertInputValue (*right++) << 16);
dest = static_cast<int*> (lpbuf2);
while (--samples2 >= 0)
*dest++ = (convertInputValue (*right++) << 16);
for (int* dest = buf1; --samples1 >= 0;) *dest++ = convertInputValues (0, *right++);
for (int* dest = buf2; --samples2 >= 0;) *dest++ = convertInputValues (0, *right++);
}
else if (right == 0)
else if (right == nullptr)
{
while (--samples1 >= 0)
*dest++ = (0xffff & convertInputValue (*left++));
dest = static_cast<int*> (lpbuf2);
while (--samples2 >= 0)
*dest++ = (0xffff & convertInputValue (*left++));
for (int* dest = buf1; --samples1 >= 0;) *dest++ = convertInputValues (*left++, 0);
for (int* dest = buf2; --samples2 >= 0;) *dest++ = convertInputValues (*left++, 0);
}
else
{
while (--samples1 >= 0)
{
const int l = convertInputValue (*left++);
const int r = convertInputValue (*right++);
*dest++ = (r << 16) | (0xffff & l);
}
dest = static_cast<int*> (lpbuf2);
while (--samples2 >= 0)
{
const int l = convertInputValue (*left++);
const int r = convertInputValue (*right++);
*dest++ = (r << 16) | (0xffff & l);
}
for (int* dest = buf1; --samples1 >= 0;) *dest++ = convertInputValues (*left++, *right++);
for (int* dest = buf2; --samples2 >= 0;) *dest++ = convertInputValues (*left++, *right++);
}
}
else
@@ -486,7 +459,7 @@ public:
writeOffset = (writeOffset + dwSize1 + dwSize2) % totalBytesPerBuffer;
pOutputBuffer->Unlock (lpbuf1, dwSize1, lpbuf2, dwSize2);
pOutputBuffer->Unlock (buf1, dwSize1, buf2, dwSize2);
}
else
{
@@ -519,9 +492,10 @@ private:
int totalBytesPerBuffer, bytesPerBuffer;
unsigned int lastPlayCursor;
static inline int convertInputValue (const float v) noexcept
static inline int convertInputValues (const float l, const float r) noexcept
{
return jlimit (-32768, 32767, roundToInt (32767.0f * v));
return jlimit (-32768, 32767, roundToInt (32767.0f * r)) << 16
| (0xffff & jlimit (-32768, 32767, roundToInt (32767.0f * l)));
}
JUCE_DECLARE_NON_COPYABLE (DSoundInternalOutChannel);
@@ -582,27 +556,23 @@ public:
readOffset = 0;
totalBytesPerBuffer = 0;
String error;
HRESULT hr = E_NOINTERFACE;
if (dsDirectSoundCaptureCreate != 0)
hr = dsDirectSoundCaptureCreate (&guid, &pDirectSoundCapture, 0);
logError (hr);
HRESULT hr = dsDirectSoundCaptureCreate != nullptr
? dsDirectSoundCaptureCreate (&guid, &pDirectSoundCapture, nullptr)
: E_NOINTERFACE;
if (hr == S_OK)
if (SUCCEEDED (hr))
{
const int numChannels = 2;
bytesPerBuffer = (bufferSizeSamples * (bitDepth >> 2)) & ~15;
totalBytesPerBuffer = (3 * bytesPerBuffer) & ~15;
WAVEFORMATEX wfFormat;
wfFormat.wFormatTag = WAVE_FORMAT_PCM;
wfFormat.nChannels = (unsigned short)numChannels;
wfFormat.nSamplesPerSec = (DWORD) sampleRate;
wfFormat.wBitsPerSample = (unsigned short)bitDepth;
wfFormat.nBlockAlign = (unsigned short)(wfFormat.nChannels * (wfFormat.wBitsPerSample / 8));
wfFormat.nAvgBytesPerSec = wfFormat.nSamplesPerSec * wfFormat.nBlockAlign;
wfFormat.wFormatTag = WAVE_FORMAT_PCM;
wfFormat.nChannels = (unsigned short)numChannels;
wfFormat.nSamplesPerSec = (DWORD) sampleRate;
wfFormat.wBitsPerSample = (unsigned short) bitDepth;
wfFormat.nBlockAlign = (unsigned short) (wfFormat.nChannels * (wfFormat.wBitsPerSample / 8));
wfFormat.nAvgBytesPerSec = wfFormat.nSamplesPerSec * wfFormat.nBlockAlign;
wfFormat.cbSize = 0;
DSCBUFFERDESC captureDesc = { 0 };
@@ -614,19 +584,17 @@ public:
log ("opening dsound in step 2");
hr = pDirectSoundCapture->CreateCaptureBuffer (&captureDesc, &pInputBuffer, 0);
logError (hr);
if (hr == S_OK)
if (SUCCEEDED (hr))
{
hr = pInputBuffer->Start (1 /* DSCBSTART_LOOPING */);
logError (hr);
if (hr == S_OK)
if (SUCCEEDED (hr))
return String::empty;
}
}
error = getDSErrorMessage (hr);
logError (hr);
const String error (getDSErrorMessage (hr));
close();
return error;
@@ -637,7 +605,7 @@ public:
if (pInputBuffer != nullptr)
{
DWORD capturePos;
pInputBuffer->GetCurrentPosition (&capturePos, (DWORD*)&readOffset);
pInputBuffer->GetCurrentPosition (&capturePos, (DWORD*) &readOffset);
}
}
@@ -650,7 +618,7 @@ public:
HRESULT hr = pInputBuffer->GetCurrentPosition (&capturePos, &readPos);
logError (hr);
if (hr != S_OK)
if (FAILED (hr))
return true;
int bytesFilled = (int) (readPos - readOffset);
@@ -659,16 +627,16 @@ public:
if (bytesFilled >= bytesPerBuffer)
{
LPBYTE lpbuf1 = nullptr;
LPBYTE lpbuf2 = nullptr;
short* buf1 = nullptr;
short* buf2 = nullptr;
DWORD dwsize1 = 0;
DWORD dwsize2 = 0;
HRESULT hr = pInputBuffer->Lock ((DWORD) readOffset, (DWORD) bytesPerBuffer,
(void**) &lpbuf1, &dwsize1,
(void**) &lpbuf2, &dwsize2, 0);
(void**) &buf1, &dwsize1,
(void**) &buf2, &dwsize2, 0);
if (hr == S_OK)
if (SUCCEEDED (hr))
{
if (bitDepth == 16)
{
@@ -679,55 +647,20 @@ public:
int samples1 = (int) (dwsize1 >> 2);
int samples2 = (int) (dwsize2 >> 2);
const short* src = (const short*)lpbuf1;
if (destL == 0)
if (destL == nullptr)
{
while (--samples1 >= 0)
{
++src;
*destR++ = *src++ * g;
}
src = (const short*)lpbuf2;
while (--samples2 >= 0)
{
++src;
*destR++ = *src++ * g;
}
for (const short* src = buf1; --samples1 >= 0;) { ++src; *destR++ = *src++ * g; }
for (const short* src = buf2; --samples2 >= 0;) { ++src; *destR++ = *src++ * g; }
}
else if (destR == 0)
else if (destR == nullptr)
{
while (--samples1 >= 0)
{
*destL++ = *src++ * g;
++src;
}
src = (const short*)lpbuf2;
while (--samples2 >= 0)
{
*destL++ = *src++ * g;
++src;
}
for (const short* src = buf1; --samples1 >= 0;) { *destL++ = *src++ * g; ++src; }
for (const short* src = buf2; --samples2 >= 0;) { *destL++ = *src++ * g; ++src; }
}
else
{
while (--samples1 >= 0)
{
*destL++ = *src++ * g;
*destR++ = *src++ * g;
}
src = (const short*)lpbuf2;
while (--samples2 >= 0)
{
*destL++ = *src++ * g;
*destR++ = *src++ * g;
}
for (const short* src = buf1; --samples1 >= 0;) { *destL++ = *src++ * g; *destR++ = *src++ * g; }
for (const short* src = buf2; --samples2 >= 0;) { *destL++ = *src++ * g; *destR++ = *src++ * g; }
}
}
else
@@ -737,7 +670,7 @@ public:
readOffset = (readOffset + dwsize1 + dwsize2) % totalBytesPerBuffer;
pInputBuffer->Unlock (lpbuf1, dwsize1, lpbuf2, dwsize2);
pInputBuffer->Unlock (buf1, dwsize1, buf2, dwsize2);
}
else
{
@@ -789,7 +722,6 @@ public:
isOpen_ (false),
isStarted (false),
bufferSizeSamples (0),
totalSamplesOut (0),
sampleRate (0.0),
inputBuffers (1, 1),
outputBuffers (1, 1),
@@ -867,12 +799,12 @@ public:
int getCurrentBitDepth()
{
int i, bits = 256;
int bits = 256;
for (i = inChans.size(); --i >= 0;)
for (int i = inChans.size(); --i >= 0;)
bits = jmin (bits, inChans[i]->bitDepth);
for (i = outChans.size(); --i >= 0;)
for (int i = outChans.size(); --i >= 0;)
bits = jmin (bits, outChans[i]->bitDepth);
if (bits > 32)
@@ -933,8 +865,6 @@ private:
WaitableEvent startEvent;
int bufferSizeSamples;
int volatile totalSamplesOut;
int64 volatile lastBlockTime;
double sampleRate;
BigInteger enabledInputs, enabledOutputs;
AudioSampleBuffer inputBuffers, outputBuffers;
@@ -963,11 +893,10 @@ private:
{
sleep (5);
int i;
for (i = 0; i < outChans.size(); ++i)
for (int i = 0; i < outChans.size(); ++i)
outChans.getUnchecked(i)->synchronisePosition();
for (i = 0; i < inChans.size(); ++i)
for (int i = 0; i < inChans.size(); ++i)
inChans.getUnchecked(i)->synchronisePosition();
}
}
@@ -989,14 +918,13 @@ public:
int numToDo = 0;
uint32 startTime = Time::getMillisecondCounter();
int i;
for (i = inChans.size(); --i >= 0;)
for (int i = inChans.size(); --i >= 0;)
{
inChans.getUnchecked(i)->doneFlag = false;
++numToDo;
}
for (i = outChans.size(); --i >= 0;)
for (int i = outChans.size(); --i >= 0;)
{
outChans.getUnchecked(i)->doneFlag = false;
++numToDo;
@@ -1009,7 +937,7 @@ public:
for (;;)
{
for (i = inChans.size(); --i >= 0;)
for (int i = inChans.size(); --i >= 0;)
{
DSoundInternalInChannel* const in = inChans.getUnchecked(i);
@@ -1020,7 +948,7 @@ public:
}
}
for (i = outChans.size(); --i >= 0;)
for (int i = outChans.size(); --i >= 0;)
{
DSoundInternalOutChannel* const out = outChans.getUnchecked(i);
@@ -1068,13 +996,10 @@ public:
bufferSizeSamples);
}
JUCE_CATCH_EXCEPTION
totalSamplesOut += bufferSizeSamples;
}
else
{
outputBuffers.clear();
totalSamplesOut = 0;
sleep (1);
}
}
@@ -1132,7 +1057,7 @@ private:
}
BOOL outputEnumProc (LPGUID guid, LPCWSTR desc) { return enumProc (guid, desc, outputDeviceNames, outputGuids); }
BOOL inputEnumProc (LPGUID guid, LPCWSTR desc) { return enumProc (guid, desc, inputDeviceNames, inputGuids); }
BOOL inputEnumProc (LPGUID guid, LPCWSTR desc) { return enumProc (guid, desc, inputDeviceNames, inputGuids); }
static BOOL CALLBACK outputEnumProcW (LPGUID lpGUID, LPCWSTR description, LPCWSTR, LPVOID object)
{
@@ -1151,7 +1076,6 @@ String DSoundAudioIODevice::openDevice (const BigInteger& inputChannels,
double sampleRate_, int bufferSizeSamples_)
{
closeDevice();
totalSamplesOut = 0;
sampleRate = sampleRate_;
@@ -1170,9 +1094,9 @@ String DSoundAudioIODevice::openDevice (const BigInteger& inputChannels,
inputBuffers.setSize (jmax (1, enabledInputs.countNumberOfSetBits()), bufferSizeSamples);
inputBuffers.clear();
int i, numIns = 0;
int numIns = 0;
for (i = 0; i <= enabledInputs.getHighestBit(); i += 2)
for (int i = 0; i <= enabledInputs.getHighestBit(); i += 2)
{
float* left = nullptr;
if (enabledInputs[i])
@@ -1198,7 +1122,7 @@ String DSoundAudioIODevice::openDevice (const BigInteger& inputChannels,
outputBuffers.clear();
int numOuts = 0;
for (i = 0; i <= enabledOutputs.getHighestBit(); i += 2)
for (int i = 0; i <= enabledOutputs.getHighestBit(); i += 2)
{
float* left = nullptr;
if (enabledOutputs[i])
@@ -1223,7 +1147,7 @@ String DSoundAudioIODevice::openDevice (const BigInteger& inputChannels,
SetThreadPriority (GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
SetPriorityClass (GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
for (i = 0; i < outChans.size(); ++i)
for (int i = 0; i < outChans.size(); ++i)
{
error = outChans[i]->open();
@@ -1236,7 +1160,7 @@ String DSoundAudioIODevice::openDevice (const BigInteger& inputChannels,
if (error.isEmpty())
{
for (i = 0; i < inChans.size(); ++i)
for (int i = 0; i < inChans.size(); ++i)
{
error = inChans[i]->open();
@@ -1250,12 +1174,10 @@ String DSoundAudioIODevice::openDevice (const BigInteger& inputChannels,
if (error.isEmpty())
{
totalSamplesOut = 0;
for (i = 0; i < outChans.size(); ++i)
for (int i = 0; i < outChans.size(); ++i)
outChans.getUnchecked(i)->synchronisePosition();
for (i = 0; i < inChans.size(); ++i)
for (int i = 0; i < inChans.size(); ++i)
inChans.getUnchecked(i)->synchronisePosition();
startThread (9);


Loading…
Cancel
Save