removed old Windows sound interface code because it does not make any sense to be used with the llcon software
This commit is contained in:
parent
71598931e2
commit
5eea2d96a9
3 changed files with 10 additions and 739 deletions
|
@ -417,13 +417,8 @@ bool CConvBuf::Put ( const CVector<short>& vecsData )
|
||||||
vecsMemory[iPutPos++] = vecsData[iCurPos++];
|
vecsMemory[iPutPos++] = vecsData[iCurPos++];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool bBufOk = false;
|
// return "buffer is ready for readout" flag
|
||||||
if ( iEnd == iMemSize )
|
return iEnd == iMemSize;
|
||||||
{
|
|
||||||
bBufOk = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return bBufOk;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CVector<short> CConvBuf::Get()
|
CVector<short> CConvBuf::Get()
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/******************************************************************************\
|
/******************************************************************************\
|
||||||
* Copyright (c) 2004-2008
|
* Copyright (c) 2004-2009
|
||||||
*
|
*
|
||||||
* Author(s):
|
* Author(s):
|
||||||
* Volker Fischer
|
* Volker Fischer
|
||||||
|
@ -29,7 +29,6 @@
|
||||||
|
|
||||||
|
|
||||||
/* Implementation *************************************************************/
|
/* Implementation *************************************************************/
|
||||||
#ifdef USE_ASIO_SND_INTERFACE
|
|
||||||
#include <qmutex.h>
|
#include <qmutex.h>
|
||||||
|
|
||||||
// external references
|
// external references
|
||||||
|
@ -929,643 +928,3 @@ long CSound::asioMessages ( long selector, long value, void* message, double* op
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else // USE_ASIO_SND_INTERFACE
|
|
||||||
|
|
||||||
/******************************************************************************\
|
|
||||||
* Wave in *
|
|
||||||
\******************************************************************************/
|
|
||||||
bool CSound::Read ( CVector<short>& psData )
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
bool bError;
|
|
||||||
|
|
||||||
// check if device must be opened or reinitialized
|
|
||||||
if ( bChangParamIn )
|
|
||||||
{
|
|
||||||
OpenInDevice();
|
|
||||||
|
|
||||||
// Reinit sound interface
|
|
||||||
InitRecording ( iBufferSizeIn, bBlockingRec );
|
|
||||||
|
|
||||||
// Reset flag
|
|
||||||
bChangParamIn = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// wait until data is available
|
|
||||||
if ( ! ( m_WaveInHeader[iWhichBufferIn].dwFlags & WHDR_DONE ) )
|
|
||||||
{
|
|
||||||
if ( bBlockingRec )
|
|
||||||
{
|
|
||||||
WaitForSingleObject ( m_WaveInEvent, INFINITE );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if buffers got lost
|
|
||||||
int iNumInBufDone = 0;
|
|
||||||
for ( i = 0; i < iCurNumSndBufIn; i++ )
|
|
||||||
{
|
|
||||||
if ( m_WaveInHeader[i].dwFlags & WHDR_DONE )
|
|
||||||
{
|
|
||||||
iNumInBufDone++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If the number of done buffers equals the total number of buffers, it is
|
|
||||||
very likely that a buffer got lost -> set error flag */
|
|
||||||
if ( iNumInBufDone == iCurNumSndBufIn )
|
|
||||||
{
|
|
||||||
bError = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bError = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// copy data from sound card in output buffer
|
|
||||||
for ( i = 0; i < iBufferSizeIn; i++ )
|
|
||||||
{
|
|
||||||
psData[i] = psSoundcardBuffer[iWhichBufferIn][i];
|
|
||||||
}
|
|
||||||
|
|
||||||
// add the buffer so that it can be filled with new samples
|
|
||||||
AddInBuffer();
|
|
||||||
|
|
||||||
// in case more than one buffer was ready, reset event
|
|
||||||
ResetEvent ( m_WaveInEvent );
|
|
||||||
|
|
||||||
return bError;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSound::AddInBuffer()
|
|
||||||
{
|
|
||||||
// unprepare old wave-header
|
|
||||||
waveInUnprepareHeader (
|
|
||||||
m_WaveIn, &m_WaveInHeader[iWhichBufferIn], sizeof ( WAVEHDR ) );
|
|
||||||
|
|
||||||
// prepare buffers for sending to sound interface
|
|
||||||
PrepareInBuffer ( iWhichBufferIn );
|
|
||||||
|
|
||||||
// send buffer to driver for filling with new data
|
|
||||||
waveInAddBuffer ( m_WaveIn, &m_WaveInHeader[iWhichBufferIn], sizeof ( WAVEHDR ) );
|
|
||||||
|
|
||||||
// toggle buffers
|
|
||||||
iWhichBufferIn++;
|
|
||||||
if ( iWhichBufferIn == iCurNumSndBufIn )
|
|
||||||
{
|
|
||||||
iWhichBufferIn = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSound::PrepareInBuffer ( int iBufNum )
|
|
||||||
{
|
|
||||||
// set struct entries
|
|
||||||
m_WaveInHeader[iBufNum].lpData = (LPSTR) &psSoundcardBuffer[iBufNum][0];
|
|
||||||
m_WaveInHeader[iBufNum].dwBufferLength = iBufferSizeIn * BYTES_PER_SAMPLE;
|
|
||||||
m_WaveInHeader[iBufNum].dwFlags = 0;
|
|
||||||
|
|
||||||
// prepare wave-header
|
|
||||||
waveInPrepareHeader ( m_WaveIn, &m_WaveInHeader[iBufNum], sizeof ( WAVEHDR ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSound::InitRecording ( int iNewBufferSize, bool bNewBlocking )
|
|
||||||
{
|
|
||||||
// check if device must be opened or reinitialized
|
|
||||||
if ( bChangParamIn )
|
|
||||||
{
|
|
||||||
OpenInDevice();
|
|
||||||
|
|
||||||
// reset flag
|
|
||||||
bChangParamIn = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// set internal parameter
|
|
||||||
iBufferSizeIn = iNewBufferSize;
|
|
||||||
bBlockingRec = bNewBlocking;
|
|
||||||
|
|
||||||
// reset interface so that all buffers are returned from the interface
|
|
||||||
waveInReset ( m_WaveIn );
|
|
||||||
waveInStop ( m_WaveIn );
|
|
||||||
|
|
||||||
/* reset current buffer ID (it is important to do this BEFORE calling
|
|
||||||
"AddInBuffer()" */
|
|
||||||
iWhichBufferIn = 0;
|
|
||||||
|
|
||||||
// create memory for sound card buffer
|
|
||||||
for ( int i = 0; i < iCurNumSndBufIn; i++ )
|
|
||||||
{
|
|
||||||
/* Unprepare old wave-header in case that we "re-initialized" this
|
|
||||||
module. Calling "waveInUnprepareHeader()" with an unprepared
|
|
||||||
buffer (when the module is initialized for the first time) has
|
|
||||||
simply no effect */
|
|
||||||
waveInUnprepareHeader ( m_WaveIn, &m_WaveInHeader[i], sizeof ( WAVEHDR ) );
|
|
||||||
|
|
||||||
if ( psSoundcardBuffer[i] != NULL )
|
|
||||||
{
|
|
||||||
delete[] psSoundcardBuffer[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
psSoundcardBuffer[i] = new short[iBufferSizeIn];
|
|
||||||
|
|
||||||
|
|
||||||
// Send all buffers to driver for filling the queue --------------------
|
|
||||||
// prepare buffers before sending them to the sound interface
|
|
||||||
PrepareInBuffer ( i );
|
|
||||||
|
|
||||||
AddInBuffer();
|
|
||||||
}
|
|
||||||
|
|
||||||
// notify that sound capturing can start now
|
|
||||||
waveInStart ( m_WaveIn );
|
|
||||||
|
|
||||||
/* This reset event is very important for initialization, otherwise we will
|
|
||||||
get errors! */
|
|
||||||
ResetEvent ( m_WaveInEvent );
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSound::OpenInDevice()
|
|
||||||
{
|
|
||||||
// open wave-input and set call-back mechanism to event handle
|
|
||||||
if ( m_WaveIn != NULL )
|
|
||||||
{
|
|
||||||
waveInReset ( m_WaveIn );
|
|
||||||
waveInClose ( m_WaveIn );
|
|
||||||
}
|
|
||||||
|
|
||||||
MMRESULT result = waveInOpen ( &m_WaveIn, iCurInDev, &sWaveFormatEx,
|
|
||||||
(DWORD) m_WaveInEvent, NULL, CALLBACK_EVENT );
|
|
||||||
|
|
||||||
if ( result != MMSYSERR_NOERROR )
|
|
||||||
{
|
|
||||||
throw CGenErr ( "Sound Interface Start, waveInOpen() failed. This error "
|
|
||||||
"usually occurs if another application blocks the sound in." );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSound::SetInDev ( int iNewDev )
|
|
||||||
{
|
|
||||||
// set device to wave mapper if iNewDev is invalid
|
|
||||||
if ( ( iNewDev >= iNumDevs ) || ( iNewDev < 0 ) )
|
|
||||||
{
|
|
||||||
iNewDev = WAVE_MAPPER;
|
|
||||||
}
|
|
||||||
|
|
||||||
// change only in case new device id is not already active
|
|
||||||
if ( iNewDev != iCurInDev )
|
|
||||||
{
|
|
||||||
iCurInDev = iNewDev;
|
|
||||||
bChangParamIn = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSound::SetInNumBuf ( int iNewNum )
|
|
||||||
{
|
|
||||||
// check new parameter
|
|
||||||
if ( ( iNewNum >= MAX_SND_BUF_IN ) || ( iNewNum < 1 ) )
|
|
||||||
{
|
|
||||||
iNewNum = NUM_SOUND_BUFFERS_IN;
|
|
||||||
}
|
|
||||||
|
|
||||||
// change only if parameter is different
|
|
||||||
if ( iNewNum != iCurNumSndBufIn )
|
|
||||||
{
|
|
||||||
iCurNumSndBufIn = iNewNum;
|
|
||||||
bChangParamIn = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************\
|
|
||||||
* Wave out *
|
|
||||||
\******************************************************************************/
|
|
||||||
bool CSound::Write ( CVector<short>& psData )
|
|
||||||
{
|
|
||||||
int i, j;
|
|
||||||
int iCntPrepBuf;
|
|
||||||
int iIndexDoneBuf;
|
|
||||||
bool bError;
|
|
||||||
|
|
||||||
// check if device must be opened or reinitialized
|
|
||||||
if ( bChangParamOut )
|
|
||||||
{
|
|
||||||
OpenOutDevice();
|
|
||||||
|
|
||||||
// reinit sound interface
|
|
||||||
InitPlayback ( iBufferSizeOut, bBlockingPlay );
|
|
||||||
|
|
||||||
// reset flag
|
|
||||||
bChangParamOut = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get number of "done"-buffers and position of one of them
|
|
||||||
GetDoneBuffer ( iCntPrepBuf, iIndexDoneBuf );
|
|
||||||
|
|
||||||
// now check special cases (Buffer is full or empty)
|
|
||||||
if ( iCntPrepBuf == 0 )
|
|
||||||
{
|
|
||||||
if ( bBlockingPlay )
|
|
||||||
{
|
|
||||||
/* Blocking wave out routine. Always
|
|
||||||
ensure that the buffer is completely filled to avoid buffer
|
|
||||||
underruns */
|
|
||||||
while ( iCntPrepBuf == 0 )
|
|
||||||
{
|
|
||||||
WaitForSingleObject ( m_WaveOutEvent, INFINITE );
|
|
||||||
|
|
||||||
GetDoneBuffer ( iCntPrepBuf, iIndexDoneBuf );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// All buffers are filled, dump new block --------------------------
|
|
||||||
// It would be better to kill half of the buffer blocks to set the start
|
|
||||||
// back to the middle: TODO
|
|
||||||
return true; // an error occurred
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ( iCntPrepBuf == iCurNumSndBufOut )
|
|
||||||
{
|
|
||||||
/* -----------------------------------------------------------------
|
|
||||||
Buffer is empty -> send as many cleared blocks to the sound-
|
|
||||||
interface until half of the buffer size is reached */
|
|
||||||
// send half of the buffer size blocks to the sound-interface
|
|
||||||
for ( j = 0; j < iCurNumSndBufOut / 2; j++ )
|
|
||||||
{
|
|
||||||
// first, clear these buffers
|
|
||||||
for ( i = 0; i < iBufferSizeOut; i++ )
|
|
||||||
{
|
|
||||||
psPlaybackBuffer[j][i] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// then send them to the interface
|
|
||||||
AddOutBuffer ( j );
|
|
||||||
}
|
|
||||||
|
|
||||||
// set index for done buffer
|
|
||||||
iIndexDoneBuf = iCurNumSndBufOut / 2;
|
|
||||||
|
|
||||||
bError = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bError = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// copy stereo data from input in soundcard buffer
|
|
||||||
for ( i = 0; i < iBufferSizeOut; i++ )
|
|
||||||
{
|
|
||||||
psPlaybackBuffer[iIndexDoneBuf][i] = psData[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
// now, send the current block
|
|
||||||
AddOutBuffer ( iIndexDoneBuf );
|
|
||||||
|
|
||||||
return bError;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSound::GetDoneBuffer ( int& iCntPrepBuf, int& iIndexDoneBuf )
|
|
||||||
{
|
|
||||||
// get number of "done"-buffers and position of one of them
|
|
||||||
iCntPrepBuf = 0;
|
|
||||||
for ( int i = 0; i < iCurNumSndBufOut; i++ )
|
|
||||||
{
|
|
||||||
if ( m_WaveOutHeader[i].dwFlags & WHDR_DONE )
|
|
||||||
{
|
|
||||||
iCntPrepBuf++;
|
|
||||||
iIndexDoneBuf = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSound::AddOutBuffer ( int iBufNum )
|
|
||||||
{
|
|
||||||
// unprepare old wave-header
|
|
||||||
waveOutUnprepareHeader (
|
|
||||||
m_WaveOut, &m_WaveOutHeader[iBufNum], sizeof ( WAVEHDR ) );
|
|
||||||
|
|
||||||
// prepare buffers for sending to sound interface
|
|
||||||
PrepareOutBuffer ( iBufNum );
|
|
||||||
|
|
||||||
// send buffer to driver for filling with new data
|
|
||||||
waveOutWrite ( m_WaveOut, &m_WaveOutHeader[iBufNum], sizeof ( WAVEHDR ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSound::PrepareOutBuffer ( int iBufNum )
|
|
||||||
{
|
|
||||||
// set Header data
|
|
||||||
m_WaveOutHeader[iBufNum].lpData = (LPSTR) &psPlaybackBuffer[iBufNum][0];
|
|
||||||
m_WaveOutHeader[iBufNum].dwBufferLength = iBufferSizeOut * BYTES_PER_SAMPLE;
|
|
||||||
m_WaveOutHeader[iBufNum].dwFlags = 0;
|
|
||||||
|
|
||||||
// prepare wave-header
|
|
||||||
waveOutPrepareHeader ( m_WaveOut, &m_WaveOutHeader[iBufNum], sizeof ( WAVEHDR ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSound::InitPlayback ( int iNewBufferSize, bool bNewBlocking )
|
|
||||||
{
|
|
||||||
int i, j;
|
|
||||||
|
|
||||||
// check if device must be opened or reinitialized
|
|
||||||
if ( bChangParamOut )
|
|
||||||
{
|
|
||||||
OpenOutDevice();
|
|
||||||
|
|
||||||
// reset flag
|
|
||||||
bChangParamOut = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// set internal parameters
|
|
||||||
iBufferSizeOut = iNewBufferSize;
|
|
||||||
bBlockingPlay = bNewBlocking;
|
|
||||||
|
|
||||||
// reset interface
|
|
||||||
waveOutReset ( m_WaveOut );
|
|
||||||
|
|
||||||
for ( j = 0; j < iCurNumSndBufOut; j++ )
|
|
||||||
{
|
|
||||||
/* Unprepare old wave-header (in case header was not prepared before,
|
|
||||||
simply nothing happens with this function call */
|
|
||||||
waveOutUnprepareHeader ( m_WaveOut, &m_WaveOutHeader[j], sizeof ( WAVEHDR ) );
|
|
||||||
|
|
||||||
// create memory for playback buffer
|
|
||||||
if ( psPlaybackBuffer[j] != NULL )
|
|
||||||
{
|
|
||||||
delete[] psPlaybackBuffer[j];
|
|
||||||
}
|
|
||||||
|
|
||||||
psPlaybackBuffer[j] = new short[iBufferSizeOut];
|
|
||||||
|
|
||||||
// clear new buffer
|
|
||||||
for ( i = 0; i < iBufferSizeOut; i++ )
|
|
||||||
{
|
|
||||||
psPlaybackBuffer[j][i] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// prepare buffer for sending to the sound interface
|
|
||||||
PrepareOutBuffer ( j );
|
|
||||||
|
|
||||||
// initially, send all buffers to the interface
|
|
||||||
AddOutBuffer ( j );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSound::OpenOutDevice()
|
|
||||||
{
|
|
||||||
if ( m_WaveOut != NULL )
|
|
||||||
{
|
|
||||||
waveOutReset ( m_WaveOut );
|
|
||||||
waveOutClose ( m_WaveOut );
|
|
||||||
}
|
|
||||||
|
|
||||||
MMRESULT result = waveOutOpen ( &m_WaveOut, iCurOutDev, &sWaveFormatEx,
|
|
||||||
(DWORD) m_WaveOutEvent, NULL, CALLBACK_EVENT );
|
|
||||||
|
|
||||||
if ( result != MMSYSERR_NOERROR )
|
|
||||||
{
|
|
||||||
throw CGenErr ( "Sound Interface Start, waveOutOpen() failed." );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSound::SetOutDev ( int iNewDev )
|
|
||||||
{
|
|
||||||
// set device to wave mapper if iNewDev is invalid
|
|
||||||
if ( ( iNewDev >= iNumDevs ) || ( iNewDev < 0 ) )
|
|
||||||
{
|
|
||||||
iNewDev = WAVE_MAPPER;
|
|
||||||
}
|
|
||||||
|
|
||||||
// change only in case new device id is not already active
|
|
||||||
if ( iNewDev != iCurOutDev )
|
|
||||||
{
|
|
||||||
iCurOutDev = iNewDev;
|
|
||||||
bChangParamOut = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSound::SetOutNumBuf ( int iNewNum )
|
|
||||||
{
|
|
||||||
// check new parameter
|
|
||||||
if ( ( iNewNum >= MAX_SND_BUF_OUT ) || ( iNewNum < 1 ) )
|
|
||||||
{
|
|
||||||
iNewNum = NUM_SOUND_BUFFERS_OUT;
|
|
||||||
}
|
|
||||||
|
|
||||||
// change only if parameter is different
|
|
||||||
if ( iNewNum != iCurNumSndBufOut )
|
|
||||||
{
|
|
||||||
iCurNumSndBufOut = iNewNum;
|
|
||||||
bChangParamOut = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************\
|
|
||||||
* Common *
|
|
||||||
\******************************************************************************/
|
|
||||||
void CSound::Close()
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
MMRESULT result;
|
|
||||||
|
|
||||||
// reset audio driver
|
|
||||||
if ( m_WaveOut != NULL )
|
|
||||||
{
|
|
||||||
result = waveOutReset ( m_WaveOut );
|
|
||||||
|
|
||||||
if ( result != MMSYSERR_NOERROR )
|
|
||||||
{
|
|
||||||
throw CGenErr ( "Sound Interface, waveOutReset() failed." );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( m_WaveIn != NULL )
|
|
||||||
{
|
|
||||||
result = waveInReset ( m_WaveIn );
|
|
||||||
|
|
||||||
if ( result != MMSYSERR_NOERROR )
|
|
||||||
{
|
|
||||||
throw CGenErr ( "Sound Interface, waveInReset() failed." );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// set event to ensure that thread leaves the waiting function
|
|
||||||
if ( m_WaveInEvent != NULL )
|
|
||||||
{
|
|
||||||
SetEvent(m_WaveInEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
// wait for the thread to terminate
|
|
||||||
Sleep ( 500 );
|
|
||||||
|
|
||||||
// unprepare wave-headers
|
|
||||||
if ( m_WaveIn != NULL )
|
|
||||||
{
|
|
||||||
for ( i = 0; i < iCurNumSndBufIn; i++ )
|
|
||||||
{
|
|
||||||
result = waveInUnprepareHeader (
|
|
||||||
m_WaveIn, &m_WaveInHeader[i], sizeof ( WAVEHDR ) );
|
|
||||||
|
|
||||||
if ( result != MMSYSERR_NOERROR )
|
|
||||||
{
|
|
||||||
throw CGenErr ( "Sound Interface, waveInUnprepareHeader()"
|
|
||||||
" failed." );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// close the sound in device
|
|
||||||
result = waveInClose ( m_WaveIn );
|
|
||||||
if ( result != MMSYSERR_NOERROR )
|
|
||||||
{
|
|
||||||
throw CGenErr ( "Sound Interface, waveInClose() failed." );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( m_WaveOut != NULL )
|
|
||||||
{
|
|
||||||
for ( i = 0; i < iCurNumSndBufOut; i++ )
|
|
||||||
{
|
|
||||||
result = waveOutUnprepareHeader (
|
|
||||||
m_WaveOut, &m_WaveOutHeader[i], sizeof ( WAVEHDR ) );
|
|
||||||
|
|
||||||
if ( result != MMSYSERR_NOERROR )
|
|
||||||
{
|
|
||||||
throw CGenErr ( "Sound Interface, waveOutUnprepareHeader()"
|
|
||||||
" failed." );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// close the sound out device
|
|
||||||
result = waveOutClose ( m_WaveOut );
|
|
||||||
if ( result != MMSYSERR_NOERROR )
|
|
||||||
{
|
|
||||||
throw CGenErr ( "Sound Interface, waveOutClose() failed." );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// set flag to open devices the next time it is initialized
|
|
||||||
bChangParamIn = true;
|
|
||||||
bChangParamOut = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
CSound::CSound()
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
// init number of sound buffers
|
|
||||||
iCurNumSndBufIn = NUM_SOUND_BUFFERS_IN;
|
|
||||||
iCurNumSndBufOut = NUM_SOUND_BUFFERS_OUT;
|
|
||||||
|
|
||||||
// should be initialized because an error can occur during init
|
|
||||||
m_WaveInEvent = NULL;
|
|
||||||
m_WaveOutEvent = NULL;
|
|
||||||
m_WaveIn = NULL;
|
|
||||||
m_WaveOut = NULL;
|
|
||||||
|
|
||||||
// init buffer pointer to zero
|
|
||||||
for ( i = 0; i < MAX_SND_BUF_IN; i++ )
|
|
||||||
{
|
|
||||||
memset ( &m_WaveInHeader[i], 0, sizeof ( WAVEHDR ) );
|
|
||||||
psSoundcardBuffer[i] = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( i = 0; i < MAX_SND_BUF_OUT; i++ )
|
|
||||||
{
|
|
||||||
memset ( &m_WaveOutHeader[i], 0, sizeof ( WAVEHDR ) );
|
|
||||||
psPlaybackBuffer[i] = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// init wave-format structure
|
|
||||||
sWaveFormatEx.wFormatTag = WAVE_FORMAT_PCM;
|
|
||||||
sWaveFormatEx.nChannels = NUM_IN_OUT_CHANNELS;
|
|
||||||
sWaveFormatEx.wBitsPerSample = BITS_PER_SAMPLE;
|
|
||||||
sWaveFormatEx.nSamplesPerSec = SND_CRD_SAMPLE_RATE;
|
|
||||||
sWaveFormatEx.nBlockAlign = sWaveFormatEx.nChannels *
|
|
||||||
sWaveFormatEx.wBitsPerSample / 8;
|
|
||||||
sWaveFormatEx.nAvgBytesPerSec = sWaveFormatEx.nBlockAlign *
|
|
||||||
sWaveFormatEx.nSamplesPerSec;
|
|
||||||
sWaveFormatEx.cbSize = 0;
|
|
||||||
|
|
||||||
// get the number of digital audio devices in this computer, check range
|
|
||||||
iNumDevs = waveInGetNumDevs();
|
|
||||||
|
|
||||||
if ( iNumDevs > MAX_NUMBER_SOUND_CARDS )
|
|
||||||
{
|
|
||||||
iNumDevs = MAX_NUMBER_SOUND_CARDS;
|
|
||||||
}
|
|
||||||
|
|
||||||
// at least one device must exist in the system
|
|
||||||
if ( iNumDevs == 0 )
|
|
||||||
{
|
|
||||||
throw CGenErr ( "No audio device found." );
|
|
||||||
}
|
|
||||||
|
|
||||||
// get info about the devices and store the names
|
|
||||||
for ( i = 0; i < iNumDevs; i++ )
|
|
||||||
{
|
|
||||||
if ( !waveInGetDevCaps ( i, &m_WaveInDevCaps, sizeof ( WAVEINCAPS ) ) )
|
|
||||||
{
|
|
||||||
pstrDevices[i] = m_WaveInDevCaps.szPname;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// we use an event controlled wave-in (wave-out) structure
|
|
||||||
// create events
|
|
||||||
m_WaveInEvent = CreateEvent ( NULL, FALSE, FALSE, NULL );
|
|
||||||
m_WaveOutEvent = CreateEvent ( NULL, FALSE, FALSE, NULL );
|
|
||||||
|
|
||||||
// set flag to open devices
|
|
||||||
bChangParamIn = true;
|
|
||||||
bChangParamOut = true;
|
|
||||||
|
|
||||||
// default device number, "wave mapper"
|
|
||||||
iCurInDev = WAVE_MAPPER;
|
|
||||||
iCurOutDev = WAVE_MAPPER;
|
|
||||||
|
|
||||||
// non-blocking wave out is default
|
|
||||||
bBlockingPlay = false;
|
|
||||||
|
|
||||||
// blocking wave in is default
|
|
||||||
bBlockingRec = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
CSound::~CSound()
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
// delete allocated memory
|
|
||||||
for ( i = 0; i < iCurNumSndBufIn; i++ )
|
|
||||||
{
|
|
||||||
if ( psSoundcardBuffer[i] != NULL )
|
|
||||||
{
|
|
||||||
delete[] psSoundcardBuffer[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( i = 0; i < iCurNumSndBufOut; i++ )
|
|
||||||
{
|
|
||||||
if ( psPlaybackBuffer[i] != NULL )
|
|
||||||
{
|
|
||||||
delete[] psPlaybackBuffer[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// close the handle for the events
|
|
||||||
if ( m_WaveInEvent != NULL )
|
|
||||||
{
|
|
||||||
CloseHandle ( m_WaveInEvent );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( m_WaveOutEvent != NULL )
|
|
||||||
{
|
|
||||||
CloseHandle ( m_WaveOutEvent );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // USE_ASIO_SND_INTERFACE
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/******************************************************************************\
|
/******************************************************************************\
|
||||||
* Copyright (c) 2004-2008
|
* Copyright (c) 2004-2009
|
||||||
*
|
*
|
||||||
* Author(s):
|
* Author(s):
|
||||||
* Volker Fischer
|
* Volker Fischer
|
||||||
|
@ -27,23 +27,21 @@
|
||||||
#define AFX_SOUNDIN_H__9518A621_7F78_11D3_8C0D_EEBF182CF549__INCLUDED_
|
#define AFX_SOUNDIN_H__9518A621_7F78_11D3_8C0D_EEBF182CF549__INCLUDED_
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <mmsystem.h>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <qmessagebox.h>
|
#include <qmessagebox.h>
|
||||||
#include "../src/util.h"
|
#include "../src/util.h"
|
||||||
#include "../src/global.h"
|
#include "../src/global.h"
|
||||||
|
|
||||||
|
// copy the ASIO SDK in the llcon/windows directory: "llcon/windows/ASIOSDK2" to
|
||||||
|
// get it work
|
||||||
|
#include "asiosys.h"
|
||||||
|
#include "asio.h"
|
||||||
|
#include "asiodrivers.h"
|
||||||
|
|
||||||
|
|
||||||
/* Definitions ****************************************************************/
|
/* Definitions ****************************************************************/
|
||||||
// switch here between ASIO (Steinberg) or native Windows(TM) sound interface
|
|
||||||
//#undef USE_ASIO_SND_INTERFACE
|
|
||||||
#define USE_ASIO_SND_INTERFACE
|
|
||||||
|
|
||||||
|
|
||||||
#define NUM_IN_OUT_CHANNELS 2 /* Stereo recording (but we only
|
#define NUM_IN_OUT_CHANNELS 2 /* Stereo recording (but we only
|
||||||
use one channel for recording) */
|
use one channel for recording) */
|
||||||
#define BITS_PER_SAMPLE 16 // use all bits of the D/A-converter
|
|
||||||
#define BYTES_PER_SAMPLE 2 // number of bytes per sample
|
|
||||||
|
|
||||||
#define MAX_SND_BUF_IN 100
|
#define MAX_SND_BUF_IN 100
|
||||||
#define MAX_SND_BUF_OUT 100
|
#define MAX_SND_BUF_OUT 100
|
||||||
|
@ -53,16 +51,6 @@
|
||||||
|
|
||||||
|
|
||||||
/* Classes ********************************************************************/
|
/* Classes ********************************************************************/
|
||||||
#ifdef USE_ASIO_SND_INTERFACE
|
|
||||||
|
|
||||||
// copy the ASIO SDK in the llcon/windows directory: "llcon/windows/ASIOSDK2" to
|
|
||||||
// get it work
|
|
||||||
|
|
||||||
#include "asiosys.h"
|
|
||||||
#include "asio.h"
|
|
||||||
#include "asiodrivers.h"
|
|
||||||
|
|
||||||
|
|
||||||
class CSound
|
class CSound
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -127,75 +115,4 @@ protected:
|
||||||
bool bBlockingPlay;
|
bool bBlockingPlay;
|
||||||
};
|
};
|
||||||
|
|
||||||
#else // USE_ASIO_SND_INTERFACE
|
|
||||||
|
|
||||||
class CSound
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CSound();
|
|
||||||
virtual ~CSound();
|
|
||||||
|
|
||||||
void InitRecording ( int iNewBufferSize, bool bNewBlocking = true );
|
|
||||||
void InitPlayback ( int iNewBufferSize, bool bNewBlocking = false );
|
|
||||||
bool Read ( CVector<short>& psData );
|
|
||||||
bool Write ( CVector<short>& psData );
|
|
||||||
|
|
||||||
int GetNumDev() { return iNumDevs; }
|
|
||||||
std::string GetDeviceName ( int iDiD ) { return pstrDevices[iDiD]; }
|
|
||||||
|
|
||||||
// dummy functions
|
|
||||||
int SetDev ( const int iNewDev ) {}
|
|
||||||
int GetDev() { return 0; }
|
|
||||||
|
|
||||||
void SetOutDev ( int iNewDev );
|
|
||||||
int GetOutDev() { return iCurOutDev; }
|
|
||||||
void SetInDev ( int iNewDev );
|
|
||||||
int GetInDev() { return iCurInDev; }
|
|
||||||
void SetOutNumBuf ( int iNewNum );
|
|
||||||
int GetOutNumBuf() { return iCurNumSndBufOut; }
|
|
||||||
void SetInNumBuf ( int iNewNum );
|
|
||||||
int GetInNumBuf() { return iCurNumSndBufIn; }
|
|
||||||
|
|
||||||
void Close();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void OpenInDevice();
|
|
||||||
void OpenOutDevice();
|
|
||||||
void PrepareInBuffer ( int iBufNum );
|
|
||||||
void PrepareOutBuffer ( int iBufNum );
|
|
||||||
void AddInBuffer();
|
|
||||||
void AddOutBuffer ( int iBufNum );
|
|
||||||
void GetDoneBuffer ( int& iCntPrepBuf, int& iIndexDoneBuf );
|
|
||||||
|
|
||||||
WAVEFORMATEX sWaveFormatEx;
|
|
||||||
UINT iNumDevs;
|
|
||||||
std::string pstrDevices[MAX_NUMBER_SOUND_CARDS];
|
|
||||||
UINT iCurInDev;
|
|
||||||
UINT iCurOutDev;
|
|
||||||
bool bChangParamIn;
|
|
||||||
bool bChangParamOut;
|
|
||||||
int iCurNumSndBufIn;
|
|
||||||
int iCurNumSndBufOut;
|
|
||||||
|
|
||||||
// wave in
|
|
||||||
WAVEINCAPS m_WaveInDevCaps;
|
|
||||||
HWAVEIN m_WaveIn;
|
|
||||||
HANDLE m_WaveInEvent;
|
|
||||||
WAVEHDR m_WaveInHeader[MAX_SND_BUF_IN];
|
|
||||||
int iBufferSizeIn;
|
|
||||||
int iWhichBufferIn;
|
|
||||||
short* psSoundcardBuffer[MAX_SND_BUF_IN];
|
|
||||||
bool bBlockingRec;
|
|
||||||
|
|
||||||
// wave out
|
|
||||||
int iBufferSizeOut;
|
|
||||||
HWAVEOUT m_WaveOut;
|
|
||||||
short* psPlaybackBuffer[MAX_SND_BUF_OUT];
|
|
||||||
WAVEHDR m_WaveOutHeader[MAX_SND_BUF_OUT];
|
|
||||||
HANDLE m_WaveOutEvent;
|
|
||||||
bool bBlockingPlay;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // USE_ASIO_SND_INTERFACE
|
|
||||||
|
|
||||||
#endif // !defined ( AFX_SOUNDIN_H__9518A621_7F78_11D3_8C0D_EEBF182CF549__INCLUDED_ )
|
#endif // !defined ( AFX_SOUNDIN_H__9518A621_7F78_11D3_8C0D_EEBF182CF549__INCLUDED_ )
|
||||||
|
|
Loading…
Reference in a new issue