/** * generic linear sample quantize and dither routine * (copied from mpg231, mad.c) * @author Rob Leslie */ static inline qint32 audio_linear_dither(unsigned int bits, mad_fixed_t sample, Kwave::audio_dither *dither) { unsigned int scalebits; mad_fixed_t output, mask, random; enum { MIN = -MAD_F_ONE, MAX = MAD_F_ONE - 1 }; /* noise shape */ sample += dither->error[0] - dither->error[1] + dither->error[2]; dither->error[2] = dither->error[1]; dither->error[1] = dither->error[0] / 2; /* bias */ output = sample + mad_fixed_t(1L << (MAD_F_FRACBITS + 1 - bits - 1)); scalebits = MAD_F_FRACBITS + 1 - bits; mask = mad_fixed_t(1L << scalebits) - 1; /* dither */ random = static_cast<mad_fixed_t>(prng(dither->random)); output += (random & mask) - (dither->random & mask); dither->random = random; /* clip */ if (output > MAX) { output = MAX; if (sample > MAX) sample = MAX; } else if (output < MIN) { output = MIN; if (sample < MIN) sample = MIN; } /* quantize */ output &= ~mask; /* error feedback */ dither->error[0] = sample - output; /* scale */ return output >> scalebits; }
/* * NAME: synth->half() * DESCRIPTION: perform half frequency PCM synthesis */ static void synth_half(struct mad_synth *synth, struct mad_frame /*const*/ *frame, unsigned int nch, unsigned int ns) { unsigned int phase, ch, s, sb, pe, po; short int *pcm1, *pcm2; mad_fixed_t (*filter)[2][2][16][8]; mad_fixed_t (*sbsample)[36][32]; register mad_fixed_t (*fe)[8], (*fx)[8], (*fo)[8]; register mad_fixed_t const (*Dptr)[32], *ptr ; register mad_fixed64hi_t hi; register mad_fixed64lo_t lo; mad_fixed_t raw_sample; static short int short_sample_buff[16]; phase = synth->phase; for (s = 0; s < ns; ++s) { memset (short_sample_buff, 0x00, sizeof(short_sample_buff)); for (ch = 0; ch < nch; ++ch) { sbsample = &frame->sbsample[ch]; filter = &synth->filter[ch]; pcm1 = short_sample_buff; dct32((*sbsample)[s], phase >> 1, (*filter)[0][phase & 1], (*filter)[1][phase & 1]); pe = phase & ~1; po = ((phase - 1) & 0xf) | 1; /* calculate 16 samples */ fe = &(*filter)[0][ phase & 1][0]; fx = &(*filter)[0][~phase & 1][0]; fo = &(*filter)[1][~phase & 1][0]; Dptr = &D[0]; ptr = *Dptr + po; ML0(hi, lo, (*fx)[0], ptr[ 0]); MLA(hi, lo, (*fx)[1], ptr[14]); MLA(hi, lo, (*fx)[2], ptr[12]); MLA(hi, lo, (*fx)[3], ptr[10]); MLA(hi, lo, (*fx)[4], ptr[ 8]); MLA(hi, lo, (*fx)[5], ptr[ 6]); MLA(hi, lo, (*fx)[6], ptr[ 4]); MLA(hi, lo, (*fx)[7], ptr[ 2]); MLN(hi, lo); ptr = *Dptr + pe; MLA(hi, lo, (*fe)[0], ptr[ 0]); MLA(hi, lo, (*fe)[1], ptr[14]); MLA(hi, lo, (*fe)[2], ptr[12]); MLA(hi, lo, (*fe)[3], ptr[10]); MLA(hi, lo, (*fe)[4], ptr[ 8]); MLA(hi, lo, (*fe)[5], ptr[ 6]); MLA(hi, lo, (*fe)[6], ptr[ 4]); MLA(hi, lo, (*fe)[7], ptr[ 2]); raw_sample = SHIFT(MLZ(hi, lo)); raw_sample = scale(raw_sample); (*pcm1++) += (short int)raw_sample; pcm2 = pcm1 + 14; for (sb = 1; sb < 16; ++sb) { ++fe; ++Dptr; /* D[32 - sb][i] == -D[sb][31 - i] */ ptr = *Dptr + po; ML0(hi, lo, (*fo)[0], ptr[ 0]); MLA(hi, lo, (*fo)[1], ptr[14]); MLA(hi, lo, (*fo)[2], ptr[12]); MLA(hi, lo, (*fo)[3], ptr[10]); MLA(hi, lo, (*fo)[4], ptr[ 8]); MLA(hi, lo, (*fo)[5], ptr[ 6]); MLA(hi, lo, (*fo)[6], ptr[ 4]); MLA(hi, lo, (*fo)[7], ptr[ 2]); MLN(hi, lo); ptr = *Dptr + pe; MLA(hi, lo, (*fe)[7], ptr[ 2]); MLA(hi, lo, (*fe)[6], ptr[ 4]); MLA(hi, lo, (*fe)[5], ptr[ 6]); MLA(hi, lo, (*fe)[4], ptr[ 8]); MLA(hi, lo, (*fe)[3], ptr[10]); MLA(hi, lo, (*fe)[2], ptr[12]); MLA(hi, lo, (*fe)[1], ptr[14]); MLA(hi, lo, (*fe)[0], ptr[ 0]); raw_sample = SHIFT(MLZ(hi, lo)); raw_sample = scale(raw_sample); (*pcm1++) += (short int)raw_sample; ptr = *Dptr - pe; ML0(hi, lo, (*fe)[0], ptr[31 - 16]); MLA(hi, lo, (*fe)[1], ptr[31 - 14]); MLA(hi, lo, (*fe)[2], ptr[31 - 12]); MLA(hi, lo, (*fe)[3], ptr[31 - 10]); MLA(hi, lo, (*fe)[4], ptr[31 - 8]); MLA(hi, lo, (*fe)[5], ptr[31 - 6]); MLA(hi, lo, (*fe)[6], ptr[31 - 4]); MLA(hi, lo, (*fe)[7], ptr[31 - 2]); ptr = *Dptr - po; MLA(hi, lo, (*fo)[7], ptr[31 - 2]); MLA(hi, lo, (*fo)[6], ptr[31 - 4]); MLA(hi, lo, (*fo)[5], ptr[31 - 6]); MLA(hi, lo, (*fo)[4], ptr[31 - 8]); MLA(hi, lo, (*fo)[3], ptr[31 - 10]); MLA(hi, lo, (*fo)[2], ptr[31 - 12]); MLA(hi, lo, (*fo)[1], ptr[31 - 14]); MLA(hi, lo, (*fo)[0], ptr[31 - 16]); raw_sample = SHIFT(MLZ(hi, lo)); raw_sample = scale(raw_sample); (*pcm2--) += (short int)raw_sample; ++fo; } Dptr++; ptr = *Dptr + po; ML0(hi, lo, (*fo)[0], ptr[ 0]); MLA(hi, lo, (*fo)[1], ptr[14]); MLA(hi, lo, (*fo)[2], ptr[12]); MLA(hi, lo, (*fo)[3], ptr[10]); MLA(hi, lo, (*fo)[4], ptr[ 8]); MLA(hi, lo, (*fo)[5], ptr[ 6]); MLA(hi, lo, (*fo)[6], ptr[ 4]); MLA(hi, lo, (*fo)[7], ptr[ 2]); raw_sample = SHIFT(-MLZ(hi, lo)); raw_sample = scale(raw_sample); (*pcm1) += (short int)raw_sample; } /* Channel For */ /* Block render */ //--render_sample_block(short_sample_buff, 16); WriteMP3ToBuffer(short_sample_buff,16); phase = (phase + 1) % 16; }/* Block For */ }