microphonedevicedriver.cpp
来自「一个语言识别引擎」· C++ 代码 · 共 636 行 · 第 1/2 页
CPP
636 行
// -*- mode:C++; tab-width:4; c-basic-offset:4; indent-tabs-mode:nil -*-
/*
* Copyright (C) 2006 Julio Gomes, Alexandre Bernardino
* CopyPolicy: Released under the terms of the GNU GPL v2.0.
*
*/
/***********************************************************************
YARP2 MicrophoneDeviceDriver
Windows Native Implementation for sound acquisition
Adapted from YARP1 - YarpSoundDeviceDriver, YarpSoundCardUtils
Author of YARP1 (original) Code: Carlos Beltran, Lira-Lab, DIST, UNIGE
Authors of YARP2 (adapted) Code: Julio Gomes, Alexandre Bernardino, VisLab, ISR-IST
Contact: jgomes(a)isr.ist.utl.pt, alex(a)isr.ist.utl.pt
************************************************************************/
#include <yarp/MicrophoneDeviceDriver.h>
#include <yarp/os/all.h>
#include <ace/Sched_Params.h>
#undef main
#include <windows.h>
#include <mmsystem.h>
using namespace yarp::os;
using namespace yarp::dev;
/*
SoundOpenParameters contains initialization parameters.
It is inherited from YARP1 and is now obsolete.
Future: use Searchable class instead.
*/
struct SoundOpenParameters
{
SoundOpenParameters()
{
m_callbackthread_identifier = 0;
m_Channels = 0;
m_SamplesPerSec = 0;
m_BitsPerSample = 0;
m_BufferLength = 0;
}
int m_callbackthread_identifier; //This is the thread identifier for the callback
int m_Channels;
int m_SamplesPerSec;
int m_BitsPerSample;
int m_BufferLength;
};
/*
SoundResources:
Encapsulates windows native stuff for sound acquisition.
*/
class SoundResources : public yarp::os::Semaphore, public yarp::os::Thread
{
public:
//----------------------------------------------------------------------
// Constructor/Destructor
//----------------------------------------------------------------------
SoundResources (void) : _bmutex(1),
_new_frame(0),
_canpost(true),
numSamples(2048),
microDistance(0.14)
{
//----------------------------------------------------------------------
// Initialize variables
// Default: 16-bit, 44KHz, stereo
//----------------------------------------------------------------------
m_InRecord = false;
dwBufferLength = 8192;
freqSample = 44100;
nBitsSample = 16;
channels = 2;
}
~SoundResources () { _uninitialize (); }
//----------------------------------------------------------------------
// Variables
//----------------------------------------------------------------------
yarp::os::Semaphore _bmutex;
yarp::os::Semaphore _new_frame;
bool _canpost;
//Declare usefull variables
HWAVEIN m_WaveInHandle; // Handle to the WAVE In Device
HMIXER m_MixerHandle; // Handle to Mixer for WAVE In Device
WAVEHDR m_WaveHeader[3]; // We use two WAVEHDR's for recording (ie, double-buffering) in this example
bool m_InRecord; // Variable used to indicate whether we are in record
unsigned char m_DoneAll; // Variable used by recording thread to indicate whether we are in record
MMRESULT m_err;
WAVEFORMATEX m_waveFormat;
MIXERLINE m_mixerLine;
HANDLE m_waveInThread;
unsigned long m_n;
unsigned long m_numSrc;
// Control structures
MIXERCONTROL m_mixerControlArray;
MIXERLINECONTROLS m_mixerLineControls;
//Local lockable buffer
unsigned char *_rawBuffer;
//----------------------------------------------------------------------
// Parameters
//----------------------------------------------------------------------
DWORD dwBufferLength;
const DWORD numSamples; //dwBufferLength/4
DWORD freqSample;
const double microDistance; // babybot
WORD nBitsSample;
WORD channels;
//----------------------------------------------------------------------
// Public Method definitions
//----------------------------------------------------------------------
int _initialize (const SoundOpenParameters& params);
int _uninitialize (void);
int _select_line(unsigned int type);
int _select_control(unsigned int control);
int acquireBuffer (void *buffer);
int releaseBuffer (void);
int waitOnNewFrame(void);
void run(void);
protected:
//----------------------------------------------------------------------
// Protected method definitions
//----------------------------------------------------------------------
int _init (const SoundOpenParameters& params);
void _prepareBuffers (void);
void _print_dst_lines();
void _print_src_lines();
};
//--------------------------------------------------------------------------------------
// Class: SoundResources
// Method: _print_src_lines
// Description: This function prints in the screen the source lines present
//--------------------------------------------------------------------------------------
void
SoundResources::_print_src_lines()
{
for (int i = 0; i < m_numSrc; i++)
{
m_mixerLine.cbStruct = sizeof(MIXERLINE);
m_mixerLine.dwSource = i;
if (!(m_err = mixerGetLineInfo((HMIXEROBJ)m_MixerHandle, &m_mixerLine, MIXER_GETLINEINFOF_SOURCE)))
{
if (m_mixerLine.dwComponentType != MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER)
printf("\t\t#%lu: %s\n", i, m_mixerLine.szName);
}
}
}
//--------------------------------------------------------------------------------------
// Class: SoundResources
// Method: (public)_select_control
// Description: This methos allows to select the type of control in the selected line
//--------------------------------------------------------------------------------------
int
SoundResources::_select_control(unsigned int control_type)
{
//----------------------------------------------------------------------
// Fill the mixerLineControls structure
//----------------------------------------------------------------------
m_mixerLineControls.cbStruct = sizeof(MIXERLINECONTROLS);
m_mixerLineControls.dwLineID = m_mixerLine.dwLineID;
m_mixerLineControls.cControls = 1;
m_mixerLineControls.dwControlType = control_type;
m_mixerLineControls.pamxctrl = &m_mixerControlArray;
m_mixerLineControls.cbmxctrl = sizeof(MIXERCONTROL);
m_err = mixerGetLineControls((HMIXEROBJ)m_MixerHandle,
&m_mixerLineControls,
MIXER_GETLINECONTROLSF_ONEBYTYPE);
if (m_err != MMSYSERR_NOERROR)
printf("yarpsounddriver: %s has no %s control!\n",
m_mixerLine.szName,
m_mixerLineControls.pamxctrl->szName);
return 1;
}
int SoundResources::_select_line(unsigned int type)
{
for(int i = 0; i < m_numSrc; i++) {
m_mixerLine.cbStruct = sizeof(MIXERLINE);
m_mixerLine.dwSource = i;
m_err = mixerGetLineInfo((HMIXEROBJ)m_MixerHandle,
&m_mixerLine,
MIXER_GETLINEINFOF_SOURCE);
if (m_err != MMSYSERR_NOERROR) continue;
if (m_mixerLine.dwComponentType == type)
{
printf("yarpsounddriver: source line found\n");
return 1;
}
}
printf("yarpsounddriver: -warning- source line not found\n");
return -1;
}
void SoundResources::_prepareBuffers(void) {
//----------------------------------------------------------------------
// Preparing all memory buffer allocation
//----------------------------------------------------------------------
m_WaveHeader[2].dwBufferLength =
m_WaveHeader[1].dwBufferLength =
m_WaveHeader[0].dwBufferLength = dwBufferLength;
m_WaveHeader[0].lpData = (char *)VirtualAlloc(0,
m_WaveHeader[0].dwBufferLength,
MEM_COMMIT,
PAGE_READWRITE);
m_WaveHeader[1].lpData = (char *)VirtualAlloc(0,
m_WaveHeader[1].dwBufferLength,
MEM_COMMIT,
PAGE_READWRITE);
m_WaveHeader[2].lpData = (char *)VirtualAlloc(0,
m_WaveHeader[2].dwBufferLength,
MEM_COMMIT,
PAGE_READWRITE);
//----------------------------------------------------------------------
// Initialize dwFlags and dwLoops to 0. This seems to be necesary according to the
// Microsoft Windows documentation
//----------------------------------------------------------------------
m_WaveHeader[0].dwFlags = m_WaveHeader[1].dwFlags = m_WaveHeader[2].dwFlags = 0L;
m_WaveHeader[0].dwLoops = m_WaveHeader[1].dwLoops = m_WaveHeader[2].dwFlags = 0L;
//----------------------------------------------------------------------
// Initialize the headers
//----------------------------------------------------------------------
if ((m_err = waveInPrepareHeader(m_WaveInHandle, &m_WaveHeader[0], sizeof(WAVEHDR))))
printf("yarpsounddriver: Error preparing WAVEHDR -- %08X\n", m_err);
if ((m_err = waveInPrepareHeader(m_WaveInHandle, &m_WaveHeader[1], sizeof(WAVEHDR))))
printf("yarpsounddriver: Error preparing WAVEHDR -- %08X\n", m_err);
if ((m_err = waveInPrepareHeader(m_WaveInHandle, &m_WaveHeader[2], sizeof(WAVEHDR))))
printf("yarpsounddriver: Error preparing WAVEHDR -- %08X\n", m_err);
//----------------------------------------------------------------------
// It is necessary to queue the two buffers.
//----------------------------------------------------------------------
if ((m_err = waveInAddBuffer(m_WaveInHandle, &m_WaveHeader[0], sizeof(WAVEHDR))))
printf("yarpsounddriver: Error queueing WAVEHDR 1! -- %08X\n", m_err);
if ((m_err = waveInAddBuffer(m_WaveInHandle, &m_WaveHeader[1], sizeof(WAVEHDR))))
printf("yarpsounddriver: Error queueing WAVEHDR 2! -- %08X\n", m_err);
if ((m_err = waveInAddBuffer(m_WaveInHandle, &m_WaveHeader[2], sizeof(WAVEHDR))))
printf("yarpsounddriver: Error queueing WAVEHDR 2! -- %08X\n", m_err);
return;
}
void SoundResources::_print_dst_lines() {
MIXERCAPS mixerCaps;
mixerGetDevCaps(0,&mixerCaps, sizeof(mixerCaps));
for (int i = 0; i < mixerCaps.cDestinations; i++)
{
m_mixerLine.cbStruct = sizeof(MIXERLINE);
m_mixerLine.dwSource = 0;
m_mixerLine.dwDestination = i;
if (!(m_err = mixerGetLineInfo((HMIXEROBJ)m_MixerHandle, &m_mixerLine, MIXER_GETLINEINFOF_DESTINATION))) {
printf("\t#%lu: %s\n", i, m_mixerLine.szName);
}
m_numSrc = m_mixerLine.cConnections;
_print_src_lines();
}
return;
}
int SoundResources::_initialize (const SoundOpenParameters& params)
{
_init (params);
_prepareBuffers ();
//start continuous acquisition
if ((m_err = waveInStart(m_WaveInHandle))) {
printf("MicrophoneDeviceDriver: Error starting record! -- %08X\n", m_err);
}
m_InRecord = true;
return 1;
}
//--------------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?