Commit d5c02e56 authored by Felix Paul Kühne's avatar Felix Paul Kühne

auhal: converted to a more sane coding style

No functional changes.
parent e32b67d0
...@@ -27,25 +27,25 @@ ...@@ -27,25 +27,25 @@
*****************************************************************************/ *****************************************************************************/
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include "config.h" # import "config.h"
#endif #endif
#include <vlc_common.h> #import <vlc_common.h>
#include <vlc_plugin.h> #import <vlc_plugin.h>
#include <vlc_dialog.h> // dialog_Fatal #import <vlc_dialog.h> // dialog_Fatal
#include <vlc_aout.h> // aout_* #import <vlc_aout.h> // aout_*
#include <vlc_aout_intf.h> #import <vlc_aout_intf.h>
#include <AudioUnit/AudioUnit.h> // AudioUnit #import <AudioUnit/AudioUnit.h> // AudioUnit
#include <CoreAudio/CoreAudio.h> // AudioDeviceID #import <CoreAudio/CoreAudio.h> // AudioDeviceID
#include <AudioToolbox/AudioFormat.h> // AudioFormatGetProperty #import <AudioToolbox/AudioFormat.h> // AudioFormatGetProperty
#include <CoreServices/CoreServices.h> #import <CoreServices/CoreServices.h>
#ifndef verify_noerr #ifndef verify_noerr
# define verify_noerr(a) assert((a) == noErr) # define verify_noerr(a) assert((a) == noErr)
#endif #endif
#define STREAM_FORMAT_MSG( pre, sfm ) \ #define STREAM_FORMAT_MSG(pre, sfm) \
pre "[%f][%4.4s][%u][%u][%u][%u][%u][%u]", \ pre "[%f][%4.4s][%u][%u][%u][%u][%u][%u]", \
sfm.mSampleRate, (char *)&sfm.mFormatID, \ sfm.mSampleRate, (char *)&sfm.mFormatID, \
(unsigned int)sfm.mFormatFlags, (unsigned int)sfm.mBytesPerPacket, \ (unsigned int)sfm.mFormatFlags, (unsigned int)sfm.mBytesPerPacket, \
...@@ -99,29 +99,29 @@ struct aout_sys_t ...@@ -99,29 +99,29 @@ struct aout_sys_t
/***************************************************************************** /*****************************************************************************
* Local prototypes. * Local prototypes.
*****************************************************************************/ *****************************************************************************/
static int Open ( vlc_object_t * ); static int Open (vlc_object_t *);
static int OpenAnalog ( audio_output_t * ); static int OpenAnalog (audio_output_t *);
static int OpenSPDIF ( audio_output_t * ); static int OpenSPDIF (audio_output_t *);
static void Close ( vlc_object_t * ); static void Close (vlc_object_t *);
static void Probe ( audio_output_t * ); static void Probe (audio_output_t *);
static int AudioDeviceHasOutput ( AudioDeviceID ); static int AudioDeviceHasOutput (AudioDeviceID);
static int AudioDeviceSupportsDigital( audio_output_t *, AudioDeviceID ); static int AudioDeviceSupportsDigital(audio_output_t *, AudioDeviceID);
static int AudioStreamSupportsDigital( audio_output_t *, AudioStreamID ); static int AudioStreamSupportsDigital(audio_output_t *, AudioStreamID);
static int AudioStreamChangeFormat ( audio_output_t *, AudioStreamID, AudioStreamBasicDescription ); static int AudioStreamChangeFormat (audio_output_t *, AudioStreamID, AudioStreamBasicDescription);
static OSStatus RenderCallbackAnalog ( vlc_object_t *, AudioUnitRenderActionFlags *, const AudioTimeStamp *, static OSStatus RenderCallbackAnalog (vlc_object_t *, AudioUnitRenderActionFlags *, const AudioTimeStamp *,
unsigned int, unsigned int, AudioBufferList *); unsigned int, unsigned int, AudioBufferList *);
static OSStatus RenderCallbackSPDIF ( AudioDeviceID, const AudioTimeStamp *, const void *, const AudioTimeStamp *, static OSStatus RenderCallbackSPDIF (AudioDeviceID, const AudioTimeStamp *, const void *, const AudioTimeStamp *,
AudioBufferList *, const AudioTimeStamp *, void * ); AudioBufferList *, const AudioTimeStamp *, void *);
static OSStatus HardwareListener ( AudioObjectID, UInt32, const AudioObjectPropertyAddress *, void * ); static OSStatus HardwareListener (AudioObjectID, UInt32, const AudioObjectPropertyAddress *, void *);
static OSStatus StreamListener ( AudioObjectID, UInt32, const AudioObjectPropertyAddress *, void * ); static OSStatus StreamListener (AudioObjectID, UInt32, const AudioObjectPropertyAddress *, void *);
static int AudioDeviceCallback ( vlc_object_t *, const char *, static int AudioDeviceCallback (vlc_object_t *, const char *,
vlc_value_t, vlc_value_t, void * ); vlc_value_t, vlc_value_t, void *);
static int VolumeSet ( audio_output_t *, float ); static int VolumeSet (audio_output_t *, float);
static int MuteSet ( audio_output_t *, bool ); static int MuteSet (audio_output_t *, bool);
/***************************************************************************** /*****************************************************************************
...@@ -133,19 +133,19 @@ static int MuteSet ( audio_output_t *, bool ); ...@@ -133,19 +133,19 @@ static int MuteSet ( audio_output_t *, bool );
"then be used by default for audio playback.") "then be used by default for audio playback.")
vlc_module_begin () vlc_module_begin ()
set_shortname( "auhal" ) set_shortname("auhal")
set_description( N_("HAL AudioUnit output") ) set_description(N_("HAL AudioUnit output"))
set_capability( "audio output", 101 ) set_capability("audio output", 101)
set_category( CAT_AUDIO ) set_category(CAT_AUDIO)
set_subcategory( SUBCAT_AUDIO_AOUT ) set_subcategory(SUBCAT_AUDIO_AOUT)
set_callbacks( Open, Close ) set_callbacks(Open, Close)
add_integer( "macosx-audio-device", 0, ADEV_TEXT, ADEV_LONGTEXT, false ) add_integer("macosx-audio-device", 0, ADEV_TEXT, ADEV_LONGTEXT, false)
vlc_module_end () vlc_module_end ()
/***************************************************************************** /*****************************************************************************
* Open: open macosx audio output * Open: open macosx audio output
*****************************************************************************/ *****************************************************************************/
static int Open( vlc_object_t * p_this ) static int Open(vlc_object_t * p_this)
{ {
OSStatus err = noErr; OSStatus err = noErr;
UInt32 i_param_size = 0; UInt32 i_param_size = 0;
...@@ -158,8 +158,8 @@ static int Open( vlc_object_t * p_this ) ...@@ -158,8 +158,8 @@ static int Open( vlc_object_t * p_this )
int b_alive = false; int b_alive = false;
/* Allocate structure */ /* Allocate structure */
p_aout->sys = malloc( sizeof( aout_sys_t ) ); p_aout->sys = malloc(sizeof(aout_sys_t));
if( p_aout->sys == NULL ) if (p_aout->sys == NULL)
return VLC_ENOMEM; return VLC_ENOMEM;
p_sys = p_aout->sys; p_sys = p_aout->sys;
...@@ -177,119 +177,108 @@ static int Open( vlc_object_t * p_this ) ...@@ -177,119 +177,108 @@ static int Open( vlc_object_t * p_this )
p_sys->i_stream_index = -1; p_sys->i_stream_index = -1;
p_sys->b_revert = false; p_sys->b_revert = false;
p_sys->b_changed_mixing = false; p_sys->b_changed_mixing = false;
memset( p_sys->p_remainder_buffer, 0, sizeof(uint8_t) * BUFSIZE ); memset(p_sys->p_remainder_buffer, 0, sizeof(uint8_t) * BUFSIZE);
p_aout->pf_play = aout_PacketPlay; p_aout->pf_play = aout_PacketPlay;
p_aout->pf_pause = aout_PacketPause; p_aout->pf_pause = aout_PacketPause;
p_aout->pf_flush = aout_PacketFlush; p_aout->pf_flush = aout_PacketFlush;
aout_FormatPrint( p_aout, "VLC is looking for:", &p_aout->format ); aout_FormatPrint(p_aout, "VLC is looking for:", &p_aout->format);
/* Persistent device variable */ /* Persistent device variable */
if( var_Type( p_aout->p_libvlc, "macosx-audio-device" ) == 0 ) if (var_Type(p_aout->p_libvlc, "macosx-audio-device") == 0)
var_Create( p_aout->p_libvlc, "macosx-audio-device", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT ); var_Create(p_aout->p_libvlc, "macosx-audio-device", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT);
/* Build a list of devices */ /* Build a list of devices */
if( var_Type( p_aout, "audio-device" ) == 0 ) if (var_Type(p_aout, "audio-device") == 0)
Probe( p_aout ); Probe(p_aout);
/* What device do we want? */ /* What device do we want? */
if( var_Get( p_aout, "audio-device", &val ) < 0 ) if (var_Get(p_aout, "audio-device", &val) < 0) {
{ msg_Err(p_aout, "audio-device var does not exist. device probe failed.");
msg_Err( p_aout, "audio-device var does not exist. device probe failed." );
goto error; goto error;
} }
p_sys->i_selected_dev = val.i_int & ~AOUT_VAR_SPDIF_FLAG; /* remove SPDIF flag to get the true DeviceID */ p_sys->i_selected_dev = val.i_int & ~AOUT_VAR_SPDIF_FLAG; /* remove SPDIF flag to get the true DeviceID */
bool b_supports_digital = ( val.i_int & AOUT_VAR_SPDIF_FLAG ); bool b_supports_digital = (val.i_int & AOUT_VAR_SPDIF_FLAG);
if( b_supports_digital ) if (b_supports_digital)
msg_Dbg( p_aout, "audio device supports digital output" ); msg_Dbg(p_aout, "audio device supports digital output");
/* Check if the desired device is alive and usable */ /* Check if the desired device is alive and usable */
i_param_size = sizeof( b_alive ); i_param_size = sizeof(b_alive);
AudioObjectPropertyAddress audioDeviceAliveAddress = { kAudioDevicePropertyDeviceIsAlive, AudioObjectPropertyAddress audioDeviceAliveAddress = { kAudioDevicePropertyDeviceIsAlive,
kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyScopeGlobal,
kAudioObjectPropertyElementMaster }; kAudioObjectPropertyElementMaster };
err = AudioObjectGetPropertyData( p_sys->i_selected_dev, &audioDeviceAliveAddress, 0, NULL, &i_param_size, &b_alive ); err = AudioObjectGetPropertyData(p_sys->i_selected_dev, &audioDeviceAliveAddress, 0, NULL, &i_param_size, &b_alive);
if( err != noErr ) if (err != noErr) {
{
/* Be tolerant, only give a warning here */ /* Be tolerant, only give a warning here */
msg_Warn( p_aout, "could not check whether device [0x%x] is alive: %4.4s", msg_Warn(p_aout, "could not check whether device [0x%x] is alive: %4.4s",
(unsigned int)p_sys->i_selected_dev, (char *)&err ); (unsigned int)p_sys->i_selected_dev, (char *)&err);
b_alive = false; b_alive = false;
} }
if( !b_alive ) if (!b_alive) {
{ msg_Warn(p_aout, "selected audio device is not alive, switching to default device");
msg_Warn( p_aout, "selected audio device is not alive, switching to default device" );
p_sys->i_selected_dev = p_sys->i_default_dev; p_sys->i_selected_dev = p_sys->i_default_dev;
} }
/* add a callback to see if the device dies later on */ /* add a callback to see if the device dies later on */
err = AudioObjectAddPropertyListener( p_sys->i_selected_dev, &audioDeviceAliveAddress, HardwareListener, (void *)p_aout ); err = AudioObjectAddPropertyListener(p_sys->i_selected_dev, &audioDeviceAliveAddress, HardwareListener, (void *)p_aout);
if( err != noErr ) if (err != noErr) {
{
/* Be tolerant, only give a warning here */ /* Be tolerant, only give a warning here */
msg_Warn( p_aout, "could not set alive check callback on device [0x%x]: %4.4s", msg_Warn(p_aout, "could not set alive check callback on device [0x%x]: %4.4s",
(unsigned int)p_sys->i_selected_dev, (char *)&err ); (unsigned int)p_sys->i_selected_dev, (char *)&err);
} }
AudioObjectPropertyAddress audioDeviceHogModeAddress = { kAudioDevicePropertyHogMode, AudioObjectPropertyAddress audioDeviceHogModeAddress = { kAudioDevicePropertyHogMode,
kAudioDevicePropertyScopeOutput, kAudioDevicePropertyScopeOutput,
kAudioObjectPropertyElementMaster }; kAudioObjectPropertyElementMaster };
i_param_size = sizeof( p_sys->i_hog_pid ); i_param_size = sizeof(p_sys->i_hog_pid);
err = AudioObjectGetPropertyData( p_sys->i_selected_dev, &audioDeviceHogModeAddress, 0, NULL, &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 ) if (err != noErr) {
{
/* This is not a fatal error. Some drivers simply don't support this property */ /* This is not a fatal error. Some drivers simply don't support this property */
msg_Warn( p_aout, "could not check whether device is hogged: %4.4s", msg_Warn(p_aout, "could not check whether device is hogged: %4.4s",
(char *)&err ); (char *)&err);
p_sys->i_hog_pid = -1; p_sys->i_hog_pid = -1;
} }
if( p_sys->i_hog_pid != -1 && p_sys->i_hog_pid != getpid() ) 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.");
msg_Err( p_aout, "Selected audio device is exclusively in use by another program." ); dialog_Fatal(p_aout, _("Audio output failed"), "%s",
dialog_Fatal( p_aout, _("Audio output failed"), "%s",
_("The selected audio output device is exclusively in " _("The selected audio output device is exclusively in "
"use by another program.") ); "use by another program."));
goto error; goto error;
} }
/* If we change the device we want to use, we should renegotiate the audio chain */ /* If we change the device we want to use, we should renegotiate the audio chain */
var_AddCallback( p_aout, "audio-device", AudioDeviceCallback, NULL ); var_AddCallback(p_aout, "audio-device", AudioDeviceCallback, NULL);
/* Check for Digital mode or Analog output mode */ /* Check for Digital mode or Analog output mode */
if( AOUT_FMT_SPDIF( &p_aout->format ) && b_supports_digital ) if (AOUT_FMT_SPDIF (&p_aout->format) && b_supports_digital) {
{ if (OpenSPDIF (p_aout)) {
if( OpenSPDIF( p_aout ) ) msg_Dbg(p_aout, "digital output successfully opened");
{
msg_Dbg( p_aout, "digital output successfully opened" );
return VLC_SUCCESS; return VLC_SUCCESS;
} }
} } else {
else if (OpenAnalog(p_aout)) {
{ msg_Dbg(p_aout, "analog output successfully opened");
if( OpenAnalog( p_aout ) )
{
msg_Dbg( p_aout, "analog output successfully opened" );
return VLC_SUCCESS; return VLC_SUCCESS;
} }
} }
error: error:
/* If we reach this, this aout has failed */ /* If we reach this, this aout has failed */
msg_Err( p_aout, "opening the auhal output failed" ); msg_Err(p_aout, "opening the auhal output failed");
var_Destroy( p_aout, "audio-device" ); var_Destroy(p_aout, "audio-device");
free( p_sys ); free(p_sys);
return VLC_EGENERIC; return VLC_EGENERIC;
} }
/***************************************************************************** /*****************************************************************************
* Open: open and setup a HAL AudioUnit to do analog (multichannel) audio output * Open: open and setup a HAL AudioUnit to do analog (multichannel) audio output
*****************************************************************************/ *****************************************************************************/
static int OpenAnalog( audio_output_t *p_aout ) static int OpenAnalog(audio_output_t *p_aout)
{ {
struct aout_sys_t *p_sys = p_aout->sys; struct aout_sys_t *p_sys = p_aout->sys;
OSStatus err = noErr; OSStatus err = noErr;
...@@ -308,109 +297,98 @@ static int OpenAnalog( audio_output_t *p_aout ) ...@@ -308,109 +297,98 @@ static int OpenAnalog( audio_output_t *p_aout )
desc.componentFlags = 0; desc.componentFlags = 0;
desc.componentFlagsMask = 0; desc.componentFlagsMask = 0;
p_sys->au_component = FindNextComponent( NULL, &desc ); p_sys->au_component = FindNextComponent(NULL, &desc);
if( p_sys->au_component == NULL ) if (p_sys->au_component == NULL) {
{ msg_Warn(p_aout, "we cannot find our HAL component");
msg_Warn( p_aout, "we cannot find our HAL component" );
return false; return false;
} }
err = OpenAComponent( p_sys->au_component, &p_sys->au_unit ); err = OpenAComponent(p_sys->au_component, &p_sys->au_unit);
if( err != noErr ) if (err != noErr) {
{ msg_Warn(p_aout, "we cannot open our HAL component");
msg_Warn( p_aout, "we cannot open our HAL component" );
return false; return false;
} }
/* Set the device we will use for this output unit */ /* Set the device we will use for this output unit */
err = AudioUnitSetProperty( p_sys->au_unit, err = AudioUnitSetProperty(p_sys->au_unit,
kAudioOutputUnitProperty_CurrentDevice, kAudioOutputUnitProperty_CurrentDevice,
kAudioUnitScope_Global, kAudioUnitScope_Global,
0, 0,
&p_sys->i_selected_dev, &p_sys->i_selected_dev,
sizeof( AudioDeviceID )); sizeof(AudioDeviceID));
if( err != noErr ) if (err != noErr) {
{ msg_Warn(p_aout, "we cannot select the audio device");
msg_Warn( p_aout, "we cannot select the audio device" );
return false; return false;
} }
/* Get the current format */ /* Get the current format */
i_param_size = sizeof(AudioStreamBasicDescription); i_param_size = sizeof(AudioStreamBasicDescription);
err = AudioUnitGetProperty( p_sys->au_unit, err = AudioUnitGetProperty(p_sys->au_unit,
kAudioUnitProperty_StreamFormat, kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input, kAudioUnitScope_Input,
0, 0,
&DeviceFormat, &DeviceFormat,
&i_param_size ); &i_param_size);
if( err != noErr ) return false; if (err != noErr)
else msg_Dbg( p_aout, STREAM_FORMAT_MSG( "current format is: ", DeviceFormat ) ); 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) */ /* Get the channel layout of the device side of the unit (vlc -> unit -> device) */
err = AudioUnitGetPropertyInfo( p_sys->au_unit, err = AudioUnitGetPropertyInfo(p_sys->au_unit,
kAudioDevicePropertyPreferredChannelLayout, kAudioDevicePropertyPreferredChannelLayout,
kAudioUnitScope_Output, kAudioUnitScope_Output,
0, 0,
&i_param_size, &i_param_size,
NULL ); NULL);
if( err == noErr ) if (err == noErr) {
{ layout = (AudioChannelLayout *)malloc(i_param_size);
layout = (AudioChannelLayout *)malloc( i_param_size);
verify_noerr( AudioUnitGetProperty( p_sys->au_unit, verify_noerr(AudioUnitGetProperty(p_sys->au_unit,
kAudioDevicePropertyPreferredChannelLayout, kAudioDevicePropertyPreferredChannelLayout,
kAudioUnitScope_Output, kAudioUnitScope_Output,
0, 0,
layout, layout,
&i_param_size )); &i_param_size));
/* We need to "fill out" the ChannelLayout, because there are multiple ways that it can be set */ /* We need to "fill out" the ChannelLayout, because there are multiple ways that it can be set */
if( layout->mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelBitmap) if (layout->mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelBitmap) {
{
/* bitmap defined channellayout */ /* bitmap defined channellayout */
verify_noerr( AudioFormatGetProperty( kAudioFormatProperty_ChannelLayoutForBitmap, verify_noerr(AudioFormatGetProperty(kAudioFormatProperty_ChannelLayoutForBitmap,
sizeof( UInt32), &layout->mChannelBitmap, sizeof(UInt32), &layout->mChannelBitmap,
&i_param_size, &i_param_size,
layout )); layout));
} } else if (layout->mChannelLayoutTag != kAudioChannelLayoutTag_UseChannelDescriptions)
else if( layout->mChannelLayoutTag != kAudioChannelLayoutTag_UseChannelDescriptions )
{ {
/* layouttags defined channellayout */ /* layouttags defined channellayout */
verify_noerr( AudioFormatGetProperty( kAudioFormatProperty_ChannelLayoutForTag, verify_noerr(AudioFormatGetProperty(kAudioFormatProperty_ChannelLayoutForTag,
sizeof( AudioChannelLayoutTag ), &layout->mChannelLayoutTag, sizeof(AudioChannelLayoutTag), &layout->mChannelLayoutTag,
&i_param_size, &i_param_size,
layout )); layout));
} }
msg_Dbg( p_aout, "layout of AUHAL has %d channels" , (int)layout->mNumberChannelDescriptions ); msg_Dbg(p_aout, "layout of AUHAL has %d channels" , (int)layout->mNumberChannelDescriptions);
/* Initialize the VLC core channel count */ /* Initialize the VLC core channel count */
p_aout->format.i_physical_channels = 0; p_aout->format.i_physical_channels = 0;
i_original = p_aout->format.i_original_channels & AOUT_CHAN_PHYSMASK; i_original = p_aout->format.i_original_channels & AOUT_CHAN_PHYSMASK;
if( i_original == AOUT_CHAN_CENTER || layout->mNumberChannelDescriptions < 2 ) if (i_original == AOUT_CHAN_CENTER || layout->mNumberChannelDescriptions < 2) {
{
/* We only need Mono or cannot output more than 1 channel */ /* We only need Mono or cannot output more than 1 channel */
p_aout->format.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) {
else if( i_original == (AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT) || layout->mNumberChannelDescriptions < 3 )
{
/* We only need Stereo or cannot output more than 2 channels */ /* We only need Stereo or cannot output more than 2 channels */
p_aout->format.i_physical_channels = AOUT_CHAN_RIGHT | AOUT_CHAN_LEFT; p_aout->format.i_physical_channels = AOUT_CHAN_RIGHT | AOUT_CHAN_LEFT;
} } else {
else
{
/* We want more than stereo and we can do that */ /* We want more than stereo and we can do that */
for( unsigned int 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);
msg_Dbg( p_aout, "this is channel: %d", (int)layout->mChannelDescriptions[i].mChannelLabel );
switch( layout->mChannelDescriptions[i].mChannelLabel ) switch(layout->mChannelDescriptions[i].mChannelLabel) {
{
case kAudioChannelLabel_Left: case kAudioChannelLabel_Left:
p_aout->format.i_physical_channels |= AOUT_CHAN_LEFT; p_aout->format.i_physical_channels |= AOUT_CHAN_LEFT;
continue; continue;
...@@ -439,33 +417,29 @@ static int OpenAnalog( audio_output_t *p_aout ) ...@@ -439,33 +417,29 @@ static int OpenAnalog( audio_output_t *p_aout )
p_aout->format.i_physical_channels |= AOUT_CHAN_REARCENTER; p_aout->format.i_physical_channels |= AOUT_CHAN_REARCENTER;
continue; continue;
default: default:
msg_Warn( p_aout, "unrecognized channel form provided by driver: %d", (int)layout->mChannelDescriptions[i].mChannelLabel ); msg_Warn(p_aout, "unrecognized channel form provided by driver: %d", (int)layout->mChannelDescriptions[i].mChannelLabel);
} }
} }
if( p_aout->format.i_physical_channels == 0 ) if (p_aout->format.i_physical_channels == 0) {
{
p_aout->format.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." ); msg_Err(p_aout, "You should configure your speaker layout with Audio Midi Setup Utility in /Applications/Utilities. Now using Stereo mode.");
dialog_Fatal( p_aout, _("Audio device is not configured"), "%s", dialog_Fatal(p_aout, _("Audio device is not configured"), "%s",
_("You should configure your speaker layout with " _("You should configure your speaker layout with "
"the \"Audio Midi Setup\" utility in /Applications/" "the \"Audio Midi Setup\" utility in /Applications/"
"Utilities. Stereo mode is being used now.") ); "Utilities. Stereo mode is being used now."));
} }
} }
free( layout ); free(layout);
} } else {
else msg_Warn(p_aout, "this driver does not support kAudioDevicePropertyPreferredChannelLayout. BAD DRIVER AUTHOR !!!");
{
msg_Warn( p_aout, "this driver does not support kAudioDevicePropertyPreferredChannelLayout. BAD DRIVER AUTHOR !!!" );
p_aout->format.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->format ) ); 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 )); msg_Dbg(p_aout, "VLC will output: %s", aout_FormatPrintChannels(&p_aout->format));
memset (&new_layout, 0, sizeof(new_layout)); memset (&new_layout, 0, sizeof(new_layout));
switch( aout_FormatNbChannels( &p_aout->format ) ) switch(aout_FormatNbChannels(&p_aout->format)) {
{
case 1: case 1:
new_layout.mChannelLayoutTag = kAudioChannelLayoutTag_Mono; new_layout.mChannelLayoutTag = kAudioChannelLayoutTag_Mono;
break; break;
...@@ -473,27 +447,27 @@ static int OpenAnalog( audio_output_t *p_aout ) ...@@ -473,27 +447,27 @@ static int OpenAnalog( audio_output_t *p_aout )
new_layout.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo; new_layout.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo;
break; break;
case 3: case 3:
if( p_aout->format.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 new_layout.mChannelLayoutTag = kAudioChannelLayoutTag_DVD_7; // L R C
else if( p_aout->format.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 new_layout.mChannelLayoutTag = kAudioChannelLayoutTag_DVD_4; // L R LFE
break; break;
case 4: case 4:
if( p_aout->format.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 new_layout.mChannelLayoutTag = kAudioChannelLayoutTag_DVD_10; // L R C LFE
else if( p_aout->format.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 new_layout.mChannelLayoutTag = kAudioChannelLayoutTag_DVD_3; // L R Ls Rs
else if( p_aout->format.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 new_layout.mChannelLayoutTag = kAudioChannelLayoutTag_DVD_3; // L R C Cs
break; break;
case 5: case 5:
if( p_aout->format.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 new_layout.mChannelLayoutTag = kAudioChannelLayoutTag_DVD_19; // L R Ls Rs C
else if( p_aout->format.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 new_layout.mChannelLayoutTag = kAudioChannelLayoutTag_DVD_18; // L R Ls Rs LFE
break; break;
case 6: case 6:
if( p_aout->format.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 new_layout.mChannelLayoutTag = kAudioChannelLayoutTag_DVD_20; // L R Ls Rs C LFE
else else
new_layout.mChannelLayoutTag = kAudioChannelLayoutTag_AudioUnit_6_0; // L R Ls Rs C Cs new_layout.mChannelLayoutTag = kAudioChannelLayoutTag_AudioUnit_6_0; // L R Ls Rs C Cs
...@@ -516,7 +490,7 @@ static int OpenAnalog( audio_output_t *p_aout ) ...@@ -516,7 +490,7 @@ static int OpenAnalog( audio_output_t *p_aout )
p_aout->format.i_format = VLC_CODEC_FL32; p_aout->format.i_format = VLC_CODEC_FL32;
DeviceFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked; DeviceFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked;
DeviceFormat.mBitsPerChannel = 32; DeviceFormat.mBitsPerChannel = 32;
DeviceFormat.mChannelsPerFrame = aout_FormatNbChannels( &p_aout->format ); DeviceFormat.mChannelsPerFrame = aout_FormatNbChannels(&p_aout->format);
/* Calculate framesizes and stuff */ /* Calculate framesizes and stuff */
DeviceFormat.mFramesPerPacket = 1; DeviceFormat.mFramesPerPacket = 1;
...@@ -525,28 +499,28 @@ static int OpenAnalog( audio_output_t *p_aout ) ...@@ -525,28 +499,28 @@ static int OpenAnalog( audio_output_t *p_aout )
/* Set the desired format */ /* Set the desired format */
i_param_size = sizeof(AudioStreamBasicDescription); i_param_size = sizeof(AudioStreamBasicDescription);
verify_noerr( AudioUnitSetProperty( p_sys->au_unit, verify_noerr(AudioUnitSetProperty(p_sys->au_unit,
kAudioUnitProperty_StreamFormat, kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input, kAudioUnitScope_Input,
0, 0,
&DeviceFormat, &DeviceFormat,
i_param_size )); i_param_size));
msg_Dbg( p_aout, STREAM_FORMAT_MSG( "we set the AU format: " , DeviceFormat ) ); msg_Dbg(p_aout, STREAM_FORMAT_MSG("we set the AU format: " , DeviceFormat));
/* Retrieve actual format */ /* Retrieve actual format */
verify_noerr( AudioUnitGetProperty( p_sys->au_unit, verify_noerr(AudioUnitGetProperty(p_sys->au_unit,
kAudioUnitProperty_StreamFormat, kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input, kAudioUnitScope_Input,
0, 0,
&DeviceFormat, &DeviceFormat,
&i_param_size )); &i_param_size));
msg_Dbg( p_aout, STREAM_FORMAT_MSG( "the actual set AU format is " , DeviceFormat ) ); msg_Dbg(p_aout, STREAM_FORMAT_MSG("the actual set AU format is " , DeviceFormat));
/* Do the last VLC aout setups */ /* Do the last VLC aout setups */
aout_FormatPrepare( &p_aout->format ); aout_FormatPrepare(&p_aout->format);
aout_PacketInit( p_aout, &p_sys->packet, FRAMESIZE ); aout_PacketInit(p_aout, &p_sys->packet, FRAMESIZE);
p_aout->volume_set = VolumeSet; p_aout->volume_set = VolumeSet;
p_aout->mute_set = MuteSet; p_aout->mute_set = MuteSet;
...@@ -554,33 +528,33 @@ static int OpenAnalog( audio_output_t *p_aout ) ...@@ -554,33 +528,33 @@ static int OpenAnalog( audio_output_t *p_aout )
input.inputProc = (AURenderCallback) RenderCallbackAnalog; input.inputProc = (AURenderCallback) RenderCallbackAnalog;
input.inputProcRefCon = p_aout; input.inputProcRefCon = p_aout;
verify_noerr( AudioUnitSetProperty( p_sys->au_unit, verify_noerr(AudioUnitSetProperty(p_sys->au_unit,
kAudioUnitProperty_SetRenderCallback, kAudioUnitProperty_SetRenderCallback,
kAudioUnitScope_Input, kAudioUnitScope_Input,
0, &input, sizeof( input ) ) ); 0, &input, sizeof(input)));
input.inputProc = (AURenderCallback) RenderCallbackAnalog; input.inputProc = (AURenderCallback) RenderCallbackAnalog;
input.inputProcRefCon = p_aout; input.inputProcRefCon = p_aout;
/* Set the new_layout as the layout VLC will use to feed the AU unit */ /* Set the new_layout as the layout VLC will use to feed the AU unit */
verify_noerr( AudioUnitSetProperty( p_sys->au_unit, verify_noerr(AudioUnitSetProperty(p_sys->au_unit,
kAudioUnitProperty_AudioChannelLayout, kAudioUnitProperty_AudioChannelLayout,
kAudioUnitScope_Input, kAudioUnitScope_Input,
0, &new_layout, sizeof(new_layout) ) ); 0, &new_layout, sizeof(new_layout)));
if( new_layout.mNumberChannelDescriptions > 0 ) if (new_layout.mNumberChannelDescriptions > 0)
free( new_layout.mChannelDescriptions ); free(new_layout.mChannelDescriptions);
/* AU initiliaze */ /* AU initiliaze */
verify_noerr( AudioUnitInitialize(p_sys->au_unit) ); verify_noerr(AudioUnitInitialize(p_sys->au_unit));
/* Find the difference between device clock and mdate clock */ /* Find the difference between device clock and mdate clock */
p_sys->clock_diff = - (mtime_t) p_sys->clock_diff = - (mtime_t)
AudioConvertHostTimeToNanos( AudioGetCurrentHostTime() ) / 1000; AudioConvertHostTimeToNanos(AudioGetCurrentHostTime()) / 1000;
p_sys->clock_diff += mdate(); p_sys->clock_diff += mdate();
/* Start the AU */ /* Start the AU */
verify_noerr( AudioOutputUnitStart(p_sys->au_unit) ); verify_noerr(AudioOutputUnitStart(p_sys->au_unit));
return true; return true;
} }
...@@ -588,7 +562,7 @@ static int OpenAnalog( audio_output_t *p_aout ) ...@@ -588,7 +562,7 @@ static int OpenAnalog( audio_output_t *p_aout )
/***************************************************************************** /*****************************************************************************
* Setup a encoded digital stream (SPDIF) * Setup a encoded digital stream (SPDIF)
*****************************************************************************/ *****************************************************************************/
static int OpenSPDIF( audio_output_t * p_aout ) static int OpenSPDIF (audio_output_t * p_aout)
{ {
struct aout_sys_t *p_sys = p_aout->sys; struct aout_sys_t *p_sys = p_aout->sys;
OSStatus err = noErr; OSStatus err = noErr;
...@@ -602,107 +576,95 @@ static int OpenSPDIF( audio_output_t * p_aout ) ...@@ -602,107 +576,95 @@ static int OpenSPDIF( audio_output_t * p_aout )
/* Hog the device */ /* Hog the device */
AudioObjectPropertyAddress audioDeviceHogModeAddress = { kAudioDevicePropertyHogMode, kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementMaster }; AudioObjectPropertyAddress audioDeviceHogModeAddress = { kAudioDevicePropertyHogMode, kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementMaster };
i_param_size = sizeof( p_sys->i_hog_pid ); i_param_size = sizeof(p_sys->i_hog_pid);
p_sys->i_hog_pid = getpid() ; p_sys->i_hog_pid = getpid() ;
err = AudioObjectSetPropertyData( p_sys->i_selected_dev, &audioDeviceHogModeAddress, 0, NULL, 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 ) if (err != noErr) {
{ msg_Err(p_aout, "failed to set hogmode: [%4.4s]", (char *)&err);
msg_Err( p_aout, "failed to set hogmode: [%4.4s]", (char *)&err );
return false; return false;
} }
AudioObjectPropertyAddress audioDeviceSupportsMixingAddress = { kAudioDevicePropertySupportsMixing , kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; AudioObjectPropertyAddress audioDeviceSupportsMixingAddress = { kAudioDevicePropertySupportsMixing , kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
if (AudioObjectHasProperty(p_sys->i_selected_dev, &audioDeviceSupportsMixingAddress)) if (AudioObjectHasProperty(p_sys->i_selected_dev, &audioDeviceSupportsMixingAddress)) {
{
/* Set mixable to false if we are allowed to */ /* Set mixable to false if we are allowed to */
err = AudioObjectIsPropertySettable( p_sys->i_selected_dev, &audioDeviceSupportsMixingAddress, &b_writeable ); err = AudioObjectIsPropertySettable(p_sys->i_selected_dev, &audioDeviceSupportsMixingAddress, &b_writeable);
err = AudioObjectGetPropertyDataSize( p_sys->i_selected_dev, &audioDeviceSupportsMixingAddress, 0, NULL, &i_param_size ); 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 = AudioObjectGetPropertyData(p_sys->i_selected_dev, &audioDeviceSupportsMixingAddress, 0, NULL, &i_param_size, &b_mix);
if( err == noErr && b_writeable ) if (err == noErr && b_writeable) {
{
b_mix = 0; b_mix = 0;
err = AudioObjectSetPropertyData( p_sys->i_selected_dev, &audioDeviceSupportsMixingAddress, 0, NULL, i_param_size, &b_mix ); err = AudioObjectSetPropertyData(p_sys->i_selected_dev, &audioDeviceSupportsMixingAddress, 0, NULL, i_param_size, &b_mix);
p_sys->b_changed_mixing = true; p_sys->b_changed_mixing = true;
} }
if( err != noErr ) if (err != noErr) {
{ msg_Err(p_aout, "failed to set mixmode: [%4.4s]", (char *)&err);
msg_Err( p_aout, "failed to set mixmode: [%4.4s]", (char *)&err );
return false; return false;
} }
} }
/* Get a list of all the streams on this device */ /* Get a list of all the streams on this device */
AudioObjectPropertyAddress streamsAddress = { kAudioDevicePropertyStreams, kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementMaster }; AudioObjectPropertyAddress streamsAddress = { kAudioDevicePropertyStreams, kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementMaster };
err = AudioObjectGetPropertyDataSize( p_sys->i_selected_dev, &streamsAddress, 0, NULL, &i_param_size ); err = AudioObjectGetPropertyDataSize(p_sys->i_selected_dev, &streamsAddress, 0, NULL, &i_param_size);
if( err != noErr ) if (err != noErr) {
{ msg_Err(p_aout, "could not get number of streams: [%4.4s]", (char *)&err);
msg_Err( p_aout, "could not get number of streams: [%4.4s]", (char *)&err );
return false; return false;
} }
i_streams = i_param_size / sizeof( AudioStreamID ); i_streams = i_param_size / sizeof(AudioStreamID);
p_streams = (AudioStreamID *)malloc( i_param_size ); p_streams = (AudioStreamID *)malloc(i_param_size);
if( p_streams == NULL ) if (p_streams == NULL)
return false; return false;
err = AudioObjectGetPropertyData( p_sys->i_selected_dev, &streamsAddress, 0, NULL, &i_param_size, p_streams ); err = AudioObjectGetPropertyData(p_sys->i_selected_dev, &streamsAddress, 0, NULL, &i_param_size, p_streams);
if( err != noErr ) if (err != noErr) {
{ msg_Err(p_aout, "could not get number of streams: [%4.4s]", (char *)&err);
msg_Err( p_aout, "could not get number of streams: [%4.4s]", (char *)&err ); free(p_streams);
free( p_streams );
return false; return false;
} }
AudioObjectPropertyAddress physicalFormatsAddress = { kAudioStreamPropertyAvailablePhysicalFormats, kAudioObjectPropertyScopeGlobal, 0 }; AudioObjectPropertyAddress physicalFormatsAddress = { kAudioStreamPropertyAvailablePhysicalFormats, kAudioObjectPropertyScopeGlobal, 0 };
for( unsigned i = 0; i < i_streams && p_sys->i_stream_index < 0 ; i++ ) for (unsigned i = 0; i < i_streams && p_sys->i_stream_index < 0 ; i++) {
{
/* Find a stream with a cac3 stream */ /* Find a stream with a cac3 stream */
AudioStreamRangedDescription *p_format_list = NULL; AudioStreamRangedDescription *p_format_list = NULL;
int i_formats = 0; int i_formats = 0;
bool b_digital = false; bool b_digital = false;
/* Retrieve all the stream formats supported by each output stream */ /* Retrieve all the stream formats supported by each output stream */
err = AudioObjectGetPropertyDataSize( p_streams[i], &physicalFormatsAddress, 0, NULL, &i_param_size ); err = AudioObjectGetPropertyDataSize(p_streams[i], &physicalFormatsAddress, 0, NULL, &i_param_size);
if( err != noErr ) if (err != noErr) {
{ msg_Err(p_aout, "OpenSPDIF: could not get number of streamformats: [%s] (%i)", (char *)&err, (int32_t)err);
msg_Err( p_aout, "OpenSPDIF: could not get number of streamformats: [%s] (%i)", (char *)&err, (int32_t)err );
continue; continue;
} }
i_formats = i_param_size / sizeof( AudioStreamRangedDescription ); i_formats = i_param_size / sizeof(AudioStreamRangedDescription);
p_format_list = (AudioStreamRangedDescription *)malloc( i_param_size ); p_format_list = (AudioStreamRangedDescription *)malloc(i_param_size);
if( p_format_list == NULL ) if (p_format_list == NULL)
continue; continue;
err = AudioObjectGetPropertyData( p_streams[i], &physicalFormatsAddress, 0, NULL, &i_param_size, p_format_list ); err = AudioObjectGetPropertyData(p_streams[i], &physicalFormatsAddress, 0, NULL, &i_param_size, p_format_list);
if( err != noErr ) if (err != noErr) {
{ msg_Err(p_aout, "could not get the list of streamformats: [%4.4s]", (char *)&err);
msg_Err( p_aout, "could not get the list of streamformats: [%4.4s]", (char *)&err ); free(p_format_list);
free( p_format_list );
continue; continue;
} }
/* Check if one of the supported formats is a digital format */ /* Check if one of the supported formats is a digital format */
for( int j = 0; j < i_formats; j++ ) for (int j = 0; j < i_formats; j++) {
{ if (p_format_list[j].mFormat.mFormatID == 'IAC3' ||
if( p_format_list[j].mFormat.mFormatID == 'IAC3' ||
p_format_list[j].mFormat.mFormatID == 'iac3' || p_format_list[j].mFormat.mFormatID == 'iac3' ||
p_format_list[j].mFormat.mFormatID == kAudioFormat60958AC3 || p_format_list[j].mFormat.mFormatID == kAudioFormat60958AC3 ||
p_format_list[j].mFormat.mFormatID == kAudioFormatAC3 ) p_format_list[j].mFormat.mFormatID == kAudioFormatAC3) {
{
b_digital = true; b_digital = true;
break; break;
} }
} }
if( b_digital ) if (b_digital) {
{
/* if this stream supports a digital (cac3) format, then go set it. */ /* if this stream supports a digital (cac3) format, then go set it. */
int i_requested_rate_format = -1; int i_requested_rate_format = -1;
int i_current_rate_format = -1; int i_current_rate_format = -1;
...@@ -711,98 +673,89 @@ static int OpenSPDIF( audio_output_t * p_aout ) ...@@ -711,98 +673,89 @@ static int OpenSPDIF( audio_output_t * p_aout )
p_sys->i_stream_id = p_streams[i]; p_sys->i_stream_id = p_streams[i];
p_sys->i_stream_index = i; p_sys->i_stream_index = i;
if( !p_sys->b_revert ) if (!p_sys->b_revert) {
{
AudioObjectPropertyAddress currentPhysicalFormatAddress = { kAudioStreamPropertyPhysicalFormat, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; AudioObjectPropertyAddress currentPhysicalFormatAddress = { kAudioStreamPropertyPhysicalFormat, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
/* Retrieve the original format of this stream first if not done so already */ /* Retrieve the original format of this stream first if not done so already */
i_param_size = sizeof( p_sys->sfmt_revert ); i_param_size = sizeof(p_sys->sfmt_revert);
err = AudioObjectGetPropertyData( p_sys->i_stream_id, &currentPhysicalFormatAddress, 0, NULL, &i_param_size, &p_sys->sfmt_revert ); err = AudioObjectGetPropertyData(p_sys->i_stream_id, &currentPhysicalFormatAddress, 0, NULL, &i_param_size, &p_sys->sfmt_revert);
if( err != noErr ) if (err != noErr) {
{ msg_Err(p_aout, "could not retrieve the original streamformat: [%4.4s]", (char *)&err);
msg_Err( p_aout, "could not retrieve the original streamformat: [%4.4s]", (char *)&err );
continue; continue;
} }
p_sys->b_revert = true; p_sys->b_revert = true;
} }
for( int j = 0; j < i_formats; j++ ) for (int j = 0; j < i_formats; j++) {
{ if (p_format_list[j].mFormat.mFormatID == 'IAC3' ||
if( p_format_list[j].mFormat.mFormatID == 'IAC3' ||
p_format_list[j].mFormat.mFormatID == 'iac3' || p_format_list[j].mFormat.mFormatID == 'iac3' ||
p_format_list[j].mFormat.mFormatID == kAudioFormat60958AC3 || p_format_list[j].mFormat.mFormatID == kAudioFormat60958AC3 ||
p_format_list[j].mFormat.mFormatID == kAudioFormatAC3 ) p_format_list[j].mFormat.mFormatID == kAudioFormatAC3) {
{ if (p_format_list[j].mFormat.mSampleRate == p_aout->format.i_rate) {
if( p_format_list[j].mFormat.mSampleRate == p_aout->format.i_rate )
{
i_requested_rate_format = j; i_requested_rate_format = j;
break; break;
} } else if (p_format_list[j].mFormat.mSampleRate == p_sys->sfmt_revert.mSampleRate)
else if( p_format_list[j].mFormat.mSampleRate == p_sys->sfmt_revert.mSampleRate )
i_current_rate_format = j; i_current_rate_format = j;
else else {
{ if (i_backup_rate_format < 0 || p_format_list[j].mFormat.mSampleRate > p_format_list[i_backup_rate_format].mFormat.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; i_backup_rate_format = j;
} }
} }
} }
if( i_requested_rate_format >= 0 ) /* We prefer to output at the samplerate of the original audio */ 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].mFormat; 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 */ 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].mFormat; 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) */ 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) */
} }
free( p_format_list ); free(p_format_list);
} }
free( p_streams ); free(p_streams);
msg_Dbg( p_aout, STREAM_FORMAT_MSG( "original stream format: ", p_sys->sfmt_revert ) ); 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 ) ) if (!AudioStreamChangeFormat(p_aout, p_sys->i_stream_id, p_sys->stream_format))
return false; return false;
/* Set the format flags */ /* Set the format flags */
if( p_sys->stream_format.mFormatFlags & kAudioFormatFlagIsBigEndian ) if (p_sys->stream_format.mFormatFlags & kAudioFormatFlagIsBigEndian)
p_aout->format.i_format = VLC_CODEC_SPDIFB; p_aout->format.i_format = VLC_CODEC_SPDIFB;
else else
p_aout->format.i_format = VLC_CODEC_SPDIFL; p_aout->format.i_format = VLC_CODEC_SPDIFL;
p_aout->format.i_bytes_per_frame = AOUT_SPDIF_SIZE; p_aout->format.i_bytes_per_frame = AOUT_SPDIF_SIZE;
p_aout->format.i_frame_length = A52_FRAME_NB; p_aout->format.i_frame_length = A52_FRAME_NB;
p_aout->format.i_rate = (unsigned int)p_sys->stream_format.mSampleRate; p_aout->format.i_rate = (unsigned int)p_sys->stream_format.mSampleRate;
aout_FormatPrepare( &p_aout->format ); aout_FormatPrepare(&p_aout->format);
aout_PacketInit( p_aout, &p_sys->packet, A52_FRAME_NB ); aout_PacketInit(p_aout, &p_sys->packet, A52_FRAME_NB);
p_aout->volume_set = NULL; p_aout->volume_set = NULL;
p_aout->mute_set = NULL; p_aout->mute_set = NULL;
/* Add IOProc callback */ /* Add IOProc callback */
err = AudioDeviceCreateIOProcID( p_sys->i_selected_dev, err = AudioDeviceCreateIOProcID(p_sys->i_selected_dev,
(AudioDeviceIOProc)RenderCallbackSPDIF, (AudioDeviceIOProc)RenderCallbackSPDIF,
(void *)p_aout, (void *)p_aout,
&p_sys->i_procID ); &p_sys->i_procID);
if( err != noErr ) if (err != noErr) {
{ msg_Err(p_aout, "AudioDeviceCreateIOProcID failed: [%4.4s]", (char *)&err);
msg_Err( p_aout, "AudioDeviceCreateIOProcID failed: [%4.4s]", (char *)&err );
aout_PacketDestroy (p_aout); aout_PacketDestroy (p_aout);
return false; return false;
} }
/* Check for the difference between the Device clock and mdate */ /* Check for the difference between the Device clock and mdate */
p_sys->clock_diff = - (mtime_t) p_sys->clock_diff = - (mtime_t)
AudioConvertHostTimeToNanos( AudioGetCurrentHostTime() ) / 1000; AudioConvertHostTimeToNanos(AudioGetCurrentHostTime()) / 1000;
p_sys->clock_diff += mdate(); p_sys->clock_diff += mdate();
/* Start device */ /* Start device */
err = AudioDeviceStart( p_sys->i_selected_dev, p_sys->i_procID ); err = AudioDeviceStart(p_sys->i_selected_dev, p_sys->i_procID);
if( err != noErr ) if (err != noErr) {
{ msg_Err(p_aout, "AudioDeviceStart failed: [%4.4s]", (char *)&err);
msg_Err( p_aout, "AudioDeviceStart failed: [%4.4s]", (char *)&err );
err = AudioDeviceDestroyIOProcID( p_sys->i_selected_dev, err = AudioDeviceDestroyIOProcID(p_sys->i_selected_dev, p_sys->i_procID);
p_sys->i_procID ); if (err != noErr)
if( err != noErr ) msg_Err(p_aout, "AudioDeviceDestroyIOProcID failed: [%4.4s]", (char *)&err);
msg_Err( p_aout, "AudioDeviceDestroyIOProcID failed: [%4.4s]", (char *)&err );
aout_PacketDestroy (p_aout); aout_PacketDestroy (p_aout);
return false; return false;
...@@ -815,7 +768,7 @@ static int OpenSPDIF( audio_output_t * p_aout ) ...@@ -815,7 +768,7 @@ static int OpenSPDIF( audio_output_t * p_aout )
/***************************************************************************** /*****************************************************************************
* Close: Close HAL AudioUnit * Close: Close HAL AudioUnit
*****************************************************************************/ *****************************************************************************/
static void Close( vlc_object_t * p_this ) static void Close(vlc_object_t * p_this)
{ {
audio_output_t *p_aout = (audio_output_t *)p_this; audio_output_t *p_aout = (audio_output_t *)p_this;
struct aout_sys_t *p_sys = p_aout->sys; struct aout_sys_t *p_sys = p_aout->sys;
...@@ -823,82 +776,78 @@ static void Close( vlc_object_t * p_this ) ...@@ -823,82 +776,78 @@ static void Close( vlc_object_t * p_this )
UInt32 i_param_size = 0; UInt32 i_param_size = 0;
AudioObjectPropertyAddress deviceAliveAddress = { kAudioDevicePropertyDeviceIsAlive, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; AudioObjectPropertyAddress deviceAliveAddress = { kAudioDevicePropertyDeviceIsAlive, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
err = AudioObjectRemovePropertyListener( p_sys->i_selected_dev, &deviceAliveAddress, HardwareListener, NULL ); err = AudioObjectRemovePropertyListener(p_sys->i_selected_dev, &deviceAliveAddress, HardwareListener, NULL);
if( err != noErr ) if (err != noErr)
msg_Err( p_aout, "failed to remove audio device life checker: [%4.4s]", (char *)&err ); msg_Err(p_aout, "failed to remove audio device life checker: [%4.4s]", (char *)&err);
if( p_sys->au_unit ) if (p_sys->au_unit) {
{ verify_noerr(AudioOutputUnitStop(p_sys->au_unit));
verify_noerr( AudioOutputUnitStop( p_sys->au_unit ) ); verify_noerr(AudioUnitUninitialize(p_sys->au_unit));
verify_noerr( AudioUnitUninitialize( p_sys->au_unit ) ); verify_noerr(CloseComponent(p_sys->au_unit));
verify_noerr( CloseComponent( p_sys->au_unit ) );
} }
if( p_sys->b_digital ) if (p_sys->b_digital) {
{
/* Stop device */ /* Stop device */
err = AudioDeviceStop( p_sys->i_selected_dev, err = AudioDeviceStop(p_sys->i_selected_dev,
p_sys->i_procID ); p_sys->i_procID);
if( err != noErr ) if (err != noErr)
msg_Err( p_aout, "AudioDeviceStop failed: [%4.4s]", (char *)&err ); msg_Err(p_aout, "AudioDeviceStop failed: [%4.4s]", (char *)&err);
/* Remove IOProc callback */ /* Remove IOProc callback */
err = AudioDeviceDestroyIOProcID( p_sys->i_selected_dev, err = AudioDeviceDestroyIOProcID(p_sys->i_selected_dev,
p_sys->i_procID ); p_sys->i_procID);
if( err != noErr ) if (err != noErr)
msg_Err( p_aout, "AudioDeviceDestroyIOProcID failed: [%4.4s]", (char *)&err ); msg_Err(p_aout, "AudioDeviceDestroyIOProcID failed: [%4.4s]", (char *)&err);
if( p_sys->b_revert ) if (p_sys->b_revert)
AudioStreamChangeFormat( p_aout, p_sys->i_stream_id, p_sys->sfmt_revert ); AudioStreamChangeFormat(p_aout, p_sys->i_stream_id, p_sys->sfmt_revert);
if( p_sys->b_changed_mixing && p_sys->sfmt_revert.mFormatID != kAudioFormat60958AC3 ) if (p_sys->b_changed_mixing && p_sys->sfmt_revert.mFormatID != kAudioFormat60958AC3) {
{
int b_mix; int b_mix;
Boolean b_writeable = false; Boolean b_writeable = false;
/* Revert mixable to true if we are allowed to */ /* Revert mixable to true if we are allowed to */
AudioObjectPropertyAddress audioDeviceSupportsMixingAddress = { kAudioDevicePropertySupportsMixing , kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementMaster }; AudioObjectPropertyAddress audioDeviceSupportsMixingAddress = { kAudioDevicePropertySupportsMixing , kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementMaster };
err = AudioObjectIsPropertySettable( p_sys->i_selected_dev, &audioDeviceSupportsMixingAddress, &b_writeable ); 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 = AudioObjectGetPropertyData(p_sys->i_selected_dev, &audioDeviceSupportsMixingAddress, 0, NULL, &i_param_size, &b_mix);
if( err == noErr && b_writeable ) if (err == noErr && b_writeable) {
{ msg_Dbg(p_aout, "mixable is: %d", b_mix);
msg_Dbg( p_aout, "mixable is: %d", b_mix );
b_mix = 1; b_mix = 1;
err = AudioObjectSetPropertyData( p_sys->i_selected_dev, &audioDeviceSupportsMixingAddress, 0, NULL, i_param_size, &b_mix ); err = AudioObjectSetPropertyData(p_sys->i_selected_dev, &audioDeviceSupportsMixingAddress, 0, NULL, i_param_size, &b_mix);
} }
if( err != noErr ) if (err != noErr)
msg_Err( p_aout, "failed to set mixmode: [%4.4s]", (char *)&err ); msg_Err(p_aout, "failed to set mixmode: [%4.4s]", (char *)&err);
} }
} }
AudioObjectPropertyAddress audioDevicesAddress = { kAudioHardwarePropertyDevices, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; AudioObjectPropertyAddress audioDevicesAddress = { kAudioHardwarePropertyDevices, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
err = AudioObjectRemovePropertyListener( kAudioObjectSystemObject, &audioDevicesAddress, HardwareListener, NULL ); err = AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &audioDevicesAddress, HardwareListener, NULL);
if( err != noErr ) if (err != noErr)
msg_Err( p_aout, "AudioHardwareRemovePropertyListener failed: [%4.4s]", (char *)&err ); msg_Err(p_aout, "AudioHardwareRemovePropertyListener failed: [%4.4s]", (char *)&err);
if( p_sys->i_hog_pid == getpid() ) if (p_sys->i_hog_pid == getpid()) {
{
p_sys->i_hog_pid = -1; p_sys->i_hog_pid = -1;
i_param_size = sizeof( p_sys->i_hog_pid ); i_param_size = sizeof(p_sys->i_hog_pid);
AudioObjectPropertyAddress audioDeviceHogModeAddress = { kAudioDevicePropertyHogMode, AudioObjectPropertyAddress audioDeviceHogModeAddress = { kAudioDevicePropertyHogMode,
kAudioDevicePropertyScopeOutput, kAudioDevicePropertyScopeOutput,
kAudioObjectPropertyElementMaster }; kAudioObjectPropertyElementMaster };
err = AudioObjectSetPropertyData( p_sys->i_selected_dev, &audioDeviceHogModeAddress, 0, NULL, 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, "Could not release hogmode: [%4.4s]", (char *)&err ); if (err != noErr)
msg_Err(p_aout, "Could not release hogmode: [%4.4s]", (char *)&err);
} }
var_DelCallback( p_aout, "audio-device", AudioDeviceCallback, NULL ); var_DelCallback(p_aout, "audio-device", AudioDeviceCallback, NULL);
aout_PacketDestroy( p_aout ); aout_PacketDestroy(p_aout);
free( p_sys ); free(p_sys);
} }
/***************************************************************************** /*****************************************************************************
* Probe: Check which devices the OS has, and add them to our audio-device menu * Probe: Check which devices the OS has, and add them to our audio-device menu
*****************************************************************************/ *****************************************************************************/
static void Probe( audio_output_t * p_aout ) static void Probe(audio_output_t * p_aout)
{ {
OSStatus err = noErr; OSStatus err = noErr;
UInt32 i_param_size = 0; UInt32 i_param_size = 0;
...@@ -911,145 +860,133 @@ static void Probe( audio_output_t * p_aout ) ...@@ -911,145 +860,133 @@ static void Probe( audio_output_t * p_aout )
/* Get number of devices */ /* Get number of devices */
AudioObjectPropertyAddress audioDevicesAddress = { kAudioHardwarePropertyDevices, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; AudioObjectPropertyAddress audioDevicesAddress = { kAudioHardwarePropertyDevices, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
err = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &audioDevicesAddress, 0, NULL, &i_param_size); err = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &audioDevicesAddress, 0, NULL, &i_param_size);
if( err != noErr ) if (err != noErr) {
{ msg_Err(p_aout, "Could not get number of devices: [%s]", (char *)&err);
msg_Err( p_aout, "Could not get number of devices: [%s]", (char *)&err );
goto error; goto error;
} }
p_sys->i_devices = i_param_size / sizeof( AudioDeviceID ); p_sys->i_devices = i_param_size / sizeof(AudioDeviceID);
if( p_sys->i_devices < 1 ) if (p_sys->i_devices < 1) {
{ msg_Err(p_aout, "No audio output devices were found.");
msg_Err( p_aout, "No audio output devices were found." );
goto error; goto error;
} }
msg_Dbg( p_aout, "found %u audio device(s)", (unsigned)p_sys->i_devices ); msg_Dbg(p_aout, "found %u audio device(s)", (unsigned)p_sys->i_devices);
/* Allocate DeviceID array */ /* Allocate DeviceID array */
p_devices = (AudioDeviceID*)malloc( sizeof(AudioDeviceID) * p_sys->i_devices ); p_devices = (AudioDeviceID*)malloc(sizeof(AudioDeviceID) * p_sys->i_devices);
if( p_devices == NULL ) if (p_devices == NULL)
goto error; goto error;
/* Populate DeviceID array */ /* Populate DeviceID array */
err = AudioObjectGetPropertyData( kAudioObjectSystemObject, &audioDevicesAddress, 0, NULL, &i_param_size, p_devices ); err = AudioObjectGetPropertyData(kAudioObjectSystemObject, &audioDevicesAddress, 0, NULL, &i_param_size, p_devices);
if( err != noErr ) if (err != noErr) {
{ msg_Err(p_aout, "could not get the device IDs: [%s]", (char *)&err);
msg_Err( p_aout, "could not get the device IDs: [%s]", (char *)&err );
goto error; goto error;
} }
/* Find the ID of the default Device */ /* Find the ID of the default Device */
AudioObjectPropertyAddress defaultDeviceAddress = { kAudioHardwarePropertyDefaultOutputDevice, kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementMaster }; AudioObjectPropertyAddress defaultDeviceAddress = { kAudioHardwarePropertyDefaultOutputDevice, kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementMaster };
i_param_size = sizeof( AudioDeviceID ); i_param_size = sizeof(AudioDeviceID);
err= AudioObjectGetPropertyData( kAudioObjectSystemObject, &defaultDeviceAddress, 0, NULL, &i_param_size, &devid_def ); err= AudioObjectGetPropertyData(kAudioObjectSystemObject, &defaultDeviceAddress, 0, NULL, &i_param_size, &devid_def);
if( err != noErr ) if (err != noErr) {
{ msg_Err(p_aout, "could not get default audio device: [%s]", (char *)&err);
msg_Err( p_aout, "could not get default audio device: [%s]", (char *)&err );
goto error; goto error;
} }
p_sys->i_default_dev = devid_def; p_sys->i_default_dev = devid_def;
var_Create( p_aout, "audio-device", VLC_VAR_INTEGER|VLC_VAR_HASCHOICE ); var_Create(p_aout, "audio-device", VLC_VAR_INTEGER|VLC_VAR_HASCHOICE);
text.psz_string = (char*)_("Audio Device"); text.psz_string = (char*)_("Audio Device");
var_Change( p_aout, "audio-device", VLC_VAR_SETTEXT, &text, NULL ); var_Change(p_aout, "audio-device", VLC_VAR_SETTEXT, &text, NULL);
AudioObjectPropertyAddress deviceNameAddress = { kAudioDevicePropertyDeviceName, kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementMaster }; AudioObjectPropertyAddress deviceNameAddress = { kAudioDevicePropertyDeviceName, kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementMaster };
for( unsigned int i = 0; i < p_sys->i_devices; i++ ) for (unsigned int i = 0; i < p_sys->i_devices; i++) {
{
char *psz_name; char *psz_name;
i_param_size = 0; i_param_size = 0;
/* Retrieve the length of the device name */ /* Retrieve the length of the device name */
err = AudioObjectGetPropertyDataSize( p_devices[i], &deviceNameAddress, 0, NULL, &i_param_size ); err = AudioObjectGetPropertyDataSize(p_devices[i], &deviceNameAddress, 0, NULL, &i_param_size);
if( err != noErr ) if (err != noErr)
goto error; goto error;
/* Retrieve the name of the device */ /* Retrieve the name of the device */
psz_name = (char *)malloc( i_param_size ); psz_name = (char *)malloc(i_param_size);
err = AudioObjectGetPropertyData( p_devices[i], &deviceNameAddress, 0, NULL, &i_param_size, psz_name ); err = AudioObjectGetPropertyData(p_devices[i], &deviceNameAddress, 0, NULL, &i_param_size, psz_name);
if( err != noErr ) if (err != noErr)
goto error; goto error;
msg_Dbg( p_aout, "DevID: %u DevName: %s", (unsigned)p_devices[i], psz_name ); msg_Dbg(p_aout, "DevID: %u DevName: %s", (unsigned)p_devices[i], psz_name);
if( !AudioDeviceHasOutput( p_devices[i]) ) if (!AudioDeviceHasOutput(p_devices[i])) {
{ msg_Dbg(p_aout, "this device is INPUT only. skipping...");
msg_Dbg( p_aout, "this device is INPUT only. skipping..." ); free(psz_name);
free( psz_name );
continue; continue;
} }
/* Add the menu entries */ /* Add the menu entries */
val.i_int = (int)p_devices[i]; val.i_int = (int)p_devices[i];
text.psz_string = psz_name; text.psz_string = psz_name;
var_Change( p_aout, "audio-device", VLC_VAR_ADDCHOICE, &val, &text ); var_Change(p_aout, "audio-device", VLC_VAR_ADDCHOICE, &val, &text);
text.psz_string = NULL; text.psz_string = NULL;
if( p_sys->i_default_dev == p_devices[i] ) if (p_sys->i_default_dev == p_devices[i]) {
{
/* The default device is the selected device normally */ /* The default device is the selected device normally */
var_Change( p_aout, "audio-device", VLC_VAR_SETDEFAULT, &val, NULL ); var_Change(p_aout, "audio-device", VLC_VAR_SETDEFAULT, &val, NULL);
var_Set( p_aout, "audio-device", val ); var_Set(p_aout, "audio-device", val);
} }
if( AudioDeviceSupportsDigital( p_aout, p_devices[i] ) ) if (AudioDeviceSupportsDigital(p_aout, p_devices[i])) {
{
val.i_int = (int)p_devices[i] | AOUT_VAR_SPDIF_FLAG; val.i_int = (int)p_devices[i] | AOUT_VAR_SPDIF_FLAG;
if( asprintf( &text.psz_string, _("%s (Encoded Output)"), psz_name ) != -1 ) if (asprintf(&text.psz_string, _("%s (Encoded Output)"), psz_name) != -1) {
{ var_Change(p_aout, "audio-device", VLC_VAR_ADDCHOICE, &val, &text);
var_Change( p_aout, "audio-device", VLC_VAR_ADDCHOICE, &val, &text ); free(text.psz_string);
free( text.psz_string ); if (p_sys->i_default_dev == p_devices[i] && var_InheritBool(p_aout, "spdif")) {
if( p_sys->i_default_dev == p_devices[i]
&& var_InheritBool( p_aout, "spdif" ) )
{
/* We selected to prefer SPDIF output if available /* We selected to prefer SPDIF output if available
* then this "dummy" entry should be selected */ * then this "dummy" entry should be selected */
var_Change( p_aout, "audio-device", VLC_VAR_SETDEFAULT, &val, NULL ); var_Change(p_aout, "audio-device", VLC_VAR_SETDEFAULT, &val, NULL);
var_Set( p_aout, "audio-device", val ); var_Set(p_aout, "audio-device", val);
} }
} }
} }
free( psz_name); free(psz_name);
} }
/* If a device is already "preselected", then use this device */ /* If a device is already "preselected", then use this device */
var_Get( p_aout->p_libvlc, "macosx-audio-device", &val ); var_Get(p_aout->p_libvlc, "macosx-audio-device", &val);
if( val.i_int > 0 ) if (val.i_int > 0) {
{ msg_Dbg(p_aout, "using preselected output device %#"PRIx64, val.i_int);
msg_Dbg( p_aout, "using preselected output device %#"PRIx64, val.i_int ); var_Change(p_aout, "audio-device", VLC_VAR_SETDEFAULT, &val, NULL);
var_Change( p_aout, "audio-device", VLC_VAR_SETDEFAULT, &val, NULL ); var_Set(p_aout, "audio-device", val);
var_Set( p_aout, "audio-device", val );
} }
/* Attach a Listener so that we are notified of a change in the Device setup */ /* Attach a Listener so that we are notified of a change in the Device setup */
err = AudioObjectAddPropertyListener( kAudioObjectSystemObject, &audioDevicesAddress, HardwareListener, (void *)p_aout ); err = AudioObjectAddPropertyListener(kAudioObjectSystemObject, &audioDevicesAddress, HardwareListener, (void *)p_aout);
if( err != noErr ) if (err != noErr) {
{ msg_Warn(p_aout, "failed to add listener for audio device configuration (%i)", err);
msg_Warn( p_aout, "failed to add listener for audio device configuration (%i)", err );
goto error; goto error;
} }
free( p_devices ); free(p_devices);
return; return;
error: error:
msg_Warn( p_aout, "audio device already in use" ); msg_Warn(p_aout, "audio device already in use");
free( p_devices ); free(p_devices);
return; return;
} }
/***************************************************************************** /*****************************************************************************
* AudioDeviceHasOutput: Checks if the Device actually provides any outputs at all * AudioDeviceHasOutput: Checks if the Device actually provides any outputs at all
*****************************************************************************/ *****************************************************************************/
static int AudioDeviceHasOutput( AudioDeviceID i_dev_id ) static int AudioDeviceHasOutput(AudioDeviceID i_dev_id)
{ {
UInt32 dataSize; UInt32 dataSize;
AudioObjectPropertyAddress streamsAddress = { kAudioDevicePropertyStreams, kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementMaster }; AudioObjectPropertyAddress streamsAddress = { kAudioDevicePropertyStreams, kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementMaster };
verify_noerr( AudioObjectGetPropertyDataSize( i_dev_id, &streamsAddress, 0, NULL, &dataSize ) ); verify_noerr(AudioObjectGetPropertyDataSize(i_dev_id, &streamsAddress, 0, NULL, &dataSize));
if (dataSize == 0) return FALSE; if (dataSize == 0)
return FALSE;
return TRUE; return TRUE;
} }
...@@ -1057,7 +994,7 @@ static int AudioDeviceHasOutput( AudioDeviceID i_dev_id ) ...@@ -1057,7 +994,7 @@ static int AudioDeviceHasOutput( AudioDeviceID i_dev_id )
/***************************************************************************** /*****************************************************************************
* AudioDeviceSupportsDigital: Check i_dev_id for digital stream support. * AudioDeviceSupportsDigital: Check i_dev_id for digital stream support.
*****************************************************************************/ *****************************************************************************/
static int AudioDeviceSupportsDigital( audio_output_t *p_aout, AudioDeviceID i_dev_id ) static int AudioDeviceSupportsDigital(audio_output_t *p_aout, AudioDeviceID i_dev_id)
{ {
OSStatus err = noErr; OSStatus err = noErr;
UInt32 i_param_size = 0; UInt32 i_param_size = 0;
...@@ -1067,39 +1004,36 @@ static int AudioDeviceSupportsDigital( audio_output_t *p_aout, AudioDeviceID i_d ...@@ -1067,39 +1004,36 @@ static int AudioDeviceSupportsDigital( audio_output_t *p_aout, AudioDeviceID i_d
/* Retrieve all the output streams */ /* Retrieve all the output streams */
AudioObjectPropertyAddress streamsAddress = { kAudioDevicePropertyStreams, kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementMaster }; AudioObjectPropertyAddress streamsAddress = { kAudioDevicePropertyStreams, kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementMaster };
err = AudioObjectGetPropertyDataSize( i_dev_id, &streamsAddress, 0, NULL, &i_param_size ); err = AudioObjectGetPropertyDataSize(i_dev_id, &streamsAddress, 0, NULL, &i_param_size);
if( err != noErr ) if (err != noErr) {
{ msg_Err(p_aout, "could not get number of streams: [%s] (%i)", (char *)&err, (int32_t)err);
msg_Err( p_aout, "could not get number of streams: [%s] (%i)", (char *)&err, (int32_t)err );
return false; return false;
} }
i_streams = i_param_size / sizeof( AudioStreamID ); i_streams = i_param_size / sizeof(AudioStreamID);
p_streams = (AudioStreamID *)malloc( i_param_size ); p_streams = (AudioStreamID *)malloc(i_param_size);
if( p_streams == NULL ) if (p_streams == NULL)
return VLC_ENOMEM; return VLC_ENOMEM;
err = AudioObjectGetPropertyData( i_dev_id, &streamsAddress, 0, NULL, &i_param_size, p_streams ); err = AudioObjectGetPropertyData(i_dev_id, &streamsAddress, 0, NULL, &i_param_size, p_streams);
if( err != noErr ) if (err != noErr) {
{ msg_Err(p_aout, "could not get list of streams: [%s]", (char *)&err);
msg_Err( p_aout, "could not get list of streams: [%s]", (char *)&err );
return false; return false;
} }
for( int i = 0; i < i_streams; i++ ) for (int i = 0; i < i_streams; i++) {
{ if (AudioStreamSupportsDigital(p_aout, p_streams[i]))
if( AudioStreamSupportsDigital( p_aout, p_streams[i] ) )
b_return = true; b_return = true;
} }
free( p_streams ); free(p_streams);
return b_return; return b_return;
} }
/***************************************************************************** /*****************************************************************************
* AudioStreamSupportsDigital: Check i_stream_id for digital stream support. * AudioStreamSupportsDigital: Check i_stream_id for digital stream support.
*****************************************************************************/ *****************************************************************************/
static int AudioStreamSupportsDigital( audio_output_t *p_aout, AudioStreamID i_stream_id ) static int AudioStreamSupportsDigital(audio_output_t *p_aout, AudioStreamID i_stream_id)
{ {
OSStatus err = noErr; OSStatus err = noErr;
UInt32 i_param_size = 0; UInt32 i_param_size = 0;
...@@ -1109,48 +1043,45 @@ static int AudioStreamSupportsDigital( audio_output_t *p_aout, AudioStreamID i_s ...@@ -1109,48 +1043,45 @@ static int AudioStreamSupportsDigital( audio_output_t *p_aout, AudioStreamID i_s
/* Retrieve all the stream formats supported by each output stream */ /* Retrieve all the stream formats supported by each output stream */
AudioObjectPropertyAddress physicalFormatsAddress = { kAudioStreamPropertyAvailablePhysicalFormats, kAudioObjectPropertyScopeGlobal, 0 }; AudioObjectPropertyAddress physicalFormatsAddress = { kAudioStreamPropertyAvailablePhysicalFormats, kAudioObjectPropertyScopeGlobal, 0 };
err = AudioObjectGetPropertyDataSize( i_stream_id, &physicalFormatsAddress, 0, NULL, &i_param_size ); err = AudioObjectGetPropertyDataSize(i_stream_id, &physicalFormatsAddress, 0, NULL, &i_param_size);
if( err != noErr ) if (err != noErr) {
{ msg_Err(p_aout, "could not get number of streamformats: [%s] (%i)", (char *)&err, (int32_t)err);
msg_Err( p_aout, "could not get number of streamformats: [%s] (%i)", (char *)&err, (int32_t)err );
return false; return false;
} }
i_formats = i_param_size / sizeof( AudioStreamRangedDescription ); i_formats = i_param_size / sizeof(AudioStreamRangedDescription);
msg_Dbg( p_aout, "found %i stream formats", i_formats ); msg_Dbg(p_aout, "found %i stream formats", i_formats);
p_format_list = (AudioStreamRangedDescription *)malloc( i_param_size ); p_format_list = (AudioStreamRangedDescription *)malloc(i_param_size);
if( p_format_list == NULL ) if (p_format_list == NULL)
return false; return false;
err = AudioObjectGetPropertyData( i_stream_id, &physicalFormatsAddress, 0, NULL, &i_param_size, p_format_list ); err = AudioObjectGetPropertyData(i_stream_id, &physicalFormatsAddress, 0, NULL, &i_param_size, p_format_list);
if( err != noErr ) if (err != noErr) {
{ msg_Err(p_aout, "could not get the list of streamformats: [%4.4s]", (char *)&err);
msg_Err( p_aout, "could not get the list of streamformats: [%4.4s]", (char *)&err ); free(p_format_list);
free( p_format_list);
p_format_list = NULL; p_format_list = NULL;
return false; return false;
} }
for( int 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].mFormat));
msg_Dbg( p_aout, STREAM_FORMAT_MSG( "supported format: ", p_format_list[i].mFormat ) );
if( p_format_list[i].mFormat.mFormatID == 'IAC3' || if (p_format_list[i].mFormat.mFormatID == 'IAC3' ||
p_format_list[i].mFormat.mFormatID == 'iac3' || p_format_list[i].mFormat.mFormatID == 'iac3' ||
p_format_list[i].mFormat.mFormatID == kAudioFormat60958AC3 || p_format_list[i].mFormat.mFormatID == kAudioFormat60958AC3 ||
p_format_list[i].mFormat.mFormatID == kAudioFormatAC3 ) p_format_list[i].mFormat.mFormatID == kAudioFormatAC3)
b_return = true; b_return = true;
} }
free( p_format_list ); free(p_format_list);
return b_return; return b_return;
} }
/***************************************************************************** /*****************************************************************************
* AudioStreamChangeFormat: Change i_stream_id to change_format * AudioStreamChangeFormat: Change i_stream_id to change_format
*****************************************************************************/ *****************************************************************************/
static int AudioStreamChangeFormat( audio_output_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; OSStatus err = noErr;
UInt32 i_param_size = 0; UInt32 i_param_size = 0;
...@@ -1159,27 +1090,25 @@ static int AudioStreamChangeFormat( audio_output_t *p_aout, AudioStreamID i_stre ...@@ -1159,27 +1090,25 @@ static int AudioStreamChangeFormat( audio_output_t *p_aout, AudioStreamID i_stre
struct { vlc_mutex_t lock; vlc_cond_t cond; } w; struct { vlc_mutex_t lock; vlc_cond_t cond; } w;
msg_Dbg( p_aout, STREAM_FORMAT_MSG( "setting stream format: ", change_format ) ); msg_Dbg(p_aout, STREAM_FORMAT_MSG("setting stream format: ", change_format));
/* Condition because SetProperty is asynchronious */ /* Condition because SetProperty is asynchronious */
vlc_cond_init( &w.cond ); vlc_cond_init(&w.cond);
vlc_mutex_init( &w.lock ); vlc_mutex_init(&w.lock);
vlc_mutex_lock( &w.lock ); vlc_mutex_lock(&w.lock);
/* Install the callback */ /* Install the callback */
err = AudioObjectAddPropertyListener( i_stream_id, &physicalFormatAddress, StreamListener, (void *)&w ); err = AudioObjectAddPropertyListener(i_stream_id, &physicalFormatAddress, StreamListener, (void *)&w);
if( err != noErr ) if (err != noErr) {
{ msg_Err(p_aout, "AudioObjectAddPropertyListener for kAudioStreamPropertyPhysicalFormat failed: [%4.4s]", (char *)&err);
msg_Err( p_aout, "AudioObjectAddPropertyListener for kAudioStreamPropertyPhysicalFormat failed: [%4.4s]", (char *)&err );
return false; return false;
} }
/* change the format */ /* change the format */
err = AudioObjectSetPropertyData( i_stream_id, &physicalFormatAddress, 0, NULL, sizeof( AudioStreamBasicDescription ), err = AudioObjectSetPropertyData(i_stream_id, &physicalFormatAddress, 0, NULL, sizeof(AudioStreamBasicDescription),
&change_format ); &change_format);
if( err != noErr ) if (err != noErr) {
{ msg_Err(p_aout, "could not set the stream format: [%4.4s]", (char *)&err);
msg_Err( p_aout, "could not set the stream format: [%4.4s]", (char *)&err );
return false; return false;
} }
...@@ -1187,24 +1116,20 @@ static int AudioStreamChangeFormat( audio_output_t *p_aout, AudioStreamID i_stre ...@@ -1187,24 +1116,20 @@ static int AudioStreamChangeFormat( audio_output_t *p_aout, AudioStreamID i_stre
* it is also not atomic in its behaviour. * it is also not atomic in its behaviour.
* Therefore we check 5 times before we really give up. * Therefore we check 5 times before we really give up.
* FIXME: failing isn't actually implemented yet. */ * FIXME: failing isn't actually implemented yet. */
for( int i = 0; i < 5; i++ ) for (int i = 0; i < 5; i++) {
{
AudioStreamBasicDescription actual_format; AudioStreamBasicDescription actual_format;
mtime_t timeout = mdate() + 500000; mtime_t timeout = mdate() + 500000;
if( vlc_cond_timedwait( &w.cond, &w.lock, timeout ) ) if (vlc_cond_timedwait(&w.cond, &w.lock, timeout))
{ msg_Dbg(p_aout, "reached timeout");
msg_Dbg( p_aout, "reached timeout" );
}
i_param_size = sizeof( AudioStreamBasicDescription ); i_param_size = sizeof(AudioStreamBasicDescription);
err = AudioObjectGetPropertyData( i_stream_id, &physicalFormatAddress, 0, NULL, &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 ) ); msg_Dbg(p_aout, STREAM_FORMAT_MSG("actual format in use: ", actual_format));
if( actual_format.mSampleRate == change_format.mSampleRate && if (actual_format.mSampleRate == change_format.mSampleRate &&
actual_format.mFormatID == change_format.mFormatID && actual_format.mFormatID == change_format.mFormatID &&
actual_format.mFramesPerPacket == change_format.mFramesPerPacket ) actual_format.mFramesPerPacket == change_format.mFramesPerPacket) {
{
/* The right format is now active */ /* The right format is now active */
break; break;
} }
...@@ -1212,17 +1137,16 @@ static int AudioStreamChangeFormat( audio_output_t *p_aout, AudioStreamID i_stre ...@@ -1212,17 +1137,16 @@ static int AudioStreamChangeFormat( audio_output_t *p_aout, AudioStreamID i_stre
} }
/* Removing the property listener */ /* Removing the property listener */
err = AudioObjectRemovePropertyListener( i_stream_id, &physicalFormatAddress, StreamListener, (void *)&w ); err = AudioObjectRemovePropertyListener(i_stream_id, &physicalFormatAddress, StreamListener, (void *)&w);
if( err != noErr ) if (err != noErr) {
{ msg_Err(p_aout, "AudioStreamRemovePropertyListener failed: [%4.4s]", (char *)&err);
msg_Err( p_aout, "AudioStreamRemovePropertyListener failed: [%4.4s]", (char *)&err );
return false; return false;
} }
/* Destroy the lock and condition */ /* Destroy the lock and condition */
vlc_mutex_unlock( &w.lock ); vlc_mutex_unlock(&w.lock);
vlc_mutex_destroy( &w.lock ); vlc_mutex_destroy(&w.lock);
vlc_cond_destroy( &w.cond ); vlc_cond_destroy(&w.cond);
return true; return true;
} }
...@@ -1233,12 +1157,12 @@ static int AudioStreamChangeFormat( audio_output_t *p_aout, AudioStreamID i_stre ...@@ -1233,12 +1157,12 @@ static int AudioStreamChangeFormat( audio_output_t *p_aout, AudioStreamID i_stre
* Don't print anything during normal playback, calling blocking function from * Don't print anything during normal playback, calling blocking function from
* this callback is not allowed. * this callback is not allowed.
*****************************************************************************/ *****************************************************************************/
static OSStatus RenderCallbackAnalog( vlc_object_t *_p_aout, static OSStatus RenderCallbackAnalog(vlc_object_t *_p_aout,
AudioUnitRenderActionFlags *ioActionFlags, AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp, const AudioTimeStamp *inTimeStamp,
unsigned int inBusNumber, unsigned int inBusNumber,
unsigned int inNumberFrames, unsigned int inNumberFrames,
AudioBufferList *ioData ) AudioBufferList *ioData)
{ {
AudioTimeStamp host_time; AudioTimeStamp host_time;
mtime_t current_date = 0; mtime_t current_date = 0;
...@@ -1252,91 +1176,83 @@ static OSStatus RenderCallbackAnalog( vlc_object_t *_p_aout, ...@@ -1252,91 +1176,83 @@ static OSStatus RenderCallbackAnalog( vlc_object_t *_p_aout,
VLC_UNUSED(inNumberFrames); VLC_UNUSED(inNumberFrames);
host_time.mFlags = kAudioTimeStampHostTimeValid; host_time.mFlags = kAudioTimeStampHostTimeValid;
AudioDeviceTranslateTime( p_sys->i_selected_dev, inTimeStamp, &host_time ); AudioDeviceTranslateTime(p_sys->i_selected_dev, inTimeStamp, &host_time);
/* Check for the difference between the Device clock and mdate */ /* Check for the difference between the Device clock and mdate */
p_sys->clock_diff = - (mtime_t) p_sys->clock_diff = - (mtime_t)
AudioConvertHostTimeToNanos( AudioGetCurrentHostTime() ) / 1000; AudioConvertHostTimeToNanos(AudioGetCurrentHostTime()) / 1000;
p_sys->clock_diff += mdate(); p_sys->clock_diff += mdate();
current_date = p_sys->clock_diff + current_date = p_sys->clock_diff +
AudioConvertHostTimeToNanos( host_time.mHostTime ) / 1000; AudioConvertHostTimeToNanos(host_time.mHostTime) / 1000;
//- ((mtime_t) 1000000 / p_aout->format.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 ) if (ioData == NULL || ioData->mNumberBuffers < 1) {
{ msg_Err(p_aout, "no iodata or buffers");
msg_Err( p_aout, "no iodata or buffers");
return 0; return 0;
} }
if( ioData->mNumberBuffers > 1 ) if (ioData->mNumberBuffers > 1)
msg_Err( p_aout, "well this is weird. seems like there is more than one buffer..." ); msg_Err(p_aout, "well this is weird. seems like there is more than one buffer...");
if( p_sys->i_total_bytes > 0 ) 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);
i_mData_bytes = __MIN( p_sys->i_total_bytes - p_sys->i_read_bytes, ioData->mBuffers[0].mDataByteSize ); memcpy(ioData->mBuffers[0].mData,
memcpy( ioData->mBuffers[0].mData,
&p_sys->p_remainder_buffer[p_sys->i_read_bytes], &p_sys->p_remainder_buffer[p_sys->i_read_bytes],
i_mData_bytes ); i_mData_bytes);
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->format.i_rate ) * 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 (i_mData_bytes / 4 / aout_FormatNbChannels(&p_aout->format)); // 4 is fl32 specific
if( p_sys->i_read_bytes >= p_sys->i_total_bytes ) if (p_sys->i_read_bytes >= p_sys->i_total_bytes)
p_sys->i_read_bytes = p_sys->i_total_bytes = 0; p_sys->i_read_bytes = p_sys->i_total_bytes = 0;
} }
while( i_mData_bytes < ioData->mBuffers[0].mDataByteSize ) while(i_mData_bytes < ioData->mBuffers[0].mDataByteSize) {
{
/* We don't have enough data yet */ /* We don't have enough data yet */
block_t * p_buffer; block_t * p_buffer;
p_buffer = aout_PacketNext( p_aout, current_date ); p_buffer = aout_PacketNext(p_aout, current_date);
if( p_buffer != NULL ) if (p_buffer != NULL)
{ {
uint32_t i_second_mData_bytes = __MIN( p_buffer->i_buffer, 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);
memcpy( (uint8_t *)ioData->mBuffers[0].mData + i_mData_bytes, memcpy((uint8_t *)ioData->mBuffers[0].mData + i_mData_bytes,
p_buffer->p_buffer, i_second_mData_bytes ); p_buffer->p_buffer, i_second_mData_bytes);
i_mData_bytes += i_second_mData_bytes; i_mData_bytes += i_second_mData_bytes;
if( i_mData_bytes >= ioData->mBuffers[0].mDataByteSize ) if (i_mData_bytes >= ioData->mBuffers[0].mDataByteSize)
{ {
p_sys->i_total_bytes = p_buffer->i_buffer - i_second_mData_bytes; p_sys->i_total_bytes = p_buffer->i_buffer - i_second_mData_bytes;
memcpy( p_sys->p_remainder_buffer, memcpy(p_sys->p_remainder_buffer,
&p_buffer->p_buffer[i_second_mData_bytes], &p_buffer->p_buffer[i_second_mData_bytes],
p_sys->i_total_bytes ); p_sys->i_total_bytes);
block_Release( p_buffer ); block_Release(p_buffer);
break; break;
} } else
else
{
/* update current_date */ /* update current_date */
current_date += (mtime_t) ( (mtime_t) 1000000 / p_aout->format.i_rate ) * 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 (i_second_mData_bytes / 4 / aout_FormatNbChannels(&p_aout->format)); // 4 is fl32 specific
} block_Release(p_buffer);
block_Release( p_buffer ); } else {
} memset((uint8_t *)ioData->mBuffers[0].mData +i_mData_bytes,
else 0,ioData->mBuffers[0].mDataByteSize - i_mData_bytes);
{
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; i_mData_bytes += ioData->mBuffers[0].mDataByteSize - i_mData_bytes;
} }
} }
return( noErr ); return noErr;
} }
/***************************************************************************** /*****************************************************************************
* RenderCallbackSPDIF: callback for SPDIF audio output * RenderCallbackSPDIF: callback for SPDIF audio output
*****************************************************************************/ *****************************************************************************/
static OSStatus RenderCallbackSPDIF( AudioDeviceID inDevice, static OSStatus RenderCallbackSPDIF (AudioDeviceID inDevice,
const AudioTimeStamp * inNow, const AudioTimeStamp * inNow,
const void * inInputData, const void * inInputData,
const AudioTimeStamp * inInputTime, const AudioTimeStamp * inInputTime,
AudioBufferList * outOutputData, AudioBufferList * outOutputData,
const AudioTimeStamp * inOutputTime, const AudioTimeStamp * inOutputTime,
void * threadGlobals ) void * threadGlobals)
{ {
block_t * p_buffer; block_t * p_buffer;
mtime_t current_date; mtime_t current_date;
...@@ -1350,126 +1266,117 @@ static OSStatus RenderCallbackSPDIF( AudioDeviceID inDevice, ...@@ -1350,126 +1266,117 @@ static OSStatus RenderCallbackSPDIF( AudioDeviceID inDevice,
/* Check for the difference between the Device clock and mdate */ /* Check for the difference between the Device clock and mdate */
p_sys->clock_diff = - (mtime_t) p_sys->clock_diff = - (mtime_t)
AudioConvertHostTimeToNanos( inNow->mHostTime ) / 1000; AudioConvertHostTimeToNanos(inNow->mHostTime) / 1000;
p_sys->clock_diff += mdate(); p_sys->clock_diff += mdate();
current_date = p_sys->clock_diff + current_date = p_sys->clock_diff +
AudioConvertHostTimeToNanos( inOutputTime->mHostTime ) / 1000; AudioConvertHostTimeToNanos(inOutputTime->mHostTime) / 1000;
//- ((mtime_t) 1000000 / p_aout->format.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_PacketNext( p_aout, current_date ); p_buffer = aout_PacketNext(p_aout, current_date);
#define BUFFER outOutputData->mBuffers[p_sys->i_stream_index] #define BUFFER outOutputData->mBuffers[p_sys->i_stream_index]
if( p_buffer != NULL ) if (p_buffer != NULL) {
{ if ((int)BUFFER.mDataByteSize != (int)p_buffer->i_buffer)
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);
msg_Warn( p_aout, "bytesize: %d nb_bytes: %d", (int)BUFFER.mDataByteSize, (int)p_buffer->i_buffer );
/* move data into output data buffer */ /* move data into output data buffer */
memcpy( BUFFER.mData, p_buffer->p_buffer, p_buffer->i_buffer ); memcpy(BUFFER.mData, p_buffer->p_buffer, p_buffer->i_buffer);
block_Release( p_buffer ); block_Release(p_buffer);
} }
else else
{ memset(BUFFER.mData, 0, BUFFER.mDataByteSize);
memset( BUFFER.mData, 0, BUFFER.mDataByteSize );
}
#undef BUFFER #undef BUFFER
return( noErr ); return noErr;
} }
/***************************************************************************** /*****************************************************************************
* HardwareListener: Warns us of changes in the list of registered devices * HardwareListener: Warns us of changes in the list of registered devices
*****************************************************************************/ *****************************************************************************/
static OSStatus HardwareListener( AudioObjectID inObjectID, UInt32 inNumberAddresses, const AudioObjectPropertyAddress inAddresses[], void*inClientData) static OSStatus HardwareListener(AudioObjectID inObjectID, UInt32 inNumberAddresses, const AudioObjectPropertyAddress inAddresses[], void*inClientData)
{ {
OSStatus err = noErr; OSStatus err = noErr;
audio_output_t *p_aout = (audio_output_t *)inClientData; audio_output_t *p_aout = (audio_output_t *)inClientData;
VLC_UNUSED(inObjectID); VLC_UNUSED(inObjectID);
for ( unsigned int i = 0; i < inNumberAddresses; i++ ) for (unsigned int i = 0; i < inNumberAddresses; i++) {
{ if (inAddresses[i].mSelector == kAudioHardwarePropertyDevices) {
if( inAddresses[i].mSelector == kAudioHardwarePropertyDevices )
{
/* something changed in the list of devices */ /* something changed in the list of devices */
/* We trigger the audio-device's aout_ChannelsRestart callback */ /* We trigger the audio-device's aout_ChannelsRestart callback */
msg_Warn( p_aout, "audio device configuration changed, resetting cache" ); msg_Warn(p_aout, "audio device configuration changed, resetting cache");
var_TriggerCallback( p_aout, "audio-device" ); var_TriggerCallback(p_aout, "audio-device");
var_Destroy( p_aout, "audio-device" ); var_Destroy(p_aout, "audio-device");
} } else if (inAddresses[i].mSelector == kAudioDevicePropertyDeviceIsAlive) {
else if( inAddresses[i].mSelector == kAudioDevicePropertyDeviceIsAlive ) msg_Warn(p_aout, "audio device died, resetting aout");
{ var_TriggerCallback(p_aout, "audio-device");
msg_Warn( p_aout, "audio device died, resetting aout" ); var_Destroy(p_aout, "audio-device");
var_TriggerCallback( p_aout, "audio-device" );
var_Destroy( p_aout, "audio-device" );
} }
} }
return( err ); return err;
} }
/***************************************************************************** /*****************************************************************************
* StreamListener * StreamListener
*****************************************************************************/ *****************************************************************************/
static OSStatus StreamListener( AudioObjectID inObjectID, UInt32 inNumberAddresses, const AudioObjectPropertyAddress inAddresses[], void*inClientData) static OSStatus StreamListener(AudioObjectID inObjectID, UInt32 inNumberAddresses, const AudioObjectPropertyAddress inAddresses[], void*inClientData)
{ {
OSStatus err = noErr; OSStatus err = noErr;
struct { vlc_mutex_t lock; vlc_cond_t cond; } * w = inClientData; struct { vlc_mutex_t lock; vlc_cond_t cond; } * w = inClientData;
VLC_UNUSED(inObjectID); VLC_UNUSED(inObjectID);
for( unsigned int i = 0; i < inNumberAddresses; i++ ) for (unsigned int i = 0; i < inNumberAddresses; i++) {
{ if (inAddresses[i].mSelector == kAudioStreamPropertyPhysicalFormat) {
if( inAddresses[i].mSelector == kAudioStreamPropertyPhysicalFormat ) vlc_mutex_lock(&w->lock);
{ vlc_cond_signal(&w->cond);
vlc_mutex_lock( &w->lock ); vlc_mutex_unlock(&w->lock);
vlc_cond_signal( &w->cond );
vlc_mutex_unlock( &w->lock );
break; break;
} }
} }
return( err ); return err;
} }
/***************************************************************************** /*****************************************************************************
* AudioDeviceCallback: Callback triggered when the audio-device variable is changed * AudioDeviceCallback: Callback triggered when the audio-device variable is changed
*****************************************************************************/ *****************************************************************************/
static int AudioDeviceCallback( vlc_object_t *p_this, const char *psz_variable, static int AudioDeviceCallback(vlc_object_t *p_this, const char *psz_variable,
vlc_value_t old_val, vlc_value_t new_val, void *param ) vlc_value_t old_val, vlc_value_t new_val, void *param)
{ {
audio_output_t *p_aout = (audio_output_t *)p_this; audio_output_t *p_aout = (audio_output_t *)p_this;
var_Set( p_aout->p_libvlc, "macosx-audio-device", new_val ); var_Set(p_aout->p_libvlc, "macosx-audio-device", new_val);
msg_Dbg( p_aout, "Set Device: %#"PRIx64, 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 ); return aout_ChannelsRestart(p_this, psz_variable, old_val, new_val, param);
} }
/***************************************************************************** /*****************************************************************************
* VolumeSet: Implements pf_volume_set(). Update the CoreAudio AU volume immediately. * VolumeSet: Implements pf_volume_set(). Update the CoreAudio AU volume immediately.
*****************************************************************************/ *****************************************************************************/
static int VolumeSet( audio_output_t * p_aout, float volume ) static int VolumeSet(audio_output_t * p_aout, float volume)
{ {
struct aout_sys_t *p_sys = p_aout->sys; struct aout_sys_t *p_sys = p_aout->sys;
OSStatus ostatus; OSStatus ostatus;
aout_VolumeReport( p_aout, volume ); aout_VolumeReport(p_aout, volume);
volume = volume * volume * volume; // cubic mapping from output.c volume = volume * volume * volume; // cubic mapping from output.c
/* Set volume for output unit */ /* Set volume for output unit */
ostatus = AudioUnitSetParameter( p_sys->au_unit, ostatus = AudioUnitSetParameter(p_sys->au_unit,
kHALOutputParam_Volume, kHALOutputParam_Volume,
kAudioUnitScope_Global, kAudioUnitScope_Global,
0, 0,
volume, volume,
0 ); 0);
return ostatus; return ostatus;
} }
static int MuteSet( audio_output_t * p_aout, bool mute ) static int MuteSet(audio_output_t * p_aout, bool mute)
{ {
aout_MuteReport( p_aout, mute ); aout_MuteReport(p_aout, mute);
return 0; return 0;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment