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