resampler.c revision d0e472977acbfd5c8d56d506f40039f451f84f8f
1c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler/* 2c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler** Copyright 2011, The Android Open-Source Project 3c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler** 4c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler** Licensed under the Apache License, Version 2.0 (the "License"); 5c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler** you may not use this file except in compliance with the License. 6c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler** You may obtain a copy of the License at 7c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler** 8c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler** http://www.apache.org/licenses/LICENSE-2.0 9c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler** 10c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler** Unless required by applicable law or agreed to in writing, software 11c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler** distributed under the License is distributed on an "AS IS" BASIS, 12c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler** See the License for the specific language governing permissions and 14c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler** limitations under the License. 15c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler*/ 16c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler 17c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler//#define LOG_NDEBUG 0 18c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler#define LOG_TAG "resampler" 19ed2084787cec0f02e6cead215d409d6f2f60f737Alon Albert 20ed2084787cec0f02e6cead215d409d6f2f60f737Alon Albert#include <errno.h> 21ed2084787cec0f02e6cead215d409d6f2f60f737Alon Albert#include <stdlib.h> 22ed2084787cec0f02e6cead215d409d6f2f60f737Alon Albert#include <cutils/log.h> 2390dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock#include <system/audio.h> 24ed2084787cec0f02e6cead215d409d6f2f60f737Alon Albert#include <audio_utils/resampler.h> 2590dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock#include <speex/speex_resampler.h> 264560461b08b1660fa5776523d8344df0d8d23f1dItzhak Katzenelson 27ed2084787cec0f02e6cead215d409d6f2f60f737Alon Albert 2817b4ca405a8b0d154f4d8354ab62044cd25b2204Daniel Sandlerstruct resampler { 2990dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock struct resampler_itfe itfe; 30c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler SpeexResamplerState *speex_resampler; // handle on speex resampler 31c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler struct resampler_buffer_provider *provider; // buffer provider installed by client 3278b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein uint32_t in_sample_rate; // input sampling rate in Hz 3378b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein uint32_t out_sample_rate; // output sampling rate in Hz 3417b4ca405a8b0d154f4d8354ab62044cd25b2204Daniel Sandler uint32_t channel_count; // number of channels (interleaved) 35e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler int16_t *in_buf; // input buffer 36e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler size_t in_buf_size; // input buffer size 37c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler size_t frames_in; // number of frames in input buffer 38e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler size_t frames_rq; // cached number of output frames 394560461b08b1660fa5776523d8344df0d8d23f1dItzhak Katzenelson size_t frames_needed; // minimum number of input frames to produce 40c5b45b80a280794ca131b9857c5885c337d4d6e1Isaac Katzenelson // frames_rq output frames 41c5b45b80a280794ca131b9857c5885c337d4d6e1Isaac Katzenelson int32_t speex_delay_ns; // delay introduced by speex resampler in ns 42e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler}; 439df9aff951dce59b327f56f5821386a7b40798bdIsaac Katzenelson 44c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler 4578b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein//------------------------------------------------------------------------------ 464560461b08b1660fa5776523d8344df0d8d23f1dItzhak Katzenelson// speex based resampler 47ed2084787cec0f02e6cead215d409d6f2f60f737Alon Albert//------------------------------------------------------------------------------ 48ed2084787cec0f02e6cead215d409d6f2f60f737Alon Albert 49ed2084787cec0f02e6cead215d409d6f2f60f737Alon Albertstatic void resampler_reset(struct resampler_itfe *resampler) 50ed2084787cec0f02e6cead215d409d6f2f60f737Alon Albert{ 51ed2084787cec0f02e6cead215d409d6f2f60f737Alon Albert struct resampler *rsmp = (struct resampler *)resampler; 52ed2084787cec0f02e6cead215d409d6f2f60f737Alon Albert 53ed2084787cec0f02e6cead215d409d6f2f60f737Alon Albert rsmp->frames_in = 0; 54eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas rsmp->frames_rq = 0; 55eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas 56eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas if (rsmp != NULL && rsmp->speex_resampler != NULL) { 57eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas speex_resampler_reset_mem(rsmp->speex_resampler); 58eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas } 59eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas} 60eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas 61eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultasstatic int32_t resampler_delay_ns(struct resampler_itfe *resampler) 62eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas{ 63eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas struct resampler *rsmp = (struct resampler *)resampler; 64eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas 65eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas int32_t delay = (int32_t)((1000000000 * (int64_t)rsmp->frames_in) / rsmp->in_sample_rate); 66eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas delay += rsmp->speex_delay_ns; 67eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas 68eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas return delay; 69eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas} 70eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas 71eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas// outputs a number of frames less or equal to *outFrameCount and updates *outFrameCount 72eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas// with the actual number of frames produced. 73eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultasint resampler_resample_from_provider(struct resampler_itfe *resampler, 74eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas int16_t *out, 75eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas size_t *outFrameCount) 76eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas{ 77eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas struct resampler *rsmp = (struct resampler *)resampler; 78eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas 7990dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock if (rsmp == NULL || out == NULL || outFrameCount == NULL) { 8090dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock return -EINVAL; 8178b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein } 8290dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock if (rsmp->provider == NULL) { 834560461b08b1660fa5776523d8344df0d8d23f1dItzhak Katzenelson *outFrameCount = 0; 8490dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock return -ENOSYS; 8590dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock } 8690dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock 8790dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock size_t framesRq = *outFrameCount; 88c5b45b80a280794ca131b9857c5885c337d4d6e1Isaac Katzenelson // update and cache the number of frames needed at the input sampling rate to produce 89c5b45b80a280794ca131b9857c5885c337d4d6e1Isaac Katzenelson // the number of frames requested at the output sampling rate 90c5b45b80a280794ca131b9857c5885c337d4d6e1Isaac Katzenelson if (framesRq != rsmp->frames_rq) { 919a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler rsmp->frames_needed = (framesRq * rsmp->in_sample_rate) / rsmp->out_sample_rate + 1; 929a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler rsmp->frames_rq = framesRq; 93e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler } 9490dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock 9590dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock size_t framesWr = 0; 9690dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock size_t inFrames = 0; 9790dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock while (framesWr < framesRq) { 9890dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock if (rsmp->frames_in < rsmp->frames_needed) { 9990dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock // make sure that the number of frames present in rsmp->in_buf (rsmp->frames_in) is at 100e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler // least the number of frames needed to produce the number of frames requested at 101e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler // the output sampling rate 102e269bd8658721a71fd9d42084b280042c5258945Daniel Sandler if (rsmp->in_buf_size < rsmp->frames_needed) { 10390dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock rsmp->in_buf_size = rsmp->frames_needed; 10490dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock rsmp->in_buf = (int16_t *)realloc(rsmp->in_buf, 10590dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock rsmp->in_buf_size * rsmp->channel_count * sizeof(int16_t)); 106c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler } 10757ca681913fa5b9cd86a7342a91cfe4cc5b910dfDaniel Sandler struct resampler_buffer buf; 10857ca681913fa5b9cd86a7342a91cfe4cc5b910dfDaniel Sandler buf.frame_count = rsmp->frames_needed - rsmp->frames_in; 10957ca681913fa5b9cd86a7342a91cfe4cc5b910dfDaniel Sandler rsmp->provider->get_next_buffer(rsmp->provider, &buf); 1103d6adf080cb4a1469244e393807f6921b9f1149bJohn Spurlock if (buf.raw == NULL) { 1111a7820902f3a6428f0bb586f8f1b5a2824838cb0Daniel Sandler break; 1129a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler } 1139a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler memcpy(rsmp->in_buf + rsmp->frames_in * rsmp->channel_count, 114eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas buf.raw, 115eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas buf.frame_count * rsmp->channel_count * sizeof(int16_t)); 116eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas rsmp->frames_in += buf.frame_count; 117eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas rsmp->provider->release_buffer(rsmp->provider, &buf); 118eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas } 119eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas 120eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas size_t outFrames = framesRq - framesWr; 121ed2084787cec0f02e6cead215d409d6f2f60f737Alon Albert inFrames = rsmp->frames_in; 122ed2084787cec0f02e6cead215d409d6f2f60f737Alon Albert if (rsmp->channel_count == 1) { 123ed2084787cec0f02e6cead215d409d6f2f60f737Alon Albert speex_resampler_process_int(rsmp->speex_resampler, 124ed2084787cec0f02e6cead215d409d6f2f60f737Alon Albert 0, 1250d4404c04475a66c9bcbda6960bd94597985b785Daniel Sandler rsmp->in_buf, 126c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler &inFrames, 127c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler out + framesWr, 128c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler &outFrames); 12990dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock } else { 13090dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock speex_resampler_process_interleaved_int(rsmp->speex_resampler, 13190dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock rsmp->in_buf, 13290dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock &inFrames, 133c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler out + framesWr * rsmp->channel_count, 134ed2084787cec0f02e6cead215d409d6f2f60f737Alon Albert &outFrames); 135eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas } 136eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas framesWr += outFrames; 137eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas rsmp->frames_in -= inFrames; 138eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas ALOGW_IF((framesWr != framesRq) && (rsmp->frames_in != 0), 139c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler "ReSampler::resample() remaining %d frames in and %d frames out", 140c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler rsmp->frames_in, (framesRq - framesWr)); 1414560461b08b1660fa5776523d8344df0d8d23f1dItzhak Katzenelson } 142b41f177aef12a5aa5ec43057535f5deacf98a881Isaac Katzenelson if (rsmp->frames_in) { 14378b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein memmove(rsmp->in_buf, 144b41f177aef12a5aa5ec43057535f5deacf98a881Isaac Katzenelson rsmp->in_buf + inFrames * rsmp->channel_count, 14578b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein rsmp->frames_in * rsmp->channel_count * sizeof(int16_t)); 14678b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein } 14778b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein *outFrameCount = framesWr; 14878b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein 1498f873a2bca1277f37cc8d08655d73385e5508232Daniel Sandler return 0; 1509a1fd04f15b653a6600629aee41c7d3fd7d843b3Daniel Sandler} 15190dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock 15290dc136d444ba29fe8db6b20872022b18f18dc94John Spurlockint resampler_resample_from_input(struct resampler_itfe *resampler, 153b41f177aef12a5aa5ec43057535f5deacf98a881Isaac Katzenelson int16_t *in, 154b41f177aef12a5aa5ec43057535f5deacf98a881Isaac Katzenelson size_t *inFrameCount, 1554560461b08b1660fa5776523d8344df0d8d23f1dItzhak Katzenelson int16_t *out, 15690dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock size_t *outFrameCount) 15790dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock{ 15878b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein struct resampler *rsmp = (struct resampler *)resampler; 15978b8e1513e24c58ffea6ee4edbebdce85c248f6fSam Blitzstein 160c5b45b80a280794ca131b9857c5885c337d4d6e1Isaac Katzenelson if (rsmp == NULL || in == NULL || inFrameCount == NULL || 161eb3a1f0714e209a8335d84142778465aa6b44c5cRobyn Coultas out == NULL || outFrameCount == NULL) { 162c5b45b80a280794ca131b9857c5885c337d4d6e1Isaac Katzenelson return -EINVAL; 16390dc136d444ba29fe8db6b20872022b18f18dc94John Spurlock } 164c57490dff5bfbf601d4b708fdae029df99f807b2Daniel Sandler 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 189int 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 return -ENODEV; 222 } 223 224 rsmp->itfe.reset = resampler_reset; 225 rsmp->itfe.resample_from_provider = resampler_resample_from_provider; 226 rsmp->itfe.resample_from_input = resampler_resample_from_input; 227 rsmp->itfe.delay_ns = resampler_delay_ns; 228 229 rsmp->provider = provider; 230 rsmp->in_sample_rate = inSampleRate; 231 rsmp->out_sample_rate = outSampleRate; 232 rsmp->channel_count = channelCount; 233 rsmp->in_buf = NULL; 234 rsmp->in_buf_size = 0; 235 236 resampler_reset(&rsmp->itfe); 237 238 int frames = speex_resampler_get_input_latency(rsmp->speex_resampler); 239 rsmp->speex_delay_ns = (int32_t)((1000000000 * (int64_t)frames) / rsmp->in_sample_rate); 240 frames = speex_resampler_get_output_latency(rsmp->speex_resampler); 241 rsmp->speex_delay_ns += (int32_t)((1000000000 * (int64_t)frames) / rsmp->out_sample_rate); 242 243 *resampler = &rsmp->itfe; 244 ALOGV("create_resampler() DONE rsmp %p &rsmp->itfe %p speex %p", 245 rsmp, &rsmp->itfe, rsmp->speex_resampler); 246 return 0; 247} 248 249void release_resampler(struct resampler_itfe *resampler) 250{ 251 struct resampler *rsmp = (struct resampler *)resampler; 252 253 if (rsmp == NULL) { 254 return; 255 } 256 257 free(rsmp->in_buf); 258 259 if (rsmp->speex_resampler != NULL) { 260 speex_resampler_destroy(rsmp->speex_resampler); 261 } 262 free(rsmp); 263} 264