diff options
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/sndfile/sndfile.c | 152 |
1 files changed, 81 insertions, 71 deletions
diff --git a/plugins/sndfile/sndfile.c b/plugins/sndfile/sndfile.c index cbfbeaf8..0202439e 100644 --- a/plugins/sndfile/sndfile.c +++ b/plugins/sndfile/sndfile.c @@ -30,27 +30,25 @@ static DB_decoder_t plugin; static DB_functions_t *deadbeef; typedef struct { + DB_fileinfo_t info; SNDFILE *ctx; DB_FILE *file; int startsample; int endsample; int currentsample; int bitrate; -} sndfilectx_t; - -static sndfilectx_t sfctx; - +} sndfile_info_t; // vfs wrapper for sf static sf_count_t sf_vfs_get_filelen (void *user_data) { - sndfilectx_t *ctx = user_data; + sndfile_info_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; + sndfile_info_t *ctx = user_data; return deadbeef->fread (ptr, 1, count, ctx->file); } @@ -61,7 +59,7 @@ sf_vfs_write (const void *ptr, sf_count_t count, void *user_data) { static sf_count_t sf_vfs_seek (sf_count_t offset, int whence, void *user_data) { - sndfilectx_t *ctx = user_data; + sndfile_info_t *ctx = user_data; int ret = deadbeef->fseek (ctx->file, offset, whence); if (!ret) { return offset; @@ -71,7 +69,7 @@ sf_vfs_seek (sf_count_t offset, int whence, void *user_data) { static sf_count_t sf_vfs_tell (void *user_data) { - sndfilectx_t *ctx = user_data; + sndfile_info_t *ctx = user_data; return deadbeef->ftell (ctx->file); } @@ -83,137 +81,149 @@ static SF_VIRTUAL_IO vfs = { .tell = sf_vfs_tell }; -static int +static DB_fileinfo_t * sndfile_init (DB_playItem_t *it) { - memset (&sfctx, 0, sizeof (sfctx)); + DB_fileinfo_t *_info = malloc (sizeof (sndfile_info_t)); + sndfile_info_t *info = (sndfile_info_t*)_info; + memset (info, 0, sizeof (sndfile_info_t)); + SF_INFO inf; DB_FILE *fp = deadbeef->fopen (it->fname); if (!fp) { trace ("sndfile: failed to open %s\n", it->fname); - return -1; + plugin.free (_info); + return NULL; } int fsize = deadbeef->fgetlength (fp); - sfctx.file = fp; - sfctx.ctx = sf_open_virtual (&vfs, SFM_READ, &inf, &sfctx); - if (!sfctx.ctx) { - return -1; + info->file = fp; + info->ctx = sf_open_virtual (&vfs, SFM_READ, &inf, info); + if (!info->ctx) { + trace ("sndfile: %s: unsupported file format\n"); + plugin.free (_info); + return NULL; } - plugin.info.bps = 16; - plugin.info.channels = inf.channels; - plugin.info.samplerate = inf.samplerate; - plugin.info.readpos = 0; + _info->plugin = &plugin; + _info->bps = 16; + _info->channels = inf.channels; + _info->samplerate = inf.samplerate; + _info->readpos = 0; if (it->endsample > 0) { - sfctx.startsample = it->startsample; - sfctx.endsample = it->endsample; - if (plugin.seek_sample (0) < 0) { - plugin.free (); - return -1; + info->startsample = it->startsample; + info->endsample = it->endsample; + if (plugin.seek_sample (_info, 0) < 0) { + plugin.free (_info); + return NULL; } } else { - sfctx.startsample = 0; - sfctx.endsample = inf.frames-1; + info->startsample = 0; + info->endsample = inf.frames-1; } // hack bitrate - float sec = (float)(sfctx.endsample-sfctx.startsample) / inf.samplerate; + float sec = (float)(info->endsample-info->startsample) / inf.samplerate; if (sec > 0) { - sfctx.bitrate = fsize / sec * 8 / 1000; + info->bitrate = fsize / sec * 8 / 1000; } else { - sfctx.bitrate = -1; + info->bitrate = -1; } - return 0; + return _info; } static void -sndfile_free (void) { - if (sfctx.ctx) { - sf_close (sfctx.ctx); +sndfile_free (DB_fileinfo_t *_info) { + sndfile_info_t *info = (sndfile_info_t*)_info; + if (info->ctx) { + sf_close (info->ctx); } - if (sfctx.file) { - deadbeef->fclose (sfctx.file); + if (info->file) { + deadbeef->fclose (info->file); } - memset (&sfctx, 0, sizeof (sfctx)); + memset (&info, 0, sizeof (info)); } static int -sndfile_read_int16 (char *bytes, int size) { - if (size / (2 * plugin.info.channels) + sfctx.currentsample > sfctx.endsample) { - size = (sfctx.endsample - sfctx.currentsample + 1) * 2 * plugin.info.channels; - trace ("wv: size truncated to %d bytes, cursample=%d, endsample=%d\n", size, sfctx.currentsample, sfctx.endsample); +sndfile_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) { + sndfile_info_t *info = (sndfile_info_t*)_info; + if (size / (2 * _info->channels) + info->currentsample > info->endsample) { + size = (info->endsample - info->currentsample + 1) * 2 * _info->channels; + trace ("wv: size truncated to %d bytes, cursample=%d, endsample=%d\n", size, info->currentsample, info->endsample); if (size <= 0) { return 0; } } - int n = sf_readf_short (sfctx.ctx, (short *)bytes, size/(2*plugin.info.channels)); - 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); + int n = sf_readf_short (info->ctx, (short *)bytes, size/(2*_info->channels)); + info->currentsample += n; + size = n * 2 * _info->channels; + _info->readpos = (float)(info->currentsample-info->startsample)/_info->samplerate; + if (info->bitrate > 0) { + deadbeef->streamer_set_bitrate (info->bitrate); } return size; } static int -sndfile_read_float32 (char *bytes, int size) { - if (size / (4 * plugin.info.channels) + sfctx.currentsample > sfctx.endsample) { - size = (sfctx.endsample - sfctx.currentsample + 1) * 4 * plugin.info.channels; - trace ("wv: size truncated to %d bytes, cursample=%d, endsample=%d\n", size, sfctx.currentsample, sfctx.endsample); +sndfile_read_float32 (DB_fileinfo_t *_info, char *bytes, int size) { + sndfile_info_t *info = (sndfile_info_t*)_info; + if (size / (4 * _info->channels) + info->currentsample > info->endsample) { + size = (info->endsample - info->currentsample + 1) * 4 * _info->channels; + trace ("wv: size truncated to %d bytes, cursample=%d, endsample=%d\n", size, info->currentsample, info->endsample); if (size <= 0) { return 0; } } - int n = sf_readf_float (sfctx.ctx, (float *)bytes, size/(4*plugin.info.channels)); - 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); + int n = sf_readf_float (info->ctx, (float *)bytes, size/(4*_info->channels)); + info->currentsample += n; + size = n * 4 * _info->channels; + _info->readpos = (float)(info->currentsample-info->startsample)/_info->samplerate; + if (info->bitrate > 0) { + deadbeef->streamer_set_bitrate (info->bitrate); } return size; } static int -sndfile_seek_sample (int sample) { - int ret = sf_seek (sfctx.ctx, sample + sfctx.startsample, SEEK_SET); +sndfile_seek_sample (DB_fileinfo_t *_info, int sample) { + sndfile_info_t *info = (sndfile_info_t*)_info; + int ret = sf_seek (info->ctx, sample + info->startsample, SEEK_SET); if (ret < 0) { return -1; } - sfctx.currentsample = ret; - plugin.info.readpos = (float)(sfctx.currentsample - sfctx.startsample) / plugin.info.samplerate; + info->currentsample = ret; + _info->readpos = (float)(info->currentsample - info->startsample) / _info->samplerate; return 0; } static int -sndfile_seek (float sec) { - return sndfile_seek_sample (sec * plugin.info.samplerate); +sndfile_seek (DB_fileinfo_t *_info, float sec) { + return sndfile_seek_sample (_info, sec * _info->samplerate); } static DB_playItem_t * sndfile_insert (DB_playItem_t *after, const char *fname) { SF_INFO inf; - sndfilectx_t sfctx; - sfctx.file = deadbeef->fopen (fname); - if (!sfctx.file) { + sndfile_info_t info; + memset (&info, 0, sizeof (info)); + info.file = deadbeef->fopen (fname); + if (!info.file) { trace ("sndfile: failed to open %s\n", fname); return NULL; } - sfctx.ctx = sf_open_virtual (&vfs, SFM_READ, &inf, &sfctx); - if (!sfctx.ctx) { + info.ctx = sf_open_virtual (&vfs, SFM_READ, &inf, &info); + if (!info.ctx) { trace ("sndfile: sf_open failed"); return NULL; } int totalsamples = inf.frames; int samplerate = inf.samplerate; - sf_close (sfctx.ctx); - deadbeef->fclose (sfctx.file); + sf_close (info.ctx); + deadbeef->fclose (info.file); float duration = (float)totalsamples / samplerate; 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 = "wav"; deadbeef->pl_set_item_duration (it, duration); @@ -240,6 +250,7 @@ static DB_decoder_t plugin = { .plugin.version_major = 0, .plugin.version_minor = 1, .plugin.type = DB_PLUGIN_DECODER, + .plugin.id = "sndfile", .plugin.name = "pcm player", .plugin.descr = "wav/aiff player using libsndfile", .plugin.author = "Alexey Yakovenko", @@ -253,7 +264,6 @@ static DB_decoder_t plugin = { .seek_sample = sndfile_seek_sample, .insert = sndfile_insert, .exts = exts, - .id = "sndfile", .filetypes = filetypes }; |