Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

174 lines
5.1KB

  1. /**
  2. Copyright (C) 2011-2013 Robin Gareus <robin@gareus.org>
  3. Copyright (C) 2014-2023 Filipe Coelho <falktx@falktx.com>
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU Lesser Public License as published by
  6. the Free Software Foundation; either version 2.1, or (at your option)
  7. any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU Lesser Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with this library; if not, write to the Free Software
  14. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  15. */
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #include <math.h>
  20. #include "ad_plugin.h"
  21. #ifdef HAVE_SNDFILE
  22. #include <sndfile.h>
  23. #ifdef _MSC_VER
  24. #define strcasecmp stricmp
  25. #endif
  26. /* internal abstraction */
  27. typedef struct {
  28. SF_INFO sfinfo;
  29. SNDFILE *sffile;
  30. } sndfile_audio_decoder;
  31. static int parse_bit_depth(int format) {
  32. /* see http://www.mega-nerd.com/libsndfile/api.html */
  33. switch (format&0x0f) {
  34. case SF_FORMAT_PCM_S8: return 8;
  35. case SF_FORMAT_PCM_16: return 16; /* Signed 16 bit data */
  36. case SF_FORMAT_PCM_24: return 24; /* Signed 24 bit data */
  37. case SF_FORMAT_PCM_32: return 32; /* Signed 32 bit data */
  38. case SF_FORMAT_PCM_U8: return 8; /* Unsigned 8 bit data (WAV and RAW only) */
  39. case SF_FORMAT_FLOAT : return 32; /* 32 bit float data */
  40. case SF_FORMAT_DOUBLE: return 64; /* 64 bit float data */
  41. default: break;
  42. }
  43. return 16;
  44. }
  45. static int ad_info_sndfile(void *sf, struct adinfo *nfo) {
  46. sndfile_audio_decoder *priv = (sndfile_audio_decoder*) sf;
  47. if (!priv) return -1;
  48. if (nfo) {
  49. nfo->channels = priv->sfinfo.channels;
  50. nfo->frames = priv->sfinfo.frames;
  51. nfo->sample_rate = priv->sfinfo.samplerate;
  52. nfo->length = priv->sfinfo.samplerate ? (priv->sfinfo.frames * 1000) / priv->sfinfo.samplerate : 0;
  53. nfo->bit_depth = parse_bit_depth(priv->sfinfo.format);
  54. nfo->bit_rate = nfo->bit_depth * nfo->channels * nfo->sample_rate;
  55. nfo->meta_data = NULL;
  56. nfo->can_seek = 1;
  57. }
  58. return 0;
  59. }
  60. static void *ad_open_sndfile(const char *fn, struct adinfo *nfo) {
  61. sndfile_audio_decoder *priv = (sndfile_audio_decoder*) calloc(1, sizeof(sndfile_audio_decoder));
  62. priv->sfinfo.format=0;
  63. if(!(priv->sffile = sf_open(fn, SFM_READ, &priv->sfinfo))){
  64. dbg(0, "unable to open file '%s'.", fn);
  65. puts(sf_strerror(NULL));
  66. int e = sf_error(NULL);
  67. dbg(0, "error=%i", e);
  68. free(priv);
  69. return NULL;
  70. }
  71. ad_info_sndfile(priv, nfo);
  72. return (void*) priv;
  73. }
  74. static int ad_close_sndfile(void *sf) {
  75. sndfile_audio_decoder *priv = (sndfile_audio_decoder*) sf;
  76. if (!priv) return -1;
  77. if(!sf || sf_close(priv->sffile)) {
  78. dbg(0, "fatal: bad file close.\n");
  79. return -1;
  80. }
  81. free(priv);
  82. return 0;
  83. }
  84. static int64_t ad_seek_sndfile(void *sf, int64_t pos) {
  85. sndfile_audio_decoder *priv = (sndfile_audio_decoder*) sf;
  86. if (!priv) return -1;
  87. return sf_seek(priv->sffile, pos, SEEK_SET);
  88. }
  89. static ssize_t ad_read_sndfile(void *sf, float* d, size_t len) {
  90. sndfile_audio_decoder *priv = (sndfile_audio_decoder*) sf;
  91. if (!priv) return -1;
  92. return sf_read_float (priv->sffile, d, len);
  93. }
  94. static int ad_get_bitrate_sndfile(void *sf) {
  95. sndfile_audio_decoder *priv = (sndfile_audio_decoder*) sf;
  96. if (!priv) return -1;
  97. return parse_bit_depth(priv->sfinfo.format) * priv->sfinfo.channels * priv->sfinfo.samplerate;
  98. }
  99. static int ad_eval_sndfile(const char *f) {
  100. char *ext = strrchr(f, '.');
  101. if (strstr (f, "://")) return 0;
  102. if (!ext) return 5;
  103. /* see http://www.mega-nerd.com/libsndfile/ */
  104. if (!strcasecmp(ext, ".wav")) return 100;
  105. if (!strcasecmp(ext, ".aiff")) return 100;
  106. if (!strcasecmp(ext, ".aifc")) return 100;
  107. if (!strcasecmp(ext, ".snd")) return 100;
  108. if (!strcasecmp(ext, ".au")) return 100;
  109. if (!strcasecmp(ext, ".paf")) return 100;
  110. if (!strcasecmp(ext, ".iff")) return 100;
  111. if (!strcasecmp(ext, ".svx")) return 100;
  112. if (!strcasecmp(ext, ".sf")) return 100;
  113. if (!strcasecmp(ext, ".vcc")) return 100;
  114. if (!strcasecmp(ext, ".w64")) return 100;
  115. if (!strcasecmp(ext, ".mat4")) return 100;
  116. if (!strcasecmp(ext, ".mat5")) return 100;
  117. if (!strcasecmp(ext, ".pvf5")) return 100;
  118. if (!strcasecmp(ext, ".xi")) return 100;
  119. if (!strcasecmp(ext, ".htk")) return 100;
  120. if (!strcasecmp(ext, ".pvf")) return 100;
  121. if (!strcasecmp(ext, ".sd2")) return 100;
  122. // libsndfile >= 1.0.18
  123. if (!strcasecmp(ext, ".flac")) return 80;
  124. if (!strcasecmp(ext, ".oga")) return 80;
  125. if (!strcasecmp(ext, ".ogg")) return 80;
  126. if (!strcasecmp(ext, ".opus")) return 80;
  127. return 0;
  128. }
  129. #endif
  130. static const ad_plugin ad_sndfile = {
  131. #ifdef HAVE_SNDFILE
  132. &ad_eval_sndfile,
  133. &ad_open_sndfile,
  134. &ad_close_sndfile,
  135. &ad_info_sndfile,
  136. &ad_seek_sndfile,
  137. &ad_read_sndfile,
  138. &ad_get_bitrate_sndfile
  139. #else
  140. &ad_eval_null,
  141. &ad_open_null,
  142. &ad_close_null,
  143. &ad_info_null,
  144. &ad_seek_null,
  145. &ad_read_null,
  146. &ad_bitrate_null
  147. #endif
  148. };
  149. /* dlopen handler */
  150. const ad_plugin * adp_get_sndfile() {
  151. return &ad_sndfile;
  152. }