alsa: fix paSwapEndian applied to non-24bit formats due to incorrect logic of tests
This commit is contained in:
parent
00502bdef0
commit
1526a5bfc7
1 changed files with 84 additions and 68 deletions
|
|
@ -1528,36 +1528,58 @@ static PaSampleFormat GetAvailableFormats( snd_pcm_t *pcm )
|
||||||
|
|
||||||
alsa_snd_pcm_hw_params_any( pcm, hwParams );
|
alsa_snd_pcm_hw_params_any( pcm, hwParams );
|
||||||
|
|
||||||
if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_FLOAT ) >= 0)
|
if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_FLOAT ) >= 0 )
|
||||||
available |= paFloat32;
|
available |= paFloat32;
|
||||||
|
|
||||||
if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S32 ) >= 0)
|
if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S32 ) >= 0 )
|
||||||
available |= paInt32;
|
available |= paInt32;
|
||||||
|
|
||||||
#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_3LE ) >= 0)
|
|
||||||
available |= paInt24;
|
available |= paInt24;
|
||||||
if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S24_3BE ) >= 0)
|
else
|
||||||
available |= (paInt24|paSwapEndian);
|
if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S24_3BE ) >= 0 )
|
||||||
#elif defined PA_BIG_ENDIAN
|
|
||||||
if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S24_3BE ) >= 0)
|
|
||||||
available |= paInt24;
|
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)
|
if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S16 ) >= 0 )
|
||||||
available |= paInt16;
|
available |= paInt16;
|
||||||
|
|
||||||
if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_U8 ) >= 0)
|
if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_U8 ) >= 0 )
|
||||||
available |= paUInt8;
|
available |= paUInt8;
|
||||||
|
|
||||||
if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S8 ) >= 0)
|
if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S8 ) >= 0 )
|
||||||
available |= paInt8;
|
available |= paInt8;
|
||||||
|
|
||||||
return available;
|
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 */
|
/* Output to console all formats supported by device */
|
||||||
static void LogAllAvailableFormats( snd_pcm_t *pcm )
|
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 ) );
|
PA_ENSURE( hostFormat = PaUtil_SelectClosestAvailableFormat( PA_ALSA_TO_FORMAT(availableFormats), parameters->sampleFormat ) );
|
||||||
|
|
||||||
/* Append endiannes conversion flag */
|
/* Append endiannes conversion flag */
|
||||||
if ( availableFormats & paSwapEndian )
|
CheckAndApplyEndianSwapToFormat( &hostFormat, pcm );
|
||||||
{
|
|
||||||
hostFormat |= paSwapEndian;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Some specific hardware (reported: Audio8 DJ) can fail with assertion during this step. */
|
/* 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 );
|
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 ) );
|
PA_ENSURE( hostSampleFormat = PaUtil_SelectClosestAvailableFormat( PA_ALSA_TO_FORMAT(availableFormats), userSampleFormat ) );
|
||||||
|
|
||||||
/* Append endiannes conversion flag */
|
/* Append endiannes conversion flag */
|
||||||
if ( availableFormats & paSwapEndian )
|
CheckAndApplyEndianSwapToFormat( &hostSampleFormat, self->pcm );
|
||||||
{
|
|
||||||
hostSampleFormat |= paSwapEndian;
|
|
||||||
}
|
|
||||||
|
|
||||||
self->hostSampleFormat = hostSampleFormat;
|
self->hostSampleFormat = hostSampleFormat;
|
||||||
self->nativeFormat = Pa2AlsaFormat( hostSampleFormat );
|
self->nativeFormat = Pa2AlsaFormat( hostSampleFormat );
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue