]> git.sesse.net Git - vlc/blobdiff - modules/audio_output/auhal.c
Factorize.
[vlc] / modules / audio_output / auhal.c
index d1aeedb2cf73c888dba749cf5cb48a2f46d9687d..651c5c62e52f84a4bf49339f2b8ea79f23c672ef 100644 (file)
 /*****************************************************************************
  * Preamble
  *****************************************************************************/
-#include <unistd.h>
-#include <sys/time.h> /* gettimeofday() */
-
 #ifdef HAVE_CONFIG_H
 # include "config.h"
 #endif
 
-#include <vlc/vlc.h>
-#include <vlc_interface.h>
+#include <unistd.h>
+
+#include <vlc_common.h>
+#include <vlc_plugin.h>
+#include <vlc_dialog.h>
 #include <vlc_aout.h>
 
+// By pass part of header which compile with some warnings,
+// and that we don't require.
+#define __MACHINEEXCEPTIONS__
+
 #include <CoreAudio/CoreAudio.h>
 #include <AudioUnit/AudioUnitProperties.h>
 #include <AudioUnit/AudioUnitParameters.h>
@@ -87,7 +91,6 @@ struct aout_sys_t
     uint8_t                     p_remainder_buffer[BUFSIZE];
     uint32_t                    i_read_bytes;
     uint32_t                    i_total_bytes;
-    AudioDeviceIOProcID         procId;
 
     /* CoreAudio SPDIF mode specific */
     pid_t                       i_hog_pid;      /* The keep the pid of our hog status */
@@ -134,15 +137,15 @@ static int      AudioDeviceCallback     ( vlc_object_t *, const char *,
     "audio device, as listed in your 'Audio Device' menu. This device will " \
     "then be used by default for audio playback.")
 
-vlc_module_begin();
-    set_shortname( "auhal" );
-    set_description( _("HAL AudioUnit output") );
-    set_capability( "audio output", 101 );
-    set_category( CAT_AUDIO );
-    set_subcategory( SUBCAT_AUDIO_AOUT );
-    set_callbacks( Open, Close );
-    add_integer( "macosx-audio-device", 0, NULL, ADEV_TEXT, ADEV_LONGTEXT, false );
-vlc_module_end();
+vlc_module_begin ()
+    set_shortname( "auhal" )
+    set_description( N_("HAL AudioUnit output") )
+    set_capability( "audio output", 101 )
+    set_category( CAT_AUDIO )
+    set_subcategory( SUBCAT_AUDIO_AOUT )
+    set_callbacks( Open, Close )
+    add_integer( "macosx-audio-device", 0, NULL, ADEV_TEXT, ADEV_LONGTEXT, false )
+vlc_module_end ()
 
 /*****************************************************************************
  * Open: open macosx audio output
@@ -162,10 +165,7 @@ static int Open( vlc_object_t * p_this )
     /* Allocate structure */
     p_aout->output.p_sys = malloc( sizeof( aout_sys_t ) );
     if( p_aout->output.p_sys == NULL )
-    {
-        msg_Err( p_aout, "out of memory" );
-        return( VLC_ENOMEM );
-    }
+        return VLC_ENOMEM;
 
     p_sys = p_aout->output.p_sys;
     p_sys->i_default_dev = 0;
@@ -221,7 +221,7 @@ 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", 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;
     }
 
@@ -247,7 +247,7 @@ static int Open( vlc_object_t * p_this )
     if( p_sys->i_hog_pid != -1 && p_sys->i_hog_pid != getpid() )
     {
         msg_Err( p_aout, "Selected audio device is exclusively in use by another program." );
-        intf_UserFatal( p_aout, false, _("Audio output failed"),
+        dialog_Fatal( p_aout, _("Audio output failed"), "%s",
                         _("The selected audio output device is exclusively in "
                           "use by another program.") );
         goto error;
@@ -432,7 +432,7 @@ static int OpenAnalog( aout_instance_t *p_aout )
             {
                 p_aout->output.output.i_physical_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
                 msg_Err( p_aout, "You should configure your speaker layout with Audio Midi Setup Utility in /Applications/Utilities. Now using Stereo mode." );
-                intf_UserFatal( p_aout, false, _("Audio device is not configured"),
+                dialog_Fatal( p_aout, _("Audio device is not configured"), "%s",
                                 _("You should configure your speaker layout with "
                                   "the \"Audio Midi Setup\" utility in /Applications/"
                                   "Utilities. Stereo mode is being used now.") );
@@ -517,7 +517,7 @@ static int OpenAnalog( aout_instance_t *p_aout )
     DeviceFormat.mFormatID = kAudioFormatLinearPCM;
 
     /* We use float 32. It's the best supported format by both VLC and Coreaudio */
-    p_aout->output.output.i_format = VLC_FOURCC( 'f','l','3','2');
+    p_aout->output.output.i_format = VLC_CODEC_FL32;
     DeviceFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked;
     DeviceFormat.mBitsPerChannel = 32;
     DeviceFormat.mChannelsPerFrame = aout_FormatNbChannels( &p_aout->output.output );
@@ -650,10 +650,7 @@ static int OpenSPDIF( aout_instance_t * p_aout )
     i_streams = i_param_size / sizeof( AudioStreamID );
     p_streams = (AudioStreamID *)malloc( i_param_size );
     if( p_streams == NULL )
-    {
-        msg_Err( p_aout, "out of memory" );
         return false;
-    }
  
     err = AudioDeviceGetProperty( p_sys->i_selected_dev, 0, FALSE,
                                     kAudioDevicePropertyStreams,
@@ -686,10 +683,7 @@ static int OpenSPDIF( aout_instance_t * p_aout )
         i_formats = i_param_size / sizeof( AudioStreamBasicDescription );
         p_format_list = (AudioStreamBasicDescription *)malloc( i_param_size );
         if( p_format_list == NULL )
-        {
-            msg_Err( p_aout, "could not malloc the memory" );
             continue;
-        }
  
         err = AudioStreamGetProperty( p_streams[i], 0,
                                           kAudioStreamPropertyPhysicalFormats,
@@ -778,9 +772,9 @@ static int OpenSPDIF( aout_instance_t * p_aout )
 
     /* Set the format flags */
     if( p_sys->stream_format.mFormatFlags & kAudioFormatFlagIsBigEndian )
-        p_aout->output.output.i_format = VLC_FOURCC('s','p','d','b');
+        p_aout->output.output.i_format = VLC_CODEC_SPDIFB;
     else
-        p_aout->output.output.i_format = VLC_FOURCC('s','p','d','i');
+        p_aout->output.output.i_format = VLC_CODEC_SPDIFL;
     p_aout->output.output.i_bytes_per_frame = AOUT_SPDIF_SIZE;
     p_aout->output.output.i_frame_length = A52_FRAME_NB;
     p_aout->output.i_nb_samples = p_aout->output.output.i_frame_length;
@@ -789,10 +783,10 @@ static int OpenSPDIF( aout_instance_t * p_aout )
     aout_VolumeNoneInit( p_aout );
 
     /* Add IOProc callback */
-    err = AudioDeviceCreateIOProcID( p_sys->i_selected_dev,
-                                    (AudioDeviceIOProc)RenderCallbackSPDIF,
-                                    (void *)p_aout,
-                                    &p_sys->procId);
+    err = AudioDeviceAddIOProc( p_sys->i_selected_dev,
+                               (AudioDeviceIOProc)RenderCallbackSPDIF,
+                               (void *)p_aout );
+
     if( err != noErr )
     {
         msg_Err( p_aout, "AudioDeviceAddIOProc failed: [%4.4s]", (char *)&err );
@@ -810,8 +804,8 @@ static int OpenSPDIF( aout_instance_t * p_aout )
     {
         msg_Err( p_aout, "AudioDeviceStart failed: [%4.4s]", (char *)&err );
 
-        err = AudioDeviceDestroyIOProcID( p_sys->i_selected_dev,
-                                          p_sys->procId );
+        err = AudioDeviceRemoveIOProc( p_sys->i_selected_dev,
+                                     (AudioDeviceIOProc)RenderCallbackSPDIF );
         if( err != noErr )
         {
             msg_Err( p_aout, "AudioDeviceRemoveIOProc failed: [%4.4s]", (char *)&err );
@@ -851,8 +845,8 @@ static void Close( vlc_object_t * p_this )
         }
 
         /* Remove IOProc callback */
-        err = AudioDeviceDestroyIOProcID( p_sys->i_selected_dev,
-                                          p_sys->procId );
+        err = AudioDeviceRemoveIOProc( p_sys->i_selected_dev,
+                                      (AudioDeviceIOProc)RenderCallbackSPDIF );
         if( err != noErr )
         {
             msg_Err( p_aout, "AudioDeviceRemoveIOProc failed: [%4.4s]", (char *)&err );
@@ -914,6 +908,7 @@ static void Close( vlc_object_t * p_this )
  *****************************************************************************/
 static void Play( aout_instance_t * p_aout )
 {
+    VLC_UNUSED(p_aout);
 }
 
 
@@ -952,10 +947,7 @@ static void Probe( aout_instance_t * p_aout )
     /* Allocate DeviceID array */
     p_devices = (AudioDeviceID*)malloc( sizeof(AudioDeviceID) * p_sys->i_devices );
     if( p_devices == NULL )
-    {
-        msg_Err( p_aout, "out of memory" );
         goto error;
-    }
 
     /* Populate DeviceID array */
     err = AudioHardwareGetProperty( kAudioHardwarePropertyDevices,
@@ -978,7 +970,7 @@ static void Probe( aout_instance_t * p_aout )
     p_sys->i_default_dev = devid_def;
  
     var_Create( p_aout, "audio-device", VLC_VAR_INTEGER|VLC_VAR_HASCHOICE );
-    text.psz_string = _("Audio Device");
+    text.psz_string = (char*)_("Audio Device");
     var_Change( p_aout, "audio-device", VLC_VAR_SETTEXT, &text, NULL );
  
     for( i = 0; i < p_sys->i_devices; i++ )
@@ -1006,13 +998,15 @@ static void Probe( aout_instance_t * p_aout )
         if( !AudioDeviceHasOutput( p_devices[i]) )
         {
             msg_Dbg( p_aout, "this device is INPUT only. skipping..." );
+            free( psz_name );
             continue;
         }
 
         /* Add the menu entries */
         val.i_int = (int)p_devices[i];
-        text.psz_string = strdup( psz_name );
+        text.psz_string = psz_name;
         var_Change( p_aout, "audio-device", VLC_VAR_ADDCHOICE, &val, &text );
+        text.psz_string = NULL;
         if( p_sys->i_default_dev == p_devices[i] )
         {
             /* The default device is the selected device normally */
@@ -1023,14 +1017,17 @@ static void Probe( aout_instance_t * p_aout )
         if( AudioDeviceSupportsDigital( p_aout, p_devices[i] ) )
         {
             val.i_int = (int)p_devices[i] | AOUT_VAR_SPDIF_FLAG;
-            asprintf( &text.psz_string, _("%s (Encoded Output)"), psz_name );
-            var_Change( p_aout, "audio-device", VLC_VAR_ADDCHOICE, &val, &text );
-            if( p_sys->i_default_dev == p_devices[i] && config_GetInt( p_aout, "spdif" ) )
+            if( asprintf( &text.psz_string, _("%s (Encoded Output)"), psz_name ) != -1 )
             {
-                /* We selected to prefer SPDIF output if available
-                 * then this "dummy" entry should be selected */
-                var_Change( p_aout, "audio-device", VLC_VAR_SETDEFAULT, &val, NULL );
-                var_Set( p_aout, "audio-device", val );
+                var_Change( p_aout, "audio-device", VLC_VAR_ADDCHOICE, &val, &text );
+                free( text.psz_string );
+                if( p_sys->i_default_dev == p_devices[i] && config_GetInt( p_aout, "spdif" ) )
+                {
+                    /* We selected to prefer SPDIF output if available
+                     * then this "dummy" entry should be selected */
+                    var_Change( p_aout, "audio-device", VLC_VAR_SETDEFAULT, &val, NULL );
+                    var_Set( p_aout, "audio-device", val );
+                }
             }
         }
  
@@ -1059,7 +1056,7 @@ static void Probe( aout_instance_t * p_aout )
     return;
 
 error:
-    var_Destroy( p_aout, "audio-device" );
+    msg_Warn( p_aout, "audio device already in use" );
     free( p_devices );
     return;
 }
@@ -1102,10 +1099,7 @@ static int AudioDeviceSupportsDigital( aout_instance_t *p_aout, AudioDeviceID i_
     i_streams = i_param_size / sizeof( AudioStreamID );
     p_streams = (AudioStreamID *)malloc( i_param_size );
     if( p_streams == NULL )
-    {
-        msg_Err( p_aout, "out of memory" );
         return VLC_ENOMEM;
-    }
  
     err = AudioDeviceGetProperty( i_dev_id, 0, FALSE,
                                     kAudioDevicePropertyStreams,
@@ -1151,10 +1145,7 @@ static int AudioStreamSupportsDigital( aout_instance_t *p_aout, AudioStreamID i_
     i_formats = i_param_size / sizeof( AudioStreamBasicDescription );
     p_format_list = (AudioStreamBasicDescription *)malloc( i_param_size );
     if( p_format_list == NULL )
-    {
-        msg_Err( p_aout, "could not malloc the memory" );
         return false;
-    }
  
     err = AudioStreamGetProperty( i_stream_id, 0,
                                       kAudioStreamPropertyPhysicalFormats,
@@ -1191,15 +1182,13 @@ static int AudioStreamChangeFormat( aout_instance_t *p_aout, AudioStreamID i_str
     UInt32              i_param_size = 0;
     int i;
 
-    struct timeval now;
-    struct timespec timeout;
     struct { vlc_mutex_t lock; vlc_cond_t cond; } w;
  
     msg_Dbg( p_aout, STREAM_FORMAT_MSG( "setting stream format: ", change_format ) );
 
     /* Condition because SetProperty is asynchronious */
-    vlc_cond_init( p_aout, &w.cond );
-    vlc_mutex_init( p_aout, &w.lock );
+    vlc_cond_init( &w.cond );
+    vlc_mutex_init( &w.lock );
     vlc_mutex_lock( &w.lock );
 
     /* Install the callback */
@@ -1230,12 +1219,9 @@ static int AudioStreamChangeFormat( aout_instance_t *p_aout, AudioStreamID i_str
     for( i = 0; i < 5; i++ )
     {
         AudioStreamBasicDescription actual_format;
+        mtime_t timeout = mdate() + 500000;
 
-        gettimeofday( &now, NULL );
-        timeout.tv_sec = now.tv_sec;
-        timeout.tv_nsec = (now.tv_usec + 500000) * 1000;
-
-        if( pthread_cond_timedwait( &w.cond.cond, &w.lock.mutex, &timeout ) )
+        if( vlc_cond_timedwait( &w.cond, &w.lock, timeout ) )
         {
             msg_Dbg( p_aout, "reached timeout" );
         }
@@ -1284,7 +1270,7 @@ static int AudioStreamChangeFormat( aout_instance_t *p_aout, AudioStreamID i_str
 static OSStatus RenderCallbackAnalog( vlc_object_t *_p_aout,
                                       AudioUnitRenderActionFlags *ioActionFlags,
                                       const AudioTimeStamp *inTimeStamp,
-                                      unsigned int inBusNummer,
+                                      unsigned int inBusNumber,
                                       unsigned int inNumberFrames,
                                       AudioBufferList *ioData )
 {
@@ -1295,6 +1281,10 @@ static OSStatus RenderCallbackAnalog( vlc_object_t *_p_aout,
     aout_instance_t * p_aout = (aout_instance_t *)_p_aout;
     struct aout_sys_t * p_sys = p_aout->output.p_sys;
 
+    VLC_UNUSED(ioActionFlags);
+    VLC_UNUSED(inBusNumber);
+    VLC_UNUSED(inNumberFrames);
+
     host_time.mFlags = kAudioTimeStampHostTimeValid;
     AudioDeviceTranslateTime( p_sys->i_selected_dev, inTimeStamp, &host_time );
 
@@ -1319,7 +1309,9 @@ static OSStatus RenderCallbackAnalog( vlc_object_t *_p_aout,
     if( p_sys->i_total_bytes > 0 )
     {
         i_mData_bytes = __MIN( p_sys->i_total_bytes - p_sys->i_read_bytes, ioData->mBuffers[0].mDataByteSize );
-        p_aout->p_libvlc->pf_memcpy( ioData->mBuffers[0].mData, &p_sys->p_remainder_buffer[p_sys->i_read_bytes], i_mData_bytes );
+        vlc_memcpy( ioData->mBuffers[0].mData,
+                    &p_sys->p_remainder_buffer[p_sys->i_read_bytes],
+                    i_mData_bytes );
         p_sys->i_read_bytes += i_mData_bytes;
         current_date += (mtime_t) ( (mtime_t) 1000000 / p_aout->output.output.i_rate ) *
                         ( i_mData_bytes / 4 / aout_FormatNbChannels( &p_aout->output.output )  ); // 4 is fl32 specific
@@ -1336,15 +1328,18 @@ static OSStatus RenderCallbackAnalog( vlc_object_t *_p_aout,
  
         if( p_buffer != NULL )
         {
-            uint32_t i_second_mData_bytes = __MIN( p_buffer->i_nb_bytes, ioData->mBuffers[0].mDataByteSize - i_mData_bytes );
+            uint32_t i_second_mData_bytes = __MIN( p_buffer->i_buffer, ioData->mBuffers[0].mDataByteSize - i_mData_bytes );
  
-            p_aout->p_libvlc->pf_memcpy( (uint8_t *)ioData->mBuffers[0].mData + i_mData_bytes, p_buffer->p_buffer, i_second_mData_bytes );
+            vlc_memcpy( (uint8_t *)ioData->mBuffers[0].mData + i_mData_bytes,
+                        p_buffer->p_buffer, i_second_mData_bytes );
             i_mData_bytes += i_second_mData_bytes;
 
             if( i_mData_bytes >= ioData->mBuffers[0].mDataByteSize )
             {
-                p_sys->i_total_bytes = p_buffer->i_nb_bytes - i_second_mData_bytes;
-                p_aout->p_libvlc->pf_memcpy( p_sys->p_remainder_buffer, &p_buffer->p_buffer[i_second_mData_bytes], p_sys->i_total_bytes );
+                p_sys->i_total_bytes = p_buffer->i_buffer - i_second_mData_bytes;
+                vlc_memcpy( p_sys->p_remainder_buffer,
+                            &p_buffer->p_buffer[i_second_mData_bytes],
+                            p_sys->i_total_bytes );
             }
             else
             {
@@ -1356,7 +1351,8 @@ static OSStatus RenderCallbackAnalog( vlc_object_t *_p_aout,
         }
         else
         {
-             p_aout->p_libvlc->pf_memset( (uint8_t *)ioData->mBuffers[0].mData +i_mData_bytes, 0, ioData->mBuffers[0].mDataByteSize - i_mData_bytes );
+             vlc_memset( (uint8_t *)ioData->mBuffers[0].mData +i_mData_bytes,
+                         0,ioData->mBuffers[0].mDataByteSize - i_mData_bytes );
              i_mData_bytes += ioData->mBuffers[0].mDataByteSize - i_mData_bytes;
         }
     }
@@ -1380,6 +1376,10 @@ static OSStatus RenderCallbackSPDIF( AudioDeviceID inDevice,
     aout_instance_t * p_aout = (aout_instance_t *)threadGlobals;
     struct aout_sys_t * p_sys = p_aout->output.p_sys;
 
+    VLC_UNUSED(inDevice);
+    VLC_UNUSED(inInputData);
+    VLC_UNUSED(inInputTime);
+
     /* Check for the difference between the Device clock and mdate */
     p_sys->clock_diff = - (mtime_t)
         AudioConvertHostTimeToNanos( inNow->mHostTime ) / 1000;
@@ -1394,17 +1394,16 @@ static OSStatus RenderCallbackSPDIF( AudioDeviceID inDevice,
 #define BUFFER outOutputData->mBuffers[p_sys->i_stream_index]
     if( p_buffer != NULL )
     {
-        if( (int)BUFFER.mDataByteSize != (int)p_buffer->i_nb_bytes)
-            msg_Warn( p_aout, "bytesize: %d nb_bytes: %d", (int)BUFFER.mDataByteSize, (int)p_buffer->i_nb_bytes );
+        if( (int)BUFFER.mDataByteSize != (int)p_buffer->i_buffer)
+            msg_Warn( p_aout, "bytesize: %d nb_bytes: %d", (int)BUFFER.mDataByteSize, (int)p_buffer->i_buffer );
  
         /* move data into output data buffer */
-        p_aout->p_libvlc->pf_memcpy( BUFFER.mData,
-                                  p_buffer->p_buffer, p_buffer->i_nb_bytes );
+        vlc_memcpy( BUFFER.mData, p_buffer->p_buffer, p_buffer->i_buffer );
         aout_BufferFree( p_buffer );
     }
     else
     {
-        p_aout->p_libvlc->pf_memset( BUFFER.mData, 0, BUFFER.mDataByteSize );
+        vlc_memset( BUFFER.mData, 0, BUFFER.mDataByteSize );
     }
 #undef BUFFER
 
@@ -1426,7 +1425,7 @@ static OSStatus HardwareListener( AudioHardwarePropertyID inPropertyID,
         {
             /* something changed in the list of devices */
             /* We trigger the audio-device's aout_ChannelsRestart callback */
-            var_Change( p_aout, "audio-device", VLC_VAR_TRIGGER_CALLBACKS, NULL, NULL );
+            var_TriggerCallback( p_aout, "audio-device" );
             var_Destroy( p_aout, "audio-device" );
         }
         break;
@@ -1445,6 +1444,9 @@ static OSStatus StreamListener( AudioStreamID inStream,
 {
     OSStatus err = noErr;
     struct { vlc_mutex_t lock; vlc_cond_t cond; } * w = inClientData;
+
+    VLC_UNUSED(inStream);
+    VLC_UNUSED(inChannel);
  
     switch( inPropertyID )
     {