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

📄 waveaudiosource.cxx

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

#include "AudioSample.h"
#include "AudioSampleManager.h"
#include "WaveAudioSource.h"

using namespace std;

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

WaveAudioSource::WaveAudioSource()
{
	char subFacilityName[100];
	sprintf(subFacilityName, "WaveAudioSource:%x", this);
	tracer.SetSubFacilityName(subFacilityName);
	SetTraceLevel();
	tracer.tracef(EE, "Constructor begin\n");
	numBuffers = WAVESOURCE_NUM_WAVEHDR;
	bufferSize = WAVESOURCE_DEFAULT_WAVEHDR_SIZE;
	InitializeCriticalSection(&waveInMutex);
	InitializeCriticalSection(&bufferListMutex);
	InitializeCriticalSection(&filterMutex);
	dataEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
	bEnableAddBuffer = false;
	hWaveIn = NULL;
	waveinDeviceID = WAVE_MAPPER;
	buffersToAdd.clear();
	bRunning = false;
	needToSetVolume = false;
	micVolume = 0;

	// set default format
	SetFormat(WaveFormat_PCM_16_8_1);
}

WaveAudioSource::~WaveAudioSource()
{
	tracer.tracef(EE, "Destructor begin\n");
	EnterCriticalSection(&filterMutex);
	tracer.tracef(ARB, "WaveAudioSource~ : entered filterMutex\n");
	LeaveCriticalSection(&filterMutex);
	tracer.tracef(ARB, "WaveAudioSource~ : left filterMutex\n");
	DeleteCriticalSection(&waveInMutex);
	DeleteCriticalSection(&bufferListMutex);
	DeleteCriticalSection(&filterMutex);
	CloseHandle(dataEvent);
	tracer.tracef(EE, "Destructor end\n");
}

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

int
WaveAudioSource::SetFormat(int waveFormatNumber)
{
	tracer.tracef(EE, "SetFormat %d : bRunning = %d\n", waveFormatNumber, bRunning);
	if (!bRunning)
	{
		format = WaveFormat::GetWaveFormat(waveFormatNumber);
	}
	tracer.tracef(EE, "~SetFormat\n");
	return 0;
}

int
WaveAudioSource::SetVolume(unsigned long vvolume)
{
	if (bRunning)
	{
		MMRESULT rc;              // Return code.
		HMIXER hMixer;            // Mixer handle used in mixer API calls.
		MIXERCONTROL mxc;         // Holds the mixer control data.
		MIXERLINE mxl;            // Holds the mixer line data.
		MIXERLINECONTROLS mxlc;   // Obtains the mixer control.
		bool volumeChanged = false;

		// Open the mixer. This opens the mixer with a deviceID of 0. If you
		// have a single sound card/mixer, then this will open it. If you have
		// multiple sound cards/mixers, the deviceIDs will be 0, 1, 2, and
		// so on.
		rc = mixerOpen(&hMixer, (UINT)hWaveIn, 0, 0, MIXER_OBJECTF_HWAVEIN);
		if (MMSYSERR_NOERROR == rc) 
		{
			tracer.tracef(DET, "SetVolume : mixerOpen succeeded\n");
			do
			{
				// Initialize MIXERLINE structure.
				ZeroMemory(&mxl,sizeof(mxl));
				mxl.cbStruct = sizeof(mxl);

				// Specify the line you want to get. You are getting the input line
				// here. If you want to get the output line, you need to use
				// MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT.
				mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;

				rc = mixerGetLineInfo((HMIXEROBJ)hMixer, &mxl,
									   MIXER_GETLINEINFOF_COMPONENTTYPE);
				if (MMSYSERR_NOERROR != rc)
				{
					tracer.tracef(ERR, "SetVolume : e-mixerGetLineInfo((HMIXEROBJ)hMixer, &mxl, MIXER_GETLINEINFOF_COMPONENTTYPE) : %d\n", rc);
					break;
				}

				// now find out the microphone input for that line (the ADC)
				int numConnections = mxl.cConnections;
				tracer.tracef(DET, "SetVolume : mixerGetLineInfo succeeded. numConnections = %d\n", numConnections);
				DWORD destinationLineID = mxl.dwDestination;
				for (int j=0; j<numConnections; j++)
				{
					mxl.cbStruct = sizeof(MIXERLINE);
					mxl.dwDestination = destinationLineID;
					mxl.dwSource = j;

					rc = mixerGetLineInfo((HMIXEROBJ)hMixer, &mxl, MIXER_GETLINEINFOF_SOURCE);
					if (rc == MMSYSERR_NOERROR)
					{
						tracer.tracef(DET, "SetVolume : mixerGetLineInfo succeeded. dwComponentType %d = 0x%x\n", j, mxl.dwComponentType);
						if (mxl.dwComponentType == MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE ||
							mxl.dwComponentType == MIXERLINE_COMPONENTTYPE_SRC_UNDEFINED)
						{
							// Get the control.
							ZeroMemory(&mxlc, sizeof(mxlc));
							mxlc.cbStruct = sizeof(mxlc);
							mxlc.dwLineID = mxl.dwLineID;
							mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
							mxlc.cControls = 1;
							mxlc.cbmxctrl = sizeof(mxc);
							mxlc.pamxctrl = &mxc;
							ZeroMemory(&mxc, sizeof(mxc));
							mxc.cbStruct = sizeof(mxc);
							rc = mixerGetLineControls((HMIXEROBJ)hMixer,&mxlc,
													   MIXER_GETLINECONTROLSF_ONEBYTYPE);
							if (MMSYSERR_NOERROR != rc)
							{
								tracer.tracef(ERR, "SetVolume : e-mixerGetLineControls((HMIXEROBJ)hMixer,&mxlc, MIXER_GETLINECONTROLSF_ONEBYTYPE) : %d. Could not get MIXERCONTROL_CONTROLTYPE_VOLUME\n", rc);
								break;
							}

							// After successfully getting the peakmeter control, the volume range
							// will be specified by mxc.Bounds.lMinimum to mxc.Bounds.lMaximum.

							MIXERCONTROLDETAILS mxcd;             // Gets the control values.
							MIXERCONTROLDETAILS_UNSIGNED volStruct; // Gets the control values.
							MIXERCONTROLDETAILS_BOOLEAN muteStruct; // Get Mute Setting
							long volume;                          // Holds the final volume value.

							// Initialize the MIXERCONTROLDETAILS structure
							ZeroMemory(&mxcd, sizeof(mxcd));
							mxcd.cbStruct = sizeof(mxcd);
							mxcd.cbDetails = sizeof(volStruct);
							mxcd.dwControlID = mxc.dwControlID;
							mxcd.paDetails = &volStruct;
							mxcd.cChannels = 1;

							// Get the current value of the volume control. Typically, you
							// would set a timer in your program to query the volume every 10th
							// of a second or so.
							rc = mixerGetControlDetails((HMIXEROBJ)hMixer, &mxcd,
														 MIXER_GETCONTROLDETAILSF_VALUE);
							if (MMSYSERR_NOERROR != rc) 
							{
								tracer.tracef(ERR, "SetVolume : e-mixerGetControlDetails((HMIXEROBJ)hMixer, &mxcd, MIXER_GETCONTROLDETAILSF_VALUE) : %d\n", rc);
								break;
							}
							volume = volStruct.dwValue;

							volStruct.dwValue = (0xffff * vvolume) / 100;
							rc = mixerSetControlDetails((HMIXEROBJ)hMixer, &mxcd,
														 MIXER_SETCONTROLDETAILSF_VALUE);
							if (MMSYSERR_NOERROR != rc) 
							{
								tracer.tracef(ERR, "SetVolume : e-mixerSetControlDetails((HMIXEROBJ)hMixer, &mxcd, MIXER_SETCONTROLDETAILSF_VALUE) : %d\n", rc);
								break;
							}

							volumeChanged = true;

							// Get the mute control.
							ZeroMemory(&mxlc, sizeof(mxlc));
							mxlc.cbStruct = sizeof(mxlc);
							mxlc.dwLineID = mxl.dwLineID;
							mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_MUTE;
							mxlc.cControls = 1;
							mxlc.cbmxctrl = sizeof(mxc);
							mxlc.pamxctrl = &mxc;
							ZeroMemory(&mxc, sizeof(mxc));
							mxc.cbStruct = sizeof(mxc);
							rc = mixerGetLineControls((HMIXEROBJ)hMixer,&mxlc,
													   MIXER_GETLINECONTROLSF_ONEBYTYPE);
							if (MMSYSERR_NOERROR != rc)
							{
								tracer.tracef(ERR, "SetVolume : e-mixerGetLineControls((HMIXEROBJ)hMixer,&mxlc, MIXER_GETLINECONTROLSF_ONEBYTYPE) : %d. Could not get MIXERCONTROL_CONTROLTYPE_VOLUME\n", rc);
								if (mxl.dwComponentType != MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE)
								{
									continue;
								}
								else
								{
									break;
								}
							}

							ZeroMemory(&mxcd, sizeof(mxcd));
							mxcd.cbStruct = sizeof(mxcd);
							mxcd.cbDetails = sizeof(muteStruct);
							mxcd.dwControlID = mxc.dwControlID;
							mxcd.paDetails = &muteStruct;
							mxcd.cChannels = 1;

							// Get the current value of the mute control. Typically, you
							// would set a timer in your program to query the volume every 10th
							// of a second or so.
							rc = mixerGetControlDetails((HMIXEROBJ)hMixer, &mxcd,
														 MIXER_GETCONTROLDETAILSF_VALUE);
							if (MMSYSERR_NOERROR != rc) 
							{
								tracer.tracef(ERR, "SetVolume : e-mixerGetControlDetails((HMIXEROBJ)hMixer, &mxcd, MIXER_GETCONTROLDETAILSF_VALUE) : %d\n", rc);
								break;
							}
							muteStruct.fValue = vvolume == 0 ? 1 : 0;
							rc = mixerSetControlDetails((HMIXEROBJ)hMixer, &mxcd,
														 MIXER_SETCONTROLDETAILSF_VALUE);
							if (MMSYSERR_NOERROR != rc) 
							{
								tracer.tracef(ERR, "SetVolume : e-mixerSetControlDetails((HMIXEROBJ)hMixer, &mxcd, MIXER_SETCONTROLDETAILSF_VALUE) : %d\n", rc);
								break;
							}
							break;
						}
					}
				}
			} while (false);
			if (volumeChanged == false)
			{
				do
				{
					// Initialize MIXERLINE structure.
					ZeroMemory(&mxl,sizeof(mxl));
					mxl.cbStruct = sizeof(mxl);

					// Specify the line you want to get. You are getting the input line
					// here. If you want to get the output line, you need to use
					// MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT.
					mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;

					rc = mixerGetLineInfo((HMIXEROBJ)hMixer, &mxl,
										   MIXER_GETLINEINFOF_COMPONENTTYPE);
					if (MMSYSERR_NOERROR != rc)
					{
						tracer.tracef(ERR, "SetVolume : e-mixerGetLineInfo((HMIXEROBJ)hMixer, &mxl, MIXER_GETLINEINFOF_COMPONENTTYPE) : %d\n", rc);
						break;
					}

					// now find out the microphone input for that line (the ADC)
					int numConnections = mxl.cConnections;
					tracer.tracef(DET, "SetVolume : mixerGetLineInfo succeeded. numConnections = %d\n", numConnections);
					DWORD destinationLineID = mxl.dwDestination;

					// Get the control.
					ZeroMemory(&mxlc, sizeof(mxlc));
					mxlc.cbStruct = sizeof(mxlc);
					mxlc.dwLineID = mxl.dwLineID;
					mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
					mxlc.cControls = 1;
					mxlc.cbmxctrl = sizeof(mxc);
					mxlc.pamxctrl = &mxc;
					ZeroMemory(&mxc, sizeof(mxc));
					mxc.cbStruct = sizeof(mxc);
					rc = mixerGetLineControls((HMIXEROBJ)hMixer,&mxlc,
											   MIXER_GETLINECONTROLSF_ONEBYTYPE);
					if (MMSYSERR_NOERROR != rc)
					{
						tracer.tracef(ERR, "SetVolume : e-mixerGetLineControls((HMIXEROBJ)hMixer,&mxlc, MIXER_GETLINECONTROLSF_ONEBYTYPE) : %d. Could not get MIXERCONTROL_CONTROLTYPE_VOLUME\n", rc);
						if (mxl.dwComponentType != MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE)
						{
							continue;
						}
						else
						{
							break;
						}
					}
					MIXERCONTROLDETAILS mxcd;             // Gets the control values.
					MIXERCONTROLDETAILS_UNSIGNED volStruct; // Gets the control values.
					MIXERCONTROLDETAILS_BOOLEAN muteStruct; // Get Mute Setting
					long volume;                          // Holds the final volume value.

					// Initialize the MIXERCONTROLDETAILS structure
					ZeroMemory(&mxcd, sizeof(mxcd));
					mxcd.cbStruct = sizeof(mxcd);
					mxcd.cbDetails = sizeof(volStruct);
					mxcd.dwControlID = mxc.dwControlID;
					mxcd.paDetails = &volStruct;
					mxcd.cChannels = 1;

					// Get the current value of the peakmeter control. Typically, you
					// would set a timer in your program to query the volume every 10th
					// of a second or so.
					rc = mixerGetControlDetails((HMIXEROBJ)hMixer, &mxcd,
												 MIXER_GETCONTROLDETAILSF_VALUE);
					if (MMSYSERR_NOERROR != rc) 
					{
						tracer.tracef(ERR, "SetVolume : e-mixerGetControlDetails((HMIXEROBJ)hMixer, &mxcd, MIXER_GETCONTROLDETAILSF_VALUE) : %d\n", rc);
						break;
					}
					volume = volStruct.dwValue;

					volStruct.dwValue = (0xffff * vvolume) / 100;
					rc = mixerSetControlDetails((HMIXEROBJ)hMixer, &mxcd,
												 MIXER_SETCONTROLDETAILSF_VALUE);
					if (MMSYSERR_NOERROR != rc) 
					{
						tracer.tracef(ERR, "SetVolume : e-mixerSetControlDetails((HMIXEROBJ)hMixer, &mxcd, MIXER_SETCONTROLDETAILSF_VALUE) : %d\n", rc);
						break;
					}
					volumeChanged = true;

					// Get the mute control.
					ZeroMemory(&mxlc, sizeof(mxlc));
					mxlc.cbStruct = sizeof(mxlc);
					mxlc.dwLineID = mxl.dwLineID;
					mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_MUTE;
					mxlc.cControls = 1;
					mxlc.cbmxctrl = sizeof(mxc);
					mxlc.pamxctrl = &mxc;
					ZeroMemory(&mxc, sizeof(mxc));
					mxc.cbStruct = sizeof(mxc);
					rc = mixerGetLineControls((HMIXEROBJ)hMixer,&mxlc,
											   MIXER_GETLINECONTROLSF_ONEBYTYPE);
					if (MMSYSERR_NOERROR != rc)
					{
						tracer.tracef(ERR, "SetVolume : e-mixerGetLineControls((HMIXEROBJ)hMixer,&mxlc, MIXER_GETLINECONTROLSF_ONEBYTYPE) : %d. Could not get MIXERCONTROL_CONTROLTYPE_VOLUME\n", rc);
						if (mxl.dwComponentType != MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE)
						{
							continue;
						}
						else
						{
							break;
						}
					}

					ZeroMemory(&mxcd, sizeof(mxcd));
					mxcd.cbStruct = sizeof(mxcd);
					mxcd.cbDetails = sizeof(muteStruct);
					mxcd.dwControlID = mxc.dwControlID;
					mxcd.paDetails = &muteStruct;
					mxcd.cChannels = 1;

					// Get the current value of the mute control. Typically, you
					// would set a timer in your program to query the volume every 10th
					// of a second or so.
					rc = mixerGetControlDetails((HMIXEROBJ)hMixer, &mxcd,
												 MIXER_GETCONTROLDETAILSF_VALUE);
					if (MMSYSERR_NOERROR != rc) 
					{
						tracer.tracef(ERR, "SetVolume : e-mixerGetControlDetails((HMIXEROBJ)hMixer, &mxcd, MIXER_GETCONTROLDETAILSF_VALUE) : %d\n", rc);
						break;
					}
					muteStruct.fValue = vvolume == 0 ? 1 : 0;
					rc = mixerSetControlDetails((HMIXEROBJ)hMixer, &mxcd,
												 MIXER_SETCONTROLDETAILSF_VALUE);
					if (MMSYSERR_NOERROR != rc) 
					{
						tracer.tracef(ERR, "SetVolume : e-mixerSetControlDetails((HMIXEROBJ)hMixer, &mxcd, MIXER_SETCONTROLDETAILSF_VALUE) : %d\n", rc);
						break;
					}
					break;
				} while (false);
			}
			mixerClose(hMixer);
		}
		else
		{
			tracer.tracef(ERR, "SetVolume : e-mixerOpen : %d\n", rc);
		}
	}
	else
	{
		needToSetVolume = true;
	}
	micVolume = vvolume;
	return 0;
}

int
WaveAudioSource::SetDeviceID(unsigned int deviceID)
{
	waveinDeviceID = deviceID;
	return 0;
}

int
WaveAudioSource::SetBufferSize(int size)
{
	tracer.tracef(EE, "SetBufferSize %d : bRunning = %d\n", size, bRunning);
	if (!bRunning)
	{
		bufferSize = size;
	}
	tracer.tracef(EE, "~SetBufferSize\n");
	return 0;
}

int
WaveAudioSource::SetNumBuffers(int num)
{
	tracer.tracef(EE, "SetNumBuffers %d : bRunning = %d\n", num, bRunning);
	if (!bRunning)
	{
		numBuffers = num;
	}
	tracer.tracef(EE, "~SetNumBuffers\n");
	return 0;
}

int
WaveAudioSource::BeginAudioCapture()

⌨️ 快捷键说明

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