resampler.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. // SPDX-License-Identifier: Apache-2.0
  2. /*
  3. ** Copyright 2011, The Android Open-Source Project
  4. **
  5. */
  6. //#define LOG_NDEBUG 0
  7. #include <errno.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include <system/audio.h>
  11. #include <audio_utils/resampler.h>
  12. #include <speex/speex_resampler.h>
  13. #include "hal-log.h"
  14. struct resampler {
  15. struct resampler_itfe itfe;
  16. SpeexResamplerState *speex_resampler; // handle on speex resampler
  17. struct resampler_buffer_provider *provider; // buffer provider installed by client
  18. uint32_t in_sample_rate; // input sampling rate in Hz
  19. uint32_t out_sample_rate; // output sampling rate in Hz
  20. uint32_t channel_count; // number of channels (interleaved)
  21. int16_t *in_buf; // input buffer
  22. size_t in_buf_size; // input buffer size
  23. size_t frames_in; // number of frames in input buffer
  24. size_t frames_rq; // cached number of output frames
  25. size_t frames_needed; // minimum number of input frames to produce
  26. // frames_rq output frames
  27. int32_t speex_delay_ns; // delay introduced by speex resampler in ns
  28. };
  29. //------------------------------------------------------------------------------
  30. // speex based resampler
  31. //------------------------------------------------------------------------------
  32. static void resampler_reset(struct resampler_itfe *resampler)
  33. {
  34. struct resampler *rsmp = (struct resampler *)resampler;
  35. rsmp->frames_in = 0;
  36. rsmp->frames_rq = 0;
  37. if (rsmp != NULL && rsmp->speex_resampler != NULL) {
  38. speex_resampler_reset_mem(rsmp->speex_resampler);
  39. }
  40. }
  41. static int32_t resampler_delay_ns(struct resampler_itfe *resampler)
  42. {
  43. struct resampler *rsmp = (struct resampler *)resampler;
  44. int32_t delay = (int32_t)((1000000000 * (int64_t)rsmp->frames_in) / rsmp->in_sample_rate);
  45. delay += rsmp->speex_delay_ns;
  46. return delay;
  47. }
  48. // outputs a number of frames less or equal to *outFrameCount and updates *outFrameCount
  49. // with the actual number of frames produced.
  50. static int resampler_resample_from_provider(struct resampler_itfe *resampler,
  51. int16_t *out,
  52. size_t *outFrameCount)
  53. {
  54. struct resampler *rsmp = (struct resampler *)resampler;
  55. size_t framesRq;
  56. size_t framesWr;
  57. size_t inFrames;
  58. if (rsmp == NULL || out == NULL || outFrameCount == NULL) {
  59. return -EINVAL;
  60. }
  61. if (rsmp->provider == NULL) {
  62. *outFrameCount = 0;
  63. return -ENOSYS;
  64. }
  65. framesRq = *outFrameCount;
  66. // update and cache the number of frames needed at the input sampling rate to produce
  67. // the number of frames requested at the output sampling rate
  68. if (framesRq != rsmp->frames_rq) {
  69. rsmp->frames_needed = (framesRq * rsmp->in_sample_rate) / rsmp->out_sample_rate + 1;
  70. rsmp->frames_rq = framesRq;
  71. }
  72. framesWr = 0;
  73. inFrames = 0;
  74. while (framesWr < framesRq) {
  75. size_t outFrames;
  76. if (rsmp->frames_in < rsmp->frames_needed) {
  77. struct resampler_buffer buf;
  78. // make sure that the number of frames present in rsmp->in_buf (rsmp->frames_in) is at
  79. // least the number of frames needed to produce the number of frames requested at
  80. // the output sampling rate
  81. if (rsmp->in_buf_size < rsmp->frames_needed) {
  82. rsmp->in_buf_size = rsmp->frames_needed;
  83. rsmp->in_buf = (int16_t *)realloc(rsmp->in_buf,
  84. rsmp->in_buf_size * rsmp->channel_count * sizeof(int16_t));
  85. }
  86. buf.frame_count = rsmp->frames_needed - rsmp->frames_in;
  87. rsmp->provider->get_next_buffer(rsmp->provider, &buf);
  88. if (buf.raw == NULL) {
  89. break;
  90. }
  91. memcpy(rsmp->in_buf + rsmp->frames_in * rsmp->channel_count,
  92. buf.raw,
  93. buf.frame_count * rsmp->channel_count * sizeof(int16_t));
  94. rsmp->frames_in += buf.frame_count;
  95. rsmp->provider->release_buffer(rsmp->provider, &buf);
  96. }
  97. outFrames = framesRq - framesWr;
  98. inFrames = rsmp->frames_in;
  99. if (rsmp->channel_count == 1) {
  100. speex_resampler_process_int(rsmp->speex_resampler,
  101. 0,
  102. rsmp->in_buf,
  103. (void *) &inFrames,
  104. out + framesWr,
  105. (void *) &outFrames);
  106. } else {
  107. speex_resampler_process_interleaved_int(rsmp->speex_resampler,
  108. rsmp->in_buf,
  109. (void *) &inFrames,
  110. out + framesWr * rsmp->channel_count,
  111. (void *) &outFrames);
  112. }
  113. framesWr += outFrames;
  114. rsmp->frames_in -= inFrames;
  115. if ((framesWr != framesRq) && (rsmp->frames_in != 0))
  116. warn("ReSampler::resample() remaining %zd frames in and %zd out",
  117. rsmp->frames_in, (framesRq - framesWr));
  118. }
  119. if (rsmp->frames_in) {
  120. memmove(rsmp->in_buf,
  121. rsmp->in_buf + inFrames * rsmp->channel_count,
  122. rsmp->frames_in * rsmp->channel_count * sizeof(int16_t));
  123. }
  124. *outFrameCount = framesWr;
  125. return 0;
  126. }
  127. static int resampler_resample_from_input(struct resampler_itfe *resampler,
  128. int16_t *in,
  129. size_t *inFrameCount,
  130. int16_t *out,
  131. size_t *outFrameCount)
  132. {
  133. struct resampler *rsmp = (struct resampler *)resampler;
  134. if (rsmp == NULL || in == NULL || inFrameCount == NULL ||
  135. out == NULL || outFrameCount == NULL) {
  136. return -EINVAL;
  137. }
  138. if (rsmp->provider != NULL) {
  139. *outFrameCount = 0;
  140. return -ENOSYS;
  141. }
  142. if (rsmp->channel_count == 1) {
  143. speex_resampler_process_int(rsmp->speex_resampler,
  144. 0,
  145. in,
  146. (void *) inFrameCount,
  147. out,
  148. (void *) outFrameCount);
  149. } else {
  150. speex_resampler_process_interleaved_int(rsmp->speex_resampler,
  151. in,
  152. (void *) inFrameCount,
  153. out,
  154. (void *) outFrameCount);
  155. }
  156. DBG("resampler_resample_from_input() DONE in %zd out %zd", *inFrameCount, *outFrameCount);
  157. return 0;
  158. }
  159. int create_resampler(uint32_t inSampleRate,
  160. uint32_t outSampleRate,
  161. uint32_t channelCount,
  162. uint32_t quality,
  163. struct resampler_buffer_provider* provider,
  164. struct resampler_itfe **resampler)
  165. {
  166. int error;
  167. struct resampler *rsmp;
  168. int frames;
  169. DBG("create_resampler() In SR %d Out SR %d channels %d",
  170. inSampleRate, outSampleRate, channelCount);
  171. if (resampler == NULL) {
  172. return -EINVAL;
  173. }
  174. *resampler = NULL;
  175. if (quality <= RESAMPLER_QUALITY_MIN || quality >= RESAMPLER_QUALITY_MAX) {
  176. return -EINVAL;
  177. }
  178. rsmp = (struct resampler *)calloc(1, sizeof(struct resampler));
  179. rsmp->speex_resampler = speex_resampler_init(channelCount,
  180. inSampleRate,
  181. outSampleRate,
  182. quality,
  183. &error);
  184. if (rsmp->speex_resampler == NULL) {
  185. error("ReSampler: Cannot create speex resampler: %s", speex_resampler_strerror(error));
  186. free(rsmp);
  187. return -ENODEV;
  188. }
  189. rsmp->itfe.reset = resampler_reset;
  190. rsmp->itfe.resample_from_provider = resampler_resample_from_provider;
  191. rsmp->itfe.resample_from_input = resampler_resample_from_input;
  192. rsmp->itfe.delay_ns = resampler_delay_ns;
  193. rsmp->provider = provider;
  194. rsmp->in_sample_rate = inSampleRate;
  195. rsmp->out_sample_rate = outSampleRate;
  196. rsmp->channel_count = channelCount;
  197. rsmp->in_buf = NULL;
  198. rsmp->in_buf_size = 0;
  199. resampler_reset(&rsmp->itfe);
  200. frames = speex_resampler_get_input_latency(rsmp->speex_resampler);
  201. rsmp->speex_delay_ns = (int32_t)((1000000000 * (int64_t)frames) / rsmp->in_sample_rate);
  202. frames = speex_resampler_get_output_latency(rsmp->speex_resampler);
  203. rsmp->speex_delay_ns += (int32_t)((1000000000 * (int64_t)frames) / rsmp->out_sample_rate);
  204. *resampler = &rsmp->itfe;
  205. DBG("create_resampler() DONE rsmp %p &rsmp->itfe %p speex %p",
  206. rsmp, &rsmp->itfe, rsmp->speex_resampler);
  207. return 0;
  208. }
  209. void release_resampler(struct resampler_itfe *resampler)
  210. {
  211. struct resampler *rsmp = (struct resampler *)resampler;
  212. if (rsmp == NULL) {
  213. return;
  214. }
  215. free(rsmp->in_buf);
  216. if (rsmp->speex_resampler != NULL) {
  217. speex_resampler_destroy(rsmp->speex_resampler);
  218. }
  219. free(rsmp);
  220. }