// (virtual) int PcmDecoder::decode( int dst_count, int16_t* dst_data) { if (dst_count <= 0) return 0; if (dst_data == NULL) return 0; if (offset_ >= dst_count_) return 0; int actual_count = 0; const uint8_t* src_samples = static_cast<const uint8_t*>(get_raw_data()); int64_t offset = offset_; int cached_index = -1; int16_t cached_sample = 0; for (int i = 0; i < dst_count && offset < dst_count_; ++i) { int src_index = static_cast<int>((offset * dst_ratio_) >> 16); if (src_index != cached_index) { cached_index = src_index; cached_sample = pcm8_to_pcm16(src_samples[src_index]); } dst_data[i] = cached_sample; ++offset; ++actual_count; } offset = offset_; for (int i = 0; i < actual_count; ++i) { if (!(i == 0 && offset == 0)) { int16_t prev_sample; if (i > 0) prev_sample = dst_data[i - 1]; else prev_sample = last_sample_; dst_data[i] = static_cast<int16_t>( (alpha_ * dst_data[i]) + (one_minus_alpha_ * prev_sample)); } ++offset; } offset_ = offset; last_sample_ = dst_data[actual_count - 1]; return actual_count; }
int PcmDecoder::decode( const int dst_count, std::int16_t* const dst_data) { if (dst_count <= 0) { return 0; } if (!dst_data) { return 0; } if (offset_ >= dst_count_) { return 0; } auto actual_count = 0; const auto src_samples = static_cast<const std::uint8_t*>(get_raw_data()); auto offset = offset_; auto cached_index = -1; auto cached_sample = std::int16_t{}; for (int i = 0; i < dst_count && offset < dst_count_; ++i) { const auto src_index = static_cast<int>((offset * dst_ratio_) >> 16); if (src_index != cached_index) { cached_index = src_index; cached_sample = pcm8_to_pcm16(src_samples[src_index]); } dst_data[i] = cached_sample; ++offset; ++actual_count; } offset = offset_; for (int i = 0; i < actual_count; ++i) { if (!(i == 0 && offset == 0)) { auto prev_sample = std::int16_t{}; if (i > 0) { prev_sample = dst_data[i - 1]; } else { prev_sample = last_sample_; } dst_data[i] = static_cast<std::int16_t>((alpha_ * dst_data[i]) + (one_minus_alpha_ * prev_sample)); } ++offset; } offset_ = offset; last_sample_ = dst_data[actual_count - 1]; return actual_count; }