Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 17 additions & 13 deletions modules/audio_device/audio_engine_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,9 @@ class AudioEngineDevice : public AudioDeviceModule, public AudioSessionObserver
bool output_enabled = false;
bool output_running = false;

bool output_available = true;
bool input_available = true;

// Output will be enabled when input is enabled
bool input_follow_mode = true;
bool input_enabled_persistent_mode = false;
Expand All @@ -146,6 +149,7 @@ class AudioEngineDevice : public AudioDeviceModule, public AudioSessionObserver
bool operator==(const EngineState& rhs) const {
return input_enabled == rhs.input_enabled && input_running == rhs.input_running &&
output_enabled == rhs.output_enabled && output_running == rhs.output_running &&
input_available == rhs.input_available && output_available == rhs.output_available &&
input_follow_mode == rhs.input_follow_mode &&
input_enabled_persistent_mode == rhs.input_enabled_persistent_mode &&
input_muted == rhs.input_muted && is_interrupted == rhs.is_interrupted &&
Expand All @@ -164,33 +168,29 @@ class AudioEngineDevice : public AudioDeviceModule, public AudioSessionObserver
bool IsOutputInputLinked() const { return input_follow_mode && voice_processing_enabled; }

bool IsOutputEnabled() const {
return IsOutputInputLinked() ? (IsInputEnabled() || output_enabled) : output_enabled;
bool result = IsOutputInputLinked() ? (IsInputEnabled() || output_enabled) : output_enabled;
return output_available && result;
}

bool IsOutputRunning() const {
return IsOutputInputLinked() ? (IsInputRunning() || output_running) : output_running;
bool result = IsOutputInputLinked() ? (IsInputRunning() || output_running) : output_running;
return output_available && result;
}

bool IsInputEnabled() const {
return !(mute_mode == MuteMode::RestartEngine && input_muted) &&
(input_enabled || input_enabled_persistent_mode);
bool result = !(mute_mode == MuteMode::RestartEngine && input_muted) &&
(input_enabled || input_enabled_persistent_mode);
return input_available && result;
}

bool IsInputRunning() const {
return !(mute_mode == MuteMode::RestartEngine && input_muted) && input_running;
bool result = !(mute_mode == MuteMode::RestartEngine && input_muted) && input_running;
return input_available && result;
}

bool IsAnyEnabled() const { return IsInputEnabled() || IsOutputEnabled(); }
bool IsAnyRunning() const { return IsInputRunning() || IsOutputRunning(); }

bool IsAllEnabled() const {
return IsOutputInputLinked() ? IsInputEnabled() : IsInputEnabled() && output_enabled;
}

bool IsAllRunning() const {
return IsOutputInputLinked() ? input_running : input_running && output_running;
}

bool IsOutputDefaultDevice() const {
#if TARGET_OS_OSX
return output_device_id == kAudioObjectUnknown;
Expand Down Expand Up @@ -303,6 +303,9 @@ class AudioEngineDevice : public AudioDeviceModule, public AudioSessionObserver
int32_t SetEngineState(EngineState enable);
int32_t GetEngineState(EngineState* enabled);

int32_t SetEngineAvailability(bool input_available, bool output_available);
int32_t EngineAvailability(bool* input_available, bool* output_available);

int32_t SetObserver(AudioDeviceObserver* observer) override;

int32_t SetManualRenderingMode(bool enable);
Expand Down Expand Up @@ -412,6 +415,7 @@ class AudioEngineDevice : public AudioDeviceModule, public AudioSessionObserver

bool IsMicrophonePermissionGranted();
int32_t ModifyEngineState(std::function<EngineState(EngineState)> state_transform);

int32_t ApplyDeviceEngineState(EngineStateUpdate state);
int32_t ApplyManualEngineState(EngineStateUpdate state);

Expand Down
27 changes: 27 additions & 0 deletions modules/audio_device/audio_engine_device.mm
Original file line number Diff line number Diff line change
Expand Up @@ -1111,6 +1111,33 @@
return result;
}

int32_t AudioEngineDevice::SetEngineAvailability(bool input_available, bool output_available) {
RTC_DCHECK_RUN_ON(thread_);
LOGI() << "SetEngineAvailability: " << input_available << " " << output_available;

int32_t result =
ModifyEngineState([input_available, output_available](EngineState state) -> EngineState {
state.input_available = input_available;
state.output_available = output_available;
return state;
});

return result;
}

int32_t AudioEngineDevice::EngineAvailability(bool* input_available, bool* output_available) {
RTC_DCHECK_RUN_ON(thread_);

if (input_available == nullptr || output_available == nullptr) {
return -1;
}

*input_available = engine_state_.input_available;
*output_available = engine_state_.output_available;

return 0;
}

int32_t AudioEngineDevice::ManualRenderingMode(bool* enabled) {
LOGI() << "ManualRenderingMode";
RTC_DCHECK_RUN_ON(thread_);
Expand Down
19 changes: 14 additions & 5 deletions sdk/objc/api/peerconnection/RTCAudioDeviceModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,19 @@ typedef NS_ENUM(NSInteger, RTC_OBJC_TYPE(RTCAudioEngineMuteMode)) {
};

typedef struct {
bool outputEnabled;
bool outputRunning;
bool inputEnabled;
bool inputRunning;
bool inputMuted;
BOOL outputEnabled;
BOOL outputRunning;
BOOL inputEnabled;
BOOL inputRunning;
BOOL inputMuted;
RTC_OBJC_TYPE(RTCAudioEngineMuteMode) muteMode;
} RTC_OBJC_TYPE(RTCAudioEngineState);

typedef struct {
BOOL isInputAvailable;
BOOL isOutputAvailable;
} RTC_OBJC_TYPE(RTCAudioEngineAvailability);

RTC_EXTERN NSString *const RTC_CONSTANT_TYPE(RTCAudioEngineInputMixerNodeKey);

@class RTC_OBJC_TYPE(RTCAudioDeviceModule);
Expand Down Expand Up @@ -141,6 +146,8 @@ RTC_OBJC_EXPORT

- (NSInteger)initAndStartRecording;

- (NSInteger)setEngineAvailability:(RTC_OBJC_TYPE(RTCAudioEngineAvailability))availability;

// For testing purposes
@property(nonatomic, readonly) BOOL isPlayoutInitialized;
@property(nonatomic, readonly) BOOL isRecordingInitialized;
Expand Down Expand Up @@ -185,6 +192,8 @@ RTC_OBJC_EXPORT
/// enabled. Enabled by default when VPIO is enabled.
@property(nonatomic, assign, getter=isVoiceProcessingAGCEnabled) BOOL voiceProcessingAGCEnabled;

@property(nonatomic, readonly) RTC_OBJC_TYPE(RTCAudioEngineAvailability) engineAvailability;

@end

NS_ASSUME_NONNULL_END
24 changes: 24 additions & 0 deletions sdk/objc/api/peerconnection/RTCAudioDeviceModule.mm
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,30 @@ - (void)setEngineState:(RTC_OBJC_TYPE(RTCAudioEngineState))state {

#pragma mark - Unique to AudioEngineDevice

- (NSInteger)setEngineAvailability:(RTC_OBJC_TYPE(RTCAudioEngineAvailability))availability {
webrtc::AudioEngineDevice *module = dynamic_cast<webrtc::AudioEngineDevice *>(_native.get());
if (module == nullptr) return -1;

return _workerThread->BlockingCall([module, availability] {
return module->SetEngineAvailability(availability.isInputAvailable,
availability.isOutputAvailable);
});
}

- (RTC_OBJC_TYPE(RTCAudioEngineAvailability))engineAvailability {
webrtc::AudioEngineDevice *module = dynamic_cast<webrtc::AudioEngineDevice *>(_native.get());
if (module == nullptr) return RTC_OBJC_TYPE(RTCAudioEngineAvailability)(NO, NO);

return _workerThread->BlockingCall([module] {
bool input_available = false;
bool output_available = false;
int32_t result = module->EngineAvailability(&input_available, &output_available);
if (result != 0) return RTC_OBJC_TYPE(RTCAudioEngineAvailability)(NO, NO);

return RTC_OBJC_TYPE(RTCAudioEngineAvailability)(input_available, output_available);
});
}

- (BOOL)isRecordingAlwaysPreparedMode {
webrtc::AudioEngineDevice *module = dynamic_cast<webrtc::AudioEngineDevice *>(_native.get());
if (module == nullptr) return NO;
Expand Down