X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Faudio_output%2Fauhal.c;h=2af9776900ea1ad062c33958e7d0aa55bf9aea81;hb=c60652e38ac6afd74bd8225e9dae5406f13aaa4f;hp=3f9deb30a5fef2bb68a1744c62a24deed37cbf31;hpb=76d3144dc7987e73f6aa0958a7007f46a9171324;p=vlc diff --git a/modules/audio_output/auhal.c b/modules/audio_output/auhal.c index 3f9deb30a5..2af9776900 100644 --- a/modules/audio_output/auhal.c +++ b/modules/audio_output/auhal.c @@ -24,38 +24,60 @@ /***************************************************************************** * Preamble *****************************************************************************/ -#include -#include /* gettimeofday() */ - #ifdef HAVE_CONFIG_H # include "config.h" #endif -#include -#include +#include + +#include +#include +#include #include +// By pass part of header which compile with some warnings, +// and that we don't require. +#define __MACHINEEXCEPTIONS__ + #include +#include #include #include #include #include +#ifndef verify_noerr +#define verify_noerr(a) assert((a) == noErr) +#endif + +#if AUDIO_UNIT_VERSION < 1060 +#define AudioComponent Component +#define AudioComponentDescription ComponentDescription +#define AudioComponentFindNext FindNextComponent +#define AudioComponentInstanceNew OpenAComponent +#define AudioComponentInstanceDispose CloseComponent +#define AudioComponentInstanceNew OpenAComponent +#define AudioComponentInstanceNew OpenAComponent +#else +#include +#endif + #define STREAM_FORMAT_MSG( pre, sfm ) \ - pre "[%ld][%4.4s][%ld][%ld][%ld][%ld][%ld][%ld]", \ + pre "[%u][%4.4s][%u][%u][%u][%u][%u][%u]", \ (UInt32)sfm.mSampleRate, (char *)&sfm.mFormatID, \ sfm.mFormatFlags, sfm.mBytesPerPacket, \ sfm.mFramesPerPacket, sfm.mBytesPerFrame, \ sfm.mChannelsPerFrame, sfm.mBitsPerChannel #define STREAM_FORMAT_MSG_FULL( pre, sfm ) \ - pre ":\nsamplerate: [%ld]\nFormatID: [%4.4s]\nFormatFlags: [%ld]\nBypesPerPacket: [%ld]\nFramesPerPacket: [%ld]\nBytesPerFrame: [%ld]\nChannelsPerFrame: [%ld]\nBitsPerChannel[%ld]", \ + pre ":\nsamplerate: [%u]\nFormatID: [%4.4s]\nFormatFlags: [%u]\nBypesPerPacket: [%u]\nFramesPerPacket: [%u]\nBytesPerFrame: [%u]\nChannelsPerFrame: [%u]\nBitsPerChannel[%u]", \ (UInt32)sfm.mSampleRate, (char *)&sfm.mFormatID, \ sfm.mFormatFlags, sfm.mBytesPerPacket, \ sfm.mFramesPerPacket, sfm.mBytesPerFrame, \ sfm.mChannelsPerFrame, sfm.mBitsPerChannel -#define BUFSIZE 0xffffff +#define FRAMESIZE 2048 +#define BUFSIZE (FRAMESIZE * 8) * 8 #define AOUT_VAR_SPDIF_FLAG 0xf00000 /* @@ -82,7 +104,7 @@ struct aout_sys_t mtime_t clock_diff; /* Difference between VLC clock and Device clock */ /* AUHAL specific */ - Component au_component; /* The Audiocomponent we use */ + AudioComponent au_component; /* The Audiocomponent we use */ AudioUnit au_unit; /* The AudioUnit we use */ uint8_t p_remainder_buffer[BUFSIZE]; uint32_t i_read_bytes; @@ -125,6 +147,7 @@ static int AudioDeviceCallback ( vlc_object_t *, const char *, vlc_value_t, vlc_value_t, void * ); + /***************************************************************************** * Module descriptor *****************************************************************************/ @@ -133,15 +156,15 @@ static int AudioDeviceCallback ( vlc_object_t *, const char *, "audio device, as listed in your 'Audio Device' menu. This device will " \ "then be used by default for audio playback.") -vlc_module_begin(); - set_shortname( "auhal" ); - set_description( _("HAL AudioUnit output") ); - set_capability( "audio output", 101 ); - set_category( CAT_AUDIO ); - set_subcategory( SUBCAT_AUDIO_AOUT ); - set_callbacks( Open, Close ); - add_integer( "macosx-audio-device", 0, NULL, ADEV_TEXT, ADEV_LONGTEXT, false ); -vlc_module_end(); +vlc_module_begin () + set_shortname( "auhal" ) + set_description( N_("HAL AudioUnit output") ) + set_capability( "audio output", 101 ) + set_category( CAT_AUDIO ) + set_subcategory( SUBCAT_AUDIO_AOUT ) + set_callbacks( Open, Close ) + add_integer( "macosx-audio-device", 0, NULL, ADEV_TEXT, ADEV_LONGTEXT, false ) +vlc_module_end () /***************************************************************************** * Open: open macosx audio output @@ -161,10 +184,7 @@ static int Open( vlc_object_t * p_this ) /* Allocate structure */ p_aout->output.p_sys = malloc( sizeof( aout_sys_t ) ); if( p_aout->output.p_sys == NULL ) - { - msg_Err( p_aout, "out of memory" ); - return( VLC_ENOMEM ); - } + return VLC_ENOMEM; p_sys = p_aout->output.p_sys; p_sys->i_default_dev = 0; @@ -246,7 +266,7 @@ static int Open( vlc_object_t * p_this ) if( p_sys->i_hog_pid != -1 && p_sys->i_hog_pid != getpid() ) { msg_Err( p_aout, "Selected audio device is exclusively in use by another program." ); - intf_UserFatal( p_aout, false, _("Audio output failed"), + dialog_Fatal( p_aout, _("Audio output failed"), "%s", _("The selected audio output device is exclusively in " "use by another program.") ); goto error; @@ -280,7 +300,7 @@ static int OpenAnalog( aout_instance_t *p_aout ) OSStatus err = noErr; UInt32 i_param_size = 0, i = 0; int i_original; - ComponentDescription desc; + AudioComponentDescription desc; AudioStreamBasicDescription DeviceFormat; AudioChannelLayout *layout; AudioChannelLayout new_layout; @@ -293,14 +313,14 @@ static int OpenAnalog( aout_instance_t *p_aout ) desc.componentFlags = 0; desc.componentFlagsMask = 0; - p_sys->au_component = FindNextComponent( NULL, &desc ); + p_sys->au_component = AudioComponentFindNext( NULL, &desc ); if( p_sys->au_component == NULL ) { msg_Warn( p_aout, "we cannot find our HAL component" ); return false; } - err = OpenAComponent( p_sys->au_component, &p_sys->au_unit ); + err = AudioComponentInstanceNew( p_sys->au_component, &p_sys->au_unit ); if( err != noErr ) { msg_Warn( p_aout, "we cannot open our HAL component" ); @@ -431,7 +451,7 @@ static int OpenAnalog( aout_instance_t *p_aout ) { p_aout->output.output.i_physical_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT; msg_Err( p_aout, "You should configure your speaker layout with Audio Midi Setup Utility in /Applications/Utilities. Now using Stereo mode." ); - intf_UserFatal( p_aout, false, _("Audio device is not configured"), + dialog_Fatal( p_aout, _("Audio device is not configured"), "%s", _("You should configure your speaker layout with " "the \"Audio Midi Setup\" utility in /Applications/" "Utilities. Stereo mode is being used now.") ); @@ -516,7 +536,7 @@ static int OpenAnalog( aout_instance_t *p_aout ) DeviceFormat.mFormatID = kAudioFormatLinearPCM; /* We use float 32. It's the best supported format by both VLC and Coreaudio */ - p_aout->output.output.i_format = VLC_FOURCC( 'f','l','3','2'); + p_aout->output.output.i_format = VLC_CODEC_FL32; DeviceFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked; DeviceFormat.mBitsPerChannel = 32; DeviceFormat.mChannelsPerFrame = aout_FormatNbChannels( &p_aout->output.output ); @@ -525,7 +545,7 @@ static int OpenAnalog( aout_instance_t *p_aout ) DeviceFormat.mFramesPerPacket = 1; DeviceFormat.mBytesPerFrame = DeviceFormat.mBitsPerChannel * DeviceFormat.mChannelsPerFrame / 8; DeviceFormat.mBytesPerPacket = DeviceFormat.mBytesPerFrame * DeviceFormat.mFramesPerPacket; - + /* Set the desired format */ i_param_size = sizeof(AudioStreamBasicDescription); verify_noerr( AudioUnitSetProperty( p_sys->au_unit, @@ -549,7 +569,7 @@ static int OpenAnalog( aout_instance_t *p_aout ) /* Do the last VLC aout setups */ aout_FormatPrepare( &p_aout->output.output ); - p_aout->output.i_nb_samples = 2048; + p_aout->output.i_nb_samples = FRAMESIZE; aout_VolumeSoftInit( p_aout ); /* set the IOproc callback */ @@ -649,10 +669,7 @@ static int OpenSPDIF( aout_instance_t * p_aout ) i_streams = i_param_size / sizeof( AudioStreamID ); p_streams = (AudioStreamID *)malloc( i_param_size ); if( p_streams == NULL ) - { - msg_Err( p_aout, "out of memory" ); return false; - } err = AudioDeviceGetProperty( p_sys->i_selected_dev, 0, FALSE, kAudioDevicePropertyStreams, @@ -685,10 +702,7 @@ static int OpenSPDIF( aout_instance_t * p_aout ) i_formats = i_param_size / sizeof( AudioStreamBasicDescription ); p_format_list = (AudioStreamBasicDescription *)malloc( i_param_size ); if( p_format_list == NULL ) - { - msg_Err( p_aout, "could not malloc the memory" ); continue; - } err = AudioStreamGetProperty( p_streams[i], 0, kAudioStreamPropertyPhysicalFormats, @@ -777,9 +791,9 @@ static int OpenSPDIF( aout_instance_t * p_aout ) /* Set the format flags */ if( p_sys->stream_format.mFormatFlags & kAudioFormatFlagIsBigEndian ) - p_aout->output.output.i_format = VLC_FOURCC('s','p','d','b'); + p_aout->output.output.i_format = VLC_CODEC_SPDIFB; else - p_aout->output.output.i_format = VLC_FOURCC('s','p','d','i'); + p_aout->output.output.i_format = VLC_CODEC_SPDIFL; p_aout->output.output.i_bytes_per_frame = AOUT_SPDIF_SIZE; p_aout->output.output.i_frame_length = A52_FRAME_NB; p_aout->output.i_nb_samples = p_aout->output.output.i_frame_length; @@ -836,7 +850,7 @@ static void Close( vlc_object_t * p_this ) { verify_noerr( AudioOutputUnitStop( p_sys->au_unit ) ); verify_noerr( AudioUnitUninitialize( p_sys->au_unit ) ); - verify_noerr( CloseComponent( p_sys->au_unit ) ); + verify_noerr( AudioComponentInstanceDispose( p_sys->au_unit ) ); } if( p_sys->b_digital ) @@ -913,6 +927,7 @@ static void Close( vlc_object_t * p_this ) *****************************************************************************/ static void Play( aout_instance_t * p_aout ) { + VLC_UNUSED(p_aout); } @@ -946,15 +961,12 @@ static void Probe( aout_instance_t * p_aout ) goto error; } - msg_Dbg( p_aout, "system has [%ld] device(s)", p_sys->i_devices ); + msg_Dbg( p_aout, "system has [%u] device(s)", p_sys->i_devices ); /* Allocate DeviceID array */ p_devices = (AudioDeviceID*)malloc( sizeof(AudioDeviceID) * p_sys->i_devices ); if( p_devices == NULL ) - { - msg_Err( p_aout, "out of memory" ); goto error; - } /* Populate DeviceID array */ err = AudioHardwareGetProperty( kAudioHardwarePropertyDevices, @@ -977,7 +989,7 @@ static void Probe( aout_instance_t * p_aout ) p_sys->i_default_dev = devid_def; var_Create( p_aout, "audio-device", VLC_VAR_INTEGER|VLC_VAR_HASCHOICE ); - text.psz_string = _("Audio Device"); + text.psz_string = (char*)_("Audio Device"); var_Change( p_aout, "audio-device", VLC_VAR_SETTEXT, &text, NULL ); for( i = 0; i < p_sys->i_devices; i++ ) @@ -1000,18 +1012,20 @@ static void Probe( aout_instance_t * p_aout ) &i_param_size, psz_name); if( err ) goto error; - msg_Dbg( p_aout, "DevID: %#lx DevName: %s", p_devices[i], psz_name ); + msg_Dbg( p_aout, "DevID: %u DevName: %s", p_devices[i], psz_name ); if( !AudioDeviceHasOutput( p_devices[i]) ) { msg_Dbg( p_aout, "this device is INPUT only. skipping..." ); + free( psz_name ); continue; } /* Add the menu entries */ val.i_int = (int)p_devices[i]; - text.psz_string = strdup( psz_name ); + text.psz_string = psz_name; var_Change( p_aout, "audio-device", VLC_VAR_ADDCHOICE, &val, &text ); + text.psz_string = NULL; if( p_sys->i_default_dev == p_devices[i] ) { /* The default device is the selected device normally */ @@ -1022,14 +1036,18 @@ static void Probe( aout_instance_t * p_aout ) if( AudioDeviceSupportsDigital( p_aout, p_devices[i] ) ) { val.i_int = (int)p_devices[i] | AOUT_VAR_SPDIF_FLAG; - asprintf( &text.psz_string, _("%s (Encoded Output)"), psz_name ); - var_Change( p_aout, "audio-device", VLC_VAR_ADDCHOICE, &val, &text ); - if( p_sys->i_default_dev == p_devices[i] && config_GetInt( p_aout, "spdif" ) ) + if( asprintf( &text.psz_string, _("%s (Encoded Output)"), psz_name ) != -1 ) { - /* We selected to prefer SPDIF output if available - * then this "dummy" entry should be selected */ - var_Change( p_aout, "audio-device", VLC_VAR_SETDEFAULT, &val, NULL ); - var_Set( p_aout, "audio-device", val ); + var_Change( p_aout, "audio-device", VLC_VAR_ADDCHOICE, &val, &text ); + free( text.psz_string ); + if( p_sys->i_default_dev == p_devices[i] + && var_InheritBool( p_aout, "spdif" ) ) + { + /* We selected to prefer SPDIF output if available + * then this "dummy" entry should be selected */ + var_Change( p_aout, "audio-device", VLC_VAR_SETDEFAULT, &val, NULL ); + var_Set( p_aout, "audio-device", val ); + } } } @@ -1058,7 +1076,7 @@ static void Probe( aout_instance_t * p_aout ) return; error: - var_Destroy( p_aout, "audio-device" ); + msg_Warn( p_aout, "audio device already in use" ); free( p_devices ); return; } @@ -1101,10 +1119,7 @@ static int AudioDeviceSupportsDigital( aout_instance_t *p_aout, AudioDeviceID i_ i_streams = i_param_size / sizeof( AudioStreamID ); p_streams = (AudioStreamID *)malloc( i_param_size ); if( p_streams == NULL ) - { - msg_Err( p_aout, "out of memory" ); return VLC_ENOMEM; - } err = AudioDeviceGetProperty( i_dev_id, 0, FALSE, kAudioDevicePropertyStreams, @@ -1150,10 +1165,7 @@ static int AudioStreamSupportsDigital( aout_instance_t *p_aout, AudioStreamID i_ i_formats = i_param_size / sizeof( AudioStreamBasicDescription ); p_format_list = (AudioStreamBasicDescription *)malloc( i_param_size ); if( p_format_list == NULL ) - { - msg_Err( p_aout, "could not malloc the memory" ); return false; - } err = AudioStreamGetProperty( i_stream_id, 0, kAudioStreamPropertyPhysicalFormats, @@ -1190,15 +1202,13 @@ static int AudioStreamChangeFormat( aout_instance_t *p_aout, AudioStreamID i_str UInt32 i_param_size = 0; int i; - struct timeval now; - struct timespec timeout; struct { vlc_mutex_t lock; vlc_cond_t cond; } w; msg_Dbg( p_aout, STREAM_FORMAT_MSG( "setting stream format: ", change_format ) ); /* Condition because SetProperty is asynchronious */ - vlc_cond_init( p_aout, &w.cond ); - vlc_mutex_init( p_aout, &w.lock ); + vlc_cond_init( &w.cond ); + vlc_mutex_init( &w.lock ); vlc_mutex_lock( &w.lock ); /* Install the callback */ @@ -1229,12 +1239,9 @@ static int AudioStreamChangeFormat( aout_instance_t *p_aout, AudioStreamID i_str for( i = 0; i < 5; i++ ) { AudioStreamBasicDescription actual_format; + mtime_t timeout = mdate() + 500000; - gettimeofday( &now, NULL ); - timeout.tv_sec = now.tv_sec; - timeout.tv_nsec = (now.tv_usec + 500000) * 1000; - - if( pthread_cond_timedwait( &w.cond, &w.lock, &timeout ) ) + if( vlc_cond_timedwait( &w.cond, &w.lock, timeout ) ) { msg_Dbg( p_aout, "reached timeout" ); } @@ -1283,7 +1290,7 @@ static int AudioStreamChangeFormat( aout_instance_t *p_aout, AudioStreamID i_str static OSStatus RenderCallbackAnalog( vlc_object_t *_p_aout, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, - unsigned int inBusNummer, + unsigned int inBusNumber, unsigned int inNumberFrames, AudioBufferList *ioData ) { @@ -1294,6 +1301,10 @@ static OSStatus RenderCallbackAnalog( vlc_object_t *_p_aout, aout_instance_t * p_aout = (aout_instance_t *)_p_aout; struct aout_sys_t * p_sys = p_aout->output.p_sys; + VLC_UNUSED(ioActionFlags); + VLC_UNUSED(inBusNumber); + VLC_UNUSED(inNumberFrames); + host_time.mFlags = kAudioTimeStampHostTimeValid; AudioDeviceTranslateTime( p_sys->i_selected_dev, inTimeStamp, &host_time ); @@ -1318,7 +1329,9 @@ static OSStatus RenderCallbackAnalog( vlc_object_t *_p_aout, if( p_sys->i_total_bytes > 0 ) { i_mData_bytes = __MIN( p_sys->i_total_bytes - p_sys->i_read_bytes, ioData->mBuffers[0].mDataByteSize ); - p_aout->p_libvlc->pf_memcpy( ioData->mBuffers[0].mData, &p_sys->p_remainder_buffer[p_sys->i_read_bytes], i_mData_bytes ); + vlc_memcpy( ioData->mBuffers[0].mData, + &p_sys->p_remainder_buffer[p_sys->i_read_bytes], + i_mData_bytes ); p_sys->i_read_bytes += i_mData_bytes; current_date += (mtime_t) ( (mtime_t) 1000000 / p_aout->output.output.i_rate ) * ( i_mData_bytes / 4 / aout_FormatNbChannels( &p_aout->output.output ) ); // 4 is fl32 specific @@ -1332,18 +1345,23 @@ static OSStatus RenderCallbackAnalog( vlc_object_t *_p_aout, /* We don't have enough data yet */ aout_buffer_t * p_buffer; p_buffer = aout_OutputNextBuffer( p_aout, current_date , false ); - + if( p_buffer != NULL ) { - uint32_t i_second_mData_bytes = __MIN( p_buffer->i_nb_bytes, ioData->mBuffers[0].mDataByteSize - i_mData_bytes ); + uint32_t i_second_mData_bytes = __MIN( p_buffer->i_buffer, ioData->mBuffers[0].mDataByteSize - i_mData_bytes ); - p_aout->p_libvlc->pf_memcpy( (uint8_t *)ioData->mBuffers[0].mData + i_mData_bytes, p_buffer->p_buffer, i_second_mData_bytes ); + vlc_memcpy( (uint8_t *)ioData->mBuffers[0].mData + i_mData_bytes, + p_buffer->p_buffer, i_second_mData_bytes ); i_mData_bytes += i_second_mData_bytes; if( i_mData_bytes >= ioData->mBuffers[0].mDataByteSize ) { - p_sys->i_total_bytes = p_buffer->i_nb_bytes - i_second_mData_bytes; - p_aout->p_libvlc->pf_memcpy( p_sys->p_remainder_buffer, &p_buffer->p_buffer[i_second_mData_bytes], p_sys->i_total_bytes ); + p_sys->i_total_bytes = p_buffer->i_buffer - i_second_mData_bytes; + vlc_memcpy( p_sys->p_remainder_buffer, + &p_buffer->p_buffer[i_second_mData_bytes], + p_sys->i_total_bytes ); + aout_BufferFree( p_buffer ); + break; } else { @@ -1355,7 +1373,8 @@ static OSStatus RenderCallbackAnalog( vlc_object_t *_p_aout, } else { - p_aout->p_libvlc->pf_memset( (uint8_t *)ioData->mBuffers[0].mData +i_mData_bytes, 0, ioData->mBuffers[0].mDataByteSize - i_mData_bytes ); + vlc_memset( (uint8_t *)ioData->mBuffers[0].mData +i_mData_bytes, + 0,ioData->mBuffers[0].mDataByteSize - i_mData_bytes ); i_mData_bytes += ioData->mBuffers[0].mDataByteSize - i_mData_bytes; } } @@ -1379,6 +1398,10 @@ static OSStatus RenderCallbackSPDIF( AudioDeviceID inDevice, aout_instance_t * p_aout = (aout_instance_t *)threadGlobals; struct aout_sys_t * p_sys = p_aout->output.p_sys; + VLC_UNUSED(inDevice); + VLC_UNUSED(inInputData); + VLC_UNUSED(inInputTime); + /* Check for the difference between the Device clock and mdate */ p_sys->clock_diff = - (mtime_t) AudioConvertHostTimeToNanos( inNow->mHostTime ) / 1000; @@ -1393,17 +1416,16 @@ static OSStatus RenderCallbackSPDIF( AudioDeviceID inDevice, #define BUFFER outOutputData->mBuffers[p_sys->i_stream_index] if( p_buffer != NULL ) { - if( (int)BUFFER.mDataByteSize != (int)p_buffer->i_nb_bytes) - msg_Warn( p_aout, "bytesize: %d nb_bytes: %d", (int)BUFFER.mDataByteSize, (int)p_buffer->i_nb_bytes ); + if( (int)BUFFER.mDataByteSize != (int)p_buffer->i_buffer) + msg_Warn( p_aout, "bytesize: %d nb_bytes: %d", (int)BUFFER.mDataByteSize, (int)p_buffer->i_buffer ); /* move data into output data buffer */ - p_aout->p_libvlc->pf_memcpy( BUFFER.mData, - p_buffer->p_buffer, p_buffer->i_nb_bytes ); + vlc_memcpy( BUFFER.mData, p_buffer->p_buffer, p_buffer->i_buffer ); aout_BufferFree( p_buffer ); } else { - p_aout->p_libvlc->pf_memset( BUFFER.mData, 0, BUFFER.mDataByteSize ); + vlc_memset( BUFFER.mData, 0, BUFFER.mDataByteSize ); } #undef BUFFER @@ -1425,7 +1447,7 @@ static OSStatus HardwareListener( AudioHardwarePropertyID inPropertyID, { /* something changed in the list of devices */ /* We trigger the audio-device's aout_ChannelsRestart callback */ - var_Change( p_aout, "audio-device", VLC_VAR_TRIGGER_CALLBACKS, NULL, NULL ); + var_TriggerCallback( p_aout, "audio-device" ); var_Destroy( p_aout, "audio-device" ); } break; @@ -1444,6 +1466,9 @@ static OSStatus StreamListener( AudioStreamID inStream, { OSStatus err = noErr; struct { vlc_mutex_t lock; vlc_cond_t cond; } * w = inClientData; + + VLC_UNUSED(inStream); + VLC_UNUSED(inChannel); switch( inPropertyID ) { @@ -1467,7 +1492,7 @@ static int AudioDeviceCallback( vlc_object_t *p_this, const char *psz_variable, { aout_instance_t *p_aout = (aout_instance_t *)p_this; var_Set( p_aout->p_libvlc, "macosx-audio-device", new_val ); - msg_Dbg( p_aout, "Set Device: %#x", new_val.i_int ); + msg_Dbg( p_aout, "Set Device: %#"PRIx64, new_val.i_int ); return aout_ChannelsRestart( p_this, psz_variable, old_val, new_val, param ); }