]> git.sesse.net Git - vlc/blobdiff - modules/audio_output/auhal.c
ASF: help stupid compiler
[vlc] / modules / audio_output / auhal.c
index 6e12887176dece6c5f5cce9a13f65edf8c2bb90f..999771a3b9f0c1f1becdf7423e2d26048d88a58b 100644 (file)
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  *****************************************************************************/
 
 /*****************************************************************************
  * Preamble
  *****************************************************************************/
+
 #ifdef HAVE_CONFIG_H
 # include "config.h"
 #endif
 
-#include <unistd.h>
-
 #include <vlc_common.h>
 #include <vlc_plugin.h>
-#include <vlc_dialog.h>
-#include <vlc_aout.h>
-
-#include <CoreAudio/CoreAudio.h>
-#include <AudioUnit/AudioUnit.h>
-#include <AudioToolbox/AudioFormat.h>
+#include <vlc_dialog.h>                   // dialog_Fatal
+#include <vlc_aout.h>                     // aout_*
 
+#include <AudioUnit/AudioUnit.h>          // AudioUnit
+#include <CoreAudio/CoreAudio.h>      // AudioDeviceID
+#include <AudioToolbox/AudioFormat.h>     // AudioFormatGetProperty
 #include <CoreServices/CoreServices.h>
 
 #ifndef verify_noerr
-#define verify_noerr(a) assert((a) == noErr)
+# define verify_noerr(a) assert((a) == noErr)
 #endif
 
 #define STREAM_FORMAT_MSG( pre, sfm ) \
-    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: [%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
+    pre "[%f][%4.4s][%u][%u][%u][%u][%u][%u]", \
+    sfm.mSampleRate, (char *)&sfm.mFormatID, \
+    (unsigned int)sfm.mFormatFlags, (unsigned int)sfm.mBytesPerPacket, \
+    (unsigned int)sfm.mFramesPerPacket, (unsigned int)sfm.mBytesPerFrame, \
+    (unsigned int)sfm.mChannelsPerFrame, (unsigned int)sfm.mBitsPerChannel
 
 #define FRAMESIZE 2048
 #define BUFSIZE (FRAMESIZE * 8) * 8
 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 */
-    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 */
+    AudioDeviceID               i_default_dev;       /* DeviceID of defaultOutputDevice */
+    AudioDeviceID               i_selected_dev;      /* DeviceID of the selected device */
+    AudioDeviceIOProcID         i_procID;            /* DeviceID of current device */
+    UInt32                      i_devices;           /* Number of CoreAudio Devices */
+    bool                        b_digital;           /* Are we running in digital mode? */
+    mtime_t                     clock_diff;          /* Difference between VLC clock and Device clock */
 
     /* AUHAL specific */
-    Component                   au_component;   /* The Audiocomponent we use */
-    AudioUnit                   au_unit;        /* The AudioUnit we use */
+    Component                   au_component;        /* The Audiocomponent we use */
+    AudioUnit                   au_unit;             /* The AudioUnit we use */
     uint8_t                     p_remainder_buffer[BUFSIZE];
     uint32_t                    i_read_bytes;
     uint32_t                    i_total_bytes;
 
     /* CoreAudio SPDIF mode specific */
-    pid_t                       i_hog_pid;      /* The keep the pid of our hog status */
-    AudioStreamID               i_stream_id;    /* The StreamID that has a cac3 streamformat */
-    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 */
-    bool                        b_revert;       /* Wether we need to revert the stream format */
-    bool                        b_changed_mixing;/* Wether we need to set the mixing mode back */
+    pid_t                       i_hog_pid;           /* The keep the pid of our hog status */
+    AudioStreamID               i_stream_id;         /* The StreamID that has a cac3 streamformat */
+    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 */
+    bool                        b_revert;            /* Wether we need to revert the stream format */
+    bool                        b_changed_mixing;    /* Wether we need to set the mixing mode back */
 };
 
 /*****************************************************************************
@@ -113,7 +103,6 @@ static int      OpenAnalog              ( audio_output_t * );
 static int      OpenSPDIF               ( audio_output_t * );
 static void     Close                   ( vlc_object_t * );
 
-static void     Play                    ( audio_output_t *, block_t * );
 static void     Probe                   ( audio_output_t * );
 
 static int      AudioDeviceHasOutput    ( AudioDeviceID );
@@ -131,7 +120,6 @@ static int      AudioDeviceCallback     ( vlc_object_t *, const char *,
                                           vlc_value_t, vlc_value_t, void * );
 
 
-
 /*****************************************************************************
  * Module descriptor
  *****************************************************************************/
@@ -159,7 +147,7 @@ static int Open( vlc_object_t * p_this )
     UInt32                  i_param_size = 0;
     struct aout_sys_t       *p_sys = NULL;
     vlc_value_t             val;
-    audio_output_t         *p_aout = (audio_output_t *)p_this;
+    audio_output_t          *p_aout = (audio_output_t *)p_this;
 
     /* Use int here, to match kAudioDevicePropertyDeviceIsAlive
      * property size */
@@ -174,7 +162,6 @@ static int Open( vlc_object_t * p_this )
     p_sys->i_default_dev = 0;
     p_sys->i_selected_dev = 0;
     p_sys->i_devices = 0;
-    p_sys->b_supports_digital = false;
     p_sys->b_digital = false;
     p_sys->au_component = NULL;
     p_sys->au_unit = NULL;
@@ -214,11 +201,9 @@ 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 ) ? true : false;
-    if( p_sys->b_supports_digital )
+    bool b_supports_digital = ( val.i_int & AOUT_VAR_SPDIF_FLAG );
+    if( 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 */
@@ -231,7 +216,8 @@ static int Open( vlc_object_t * p_this )
     if( err != noErr )
     {
         /* 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 );
+        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;
     }
 
@@ -264,7 +250,7 @@ static int Open( vlc_object_t * p_this )
     }
 
     /* Check for Digital mode or Analog output mode */
-    if( AOUT_FMT_NON_LINEAR( &p_aout->format ) && p_sys->b_supports_digital )
+    if( AOUT_FMT_SPDIF( &p_aout->format ) && b_supports_digital )
     {
         if( OpenSPDIF( p_aout ) )
         {
@@ -633,23 +619,27 @@ static int OpenSPDIF( audio_output_t * p_aout )
         return false;
     }
 
-    /* Set mixable to false if we are allowed to */
-    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 );
+    AudioObjectPropertyAddress audioDeviceSupportsMixingAddress = { kAudioDevicePropertySupportsMixing , kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
 
-    if( !err && b_writeable )
+    if (AudioObjectHasProperty(p_sys->i_selected_dev, &audioDeviceSupportsMixingAddress))
     {
-        b_mix = 0;
-        err = AudioObjectSetPropertyData( p_sys->i_selected_dev, &audioDeviceSupportsMixingAddress, 0, NULL, i_param_size, &b_mix );
-        p_sys->b_changed_mixing = true;
-    }
+        /* Set mixable to false if we are allowed to */
+        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 );
 
-    if( err != noErr )
-    {
-        msg_Err( p_aout, "failed to set mixmode: [%4.4s]", (char *)&err );
-        return false;
+        if( err == noErr && b_writeable )
+        {
+            b_mix = 0;
+            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 false;
+        }
     }
 
     /* Get a list of all the streams on this device */
@@ -676,18 +666,18 @@ static int OpenSPDIF( audio_output_t * p_aout )
     }
 
     AudioObjectPropertyAddress physicalFormatsAddress = { kAudioStreamPropertyAvailablePhysicalFormats, kAudioObjectPropertyScopeGlobal, 0 };
-    for( int 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 */
         AudioStreamRangedDescription *p_format_list = NULL;
-        int                         i_formats = 0;
-        bool                  b_digital = false;
+        int                          i_formats = 0;
+        bool                         b_digital = false;
 
         /* Retrieve all the stream formats supported by each output stream */
         err = AudioObjectGetPropertyDataSize( p_streams[i], &physicalFormatsAddress, 0, NULL, &i_param_size );
         if( err != noErr )
         {
-            msg_Err( p_aout, "OpenSPDIF: could not get number of streamformats: [%s] (%i)", (char *)&err, err );
+            msg_Err( p_aout, "OpenSPDIF: could not get number of streamformats: [%s] (%i)", (char *)&err, (int32_t)err );
             continue;
         }
 
@@ -708,7 +698,9 @@ static int OpenSPDIF( audio_output_t * p_aout )
         for( int j = 0; j < i_formats; j++ )
         {
             if( p_format_list[j].mFormat.mFormatID == 'IAC3' ||
-                  p_format_list[j].mFormat.mFormatID == kAudioFormat60958AC3 )
+               p_format_list[j].mFormat.mFormatID == 'iac3' ||
+               p_format_list[j].mFormat.mFormatID == kAudioFormat60958AC3 ||
+               p_format_list[j].mFormat.mFormatID == kAudioFormatAC3 )
             {
                 b_digital = true;
                 break;
@@ -727,9 +719,10 @@ static int OpenSPDIF( audio_output_t * p_aout )
 
             if( !p_sys->b_revert )
             {
+                AudioObjectPropertyAddress currentPhysicalFormatAddress = { kAudioStreamPropertyPhysicalFormat, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
                 /* Retrieve the original format of this stream first if not done so already */
                 i_param_size = sizeof( p_sys->sfmt_revert );
-                err = AudioObjectGetPropertyData( p_sys->i_stream_id, &physicalFormatsAddress, 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 )
                 {
                     msg_Err( p_aout, "could not retrieve the original streamformat: [%4.4s]", (char *)&err );
@@ -741,7 +734,9 @@ static int OpenSPDIF( audio_output_t * p_aout )
             for( int j = 0; j < i_formats; j++ )
             {
                 if( p_format_list[j].mFormat.mFormatID == 'IAC3' ||
-                      p_format_list[j].mFormat.mFormatID == kAudioFormat60958AC3 )
+                   p_format_list[j].mFormat.mFormatID == 'iac3' ||
+                   p_format_list[j].mFormat.mFormatID == kAudioFormat60958AC3 ||
+                   p_format_list[j].mFormat.mFormatID == kAudioFormatAC3 )
                 {
                     if( p_format_list[j].mFormat.mSampleRate == p_aout->format.i_rate )
                     {
@@ -868,13 +863,13 @@ static void Close( vlc_object_t * p_this )
         if( p_sys->b_changed_mixing && p_sys->sfmt_revert.mFormatID != kAudioFormat60958AC3 )
         {
             int b_mix;
-            Boolean b_writeable;
+            Boolean b_writeable = false;
             /* Revert mixable to true if we are allowed to */
             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 );
 
-            if( !err && b_writeable )
+            if( err == noErr && b_writeable )
             {
                 msg_Dbg( p_aout, "mixable is: %d", b_mix );
                 b_mix = 1;
@@ -907,6 +902,8 @@ static void Close( vlc_object_t * p_this )
         if( err != noErr ) msg_Err( p_aout, "Could not release hogmode: [%4.4s]", (char *)&err );
     }
 
+    var_DelCallback( p_aout, "audio-device", AudioDeviceCallback, NULL );
+
     aout_PacketDestroy( p_aout );
     free( p_sys );
 }
@@ -940,7 +937,7 @@ static void Probe( audio_output_t * p_aout )
         msg_Err( p_aout, "No audio output devices were found." );
         goto error;
     }
-    msg_Dbg( p_aout, "found %u audio device(s)", p_sys->i_devices );
+    msg_Dbg( p_aout, "found %u audio device(s)", (unsigned)p_sys->i_devices );
 
     /* Allocate DeviceID array */
     p_devices = (AudioDeviceID*)malloc( sizeof(AudioDeviceID) * p_sys->i_devices );
@@ -986,7 +983,7 @@ static void Probe( audio_output_t * p_aout )
         err = AudioObjectGetPropertyData( p_devices[i], &deviceNameAddress, 0, NULL, &i_param_size, psz_name );
         if( err ) goto error;
 
-        msg_Dbg( p_aout, "DevID: %u DevName: %s", p_devices[i], psz_name );
+        msg_Dbg( p_aout, "DevID: %u DevName: %s", (unsigned)p_devices[i], psz_name );
 
         if( !AudioDeviceHasOutput( p_devices[i]) )
         {
@@ -1083,7 +1080,7 @@ static int AudioDeviceSupportsDigital( audio_output_t *p_aout, AudioDeviceID i_d
     err = AudioObjectGetPropertyDataSize( i_dev_id, &streamsAddress, 0, NULL, &i_param_size );
     if( err != noErr )
     {
-        msg_Err( p_aout, "could not get number of streams: [%s] (%i)", (char *)&err, err );
+        msg_Err( p_aout, "could not get number of streams: [%s] (%i)", (char *)&err, (int32_t)err );
         return false;
     }
 
@@ -1125,7 +1122,7 @@ static int AudioStreamSupportsDigital( audio_output_t *p_aout, AudioStreamID i_s
     err = AudioObjectGetPropertyDataSize( i_stream_id, &physicalFormatsAddress, 0, NULL, &i_param_size );
     if( err != noErr )
     {
-        msg_Err( p_aout, "could not get number of streamformats: [%s] (%i)", (char *)&err, err );
+        msg_Err( p_aout, "could not get number of streamformats: [%s] (%i)", (char *)&err, (int32_t)err );
         return false;
     }
 
@@ -1150,7 +1147,9 @@ static int AudioStreamSupportsDigital( audio_output_t *p_aout, AudioStreamID i_s
         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 )
+           p_format_list[i].mFormat.mFormatID == 'iac3' ||
+           p_format_list[i].mFormat.mFormatID == kAudioFormat60958AC3 ||
+           p_format_list[i].mFormat.mFormatID == kAudioFormatAC3 )
         {
             b_return = true;
         }
@@ -1168,7 +1167,7 @@ static int AudioStreamChangeFormat( audio_output_t *p_aout, AudioStreamID i_stre
     OSStatus            err = noErr;
     UInt32              i_param_size = 0;
 
-    AudioObjectPropertyAddress physicalFormatAddress = { kAudioStreamPropertyPhysicalFormat, kAudioDevicePropertyScopeOutput, kAudioObjectPropertyElementMaster };
+    AudioObjectPropertyAddress physicalFormatAddress = { kAudioStreamPropertyPhysicalFormat, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
 
     struct { vlc_mutex_t lock; vlc_cond_t cond; } w;
 
@@ -1225,7 +1224,7 @@ static int AudioStreamChangeFormat( audio_output_t *p_aout, AudioStreamID i_stre
     }
 
     /* Removing the property listener */
-    err = AudioObjectRemovePropertyListener( i_stream_id, &physicalFormatAddress, StreamListener, NULL );
+    err = AudioObjectRemovePropertyListener( i_stream_id, &physicalFormatAddress, StreamListener, (void *)&w );
     if( err != noErr )
     {
         msg_Err( p_aout, "AudioStreamRemovePropertyListener failed: [%4.4s]", (char *)&err );
@@ -1424,13 +1423,14 @@ static OSStatus StreamListener( AudioObjectID inObjectID,  UInt32 inNumberAddres
 
     VLC_UNUSED(inObjectID);
 
-    for ( unsigned int i = 0; i < inNumberAddresses; i++ )
+    for( unsigned int i = 0; i < inNumberAddresses; i++ )
     {
         if( inAddresses[i].mSelector == kAudioStreamPropertyPhysicalFormat )
         {
             vlc_mutex_lock( &w->lock );
             vlc_cond_signal( &w->cond );
             vlc_mutex_unlock( &w->lock );
+            break;
         }
     }
     return( err );