diff --git a/plugins/sndfile/sndfile.c b/plugins/sndfile/sndfile.c index 6da1bd4b4e..b6192a659c 100644 --- a/plugins/sndfile/sndfile.c +++ b/plugins/sndfile/sndfile.c @@ -17,10 +17,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifdef HAVE_CONFIG_H -# include +# include #endif #ifndef __linux__ -#define _LARGEFILE64_SOURCE +# define _LARGEFILE64_SOURCE #endif #include #include @@ -29,10 +29,11 @@ #include #include -#define min(x,y) ((x)<(y)?(x):(y)) -#define max(x,y) ((x)>(y)?(x):(y)) +#define min(x, y) ((x) < (y) ? (x) : (y)) +#define max(x, y) ((x) > (y) ? (x) : (y)) -#define trace(...) { deadbeef->log_detailed (&plugin.decoder.plugin, 0, __VA_ARGS__); } +#define trace(...) \ + { deadbeef->log_detailed (&plugin.decoder.plugin, 0, __VA_ARGS__); } static ddb_decoder2_t plugin; static DB_functions_t *deadbeef; @@ -87,13 +88,11 @@ sf_vfs_tell (void *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 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 DB_fileinfo_t * sndfile_open (uint32_t hints) { @@ -101,10 +100,9 @@ sndfile_open (uint32_t hints) { return &info->info; } - #if 0 // taken from libsndfile -#define ARRAY_LEN(x) ((int) (sizeof (x) / sizeof ((x) [0]))) +# define ARRAY_LEN(x) ((int)(sizeof (x) / sizeof ((x)[0]))) /* This stores which bit in dwChannelMask maps to which channel */ static const struct chanmap_s { int id ; @@ -162,9 +160,9 @@ wavex_gen_channel_mask (const int *chan_map, int channels) static int sndfile_init (DB_fileinfo_t *_info, DB_playItem_t *it) { - sndfile_info_t *info = (sndfile_info_t*)_info; + sndfile_info_t *info = (sndfile_info_t *)_info; - SF_INFO inf = {0}; + SF_INFO inf = { 0 }; deadbeef->pl_lock (); const char *uri = strdupa (deadbeef->pl_find_meta (it, ":URI")); deadbeef->pl_unlock (); @@ -185,10 +183,10 @@ sndfile_init (DB_fileinfo_t *_info, DB_playItem_t *it) { return -1; } _info->plugin = &plugin.decoder; - info->sf_format = inf.format&SF_FORMAT_SUBMASK; + info->sf_format = inf.format & SF_FORMAT_SUBMASK; info->sf_need_endswap = sf_command (info->ctx, SFC_RAW_DATA_NEEDS_ENDSWAP, NULL, 0); - switch (inf.format&SF_FORMAT_SUBMASK) { + switch (inf.format & SF_FORMAT_SUBMASK) { case SF_FORMAT_PCM_S8: case SF_FORMAT_PCM_U8: _info->fmt.bps = 8; @@ -207,23 +205,23 @@ sndfile_init (DB_fileinfo_t *_info, DB_playItem_t *it) { default: info->read_as_short = 1; _info->fmt.bps = 16; - trace ("[sndfile] unidentified input format: 0x%X\n", inf.format&SF_FORMAT_SUBMASK); + trace ("[sndfile] unidentified input format: 0x%X\n", inf.format & SF_FORMAT_SUBMASK); break; } _info->fmt.channels = inf.channels; _info->fmt.samplerate = inf.samplerate; -// FIXME: streamer and maybe output plugins need to be fixed to support -// arbitrary channelmask -// -// int channel_map [inf.channels]; -// int cmdres = sf_command (info->ctx, SFC_GET_CHANNEL_MAP_INFO, channel_map, sizeof (channel_map)) ; -// if (cmdres != SF_FALSE) { -// // channel map found, convert to channel mask -// _info->fmt.channelmask = wavex_gen_channel_mask (channel_map, inf.channels); -// } -// else + // FIXME: streamer and maybe output plugins need to be fixed to support + // arbitrary channelmask + // + // int channel_map [inf.channels]; + // int cmdres = sf_command (info->ctx, SFC_GET_CHANNEL_MAP_INFO, channel_map, sizeof (channel_map)) ; + // if (cmdres != SF_FALSE) { + // // channel map found, convert to channel mask + // _info->fmt.channelmask = wavex_gen_channel_mask (channel_map, inf.channels); + // } + // else { // channel map not found, generate from channel number for (int i = 0; i < inf.channels; i++) { @@ -242,7 +240,7 @@ sndfile_init (DB_fileinfo_t *_info, DB_playItem_t *it) { } else { info->startsample = 0; - info->endsample = inf.frames-1; + info->endsample = inf.frames - 1; } // hack bitrate @@ -261,8 +259,8 @@ sndfile_init (DB_fileinfo_t *_info, DB_playItem_t *it) { static void sndfile_free (DB_fileinfo_t *_info) { if (!_info) - return ; - sndfile_info_t *info = (sndfile_info_t*)_info; + return; + sndfile_info_t *info = (sndfile_info_t *)_info; if (info->ctx) { sf_close (info->ctx); } @@ -274,11 +272,15 @@ sndfile_free (DB_fileinfo_t *_info) { static int sndfile_read (DB_fileinfo_t *_info, char *bytes, int size) { - sndfile_info_t *info = (sndfile_info_t*)_info; + sndfile_info_t *info = (sndfile_info_t *)_info; int samplesize = _info->fmt.channels * _info->fmt.bps / 8; if (size / samplesize + info->currentsample > info->endsample) { size = (int)((info->endsample - info->currentsample + 1) * samplesize); - trace ("sndfile: size truncated to %d bytes, cursample=%d, endsample=%d\n", size, info->currentsample, info->endsample); + trace ( + "sndfile: size truncated to %d bytes, cursample=%d, endsample=%d\n", + size, + info->currentsample, + info->endsample); if (size <= 0) { return 0; } @@ -286,7 +288,7 @@ sndfile_read (DB_fileinfo_t *_info, char *bytes, int size) { int64_t n = 0; if (info->read_as_short) { - n = sf_readf_short(info->ctx, (short *)bytes, size/samplesize); + n = sf_readf_short (info->ctx, (short *)bytes, size / samplesize); } else { n = sf_read_raw (info->ctx, (short *)bytes, size); @@ -294,37 +296,32 @@ sndfile_read (DB_fileinfo_t *_info, char *bytes, int size) { if (info->sf_format == SF_FORMAT_PCM_U8) { for (int i = 0; i < n; i++) { int sample = ((uint8_t *)bytes)[i]; - ((int8_t *)bytes)[i] = sample-0x80; + ((int8_t *)bytes)[i] = sample - 0x80; } } else if (info->sf_need_endswap) { switch (info->info.fmt.bps) { - case 16: - { - uint16_t *data = (uint16_t *)bytes; - for (int i = 0; i < n/2; i++, data++) { - *data = ((*data & 0xff) << 8) | ((*data & 0xff00) >> 8); - } + case 16: { + uint16_t *data = (uint16_t *)bytes; + for (int i = 0; i < n / 2; i++, data++) { + *data = ((*data & 0xff) << 8) | ((*data & 0xff00) >> 8); } - break; - case 24: - { - uint8_t *data = (uint8_t *)bytes; - for (int i = 0; i < n/3; i++, data += 3) { - uint8_t temp = data[0]; - data[0] = data[2]; - data[2] = temp; - } + } break; + case 24: { + uint8_t *data = (uint8_t *)bytes; + for (int i = 0; i < n / 3; i++, data += 3) { + uint8_t temp = data[0]; + data[0] = data[2]; + data[2] = temp; } - break; - case 32: - { - uint32_t *data = (uint32_t *)bytes; - for (int i = 0; i < n/4; i++, data++) { - *data = ((*data & 0xff) << 24) | ((*data & 0xff00) << 8) | ((*data & 0xff0000) >> 8) | ((*data & 0xff0000) >> 24); - } + } break; + case 32: { + uint32_t *data = (uint32_t *)bytes; + for (int i = 0; i < n / 4; i++, data++) { + *data = ((*data & 0xff) << 24) | ((*data & 0xff00) << 8) | ((*data & 0xff0000) >> 8) | + ((*data & 0xff0000) >> 24); } - break; + } break; } } n /= samplesize; @@ -333,7 +330,7 @@ sndfile_read (DB_fileinfo_t *_info, char *bytes, int size) { info->currentsample += n; size = (int)(n * samplesize); - _info->readpos = (float)(info->currentsample-info->startsample)/_info->fmt.samplerate; + _info->readpos = (float)(info->currentsample - info->startsample) / _info->fmt.samplerate; if (info->bitrate > 0) { deadbeef->streamer_set_bitrate (info->bitrate); } @@ -342,7 +339,7 @@ sndfile_read (DB_fileinfo_t *_info, char *bytes, int size) { static int sndfile_seek_sample64 (DB_fileinfo_t *_info, int64_t sample) { - sndfile_info_t *info = (sndfile_info_t*)_info; + sndfile_info_t *info = (sndfile_info_t *)_info; int64_t ret = sf_seek (info->ctx, sample + info->startsample, SEEK_SET); if (ret < 0) { return -1; @@ -354,7 +351,7 @@ sndfile_seek_sample64 (DB_fileinfo_t *_info, int64_t sample) { static int sndfile_seek_sample (DB_fileinfo_t *_info, int sample) { - return sndfile_seek_sample64(_info, sample); + return sndfile_seek_sample64 (_info, sample); } static int @@ -368,8 +365,8 @@ _sndfile_ctx_read_tags (DB_playItem_t *it, SNDFILE *ctx); static DB_playItem_t * sndfile_insert (ddb_playlist_t *plt, DB_playItem_t *after, const char *fname) { trace ("adding file %s\n", fname); - SF_INFO inf = {0}; - sndfile_info_t info = {0}; + SF_INFO inf = { 0 }; + sndfile_info_t info = { 0 }; DB_FILE *fp = deadbeef->fopen (fname); if (!fp) { trace ("sndfile: failed to open %s\n", fname); @@ -378,11 +375,12 @@ sndfile_insert (ddb_playlist_t *plt, DB_playItem_t *after, const char *fname) { info.file = fp; - int64_t fsize = deadbeef->fgetlength(fp); + int64_t fsize = deadbeef->fgetlength (fp); trace ("file: %p, size: %lld\n", fp, fsize); trace ("calling sf_open_virtual\n"); info.ctx = sf_open_virtual (&vfs, SFM_READ, &inf, &info); + if (!info.ctx) { trace ("sndfile: sf_open failed for %s\n", fname); deadbeef->fclose (fp); @@ -401,7 +399,36 @@ sndfile_insert (ddb_playlist_t *plt, DB_playItem_t *after, const char *fname) { float duration = (float)totalsamples / samplerate; DB_playItem_t *it = deadbeef->pl_item_alloc_init (fname, plugin.decoder.plugin.id); - deadbeef->pl_add_meta (it, ":FILETYPE", "wav"); + + const char *type = "WAV"; + + struct { + int identifier; + const char *name; + } map[] = { { SF_FORMAT_WAV, "WAV" }, { SF_FORMAT_AIFF, "AIFF" }, + { SF_FORMAT_AU, "AU" }, { SF_FORMAT_RAW, "RAW" }, + { SF_FORMAT_PAF, "PAF" }, { SF_FORMAT_SVX, "SVX" }, + { SF_FORMAT_NIST, "NIST" }, { SF_FORMAT_VOC, "VOC" }, + { SF_FORMAT_IRCAM, "IRCAM" }, { SF_FORMAT_W64, "W64" }, + { SF_FORMAT_MAT4, "MAT4" }, { SF_FORMAT_MAT5, "MAT5" }, + { SF_FORMAT_PVF, "PVF" }, { SF_FORMAT_XI, "XI" }, + { SF_FORMAT_HTK, "HTK" }, { SF_FORMAT_SDS, "SDS" }, + { SF_FORMAT_AVR, "AVR" }, { SF_FORMAT_WAVEX, "WAVEX" }, + { SF_FORMAT_SD2, "SD2" }, { SF_FORMAT_FLAC, "FLAC" }, + { SF_FORMAT_CAF, "CAF" }, { SF_FORMAT_WVE, "WVE" }, + { SF_FORMAT_OGG, "OGG" }, { SF_FORMAT_MPC2K, "MPC2K" }, + { SF_FORMAT_RF64, "RF64" }, { 0, NULL } }; + + int identifier = inf.format & SF_FORMAT_TYPEMASK; + const char *format_name = "WAV"; + for (int i = 0; map[i].name != NULL; i++) { + if (map[i].identifier == identifier) { + format_name = map[i].name; + } + } + + deadbeef->pl_add_meta (it, ":FILETYPE", format_name); + deadbeef->plt_set_item_duration (plt, it, duration); trace ("sndfile: totalsamples=%d, samplerate=%d, duration=%f\n", totalsamples, samplerate, duration); @@ -411,7 +438,7 @@ sndfile_insert (ddb_playlist_t *plt, DB_playItem_t *after, const char *fname) { deadbeef->pl_add_meta (it, ":FILE_SIZE", s); int bps = -1; - switch (inf.format&SF_FORMAT_SUBMASK) { + switch (inf.format & SF_FORMAT_SUBMASK) { case SF_FORMAT_IMA_ADPCM: case SF_FORMAT_MS_ADPCM: bps = 4; @@ -446,75 +473,28 @@ sndfile_insert (ddb_playlist_t *plt, DB_playItem_t *after, const char *fname) { snprintf (s, sizeof (s), "%d", samplerate); deadbeef->pl_add_meta (it, ":SAMPLERATE", s); if (duration > 0) { - int br = (int)roundf(fsize / duration * 8 / 1000); + int br = (int)roundf (fsize / duration * 8 / 1000); snprintf (s, sizeof (s), "%d", br); deadbeef->pl_add_meta (it, ":BITRATE", s); } // sndfile subformats - int subformat_ids[] = { - SF_FORMAT_PCM_S8, - SF_FORMAT_PCM_16, - SF_FORMAT_PCM_24, - SF_FORMAT_PCM_32, - SF_FORMAT_PCM_U8, - SF_FORMAT_FLOAT, - SF_FORMAT_DOUBLE, - SF_FORMAT_ULAW, - SF_FORMAT_ALAW, - SF_FORMAT_IMA_ADPCM, - SF_FORMAT_MS_ADPCM, - SF_FORMAT_GSM610, - SF_FORMAT_VOX_ADPCM, - SF_FORMAT_G721_32, - SF_FORMAT_G723_24, - SF_FORMAT_G723_40, - SF_FORMAT_DWVW_12, - SF_FORMAT_DWVW_16, - SF_FORMAT_DWVW_24, - SF_FORMAT_DWVW_N, - SF_FORMAT_DPCM_8, - SF_FORMAT_DPCM_16, - SF_FORMAT_VORBIS, - SF_FORMAT_ALAC_16, - SF_FORMAT_ALAC_20, - SF_FORMAT_ALAC_24, - SF_FORMAT_ALAC_32, - -1 - }; + int subformat_ids[] = { SF_FORMAT_PCM_S8, SF_FORMAT_PCM_16, SF_FORMAT_PCM_24, SF_FORMAT_PCM_32, + SF_FORMAT_PCM_U8, SF_FORMAT_FLOAT, SF_FORMAT_DOUBLE, SF_FORMAT_ULAW, + SF_FORMAT_ALAW, SF_FORMAT_IMA_ADPCM, SF_FORMAT_MS_ADPCM, SF_FORMAT_GSM610, + SF_FORMAT_VOX_ADPCM, SF_FORMAT_G721_32, SF_FORMAT_G723_24, SF_FORMAT_G723_40, + SF_FORMAT_DWVW_12, SF_FORMAT_DWVW_16, SF_FORMAT_DWVW_24, SF_FORMAT_DWVW_N, + SF_FORMAT_DPCM_8, SF_FORMAT_DPCM_16, SF_FORMAT_VORBIS, SF_FORMAT_ALAC_16, + SF_FORMAT_ALAC_20, SF_FORMAT_ALAC_24, SF_FORMAT_ALAC_32, -1 }; const char *subformats[] = { - "PCM_S8", - "PCM_16", - "PCM_24", - "PCM_32", - "PCM_U8", - "FLOAT", - "DOUBLE", - "ULAW", - "ALAW", - "IMA_ADPCM", - "MS_ADPCM", - "GSM610", - "VOX_ADPCM", - "G721_32", - "G723_24", - "G723_40", - "DWVW_12", - "DWVW_16", - "DWVW_24", - "DWVW_N", - "DPCM_8", - "DPCM_16", - "VORBIS", - "ALAC_16", - "ALAC_20", - "ALAC_24", - "ALAC_32", + "PCM_S8", "PCM_16", "PCM_24", "PCM_32", "PCM_U8", "FLOAT", "DOUBLE", "ULAW", "ALAW", + "IMA_ADPCM", "MS_ADPCM", "GSM610", "VOX_ADPCM", "G721_32", "G723_24", "G723_40", "DWVW_12", "DWVW_16", + "DWVW_24", "DWVW_N", "DPCM_8", "DPCM_16", "VORBIS", "ALAC_16", "ALAC_20", "ALAC_24", "ALAC_32", }; for (int i = 0; subformat_ids[i] != -1; i++) { - if ((inf.format&SF_FORMAT_SUBMASK) == subformat_ids[i]) { + if ((inf.format & SF_FORMAT_SUBMASK) == subformat_ids[i]) { deadbeef->pl_add_meta (it, ":SF_FORMAT", subformats[i]); break; } @@ -540,32 +520,26 @@ sndfile_insert (ddb_playlist_t *plt, DB_playItem_t *after, const char *fname) { return after; } -#define ARRAY_LEN(x) ((int) (sizeof (x) / sizeof ((x) [0]))) +#define ARRAY_LEN(x) ((int)(sizeof (x) / sizeof ((x)[0]))) static const struct metamap_s { int str_type; - const char* meta_name; -} metamap_items [] = { - { SF_STR_TITLE, "title" }, - { SF_STR_COPYRIGHT, "copyright" } , - { SF_STR_SOFTWARE, "encoder" }, - { SF_STR_ARTIST, "artist" }, - { SF_STR_COMMENT, "comment" }, - { SF_STR_DATE, "year" }, - { SF_STR_ALBUM, "album" }, - { SF_STR_TRACKNUMBER, "track" }, - { SF_STR_GENRE, "genre" }, + const char *meta_name; +} metamap_items[] = { + { SF_STR_TITLE, "title" }, { SF_STR_COPYRIGHT, "copyright" }, { SF_STR_SOFTWARE, "encoder" }, + { SF_STR_ARTIST, "artist" }, { SF_STR_COMMENT, "comment" }, { SF_STR_DATE, "year" }, + { SF_STR_ALBUM, "album" }, { SF_STR_TRACKNUMBER, "track" }, { SF_STR_GENRE, "genre" }, }; static int sndfile_read_metadata (DB_playItem_t *it) { - DB_fileinfo_t* info = sndfile_open (0); + DB_fileinfo_t *info = sndfile_open (0); int res = sndfile_init (info, it); if (res) { sndfile_free (info); return -1; } - SNDFILE *ctx = ((sndfile_info_t*)info)->ctx; + SNDFILE *ctx = ((sndfile_info_t *)info)->ctx; _sndfile_ctx_read_tags (it, ctx); sndfile_free (info); @@ -573,14 +547,13 @@ sndfile_read_metadata (DB_playItem_t *it) { } static int -_sndfile_ctx_read_tags (DB_playItem_t *it, SNDFILE *ctx) -{ +_sndfile_ctx_read_tags (DB_playItem_t *it, SNDFILE *ctx) { int i; - for (i = 0; i < ARRAY_LEN(metamap_items); i++) { + for (i = 0; i < ARRAY_LEN (metamap_items); i++) { const struct metamap_s *kv = &metamap_items[i]; const char *meta_str = sf_get_string (ctx, kv->str_type); if (!meta_str) - continue ; + continue; const char *charset = deadbeef->junk_detect_charset (meta_str); if (charset) { // recode non-UTF-8 metadata string. @@ -603,7 +576,7 @@ _sndfile_ctx_read_tags (DB_playItem_t *it, SNDFILE *ctx) #define EXT_MAX 100 -static char *exts[EXT_MAX] = {NULL}; +static char *exts[EXT_MAX] = { NULL }; static void sndfile_init_exts (void) { @@ -625,15 +598,15 @@ sndfile_init_exts (void) { e++; } if (e != new_exts) { - char *ext = malloc (e-new_exts+1); - memcpy (ext, new_exts, e-new_exts); - ext[e-new_exts] = 0; + char *ext = malloc (e - new_exts + 1); + memcpy (ext, new_exts, e - new_exts); + ext[e - new_exts] = 0; exts[n++] = ext; } if (*e == 0) { break; } - new_exts = e+1; + new_exts = e + 1; } deadbeef->conf_unlock (); exts[n] = NULL; @@ -672,8 +645,7 @@ sndfile_stop (void) { static const char settings_dlg[] = "property \"File Extensions (separate with ';')\" entry sndfile.extensions \"" DEFAULT_EXTS "\";\n" - "property \"Enable logging\" checkbox sndfile.trace 0;\n" -; + "property \"Enable logging\" checkbox sndfile.trace 0;\n"; // define plugin interface static ddb_decoder2_t plugin = { @@ -686,24 +658,22 @@ static ddb_decoder2_t plugin = { .decoder.plugin.id = "sndfile", .decoder.plugin.name = "WAV/PCM player", .decoder.plugin.descr = "wav/aiff player using libsndfile", - .decoder.plugin.copyright = - "libsndfile plugin for DeaDBeeF Player\n" - "Copyright (C) 2009-2014 Oleksiy Yakovenko \n" - "\n" - "This program is free software; you can redistribute it and/or\n" - "modify it under the terms of the GNU General Public License\n" - "as published by the Free Software Foundation; either version 2\n" - "of the License, or (at your option) any later version.\n" - "\n" - "This program is distributed in the hope that it will be useful,\n" - "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" - "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" - "GNU General Public License for more details.\n" - "\n" - "You should have received a copy of the GNU General Public License\n" - "along with this program; if not, write to the Free Software\n" - "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n" - , + .decoder.plugin.copyright = "libsndfile plugin for DeaDBeeF Player\n" + "Copyright (C) 2009-2014 Oleksiy Yakovenko \n" + "\n" + "This program is free software; you can redistribute it and/or\n" + "modify it under the terms of the GNU General Public License\n" + "as published by the Free Software Foundation; either version 2\n" + "of the License, or (at your option) any later version.\n" + "\n" + "This program is distributed in the hope that it will be useful,\n" + "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" + "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" + "GNU General Public License for more details.\n" + "\n" + "You should have received a copy of the GNU General Public License\n" + "along with this program; if not, write to the Free Software\n" + "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n", .decoder.plugin.website = "http://deadbeef.sf.net", .decoder.open = sndfile_open, .decoder.init = sndfile_init,