23,8 → 23,12 |
MPG123_ENC_UNSIGNED_16, |
MPG123_ENC_SIGNED_32, |
MPG123_ENC_UNSIGNED_32, |
MPG123_ENC_SIGNED_24, |
MPG123_ENC_UNSIGNED_24, |
/* Floating point range, see below. */ |
MPG123_ENC_FLOAT_32, |
MPG123_ENC_FLOAT_64, |
/* 8 bit range, see below. */ |
MPG123_ENC_SIGNED_8, |
MPG123_ENC_UNSIGNED_8, |
MPG123_ENC_ULAW_8, |
31,6 → 35,13 |
MPG123_ENC_ALAW_8 |
}; |
|
/* Make that match the above table. |
And yes, I still don't like this kludgy stuff. */ |
/* range[0] <= i < range[1] for forced floating point */ |
static const int enc_float_range[2] = { 6, 8 }; |
/* same for 8 bit encodings */ |
static const int enc_8bit_range[2] = { 8, 12 }; |
|
/* Only one type of float is supported. */ |
# ifdef REAL_IS_FLOAT |
# define MPG123_FLOAT_ENC MPG123_ENC_FLOAT_32 |
48,6 → 59,8 |
#ifndef NO_32BIT |
MPG123_ENC_SIGNED_32, |
MPG123_ENC_UNSIGNED_32, |
MPG123_ENC_SIGNED_24, |
MPG123_ENC_UNSIGNED_24, |
#endif |
#ifndef NO_REAL |
MPG123_FLOAT_ENC, |
84,6 → 97,22 |
if(number != NULL) *number = sizeof(good_encodings)/sizeof(int); |
} |
|
int attribute_align_arg mpg123_encsize(int encoding) |
{ |
if(encoding & MPG123_ENC_8) |
return 1; |
else if(encoding & MPG123_ENC_16) |
return 2; |
else if(encoding & MPG123_ENC_24) |
return 3; |
else if(encoding & MPG123_ENC_32 || encoding == MPG123_ENC_FLOAT_32) |
return 4; |
else if(encoding == MPG123_ENC_FLOAT_64) |
return 8; |
else |
return 0; |
} |
|
/* char audio_caps[NUM_CHANNELS][MPG123_RATES+1][MPG123_ENCODINGS]; */ |
|
static int rate2num(mpg123_pars *mp, long r) |
126,14 → 155,18 |
{ |
nf->rate = frame_freq(fr)>>fr->p.down_sample; |
if(cap_fit(fr,nf,f0,f2)) return 1; |
if(fr->p.flags & MPG123_AUTO_RESAMPLE) |
{ |
nf->rate>>=1; |
if(cap_fit(fr,nf,f0,f2)) return 1; |
nf->rate>>=1; |
if(cap_fit(fr,nf,f0,f2)) return 1; |
} |
#ifndef NO_NTOM |
/* If nothing worked, try the other rates, only without constrains from user. |
In case you didn't guess: We enable flexible resampling if we find a working rate. */ |
if(!fr->p.force_rate && fr->p.down_sample == 0) |
if( fr->p.flags & MPG123_AUTO_RESAMPLE && |
!fr->p.force_rate && fr->p.down_sample == 0) |
{ |
int i; |
int c = nf->channels-1; |
176,13 → 209,13 |
/* All this forcing should be removed in favour of the capabilities table... */ |
if(p->flags & MPG123_FORCE_8BIT) |
{ |
f0 = 6; |
f2 = 10; |
f0 = enc_8bit_range[0]; |
f2 = enc_8bit_range[1]; |
} |
if(p->flags & MPG123_FORCE_FLOAT) |
{ |
f0 = 4; |
f2 = 6; |
f0 = enc_float_range[0]; |
f2 = enc_float_range[1]; |
} |
|
/* force stereo is stronger */ |
254,15 → 287,8 |
fr->af.channels = nf.channels; |
fr->af.encoding = nf.encoding; |
/* Cache the size of one sample in bytes, for ease of use. */ |
if(fr->af.encoding & MPG123_ENC_8) |
fr->af.encsize = 1; |
else if(fr->af.encoding & MPG123_ENC_16) |
fr->af.encsize = 2; |
else if(fr->af.encoding & MPG123_ENC_32 || fr->af.encoding == MPG123_ENC_FLOAT_32) |
fr->af.encsize = 4; |
else if(fr->af.encoding == MPG123_ENC_FLOAT_64) |
fr->af.encsize = 8; |
else |
fr->af.encsize = mpg123_encsize(fr->af.encoding); |
if(fr->af.encsize < 1) |
{ |
if(NOQUIET) error1("Some unknown encoding??? (%i)", fr->af.encoding); |
|
383,6 → 409,15 |
af->channels = 0; |
} |
|
/* Consider 24bit output needing 32bit output as temporary storage. */ |
off_t samples_to_storage(mpg123_handle *fr, off_t s) |
{ |
if(fr->af.encoding & MPG123_ENC_24) |
return s*4*fr->af.channels; /* 4 bytes per sample */ |
else |
return samples_to_bytes(fr, s); |
} |
|
/* take into account: channels, bytes per sample -- NOT resampling!*/ |
off_t samples_to_bytes(mpg123_handle *fr , off_t s) |
{ |
393,3 → 428,94 |
{ |
return b / fr->af.encsize / fr->af.channels; |
} |
|
|
#ifndef NO_32BIT |
/* Remove every fourth byte, facilitating conversion from 32 bit to 24 bit integers. |
This has to be aware of endianness, of course. */ |
static void chop_fourth_byte(struct outbuffer *buf) |
{ |
unsigned char *wpos = buf->data; |
unsigned char *rpos = buf->data; |
#ifdef WORDS_BIGENDIAN |
while((size_t) (rpos - buf->data + 4) <= buf->fill) |
{ |
/* Really stupid: Copy, increment. Byte per byte. */ |
*wpos = *rpos; |
wpos++; rpos++; |
*wpos = *rpos; |
wpos++; rpos++; |
*wpos = *rpos; |
wpos++; rpos++; |
rpos++; /* Skip the lowest byte (last). */ |
} |
#else |
while((size_t) (rpos - buf->data + 4) <= buf->fill) |
{ |
/* Really stupid: Copy, increment. Byte per byte. */ |
rpos++; /* Skip the lowest byte (first). */ |
*wpos = *rpos; |
wpos++; rpos++; |
*wpos = *rpos; |
wpos++; rpos++; |
*wpos = *rpos; |
wpos++; rpos++; |
} |
#endif |
buf->fill = wpos-buf->data; |
} |
#endif |
|
void postprocess_buffer(mpg123_handle *fr) |
{ |
/* Handle unsigned output formats via reshifting after decode here. |
Also handle conversion to 24 bit. */ |
#ifndef NO_32BIT |
if(fr->af.encoding == MPG123_ENC_UNSIGNED_32 || fr->af.encoding == MPG123_ENC_UNSIGNED_24) |
{ /* 32bit signed -> unsigned */ |
size_t i; |
int32_t *ssamples; |
uint32_t *usamples; |
ssamples = (int32_t*)fr->buffer.data; |
usamples = (uint32_t*)fr->buffer.data; |
debug("converting output to unsigned 32 bit integer"); |
for(i=0; i<fr->buffer.fill/sizeof(int32_t); ++i) |
{ |
/* Different strategy since we don't have a larger type at hand. |
Also watch out for silly +-1 fun because integer constants are signed in C90! */ |
if(ssamples[i] >= 0) |
usamples[i] = (uint32_t)ssamples[i] + 2147483647+1; |
/* The smalles value goes zero. */ |
else if(ssamples[i] == ((int32_t)-2147483647-1)) |
usamples[i] = 0; |
/* Now -value is in the positive range of signed int ... so it's a possible value at all. */ |
else |
usamples[i] = (uint32_t)2147483647+1 - (uint32_t)(-ssamples[i]); |
} |
/* Dumb brute force: A second pass for hacking off the last byte. */ |
if(fr->af.encoding == MPG123_ENC_UNSIGNED_24) |
chop_fourth_byte(&fr->buffer); |
} |
else if(fr->af.encoding == MPG123_ENC_SIGNED_24) |
{ |
/* We got 32 bit signed ... chop off for 24 bit signed. */ |
chop_fourth_byte(&fr->buffer); |
} |
#endif |
#ifndef NO_16BIT |
if(fr->af.encoding == MPG123_ENC_UNSIGNED_16) |
{ |
size_t i; |
short *ssamples; |
unsigned short *usamples; |
ssamples = (short*)fr->buffer.data; |
usamples = (unsigned short*)fr->buffer.data; |
debug("converting output to unsigned 16 bit integer"); |
for(i=0; i<fr->buffer.fill/sizeof(short); ++i) |
{ |
long tmp = (long)ssamples[i]+32768; |
usamples[i] = (unsigned short)tmp; |
} |
} |
#endif |
} |