📄 fixedsizeaudiobuffer.cxx
字号:
// FixedSizeAudioBuffer.cpp: implementation of the FixedSizeAudioBuffer class.
//
//////////////////////////////////////////////////////////////////////
#include "FixedSizeAudioBuffer.h"
#include "AudioSample.h"
#include "AudioSampleManager.h"
#include <stdio.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()
{
#ifdef WIN32
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);
#endif
return 0;
}
int
FixedSizeAudioBuffer::SetOutputDuration(int duration)
{
outputDuration = duration;
return 0;
}
int
FixedSizeAudioBuffer::EnqueuePacket(std::vector<std::pair<AudioSample *, AudioSource *> > &data)
{
if(data.size() == 0)
{
tracer.tracef(DET, "Nothing to enqueue\n");
return 0;
}
AudioSample *audioSample = data[0].first;
minFrameDuration = audioSample->MinFrameDuration();
minFrameSize = audioSample->MinFrameSize();
audioSample->GetFormat(&audioFormat);
outputSize = (outputDuration * 1000 * minFrameSize) / minFrameDuration;
#ifndef WIN32
EnterCriticalSection(&audioSinksMutex);
std::vector<AudioSink *>::iterator iter;
for (iter = audioSinks.begin(); iter != audioSinks.end(); iter++)
{
AUDIOBUFFER& aBuffer = myAudioBufferMap[(*iter)];
//myAudioBufferMap[(*iter)].push_back(audioSample);
if (audioSample->DataSize() > 0)
{
EnterCriticalSection(&audioBufferMutex);
aBuffer.insert(aBuffer.end(), audioSample->Data(), audioSample->Data() + audioSample->DataSize());
LeaveCriticalSection(&audioBufferMutex);
}
else if (audioSample->GetSilenceDuration() > 0)
{
EnterCriticalSection(&audioBufferMutex);
for (int i=0; i<audioSample->SilenceSize(); i++)
{
aBuffer.push_back(0);
}
LeaveCriticalSection(&audioBufferMutex);
}
}
LeaveCriticalSection(&audioSinksMutex);
#else
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; i<audioSample->SilenceSize(); i++)
{
audioBuffer.push_back(0);
}
LeaveCriticalSection(&audioBufferMutex);
}
#endif
return 0;
}
int
FixedSizeAudioBuffer::StartTransform()
{
SetTraceLevel();
EnterCriticalSection(&audioBufferMutex);
audioBuffer.clear();
audioFormat = WaveFormat::GetWaveFormat(WaveFormat_PCM_16_8_1);
LeaveCriticalSection(&audioBufferMutex);
bRunning = true;
return 0;
}
int
FixedSizeAudioBuffer::StopTransform()
{
bRunning = false;
return 0;
}
int
FixedSizeAudioBuffer::RenderAudioSamples(std::vector<std::pair<AudioSample *, AudioSource *> > &data)
{
if (bRunning)
{
EnqueuePacket(data);
#ifdef WIN32
int outputSize = (outputDuration * 1000 * minFrameSize) / minFrameDuration;
EnterCriticalSection(&audioBufferMutex);
while (audioBuffer.size() >= outputSize)
{
AudioSample *outputSample;
(AudioSampleManager::GetInstance())->GetAudioSample(&outputSample);
outputSample->SetFormat(audioFormat);
char *outputData = outputSample->Data();
for (int i=0; i<outputSize; i++)
{
*outputData = audioBuffer[0];
audioBuffer.erase(audioBuffer.begin());
}
outputSample->SetDataSize(outputSize);
EnterCriticalSection(&audioSinksMutex);
std::vector<AudioSink *>::iterator iter;
for (iter = audioSinks.begin(); iter != audioSinks.end(); iter++)
{
SendAudioSample(outputSample, *iter);
}
LeaveCriticalSection(&audioSinksMutex);
outputSample->Release();
}
LeaveCriticalSection(&audioBufferMutex);
#endif
}
return 0;
}
int
FixedSizeAudioBuffer::GenerateData(AudioSample **ppAudioSample)
{
tracer.tracef(DET, "FixedSizeAudioBuffer::GenerateData\n");
tracer.tracef(DET, "GenerateData : filling data\n");
*ppAudioSample = 0;
if(audioBuffer.size() == 0)
{
AudioSample* audioSample;
(AudioSampleManager::GetInstance())->GetAudioSample(&audioSample);
*ppAudioSample = audioSample;
if (audioSample)
{
audioSample->SetFormat(WaveFormat::GetWaveFormat(WaveFormat_PCM_16_8_1));
audioSample->SetSilenceDuration(20);
audioSample->SetDataSize(0);
}
tracer.tracef(DET, "~GenerateData : Sending silence data\n");
return 0;
}
#ifdef WIN32
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<AudioSource *>::iterator iter = audioSources.begin();
for (iter = audioSources.begin(); iter != audioSources.end(); iter++)
{
AudioSample *pAudioSample;
tracer.tracef(DET, "GenerateData : calling GiveNextAudioSample\n");
(*iter)->GiveNextAudioSample(&pAudioSample, this);
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;
sample->Release();
}
}
tracer.tracef(DET, "GenerateData : transmitting data\n");
if (bRunning && audioBuffer.size() >= outputSize)
{
AudioSample *outputSample;
(AudioSampleManager::GetInstance())->GetAudioSample(&outputSample);
outputSample->SetFormat(audioFormat);
char *outputData = outputSample->Data();
for (int i=0; i<outputSize; i++)
{
*outputData = audioBuffer[0];
outputData++;
audioBuffer.erase(audioBuffer.begin());
}
outputSample->SetDataSize(outputSize);
*ppAudioSample = outputSample;
}
if (*ppAudioSample == NULL)
{
(AudioSampleManager::GetInstance())->GetAudioSample(ppAudioSample);
(*ppAudioSample)->SetFormat(audioFormat);
(*ppAudioSample)->SetDataSize(0);
(*ppAudioSample)->SetSilenceDuration(outputDuration);
}
#else
assert(0);
#endif
tracer.tracef(DET, "~GenerateData\n");
return 0;
}
int
FixedSizeAudioBuffer::TransformAudioSamples(std::vector<std::pair<AudioSample *, AudioSource *> > &data, AudioSample **ppAudioSample)
{
return 0;
}
int
FixedSizeAudioBuffer::GiveNextAudioSample(AudioSample **ppAudioSample, AudioSink *audioSink)
{
#ifndef WIN32
tracer.tracef(DET, "GiveNextAudioSample : \n");
AUDIOBUFFER & aBuffer = myAudioBufferMap[audioSink];
if(aBuffer.size())
{
tracer.tracef(DET, "GiveNextAudioSample giving sample: \n");
//AudioSample* front = aBuffer[0];
//aBuffer.erase(aBuffer.begin());
//*ppAudioSample = front;
//tracer.tracef(DET, "GiveNextAudioSample giving sample: %d\n", front->DataSize());
//front->Release();
int outputSize = (outputDuration * 1000 * minFrameSize) / minFrameDuration;
EnterCriticalSection(&audioBufferMutex);
while (aBuffer.size() >= outputSize)
{
AudioSample *outputSample;
(AudioSampleManager::GetInstance())->GetAudioSample(&outputSample);
outputSample->SetFormat(audioFormat);
char *outputData = outputSample->Data();
for (int i=0; i<outputSize; i++)
{
*outputData = aBuffer[0];
outputData++;
aBuffer.erase(aBuffer.begin());
}
outputSample->SetDataSize(outputSize);
*ppAudioSample = outputSample;
}
LeaveCriticalSection(&audioBufferMutex);
}
else
{
//Give silent packet
AudioSample* audioSample;
(AudioSampleManager::GetInstance())->GetAudioSample(&audioSample);
*ppAudioSample = audioSample;
if (audioSample)
{
audioSample->SetFormat(WaveFormat::GetWaveFormat(WaveFormat_PCM_16_8_1));
//audioSample->SetSilenceDuration(20);
audioSample->SetSilenceDuration(0);
audioSample->SetDataSize(0);
}
tracer.tracef(DET, "~GiveNextAudioSample : Sending silence data\n");
}
#else
AudioSource::GiveNextAudioSample(ppAudioSample, audioSink);
#endif
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -