summaryrefslogtreecommitdiff
path: root/plugins/vorbis
diff options
context:
space:
mode:
authorGravatar Alexey Yakovenko <wakeroid@gmail.com>2010-01-13 22:44:33 +0100
committerGravatar Alexey Yakovenko <wakeroid@gmail.com>2010-01-13 22:44:33 +0100
commit00ddc698b1825626cb7671c75d8225ce90979f9c (patch)
tree53bc865b303b9cb655a8eb6df278596dff7fd442 /plugins/vorbis
parent5abf61660956619361e5b6fd544c6fb2b968ec10 (diff)
ported vorbis plugin to new API
Diffstat (limited to 'plugins/vorbis')
-rw-r--r--plugins/vorbis/vorbis.c210
1 files changed, 113 insertions, 97 deletions
diff --git a/plugins/vorbis/vorbis.c b/plugins/vorbis/vorbis.c
index d0620d6e..aff400ab 100644
--- a/plugins/vorbis/vorbis.c
+++ b/plugins/vorbis/vorbis.c
@@ -34,18 +34,18 @@
static DB_decoder_t plugin;
static DB_functions_t *deadbeef;
-static DB_FILE *file;
-static OggVorbis_File vorbis_file;
-static vorbis_info *vi;
-static int cur_bit_stream;
-static int startsample;
-static int endsample;
-static int currentsample;
-static int last_comment_update;
-static DB_playItem_t *ptrack;
-
-static void
-cvorbis_free (void);
+typedef struct {
+ DB_fileinfo_t info;
+ DB_FILE *file;
+ OggVorbis_File vorbis_file;
+ vorbis_info *vi;
+ int cur_bit_stream;
+ int startsample;
+ int endsample;
+ int currentsample;
+ int last_comment_update;
+ DB_playItem_t *ptrack; // FIXME: addref that
+} ogg_info_t;
static size_t
cvorbis_fread (void *ptr, size_t size, size_t nmemb, void *datasource) {
@@ -121,21 +121,26 @@ update_vorbis_comments (DB_playItem_t *it, vorbis_comment *vc) {
deadbeef->pl_add_meta (it, "title", NULL);
}
-static int
+static DB_fileinfo_t *
cvorbis_init (DB_playItem_t *it) {
- file = NULL;
- vi = NULL;
- cur_bit_stream = -1;
- ptrack = it;
-
- file = deadbeef->fopen (it->fname);
- if (!file) {
- return -1;
+ DB_fileinfo_t *_info = malloc (sizeof (ogg_info_t));
+ ogg_info_t *info = (ogg_info_t *)_info;
+ memset (info, 0, sizeof (ogg_info_t));
+ info->file = NULL;
+ info->vi = NULL;
+ info->cur_bit_stream = -1;
+ info->ptrack = it;
+ // FIXME: add reference to that one
+ // deadbeef->pl_item_ref (it);
+
+ info->file = deadbeef->fopen (it->fname);
+ if (!info->file) {
+ trace ("ogg: failed to open file %s\n", it->fname);
+ plugin.free (_info);
+ return NULL;
}
- memset (&plugin.info, 0, sizeof (plugin.info));
-
- int ln = deadbeef->fgetlength (file);
- if (file->vfs->streaming && ln == -1) {
+ int ln = deadbeef->fgetlength (info->file);
+ if (info->file->vfs->streaming && ln == -1) {
ov_callbacks ovcb = {
.read_func = cvorbis_fread,
.seek_func = NULL,
@@ -144,11 +149,11 @@ cvorbis_init (DB_playItem_t *it) {
};
trace ("calling ov_open_callbacks\n");
- int err = ov_open_callbacks (file, &vorbis_file, NULL, 0, ovcb);
+ int err = ov_open_callbacks (info->file, &info->vorbis_file, NULL, 0, ovcb);
if (err != 0) {
trace ("ov_open_callbacks returned %d\n", err);
- plugin.free ();
- return -1;
+ plugin.free (_info);
+ return NULL;
}
deadbeef->pl_set_item_duration (it, -1);
}
@@ -162,85 +167,93 @@ cvorbis_init (DB_playItem_t *it) {
};
trace ("calling ov_open_callbacks\n");
- int err = ov_open_callbacks (file, &vorbis_file, NULL, 0, ovcb);
+ int err = ov_open_callbacks (info->file, &info->vorbis_file, NULL, 0, ovcb);
if (err != 0) {
trace ("ov_open_callbacks returned %d\n", err);
- plugin.free ();
- return -1;
+ plugin.free (_info);
+ return NULL;
}
// deadbeef->pl_set_item_duration (it, ov_time_total (&vorbis_file, -1));
}
- vi = ov_info (&vorbis_file, -1);
- if (!vi) { // not a vorbis stream
- cvorbis_free ();
+ info->vi = ov_info (&info->vorbis_file, -1);
+ if (!info->vi) { // not a vorbis stream
trace ("not a vorbis stream\n");
- return -1;
+ plugin.free (_info);
+ return NULL;
}
- plugin.info.bps = 16;
- //plugin.info.dataSize = ov_pcm_total (&vorbis_file, -1) * vi->channels * 2;
- plugin.info.channels = vi->channels;
- plugin.info.samplerate = vi->rate;
- plugin.info.readpos = 0;
- currentsample = 0;
- if (!file->vfs->streaming) {
+ _info->plugin = &plugin;
+ _info->bps = 16;
+ //_info->dataSize = ov_pcm_total (&vorbis_file, -1) * vi->channels * 2;
+ _info->channels = info->vi->channels;
+ _info->samplerate = info->vi->rate;
+ _info->readpos = 0;
+ info->currentsample = 0;
+ if (!info->file->vfs->streaming) {
if (it->endsample > 0) {
- startsample = it->startsample;
- endsample = it->endsample;
- plugin.seek_sample (0);
+ info->startsample = it->startsample;
+ info->endsample = it->endsample;
+ plugin.seek_sample (_info, 0);
}
else {
- startsample = 0;
- endsample = ov_pcm_total (&vorbis_file, -1)-1;
+ info->startsample = 0;
+ info->endsample = ov_pcm_total (&info->vorbis_file, -1)-1;
}
}
else {
- startsample = 0;
+ info->startsample = 0;
if (deadbeef->pl_get_item_duration (it) < 0) {
- endsample = -1;
+ info->endsample = -1;
}
else {
- endsample = ov_pcm_total (&vorbis_file, -1)-1;
+ info->endsample = ov_pcm_total (&info->vorbis_file, -1)-1;
}
- vorbis_comment *vc = ov_comment (&vorbis_file, -1);
+ vorbis_comment *vc = ov_comment (&info->vorbis_file, -1);
update_vorbis_comments (it, vc);
}
- return 0;
+ return _info;
}
static void
-cvorbis_free (void) {
- if (file) {
- ptrack = NULL;
- ov_clear (&vorbis_file);
- //fclose (file); //-- ov_clear closes it
- file = NULL;
- vi = NULL;
+cvorbis_free (DB_fileinfo_t *_info) {
+ ogg_info_t *info = (ogg_info_t *)_info;
+ if (info) {
+ if (info->file) {
+ info->ptrack = NULL;
+ // FIXME: unref that
+ // if (info->ptrack) {
+ // deadbeef->pl_item_unref (info->ptrack);
+ // }
+ ov_clear (&info->vorbis_file);
+ //fclose (file); //-- ov_clear closes it
+ }
+ free (info);
}
}
static int
-cvorbis_read (char *bytes, int size) {
+cvorbis_read (DB_fileinfo_t *_info, char *bytes, int size) {
+ ogg_info_t *info = (ogg_info_t *)_info;
// trace ("cvorbis_read %d bytes\n", size);
- if (!file->vfs->streaming) {
- if (currentsample + size / (2 * plugin.info.channels) > endsample) {
- size = (endsample - currentsample + 1) * 2 * plugin.info.channels;
- trace ("size truncated to %d bytes, cursample=%d, endsample=%d, totalsamples=%d\n", size, currentsample, endsample, ov_pcm_total (&vorbis_file, -1));
+ if (!info->file->vfs->streaming) {
+ if (info->currentsample + size / (2 * _info->channels) > info->endsample) {
+ size = (info->endsample - info->currentsample + 1) * 2 * _info->channels;
+ trace ("size truncated to %d bytes, cursample=%d, info->endsample=%d, totalsamples=%d\n", size, info->currentsample, info->endsample, ov_pcm_total (&vorbis_file, -1));
if (size <= 0) {
return 0;
}
}
}
else {
- if (ptrack && currentsample - last_comment_update > 5 * plugin.info.samplerate) {
- int idx = deadbeef->pl_get_idx_of (ptrack);
+ if (info->ptrack && info->currentsample - info->last_comment_update > 5 * _info->samplerate) {
+ int idx = deadbeef->pl_get_idx_of (info->ptrack);
if (idx >= 0) {
- last_comment_update = currentsample;
- vorbis_comment *vc = ov_comment (&vorbis_file, -1);
- update_vorbis_comments (ptrack, vc);
+ info->last_comment_update = info->currentsample;
+ vorbis_comment *vc = ov_comment (&info->vorbis_file, -1);
+ update_vorbis_comments (info->ptrack, vc);
deadbeef->sendmessage (M_TRACKCHANGED, 0, idx, 0);
}
else {
- ptrack = NULL;
+ info->ptrack = NULL;
}
}
}
@@ -254,7 +267,7 @@ cvorbis_read (char *bytes, int size) {
#if WORDS_BIGENDIAN
endianess = 1;
#endif
- ret=ov_read (&vorbis_file, bytes, size, endianess, 2, 1, &cur_bit_stream);
+ ret=ov_read (&info->vorbis_file, bytes, size, endianess, 2, 1, &info->cur_bit_stream);
if (ret <= 0)
{
if (ret < 0) {
@@ -279,52 +292,54 @@ cvorbis_read (char *bytes, int size) {
}
else if (ret < size)
{
- currentsample += ret / (vi->channels * 2);
+ info->currentsample += ret / (info->vi->channels * 2);
size -= ret;
bytes += ret;
}
else {
- currentsample += ret / (vi->channels * 2);
+ info->currentsample += ret / (info->vi->channels * 2);
size = 0;
break;
}
}
- plugin.info.readpos = (float)(ov_pcm_tell(&vorbis_file)-startsample)/vi->rate;
- trace ("cvorbis_read got %d bytes, readpos %f, currentsample %d, ret %d\n", initsize-size, plugin.info.readpos, currentsample, ret);
- deadbeef->streamer_set_bitrate (ov_bitrate_instant (&vorbis_file)/1000);
+ _info->readpos = (float)(ov_pcm_tell(&info->vorbis_file)-info->startsample)/info->vi->rate;
+ trace ("cvorbis_read got %d bytes, readpos %f, info->currentsample %d, ret %d\n", initsize-size, _info->readpos, info->currentsample, ret);
+ deadbeef->streamer_set_bitrate (ov_bitrate_instant (&info->vorbis_file)/1000);
return initsize - size;
}
static int
-cvorbis_seek_sample (int sample) {
+cvorbis_seek_sample (DB_fileinfo_t *_info, int sample) {
+ ogg_info_t *info = (ogg_info_t *)_info;
if (sample < 0) {
trace ("vorbis: negative seek sample - ignored, but it is a bug!\n");
return -1;
}
- if (!file) {
+ if (!info->file) {
trace ("vorbis: file is NULL on seek\n");
return -1;
}
trace ("vorbis: seek to sample %d\n");
- sample += startsample;
- int res = ov_pcm_seek (&vorbis_file, sample);
+ sample += info->startsample;
+ int res = ov_pcm_seek (&info->vorbis_file, sample);
if (res != 0 && res != OV_ENOSEEK) {
trace ("vorbis: error %x seeking to sample %d\n", sample);
return -1;
}
- int tell = ov_pcm_tell (&vorbis_file);
+ int tell = ov_pcm_tell (&info->vorbis_file);
if (tell != sample) {
trace ("oggvorbis: failed to do sample-accurate seek (%d->%d)\n", sample, tell);
}
trace ("vorbis: seek successful\n")
- currentsample = sample;
- plugin.info.readpos = (float)(ov_pcm_tell(&vorbis_file) - startsample)/vi->rate;
+ info->currentsample = sample;
+ _info->readpos = (float)(ov_pcm_tell(&info->vorbis_file) - info->startsample)/info->vi->rate;
return 0;
}
static int
-cvorbis_seek (float time) {
- return cvorbis_seek_sample (time * vi->rate);
+cvorbis_seek (DB_fileinfo_t *_info, float time) {
+ ogg_info_t *info = (ogg_info_t *)_info;
+ return cvorbis_seek_sample (_info, time * info->vi->rate);
}
static DB_playItem_t *
@@ -337,7 +352,6 @@ cvorbis_insert (DB_playItem_t *after, const char *fname) {
}
if (fp->vfs->streaming) {
DB_playItem_t *it = deadbeef->pl_item_alloc ();
- it->decoder_id = deadbeef->plug_get_decoder_id (plugin.id);
it->fname = strdup (fname);
it->filetype = "OggVorbis";
deadbeef->pl_set_item_duration (it, -1);
@@ -367,7 +381,7 @@ cvorbis_insert (DB_playItem_t *after, const char *fname) {
int totalsamples = ov_pcm_total (&vorbis_file, -1);
DB_playItem_t *it = deadbeef->pl_item_alloc ();
- it->decoder_id = deadbeef->plug_get_decoder_id (plugin.id);
+ it->decoder_id = deadbeef->plug_get_decoder_id (plugin.plugin.id);
it->fname = strdup (fname);
it->filetype = "OggVorbis";
deadbeef->pl_set_item_duration (it, duration);
@@ -398,23 +412,25 @@ cvorbis_insert (DB_playItem_t *after, const char *fname) {
return after;
}
-static int
-vorbis_trackdeleted (DB_event_track_t *ev, uintptr_t data) {
- if (ev->track == ptrack) {
- ptrack = NULL;
- }
- return 0;
-}
+// that won't be needed with refcounting
+
+//static int
+//vorbis_trackdeleted (DB_event_track_t *ev, uintptr_t data) {
+// if (ev->track == info->ptrack) {
+// info->ptrack = NULL;
+// }
+// return 0;
+//}
static int
vorbis_start (void) {
- deadbeef->ev_subscribe (DB_PLUGIN (&plugin), DB_EV_TRACKDELETED, DB_CALLBACK (vorbis_trackdeleted), 0);
+// deadbeef->ev_subscribe (DB_PLUGIN (&plugin), DB_EV_TRACKDELETED, DB_CALLBACK (vorbis_trackdeleted), 0);
return 0;
}
static int
vorbis_stop (void) {
- deadbeef->ev_unsubscribe (DB_PLUGIN (&plugin), DB_EV_TRACKDELETED, DB_CALLBACK (vorbis_trackdeleted), 0);
+// deadbeef->ev_unsubscribe (DB_PLUGIN (&plugin), DB_EV_TRACKDELETED, DB_CALLBACK (vorbis_trackdeleted), 0);
return 0;
}
@@ -427,6 +443,7 @@ static DB_decoder_t plugin = {
.plugin.version_major = 0,
.plugin.version_minor = 1,
.plugin.type = DB_PLUGIN_DECODER,
+ .plugin.id = "stdogg",
.plugin.name = "OggVorbis decoder",
.plugin.descr = "OggVorbis decoder using standard xiph.org libraries",
.plugin.author = "Alexey Yakovenko",
@@ -443,7 +460,6 @@ static DB_decoder_t plugin = {
.seek_sample = cvorbis_seek_sample,
.insert = cvorbis_insert,
.exts = exts,
- .id = "stdogg",
.filetypes = filetypes
};