some cleanup
This commit is contained in:
parent
c5cf24f58e
commit
50eba66c0c
4 changed files with 204 additions and 148 deletions
283
linux/sound.cpp
283
linux/sound.cpp
|
@ -21,8 +21,10 @@ void CSound::InitRecording(int iNewBufferSize, bool bNewBlocking)
|
||||||
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,
|
||||||
|
@ -32,87 +34,82 @@ void CSound::InitRecording(int iNewBufferSize, bool bNewBlocking)
|
||||||
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 ) );
|
||||||
// throw CGenErr("alsa CSound::Init_HW record");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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 ) );
|
||||||
// throw CGenErr("alsa CSound::Init_HW record");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set hardware parameters */
|
/* set hardware parameters */
|
||||||
SetHWParams(rhandle, true, iBufferSizeIn, iCurPeriodSizeIn);
|
SetHWParams ( rhandle, iBufferSizeIn, iCurPeriodSizeIn );
|
||||||
|
|
||||||
|
|
||||||
/* sw parameters --------------------------------------------------------- */
|
/* sw parameters --------------------------------------------------------- */
|
||||||
snd_pcm_sw_params_t* swparams;
|
snd_pcm_sw_params_t* swparams;
|
||||||
|
|
||||||
if (err = snd_pcm_sw_params_malloc (&swparams) != 0)
|
// allocate an invalid snd_pcm_sw_params_t using standard malloc
|
||||||
|
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 ) );
|
||||||
// return NULL ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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 ) );
|
||||||
// throw CGenErr("alsa CSound::Init_HW ");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Start the transfer when the buffer immediately */
|
// 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));
|
{
|
||||||
// throw CGenErr("alsa CSound::Init_HW ");
|
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));
|
{
|
||||||
// throw CGenErr("alsa CSound::Init_HW ");
|
qDebug ( "Unable to set transfer align : %s", snd_strerror ( err ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// set avail min inside a software configuration container
|
||||||
|
/* 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
|
||||||
|
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
|
||||||
|
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
|
||||||
|
timing source is used */
|
||||||
|
snd_pcm_uframes_t period_size = iBufferSizeIn;
|
||||||
|
|
||||||
// TEST
|
err = snd_pcm_sw_params_set_avail_min ( rhandle, swparams, period_size );
|
||||||
/* Allow the transfer when at least period_size samples can be processed */
|
if ( err < 0 )
|
||||||
// /* round up to closest transfer boundary */
|
{
|
||||||
// start_threshold = (buffer_size / xfer_align) * xfer_align ;
|
qDebug ( "Unable to set avail min : %s", snd_strerror ( err ) );
|
||||||
// if (start_threshold < 1)
|
|
||||||
// start_threshold = 1 ;
|
|
||||||
|
|
||||||
|
|
||||||
// TEST
|
|
||||||
snd_pcm_uframes_t period_size = iBufferSizeIn;
|
|
||||||
|
|
||||||
err = snd_pcm_sw_params_set_avail_min(rhandle, swparams, period_size);
|
|
||||||
if (err < 0) {
|
|
||||||
qDebug("Unable to set avail min : %s", snd_strerror(err));
|
|
||||||
// throw CGenErr("alsa CSound::Init_HW ");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// write the parameters to the record/playback device
|
||||||
|
err = snd_pcm_sw_params ( rhandle, swparams );
|
||||||
/* Write the parameters to the record/playback device */
|
if ( err < 0 )
|
||||||
err = snd_pcm_sw_params(rhandle, swparams);
|
{
|
||||||
if (err < 0) {
|
qDebug ( "Unable to set sw params : %s", snd_strerror ( err ) );
|
||||||
qDebug("Unable to set sw params : %s", snd_strerror(err));
|
|
||||||
// throw CGenErr("alsa CSound::Init_HW ");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* clean-up */
|
// clean-up
|
||||||
snd_pcm_sw_params_free(swparams);
|
snd_pcm_sw_params_free ( swparams );
|
||||||
|
|
||||||
snd_pcm_reset(rhandle);
|
|
||||||
snd_pcm_start(rhandle);
|
|
||||||
|
|
||||||
qDebug("alsa init record done");
|
// start record
|
||||||
|
snd_pcm_reset ( rhandle );
|
||||||
|
snd_pcm_start ( rhandle );
|
||||||
|
|
||||||
|
qDebug ( "alsa init record done" );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CSound::Read(CVector<short>& psData)
|
bool CSound::Read(CVector<short>& psData)
|
||||||
|
@ -210,34 +207,88 @@ 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 */
|
// playback device (either "hw:0,0" or "plughw:0,0")
|
||||||
/* 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 ) );
|
||||||
// throw CGenErr("alsa CSound::Init_HW playback");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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 ) );
|
||||||
// throw CGenErr("alsa CSound::Init_HW record");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set hardware parameters */
|
// set hardware parameters
|
||||||
SetHWParams ( phandle, false, iBufferSizeOut, iCurPeriodSizeOut );
|
SetHWParams ( phandle, iBufferSizeOut, iCurPeriodSizeOut );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* sw parameters --------------------------------------------------------- */
|
||||||
|
snd_pcm_sw_params_t* swparams;
|
||||||
|
|
||||||
|
// TEST
|
||||||
|
// allocate an invalid snd_pcm_sw_params_t using standard malloc
|
||||||
|
if ( err = snd_pcm_sw_params_malloc ( &swparams ) != 0 )
|
||||||
|
{
|
||||||
|
qDebug ( "snd_pcm_sw_params_malloc: %s", snd_strerror ( err ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get the current swparams */
|
||||||
|
err = snd_pcm_sw_params_current(phandle, swparams);
|
||||||
|
if (err < 0)
|
||||||
|
{
|
||||||
|
qDebug("Unable to determine current swparams for playback: %s\n", snd_strerror(err));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* start the transfer when the buffer is almost full: */
|
||||||
|
/* (buffer_size / avail_min) * avail_min */
|
||||||
|
err = snd_pcm_sw_params_set_start_threshold(phandle, swparams, iCurPeriodSizeOut - 1);
|
||||||
|
if (err < 0) {
|
||||||
|
qDebug("Unable to set start threshold mode for playback: %s\n", snd_strerror(err));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* allow the transfer when at least period_size samples can be processed */
|
||||||
|
err = snd_pcm_sw_params_set_avail_min(phandle, swparams, iBufferSizeOut);
|
||||||
|
if (err < 0) {
|
||||||
|
qDebug("Unable to set avail min for playback: %s\n", snd_strerror(err));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* align all transfers to 1 sample */
|
||||||
|
err = snd_pcm_sw_params_set_xfer_align(phandle, swparams, 1);
|
||||||
|
if (err < 0) {
|
||||||
|
qDebug("Unable to set transfer align for playback: %s\n", snd_strerror(err));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* write the parameters to the playback device */
|
||||||
|
err = snd_pcm_sw_params(phandle, swparams);
|
||||||
|
if (err < 0) {
|
||||||
|
qDebug("Unable to set sw params for playback: %s\n", snd_strerror(err));
|
||||||
|
}
|
||||||
|
|
||||||
|
// clean-up
|
||||||
|
snd_pcm_sw_params_free ( swparams );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// start playback
|
||||||
snd_pcm_start ( phandle );
|
snd_pcm_start ( phandle );
|
||||||
|
|
||||||
qDebug ( "alsa init playback done" );
|
qDebug ( "alsa init playback done" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,17 +314,7 @@ bool CSound::Write ( CVector<short>& psData )
|
||||||
|
|
||||||
if ( ret < 0 )
|
if ( ret < 0 )
|
||||||
{
|
{
|
||||||
if ( ret == -EAGAIN )
|
if ( ret == -EPIPE )
|
||||||
{
|
|
||||||
if ( ( ret = snd_pcm_wait ( phandle, 1 ) ) < 0 )
|
|
||||||
{
|
|
||||||
qDebug ( "poll failed (%s)", snd_strerror ( ret ) );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else if ( ret == -EPIPE )
|
|
||||||
{
|
{
|
||||||
/* under-run */
|
/* under-run */
|
||||||
qDebug ( "wunderrun" );
|
qDebug ( "wunderrun" );
|
||||||
|
@ -284,6 +325,16 @@ bool CSound::Write ( CVector<short>& psData )
|
||||||
{
|
{
|
||||||
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;
|
||||||
|
}
|
||||||
|
else if ( ret == -EAGAIN )
|
||||||
|
{
|
||||||
|
if ( ( ret = snd_pcm_wait ( phandle, 1 ) ) < 0 )
|
||||||
|
{
|
||||||
|
qDebug ( "poll failed (%s)", snd_strerror ( ret ) );
|
||||||
|
break;
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if ( ret == -ESTRPIPE )
|
else if ( ret == -ESTRPIPE )
|
||||||
|
@ -310,12 +361,11 @@ bool CSound::Write ( CVector<short>& psData )
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
qDebug ( "Write error: %s", snd_strerror ( ret ) );
|
qDebug ( "Write error: %s", snd_strerror ( ret ) );
|
||||||
// throw CGenErr ( "Write error" );
|
|
||||||
}
|
}
|
||||||
break; /* skip one period */
|
break; // skip one period
|
||||||
}
|
}
|
||||||
|
|
||||||
size -= ret;
|
size -= ret;
|
||||||
start += ret;
|
start += ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -340,60 +390,59 @@ void CSound::SetOutNumBuf(int iNewNum)
|
||||||
|
|
||||||
|
|
||||||
/* common **********************************************************************/
|
/* common **********************************************************************/
|
||||||
bool CSound::SetHWParams(snd_pcm_t* handle, const bool bIsRecord,
|
bool CSound::SetHWParams(snd_pcm_t* handle, const int iBufferSizeIn,
|
||||||
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;
|
||||||
|
|
||||||
if (err = snd_pcm_hw_params_malloc(&hwparams) < 0)
|
// allocate an invalid snd_pcm_hw_params_t using standard malloc
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err = snd_pcm_hw_params_any(handle, hwparams) < 0)
|
// fill params with a full configuration space for a PCM
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get configuration */
|
// restrict a configuration space to contain only one access type:
|
||||||
if (err = snd_pcm_hw_params_any(handle, hwparams) < 0)
|
// set the interleaved read/write format
|
||||||
|
if ( err = snd_pcm_hw_params_set_access ( handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED ) < 0 )
|
||||||
{
|
{
|
||||||
qDebug("Broken configuration : no configurations available: %s", snd_strerror(err));
|
qDebug ( "Access type not available : %s", snd_strerror ( err ) );
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set the interleaved read/write format */
|
|
||||||
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));
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the sample format */
|
// restrict a configuration space to contain only one format:
|
||||||
if (err = snd_pcm_hw_params_set_format(handle, hwparams, SND_PCM_FORMAT_S16) < 0)
|
// set the sample format PCM, 16 bit
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the count of channels */
|
// restrict a configuration space to contain only one channels count:
|
||||||
if (err = snd_pcm_hw_params_set_channels(handle, hwparams, NUM_IN_OUT_CHANNELS) < 0)
|
// set the count of channels (usually stereo, 2 channels)
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the sample-rate */
|
// restrict a configuration space to have rate nearest to a target:
|
||||||
|
// 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 )
|
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;
|
||||||
|
@ -433,46 +482,46 @@ snd_pcm_uframes_t PeriodSize = iBufferSizeIn;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check period and buffer size */
|
|
||||||
qDebug("desired block size: %d / desired buffer size: %d", iBufferSizeIn, iBufferSizeIn * iNumPeriodBlocks);
|
|
||||||
|
|
||||||
// TEST
|
|
||||||
|
/* 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));
|
||||||
// throw CGenErr("alsa CSound::Init_HW ");
|
|
||||||
}
|
}
|
||||||
qDebug("buffer size %d", buffer_size);
|
qDebug("buffer size: %d (desired: %d)", buffer_size, iBufferSizeIn * iNumPeriodBlocks);
|
||||||
|
|
||||||
snd_pcm_uframes_t period_size;
|
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));
|
||||||
// throw CGenErr("alsa CSound::Init_HW ");
|
|
||||||
}
|
}
|
||||||
qDebug("period size %d", period_size);
|
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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,8 @@ 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)
|
iCurPeriodSizeOut(NUM_PERIOD_BLOCKS_OUT), bChangParamIn(true),
|
||||||
|
bChangParamOut(true)
|
||||||
#endif
|
#endif
|
||||||
{}
|
{}
|
||||||
virtual ~CSound() {Close();}
|
virtual ~CSound() {Close();}
|
||||||
|
@ -78,8 +79,8 @@ protected:
|
||||||
snd_pcm_t* rhandle;
|
snd_pcm_t* rhandle;
|
||||||
snd_pcm_t* phandle;
|
snd_pcm_t* phandle;
|
||||||
|
|
||||||
bool SetHWParams(snd_pcm_t* handle, const bool bIsRecord,
|
bool SetHWParams(snd_pcm_t* handle, const int iBufferSizeIn,
|
||||||
const int iBufferSizeIn, const int iNumPeriodBlocks);
|
const int iNumPeriodBlocks);
|
||||||
|
|
||||||
int iBufferSizeOut;
|
int iBufferSizeOut;
|
||||||
int iBufferSizeIn;
|
int iBufferSizeIn;
|
||||||
|
|
|
@ -130,13 +130,15 @@ void CClient::run()
|
||||||
/* 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 */
|
/* set the process to realtime privs, taken from
|
||||||
|
"http://www.gardena.net/benno/linux/audio" but does not seem to work,
|
||||||
|
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 */
|
||||||
|
|
|
@ -205,41 +205,45 @@ void CLlconClientDlg::closeEvent ( QCloseEvent * Event )
|
||||||
Event->accept();
|
Event->accept();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CLlconClientDlg::OnConnectDisconBut()
|
void CLlconClientDlg::OnConnectDisconBut ()
|
||||||
{
|
{
|
||||||
/* start/stop client, set button text */
|
/* start/stop client, set button text */
|
||||||
if (pClient->IsRunning())
|
if ( pClient->IsRunning () )
|
||||||
{
|
{
|
||||||
pClient->Stop();
|
pClient->Stop ();
|
||||||
PushButtonConnect->setText(CON_BUT_CONNECTTEXT);
|
PushButtonConnect->setText ( CON_BUT_CONNECTTEXT );
|
||||||
|
|
||||||
/* stop timer for level meter bars and reset them */
|
/* stop timer for level meter bars and reset them */
|
||||||
TimerSigMet.stop();
|
TimerSigMet.stop ();
|
||||||
ProgressBarInputLevelL->setProgress(0);
|
ProgressBarInputLevelL->setProgress ( 0 );
|
||||||
ProgressBarInputLevelR->setProgress(0);
|
ProgressBarInputLevelR->setProgress ( 0 );
|
||||||
|
|
||||||
/* immediately update status bar */
|
/* immediately update status bar */
|
||||||
OnTimerStatus();
|
OnTimerStatus ();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* set address and check if address is valid */
|
/* set address and check if address is valid */
|
||||||
if (pClient->SetServerAddr(LineEditServerAddr->text()))
|
if ( pClient->SetServerAddr ( LineEditServerAddr->text () ) )
|
||||||
{
|
{
|
||||||
pClient->start();
|
#if ( QT_VERSION > 300 )
|
||||||
PushButtonConnect->setText(CON_BUT_DISCONNECTTEXT);
|
pClient->start ( QThread::TimeCriticalPriority );
|
||||||
|
#else
|
||||||
|
pClient->start ();
|
||||||
|
#endif
|
||||||
|
PushButtonConnect->setText ( CON_BUT_DISCONNECTTEXT );
|
||||||
|
|
||||||
/* start timer for level meter bar */
|
/* start timer for level meter bar */
|
||||||
TimerSigMet.start(LEVELMETER_UPDATE_TIME);
|
TimerSigMet.start ( LEVELMETER_UPDATE_TIME );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Restart timer to ensure that the text is visible at
|
/* Restart timer to ensure that the text is visible at
|
||||||
least the time for one complete interval */
|
least the time for one complete interval */
|
||||||
TimerStatus.changeInterval(STATUSBAR_UPDATE_TIME);
|
TimerStatus.changeInterval ( STATUSBAR_UPDATE_TIME );
|
||||||
|
|
||||||
/* show the error in the status bar */
|
/* show the error in the status bar */
|
||||||
TextLabelStatus->setText(tr("invalid address"));
|
TextLabelStatus->setText ( tr ( "invalid address" ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue