Skip to content

Commit

Permalink
ios_simulator: trigger category change notification through timer, si…
Browse files Browse the repository at this point in the history
…nce NC does not work
  • Loading branch information
z-dule committed May 30, 2024
1 parent 6cc7b79 commit 0c245dd
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 60 deletions.
7 changes: 4 additions & 3 deletions src/audio_io/ios/audio_io_ios.mm
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@
if (!is_recording_.load()) {
OSStatus result = AudioOutputUnitStart(au_);
if (result != noErr) {
error("audio_io_ios: AudioOutputUnitStart failed:0x08x\n", result);
error("audio_io_ios: AudioOutputUnitStart failed:0x%08x\n", result);
return -1;
}
}
Expand Down Expand Up @@ -550,7 +550,7 @@

int32_t audio_io_ios::init_play_or_record(void)
{
info("audio_io_ios: AudioDeviceIOS::InitPlayOrRecord \n");
info("audio_io_ios: AudioDeviceIOS::InitPlayOrRecord\n");

assert(!au_);

Expand Down Expand Up @@ -579,6 +579,7 @@
want_stereo_playout_, use_stereo_playout);

NSString *cat = [AVAudioSession sharedInstance].category;
info("audio_io_ios: category=%s\n", [cat UTF8String]);
if (cat != AVAudioSessionCategoryPlayAndRecord){
error("audio_io_ios: catagory not "
"AVAudioSessionCategoryPlayAndRecord\n");
Expand Down Expand Up @@ -776,7 +777,7 @@
// Initialize here already to be able to get/set stream properties.
result = AudioUnitInitialize(au_);
if (0 != result) {
error("audio_io_ios: AudioUnitInitialize failed: %d \n", result);
error("audio_io_ios: AudioUnitInitialize failed: 0x%08x\n", result);
return -1;
}

Expand Down
155 changes: 98 additions & 57 deletions src/mediamgr/mm_platform_iosx.m
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@

#include <TargetConditionals.h>

#import <Foundation/Foundation.h>
#import <AVFoundation/AVFoundation.h>
Expand Down Expand Up @@ -31,6 +32,10 @@
struct tmr tmr_play;
struct tmr tmr_rec;

#if TARGET_IPHONE_SIMULATOR
struct tmr tmr_cat;
#endif

} mm_ios = {
.mm = NULL,
.incall = false,
Expand All @@ -52,6 +57,9 @@
static void set_category(NSString *cat, bool speaker);
static bool set_category_sync(NSString *cat, bool speaker);
static void default_category(bool sync);
#if TARGET_IPHONE_SIMULATOR
static void cat_change_timeout(void *arg);
#endif


static bool set_active_sync(bool active)
Expand All @@ -61,7 +69,7 @@ static bool set_active_sync(bool active)
AVAudioSessionSetActiveOptions options =
AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation;

info("mm_ios: set_active_sync: active=%d\n", active);
info("mm_platform_ios: set_active_sync: active=%d\n", active);

success = [[AVAudioSession sharedInstance]
setActive:active ? YES : NO
Expand All @@ -74,6 +82,9 @@ static bool set_active_sync(bool active)
active ? "YES" : "NO", (long)err.code,
[err.localizedDescription UTF8String]);
}
else {
NSLog(@"mm_platform_ios: active successfull\n");
}

mm_ios.active = active;

Expand All @@ -85,6 +96,8 @@ static void set_active(bool active)
{
info("mm_platform_ios: set_active: active=%s\n",
active ? "yes" : "no");
NSLog(@"mm_platform_ios: set_active: active=%s\n",
active ? "yes" : "no");

dispatch_sync(dispatch_get_main_queue(), ^{
set_active_sync(active);
Expand Down Expand Up @@ -342,6 +355,13 @@ static bool set_category_sync(NSString *cat, bool speaker)
[err.localizedDescription UTF8String]);
}

#if TARGET_IPHONE_SIMULATOR
NSLog(@"mm_platform_ios: simulator using timer for cat change success=%d\n", success);
if (success) {
tmr_start(&mm_ios.tmr_cat, 500, cat_change_timeout, NULL);
}
#endif

return success ? true : false;
}

Expand Down Expand Up @@ -490,7 +510,7 @@ static void handle_audio_interruption(NSNotification *notification)

NSDictionary *dict;
NSInteger type;

dict = notification.userInfo;
type = [[dict valueForKey:AVAudioSessionInterruptionTypeKey]
integerValue];
Expand All @@ -512,6 +532,67 @@ static void handle_audio_interruption(NSNotification *notification)
}
}

static void category_change(NSString *cat)
{
AVAudioSession *sess = [AVAudioSession sharedInstance];

info("mm_platform_ios: cat change: in:%s new=%s rec=%d\n",
cat_name(mm_ios.cat), cat_name(cat), mm_ios.recording);

if (msystem_audio_is_activated()) {
debug("mm_platform_ios: cat change without CallKit\n");
if (!mm_ios.interrupted
&& mediamgr_should_reset(mm_ios.mm)) {
debug("mm_platform_ios: reseting audio\n");
mediamgr_audio_reset_mm(mm_ios.mm);
}
}
else {
debug("mm_platform_ios: cat change with CallKit\n");
}

if (mm_ios.cat == cat && !mm_ios.incall)
return;

if (mm_ios.recording)
return;

if (cat == AVAudioSessionCategoryPlayAndRecord) {
NSError *err = nil;
BOOL success = [sess setMode:AVAudioSessionModeVoiceChat
error:&err];
if (!success) {
error("mm_platform_ios: incall_category: "
"could not set VoiceChat mode: %ld\n",
(long)err.code);
}
mediamgr_sys_entered_call(mm_ios.mm);
}
else if (cat == AVAudioSessionCategorySoloAmbient) {
if (mm_ios.cat == AVAudioSessionCategoryPlayAndRecord)
leave_call();
else
mediamgr_sys_incoming(mm_ios.mm);
}
else {
leave_call();
}
mm_ios.cat = cat;
}

#if TARGET_IPHONE_SIMULATOR
static void cat_change_timeout(void *arg)
{
NSString *cat = [[AVAudioSession sharedInstance] category];

(void)arg;

NSLog(@"mm_platform_ios: cat_change_timeout: cat=%@\n", cat);

category_change(cat);
}
#endif

static void handle_audio_notification(NSNotification *notification)
{
NSDictionary *dict;
Expand All @@ -520,8 +601,8 @@ static void handle_audio_notification(NSNotification *notification)
AVAudioSession* sess;
NSString *cat;
NSArray *input_routes;
BOOL success;
NSError *err = nil;

NSLog(@"mm_platform_ios: handle_audio_notification: mm=%p\n", mm_ios.mm);

if (!mm_ios.mm)
return;
Expand Down Expand Up @@ -627,48 +708,7 @@ static void handle_audio_notification(NSNotification *notification)

case AVAudioSessionRouteChangeReasonOverride:
case AVAudioSessionRouteChangeReasonCategoryChange:
info("mm_platform_ios: cat change: in:%s new=%s rec=%d\n",
cat_name(mm_ios.cat), cat_name(cat), mm_ios.recording);

if (msystem_audio_is_activated()) {
debug("mm_platform_ios: cat change without CallKit\n");
if (!mm_ios.interrupted
&& mediamgr_should_reset(mm_ios.mm)) {
debug("mm_platform_ios: reseting audio\n");
mediamgr_audio_reset_mm(mm_ios.mm);
}
}
else {
debug("mm_platform_ios: cat change with CallKit\n");
}

if (mm_ios.cat == cat && !mm_ios.incall)
break;

if (mm_ios.recording)
break;

if (cat == AVAudioSessionCategoryPlayAndRecord) {
success = [sess setMode:AVAudioSessionModeVoiceChat
error:&err];
if (!success) {
error("mm_platform_ios: incall_category: "
"could not set VoiceChat mode: %ld\n",
(long)err.code);
}

mediamgr_sys_entered_call(mm_ios.mm);
}
else if (cat == AVAudioSessionCategorySoloAmbient) {
if (mm_ios.cat == AVAudioSessionCategoryPlayAndRecord)
leave_call();
else
mediamgr_sys_incoming(mm_ios.mm);
}
else {
leave_call();
}
mm_ios.cat = cat;
category_change(cat);
break;
}
}
Expand Down Expand Up @@ -721,7 +761,7 @@ static void incall_category(void)
int mm_platform_init(struct mm *mm, struct dict *sounds)
{
info("mm_platform_ios: init for mm=%p\n", mm);
NSLog(@"mm_platform_ios: init changed for mm=%p\n", mm);
NSLog(@"mm_platform_ios: init for mm=%p\n", mm);

mm_ios.mm = mm;
tmr_init(&mm_ios.tmr_play);
Expand All @@ -735,26 +775,28 @@ int mm_platform_init(struct mm *mm, struct dict *sounds)

#if TARGET_OS_IPHONE
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
NSOperationQueue *mq = [NSOperationQueue mainQueue];

NSLog(@"mm_platform_ios: adding observers for nc=%p mq=%p\n", nc, mq);

[nc addObserverForName:AVAudioSessionInterruptionNotification
object:nil
queue:[NSOperationQueue mainQueue]
queue:mq
usingBlock: ^(NSNotification *notification) {
handle_audio_interruption(notification);
}];


[nc addObserverForName:AVAudioSessionRouteChangeNotification
object:nil
queue:[NSOperationQueue mainQueue]
queue:mq
usingBlock: ^(NSNotification *notification) {

NSLog(@"mm_platform_ios: notifcication SessionRouteChange\n");
handle_audio_notification(notification);
}];

[nc addObserverForName:AVAudioSessionMediaServicesWereLostNotification
object:nil
queue:[NSOperationQueue mainQueue]
queue:mq
usingBlock: ^(NSNotification *notification) {

info("mediamgr: AVAudioSessionMediaServices"
Expand All @@ -764,7 +806,7 @@ int mm_platform_init(struct mm *mm, struct dict *sounds)

[nc addObserverForName:AVAudioSessionMediaServicesWereResetNotification
object:nil
queue:[NSOperationQueue mainQueue]
queue:mq
usingBlock: ^(NSNotification *notification) {

/* According to Apple documentation we MUST
Expand Down Expand Up @@ -792,8 +834,8 @@ int mm_platform_init(struct mm *mm, struct dict *sounds)
if (mm_ios.incall)
mediamgr_audio_reset_mm(mm_ios.mm);
}];

#endif

set_category(AVAudioSessionCategoryAmbient, true);
mm_ios.cat = [AVAudioSession sharedInstance].category;
set_active_sync(false);
Expand Down Expand Up @@ -1067,8 +1109,7 @@ void mm_platform_enter_call(void)
}

mm_ios.incall = true;
if ([sess category] == AVAudioSessionCategoryPlayAndRecord
|| TARGET_IPHONE_SIMULATOR)
if ([sess category] == AVAudioSessionCategoryPlayAndRecord)
mediamgr_sys_entered_call(mm_ios.mm);
else
incall_category();
Expand Down

0 comments on commit 0c245dd

Please sign in to comment.