summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYoshihisa Uchida <uchida@rockbox.org>2010-03-22 10:02:05 +0000
committerYoshihisa Uchida <uchida@rockbox.org>2010-03-22 10:02:05 +0000
commit7a3822c8b03a5438a1bcfd6e38c0e6860dda3348 (patch)
treee50740c7f0ccd6aff1aac0e292a000ac7ef6be14
parent20fccd84897352478c3306e41ca0fab0a5f4c65e (diff)
downloadrockbox-7a3822c8b03a5438a1bcfd6e38c0e6860dda3348.tar.gz
rockbox-7a3822c8b03a5438a1bcfd6e38c0e6860dda3348.zip
fix bug: WAV file playback does not resume (FS#11077)
Not only WAV but also Sun audio, SMAF, vox and WAV64 can resume. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@25289 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/codecs/aiff.c28
-rw-r--r--apps/codecs/au.c27
-rw-r--r--apps/codecs/libpcm/dialogic_oki_adpcm.c20
-rw-r--r--apps/codecs/libpcm/dvi_adpcm.c8
-rw-r--r--apps/codecs/libpcm/ieee_float.c8
-rw-r--r--apps/codecs/libpcm/itut_g711.c8
-rw-r--r--apps/codecs/libpcm/linear_pcm.c8
-rw-r--r--apps/codecs/libpcm/ms_adpcm.c8
-rw-r--r--apps/codecs/libpcm/pcm_common.h13
-rw-r--r--apps/codecs/libpcm/qt_ima_adpcm.c8
-rw-r--r--apps/codecs/libpcm/swf_adpcm.c15
-rw-r--r--apps/codecs/libpcm/yamaha_adpcm.c11
-rw-r--r--apps/codecs/smaf.c25
-rw-r--r--apps/codecs/vox.c37
-rw-r--r--apps/codecs/wav.c16
-rw-r--r--apps/codecs/wav64.c16
-rw-r--r--apps/metadata/vox.c1
17 files changed, 188 insertions, 69 deletions
diff --git a/apps/codecs/aiff.c b/apps/codecs/aiff.c
index 62d79ac340..4e16788e06 100644
--- a/apps/codecs/aiff.c
+++ b/apps/codecs/aiff.c
@@ -100,6 +100,9 @@ next_track:
100 100
101 codec_set_replaygain(ci->id3); 101 codec_set_replaygain(ci->id3);
102 102
103 /* Need to save offset for later use (cleared indirectly by advance_buffer) */
104 bytesdone = ci->id3->offset;
105
103 /* assume the AIFF header is less than 1024 bytes */ 106 /* assume the AIFF header is less than 1024 bytes */
104 buf = ci->request_buffer(&n, 1024); 107 buf = ci->request_buffer(&n, 1024);
105 if (n < 54) { 108 if (n < 54) {
@@ -279,9 +282,26 @@ next_track:
279 firstblockposn = 1024 - n; 282 firstblockposn = 1024 - n;
280 ci->advance_buffer(firstblockposn); 283 ci->advance_buffer(firstblockposn);
281 284
285 /* make sure we're at the correct offset */
286 if (bytesdone > (uint32_t) firstblockposn) {
287 /* Round down to previous block */
288 struct pcm_pos *newpos = codec->get_seek_pos(bytesdone - firstblockposn,
289 PCM_SEEK_POS, NULL);
290
291 if (newpos->pos > format.numbytes)
292 goto done;
293 if (ci->seek_buffer(firstblockposn + newpos->pos))
294 {
295 bytesdone = newpos->pos;
296 decodedsamples = newpos->samples;
297 }
298 ci->seek_complete();
299 } else {
300 /* already where we need to be */
301 bytesdone = 0;
302 }
303
282 /* The main decoder loop */ 304 /* The main decoder loop */
283 bytesdone = 0;
284 ci->set_elapsed(0);
285 endofstream = 0; 305 endofstream = 0;
286 306
287 while (!endofstream) { 307 while (!endofstream) {
@@ -290,8 +310,8 @@ next_track:
290 break; 310 break;
291 311
292 if (ci->seek_time) { 312 if (ci->seek_time) {
293 /* 2nd args(read_buffer) is unnecessary in the format which AIFF supports. */ 313 /* 3rd args(read_buffer) is unnecessary in the format which AIFF supports. */
294 struct pcm_pos *newpos = codec->get_seek_pos(ci->seek_time, NULL); 314 struct pcm_pos *newpos = codec->get_seek_pos(ci->seek_time, PCM_SEEK_TIME, NULL);
295 315
296 if (newpos->pos > format.numbytes) 316 if (newpos->pos > format.numbytes)
297 break; 317 break;
diff --git a/apps/codecs/au.c b/apps/codecs/au.c
index 19348bc299..1e6af25924 100644
--- a/apps/codecs/au.c
+++ b/apps/codecs/au.c
@@ -135,6 +135,9 @@ next_track:
135 135
136 codec_set_replaygain(ci->id3); 136 codec_set_replaygain(ci->id3);
137 137
138 /* Need to save offset for later use (cleared indirectly by advance_buffer) */
139 bytesdone = ci->id3->offset;
140
138 ci->memset(&format, 0, sizeof(struct pcm_format)); 141 ci->memset(&format, 0, sizeof(struct pcm_format));
139 format.is_signed = true; 142 format.is_signed = true;
140 format.is_little_endian = false; 143 format.is_little_endian = false;
@@ -191,7 +194,6 @@ next_track:
191 194
192 decodedsamples = 0; 195 decodedsamples = 0;
193 codec = 0; 196 codec = 0;
194 bytesdone = 0;
195 197
196 /* get codec */ 198 /* get codec */
197 codec = get_au_codec(format.formattag); 199 codec = get_au_codec(format.formattag);
@@ -236,6 +238,25 @@ next_track:
236 goto done; 238 goto done;
237 } 239 }
238 240
241 /* make sure we're at the correct offset */
242 if (bytesdone > (uint32_t) firstblockposn) {
243 /* Round down to previous block */
244 struct pcm_pos *newpos = codec->get_seek_pos(bytesdone - firstblockposn,
245 PCM_SEEK_POS, NULL);
246
247 if (newpos->pos > format.numbytes)
248 goto done;
249 if (ci->seek_buffer(firstblockposn + newpos->pos))
250 {
251 bytesdone = newpos->pos;
252 decodedsamples = newpos->samples;
253 }
254 ci->seek_complete();
255 } else {
256 /* already where we need to be */
257 bytesdone = 0;
258 }
259
239 /* The main decoder loop */ 260 /* The main decoder loop */
240 endofstream = 0; 261 endofstream = 0;
241 262
@@ -246,8 +267,8 @@ next_track:
246 } 267 }
247 268
248 if (ci->seek_time) { 269 if (ci->seek_time) {
249 /* 2nd args(read_buffer) is unnecessary in the format which Sun Audio supports. */ 270 /* 3rd args(read_buffer) is unnecessary in the format which Sun Audio supports. */
250 struct pcm_pos *newpos = codec->get_seek_pos(ci->seek_time, NULL); 271 struct pcm_pos *newpos = codec->get_seek_pos(ci->seek_time, PCM_SEEK_TIME, NULL);
251 272
252 if (newpos->pos > format.numbytes) 273 if (newpos->pos > format.numbytes)
253 break; 274 break;
diff --git a/apps/codecs/libpcm/dialogic_oki_adpcm.c b/apps/codecs/libpcm/dialogic_oki_adpcm.c
index 62d092e677..4a6465f196 100644
--- a/apps/codecs/libpcm/dialogic_oki_adpcm.c
+++ b/apps/codecs/libpcm/dialogic_oki_adpcm.c
@@ -44,6 +44,7 @@ static const int index_table[] ICONST_ATTR = {
44}; 44};
45 45
46static struct adpcm_data cur_data; 46static struct adpcm_data cur_data;
47static int blocksperchunk;
47 48
48static struct pcm_format *fmt; 49static struct pcm_format *fmt;
49 50
@@ -71,7 +72,8 @@ static bool set_format(struct pcm_format *format)
71 fmt->samplesperblock = 2; 72 fmt->samplesperblock = 2;
72 73
73 /* chunksize = about 1/32[sec] data */ 74 /* chunksize = about 1/32[sec] data */
74 fmt->chunksize = ci->id3->frequency >> 6; 75 blocksperchunk = ci->id3->frequency >> 6;
76 fmt->chunksize = blocksperchunk * fmt->blockalign;
75 77
76 max_chunk_count = (uint64_t)ci->id3->length * ci->id3->frequency 78 max_chunk_count = (uint64_t)ci->id3->length * ci->id3->frequency
77 / (2000LL * fmt->chunksize); 79 / (2000LL * fmt->chunksize);
@@ -146,20 +148,18 @@ static int decode_for_seek(const uint8_t *inbuf, size_t inbufsize)
146 return CODEC_OK; 148 return CODEC_OK;
147} 149}
148 150
149static struct pcm_pos *get_seek_pos(long seek_time, 151static struct pcm_pos *get_seek_pos(uint32_t seek_val, int seek_mode,
150 uint8_t *(*read_buffer)(size_t *realsize)) 152 uint8_t *(*read_buffer)(size_t *realsize))
151{ 153{
152 static struct pcm_pos newpos; 154 static struct pcm_pos newpos;
153 uint32_t seek_count = 0; 155 uint32_t seek_count = (seek_mode == PCM_SEEK_TIME)?
154 uint32_t new_count; 156 ((uint64_t)seek_val * ci->id3->frequency / 1000LL)
157 / (blocksperchunk * fmt->samplesperblock) :
158 seek_val / fmt->chunksize;
159 uint32_t new_count = seek(seek_count, &cur_data, read_buffer, &decode_for_seek);
155 160
156 if (seek_time > 0)
157 seek_count = (uint64_t)seek_time * ci->id3->frequency
158 / (2000LL * fmt->chunksize);
159
160 new_count = seek(seek_count, &cur_data, read_buffer, &decode_for_seek);
161 newpos.pos = new_count * fmt->chunksize; 161 newpos.pos = new_count * fmt->chunksize;
162 newpos.samples = (newpos.pos / fmt->blockalign) * fmt->samplesperblock; 162 newpos.samples = new_count * blocksperchunk * fmt->samplesperblock;
163 return &newpos; 163 return &newpos;
164} 164}
165 165
diff --git a/apps/codecs/libpcm/dvi_adpcm.c b/apps/codecs/libpcm/dvi_adpcm.c
index 2784b21786..2e702ca394 100644
--- a/apps/codecs/libpcm/dvi_adpcm.c
+++ b/apps/codecs/libpcm/dvi_adpcm.c
@@ -54,12 +54,14 @@ static bool set_format(struct pcm_format *format)
54 return true; 54 return true;
55} 55}
56 56
57static struct pcm_pos *get_seek_pos(long seek_time, 57static struct pcm_pos *get_seek_pos(uint32_t seek_val, int seek_mode,
58 uint8_t *(*read_buffer)(size_t *realsize)) 58 uint8_t *(*read_buffer)(size_t *realsize))
59{ 59{
60 static struct pcm_pos newpos; 60 static struct pcm_pos newpos;
61 uint32_t newblock = ((uint64_t)seek_time * ci->id3->frequency) 61 uint32_t newblock = (seek_mode == PCM_SEEK_TIME) ?
62 / (1000LL * fmt->samplesperblock); 62 ((uint64_t)seek_val * ci->id3->frequency / 1000LL)
63 / fmt->samplesperblock :
64 seek_val / fmt->blockalign;
63 65
64 (void)read_buffer; 66 (void)read_buffer;
65 newpos.pos = newblock * fmt->blockalign; 67 newpos.pos = newblock * fmt->blockalign;
diff --git a/apps/codecs/libpcm/ieee_float.c b/apps/codecs/libpcm/ieee_float.c
index 7e3498edcb..639390bcd5 100644
--- a/apps/codecs/libpcm/ieee_float.c
+++ b/apps/codecs/libpcm/ieee_float.c
@@ -59,12 +59,14 @@ static bool set_format(struct pcm_format *format)
59 return true; 59 return true;
60} 60}
61 61
62static struct pcm_pos *get_seek_pos(long seek_time, 62static struct pcm_pos *get_seek_pos(uint32_t seek_val, int seek_mode,
63 uint8_t *(*read_buffer)(size_t *realsize)) 63 uint8_t *(*read_buffer)(size_t *realsize))
64{ 64{
65 static struct pcm_pos newpos; 65 static struct pcm_pos newpos;
66 uint32_t newblock = ((uint64_t)seek_time * ci->id3->frequency) 66 uint32_t newblock = (seek_mode == PCM_SEEK_TIME) ?
67 / (1000LL * fmt->samplesperblock); 67 ((uint64_t)seek_val * ci->id3->frequency / 1000LL)
68 / fmt->samplesperblock :
69 seek_val / fmt->blockalign;
68 70
69 (void)read_buffer; 71 (void)read_buffer;
70 newpos.pos = newblock * fmt->blockalign; 72 newpos.pos = newblock * fmt->blockalign;
diff --git a/apps/codecs/libpcm/itut_g711.c b/apps/codecs/libpcm/itut_g711.c
index 097dd5cc25..88ff5f59e6 100644
--- a/apps/codecs/libpcm/itut_g711.c
+++ b/apps/codecs/libpcm/itut_g711.c
@@ -139,12 +139,14 @@ static bool set_format(struct pcm_format *format)
139 return true; 139 return true;
140} 140}
141 141
142static struct pcm_pos *get_seek_pos(long seek_time, 142static struct pcm_pos *get_seek_pos(uint32_t seek_val, int seek_mode,
143 uint8_t *(*read_buffer)(size_t *realsize)) 143 uint8_t *(*read_buffer)(size_t *realsize))
144{ 144{
145 static struct pcm_pos newpos; 145 static struct pcm_pos newpos;
146 uint32_t newblock = ((uint64_t)seek_time * ci->id3->frequency) 146 uint32_t newblock = (seek_mode == PCM_SEEK_TIME) ?
147 / (1000LL * fmt->samplesperblock); 147 ((uint64_t)seek_val * ci->id3->frequency / 1000LL)
148 / fmt->samplesperblock :
149 seek_val / fmt->blockalign;
148 150
149 (void)read_buffer; 151 (void)read_buffer;
150 newpos.pos = newblock * fmt->blockalign; 152 newpos.pos = newblock * fmt->blockalign;
diff --git a/apps/codecs/libpcm/linear_pcm.c b/apps/codecs/libpcm/linear_pcm.c
index e58856efe8..5c3c140b8c 100644
--- a/apps/codecs/libpcm/linear_pcm.c
+++ b/apps/codecs/libpcm/linear_pcm.c
@@ -71,12 +71,14 @@ static bool set_format(struct pcm_format *format)
71 return true; 71 return true;
72} 72}
73 73
74static struct pcm_pos *get_seek_pos(long seek_time, 74static struct pcm_pos *get_seek_pos(uint32_t seek_val, int seek_mode,
75 uint8_t *(*read_buffer)(size_t *realsize)) 75 uint8_t *(*read_buffer)(size_t *realsize))
76{ 76{
77 static struct pcm_pos newpos; 77 static struct pcm_pos newpos;
78 uint32_t newblock = ((uint64_t)seek_time * ci->id3->frequency) 78 uint32_t newblock = (seek_mode == PCM_SEEK_TIME) ?
79 / (1000LL * fmt->samplesperblock); 79 ((uint64_t)seek_val * ci->id3->frequency / 1000LL)
80 / fmt->samplesperblock :
81 seek_val / fmt->blockalign;
80 82
81 (void)read_buffer; 83 (void)read_buffer;
82 newpos.pos = newblock * fmt->blockalign; 84 newpos.pos = newblock * fmt->blockalign;
diff --git a/apps/codecs/libpcm/ms_adpcm.c b/apps/codecs/libpcm/ms_adpcm.c
index 79365807ef..a385d6c99f 100644
--- a/apps/codecs/libpcm/ms_adpcm.c
+++ b/apps/codecs/libpcm/ms_adpcm.c
@@ -60,12 +60,14 @@ static bool set_format(struct pcm_format *format)
60 return true; 60 return true;
61} 61}
62 62
63static struct pcm_pos *get_seek_pos(long seek_time, 63static struct pcm_pos *get_seek_pos(uint32_t seek_val, int seek_mode,
64 uint8_t *(*read_buffer)(size_t *realsize)) 64 uint8_t *(*read_buffer)(size_t *realsize))
65{ 65{
66 static struct pcm_pos newpos; 66 static struct pcm_pos newpos;
67 uint32_t newblock = ((uint64_t)seek_time * ci->id3->frequency) 67 uint32_t newblock = (seek_mode == PCM_SEEK_TIME) ?
68 / (1000LL * fmt->samplesperblock); 68 ((uint64_t)seek_val * ci->id3->frequency / 1000LL)
69 / fmt->samplesperblock :
70 seek_val / fmt->blockalign;
69 71
70 (void)read_buffer; 72 (void)read_buffer;
71 newpos.pos = newblock * fmt->blockalign; 73 newpos.pos = newblock * fmt->blockalign;
diff --git a/apps/codecs/libpcm/pcm_common.h b/apps/codecs/libpcm/pcm_common.h
index 412ffbce0b..91c3ab7f1e 100644
--- a/apps/codecs/libpcm/pcm_common.h
+++ b/apps/codecs/libpcm/pcm_common.h
@@ -124,6 +124,9 @@ struct pcm_pos {
124 uint32_t samples; 124 uint32_t samples;
125}; 125};
126 126
127#define PCM_SEEK_TIME 0
128#define PCM_SEEK_POS 1
129
127struct pcm_codec { 130struct pcm_codec {
128 /* 131 /*
129 * sets the format speciffic RIFF/AIFF header information and checks the pcm_format. 132 * sets the format speciffic RIFF/AIFF header information and checks the pcm_format.
@@ -140,8 +143,12 @@ struct pcm_codec {
140 /* 143 /*
141 * get seek position 144 * get seek position
142 * 145 *
143 * [In] seek_time 146 * [In] seek_val
144 * seek time [ms] 147 * seek time [ms] or seek position
148 *
149 * [In] seek_mode
150 * if seek_mode sets PCM_SEEK_TIME, then seek_val means the seek time.
151 * if seek_mode sets PCM_SEEK_POS, then seek_val means the seek position.
145 * 152 *
146 * [In] read_buffer 153 * [In] read_buffer
147 * the function which reads the data from the file (chunksize bytes read). 154 * the function which reads the data from the file (chunksize bytes read).
@@ -149,7 +156,7 @@ struct pcm_codec {
149 * return 156 * return
150 * position after the seeking. 157 * position after the seeking.
151 */ 158 */
152 struct pcm_pos *(*get_seek_pos)(long seek_time, 159 struct pcm_pos *(*get_seek_pos)(uint32_t seek_val, int seek_mode,
153 uint8_t *(*read_buffer)(size_t *realsize)); 160 uint8_t *(*read_buffer)(size_t *realsize));
154 161
155 /* 162 /*
diff --git a/apps/codecs/libpcm/qt_ima_adpcm.c b/apps/codecs/libpcm/qt_ima_adpcm.c
index 003de22dd8..d7b3360eb3 100644
--- a/apps/codecs/libpcm/qt_ima_adpcm.c
+++ b/apps/codecs/libpcm/qt_ima_adpcm.c
@@ -57,12 +57,14 @@ static bool set_format(struct pcm_format *format)
57 return true; 57 return true;
58} 58}
59 59
60static struct pcm_pos *get_seek_pos(long seek_time, 60static struct pcm_pos *get_seek_pos(uint32_t seek_val, int seek_mode,
61 uint8_t *(*read_buffer)(size_t *realsize)) 61 uint8_t *(*read_buffer)(size_t *realsize))
62{ 62{
63 static struct pcm_pos newpos; 63 static struct pcm_pos newpos;
64 uint32_t newblock = ((uint64_t)seek_time * ci->id3->frequency) 64 uint32_t newblock = (seek_mode == PCM_SEEK_TIME) ?
65 / (1000LL * fmt->samplesperblock); 65 ((uint64_t)seek_val * ci->id3->frequency / 1000LL)
66 / fmt->samplesperblock :
67 seek_val / fmt->blockalign;
66 68
67 (void)read_buffer; 69 (void)read_buffer;
68 newpos.pos = newblock * fmt->blockalign; 70 newpos.pos = newblock * fmt->blockalign;
diff --git a/apps/codecs/libpcm/swf_adpcm.c b/apps/codecs/libpcm/swf_adpcm.c
index ebc4328c59..c440fd1303 100644
--- a/apps/codecs/libpcm/swf_adpcm.c
+++ b/apps/codecs/libpcm/swf_adpcm.c
@@ -81,20 +81,21 @@ static bool set_format(struct pcm_format *format)
81 return true; 81 return true;
82} 82}
83 83
84static struct pcm_pos *get_seek_pos(long seek_time, 84static struct pcm_pos *get_seek_pos(uint32_t seek_val, int seek_mode,
85 uint8_t *(*read_buffer)(size_t *realsize)) 85 uint8_t *(*read_buffer)(size_t *realsize))
86{ 86{
87 static struct pcm_pos newpos; 87 static struct pcm_pos newpos;
88 uint32_t chunkbits = blockbits; 88 uint32_t chunkbits = blockbits;
89 uint32_t seekbits = (((uint64_t)seek_time * ci->id3->frequency) 89 uint32_t seekblocks = (seek_mode == PCM_SEEK_TIME)?
90 / (1000LL * fmt->samplesperblock)) * blockbits + 2; 90 ((uint64_t)seek_val * ci->id3->frequency)
91 / (1000LL * fmt->samplesperblock) :
92 ((seek_val << 3) - 2) / blockbits;
93 uint32_t seekbits = seekblocks * blockbits + 2;
91 94
92 (void)read_buffer; 95 (void)read_buffer;
93 96
94 newpos.pos = seekbits >> 3; 97 newpos.pos = seekbits >> 3;
95 newpos.samples = (((uint64_t)seek_time * ci->id3->frequency) 98 newpos.samples = seekblocks * fmt->samplesperblock;
96 / (1000LL * fmt->samplesperblock))
97 * fmt->samplesperblock;
98 99
99 if (newpos.pos == 0) 100 if (newpos.pos == 0)
100 { 101 {
diff --git a/apps/codecs/libpcm/yamaha_adpcm.c b/apps/codecs/libpcm/yamaha_adpcm.c
index 0b997ad776..f1fb9b68ae 100644
--- a/apps/codecs/libpcm/yamaha_adpcm.c
+++ b/apps/codecs/libpcm/yamaha_adpcm.c
@@ -214,15 +214,14 @@ static int decode_for_seek(const uint8_t *inbuf, size_t inbufsize)
214 return CODEC_OK; 214 return CODEC_OK;
215} 215}
216 216
217static struct pcm_pos *get_seek_pos(long seek_time, 217static struct pcm_pos *get_seek_pos(uint32_t seek_val, int seek_mode,
218 uint8_t *(*read_buffer)(size_t *realsize)) 218 uint8_t *(*read_buffer)(size_t *realsize))
219{ 219{
220 static struct pcm_pos newpos; 220 static struct pcm_pos newpos;
221 uint32_t new_count= 0; 221 uint32_t new_count = (seek_mode == PCM_SEEK_TIME)?
222 222 ((uint64_t)seek_val * ci->id3->frequency / 1000LL)
223 if (seek_time > 0) 223 / (blocksperchunk * fmt->samplesperblock) :
224 new_count = ((uint64_t)seek_time * ci->id3->frequency 224 seek_val / fmt->chunksize;
225 / (1000LL * fmt->samplesperblock)) / blocksperchunk;
226 225
227 if (!has_block_header) 226 if (!has_block_header)
228 { 227 {
diff --git a/apps/codecs/smaf.c b/apps/codecs/smaf.c
index 33a2a4b403..6763e95001 100644
--- a/apps/codecs/smaf.c
+++ b/apps/codecs/smaf.c
@@ -409,6 +409,28 @@ next_track:
409 ci->seek_buffer(firstblockposn); 409 ci->seek_buffer(firstblockposn);
410 ci->seek_complete(); 410 ci->seek_complete();
411 411
412 /* make sure we're at the correct offset */
413 if (bytesdone > (uint32_t) firstblockposn)
414 {
415 /* Round down to previous block */
416 struct pcm_pos *newpos = codec->get_seek_pos(bytesdone - firstblockposn,
417 PCM_SEEK_POS, &read_buffer);
418
419 if (newpos->pos > format.numbytes)
420 goto done;
421 if (ci->seek_buffer(firstblockposn + newpos->pos))
422 {
423 bytesdone = newpos->pos;
424 decodedsamples = newpos->samples;
425 }
426 ci->seek_complete();
427 }
428 else
429 {
430 /* already where we need to be */
431 bytesdone = 0;
432 }
433
412 /* The main decoder loop */ 434 /* The main decoder loop */
413 endofstream = 0; 435 endofstream = 0;
414 436
@@ -418,7 +440,8 @@ next_track:
418 break; 440 break;
419 441
420 if (ci->seek_time) { 442 if (ci->seek_time) {
421 struct pcm_pos *newpos = codec->get_seek_pos(ci->seek_time, &read_buffer); 443 struct pcm_pos *newpos = codec->get_seek_pos(ci->seek_time, PCM_SEEK_TIME,
444 &read_buffer);
422 445
423 if (newpos->pos > format.numbytes) 446 if (newpos->pos > format.numbytes)
424 break; 447 break;
diff --git a/apps/codecs/vox.c b/apps/codecs/vox.c
index 21742e16d9..ff5d571e8d 100644
--- a/apps/codecs/vox.c
+++ b/apps/codecs/vox.c
@@ -52,9 +52,8 @@ enum codec_status codec_main(void)
52 int bufcount; 52 int bufcount;
53 int endofstream; 53 int endofstream;
54 uint8_t *voxbuf; 54 uint8_t *voxbuf;
55 off_t firstblockposn; /* position of the first block in file */ 55 off_t firstblockposn = 0; /* position of the first block in file */
56 const struct pcm_codec *codec; 56 const struct pcm_codec *codec;
57 int offset = 0;
58 57
59 /* Generic codec initialisation */ 58 /* Generic codec initialisation */
60 ci->configure(DSP_SET_SAMPLE_DEPTH, PCM_OUTPUT_DEPTH-1); 59 ci->configure(DSP_SET_SAMPLE_DEPTH, PCM_OUTPUT_DEPTH-1);
@@ -70,7 +69,10 @@ next_track:
70 ci->sleep(1); 69 ci->sleep(1);
71 70
72 codec_set_replaygain(ci->id3); 71 codec_set_replaygain(ci->id3);
73 72
73 /* Need to save offset for later use (cleared indirectly by advance_buffer) */
74 bytesdone = ci->id3->offset;
75
74 ci->memset(&format, 0, sizeof(struct pcm_format)); 76 ci->memset(&format, 0, sizeof(struct pcm_format));
75 77
76 /* set format */ 78 /* set format */
@@ -80,12 +82,9 @@ next_track:
80 format.blockalign = 1; 82 format.blockalign = 1;
81 83
82 /* advance to first WAVE chunk */ 84 /* advance to first WAVE chunk */
83 ci->advance_buffer(offset); 85 firstblockposn = 0;
84
85 firstblockposn = offset;
86
87 decodedsamples = 0; 86 decodedsamples = 0;
88 bytesdone = 0; 87 ci->advance_buffer(firstblockposn);
89 88
90 /* 89 /*
91 * get codec 90 * get codec
@@ -124,6 +123,25 @@ next_track:
124 ci->configure(DSP_SWITCH_FREQUENCY, ci->id3->frequency); 123 ci->configure(DSP_SWITCH_FREQUENCY, ci->id3->frequency);
125 ci->configure(DSP_SET_STEREO_MODE, STEREO_MONO); 124 ci->configure(DSP_SET_STEREO_MODE, STEREO_MONO);
126 125
126 /* make sure we're at the correct offset */
127 if (bytesdone > (uint32_t) firstblockposn) {
128 /* Round down to previous block */
129 struct pcm_pos *newpos = codec->get_seek_pos(bytesdone - firstblockposn,
130 PCM_SEEK_POS, &read_buffer);
131
132 if (newpos->pos > format.numbytes)
133 goto done;
134 if (ci->seek_buffer(firstblockposn + newpos->pos))
135 {
136 bytesdone = newpos->pos;
137 decodedsamples = newpos->samples;
138 }
139 ci->seek_complete();
140 } else {
141 /* already where we need to be */
142 bytesdone = 0;
143 }
144
127 /* The main decoder loop */ 145 /* The main decoder loop */
128 endofstream = 0; 146 endofstream = 0;
129 147
@@ -134,7 +152,8 @@ next_track:
134 } 152 }
135 153
136 if (ci->seek_time) { 154 if (ci->seek_time) {
137 struct pcm_pos *newpos = codec->get_seek_pos(ci->seek_time, &read_buffer); 155 struct pcm_pos *newpos = codec->get_seek_pos(ci->seek_time, PCM_SEEK_TIME,
156 &read_buffer);
138 157
139 if (newpos->pos > format.numbytes) 158 if (newpos->pos > format.numbytes)
140 break; 159 break;
diff --git a/apps/codecs/wav.c b/apps/codecs/wav.c
index 14d7136592..e286f4dc6a 100644
--- a/apps/codecs/wav.c
+++ b/apps/codecs/wav.c
@@ -374,10 +374,17 @@ next_track:
374 /* make sure we're at the correct offset */ 374 /* make sure we're at the correct offset */
375 if (bytesdone > (uint32_t) firstblockposn) { 375 if (bytesdone > (uint32_t) firstblockposn) {
376 /* Round down to previous block */ 376 /* Round down to previous block */
377 uint32_t offset = bytesdone - bytesdone % format.blockalign; 377 struct pcm_pos *newpos = codec->get_seek_pos(bytesdone - firstblockposn,
378 PCM_SEEK_POS, &read_buffer);
378 379
379 ci->advance_buffer(offset-firstblockposn); 380 if (newpos->pos > format.numbytes)
380 bytesdone = offset - firstblockposn; 381 goto done;
382 if (ci->seek_buffer(firstblockposn + newpos->pos))
383 {
384 bytesdone = newpos->pos;
385 decodedsamples = newpos->samples;
386 }
387 ci->seek_complete();
381 } else { 388 } else {
382 /* already where we need to be */ 389 /* already where we need to be */
383 bytesdone = 0; 390 bytesdone = 0;
@@ -393,7 +400,8 @@ next_track:
393 } 400 }
394 401
395 if (ci->seek_time) { 402 if (ci->seek_time) {
396 struct pcm_pos *newpos = codec->get_seek_pos(ci->seek_time, &read_buffer); 403 struct pcm_pos *newpos = codec->get_seek_pos(ci->seek_time, PCM_SEEK_TIME,
404 &read_buffer);
397 405
398 if (newpos->pos > format.numbytes) 406 if (newpos->pos > format.numbytes)
399 break; 407 break;
diff --git a/apps/codecs/wav64.c b/apps/codecs/wav64.c
index 1913dafe5c..c06f78c802 100644
--- a/apps/codecs/wav64.c
+++ b/apps/codecs/wav64.c
@@ -380,10 +380,17 @@ next_track:
380 /* make sure we're at the correct offset */ 380 /* make sure we're at the correct offset */
381 if (bytesdone > (uint32_t) firstblockposn) { 381 if (bytesdone > (uint32_t) firstblockposn) {
382 /* Round down to previous block */ 382 /* Round down to previous block */
383 uint32_t offset = bytesdone - bytesdone % format.blockalign; 383 struct pcm_pos *newpos = codec->get_seek_pos(bytesdone - firstblockposn,
384 PCM_SEEK_POS, &read_buffer);
384 385
385 ci->advance_buffer(offset-firstblockposn); 386 if (newpos->pos > format.numbytes)
386 bytesdone = offset - firstblockposn; 387 goto done;
388 if (ci->seek_buffer(firstblockposn + newpos->pos))
389 {
390 bytesdone = newpos->pos;
391 decodedsamples = newpos->samples;
392 }
393 ci->seek_complete();
387 } else { 394 } else {
388 /* already where we need to be */ 395 /* already where we need to be */
389 bytesdone = 0; 396 bytesdone = 0;
@@ -399,7 +406,8 @@ next_track:
399 } 406 }
400 407
401 if (ci->seek_time) { 408 if (ci->seek_time) {
402 struct pcm_pos *newpos = codec->get_seek_pos(ci->seek_time, &read_buffer); 409 struct pcm_pos *newpos = codec->get_seek_pos(ci->seek_time, PCM_SEEK_TIME,
410 &read_buffer);
403 411
404 if (newpos->pos > format.numbytes) 412 if (newpos->pos > format.numbytes)
405 break; 413 break;
diff --git a/apps/metadata/vox.c b/apps/metadata/vox.c
index 3f4e5d553c..f6bc849a88 100644
--- a/apps/metadata/vox.c
+++ b/apps/metadata/vox.c
@@ -40,6 +40,7 @@ bool get_vox_metadata(int fd, struct mp3entry* id3)
40 * bitspersample: 4 40 * bitspersample: 4
41 */ 41 */
42 id3->frequency = 8000; 42 id3->frequency = 8000;
43 id3->bitrate = 8000 * 4 / 1000;
43 id3->vbr = false; /* All VOX files are CBR */ 44 id3->vbr = false; /* All VOX files are CBR */
44 id3->filesize = filesize(fd); 45 id3->filesize = filesize(fd);
45 id3->length = id3->filesize >> 2; 46 id3->length = id3->filesize >> 2;