Commit 4f2beec2 authored by Christophe Massiot's avatar Christophe Massiot

* Mac OS X audio device discovery and selection, patch courtesy of

Heiko Panther <heiko.panther@web.de>.
parent 415af2ad
......@@ -346,6 +346,11 @@ C: fgp
D: MacOS X port
S: Austria
N: Heiko Panther
E: heiko.panther@web.de
D: Mac OS X audio device selection framework
S: Germany
N: Olivier Pomel
E: pomel@via.ecp.fr
C: pomel
......
......@@ -106,8 +106,8 @@
productName = vlc;
productReference = 014CEA410018CDE011CA2923;
productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<!DOCTYPE plist SYSTEM \"file://localhost/System/Library/DTDs/PropertyList.dtd\">
<plist version=\"0.9\">
<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
<plist version=\"1.0\">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
......@@ -215,6 +215,7 @@
files = (
);
isa = PBXHeadersBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
};
089C1675FE841209C02AAC07 = {
buildActionMask = 2147483647;
......@@ -230,12 +231,14 @@
F69B0CA802E24F6401A80112,
);
isa = PBXResourcesBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
};
089C1676FE841209C02AAC07 = {
buildActionMask = 2147483647;
files = (
);
isa = PBXSourcesBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
};
089C1677FE841209C02AAC07 = {
buildActionMask = 2147483647;
......@@ -243,12 +246,14 @@
1058C7AFFEA557BF11CA2CBB,
);
isa = PBXFrameworksBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
};
089C1679FE841209C02AAC07 = {
buildActionMask = 2147483647;
files = (
);
isa = PBXRezBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
};
089C167CFE841241C02AAC07 = {
children = (
......
......@@ -5,11 +5,14 @@ SOURCES_macosx = \
modules/gui/macosx/intf.m \
modules/gui/macosx/open.m \
modules/gui/macosx/playlist.m \
modules/gui/macosx/controls.m
modules/gui/macosx/controls.m \
modules/gui/macosx/asystm.m
noinst_HEADERS += \
modules/gui/macosx/intf.h \
modules/gui/macosx/open.h \
modules/gui/macosx/playlist.h \
modules/gui/macosx/vout.h
modules/gui/macosx/vout.h \
modules/gui/macosx/adev_discovery.h \
modules/gui/macosx/asystm.h
//
// main.h
// FindHW
//
// Created by Heiko Panther on Sun Sep 08 2002.
//
#import <Foundation/Foundation.h>
#import <CoreAudio/CoreAudio.h>
enum audiodeviceClasses
{
audiodevice_class_ac3 =1<<0, // compressed AC3
audiodevice_class_pcm2 =1<<1, // stereo PCM (uncompressed)
audiodevice_class_pcm6 =1<<2 // 6-channel PCM (uncompressed)
};
// specifies a rule for finding if a Device belongs to a class from above.
// if value==0, the value is ignored when matching. All other values must match.
struct classificationRule
{
UInt32 mFormatID;
UInt32 mChannelsPerFrame;
enum audiodeviceClasses characteristic;
char qualifierString[16];
};
......@@ -2,7 +2,7 @@
* aout.m: CoreAudio output plugin
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: aout.m,v 1.11 2002/09/30 21:32:33 massiot Exp $
* $Id: aout.m,v 1.12 2002/10/02 22:56:53 massiot Exp $
*
* Authors: Colin Delacroix <colin@zoy.org>
* Jon Lech Johansen <jon-vl@nanocrew.net>
......@@ -32,12 +32,15 @@
#include <vlc/vlc.h>
#include <vlc/aout.h>
#include "aout_internal.h"
#include "asystm.h"
#include <Carbon/Carbon.h>
#include <CoreAudio/AudioHardware.h>
#include <CoreAudio/HostTime.h>
#include <AudioToolbox/AudioConverter.h>
#define A52_FRAME_NB 1536
/*****************************************************************************
* aout_sys_t: private audio output method descriptor
*****************************************************************************
......@@ -70,13 +73,16 @@ static OSStatus IOCallback ( AudioDeviceID inDevice,
/*****************************************************************************
* Open: open a CoreAudio HAL device
*****************************************************************************/
extern MacOSXAudioSystem *gTheMacOSXAudioSystem; // Remove this global, access audio system froma aout some other way
int E_(OpenAudio)( vlc_object_t * p_this )
{
OSStatus err;
UInt32 i_param_size;
aout_instance_t * p_aout = (aout_instance_t *)p_this;
struct aout_sys_t * p_sys;
msg_Dbg(p_aout, "************************* ENTER OpenAudio ****************************");
/* Allocate instance */
p_sys = p_aout->output.p_sys = malloc( sizeof( struct aout_sys_t ) );
memset( p_sys, 0, sizeof( struct aout_sys_t ) );
......@@ -87,68 +93,89 @@ int E_(OpenAudio)( vlc_object_t * p_this )
}
/* Get the default output device */
/* FIXME : be more clever in choosing from several devices */
i_param_size = sizeof( p_sys->device );
err = AudioHardwareGetProperty( kAudioHardwarePropertyDefaultOutputDevice,
&i_param_size,
(void *)&p_sys->device );
if( err != noErr )
// We now ask the GUI for the selected device
p_sys->device=[gTheMacOSXAudioSystem getSelectedDeviceSetToRate:p_aout->output.output.i_rate];
if(p_sys->device==0)
{
msg_Err( p_aout, "failed to get the device: %d", err );
msg_Err( p_aout, "couldn't get output device");
return( -1 );
}
msg_Dbg(p_aout, "device returned: %ld", p_sys->device);
p_aout->output.pf_play = Play;
aout_VolumeSoftInit( p_aout );
/* Get a description of the data format used by the device */
i_param_size = sizeof( p_sys->stream_format );
err = AudioDeviceGetProperty( p_sys->device, 0, false,
kAudioDevicePropertyStreamFormat,
&i_param_size,
&p_sys->stream_format );
i_param_size = sizeof(AudioStreamBasicDescription);
err = AudioDeviceGetProperty(p_sys->device, 0, false, kAudioDevicePropertyStreamFormat, &i_param_size, &p_sys->stream_format );
if( err != noErr )
{
msg_Err( p_aout, "failed to get stream format: %d", err );
msg_Err( p_aout, "failed to get stream format: %4.4s", &err );
return -1 ;
}
if( p_sys->stream_format.mFormatID != kAudioFormatLinearPCM )
msg_Dbg( p_aout, "mSampleRate %ld, mFormatID %4.4s, mFormatFlags %ld, mBytesPerPacket %ld, mFramesPerPacket %ld, mBytesPerFrame %ld, mChannelsPerFrame %ld, mBitsPerChannel %ld",
(UInt32)p_sys->stream_format.mSampleRate, &p_sys->stream_format.mFormatID,
p_sys->stream_format.mFormatFlags, p_sys->stream_format.mBytesPerPacket,
p_sys->stream_format.mFramesPerPacket, p_sys->stream_format.mBytesPerFrame,
p_sys->stream_format.mChannelsPerFrame, p_sys->stream_format.mBitsPerChannel );
msg_Dbg( p_aout, "vlc format %4.4s, mac output format '%4.4s'",
(char *)&p_aout->output.output.i_format, &p_sys->stream_format.mFormatID );
switch(p_sys->stream_format.mFormatID)
{
msg_Err( p_aout, "kAudioFormatLinearPCM required" );
return -1 ;
case 0:
case kAudioFormatLinearPCM:
p_aout->output.output.i_format = VLC_FOURCC('f','l','3','2');
if ( p_sys->stream_format.mChannelsPerFrame < 6 )
p_aout->output.output.i_channels = AOUT_CHAN_STEREO;
else
p_aout->output.output.i_channels = AOUT_CHAN_3F2R | AOUT_CHAN_LFE;
break;
case kAudioFormat60958AC3:
case 'IAC3':
p_aout->output.output.i_format = VLC_FOURCC('s','p','d','i');
//not necessary, use the input's format by default --Meuuh
//p_aout->output.output.i_channels = AOUT_CHAN_DOLBY | AOUT_CHAN_LFE;
p_aout->output.output.i_bytes_per_frame = AOUT_SPDIF_SIZE; //p_sys->stream_format.mBytesPerFrame;
p_aout->output.output.i_frame_length = A52_FRAME_NB; //p_sys->stream_format.mFramesPerPacket;
break;
default:
msg_Err( p_aout, "Unknown hardware format '%4.4s'. Go ask Heiko.", &p_sys->stream_format.mFormatID );
return -1;
}
/* We only deal with floats. FIXME : this is where we should do S/PDIF. */
p_aout->output.output.i_format = VLC_FOURCC('f','l','3','2');
/* Set sample rate and channels per frame */
p_aout->output.output.i_rate = p_sys->stream_format.mSampleRate;
/* FIXME : this is where we should ask for downmixing. */
p_aout->output.output.i_channels = 2; //p_sys->stream_format.mChannelsPerFrame;
/* Get the buffer size that the device uses for IO */
i_param_size = sizeof( p_sys->i_buffer_size );
#if 0
err = AudioDeviceGetProperty( p_sys->device, 0, false,
#if 1 // i have a feeling we should use the buffer size imposed by the AC3 device (usually about 6144)
err = AudioDeviceGetProperty( p_sys->device, 1, false,
kAudioDevicePropertyBufferSize,
&i_param_size, &p_sys->i_buffer_size );
msg_Dbg( p_aout, "toto : %d", p_sys->i_buffer_size );
if(err) {
msg_Err(p_aout, "failed to get buffer size - err %4.4s, device %ld", &err, p_sys->device);
return -1;
}
else msg_Dbg( p_aout, "native buffer Size: %d", p_sys->i_buffer_size );
#else
p_sys->i_buffer_size = sizeof(float) * p_aout->output.output.i_channels
* 4096;
err = AudioDeviceSetProperty( p_sys->device, 0, 0, false,
p_sys->i_buffer_size = p_aout->output.output.i_bytes_per_frame;
err = AudioDeviceSetProperty( p_sys->device, 0, 1, false,
kAudioDevicePropertyBufferSize,
i_param_size, &p_sys->i_buffer_size );
#endif
if( err != noErr )
{
msg_Err( p_aout, "failed to set device buffer size: %d", err );
msg_Err( p_aout, "failed to set device buffer size: %4.4s", err );
return( -1 );
}
else msg_Dbg(p_aout, "bufferSize set to %d", p_sys->i_buffer_size);
#endif
p_aout->output.i_nb_samples = p_sys->i_buffer_size / sizeof(float)
/ p_aout->output.output.i_channels;
p_aout->output.i_nb_samples = p_sys->i_buffer_size / p_sys->stream_format.mBytesPerFrame;
/* Add callback */
err = AudioDeviceAddIOProc( p_sys->device,
......@@ -220,15 +247,19 @@ static OSStatus IOCallback( AudioDeviceID inDevice,
current_date = p_sys->clock_diff
+ AudioConvertHostTimeToNanos(host_time.mHostTime) / 1000;
p_buffer = aout_OutputNextBuffer( p_aout, current_date, VLC_FALSE );
// msg_Dbg(p_aout, "Now fetching audio data");
p_buffer = aout_OutputNextBuffer( p_aout, current_date, (p_aout->output.output.i_format == VLC_FOURCC('s','p','d','i')) );
/* move data into output data buffer */
if ( p_buffer != NULL )
{
BlockMoveData( p_buffer->p_buffer,
BlockMoveData( p_buffer->p_buffer,
outOutputData->mBuffers[ 0 ].mData,
p_sys->i_buffer_size );
aout_BufferFree( p_buffer );
// msg_Dbg(p_aout, "This buffer has %d bytes, i take %d", p_buffer->i_nb_bytes, p_sys->i_buffer_size);
aout_BufferFree( p_buffer );
}
else
{
......
//
// asystm.h
//
//
// Created by Heiko Panther on Tue Sep 10 2002.
// Copyright (c) 2002 __MyCompanyName__. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <CoreAudio/CoreAudio.h>
#import "adev_discovery.h"
#import "intf.h"
/*****************************************************************************
* MacOSXSoundOption
* Each audio device can give several sound options: there might be several
* streams on one device, each can have different formats which might qualify
* as an option.
* We record format and channels, since these attributes are requirements
* from the user and the aout should deliver what the user wants. This
* selection is basically done when the user chooses the output option.
* We do not record sample rate and bit depth, since these attributes are
* tied to the media source, and the device format that matches these media
* formats best should be selected. This selection is done when the aout
* module is created with a certain stream, and asks the asystm for a device.
*****************************************************************************/
@interface MacOSXSoundOption:NSObject
{
NSString *name;
AudioDeviceID deviceID;
UInt32 streamIndex;
UInt32 mFormatID;
UInt32 mChannels;
}
- (id)initWithName:(NSString*)_name deviceID:(AudioDeviceID)devID streamIndex:(UInt32)strInd formatID:(UInt32)formID chans:(UInt32)chans;
- (AudioDeviceID)deviceID;
- (UInt32)streamIndex;
- (UInt32)mFormatID;
- (UInt32)mChannels;
- (void)dealloc;
- (NSString*)name;
@end
@interface MacOSXAudioSystem : NSObject {
VLCMain *main;
/* selected output device */
NSMenuItem *selectedOutput;
NSMenu *newMenu;
}
- (id)initWithGUI:(VLCMain*)main;
- (AudioStreamID) getStreamIDForIndex:(UInt32)streamIndex device:(AudioDeviceID)deviceID;
- (void)CheckDevice:(AudioDeviceID)deviceID isInput:(bool)isInput;
- (void)registerSoundOption:(MacOSXSoundOption*)option;
- (void)selectAction:(id)sender;
- (AudioStreamID)getSelectedDeviceSetToRate:(int)preferredSampleRate;
- (void)dealloc;
@end
This diff is collapsed.
......@@ -2,7 +2,7 @@
* intf.h: MacOS X interface plugin
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: intf.h,v 1.1 2002/08/04 17:23:43 sam Exp $
* $Id: intf.h,v 1.2 2002/10/02 22:56:53 massiot Exp $
*
* Authors: Jon Lech Johansen <jon-vl@nanocrew.net>
* Christophe Massiot <massiot@via.ecp.fr>
......@@ -22,6 +22,12 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#include <vlc/vlc.h>
#include <vlc/intf.h>
#include <vlc/vout.h>
#include <Cocoa/Cocoa.h>
/*****************************************************************************
* VLCApplication interface
*****************************************************************************/
......@@ -140,6 +146,8 @@ struct intf_sys_t
IBOutlet id o_dmi_play;
IBOutlet id o_dmi_pause;
IBOutlet id o_dmi_stop;
id asystm; // MacOSXAudioSystem
}
- (void)terminate;
......@@ -156,6 +164,8 @@ struct intf_sys_t
- (IBAction)clearRecentItems:(id)sender;
- (void)openRecentItem:(id)sender;
//- (void)selectAction:(id)sender;
@end
@interface VLCMain (Internal)
......
......@@ -2,7 +2,7 @@
* intf.m: MacOS X interface plugin
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: intf.m,v 1.2 2002/08/12 09:34:15 sam Exp $
* $Id: intf.m,v 1.3 2002/10/02 22:56:53 massiot Exp $
*
* Authors: Jon Lech Johansen <jon-vl@nanocrew.net>
* Christophe Massiot <massiot@via.ecp.fr>
......@@ -29,16 +29,12 @@
#include <sys/param.h> /* for MAXPATHLEN */
#include <string.h>
#include <vlc/vlc.h>
#include <vlc/intf.h>
#include <vlc/vout.h>
#include <Cocoa/Cocoa.h>
#include <QuickTime/QuickTime.h>
#include "intf.h"
#include "vout.h"
#include "playlist.h"
#include "asystm.h"
/*****************************************************************************
* Local prototypes.
......@@ -246,6 +242,15 @@ static void Run( intf_thread_t *p_intf )
[[NSRunLoop currentRunLoop]
addPort: p_intf->p_sys->o_sendport
forMode: NSDefaultRunLoopMode];
// Since we need the sound menu now, it's a good time to create the sound system class
asystm=[[MacOSXAudioSystem alloc] initWithGUI:self];
[asystm retain];
}
- (void)noopAction:(id)sender {
// nothing
}
- (BOOL)application:(NSApplication *)o_app openFile:(NSString *)o_filename
......@@ -431,6 +436,8 @@ static void Run( intf_thread_t *p_intf )
context: [NSGraphicsContext currentContext] eventNumber: 1
clickCount: 1 pressure: 0.0];
[NSApp postEvent: pEvent atStart: YES];
[asystm release];
}
- (void)manageMode
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment