]> git.sesse.net Git - vlc/blobdiff - modules/audio_output/coreaudio.c
* modules/audio_output/portaudio.c: channel reordering patch by Frederic Ruget +...
[vlc] / modules / audio_output / coreaudio.c
index f699c4501acae162b8e8b2f53544702dc8f48452..b2ef49020cd8e2b160f4e115282893dd5b75d759 100644 (file)
@@ -1,8 +1,8 @@
 /*****************************************************************************
  * coreaudio.c: CoreAudio output plugin
  *****************************************************************************
- * Copyright (C) 2002-2003 VideoLAN
- * $Id: coreaudio.c,v 1.7 2003/11/25 21:21:36 hartman Exp $
+ * Copyright (C) 2002-2004 VideoLAN
+ * $Id$
  *
  * Authors: Colin Delacroix <colin@zoy.org>
  *          Jon Lech Johansen <jon-vl@nanocrew.net>
@@ -37,8 +37,6 @@
 
 #include <CoreAudio/CoreAudio.h>
 
-#define A52_FRAME_NB 1536
-
 #define STREAM_FORMAT_MSG( pre, sfm ) \
     pre ": [%ld][%4.4s][%ld][%ld][%ld][%ld][%ld][%ld]", \
     (UInt32)sfm.mSampleRate, (char *)&sfm.mFormatID, \
@@ -157,13 +155,14 @@ struct aout_sys_t
     struct aout_option_t *      p_options;
 
     AudioDeviceID               devid;
+    UInt32                      i_stream_index;
     AudioStreamBasicDescription stream_format;
     UInt32                      b_dev_alive;
 
     vlc_bool_t                  b_revert_sfmt;
     AudioStreamBasicDescription sfmt_revert;
 
-    UInt32                      i_buffer_size;
+    UInt32                      i_bufframe_size;
     mtime_t                     clock_diff;
 };
 
@@ -215,16 +214,15 @@ static OSStatus StreamListener   ( AudioStreamID inStream,
 /*****************************************************************************
  * Module descriptor
  *****************************************************************************/
-#define ADEV_TEXT N_("Audio device")
+#define ADEV_TEXT N_("Audio Device")
 #define ADEV_LONGTEXT N_("Choose a number corresponding to the number of an " \
-    "audio device, as listed in your 'audio device' menu. This device will " \
+    "audio device, as listed in your 'Audio Device' menu. This device will " \
     "then be used by default for audio playback.")
 
 vlc_module_begin();
     set_description( _("CoreAudio output") );
     set_capability( "audio output", 100 );
     set_callbacks( Open, Close );
-    add_category_hint( N_("Audio"), NULL, VLC_FALSE );
     add_integer( "coreaudio-dev", -1, NULL, ADEV_TEXT, ADEV_LONGTEXT, VLC_FALSE ); 
 vlc_module_end();
 
@@ -237,6 +235,8 @@ static int Open( vlc_object_t * p_this )
     UInt32 i_param_size;
     struct aout_sys_t * p_sys;
     aout_instance_t * p_aout = (aout_instance_t *)p_this;
+    struct aout_option_t * p_option;
+    UInt32 i_startingChannel;
 
     /* Allocate structure */
     p_sys = (struct aout_sys_t *)malloc( sizeof( struct aout_sys_t ) );
@@ -276,9 +276,29 @@ static int Open( vlc_object_t * p_this )
         return( VLC_EGENERIC );
     } 
 
+    /* get starting channel for the selected stream */
+    p_option = &p_sys->p_options[p_sys->i_sel_opt];
+
+    i_param_size = sizeof( UInt32 ); 
+    err = AudioStreamGetProperty( p_option->i_sid, 0, 
+                                  kAudioStreamPropertyStartingChannel,
+                                  &i_param_size, &i_startingChannel );
+    if( err != noErr )
+    {
+        msg_Err( p_aout, "failed to get channel number: [%4.4s]", 
+                 (char *)&err );
+        FreeDevice( p_aout );
+        FreeHardwareInfo( p_aout );
+        vlc_mutex_destroy( &p_sys->lock );
+        free( (void *)p_sys );
+        return( VLC_EGENERIC );
+    }
+    
+    msg_Dbg( p_aout, "starting channel: [%ld]", i_startingChannel );
+
     /* Get a description of the stream format */
     i_param_size = sizeof( AudioStreamBasicDescription ); 
-    err = AudioDeviceGetProperty( p_sys->devid, 0, FALSE, 
+    err = AudioDeviceGetProperty( p_sys->devid, i_startingChannel, FALSE, 
                                   kAudioDevicePropertyStreamFormat,
                                   &i_param_size, &p_sys->stream_format );
     if( err != noErr )
@@ -299,14 +319,14 @@ static int Open( vlc_object_t * p_this )
     msg_Dbg( p_aout, STREAM_FORMAT_MSG( "using format",
                                         p_sys->stream_format ) );
 
-    /* Get the buffer size */
-    i_param_size = sizeof( p_sys->i_buffer_size );
-    err = AudioDeviceGetProperty( p_sys->devid, 0, FALSE, 
-                                  kAudioDevicePropertyBufferSize, 
-                                  &i_param_size, &p_sys->i_buffer_size );
+    /* Get the bufframe size */
+    i_param_size = sizeof( p_sys->i_bufframe_size );
+    err = AudioDeviceGetProperty( p_sys->devid, i_startingChannel, FALSE, 
+                                  kAudioDevicePropertyBufferFrameSize, 
+                                  &i_param_size, &p_sys->i_bufframe_size );
     if( err != noErr )
     {
-        msg_Err( p_aout, "failed to get buffer size: [%4.4s]", 
+        msg_Err( p_aout, "failed to get bufframe size: [%4.4s]", 
                  (char *)&err );
         FreeDevice( p_aout );
         FreeHardwareInfo( p_aout );
@@ -315,42 +335,23 @@ static int Open( vlc_object_t * p_this )
         return( VLC_EGENERIC );
     }
 
-    msg_Dbg( p_aout, "device buffer size: [%ld]", p_sys->i_buffer_size );
+    msg_Dbg( p_aout, "device bufframe size: [%ld]", p_sys->i_bufframe_size );
+    msg_Dbg( p_aout, "device buffer index: [%ld]", p_sys->i_stream_index );
 
     /* If we do AC3 over SPDIF, set buffer size to one AC3 frame */
     if( ( p_sys->stream_format.mFormatID == kAudioFormat60958AC3 ||
           p_sys->stream_format.mFormatID == 'IAC3' ) &&
-        p_sys->i_buffer_size != AOUT_SPDIF_SIZE )
+        p_sys->i_bufframe_size != A52_FRAME_NB )
     {
-        p_sys->i_buffer_size = AOUT_SPDIF_SIZE;
-        i_param_size = sizeof( p_sys->i_buffer_size );
-        err = AudioDeviceSetProperty( p_sys->devid, 0, 0, FALSE,
-                                      kAudioDevicePropertyBufferSize,
-                                      i_param_size, &p_sys->i_buffer_size );
-        if( err != noErr )
-        {
-            msg_Err( p_aout, "failed to set buffer size: [%4.4s]", 
-                     (char *)&err );
-            FreeDevice( p_aout );
-            FreeHardwareInfo( p_aout );
-            vlc_mutex_destroy( &p_sys->lock );
-            free( (void *)p_sys );
-            return( VLC_EGENERIC );
-        }
-
-        msg_Dbg( p_aout, "device buffer size set to: [%ld]", 
-                 p_sys->i_buffer_size );
-
-        /* Set buffer frame size */
-        i_param_size = sizeof( p_aout->output.i_nb_samples );
+        p_sys->i_bufframe_size = A52_FRAME_NB;
+        i_param_size = sizeof( p_sys->i_bufframe_size );
         err = AudioDeviceSetProperty( p_sys->devid, 0, 0, FALSE,
                                       kAudioDevicePropertyBufferFrameSize,
-                                      i_param_size,
-                                      &p_aout->output.i_nb_samples );
+                                      i_param_size, &p_sys->i_bufframe_size );
         if( err != noErr )
         {
-            msg_Err( p_aout, "failed to set buffer frame size: [%4.4s]", 
-                     (char *)&err );
+            msg_Err( p_aout, "failed to set bufframe size (%ld): [%4.4s]", 
+                     p_sys->i_bufframe_size, (char *)&err );
             FreeDevice( p_aout );
             FreeHardwareInfo( p_aout );
             vlc_mutex_destroy( &p_sys->lock );
@@ -358,8 +359,8 @@ static int Open( vlc_object_t * p_this )
             return( VLC_EGENERIC );
         }
 
-        msg_Dbg( p_aout, "device buffer frame size set to: [%d]",
-                 p_aout->output.i_nb_samples );
+        msg_Dbg( p_aout, "device bufframe size set to: [%ld]", 
+                 p_sys->i_bufframe_size );
     }
 
     switch( p_sys->stream_format.mFormatID )
@@ -409,8 +410,7 @@ static int Open( vlc_object_t * p_this )
             return( VLC_EGENERIC );
         }
 
-        p_aout->output.i_nb_samples = (int)( p_sys->i_buffer_size /
-                                      p_sys->stream_format.mBytesPerFrame );
+        p_aout->output.i_nb_samples = p_sys->i_bufframe_size;
 
         aout_VolumeSoftInit( p_aout );
         break;
@@ -603,12 +603,12 @@ static OSStatus IOCallback( AudioDeviceID inDevice,
     p_buffer = aout_OutputNextBuffer( p_aout, current_date, B_SPDI );
 #undef B_SPDI
 
+#define BUFFER outOutputData->mBuffers[ p_sys->i_stream_index ]
     if( p_buffer != NULL )
     {
         /* move data into output data buffer */
-        p_aout->p_vlc->pf_memcpy( outOutputData->mBuffers[ 0 ].mData, 
-                                  p_buffer->p_buffer, 
-                                  p_sys->i_buffer_size );
+        p_aout->p_vlc->pf_memcpy( BUFFER.mData,
+                                  p_buffer->p_buffer, p_buffer->i_nb_bytes );
 
         aout_BufferFree( p_buffer );
     }
@@ -616,8 +616,9 @@ static OSStatus IOCallback( AudioDeviceID inDevice,
     {
         if( p_aout->output.output.i_format == VLC_FOURCC('f','l','3','2') )
         {
-            UInt32 i, i_size = p_sys->i_buffer_size / sizeof(float);
-            float * p = (float *)outOutputData->mBuffers[ 0 ].mData;
+            UInt32 i, i_size = p_sys->i_bufframe_size * 
+                               p_sys->stream_format.mChannelsPerFrame;
+            float * p = (float *)BUFFER.mData;
 
             for( i = 0; i < i_size; i++ )
             {
@@ -626,10 +627,10 @@ static OSStatus IOCallback( AudioDeviceID inDevice,
         }
         else
         {
-            memset( outOutputData->mBuffers[ 0 ].mData, 
-                    0, p_sys->i_buffer_size );
+            p_aout->p_vlc->pf_memset( BUFFER.mData, 0, BUFFER.mDataByteSize );
         }
     }
+#undef BUFFER
 
     return( noErr );     
 }
@@ -653,7 +654,7 @@ static int InitHardwareInfo( aout_instance_t * p_aout )
                                         &i_param_size, NULL );
     if( err != noErr )
     {
-        msg_Err( p_aout, "Could not get number of devices: [%4.4s]",
+        msg_Err( p_aout, "could not get number of devices: [%4.4s]",
                  (char *)&err );
         vlc_mutex_unlock( &p_sys->lock );
         return( VLC_EGENERIC );
@@ -684,7 +685,7 @@ static int InitHardwareInfo( aout_instance_t * p_aout )
                                     &i_param_size, (void *)p_devices );
     if( err != noErr )
     {
-        msg_Err( p_aout, "Could not get the device ID's: [%4.4s]",
+        msg_Err( p_aout, "could not get the device ID's: [%4.4s]",
                  (char *)&err );
         free( (void *)p_devices );
         vlc_mutex_unlock( &p_sys->lock );
@@ -696,7 +697,7 @@ static int InitHardwareInfo( aout_instance_t * p_aout )
                                     &i_param_size, (void *)&devid_def );
     if( err != noErr )
     {
-        msg_Err( p_aout, "Could not get default audio device: [%4.4s]",
+        msg_Err( p_aout, "could not get default audio device: [%4.4s]",
                  (char *)&err );
         free( (void *)p_devices );
         vlc_mutex_unlock( &p_sys->lock );
@@ -772,7 +773,7 @@ static int InitDeviceInfo( UInt32 i_dev, aout_instance_t * p_aout )
                                       &i_param_size, NULL ); 
     if( err != noErr )
     {
-        msg_Err( p_aout, "Could not get size of devicename: [%4.4s]",
+        msg_Err( p_aout, "could not get size of devicename: [%4.4s]",
                  (char *)&err ); 
         return( VLC_EGENERIC );
     }
@@ -791,7 +792,7 @@ static int InitDeviceInfo( UInt32 i_dev, aout_instance_t * p_aout )
                                   &i_param_size, p_dev->psz_device_name ); 
     if( err != noErr )
     {
-        msg_Err( p_aout, "Could not get devicename: [%4.4s]",
+        msg_Err( p_aout, "could not get devicename: [%4.4s]",
                  (char *)&err );
         free( (void *)p_dev->psz_device_name );
         return( VLC_EGENERIC );
@@ -805,7 +806,7 @@ static int InitDeviceInfo( UInt32 i_dev, aout_instance_t * p_aout )
                                       &i_param_size, NULL );
     if( err != noErr )
     {
-        msg_Err( p_aout, "Could not get size of stream configuration: [%4.4s]",
+        msg_Err( p_aout, "could not get size of stream configuration: [%4.4s]",
                  (char *)&err );
         free( (void *)p_dev->psz_device_name );
         return( VLC_EGENERIC );
@@ -824,7 +825,7 @@ static int InitDeviceInfo( UInt32 i_dev, aout_instance_t * p_aout )
                                   &i_param_size, p_buffer_list );
     if( err != noErr )
     {
-        msg_Err( p_aout, "Could not get stream configuration: [%4.4s]",
+        msg_Err( p_aout, "could not get stream configuration: [%4.4s]",
                  (char *)&err );
         free( (void *)p_dev->psz_device_name );
         free( (void *)p_buffer_list );
@@ -995,7 +996,7 @@ static int InitStreamInfo( UInt32 i_dev, aout_instance_t * p_aout,
                                       &i_param_size, NULL );
     if( err != noErr )
     {
-        msg_Err( p_aout, "Could not retrieve the number of streams: [%4.4s]",
+        msg_Err( p_aout, "could not retrieve the number of streams: [%4.4s]",
                  (char *)&err );
         return( VLC_EGENERIC );
     }
@@ -1019,7 +1020,7 @@ static int InitStreamInfo( UInt32 i_dev, aout_instance_t * p_aout,
                                   &i_param_size, P_STREAMS );
     if( err != noErr )
     {
-        msg_Err( p_aout, "Could no get the streams: [%4.4s]",
+        msg_Err( p_aout, "could no get the streams: [%4.4s]",
                  (char *)&err );
         free( (void *)P_STREAMS );
         return( VLC_EGENERIC );
@@ -1117,7 +1118,7 @@ static int InitDevice( aout_instance_t * p_aout )
     vlc_value_t val;
     unsigned int i_option;
     vlc_bool_t b_found = VLC_FALSE;
-    UInt32 i, i_stream, i_param_size;
+    UInt32 i, i_stream, i_param_size, i_firstChannelNum;
 
     struct aout_dev_t * p_dev;
     struct aout_option_t * p_option;
@@ -1141,7 +1142,7 @@ static int InitDevice( aout_instance_t * p_aout )
                                   &i_param_size, &p_sys->b_dev_alive );
     if( err != noErr )
     {
-        msg_Err( p_aout, "Could not check whether device is alive: %4.4s",
+        msg_Err( p_aout, "could not check whether device is alive: %4.4s",
                  (char *)&err );
         return( VLC_EGENERIC );
     }
@@ -1164,6 +1165,13 @@ static int InitDevice( aout_instance_t * p_aout )
 
     i_stream = b_found ? i : p_option->i_sdx;
 
+    i_firstChannelNum = 0;
+    for( i = 0; i < i_stream; i++ )
+    {
+        i_firstChannelNum += P_STREAMS[i].mChannelsPerFrame;
+    } 
+
+
     i_param_size = sizeof( p_sys->sfmt_revert );
     err = AudioStreamGetProperty( p_option->i_sid, 0,
                                   kAudioStreamPropertyPhysicalFormat,
@@ -1171,7 +1179,7 @@ static int InitDevice( aout_instance_t * p_aout )
                                   (void *)&p_sys->sfmt_revert );
     if( err != noErr )
     {
-        msg_Err( p_aout, "Could not retrieve the original streamformat: [%4.4s]",
+        msg_Err( p_aout, "could not retrieve the original streamformat: [%4.4s]",
                  (char *)&err );
         return( VLC_EGENERIC ); 
     }
@@ -1212,7 +1220,7 @@ static int InitDevice( aout_instance_t * p_aout )
                                       &P_STREAMS[i_stream] ); 
         if( err != noErr )
         {
-            msg_Err( p_aout, "Could not set the stream format: [%4.4s]",
+            msg_Err( p_aout, "could not set the stream format: [%4.4s]",
                      (char *)&err );
             vlc_mutex_unlock( &w.lock );
             vlc_mutex_destroy( &w.lock );
@@ -1255,8 +1263,6 @@ static int InitDevice( aout_instance_t * p_aout )
         p_sys->b_revert_sfmt = VLC_TRUE;
     }
 
-#undef I_STREAMS
-#undef P_STREAMS
 
     err = AudioDeviceAddPropertyListener( p_dev->devid, 0, FALSE,
                                           kAudioDevicePropertyDeviceIsAlive,
@@ -1272,6 +1278,9 @@ static int InitDevice( aout_instance_t * p_aout )
 
     p_sys->i_sel_opt = i_option;
     p_sys->devid = p_dev->devid;
+    p_sys->i_stream_index = p_option->i_idx;
+#undef I_STREAMS
+#undef P_STREAMS
 
     return( VLC_SUCCESS );
 } 
@@ -1409,7 +1418,7 @@ static OSStatus DeviceListener( AudioDeviceID inDevice,
                                           &i_param_size, &p_sys->b_dev_alive );
             if( err != noErr )
             {
-                msg_Err( p_aout, "Could not determine wether device is alive: %4.4s",
+                msg_Err( p_aout, "could not determine wether device is alive: %4.4s",
                          (char *)&err );
             }
         }
@@ -1470,7 +1479,7 @@ static void InitDeviceVar( aout_instance_t * p_aout, int i_option,
     }
 
     var_Create( p_aout, "audio-device", VLC_VAR_INTEGER | VLC_VAR_HASCHOICE );
-    text.psz_string = _("Audio device");
+    text.psz_string = ADEV_TEXT;
     var_Change( p_aout, "audio-device", VLC_VAR_SETTEXT, &text, NULL );
 
     for( i = 0; i < p_sys->i_options; i++ )