summaryrefslogtreecommitdiff
path: root/apps/codecs/atrac3_rm.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/codecs/atrac3_rm.c')
-rw-r--r--apps/codecs/atrac3_rm.c67
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 */
45enum codec_status codec_main(void) 45enum 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
56next_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(&param);
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}