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

📄 waveaudiosink.cxx

📁 rtp在linux下的实现
💻 CXX
📖 第 1 页 / 共 2 页
字号:
// WaveAudioSink.cpp: implementation of the WaveAudioSink class.
//
//////////////////////////////////////////////////////////////////////

#ifndef WIN32
#include <stdio.h>
#endif

#include "AudioSample.h"
#include "AudioSource.h"
#include "WaveAudioSink.h"

using namespace std;

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

WaveAudioSink::WaveAudioSink()
{
	char subFacilityName[100];
	sprintf(subFacilityName, "WaveAudioSink:%x", this);
	tracer.SetSubFacilityName(subFacilityName);
	SetTraceLevel();
	tracer.tracef(EE, "Constructor begin\n");
	enabled = true;
#ifdef WIN32
	waveoutDeviceID = WAVE_MAPPER;
	dataEvent	= CreateEvent(NULL, FALSE, FALSE, NULL);
	pauseEvent	= CreateEvent(NULL, FALSE, FALSE, NULL);
#else
        //Need a wave mapper equivalent here - TODO
#endif
	frameSize = WAVESINK_DEFAULT_WAVEHDR_SIZE;
	numFrames = WAVESINK_NUM_WAVEHDR;
	InitializeCriticalSection(&dataMutex);
	InitializeCriticalSection(&freeBuffersMutex);
	InitializeCriticalSection(&filterMutex);

	// set default format
	wfx.nAvgBytesPerSec = 16000;
	wfx.wFormatTag = WAVE_FORMAT_PCM;
	wfx.wBitsPerSample = 16;
	wfx.nChannels = 1;
	wfx.nBlockAlign = 2;
	wfx.nSamplesPerSec = 8000;
	wfx.cbSize = 0;
	tracer.tracef(EE, "Constructor end\n");
}

WaveAudioSink::~WaveAudioSink()
{
	tracer.tracef(EE, "Destructor begin\n");
	EnterCriticalSection(&filterMutex);
	tracer.tracef(ARB, "WaveAudioSink~ : entered filterMutex\n");
	LeaveCriticalSection(&filterMutex);
	tracer.tracef(ARB, "WaveAudioSink~ : left filterMutex\n");
	DeleteCriticalSection(&dataMutex);
	DeleteCriticalSection(&freeBuffersMutex);
	DeleteCriticalSection(&filterMutex);
#ifdef WIN32
	CloseHandle(dataEvent);
	CloseHandle(pauseEvent);
#endif
	tracer.tracef(EE, "Destructor end\n");
}

int
WaveAudioSink::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", "WaveAudioSink", 0x100000);
	}
	tracer.SetSystemMask(SystemMask);
#endif
	return 0;
}

int
WaveAudioSink::SetVolume(unsigned long volume)
{
#ifdef WIN32
	tracer.tracef(SDI_LEVEL_ENTRY_EXIT, "SetVolume %d\n", volume);
	volume = min(100, volume);
	unsigned long normalizedVolume = (volume * 0xffff) / 100;
	unsigned long volumeToSet = (normalizedVolume << 16) + normalizedVolume;
	tracer.tracef(SDI_LEVEL_DETAILED, "SetVolume : Entering dataMutex\n");
	EnterCriticalSection(&dataMutex);
	if (bRunning)
	{
		tracer.tracef(SDI_LEVEL_ARBITRARY, "SetVolume : waveOutSetVolume\n");
		MMRESULT mr = waveOutSetVolume(hWaveOut, volumeToSet);
		tracer.tracef(SDI_LEVEL_ARBITRARY, "SetVolume : ~waveOutSetVolume\n");
		LeaveCriticalSection(&dataMutex);
		tracer.tracef(SDI_LEVEL_DETAILED, "SetVolume : Left dataMutex\n");
		if (FAILED(mr)) 
		{
			tracer.tracef(SDI_LEVEL_ERROR, "SetVolume : e-waveOutSetVolume : 0x%x\n", mr);
		}
	}
	else
	{
		LeaveCriticalSection(&dataMutex);
		tracer.tracef(SDI_LEVEL_DETAILED, "SetVolume : Left dataMutex\n");
	}
	tracer.tracef(SDI_LEVEL_ENTRY_EXIT, "~SetVolume\n");
	return NOERROR;
#else
       //Need Linux specific code to set the volume
       return 0;
#endif
}


int
WaveAudioSink::SetFrameSize(unsigned long size)
{
	tracer.tracef(EE, "SetFrameSize %u\n", size);
#ifdef WIN32
	frameSize = min(size, WAVESINK_MAX_WAVEHDR_SIZE);
	tracer.tracef(EE, "~SetFrameSize\n");
	return NOERROR;
#else
	frameSize = (size <  WAVESINK_MAX_WAVEHDR_SIZE) ? size : WAVESINK_MAX_WAVEHDR_SIZE;
        return 0;
#endif
}


int
WaveAudioSink::SetNumFrames(unsigned long num)
{
	tracer.tracef(EE, "SetNumFrames %u\n", num);
#ifdef WIN32
	numFrames = min(num, WAVESINK_MAX_WAVEHDR);
	tracer.tracef(EE, "~SetNumFrames\n");
	return NOERROR;
#else
	numFrames = (num <  WAVESINK_MAX_WAVEHDR) ? num : WAVESINK_MAX_WAVEHDR;
        return 0;
#endif
}



int
WaveAudioSink::BeginAudioRender()
{
#ifdef WIN32
	tracer.tracef(SDI_LEVEL_ENTRY_EXIT, "BeginAudioRender\n");
	HRESULT result = NOERROR;

	tracer.tracef(SDI_LEVEL_DETAILED, "BeginAudioRender : Entering freeBuffersMutex\n");
	EnterCriticalSection(&freeBuffersMutex);
	freeBuffers.clear();
	LeaveCriticalSection(&freeBuffersMutex);
	tracer.tracef(SDI_LEVEL_DETAILED, "BeginAudioRender : Left freeBuffersMutex\n");

	MMRESULT mr = NOERROR;
	tracer.tracef(SDI_LEVEL_ARBITRARY, "BeginAudioRender : waveOutOpen\n");
	mr = waveOutOpen(&hWaveOut, waveoutDeviceID, &wfx, (DWORD)SpeakerCallback, DWORD(this), CALLBACK_FUNCTION);
	tracer.tracef(SDI_LEVEL_ARBITRARY, "BeginAudioRender : ~waveOutOpen\n");
	if (mr != NOERROR)
	{
		tracer.tracef(SDI_LEVEL_ERROR, "BeginAudioRender : e-waveOutOpen : 0x%x\n", mr);
		result = -10;
	}
	else
	{
		for (int i=0; i<numFrames; i++)
		{
			memset(&(waveHdr[i]), 0, sizeof(waveHdr[i]));
			waveHdr[i].lpData = dataBuffer[i];
			waveHdr[i].dwBufferLength = frameSize;
			waveHdr[i].dwFlags = 0;
			waveHdr[i].dwUser = i;

			tracer.tracef(SDI_LEVEL_ARBITRARY, "BeginAudioRender : waveOutPrepareHeader\n");
			result = waveOutPrepareHeader(hWaveOut, &(waveHdr[i]), sizeof(waveHdr[i]));
			tracer.tracef(SDI_LEVEL_ARBITRARY, "BeginAudioRender : ~waveOutPrepareHeader\n");
			if (result != MMSYSERR_NOERROR)
			{
				tracer.tracef(SDI_LEVEL_ERROR, "BeginAudioRender : e-waveOutPrepareHeader : 0x%x\n", result);
			}
			else
			{
				tracer.tracef(SDI_LEVEL_ARBITRARY, "BeginAudioRender : Entering freeBuffersMutex\n");
				EnterCriticalSection(&freeBuffersMutex);
				freeBuffers.push_back(&(waveHdr[i]));
				LeaveCriticalSection(&freeBuffersMutex);
			}
		}
	}
	tracer.tracef(SDI_LEVEL_ENTRY_EXIT, "~BeginAudioRender : returning %d 0x%x\n", result);
	return result;
#else
        return 0;
#endif
}


int
WaveAudioSink::EndAudioRender() 
{
#ifdef WIN32
	tracer.tracef(SDI_LEVEL_ENTRY_EXIT, "EndAudioRender\n");
	HRESULT result = NOERROR;

	tracer.tracef(SDI_LEVEL_ARBITRARY, "EndAudioRender : waveOutReset\n");
	result = waveOutReset(hWaveOut);
	tracer.tracef(SDI_LEVEL_ARBITRARY, "EndAudioRender : ~waveOutReset\n");
	if (result != MMSYSERR_NOERROR) 
	{
		tracer.tracef(SDI_LEVEL_ERROR, "EndAudioRender : e-waveOutReset : 0x%x\n", result);
		result = -10;
	}
	else 
	{
		for (int i=0; i<numFrames; i++) 
		{
			tracer.tracef(SDI_LEVEL_ARBITRARY, "EndAudioRender : waveOutUnprepareHeader\n");
			result = waveOutUnprepareHeader(hWaveOut, &(waveHdr[i]), sizeof(waveHdr[i]));
			tracer.tracef(SDI_LEVEL_ARBITRARY, "EndAudioRender : ~waveOutUnprepareHeader\n");
			if (result != MMSYSERR_NOERROR) 
			{
				tracer.tracef(SDI_LEVEL_ERROR, "EndAudioRender : e-waveOutUnprepareHeader : 0x%x\n", result);
			}
		}
		tracer.tracef(SDI_LEVEL_ARBITRARY, "EndAudioRender : waveOutClose\n");
		result = waveOutClose(hWaveOut);
		tracer.tracef(SDI_LEVEL_ARBITRARY, "EndAudioRender : ~waveOutClose\n");
		if (result != MMSYSERR_NOERROR) 
		{
			tracer.tracef(SDI_LEVEL_ERROR, "EndAudioRender : e-waveOutClose : 0x%x\n", result);
			result = -30;
		}
	}
	tracer.tracef(SDI_LEVEL_ENTRY_EXIT, "~EndAudioRender : returning %d 0x%x\n", result);
	return result;
#else
        //Do we do somthing for Linux ? - TODO
        return 0;
#endif
}


int
WaveAudioSink::ResetAudioRender() 
{
#ifdef WIN32
	tracer.tracef(SDI_LEVEL_ENTRY_EXIT, "ResetAudioRender\n");
	HRESULT result = NOERROR;
	result = EndAudioRender();
	if (result == MMSYSERR_NOERROR) 
	{
		result = BeginAudioRender();
	}
	tracer.tracef(SDI_LEVEL_ENTRY_EXIT, "~ResetAudioRender : %d 0x%x\n", result, result);
	return result;
#else
        //Handle for Linux - TODO
        return 0;
#endif
}


WAVEHDR *
WaveAudioSink::GetBuffer() 
{
	tracer.tracef(DET, "GetBuffer\n");
	WAVEHDR *wHdr = NULL;
#ifdef WIN32
	int bufferLength;
	while(true) {
		tracer.tracef(SDI_LEVEL_DETAILED, "GetBuffer : Entering dataMutex\n");
		EnterCriticalSection(&dataMutex);
		bool running = bRunning;
		LeaveCriticalSection(&dataMutex);
		tracer.tracef(SDI_LEVEL_DETAILED, "GetBuffer : Left dataMutex\n");
		if (!running) 
		{
			tracer.tracef(SDI_LEVEL_DETAILED, "GetBuffer : !bRunning\n");
			break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -