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
This commit is contained in:
Yoshihisa Uchida 2010-03-22 10:02:05 +00:00
parent 20fccd8489
commit 7a3822c8b0
17 changed files with 188 additions and 69 deletions

View file

@ -44,6 +44,7 @@ static const int index_table[] ICONST_ATTR = {
};
static struct adpcm_data cur_data;
static int blocksperchunk;
static struct pcm_format *fmt;
@ -71,7 +72,8 @@ static bool set_format(struct pcm_format *format)
fmt->samplesperblock = 2;
/* chunksize = about 1/32[sec] data */
fmt->chunksize = ci->id3->frequency >> 6;
blocksperchunk = ci->id3->frequency >> 6;
fmt->chunksize = blocksperchunk * fmt->blockalign;
max_chunk_count = (uint64_t)ci->id3->length * ci->id3->frequency
/ (2000LL * fmt->chunksize);
@ -146,20 +148,18 @@ static int decode_for_seek(const uint8_t *inbuf, size_t inbufsize)
return CODEC_OK;
}
static struct pcm_pos *get_seek_pos(long seek_time,
static struct pcm_pos *get_seek_pos(uint32_t seek_val, int seek_mode,
uint8_t *(*read_buffer)(size_t *realsize))
{
static struct pcm_pos newpos;
uint32_t seek_count = 0;
uint32_t new_count;
uint32_t seek_count = (seek_mode == PCM_SEEK_TIME)?
((uint64_t)seek_val * ci->id3->frequency / 1000LL)
/ (blocksperchunk * fmt->samplesperblock) :
seek_val / fmt->chunksize;
uint32_t new_count = seek(seek_count, &cur_data, read_buffer, &decode_for_seek);
if (seek_time > 0)
seek_count = (uint64_t)seek_time * ci->id3->frequency
/ (2000LL * fmt->chunksize);
new_count = seek(seek_count, &cur_data, read_buffer, &decode_for_seek);
newpos.pos = new_count * fmt->chunksize;
newpos.samples = (newpos.pos / fmt->blockalign) * fmt->samplesperblock;
newpos.samples = new_count * blocksperchunk * fmt->samplesperblock;
return &newpos;
}

View file

@ -54,12 +54,14 @@ static bool set_format(struct pcm_format *format)
return true;
}
static struct pcm_pos *get_seek_pos(long seek_time,
static struct pcm_pos *get_seek_pos(uint32_t seek_val, int seek_mode,
uint8_t *(*read_buffer)(size_t *realsize))
{
static struct pcm_pos newpos;
uint32_t newblock = ((uint64_t)seek_time * ci->id3->frequency)
/ (1000LL * fmt->samplesperblock);
uint32_t newblock = (seek_mode == PCM_SEEK_TIME) ?
((uint64_t)seek_val * ci->id3->frequency / 1000LL)
/ fmt->samplesperblock :
seek_val / fmt->blockalign;
(void)read_buffer;
newpos.pos = newblock * fmt->blockalign;

View file

@ -59,12 +59,14 @@ static bool set_format(struct pcm_format *format)
return true;
}
static struct pcm_pos *get_seek_pos(long seek_time,
static struct pcm_pos *get_seek_pos(uint32_t seek_val, int seek_mode,
uint8_t *(*read_buffer)(size_t *realsize))
{
static struct pcm_pos newpos;
uint32_t newblock = ((uint64_t)seek_time * ci->id3->frequency)
/ (1000LL * fmt->samplesperblock);
uint32_t newblock = (seek_mode == PCM_SEEK_TIME) ?
((uint64_t)seek_val * ci->id3->frequency / 1000LL)
/ fmt->samplesperblock :
seek_val / fmt->blockalign;
(void)read_buffer;
newpos.pos = newblock * fmt->blockalign;

View file

@ -139,12 +139,14 @@ static bool set_format(struct pcm_format *format)
return true;
}
static struct pcm_pos *get_seek_pos(long seek_time,
static struct pcm_pos *get_seek_pos(uint32_t seek_val, int seek_mode,
uint8_t *(*read_buffer)(size_t *realsize))
{
static struct pcm_pos newpos;
uint32_t newblock = ((uint64_t)seek_time * ci->id3->frequency)
/ (1000LL * fmt->samplesperblock);
uint32_t newblock = (seek_mode == PCM_SEEK_TIME) ?
((uint64_t)seek_val * ci->id3->frequency / 1000LL)
/ fmt->samplesperblock :
seek_val / fmt->blockalign;
(void)read_buffer;
newpos.pos = newblock * fmt->blockalign;

View file

@ -71,12 +71,14 @@ static bool set_format(struct pcm_format *format)
return true;
}
static struct pcm_pos *get_seek_pos(long seek_time,
static struct pcm_pos *get_seek_pos(uint32_t seek_val, int seek_mode,
uint8_t *(*read_buffer)(size_t *realsize))
{
static struct pcm_pos newpos;
uint32_t newblock = ((uint64_t)seek_time * ci->id3->frequency)
/ (1000LL * fmt->samplesperblock);
uint32_t newblock = (seek_mode == PCM_SEEK_TIME) ?
((uint64_t)seek_val * ci->id3->frequency / 1000LL)
/ fmt->samplesperblock :
seek_val / fmt->blockalign;
(void)read_buffer;
newpos.pos = newblock * fmt->blockalign;

View file

@ -60,12 +60,14 @@ static bool set_format(struct pcm_format *format)
return true;
}
static struct pcm_pos *get_seek_pos(long seek_time,
static struct pcm_pos *get_seek_pos(uint32_t seek_val, int seek_mode,
uint8_t *(*read_buffer)(size_t *realsize))
{
static struct pcm_pos newpos;
uint32_t newblock = ((uint64_t)seek_time * ci->id3->frequency)
/ (1000LL * fmt->samplesperblock);
uint32_t newblock = (seek_mode == PCM_SEEK_TIME) ?
((uint64_t)seek_val * ci->id3->frequency / 1000LL)
/ fmt->samplesperblock :
seek_val / fmt->blockalign;
(void)read_buffer;
newpos.pos = newblock * fmt->blockalign;

View file

@ -124,6 +124,9 @@ struct pcm_pos {
uint32_t samples;
};
#define PCM_SEEK_TIME 0
#define PCM_SEEK_POS 1
struct pcm_codec {
/*
* sets the format speciffic RIFF/AIFF header information and checks the pcm_format.
@ -140,8 +143,12 @@ struct pcm_codec {
/*
* get seek position
*
* [In] seek_time
* seek time [ms]
* [In] seek_val
* seek time [ms] or seek position
*
* [In] seek_mode
* if seek_mode sets PCM_SEEK_TIME, then seek_val means the seek time.
* if seek_mode sets PCM_SEEK_POS, then seek_val means the seek position.
*
* [In] read_buffer
* the function which reads the data from the file (chunksize bytes read).
@ -149,7 +156,7 @@ struct pcm_codec {
* return
* position after the seeking.
*/
struct pcm_pos *(*get_seek_pos)(long seek_time,
struct pcm_pos *(*get_seek_pos)(uint32_t seek_val, int seek_mode,
uint8_t *(*read_buffer)(size_t *realsize));
/*

View file

@ -57,12 +57,14 @@ static bool set_format(struct pcm_format *format)
return true;
}
static struct pcm_pos *get_seek_pos(long seek_time,
static struct pcm_pos *get_seek_pos(uint32_t seek_val, int seek_mode,
uint8_t *(*read_buffer)(size_t *realsize))
{
static struct pcm_pos newpos;
uint32_t newblock = ((uint64_t)seek_time * ci->id3->frequency)
/ (1000LL * fmt->samplesperblock);
uint32_t newblock = (seek_mode == PCM_SEEK_TIME) ?
((uint64_t)seek_val * ci->id3->frequency / 1000LL)
/ fmt->samplesperblock :
seek_val / fmt->blockalign;
(void)read_buffer;
newpos.pos = newblock * fmt->blockalign;

View file

@ -81,20 +81,21 @@ static bool set_format(struct pcm_format *format)
return true;
}
static struct pcm_pos *get_seek_pos(long seek_time,
static struct pcm_pos *get_seek_pos(uint32_t seek_val, int seek_mode,
uint8_t *(*read_buffer)(size_t *realsize))
{
static struct pcm_pos newpos;
uint32_t chunkbits = blockbits;
uint32_t seekbits = (((uint64_t)seek_time * ci->id3->frequency)
/ (1000LL * fmt->samplesperblock)) * blockbits + 2;
uint32_t chunkbits = blockbits;
uint32_t seekblocks = (seek_mode == PCM_SEEK_TIME)?
((uint64_t)seek_val * ci->id3->frequency)
/ (1000LL * fmt->samplesperblock) :
((seek_val << 3) - 2) / blockbits;
uint32_t seekbits = seekblocks * blockbits + 2;
(void)read_buffer;
newpos.pos = seekbits >> 3;
newpos.samples = (((uint64_t)seek_time * ci->id3->frequency)
/ (1000LL * fmt->samplesperblock))
* fmt->samplesperblock;
newpos.samples = seekblocks * fmt->samplesperblock;
if (newpos.pos == 0)
{

View file

@ -214,15 +214,14 @@ static int decode_for_seek(const uint8_t *inbuf, size_t inbufsize)
return CODEC_OK;
}
static struct pcm_pos *get_seek_pos(long seek_time,
static struct pcm_pos *get_seek_pos(uint32_t seek_val, int seek_mode,
uint8_t *(*read_buffer)(size_t *realsize))
{
static struct pcm_pos newpos;
uint32_t new_count= 0;
if (seek_time > 0)
new_count = ((uint64_t)seek_time * ci->id3->frequency
/ (1000LL * fmt->samplesperblock)) / blocksperchunk;
uint32_t new_count = (seek_mode == PCM_SEEK_TIME)?
((uint64_t)seek_val * ci->id3->frequency / 1000LL)
/ (blocksperchunk * fmt->samplesperblock) :
seek_val / fmt->chunksize;
if (!has_block_header)
{