diff options
Diffstat (limited to 'tinyDAV/src/tdav_apple.mm')
-rw-r--r-- | tinyDAV/src/tdav_apple.mm | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/tinyDAV/src/tdav_apple.mm b/tinyDAV/src/tdav_apple.mm new file mode 100644 index 0000000..9e68d23 --- /dev/null +++ b/tinyDAV/src/tdav_apple.mm @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2014-2015 Mamadou DIOP. + * + * + * This file is part of Open Source Doubango Framework. + * + * DOUBANGO is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * DOUBANGO is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with DOUBANGO. + * + */ +#include "tinydav/tdav_apple.h" + +#if TDAV_UNDER_APPLE + +#import <UIKit/UIKit.h> +#include <AudioToolbox/AudioToolbox.h> +#import <AVFoundation/AVFoundation.h> + +#include "tsk_debug.h" + +static tsk_bool_t g_apple_initialized = tsk_false; +static tsk_bool_t g_apple_audio_enabled = tsk_false; + +#if TARGET_OS_IPHONE +// deprecated in iOS7+ +static void _AudioSessionInterruptionListener(void * inClientData, UInt32 inInterruptionState) +{ + switch(inInterruptionState) { + case kAudioSessionBeginInterruption: + { + TSK_DEBUG_INFO("_AudioSessionInterruptionListener:kAudioSessionBeginInterruption"); + break; + } + case kAudioSessionEndInterruption: + { + TSK_DEBUG_INFO("_AudioSessionInterruptionListener:kAudioSessionEndInterruption"); + break; + } + default: + { + TSK_DEBUG_INFO("_AudioSessionInterruptionListener:%u", (unsigned int)inInterruptionState); + break; + } + } +} +#endif + +int tdav_apple_init() +{ + if (g_apple_initialized) { + return 0; + } + // initialize audio session +#if TARGET_OS_IPHONE + if ([[[UIDevice currentDevice] systemVersion] doubleValue] >= 7.0) { + // Listening to interruption must be done in your AppDelegate: + // https://code.google.com/p/idoubs/source/browse/branches/2.0/ios-idoubs/Classes/idoubs2AppDelegate.mm?r=264#433 + + /* Set the audio session category to allow for playback/recording and mixing */ + NSError *setCategoryError = nil; + BOOL setCategorySuccess = [[AVAudioSession sharedInstance] + setCategory:AVAudioSessionCategoryPlayAndRecord + withOptions: AVAudioSessionCategoryOptionMixWithOthers + error:&setCategoryError]; + + if (setCategorySuccess == NO) { + TSK_DEBUG_ERROR("Failed to set audio catrgory. Error code=%ld", (long)[setCategoryError code]); + return -1; + } + } + else { + OSStatus status; + status = AudioSessionInitialize(NULL, NULL, _AudioSessionInterruptionListener, NULL); + if (status) { + TSK_DEBUG_ERROR("AudioSessionInitialize() failed with status code=%d", (int32_t)status); + return -1; + } + + // enable record/playback + UInt32 audioCategory = kAudioSessionCategory_PlayAndRecord; + status = AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(audioCategory), &audioCategory); + if(status){ + TSK_DEBUG_ERROR("AudioSessionSetProperty(kAudioSessionProperty_AudioCategory) failed with status code=%d", (int32_t)status); + return -2; + } + + // allow mixing + UInt32 allowMixing = true; + status = AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryMixWithOthers, sizeof(allowMixing), &allowMixing); + if(status){ + TSK_DEBUG_ERROR("AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryMixWithOthers) failed with status code=%d", (int32_t)status); + return -3; + } + } +#endif + g_apple_initialized = tsk_true; + return 0; +} + +int tdav_apple_enable_audio() +{ + if (g_apple_audio_enabled) { + return 0; + } + int ret = 0; + if (!g_apple_initialized) { + if ((ret = tdav_apple_init())) { + return ret; + } + } +#if TARGET_OS_IPHONE + if ([[[UIDevice currentDevice] systemVersion] doubleValue] >= 7.0) { + NSError *activationError = nil; + BOOL activationResult = [[AVAudioSession sharedInstance] setActive: YES error: &activationError]; + + if (activationResult == NO) { + NSInteger code = [activationError code]; + if (code == AVAudioSessionErrorInsufficientPriority || [[AVAudioSession sharedInstance] isOtherAudioPlaying]) { + TSK_DEBUG_WARN("Delaying audio initialization because another app is using it"); + return 0; // application is interrupted -> wait for notification -> not error + } + else { + TSK_DEBUG_ERROR("AVAudioSession.setActive(YES) faile with error code: %ld", (long)code); + return -1; + } + } + } + else { + // enable audio session + OSStatus status = AudioSessionSetActive(true); + if (status) { + TSK_DEBUG_ERROR("AudioSessionSetActive(true) failed with status code=%d", (int32_t)status); + ret = -1; + } + } +#endif /* TARGET_OS_IPHONE */ + g_apple_audio_enabled = (ret == 0) ? tsk_true : tsk_false; + return ret; +} + +int tdav_apple_deinit() +{ + // maybe other code use the session + // OSStatus status = AudioSessionSetActive(false); + return 0; +} + +#endif /* TDAV_UNDER_APPLE */ + |