⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fixedsizeaudiobuffer.cxx

📁 rtp在linux下的实现
💻 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 + -