SWITCH_DECLARE(switch_status_t) switch_resample_perform_create(switch_audio_resampler_t **new_resampler,
uint32_t from_rate, uint32_t to_rate, uint32_t to_size,
int quality,
+ uint32_t channels,
const char *file, const char *func, int line);
-#define switch_resample_create(_n, _fr, _tr, _ts, _q) switch_resample_perform_create(_n, _fr, _tr, _ts, _q, __FILE__, __SWITCH_FUNC__, __LINE__)
+#define switch_resample_create(_n, _fr, _tr, _ts, _q, _c) switch_resample_perform_create(_n, _fr, _tr, _ts, _q, _c, __FILE__, __SWITCH_FUNC__, __LINE__)
/*!
\brief Destroy an existing resampler handle
if (read_impl.actual_samples_per_second != conference->rate) {
if (switch_resample_create(&member->read_resampler,
read_impl.actual_samples_per_second,
- conference->rate, member->frame_size, SWITCH_RESAMPLE_QUALITY) != SWITCH_STATUS_SUCCESS) {
+ conference->rate, member->frame_size, SWITCH_RESAMPLE_QUALITY, 1) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Unable to create resampler!\n");
goto done;
}
}
}
+ if (fh->pre_buffer_datalen) {
+ //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Prebuffering %d bytes\n", (int)fh->pre_buffer_datalen);
+ switch_buffer_create_dynamic(&fh->pre_buffer, fh->pre_buffer_datalen * fh->channels, fh->pre_buffer_datalen * fh->channels / 2, 0);
+ fh->pre_buffer_data = switch_core_alloc(fh->memory_pool, fh->pre_buffer_datalen * fh->channels);
+ }
+
if (fh->channels > 1 && (flags & SWITCH_FILE_FLAG_READ)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "File has %d channels, muxing to mono will occur.\n", fh->channels);
}
if (!switch_test_flag(fh, SWITCH_FILE_NATIVE) && fh->native_rate != fh->samplerate) {
if (!fh->resampler) {
if (switch_resample_create(&fh->resampler,
- fh->native_rate, fh->samplerate, (uint32_t) orig_len, SWITCH_RESAMPLE_QUALITY) != SWITCH_STATUS_SUCCESS) {
+ fh->native_rate, fh->samplerate, (uint32_t) orig_len, SWITCH_RESAMPLE_QUALITY, 1) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Unable to create resampler!\n");
return SWITCH_STATUS_GENERR;
}
if (switch_resample_create(&fh->resampler,
fh->native_rate,
fh->samplerate,
- (uint32_t) orig_len *fh->channels,
- SWITCH_RESAMPLE_QUALITY) != SWITCH_STATUS_SUCCESS) {
+ (uint32_t) orig_len * 2 * fh->channels,
+ SWITCH_RESAMPLE_QUALITY, fh->channels) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Unable to create resampler!\n");
return SWITCH_STATUS_GENERR;
}
}
- switch_resample_process(fh->resampler, data, (uint32_t)(*len * fh->channels));
- if (fh->resampler->to_len > orig_len * fh->channels) {
+ switch_resample_process(fh->resampler, data, (uint32_t)*len);
+
+ if (fh->resampler->to_len > orig_len) {
if (!fh->dbuf) {
void *mem;
- fh->dbuflen = fh->resampler->to_len * 2;
+ fh->dbuflen = fh->resampler->to_len * 2 * fh->channels;
mem = realloc(fh->dbuf, fh->dbuflen);
switch_assert(mem);
fh->dbuf = mem;
}
switch_assert(fh->resampler->to_len * 2 <= fh->dbuflen);
- memcpy(fh->dbuf, fh->resampler->to, fh->resampler->to_len * 2);
+ memcpy(fh->dbuf, fh->resampler->to, fh->resampler->to_len * 2 * fh->channels);
data = fh->dbuf;
} else {
- memcpy(data, fh->resampler->to, fh->resampler->to_len * 2);
+ memcpy(data, fh->resampler->to, fh->resampler->to_len * 2 * fh->channels);
}
- *len = fh->resampler->to_len / fh->channels;
-
+ *len = fh->resampler->to_len;
}
if (!*len) {
if (rlen >= fh->pre_buffer_datalen) {
if ((blen = switch_buffer_read(fh->pre_buffer, fh->pre_buffer_data, fh->pre_buffer_datalen))) {
if (!asis) blen /= 2;
- if (fh->channels) blen /= fh->channels;
+ if (fh->channels > 1) blen /= fh->channels;
if ((status = fh->file_interface->file_write(fh, fh->pre_buffer_data, &blen)) != SWITCH_STATUS_SUCCESS) {
*len = 0;
}
while((rlen = switch_buffer_inuse(fh->pre_buffer))) {
if ((blen = switch_buffer_read(fh->pre_buffer, fh->pre_buffer_data, fh->pre_buffer_datalen))) {
if (!asis) blen /= 2;
- if (fh->channels) blen /= fh->channels;
+ if (fh->channels > 1) blen /= fh->channels;
if (fh->file_interface->file_write(fh, fh->pre_buffer_data, &blen) != SWITCH_STATUS_SUCCESS) {
break;
}
read_frame->codec->implementation->actual_samples_per_second,
session->read_impl.actual_samples_per_second,
session->read_impl.decoded_bytes_per_packet,
- SWITCH_RESAMPLE_QUALITY);
+ SWITCH_RESAMPLE_QUALITY, 1);
switch_mutex_unlock(session->resample_mutex);
frame->codec->implementation->actual_samples_per_second,
session->write_impl.actual_samples_per_second,
session->write_impl.decoded_bytes_per_packet,
- SWITCH_RESAMPLE_QUALITY);
+ SWITCH_RESAMPLE_QUALITY, 1);
switch_mutex_unlock(session->resample_mutex);
frame->codec->implementation->actual_samples_per_second,
session->write_impl.actual_samples_per_second,
session->write_impl.decoded_bytes_per_packet,
- SWITCH_RESAMPLE_QUALITY);
+ SWITCH_RESAMPLE_QUALITY, 1);
}
switch_mutex_unlock(session->resample_mutex);
if (sh->native_rate && sh->samplerate && sh->native_rate != sh->samplerate) {
if (!sh->resampler) {
if (switch_resample_create(&sh->resampler,
- sh->native_rate, sh->samplerate, (uint32_t) orig_len, SWITCH_RESAMPLE_QUALITY) != SWITCH_STATUS_SUCCESS) {
+ sh->native_rate, sh->samplerate, (uint32_t) orig_len, SWITCH_RESAMPLE_QUALITY, 1) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Unable to create resampler!\n");
return SWITCH_STATUS_GENERR;
}
uint32_t from_rate, uint32_t to_rate,
uint32_t to_size,
int quality,
+ uint32_t channels,
const char *file, const char *func, int line)
{
int err = 0;
switch_zmalloc(resampler, sizeof(*resampler));
- resampler->resampler = speex_resampler_init(1, from_rate, to_rate, quality, &err);
+ resampler->resampler = speex_resampler_init(channels ? channels : 1, from_rate, to_rate, quality, &err);
if (!resampler->resampler) {
free(resampler);
SWITCH_DECLARE(uint32_t) switch_resample_process(switch_audio_resampler_t *resampler, int16_t *src, uint32_t srclen)
{
resampler->to_len = resampler->to_size;
- speex_resampler_process_int(resampler->resampler, 0, src, &srclen, resampler->to, &resampler->to_len);
+ speex_resampler_process_interleaved_int(resampler->resampler, src, &srclen, resampler->to, &resampler->to_len);
return resampler->to_len;
}