// FixedSizeAudioBuffer.cpp: implementation of the FixedSizeAudioBuffer class. // ////////////////////////////////////////////////////////////////////// #include "FixedSizeAudioBuffer.h" #include "AudioSample.h" #include "AudioSampleManager.h" using namespace std; ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// FixedSizeAudioBuffer::FixedSizeAudioBuffer() { char subFacilityName[100]; sprintf(subFacilityName, "FixedSizeAudioBuffer:%x", this); tracer.SetSubFacilityName(subFacilityName); SetTraceLevel(); outputDuration = 20; minFrameSize = 1; minFrameDuration = 1; outputSize = 1000; // any high number bRunning = false; InitializeCriticalSection(&audioBufferMutex); } FixedSizeAudioBuffer::~FixedSizeAudioBuffer() { DeleteCriticalSection(&audioBufferMutex); } int FixedSizeAudioBuffer::SetTraceLevel() { long SystemMask = 0; if ((SystemMask = GetRegKeyLong(HKEY_CURRENT_USER, "Software\\Cisco Systems\\MTC\\Tracing", "AllComponents", 0x0)) == 0) { SystemMask = GetRegKeyLong(HKEY_CURRENT_USER, "Software\\Cisco Systems\\MTC\\Tracing", "FixedSizeAudioBuffer", 0x100000); } tracer.SetSystemMask(SystemMask); return 0; } int FixedSizeAudioBuffer::SetOutputDuration(int duration) { outputDuration = duration; return 0; } int FixedSizeAudioBuffer::EnqueuePacket(std::vector > &data) { AudioSample *audioSample = NULL; if (data.size() > 0) { audioSample = data[0].first; } if (audioSample) { minFrameDuration = audioSample->MinFrameDuration(); minFrameSize = audioSample->MinFrameSize(); audioSample->GetFormat(&audioFormat); outputSize = (outputDuration * 1000 * minFrameSize) / minFrameDuration; if (audioSample->DataSize() > 0) { EnterCriticalSection(&audioBufferMutex); audioBuffer.insert(audioBuffer.end(), audioSample->Data(), audioSample->Data() + audioSample->DataSize()); LeaveCriticalSection(&audioBufferMutex); } else if (audioSample->GetSilenceDuration() > 0) { EnterCriticalSection(&audioBufferMutex); for (int i=0; iSilenceSize(); i++) { audioBuffer.push_back(0); } LeaveCriticalSection(&audioBufferMutex); } } else { tracer.tracef(ERR, "EnquePacket : asked to enqueue NULL packet\n"); Sleep(5); } return 0; } int FixedSizeAudioBuffer::TransformStarted() { EnterCriticalSection(&audioBufferMutex); audioBuffer.clear(); audioFormat = WaveFormat::GetWaveFormat(WaveFormat_PCM_16_8_1); LeaveCriticalSection(&audioBufferMutex); bRunning = true; return 0; } int FixedSizeAudioBuffer::TransformStopped() { bRunning = false; return 0; } int FixedSizeAudioBuffer::RenderAudioSamples(std::vector > &data) { if (bRunning) { EnqueuePacket(data); int outputSize = (outputDuration * 1000 * minFrameSize) / minFrameDuration; EnterCriticalSection(&audioBufferMutex); while (audioBuffer.size() >= outputSize) { AudioSample *outputSample = NULL; (AudioSampleManager::GetInstance())->GetAudioSample(&outputSample, this); outputSample->SetFormat(audioFormat); char *outputData = outputSample->Data(); for (int i=0; iSetDataSize(outputSize); EnterCriticalSection(&audioSinksMutex); std::vector::iterator iter; for (iter = audioSinks.begin(); iter != audioSinks.end(); iter++) { SendAudioSample(outputSample, *iter); } LeaveCriticalSection(&audioSinksMutex); outputSample->Release(this); outputSample = NULL; } LeaveCriticalSection(&audioBufferMutex); } return 0; } int FixedSizeAudioBuffer::GenerateData(AudioSample **ppAudioSample) { tracer.tracef(DET, "GenerateData\n"); tracer.tracef(DET, "GenerateData : filling data\n"); int result(0); *ppAudioSample = NULL; while(audioBuffer.size() < outputSize) { tracer.tracef(DET, "GenerateData : audioBuffer.size = %d, outputSize = %d\n", audioBuffer.size(), outputSize); if (!bRunning) { break; } // get data from all sources inputData.clear(); EnterCriticalSection(&audioSourcesMutex); vector::iterator iter = audioSources.begin(); for (iter = audioSources.begin(); iter != audioSources.end(); iter++) { AudioSample *pAudioSample = NULL; // tracer.tracef(DET, "GenerateData : calling GiveNextAudioSample\n"); result = (*iter)->GiveNextAudioSample(&pAudioSample, this); if (result != 0) { if (pAudioSample) { pAudioSample->Release(this); pAudioSample = NULL; } } else { if (pAudioSample) { inputData.push_back(make_pair(pAudioSample, *iter)); } } } LeaveCriticalSection(&audioSourcesMutex); // add the data to the queue EnqueuePacket(inputData); // release all the input samples // (since they were obtained by GiveNextAudioSample, they will not be released by the corresponding source for (int i = 0; i < inputData.size(); i++) { AudioSample *sample = (inputData[i]).first; if (sample) { sample->Release(this); sample = NULL; } } } tracer.tracef(DET, "GenerateData : transmitting data\n"); if (bRunning && audioBuffer.size() >= outputSize) { AudioSample *outputSample = NULL; (AudioSampleManager::GetInstance())->GetAudioSample(&outputSample, this); outputSample->SetFormat(audioFormat); char *outputData = outputSample->Data(); for (int i=0; iSetDataSize(outputSize); *ppAudioSample = outputSample; } if (*ppAudioSample == NULL) { (AudioSampleManager::GetInstance())->GetAudioSample(ppAudioSample, this); (*ppAudioSample)->SetFormat(audioFormat); (*ppAudioSample)->SetDataSize(0); (*ppAudioSample)->SetSilenceDuration(outputDuration); } tracer.tracef(DET, "~GenerateData\n"); return 0; } int FixedSizeAudioBuffer::TransformAudioSamples(std::vector > &data, AudioSample **ppAudioSample) { return 0; }