diff options
Diffstat (limited to 'apps/codecs/atrac3_oma.c')
-rw-r--r-- | apps/codecs/atrac3_oma.c | 136 |
1 files changed, 69 insertions, 67 deletions
diff --git a/apps/codecs/atrac3_oma.c b/apps/codecs/atrac3_oma.c index 73f3ad29fd..ab24783368 100644 --- a/apps/codecs/atrac3_oma.c +++ b/apps/codecs/atrac3_oma.c | |||
@@ -33,24 +33,22 @@ CODEC_HEADER | |||
33 | 33 | ||
34 | static ATRAC3Context q IBSS_ATTR; | 34 | static ATRAC3Context q IBSS_ATTR; |
35 | 35 | ||
36 | /* this is the codec entry point */ | 36 | /* this is called for each file to process */ |
37 | enum codec_status codec_main(void) | 37 | enum codec_status codec_run(void) |
38 | { | 38 | { |
39 | static size_t buff_size; | 39 | static size_t buff_size; |
40 | int datasize, res, frame_counter, total_frames, seek_frame_offset; | 40 | int datasize, res, frame_counter, total_frames, seek_frame_offset; |
41 | uint8_t *bit_buffer; | 41 | uint8_t *bit_buffer; |
42 | int elapsed = 0; | 42 | int elapsed = 0; |
43 | size_t resume_offset; | 43 | size_t resume_offset; |
44 | intptr_t param; | ||
45 | enum codec_command_action action = CODEC_ACTION_NULL; | ||
44 | 46 | ||
45 | next_track: | ||
46 | if (codec_init()) { | 47 | if (codec_init()) { |
47 | DEBUGF("codec init failed\n"); | 48 | DEBUGF("codec init failed\n"); |
48 | return CODEC_ERROR; | 49 | return CODEC_ERROR; |
49 | } | 50 | } |
50 | 51 | ||
51 | if (codec_wait_taginfo() != 0) | ||
52 | goto done; | ||
53 | |||
54 | resume_offset = ci->id3->offset; | 52 | resume_offset = ci->id3->offset; |
55 | 53 | ||
56 | codec_set_replaygain(ci->id3); | 54 | codec_set_replaygain(ci->id3); |
@@ -60,84 +58,88 @@ next_track: | |||
60 | ci->configure(DSP_SET_SAMPLE_DEPTH, 17); /* Remark: atrac3 uses s15.0 by default, s15.2 was hacked. */ | 58 | ci->configure(DSP_SET_SAMPLE_DEPTH, 17); /* Remark: atrac3 uses s15.0 by default, s15.2 was hacked. */ |
61 | ci->configure(DSP_SET_STEREO_MODE, ci->id3->channels == 1 ? | 59 | ci->configure(DSP_SET_STEREO_MODE, ci->id3->channels == 1 ? |
62 | STEREO_MONO : STEREO_NONINTERLEAVED); | 60 | STEREO_MONO : STEREO_NONINTERLEAVED); |
63 | 61 | ||
64 | res =atrac3_decode_init(&q, ci->id3); | 62 | ci->seek_buffer(0); |
63 | |||
64 | res = atrac3_decode_init(&q, ci->id3); | ||
65 | if(res < 0) { | 65 | if(res < 0) { |
66 | DEBUGF("failed to initialize OMA atrac decoder\n"); | 66 | DEBUGF("failed to initialize OMA atrac decoder\n"); |
67 | return CODEC_ERROR; | 67 | return CODEC_ERROR; |
68 | } | 68 | } |
69 | 69 | ||
70 | total_frames = (ci->id3->filesize - ci->id3->first_frame_offset) / FRAMESIZE; | ||
71 | frame_counter = 0; | ||
72 | |||
70 | /* check for a mid-track resume and force a seek time accordingly */ | 73 | /* check for a mid-track resume and force a seek time accordingly */ |
71 | if(resume_offset > ci->id3->first_frame_offset) { | 74 | if(resume_offset > ci->id3->first_frame_offset) { |
72 | resume_offset -= ci->id3->first_frame_offset; | 75 | resume_offset -= ci->id3->first_frame_offset; |
73 | /* calculate resume_offset in frames */ | 76 | /* calculate resume_offset in frames */ |
74 | resume_offset = (int)resume_offset / FRAMESIZE; | 77 | resume_offset = (int)resume_offset / FRAMESIZE; |
75 | ci->seek_time = (int)resume_offset * ((FRAMESIZE * 8)/BITRATE); | 78 | param = (int)resume_offset * ((FRAMESIZE * 8)/BITRATE); |
79 | action = CODEC_ACTION_SEEK_TIME; | ||
80 | } | ||
81 | else { | ||
82 | ci->set_elapsed(0); | ||
83 | ci->seek_buffer(ci->id3->first_frame_offset); | ||
76 | } | 84 | } |
77 | total_frames = (ci->id3->filesize - ci->id3->first_frame_offset) / FRAMESIZE; | ||
78 | frame_counter = 0; | ||
79 | |||
80 | ci->set_elapsed(0); | ||
81 | ci->seek_buffer(0); | ||
82 | ci->advance_buffer(ci->id3->first_frame_offset); | ||
83 | 85 | ||
84 | /* The main decoder loop */ | 86 | /* The main decoder loop */ |
85 | seek_start : | ||
86 | while(frame_counter < total_frames) | 87 | while(frame_counter < total_frames) |
87 | { | 88 | { |
89 | if (action == CODEC_ACTION_NULL) | ||
90 | action = ci->get_command(¶m); | ||
91 | |||
92 | if (action == CODEC_ACTION_HALT) | ||
93 | break; | ||
94 | |||
88 | bit_buffer = (uint8_t *) ci->request_buffer(&buff_size, FRAMESIZE); | 95 | bit_buffer = (uint8_t *) ci->request_buffer(&buff_size, FRAMESIZE); |
89 | 96 | ||
90 | ci->yield(); | 97 | if (action == CODEC_ACTION_SEEK_TIME) { |
91 | if (ci->stop_codec || ci->new_track) | 98 | /* Do not allow seeking beyond the file's length */ |
92 | goto done; | 99 | if ((unsigned) param > ci->id3->length) { |
93 | 100 | ci->set_elapsed(ci->id3->length); | |
94 | if (ci->seek_time) { | 101 | ci->seek_complete(); |
95 | ci->set_elapsed(ci->seek_time); | 102 | break; |
96 | 103 | } | |
97 | /* Do not allow seeking beyond the file's length */ | 104 | |
98 | if ((unsigned) ci->seek_time > ci->id3->length) { | 105 | /* Seek to the start of the track */ |
99 | ci->seek_complete(); | 106 | if (param == 0) { |
100 | goto done; | 107 | elapsed = 0; |
101 | } | 108 | ci->set_elapsed(0); |
102 | 109 | ci->seek_buffer(ci->id3->first_frame_offset); | |
103 | /* Seek to the start of the track */ | 110 | ci->seek_complete(); |
104 | if (ci->seek_time == 1) { | 111 | action = CODEC_ACTION_NULL; |
105 | ci->set_elapsed(0); | 112 | continue; |
106 | ci->seek_complete(); | 113 | } |
107 | ci->seek_buffer(ci->id3->first_frame_offset); | 114 | |
108 | elapsed = 0; | 115 | seek_frame_offset = (param * BITRATE) / (8 * FRAMESIZE); |
109 | goto seek_start; | 116 | frame_counter = seek_frame_offset; |
110 | } | 117 | ci->seek_buffer(ci->id3->first_frame_offset + seek_frame_offset* FRAMESIZE); |
111 | seek_frame_offset = (ci->seek_time * BITRATE) / (8 * FRAMESIZE); | 118 | bit_buffer = (uint8_t *) ci->request_buffer(&buff_size, FRAMESIZE); |
112 | frame_counter = seek_frame_offset; | 119 | elapsed = param; |
113 | ci->seek_buffer(ci->id3->first_frame_offset + seek_frame_offset* FRAMESIZE); | ||
114 | bit_buffer = (uint8_t *) ci->request_buffer(&buff_size, FRAMESIZE); | ||
115 | elapsed = ci->seek_time; | ||
116 | |||
117 | ci->set_elapsed(elapsed); | ||
118 | ci->seek_complete(); | ||
119 | } | ||
120 | |||
121 | res = atrac3_decode_frame(FRAMESIZE, &q, &datasize, bit_buffer, FRAMESIZE); | ||
122 | |||
123 | if(res != (int)FRAMESIZE) { | ||
124 | DEBUGF("codec error\n"); | ||
125 | return CODEC_ERROR; | ||
126 | } | ||
127 | |||
128 | if(datasize) | ||
129 | ci->pcmbuf_insert(q.outSamples, q.outSamples + 1024, q.samples_per_frame / ci->id3->channels); | ||
130 | |||
131 | elapsed += (FRAMESIZE * 8) / BITRATE; | ||
132 | ci->set_elapsed(elapsed); | 120 | ci->set_elapsed(elapsed); |
133 | 121 | ci->seek_complete(); | |
134 | ci->advance_buffer(FRAMESIZE); | 122 | } |
135 | frame_counter++; | 123 | |
136 | } | 124 | action = CODEC_ACTION_NULL; |
137 | 125 | ||
138 | done: | 126 | res = atrac3_decode_frame(FRAMESIZE, &q, &datasize, bit_buffer, FRAMESIZE); |
139 | if (ci->request_next_track()) | 127 | |
140 | goto next_track; | 128 | if(res != (int)FRAMESIZE) { |
129 | DEBUGF("codec error\n"); | ||
130 | return CODEC_ERROR; | ||
131 | } | ||
132 | |||
133 | if(datasize) | ||
134 | ci->pcmbuf_insert(q.outSamples, q.outSamples + 1024, | ||
135 | q.samples_per_frame / ci->id3->channels); | ||
136 | |||
137 | elapsed += (FRAMESIZE * 8) / BITRATE; | ||
138 | ci->set_elapsed(elapsed); | ||
139 | |||
140 | ci->advance_buffer(FRAMESIZE); | ||
141 | frame_counter++; | ||
142 | } | ||
141 | 143 | ||
142 | return CODEC_OK; | 144 | return CODEC_OK; |
143 | } | 145 | } |