This source file includes following definitions.
- output_frames_ready_
 
- ProvideInput
 
- Flush
 
- SetRatio
 
- ChunkSize
 
#include "media/base/multi_channel_resampler.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/logging.h"
#include "media/base/audio_bus.h"
namespace media {
MultiChannelResampler::MultiChannelResampler(int channels,
                                             double io_sample_rate_ratio,
                                             size_t request_size,
                                             const ReadCB& read_cb)
    : read_cb_(read_cb),
      wrapped_resampler_audio_bus_(AudioBus::CreateWrapper(channels)),
      output_frames_ready_(0) {
  
  resamplers_.reserve(channels);
  for (int i = 0; i < channels; ++i) {
    resamplers_.push_back(new SincResampler(
        io_sample_rate_ratio, request_size, base::Bind(
            &MultiChannelResampler::ProvideInput, base::Unretained(this), i)));
  }
  
  wrapped_resampler_audio_bus_->set_frames(request_size);
  
  
  if (channels > 1) {
    resampler_audio_bus_ = AudioBus::Create(channels - 1, request_size);
    for (int i = 0; i < resampler_audio_bus_->channels(); ++i) {
      wrapped_resampler_audio_bus_->SetChannelData(
          i + 1, resampler_audio_bus_->channel(i));
    }
  }
}
MultiChannelResampler::~MultiChannelResampler() {}
void MultiChannelResampler::Resample(int frames, AudioBus* audio_bus) {
  DCHECK_EQ(static_cast<size_t>(audio_bus->channels()), resamplers_.size());
  
  if (audio_bus->channels() == 1) {
    resamplers_[0]->Resample(frames, audio_bus->channel(0));
    return;
  }
  
  
  
  
  output_frames_ready_ = 0;
  while (output_frames_ready_ < frames) {
    int chunk_size = resamplers_[0]->ChunkSize();
    int frames_this_time = std::min(frames - output_frames_ready_, chunk_size);
    
    for (size_t i = 0; i < resamplers_.size(); ++i) {
      DCHECK_EQ(chunk_size, resamplers_[i]->ChunkSize());
      
      
      
      
      
      
      resamplers_[i]->Resample(
          frames_this_time, audio_bus->channel(i) + output_frames_ready_);
    }
    output_frames_ready_ += frames_this_time;
  }
}
void MultiChannelResampler::ProvideInput(int channel,
                                         int frames,
                                         float* destination) {
  
  
  
  if (channel == 0) {
    wrapped_resampler_audio_bus_->SetChannelData(0, destination);
    read_cb_.Run(output_frames_ready_, wrapped_resampler_audio_bus_.get());
  } else {
    
    
    DCHECK_EQ(frames, wrapped_resampler_audio_bus_->frames());
    
    memcpy(destination, wrapped_resampler_audio_bus_->channel(channel),
           sizeof(*wrapped_resampler_audio_bus_->channel(channel)) * frames);
  }
}
void MultiChannelResampler::Flush() {
  for (size_t i = 0; i < resamplers_.size(); ++i)
    resamplers_[i]->Flush();
}
void MultiChannelResampler::SetRatio(double io_sample_rate_ratio) {
  for (size_t i = 0; i < resamplers_.size(); ++i)
    resamplers_[i]->SetRatio(io_sample_rate_ratio);
}
int MultiChannelResampler::ChunkSize() const {
  DCHECK(!resamplers_.empty());
  return resamplers_[0]->ChunkSize();
}
}