📄 waveaudiosink.cxx
字号:
}
tracer.tracef(SDI_LEVEL_DETAILED, "GetBuffer : Entering freeBuffersMutex\n");
EnterCriticalSection(&freeBuffersMutex);
bufferLength = freeBuffers.size();
if (bufferLength > 0)
{
tracer.tracef(SDI_LEVEL_DETAILED, "GetBuffer : bufferLength > 0\n");
wHdr = freeBuffers.front();
freeBuffers.pop_front();
LeaveCriticalSection(&freeBuffersMutex);
tracer.tracef(SDI_LEVEL_DETAILED, "GetBuffer : Left freeBuffersMutex\n");
break;
}
else
{
tracer.tracef(SDI_LEVEL_DETAILED, "GetBuffer : bufferLength <= 0\n");
ResetEvent(dataEvent);
LeaveCriticalSection(&freeBuffersMutex);
tracer.tracef(SDI_LEVEL_DETAILED, "GetBuffer : Left freeBuffersMutex - waiting for dataEvent (1000 ms)\n");
WaitForSingleObject(dataEvent, 1000);
}
}
tracer.tracef(DET, "~GetBuffer\n");
#else
//Handle Linux case
#endif
return wHdr;
}
#ifdef WIN32
void CALLBACK
WaveAudioSink::SpeakerCallback(HWAVEOUT hWaveOut, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2) {
WAVEHDR *wHdr;
WaveAudioSink *filter = (WaveAudioSink *)dwInstance;
// (filter->tracer).tracef(SDI_LEVEL_ENTRY_EXIT, "SpeakerCallback\n");
switch(uMsg) {
case WOM_OPEN:
// (filter->tracer).tracef(SDI_LEVEL_ARBITRARY, "SpeakerCallback : WOM_OPEN\n");
break;
case WOM_CLOSE:
// (filter->tracer).tracef(SDI_LEVEL_ARBITRARY, "SpeakerCallback : WOM_CLOSE\n");
SetEvent(filter->dataEvent);
break;
case WOM_DONE:
(filter->tracer).tracef(SDI_LEVEL_DETAILED, "SpeakerCallback : WOM_DONE\n");
wHdr = (WAVEHDR *)dwParam1;
(filter->tracer).tracef(SDI_LEVEL_DETAILED, "SpeakerCallback : Entering freeBuffersMutex\n");
EnterCriticalSection(&(filter->freeBuffersMutex));
(filter->freeBuffers).push_back(wHdr);
SetEvent(filter->dataEvent); // we do this within the critsec because getbuffer resets this within the same critsec
LeaveCriticalSection(&(filter->freeBuffersMutex));
(filter->tracer).tracef(SDI_LEVEL_DETAILED, "SpeakerCallback : Left freeBuffersMutex\n");
break;
default:
break;
}
// (filter->tracer).tracef(SDI_LEVEL_ENTRY_EXIT, "~SpeakerCallback\n");
}
#endif
int
WaveAudioSink::StartSink()
{
int result(0);
int returnCode(0);
SetTraceLevel();
tracer.tracef(SDI_LEVEL_ENTRY_EXIT, "StartSink\n");
EnterCriticalSection(&filterMutex);
tracer.tracef(ARB, "StartSink : entered filterMutex\n");
do
{
if (bRunning)
{
tracer.tracef(ERR, "StartSink : e-error : already running\n");
result = -10;
break;
}
returnCode = BeginAudioRender();
if (returnCode != 0)
{
tracer.tracef(ERR, "StartSink : e-BeginAudioRender : %d 0x%x\n", returnCode, returnCode);
result = -20;
break;
}
returnCode = AudioSink::StartSink();
if (returnCode != 0)
{
tracer.tracef(ERR, "StartSink : e-AudioSink::StartSink : %d 0x%x\n", returnCode, returnCode);
result = -30;
break;
}
bRunning = true;
}
while (false);
LeaveCriticalSection(&filterMutex);
tracer.tracef(ARB, "StartSink : left filterMutex\n");
tracer.tracef(SDI_LEVEL_ENTRY_EXIT, "~StartSink : returning %d\n", result);
return result;
}
int
WaveAudioSink::StopSink()
{
int result(0);
int returnCode(0);
tracer.tracef(SDI_LEVEL_ENTRY_EXIT, "StopSink\n");
EnterCriticalSection(&filterMutex);
tracer.tracef(ARB, "StopSink : entered filterMutex\n");
do
{
if (!bRunning)
{
tracer.tracef(ERR, "StopSink : e-error : not running\n");
result = -10;
break;
}
returnCode = EndAudioRender();
if (returnCode != 0)
{
tracer.tracef(ERR, "StopSink : e-EndAudioRender : %d 0x%x\n", returnCode, returnCode);
result = -20;
break;
}
returnCode = AudioSink::StopSink();
if (returnCode != 0)
{
tracer.tracef(ERR, "StopSink : e-AudioSink::StopSink : %d 0x%x\n", returnCode, returnCode);
result = -30;
break;
}
bRunning = false;
}
while (false);
LeaveCriticalSection(&filterMutex);
tracer.tracef(ARB, "StopSink : left filterMutex\n");
tracer.tracef(SDI_LEVEL_ENTRY_EXIT, "~StopSink : returning %d\n", result);
return result;
}
#ifdef WIN32
int
WaveAudioSink::SinkThreadStarted(HANDLE sourceThreadHandle, DWORD sourceThreadID)
{
int result(0);
int returnCode(0);
SetTraceLevel();
tracer.tracef(SDI_LEVEL_ENTRY_EXIT, "SinkThreadStarted\n");
EnterCriticalSection(&filterMutex);
tracer.tracef(ARB, "SinkThreadStarted : entered filterMutex\n");
do
{
returnCode = SetThreadPriority(sinkThreadHandle, THREAD_PRIORITY_TIME_CRITICAL);
if (returnCode == 0)
{
returnCode = GetLastError();
tracer.tracef(ERR, "SinkThreadStarted : e-SetThreadPriority : %d 0x%x\n", returnCode, returnCode);
}
returnCode = BeginAudioRender();
if (returnCode != 0)
{
tracer.tracef(ERR, "SinkThreadStarted : e-BeginAudioRender : %d 0x%x\n", returnCode, returnCode);
result = -10;
break;
}
bRunning = true;
}
while (false);
LeaveCriticalSection(&filterMutex);
tracer.tracef(ARB, "SinkThreadStarted : left filterMutex\n");
tracer.tracef(SDI_LEVEL_ENTRY_EXIT, "~SinkThreadStarted : returning %d\n", result);
return result;
}
#else
int
WaveAudioSink::SinkThreadStarted(vthread_t sourceThreadHandle, DWORD sourceThreadID)
{
return 0;
}
#endif
#ifdef WIN32
int
WaveAudioSink::SinkThreadStopped(HANDLE sourceThreadHandle, DWORD sourceThreadID)
{
int result(0);
int returnCode(0);
tracer.tracef(SDI_LEVEL_ENTRY_EXIT, "SinkThreadStopped\n");
EnterCriticalSection(&filterMutex);
tracer.tracef(ARB, "SinkThreadStopped : entered filterMutex\n");
do
{
returnCode = EndAudioRender();
if (returnCode != 0)
{
tracer.tracef(ERR, "SinkThreadStopped : e-EndAudioRender : %d 0x%x\n", returnCode, returnCode);
result = -10;
break;
}
bRunning = true;
}
while (false);
LeaveCriticalSection(&filterMutex);
tracer.tracef(ARB, "SinkThreadStopped : left filterMutex\n");
tracer.tracef(SDI_LEVEL_ENTRY_EXIT, "~SinkThreadStopped : returning %d\n", result);
return result;
}
#else
int
WaveAudioSink::SinkThreadStopped(vthread_t sourceThreadHandle, DWORD sourceThreadID)
{
return 0;
}
#endif
int
WaveAudioSink::SetDeviceID(unsigned int deviceID)
{
waveoutDeviceID = deviceID;
return 0;
}
unsigned int
WaveAudioSink::GetDeviceID()
{
return (unsigned int)waveoutDeviceID;
}
int
WaveAudioSink::SetFormat(int waveFormatNumber)
{
tracer.tracef(SDI_LEVEL_ENTRY_EXIT, "SetFormat %d\n", waveFormatNumber);
wfx = WaveFormat::GetWaveFormat(waveFormatNumber);
tracer.tracef(SDI_LEVEL_ENTRY_EXIT, "~SetFormat\n");
return 0;
}
int
WaveAudioSink::RenderAudioSamples(std::vector<std::pair<AudioSample*, AudioSource* > > &data)
{
#ifdef WIN32
tracer.tracef(SDI_LEVEL_DETAILED, "RenderAudioSamples\n");
HRESULT result = NOERROR;
AudioSample *sample = data[0].first;
WAVEHDR *wHdr = GetBuffer();
if (!wHdr)
{
result = -10;
}
else
{
int bytesToPlay;
if (sample->DataSize() > 0)
{
bytesToPlay = min(frameSize, sample->DataSize());
tracer.tracef(SDI_LEVEL_DETAILED, "RenderAudioSamples : memcpy(0x%x, 0x%x, %d)\n", wHdr->lpData, sample->Data(), bytesToPlay);
memcpy(wHdr->lpData, sample->Data(), bytesToPlay);
}
else
{
bytesToPlay = min(frameSize, sample->SilenceSize());
tracer.tracef(SDI_LEVEL_DETAILED, "RenderAudioSamples : memset(0x%x, 0, %d)\n", wHdr->lpData, bytesToPlay);
memset(wHdr->lpData, 0, bytesToPlay);
}
wHdr->dwBufferLength = bytesToPlay;
tracer.tracef(SDI_LEVEL_DETAILED, "RenderAudioSamples : Entering dataMutex\n");
EnterCriticalSection(&dataMutex);
tracer.tracef(SDI_LEVEL_DETAILED, "RenderAudioSamples : waveOutWrite\n");
MMRESULT mmr = waveOutWrite(hWaveOut, wHdr, sizeof(*wHdr));
tracer.tracef(SDI_LEVEL_DETAILED, "RenderAudioSamples : ~waveOutWrite\n");
LeaveCriticalSection(&dataMutex);
tracer.tracef(SDI_LEVEL_DETAILED, "RenderAudioSamples : Left dataMutex\n");
}
tracer.tracef(SDI_LEVEL_DETAILED, "~RenderAudioSamples\n");
return result;
#else
return 0;
#endif
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -