1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192 |
- #include "precompile.h"
- #include "audioresample.h"
- #include "audiolog.h"
- #include "audiocontext.h"
- #include <speex/speex_resampler.h>
- static apr_status_t read_frame(void *self, audioframe_t *frame)
- {
- apr_status_t status;
- audioresample_t *resample = CONTAINING_RECORD(self, audioresample_t, base);
- spx_uint32_t in_len;
- spx_uint32_t out_len;
- resample->read_resampled_frame.size = SUGGEST_FRAME_SIZE;
- status = resample->base.downstream->vtbl->read_frame(resample->base.downstream,
- &resample->read_resampled_frame);
- if (status != APR_SUCCESS)
- return status;
- in_len = (spx_uint32_t)resample->downstream_psize / 2;
- speex_resampler_process_int(resample->read_state, 0,
- (spx_int16_t*)&resample->read_resampled_frame.buffer[0], &in_len,
- (spx_int16_t*)&frame->buffer[0], &out_len);
- frame->size = out_len * 2;
- frame->dtmf = resample->read_resampled_frame.dtmf;
- return APR_SUCCESS;
- }
- static apr_status_t write_frame(void *self, const audioframe_t *frame)
- {
- apr_status_t status;
- audioresample_t *resample = CONTAINING_RECORD(self, audioresample_t, base);
- spx_uint32_t in_len;
- spx_uint32_t out_len;
- in_len = resample->upstream_psize / 2;
- speex_resampler_process_int(resample->write_state, 0,
- (spx_int16_t*)&frame->buffer[0], &in_len,
- (spx_int16_t*)&resample->write_resampled_frame.buffer[0], &out_len);
- resample->write_resampled_frame.size = out_len * 2;
- resample->write_resampled_frame.dtmf = frame->dtmf;
-
- status = resample->base.downstream->vtbl->write_frame(resample->base.downstream,
- &resample->write_resampled_frame);
- if (status != APR_SUCCESS)
- return status;
- return APR_SUCCESS;
- }
- static audiostream_vtbl_t g_stream_vtbl = {
- &read_frame,
- &write_frame,
- };
- apr_status_t audioresample_create(apr_pool_t *pool,
- audioengine_t *engine,
- int upstream_rate,
- int downstream_rate,
- int quality,
- audioresample_t **p_resample)
- {
- audioresample_t *resample;
- resample = apr_palloc(pool, sizeof(audioresample_t));
- audiostream_init(engine, &g_stream_vtbl, &resample->base);
- resample->base.direction = STREAM_DIR_BOTH;
- resample->quality = quality;
- resample->upstream_rate = upstream_rate;
- resample->downstream_rate = downstream_rate;
- resample->upstream_psize = 2 * FRAME_TIME * upstream_rate / 1000;
- resample->downstream_psize = 2 * FRAME_TIME * downstream_rate / 1000;
- resample->read_resampled_frame.size = SUGGEST_FRAME_SIZE;
- resample->read_resampled_frame.buffer = apr_palloc(pool, SUGGEST_FRAME_SIZE);
- resample->read_resampled_frame.dtmf = 0;
- resample->write_resampled_frame.size = SUGGEST_FRAME_SIZE;
- resample->write_resampled_frame.buffer = apr_palloc(pool, SUGGEST_FRAME_SIZE);
- resample->write_resampled_frame.dtmf = 0;
- resample->read_state = speex_resampler_init(1, downstream_rate, upstream_rate, quality, NULL);
- resample->write_state = speex_resampler_init(1, upstream_rate, downstream_rate, quality, NULL);
- *p_resample = resample;
- return APR_SUCCESS;
- }
- void audioresample_destroy(audioresample_t *resample)
- {
- speex_resampler_destroy(resample->read_state);
- speex_resampler_destroy(resample->write_state);
- }
|