Spaces:
Runtime error
Runtime error
| /* | |
| Copyright 2015 Google Inc. All rights reserved. | |
| Licensed under the Apache License, Version 2.0 (the "License"); | |
| you may not use this file except in compliance with the License. | |
| You may obtain a copy of the License at | |
| http://www.apache.org/licenses/LICENSE-2.0 | |
| Unless required by applicable law or agreed to in writing, software | |
| distributed under the License is distributed on an "AS IS" BASIS, | |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| See the License for the specific language governing permissions and | |
| limitations under the License. | |
| */ | |
| WaveData::WaveData() : sample_rate_(16000) { | |
| } | |
| WaveData::~WaveData() { | |
| } | |
| void WaveData::Set(int number_samples, int sampling_rate, const int16_t *data) { | |
| set_sample_rate(sampling_rate); | |
| resize(number_samples); | |
| for (int n = 0; n < number_samples; ++n) { | |
| (*this)[n] = data[n]; | |
| } | |
| } | |
| int WaveData::sample_rate(void) const { | |
| return sample_rate_; | |
| } | |
| void WaveData::set_sample_rate(int sample_rate) { | |
| sample_rate_ = sample_rate; | |
| } | |
| bool WaveData::Equals(const WaveData &wave_data, int threshold) const { | |
| if (wave_data.size() != size()) { | |
| fprintf(stderr, "Different number of samples"); | |
| return false; | |
| } | |
| if (wave_data.sample_rate() != sample_rate()) { | |
| fprintf(stderr, "Different sample rate"); | |
| return false; | |
| } | |
| for (int i = 0; i < size(); ++i) { | |
| if (abs(wave_data[i] - (*this)[i]) > threshold) { | |
| fprintf(stderr, "Sample %d differs", i); | |
| return false; | |
| } | |
| } | |
| return true; | |
| } | |
| Wave::Wave() { | |
| data_ = new WaveData; | |
| owner_ = true; | |
| } | |
| Wave::Wave(const WaveData *data) { | |
| // Shallow copy | |
| data_ = const_cast<WaveData *>(data); | |
| owner_ = false; | |
| } | |
| Wave::~Wave() { | |
| Clear(); | |
| } | |
| void Wave::Clear() { | |
| if (owner_) { | |
| delete data_; | |
| } | |
| data_ = NULL; | |
| owner_ = true; | |
| } | |
| void Wave::set_data(const WaveData *data) { | |
| if (owner_) { | |
| delete data_; | |
| } | |
| data_ = const_cast<WaveData *>(data); | |
| owner_ = false; | |
| } | |
| void Wave::copy_data(const WaveData &data) { | |
| if (owner_) { | |
| delete data_; | |
| } | |
| data_ = new WaveData(data); | |
| owner_ = true; | |
| } | |
| void Wave::resize(int n, bool clear) { | |
| if (!owner_) { | |
| // copy the data to a local copy | |
| WaveData *new_wave_data = new WaveData(*data_); | |
| new_wave_data->set_sample_rate(data_->sample_rate()); | |
| data_ = new_wave_data; | |
| } | |
| data_->resize(n); | |
| owner_ = true; | |
| } | |
| void Wave::ZeroFill() { | |
| if (!owner_) { | |
| // copy the data to a local copy | |
| WaveData *new_wave_data = new WaveData(*data_); | |
| new_wave_data->set_sample_rate(data_->sample_rate()); | |
| data_ = new_wave_data; | |
| owner_ = true; | |
| } | |
| std::fill(data_->begin(), data_->end(), 0); | |
| } | |
| bool Wave::Load(FileResource *fr) { | |
| WaveIO wave_io; | |
| std::vector<int16_t> *samples = reinterpret_cast<std::vector<int16_t> *>(data_); | |
| int sampling_rate; | |
| bool status = wave_io.Load(fr, samples, &sampling_rate); | |
| set_sample_rate(sampling_rate); | |
| return status; | |
| } | |
| const int16_t Wave::kMaxShort = std::numeric_limits<int16_t>::max() - 1; | |
| const int16_t Wave::kMinShort = std::numeric_limits<int16_t>::min() + 1; | |
| bool Wave::Amplify(float gain) { | |
| return AmplifyBuffer(gain, &(*data_)[0], data_->size()); | |
| } | |
| bool Wave::AmplifyBuffer(float gain, int16_t *buf, uint32_t size) { | |
| bool clipped = false; | |
| for (uint32_t i = 0; i < size; ++i) { | |
| float sample = static_cast<float>(buf[i]) * gain; | |
| if (sample > kMaxShort) { | |
| sample = kMaxShort; | |
| clipped = true; | |
| } else if (sample < kMinShort) { | |
| sample = kMinShort; | |
| clipped = true; | |
| } | |
| buf[i] = static_cast<int16_t>(sample); | |
| } | |
| return !clipped; | |
| } | |