some code style changes, added first implementation of mixer in client window

This commit is contained in:
Volker Fischer 2006-12-07 18:57:26 +00:00
parent 63adf15507
commit 7f4bea94eb
5 changed files with 531 additions and 490 deletions

View file

@ -2,7 +2,7 @@
* Copyright (c) 2004-2005 * Copyright (c) 2004-2005
* *
* Author(s): * Author(s):
* Volker Fischer, Alexander Kurpiers * Volker Fischer, Alexander Kurpiers
* *
* This code is based on the Open-Source sound interface implementation of * This code is based on the Open-Source sound interface implementation of
* the Dream DRM Receiver project. * the Dream DRM Receiver project.
@ -15,412 +15,412 @@
/* Wave in ********************************************************************/ /* Wave in ********************************************************************/
void CSound::InitRecording(int iNewBufferSize, bool bNewBlocking) void CSound::InitRecording(int iNewBufferSize, bool bNewBlocking)
{ {
int err; int err;
/* set internal buffer size for read */ /* set internal buffer size for read */
iBufferSizeIn = iNewBufferSize / NUM_IN_OUT_CHANNELS; /* mono size */ iBufferSizeIn = iNewBufferSize / NUM_IN_OUT_CHANNELS; /* mono size */
/* if recording device was already open, close it first */ /* if recording device was already open, close it first */
if ( rhandle != NULL ) if ( rhandle != NULL )
{ {
snd_pcm_close ( rhandle ); snd_pcm_close ( rhandle );
} }
/* record device: The most important ALSA interfaces to the PCM devices are /* record device: The most important ALSA interfaces to the PCM devices are
the "plughw" and the "hw" interface. If you use the "plughw" interface, the "plughw" and the "hw" interface. If you use the "plughw" interface,
you need not care much about the sound hardware. If your soundcard does you need not care much about the sound hardware. If your soundcard does
not support the sample rate or sample format you specify, your data will not support the sample rate or sample format you specify, your data will
be automatically converted. This also applies to the access type and the be automatically converted. This also applies to the access type and the
number of channels. With the "hw" interface, you have to check whether number of channels. With the "hw" interface, you have to check whether
your hardware supports the configuration you would like to use */ your hardware supports the configuration you would like to use */
/* either "hw:0,0" or "plughw:0,0" */ /* either "hw:0,0" or "plughw:0,0" */
if ( err = snd_pcm_open ( &rhandle, "hw:0,0", SND_PCM_STREAM_CAPTURE, 0 ) != 0 ) if ( err = snd_pcm_open ( &rhandle, "hw:0,0", SND_PCM_STREAM_CAPTURE, 0 ) != 0 )
{ {
qDebug ( "open error: %s", snd_strerror ( err ) ); qDebug ( "open error: %s", snd_strerror ( err ) );
} }
/* recording should be blocking */ /* recording should be blocking */
if ( err = snd_pcm_nonblock ( rhandle, FALSE ) != 0 ) if ( err = snd_pcm_nonblock ( rhandle, FALSE ) != 0 )
{ {
qDebug ( "cannot set blocking: %s", snd_strerror ( err ) ); qDebug ( "cannot set blocking: %s", snd_strerror ( err ) );
} }
/* set hardware parameters */ /* set hardware parameters */
SetHWParams ( rhandle, iBufferSizeIn, iCurPeriodSizeIn ); SetHWParams ( rhandle, iBufferSizeIn, iCurPeriodSizeIn );
/* sw parameters --------------------------------------------------------- */ /* sw parameters --------------------------------------------------------- */
snd_pcm_sw_params_t* swparams; snd_pcm_sw_params_t* swparams;
// allocate an invalid snd_pcm_sw_params_t using standard malloc // allocate an invalid snd_pcm_sw_params_t using standard malloc
if ( err = snd_pcm_sw_params_malloc ( &swparams ) != 0 ) if ( err = snd_pcm_sw_params_malloc ( &swparams ) != 0 )
{ {
qDebug ( "snd_pcm_sw_params_malloc: %s", snd_strerror ( err ) ); qDebug ( "snd_pcm_sw_params_malloc: %s", snd_strerror ( err ) );
} }
// get the current swparams // get the current swparams
if ( err = snd_pcm_sw_params_current ( rhandle, swparams ) < 0 ) if ( err = snd_pcm_sw_params_current ( rhandle, swparams ) < 0 )
{ {
qDebug ( "Unable to determine current swparams : %s", snd_strerror ( err ) ); qDebug ( "Unable to determine current swparams : %s", snd_strerror ( err ) );
} }
// start the transfer when the buffer immediately -> no threshold, val: 0 // start the transfer when the buffer immediately -> no threshold, val: 0
err = snd_pcm_sw_params_set_start_threshold ( rhandle, swparams, 0 ); err = snd_pcm_sw_params_set_start_threshold ( rhandle, swparams, 0 );
if ( err < 0 ) if ( err < 0 )
{ {
qDebug ( "Unable to set start threshold mode : %s", snd_strerror ( err ) ); qDebug ( "Unable to set start threshold mode : %s", snd_strerror ( err ) );
} }
// align all transfers to 1 sample // align all transfers to 1 sample
err = snd_pcm_sw_params_set_xfer_align ( rhandle, swparams, 1 ); err = snd_pcm_sw_params_set_xfer_align ( rhandle, swparams, 1 );
if ( err < 0 ) if ( err < 0 )
{ {
qDebug ( "Unable to set transfer align : %s", snd_strerror ( err ) ); qDebug ( "Unable to set transfer align : %s", snd_strerror ( err ) );
} }
// set avail min inside a software configuration container // set avail min inside a software configuration container
/* Note: This is similar to setting an OSS wakeup point. The valid values /* Note: This is similar to setting an OSS wakeup point. The valid values
for 'val' are determined by the specific hardware. Most PC sound cards for 'val' are determined by the specific hardware. Most PC sound cards
can only accept power of 2 frame counts (i.e. 512, 1024, 2048). You can only accept power of 2 frame counts (i.e. 512, 1024, 2048). You
cannot use this as a high resolution timer - it is limited to how often cannot use this as a high resolution timer - it is limited to how often
the sound card hardware raises an interrupt. Note that you can greatly the sound card hardware raises an interrupt. Note that you can greatly
improve the reponses using snd_pcm_sw_params_set_sleep_min where another improve the reponses using snd_pcm_sw_params_set_sleep_min where another
timing source is used */ timing source is used */
snd_pcm_uframes_t period_size = iBufferSizeIn; snd_pcm_uframes_t period_size = iBufferSizeIn;
err = snd_pcm_sw_params_set_avail_min ( rhandle, swparams, period_size ); err = snd_pcm_sw_params_set_avail_min ( rhandle, swparams, period_size );
if ( err < 0 ) if ( err < 0 )
{ {
qDebug ( "Unable to set avail min : %s", snd_strerror ( err ) ); qDebug ( "Unable to set avail min : %s", snd_strerror ( err ) );
} }
// write the parameters to the record/playback device // write the parameters to the record/playback device
err = snd_pcm_sw_params ( rhandle, swparams ); err = snd_pcm_sw_params ( rhandle, swparams );
if ( err < 0 ) if ( err < 0 )
{ {
qDebug ( "Unable to set sw params : %s", snd_strerror ( err ) ); qDebug ( "Unable to set sw params : %s", snd_strerror ( err ) );
} }
// clean-up // clean-up
snd_pcm_sw_params_free ( swparams ); snd_pcm_sw_params_free ( swparams );
// start record // start record
snd_pcm_reset ( rhandle ); snd_pcm_reset ( rhandle );
snd_pcm_start ( rhandle ); snd_pcm_start ( rhandle );
qDebug ( "alsa init record done" ); qDebug ( "alsa init record done" );
} }
bool CSound::Read(CVector<short>& psData) bool CSound::Read(CVector<short>& psData)
{ {
int ret; int ret;
/* Check if device must be opened or reinitialized */ /* Check if device must be opened or reinitialized */
if (bChangParamIn == true) if (bChangParamIn == true)
{ {
InitRecording ( iBufferSizeIn * NUM_IN_OUT_CHANNELS ); InitRecording ( iBufferSizeIn * NUM_IN_OUT_CHANNELS );
/* Reset flag */ /* Reset flag */
bChangParamIn = false; bChangParamIn = false;
} }
ret = snd_pcm_readi(rhandle, &psData[0], iBufferSizeIn); ret = snd_pcm_readi(rhandle, &psData[0], iBufferSizeIn);
if ( ret < 0 ) if ( ret < 0 )
{ {
if ( ret == -EPIPE ) if ( ret == -EPIPE )
{ {
// under-run // under-run
qDebug ( "rprepare" ); qDebug ( "rprepare" );
ret = snd_pcm_prepare ( rhandle ); ret = snd_pcm_prepare ( rhandle );
if ( ret < 0 ) if ( ret < 0 )
{ {
qDebug ( "Can't recover from underrun, prepare failed: %s", snd_strerror ( ret ) ); qDebug ( "Can't recover from underrun, prepare failed: %s", snd_strerror ( ret ) );
} }
ret = snd_pcm_start ( rhandle ); ret = snd_pcm_start ( rhandle );
if (ret < 0) if (ret < 0)
{ {
qDebug ( "Can't recover from underrun, start failed: %s", snd_strerror ( ret ) ); qDebug ( "Can't recover from underrun, start failed: %s", snd_strerror ( ret ) );
} }
return true; return true;
} }
else if ( ret == -ESTRPIPE ) else if ( ret == -ESTRPIPE )
{ {
qDebug ( "strpipe" ); qDebug ( "strpipe" );
// wait until the suspend flag is released // wait until the suspend flag is released
while ( ( ret = snd_pcm_resume ( rhandle ) ) == -EAGAIN ) while ( ( ret = snd_pcm_resume ( rhandle ) ) == -EAGAIN )
{ {
sleep ( 1 ); sleep ( 1 );
} }
if ( ret < 0 ) if ( ret < 0 )
{ {
ret = snd_pcm_prepare ( rhandle ); ret = snd_pcm_prepare ( rhandle );
if (ret < 0) if (ret < 0)
{ {
qDebug ( "Can't recover from suspend, prepare failed: %s", snd_strerror ( ret ) ); qDebug ( "Can't recover from suspend, prepare failed: %s", snd_strerror ( ret ) );
} }
throw CGenErr ( "CSound:Read" ); throw CGenErr ( "CSound:Read" );
} }
return true; return true;
} }
else else
{ {
qDebug ( "CSound::Read: %s", snd_strerror ( ret ) ); qDebug ( "CSound::Read: %s", snd_strerror ( ret ) );
throw CGenErr ( "CSound:Read" ); throw CGenErr ( "CSound:Read" );
} }
} }
else else
{ {
return false; return false;
} }
} }
void CSound::SetInNumBuf ( int iNewNum ) void CSound::SetInNumBuf ( int iNewNum )
{ {
/* check new parameter */ /* check new parameter */
if ( ( iNewNum >= MAX_SND_BUF_IN ) || ( iNewNum < 1 ) ) if ( ( iNewNum >= MAX_SND_BUF_IN ) || ( iNewNum < 1 ) )
{ {
iNewNum = NUM_PERIOD_BLOCKS_IN; iNewNum = NUM_PERIOD_BLOCKS_IN;
} }
/* Change only if parameter is different */ /* Change only if parameter is different */
if ( iNewNum != iCurPeriodSizeIn ) if ( iNewNum != iCurPeriodSizeIn )
{ {
iCurPeriodSizeIn = iNewNum; iCurPeriodSizeIn = iNewNum;
bChangParamIn = true; bChangParamIn = true;
} }
} }
/* Wave out *******************************************************************/ /* Wave out *******************************************************************/
void CSound::InitPlayback ( int iNewBufferSize, bool bNewBlocking ) void CSound::InitPlayback ( int iNewBufferSize, bool bNewBlocking )
{ {
int err; int err;
// save buffer size // save buffer size
iBufferSizeOut = iNewBufferSize / NUM_IN_OUT_CHANNELS; // mono size iBufferSizeOut = iNewBufferSize / NUM_IN_OUT_CHANNELS; // mono size
// if playback device was already open, close it first // if playback device was already open, close it first
if ( phandle != NULL ) if ( phandle != NULL )
{ {
snd_pcm_close ( phandle ); snd_pcm_close ( phandle );
} }
// playback device (either "hw:0,0" or "plughw:0,0") // playback device (either "hw:0,0" or "plughw:0,0")
if ( err = snd_pcm_open ( &phandle, "hw:0,0", if ( err = snd_pcm_open ( &phandle, "hw:0,0",
SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK ) != 0) SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK ) != 0)
{ {
qDebug ( "open error: %s", snd_strerror ( err ) ); qDebug ( "open error: %s", snd_strerror ( err ) );
} }
// non-blocking playback // non-blocking playback
if ( err = snd_pcm_nonblock ( phandle, TRUE ) != 0 ) if ( err = snd_pcm_nonblock ( phandle, TRUE ) != 0 )
{ {
qDebug ( "cannot set blocking: %s", snd_strerror ( err ) ); qDebug ( "cannot set blocking: %s", snd_strerror ( err ) );
} }
// set hardware parameters // set hardware parameters
SetHWParams ( phandle, iBufferSizeOut, iCurPeriodSizeOut ); SetHWParams ( phandle, iBufferSizeOut, iCurPeriodSizeOut );
// start playback // start playback
snd_pcm_start ( phandle ); snd_pcm_start ( phandle );
qDebug ( "alsa init playback done" ); qDebug ( "alsa init playback done" );
} }
bool CSound::Write ( CVector<short>& psData ) bool CSound::Write ( CVector<short>& psData )
{ {
int size = iBufferSizeIn; int size = iBufferSizeIn;
int start = 0; int start = 0;
int ret; int ret;
/* Check if device must be opened or reinitialized */ /* Check if device must be opened or reinitialized */
if ( bChangParamOut == true ) if ( bChangParamOut == true )
{ {
InitPlayback ( iBufferSizeOut * NUM_IN_OUT_CHANNELS ); InitPlayback ( iBufferSizeOut * NUM_IN_OUT_CHANNELS );
/* Reset flag */ /* Reset flag */
bChangParamOut = false; bChangParamOut = false;
} }
while ( size ) while ( size )
{ {
ret = snd_pcm_writei ( phandle, &psData[start], size ); ret = snd_pcm_writei ( phandle, &psData[start], size );
if ( ret < 0 ) if ( ret < 0 )
{ {
if ( ret == -EPIPE ) if ( ret == -EPIPE )
{ {
/* under-run */ /* under-run */
qDebug ( "wunderrun" ); qDebug ( "wunderrun" );
ret = snd_pcm_prepare ( phandle ); ret = snd_pcm_prepare ( phandle );
if ( ret < 0 ) if ( ret < 0 )
{ {
qDebug ( "Can't recover from underrun, prepare failed: %s", snd_strerror ( ret ) ); qDebug ( "Can't recover from underrun, prepare failed: %s", snd_strerror ( ret ) );
} }
continue; continue;
} }
else if ( ret == -EAGAIN ) else if ( ret == -EAGAIN )
{ {
if ( ( ret = snd_pcm_wait ( phandle, 1 ) ) < 0 ) if ( ( ret = snd_pcm_wait ( phandle, 1 ) ) < 0 )
{ {
qDebug ( "poll failed (%s)", snd_strerror ( ret ) ); qDebug ( "poll failed (%s)", snd_strerror ( ret ) );
break; break;
} }
continue; continue;
} }
else if ( ret == -ESTRPIPE ) else if ( ret == -ESTRPIPE )
{ {
qDebug("wstrpipe"); qDebug("wstrpipe");
/* wait until the suspend flag is released */ /* wait until the suspend flag is released */
while ( (ret = snd_pcm_resume ( phandle ) ) == -EAGAIN ) while ( (ret = snd_pcm_resume ( phandle ) ) == -EAGAIN )
{ {
sleep(1); sleep(1);
} }
if ( ret < 0 ) if ( ret < 0 )
{ {
ret = snd_pcm_prepare ( phandle ); ret = snd_pcm_prepare ( phandle );
if ( ret < 0 ) if ( ret < 0 )
{ {
qDebug ( "Can't recover from suspend, prepare failed: %s", snd_strerror ( ret ) ); qDebug ( "Can't recover from suspend, prepare failed: %s", snd_strerror ( ret ) );
} }
} }
continue; continue;
} }
else else
{ {
qDebug ( "Write error: %s", snd_strerror ( ret ) ); qDebug ( "Write error: %s", snd_strerror ( ret ) );
} }
break; // skip one period break; // skip one period
} }
size -= ret; size -= ret;
start += ret; start += ret;
} }
return false; return false;
} }
void CSound::SetOutNumBuf(int iNewNum) void CSound::SetOutNumBuf(int iNewNum)
{ {
/* check new parameter */ /* check new parameter */
if ( ( iNewNum >= MAX_SND_BUF_OUT ) || ( iNewNum < 1 ) ) if ( ( iNewNum >= MAX_SND_BUF_OUT ) || ( iNewNum < 1 ) )
{ {
iNewNum = NUM_PERIOD_BLOCKS_OUT; iNewNum = NUM_PERIOD_BLOCKS_OUT;
} }
/* Change only if parameter is different */ /* Change only if parameter is different */
if ( iNewNum != iCurPeriodSizeOut ) if ( iNewNum != iCurPeriodSizeOut )
{ {
iCurPeriodSizeOut = iNewNum; iCurPeriodSizeOut = iNewNum;
bChangParamOut = true; bChangParamOut = true;
} }
} }
/* common **********************************************************************/ /* common **********************************************************************/
bool CSound::SetHWParams(snd_pcm_t* handle, const int iBufferSizeIn, bool CSound::SetHWParams(snd_pcm_t* handle, const int iBufferSizeIn,
const int iNumPeriodBlocks) const int iNumPeriodBlocks)
{ {
int err; int err;
snd_pcm_hw_params_t* hwparams; snd_pcm_hw_params_t* hwparams;
// allocate an invalid snd_pcm_hw_params_t using standard malloc // allocate an invalid snd_pcm_hw_params_t using standard malloc
if ( err = snd_pcm_hw_params_malloc ( &hwparams ) < 0 ) if ( err = snd_pcm_hw_params_malloc ( &hwparams ) < 0 )
{ {
qDebug ( "cannot allocate hardware parameter structure (%s)\n", snd_strerror ( err ) ); qDebug ( "cannot allocate hardware parameter structure (%s)\n", snd_strerror ( err ) );
return true; return true;
} }
// fill params with a full configuration space for a PCM // fill params with a full configuration space for a PCM
if ( err = snd_pcm_hw_params_any ( handle, hwparams ) < 0 ) if ( err = snd_pcm_hw_params_any ( handle, hwparams ) < 0 )
{ {
qDebug ( "cannot initialize hardware parameter structure (%s)\n", snd_strerror ( err ) ); qDebug ( "cannot initialize hardware parameter structure (%s)\n", snd_strerror ( err ) );
return true; return true;
} }
// restrict a configuration space to contain only one access type: // restrict a configuration space to contain only one access type:
// set the interleaved read/write format // set the interleaved read/write format
if ( err = snd_pcm_hw_params_set_access ( handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED ) < 0 ) if ( err = snd_pcm_hw_params_set_access ( handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED ) < 0 )
{ {
qDebug ( "Access type not available : %s", snd_strerror ( err ) ); qDebug ( "Access type not available : %s", snd_strerror ( err ) );
return true; return true;
} }
// restrict a configuration space to contain only one format: // restrict a configuration space to contain only one format:
// set the sample format PCM, 16 bit // set the sample format PCM, 16 bit
if ( err = snd_pcm_hw_params_set_format ( handle, hwparams, SND_PCM_FORMAT_S16 ) < 0 ) if ( err = snd_pcm_hw_params_set_format ( handle, hwparams, SND_PCM_FORMAT_S16 ) < 0 )
{ {
qDebug ( "Sample format not available : %s", snd_strerror ( err ) ); qDebug ( "Sample format not available : %s", snd_strerror ( err ) );
return true; return true;
} }
// restrict a configuration space to contain only one channels count: // restrict a configuration space to contain only one channels count:
// set the count of channels (usually stereo, 2 channels) // set the count of channels (usually stereo, 2 channels)
if ( err = snd_pcm_hw_params_set_channels(handle, hwparams, NUM_IN_OUT_CHANNELS ) < 0 ) if ( err = snd_pcm_hw_params_set_channels(handle, hwparams, NUM_IN_OUT_CHANNELS ) < 0 )
{ {
qDebug ( "Channels count (%i) not available s: %s", NUM_IN_OUT_CHANNELS, snd_strerror ( err ) ); qDebug ( "Channels count (%i) not available s: %s", NUM_IN_OUT_CHANNELS, snd_strerror ( err ) );
return true; return true;
} }
// restrict a configuration space to have rate nearest to a target: // restrict a configuration space to have rate nearest to a target:
// set the sample-rate // set the sample-rate
unsigned int rrate = SND_CRD_SAMPLE_RATE; unsigned int rrate = SND_CRD_SAMPLE_RATE;
if ( err = snd_pcm_hw_params_set_rate_near ( handle, hwparams, &rrate, 0 ) < 0 ) if ( err = snd_pcm_hw_params_set_rate_near ( handle, hwparams, &rrate, 0 ) < 0 )
{ {
qDebug ( "Rate %iHz not available : %s", rrate, snd_strerror ( err ) ); qDebug ( "Rate %iHz not available : %s", rrate, snd_strerror ( err ) );
return true; return true;
} }
if ( rrate != SND_CRD_SAMPLE_RATE ) // check if rate is possible if ( rrate != SND_CRD_SAMPLE_RATE ) // check if rate is possible
{ {
qDebug ( "Rate doesn't match (requested %iHz, get %iHz)", rrate, err ); qDebug ( "Rate doesn't match (requested %iHz, get %iHz)", rrate, err );
return true; return true;
} }
// set the buffer size and period size // set the buffer size and period size
snd_pcm_uframes_t BufferFrames = iBufferSizeIn * iNumPeriodBlocks; snd_pcm_uframes_t BufferFrames = iBufferSizeIn * iNumPeriodBlocks;
if ( err = snd_pcm_hw_params_set_buffer_size_near ( handle, hwparams, &BufferFrames ) < 0 ) if ( err = snd_pcm_hw_params_set_buffer_size_near ( handle, hwparams, &BufferFrames ) < 0 )
{ {
qDebug ( "cannot set buffer size (%s)\n", snd_strerror ( err ) ); qDebug ( "cannot set buffer size (%s)\n", snd_strerror ( err ) );
return true; return true;
} }
// set the period size // set the period size
snd_pcm_uframes_t PeriodSize = iBufferSizeIn; snd_pcm_uframes_t PeriodSize = iBufferSizeIn;
if ( err = snd_pcm_hw_params_set_period_size_near ( handle, hwparams, &PeriodSize, 0 ) < 0 ) if ( err = snd_pcm_hw_params_set_period_size_near ( handle, hwparams, &PeriodSize, 0 ) < 0 )
{ {
qDebug ( "cannot set period size (%s)\n", snd_strerror ( err ) ); qDebug ( "cannot set period size (%s)\n", snd_strerror ( err ) );
return true; return true;
} }
// write the parameters to device // write the parameters to device
if ( err = snd_pcm_hw_params ( handle, hwparams ) < 0 ) if ( err = snd_pcm_hw_params ( handle, hwparams ) < 0 )
{ {
qDebug("Unable to set hw params : %s", snd_strerror(err)); qDebug("Unable to set hw params : %s", snd_strerror(err));
return true; return true;
} }
/* check period and buffer size */ /* check period and buffer size */
snd_pcm_uframes_t buffer_size; snd_pcm_uframes_t buffer_size;
if (err = snd_pcm_hw_params_get_buffer_size(hwparams, &buffer_size) < 0) { if (err = snd_pcm_hw_params_get_buffer_size(hwparams, &buffer_size) < 0) {
qDebug("Unable to get buffer size for playback: %s\n", snd_strerror(err)); qDebug("Unable to get buffer size for playback: %s\n", snd_strerror(err));
} }
qDebug("buffer size: %d (desired: %d)", buffer_size, iBufferSizeIn * iNumPeriodBlocks); qDebug("buffer size: %d (desired: %d)", buffer_size, iBufferSizeIn * iNumPeriodBlocks);
@ -428,34 +428,34 @@ snd_pcm_uframes_t period_size;
err = snd_pcm_hw_params_get_period_size(hwparams, &period_size, 0); err = snd_pcm_hw_params_get_period_size(hwparams, &period_size, 0);
if (err < 0) if (err < 0)
{ {
qDebug("Unable to get period size for playback: %s\n", snd_strerror(err)); qDebug("Unable to get period size for playback: %s\n", snd_strerror(err));
} }
qDebug("frame size: %d (desired: %d)", period_size, iBufferSizeIn); qDebug("frame size: %d (desired: %d)", period_size, iBufferSizeIn);
/* clean-up */ /* clean-up */
snd_pcm_hw_params_free ( hwparams ); snd_pcm_hw_params_free ( hwparams );
return false; return false;
} }
void CSound::Close () void CSound::Close ()
{ {
/* read */ /* read */
if ( rhandle != NULL ) if ( rhandle != NULL )
{ {
snd_pcm_close ( rhandle ); snd_pcm_close ( rhandle );
} }
rhandle = NULL; rhandle = NULL;
/* playback */ /* playback */
if ( phandle != NULL ) if ( phandle != NULL )
{ {
snd_pcm_close ( phandle ); snd_pcm_close ( phandle );
} }
phandle = NULL; phandle = NULL;
} }
#endif /* WITH_SOUND */ #endif /* WITH_SOUND */

View file

@ -2,7 +2,7 @@
* Copyright (c) 2004-2005 * Copyright (c) 2004-2005
* *
* Author(s): * Author(s):
* Volker Fischer, Alexander Kurpiers * Volker Fischer, Alexander Kurpiers
* *
* This code is based on the Open-Source sound interface implementation of * This code is based on the Open-Source sound interface implementation of
* the Dream DRM Receiver project. * the Dream DRM Receiver project.
@ -31,74 +31,74 @@
/* Definitions ****************************************************************/ /* Definitions ****************************************************************/
#define NUM_IN_OUT_CHANNELS 2 /* always stereo */ #define NUM_IN_OUT_CHANNELS 2 /* always stereo */
/* the number of periods is critical for latency */ /* the number of periods is critical for latency */
#define NUM_PERIOD_BLOCKS_IN 2 #define NUM_PERIOD_BLOCKS_IN 2
#define NUM_PERIOD_BLOCKS_OUT 2 #define NUM_PERIOD_BLOCKS_OUT 2
#define MAX_SND_BUF_IN 200 #define MAX_SND_BUF_IN 200
#define MAX_SND_BUF_OUT 200 #define MAX_SND_BUF_OUT 200
/* Classes ********************************************************************/ /* Classes ********************************************************************/
class CSound class CSound
{ {
public: public:
CSound() CSound()
#if WITH_SOUND #if WITH_SOUND
: rhandle(NULL), phandle(NULL), iCurPeriodSizeIn(NUM_PERIOD_BLOCKS_IN), : rhandle(NULL), phandle(NULL), iCurPeriodSizeIn(NUM_PERIOD_BLOCKS_IN),
iCurPeriodSizeOut(NUM_PERIOD_BLOCKS_OUT), bChangParamIn(true), iCurPeriodSizeOut(NUM_PERIOD_BLOCKS_OUT), bChangParamIn(true),
bChangParamOut(true) bChangParamOut(true)
#endif #endif
{} {}
virtual ~CSound() {Close();} virtual ~CSound() {Close();}
/* Not implemented yet, always return one device and default string */ /* Not implemented yet, always return one device and default string */
int GetNumDev() {return 1;} int GetNumDev() {return 1;}
void SetOutDev(int iNewDev) {} void SetOutDev(int iNewDev) {}
void SetInDev(int iNewDev) {} void SetInDev(int iNewDev) {}
/* Return invalid device ID which is the same as using "wave mapper" which /* Return invalid device ID which is the same as using "wave mapper" which
we assume here to be used */ we assume here to be used */
int GetOutDev() {return 1;} int GetOutDev() {return 1;}
int GetInDev() {return 1;} int GetInDev() {return 1;}
#if WITH_SOUND #if WITH_SOUND
void SetInNumBuf(int iNewNum); void SetInNumBuf(int iNewNum);
int GetInNumBuf() {return iCurPeriodSizeIn;} int GetInNumBuf() {return iCurPeriodSizeIn;}
void SetOutNumBuf(int iNewNum); void SetOutNumBuf(int iNewNum);
int GetOutNumBuf() {return iCurPeriodSizeOut;} int GetOutNumBuf() {return iCurPeriodSizeOut;}
void InitRecording(int iNewBufferSize, bool bNewBlocking = true); void InitRecording(int iNewBufferSize, bool bNewBlocking = true);
void InitPlayback(int iNewBufferSize, bool bNewBlocking = false); void InitPlayback(int iNewBufferSize, bool bNewBlocking = false);
bool Read(CVector<short>& psData); bool Read(CVector<short>& psData);
bool Write(CVector<short>& psData); bool Write(CVector<short>& psData);
void Close(); void Close();
protected: protected:
snd_pcm_t* rhandle; snd_pcm_t* rhandle;
snd_pcm_t* phandle; snd_pcm_t* phandle;
bool SetHWParams(snd_pcm_t* handle, const int iBufferSizeIn, bool SetHWParams(snd_pcm_t* handle, const int iBufferSizeIn,
const int iNumPeriodBlocks); const int iNumPeriodBlocks);
int iBufferSizeOut; int iBufferSizeOut;
int iBufferSizeIn; int iBufferSizeIn;
bool bChangParamIn; bool bChangParamIn;
int iCurPeriodSizeIn; int iCurPeriodSizeIn;
bool bChangParamOut; bool bChangParamOut;
int iCurPeriodSizeOut; int iCurPeriodSizeOut;
#else #else
/* Dummy definitions */ /* Dummy definitions */
void SetInNumBuf(int iNewNum) {} void SetInNumBuf(int iNewNum) {}
int GetInNumBuf() {return 1;} int GetInNumBuf() {return 1;}
void SetOutNumBuf(int iNewNum) {} void SetOutNumBuf(int iNewNum) {}
int GetOutNumBuf() {return 1;} int GetOutNumBuf() {return 1;}
void InitRecording(int iNewBufferSize, bool bNewBlocking = true) {printf("no sound!");} void InitRecording(int iNewBufferSize, bool bNewBlocking = true) {printf("no sound!");}
void InitPlayback(int iNewBufferSize, bool bNewBlocking = false) {printf("no sound!");} void InitPlayback(int iNewBufferSize, bool bNewBlocking = false) {printf("no sound!");}
bool Read(CVector<short>& psData) {printf("no sound!"); return false;} bool Read(CVector<short>& psData) {printf("no sound!"); return false;}
bool Write(CVector<short>& psData) {printf("no sound!"); return false;} bool Write(CVector<short>& psData) {printf("no sound!"); return false;}
void Close() {} void Close() {}
#endif #endif
}; };

View file

@ -26,14 +26,15 @@
/* Implementation *************************************************************/ /* Implementation *************************************************************/
CClient::CClient () : bRun ( false ), Socket ( &Channel ), CClient::CClient() : bRun ( false ), Socket ( &Channel ),
iAudioInFader ( AUD_FADER_IN_MAX / 2 ), iAudioInFader ( AUD_FADER_IN_MAX / 2 ),
iReverbLevel ( AUD_REVERB_MAX / 6 ), iReverbLevel ( AUD_REVERB_MAX / 6 ),
bReverbOnLeftChan ( false ), bReverbOnLeftChan ( false ),
iNetwBufSizeFactIn ( DEF_NET_BLOCK_SIZE_FACTOR ) iNetwBufSizeFactIn ( DEF_NET_BLOCK_SIZE_FACTOR )
{ {
// connection for protocol // connection for protocol
QObject::connect ( &Channel, SIGNAL ( MessReadyForSending ( CVector<uint8_t> ) ), QObject::connect ( &Channel,
SIGNAL ( MessReadyForSending ( CVector<uint8_t> ) ),
this, SLOT ( OnSendProtMessage ( CVector<uint8_t> ) ) ); this, SLOT ( OnSendProtMessage ( CVector<uint8_t> ) ) );
QObject::connect ( &Channel, SIGNAL ( ReqJittBufSize() ), QObject::connect ( &Channel, SIGNAL ( ReqJittBufSize() ),
@ -42,7 +43,8 @@ CClient::CClient () : bRun ( false ), Socket ( &Channel ),
QObject::connect ( &Channel, SIGNAL ( ProtocolStatus ( bool ) ), QObject::connect ( &Channel, SIGNAL ( ProtocolStatus ( bool ) ),
this, SLOT ( OnProtocolStatus ( bool ) ) ); this, SLOT ( OnProtocolStatus ( bool ) ) );
QObject::connect ( &Channel, SIGNAL ( ConClientListMesReceived ( CVector<CChannelShortInfo> ) ), QObject::connect ( &Channel,
SIGNAL ( ConClientListMesReceived ( CVector<CChannelShortInfo> ) ),
SIGNAL ( ConClientListMesReceived ( CVector<CChannelShortInfo> ) ) ); SIGNAL ( ConClientListMesReceived ( CVector<CChannelShortInfo> ) ) );
} }
@ -50,15 +52,15 @@ void CClient::OnSendProtMessage ( CVector<uint8_t> vecMessage )
{ {
// convert unsigned uint8_t in char, TODO convert all buffers in uint8_t // convert unsigned uint8_t in char, TODO convert all buffers in uint8_t
CVector<unsigned char> vecbyDataConv ( vecMessage.Size () ); CVector<unsigned char> vecbyDataConv ( vecMessage.Size() );
for ( int i = 0; i < vecMessage.Size (); i++ ) { for ( int i = 0; i < vecMessage.Size(); i++ ) {
vecbyDataConv[i] = static_cast<unsigned char> ( vecMessage[i] ); vecbyDataConv[i] = static_cast<unsigned char> ( vecMessage[i] );
} }
// the protocol queries me to call the function to send the message // the protocol queries me to call the function to send the message
// send it through the network // send it through the network
Socket.SendPacket ( vecbyDataConv, Channel.GetAddress () ); Socket.SendPacket ( vecbyDataConv, Channel.GetAddress() );
} }
void CClient::OnReqJittBufSize() void CClient::OnReqJittBufSize()
@ -102,37 +104,37 @@ void CClient::OnProtocolStatus ( bool bOk )
void CClient::Init() void CClient::Init()
{ {
/* set block sizes (in samples) */ // set block sizes (in samples)
iBlockSizeSam = MIN_BLOCK_SIZE_SAMPLES; iBlockSizeSam = MIN_BLOCK_SIZE_SAMPLES;
iSndCrdBlockSizeSam = MIN_SND_CRD_BLOCK_SIZE_SAMPLES; iSndCrdBlockSizeSam = MIN_SND_CRD_BLOCK_SIZE_SAMPLES;
vecsAudioSndCrd.Init(iSndCrdBlockSizeSam * 2); /* stereo */ vecsAudioSndCrd.Init ( iSndCrdBlockSizeSam * 2 ); // stereo
vecdAudioSndCrdL.Init(iSndCrdBlockSizeSam); vecdAudioSndCrdL.Init ( iSndCrdBlockSizeSam );
vecdAudioSndCrdR.Init(iSndCrdBlockSizeSam); vecdAudioSndCrdR.Init ( iSndCrdBlockSizeSam );
vecdAudioL.Init(iBlockSizeSam); vecdAudioL.Init ( iBlockSizeSam );
vecdAudioR.Init(iBlockSizeSam); vecdAudioR.Init ( iBlockSizeSam );
Sound.InitRecording(iSndCrdBlockSizeSam * 2 /* stereo */); Sound.InitRecording ( iSndCrdBlockSizeSam * 2 ); // stereo
Sound.InitPlayback(iSndCrdBlockSizeSam * 2 /* stereo */); Sound.InitPlayback ( iSndCrdBlockSizeSam * 2 ); // stereo
/* resample objects are always initialized with the input block size */ // resample objects are always initialized with the input block size
/* record */ // record
ResampleObjDownL.Init(iSndCrdBlockSizeSam, SND_CRD_SAMPLE_RATE, SAMPLE_RATE); ResampleObjDownL.Init ( iSndCrdBlockSizeSam, SND_CRD_SAMPLE_RATE, SAMPLE_RATE );
ResampleObjDownR.Init(iSndCrdBlockSizeSam, SND_CRD_SAMPLE_RATE, SAMPLE_RATE); ResampleObjDownR.Init ( iSndCrdBlockSizeSam, SND_CRD_SAMPLE_RATE, SAMPLE_RATE );
/* playback */ // playback
ResampleObjUpL.Init(iBlockSizeSam, SAMPLE_RATE, SND_CRD_SAMPLE_RATE); ResampleObjUpL.Init ( iBlockSizeSam, SAMPLE_RATE, SND_CRD_SAMPLE_RATE );
ResampleObjUpR.Init(iBlockSizeSam, SAMPLE_RATE, SND_CRD_SAMPLE_RATE); ResampleObjUpR.Init ( iBlockSizeSam, SAMPLE_RATE, SND_CRD_SAMPLE_RATE );
/* init network buffers */ // init network buffers
vecsNetwork.Init(iBlockSizeSam); vecsNetwork.Init ( iBlockSizeSam );
vecdNetwData.Init(iBlockSizeSam); vecdNetwData.Init ( iBlockSizeSam );
/* init moving average buffer for response time evaluation */ // init moving average buffer for response time evaluation
RespTimeMoAvBuf.Init(LEN_MOV_AV_RESPONSE); RespTimeMoAvBuf.Init ( LEN_MOV_AV_RESPONSE );
/* init time for response time evaluation */ // init time for response time evaluation
TimeLastBlock = QTime::currentTime(); TimeLastBlock = QTime::currentTime();
AudioReverb.Clear(); AudioReverb.Clear();
@ -142,111 +144,116 @@ void CClient::run()
{ {
int i, iInCnt; int i, iInCnt;
/* Set thread priority (The working thread should have a higher // Set thread priority (The working thread should have a higher
priority than the GUI) */ // priority than the GUI)
#ifdef _WIN32 #ifdef _WIN32
SetThreadPriority ( GetCurrentThread (), THREAD_PRIORITY_ABOVE_NORMAL ); SetThreadPriority ( GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL );
#else #else
/* set the process to realtime privs, taken from // set the process to realtime privs, taken from
"http://www.gardena.net/benno/linux/audio" but does not seem to work, // "http://www.gardena.net/benno/linux/audio" but does not seem to work,
maybe a problem with user rights */ // maybe a problem with user rights
struct sched_param schp; struct sched_param schp;
memset ( &schp, 0, sizeof ( schp ) ); memset ( &schp, 0, sizeof ( schp ) );
schp.sched_priority = sched_get_priority_max ( SCHED_FIFO ); schp.sched_priority = sched_get_priority_max ( SCHED_FIFO );
sched_setscheduler ( 0, SCHED_FIFO, &schp ); sched_setscheduler ( 0, SCHED_FIFO, &schp );
#endif #endif
/* init object */ // init object
Init(); Init();
/* runtime phase --------------------------------------------------------- */ // runtime phase ------------------------------------------------------------
bRun = true; bRun = true;
/* main loop of working thread */ // main loop of working thread
while (bRun) while ( bRun )
{ {
/* get audio from sound card (blocking function) */ // get audio from sound card (blocking function)
if (Sound.Read(vecsAudioSndCrd)) if ( Sound.Read ( vecsAudioSndCrd ) )
{ {
PostWinMessage(MS_SOUND_IN, MUL_COL_LED_RED); PostWinMessage ( MS_SOUND_IN, MUL_COL_LED_RED );
} }
else else
{ {
PostWinMessage(MS_SOUND_IN, MUL_COL_LED_GREEN); PostWinMessage ( MS_SOUND_IN, MUL_COL_LED_GREEN );
} }
/* copy data from one stereo buffer in two separate buffers */ // copy data from one stereo buffer in two separate buffers
iInCnt = 0; iInCnt = 0;
for (i = 0; i < iSndCrdBlockSizeSam; i++) for ( i = 0; i < iSndCrdBlockSizeSam; i++ )
{ {
vecdAudioSndCrdL[i] = (double) vecsAudioSndCrd[iInCnt++]; vecdAudioSndCrdL[i] = (double) vecsAudioSndCrd[iInCnt++];
vecdAudioSndCrdR[i] = (double) vecsAudioSndCrd[iInCnt++]; vecdAudioSndCrdR[i] = (double) vecsAudioSndCrd[iInCnt++];
} }
/* resample data for each channel seaparately */ // resample data for each channel seaparately
ResampleObjDownL.Resample(vecdAudioSndCrdL, vecdAudioL); ResampleObjDownL.Resample ( vecdAudioSndCrdL, vecdAudioL );
ResampleObjDownR.Resample(vecdAudioSndCrdR, vecdAudioR); ResampleObjDownR.Resample ( vecdAudioSndCrdR, vecdAudioR );
/* update signal level meters */ // update signal level meters
SignalLevelMeterL.Update(vecdAudioL); SignalLevelMeterL.Update ( vecdAudioL );
SignalLevelMeterR.Update(vecdAudioR); SignalLevelMeterR.Update ( vecdAudioR );
/* add reverberation effect if activated */ // add reverberation effect if activated
if (iReverbLevel != 0) if ( iReverbLevel != 0 )
{ {
/* first attenuation amplification factor */ // first attenuation amplification factor
const double dRevLev = (double) iReverbLevel / AUD_REVERB_MAX / 2; const double dRevLev = (double) iReverbLevel / AUD_REVERB_MAX / 2;
if (bReverbOnLeftChan) if ( bReverbOnLeftChan )
{ {
for (i = 0; i < iBlockSizeSam; i++) for (i = 0; i < iBlockSizeSam; i++)
{ {
/* left channel */ // left channel
vecdAudioL[i] += vecdAudioL[i] +=
dRevLev * AudioReverb.ProcessSample(vecdAudioL[i]); dRevLev * AudioReverb.ProcessSample ( vecdAudioL[i] );
} }
} }
else else
{ {
for (i = 0; i < iBlockSizeSam; i++) for ( i = 0; i < iBlockSizeSam; i++ )
{ {
/* right channel */ // right channel
vecdAudioR[i] += vecdAudioR[i] +=
dRevLev * AudioReverb.ProcessSample(vecdAudioR[i]); dRevLev * AudioReverb.ProcessSample ( vecdAudioR[i] );
} }
} }
} }
/* mix both signals depending on the fading setting */ // mix both signals depending on the fading setting
const int iMiddleOfFader = AUD_FADER_IN_MAX / 2; const int iMiddleOfFader = AUD_FADER_IN_MAX / 2;
const double dAttFact = const double dAttFact =
(double) (iMiddleOfFader - abs(iMiddleOfFader - iAudioInFader)) / (double) ( iMiddleOfFader - abs ( iMiddleOfFader - iAudioInFader ) ) /
iMiddleOfFader; iMiddleOfFader;
for (i = 0; i < iBlockSizeSam; i++)
for ( i = 0; i < iBlockSizeSam; i++ )
{ {
double dMixedSignal; double dMixedSignal;
if (iAudioInFader > iMiddleOfFader) if ( iAudioInFader > iMiddleOfFader )
{
dMixedSignal = vecdAudioL[i] + dAttFact * vecdAudioR[i]; dMixedSignal = vecdAudioL[i] + dAttFact * vecdAudioR[i];
}
else else
{
dMixedSignal = vecdAudioR[i] + dAttFact * vecdAudioL[i]; dMixedSignal = vecdAudioR[i] + dAttFact * vecdAudioL[i];
}
vecsNetwork[i] = Double2Short(dMixedSignal); vecsNetwork[i] = Double2Short ( dMixedSignal );
} }
/* send it through the network */ // send it through the network
Socket.SendPacket ( Channel.PrepSendPacket ( vecsNetwork ), Socket.SendPacket ( Channel.PrepSendPacket ( vecsNetwork ),
Channel.GetAddress () ); Channel.GetAddress () );
/* receive a new block */ // receive a new block
if (Channel.GetData(vecdNetwData)) if ( Channel.GetData ( vecdNetwData ) )
{ {
PostWinMessage(MS_JIT_BUF_GET, MUL_COL_LED_GREEN); PostWinMessage ( MS_JIT_BUF_GET, MUL_COL_LED_GREEN );
} }
else else
{ {
PostWinMessage(MS_JIT_BUF_GET, MUL_COL_LED_RED); PostWinMessage ( MS_JIT_BUF_GET, MUL_COL_LED_RED );
} }
#ifdef _DEBUG_ #ifdef _DEBUG_
@ -311,53 +318,53 @@ fflush(pFileDelay);
*/ */
/* check if channel is connected */ // check if channel is connected
if (Channel.IsConnected()) if ( Channel.IsConnected() )
{ {
/* write mono input signal in both sound-card channels */ // write mono input signal in both sound-card channels
for (i = 0; i < iBlockSizeSam; i++) for ( i = 0; i < iBlockSizeSam; i++ )
{ {
vecdAudioL[i] = vecdAudioR[i] = vecdNetwData[i]; vecdAudioL[i] = vecdAudioR[i] = vecdNetwData[i];
} }
} }
else else
{ {
/* if not connected, clear data */ // if not connected, clear data
for (i = 0; i < iBlockSizeSam; i++) for ( i = 0; i < iBlockSizeSam; i++ )
{ {
vecdAudioL[i] = vecdAudioR[i] = 0.0; vecdAudioL[i] = vecdAudioR[i] = 0.0;
} }
} }
/* resample data for each channel separately */ // resample data for each channel separately
ResampleObjUpL.Resample(vecdAudioL, vecdAudioSndCrdL); ResampleObjUpL.Resample ( vecdAudioL, vecdAudioSndCrdL );
ResampleObjUpR.Resample(vecdAudioR, vecdAudioSndCrdR); ResampleObjUpR.Resample ( vecdAudioR, vecdAudioSndCrdR );
/* copy data from one stereo buffer in two separate buffers */ // copy data from one stereo buffer in two separate buffers
iInCnt = 0; iInCnt = 0;
for (i = 0; i < iSndCrdBlockSizeSam; i++) for ( i = 0; i < iSndCrdBlockSizeSam; i++ )
{ {
vecsAudioSndCrd[iInCnt++] = Double2Short(vecdAudioSndCrdL[i]); vecsAudioSndCrd[iInCnt++] = Double2Short ( vecdAudioSndCrdL[i] );
vecsAudioSndCrd[iInCnt++] = Double2Short(vecdAudioSndCrdR[i]); vecsAudioSndCrd[iInCnt++] = Double2Short ( vecdAudioSndCrdR[i] );
} }
/* play the new block */ // play the new block
if (Sound.Write(vecsAudioSndCrd)) if ( Sound.Write ( vecsAudioSndCrd ) )
{ {
PostWinMessage(MS_SOUND_OUT, MUL_COL_LED_RED); PostWinMessage ( MS_SOUND_OUT, MUL_COL_LED_RED );
} }
else else
{ {
PostWinMessage(MS_SOUND_OUT, MUL_COL_LED_GREEN); PostWinMessage ( MS_SOUND_OUT, MUL_COL_LED_GREEN );
} }
/* update response time measurement --------------------------------- */ // update response time measurement ------------------------------------
/* add time difference */ // add time difference
const QTime CurTime = QTime::currentTime(); const QTime CurTime = QTime::currentTime();
/* we want to calculate the standard deviation (we assume that the mean // we want to calculate the standard deviation (we assume that the mean
is correct at the block period time) */ // is correct at the block period time)
const double dCurAddVal = const double dCurAddVal =
( (double) TimeLastBlock.msecsTo ( CurTime ) - MIN_BLOCK_DURATION_MS ); ( (double) TimeLastBlock.msecsTo ( CurTime ) - MIN_BLOCK_DURATION_MS );
@ -368,23 +375,23 @@ fprintf(pFileTest, "%e\n", dCurAddVal);
fflush(pFileTest); fflush(pFileTest);
*/ */
RespTimeMoAvBuf.Add ( dCurAddVal * dCurAddVal ); /* add squared value */ RespTimeMoAvBuf.Add ( dCurAddVal * dCurAddVal ); // add squared value
/* store old time value */ // store old time value
TimeLastBlock = CurTime; TimeLastBlock = CurTime;
} }
/* reset current signal level and LEDs */ // reset current signal level and LEDs
SignalLevelMeterL.Reset(); SignalLevelMeterL.Reset();
SignalLevelMeterR.Reset(); SignalLevelMeterR.Reset();
PostWinMessage(MS_RESET_ALL, 0); PostWinMessage ( MS_RESET_ALL, 0 );
} }
bool CClient::Stop() bool CClient::Stop()
{ {
/* set flag so that thread can leave the main loop */ // set flag so that thread can leave the main loop
bRun = false; bRun = false;
/* give thread some time to terminate, return status */ // give thread some time to terminate, return status
return wait(5000); return wait ( 5000 );
} }

View file

@ -114,9 +114,13 @@ CLlconClientDlg::CLlconClientDlg ( CClient* pNCliP, QWidget* parent,
/* set radio buttons --- */ /* set radio buttons --- */
// reverb channel // reverb channel
if (pClient->IsReverbOnLeftChan()) if (pClient->IsReverbOnLeftChan())
{
RadioButtonRevSelL->setChecked(true); RadioButtonRevSelL->setChecked(true);
}
else else
{
RadioButtonRevSelR->setChecked(true); RadioButtonRevSelR->setChecked(true);
}
/* Settings menu ------------------------------------------------------- */ /* Settings menu ------------------------------------------------------- */
@ -138,6 +142,18 @@ CLlconClientDlg::CLlconClientDlg ( CClient* pNCliP, QWidget* parent,
/* Now tell the layout about the menu */ /* Now tell the layout about the menu */
CLlconClientDlgBaseLayout->setMenuBar ( pMenu ); CLlconClientDlgBaseLayout->setMenuBar ( pMenu );
// mixer board -------------------------------------------------------------
// create all mixer controls and make them invisible
vecpChanFader.Init ( MAX_NUM_CHANNELS );
for ( int i = 0; i < MAX_NUM_CHANNELS; i++ )
{
vecpChanFader[i] = new CLlconClientDlg::CChannelFader ( FrameAudioFaders,
FrameAudioFadersLayout, "test" );
vecpChanFader[i]->Hide();
}
/* connections ---------------------------------------------------------- */ /* connections ---------------------------------------------------------- */
// push-buttons // push-buttons
@ -221,7 +237,20 @@ void CLlconClientDlg::OnConnectDisconBut ()
ProgressBarInputLevelR->setProgress ( 0 ); ProgressBarInputLevelR->setProgress ( 0 );
/* immediately update status bar */ /* immediately update status bar */
OnTimerStatus (); OnTimerStatus ();
// TEST
/*
// make old controls invisible
for ( int i = 0; i < MAX_NUM_CHANNELS; i++ )
{
vecpChanFader[i]->Hide();
}
*/
} }
else else
{ {
@ -294,32 +323,28 @@ void CLlconClientDlg::OnConClientListMesReceived ( CVector<CChannelShortInfo> ve
int i; int i;
//FrameAudioFadersLayout->addWidget(new QLabel ( "test", FrameAudioFaders ));
// TODO // TODO
// remove old controls // make old controls invisible
for ( i = 0; i < vecpChanFader.Size(); i++ ) for ( i = 0; i < MAX_NUM_CHANNELS; i++ )
{ {
delete vecpChanFader[i]; vecpChanFader[i]->Hide();
} }
// TEST add current faders // TEST add current faders
vecpChanFader.Init ( vecChanInfo.Size() );
for ( i = 0; i < vecChanInfo.Size(); i++ ) for ( i = 0; i < vecChanInfo.Size(); i++ )
{ {
QHostAddress addrTest ( vecChanInfo[i].veciIpAddr ); QHostAddress addrTest ( vecChanInfo[i].veciIpAddr );
vecpChanFader[i] = new CLlconClientDlg::CChannelFader ( FrameAudioFaders, vecpChanFader[i]->Show();
FrameAudioFadersLayout, addrTest.toString() ); vecpChanFader[i]->SetText ( addrTest.toString().latin1() );
// vecpChanFader[i] = new CLlconClientDlg::CChannelFader ( FrameAudioFaders,
// FrameAudioFadersLayout, addrTest.toString() );
} }
//FrameAudioFadersLayout->addWidget(new QLabel ( "test", FrameAudioFaders ));
} }
@ -399,3 +424,8 @@ pFader->setEnabled ( FALSE );
pParentLayout->insertLayout ( 0, pMainGrid ); pParentLayout->insertLayout ( 0, pMainGrid );
} }
void CLlconClientDlg::CChannelFader::SetText ( const std::string sText )
{
pLabel->setText ( sText.c_str() );
}

View file

@ -85,6 +85,10 @@ protected:
// TODO get rid of pMainGrid // TODO get rid of pMainGrid
} }
void SetText ( const std::string sText );
void Show() { pLabel->show(); pFader->show(); }
void Hide() { pLabel->hide(); pFader->hide(); }
protected: protected:
QGridLayout* pMainGrid; QGridLayout* pMainGrid;
QSlider* pFader; QSlider* pFader;