HRESULT CoreAudioAUHAL::Deinitialize() { // Don't allow double deinitialization. if (m_bIsInitialized == false) return S_OK; CLog::Log(LOGDEBUG,"CoreAudioAUHAL::Deinitialize"); OSStatus err = noErr; UInt32 i_param_size = 0; if(deviceParameters->au_unit) { verify_noerr( AudioOutputUnitStop( deviceParameters->au_unit ) ); verify_noerr( AudioUnitUninitialize( deviceParameters->au_unit ) ); verify_noerr( CloseComponent( deviceParameters->au_unit ) ); deviceParameters->au_unit = NULL; } if (deviceParameters->m_bEncodeAC3) { ac3encoderFinalise(&deviceParameters->m_ac3encoder); } if( deviceParameters->b_digital ) { /* Stop device */ err = AudioDeviceStop( deviceParameters->device_id, (AudioDeviceIOProc)RenderCallbackSPDIF ); if( err != noErr ) { CLog::Log(LOGERROR, "AudioDeviceStop failed: [%4.4s]", (char *)&err ); } /* Remove IOProc callback */ err = AudioDeviceDestroyIOProcID(deviceParameters->device_id, deviceParameters->sInputIOProcID); if( err != noErr ) { CLog::Log(LOGERROR, "AudioDeviceRemoveIOProc failed: [%4.4s]", (char *)&err ); } if( deviceParameters->b_changed_mixing && deviceParameters->sfmt_revert.mFormatID != kAudioFormat60958AC3 ) { int b_mix; Boolean b_writeable = false; /* Revert mixable to true if we are allowed to */ err = AudioDeviceGetPropertyInfo(deviceParameters->device_id, 0, FALSE, kAudioDevicePropertySupportsMixing, &i_param_size, &b_writeable ); err = AudioDeviceGetProperty( deviceParameters->device_id, 0, FALSE, kAudioDevicePropertySupportsMixing, &i_param_size, &b_mix ); if( !err && b_writeable ) { CLog::Log(LOGDEBUG, "mixable is: %d", b_mix ); b_mix = 1; err = AudioDeviceSetProperty( deviceParameters->device_id, 0, 0, FALSE, kAudioDevicePropertySupportsMixing, i_param_size, &b_mix ); } if( err != noErr ) { CLog::Log(LOGERROR, "failed to set mixmode: [%4.4s]", (char *)&err ); } } } #warning fix listener //err = AudioHardwareRemovePropertyListener( kAudioHardwarePropertyDevices, // HardwareListener ); if( err != noErr ) { CLog::Log(LOGERROR, "AudioHardwareRemovePropertyListener failed: [%4.4s]", (char *)&err ); } if( deviceParameters->i_hog_pid == getpid() ) { deviceParameters->i_hog_pid = -1; i_param_size = sizeof( deviceParameters->i_hog_pid ); err = AudioDeviceSetProperty( deviceParameters->device_id, 0, 0, FALSE, kAudioDevicePropertyHogMode, i_param_size, &deviceParameters->i_hog_pid ); if( err != noErr ) CLog::Log(LOGERROR, "Could not release hogmode: [%4.4s]", (char *)&err ); } // Revert the stream format *after* we've set all the parameters, as doing it before seems to // result in a hang under some circumstances, an apparent deadlock in CoreAudio between handing // the stream format change and setting parameters. // if (deviceParameters->b_digital && deviceParameters->b_revert) AudioStreamChangeFormat(deviceParameters, deviceParameters->i_stream_id, deviceParameters->sfmt_revert); m_bIsInitialized = false; return S_OK; }
static void macosx_play (int argc, char *argv []) { MacOSXAudioData audio_data ; OSStatus err ; UInt32 count, buffer_size ; int k ; audio_data.fake_stereo = 0 ; audio_data.device = kAudioDeviceUnknown ; /* get the default output device for the HAL */ count = sizeof (AudioDeviceID) ; if ((err = AudioHardwareGetProperty (kAudioHardwarePropertyDefaultOutputDevice, &count, (void *) &(audio_data.device))) != noErr) { printf ("AudioHardwareGetProperty (kAudioDevicePropertyDefaultOutputDevice) failed.\n") ; return ; } ; /* get the buffersize that the default device uses for IO */ count = sizeof (UInt32) ; if ((err = AudioDeviceGetProperty (audio_data.device, 0, false, kAudioDevicePropertyBufferSize, &count, &buffer_size)) != noErr) { printf ("AudioDeviceGetProperty (kAudioDevicePropertyBufferSize) failed.\n") ; return ; } ; /* get a description of the data format used by the default device */ count = sizeof (AudioStreamBasicDescription) ; if ((err = AudioDeviceGetProperty (audio_data.device, 0, false, kAudioDevicePropertyStreamFormat, &count, &(audio_data.format))) != noErr) { printf ("AudioDeviceGetProperty (kAudioDevicePropertyStreamFormat) failed.\n") ; return ; } ; /* Base setup completed. Now play files. */ for (k = 1 ; k < argc ; k++) { printf ("Playing %s\n", argv [k]) ; if (! (audio_data.sndfile = sf_open (argv [k], SFM_READ, &(audio_data.sfinfo)))) { puts (sf_strerror (NULL)) ; continue ; } ; if (audio_data.sfinfo.channels < 1 || audio_data.sfinfo.channels > 2) { printf ("Error : channels = %d.\n", audio_data.sfinfo.channels) ; continue ; } ; audio_data.format.mSampleRate = audio_data.sfinfo.samplerate ; if (audio_data.sfinfo.channels == 1) { audio_data.format.mChannelsPerFrame = 2 ; audio_data.fake_stereo = 1 ; } else audio_data.format.mChannelsPerFrame = audio_data.sfinfo.channels ; if ((err = AudioDeviceSetProperty (audio_data.device, NULL, 0, false, kAudioDevicePropertyStreamFormat, sizeof (AudioStreamBasicDescription), &(audio_data.format))) != noErr) { printf ("AudioDeviceSetProperty (kAudioDevicePropertyStreamFormat) failed.\n") ; return ; } ; /* we want linear pcm */ if (audio_data.format.mFormatID != kAudioFormatLinearPCM) return ; /* Fire off the device. */ if ((err = AudioDeviceAddIOProc (audio_data.device, macosx_audio_out_callback, (void *) &audio_data)) != noErr) { printf ("AudioDeviceAddIOProc failed.\n") ; return ; } ; err = AudioDeviceStart (audio_data.device, macosx_audio_out_callback) ; if (err != noErr) return ; audio_data.done_playing = SF_FALSE ; while (audio_data.done_playing == SF_FALSE) usleep (10 * 1000) ; /* 10 000 milliseconds. */ if ((err = AudioDeviceStop (audio_data.device, macosx_audio_out_callback)) != noErr) { printf ("AudioDeviceStop failed.\n") ; return ; } ; err = AudioDeviceRemoveIOProc (audio_data.device, macosx_audio_out_callback) ; if (err != noErr) { printf ("AudioDeviceRemoveIOProc failed.\n") ; return ; } ; sf_close (audio_data.sndfile) ; } ; return ; } /* macosx_play */
/* unload plugin and deregister from coreaudio */ static void uninit(int immed) { OSStatus err = noErr; if (!immed) { long long timeleft=(1000000LL*av_fifo_size(ao->buffer))/ao_data.bps; ao_msg(MSGT_AO,MSGL_DBG2, "%d bytes left @%d bps (%d usec)\n", av_fifo_size(ao->buffer), ao_data.bps, (int)timeleft); usec_sleep((int)timeleft); } if (!ao->b_digital) { AudioOutputUnitStop(ao->theOutputUnit); AudioUnitUninitialize(ao->theOutputUnit); CloseComponent(ao->theOutputUnit); } else { /* Stop device. */ err = AudioDeviceStop(ao->i_selected_dev, ao->renderCallback); if (err != noErr) ao_msg(MSGT_AO, MSGL_WARN, "AudioDeviceStop failed: [%4.4s]\n", (char *)&err); /* Remove IOProc callback. */ err = AudioDeviceDestroyIOProcID(ao->i_selected_dev, ao->renderCallback); if (err != noErr) ao_msg(MSGT_AO, MSGL_WARN, "AudioDeviceRemoveIOProc failed: [%4.4s]\n", (char *)&err); if (ao->b_revert) AudioStreamChangeFormat(ao->i_stream_id, ao->sfmt_revert); if (ao->b_changed_mixing && ao->sfmt_revert.mFormatID != kAudioFormat60958AC3) { UInt32 b_mix; Boolean b_writeable; /* Revert mixable to true if we are allowed to. */ err = IsAudioPropertySettable(ao->i_selected_dev, kAudioDevicePropertySupportsMixing, &b_writeable); err = GetAudioProperty(ao->i_selected_dev, kAudioDevicePropertySupportsMixing, sizeof(UInt32), &b_mix); if (err != noErr && b_writeable) { b_mix = 1; err = SetAudioProperty(ao->i_selected_dev, kAudioDevicePropertySupportsMixing, sizeof(UInt32), &b_mix); } if (err != noErr) ao_msg(MSGT_AO, MSGL_WARN, "failed to set mixmode: [%4.4s]\n", (char *)&err); } if (ao->i_hog_pid == getpid()) { ao->i_hog_pid = -1; err = SetAudioProperty(ao->i_selected_dev, kAudioDevicePropertyHogMode, sizeof(ao->i_hog_pid), &ao->i_hog_pid); if (err != noErr) ao_msg(MSGT_AO, MSGL_WARN, "Could not release hogmode: [%4.4s]\n", (char *)&err); } } av_fifo_free(ao->buffer); free(ao); ao = NULL; }
void CAHALAudioDevice::StopIOProc(AudioDeviceIOProcID inIOProcID) { OSStatus theError = AudioDeviceStop(mObjectID, inIOProcID); ThrowIfError(theError, CAException(theError), "CAHALAudioDevice::StopIOProc: got an error stopping an IOProc"); }