- Timestamp:
- Feb 15, 2011 5:33:23 AM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/src/pjmedia-audiodev/coreaudio_dev.c
r3411 r3413 126 126 }; 127 127 128 /* Static variable */ 129 static struct coreaudio_factory *cf_instance = NULL; 128 130 129 131 /* Prototypes */ … … 287 289 288 290 /* Initialize the Audio Session */ 289 ostatus = AudioSessionInitialize(NULL, NULL, interruptionListener, cf);291 ostatus = AudioSessionInitialize(NULL, NULL, interruptionListener, NULL); 290 292 if (ostatus != kAudioSessionNoError) { 291 293 PJ_LOG(4, (THIS_FILE, … … 314 316 "notifications (%i)", ostatus)); 315 317 } 318 319 cf_instance = cf; 316 320 #endif 317 321 … … 335 339 kAudioSessionProperty_AudioRouteChange, propListener, cf); 336 340 #endif 337 341 338 342 if (cf->pool) { 339 343 pj_pool_release(cf->pool); … … 342 346 343 347 if (cf->mutex) { 348 pj_mutex_lock(cf->mutex); 349 cf_instance = NULL; 350 pj_mutex_unlock(cf->mutex); 344 351 pj_mutex_destroy(cf->mutex); 345 352 cf->mutex = NULL; … … 1053 1060 struct coreaudio_factory *cf = (struct coreaudio_factory*)inClientData; 1054 1061 struct stream_list *it, *itBegin; 1055 pj_status_t status;1056 OSStatus ostatus;1057 1062 CFDictionaryRef routeDictionary; 1058 1063 CFNumberRef reason; … … 1070 1075 CFNumberGetValue(reason, kCFNumberSInt32Type, &reasonVal); 1071 1076 1072 if (reasonVal == kAudioSessionRouteChangeReason_CategoryChange) { 1073 PJ_LOG(3, (THIS_FILE, "audio route changed due to category change, " 1074 "ignoring...")); 1075 return; 1076 } 1077 if (reasonVal == kAudioSessionRouteChangeReason_Override) { 1078 PJ_LOG(3, (THIS_FILE, "audio route changed due to user override, " 1079 "ignoring...")); 1077 if (reasonVal != kAudioSessionRouteChangeReason_OldDeviceUnavailable) { 1078 PJ_LOG(3, (THIS_FILE, "ignoring audio route change...")); 1080 1079 return; 1081 1080 } … … 1086 1085 itBegin = &cf->streams; 1087 1086 for (it = itBegin->next; it != itBegin; it = it->next) { 1088 pj_bool_t running = it->stream->running;1089 1090 1087 if (it->stream->interrupted) 1091 1088 continue; 1092 1089 1090 /* This does not seem necessary anymore. Just make sure 1091 * that your application can receive remote control 1092 * events by adding the code: 1093 * [[UIApplication sharedApplication] 1094 * beginReceivingRemoteControlEvents]; 1095 * Otherwise audio route change (such as headset plug/unplug) 1096 * will not be processed while your application is in the 1097 * background mode. 1098 */ 1099 /* 1093 1100 status = ca_stream_stop((pjmedia_aud_stream *)it->stream); 1094 1095 ostatus = AudioUnitUninitialize(it->stream->io_units[0]); 1096 ostatus = AudioComponentInstanceDispose(it->stream->io_units[0]); 1097 1098 status = create_audio_unit(it->stream->cf->io_comp, 0, 1099 it->stream->param.dir, 1100 it->stream, &it->stream->io_units[0]); 1101 if (status != PJ_SUCCESS) { 1102 PJ_LOG(3, (THIS_FILE, 1103 "Error: failed to create a replacement audio unit (%i)", 1104 status)); 1105 continue; 1106 } 1107 1108 if (running) { 1109 status = ca_stream_start((pjmedia_aud_stream *)it->stream); 1110 } 1101 status = ca_stream_start((pjmedia_aud_stream *)it->stream); 1111 1102 if (status != PJ_SUCCESS) { 1112 1103 PJ_LOG(3, (THIS_FILE, … … 1115 1106 continue; 1116 1107 } 1117 PJ_LOG(3, (THIS_FILE, "core audio unit successfully reinstantiated")); 1108 PJ_LOG(3, (THIS_FILE, "core audio unit successfully restarted")); 1109 */ 1118 1110 } 1119 1111 pj_mutex_unlock(cf->mutex); … … 1122 1114 static void interruptionListener(void *inClientData, UInt32 inInterruption) 1123 1115 { 1124 struct coreaudio_factory *cf = (struct coreaudio_factory*)inClientData;1125 1116 struct stream_list *it, *itBegin; 1126 1117 pj_status_t status; 1127 OSStatus ostatus;1128 pj_assert(cf);1129 1118 1130 1119 PJ_LOG(3, (THIS_FILE, "Session interrupted! --- %s ---", … … 1132 1121 "Begin Interruption" : "End Interruption")); 1133 1122 1134 pj_mutex_lock(cf->mutex); 1135 itBegin = &cf->streams; 1123 if (!cf_instance) 1124 return; 1125 1126 pj_mutex_lock(cf_instance->mutex); 1127 itBegin = &cf_instance->streams; 1136 1128 for (it = itBegin->next; it != itBegin; it = it->next) { 1137 if (!it->stream->running)1138 continue;1139 1140 1129 if (inInterruption == kAudioSessionEndInterruption && 1141 1130 it->stream->interrupted == PJ_TRUE) 1142 1131 { 1143 ostatus = AudioUnitUninitialize(it->stream->io_units[0]); 1144 ostatus = AudioComponentInstanceDispose(it->stream->io_units[0]); 1145 1146 status = create_audio_unit(it->stream->cf->io_comp, 0, 1147 it->stream->param.dir, 1148 it->stream, &it->stream->io_units[0]); 1149 if (status != PJ_SUCCESS) { 1150 PJ_LOG(3, (THIS_FILE, 1151 "Error: failed to create a replacement " 1152 "audio unit (%i)", ostatus)); 1153 continue; 1154 } 1155 1132 /* Make sure that your application can receive remote control 1133 * events by adding the code: 1134 * [[UIApplication sharedApplication] 1135 * beginReceivingRemoteControlEvents]; 1136 * Otherwise audio unit will fail to restart while your 1137 * application is in the background mode. 1138 */ 1156 1139 status = ca_stream_start((pjmedia_aud_stream*)it->stream); 1157 1140 if (status != PJ_SUCCESS) { 1158 1141 PJ_LOG(3, (THIS_FILE, 1159 1142 "Error: failed to restart the audio unit (%i)", 1160 ostatus));1161 1143 status)); 1144 continue; 1162 1145 } 1163 PJ_LOG(3, (THIS_FILE, "core audio unit successfully "1164 " reinstantiated"));1146 PJ_LOG(3, (THIS_FILE, "core audio unit successfully resumed" 1147 " after interruption")); 1165 1148 } else if (inInterruption == kAudioSessionBeginInterruption && 1166 1149 it->stream->running == PJ_TRUE) … … 1170 1153 } 1171 1154 } 1172 pj_mutex_unlock(cf ->mutex);1155 pj_mutex_unlock(cf_instance->mutex); 1173 1156 } 1174 1157 … … 1525 1508 PJMEDIA_AUD_DEV_CAP_EC, 1526 1509 ¶m->ec_enabled); 1510 } else { 1511 pj_bool_t ec = PJ_FALSE; 1512 ca_stream_set_cap(&strm->base, 1513 PJMEDIA_AUD_DEV_CAP_EC, &ec); 1527 1514 } 1528 1515 … … 1957 1944 OSStatus ostatus; 1958 1945 UInt32 i; 1959 pj_bool_t should_activate;1960 struct stream_list *it, *itBegin;1961 1946 1962 1947 if (stream->running) … … 1975 1960 } 1976 1961 1962 #if !COREAUDIO_MAC 1963 AudioSessionSetActive(true); 1964 #endif 1965 1977 1966 for (i = 0; i < 2; i++) { 1978 1967 if (stream->io_units[i] == NULL) break; … … 1985 1974 } 1986 1975 1987 /*1988 * Make sure this stream is not in the list of running streams.1989 * If this is the 1st stream that is running we need to activate1990 * the audio session.1991 */1992 pj_mutex_lock(stream->cf->mutex);1993 pj_assert(!pj_list_empty(&stream->cf->streams));1994 pj_assert(!pj_list_empty(&stream->list_entry));1995 should_activate = PJ_TRUE;1996 itBegin = &stream->cf->streams;1997 for (it = itBegin->next; it != itBegin; it = it->next) {1998 if (it->stream->running) {1999 should_activate = PJ_FALSE;2000 break;2001 }2002 }2003 1976 stream->running = PJ_TRUE; 2004 pj_mutex_unlock(stream->cf->mutex);2005 2006 #if !COREAUDIO_MAC2007 if (should_activate)2008 AudioSessionSetActive(true);2009 #endif2010 1977 2011 1978 PJ_LOG(4, (THIS_FILE, "core audio stream started")); … … 2036 2003 } 2037 2004 2038 /* 2039 * Make sure this stream is not in the list of running streams. 2040 * If this is the 1st stream that is running we need to activate 2041 * the audio session. 2042 */ 2005 /* Check whether we need to deactivate the audio session. */ 2043 2006 pj_mutex_lock(stream->cf->mutex); 2044 2007 pj_assert(!pj_list_empty(&stream->cf->streams));
Note: See TracChangeset
for help on using the changeset viewer.