Revert changes to modules/audio_device files

This commit is contained in:
Jim Gustafson 2025-11-07 17:17:33 -08:00 committed by GitHub
parent 37c5088468
commit f6d7f2beaa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 152 additions and 165 deletions

View File

@ -14,7 +14,7 @@ jobs:
- check: 'ringrtc'
exclude: '(oboe|opus)'
- check: 'sdk'
exclude: '(objc)'
exclude: '(objc|jni_helpers\.h)'
steps:
- uses: actions/checkout@v4
- name: Run clang-format

View File

@ -256,8 +256,6 @@ rtc_library("audio_device_impl") {
":audio_device_default",
":audio_device_dummy",
":audio_device_generic",
# RingRTC change to include Windows ADM2.
":audio_device_module_from_input_and_output",
"../../api:array_view",
"../../api:make_ref_counted",
"../../api:ref_count",

View File

@ -1598,8 +1598,7 @@ int32_t AudioDeviceLinuxPulse::InitPulseAudio() {
PaUnLock();
return -1;
}
// RingRTC change to the name of the context.
_paContext = LATE(pa_context_new)(_paMainloopApi, "Signal Calling");
_paContext = LATE(pa_context_new)(_paMainloopApi, "WEBRTC VoiceEngine");
if (!_paContext) {
RTC_LOG(LS_ERROR) << "could not create context";

View File

@ -72,11 +72,7 @@ const uint32_t WEBRTC_PA_PLAYBACK_LATENCY_INCREMENT_MSECS = 20;
// CPU from the overhead of transfering small amounts of data at once. Too large
// and the amount of data remaining in the buffer right before refilling it
// would be a buffer underflow risk. We set it to half of the buffer size.
// RingRTC change to avoid scratchy audio.
// Update: with 2, we often get scratchy audio.
// The Pulse code indicates 2 is a bad idea and 4 is a good idea.
// See https://github.com/pulseaudio/pulseaudio/blob/master/src/pulsecore/protocol-native.c#L814
const uint32_t WEBRTC_PA_PLAYBACK_REQUEST_FACTOR = 4;
const uint32_t WEBRTC_PA_PLAYBACK_REQUEST_FACTOR = 2;
// Capture.

View File

@ -118,6 +118,8 @@ AudioDeviceMac::AudioDeviceMac()
_twoDevices(true),
_doStop(false),
_doStopRec(false),
_macBookPro(false),
_macBookProPanRight(false),
_captureLatencyUs(0),
_renderLatencyUs(0),
_captureDelayUs(0),
@ -291,7 +293,22 @@ AudioDeviceGeneric::InitStatus AudioDeviceMac::Init() {
WEBRTC_CA_LOG_ERR(AudioObjectAddPropertyListener(
kAudioObjectSystemObject, &propertyAddress, &objectListenerProc, this));
// RingRTC changes (code removed) to avoid speaker panning
// Determine if this is a MacBook Pro
_macBookPro = false;
_macBookProPanRight = false;
char buf[128];
size_t length = sizeof(buf);
memset(buf, 0, length);
int intErr = sysctlbyname("hw.model", buf, &length, NULL, 0);
if (intErr != 0) {
RTC_LOG(LS_ERROR) << "Error in sysctlbyname(): " << err;
} else {
RTC_LOG(LS_VERBOSE) << "Hardware model: " << buf;
if (strncmp(buf, "MacBookPro", 10) == 0) {
_macBookPro = true;
}
}
_initialized = true;
@ -960,9 +977,34 @@ int32_t AudioDeviceMac::InitPlayout() {
_renderDeviceIsAlive = 1;
_doStop = false;
// RingRTC changes (code removed) to avoid speaker panning
// The internal microphone of a MacBook Pro is located under the left speaker
// grille. When the internal speakers are in use, we want to fully stereo
// pan to the right.
AudioObjectPropertyAddress propertyAddress = {
kAudioDevicePropertyDataSource, kAudioDevicePropertyScopeOutput, 0};
if (_macBookPro) {
_macBookProPanRight = false;
Boolean hasProperty =
AudioObjectHasProperty(_outputDeviceID, &propertyAddress);
if (hasProperty) {
UInt32 dataSource = 0;
size = sizeof(dataSource);
WEBRTC_CA_LOG_WARN(AudioObjectGetPropertyData(
_outputDeviceID, &propertyAddress, 0, NULL, &size, &dataSource));
if (dataSource == 'ispk') {
_macBookProPanRight = true;
RTC_LOG(LS_VERBOSE)
<< "MacBook Pro using internal speakers; stereo panning right";
} else {
RTC_LOG(LS_VERBOSE) << "MacBook Pro not using internal speakers";
}
// Add a listener to determine if the status changes.
WEBRTC_CA_LOG_WARN(AudioObjectAddPropertyListener(
_outputDeviceID, &propertyAddress, &objectListenerProc, this));
}
}
// Get current stream description
propertyAddress.mSelector = kAudioDevicePropertyStreamFormat;
@ -1033,8 +1075,7 @@ int32_t AudioDeviceMac::InitPlayout() {
}
int32_t AudioDeviceMac::InitRecording() {
// RingRTC change to log more information around audio capture
RTC_LOG(LS_WARNING) << "InitRecording";
RTC_LOG(LS_INFO) << "InitRecording";
MutexLock lock(&mutex_);
if (_recording) {
@ -1264,8 +1305,6 @@ int32_t AudioDeviceMac::StartRecording() {
}
_recording = true;
// RingRTC change to log more information around audio capture
RTC_LOG(LS_WARNING) << "Started recording";
return 0;
}
@ -1284,8 +1323,6 @@ int32_t AudioDeviceMac::StopRecording() {
// Recording side uses its own dedicated device and IOProc.
if (_recording) {
_recording = false;
// RingRTC change to log more information around audio capture
RTC_LOG(LS_WARNING) << "Stopped recording";
_doStopRec = true; // Signal to io proc to stop audio device
mutex_.Unlock(); // Cannot be under lock, risk of deadlock
if (!_stopEventRec.Wait(TimeDelta::Seconds(2))) {
@ -1314,10 +1351,8 @@ int32_t AudioDeviceMac::StopRecording() {
// rendering has ended before stopping itself.
if (_recording && captureDeviceIsAlive == 1) {
_recording = false;
// RingRTC change to log more information around audio capture
RTC_LOG(LS_WARNING) << "Stopped recording";
_doStop = true; // Signal to io proc to stop audio device
mutex_.Unlock(); // Cannot be under lock, risk of deadlock
_doStop = true; // Signal to io proc to stop audio device
mutex_.Unlock(); // Cannot be under lock, risk of deadlock
if (!_stopEvent.Wait(TimeDelta::Seconds(2))) {
MutexLock lockScoped(&mutex_);
RTC_LOG(LS_WARNING) << "Timed out stopping the shared IOProc."
@ -1361,8 +1396,6 @@ int32_t AudioDeviceMac::StopRecording() {
_recIsInitialized = false;
_recording = false;
// RingRTC change to log more information around audio capture
RTC_LOG(LS_WARNING) << "Stopped recording";
return 0;
}
@ -1474,6 +1507,16 @@ int32_t AudioDeviceMac::StopPlayout() {
WEBRTC_CA_LOG_WARN(AudioObjectRemovePropertyListener(
_outputDeviceID, &propertyAddress, &objectListenerProc, this));
if (_macBookPro) {
Boolean hasProperty =
AudioObjectHasProperty(_outputDeviceID, &propertyAddress);
if (hasProperty) {
propertyAddress.mSelector = kAudioDevicePropertyDataSource;
WEBRTC_CA_LOG_WARN(AudioObjectRemovePropertyListener(
_outputDeviceID, &propertyAddress, &objectListenerProc, this));
}
}
_playIsInitialized = false;
_playing = false;
@ -1865,6 +1908,8 @@ OSStatus AudioDeviceMac::implObjectListenerProc(
HandleDeviceChange();
} else if (addresses[i].mSelector == kAudioDevicePropertyStreamFormat) {
HandleStreamFormatChange(objectId, addresses[i]);
} else if (addresses[i].mSelector == kAudioDevicePropertyDataSource) {
HandleDataSourceChange(objectId, addresses[i]);
} else if (addresses[i].mSelector == kAudioDeviceProcessorOverload) {
HandleProcessorOverload(addresses[i]);
}
@ -1950,13 +1995,10 @@ int32_t AudioDeviceMac::HandleStreamFormatChange(
return -1;
}
// RingRTC change to check for a channel change for the input device only
if (propertyAddress.mScope == kAudioDevicePropertyScopeInput) {
if (_ptrAudioBuffer && streamFormat.mChannelsPerFrame != _recChannels) {
RTC_LOG(LS_ERROR) << "Changing channels not supported (mChannelsPerFrame = "
<< streamFormat.mChannelsPerFrame << ")";
return -1;
}
if (_ptrAudioBuffer && streamFormat.mChannelsPerFrame != _recChannels) {
RTC_LOG(LS_ERROR) << "Changing channels not supported (mChannelsPerFrame = "
<< streamFormat.mChannelsPerFrame << ")";
return -1;
}
RTC_LOG(LS_VERBOSE) << "Stream format:";
@ -2012,8 +2054,31 @@ int32_t AudioDeviceMac::HandleStreamFormatChange(
return 0;
}
// RingRTC changes (code removed) to avoid speaker panning
int32_t AudioDeviceMac::HandleDataSourceChange(
const AudioObjectID objectId,
const AudioObjectPropertyAddress propertyAddress) {
OSStatus err = noErr;
if (_macBookPro &&
propertyAddress.mScope == kAudioDevicePropertyScopeOutput) {
RTC_LOG(LS_VERBOSE) << "Data source changed";
_macBookProPanRight = false;
UInt32 dataSource = 0;
UInt32 size = sizeof(UInt32);
WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(
objectId, &propertyAddress, 0, NULL, &size, &dataSource));
if (dataSource == 'ispk') {
_macBookProPanRight = true;
RTC_LOG(LS_VERBOSE)
<< "MacBook Pro using internal speakers; stereo panning right";
} else {
RTC_LOG(LS_VERBOSE) << "MacBook Pro not using internal speakers";
}
}
return 0;
}
int32_t AudioDeviceMac::HandleProcessorOverload(
const AudioObjectPropertyAddress propertyAddress) {
// TODO(xians): we probably want to notify the user in some way of the
@ -2331,7 +2396,24 @@ bool AudioDeviceMac::RenderWorkerThread() {
uint32_t nOutSamples = nSamples * _outDesiredFormat.mChannelsPerFrame;
SInt16* pPlayBuffer = (SInt16*)&playBuffer;
// RingRTC changes (code removed) to avoid speaker panning
if (_macBookProPanRight && (_playChannels == 2)) {
// Mix entirely into the right channel and zero the left channel.
SInt32 sampleInt32 = 0;
for (uint32_t sampleIdx = 0; sampleIdx < nOutSamples; sampleIdx += 2) {
sampleInt32 = pPlayBuffer[sampleIdx];
sampleInt32 += pPlayBuffer[sampleIdx + 1];
sampleInt32 /= 2;
if (sampleInt32 > 32767) {
sampleInt32 = 32767;
} else if (sampleInt32 < -32768) {
sampleInt32 = -32768;
}
pPlayBuffer[sampleIdx] = 0;
pPlayBuffer[sampleIdx + 1] = static_cast<SInt16>(sampleInt32);
}
}
PaUtil_WriteRingBuffer(_paRenderBuffer, pPlayBuffer, nOutSamples);
@ -2348,11 +2430,8 @@ bool AudioDeviceMac::CaptureWorkerThread() {
AudioBufferList engineBuffer;
engineBuffer.mNumberBuffers = 1; // Interleaved channels.
engineBuffer.mBuffers->mNumberChannels = _inDesiredFormat.mChannelsPerFrame;
// RingRTC change to ensure AudioConverterFillComplexBuffer doesn't write
// past the end of recordBuffer.
// (Upstream, both `noRecSamples` and `mBytesPerPacket` take
// mChannelsPerFrame into account, so if that's 2, this size is too large.)
engineBuffer.mBuffers->mDataByteSize = sizeof(SInt16) * noRecSamples;
engineBuffer.mBuffers->mDataByteSize =
_inDesiredFormat.mBytesPerPacket * noRecSamples;
engineBuffer.mBuffers->mData = recordBuffer.data();
err = AudioConverterFillComplexBuffer(_captureConverter, inConverterProc,
@ -2396,9 +2475,6 @@ bool AudioDeviceMac::CaptureWorkerThread() {
// deliver recorded samples at specified sample rate, mic level etc.
// to the observer using callback
_ptrAudioBuffer->DeliverRecordedData();
} else {
// RingRTC change to log more information around audio capture
RTC_LOG(LS_ERROR) << "Ignoring captured audio samples for invalid size of " << size;
}
return true;

View File

@ -307,6 +307,8 @@ class AudioDeviceMac : public AudioDeviceGeneric {
bool _twoDevices;
bool _doStop; // For play if not shared device or play+rec if shared device
bool _doStopRec; // For rec if not shared device
bool _macBookPro;
bool _macBookProPanRight;
AudioConverterRef _captureConverter;
AudioConverterRef _renderConverter;

View File

@ -539,8 +539,7 @@ int32_t AudioMixerManagerMac::StereoPlayoutIsAvailable(bool& available) {
return -1;
}
// RingRTC change to allow output to stereo if more than 2 channels
available = (_noOutputChannels >= 2);
available = (_noOutputChannels == 2);
return 0;
}

View File

@ -529,8 +529,7 @@ AudioDeviceWindowsCore::~AudioDeviceWindowsCore() {
<< "AudioDeviceWindowsCore::~AudioDeviceWindowsCore()"
" failed to free the loaded Avrt DLL module correctly";
} else {
// RingRTC change to reduce log noise.
RTC_LOG(LS_INFO) << "AudioDeviceWindowsCore::~AudioDeviceWindowsCore()"
RTC_LOG(LS_WARNING) << "AudioDeviceWindowsCore::~AudioDeviceWindowsCore()"
" the Avrt DLL module is now unloaded";
}
}

View File

@ -389,27 +389,15 @@ bool CoreAudioBase::Init() {
}
}
// RingRTC change to get the mix_format keep it in scope for multi-channel.
WAVEFORMATPCMEX mix_format;
HRESULT res = core_audio_utility::GetSharedModeMixFormat(
audio_client.Get(), &mix_format);
if (FAILED(res)) {
return false;
}
RTC_LOG(LS_WARNING) << (IsInput() ? "input " : "output ")
<< "mix_format: "
<< core_audio_utility::WaveFormatToString(&mix_format);
// Retrieve preferred audio input or output parameters for the given client
// and the specified client properties. Override the preferred rate if sample
// rate has been defined by the user. Rate conversion will be performed by
// the audio engine to match the client if needed.
AudioParameters params;
res = sample_rate_ ? core_audio_utility::GetPreferredAudioParameters(
audio_client.Get(), &params, &mix_format, *sample_rate_)
: core_audio_utility::GetPreferredAudioParameters(
audio_client.Get(), &params, &mix_format);
HRESULT res = sample_rate_ ? core_audio_utility::GetPreferredAudioParameters(
audio_client.Get(), &params, *sample_rate_)
: core_audio_utility::GetPreferredAudioParameters(
audio_client.Get(), &params);
if (FAILED(res)) {
return false;
}
@ -427,7 +415,9 @@ bool CoreAudioBase::Init() {
// TODO(henrika): ensure that this approach works on different multi-channel
// devices. Verified on:
// - Corsair VOID PRO Surround USB Adapter (supports 7.1)
// Try the first multi-channel format clamped to 2 (stereo).
RTC_LOG(LS_WARNING)
<< "Using channel upmixing in WASAPI audio engine (2 => "
<< params.channels() << ")";
format->nChannels = 2;
}
format->nSamplesPerSec = params.sample_rate();
@ -451,27 +441,7 @@ bool CoreAudioBase::Init() {
if (!sample_rate_) {
if (!core_audio_utility::IsFormatSupported(
audio_client.Get(), AUDCLNT_SHAREMODE_SHARED, &format_)) {
// RingRTC change to try again to match a format for multi-channel.
if (params.channels() > 2) {
format->nChannels = params.channels();
format->nBlockAlign = (format->wBitsPerSample / 8) * format->nChannels;
format->nAvgBytesPerSec = format->nSamplesPerSec * format->nBlockAlign;
// Maintain the channel mask for multi-channel from the mix_format.
format_.dwChannelMask = mix_format.dwChannelMask;
RTC_LOG(LS_WARNING) << "Trying again with: "
<< core_audio_utility::WaveFormatToString(&format_);
if (!core_audio_utility::IsFormatSupported(
audio_client.Get(), AUDCLNT_SHAREMODE_SHARED, &format_)) {
RTC_LOG(LS_ERROR) << "No multi-channel format matched";
return false;
}
} else {
RTC_LOG(LS_ERROR) << "No format matched";
return false;
}
return false;
}
}
@ -791,8 +761,8 @@ AudioSessionState CoreAudioBase::GetAudioSessionState() const {
RTC_DCHECK(audio_session_control_.Get());
_com_error error = audio_session_control_->GetState(&state);
if (FAILED(error.Error())) {
RTC_LOG(LS_ERROR) << "IAudioSessionControl::GetState failed: "
<< core_audio_utility::ErrorToString(error);
RTC_DLOG(LS_ERROR) << "IAudioSessionControl::GetState failed: "
<< core_audio_utility::ErrorToString(error);
}
return state;
}

View File

@ -121,10 +121,7 @@ int CoreAudioInput::InitRecording() {
WAVEFORMATEX* format = &format_.Format;
RTC_DCHECK_EQ(format->wFormatTag, WAVE_FORMAT_EXTENSIBLE);
audio_device_buffer_->SetRecordingSampleRate(format->nSamplesPerSec);
// RingRTC change to ensure that the audio_device_buffer is
// configured for a limit of either 1 or 2 channels.
audio_device_buffer_->SetRecordingChannels(std::min((UINT16)2, format->nChannels));
audio_device_buffer_->SetRecordingChannels(format->nChannels);
// Create a modified audio buffer class which allows us to supply any number
// of samples (and not only multiple of 10ms) to match the optimal buffer
@ -273,9 +270,7 @@ bool CoreAudioInput::OnDataCallback(uint64_t device_frequency) {
// This is concurrent examination of state across multiple threads so will
// be somewhat error prone, but we should still be defensive and not use
// audio_capture_client_ if we know it's not there.
// RingRTC change to support Windows ADM2.
RTC_LOG(LS_WARNING) << "CoreAudioInput::OnDataCallback not yet ready";
return true;
return false;
}
if (num_data_callbacks_ == 0) {
RTC_LOG(LS_INFO) << "--- Input audio stream is alive ---";
@ -358,26 +353,11 @@ bool CoreAudioInput::OnDataCallback(uint64_t device_frequency) {
audio_data, format_.Format.nBlockAlign * num_frames_to_read);
RTC_DLOG(LS_WARNING) << "Captured audio is replaced by silence";
} else {
// RingRTC change to shift multiple channels to stereo channels.
UINT16 nChannels = format_.Format.nChannels;
if (nChannels > 2) {
// Copy the first two channels of sample data from each frame and
// shift to the beginning of the audio data buffer.
int16_t* audio_data_ptr = (int16_t*)audio_data;
for (UINT32 i = 1; i < num_frames_to_read; ++i) {
memcpy(&audio_data_ptr[i * 2], &audio_data_ptr[i * nChannels], 2 * sizeof(int16_t));
}
// Reset nChannels to stereo now that the data is shifted.
nChannels = 2;
}
// Copy recorded audio in `audio_data` to the WebRTC sink using the
// FineAudioBuffer object.
fine_audio_buffer_->DeliverRecordedData(
webrtc::MakeArrayView(reinterpret_cast<const int16_t*>(audio_data),
nChannels * num_frames_to_read),
format_.Format.nChannels * num_frames_to_read),
latency_ms_);
}

View File

@ -118,11 +118,7 @@ int CoreAudioOutput::InitPlayout() {
WAVEFORMATEX* format = &format_.Format;
RTC_DCHECK_EQ(format->wFormatTag, WAVE_FORMAT_EXTENSIBLE);
audio_device_buffer_->SetPlayoutSampleRate(format->nSamplesPerSec);
// RingRTC change to ensure that the audio_device_buffer is configured
// for a limit of either 1 or 2 channels.
audio_device_buffer_->SetPlayoutChannels(
std::min((UINT16)2, format->nChannels));
audio_device_buffer_->SetPlayoutChannels(format->nChannels);
// Create a modified audio buffer class which allows us to ask for any number
// of samples (and not only multiple of 10ms) to match the optimal
@ -159,7 +155,7 @@ int CoreAudioOutput::StartPlayout() {
RTC_DCHECK(fine_audio_buffer_);
RTC_DCHECK(audio_device_buffer_);
if (!initialized_) {
RTC_LOG(LS_WARNING)
RTC_DLOG(LS_WARNING)
<< "Playout can not start since InitPlayout must succeed first";
}
@ -192,7 +188,7 @@ int CoreAudioOutput::StopPlayout() {
// Release resources allocated in InitPlayout() and then return if this
// method is called without any active output audio.
if (!Playing()) {
RTC_LOG(LS_WARNING) << "No output stream is active";
RTC_DLOG(LS_WARNING) << "No output stream is active";
ReleaseCOMObjects();
initialized_ = false;
return 0;
@ -341,29 +337,9 @@ bool CoreAudioOutput::OnDataCallback(uint64_t device_frequency) {
// `audio_data`. The playout latency is not updated for each callback.
fine_audio_buffer_->GetPlayoutData(
webrtc::MakeArrayView(reinterpret_cast<int16_t*>(audio_data),
num_requested_frames *
// RingRTC change to ensure that only 1 or 2
// channels are read from the buffer.
std::min((UINT16)2, format_.Format.nChannels)),
num_requested_frames * format_.Format.nChannels),
latency_ms_);
// RingRTC change to expand 2 channels to multiple channels.
if (format_.Format.nChannels > 2) {
UINT32 bytes_per_frame = format_.Format.nChannels * sizeof(int16_t);
UINT32 bytes_per_stereo_frame = 2 * sizeof(int16_t);
// Shift each stereo frame to start on the render frame's stride and
// set the remaining channels to zero (silence).
int16_t* audio_data_ptr = (int16_t*)audio_data;
for (UINT32 i = num_requested_frames - 1; i > 0; --i) {
memmove(&audio_data_ptr[i * format_.Format.nChannels],
&audio_data_ptr[i * 2], bytes_per_stereo_frame);
memset(&audio_data_ptr[i * format_.Format.nChannels + 2],
0, bytes_per_frame - bytes_per_stereo_frame);
}
memset(&audio_data_ptr[2], 0, bytes_per_frame - bytes_per_stereo_frame);
}
// Release the buffer space acquired in IAudioRenderClient::GetBuffer.
error = audio_render_client_->ReleaseBuffer(num_requested_frames, 0);
if (FAILED(error.Error())) {

View File

@ -496,7 +496,7 @@ bool GetDeviceNamesInternal(EDataFlow data_flow,
}
if (number_of_active_devices == 0) {
RTC_LOG(LS_WARNING) << "Found no active devices";
RTC_DLOG(LS_WARNING) << "Found no active devices";
return false;
}
@ -596,19 +596,21 @@ bool GetDeviceNamesInternal(EDataFlow data_flow,
return true;
}
// RingRTC change to pass the mix_format for multi-channel.
HRESULT GetPreferredAudioParametersInternal(IAudioClient* client,
AudioParameters* params,
const WAVEFORMATPCMEX* mix_format,
int fixed_sample_rate) {
REFERENCE_TIME default_period = 0;
HRESULT hr = core_audio_utility::GetDevicePeriod(client,
AUDCLNT_SHAREMODE_SHARED,
&default_period);
WAVEFORMATPCMEX mix_format;
HRESULT hr = core_audio_utility::GetSharedModeMixFormat(client, &mix_format);
if (FAILED(hr))
return hr;
int sample_rate = mix_format->Format.nSamplesPerSec;
REFERENCE_TIME default_period = 0;
hr = core_audio_utility::GetDevicePeriod(client, AUDCLNT_SHAREMODE_SHARED,
&default_period);
if (FAILED(hr))
return hr;
int sample_rate = mix_format.Format.nSamplesPerSec;
// Override default sample rate if `fixed_sample_rate` is set and different
// from the default rate.
if (fixed_sample_rate > 0 && fixed_sample_rate != sample_rate) {
@ -616,10 +618,10 @@ HRESULT GetPreferredAudioParametersInternal(IAudioClient* client,
<< sample_rate << " is replaced by " << fixed_sample_rate;
sample_rate = fixed_sample_rate;
}
// TODO(henrika): utilize full mix_format->Format.wBitsPerSample.
// TODO(henrika): utilize full mix_format.Format.wBitsPerSample.
// const size_t bits_per_sample = AudioParameters::kBitsPerSample;
// TODO(henrika): improve channel layout support.
const size_t channels = mix_format->Format.nChannels;
const size_t channels = mix_format.Format.nChannels;
// Use the native device period to derive the smallest possible buffer size
// in shared mode.
@ -1010,8 +1012,7 @@ HRESULT GetSharedModeMixFormat(IAudioClient* client,
// Verify that the reported format can be mixed by the audio engine in
// shared mode.
if (!wrapped_format.IsPcm() && !wrapped_format.IsFloat()) {
// RingRTC change to pass the mix_format for multi-channel.
RTC_LOG(LS_ERROR)
RTC_DLOG(LS_ERROR)
<< "Only pure PCM or float audio streams can be mixed in shared mode";
return AUDCLNT_E_UNSUPPORTED_FORMAT;
}
@ -1019,8 +1020,7 @@ HRESULT GetSharedModeMixFormat(IAudioClient* client,
// Log a warning for the rare case where `mix_format` only contains a
// stand-alone WAVEFORMATEX structure but don't return.
if (!wrapped_format.IsExtensible()) {
// RingRTC change to pass the mix_format for multi-channel.
RTC_LOG(LS_WARNING)
RTC_DLOG(LS_WARNING)
<< "The returned format contains no extended information. "
"The size is "
<< wrapped_format.size() << " bytes.";
@ -1057,9 +1057,9 @@ bool IsFormatSupported(IAudioClient* client,
} else if ((error.Error() == S_FALSE) && (closest_match != nullptr)) {
// Call succeeded with a closest match to the specified format. This log can
// only be triggered for shared mode.
// RingRTC change to pass the mix_format for multi-channel.
RTC_LOG(LS_WARNING) << "No exact match, closest: "
<< WaveFormatToString(closest_match.Get());
RTC_LOG(LS_WARNING)
<< "Exact format is not supported, but a closest match exists";
RTC_LOG(LS_INFO) << WaveFormatToString(closest_match.Get());
} else if ((error.Error() == AUDCLNT_E_UNSUPPORTED_FORMAT) &&
(closest_match == nullptr)) {
// The audio engine does not support the caller-specified format or any
@ -1143,23 +1143,19 @@ HRESULT GetSharedModeEnginePeriod(IAudioClient3* client3,
return error.Error();
}
// RingRTC change to pass the mix_format for multi-channel.
HRESULT GetPreferredAudioParameters(IAudioClient* client,
AudioParameters* params,
const WAVEFORMATPCMEX* mix_format) {
AudioParameters* params) {
RTC_DLOG(LS_INFO) << "GetPreferredAudioParameters";
RTC_DCHECK(client);
return GetPreferredAudioParametersInternal(client, params, mix_format, -1);
return GetPreferredAudioParametersInternal(client, params, -1);
}
// RingRTC change to pass the mix_format for multi-channel.
HRESULT GetPreferredAudioParameters(IAudioClient* client,
webrtc::AudioParameters* params,
const WAVEFORMATPCMEX* mix_format,
uint32_t sample_rate) {
RTC_DLOG(LS_INFO) << "GetPreferredAudioParameters: " << sample_rate;
RTC_DCHECK(client);
return GetPreferredAudioParametersInternal(client, params, mix_format, sample_rate);
return GetPreferredAudioParametersInternal(client, params, sample_rate);
}
HRESULT SharedModeInitialize(IAudioClient* client,

View File

@ -452,17 +452,13 @@ HRESULT GetSharedModeEnginePeriod(IAudioClient3* client3,
// shared-mode streams. The acquired values should only be utilized for shared
// mode streamed since there are no preferred settings for an exclusive mode
// stream.
// RingRTC change to pass the mix_format for multi-channel.
HRESULT GetPreferredAudioParameters(IAudioClient* client,
webrtc::AudioParameters* params,
const WAVEFORMATPCMEX* mix_format);
webrtc::AudioParameters* params);
// As above but override the preferred sample rate and use `sample_rate`
// instead. Intended mainly for testing purposes and in combination with rate
// conversion.
// RingRTC change to pass the mix_format for multi-channel.
HRESULT GetPreferredAudioParameters(IAudioClient* client,
webrtc::AudioParameters* params,
const WAVEFORMATPCMEX* mix_format,
uint32_t sample_rate);
// After activating an IAudioClient interface on an audio endpoint device,