resample.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. /*
  2. * Squeezelite - lightweight headless squeezebox emulator
  3. *
  4. * (c) Adrian Smith 2012-2015, triode1@btinternet.com
  5. * Ralph Irving 2015-2017, ralph_irving@hotmail.com
  6. *
  7. * This program is free software: you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation, either version 3 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  19. *
  20. */
  21. // upsampling using libsoxr - only included if RESAMPLE set
  22. #include "squeezelite.h"
  23. #if RESAMPLE
  24. #include <math.h>
  25. #include <soxr.h>
  26. extern log_level loglevel;
  27. struct soxr {
  28. soxr_t resampler;
  29. size_t old_clips;
  30. unsigned long q_recipe;
  31. unsigned long q_flags;
  32. double q_precision; /* Conversion precision (in bits). 20 */
  33. double q_phase_response; /* 0=minimum, ... 50=linear, ... 100=maximum 50 */
  34. double q_passband_end; /* 0dB pt. bandwidth to preserve; nyquist=1 0.913 */
  35. double q_stopband_begin; /* Aliasing/imaging control; > passband_end 1 */
  36. double scale;
  37. bool max_rate;
  38. bool exception;
  39. #if !LINKALL
  40. // soxr symbols to be dynamically loaded
  41. soxr_io_spec_t (* soxr_io_spec)(soxr_datatype_t itype, soxr_datatype_t otype);
  42. soxr_quality_spec_t (* soxr_quality_spec)(unsigned long recipe, unsigned long flags);
  43. soxr_t (* soxr_create)(double, double, unsigned, soxr_error_t *,
  44. soxr_io_spec_t const *, soxr_quality_spec_t const *, soxr_runtime_spec_t const *);
  45. void (* soxr_delete)(soxr_t);
  46. soxr_error_t (* soxr_process)(soxr_t, soxr_in_t, size_t, size_t *, soxr_out_t, size_t olen, size_t *);
  47. size_t *(* soxr_num_clips)(soxr_t);
  48. #if RESAMPLE_MP
  49. soxr_runtime_spec_t (* soxr_runtime_spec)(unsigned num_threads);
  50. #endif
  51. // soxr_strerror is a macro so not included here
  52. #endif
  53. };
  54. static struct soxr *r;
  55. #if LINKALL
  56. #define SOXR(h, fn, ...) (soxr_ ## fn)(__VA_ARGS__)
  57. #else
  58. #define SOXR(h, fn, ...) (h)->soxr_##fn(__VA_ARGS__)
  59. #endif
  60. void resample_samples(struct processstate *process) {
  61. size_t idone, odone;
  62. size_t clip_cnt;
  63. soxr_error_t error =
  64. SOXR(r, process, r->resampler, process->inbuf, process->in_frames, &idone, process->outbuf, process->max_out_frames, &odone);
  65. if (error) {
  66. LOG_INFO("soxr_process error: %s", soxr_strerror(error));
  67. return;
  68. }
  69. if (idone != process->in_frames) {
  70. // should not get here if buffers are big enough...
  71. LOG_ERROR("should not get here - partial sox process: %u of %u processed %u of %u out",
  72. (unsigned)idone, process->in_frames, (unsigned)odone, process->max_out_frames);
  73. }
  74. process->out_frames = odone;
  75. process->total_in += idone;
  76. process->total_out += odone;
  77. clip_cnt = *(SOXR(r, num_clips, r->resampler));
  78. if (clip_cnt - r->old_clips) {
  79. LOG_SDEBUG("resampling clips: %u", (unsigned)(clip_cnt - r->old_clips));
  80. r->old_clips = clip_cnt;
  81. }
  82. }
  83. bool resample_drain(struct processstate *process) {
  84. size_t odone;
  85. size_t clip_cnt;
  86. soxr_error_t error = SOXR(r, process, r->resampler, NULL, 0, NULL, process->outbuf, process->max_out_frames, &odone);
  87. if (error) {
  88. LOG_INFO("soxr_process error: %s", soxr_strerror(error));
  89. return true;
  90. }
  91. process->out_frames = odone;
  92. process->total_out += odone;
  93. clip_cnt = *(SOXR(r, num_clips, r->resampler));
  94. if (clip_cnt - r->old_clips) {
  95. LOG_DEBUG("resampling clips: %u", (unsigned)(clip_cnt - r->old_clips));
  96. r->old_clips = clip_cnt;
  97. }
  98. if (odone == 0) {
  99. LOG_INFO("resample track complete - total track clips: %u", r->old_clips);
  100. SOXR(r, delete, r->resampler);
  101. r->resampler = NULL;
  102. return true;
  103. } else {
  104. return false;
  105. }
  106. }
  107. bool resample_newstream(struct processstate *process, unsigned raw_sample_rate, unsigned supported_rates[]) {
  108. unsigned outrate = 0;
  109. int i;
  110. if (r->exception) {
  111. // find direct match - avoid resampling
  112. for (i = 0; supported_rates[i]; i++) {
  113. if (raw_sample_rate == supported_rates[i]) {
  114. outrate = raw_sample_rate;
  115. break;
  116. }
  117. }
  118. // else find next highest sync sample rate
  119. while (!outrate && i >= 0) {
  120. if (supported_rates[i] > raw_sample_rate && supported_rates[i] % raw_sample_rate == 0) {
  121. outrate = supported_rates[i];
  122. break;
  123. }
  124. i--;
  125. }
  126. }
  127. if (!outrate) {
  128. if (r->max_rate) {
  129. // resample to max rate for device
  130. outrate = supported_rates[0];
  131. } else {
  132. // resample to max sync sample rate
  133. for (i = 0; supported_rates[i]; i++) {
  134. if (supported_rates[i] % raw_sample_rate == 0 || raw_sample_rate % supported_rates[i] == 0) {
  135. outrate = supported_rates[i];
  136. break;
  137. }
  138. }
  139. }
  140. if (!outrate) {
  141. outrate = supported_rates[0];
  142. }
  143. }
  144. process->in_sample_rate = raw_sample_rate;
  145. process->out_sample_rate = outrate;
  146. if (r->resampler) {
  147. SOXR(r, delete, r->resampler);
  148. r->resampler = NULL;
  149. }
  150. if (raw_sample_rate != outrate) {
  151. soxr_io_spec_t io_spec;
  152. soxr_quality_spec_t q_spec;
  153. soxr_error_t error;
  154. #if RESAMPLE_MP
  155. soxr_runtime_spec_t r_spec;
  156. #endif
  157. LOG_INFO("resampling from %u -> %u", raw_sample_rate, outrate);
  158. #if BYTES_PER_FRAME == 4
  159. io_spec = SOXR(r, io_spec, SOXR_INT16_I, SOXR_INT16_I);
  160. io_spec.flags = SOXR_NO_DITHER;
  161. #else
  162. io_spec = SOXR(r, io_spec, SOXR_INT32_I, SOXR_INT32_I);
  163. #endif
  164. io_spec.scale = r->scale;
  165. q_spec = SOXR(r, quality_spec, r->q_recipe, r->q_flags);
  166. if (r->q_precision > 0) {
  167. q_spec.precision = r->q_precision;
  168. }
  169. if (r->q_passband_end > 0) {
  170. q_spec.passband_end = r->q_passband_end;
  171. }
  172. if (r->q_stopband_begin > 0) {
  173. q_spec.stopband_begin = r->q_stopband_begin;
  174. }
  175. if (r->q_phase_response > -1) {
  176. q_spec.phase_response = r->q_phase_response;
  177. }
  178. #if RESAMPLE_MP
  179. r_spec = SOXR(r, runtime_spec, 0); // make use of libsoxr OpenMP support allowing parallel execution if multiple cores
  180. #endif
  181. LOG_DEBUG("resampling with soxr_quality_spec_t[precision: %03.1f, passband_end: %03.6f, stopband_begin: %03.6f, "
  182. "phase_response: %03.1f, flags: 0x%02x], soxr_io_spec_t[scale: %03.2f]", q_spec.precision,
  183. q_spec.passband_end, q_spec.stopband_begin, q_spec.phase_response, q_spec.flags, io_spec.scale);
  184. #if RESAMPLE_MP
  185. r->resampler = SOXR(r, create, raw_sample_rate, outrate, 2, &error, &io_spec, &q_spec, &r_spec);
  186. #else
  187. r->resampler = SOXR(r, create, raw_sample_rate, outrate, 2, &error, &io_spec, &q_spec, NULL);
  188. #endif
  189. if (error) {
  190. LOG_INFO("soxr_create error: %s", soxr_strerror(error));
  191. return false;
  192. }
  193. r->old_clips = 0;
  194. return true;
  195. } else {
  196. LOG_INFO("disable resampling - rates match");
  197. return false;
  198. }
  199. }
  200. void resample_flush(void) {
  201. if (r->resampler) {
  202. SOXR(r, delete, r->resampler);
  203. r->resampler = NULL;
  204. }
  205. }
  206. static bool load_soxr(void) {
  207. #if !LINKALL
  208. void *handle = dlopen(LIBSOXR, RTLD_NOW);
  209. char *err;
  210. if (!handle) {
  211. LOG_INFO("dlerror: %s", dlerror());
  212. return false;
  213. }
  214. r->soxr_io_spec = dlsym(handle, "soxr_io_spec");
  215. r->soxr_quality_spec = dlsym(handle, "soxr_quality_spec");
  216. r->soxr_create = dlsym(handle, "soxr_create");
  217. r->soxr_delete = dlsym(handle, "soxr_delete");
  218. r->soxr_process = dlsym(handle, "soxr_process");
  219. r->soxr_num_clips = dlsym(handle, "soxr_num_clips");
  220. #if RESAMPLE_MP
  221. r->soxr_runtime_spec = dlsym(handle, "soxr_runtime_spec");
  222. #endif
  223. if ((err = dlerror()) != NULL) {
  224. LOG_INFO("dlerror: %s", err);
  225. return false;
  226. }
  227. LOG_INFO("loaded "LIBSOXR);
  228. #endif
  229. return true;
  230. }
  231. bool resample_init(char *opt) {
  232. char *recipe = NULL, *flags = NULL;
  233. char *atten = NULL;
  234. char *precision = NULL, *passband_end = NULL, *stopband_begin = NULL, *phase_response = NULL;
  235. r = malloc(sizeof(struct soxr));
  236. if (!r) {
  237. LOG_WARN("resampling disabled");
  238. return false;
  239. }
  240. r->resampler = NULL;
  241. r->old_clips = 0;
  242. r->max_rate = false;
  243. r->exception = false;
  244. if (!load_soxr()) {
  245. LOG_WARN("resampling disabled");
  246. return false;
  247. }
  248. if (opt) {
  249. recipe = next_param(opt, ':');
  250. flags = next_param(NULL, ':');
  251. atten = next_param(NULL, ':');
  252. precision = next_param(NULL, ':');
  253. passband_end = next_param(NULL, ':');
  254. stopband_begin = next_param(NULL, ':');
  255. phase_response = next_param(NULL, ':');
  256. }
  257. #if BYTES_PER_FRAME == 4
  258. // default to LQ (16 bits) if not user specified
  259. r->q_recipe = SOXR_LQ | SOXR_MINIMUM_PHASE;
  260. r->q_flags = SOXR_ROLLOFF_NONE;
  261. r->q_phase_response = 0;
  262. #else
  263. // default to HQ (20 bits) if not user specified
  264. r->q_recipe = SOXR_HQ;
  265. r->q_flags = 0;
  266. r->q_phase_response = -1;
  267. #endif
  268. // default to 1db of attenuation if not user specified
  269. r->scale = pow(10, -1.0 / 20);
  270. // override recipe derived values with user specified values
  271. r->q_precision = 0;
  272. r->q_passband_end = 0.75;
  273. r->q_stopband_begin = 1.25;
  274. if (recipe && recipe[0] != '\0') {
  275. if (strchr(recipe, 'v')) r->q_recipe = SOXR_VHQ;
  276. if (strchr(recipe, 'h')) r->q_recipe = SOXR_HQ;
  277. if (strchr(recipe, 'm')) r->q_recipe = SOXR_MQ;
  278. if (strchr(recipe, 'l')) r->q_recipe = SOXR_LQ;
  279. if (strchr(recipe, 'q')) r->q_recipe = SOXR_QQ;
  280. if (strchr(recipe, 'L')) r->q_recipe |= SOXR_LINEAR_PHASE;
  281. if (strchr(recipe, 'I')) r->q_recipe |= SOXR_INTERMEDIATE_PHASE;
  282. if (strchr(recipe, 'M')) r->q_recipe |= SOXR_MINIMUM_PHASE;
  283. if (strchr(recipe, 's')) r->q_recipe |= SOXR_STEEP_FILTER;
  284. // X = async resampling to max_rate
  285. if (strchr(recipe, 'X')) r->max_rate = true;
  286. // E = exception, only resample if native rate is not supported
  287. if (strchr(recipe, 'E')) r->exception = true;
  288. }
  289. if (flags) {
  290. r->q_flags = strtoul(flags, 0, 16);
  291. }
  292. if (atten) {
  293. double scale = pow(10, -atof(atten) / 20);
  294. if (scale > 0 && scale <= 1.0) {
  295. r->scale = scale;
  296. }
  297. }
  298. if (precision) {
  299. r->q_precision = atof(precision);
  300. }
  301. if (passband_end) {
  302. r->q_passband_end = atof(passband_end) / 100;
  303. }
  304. if (stopband_begin) {
  305. r->q_stopband_begin = atof(stopband_begin) / 100;
  306. }
  307. if (phase_response) {
  308. r->q_phase_response = atof(phase_response);
  309. }
  310. LOG_INFO("resampling %s recipe: 0x%02x, flags: 0x%02x, scale: %03.2f, precision: %03.1f, passband_end: %03.5f, stopband_begin: %03.5f, phase_response: %03.1f",
  311. r->max_rate ? "async" : "sync",
  312. r->q_recipe, r->q_flags, r->scale, r->q_precision, r->q_passband_end, r->q_stopband_begin, r->q_phase_response);
  313. return true;
  314. }
  315. #endif // #if RESAMPLE