diff --git a/audio/audio_transport_impl.cc b/audio/audio_transport_impl.cc index d7bdd400b0..363b924f10 100644 --- a/audio/audio_transport_impl.cc +++ b/audio/audio_transport_impl.cc @@ -38,8 +38,8 @@ void InitializeCaptureFrame(int input_sample_rate, RTC_DCHECK(audio_frame); int min_processing_rate_hz = std::min(input_sample_rate, send_sample_rate_hz); for (int native_rate_hz : AudioProcessing::kNativeSampleRatesHz) { - audio_frame->sample_rate_hz_ = native_rate_hz; - if (audio_frame->sample_rate_hz_ >= min_processing_rate_hz) { + audio_frame->SetSampleRateAndChannelSize(native_rate_hz); + if (native_rate_hz >= min_processing_rate_hz) { break; } } @@ -149,6 +149,9 @@ int32_t AudioTransportImpl::RecordedDataIsAvailable( RTC_DCHECK_LE(bytes_per_sample * number_of_frames * number_of_channels, AudioFrame::kMaxDataSizeBytes); + InterleavedView source(static_cast(audio_data), + number_of_frames, number_of_channels); + int send_sample_rate_hz = 0; size_t send_num_channels = 0; bool swap_stereo_channels = false; @@ -162,9 +165,8 @@ int32_t AudioTransportImpl::RecordedDataIsAvailable( std::unique_ptr audio_frame(new AudioFrame()); InitializeCaptureFrame(sample_rate, send_sample_rate_hz, number_of_channels, send_num_channels, audio_frame.get()); - voe::RemixAndResample(static_cast(audio_data), - number_of_frames, number_of_channels, sample_rate, - &capture_resampler_, audio_frame.get()); + voe::RemixAndResample(source, sample_rate, &capture_resampler_, + audio_frame.get()); ProcessCaptureFrame(audio_delay_milliseconds, key_pressed, swap_stereo_channels, audio_processing_, audio_frame.get()); diff --git a/audio/remix_resample.cc b/audio/remix_resample.cc index fdea627675..b5f673a07c 100644 --- a/audio/remix_resample.cc +++ b/audio/remix_resample.cc @@ -24,48 +24,49 @@ namespace voe { void RemixAndResample(const AudioFrame& src_frame, PushResampler* resampler, AudioFrame* dst_frame) { - RemixAndResample(src_frame.data(), src_frame.samples_per_channel_, - src_frame.num_channels_, src_frame.sample_rate_hz_, - resampler, dst_frame); + RemixAndResample(src_frame.data_view(), src_frame.sample_rate_hz_, resampler, + dst_frame); dst_frame->timestamp_ = src_frame.timestamp_; dst_frame->elapsed_time_ms_ = src_frame.elapsed_time_ms_; dst_frame->ntp_time_ms_ = src_frame.ntp_time_ms_; dst_frame->packet_infos_ = src_frame.packet_infos_; } -// TODO: b/335805780 - Accept ArrayView. -void RemixAndResample(const int16_t* src_data, - size_t samples_per_channel, - size_t num_channels, +void RemixAndResample(InterleavedView src_data, int sample_rate_hz, PushResampler* resampler, AudioFrame* dst_frame) { - const int16_t* audio_ptr = src_data; - size_t audio_ptr_num_channels = num_channels; + // The `samples_per_channel_` members must have been set correctly based on + // the associated sample rate and the assumed 10ms buffer size. + // TODO(tommi): Remove the `sample_rate_hz` param. + RTC_DCHECK_EQ(SampleRateToDefaultChannelSize(sample_rate_hz), + src_data.samples_per_channel()); + RTC_DCHECK_EQ(SampleRateToDefaultChannelSize(dst_frame->sample_rate_hz_), + dst_frame->samples_per_channel()); + + // Temporary buffer in case downmixing is required. std::array downmixed_audio; // Downmix before resampling. - if (num_channels > dst_frame->num_channels_) { - RTC_DCHECK(num_channels == 2 || num_channels == 4) - << "num_channels: " << num_channels; + if (src_data.num_channels() > dst_frame->num_channels_) { + RTC_DCHECK(src_data.num_channels() == 2 || src_data.num_channels() == 4) + << "num_channels: " << src_data.num_channels(); RTC_DCHECK(dst_frame->num_channels_ == 1 || dst_frame->num_channels_ == 2) << "dst_frame->num_channels_: " << dst_frame->num_channels_; - AudioFrameOperations::DownmixChannels( - InterleavedView(src_data, samples_per_channel, - num_channels), - InterleavedView(&downmixed_audio[0], samples_per_channel, - dst_frame->num_channels_)); - audio_ptr = downmixed_audio.data(); - audio_ptr_num_channels = dst_frame->num_channels_; + InterleavedView downmixed(downmixed_audio.data(), + src_data.samples_per_channel(), + dst_frame->num_channels_); + AudioFrameOperations::DownmixChannels(src_data, downmixed); + src_data = downmixed; } if (resampler->InitializeIfNeeded(sample_rate_hz, dst_frame->sample_rate_hz_, - audio_ptr_num_channels) == -1) { + src_data.num_channels()) == -1) { RTC_FATAL() << "InitializeIfNeeded failed: sample_rate_hz = " << sample_rate_hz << ", dst_frame->sample_rate_hz_ = " << dst_frame->sample_rate_hz_ - << ", audio_ptr_num_channels = " << audio_ptr_num_channels; + << ", num_channels = " << src_data.num_channels(); } // TODO(yujo): for muted input frames, don't resample. Either 1) allow @@ -73,28 +74,19 @@ void RemixAndResample(const int16_t* src_data, // how much to zero here; or 2) make resampler accept a hint that the input is // zeroed. - // Ensure the `samples_per_channel_` member is set correctly based on the - // destination sample rate, number of channels and assumed 10ms buffer size. - // TODO(tommi): Could we rather assume that this has been done by the caller? - dst_frame->SetSampleRateAndChannelSize(dst_frame->sample_rate_hz_); - - InterleavedView src_view(audio_ptr, samples_per_channel, - audio_ptr_num_channels); // Stash away the originally requested number of channels. Then provide // `dst_frame` as a target buffer with the same number of channels as the // source. auto original_dst_number_of_channels = dst_frame->num_channels_; int out_length = resampler->Resample( - src_view, dst_frame->mutable_data(dst_frame->samples_per_channel_, - src_view.num_channels())); - RTC_CHECK_NE(out_length, -1) << "Resample failed: audio_ptr = " << audio_ptr - << ", src_length = " << src_view.data().size(); - + src_data, dst_frame->mutable_data(dst_frame->samples_per_channel_, + src_data.num_channels())); + RTC_CHECK_NE(out_length, -1) << "src_data.size=" << src_data.size(); RTC_DCHECK_EQ(dst_frame->samples_per_channel(), - out_length / audio_ptr_num_channels); + out_length / src_data.num_channels()); // Upmix after resampling. - if (num_channels == 1 && original_dst_number_of_channels == 2) { + if (src_data.num_channels() == 1 && original_dst_number_of_channels == 2) { // The audio in dst_frame really is mono at this point; MonoToStereo will // set this back to stereo. RTC_DCHECK_EQ(dst_frame->num_channels_, 1); diff --git a/audio/remix_resample.h b/audio/remix_resample.h index 580ba40310..d2f34686dd 100644 --- a/audio/remix_resample.h +++ b/audio/remix_resample.h @@ -12,6 +12,7 @@ #define AUDIO_REMIX_RESAMPLE_H_ #include "api/audio/audio_frame.h" +#include "api/audio/audio_view.h" #include "common_audio/resampler/include/push_resampler.h" namespace webrtc { @@ -30,12 +31,9 @@ void RemixAndResample(const AudioFrame& src_frame, PushResampler* resampler, AudioFrame* dst_frame); -// This version has a pointer to the samples `src_data` as input and receives -// `samples_per_channel`, `num_channels` and `sample_rate_hz` of the data as -// parameters. -void RemixAndResample(const int16_t* src_data, - size_t samples_per_channel, - size_t num_channels, +// TODO(tommi): The `sample_rate_hz` argument can probably be removed since it's +// always related to `src_data.samples_per_frame()'. +void RemixAndResample(InterleavedView src_data, int sample_rate_hz, PushResampler* resampler, AudioFrame* dst_frame);