alsa: fix paSwapEndian applied to non-24bit formats due to incorrect logic of tests

This commit is contained in:
dmitrykos 2012-03-28 16:14:49 +00:00
commit 1526a5bfc7

View file

@ -1534,17 +1534,11 @@ static PaSampleFormat GetAvailableFormats( snd_pcm_t *pcm )
if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S32 ) >= 0 )
available |= paInt32;
#ifdef PA_LITTLE_ENDIAN
if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S24_3LE ) >= 0 )
available |= paInt24;
if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S24_3BE ) >= 0)
available |= (paInt24|paSwapEndian);
#elif defined PA_BIG_ENDIAN
else
if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S24_3BE ) >= 0 )
available |= paInt24;
if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S24_3LE ) >= 0)
available |= (paInt24|paSwapEndian);
#endif
if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S16 ) >= 0 )
available |= paInt16;
@ -1558,6 +1552,34 @@ static PaSampleFormat GetAvailableFormats( snd_pcm_t *pcm )
return available;
}
/* Check if format is available in native endianness, if not apply paSwapEndian flag for futher
processing by Alsa swapping converters.
*/
static void CheckAndApplyEndianSwapToFormat( PaSampleFormat *format, snd_pcm_t *pcm )
{
snd_pcm_hw_params_t *hwParams;
alsa_snd_pcm_hw_params_alloca( &hwParams );
alsa_snd_pcm_hw_params_any( pcm, hwParams );
if( *format & paInt24 )
{
#ifdef PA_LITTLE_ENDIAN
if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S24_3LE ) < 0 )
{
if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S24_3BE ) >= 0 )
*format |= paSwapEndian;
}
#elif defined PA_BIG_ENDIAN
if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S24_3BE ) < 0 )
{
if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S24_3LE ) >= 0 )
*format |= paSwapEndian;
}
#endif
}
}
/* Output to console all formats supported by device */
static void LogAllAvailableFormats( snd_pcm_t *pcm )
{
@ -1801,10 +1823,7 @@ static PaError TestParameters( const PaUtilHostApiRepresentation *hostApi, const
PA_ENSURE( hostFormat = PaUtil_SelectClosestAvailableFormat( PA_ALSA_TO_FORMAT(availableFormats), parameters->sampleFormat ) );
/* Append endiannes conversion flag */
if ( availableFormats & paSwapEndian )
{
hostFormat |= paSwapEndian;
}
CheckAndApplyEndianSwapToFormat( &hostFormat, pcm );
/* Some specific hardware (reported: Audio8 DJ) can fail with assertion during this step. */
ENSURE_( alsa_snd_pcm_hw_params_set_format( pcm, hwParams, Pa2AlsaFormat( hostFormat ) ), paUnanticipatedHostError );
@ -1929,10 +1948,7 @@ static PaError PaAlsaStreamComponent_Initialize( PaAlsaStreamComponent *self, Pa
PA_ENSURE( hostSampleFormat = PaUtil_SelectClosestAvailableFormat( PA_ALSA_TO_FORMAT(availableFormats), userSampleFormat ) );
/* Append endiannes conversion flag */
if ( availableFormats & paSwapEndian )
{
hostSampleFormat |= paSwapEndian;
}
CheckAndApplyEndianSwapToFormat( &hostSampleFormat, self->pcm );
self->hostSampleFormat = hostSampleFormat;
self->nativeFormat = Pa2AlsaFormat( hostSampleFormat );