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

📄 usbaudiodevice.cpp

📁 USB_Audio c8051Fxxx
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// USBAudioDevice.cpp: implementation of the CUSBAudioDevice class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "USBAudioDevice.h"
#include "math.h"


#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

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

CUSBAudioDevice::CUSBAudioDevice()
{
	//Initialize the critical section variable used for exclusivity
	InitializeCriticalSection(&gWaveCriticalSection);

	//Make the handles NULL to begin with
	m_USBAudioAudioHandle = NULL;
	m_USBAudioDataHandle = NULL;
	m_SoundCardHandle = NULL;

	//Set the input buffer pointers to NULL, and size to 0
	m_pEndpoint0ReportBuffer = NULL;
	m_pEndpoint1ReportBuffer = NULL;
	m_pEndpoint2ReportBuffer = NULL;
	m_Endpoint0ReportBufferSize = 0;
	m_Endpoint1ReportBufferSize = 0;
	m_Endpoint2ReportBufferSize = 0;

	//The device is not streaming or tuning initially
	m_Streaming = false;
	m_Tuning = false;

//	m_RDSCleared = false;

	//The current block starts at zero, and all blocks are initially free
	m_CurrentBlock = 0;
	m_FreeBlock = 0;
	gWaveFreeBlockCount = BLOCK_COUNT;

	//Allocate memory for the blocks of audio data to stream
	m_OutputHeader = AllocateBlocks(BLOCK_SIZE, BLOCK_COUNT);

	m_WaveformBuffer = (char*)malloc(BLOCK_SIZE);
	m_InputHeader.lpData = m_WaveformBuffer;
	m_InputHeader.dwBufferLength = BLOCK_SIZE;
	m_InputHeader.dwFlags = 0;

}

CUSBAudioDevice::~CUSBAudioDevice()
{
	//Free all allocated memory when destroyed
	FreeBlocks(m_OutputHeader);
	free(m_WaveformBuffer);
}

BYTE CUSBAudioDevice::OpenUSBAudio(AudioData* audioData)
{
	BYTE status = STATUS_ERROR;

	//Check that audiodata is not NULL
	if (audioData)
	{
		//Open the USB audio input device
		if (OpenUSBAudioAudio())
		{
			//Open the sound card
			if (OpenSoundCard())
			{
				status = STATUS_OK;
			}
			else
			{
				status = STATUS_OUTPUTAUDIO_ERROR;
			}
		}
		else
		{
			status = STATUS_USBAudioAUDIO_ERROR;
		}	
	}

	return status;
}

bool CUSBAudioDevice::CloseUSBAudio()
{
	bool status = false;
	
	//Close all pipes
	CloseUSBAudioAudio();
	CloseSoundCard();
	CloseUSBAudioData();
	
	status = true;

	return status;
}
bool CUSBAudioDevice::OpenUSBAudioAudio()
{
	bool status = false;

	WAVEINCAPS		waveInputCapabilities;
	WAVEFORMATEX	USBAudioWaveFormat;

	//Setup the wave format based on our defined audio data
	USBAudioWaveFormat.wFormatTag = WAVE_FORMAT_PCM;
	USBAudioWaveFormat.nSamplesPerSec = SAMPLES_PER_SECOND;
	USBAudioWaveFormat.wBitsPerSample = BITS_PER_SAMPLE;
	USBAudioWaveFormat.nChannels = CHANNELS;

	//Obtain the number of input devices on the system
	DWORD numWaveInputDevices = waveInGetNumDevs();

	//Scan through each input device to see if we can find our device
	for (DWORD i = 0; i < numWaveInputDevices; i++)
	{
		//Get the device capabilities of the currently indexed device
		if (waveInGetDevCaps(i, &waveInputCapabilities, sizeof(waveInputCapabilities)) == MMSYSERR_NOERROR)
		{
			//Compare the name of the device to see if it is the correct device
			if (!strcmp(waveInputCapabilities.szPname, "TONE GENERATOR") || !strcmp(waveInputCapabilities.szPname, "USB Audio Device"))
			{
				//When the device is found, open a handle to the device
				if (waveInOpen(&m_USBAudioAudioHandle, i, &USBAudioWaveFormat, 0, 0, CALLBACK_NULL) == MMSYSERR_NOERROR)
				{
					//Set i to the last item to kill the loop once the device is found
					i = numWaveInputDevices;

					status = true;
				}
			}
		}
	}

	return status;
}

bool CUSBAudioDevice::OpenSoundCard()
{
	bool status = false;

	WAVEFORMATEX	soundCardWaveFormat;

	//Setup the wave format based on our defined audio data
	soundCardWaveFormat.wFormatTag = WAVE_FORMAT_PCM;
	soundCardWaveFormat.nSamplesPerSec = SAMPLES_PER_SECOND;
	soundCardWaveFormat.wBitsPerSample = BITS_PER_SAMPLE;
	soundCardWaveFormat.nChannels = CHANNELS;

	//Open a handle to the default wave output device (sound card)
	if (waveOutOpen(&m_SoundCardHandle, WAVE_MAPPER, &soundCardWaveFormat, (DWORD)waveOutProc, (DWORD)&gWaveFreeBlockCount, CALLBACK_FUNCTION | WAVE_ALLOWSYNC) == MMSYSERR_NOERROR)
	{
		status = true;
	}

	return status;
}

void CUSBAudioDevice::InitializeStream()
{
	waveInStart(m_USBAudioAudioHandle);

	//Fill the audio buffer to initialize the stream
	while (gWaveFreeBlockCount > BUFFER_PADDING)
	{
		StreamAudioIn();
		Sleep(50);
	}

	//Set streaming to true
	m_Streaming = true;
}

void CUSBAudioDevice::StreamAudio()
{
	if (!m_Streaming)
	{
		In_Count = 0;
		Out_Count = 0;
		InitializeStream();
	}

		//Check that the handles arent NULL
		if ((m_USBAudioAudioHandle) && (m_SoundCardHandle))
		{
			//If there are any free blocks, then stream audio in
			if (gWaveFreeBlockCount)
			{
				if (StreamAudioIn())
				{
					In_Count++;
					TRACE(_T("StreamIn Success\n"));
				}
			}
			//If there are any blocks ready for output, then stream audio out
			if (gWaveFreeBlockCount < BLOCK_COUNT)
				if (StreamAudioOut())
				{
					Out_Count++;
					TRACE(_T("StreamOut Success\n"));
				}
		}
	
}

bool CUSBAudioDevice::IsStreaming()
{
	return m_Streaming;
}

bool CUSBAudioDevice::StreamAudioIn()
{
	bool status = false;

	//Prepare the header for streaming in
	if (waveInPrepareHeader(m_USBAudioAudioHandle, &m_OutputHeader[m_FreeBlock], sizeof(m_InputHeader)) == MMSYSERR_NOERROR)
	{
		//Get the buffer of audio in the input header
		if (waveInAddBuffer(m_USBAudioAudioHandle, &m_OutputHeader[m_FreeBlock], sizeof(m_InputHeader)) == MMSYSERR_NOERROR)
		{				
			//Enter the critical section to decrement the free block count
			EnterCriticalSection(&gWaveCriticalSection);
			gWaveFreeBlockCount--;
			LeaveCriticalSection(&gWaveCriticalSection);

			//Increment the free block index, and scale it
			m_FreeBlock++;
			m_FreeBlock %= BLOCK_COUNT;

			status = true;
		}
	}
	else
		TRACE(_T("Could not prepare header\n"));

	return status;
}

static void CALLBACK waveOutProc(HWAVEOUT hwo, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
{
	if (uMsg == WOM_DONE)
	{
		EnterCriticalSection(&gWaveCriticalSection);
		int* freeBlockCounter = (int*)dwInstance;
		(*freeBlockCounter)++;
		LeaveCriticalSection(&gWaveCriticalSection);
	}
}

bool CUSBAudioDevice::StreamAudioOut()
{
	bool status = false;

	//Prepare the header for streaming out
	if (waveOutPrepareHeader(m_SoundCardHandle, &m_OutputHeader[m_CurrentBlock], sizeof(WAVEHDR)) == MMSYSERR_NOERROR)
	{
		//Write the sound to the sound card
		if (waveOutWrite(m_SoundCardHandle, &m_OutputHeader[m_CurrentBlock], sizeof(WAVEHDR)) == MMSYSERR_NOERROR)
		{
			//waveOutProc callback function will get called, and free block counter gets incremented

			//Increment the index of the current block to be played
			m_CurrentBlock++;
			m_CurrentBlock %= BLOCK_COUNT;

			status = true;
		}
	}

	return status;
}

UINT CUSBAudioDevice::GetCurrentBlock(void)
{
	return m_CurrentBlock;
}

⌨️ 快捷键说明

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