| // 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 |
| |