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..b372ead4ffe704c6966a70c09011b5e3042d47c7 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 = 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() {} |
@@ -47,20 +67,30 @@ int32_t AudioTransportProxy::NeedMorePlayData(const size_t nSamples, |
size_t& nSamplesOut, |
int64_t* elapsed_time_ms, |
int64_t* ntp_time_ms) { |
- RTC_DCHECK_EQ(sizeof(int16_t) * nChannels, nBytesPerSample); |
+ // 2 = bytes in sample. |
+ RTC_DCHECK_EQ(2 * nChannels, nBytesPerSample); |
the sun
2016/11/16 20:22:58
Here I think sizeof(int16_t) made the code more re
|
RTC_DCHECK_GE(nChannels, 1u); |
RTC_DCHECK_LE(nChannels, 2u); |
RTC_DCHECK_GE( |
samplesPerSec, |
static_cast<uint32_t>(AudioProcessing::NativeRate::kSampleRate8kHz)); |
+ |
+ // 100 = 1 second / data duration. |
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 +111,26 @@ 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)); |
+ // 8 * 2 = bits per byte * bytes in sample. |
the sun
2016/11/16 20:22:57
Sorry for not being clear. I thought you could jus
aleloi
2016/11/17 18:12:26
Ah, of course...
|
+ RTC_DCHECK_EQ(static_cast<size_t>(bits_per_sample), 8 * 2); |
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. |
the sun
2016/11/16 20:22:57
1 s / 10 ms ?
aleloi
2016/11/17 18:12:26
Acknowledged.
|
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 |