summaryrefslogtreecommitdiff
path: root/plugins/sndfile
diff options
context:
space:
mode:
authorGravatar Alexey Yakovenko <wakeroid@gmail.com>2009-12-26 14:03:44 +0100
committerGravatar Alexey Yakovenko <wakeroid@gmail.com>2009-12-26 14:07:30 +0100
commit54831e4cd6a00d4d903b9254862881a92285ced5 (patch)
treee07b637e2dda2877e8edab3989536cfcb3c8d9a7 /plugins/sndfile
parentf423d7487aebf82fcbe90ba9b27a95fecc7aafb6 (diff)
sndfile plugin: now uses deadbeef vfs to read files; added bitrate display
Diffstat (limited to 'plugins/sndfile')
-rw-r--r--plugins/sndfile/sndfile.c87
1 files changed, 81 insertions, 6 deletions
diff --git a/plugins/sndfile/sndfile.c b/plugins/sndfile/sndfile.c
index 46e3a99f..dfb956de 100644
--- a/plugins/sndfile/sndfile.c
+++ b/plugins/sndfile/sndfile.c
@@ -23,26 +23,75 @@
#define min(x,y) ((x)<(y)?(x):(y))
#define max(x,y) ((x)>(y)?(x):(y))
-#define trace(...) { fprintf(stderr, __VA_ARGS__); }
-//#define trace(fmt,...)
+//#define trace(...) { fprintf(stderr, __VA_ARGS__); }
+#define trace(fmt,...)
static DB_decoder_t plugin;
static DB_functions_t *deadbeef;
typedef struct {
SNDFILE *ctx;
+ DB_FILE *file;
int startsample;
int endsample;
int currentsample;
+ int bitrate;
} sndfilectx_t;
static sndfilectx_t sfctx;
+
+// vfs wrapper for sf
+static sf_count_t
+sf_vfs_get_filelen (void *user_data) {
+ sndfilectx_t *ctx = user_data;
+ return deadbeef->fgetlength (ctx->file);
+}
+
+static sf_count_t
+sf_vfs_read (void *ptr, sf_count_t count, void *user_data) {
+ sndfilectx_t *ctx = user_data;
+ return deadbeef->fread (ptr, 1, count, ctx->file);
+}
+
+static sf_count_t
+sf_vfs_write (const void *ptr, sf_count_t count, void *user_data) {
+ return -1;
+}
+
+static sf_count_t
+sf_vfs_seek (sf_count_t offset, int whence, void *user_data) {
+ sndfilectx_t *ctx = user_data;
+ return deadbeef->fseek (ctx->file, offset, whence);
+}
+
+static sf_count_t
+sf_vfs_tell (void *user_data) {
+ sndfilectx_t *ctx = user_data;
+ return deadbeef->ftell (ctx->file);
+}
+
+static SF_VIRTUAL_IO vfs = {
+ .get_filelen = sf_vfs_get_filelen,
+ .seek = sf_vfs_seek,
+ .read = sf_vfs_read,
+ .write = sf_vfs_write,
+ .tell = sf_vfs_tell
+};
+
static int
sndfile_init (DB_playItem_t *it) {
memset (&sfctx, 0, sizeof (sfctx));
SF_INFO inf;
- sfctx.ctx = sf_open (it->fname, SFM_READ, &inf);
+ DB_FILE *fp = deadbeef->fopen (it->fname);
+ if (!fp) {
+ trace ("sndfile: failed to open %s\n", it->fname);
+ return -1;
+ }
+ int fsize = deadbeef->fgetlength (fp);
+
+ sfctx.file = fp;
+ sfctx.ctx = sf_open_virtual (&vfs, SFM_READ, &inf, &sfctx);
if (!sfctx.ctx) {
return -1;
}
@@ -62,6 +111,15 @@ sndfile_init (DB_playItem_t *it) {
sfctx.startsample = 0;
sfctx.endsample = inf.frames-1;
}
+ // hack bitrate
+ float sec = (float)(sfctx.endsample-sfctx.startsample) / inf.samplerate;
+ if (sec != 0) {
+ sfctx.bitrate = fsize / sec * 8 / 1000;
+ }
+ else {
+ sfctx.bitrate = -1;
+ }
+
return 0;
}
@@ -70,6 +128,9 @@ sndfile_free (void) {
if (sfctx.ctx) {
sf_close (sfctx.ctx);
}
+ if (sfctx.file) {
+ deadbeef->fclose (sfctx.file);
+ }
memset (&sfctx, 0, sizeof (sfctx));
}
@@ -86,6 +147,9 @@ sndfile_read_int16 (char *bytes, int size) {
sfctx.currentsample += n;
size = n * 2 * plugin.info.channels;
plugin.info.readpos = (float)(sfctx.currentsample-sfctx.startsample)/plugin.info.samplerate;
+ if (sfctx.bitrate > 0) {
+ deadbeef->streamer_set_bitrate (sfctx.bitrate);
+ }
return size;
}
@@ -102,6 +166,9 @@ sndfile_read_float32 (char *bytes, int size) {
sfctx.currentsample += n;
size = n * 4 * plugin.info.channels;
plugin.info.readpos = (float)(sfctx.currentsample-sfctx.startsample)/plugin.info.samplerate;
+ if (sfctx.bitrate > 0) {
+ deadbeef->streamer_set_bitrate (sfctx.bitrate);
+ }
return size;
}
@@ -120,14 +187,22 @@ sndfile_seek (float sec) {
static DB_playItem_t *
sndfile_insert (DB_playItem_t *after, const char *fname) {
SF_INFO inf;
- SNDFILE *sf = sf_open (fname, SFM_READ, &inf);
- if (!sf) {
+ sndfilectx_t sfctx;
+ sfctx.file = deadbeef->fopen (fname);
+ if (!sfctx.file) {
+ trace ("sndfile: failed to open %s\n", fname);
+ return NULL;
+ }
+ sfctx.ctx = sf_open_virtual (&vfs, SFM_READ, &inf, &sfctx);
+ if (!sfctx.ctx) {
trace ("sndfile: sf_open failed");
return NULL;
}
int totalsamples = inf.frames;
int samplerate = inf.samplerate;
- sf_close (sf);
+ sf_close (sfctx.ctx);
+ deadbeef->fclose (sfctx.file);
+
float duration = (float)totalsamples / samplerate;
DB_playItem_t *cue_after = deadbeef->pl_insert_cue (after, fname, &plugin, "sndfile", totalsamples, samplerate);
if (cue_after) {