summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorGravatar Alexey Yakovenko <wakeroid@gmail.com>2010-07-04 13:00:04 +0200
committerGravatar Alexey Yakovenko <wakeroid@gmail.com>2010-07-04 13:00:04 +0200
commit050417b22e9bd0e9f73b6444727bd725c738157a (patch)
treec6fa92603e69a47d45b1baea31db8340e0e23c6c /plugins
parente6013001a3e730497e4606add4aff3ac743aedc4 (diff)
ao plugin: psf/psf2/spu seeking
Diffstat (limited to 'plugins')
-rwxr-xr-xplugins/ao/ao.h2
-rw-r--r--plugins/ao/eng_psf/eng_spu.c36
-rw-r--r--plugins/ao/main.c5
-rw-r--r--plugins/ao/plugin.c33
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];
}
}