forked from len0rd/rockbox
Commit FS#9318 - MP3 synthesis filter on COP. Loads the MP3 synth filer on to the CoProcessor on all PortalPlayer devices, resulting in an ~90% speedup according to test_codec on the Sansa. Real world improvement is somewhat less, but still considerable. Allows MP3 decoding at 30MHz without boosting, or use of more DSP/EQ with less boosting/skipping, thus improving battery life. Minor changes to mpegplayer to retain compatibility with libmad changes. Should be no significant changes for other targets or codecs.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@18557 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
3d0d6d6bb2
commit
4e36a2b991
9 changed files with 180 additions and 32 deletions
|
@ -31,6 +31,7 @@
|
||||||
# include "timer.h"
|
# include "timer.h"
|
||||||
# include "layer12.h"
|
# include "layer12.h"
|
||||||
# include "layer3.h"
|
# include "layer3.h"
|
||||||
|
# include "../lib/codeclib.h"
|
||||||
|
|
||||||
static
|
static
|
||||||
unsigned long const bitrate_table[5][15] = {
|
unsigned long const bitrate_table[5][15] = {
|
||||||
|
@ -468,6 +469,8 @@ int mad_frame_decode(struct mad_frame *frame, struct mad_stream *stream)
|
||||||
mad_bit_finish(&next_frame);
|
mad_bit_finish(&next_frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
@ -485,8 +488,8 @@ void mad_frame_mute(struct mad_frame *frame)
|
||||||
|
|
||||||
for (s = 0; s < 36; ++s) {
|
for (s = 0; s < 36; ++s) {
|
||||||
for (sb = 0; sb < 32; ++sb) {
|
for (sb = 0; sb < 32; ++sb) {
|
||||||
frame->sbsample[0][s][sb] =
|
(*frame->sbsample)[0][s][sb] =
|
||||||
frame->sbsample[1][s][sb] = 0;
|
(*frame->sbsample)[1][s][sb] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -66,10 +66,13 @@ struct mad_header {
|
||||||
|
|
||||||
struct mad_frame {
|
struct mad_frame {
|
||||||
struct mad_header header; /* MPEG audio header */
|
struct mad_header header; /* MPEG audio header */
|
||||||
|
|
||||||
int options; /* decoding options (from stream) */
|
int options; /* decoding options (from stream) */
|
||||||
|
|
||||||
mad_fixed_t sbsample[2][36][32]; /* synthesis subband filter samples */
|
mad_fixed_t (*sbsample)[2][36][32]; /* synthesis subband filter samples */
|
||||||
|
mad_fixed_t (*sbsample_prev)[2][36][32]; /* synthesis subband filter samples
|
||||||
|
from previous frame only needed
|
||||||
|
when synthesis is on cop */
|
||||||
|
|
||||||
mad_fixed_t (*overlap)[2][32][18]; /* Layer III block overlap data */
|
mad_fixed_t (*overlap)[2][32][18]; /* Layer III block overlap data */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -185,7 +185,7 @@ int mad_layer_I(struct mad_stream *stream, struct mad_frame *frame)
|
||||||
for (sb = 0; sb < bound; ++sb) {
|
for (sb = 0; sb < bound; ++sb) {
|
||||||
for (ch = 0; ch < nch; ++ch) {
|
for (ch = 0; ch < nch; ++ch) {
|
||||||
nb = allocation[ch][sb];
|
nb = allocation[ch][sb];
|
||||||
frame->sbsample[ch][s][sb] = nb ?
|
(*frame->sbsample)[ch][s][sb] = nb ?
|
||||||
mad_f_mul(I_sample(&stream->ptr, nb),
|
mad_f_mul(I_sample(&stream->ptr, nb),
|
||||||
sf_table[scalefactor[ch][sb]]) : 0;
|
sf_table[scalefactor[ch][sb]]) : 0;
|
||||||
}
|
}
|
||||||
|
@ -198,13 +198,13 @@ int mad_layer_I(struct mad_stream *stream, struct mad_frame *frame)
|
||||||
sample = I_sample(&stream->ptr, nb);
|
sample = I_sample(&stream->ptr, nb);
|
||||||
|
|
||||||
for (ch = 0; ch < nch; ++ch) {
|
for (ch = 0; ch < nch; ++ch) {
|
||||||
frame->sbsample[ch][s][sb] =
|
(*frame->sbsample)[ch][s][sb] =
|
||||||
mad_f_mul(sample, sf_table[scalefactor[ch][sb]]);
|
mad_f_mul(sample, sf_table[scalefactor[ch][sb]]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for (ch = 0; ch < nch; ++ch)
|
for (ch = 0; ch < nch; ++ch)
|
||||||
frame->sbsample[ch][s][sb] = 0;
|
(*frame->sbsample)[ch][s][sb] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -492,13 +492,13 @@ int mad_layer_II(struct mad_stream *stream, struct mad_frame *frame)
|
||||||
II_samples(&stream->ptr, &qc_table[index], samples);
|
II_samples(&stream->ptr, &qc_table[index], samples);
|
||||||
|
|
||||||
for (s = 0; s < 3; ++s) {
|
for (s = 0; s < 3; ++s) {
|
||||||
frame->sbsample[ch][3 * gr + s][sb] =
|
(*frame->sbsample)[ch][3 * gr + s][sb] =
|
||||||
mad_f_mul(samples[s], sf_table[scalefactor[ch][sb][gr / 4]]);
|
mad_f_mul(samples[s], sf_table[scalefactor[ch][sb][gr / 4]]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for (s = 0; s < 3; ++s)
|
for (s = 0; s < 3; ++s)
|
||||||
frame->sbsample[ch][3 * gr + s][sb] = 0;
|
(*frame->sbsample)[ch][3 * gr + s][sb] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -512,7 +512,7 @@ int mad_layer_II(struct mad_stream *stream, struct mad_frame *frame)
|
||||||
|
|
||||||
for (ch = 0; ch < nch; ++ch) {
|
for (ch = 0; ch < nch; ++ch) {
|
||||||
for (s = 0; s < 3; ++s) {
|
for (s = 0; s < 3; ++s) {
|
||||||
frame->sbsample[ch][3 * gr + s][sb] =
|
(*frame->sbsample)[ch][3 * gr + s][sb] =
|
||||||
mad_f_mul(samples[s], sf_table[scalefactor[ch][sb][gr / 4]]);
|
mad_f_mul(samples[s], sf_table[scalefactor[ch][sb][gr / 4]]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -520,7 +520,7 @@ int mad_layer_II(struct mad_stream *stream, struct mad_frame *frame)
|
||||||
else {
|
else {
|
||||||
for (ch = 0; ch < nch; ++ch) {
|
for (ch = 0; ch < nch; ++ch) {
|
||||||
for (s = 0; s < 3; ++s)
|
for (s = 0; s < 3; ++s)
|
||||||
frame->sbsample[ch][3 * gr + s][sb] = 0;
|
(*frame->sbsample)[ch][3 * gr + s][sb] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -528,7 +528,7 @@ int mad_layer_II(struct mad_stream *stream, struct mad_frame *frame)
|
||||||
for (ch = 0; ch < nch; ++ch) {
|
for (ch = 0; ch < nch; ++ch) {
|
||||||
for (s = 0; s < 3; ++s) {
|
for (s = 0; s < 3; ++s) {
|
||||||
for (sb = sblimit; sb < 32; ++sb)
|
for (sb = sblimit; sb < 32; ++sb)
|
||||||
frame->sbsample[ch][3 * gr + s][sb] = 0;
|
(*frame->sbsample)[ch][3 * gr + s][sb] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3112,7 +3112,7 @@ enum mad_error III_decode(struct mad_bitptr *ptr, struct mad_frame *frame,
|
||||||
|
|
||||||
for (ch = 0; ch < nch; ++ch) {
|
for (ch = 0; ch < nch; ++ch) {
|
||||||
struct channel const *channel = &granule->ch[ch];
|
struct channel const *channel = &granule->ch[ch];
|
||||||
mad_fixed_t (*sample)[32] = &frame->sbsample[ch][18 * gr];
|
mad_fixed_t (*sample)[32] = &((*frame->sbsample)[ch][18 * gr]);
|
||||||
unsigned int sb, l, i, sblimit;
|
unsigned int sb, l, i, sblimit;
|
||||||
mad_fixed_t output[36];
|
mad_fixed_t output[36];
|
||||||
|
|
||||||
|
|
|
@ -777,10 +777,13 @@ struct mad_header {
|
||||||
|
|
||||||
struct mad_frame {
|
struct mad_frame {
|
||||||
struct mad_header header; /* MPEG audio header */
|
struct mad_header header; /* MPEG audio header */
|
||||||
|
|
||||||
int options; /* decoding options (from stream) */
|
int options; /* decoding options (from stream) */
|
||||||
|
|
||||||
mad_fixed_t sbsample[2][36][32]; /* synthesis subband filter samples */
|
mad_fixed_t (*sbsample)[2][36][32]; /* synthesis subband filter samples */
|
||||||
|
mad_fixed_t (*sbsample_prev)[2][36][32]; /* synthesis subband filter samples
|
||||||
|
from previous frame only needed
|
||||||
|
when synthesis is on cop */
|
||||||
|
|
||||||
mad_fixed_t (*overlap)[2][32][18]; /* Layer III block overlap data */
|
mad_fixed_t (*overlap)[2][32][18]; /* Layer III block overlap data */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -592,14 +592,14 @@ void synth_full(struct mad_synth *synth, struct mad_frame const *frame,
|
||||||
int sb;
|
int sb;
|
||||||
unsigned int phase, ch, s, p;
|
unsigned int phase, ch, s, p;
|
||||||
mad_fixed_t *pcm, (*filter)[2][2][16][8];
|
mad_fixed_t *pcm, (*filter)[2][2][16][8];
|
||||||
mad_fixed_t const (*sbsample)[36][32];
|
mad_fixed_t (*sbsample)[36][32];
|
||||||
mad_fixed_t (*fe)[8], (*fx)[8], (*fo)[8];
|
mad_fixed_t (*fe)[8], (*fx)[8], (*fo)[8];
|
||||||
mad_fixed_t const (*D0ptr)[32];
|
mad_fixed_t const (*D0ptr)[32];
|
||||||
mad_fixed_t const (*D1ptr)[32];
|
mad_fixed_t const (*D1ptr)[32];
|
||||||
mad_fixed64hi_t hi0, hi1;
|
mad_fixed64hi_t hi0, hi1;
|
||||||
|
|
||||||
for (ch = 0; ch < nch; ++ch) {
|
for (ch = 0; ch < nch; ++ch) {
|
||||||
sbsample = &frame->sbsample[ch];
|
sbsample = &*frame->sbsample_prev[ch];
|
||||||
filter = &synth->filter[ch];
|
filter = &synth->filter[ch];
|
||||||
phase = synth->phase;
|
phase = synth->phase;
|
||||||
pcm = synth->pcm.samples[ch];
|
pcm = synth->pcm.samples[ch];
|
||||||
|
@ -1053,7 +1053,7 @@ void synth_full(struct mad_synth *synth, struct mad_frame const *frame,
|
||||||
int p;
|
int p;
|
||||||
unsigned int phase, ch, s;
|
unsigned int phase, ch, s;
|
||||||
mad_fixed_t *pcm, (*filter)[2][2][16][8];
|
mad_fixed_t *pcm, (*filter)[2][2][16][8];
|
||||||
mad_fixed_t const (*sbsample)[36][32];
|
mad_fixed_t (*sbsample)[36][32];
|
||||||
mad_fixed_t (*fe)[8], (*fx)[8], (*fo)[8];
|
mad_fixed_t (*fe)[8], (*fx)[8], (*fo)[8];
|
||||||
mad_fixed_t const (*D0ptr)[32], *ptr;
|
mad_fixed_t const (*D0ptr)[32], *ptr;
|
||||||
mad_fixed_t const (*D1ptr)[32];
|
mad_fixed_t const (*D1ptr)[32];
|
||||||
|
@ -1061,7 +1061,7 @@ void synth_full(struct mad_synth *synth, struct mad_frame const *frame,
|
||||||
mad_fixed64lo_t lo;
|
mad_fixed64lo_t lo;
|
||||||
|
|
||||||
for (ch = 0; ch < nch; ++ch) {
|
for (ch = 0; ch < nch; ++ch) {
|
||||||
sbsample = &frame->sbsample[ch];
|
sbsample = &(*frame->sbsample_prev)[ch];
|
||||||
filter = &synth->filter[ch];
|
filter = &synth->filter[ch];
|
||||||
phase = synth->phase;
|
phase = synth->phase;
|
||||||
pcm = synth->pcm.samples[ch];
|
pcm = synth->pcm.samples[ch];
|
||||||
|
@ -1202,7 +1202,7 @@ void synth_full(struct mad_synth *synth, struct mad_frame const *frame,
|
||||||
mad_fixed64lo_t lo;
|
mad_fixed64lo_t lo;
|
||||||
|
|
||||||
for (ch = 0; ch < nch; ++ch) {
|
for (ch = 0; ch < nch; ++ch) {
|
||||||
sbsample = &frame->sbsample[ch];
|
sbsample = &frame->sbsample_prev[ch];
|
||||||
filter = &synth->filter[ch];
|
filter = &synth->filter[ch];
|
||||||
phase = synth->phase;
|
phase = synth->phase;
|
||||||
pcm = synth->pcm.samples[ch];
|
pcm = synth->pcm.samples[ch];
|
||||||
|
@ -1403,14 +1403,14 @@ void synth_half(struct mad_synth *synth, struct mad_frame const *frame,
|
||||||
{
|
{
|
||||||
unsigned int phase, ch, s, sb, pe, po;
|
unsigned int phase, ch, s, sb, pe, po;
|
||||||
mad_fixed_t *pcm1, *pcm2, (*filter)[2][2][16][8];
|
mad_fixed_t *pcm1, *pcm2, (*filter)[2][2][16][8];
|
||||||
mad_fixed_t const (*sbsample)[36][32];
|
mad_fixed_t (*sbsample)[36][32];
|
||||||
register mad_fixed_t (*fe)[8], (*fx)[8], (*fo)[8];
|
register mad_fixed_t (*fe)[8], (*fx)[8], (*fo)[8];
|
||||||
register mad_fixed_t const (*Dptr)[32], *ptr;
|
register mad_fixed_t const (*Dptr)[32], *ptr;
|
||||||
register mad_fixed64hi_t hi;
|
register mad_fixed64hi_t hi;
|
||||||
register mad_fixed64lo_t lo;
|
register mad_fixed64lo_t lo;
|
||||||
|
|
||||||
for (ch = 0; ch < nch; ++ch) {
|
for (ch = 0; ch < nch; ++ch) {
|
||||||
sbsample = &frame->sbsample[ch];
|
sbsample = &(*frame->sbsample_prev)[ch];
|
||||||
filter = &synth->filter[ch];
|
filter = &synth->filter[ch];
|
||||||
phase = synth->phase;
|
phase = synth->phase;
|
||||||
pcm1 = synth->pcm.samples[ch];
|
pcm1 = synth->pcm.samples[ch];
|
||||||
|
|
|
@ -25,13 +25,34 @@
|
||||||
|
|
||||||
CODEC_HEADER
|
CODEC_HEADER
|
||||||
|
|
||||||
|
#if (CONFIG_CPU == PP5024 || CONFIG_CPU == PP5022 || CONFIG_CPU == PP5020 \
|
||||||
|
|| CONFIG_CPU == PP5002) && !defined(MPEGPLAYER)
|
||||||
|
#define MPA_SYNTH_ON_COP
|
||||||
|
#endif
|
||||||
|
|
||||||
struct mad_stream stream IBSS_ATTR;
|
struct mad_stream stream IBSS_ATTR;
|
||||||
struct mad_frame frame IBSS_ATTR;
|
struct mad_frame frame IBSS_ATTR;
|
||||||
struct mad_synth synth IBSS_ATTR;
|
struct mad_synth synth IBSS_ATTR;
|
||||||
|
|
||||||
|
#ifdef MPA_SYNTH_ON_COP
|
||||||
|
volatile short synth_running IBSS_ATTR; /*synthesis is running*/
|
||||||
|
volatile short die IBSS_ATTR; /*thread should die*/
|
||||||
|
|
||||||
|
#if (CONFIG_CPU == PP5024) || (CONFIG_CPU == PP5022)
|
||||||
|
mad_fixed_t sbsample_prev[2][36][32] IBSS_ATTR;
|
||||||
|
#else
|
||||||
|
mad_fixed_t sbsample_prev[2][36][32] SHAREDBSS_ATTR;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct semaphore synth_done_sem IBSS_ATTR;
|
||||||
|
struct semaphore synth_pending_sem IBSS_ATTR;
|
||||||
|
#endif
|
||||||
|
|
||||||
#define INPUT_CHUNK_SIZE 8192
|
#define INPUT_CHUNK_SIZE 8192
|
||||||
|
|
||||||
mad_fixed_t mad_frame_overlap[2][32][18] IBSS_ATTR;
|
mad_fixed_t mad_frame_overlap[2][32][18] IBSS_ATTR;
|
||||||
|
mad_fixed_t sbsample[2][36][32] IBSS_ATTR;
|
||||||
|
|
||||||
unsigned char mad_main_data[MAD_BUFFER_MDLEN] IBSS_ATTR;
|
unsigned char mad_main_data[MAD_BUFFER_MDLEN] IBSS_ATTR;
|
||||||
/* TODO: what latency does layer 1 have? */
|
/* TODO: what latency does layer 1 have? */
|
||||||
int mpeg_latency[3] = { 0, 481, 529 };
|
int mpeg_latency[3] = { 0, 481, 529 };
|
||||||
|
@ -43,6 +64,14 @@ void init_mad(void)
|
||||||
ci->memset(&frame, 0, sizeof(struct mad_frame));
|
ci->memset(&frame, 0, sizeof(struct mad_frame));
|
||||||
ci->memset(&synth, 0, sizeof(struct mad_synth));
|
ci->memset(&synth, 0, sizeof(struct mad_synth));
|
||||||
|
|
||||||
|
#ifdef MPA_SYNTH_ON_COP
|
||||||
|
frame.sbsample_prev = &sbsample_prev;
|
||||||
|
#else
|
||||||
|
frame.sbsample_prev = &sbsample;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
frame.sbsample=&sbsample;
|
||||||
|
|
||||||
mad_stream_init(&stream);
|
mad_stream_init(&stream);
|
||||||
mad_frame_init(&frame);
|
mad_frame_init(&frame);
|
||||||
mad_synth_init(&synth);
|
mad_synth_init(&synth);
|
||||||
|
@ -51,6 +80,8 @@ void init_mad(void)
|
||||||
ci->memset(mad_frame_overlap, 0, sizeof(mad_frame_overlap));
|
ci->memset(mad_frame_overlap, 0, sizeof(mad_frame_overlap));
|
||||||
frame.overlap = &mad_frame_overlap;
|
frame.overlap = &mad_frame_overlap;
|
||||||
stream.main_data = &mad_main_data;
|
stream.main_data = &mad_main_data;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_file_pos(int newtime)
|
int get_file_pos(int newtime)
|
||||||
|
@ -159,6 +190,90 @@ static void set_elapsed(struct mp3entry* id3)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MPA_SYNTH_ON_COP
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Run the synthesis filter on the COProcessor
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int mad_synth_thread_stack[DEFAULT_STACK_SIZE/sizeof(int)/2] IBSS_ATTR;
|
||||||
|
|
||||||
|
static const unsigned char * const mad_synth_thread_name = "mp3dec";
|
||||||
|
static struct thread_entry *mad_synth_thread_p;
|
||||||
|
|
||||||
|
|
||||||
|
static void mad_synth_thread(void){
|
||||||
|
|
||||||
|
while(1){
|
||||||
|
ci->semaphore_wait(&synth_pending_sem);
|
||||||
|
|
||||||
|
if(die){
|
||||||
|
die=0;
|
||||||
|
invalidate_icache();
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
synth_running = 1;
|
||||||
|
mad_synth_frame(&synth, &frame);
|
||||||
|
synth_running = 0;
|
||||||
|
ci->semaphore_release(&synth_done_sem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int mad_synth_thread_wait_pcm(void){
|
||||||
|
ci->semaphore_wait(&synth_done_sem);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mad_synth_thread_ready(void){
|
||||||
|
mad_fixed_t (*temp)[2][36][32];
|
||||||
|
while(1){
|
||||||
|
/*check if synth is currently running before changing its inputs! */
|
||||||
|
if(!synth_running){
|
||||||
|
/*circular buffer that holds 2 frames' samples*/
|
||||||
|
temp=frame.sbsample;
|
||||||
|
frame.sbsample = frame.sbsample_prev;
|
||||||
|
frame.sbsample_prev=temp;
|
||||||
|
|
||||||
|
ci->semaphore_release(&synth_pending_sem);
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
ci->yield(); /*synth thread currently running, wait for it*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mad_synth_thread_create(void){
|
||||||
|
synth_running=0;
|
||||||
|
die=0;
|
||||||
|
|
||||||
|
ci->semaphore_init(&synth_done_sem, 1, 0);
|
||||||
|
ci->semaphore_init(&synth_pending_sem, 1, 0);
|
||||||
|
|
||||||
|
mad_synth_thread_p = ci->create_thread(mad_synth_thread,
|
||||||
|
mad_synth_thread_stack,
|
||||||
|
sizeof(mad_synth_thread_stack), 0,
|
||||||
|
mad_synth_thread_name
|
||||||
|
IF_PRIO(, PRIORITY_PLAYBACK), COP);
|
||||||
|
|
||||||
|
if (mad_synth_thread_p == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static void mad_synth_thread_ready(void){
|
||||||
|
mad_synth_frame(&synth, &frame);
|
||||||
|
}
|
||||||
|
static int mad_synth_thread_create(void){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
static int mad_synth_thread_wait_pcm(void){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/* this is the codec entry point */
|
/* this is the codec entry point */
|
||||||
enum codec_status codec_main(void)
|
enum codec_status codec_main(void)
|
||||||
{
|
{
|
||||||
|
@ -182,6 +297,10 @@ enum codec_status codec_main(void)
|
||||||
ci->configure(DSP_SET_SAMPLE_DEPTH, MAD_F_FRACBITS);
|
ci->configure(DSP_SET_SAMPLE_DEPTH, MAD_F_FRACBITS);
|
||||||
|
|
||||||
next_track:
|
next_track:
|
||||||
|
|
||||||
|
/*does nothing on 1 processor systems*/
|
||||||
|
mad_synth_thread_create();
|
||||||
|
|
||||||
status = CODEC_OK;
|
status = CODEC_OK;
|
||||||
|
|
||||||
/* Reinitializing seems to be necessary to avoid playback quircks when seeking. */
|
/* Reinitializing seems to be necessary to avoid playback quircks when seeking. */
|
||||||
|
@ -300,6 +419,9 @@ next_track:
|
||||||
data (not the one just decoded above). When we exit the decoding
|
data (not the one just decoded above). When we exit the decoding
|
||||||
loop we will need to process the final frame that was decoded. */
|
loop we will need to process the final frame that was decoded. */
|
||||||
if (framelength > 0) {
|
if (framelength > 0) {
|
||||||
|
|
||||||
|
mad_synth_thread_wait_pcm();
|
||||||
|
|
||||||
/* In case of a mono file, the second array will be ignored. */
|
/* In case of a mono file, the second array will be ignored. */
|
||||||
ci->pcmbuf_insert(&synth.pcm.samples[0][samples_to_skip],
|
ci->pcmbuf_insert(&synth.pcm.samples[0][samples_to_skip],
|
||||||
&synth.pcm.samples[1][samples_to_skip],
|
&synth.pcm.samples[1][samples_to_skip],
|
||||||
|
@ -309,7 +431,8 @@ next_track:
|
||||||
samples_to_skip = 0;
|
samples_to_skip = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
mad_synth_frame(&synth, &frame);
|
mad_synth_thread_ready();
|
||||||
|
//mad_synth_frame(&synth, &frame);
|
||||||
|
|
||||||
/* Check if sample rate and stereo settings changed in this frame. */
|
/* Check if sample rate and stereo settings changed in this frame. */
|
||||||
if (frame.header.samplerate != current_frequency) {
|
if (frame.header.samplerate != current_frequency) {
|
||||||
|
@ -345,11 +468,20 @@ next_track:
|
||||||
|
|
||||||
/* Finish the remaining decoded frame.
|
/* Finish the remaining decoded frame.
|
||||||
Cut the required samples from the end. */
|
Cut the required samples from the end. */
|
||||||
if (framelength > stop_skip)
|
if (framelength > stop_skip){
|
||||||
|
mad_synth_thread_wait_pcm();
|
||||||
ci->pcmbuf_insert(synth.pcm.samples[0], synth.pcm.samples[1],
|
ci->pcmbuf_insert(synth.pcm.samples[0], synth.pcm.samples[1],
|
||||||
framelength - stop_skip);
|
framelength - stop_skip);
|
||||||
|
}
|
||||||
|
#ifdef MPA_SYNTH_ON_COP
|
||||||
|
/*mop up COP thread*/
|
||||||
|
die=1;
|
||||||
|
ci->semaphore_release(&synth_pending_sem);
|
||||||
|
ci->thread_wait(mad_synth_thread_p);
|
||||||
|
invalidate_icache();
|
||||||
stream.error = 0;
|
stream.error = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
if (ci->request_next_track())
|
if (ci->request_next_track())
|
||||||
goto next_track;
|
goto next_track;
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
INCLUDES = -I$(APPSDIR) -I.. -I. $(TARGET_INC) -I$(FIRMDIR)/include -I$(FIRMDIR)/export \
|
INCLUDES = -I$(APPSDIR) -I.. -I. $(TARGET_INC) -I$(FIRMDIR)/include -I$(FIRMDIR)/export \
|
||||||
-I$(FIRMDIR)/common -I$(FIRMDIR)/drivers -I$(APPSDIR)/plugins/lib -I$(OUTDIR) -I$(BUILDDIR)
|
-I$(FIRMDIR)/common -I$(FIRMDIR)/drivers -I$(APPSDIR)/plugins/lib -I$(OUTDIR) -I$(BUILDDIR)
|
||||||
CFLAGS = $(INCLUDES) $(GCCOPTS) -O2 $(TARGET) $(EXTRA_DEFINES) \
|
CFLAGS = $(INCLUDES) $(GCCOPTS) -O2 $(TARGET) $(EXTRA_DEFINES) \
|
||||||
-DTARGET_ID=$(TARGET_ID) -DMEM=${MEMORYSIZE} -DPLUGIN
|
-DTARGET_ID=$(TARGET_ID) -DMEM=${MEMORYSIZE} -DPLUGIN -DMPEGPLAYER
|
||||||
|
|
||||||
ifdef APPEXTRA
|
ifdef APPEXTRA
|
||||||
INCLUDES += $(patsubst %,-I$(APPSDIR)/%,$(subst :, ,$(APPEXTRA)))
|
INCLUDES += $(patsubst %,-I$(APPSDIR)/%,$(subst :, ,$(APPEXTRA)))
|
||||||
|
|
|
@ -55,6 +55,9 @@ static struct mad_stream stream IBSS_ATTR;
|
||||||
static struct mad_frame frame IBSS_ATTR;
|
static struct mad_frame frame IBSS_ATTR;
|
||||||
static struct mad_synth synth IBSS_ATTR;
|
static struct mad_synth synth IBSS_ATTR;
|
||||||
|
|
||||||
|
/*sbsample buffer for mad_frame*/
|
||||||
|
mad_fixed_t sbsample[2][36][32];
|
||||||
|
|
||||||
/* 2567 bytes */
|
/* 2567 bytes */
|
||||||
static unsigned char mad_main_data[MAD_BUFFER_MDLEN];
|
static unsigned char mad_main_data[MAD_BUFFER_MDLEN];
|
||||||
|
|
||||||
|
@ -229,6 +232,10 @@ static int audio_buffer(struct stream *str, enum stream_parse_mode type)
|
||||||
/* Initialise libmad */
|
/* Initialise libmad */
|
||||||
static void init_mad(void)
|
static void init_mad(void)
|
||||||
{
|
{
|
||||||
|
/*init the sbsample buffer*/
|
||||||
|
frame.sbsample = &sbsample;
|
||||||
|
frame.sbsample_prev = &sbsample;
|
||||||
|
|
||||||
mad_stream_init(&stream);
|
mad_stream_init(&stream);
|
||||||
mad_frame_init(&frame);
|
mad_frame_init(&frame);
|
||||||
mad_synth_init(&synth);
|
mad_synth_init(&synth);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue