diff options
Diffstat (limited to 'apps/codecs/atrac3_rm.c')
-rw-r--r-- | apps/codecs/atrac3_rm.c | 67 |
1 files changed, 35 insertions, 32 deletions
diff --git a/apps/codecs/atrac3_rm.c b/apps/codecs/atrac3_rm.c index 6a77d24283..1322e917ed 100644 --- a/apps/codecs/atrac3_rm.c +++ b/apps/codecs/atrac3_rm.c | |||
@@ -41,9 +41,9 @@ static void init_rm(RMContext *rmctx) | |||
41 | memcpy(ci->id3->id3v2buf, (char*)rmctx->codec_extradata, rmctx->extradata_size*sizeof(char)); | 41 | memcpy(ci->id3->id3v2buf, (char*)rmctx->codec_extradata, rmctx->extradata_size*sizeof(char)); |
42 | } | 42 | } |
43 | 43 | ||
44 | /* this is the codec entry point */ | 44 | /* this is called for each file to process */ |
45 | enum codec_status codec_main(void) | 45 | enum codec_status codec_run(void) |
46 | { | 46 | { |
47 | static size_t buff_size; | 47 | static size_t buff_size; |
48 | int datasize, res, consumed, i, time_offset; | 48 | int datasize, res, consumed, i, time_offset; |
49 | uint8_t *bit_buffer; | 49 | uint8_t *bit_buffer; |
@@ -52,16 +52,14 @@ enum codec_status codec_main(void) | |||
52 | int scrambling_unit_size, num_units, elapsed = 0; | 52 | int scrambling_unit_size, num_units, elapsed = 0; |
53 | int playback_on = -1; | 53 | int playback_on = -1; |
54 | size_t resume_offset; | 54 | size_t resume_offset; |
55 | intptr_t param; | ||
56 | enum codec_command_action action = CODEC_ACTION_NULL; | ||
55 | 57 | ||
56 | next_track: | ||
57 | if (codec_init()) { | 58 | if (codec_init()) { |
58 | DEBUGF("codec init failed\n"); | 59 | DEBUGF("codec init failed\n"); |
59 | return CODEC_ERROR; | 60 | return CODEC_ERROR; |
60 | } | 61 | } |
61 | 62 | ||
62 | if (codec_wait_taginfo() != 0) | ||
63 | goto done; | ||
64 | |||
65 | resume_offset = ci->id3->offset; | 63 | resume_offset = ci->id3->offset; |
66 | 64 | ||
67 | codec_set_replaygain(ci->id3); | 65 | codec_set_replaygain(ci->id3); |
@@ -69,6 +67,7 @@ next_track: | |||
69 | ci->memset(&pkt,0,sizeof(RMPacket)); | 67 | ci->memset(&pkt,0,sizeof(RMPacket)); |
70 | ci->memset(&q,0,sizeof(ATRAC3Context)); | 68 | ci->memset(&q,0,sizeof(ATRAC3Context)); |
71 | 69 | ||
70 | ci->seek_buffer(0); | ||
72 | init_rm(&rmctx); | 71 | init_rm(&rmctx); |
73 | 72 | ||
74 | ci->configure(DSP_SET_FREQUENCY, ci->id3->frequency); | 73 | ci->configure(DSP_SET_FREQUENCY, ci->id3->frequency); |
@@ -84,22 +83,25 @@ next_track: | |||
84 | h = rmctx.sub_packet_h; | 83 | h = rmctx.sub_packet_h; |
85 | scrambling_unit_size = h*fs; | 84 | scrambling_unit_size = h*fs; |
86 | 85 | ||
87 | res =atrac3_decode_init(&q, ci->id3); | 86 | res = atrac3_decode_init(&q, ci->id3); |
88 | if(res < 0) { | 87 | if(res < 0) { |
89 | DEBUGF("failed to initialize RM atrac decoder\n"); | 88 | DEBUGF("failed to initialize RM atrac decoder\n"); |
90 | return CODEC_ERROR; | 89 | return CODEC_ERROR; |
91 | } | 90 | } |
92 | 91 | ||
93 | /* check for a mid-track resume and force a seek time accordingly */ | 92 | /* check for a mid-track resume and force a seek time accordingly */ |
94 | if(resume_offset > rmctx.data_offset + DATA_HEADER_SIZE) { | 93 | if(resume_offset > rmctx.data_offset + DATA_HEADER_SIZE) { |
95 | resume_offset -= rmctx.data_offset + DATA_HEADER_SIZE; | 94 | resume_offset -= rmctx.data_offset + DATA_HEADER_SIZE; |
96 | num_units = (int)resume_offset / scrambling_unit_size; | 95 | num_units = (int)resume_offset / scrambling_unit_size; |
97 | /* put number of subpackets to skip in resume_offset */ | 96 | /* put number of subpackets to skip in resume_offset */ |
98 | resume_offset /= (sps + PACKET_HEADER_SIZE); | 97 | resume_offset /= (sps + PACKET_HEADER_SIZE); |
99 | ci->seek_time = (int)resume_offset * ((sps * 8 * 1000)/rmctx.bit_rate); | 98 | param = (int)resume_offset * ((sps * 8 * 1000)/rmctx.bit_rate); |
99 | action = CODEC_ACTION_SEEK_TIME; | ||
100 | } | 100 | } |
101 | 101 | else { | |
102 | ci->set_elapsed(0); | 102 | ci->set_elapsed(0); |
103 | } | ||
104 | |||
103 | ci->advance_buffer(rmctx.data_offset + DATA_HEADER_SIZE); | 105 | ci->advance_buffer(rmctx.data_offset + DATA_HEADER_SIZE); |
104 | 106 | ||
105 | /* The main decoder loop */ | 107 | /* The main decoder loop */ |
@@ -115,22 +117,23 @@ seek_start : | |||
115 | return CODEC_ERROR; | 117 | return CODEC_ERROR; |
116 | } | 118 | } |
117 | else | 119 | else |
118 | goto done; | 120 | return CODEC_OK; |
119 | } | 121 | } |
120 | 122 | ||
121 | for(i = 0; i < rmctx.audio_pkt_cnt*(fs/sps) ; i++) | 123 | for(i = 0; i < rmctx.audio_pkt_cnt*(fs/sps) ; i++) |
122 | { | 124 | { |
123 | ci->yield(); | 125 | if (action == CODEC_ACTION_NULL) |
124 | if (ci->stop_codec || ci->new_track) | 126 | action = ci->get_command(¶m); |
125 | goto done; | ||
126 | 127 | ||
127 | if (ci->seek_time) { | 128 | if (action == CODEC_ACTION_HALT) |
128 | ci->set_elapsed(ci->seek_time); | 129 | return CODEC_OK; |
129 | 130 | ||
131 | if (action == CODEC_ACTION_SEEK_TIME) { | ||
130 | /* Do not allow seeking beyond the file's length */ | 132 | /* Do not allow seeking beyond the file's length */ |
131 | if ((unsigned) ci->seek_time > ci->id3->length) { | 133 | if ((unsigned) param > ci->id3->length) { |
134 | ci->set_elapsed(ci->id3->length); | ||
132 | ci->seek_complete(); | 135 | ci->seek_complete(); |
133 | goto done; | 136 | return CODEC_OK; |
134 | } | 137 | } |
135 | 138 | ||
136 | ci->seek_buffer(rmctx.data_offset + DATA_HEADER_SIZE); | 139 | ci->seek_buffer(rmctx.data_offset + DATA_HEADER_SIZE); |
@@ -139,12 +142,13 @@ seek_start : | |||
139 | rmctx.frame_number = 0; | 142 | rmctx.frame_number = 0; |
140 | 143 | ||
141 | /* Seek to the start of the track */ | 144 | /* Seek to the start of the track */ |
142 | if (ci->seek_time == 1) { | 145 | if (param == 0) { |
143 | ci->set_elapsed(0); | 146 | ci->set_elapsed(0); |
144 | ci->seek_complete(); | 147 | ci->seek_complete(); |
148 | action = CODEC_ACTION_NULL; | ||
145 | goto seek_start; | 149 | goto seek_start; |
146 | } | 150 | } |
147 | num_units = ((ci->seek_time)/(sps*1000*8/rmctx.bit_rate))/(h*(fs/sps)); | 151 | num_units = (param/(sps*1000*8/rmctx.bit_rate))/(h*(fs/sps)); |
148 | ci->seek_buffer(rmctx.data_offset + DATA_HEADER_SIZE + consumed * num_units); | 152 | ci->seek_buffer(rmctx.data_offset + DATA_HEADER_SIZE + consumed * num_units); |
149 | bit_buffer = (uint8_t *) ci->request_buffer(&buff_size, scrambling_unit_size); | 153 | bit_buffer = (uint8_t *) ci->request_buffer(&buff_size, scrambling_unit_size); |
150 | consumed = rm_get_packet(&bit_buffer, &rmctx, &pkt); | 154 | consumed = rm_get_packet(&bit_buffer, &rmctx, &pkt); |
@@ -155,12 +159,12 @@ seek_start : | |||
155 | return CODEC_ERROR; | 159 | return CODEC_ERROR; |
156 | } | 160 | } |
157 | else | 161 | else |
158 | goto done; | 162 | return CODEC_OK; |
159 | } | 163 | } |
160 | 164 | ||
161 | packet_count = rmctx.nb_packets - rmctx.audio_pkt_cnt * num_units; | 165 | packet_count = rmctx.nb_packets - rmctx.audio_pkt_cnt * num_units; |
162 | rmctx.frame_number = ((ci->seek_time)/(sps*1000*8/rmctx.bit_rate)); | 166 | rmctx.frame_number = (param/(sps*1000*8/rmctx.bit_rate)); |
163 | while(rmctx.audiotimestamp > (unsigned) ci->seek_time) { | 167 | while(rmctx.audiotimestamp > (unsigned) param) { |
164 | rmctx.audio_pkt_cnt = 0; | 168 | rmctx.audio_pkt_cnt = 0; |
165 | ci->seek_buffer(rmctx.data_offset + DATA_HEADER_SIZE + consumed * (num_units-1)); | 169 | ci->seek_buffer(rmctx.data_offset + DATA_HEADER_SIZE + consumed * (num_units-1)); |
166 | bit_buffer = (uint8_t *) ci->request_buffer(&buff_size, scrambling_unit_size); | 170 | bit_buffer = (uint8_t *) ci->request_buffer(&buff_size, scrambling_unit_size); |
@@ -168,16 +172,19 @@ seek_start : | |||
168 | packet_count += rmctx.audio_pkt_cnt; | 172 | packet_count += rmctx.audio_pkt_cnt; |
169 | num_units--; | 173 | num_units--; |
170 | } | 174 | } |
171 | time_offset = ci->seek_time - rmctx.audiotimestamp; | 175 | time_offset = param - rmctx.audiotimestamp; |
172 | i = (time_offset/((sps * 8 * 1000)/rmctx.bit_rate)); | 176 | i = (time_offset/((sps * 8 * 1000)/rmctx.bit_rate)); |
173 | elapsed = rmctx.audiotimestamp+(1000*8*sps/rmctx.bit_rate)*i; | 177 | elapsed = rmctx.audiotimestamp+(1000*8*sps/rmctx.bit_rate)*i; |
174 | ci->set_elapsed(elapsed); | 178 | ci->set_elapsed(elapsed); |
175 | ci->seek_complete(); | 179 | ci->seek_complete(); |
176 | } | 180 | } |
181 | |||
182 | action = CODEC_ACTION_NULL; | ||
183 | |||
177 | if(pkt.length) | 184 | if(pkt.length) |
178 | res = atrac3_decode_frame(rmctx.block_align, &q, &datasize, pkt.frames[i], rmctx.block_align); | 185 | res = atrac3_decode_frame(rmctx.block_align, &q, &datasize, pkt.frames[i], rmctx.block_align); |
179 | else /* indicates that there are no remaining frames */ | 186 | else /* indicates that there are no remaining frames */ |
180 | goto done; | 187 | return CODEC_OK; |
181 | 188 | ||
182 | if(res != rmctx.block_align) { | 189 | if(res != rmctx.block_align) { |
183 | DEBUGF("codec error\n"); | 190 | DEBUGF("codec error\n"); |
@@ -196,9 +203,5 @@ seek_start : | |||
196 | ci->advance_buffer(consumed); | 203 | ci->advance_buffer(consumed); |
197 | } | 204 | } |
198 | 205 | ||
199 | done : | 206 | return CODEC_OK; |
200 | if (ci->request_next_track()) | ||
201 | goto next_track; | ||
202 | |||
203 | return CODEC_OK; | ||
204 | } | 207 | } |