1 /* 2 ** Copyright 2011, The Android Open-Source Project 3 ** 4 ** Licensed under the Apache License, Version 2.0 (the "License"); 5 ** you may not use this file except in compliance with the License. 6 ** You may obtain a copy of the License at 7 ** 8 ** http://www.apache.org/licenses/LICENSE-2.0 9 ** 10 ** Unless required by applicable law or agreed to in writing, software 11 ** distributed under the License is distributed on an "AS IS" BASIS, 12 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 ** See the License for the specific language governing permissions and 14 ** limitations under the License. 15 */ 16 17 //#define LOG_NDEBUG 0 18 #define LOG_TAG "resampler" 19 20 #include <errno.h> 21 #include <stdlib.h> 22 #include <cutils/log.h> 23 #include <system/audio.h> 24 #include <audio_utils/resampler.h> 25 #include <speex/speex_resampler.h> 26 27 28 struct resampler { 29 struct resampler_itfe itfe; 30 SpeexResamplerState *speex_resampler; // handle on speex resampler 31 struct resampler_buffer_provider *provider; // buffer provider installed by client 32 uint32_t in_sample_rate; // input sampling rate in Hz 33 uint32_t out_sample_rate; // output sampling rate in Hz 34 uint32_t channel_count; // number of channels (interleaved) 35 int16_t *in_buf; // input buffer 36 size_t in_buf_size; // input buffer size 37 size_t frames_in; // number of frames in input buffer 38 size_t frames_rq; // cached number of output frames 39 size_t frames_needed; // minimum number of input frames to produce 40 // frames_rq output frames 41 int32_t speex_delay_ns; // delay introduced by speex resampler in ns 42 }; 43 44 45 //------------------------------------------------------------------------------ 46 // speex based resampler 47 //------------------------------------------------------------------------------ 48 49 static void resampler_reset(struct resampler_itfe *resampler) 50 { 51 struct resampler *rsmp = (struct resampler *)resampler; 52 53 rsmp->frames_in = 0; 54 rsmp->frames_rq = 0; 55 56 if (rsmp != NULL && rsmp->speex_resampler != NULL) { 57 speex_resampler_reset_mem(rsmp->speex_resampler); 58 } 59 } 60 61 static int32_t resampler_delay_ns(struct resampler_itfe *resampler) 62 { 63 struct resampler *rsmp = (struct resampler *)resampler; 64 65 int32_t delay = (int32_t)((1000000000 * (int64_t)rsmp->frames_in) / rsmp->in_sample_rate); 66 delay += rsmp->speex_delay_ns; 67 68 return delay; 69 } 70 71 // outputs a number of frames less or equal to *outFrameCount and updates *outFrameCount 72 // with the actual number of frames produced. 73 int resampler_resample_from_provider(struct resampler_itfe *resampler, 74 int16_t *out, 75 size_t *outFrameCount) 76 { 77 struct resampler *rsmp = (struct resampler *)resampler; 78 79 if (rsmp == NULL || out == NULL || outFrameCount == NULL) { 80 return -EINVAL; 81 } 82 if (rsmp->provider == NULL) { 83 *outFrameCount = 0; 84 return -ENOSYS; 85 } 86 87 size_t framesRq = *outFrameCount; 88 // update and cache the number of frames needed at the input sampling rate to produce 89 // the number of frames requested at the output sampling rate 90 if (framesRq != rsmp->frames_rq) { 91 rsmp->frames_needed = (framesRq * rsmp->in_sample_rate) / rsmp->out_sample_rate + 1; 92 rsmp->frames_rq = framesRq; 93 } 94 95 size_t framesWr = 0; 96 size_t inFrames = 0; 97 while (framesWr < framesRq) { 98 if (rsmp->frames_in < rsmp->frames_needed) { 99 // make sure that the number of frames present in rsmp->in_buf (rsmp->frames_in) is at 100 // least the number of frames needed to produce the number of frames requested at 101 // the output sampling rate 102 if (rsmp->in_buf_size < rsmp->frames_needed) { 103 rsmp->in_buf_size = rsmp->frames_needed; 104 rsmp->in_buf = (int16_t *)realloc(rsmp->in_buf, 105 rsmp->in_buf_size * rsmp->channel_count * sizeof(int16_t)); 106 } 107 struct resampler_buffer buf; 108 buf.frame_count = rsmp->frames_needed - rsmp->frames_in; 109 rsmp->provider->get_next_buffer(rsmp->provider, &buf); 110 if (buf.raw == NULL) { 111 break; 112 } 113 memcpy(rsmp->in_buf + rsmp->frames_in * rsmp->channel_count, 114 buf.raw, 115 buf.frame_count * rsmp->channel_count * sizeof(int16_t)); 116 rsmp->frames_in += buf.frame_count; 117 rsmp->provider->release_buffer(rsmp->provider, &buf); 118 } 119 120 size_t outFrames = framesRq - framesWr; 121 inFrames = rsmp->frames_in; 122 if (rsmp->channel_count == 1) { 123 speex_resampler_process_int(rsmp->speex_resampler, 124 0, 125 rsmp->in_buf, 126 &inFrames, 127 out + framesWr, 128 &outFrames); 129 } else { 130 speex_resampler_process_interleaved_int(rsmp->speex_resampler, 131 rsmp->in_buf, 132 &inFrames, 133 out + framesWr * rsmp->channel_count, 134 &outFrames); 135 } 136 framesWr += outFrames; 137 rsmp->frames_in -= inFrames; 138 ALOGW_IF((framesWr != framesRq) && (rsmp->frames_in != 0), 139 "ReSampler::resample() remaining %d frames in and %d frames out", 140 rsmp->frames_in, (framesRq - framesWr)); 141 } 142 if (rsmp->frames_in) { 143 memmove(rsmp->in_buf, 144 rsmp->in_buf + inFrames * rsmp->channel_count, 145 rsmp->frames_in * rsmp->channel_count * sizeof(int16_t)); 146 } 147 *outFrameCount = framesWr; 148 149 return 0; 150 } 151 152 int resampler_resample_from_input(struct resampler_itfe *resampler, 153 int16_t *in, 154 size_t *inFrameCount, 155 int16_t *out, 156 size_t *outFrameCount) 157 { 158 struct resampler *rsmp = (struct resampler *)resampler; 159 160 if (rsmp == NULL || in == NULL || inFrameCount == NULL || 161 out == NULL || outFrameCount == NULL) { 162 return -EINVAL; 163 } 164 if (rsmp->provider != NULL) { 165 *outFrameCount = 0; 166 return -ENOSYS; 167 } 168 169 if (rsmp->channel_count == 1) { 170 speex_resampler_process_int(rsmp->speex_resampler, 171 0, 172 in, 173 inFrameCount, 174 out, 175 outFrameCount); 176 } else { 177 speex_resampler_process_interleaved_int(rsmp->speex_resampler, 178 in, 179 inFrameCount, 180 out, 181 outFrameCount); 182 } 183 184 ALOGV("resampler_resample_from_input() DONE in %d out % d", *inFrameCount, *outFrameCount); 185 186 return 0; 187 } 188 189 int create_resampler(uint32_t inSampleRate, 190 uint32_t outSampleRate, 191 uint32_t channelCount, 192 uint32_t quality, 193 struct resampler_buffer_provider* provider, 194 struct resampler_itfe **resampler) 195 { 196 int error; 197 struct resampler *rsmp; 198 199 ALOGV("create_resampler() In SR %d Out SR %d channels %d", 200 inSampleRate, outSampleRate, channelCount); 201 202 if (resampler == NULL) { 203 return -EINVAL; 204 } 205 206 *resampler = NULL; 207 208 if (quality <= RESAMPLER_QUALITY_MIN || quality >= RESAMPLER_QUALITY_MAX) { 209 return -EINVAL; 210 } 211 212 rsmp = (struct resampler *)calloc(1, sizeof(struct resampler)); 213 214 rsmp->speex_resampler = speex_resampler_init(channelCount, 215 inSampleRate, 216 outSampleRate, 217 quality, 218 &error); 219 if (rsmp->speex_resampler == NULL) { 220 ALOGW("ReSampler: Cannot create speex resampler: %s", speex_resampler_strerror(error)); 221 free(rsmp); 222 return -ENODEV; 223 } 224 225 rsmp->itfe.reset = resampler_reset; 226 rsmp->itfe.resample_from_provider = resampler_resample_from_provider; 227 rsmp->itfe.resample_from_input = resampler_resample_from_input; 228 rsmp->itfe.delay_ns = resampler_delay_ns; 229 230 rsmp->provider = provider; 231 rsmp->in_sample_rate = inSampleRate; 232 rsmp->out_sample_rate = outSampleRate; 233 rsmp->channel_count = channelCount; 234 rsmp->in_buf = NULL; 235 rsmp->in_buf_size = 0; 236 237 resampler_reset(&rsmp->itfe); 238 239 int frames = speex_resampler_get_input_latency(rsmp->speex_resampler); 240 rsmp->speex_delay_ns = (int32_t)((1000000000 * (int64_t)frames) / rsmp->in_sample_rate); 241 frames = speex_resampler_get_output_latency(rsmp->speex_resampler); 242 rsmp->speex_delay_ns += (int32_t)((1000000000 * (int64_t)frames) / rsmp->out_sample_rate); 243 244 *resampler = &rsmp->itfe; 245 ALOGV("create_resampler() DONE rsmp %p &rsmp->itfe %p speex %p", 246 rsmp, &rsmp->itfe, rsmp->speex_resampler); 247 return 0; 248 } 249 250 void release_resampler(struct resampler_itfe *resampler) 251 { 252 struct resampler *rsmp = (struct resampler *)resampler; 253 254 if (rsmp == NULL) { 255 return; 256 } 257 258 free(rsmp->in_buf); 259 260 if (rsmp->speex_resampler != NULL) { 261 speex_resampler_destroy(rsmp->speex_resampler); 262 } 263 free(rsmp); 264 } 265