X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Faudio_output%2Fauhal.c;h=6e12887176dece6c5f5cce9a13f65edf8c2bb90f;hb=97521497e5220d37c22fe92cadd3b43ad85a63cc;hp=84b05f365d5d50cfa65eb57010f27671dce2367b;hpb=42ee1b383a1a1171a33133194629161acdf168d3;p=vlc diff --git a/modules/audio_output/auhal.c b/modules/audio_output/auhal.c index 84b05f365d..6e12887176 100644 --- a/modules/audio_output/auhal.c +++ b/modules/audio_output/auhal.c @@ -1,10 +1,11 @@ /***************************************************************************** * auhal.c: AUHAL and Coreaudio output plugin ***************************************************************************** - * Copyright (C) 2005 the VideoLAN team + * Copyright (C) 2005, 2011 the VideoLAN team * $Id$ * * Authors: Derk-Jan Hartman + * Felix Paul Kühne * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,39 +25,48 @@ /***************************************************************************** * Preamble *****************************************************************************/ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + #include -#include -#include +#include +#include +#include #include #include -#include -#include -#include +#include #include +#include + +#ifndef verify_noerr +#define verify_noerr(a) assert((a) == noErr) +#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 /* * TODO: * - clean up the debug info - * - clean up C99'isms * - be better at changing stream setup or devices setup changes while playing. * - fix 6.1 and 7.1 */ @@ -69,11 +79,13 @@ *****************************************************************************/ struct aout_sys_t { + aout_packet_t packet; AudioDeviceID i_default_dev; /* Keeps DeviceID of defaultOutputDevice */ AudioDeviceID i_selected_dev; /* Keeps DeviceID of the selected device */ + AudioDeviceIOProcID i_procID; /* DeviceID of current device */ UInt32 i_devices; /* Number of CoreAudio Devices */ - vlc_bool_t b_supports_digital;/* Does the currently selected device support digital mode? */ - vlc_bool_t b_digital; /* Are we running in digital mode? */ + bool b_supports_digital;/* Does the currently selected device support digital mode? */ + bool b_digital; /* Are we running in digital mode? */ mtime_t clock_diff; /* Difference between VLC clock and Device clock */ /* AUHAL specific */ @@ -89,37 +101,37 @@ struct aout_sys_t int i_stream_index; /* The index of i_stream_id in an AudioBufferList */ AudioStreamBasicDescription stream_format; /* The format we changed the stream to */ AudioStreamBasicDescription sfmt_revert; /* The original format of the stream */ - vlc_bool_t b_revert; /* Wether we need to revert the stream format */ - vlc_bool_t b_changed_mixing;/* Wether we need to set the mixing mode back */ + bool b_revert; /* Wether we need to revert the stream format */ + bool b_changed_mixing;/* Wether we need to set the mixing mode back */ }; /***************************************************************************** * Local prototypes. *****************************************************************************/ static int Open ( vlc_object_t * ); -static int OpenAnalog ( aout_instance_t * ); -static int OpenSPDIF ( aout_instance_t * ); +static int OpenAnalog ( audio_output_t * ); +static int OpenSPDIF ( audio_output_t * ); static void Close ( vlc_object_t * ); -static void Play ( aout_instance_t * ); -static void Probe ( aout_instance_t * ); +static void Play ( audio_output_t *, block_t * ); +static void Probe ( audio_output_t * ); static int AudioDeviceHasOutput ( AudioDeviceID ); -static int AudioDeviceSupportsDigital( aout_instance_t *, AudioDeviceID ); -static int AudioStreamSupportsDigital( aout_instance_t *, AudioStreamID ); -static int AudioStreamChangeFormat ( aout_instance_t *, AudioStreamID, AudioStreamBasicDescription ); +static int AudioDeviceSupportsDigital( audio_output_t *, AudioDeviceID ); +static int AudioStreamSupportsDigital( audio_output_t *, AudioStreamID ); +static int AudioStreamChangeFormat ( audio_output_t *, AudioStreamID, AudioStreamBasicDescription ); static OSStatus RenderCallbackAnalog ( vlc_object_t *, AudioUnitRenderActionFlags *, const AudioTimeStamp *, unsigned int, unsigned int, AudioBufferList *); static OSStatus RenderCallbackSPDIF ( AudioDeviceID, const AudioTimeStamp *, const void *, const AudioTimeStamp *, AudioBufferList *, const AudioTimeStamp *, void * ); -static OSStatus HardwareListener ( AudioHardwarePropertyID, void *); -static OSStatus StreamListener ( AudioStreamID, UInt32, - AudioDevicePropertyID, void * ); +static OSStatus HardwareListener ( AudioObjectID, UInt32, const AudioObjectPropertyAddress *, void * ); +static OSStatus StreamListener ( AudioObjectID, UInt32, const AudioObjectPropertyAddress *, void * ); static int AudioDeviceCallback ( vlc_object_t *, const char *, vlc_value_t, vlc_value_t, void * ); + /***************************************************************************** * Module descriptor *****************************************************************************/ @@ -128,15 +140,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, VLC_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, ADEV_TEXT, ADEV_LONGTEXT, false ) +vlc_module_end () /***************************************************************************** * Open: open macosx audio output @@ -146,24 +158,24 @@ static int Open( vlc_object_t * p_this ) OSStatus err = noErr; UInt32 i_param_size = 0; struct aout_sys_t *p_sys = NULL; - vlc_bool_t b_alive = VLC_FALSE; vlc_value_t val; - aout_instance_t *p_aout = (aout_instance_t *)p_this; + audio_output_t *p_aout = (audio_output_t *)p_this; + + /* Use int here, to match kAudioDevicePropertyDeviceIsAlive + * property size */ + int b_alive = false; /* 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 ); - } + p_aout->sys = malloc( sizeof( aout_sys_t ) ); + if( p_aout->sys == NULL ) + return VLC_ENOMEM; - p_sys = p_aout->output.p_sys; + p_sys = p_aout->sys; p_sys->i_default_dev = 0; p_sys->i_selected_dev = 0; p_sys->i_devices = 0; - p_sys->b_supports_digital = VLC_FALSE; - p_sys->b_digital = VLC_FALSE; + p_sys->b_supports_digital = false; + p_sys->b_digital = false; p_sys->au_component = NULL; p_sys->au_unit = NULL; p_sys->clock_diff = (mtime_t) 0; @@ -172,14 +184,16 @@ static int Open( vlc_object_t * p_this ) p_sys->i_hog_pid = -1; p_sys->i_stream_id = 0; p_sys->i_stream_index = -1; - p_sys->b_revert = VLC_FALSE; - p_sys->b_changed_mixing = VLC_FALSE; + p_sys->b_revert = false; + p_sys->b_changed_mixing = false; memset( p_sys->p_remainder_buffer, 0, sizeof(uint8_t) * BUFSIZE ); - p_aout->output.pf_play = Play; - - aout_FormatPrint( p_aout, "VLC is looking for:", (audio_sample_format_t *)&p_aout->output.output ); - + p_aout->pf_play = aout_PacketPlay; + p_aout->pf_pause = aout_PacketPause; + p_aout->pf_flush = aout_PacketFlush; + + aout_FormatPrint( p_aout, "VLC is looking for:", &p_aout->format ); + /* Persistent device variable */ if( var_Type( p_aout->p_libvlc, "macosx-audio-device" ) == 0 ) { @@ -200,32 +214,38 @@ static int Open( vlc_object_t * p_this ) } p_sys->i_selected_dev = val.i_int & ~AOUT_VAR_SPDIF_FLAG; /* remove SPDIF flag to get the true DeviceID */ - p_sys->b_supports_digital = ( val.i_int & AOUT_VAR_SPDIF_FLAG ) ? VLC_TRUE : VLC_FALSE; + p_sys->b_supports_digital = ( val.i_int & AOUT_VAR_SPDIF_FLAG ) ? true : false; + if( p_sys->b_supports_digital ) + msg_Dbg( p_aout, "audio device supports digital output" ); + else + msg_Dbg( p_aout, "audio device does not support digital output" ); /* Check if the desired device is alive and usable */ /* TODO: add a callback to the device to alert us if the device dies */ i_param_size = sizeof( b_alive ); - err = AudioDeviceGetProperty( p_sys->i_selected_dev, 0, FALSE, - kAudioDevicePropertyDeviceIsAlive, - &i_param_size, &b_alive ); + AudioObjectPropertyAddress audioDeviceAliveAddress = { kAudioDevicePropertyDeviceIsAlive, + kAudioDevicePropertyScopeOutput, + kAudioObjectPropertyElementMaster }; + err = AudioObjectGetPropertyData( p_sys->i_selected_dev, &audioDeviceAliveAddress, 0, NULL, &i_param_size, &b_alive ); if( err != noErr ) { - msg_Err( p_aout, "could not check whether device is alive: %4.4s", (char *)&err ); - goto error; + /* Be tolerant, only give a warning here */ + msg_Warn( p_aout, "could not check whether device [0x%x] is alive: %4.4s", (unsigned int)p_sys->i_selected_dev, (char *)&err ); + b_alive = false; } - if( b_alive == VLC_FALSE ) + if( !b_alive ) { msg_Warn( p_aout, "selected audio device is not alive, switching to default device" ); p_sys->i_selected_dev = p_sys->i_default_dev; } + AudioObjectPropertyAddress audioDeviceHogModeAddress = { kAudioDevicePropertyHogMode, + kAudioDevicePropertyScopeOutput, + kAudioObjectPropertyElementMaster }; i_param_size = sizeof( p_sys->i_hog_pid ); - err = AudioDeviceGetProperty( p_sys->i_selected_dev, 0, FALSE, - kAudioDevicePropertyHogMode, - &i_param_size, &p_sys->i_hog_pid ); - + err = AudioObjectGetPropertyData( p_sys->i_selected_dev, &audioDeviceHogModeAddress, 0, NULL, &i_param_size, &p_sys->i_hog_pid ); if( err != noErr ) { /* This is not a fatal error. Some drivers simply don't support this property */ @@ -237,39 +257,46 @@ 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, VLC_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; } /* Check for Digital mode or Analog output mode */ - if( AOUT_FMT_NON_LINEAR( &p_aout->output.output ) && p_sys->b_supports_digital ) + if( AOUT_FMT_NON_LINEAR( &p_aout->format ) && p_sys->b_supports_digital ) { if( OpenSPDIF( p_aout ) ) + { + msg_Dbg( p_aout, "digital output successfully opened" ); return VLC_SUCCESS; + } } else { if( OpenAnalog( p_aout ) ) + { + msg_Dbg( p_aout, "analog output successfully opened" ); return VLC_SUCCESS; + } } error: /* If we reach this, this aout has failed */ + msg_Err( p_aout, "opening the auhal output failed" ); var_Destroy( p_aout, "audio-device" ); - if( p_sys ) free( p_sys ); + free( p_sys ); return VLC_EGENERIC; } /***************************************************************************** * Open: open and setup a HAL AudioUnit to do analog (multichannel) audio output *****************************************************************************/ -static int OpenAnalog( aout_instance_t *p_aout ) +static int OpenAnalog( audio_output_t *p_aout ) { - struct aout_sys_t *p_sys = p_aout->output.p_sys; + struct aout_sys_t *p_sys = p_aout->sys; OSStatus err = noErr; - UInt32 i_param_size = 0, i = 0; + UInt32 i_param_size = 0; int i_original; ComponentDescription desc; AudioStreamBasicDescription DeviceFormat; @@ -288,16 +315,16 @@ static int OpenAnalog( aout_instance_t *p_aout ) if( p_sys->au_component == NULL ) { msg_Warn( p_aout, "we cannot find our HAL component" ); - return VLC_FALSE; + return false; } err = OpenAComponent( p_sys->au_component, &p_sys->au_unit ); if( err != noErr ) { msg_Warn( p_aout, "we cannot open our HAL component" ); - return VLC_FALSE; + return false; } - + /* Set the device we will use for this output unit */ err = AudioUnitSetProperty( p_sys->au_unit, kAudioOutputUnitProperty_CurrentDevice, @@ -305,13 +332,13 @@ static int OpenAnalog( aout_instance_t *p_aout ) 0, &p_sys->i_selected_dev, sizeof( AudioDeviceID )); - + if( err != noErr ) { msg_Warn( p_aout, "we cannot select the audio device" ); - return VLC_FALSE; + return false; } - + /* Get the current format */ i_param_size = sizeof(AudioStreamBasicDescription); @@ -321,8 +348,8 @@ static int OpenAnalog( aout_instance_t *p_aout ) 0, &DeviceFormat, &i_param_size ); - - if( err != noErr ) return VLC_FALSE; + + if( err != noErr ) return false; else msg_Dbg( p_aout, STREAM_FORMAT_MSG( "current format is: ", DeviceFormat ) ); /* Get the channel layout of the device side of the unit (vlc -> unit -> device) */ @@ -343,7 +370,7 @@ static int OpenAnalog( aout_instance_t *p_aout ) 0, layout, &i_param_size )); - + /* We need to "fill out" the ChannelLayout, because there are multiple ways that it can be set */ if( layout->mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelBitmap) { @@ -363,84 +390,84 @@ static int OpenAnalog( aout_instance_t *p_aout ) } msg_Dbg( p_aout, "layout of AUHAL has %d channels" , (int)layout->mNumberChannelDescriptions ); - + /* Initialize the VLC core channel count */ - p_aout->output.output.i_physical_channels = 0; - i_original = p_aout->output.output.i_original_channels & AOUT_CHAN_PHYSMASK; - + p_aout->format.i_physical_channels = 0; + i_original = p_aout->format.i_original_channels & AOUT_CHAN_PHYSMASK; + if( i_original == AOUT_CHAN_CENTER || layout->mNumberChannelDescriptions < 2 ) { /* We only need Mono or cannot output more than 1 channel */ - p_aout->output.output.i_physical_channels = AOUT_CHAN_CENTER; + p_aout->format.i_physical_channels = AOUT_CHAN_CENTER; } else if( i_original == (AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT) || layout->mNumberChannelDescriptions < 3 ) { /* We only need Stereo or cannot output more than 2 channels */ - p_aout->output.output.i_physical_channels = AOUT_CHAN_RIGHT | AOUT_CHAN_LEFT; + p_aout->format.i_physical_channels = AOUT_CHAN_RIGHT | AOUT_CHAN_LEFT; } else { /* We want more than stereo and we can do that */ - for( i = 0; i < layout->mNumberChannelDescriptions; i++ ) + for( unsigned int i = 0; i < layout->mNumberChannelDescriptions; i++ ) { msg_Dbg( p_aout, "this is channel: %d", (int)layout->mChannelDescriptions[i].mChannelLabel ); switch( layout->mChannelDescriptions[i].mChannelLabel ) { case kAudioChannelLabel_Left: - p_aout->output.output.i_physical_channels |= AOUT_CHAN_LEFT; + p_aout->format.i_physical_channels |= AOUT_CHAN_LEFT; continue; case kAudioChannelLabel_Right: - p_aout->output.output.i_physical_channels |= AOUT_CHAN_RIGHT; + p_aout->format.i_physical_channels |= AOUT_CHAN_RIGHT; continue; case kAudioChannelLabel_Center: - p_aout->output.output.i_physical_channels |= AOUT_CHAN_CENTER; + p_aout->format.i_physical_channels |= AOUT_CHAN_CENTER; continue; case kAudioChannelLabel_LFEScreen: - p_aout->output.output.i_physical_channels |= AOUT_CHAN_LFE; + p_aout->format.i_physical_channels |= AOUT_CHAN_LFE; continue; case kAudioChannelLabel_LeftSurround: - p_aout->output.output.i_physical_channels |= AOUT_CHAN_REARLEFT; + p_aout->format.i_physical_channels |= AOUT_CHAN_REARLEFT; continue; case kAudioChannelLabel_RightSurround: - p_aout->output.output.i_physical_channels |= AOUT_CHAN_REARRIGHT; + p_aout->format.i_physical_channels |= AOUT_CHAN_REARRIGHT; continue; case kAudioChannelLabel_RearSurroundLeft: - p_aout->output.output.i_physical_channels |= AOUT_CHAN_MIDDLELEFT; + p_aout->format.i_physical_channels |= AOUT_CHAN_MIDDLELEFT; continue; case kAudioChannelLabel_RearSurroundRight: - p_aout->output.output.i_physical_channels |= AOUT_CHAN_MIDDLERIGHT; + p_aout->format.i_physical_channels |= AOUT_CHAN_MIDDLERIGHT; continue; case kAudioChannelLabel_CenterSurround: - p_aout->output.output.i_physical_channels |= AOUT_CHAN_REARCENTER; + p_aout->format.i_physical_channels |= AOUT_CHAN_REARCENTER; continue; default: msg_Warn( p_aout, "unrecognized channel form provided by driver: %d", (int)layout->mChannelDescriptions[i].mChannelLabel ); } } - if( p_aout->output.output.i_physical_channels == 0 ) + if( p_aout->format.i_physical_channels == 0 ) { - p_aout->output.output.i_physical_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT; + p_aout->format.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, VLC_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.") ); } } - if( layout ) free( layout ); + free( layout ); } else { msg_Warn( p_aout, "this driver does not support kAudioDevicePropertyPreferredChannelLayout. BAD DRIVER AUTHOR !!!" ); - p_aout->output.output.i_physical_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT; + p_aout->format.i_physical_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT; } - msg_Dbg( p_aout, "selected %d physical channels for device output", aout_FormatNbChannels( &p_aout->output.output ) ); - msg_Dbg( p_aout, "VLC will output: %s", aout_FormatPrintChannels( &p_aout->output.output )); + msg_Dbg( p_aout, "selected %d physical channels for device output", aout_FormatNbChannels( &p_aout->format ) ); + msg_Dbg( p_aout, "VLC will output: %s", aout_FormatPrintChannels( &p_aout->format )); memset (&new_layout, 0, sizeof(new_layout)); - switch( aout_FormatNbChannels( &p_aout->output.output ) ) + switch( aout_FormatNbChannels( &p_aout->format ) ) { case 1: new_layout.mChannelLayoutTag = kAudioChannelLayoutTag_Mono; @@ -449,41 +476,41 @@ static int OpenAnalog( aout_instance_t *p_aout ) new_layout.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo; break; case 3: - if( p_aout->output.output.i_physical_channels & AOUT_CHAN_CENTER ) + if( p_aout->format.i_physical_channels & AOUT_CHAN_CENTER ) { new_layout.mChannelLayoutTag = kAudioChannelLayoutTag_DVD_7; // L R C } - else if( p_aout->output.output.i_physical_channels & AOUT_CHAN_LFE ) + else if( p_aout->format.i_physical_channels & AOUT_CHAN_LFE ) { new_layout.mChannelLayoutTag = kAudioChannelLayoutTag_DVD_4; // L R LFE } break; case 4: - if( p_aout->output.output.i_physical_channels & ( AOUT_CHAN_CENTER | AOUT_CHAN_LFE ) ) + if( p_aout->format.i_physical_channels & ( AOUT_CHAN_CENTER | AOUT_CHAN_LFE ) ) { new_layout.mChannelLayoutTag = kAudioChannelLayoutTag_DVD_10; // L R C LFE } - else if( p_aout->output.output.i_physical_channels & ( AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT ) ) + else if( p_aout->format.i_physical_channels & ( AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT ) ) { new_layout.mChannelLayoutTag = kAudioChannelLayoutTag_DVD_3; // L R Ls Rs } - else if( p_aout->output.output.i_physical_channels & ( AOUT_CHAN_CENTER | AOUT_CHAN_REARCENTER ) ) + else if( p_aout->format.i_physical_channels & ( AOUT_CHAN_CENTER | AOUT_CHAN_REARCENTER ) ) { new_layout.mChannelLayoutTag = kAudioChannelLayoutTag_DVD_3; // L R C Cs } break; case 5: - if( p_aout->output.output.i_physical_channels & ( AOUT_CHAN_CENTER ) ) + if( p_aout->format.i_physical_channels & ( AOUT_CHAN_CENTER ) ) { new_layout.mChannelLayoutTag = kAudioChannelLayoutTag_DVD_19; // L R Ls Rs C } - else if( p_aout->output.output.i_physical_channels & ( AOUT_CHAN_LFE ) ) + else if( p_aout->format.i_physical_channels & ( AOUT_CHAN_LFE ) ) { new_layout.mChannelLayoutTag = kAudioChannelLayoutTag_DVD_18; // L R Ls Rs LFE } break; case 6: - if( p_aout->output.output.i_physical_channels & ( AOUT_CHAN_LFE ) ) + if( p_aout->format.i_physical_channels & ( AOUT_CHAN_LFE ) ) { new_layout.mChannelLayoutTag = kAudioChannelLayoutTag_DVD_20; // L R Ls Rs C LFE } @@ -503,20 +530,20 @@ static int OpenAnalog( aout_instance_t *p_aout ) } /* Set up the format to be used */ - DeviceFormat.mSampleRate = p_aout->output.output.i_rate; + DeviceFormat.mSampleRate = p_aout->format.i_rate; 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->format.i_format = VLC_CODEC_FL32; DeviceFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked; DeviceFormat.mBitsPerChannel = 32; - DeviceFormat.mChannelsPerFrame = aout_FormatNbChannels( &p_aout->output.output ); - + DeviceFormat.mChannelsPerFrame = aout_FormatNbChannels( &p_aout->format ); + /* Calculate framesizes and stuff */ 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, @@ -525,9 +552,9 @@ static int OpenAnalog( aout_instance_t *p_aout ) 0, &DeviceFormat, i_param_size )); - + msg_Dbg( p_aout, STREAM_FORMAT_MSG( "we set the AU format: " , DeviceFormat ) ); - + /* Retrieve actual format */ verify_noerr( AudioUnitGetProperty( p_sys->au_unit, kAudioUnitProperty_StreamFormat, @@ -535,18 +562,18 @@ static int OpenAnalog( aout_instance_t *p_aout ) 0, &DeviceFormat, &i_param_size )); - + msg_Dbg( p_aout, STREAM_FORMAT_MSG( "the actual set AU format is " , DeviceFormat ) ); /* Do the last VLC aout setups */ - aout_FormatPrepare( &p_aout->output.output ); - p_aout->output.i_nb_samples = 2048; + aout_FormatPrepare( &p_aout->format ); + aout_PacketInit( p_aout, &p_sys->packet, FRAMESIZE ); aout_VolumeSoftInit( p_aout ); /* set the IOproc callback */ input.inputProc = (AURenderCallback) RenderCallbackAnalog; input.inputProcRefCon = p_aout; - + verify_noerr( AudioUnitSetProperty( p_sys->au_unit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, @@ -554,16 +581,16 @@ static int OpenAnalog( aout_instance_t *p_aout ) input.inputProc = (AURenderCallback) RenderCallbackAnalog; input.inputProcRefCon = p_aout; - + /* Set the new_layout as the layout VLC will use to feed the AU unit */ verify_noerr( AudioUnitSetProperty( p_sys->au_unit, kAudioUnitProperty_AudioChannelLayout, kAudioUnitScope_Input, 0, &new_layout, sizeof(new_layout) ) ); - + if( new_layout.mNumberChannelDescriptions > 0 ) free( new_layout.mChannelDescriptions ); - + /* AU initiliaze */ verify_noerr( AudioUnitInitialize(p_sys->au_unit) ); @@ -574,134 +601,120 @@ static int OpenAnalog( aout_instance_t *p_aout ) /* Start the AU */ verify_noerr( AudioOutputUnitStart(p_sys->au_unit) ); - - return VLC_TRUE; + + return true; } /***************************************************************************** * Setup a encoded digital stream (SPDIF) *****************************************************************************/ -static int OpenSPDIF( aout_instance_t * p_aout ) +static int OpenSPDIF( audio_output_t * p_aout ) { - struct aout_sys_t *p_sys = p_aout->output.p_sys; + struct aout_sys_t *p_sys = p_aout->sys; OSStatus err = noErr; UInt32 i_param_size = 0, b_mix = 0; - Boolean b_writeable = VLC_FALSE; + Boolean b_writeable = false; AudioStreamID *p_streams = NULL; - int i = 0, i_streams = 0; + int i_streams = 0; /* Start doing the SPDIF setup proces */ - p_sys->b_digital = VLC_TRUE; + p_sys->b_digital = true; /* Hog the device */ + AudioObjectPropertyAddress audioDeviceHogModeAddress = { kAudioDevicePropertyHogMode, kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementMaster }; i_param_size = sizeof( p_sys->i_hog_pid ); p_sys->i_hog_pid = getpid() ; - - err = AudioDeviceSetProperty( p_sys->i_selected_dev, 0, 0, FALSE, - kAudioDevicePropertyHogMode, i_param_size, &p_sys->i_hog_pid ); - + + err = AudioObjectSetPropertyData( p_sys->i_selected_dev, &audioDeviceHogModeAddress, 0, NULL, i_param_size, &p_sys->i_hog_pid ); + if( err != noErr ) { msg_Err( p_aout, "failed to set hogmode: [%4.4s]", (char *)&err ); - return VLC_FALSE; + return false; } /* Set mixable to false if we are allowed to */ - err = AudioDeviceGetPropertyInfo( p_sys->i_selected_dev, 0, FALSE, kAudioDevicePropertySupportsMixing, - &i_param_size, &b_writeable ); + AudioObjectPropertyAddress audioDeviceSupportsMixingAddress = { kAudioDevicePropertySupportsMixing , kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementMaster }; + err = AudioObjectIsPropertySettable( p_sys->i_selected_dev, &audioDeviceSupportsMixingAddress, &b_writeable ); + err = AudioObjectGetPropertyDataSize( p_sys->i_selected_dev, &audioDeviceSupportsMixingAddress, 0, NULL, &i_param_size ); + err = AudioObjectGetPropertyData( p_sys->i_selected_dev, &audioDeviceSupportsMixingAddress, 0, NULL, &i_param_size, &b_mix ); - err = AudioDeviceGetProperty( p_sys->i_selected_dev, 0, FALSE, kAudioDevicePropertySupportsMixing, - &i_param_size, &b_mix ); - if( !err && b_writeable ) { b_mix = 0; - err = AudioDeviceSetProperty( p_sys->i_selected_dev, 0, 0, FALSE, - kAudioDevicePropertySupportsMixing, i_param_size, &b_mix ); - p_sys->b_changed_mixing = VLC_TRUE; + err = AudioObjectSetPropertyData( p_sys->i_selected_dev, &audioDeviceSupportsMixingAddress, 0, NULL, i_param_size, &b_mix ); + p_sys->b_changed_mixing = true; } - + if( err != noErr ) { msg_Err( p_aout, "failed to set mixmode: [%4.4s]", (char *)&err ); - return VLC_FALSE; + return false; } /* Get a list of all the streams on this device */ - err = AudioDeviceGetPropertyInfo( p_sys->i_selected_dev, 0, FALSE, - kAudioDevicePropertyStreams, - &i_param_size, NULL ); + AudioObjectPropertyAddress streamsAddress = { kAudioDevicePropertyStreams, kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementMaster }; + err = AudioObjectGetPropertyDataSize( p_sys->i_selected_dev, &streamsAddress, 0, NULL, &i_param_size ); if( err != noErr ) { msg_Err( p_aout, "could not get number of streams: [%4.4s]", (char *)&err ); - return VLC_FALSE; + return false; } - + 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_FALSE; - } - - err = AudioDeviceGetProperty( p_sys->i_selected_dev, 0, FALSE, - kAudioDevicePropertyStreams, - &i_param_size, p_streams ); - + return false; + + err = AudioObjectGetPropertyData( p_sys->i_selected_dev, &streamsAddress, 0, NULL, &i_param_size, p_streams ); + if( err != noErr ) { msg_Err( p_aout, "could not get number of streams: [%4.4s]", (char *)&err ); - if( p_streams ) free( p_streams ); - return VLC_FALSE; + free( p_streams ); + return false; } - for( i = 0; i < i_streams && p_sys->i_stream_index < 0 ; i++ ) + AudioObjectPropertyAddress physicalFormatsAddress = { kAudioStreamPropertyAvailablePhysicalFormats, kAudioObjectPropertyScopeGlobal, 0 }; + for( int i = 0; i < i_streams && p_sys->i_stream_index < 0 ; i++ ) { /* Find a stream with a cac3 stream */ - AudioStreamBasicDescription *p_format_list = NULL; - int i_formats = 0, j = 0; - vlc_bool_t b_digital = VLC_FALSE; - + AudioStreamRangedDescription *p_format_list = NULL; + int i_formats = 0; + bool b_digital = false; + /* Retrieve all the stream formats supported by each output stream */ - err = AudioStreamGetPropertyInfo( p_streams[i], 0, - kAudioStreamPropertyPhysicalFormats, - &i_param_size, NULL ); + err = AudioObjectGetPropertyDataSize( p_streams[i], &physicalFormatsAddress, 0, NULL, &i_param_size ); if( err != noErr ) { - msg_Err( p_aout, "could not get number of streamformats: [%4.4s]", (char *)&err ); + msg_Err( p_aout, "OpenSPDIF: could not get number of streamformats: [%s] (%i)", (char *)&err, err ); continue; } - - i_formats = i_param_size / sizeof( AudioStreamBasicDescription ); - p_format_list = (AudioStreamBasicDescription *)malloc( i_param_size ); + + i_formats = i_param_size / sizeof( AudioStreamRangedDescription ); + p_format_list = (AudioStreamRangedDescription *)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, - &i_param_size, p_format_list ); + + err = AudioObjectGetPropertyData( p_streams[i], &physicalFormatsAddress, 0, NULL, &i_param_size, p_format_list ); if( err != noErr ) { msg_Err( p_aout, "could not get the list of streamformats: [%4.4s]", (char *)&err ); - if( p_format_list) free( p_format_list); + free( p_format_list ); continue; } /* Check if one of the supported formats is a digital format */ - for( j = 0; j < i_formats; j++ ) + for( int j = 0; j < i_formats; j++ ) { - if( p_format_list[j].mFormatID == 'IAC3' || - p_format_list[j].mFormatID == kAudioFormat60958AC3 ) + if( p_format_list[j].mFormat.mFormatID == 'IAC3' || + p_format_list[j].mFormat.mFormatID == kAudioFormat60958AC3 ) { - b_digital = VLC_TRUE; + b_digital = true; break; } } - + if( b_digital ) { /* if this stream supports a digital (cac3) format, then go set it. */ @@ -712,103 +725,103 @@ static int OpenSPDIF( aout_instance_t * p_aout ) p_sys->i_stream_id = p_streams[i]; p_sys->i_stream_index = i; - if( p_sys->b_revert == VLC_FALSE ) + if( !p_sys->b_revert ) { /* Retrieve the original format of this stream first if not done so already */ i_param_size = sizeof( p_sys->sfmt_revert ); - err = AudioStreamGetProperty( p_sys->i_stream_id, 0, - kAudioStreamPropertyPhysicalFormat, - &i_param_size, - &p_sys->sfmt_revert ); + err = AudioObjectGetPropertyData( p_sys->i_stream_id, &physicalFormatsAddress, 0, NULL, &i_param_size, &p_sys->sfmt_revert ); if( err != noErr ) { msg_Err( p_aout, "could not retrieve the original streamformat: [%4.4s]", (char *)&err ); continue; } - p_sys->b_revert = VLC_TRUE; + p_sys->b_revert = true; } - for( j = 0; j < i_formats; j++ ) + for( int j = 0; j < i_formats; j++ ) { - if( p_format_list[j].mFormatID == 'IAC3' || - p_format_list[j].mFormatID == kAudioFormat60958AC3 ) + if( p_format_list[j].mFormat.mFormatID == 'IAC3' || + p_format_list[j].mFormat.mFormatID == kAudioFormat60958AC3 ) { - if( p_format_list[j].mSampleRate == p_aout->output.output.i_rate ) + if( p_format_list[j].mFormat.mSampleRate == p_aout->format.i_rate ) { i_requested_rate_format = j; break; } - else if( p_format_list[j].mSampleRate == p_sys->sfmt_revert.mSampleRate ) + else if( p_format_list[j].mFormat.mSampleRate == p_sys->sfmt_revert.mSampleRate ) { i_current_rate_format = j; } else { - if( i_backup_rate_format < 0 || p_format_list[j].mSampleRate > p_format_list[i_backup_rate_format].mSampleRate ) + if( i_backup_rate_format < 0 || p_format_list[j].mFormat.mSampleRate > p_format_list[i_backup_rate_format].mFormat.mSampleRate ) i_backup_rate_format = j; } } - + } - + if( i_requested_rate_format >= 0 ) /* We prefer to output at the samplerate of the original audio */ - p_sys->stream_format = p_format_list[i_requested_rate_format]; + p_sys->stream_format = p_format_list[i_requested_rate_format].mFormat; else if( i_current_rate_format >= 0 ) /* If not possible, we will try to use the current samplerate of the device */ - p_sys->stream_format = p_format_list[i_current_rate_format]; - else p_sys->stream_format = p_format_list[i_backup_rate_format]; /* And if we have to, any digital format will be just fine (highest rate possible) */ + p_sys->stream_format = p_format_list[i_current_rate_format].mFormat; + else p_sys->stream_format = p_format_list[i_backup_rate_format].mFormat; /* And if we have to, any digital format will be just fine (highest rate possible) */ } - if( p_format_list ) free( p_format_list ); + free( p_format_list ); } - if( p_streams ) free( p_streams ); + free( p_streams ); msg_Dbg( p_aout, STREAM_FORMAT_MSG( "original stream format: ", p_sys->sfmt_revert ) ); if( !AudioStreamChangeFormat( p_aout, p_sys->i_stream_id, p_sys->stream_format ) ) - return VLC_FALSE; + return false; /* 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->format.i_format = VLC_CODEC_SPDIFB; else - p_aout->output.output.i_format = VLC_FOURCC('s','p','d','i'); - 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; - p_aout->output.output.i_rate = (unsigned int)p_sys->stream_format.mSampleRate; - aout_FormatPrepare( &p_aout->output.output ); + p_aout->format.i_format = VLC_CODEC_SPDIFL; + p_aout->format.i_bytes_per_frame = AOUT_SPDIF_SIZE; + p_aout->format.i_frame_length = A52_FRAME_NB; + p_aout->format.i_rate = (unsigned int)p_sys->stream_format.mSampleRate; + aout_FormatPrepare( &p_aout->format ); + aout_PacketInit( p_aout, &p_sys->packet, A52_FRAME_NB ); aout_VolumeNoneInit( p_aout ); /* Add IOProc callback */ - err = AudioDeviceAddIOProc( p_sys->i_selected_dev, - (AudioDeviceIOProc)RenderCallbackSPDIF, - (void *)p_aout ); + err = AudioDeviceCreateIOProcID( p_sys->i_selected_dev, + (AudioDeviceIOProc)RenderCallbackSPDIF, + (void *)p_aout, + &p_sys->i_procID ); if( err != noErr ) { - msg_Err( p_aout, "AudioDeviceAddIOProc failed: [%4.4s]", (char *)&err ); - return VLC_FALSE; + msg_Err( p_aout, "AudioDeviceCreateIOProcID failed: [%4.4s]", (char *)&err ); + aout_PacketDestroy (p_aout); + return false; } /* Check for the difference between the Device clock and mdate */ p_sys->clock_diff = - (mtime_t) AudioConvertHostTimeToNanos( AudioGetCurrentHostTime() ) / 1000; p_sys->clock_diff += mdate(); - + /* Start device */ - err = AudioDeviceStart( p_sys->i_selected_dev, (AudioDeviceIOProc)RenderCallbackSPDIF ); + err = AudioDeviceStart( p_sys->i_selected_dev, p_sys->i_procID ); if( err != noErr ) { msg_Err( p_aout, "AudioDeviceStart failed: [%4.4s]", (char *)&err ); - err = AudioDeviceRemoveIOProc( p_sys->i_selected_dev, - (AudioDeviceIOProc)RenderCallbackSPDIF ); + err = AudioDeviceDestroyIOProcID( p_sys->i_selected_dev, + p_sys->i_procID ); if( err != noErr ) { - msg_Err( p_aout, "AudioDeviceRemoveIOProc failed: [%4.4s]", (char *)&err ); + msg_Err( p_aout, "AudioDeviceDestroyIOProcID failed: [%4.4s]", (char *)&err ); } - return VLC_FALSE; + aout_PacketDestroy (p_aout); + return false; } - return VLC_TRUE; + return true; } @@ -817,36 +830,36 @@ static int OpenSPDIF( aout_instance_t * p_aout ) *****************************************************************************/ static void Close( vlc_object_t * p_this ) { - aout_instance_t *p_aout = (aout_instance_t *)p_this; - struct aout_sys_t *p_sys = p_aout->output.p_sys; + audio_output_t *p_aout = (audio_output_t *)p_this; + struct aout_sys_t *p_sys = p_aout->sys; OSStatus err = noErr; UInt32 i_param_size = 0; - + if( p_sys->au_unit ) { verify_noerr( AudioOutputUnitStop( p_sys->au_unit ) ); verify_noerr( AudioUnitUninitialize( p_sys->au_unit ) ); verify_noerr( CloseComponent( p_sys->au_unit ) ); } - + if( p_sys->b_digital ) { /* Stop device */ err = AudioDeviceStop( p_sys->i_selected_dev, - (AudioDeviceIOProc)RenderCallbackSPDIF ); + p_sys->i_procID ); if( err != noErr ) { msg_Err( p_aout, "AudioDeviceStop failed: [%4.4s]", (char *)&err ); } /* Remove IOProc callback */ - err = AudioDeviceRemoveIOProc( p_sys->i_selected_dev, - (AudioDeviceIOProc)RenderCallbackSPDIF ); + err = AudioDeviceDestroyIOProcID( p_sys->i_selected_dev, + p_sys->i_procID ); if( err != noErr ) { - msg_Err( p_aout, "AudioDeviceRemoveIOProc failed: [%4.4s]", (char *)&err ); + msg_Err( p_aout, "AudioDeviceDestroyIOProcID failed: [%4.4s]", (char *)&err ); } - + if( p_sys->b_revert ) { AudioStreamChangeFormat( p_aout, p_sys->i_stream_id, p_sys->sfmt_revert ); @@ -857,18 +870,15 @@ static void Close( vlc_object_t * p_this ) int b_mix; Boolean b_writeable; /* Revert mixable to true if we are allowed to */ - err = AudioDeviceGetPropertyInfo( p_sys->i_selected_dev, 0, FALSE, kAudioDevicePropertySupportsMixing, - &i_param_size, &b_writeable ); + AudioObjectPropertyAddress audioDeviceSupportsMixingAddress = { kAudioDevicePropertySupportsMixing , kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementMaster }; + err = AudioObjectIsPropertySettable( p_sys->i_selected_dev, &audioDeviceSupportsMixingAddress, &b_writeable ); + err = AudioObjectGetPropertyData( p_sys->i_selected_dev, &audioDeviceSupportsMixingAddress, 0, NULL, &i_param_size, &b_mix ); - err = AudioDeviceGetProperty( p_sys->i_selected_dev, 0, FALSE, kAudioDevicePropertySupportsMixing, - &i_param_size, &b_mix ); - if( !err && b_writeable ) { msg_Dbg( p_aout, "mixable is: %d", b_mix ); b_mix = 1; - err = AudioDeviceSetProperty( p_sys->i_selected_dev, 0, 0, FALSE, - kAudioDevicePropertySupportsMixing, i_param_size, &b_mix ); + err = AudioObjectSetPropertyData( p_sys->i_selected_dev, &audioDeviceSupportsMixingAddress, 0, NULL, i_param_size, &b_mix ); } if( err != noErr ) @@ -878,53 +888,48 @@ static void Close( vlc_object_t * p_this ) } } - err = AudioHardwareRemovePropertyListener( kAudioHardwarePropertyDevices, - HardwareListener ); - + AudioObjectPropertyAddress audioDevicesAddress = { kAudioHardwarePropertyDevices, kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementMaster }; + err = AudioObjectRemovePropertyListener( kAudioObjectSystemObject, &audioDevicesAddress, HardwareListener, NULL ); + if( err != noErr ) { msg_Err( p_aout, "AudioHardwareRemovePropertyListener failed: [%4.4s]", (char *)&err ); } - + if( p_sys->i_hog_pid == getpid() ) { p_sys->i_hog_pid = -1; i_param_size = sizeof( p_sys->i_hog_pid ); - err = AudioDeviceSetProperty( p_sys->i_selected_dev, 0, 0, FALSE, - kAudioDevicePropertyHogMode, i_param_size, &p_sys->i_hog_pid ); + AudioObjectPropertyAddress audioDeviceHogModeAddress = { kAudioDevicePropertyHogMode, + kAudioDevicePropertyScopeOutput, + kAudioObjectPropertyElementMaster }; + err = AudioObjectSetPropertyData( p_sys->i_selected_dev, &audioDeviceHogModeAddress, 0, NULL, i_param_size, &p_sys->i_hog_pid ); if( err != noErr ) msg_Err( p_aout, "Could not release hogmode: [%4.4s]", (char *)&err ); } - - if( p_sys ) free( p_sys ); -} -/***************************************************************************** - * Play: nothing to do - *****************************************************************************/ -static void Play( aout_instance_t * p_aout ) -{ + aout_PacketDestroy( p_aout ); + free( p_sys ); } - /***************************************************************************** * Probe: Check which devices the OS has, and add them to our audio-device menu *****************************************************************************/ -static void Probe( aout_instance_t * p_aout ) +static void Probe( audio_output_t * p_aout ) { OSStatus err = noErr; - UInt32 i = 0, i_param_size = 0; + UInt32 i_param_size = 0; AudioDeviceID devid_def = 0; AudioDeviceID *p_devices = NULL; vlc_value_t val, text; - struct aout_sys_t *p_sys = p_aout->output.p_sys; + struct aout_sys_t *p_sys = p_aout->sys; /* Get number of devices */ - err = AudioHardwareGetPropertyInfo( kAudioHardwarePropertyDevices, - &i_param_size, NULL ); + AudioObjectPropertyAddress audioDevicesAddress = { kAudioHardwarePropertyDevices, kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementMaster }; + err = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &audioDevicesAddress, 0, NULL, &i_param_size); if( err != noErr ) { - msg_Err( p_aout, "Could not get number of devices: [%4.4s]", (char *)&err ); + msg_Err( p_aout, "Could not get number of devices: [%s]", (char *)&err ); goto error; } @@ -935,73 +940,66 @@ static void Probe( aout_instance_t * p_aout ) msg_Err( p_aout, "No audio output devices were found." ); goto error; } - - msg_Dbg( p_aout, "system has [%ld] device(s)", p_sys->i_devices ); + msg_Dbg( p_aout, "found %u audio 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, - &i_param_size, p_devices ); + err = AudioObjectGetPropertyData( kAudioObjectSystemObject, &audioDevicesAddress, 0, NULL, &i_param_size, p_devices ); if( err != noErr ) { - msg_Err( p_aout, "could not get the device IDs: [%4.4s]", (char *)&err ); + msg_Err( p_aout, "could not get the device IDs: [%s]", (char *)&err ); goto error; } /* Find the ID of the default Device */ + AudioObjectPropertyAddress defaultDeviceAddress = { kAudioHardwarePropertyDefaultOutputDevice, kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementMaster }; i_param_size = sizeof( AudioDeviceID ); - err = AudioHardwareGetProperty( kAudioHardwarePropertyDefaultOutputDevice, - &i_param_size, &devid_def ); + err= AudioObjectGetPropertyData( kAudioObjectSystemObject, &defaultDeviceAddress, 0, NULL, &i_param_size, &devid_def ); if( err != noErr ) { - msg_Err( p_aout, "could not get default audio device: [%4.4s]", (char *)&err ); + msg_Err( p_aout, "could not get default audio device: [%s]", (char *)&err ); goto error; } 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++ ) + + AudioObjectPropertyAddress deviceNameAddress = { kAudioDevicePropertyDeviceName, kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementMaster }; + + for( unsigned int i = 0; i < p_sys->i_devices; i++ ) { char *psz_name; i_param_size = 0; /* Retrieve the length of the device name */ - err = AudioDeviceGetPropertyInfo( - p_devices[i], 0, VLC_FALSE, - kAudioDevicePropertyDeviceName, - &i_param_size, NULL); + err = AudioObjectGetPropertyDataSize( p_devices[i], &deviceNameAddress, 0, NULL, &i_param_size ); if( err ) goto error; /* Retrieve the name of the device */ psz_name = (char *)malloc( i_param_size ); - err = AudioDeviceGetProperty( - p_devices[i], 0, VLC_FALSE, - kAudioDevicePropertyDeviceName, - &i_param_size, psz_name); + err = AudioObjectGetPropertyData( p_devices[i], &deviceNameAddress, 0, NULL, &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 */ @@ -1012,20 +1010,24 @@ 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 ); + } } } - + free( psz_name); } - + /* If a device is already "preselected", then use this device */ var_Get( p_aout->p_libvlc, "macosx-audio-device", &val ); if( val.i_int > 0 ) @@ -1033,23 +1035,21 @@ static void Probe( aout_instance_t * p_aout ) var_Change( p_aout, "audio-device", VLC_VAR_SETDEFAULT, &val, NULL ); var_Set( p_aout, "audio-device", val ); } - + /* If we change the device we want to use, we should renegotiate the audio chain */ var_AddCallback( p_aout, "audio-device", AudioDeviceCallback, NULL ); /* Attach a Listener so that we are notified of a change in the Device setup */ - err = AudioHardwareAddPropertyListener( kAudioHardwarePropertyDevices, - HardwareListener, - (void *)p_aout ); + err = AudioObjectAddPropertyListener( kAudioObjectSystemObject, &audioDevicesAddress, HardwareListener, (void *)p_aout ); if( err ) goto error; - if( p_devices ) free( p_devices ); + free( p_devices ); return; error: - var_Destroy( p_aout, "audio-device" ); - if( p_devices ) free( p_devices ); + msg_Warn( p_aout, "audio device already in use" ); + free( p_devices ); return; } @@ -1059,181 +1059,159 @@ error: static int AudioDeviceHasOutput( AudioDeviceID i_dev_id ) { UInt32 dataSize; - Boolean isWritable; - - verify_noerr( AudioDeviceGetPropertyInfo( i_dev_id, 0, FALSE, kAudioDevicePropertyStreams, &dataSize, &isWritable) ); + + AudioObjectPropertyAddress streamsAddress = { kAudioDevicePropertyStreams, kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementMaster }; + verify_noerr( AudioObjectGetPropertyDataSize( i_dev_id, &streamsAddress, 0, NULL, &dataSize ) ); if (dataSize == 0) return FALSE; - + return TRUE; } /***************************************************************************** * AudioDeviceSupportsDigital: Check i_dev_id for digital stream support. *****************************************************************************/ -static int AudioDeviceSupportsDigital( aout_instance_t *p_aout, AudioDeviceID i_dev_id ) +static int AudioDeviceSupportsDigital( audio_output_t *p_aout, AudioDeviceID i_dev_id ) { OSStatus err = noErr; UInt32 i_param_size = 0; AudioStreamID *p_streams = NULL; - int i = 0, i_streams = 0; - vlc_bool_t b_return = VLC_FALSE; - + int i_streams = 0; + bool b_return = false; + /* Retrieve all the output streams */ - err = AudioDeviceGetPropertyInfo( i_dev_id, 0, FALSE, - kAudioDevicePropertyStreams, - &i_param_size, NULL ); + AudioObjectPropertyAddress streamsAddress = { kAudioDevicePropertyStreams, kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementMaster }; + err = AudioObjectGetPropertyDataSize( i_dev_id, &streamsAddress, 0, NULL, &i_param_size ); if( err != noErr ) { - msg_Err( p_aout, "could not get number of streams: [%4.4s]", (char *)&err ); - return VLC_FALSE; + msg_Err( p_aout, "could not get number of streams: [%s] (%i)", (char *)&err, err ); + return false; } - + 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, - &i_param_size, p_streams ); - + + err = AudioObjectGetPropertyData( i_dev_id, &streamsAddress, 0, NULL, &i_param_size, p_streams ); if( err != noErr ) { - msg_Err( p_aout, "could not get number of streams: [%4.4s]", (char *)&err ); - return VLC_FALSE; + msg_Err( p_aout, "could not get list of streams: [%s]", (char *)&err ); + return false; } - for( i = 0; i < i_streams; i++ ) + for( int i = 0; i < i_streams; i++ ) { if( AudioStreamSupportsDigital( p_aout, p_streams[i] ) ) - b_return = VLC_TRUE; + b_return = true; } - - if( p_streams ) free( p_streams ); + + free( p_streams ); return b_return; } /***************************************************************************** * AudioStreamSupportsDigital: Check i_stream_id for digital stream support. *****************************************************************************/ -static int AudioStreamSupportsDigital( aout_instance_t *p_aout, AudioStreamID i_stream_id ) +static int AudioStreamSupportsDigital( audio_output_t *p_aout, AudioStreamID i_stream_id ) { OSStatus err = noErr; UInt32 i_param_size = 0; - AudioStreamBasicDescription *p_format_list = NULL; - int i = 0, i_formats = 0; - vlc_bool_t b_return = VLC_FALSE; - + AudioStreamRangedDescription *p_format_list = NULL; + int i_formats = 0; + bool b_return = false; + /* Retrieve all the stream formats supported by each output stream */ - err = AudioStreamGetPropertyInfo( i_stream_id, 0, - kAudioStreamPropertyPhysicalFormats, - &i_param_size, NULL ); + AudioObjectPropertyAddress physicalFormatsAddress = { kAudioStreamPropertyAvailablePhysicalFormats, kAudioObjectPropertyScopeGlobal, 0 }; + err = AudioObjectGetPropertyDataSize( i_stream_id, &physicalFormatsAddress, 0, NULL, &i_param_size ); if( err != noErr ) { - msg_Err( p_aout, "could not get number of streamformats: [%4.4s]", (char *)&err ); - return VLC_FALSE; + msg_Err( p_aout, "could not get number of streamformats: [%s] (%i)", (char *)&err, err ); + return false; } - - i_formats = i_param_size / sizeof( AudioStreamBasicDescription ); - p_format_list = (AudioStreamBasicDescription *)malloc( i_param_size ); + + i_formats = i_param_size / sizeof( AudioStreamRangedDescription ); + msg_Dbg( p_aout, "found %i stream formats", i_formats ); + + p_format_list = (AudioStreamRangedDescription *)malloc( i_param_size ); if( p_format_list == NULL ) - { - msg_Err( p_aout, "could not malloc the memory" ); - return VLC_FALSE; - } - - err = AudioStreamGetProperty( i_stream_id, 0, - kAudioStreamPropertyPhysicalFormats, - &i_param_size, p_format_list ); + return false; + + err = AudioObjectGetPropertyData( i_stream_id, &physicalFormatsAddress, 0, NULL, &i_param_size, p_format_list ); if( err != noErr ) { msg_Err( p_aout, "could not get the list of streamformats: [%4.4s]", (char *)&err ); free( p_format_list); p_format_list = NULL; - return VLC_FALSE; + return false; } - for( i = 0; i < i_formats; i++ ) + for( int i = 0; i < i_formats; i++ ) { - msg_Dbg( p_aout, STREAM_FORMAT_MSG( "supported format: ", p_format_list[i] ) ); - - if( p_format_list[i].mFormatID == 'IAC3' || - p_format_list[i].mFormatID == kAudioFormat60958AC3 ) + msg_Dbg( p_aout, STREAM_FORMAT_MSG( "supported format: ", p_format_list[i].mFormat ) ); + + if( p_format_list[i].mFormat.mFormatID == 'IAC3' || + p_format_list[i].mFormat.mFormatID == kAudioFormat60958AC3 ) { - b_return = VLC_TRUE; + b_return = true; } } - - if( p_format_list ) free( p_format_list ); + + free( p_format_list ); return b_return; } /***************************************************************************** * AudioStreamChangeFormat: Change i_stream_id to change_format *****************************************************************************/ -static int AudioStreamChangeFormat( aout_instance_t *p_aout, AudioStreamID i_stream_id, AudioStreamBasicDescription change_format ) +static int AudioStreamChangeFormat( audio_output_t *p_aout, AudioStreamID i_stream_id, AudioStreamBasicDescription change_format ) { OSStatus err = noErr; UInt32 i_param_size = 0; - int i; - struct timeval now; - struct timespec timeout; + AudioObjectPropertyAddress physicalFormatAddress = { kAudioStreamPropertyPhysicalFormat, kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementMaster }; + 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 */ - err = AudioStreamAddPropertyListener( i_stream_id, 0, - kAudioStreamPropertyPhysicalFormat, - StreamListener, (void *)&w ); + err = AudioObjectAddPropertyListener( i_stream_id, &physicalFormatAddress, StreamListener, (void *)&w ); if( err != noErr ) { - msg_Err( p_aout, "AudioStreamAddPropertyListener failed: [%4.4s]", (char *)&err ); - return VLC_FALSE; + msg_Err( p_aout, "AudioObjectAddPropertyListener for kAudioStreamPropertyPhysicalFormat failed: [%4.4s]", (char *)&err ); + return false; } /* change the format */ - err = AudioStreamSetProperty( i_stream_id, 0, 0, - kAudioStreamPropertyPhysicalFormat, - sizeof( AudioStreamBasicDescription ), - &change_format ); + err = AudioObjectSetPropertyData( i_stream_id, &physicalFormatAddress, 0, NULL, sizeof( AudioStreamBasicDescription ), + &change_format ); if( err != noErr ) { msg_Err( p_aout, "could not set the stream format: [%4.4s]", (char *)&err ); - return VLC_FALSE; + return false; } /* The AudioStreamSetProperty is not only asynchronious (requiring the locks) * it is also not atomic in its behaviour. * Therefore we check 5 times before we really give up. * FIXME: failing isn't actually implemented yet. */ - for( i = 0; i < 5; i++ ) + for( int 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.cond, &w.lock.mutex, &timeout ) ) + if( vlc_cond_timedwait( &w.cond, &w.lock, timeout ) ) { msg_Dbg( p_aout, "reached timeout" ); } i_param_size = sizeof( AudioStreamBasicDescription ); - err = AudioStreamGetProperty( i_stream_id, 0, - kAudioStreamPropertyPhysicalFormat, - &i_param_size, - &actual_format ); + err = AudioObjectGetPropertyData( i_stream_id, &physicalFormatAddress, 0, NULL, &i_param_size, &actual_format ); msg_Dbg( p_aout, STREAM_FORMAT_MSG( "actual format in use: ", actual_format ) ); if( actual_format.mSampleRate == change_format.mSampleRate && @@ -1245,23 +1223,21 @@ static int AudioStreamChangeFormat( aout_instance_t *p_aout, AudioStreamID i_str } /* We need to check again */ } - + /* Removing the property listener */ - err = AudioStreamRemovePropertyListener( i_stream_id, 0, - kAudioStreamPropertyPhysicalFormat, - StreamListener ); + err = AudioObjectRemovePropertyListener( i_stream_id, &physicalFormatAddress, StreamListener, NULL ); if( err != noErr ) { msg_Err( p_aout, "AudioStreamRemovePropertyListener failed: [%4.4s]", (char *)&err ); - return VLC_FALSE; + return false; } - + /* Destroy the lock and condition */ vlc_mutex_unlock( &w.lock ); vlc_mutex_destroy( &w.lock ); vlc_cond_destroy( &w.cond ); - - return VLC_TRUE; + + return true; } /***************************************************************************** @@ -1273,7 +1249,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 ) { @@ -1281,8 +1257,12 @@ static OSStatus RenderCallbackAnalog( vlc_object_t *_p_aout, mtime_t current_date = 0; uint32_t i_mData_bytes = 0; - aout_instance_t * p_aout = (aout_instance_t *)_p_aout; - struct aout_sys_t * p_sys = p_aout->output.p_sys; + audio_output_t * p_aout = (audio_output_t *)_p_aout; + struct aout_sys_t * p_sys = p_aout->sys; + + VLC_UNUSED(ioActionFlags); + VLC_UNUSED(inBusNumber); + VLC_UNUSED(inNumberFrames); host_time.mFlags = kAudioTimeStampHostTimeValid; AudioDeviceTranslateTime( p_sys->i_selected_dev, inTimeStamp, &host_time ); @@ -1294,7 +1274,7 @@ static OSStatus RenderCallbackAnalog( vlc_object_t *_p_aout, current_date = p_sys->clock_diff + AudioConvertHostTimeToNanos( host_time.mHostTime ) / 1000; - //- ((mtime_t) 1000000 / p_aout->output.output.i_rate * 31 ); // 31 = Latency in Frames. retrieve somewhere + //- ((mtime_t) 1000000 / p_aout->format.i_rate * 31 ); // 31 = Latency in Frames. retrieve somewhere if( ioData == NULL && ioData->mNumberBuffers < 1 ) { @@ -1308,44 +1288,52 @@ 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 - + current_date += (mtime_t) ( (mtime_t) 1000000 / p_aout->format.i_rate ) * + ( i_mData_bytes / 4 / aout_FormatNbChannels( &p_aout->format ) ); // 4 is fl32 specific + if( p_sys->i_read_bytes >= p_sys->i_total_bytes ) p_sys->i_read_bytes = p_sys->i_total_bytes = 0; } - + while( i_mData_bytes < ioData->mBuffers[0].mDataByteSize ) { /* We don't have enough data yet */ aout_buffer_t * p_buffer; - p_buffer = aout_OutputNextBuffer( p_aout, current_date , VLC_FALSE ); - + p_buffer = aout_PacketNext( p_aout, current_date ); + if( p_buffer != NULL ) { - uint32_t i_second_mData_bytes = __MIN( p_buffer->i_nb_bytes, 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 ); + uint32_t i_second_mData_bytes = __MIN( p_buffer->i_buffer, ioData->mBuffers[0].mDataByteSize - i_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 { /* update current_date */ - current_date += (mtime_t) ( (mtime_t) 1000000 / p_aout->output.output.i_rate ) * - ( i_second_mData_bytes / 4 / aout_FormatNbChannels( &p_aout->output.output ) ); // 4 is fl32 specific + current_date += (mtime_t) ( (mtime_t) 1000000 / p_aout->format.i_rate ) * + ( i_second_mData_bytes / 4 / aout_FormatNbChannels( &p_aout->format ) ); // 4 is fl32 specific } aout_BufferFree( p_buffer ); } 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; } } @@ -1366,8 +1354,12 @@ static OSStatus RenderCallbackSPDIF( AudioDeviceID inDevice, aout_buffer_t * p_buffer; mtime_t current_date; - aout_instance_t * p_aout = (aout_instance_t *)threadGlobals; - struct aout_sys_t * p_sys = p_aout->output.p_sys; + audio_output_t * p_aout = (audio_output_t *)threadGlobals; + struct aout_sys_t * p_sys = p_aout->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) @@ -1376,24 +1368,23 @@ static OSStatus RenderCallbackSPDIF( AudioDeviceID inDevice, current_date = p_sys->clock_diff + AudioConvertHostTimeToNanos( inOutputTime->mHostTime ) / 1000; - //- ((mtime_t) 1000000 / p_aout->output.output.i_rate * 31 ); // 31 = Latency in Frames. retrieve somewhere + //- ((mtime_t) 1000000 / p_aout->format.i_rate * 31 ); // 31 = Latency in Frames. retrieve somewhere - p_buffer = aout_OutputNextBuffer( p_aout, current_date, VLC_TRUE ); + p_buffer = aout_PacketNext( p_aout, current_date ); #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 @@ -1403,22 +1394,21 @@ static OSStatus RenderCallbackSPDIF( AudioDeviceID inDevice, /***************************************************************************** * HardwareListener: Warns us of changes in the list of registered devices *****************************************************************************/ -static OSStatus HardwareListener( AudioHardwarePropertyID inPropertyID, - void * inClientData ) +static OSStatus HardwareListener( AudioObjectID inObjectID, UInt32 inNumberAddresses, const AudioObjectPropertyAddress inAddresses[], void*inClientData) { OSStatus err = noErr; - aout_instance_t *p_aout = (aout_instance_t *)inClientData; + audio_output_t *p_aout = (audio_output_t *)inClientData; + VLC_UNUSED(inObjectID); - switch( inPropertyID ) + for ( unsigned int i = 0; i < inNumberAddresses; i++ ) { - case kAudioHardwarePropertyDevices: + if( inAddresses[i].mSelector == kAudioHardwarePropertyDevices ) { /* 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; } return( err ); @@ -1427,24 +1417,21 @@ static OSStatus HardwareListener( AudioHardwarePropertyID inPropertyID, /***************************************************************************** * StreamListener *****************************************************************************/ -static OSStatus StreamListener( AudioStreamID inStream, - UInt32 inChannel, - AudioDevicePropertyID inPropertyID, - void * inClientData ) +static OSStatus StreamListener( AudioObjectID inObjectID, UInt32 inNumberAddresses, const AudioObjectPropertyAddress inAddresses[], void*inClientData) { OSStatus err = noErr; struct { vlc_mutex_t lock; vlc_cond_t cond; } * w = inClientData; - - switch( inPropertyID ) + + VLC_UNUSED(inObjectID); + + for ( unsigned int i = 0; i < inNumberAddresses; i++ ) { - case kAudioStreamPropertyPhysicalFormat: + if( inAddresses[i].mSelector == kAudioStreamPropertyPhysicalFormat ) + { vlc_mutex_lock( &w->lock ); vlc_cond_signal( &w->cond ); vlc_mutex_unlock( &w->lock ); - break; - - default: - break; + } } return( err ); } @@ -1455,9 +1442,9 @@ static OSStatus StreamListener( AudioStreamID inStream, static int AudioDeviceCallback( vlc_object_t *p_this, const char *psz_variable, vlc_value_t old_val, vlc_value_t new_val, void *param ) { - aout_instance_t *p_aout = (aout_instance_t *)p_this; + audio_output_t *p_aout = (audio_output_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 ); }