diff options
author | 2010-07-04 13:00:04 +0200 | |
---|---|---|
committer | 2010-07-04 13:00:04 +0200 | |
commit | 050417b22e9bd0e9f73b6444727bd725c738157a (patch) | |
tree | c6fa92603e69a47d45b1baea31db8340e0e23c6c /plugins | |
parent | e6013001a3e730497e4606add4aff3ac743aedc4 (diff) |
ao plugin: psf/psf2/spu seeking
Diffstat (limited to 'plugins')
-rwxr-xr-x | plugins/ao/ao.h | 2 | ||||
-rw-r--r-- | plugins/ao/eng_psf/eng_spu.c | 36 | ||||
-rw-r--r-- | plugins/ao/main.c | 5 | ||||
-rw-r--r-- | plugins/ao/plugin.c | 33 |
4 files changed, 57 insertions, 19 deletions
diff --git a/plugins/ao/ao.h b/plugins/ao/ao.h index f3503df8..44320286 100755 --- a/plugins/ao/ao.h +++ b/plugins/ao/ao.h @@ -212,4 +212,6 @@ int ao_get_info (uint32 type, void *handle, ao_display_info *info); int ao_decode (uint32 type, void *handle, int16 *buffer, uint32 size); +int ao_command (uint32 type, void *handle, int32 command, int32 param); + #endif // AO_H diff --git a/plugins/ao/eng_psf/eng_spu.c b/plugins/ao/eng_psf/eng_spu.c index 2adb9470..dbda70ac 100644 --- a/plugins/ao/eng_psf/eng_spu.c +++ b/plugins/ao/eng_psf/eng_spu.c @@ -291,20 +291,28 @@ int32 spu_command(void *handle, int32 command, int32 parameter) case COMMAND_RESTART: { - s->song_ptr = &s->start_of_file[0x80200]; - - if (s->old_fmt) - { - s->num_events = s->song_ptr[4] | s->song_ptr[5]<<8 | s->song_ptr[6]<<16 | s->song_ptr[7]<<24; - } - else - { - s->end_tick = s->song_ptr[0] | s->song_ptr[1]<<8 | s->song_ptr[2]<<16 | s->song_ptr[3]<<24; - s->cur_tick = s->song_ptr[4] | s->song_ptr[5]<<8 | s->song_ptr[6]<<16 | s->song_ptr[7]<<24; - } - - s->song_ptr += 8; - s->cur_event = 0; + printf ("eng_spu restart\n"); + uint8 *buffer = s->start_of_file; + int i; + uint16 reg; + + // apply the register image + for (i = 0; i < 512; i += 2) + { + reg = buffer[0x80000+i] | buffer[0x80000+i+1]<<8; + + SPUwriteRegister(s->mips_cpu, (i/2)+0x1f801c00, reg); + } + + if (!s->old_fmt) + { + s->end_tick = buffer[0x80200] | buffer[0x80201]<<8 | buffer[0x80202]<<16 | buffer[0x80203]<<24; + s->cur_tick = buffer[0x80204] | buffer[0x80205]<<8 | buffer[0x80206]<<16 | buffer[0x80207]<<24; + s->next_tick = s->cur_tick; + } + + s->song_ptr = &buffer[0x80208]; + s->cur_event = 0; return AO_SUCCESS; } break; diff --git a/plugins/ao/main.c b/plugins/ao/main.c index 1f24628e..073347d8 100644 --- a/plugins/ao/main.c +++ b/plugins/ao/main.c @@ -254,3 +254,8 @@ ao_decode (uint32 type, void *handle, int16 *buffer, uint32 size) { (*types[type].gen)(handle, buffer, size); return size; } + +int +ao_command (uint32 type, void *handle, int32 command, int32 param) { + return (*types[type].command)(handle, command, param); +} diff --git a/plugins/ao/plugin.c b/plugins/ao/plugin.c index 06500696..5f6a12bf 100644 --- a/plugins/ao/plugin.c +++ b/plugins/ao/plugin.c @@ -43,6 +43,8 @@ typedef struct { size_t filesize; char buffer[735*4]; // psf2 decoder only works with 735 samples buffer int remaining; + int skipsamples; + float duration; } aoplug_info_t; static DB_fileinfo_t * @@ -62,6 +64,7 @@ aoplug_init (DB_fileinfo_t *_info, DB_playItem_t *it) { _info->samplerate = 44100; _info->readpos = 0; _info->plugin = &plugin; + info->duration = deadbeef->pl_get_item_duration (it); DB_FILE *file = deadbeef->fopen (it->fname); if (!file) { @@ -114,13 +117,26 @@ aoplug_free (DB_fileinfo_t *_info) { static int aoplug_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) { -// printf ("aoplug_read_int16 %d samples\n", size/4); aoplug_info_t *info = (aoplug_info_t *)_info; +// printf ("aoplug_read_int16 %d samples, curr %d, end %d\n", size/4, info->currentsample, (int)(info->duration * _info->samplerate)); + + if (info->currentsample >= info->duration * _info->samplerate) { + return 0; + } int initsize = size; while (size > 0) { if (info->remaining > 0) { + if (info->skipsamples > 0) { + int n = min (info->skipsamples, info->remaining); + if (info->remaining > n) { + memmove (info->buffer, info->buffer+n*4, (info->remaining - n)*4); + } + info->remaining -= n; + info->skipsamples -= n; + continue; + } int n = size / 4; n = min (info->remaining, n); memcpy (bytes, info->buffer, n * 4); @@ -136,14 +152,21 @@ aoplug_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) { info->remaining = 735; } } - info->currentsample += size / (_info->channels * _info->bps/8); + info->currentsample += (initsize-size) / (_info->channels * _info->bps/8); return initsize-size; } static int aoplug_seek_sample (DB_fileinfo_t *_info, int sample) { aoplug_info_t *info = (aoplug_info_t *)_info; - + if (sample > info->currentsample) { + info->skipsamples = sample-info->currentsample; + } + else { + // restart song + ao_command (info->type, info->decoder, COMMAND_RESTART, 0); + info->skipsamples = sample; + } info->currentsample = sample; _info->readpos = (float)sample / _info->samplerate; return 0; @@ -221,10 +244,10 @@ aoplug_insert (DB_playItem_t *after, const char *fname) { else if (!strcasecmp (ext, "ssf")) { it->filetype = filetypes[3]; } - else if (!strcasecmp (ext, "dsf") || !strcasecmp (ext, "ninidsf")) { + else if (!strcasecmp (ext, "dsf") || !strcasecmp (ext, "minidsf")) { it->filetype = filetypes[5]; } - else if (!strcasecmp (ext, "qsf")) { + else if (!strcasecmp (ext, "qsf") || !strcasecmp (ext, "miniqsf")) { it->filetype = filetypes[4]; } } |