doubango/tinyDAV/src/tdav_apple.mm
c732d49e
 /*
  * 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 */