/*****************************************************************************
* 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/AudioUnit.h>
#include <AudioUnit/AudioUnitProperties.h>
#include <AudioUnit/AudioUnitParameters.h>
#include <AudioUnit/AudioOutputUnit.h>
#include <AudioToolbox/AudioFormat.h>
+#ifndef verify_noerr
+#define verify_noerr(a) assert((a) == noErr)
+#endif
+
+#if AUDIO_UNIT_VERSION < 1060
+#define AudioComponent Component
+#define AudioComponentDescription ComponentDescription
+#define AudioComponentFindNext FindNextComponent
+#define AudioComponentInstanceNew OpenAComponent
+#define AudioComponentInstanceDispose CloseComponent
+#define AudioComponentInstanceNew OpenAComponent
+#define AudioComponentInstanceNew OpenAComponent
+#else
+#include <AudioUnit/AudioComponent.h>
+#endif
+
#define STREAM_FORMAT_MSG( pre, sfm ) \
- pre "[%ld][%4.4s][%ld][%ld][%ld][%ld][%ld][%ld]", \
+ pre "[%u][%4.4s][%u][%u][%u][%u][%u][%u]", \
(UInt32)sfm.mSampleRate, (char *)&sfm.mFormatID, \
sfm.mFormatFlags, sfm.mBytesPerPacket, \
sfm.mFramesPerPacket, sfm.mBytesPerFrame, \
sfm.mChannelsPerFrame, sfm.mBitsPerChannel
#define STREAM_FORMAT_MSG_FULL( pre, sfm ) \
- pre ":\nsamplerate: [%ld]\nFormatID: [%4.4s]\nFormatFlags: [%ld]\nBypesPerPacket: [%ld]\nFramesPerPacket: [%ld]\nBytesPerFrame: [%ld]\nChannelsPerFrame: [%ld]\nBitsPerChannel[%ld]", \
+ pre ":\nsamplerate: [%u]\nFormatID: [%4.4s]\nFormatFlags: [%u]\nBypesPerPacket: [%u]\nFramesPerPacket: [%u]\nBytesPerFrame: [%u]\nChannelsPerFrame: [%u]\nBitsPerChannel[%u]", \
(UInt32)sfm.mSampleRate, (char *)&sfm.mFormatID, \
sfm.mFormatFlags, sfm.mBytesPerPacket, \
sfm.mFramesPerPacket, sfm.mBytesPerFrame, \
sfm.mChannelsPerFrame, sfm.mBitsPerChannel
-#define BUFSIZE 0xffffff
+#define FRAMESIZE 2048
+#define BUFSIZE (FRAMESIZE * 8)
#define AOUT_VAR_SPDIF_FLAG 0xf00000
/*
mtime_t clock_diff; /* Difference between VLC clock and Device clock */
/* AUHAL specific */
- Component au_component; /* The Audiocomponent we use */
+ AudioComponent 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;
- AudioDeviceIOProcID procId;
/* CoreAudio SPDIF mode specific */
pid_t i_hog_pid; /* The keep the pid of our hog status */
vlc_value_t, vlc_value_t, void * );
+
/*****************************************************************************
* Module descriptor
*****************************************************************************/
"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
/* 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;
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;
OSStatus err = noErr;
UInt32 i_param_size = 0, i = 0;
int i_original;
- ComponentDescription desc;
+ AudioComponentDescription desc;
AudioStreamBasicDescription DeviceFormat;
AudioChannelLayout *layout;
AudioChannelLayout new_layout;
desc.componentFlags = 0;
desc.componentFlagsMask = 0;
- p_sys->au_component = FindNextComponent( NULL, &desc );
+ p_sys->au_component = AudioComponentFindNext( NULL, &desc );
if( p_sys->au_component == NULL )
{
msg_Warn( p_aout, "we cannot find our HAL component" );
return false;
}
- err = OpenAComponent( p_sys->au_component, &p_sys->au_unit );
+ err = AudioComponentInstanceNew( p_sys->au_component, &p_sys->au_unit );
if( err != noErr )
{
msg_Warn( p_aout, "we cannot open our HAL component" );
{
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.") );
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 );
DeviceFormat.mFramesPerPacket = 1;
DeviceFormat.mBytesPerFrame = DeviceFormat.mBitsPerChannel * DeviceFormat.mChannelsPerFrame / 8;
DeviceFormat.mBytesPerPacket = DeviceFormat.mBytesPerFrame * DeviceFormat.mFramesPerPacket;
-
+
/* Set the desired format */
i_param_size = sizeof(AudioStreamBasicDescription);
verify_noerr( AudioUnitSetProperty( p_sys->au_unit,
/* Do the last VLC aout setups */
aout_FormatPrepare( &p_aout->output.output );
- p_aout->output.i_nb_samples = 2048;
+ p_aout->output.i_nb_samples = FRAMESIZE;
aout_VolumeSoftInit( p_aout );
/* set the IOproc callback */
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,
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,
/* 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;
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 );
{
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 );
{
verify_noerr( AudioOutputUnitStop( p_sys->au_unit ) );
verify_noerr( AudioUnitUninitialize( p_sys->au_unit ) );
- verify_noerr( CloseComponent( p_sys->au_unit ) );
+ verify_noerr( AudioComponentInstanceDispose( p_sys->au_unit ) );
}
if( p_sys->b_digital )
}
/* 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 );
*****************************************************************************/
static void Play( aout_instance_t * p_aout )
{
+ VLC_UNUSED(p_aout);
}
goto error;
}
- msg_Dbg( p_aout, "system has [%ld] device(s)", p_sys->i_devices );
+ msg_Dbg( p_aout, "system has [%u] device(s)", p_sys->i_devices );
/* Allocate DeviceID array */
p_devices = (AudioDeviceID*)malloc( sizeof(AudioDeviceID) * p_sys->i_devices );
if( p_devices == NULL )
- {
- msg_Err( p_aout, "out of memory" );
goto error;
- }
/* Populate DeviceID array */
err = AudioHardwareGetProperty( kAudioHardwarePropertyDevices,
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++ )
&i_param_size, psz_name);
if( err ) goto error;
- msg_Dbg( p_aout, "DevID: %#lx DevName: %s", p_devices[i], psz_name );
+ msg_Dbg( p_aout, "DevID: %u DevName: %s", p_devices[i], psz_name );
if( !AudioDeviceHasOutput( p_devices[i]) )
{
msg_Dbg( p_aout, "this device is INPUT only. skipping..." );
+ free( psz_name );
continue;
}
/* Add the menu entries */
val.i_int = (int)p_devices[i];
- text.psz_string = strdup( psz_name );
+ text.psz_string = psz_name;
var_Change( p_aout, "audio-device", VLC_VAR_ADDCHOICE, &val, &text );
+ text.psz_string = NULL;
if( p_sys->i_default_dev == p_devices[i] )
{
/* The default device is the selected device normally */
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 );
+ }
}
}
return;
error:
- var_Destroy( p_aout, "audio-device" );
+ msg_Warn( p_aout, "audio device already in use" );
free( p_devices );
return;
}
i_streams = i_param_size / sizeof( AudioStreamID );
p_streams = (AudioStreamID *)malloc( i_param_size );
if( p_streams == NULL )
- {
- msg_Err( p_aout, "out of memory" );
return VLC_ENOMEM;
- }
err = AudioDeviceGetProperty( i_dev_id, 0, FALSE,
kAudioDevicePropertyStreams,
i_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,
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 */
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, &w.lock, &timeout ) )
+ if( vlc_cond_timedwait( &w.cond, &w.lock, timeout ) )
{
msg_Dbg( p_aout, "reached timeout" );
}
static OSStatus RenderCallbackAnalog( vlc_object_t *_p_aout,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
- unsigned int inBusNummer,
+ unsigned int inBusNumber,
unsigned int inNumberFrames,
AudioBufferList *ioData )
{
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 );
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
/* We don't have enough data yet */
aout_buffer_t * p_buffer;
p_buffer = aout_OutputNextBuffer( p_aout, current_date , false );
-
+
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 );
+ aout_BufferFree( p_buffer );
+ break;
}
else
{
}
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;
}
}
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;
#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
{
/* 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;
{
OSStatus err = noErr;
struct { vlc_mutex_t lock; vlc_cond_t cond; } * w = inClientData;
+
+ VLC_UNUSED(inStream);
+ VLC_UNUSED(inChannel);
switch( inPropertyID )
{