forked from len0rd/rockbox
Encoders: Add a little dithering with the fractional bit for mono mixdowns so faster shifts can be used again instead of division without introducing their own DC offset into the mixed channels.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@12246 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
0abfe9f8ea
commit
d52f2e4bca
4 changed files with 34 additions and 12 deletions
|
|
@ -69,9 +69,10 @@ struct aiff_header aiff_header =
|
||||||
|
|
||||||
/* (*) updated when finalizing file */
|
/* (*) updated when finalizing file */
|
||||||
|
|
||||||
static int num_channels;
|
static int num_channels IBSS_ATTR;
|
||||||
uint32_t sample_rate;
|
static uint32_t sample_rate;
|
||||||
uint32_t enc_size;
|
static uint32_t enc_size;
|
||||||
|
static int32_t err IBSS_ATTR;
|
||||||
|
|
||||||
/* convert unsigned 32 bit value to 80-bit floating point number */
|
/* convert unsigned 32 bit value to 80-bit floating point number */
|
||||||
static void uint32_h_to_ieee754_extended_be(uint8_t f[10], uint32_t l) ICODE_ATTR;
|
static void uint32_h_to_ieee754_extended_be(uint8_t f[10], uint32_t l) ICODE_ATTR;
|
||||||
|
|
@ -240,10 +241,14 @@ static void chunk_to_aiff_format(uint32_t *src, uint32_t *dst)
|
||||||
int32_t lr1, lr2;
|
int32_t lr1, lr2;
|
||||||
|
|
||||||
lr1 = *(*src)++;
|
lr1 = *(*src)++;
|
||||||
lr1 = ((int16_t)lr1 + (lr1 >> 16)) / 2;
|
lr1 = (int16_t)lr1 + (lr1 >> 16) + err;
|
||||||
|
err = lr1 & 1;
|
||||||
|
lr1 >>= 1;
|
||||||
|
|
||||||
lr2 = *(*src)++;
|
lr2 = *(*src)++;
|
||||||
lr2 = ((int16_t)lr2 + (lr2 >> 16)) / 2;
|
lr2 = (int16_t)lr2 + (lr2 >> 16) + err;
|
||||||
|
err = lr2 & 1;
|
||||||
|
lr2 >>= 1;
|
||||||
*(*dst)++ = swap_odd_even_le32((lr1 << 16) | (uint16_t)lr2);
|
*(*dst)++ = swap_odd_even_le32((lr1 << 16) | (uint16_t)lr2);
|
||||||
} /* to_mono */
|
} /* to_mono */
|
||||||
|
|
||||||
|
|
@ -311,6 +316,7 @@ static bool init_encoder(void)
|
||||||
|
|
||||||
sample_rate = inputs.sample_rate;
|
sample_rate = inputs.sample_rate;
|
||||||
num_channels = inputs.num_channels;
|
num_channels = inputs.num_channels;
|
||||||
|
err = 0;
|
||||||
|
|
||||||
/* configure the buffer system */
|
/* configure the buffer system */
|
||||||
params.afmt = AFMT_AIFF;
|
params.afmt = AFMT_AIFF;
|
||||||
|
|
|
||||||
|
|
@ -174,6 +174,7 @@ static unsigned samp_per_frame IBSS_ATTR;
|
||||||
|
|
||||||
static config_t cfg IBSS_ATTR;
|
static config_t cfg IBSS_ATTR;
|
||||||
static char *res_buffer;
|
static char *res_buffer;
|
||||||
|
static int32_t err IBSS_ATTR;
|
||||||
|
|
||||||
static const uint8_t ht_count_const[2][2][16] =
|
static const uint8_t ht_count_const[2][2][16] =
|
||||||
{ { { 1, 5, 4, 5, 6, 5, 4, 4, 7, 3, 6, 0, 7, 2, 3, 1 }, /* table0 */
|
{ { { 1, 5, 4, 5, 6, 5, 4, 4, 7, 3, 6, 0, 7, 2, 3, 1 }, /* table0 */
|
||||||
|
|
@ -2055,7 +2056,9 @@ static void to_mono_mm(void)
|
||||||
inline void to_mono(uint32_t **samp)
|
inline void to_mono(uint32_t **samp)
|
||||||
{
|
{
|
||||||
int32_t lr = **samp;
|
int32_t lr = **samp;
|
||||||
int32_t m = ((int16_t)lr + (lr >> 16)) / 2;
|
int32_t m = (int16_t)lr + (lr >> 16) + err;
|
||||||
|
err = m & 1;
|
||||||
|
m >>= 1;
|
||||||
*(*samp)++ = (m << 16) | (uint16_t)m;
|
*(*samp)++ = (m << 16) | (uint16_t)m;
|
||||||
} /* to_mono */
|
} /* to_mono */
|
||||||
|
|
||||||
|
|
@ -2434,6 +2437,8 @@ static bool enc_init(void)
|
||||||
init_mp3_encoder_engine(inputs.sample_rate, inputs.num_channels,
|
init_mp3_encoder_engine(inputs.sample_rate, inputs.num_channels,
|
||||||
inputs.config);
|
inputs.config);
|
||||||
|
|
||||||
|
err = 0;
|
||||||
|
|
||||||
/* configure the buffer system */
|
/* configure the buffer system */
|
||||||
params.afmt = AFMT_MPA_L3;
|
params.afmt = AFMT_MPA_L3;
|
||||||
params.chunk_size = cfg.byte_per_frame + 1;
|
params.chunk_size = cfg.byte_per_frame + 1;
|
||||||
|
|
|
||||||
|
|
@ -57,9 +57,10 @@ struct riff_header
|
||||||
#define PCM_SAMP_PER_CHUNK 2048
|
#define PCM_SAMP_PER_CHUNK 2048
|
||||||
#define PCM_CHUNK_SIZE (PCM_SAMP_PER_CHUNK*4)
|
#define PCM_CHUNK_SIZE (PCM_SAMP_PER_CHUNK*4)
|
||||||
|
|
||||||
static int num_channels;
|
static int num_channels IBSS_ATTR;
|
||||||
uint32_t sample_rate;
|
static uint32_t sample_rate;
|
||||||
uint32_t enc_size;
|
static uint32_t enc_size;
|
||||||
|
static int32_t err IBSS_ATTR;
|
||||||
|
|
||||||
static const struct riff_header riff_header =
|
static const struct riff_header riff_header =
|
||||||
{
|
{
|
||||||
|
|
@ -229,10 +230,14 @@ static void chunk_to_wav_format(uint32_t *src, uint32_t *dst)
|
||||||
int32_t lr1, lr2;
|
int32_t lr1, lr2;
|
||||||
|
|
||||||
lr1 = *(*src)++;
|
lr1 = *(*src)++;
|
||||||
lr1 = ((int16_t)lr1 + (lr1 >> 16)) / 2;
|
lr1 = (int16_t)lr1 + (lr1 >> 16) + err;
|
||||||
|
err = lr1 & 1;
|
||||||
|
lr1 >>= 1;
|
||||||
|
|
||||||
lr2 = *(*src)++;
|
lr2 = *(*src)++;
|
||||||
lr2 = ((int16_t)lr2 + (lr2 >> 16)) / 2;
|
lr2 = (int16_t)lr2 + (lr2 >> 16) + err;
|
||||||
|
err = lr2 & 1;
|
||||||
|
lr2 >>= 1;
|
||||||
*(*dst)++ = swap_odd_even_be32((lr1 << 16) | (uint16_t)lr2);
|
*(*dst)++ = swap_odd_even_be32((lr1 << 16) | (uint16_t)lr2);
|
||||||
} /* to_mono */
|
} /* to_mono */
|
||||||
|
|
||||||
|
|
@ -300,6 +305,7 @@ static bool init_encoder(void)
|
||||||
|
|
||||||
sample_rate = inputs.sample_rate;
|
sample_rate = inputs.sample_rate;
|
||||||
num_channels = inputs.num_channels;
|
num_channels = inputs.num_channels;
|
||||||
|
err = 0;
|
||||||
|
|
||||||
/* configure the buffer system */
|
/* configure the buffer system */
|
||||||
params.afmt = AFMT_PCM_WAV;
|
params.afmt = AFMT_PCM_WAV;
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,7 @@ static int8_t input_buffer[PCM_CHUNK_SIZE*2] IBSS_ATTR;
|
||||||
static WavpackConfig config IBSS_ATTR;
|
static WavpackConfig config IBSS_ATTR;
|
||||||
static WavpackContext *wpc;
|
static WavpackContext *wpc;
|
||||||
static int32_t data_size, input_size, input_step IBSS_ATTR;
|
static int32_t data_size, input_size, input_step IBSS_ATTR;
|
||||||
|
static int32_t err IBSS_ATTR;
|
||||||
|
|
||||||
static const WavpackMetadataHeader wvpk_mdh =
|
static const WavpackMetadataHeader wvpk_mdh =
|
||||||
{
|
{
|
||||||
|
|
@ -126,7 +127,9 @@ static void chunk_to_int32(int32_t *src)
|
||||||
{
|
{
|
||||||
int32_t t = *(*src)++;
|
int32_t t = *(*src)++;
|
||||||
/* endianness irrelevant */
|
/* endianness irrelevant */
|
||||||
*(*dst)++ = ((int16_t)t + (t >> 16)) / 2;
|
t = (int16_t)t + (t >> 16) + err;
|
||||||
|
err = t & 1;
|
||||||
|
*(*dst)++ = t >> 1;
|
||||||
} /* to_int32 */
|
} /* to_int32 */
|
||||||
|
|
||||||
do
|
do
|
||||||
|
|
@ -364,6 +367,8 @@ static bool init_encoder(void)
|
||||||
if (!WavpackSetConfiguration(wpc, &config, -1))
|
if (!WavpackSetConfiguration(wpc, &config, -1))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
err = 0;
|
||||||
|
|
||||||
/* configure the buffer system */
|
/* configure the buffer system */
|
||||||
params.afmt = AFMT_WAVPACK;
|
params.afmt = AFMT_WAVPACK;
|
||||||
input_size = PCM_CHUNK_SIZE*inputs.num_channels / 2;
|
input_size = PCM_CHUNK_SIZE*inputs.num_channels / 2;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue