/*****************************************************************************
* 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>
#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, \
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;
};
/*****************************************************************************
* 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();
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 ) );
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 )
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 );
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 );
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 )
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;
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 );
}
{
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++ )
{
}
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 );
}
&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 );
&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 );
&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 );
&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 );
}
&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 );
&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 );
&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 );
&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 );
}
&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 );
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;
&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 );
}
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,
(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 );
}
&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 );
p_sys->b_revert_sfmt = VLC_TRUE;
}
-#undef I_STREAMS
-#undef P_STREAMS
err = AudioDeviceAddPropertyListener( p_dev->devid, 0, FALSE,
kAudioDevicePropertyDeviceIsAlive,
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 );
}
&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 );
}
}
}
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++ )