1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-02-25 12:23:36 +01:00
2011-02-21 15:25:43 +01:00

772 lines
24 KiB
C

/*
* Copyright (C) 2001-2003 Haavard Kvaalen <havardk@xmms.org>
*
* Licensed under GNU LGPL version 2.
*/
#include <stdlib.h>
#include <stdint.h>
#include "xconvert.h"
// These are adapted from defines in gtypes.h and glibconfig.h
#ifndef FALSE
#define FALSE ( 0 )
#endif
#ifndef TRUE
#define TRUE ( !FALSE )
#endif
# define GUINT16_SWAP_LE_BE( val ) \
( ( uint16_t ) \
( \
( uint16_t ) ( ( uint16_t ) ( val ) >> 8 ) | \
( uint16_t ) ( ( uint16_t ) ( val ) << 8 ) \
) \
)
# define GINT16_SWAP_LE_BE( val ) ( ( int16_t ) GUINT16_SWAP_LE_BE ( val ) )
#ifdef WORDS_BIGENDIAN
# define IS_BIG_ENDIAN TRUE
# define GINT16_TO_BE( val ) ( ( int16_t ) ( val ) )
# define GINT16_FROM_BE( val ) ( ( int16_t ) ( val ) )
# define GUINT16_TO_BE( val ) ( ( uint16_t ) ( val ) )
# define GUINT16_FROM_BE( val ) ( ( uint16_t ) ( val ) )
# define GUINT16_TO_LE( val ) ( GUINT16_SWAP_LE_BE ( val ) )
# define GUINT16_FROM_LE( val ) ( GUINT16_SWAP_LE_BE ( val ) )
# define GINT16_TO_LE( val ) ( ( int16_t ) GUINT16_SWAP_LE_BE ( val ) )
# define GINT16_FROM_LE( val ) ( ( int16_t ) GUINT16_SWAP_LE_BE ( val ) )
#else
# define IS_BIG_ENDIAN FALSE
# define GINT16_TO_LE( val ) ( ( int16_t ) ( val ) )
# define GINT16_FROM_LE( val ) ( ( int16_t ) ( val ) )
# define GUINT16_TO_LE( val ) ( ( uint16_t ) ( val ) )
# define GUINT16_FROM_LE( val ) ( ( uint16_t ) ( val ) )
# define GUINT16_TO_BE( val ) ( GUINT16_SWAP_LE_BE ( val ) )
# define GUINT16_FROM_BE( val ) ( GUINT16_SWAP_LE_BE ( val ) )
# define GINT16_TO_BE( val ) ( ( int16_t ) GUINT16_SWAP_LE_BE ( val ) )
# define GINT16_FROM_BE( val ) ( ( int16_t ) GUINT16_SWAP_LE_BE ( val ) )
#endif
struct buffer {
void *buffer;
uint size;
};
struct xmms_convert_buffers {
struct buffer format_buffer, stereo_buffer, freq_buffer;
};
struct xmms_convert_buffers* xmms_convert_buffers_new( void )
{
return calloc( 1, sizeof( struct xmms_convert_buffers ) );
}
static void* convert_get_buffer( struct buffer *buffer, size_t size )
{
if ( size > 0 && size <= buffer->size )
return buffer->buffer;
buffer->size = size;
buffer->buffer = realloc( buffer->buffer, size );
return buffer->buffer;
}
void xmms_convert_buffers_free( struct xmms_convert_buffers* buf )
{
convert_get_buffer( &buf->format_buffer, 0 );
convert_get_buffer( &buf->stereo_buffer, 0 );
convert_get_buffer( &buf->freq_buffer, 0 );
}
void xmms_convert_buffers_destroy( struct xmms_convert_buffers* buf )
{
if ( !buf )
return;
xmms_convert_buffers_free( buf );
free( buf );
}
static int convert_swap_endian( struct xmms_convert_buffers* buf, void **data, int length )
{
uint16_t *ptr = *data;
int i;
for ( i = 0; i < length; i += 2, ptr++ )
*ptr = GUINT16_SWAP_LE_BE( *ptr );
return i;
}
static int convert_swap_sign_and_endian_to_native( struct xmms_convert_buffers* buf, void **data, int length )
{
uint16_t *ptr = *data;
int i;
for ( i = 0; i < length; i += 2, ptr++ )
*ptr = GUINT16_SWAP_LE_BE( *ptr ) ^ 1 << 15;
return i;
}
static int convert_swap_sign_and_endian_to_alien( struct xmms_convert_buffers* buf, void **data, int length )
{
uint16_t *ptr = *data;
int i;
for ( i = 0; i < length; i += 2, ptr++ )
*ptr = GUINT16_SWAP_LE_BE( *ptr ^ 1 << 15 );
return i;
}
static int convert_swap_sign16( struct xmms_convert_buffers* buf, void **data, int length )
{
int16_t *ptr = *data;
int i;
for ( i = 0; i < length; i += 2, ptr++ )
*ptr ^= 1 << 15;
return i;
}
static int convert_swap_sign8( struct xmms_convert_buffers* buf, void **data, int length )
{
int8_t *ptr = *data;
int i;
for ( i = 0; i < length; i++ )
*ptr++ ^= 1 << 7;
return i;
}
static int convert_to_8_native_endian( struct xmms_convert_buffers* buf, void **data, int length )
{
int8_t *output = *data;
int16_t *input = *data;
int i;
for ( i = 0; i < length / 2; i++ )
*output++ = *input++ >> 8;
return i;
}
static int convert_to_8_native_endian_swap_sign( struct xmms_convert_buffers* buf, void **data, int length )
{
int8_t *output = *data;
int16_t *input = *data;
int i;
for ( i = 0; i < length / 2; i++ )
*output++ = ( *input++ >> 8 ) ^ ( 1 << 7 );
return i;
}
static int convert_to_8_alien_endian( struct xmms_convert_buffers* buf, void **data, int length )
{
int8_t *output = *data;
int16_t *input = *data;
int i;
for ( i = 0; i < length / 2; i++ )
*output++ = *input++ & 0xff;
return i;
}
static int convert_to_8_alien_endian_swap_sign( struct xmms_convert_buffers* buf, void **data, int length )
{
int8_t *output = *data;
int16_t *input = *data;
int i;
for ( i = 0; i < length / 2; i++ )
*output++ = ( *input++ & 0xff ) ^ ( 1 << 7 );
return i;
}
static int convert_to_16_native_endian( struct xmms_convert_buffers* buf, void **data, int length )
{
uint8_t *input = *data;
uint16_t *output;
int i;
*data = convert_get_buffer( &buf->format_buffer, length * 2 );
output = *data;
for ( i = 0; i < length; i++ )
*output++ = *input++ << 8;
return i * 2;
}
static int convert_to_16_native_endian_swap_sign( struct xmms_convert_buffers* buf, void **data, int length )
{
uint8_t *input = *data;
uint16_t *output;
int i;
*data = convert_get_buffer( &buf->format_buffer, length * 2 );
output = *data;
for ( i = 0; i < length; i++ )
*output++ = ( *input++ << 8 ) ^ ( 1 << 15 );
return i * 2;
}
static int convert_to_16_alien_endian( struct xmms_convert_buffers* buf, void **data, int length )
{
uint8_t *input = *data;
uint16_t *output;
int i;
*data = convert_get_buffer( &buf->format_buffer, length * 2 );
output = *data;
for ( i = 0; i < length; i++ )
*output++ = *input++;
return i * 2;
}
static int convert_to_16_alien_endian_swap_sign( struct xmms_convert_buffers* buf, void **data, int length )
{
uint8_t *input = *data;
uint16_t *output;
int i;
*data = convert_get_buffer( &buf->format_buffer, length * 2 );
output = *data;
for ( i = 0; i < length; i++ )
*output++ = *input++ ^ ( 1 << 7 );
return i * 2;
}
static AFormat unnativize( AFormat fmt )
{
if ( fmt == FMT_S16_NE )
{
if ( IS_BIG_ENDIAN )
return FMT_S16_BE;
else
return FMT_S16_LE;
}
if ( fmt == FMT_U16_NE )
{
if ( IS_BIG_ENDIAN )
return FMT_U16_BE;
else
return FMT_U16_LE;
}
return fmt;
}
convert_func_t xmms_convert_get_func( AFormat output, AFormat input )
{
output = unnativize( output );
input = unnativize( input );
if ( output == input )
return NULL;
if ( ( output == FMT_U16_BE && input == FMT_U16_LE ) ||
( output == FMT_U16_LE && input == FMT_U16_BE ) ||
( output == FMT_S16_BE && input == FMT_S16_LE ) ||
( output == FMT_S16_LE && input == FMT_S16_BE ) )
return convert_swap_endian;
if ( ( output == FMT_U16_BE && input == FMT_S16_BE ) ||
( output == FMT_U16_LE && input == FMT_S16_LE ) ||
( output == FMT_S16_BE && input == FMT_U16_BE ) ||
( output == FMT_S16_LE && input == FMT_U16_LE ) )
return convert_swap_sign16;
if ( ( IS_BIG_ENDIAN &&
( ( output == FMT_U16_BE && input == FMT_S16_LE ) ||
( output == FMT_S16_BE && input == FMT_U16_LE ) ) ) ||
( !IS_BIG_ENDIAN &&
( ( output == FMT_U16_LE && input == FMT_S16_BE ) ||
( output == FMT_S16_LE && input == FMT_U16_BE ) ) ) )
return convert_swap_sign_and_endian_to_native;
if ( ( !IS_BIG_ENDIAN &&
( ( output == FMT_U16_BE && input == FMT_S16_LE ) ||
( output == FMT_S16_BE && input == FMT_U16_LE ) ) ) ||
( IS_BIG_ENDIAN &&
( ( output == FMT_U16_LE && input == FMT_S16_BE ) ||
( output == FMT_S16_LE && input == FMT_U16_BE ) ) ) )
return convert_swap_sign_and_endian_to_alien;
if ( ( IS_BIG_ENDIAN &&
( ( output == FMT_U8 && input == FMT_U16_BE ) ||
( output == FMT_S8 && input == FMT_S16_BE ) ) ) ||
( !IS_BIG_ENDIAN &&
( ( output == FMT_U8 && input == FMT_U16_LE ) ||
( output == FMT_S8 && input == FMT_S16_LE ) ) ) )
return convert_to_8_native_endian;
if ( ( IS_BIG_ENDIAN &&
( ( output == FMT_U8 && input == FMT_S16_BE ) ||
( output == FMT_S8 && input == FMT_U16_BE ) ) ) ||
( !IS_BIG_ENDIAN &&
( ( output == FMT_U8 && input == FMT_S16_LE ) ||
( output == FMT_S8 && input == FMT_U16_LE ) ) ) )
return convert_to_8_native_endian_swap_sign;
if ( ( !IS_BIG_ENDIAN &&
( ( output == FMT_U8 && input == FMT_U16_BE ) ||
( output == FMT_S8 && input == FMT_S16_BE ) ) ) ||
( IS_BIG_ENDIAN &&
( ( output == FMT_U8 && input == FMT_U16_LE ) ||
( output == FMT_S8 && input == FMT_S16_LE ) ) ) )
return convert_to_8_alien_endian;
if ( ( !IS_BIG_ENDIAN &&
( ( output == FMT_U8 && input == FMT_S16_BE ) ||
( output == FMT_S8 && input == FMT_U16_BE ) ) ) ||
( IS_BIG_ENDIAN &&
( ( output == FMT_U8 && input == FMT_S16_LE ) ||
( output == FMT_S8 && input == FMT_U16_LE ) ) ) )
return convert_to_8_alien_endian_swap_sign;
if ( ( output == FMT_U8 && input == FMT_S8 ) ||
( output == FMT_S8 && input == FMT_U8 ) )
return convert_swap_sign8;
if ( ( IS_BIG_ENDIAN &&
( ( output == FMT_U16_BE && input == FMT_U8 ) ||
( output == FMT_S16_BE && input == FMT_S8 ) ) ) ||
( !IS_BIG_ENDIAN &&
( ( output == FMT_U16_LE && input == FMT_U8 ) ||
( output == FMT_S16_LE && input == FMT_S8 ) ) ) )
return convert_to_16_native_endian;
if ( ( IS_BIG_ENDIAN &&
( ( output == FMT_U16_BE && input == FMT_S8 ) ||
( output == FMT_S16_BE && input == FMT_U8 ) ) ) ||
( !IS_BIG_ENDIAN &&
( ( output == FMT_U16_LE && input == FMT_S8 ) ||
( output == FMT_S16_LE && input == FMT_U8 ) ) ) )
return convert_to_16_native_endian_swap_sign;
if ( ( !IS_BIG_ENDIAN &&
( ( output == FMT_U16_BE && input == FMT_U8 ) ||
( output == FMT_S16_BE && input == FMT_S8 ) ) ) ||
( IS_BIG_ENDIAN &&
( ( output == FMT_U16_LE && input == FMT_U8 ) ||
( output == FMT_S16_LE && input == FMT_S8 ) ) ) )
return convert_to_16_alien_endian;
if ( ( !IS_BIG_ENDIAN &&
( ( output == FMT_U16_BE && input == FMT_S8 ) ||
( output == FMT_S16_BE && input == FMT_U8 ) ) ) ||
( IS_BIG_ENDIAN &&
( ( output == FMT_U16_LE && input == FMT_S8 ) ||
( output == FMT_S16_LE && input == FMT_U8 ) ) ) )
return convert_to_16_alien_endian_swap_sign;
//g_warning( "Translation needed, but not available.\n"
// "Input: %d; Output %d.", input, output );
return NULL;
}
static int convert_mono_to_stereo( struct xmms_convert_buffers* buf, void **data, int length, int b16 )
{
int i;
void *outbuf = convert_get_buffer( &buf->stereo_buffer, length * 2 );
if ( b16 )
{
uint16_t *output = outbuf, *input = *data;
for ( i = 0; i < length / 2; i++ )
{
*output++ = *input;
*output++ = *input;
input++;
}
}
else
{
uint8_t *output = outbuf, *input = *data;
for ( i = 0; i < length; i++ )
{
*output++ = *input;
*output++ = *input;
input++;
}
}
*data = outbuf;
return length * 2;
}
static int convert_mono_to_stereo_8( struct xmms_convert_buffers* buf, void **data, int length )
{
return convert_mono_to_stereo( buf, data, length, FALSE );
}
static int convert_mono_to_stereo_16( struct xmms_convert_buffers* buf, void **data, int length )
{
return convert_mono_to_stereo( buf, data, length, TRUE );
}
static int convert_stereo_to_mono_u8( struct xmms_convert_buffers* buf, void **data, int length )
{
uint8_t *output = *data, *input = *data;
int i;
for ( i = 0; i < length / 2; i++ )
{
uint16_t tmp;
tmp = *input++;
tmp += *input++;
*output++ = tmp / 2;
}
return length / 2;
}
static int convert_stereo_to_mono_s8( struct xmms_convert_buffers* buf, void **data, int length )
{
int8_t *output = *data, *input = *data;
int i;
for ( i = 0; i < length / 2; i++ )
{
int16_t tmp;
tmp = *input++;
tmp += *input++;
*output++ = tmp / 2;
}
return length / 2;
}
static int convert_stereo_to_mono_u16le( struct xmms_convert_buffers* buf, void **data, int length )
{
uint16_t *output = *data, *input = *data;
int i;
for ( i = 0; i < length / 4; i++ )
{
uint32_t tmp;
uint16_t stmp;
tmp = GUINT16_FROM_LE( *input );
input++;
tmp += GUINT16_FROM_LE( *input );
input++;
stmp = tmp / 2;
*output++ = GUINT16_TO_LE( stmp );
}
return length / 2;
}
static int convert_stereo_to_mono_u16be( struct xmms_convert_buffers* buf, void **data, int length )
{
uint16_t *output = *data, *input = *data;
int i;
for ( i = 0; i < length / 4; i++ )
{
uint32_t tmp;
uint16_t stmp;
tmp = GUINT16_FROM_BE( *input );
input++;
tmp += GUINT16_FROM_BE( *input );
input++;
stmp = tmp / 2;
*output++ = GUINT16_TO_BE( stmp );
}
return length / 2;
}
static int convert_stereo_to_mono_s16le( struct xmms_convert_buffers* buf, void **data, int length )
{
int16_t *output = *data, *input = *data;
int i;
for ( i = 0; i < length / 4; i++ )
{
int32_t tmp;
int16_t stmp;
tmp = GINT16_FROM_LE( *input );
input++;
tmp += GINT16_FROM_LE( *input );
input++;
stmp = tmp / 2;
*output++ = GINT16_TO_LE( stmp );
}
return length / 2;
}
static int convert_stereo_to_mono_s16be( struct xmms_convert_buffers* buf, void **data, int length )
{
int16_t *output = *data, *input = *data;
int i;
for ( i = 0; i < length / 4; i++ )
{
int32_t tmp;
int16_t stmp;
tmp = GINT16_FROM_BE( *input );
input++;
tmp += GINT16_FROM_BE( *input );
input++;
stmp = tmp / 2;
*output++ = GINT16_TO_BE( stmp );
}
return length / 2;
}
convert_channel_func_t xmms_convert_get_channel_func( AFormat fmt, int output, int input )
{
fmt = unnativize( fmt );
if ( output == input )
return NULL;
if ( input == 1 && output == 2 )
switch ( fmt )
{
case FMT_U8:
case FMT_S8:
return convert_mono_to_stereo_8;
case FMT_U16_LE:
case FMT_U16_BE:
case FMT_S16_LE:
case FMT_S16_BE:
return convert_mono_to_stereo_16;
default:
//g_warning( "Unknown format: %d"
// "No conversion available.", fmt );
return NULL;
}
if ( input == 2 && output == 1 )
switch ( fmt )
{
case FMT_U8:
return convert_stereo_to_mono_u8;
case FMT_S8:
return convert_stereo_to_mono_s8;
case FMT_U16_LE:
return convert_stereo_to_mono_u16le;
case FMT_U16_BE:
return convert_stereo_to_mono_u16be;
case FMT_S16_LE:
return convert_stereo_to_mono_s16le;
case FMT_S16_BE:
return convert_stereo_to_mono_s16be;
default:
//g_warning( "Unknown format: %d. "
// "No conversion available.", fmt );
return NULL;
}
//g_warning( "Input has %d channels, soundcard uses %d channels\n"
// "No conversion is available", input, output );
return NULL;
}
#define RESAMPLE_STEREO( sample_type, bswap ) \
do { \
const int shift = sizeof ( sample_type ); \
int i, in_samples, out_samples, x, delta; \
sample_type *inptr = *data, *outptr; \
uint nlen = ( ( ( length >> shift ) * ofreq ) / ifreq ); \
void *nbuf; \
if ( nlen == 0 ) \
break; \
nlen <<= shift; \
if ( bswap ) \
convert_swap_endian( NULL, data, length ); \
nbuf = convert_get_buffer( &buf->freq_buffer, nlen ); \
outptr = nbuf; \
in_samples = length >> shift; \
out_samples = nlen >> shift; \
delta = ( in_samples << 12 ) / out_samples; \
for ( x = 0, i = 0; i < out_samples; i++ ) \
{ \
int x1, frac; \
x1 = ( x >> 12 ) << 12; \
frac = x - x1; \
*outptr++ = \
( ( inptr[( x1 >> 12 ) << 1] * \
( ( 1<<12 ) - frac ) + \
inptr[( ( x1 >> 12 ) + 1 ) << 1] * \
frac ) >> 12 ); \
*outptr++ = \
( ( inptr[( ( x1 >> 12 ) << 1 ) + 1] * \
( ( 1<<12 ) - frac ) + \
inptr[( ( ( x1 >> 12 ) + 1 ) << 1 ) + 1] * \
frac ) >> 12 ); \
x += delta; \
} \
if ( bswap ) \
convert_swap_endian( NULL, &nbuf, nlen ); \
*data = nbuf; \
return nlen; \
} while ( 0 )
#define RESAMPLE_MONO( sample_type, bswap ) \
do { \
const int shift = sizeof ( sample_type ) - 1; \
int i, x, delta, in_samples, out_samples; \
sample_type *inptr = *data, *outptr; \
uint nlen = ( ( ( length >> shift ) * ofreq ) / ifreq ); \
void *nbuf; \
if ( nlen == 0 ) \
break; \
nlen <<= shift; \
if ( bswap ) \
convert_swap_endian( NULL, data, length ); \
nbuf = convert_get_buffer( &buf->freq_buffer, nlen ); \
outptr = nbuf; \
in_samples = length >> shift; \
out_samples = nlen >> shift; \
delta = ( ( length >> shift ) << 12 ) / out_samples; \
for ( x = 0, i = 0; i < out_samples; i++ ) \
{ \
int x1, frac; \
x1 = ( x >> 12 ) << 12; \
frac = x - x1; \
*outptr++ = \
( ( inptr[x1 >> 12] * ( ( 1<<12 ) - frac ) + \
inptr[( x1 >> 12 ) + 1] * frac ) >> 12 ); \
x += delta; \
} \
if ( bswap ) \
convert_swap_endian( NULL, &nbuf, nlen ); \
*data = nbuf; \
return nlen; \
} while ( 0 )
static int convert_resample_stereo_s16ne( struct xmms_convert_buffers* buf, void **data, int length, int ifreq, int ofreq )
{
RESAMPLE_STEREO( int16_t, FALSE );
return 0;
}
static int convert_resample_stereo_s16ae( struct xmms_convert_buffers* buf, void **data, int length, int ifreq, int ofreq )
{
RESAMPLE_STEREO( int16_t, TRUE );
return 0;
}
static int convert_resample_stereo_u16ne( struct xmms_convert_buffers* buf, void **data, int length, int ifreq, int ofreq )
{
RESAMPLE_STEREO( uint16_t, FALSE );
return 0;
}
static int convert_resample_stereo_u16ae( struct xmms_convert_buffers* buf, void **data, int length, int ifreq, int ofreq )
{
RESAMPLE_STEREO( uint16_t, TRUE );
return 0;
}
static int convert_resample_mono_s16ne( struct xmms_convert_buffers* buf, void **data, int length, int ifreq, int ofreq )
{
RESAMPLE_MONO( int16_t, FALSE );
return 0;
}
static int convert_resample_mono_s16ae( struct xmms_convert_buffers* buf, void **data, int length, int ifreq, int ofreq )
{
RESAMPLE_MONO( int16_t, TRUE );
return 0;
}
static int convert_resample_mono_u16ne( struct xmms_convert_buffers* buf, void **data, int length, int ifreq, int ofreq )
{
RESAMPLE_MONO( uint16_t, FALSE );
return 0;
}
static int convert_resample_mono_u16ae( struct xmms_convert_buffers* buf, void **data, int length, int ifreq, int ofreq )
{
RESAMPLE_MONO( uint16_t, TRUE );
return 0;
}
static int convert_resample_stereo_u8( struct xmms_convert_buffers* buf, void **data, int length, int ifreq, int ofreq )
{
RESAMPLE_STEREO( uint8_t, FALSE );
return 0;
}
static int convert_resample_mono_u8( struct xmms_convert_buffers* buf, void **data, int length, int ifreq, int ofreq )
{
RESAMPLE_MONO( uint8_t, FALSE );
return 0;
}
static int convert_resample_stereo_s8( struct xmms_convert_buffers* buf, void **data, int length, int ifreq, int ofreq )
{
RESAMPLE_STEREO( int8_t, FALSE );
return 0;
}
static int convert_resample_mono_s8( struct xmms_convert_buffers* buf, void **data, int length, int ifreq, int ofreq )
{
RESAMPLE_MONO( int8_t, FALSE );
return 0;
}
convert_freq_func_t xmms_convert_get_frequency_func( AFormat fmt, int channels )
{
fmt = unnativize( fmt );
//g_message( "fmt %d, channels: %d", fmt, channels );
if ( channels < 1 || channels > 2 )
{
//g_warning( "Unsupported number of channels: %d. "
// "Resample function not available", channels );
return NULL;
}
if ( ( IS_BIG_ENDIAN && fmt == FMT_U16_BE ) ||
( !IS_BIG_ENDIAN && fmt == FMT_U16_LE ) )
{
if ( channels == 1 )
return convert_resample_mono_u16ne;
else
return convert_resample_stereo_u16ne;
}
if ( ( IS_BIG_ENDIAN && fmt == FMT_S16_BE ) ||
( !IS_BIG_ENDIAN && fmt == FMT_S16_LE ) )
{
if ( channels == 1 )
return convert_resample_mono_s16ne;
else
return convert_resample_stereo_s16ne;
}
if ( ( !IS_BIG_ENDIAN && fmt == FMT_U16_BE ) ||
( IS_BIG_ENDIAN && fmt == FMT_U16_LE ) )
{
if ( channels == 1 )
return convert_resample_mono_u16ae;
else
return convert_resample_stereo_u16ae;
}
if ( ( !IS_BIG_ENDIAN && fmt == FMT_S16_BE ) ||
( IS_BIG_ENDIAN && fmt == FMT_S16_LE ) )
{
if ( channels == 1 )
return convert_resample_mono_s16ae;
else
return convert_resample_stereo_s16ae;
}
if ( fmt == FMT_U8 )
{
if ( channels == 1 )
return convert_resample_mono_u8;
else
return convert_resample_stereo_u8;
}
if ( fmt == FMT_S8 )
{
if ( channels == 1 )
return convert_resample_mono_s8;
else
return convert_resample_stereo_s8;
}
//g_warning( "Resample function not available"
// "Format %d.", fmt );
return NULL;
}