Index: webrtc/audio/audio_transport_proxy.cc |
diff --git a/webrtc/audio/audio_transport_proxy.cc b/webrtc/audio/audio_transport_proxy.cc |
index ed72200379d1d07fab29e04482b761ea732cb6e2..163cc11c7760f1495eaca6dc8c62c85715aa3f53 100644 |
--- a/webrtc/audio/audio_transport_proxy.cc |
+++ b/webrtc/audio/audio_transport_proxy.cc |
@@ -12,12 +12,32 @@ |
namespace webrtc { |
+namespace { |
+// Resample audio in |frame| to given sample rate preserving the |
+// channel count and place the result in |destination|. |
+int Resample(const AudioFrame& frame, |
+ const int destination_sample_rate, |
+ PushResampler<int16_t>* resampler, |
+ int16_t* destination) { |
+ const int number_of_channels = static_cast<int>(frame.num_channels_); |
+ const int target_number_of_samples_per_channel = |
+ destination_sample_rate / 100; |
+ resampler->InitializeIfNeeded(frame.sample_rate_hz_, destination_sample_rate, |
+ number_of_channels); |
+ |
+ return resampler->Resample( |
+ frame.data_, frame.samples_per_channel_ * number_of_channels, destination, |
+ number_of_channels * target_number_of_samples_per_channel); |
+} |
+} // namespace |
+ |
AudioTransportProxy::AudioTransportProxy(AudioTransport* voe_audio_transport, |
AudioProcessing* apm, |
AudioMixer* mixer) |
- : voe_audio_transport_(voe_audio_transport) { |
+ : voe_audio_transport_(voe_audio_transport), apm_(apm), mixer_(mixer) { |
RTC_DCHECK(voe_audio_transport); |
RTC_DCHECK(apm); |
+ RTC_DCHECK(mixer); |
} |
AudioTransportProxy::~AudioTransportProxy() {} |
@@ -53,14 +73,23 @@ int32_t AudioTransportProxy::NeedMorePlayData(const size_t nSamples, |
RTC_DCHECK_GE( |
samplesPerSec, |
static_cast<uint32_t>(AudioProcessing::NativeRate::kSampleRate8kHz)); |
+ |
+ // 100 = 1 second / data duration (10 ms). |
RTC_DCHECK_EQ(nSamples * 100, samplesPerSec); |
RTC_DCHECK_LE(nBytesPerSample * nSamples * nChannels, |
sizeof(AudioFrame::data_)); |
- // Pass call through to original audio transport instance. |
- return voe_audio_transport_->NeedMorePlayData( |
- nSamples, nBytesPerSample, nChannels, samplesPerSec, audioSamples, |
- nSamplesOut, elapsed_time_ms, ntp_time_ms); |
+ mixer_->Mix(nChannels, &mixed_frame_); |
+ *elapsed_time_ms = mixed_frame_.elapsed_time_ms_; |
+ *ntp_time_ms = mixed_frame_.ntp_time_ms_; |
+ |
+ const auto error = apm_->ProcessReverseStream(&mixed_frame_); |
+ RTC_DCHECK_EQ(error, AudioProcessing::kNoError); |
+ |
+ nSamplesOut = Resample(mixed_frame_, samplesPerSec, &resampler_, |
+ static_cast<int16_t*>(audioSamples)); |
+ RTC_DCHECK_EQ(nSamplesOut, nChannels * nSamples); |
+ return 0; |
} |
void AudioTransportProxy::PushCaptureData(int voe_channel, |
@@ -81,17 +110,25 @@ void AudioTransportProxy::PullRenderData(int bits_per_sample, |
void* audio_data, |
int64_t* elapsed_time_ms, |
int64_t* ntp_time_ms) { |
- RTC_DCHECK_EQ(static_cast<size_t>(bits_per_sample), 8 * sizeof(int16_t)); |
+ RTC_DCHECK_EQ(static_cast<size_t>(bits_per_sample), 16); |
RTC_DCHECK_GE(number_of_channels, 1u); |
RTC_DCHECK_LE(number_of_channels, 2u); |
RTC_DCHECK_GE(static_cast<int>(sample_rate), |
AudioProcessing::NativeRate::kSampleRate8kHz); |
+ |
+ // 100 = 1 second / data duration (10 ms). |
RTC_DCHECK_EQ(static_cast<int>(number_of_frames * 100), sample_rate); |
+ |
+ // 8 = bits per byte. |
RTC_DCHECK_LE(bits_per_sample / 8 * number_of_frames * number_of_channels, |
sizeof(AudioFrame::data_)); |
- voe_audio_transport_->PullRenderData( |
- bits_per_sample, sample_rate, number_of_channels, number_of_frames, |
- audio_data, elapsed_time_ms, ntp_time_ms); |
+ mixer_->Mix(number_of_channels, &mixed_frame_); |
+ *elapsed_time_ms = mixed_frame_.elapsed_time_ms_; |
+ *ntp_time_ms = mixed_frame_.ntp_time_ms_; |
+ |
+ const auto output_samples = Resample(mixed_frame_, sample_rate, &resampler_, |
+ static_cast<int16_t*>(audio_data)); |
+ RTC_DCHECK_EQ(output_samples, number_of_channels * number_of_frames); |
} |
} // namespace webrtc |