/* * 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 */