typedef struct
{
PaSampleFormat hostSampleFormat;
- unsigned long framesPerBuffer;
int numUserChannels, numHostChannels;
int userInterleaved, hostInterleaved;
int canMmap;
int useReventFix; /* Alsa older than 1.0.16, plug devices need a fix */
snd_pcm_t *pcm;
- snd_pcm_uframes_t bufferSize;
+ snd_pcm_uframes_t framesPerPeriod, alsaBufferSize;
snd_pcm_format_t nativeFormat;
unsigned int nfds;
int ready; /* Marked ready from poll */
}
/* Initialize device info with invalid values (maxInputChannels and maxOutputChannels are set to zero since these indicate
- * wether input/output is available) */
+ * whether input/output is available) */
static void InitializeDeviceInfo( PaDeviceInfo *deviceInfo )
{
deviceInfo->structVersion = -1;
double sr = *sampleRate;
unsigned int minPeriods = 2;
- /* self->framesPerBuffer = framesPerHostBuffer; */
+ /* self->framesPerPeriod = framesPerHostBuffer; */
/* ... fill up the configuration space with all possibile
* combinations of parameters this device will accept */
/** Finish the configuration of the component's ALSA device.
*
- * As part of this method, the component's bufferSize attribute will be set.
+ * As part of this method, the component's alsaBufferSize attribute will be set.
* @param latency: The latency for this component.
*/
static PaError PaAlsaStreamComponent_FinishConfigure( PaAlsaStreamComponent *self, snd_pcm_hw_params_t* hwParams,
alsa_snd_pcm_sw_params_alloca( &swParams );
- bufSz = params->suggestedLatency * sampleRate + self->framesPerBuffer;
+ bufSz = params->suggestedLatency * sampleRate + self->framesPerPeriod;
ENSURE_( alsa_snd_pcm_hw_params_set_buffer_size_near( self->pcm, hwParams, &bufSz ), paUnanticipatedHostError );
/* Set the parameters! */
}
if( alsa_snd_pcm_hw_params_get_buffer_size != NULL )
{
- ENSURE_( alsa_snd_pcm_hw_params_get_buffer_size( hwParams, &self->bufferSize ), paUnanticipatedHostError );
+ ENSURE_( alsa_snd_pcm_hw_params_get_buffer_size( hwParams, &self->alsaBufferSize ), paUnanticipatedHostError );
}
else
{
- self->bufferSize = bufSz;
+ self->alsaBufferSize = bufSz;
}
/* Latency in seconds */
- *latency = (self->bufferSize - self->framesPerBuffer) / sampleRate;
+ *latency = (self->alsaBufferSize - self->framesPerPeriod) / sampleRate;
/* Now software parameters... */
ENSURE_( alsa_snd_pcm_sw_params_current( self->pcm, swParams ), paUnanticipatedHostError );
- ENSURE_( alsa_snd_pcm_sw_params_set_start_threshold( self->pcm, swParams, self->framesPerBuffer ), paUnanticipatedHostError );
- ENSURE_( alsa_snd_pcm_sw_params_set_stop_threshold( self->pcm, swParams, self->bufferSize ), paUnanticipatedHostError );
+ ENSURE_( alsa_snd_pcm_sw_params_set_start_threshold( self->pcm, swParams, self->framesPerPeriod ), paUnanticipatedHostError );
+ ENSURE_( alsa_snd_pcm_sw_params_set_stop_threshold( self->pcm, swParams, self->alsaBufferSize ), paUnanticipatedHostError );
/* Silence buffer in the case of underrun */
if( !primeBuffers ) /* XXX: Make sense? */
ENSURE_( alsa_snd_pcm_sw_params_set_silence_size( self->pcm, swParams, boundary ), paUnanticipatedHostError );
}
- ENSURE_( alsa_snd_pcm_sw_params_set_avail_min( self->pcm, swParams, self->framesPerBuffer ), paUnanticipatedHostError );
+ ENSURE_( alsa_snd_pcm_sw_params_set_avail_min( self->pcm, swParams, self->framesPerPeriod ), paUnanticipatedHostError );
ENSURE_( alsa_snd_pcm_sw_params_set_xfer_align( self->pcm, swParams, 1 ), paUnanticipatedHostError );
ENSURE_( alsa_snd_pcm_sw_params_set_tstamp_mode( self->pcm, swParams, SND_PCM_TSTAMP_ENABLE ), paUnanticipatedHostError );
/** Determine size per host buffer.
*
- * During this method call, the component's framesPerBuffer attribute gets computed, and the corresponding period size
+ * During this method call, the component's framesPerPeriod attribute gets computed, and the corresponding period size
* gets configured for the device.
* @param accurate: If the configured period size is non-integer, this will be set to 0.
*/
}
/* Set result */
- self->framesPerBuffer = framesPerHostBuffer;
+ self->framesPerPeriod = framesPerHostBuffer;
error:
return result;
* which should be fine if the period size is the same for capture and playback. In general, if there is a specified user
* buffer size, this method tries it best to determine a period size which is a multiple of the user buffer size.
*
- * The framesPerBuffer attributes of the individual capture and playback components of the stream are set to corresponding
+ * The framesPerPeriod attributes of the individual capture and playback components of the stream are set to corresponding
* values determined here. Since these should be reported as
*
* This is one of those blocks of code that will just take a lot of
paUnanticipatedHostError );
ENSURE_( alsa_snd_pcm_hw_params_set_period_size( self->playback.pcm, hwParamsPlayback, periodSize, 0 ),
paUnanticipatedHostError );
- self->capture.framesPerBuffer = self->playback.framesPerBuffer = periodSize;
+ self->capture.framesPerPeriod = self->playback.framesPerPeriod = periodSize;
framesPerHostBuffer = periodSize;
}
else
optimalPeriodSize = PA_MAX( desiredBufSz / numPeriods, minPeriodSize );
optimalPeriodSize = PA_MIN( optimalPeriodSize, maxPeriodSize );
- self->capture.framesPerBuffer = optimalPeriodSize;
+ self->capture.framesPerPeriod = optimalPeriodSize;
dir = 0;
- ENSURE_( alsa_snd_pcm_hw_params_set_period_size_near( self->capture.pcm, hwParamsCapture, &self->capture.framesPerBuffer, &dir ),
+ ENSURE_( alsa_snd_pcm_hw_params_set_period_size_near( self->capture.pcm, hwParamsCapture, &self->capture.framesPerPeriod, &dir ),
paUnanticipatedHostError );
- self->playback.framesPerBuffer = optimalPeriodSize;
+ self->playback.framesPerPeriod = optimalPeriodSize;
dir = 0;
- ENSURE_( alsa_snd_pcm_hw_params_set_period_size_near( self->playback.pcm, hwParamsPlayback, &self->playback.framesPerBuffer, &dir ),
+ ENSURE_( alsa_snd_pcm_hw_params_set_period_size_near( self->playback.pcm, hwParamsPlayback, &self->playback.framesPerPeriod, &dir ),
paUnanticipatedHostError );
- framesPerHostBuffer = PA_MAX( self->capture.framesPerBuffer, self->playback.framesPerBuffer );
+ framesPerHostBuffer = PA_MAX( self->capture.framesPerPeriod, self->playback.framesPerPeriod );
*hostBufferSizeMode = paUtilBoundedHostBufferSize;
}
}
PA_ENSURE( PaAlsaStreamComponent_DetermineFramesPerBuffer( first, firstStreamParams, framesPerUserBuffer,
sampleRate, firstHwParams, &accurate ) );
- second->framesPerBuffer = first->framesPerBuffer;
+ second->framesPerPeriod = first->framesPerPeriod;
dir = 0;
- ENSURE_( alsa_snd_pcm_hw_params_set_period_size_near( second->pcm, secondHwParams, &second->framesPerBuffer, &dir ),
+ ENSURE_( alsa_snd_pcm_hw_params_set_period_size_near( second->pcm, secondHwParams, &second->framesPerPeriod, &dir ),
paUnanticipatedHostError );
- if( self->capture.framesPerBuffer == self->playback.framesPerBuffer )
+ if( self->capture.framesPerPeriod == self->playback.framesPerPeriod )
{
- framesPerHostBuffer = self->capture.framesPerBuffer;
+ framesPerHostBuffer = self->capture.framesPerPeriod;
}
else
{
- framesPerHostBuffer = PA_MAX( self->capture.framesPerBuffer, self->playback.framesPerBuffer );
+ framesPerHostBuffer = PA_MAX( self->capture.framesPerPeriod, self->playback.framesPerPeriod );
*hostBufferSizeMode = paUtilBoundedHostBufferSize;
}
}
{
PA_ENSURE( PaAlsaStreamComponent_DetermineFramesPerBuffer( &self->capture, inputParameters, framesPerUserBuffer,
sampleRate, hwParamsCapture, &accurate) );
- framesPerHostBuffer = self->capture.framesPerBuffer;
+ framesPerHostBuffer = self->capture.framesPerPeriod;
}
else
{
assert( self->playback.pcm );
PA_ENSURE( PaAlsaStreamComponent_DetermineFramesPerBuffer( &self->playback, outputParameters, framesPerUserBuffer,
sampleRate, hwParamsPlayback, &accurate ) );
- framesPerHostBuffer = self->playback.framesPerBuffer;
+ framesPerHostBuffer = self->playback.framesPerPeriod;
}
}
if( self->capture.pcm )
{
- assert( self->capture.framesPerBuffer != 0 );
+ assert( self->capture.framesPerPeriod != 0 );
PA_ENSURE( PaAlsaStreamComponent_FinishConfigure( &self->capture, hwParamsCapture, inParams, self->primeBuffers, realSr,
inputLatency ) );
- PA_DEBUG(( "%s: Capture period size: %lu, latency: %f\n", __FUNCTION__, self->capture.framesPerBuffer, *inputLatency ));
+ PA_DEBUG(( "%s: Capture period size: %lu, latency: %f\n", __FUNCTION__, self->capture.framesPerPeriod, *inputLatency ));
}
if( self->playback.pcm )
{
- assert( self->playback.framesPerBuffer != 0 );
+ assert( self->playback.framesPerPeriod != 0 );
PA_ENSURE( PaAlsaStreamComponent_FinishConfigure( &self->playback, hwParamsPlayback, outParams, self->primeBuffers, realSr,
outputLatency ) );
- PA_DEBUG(( "%s: Playback period size: %lu, latency: %f\n", __FUNCTION__, self->playback.framesPerBuffer, *outputLatency ));
+ PA_DEBUG(( "%s: Playback period size: %lu, latency: %f\n", __FUNCTION__, self->playback.framesPerPeriod, *outputLatency ));
}
/* Should be exact now */
}
{
- unsigned long minFramesPerHostBuffer = PA_MIN( self->capture.pcm ? self->capture.framesPerBuffer : ULONG_MAX,
- self->playback.pcm ? self->playback.framesPerBuffer : ULONG_MAX );
+ unsigned long minFramesPerHostBuffer = PA_MIN( self->capture.pcm ? self->capture.framesPerPeriod : ULONG_MAX,
+ self->playback.pcm ? self->playback.framesPerPeriod : ULONG_MAX );
self->pollTimeout = CalculatePollTimeout( self, minFramesPerHostBuffer ); /* Period in msecs, rounded up */
/* Time before watchdog unthrottles realtime thread == 1/4 of period time in msecs */
if( self->callbackMode )
{
/* If the user expects a certain number of frames per callback we will either have to rely on block adaption
- * (framesPerHostBuffer is not an integer multiple of framesPerBuffer) or we can simply align the number
+ * (framesPerHostBuffer is not an integer multiple of framesPerPeriod) or we can simply align the number
* of host buffer frames with what the user specified */
if( self->framesPerUserBuffer != paFramesPerBufferUnspecified )
{
/* Unless the ratio between number of host and user buffer frames is an integer we will have to rely
* on block adaption */
/*
- if( framesPerHostBuffer % framesPerBuffer != 0 || (self->capture.pcm && self->playback.pcm &&
- self->capture.framesPerBuffer != self->playback.framesPerBuffer) )
+ if( framesPerHostBuffer % framesPerPeriod != 0 || (self->capture.pcm && self->playback.pcm &&
+ self->capture.framesPerPeriod != self->playback.framesPerPeriod) )
self->useBlockAdaption = 1;
else
self->alignFrames = 1;
/* XXX: Why do we support this anyway? */
if( framesPerBuffer == paFramesPerBufferUnspecified && getenv( "PA_ALSA_PERIODSIZE" ) != NULL )
{
- PA_DEBUG(( "%s: Getting framesPerBuffer from environment\n", __FUNCTION__ ));
+ PA_DEBUG(( "%s: Getting framesPerBuffer (Alsa period-size) from environment\n", __FUNCTION__ ));
framesPerBuffer = atoi( getenv("PA_ALSA_PERIODSIZE") );
}
stream->streamRepresentation.streamInfo.outputLatency = outputLatency + (PaTime)(
PaUtil_GetBufferProcessorOutputLatencyFrames( &stream->bufferProcessor ) / sampleRate);
- PA_DEBUG(( "%s: Stream: framesPerBuffer = %lu, maxFramesPerHostBuffer = %lu, latency = i(%f)/o(%f), \n", __FUNCTION__, framesPerBuffer, stream->maxFramesPerHostBuffer, stream->streamRepresentation.streamInfo.inputLatency, stream->streamRepresentation.streamInfo.outputLatency));
+ PA_DEBUG(( "%s: Stream: framesPerBuffer = %lu, maxFramesPerHostBuffer = %lu, latency i=%f, o=%f\n", __FUNCTION__, framesPerBuffer, stream->maxFramesPerHostBuffer, stream->streamRepresentation.streamInfo.inputLatency, stream->streamRepresentation.streamInfo.outputLatency));
*s = (PaStream*)stream;
/** Start/prepare pcm(s) for streaming.
*
- * Depending on wether the stream is in callback or blocking mode, we will respectively start or simply
+ * Depending on whether the stream is in callback or blocking mode, we will respectively start or simply
* prepare the playback pcm. If the buffer has _not_ been primed, we will in callback mode prepare and
* silence the buffer before starting playback. In blocking mode we simply prepare, as the playback will
* be started automatically as the user writes to output.
{
PaError result = paNoError;
PaAlsaStream* stream = (PaAlsaStream*)s;
- int streamStarted = 0; /* So we can know wether we need to take the stream down */
+ int streamStarted = 0; /* So we can know whether we need to take the stream down */
/* Ready the processor */
PaUtil_ResetBufferProcessor( &stream->bufferProcessor );
/** Stop or abort stream.
*
- * If a stream is in callback mode we will have to inspect wether the background thread has
+ * If a stream is in callback mode we will have to inspect whether the background thread has
* finished, or we will have to take it out. In either case we join the thread before
* returning. In blocking mode, we simply tell ALSA to stop abruptly (abort) or finish
* buffers (drain)
if( StreamDirection_Out == streamDir )
{
/* Number of eligible frames before capture overrun */
- delay = otherComponent->bufferSize - delay;
+ delay = otherComponent->alsaBufferSize - delay;
}
- margin = delay - otherComponent->framesPerBuffer / 2;
+ margin = delay - otherComponent->framesPerPeriod / 2;
if( margin < 0 )
{
PA_DEBUG(( "%s: Stopping poll for %s\n", __FUNCTION__, StreamDirection_In == streamDir ? "capture" : "playback" ));
*continuePoll = 0;
}
- else if( margin < otherComponent->framesPerBuffer )
+ else if( margin < otherComponent->framesPerPeriod )
{
*pollTimeout = CalculatePollTimeout( stream, margin );
PA_DEBUG(( "%s: Trying to poll again for %s frames, pollTimeout: %d\n",
else
{
void *bufs[self->numHostChannels];
- int bufsize = alsa_snd_pcm_format_size( self->nativeFormat, self->framesPerBuffer + 1 );
+ int bufsize = alsa_snd_pcm_format_size( self->nativeFormat, self->framesPerPeriod + 1 );
unsigned char *buffer = self->nonMmapBuffer;
int i;
for( i = 0; i < self->numHostChannels; ++i )
{
/* Drop input, a period's worth */
assert( self->capture.ready );
- PaAlsaStreamComponent_EndProcessing( &self->capture, PA_MIN( self->capture.framesPerBuffer,
+ PaAlsaStreamComponent_EndProcessing( &self->capture, PA_MIN( self->capture.framesPerPeriod,
*framesAvail ), &xrun );
*framesAvail = 0;
self->capture.ready = 0;
/* We can't be certain that the whole ring buffer is available for priming, but there should be
* at least one period */
avail = alsa_snd_pcm_avail_update( stream->playback.pcm );
- startThreshold = avail - (avail % stream->playback.framesPerBuffer);
- assert( startThreshold >= stream->playback.framesPerBuffer );
+ startThreshold = avail - (avail % stream->playback.framesPerPeriod);
+ assert( startThreshold >= stream->playback.framesPerPeriod );
}
else
{
/* Frames residing in buffer */
PA_ENSURE( err = GetStreamWriteAvailable( stream ) );
framesAvail = err;
- hwAvail = stream->playback.bufferSize - framesAvail;
+ hwAvail = stream->playback.alsaBufferSize - framesAvail;
if( alsa_snd_pcm_state( stream->playback.pcm ) == SND_PCM_STATE_PREPARED &&
- hwAvail >= stream->playback.framesPerBuffer )
+ hwAvail >= stream->playback.framesPerPeriod )
{
ENSURE_( alsa_snd_pcm_start( stream->playback.pcm ), paUnanticipatedHostError );
}