[MPG123] Update to version 1.26.1. CORE-17098

This commit is contained in:
Thomas Faber 2020-05-30 21:43:44 +02:00
parent cab7e9ade8
commit aa811c00e3
No known key found for this signature in database
GPG key ID: 076E7C3D44720826
27 changed files with 2163 additions and 710 deletions

View file

@ -1,7 +1,7 @@
/*
format:routines to deal with audio (output) format
format: routines to deal with audio (output) format
copyright 2008-14 by the mpg123 project - free software under the terms of the LGPL 2.1
copyright 2008-20 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Thomas Orgis, starting with parts of the old audio.c, with only faintly manage to show now
@ -26,6 +26,7 @@
*/
#include "mpg123lib_intern.h"
#include "sample.h"
#include "debug.h"
/* static int chans[NUM_CHANNELS] = { 1 , 2 }; */
@ -60,6 +61,10 @@ static const int my_encodings[MPG123_ENCODINGS] =
static const int enc_float_range[2] = { 6, 8 };
/* same for 8 bit encodings */
static const int enc_8bit_range[2] = { 8, 12 };
// for 24 bit quality (24 and 32 bit integers)
static const int enc_24bit_range[2] = { 2, 6 };
// for completeness, the 16 bits
static const int enc_16bit_range[2] = { 0, 2};
/*
Only one type of float is supported.
@ -150,14 +155,14 @@ static int enc2num(int encoding)
return -1;
}
static int cap_fit(mpg123_handle *fr, struct audioformat *nf, int f0, int f2)
static int cap_fit(mpg123_pars *p, struct audioformat *nf, int f0, int f2)
{
int i;
int c = nf->channels-1;
int rn = rate2num(&fr->p, nf->rate);
int rn = rate2num(p, nf->rate);
if(rn >= 0) for(i=f0;i<f2;i++)
{
if(fr->p.audio_caps[c][rn][i])
if(p->audio_caps[c][rn][i])
{
nf->encoding = my_encodings[i];
return 1;
@ -166,48 +171,54 @@ static int cap_fit(mpg123_handle *fr, struct audioformat *nf, int f0, int f2)
return 0;
}
static int freq_fit(mpg123_handle *fr, struct audioformat *nf, int f0, int f2)
static int imin(int a, int b)
{
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.flags & MPG123_AUTO_RESAMPLE &&
!fr->p.force_rate && fr->p.down_sample == 0)
{
int i;
int c = nf->channels-1;
int rn = rate2num(&fr->p, frame_freq(fr));
int rrn;
if(rn < 0) return 0;
/* Try higher rates first. */
for(i=f0;i<f2;i++) for(rrn=rn+1; rrn<MPG123_RATES; ++rrn)
if(fr->p.audio_caps[c][rrn][i])
{
nf->rate = my_rates[rrn];
nf->encoding = my_encodings[i];
return 1;
}
/* Then lower rates. */
for(i=f0;i<f2;i++) for(rrn=rn-1; rrn>=0; --rrn)
if(fr->p.audio_caps[c][rrn][i])
{
nf->rate = my_rates[rrn];
nf->encoding = my_encodings[i];
return 1;
}
}
#endif
return a < b ? a : b;
}
return 0;
static int imax(int a, int b)
{
return a > b ? a : b;
}
// Find a possible encoding with given rate and channel count,
// try differing channel count, too.
// This updates the given format and returns TRUE if an encoding
// was found.
static int enc_chan_fit( mpg123_pars *p, long rate, struct audioformat *nnf
, int f0, int f2, int try_float )
{
#define ENCRANGE(range) imax(f0, range[0]), imin(f2, range[1])
struct audioformat nf = *nnf;
nf.rate = rate;
if(cap_fit(p, &nf, ENCRANGE(enc_16bit_range)))
goto eend;
if(cap_fit(p, &nf, ENCRANGE(enc_24bit_range)))
goto eend;
if(try_float &&
cap_fit(p, &nf, ENCRANGE(enc_float_range)))
goto eend;
if(cap_fit(p, &nf, ENCRANGE(enc_8bit_range)))
goto eend;
/* try again with different stereoness */
if(nf.channels == 2 && !(p->flags & MPG123_FORCE_STEREO)) nf.channels = 1;
else if(nf.channels == 1 && !(p->flags & MPG123_FORCE_MONO)) nf.channels = 2;
if(cap_fit(p, &nf, ENCRANGE(enc_16bit_range)))
goto eend;
if(cap_fit(p, &nf, ENCRANGE(enc_24bit_range)))
goto eend;
if(try_float &&
cap_fit(p, &nf, ENCRANGE(enc_float_range)))
goto eend;
if(cap_fit(p, &nf, ENCRANGE(enc_8bit_range)))
goto eend;
return FALSE;
eend:
*nnf = nf;
return TRUE;
#undef ENCRANGE
}
/* match constraints against supported audio formats, store possible setup in frame
@ -216,12 +227,17 @@ int frame_output_format(mpg123_handle *fr)
{
struct audioformat nf;
int f0=0;
int f2=MPG123_ENCODINGS; /* Omit the 32bit and float encodings. */
int f2=MPG123_ENCODINGS+1; // Include all encodings by default.
mpg123_pars *p = &fr->p;
int try_float = (p->flags & MPG123_FLOAT_FALLBACK) ? 0 : 1;
/* initialize new format, encoding comes later */
nf.channels = fr->stereo;
/* All this forcing should be removed in favour of the capabilities table... */
// I intended the forcing stuff to be weaved into the format support table,
// but this probably will never happen, as this would change library behaviour.
// One could introduce an additional effective format table that takes for
// forcings into account, but that would have to be updated on any flag
// change. Tedious.
if(p->flags & MPG123_FORCE_8BIT)
{
f0 = enc_8bit_range[0];
@ -229,6 +245,7 @@ int frame_output_format(mpg123_handle *fr)
}
if(p->flags & MPG123_FORCE_FLOAT)
{
try_float = 1;
f0 = enc_float_range[0];
f2 = enc_float_range[1];
}
@ -237,52 +254,105 @@ int frame_output_format(mpg123_handle *fr)
if(p->flags & MPG123_FORCE_MONO) nf.channels = 1;
if(p->flags & MPG123_FORCE_STEREO) nf.channels = 2;
// Strategy update: Avoid too early triggering of the NtoM decoder.
// Main target is the native rate, with any encoding.
// Then, native rate with any channel count and any encoding.
// Then, it's down_sample from native rate.
// As last resort: NtoM rate.
// So the priority is 1. rate 2. channels 3. encoding.
// As encodings go, 16 bit is tranditionally preferred as efficient choice.
// Next in line are wider float and integer encodings, then 8 bit as
// last resort.
#ifndef NO_NTOM
if(p->force_rate)
{
nf.rate = p->force_rate;
if(cap_fit(fr,&nf,f0,2)) goto end; /* 16bit encodings */
if(cap_fit(fr,&nf,f0<=2 ? 2 : f0,f2)) goto end; /* 8bit encodings */
if(enc_chan_fit(p, p->force_rate, &nf, f0, f2, try_float))
goto end;
// Keep the order consistent if float is considered fallback only.
if(!try_float &&
enc_chan_fit(p, p->force_rate, &nf, f0, f2, TRUE))
goto end;
/* try again with different stereoness */
if(nf.channels == 2 && !(p->flags & MPG123_FORCE_STEREO)) nf.channels = 1;
else if(nf.channels == 1 && !(p->flags & MPG123_FORCE_MONO)) nf.channels = 2;
if(cap_fit(fr,&nf,f0,2)) goto end; /* 16bit encodings */
if(cap_fit(fr,&nf,f0<=2 ? 2 : f0,f2)) goto end; /* 8bit encodings */
if(NOQUIET)
error3( "Unable to set up output format! Constraints: %s%s%liHz.",
( p->flags & MPG123_FORCE_STEREO ? "stereo, " :
(p->flags & MPG123_FORCE_MONO ? "mono, " : "") ),
(p->flags & MPG123_FORCE_8BIT ? "8bit, " : ""),
p->force_rate );
merror( "Unable to set up output format! Constraints: %s%s%liHz."
, ( p->flags & MPG123_FORCE_STEREO ? "stereo, " :
(p->flags & MPG123_FORCE_MONO ? "mono, " : "") )
, ( p->flags & MPG123_FORCE_FLOAT ? "float, " :
(p->flags & MPG123_FORCE_8BIT ? "8bit, " : "") )
, p->force_rate );
/* if(NOQUIET && p->verbose <= 1) print_capabilities(fr); */
fr->err = MPG123_BAD_OUTFORMAT;
return -1;
}
#endif
if(freq_fit(fr, &nf, f0, 2)) goto end; /* try rates with 16bit */
if(freq_fit(fr, &nf, f0<=2 ? 2 : f0, f2)) goto end; /* ... 8bit */
/* try again with different stereoness */
if(nf.channels == 2 && !(p->flags & MPG123_FORCE_STEREO)) nf.channels = 1;
else if(nf.channels == 1 && !(p->flags & MPG123_FORCE_MONO)) nf.channels = 2;
if(freq_fit(fr, &nf, f0, 2)) goto end; /* try rates with 16bit */
if(freq_fit(fr, &nf, f0<=2 ? 2 : f0, f2)) goto end; /* ... 8bit */
// Native decoder rate first.
if(enc_chan_fit(p, frame_freq(fr)>>p->down_sample, &nf, f0, f2, try_float))
goto end;
// Then downsamplings.
if(p->flags & MPG123_AUTO_RESAMPLE && p->down_sample < 2)
{
if(enc_chan_fit( p, frame_freq(fr)>>(p->down_sample+1), &nf
, f0, f2, try_float ))
goto end;
if(p->down_sample < 1 && enc_chan_fit( p, frame_freq(fr)>>2, &nf
, f0, f2, try_float ))
goto end;
}
// And again the whole deal with float fallback.
if(!try_float)
{
if(enc_chan_fit(p, frame_freq(fr)>>p->down_sample, &nf, f0, f2, TRUE))
goto end;
// Then downsamplings.
if(p->flags & MPG123_AUTO_RESAMPLE && p->down_sample < 2)
{
if(enc_chan_fit( p, frame_freq(fr)>>(p->down_sample+1), &nf
, f0, f2, TRUE ))
goto end;
if(p->down_sample < 1 && enc_chan_fit( p, frame_freq(fr)>>2, &nf
, f0, f2, TRUE ))
goto end;
}
}
#ifndef NO_NTOM
// Try to find any rate that works and resample using NtoM hackery.
if( p->flags & MPG123_AUTO_RESAMPLE && fr->p.down_sample == 0)
{
int i;
int rn = rate2num(p, frame_freq(fr));
int rrn;
if(rn < 0) return 0;
/* Try higher rates first. */
for(rrn=rn+1; rrn<MPG123_RATES; ++rrn)
if(enc_chan_fit(p, my_rates[rrn], &nf, f0, f2, try_float))
goto end;
/* Then lower rates. */
for(i=f0;i<f2;i++) for(rrn=rn-1; rrn>=0; --rrn)
if(enc_chan_fit(p, my_rates[rrn], &nf, f0, f2, try_float))
goto end;
// And again for float fallback.
if(!try_float)
{
/* Try higher rates first. */
for(rrn=rn+1; rrn<MPG123_RATES; ++rrn)
if(enc_chan_fit(p, my_rates[rrn], &nf, f0, f2, TRUE))
goto end;
/* Then lower rates. */
for(i=f0;i<f2;i++) for(rrn=rn-1; rrn>=0; --rrn)
if(enc_chan_fit(p, my_rates[rrn], &nf, f0, f2, TRUE))
goto end;
}
}
#endif
/* Here is the _bad_ end. */
if(NOQUIET)
{
error5( "Unable to set up output format! Constraints: %s%s%li, %li or %liHz.",
( p->flags & MPG123_FORCE_STEREO ? "stereo, " :
(p->flags & MPG123_FORCE_MONO ? "mono, " : "") ),
(p->flags & MPG123_FORCE_8BIT ? "8bit, " : ""),
frame_freq(fr), frame_freq(fr)>>1, frame_freq(fr)>>2 );
}
merror( "Unable to set up output format! Constraints: %s%s%li, %li or %liHz."
, ( p->flags & MPG123_FORCE_STEREO ? "stereo, " :
(p->flags & MPG123_FORCE_MONO ? "mono, " : "") )
, ( p->flags & MPG123_FORCE_FLOAT ? "float, " :
(p->flags & MPG123_FORCE_8BIT ? "8bit, " : "") )
, frame_freq(fr), frame_freq(fr)>>1, frame_freq(fr)>>2 );
/* if(NOQUIET && p->verbose <= 1) print_capabilities(fr); */
fr->err = MPG123_BAD_OUTFORMAT;
@ -305,7 +375,7 @@ end: /* Here is the _good_ end. */
fr->af.encsize = mpg123_encsize(fr->af.encoding);
if(fr->af.encsize < 1)
{
if(NOQUIET) error1("Some unknown encoding??? (%i)", fr->af.encoding);
error1("Some unknown encoding??? (%i)", fr->af.encoding);
fr->err = MPG123_BAD_OUTFORMAT;
return -1;
@ -391,6 +461,17 @@ int attribute_align_arg mpg123_fmt_all(mpg123_pars *mp)
return MPG123_OK;
}
int attribute_align_arg mpg123_format2(mpg123_handle *mh, long rate, int channels, int encodings)
{
int r;
if(mh == NULL) return MPG123_BAD_HANDLE;
r = mpg123_fmt2(&mh->p, rate, channels, encodings);
if(r != MPG123_OK){ mh->err = r; r = MPG123_ERR; }
return r;
}
// Keep old behaviour.
int attribute_align_arg mpg123_format(mpg123_handle *mh, long rate, int channels, int encodings)
{
int r;
@ -401,9 +482,9 @@ int attribute_align_arg mpg123_format(mpg123_handle *mh, long rate, int channels
return r;
}
int attribute_align_arg mpg123_fmt(mpg123_pars *mp, long rate, int channels, int encodings)
int attribute_align_arg mpg123_fmt2(mpg123_pars *mp, long rate, int channels, int encodings)
{
int ie, ic, ratei;
int ie, ic, ratei, r1, r2;
int ch[2] = {0, 1};
if(mp == NULL) return MPG123_BAD_PARS;
if(!(channels & (MPG123_MONO|MPG123_STEREO))) return MPG123_BAD_CHANNEL;
@ -412,10 +493,21 @@ int attribute_align_arg mpg123_fmt(mpg123_pars *mp, long rate, int channels, int
if(!(channels & MPG123_STEREO)) ch[1] = 0; /* {0,0} */
else if(!(channels & MPG123_MONO)) ch[0] = 1; /* {1,1} */
ratei = rate2num(mp, rate);
if(ratei < 0) return MPG123_BAD_RATE;
if(rate)
{
r1 = rate2num(mp, rate);
r2 = r1+1;
}
else
{
r1 = 0;
r2 = MPG123_RATES+1; /* including forced rate */
}
if(r1 < 0) return MPG123_BAD_RATE;
/* now match the encodings */
for(ratei = r1; ratei < r2; ++ratei)
for(ic = 0; ic < 2; ++ic)
{
for(ie = 0; ie < MPG123_ENCODINGS; ++ie)
@ -428,6 +520,14 @@ int attribute_align_arg mpg123_fmt(mpg123_pars *mp, long rate, int channels, int
return MPG123_OK;
}
// Keep old behaviour, error on rate=0.
int attribute_align_arg mpg123_fmt(mpg123_pars *mp, long rate, int channels, int encodings)
{
return (rate == 0)
? MPG123_BAD_RATE
: mpg123_fmt2(mp, rate, channels, encodings);
}
int attribute_align_arg mpg123_format_support(mpg123_handle *mh, long rate, int encoding)
{
if(mh == NULL) return 0;
@ -484,37 +584,17 @@ off_t outblock_bytes(mpg123_handle *fr, off_t s)
}
#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
size_t blocks = buf->fill/4;
size_t i;
for(i=0; i<blocks; ++i,wpos+=3,rpos+=4)
DROP4BYTE(wpos, rpos)
buf->fill = wpos-buf->data;
}
@ -526,18 +606,7 @@ static void conv_s32_to_u32(struct outbuffer *buf)
size_t count = buf->fill/sizeof(int32_t);
for(i=0; i<count; ++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 smallest 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]);
}
usamples[i] = CONV_SU32(ssamples[i]);
}
#endif
@ -559,10 +628,7 @@ static void conv_s16_to_u16(struct outbuffer *buf)
size_t count = buf->fill/sizeof(int16_t);
for(i=0; i<count; ++i)
{
long tmp = (long)ssamples[i]+32768;
usamples[i] = (uint16_t)tmp;
}
usamples[i] = CONV_SU16(ssamples[i]);
}
#ifndef NO_REAL
@ -618,6 +684,18 @@ static void conv_s16_to_s32(struct outbuffer *buf)
#endif
#endif
#include "swap_bytes_impl.h"
void swap_endian(struct outbuffer *buf, int block)
{
size_t count;
if(block >= 2)
{
count = buf->fill/(unsigned int)block;
swap_bytes(buf->data, (size_t)block, count);
}
}
void postprocess_buffer(mpg123_handle *fr)
{
@ -680,4 +758,17 @@ void postprocess_buffer(mpg123_handle *fr)
break;
#endif
}
if(fr->p.flags & MPG123_FORCE_ENDIAN)
{
if(
#ifdef WORDS_BIGENDIAN
!(
#endif
fr->p.flags & MPG123_BIG_ENDIAN
#ifdef WORDS_BIGENDIAN
)
#endif
)
swap_endian(&fr->buffer, mpg123_encsize(fr->af.encoding));
}
}