summaryrefslogtreecommitdiff
path: root/apps/codecs/cook.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/codecs/cook.c')
-rw-r--r--apps/codecs/cook.c63
1 files changed, 33 insertions, 30 deletions
diff --git a/apps/codecs/cook.c b/apps/codecs/cook.c
index 015618986c..a6b4a1153e 100644
--- a/apps/codecs/cook.c
+++ b/apps/codecs/cook.c
@@ -38,9 +38,9 @@ static void init_rm(RMContext *rmctx)
38 memcpy(rmctx, (void*)(( (intptr_t)ci->id3->id3v2buf + 3 ) &~ 3), sizeof(RMContext)); 38 memcpy(rmctx, (void*)(( (intptr_t)ci->id3->id3v2buf + 3 ) &~ 3), sizeof(RMContext));
39} 39}
40 40
41/* this is the codec entry point */ 41/* this is called for each file to process */
42enum codec_status codec_main(void) 42enum codec_status codec_run(void)
43{ 43{
44 static size_t buff_size; 44 static size_t buff_size;
45 int datasize, res, consumed, i, time_offset; 45 int datasize, res, consumed, i, time_offset;
46 uint8_t *bit_buffer; 46 uint8_t *bit_buffer;
@@ -48,16 +48,14 @@ enum codec_status codec_main(void)
48 uint32_t packet_count; 48 uint32_t packet_count;
49 int scrambling_unit_size, num_units; 49 int scrambling_unit_size, num_units;
50 size_t resume_offset; 50 size_t resume_offset;
51 intptr_t param = 0;
52 enum codec_command_action action = CODEC_ACTION_NULL;
51 53
52next_track:
53 if (codec_init()) { 54 if (codec_init()) {
54 DEBUGF("codec init failed\n"); 55 DEBUGF("codec init failed\n");
55 return CODEC_ERROR; 56 return CODEC_ERROR;
56 } 57 }
57 58
58 if (codec_wait_taginfo() != 0)
59 goto done;
60
61 resume_offset = ci->id3->offset; 59 resume_offset = ci->id3->offset;
62 60
63 codec_set_replaygain(ci->id3); 61 codec_set_replaygain(ci->id3);
@@ -65,6 +63,8 @@ next_track:
65 ci->memset(&pkt,0,sizeof(RMPacket)); 63 ci->memset(&pkt,0,sizeof(RMPacket));
66 ci->memset(&q,0,sizeof(COOKContext)); 64 ci->memset(&q,0,sizeof(COOKContext));
67 65
66 ci->seek_buffer(0);
67
68 init_rm(&rmctx); 68 init_rm(&rmctx);
69 69
70 ci->configure(DSP_SET_FREQUENCY, ci->id3->frequency); 70 ci->configure(DSP_SET_FREQUENCY, ci->id3->frequency);
@@ -87,20 +87,21 @@ next_track:
87 DEBUGF("failed to initialize cook decoder\n"); 87 DEBUGF("failed to initialize cook decoder\n");
88 return CODEC_ERROR; 88 return CODEC_ERROR;
89 } 89 }
90 90
91 /* check for a mid-track resume and force a seek time accordingly */ 91 /* check for a mid-track resume and force a seek time accordingly */
92 if(resume_offset > rmctx.data_offset + DATA_HEADER_SIZE) { 92 if(resume_offset > rmctx.data_offset + DATA_HEADER_SIZE) {
93 resume_offset -= rmctx.data_offset + DATA_HEADER_SIZE; 93 resume_offset -= rmctx.data_offset + DATA_HEADER_SIZE;
94 num_units = (int)resume_offset / scrambling_unit_size; 94 num_units = (int)resume_offset / scrambling_unit_size;
95 /* put number of subpackets to skip in resume_offset */ 95 /* put number of subpackets to skip in resume_offset */
96 resume_offset /= (sps + PACKET_HEADER_SIZE); 96 resume_offset /= (sps + PACKET_HEADER_SIZE);
97 ci->seek_time = (int)resume_offset * ((sps * 8 * 1000)/rmctx.bit_rate); 97 param = (int)resume_offset * ((sps * 8 * 1000)/rmctx.bit_rate);
98 action = CODEC_ACTION_SEEK_TIME;
98 } 99 }
99 100
100 ci->set_elapsed(0); 101 ci->set_elapsed(0);
101 ci->advance_buffer(rmctx.data_offset + DATA_HEADER_SIZE); 102 ci->advance_buffer(rmctx.data_offset + DATA_HEADER_SIZE);
102 103
103 /* The main decoder loop */ 104 /* The main decoder loop */
104seek_start : 105seek_start :
105 while(packet_count) 106 while(packet_count)
106 { 107 {
@@ -112,18 +113,19 @@ seek_start :
112 } 113 }
113 114
114 for(i = 0; i < rmctx.audio_pkt_cnt*(fs/sps) ; i++) 115 for(i = 0; i < rmctx.audio_pkt_cnt*(fs/sps) ; i++)
115 { 116 {
116 ci->yield(); 117 if (action == CODEC_ACTION_NULL)
117 if (ci->stop_codec || ci->new_track) 118 action = ci->get_command(&param);
118 goto done;
119 119
120 if (ci->seek_time) { 120 if (action == CODEC_ACTION_HALT)
121 ci->set_elapsed(ci->seek_time); 121 return CODEC_OK;
122 122
123 if (action == CODEC_ACTION_SEEK_TIME) {
123 /* Do not allow seeking beyond the file's length */ 124 /* Do not allow seeking beyond the file's length */
124 if ((unsigned) ci->seek_time > ci->id3->length) { 125 if ((unsigned) param > ci->id3->length) {
126 ci->set_elapsed(ci->id3->length);
125 ci->seek_complete(); 127 ci->seek_complete();
126 goto done; 128 return CODEC_OK;
127 } 129 }
128 130
129 ci->seek_buffer(rmctx.data_offset + DATA_HEADER_SIZE); 131 ci->seek_buffer(rmctx.data_offset + DATA_HEADER_SIZE);
@@ -132,22 +134,24 @@ seek_start :
132 rmctx.frame_number = 0; 134 rmctx.frame_number = 0;
133 135
134 /* Seek to the start of the track */ 136 /* Seek to the start of the track */
135 if (ci->seek_time == 1) { 137 if (param == 0) {
136 ci->set_elapsed(0); 138 ci->set_elapsed(0);
137 ci->seek_complete(); 139 ci->seek_complete();
140 action = CODEC_ACTION_NULL;
138 goto seek_start; 141 goto seek_start;
139 } 142 }
140 num_units = ((ci->seek_time)/(sps*1000*8/rmctx.bit_rate))/(h*(fs/sps)); 143 num_units = (param/(sps*1000*8/rmctx.bit_rate))/(h*(fs/sps));
141 ci->seek_buffer(rmctx.data_offset + DATA_HEADER_SIZE + consumed * num_units); 144 ci->seek_buffer(rmctx.data_offset + DATA_HEADER_SIZE + consumed * num_units);
142 bit_buffer = (uint8_t *) ci->request_buffer(&buff_size, scrambling_unit_size); 145 bit_buffer = (uint8_t *) ci->request_buffer(&buff_size, scrambling_unit_size);
143 consumed = rm_get_packet(&bit_buffer, &rmctx, &pkt); 146 consumed = rm_get_packet(&bit_buffer, &rmctx, &pkt);
144 if(consumed < 0) { 147 if(consumed < 0) {
145 DEBUGF("rm_get_packet failed\n"); 148 DEBUGF("rm_get_packet failed\n");
146 return CODEC_ERROR; 149 ci->seek_complete();
150 return CODEC_ERROR;
147 } 151 }
148 packet_count = rmctx.nb_packets - rmctx.audio_pkt_cnt * num_units; 152 packet_count = rmctx.nb_packets - rmctx.audio_pkt_cnt * num_units;
149 rmctx.frame_number = ((ci->seek_time)/(sps*1000*8/rmctx.bit_rate)); 153 rmctx.frame_number = (param/(sps*1000*8/rmctx.bit_rate));
150 while(rmctx.audiotimestamp > (unsigned) ci->seek_time) { 154 while(rmctx.audiotimestamp > (unsigned) param) {
151 rmctx.audio_pkt_cnt = 0; 155 rmctx.audio_pkt_cnt = 0;
152 ci->seek_buffer(rmctx.data_offset + DATA_HEADER_SIZE + consumed * (num_units-1)); 156 ci->seek_buffer(rmctx.data_offset + DATA_HEADER_SIZE + consumed * (num_units-1));
153 bit_buffer = (uint8_t *) ci->request_buffer(&buff_size, scrambling_unit_size); 157 bit_buffer = (uint8_t *) ci->request_buffer(&buff_size, scrambling_unit_size);
@@ -155,11 +159,14 @@ seek_start :
155 packet_count += rmctx.audio_pkt_cnt; 159 packet_count += rmctx.audio_pkt_cnt;
156 num_units--; 160 num_units--;
157 } 161 }
158 time_offset = ci->seek_time - rmctx.audiotimestamp; 162 time_offset = param - rmctx.audiotimestamp;
159 i = (time_offset/((sps * 8 * 1000)/rmctx.bit_rate)); 163 i = (time_offset/((sps * 8 * 1000)/rmctx.bit_rate));
160 ci->set_elapsed(rmctx.audiotimestamp+(1000*8*sps/rmctx.bit_rate)*i); 164 ci->set_elapsed(rmctx.audiotimestamp+(1000*8*sps/rmctx.bit_rate)*i);
161 ci->seek_complete(); 165 ci->seek_complete();
162 } 166 }
167
168 action = CODEC_ACTION_NULL;
169
163 res = cook_decode_frame(&rmctx,&q, rm_outbuf, &datasize, pkt.frames[i], rmctx.block_align); 170 res = cook_decode_frame(&rmctx,&q, rm_outbuf, &datasize, pkt.frames[i], rmctx.block_align);
164 rmctx.frame_number++; 171 rmctx.frame_number++;
165 172
@@ -181,9 +188,5 @@ seek_start :
181 ci->advance_buffer(consumed); 188 ci->advance_buffer(consumed);
182 } 189 }
183 190
184 done : 191 return CODEC_OK;
185 if (ci->request_next_track())
186 goto next_track;
187
188 return CODEC_OK;
189} 192}