blob: 293e1cc072a7e4381f9ced1ed2be9f3727745f60 [file] [log] [blame]
// Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <stdio.h>
#include <stdlib.h>
#include "log.h"
#include "resampler.h"
#include "libresample/libresample.h"
namespace speech_synthesis {
Resampler::Resampler(TtsDataReceiver *destination,
int source_rate,
int dest_rate,
int buffer_size)
: destination_(destination),
source_rate_(source_rate),
dest_rate_(dest_rate),
buffer_size_(buffer_size) {
const int high_quality = 0;
factor_ = dest_rate_ * 1.0 / source_rate_;
resample_handle_ = resample_open(high_quality, factor_, factor_);
in_floats_ = new float[buffer_size_];
out_floats_ = new float[buffer_size_];
out_int16s_ = new int16_t[buffer_size_];
}
Resampler::~Resampler() {
resample_close(resample_handle_);
delete[] in_floats_;
delete[] out_floats_;
delete[] out_int16s_;
}
tts_callback_status Resampler::Receive(int rate,
int num_channels,
const int16_t* data,
int num_samples,
tts_synth_status synth_status) {
if (num_samples > buffer_size_) {
LOG(ERROR) << "Got " << num_samples << " samples, buffer size is " <<
buffer_size_ << "\n";
exit(-1);
}
if (rate != source_rate_) {
LOG(ERROR) << "Got input rate of " << rate << " expected " <<
source_rate_ << "\n";
exit(-1);
}
for (int i = 0; i < num_samples; i++) {
in_floats_[i] = data[i];
}
int last_flag = (synth_status == TTS_SYNTH_DONE? 1 : 0);
int input_index = 0;
while (input_index < num_samples) {
int in_buffer_used;
int out_samples = resample_process(resample_handle_,
factor_,
&in_floats_[input_index],
num_samples - input_index,
last_flag,
&in_buffer_used,
out_floats_,
buffer_size_);
input_index += in_buffer_used;
for (int i = 0; i < out_samples; i++) {
int value = static_cast<int>(out_floats_[i]);
if (value > 32767)
value = 32767;
if (value < -32768)
value = -32768;
out_int16s_[i] = static_cast<int16_t>(value);
}
tts_synth_status status;
if (synth_status == TTS_SYNTH_DONE && input_index == num_samples) {
status = TTS_SYNTH_DONE;
} else {
status = TTS_SYNTH_PENDING;
}
tts_callback_status callback_status = destination_->Receive(
dest_rate_, 1, out_int16s_, out_samples, status);
if (callback_status != TTS_CALLBACK_CONTINUE) {
return callback_status;
}
}
return TTS_CALLBACK_CONTINUE;
}
} // namespace speech_synthesis