From 4f2beec27e23da2f8956134eb4d1e8096f03841d Mon Sep 17 00:00:00 2001 From: Christophe Massiot Date: Wed, 2 Oct 2002 22:56:53 +0000 Subject: [PATCH] * Mac OS X audio device discovery and selection, patch courtesy of Heiko Panther . --- AUTHORS | 5 + extras/MacOSX/vlc.pbproj/project.pbxproj | 9 +- modules/gui/macosx/Modules.am | 7 +- modules/gui/macosx/adev_discovery.h | 26 ++ modules/gui/macosx/aout.m | 103 ++++-- modules/gui/macosx/asystm.h | 58 +++ modules/gui/macosx/asystm.m | 449 +++++++++++++++++++++++ modules/gui/macosx/intf.h | 12 +- modules/gui/macosx/intf.m | 19 +- 9 files changed, 641 insertions(+), 47 deletions(-) create mode 100755 modules/gui/macosx/adev_discovery.h create mode 100755 modules/gui/macosx/asystm.h create mode 100755 modules/gui/macosx/asystm.m diff --git a/AUTHORS b/AUTHORS index 9e071a4316..04b8f6c16a 100644 --- a/AUTHORS +++ b/AUTHORS @@ -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 diff --git a/extras/MacOSX/vlc.pbproj/project.pbxproj b/extras/MacOSX/vlc.pbproj/project.pbxproj index bdfab1c980..fcf7da2cf4 100644 --- a/extras/MacOSX/vlc.pbproj/project.pbxproj +++ b/extras/MacOSX/vlc.pbproj/project.pbxproj @@ -106,8 +106,8 @@ productName = vlc; productReference = 014CEA410018CDE011CA2923; productSettingsXML = " - - + + CFBundleDevelopmentRegion English @@ -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 = ( diff --git a/modules/gui/macosx/Modules.am b/modules/gui/macosx/Modules.am index 48143655d0..37e442ecfe 100644 --- a/modules/gui/macosx/Modules.am +++ b/modules/gui/macosx/Modules.am @@ -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 diff --git a/modules/gui/macosx/adev_discovery.h b/modules/gui/macosx/adev_discovery.h new file mode 100755 index 0000000000..5b25c3a11f --- /dev/null +++ b/modules/gui/macosx/adev_discovery.h @@ -0,0 +1,26 @@ +// +// main.h +// FindHW +// +// Created by Heiko Panther on Sun Sep 08 2002. +// + +#import +#import + +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]; +}; diff --git a/modules/gui/macosx/aout.m b/modules/gui/macosx/aout.m index 5c4a8d0601..93bd0e502c 100644 --- a/modules/gui/macosx/aout.m +++ b/modules/gui/macosx/aout.m @@ -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 * Jon Lech Johansen @@ -32,12 +32,15 @@ #include #include #include "aout_internal.h" +#include "asystm.h" #include #include #include #include +#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 { diff --git a/modules/gui/macosx/asystm.h b/modules/gui/macosx/asystm.h new file mode 100755 index 0000000000..9aec4fff06 --- /dev/null +++ b/modules/gui/macosx/asystm.h @@ -0,0 +1,58 @@ +// +// asystm.h +// +// +// Created by Heiko Panther on Tue Sep 10 2002. +// Copyright (c) 2002 __MyCompanyName__. All rights reserved. +// + +#import +#import +#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 diff --git a/modules/gui/macosx/asystm.m b/modules/gui/macosx/asystm.m new file mode 100755 index 0000000000..a8b73705b8 --- /dev/null +++ b/modules/gui/macosx/asystm.m @@ -0,0 +1,449 @@ +// +// asystm.m +// +// +// Created by Heiko Panther on Tue Sep 10 2002. +// Copyright (c) 2002 __MyCompanyName__. All rights reserved. +// + +#import "asystm.h" +#define MAXINT 0x7fffffff + +#define DEBUG_ASYSTM 1 + +// this is a basic set of rules +#define gNumClassificationRules 4 + +const struct classificationRule gClassificationRules[gNumClassificationRules]= +{ +{ // The old AC3 format type + 'IAC3', + 0, + audiodevice_class_ac3, + "Digital AC3" +}, +{ // The new AC3 format type + kAudioFormat60958AC3, + 0, + audiodevice_class_ac3, + "Digital AC3" +}, +{ + kAudioFormatLinearPCM, + 2, + audiodevice_class_pcm2, + "Stereo PCM" +}, +{ + kAudioFormatLinearPCM, + 6, + audiodevice_class_pcm6, + "6 Channel PCM" +} +}; + +MacOSXAudioSystem *gTheMacOSXAudioSystem; // Remove this global, access audio system froma aout some other way + +@implementation MacOSXSoundOption + +- (id)initWithName:(NSString*)_name deviceID:(AudioDeviceID)devID streamIndex:(UInt32)strInd formatID:(UInt32)formID chans:(UInt32)chans; +{ + id me=0; + if((me=[super init])) + { + name = _name; + [name retain]; + deviceID=devID; + streamIndex=strInd; + mFormatID=formID; + mChannels=chans; + } + return(me); +} + +- (NSString*)name {return name;}; + +- (AudioDeviceID)deviceID {return deviceID;}; + +- (UInt32)streamIndex {return streamIndex;}; + +- (UInt32)mFormatID {return mFormatID;}; + +- (UInt32)mChannels {return mChannels;}; + +- (void)dealloc {[name release];}; + +@end + + +@implementation MacOSXAudioSystem + +OSStatus listenerProc (AudioDeviceID inDevice, + UInt32 inChannel, + Boolean isInput, + AudioDevicePropertyID inPropertyID, + void* inClientData) +{ + intf_thread_t * p_intf = [NSApp getIntf]; + msg_Dbg(p_intf, "********** Property Listener called! device %d, channel %d, isInput %d, propertyID %4.4s", + inDevice, inChannel, isInput, &inPropertyID); + return 0; +}; + +OSStatus streamListenerProc (AudioStreamID inStream, + UInt32 inChannel, + AudioDevicePropertyID inPropertyID, + void* inClientData) +{ + intf_thread_t * p_intf = [NSApp getIntf]; + msg_Dbg(p_intf, "********** Property Listener called! stream %d, channel %d, propertyID %4.4s", + inStream, inChannel, &inPropertyID); + return 0; +}; + +- (id)initWithGUI:(VLCMain*)_main +{ + id me=0; + if((me=[super init])) + { + gTheMacOSXAudioSystem=self; + main=_main; + [main retain]; + intf_thread_t * p_intf = [NSApp getIntf]; + selectedOutput=0; + + // find audio devices + // find out how many audio devices there are, if any + OSStatus status = noErr; + UInt32 theSize; + Boolean outWritable; + AudioDeviceID *deviceList = NULL; + UInt32 i; + + status = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices, &theSize, &outWritable); + if(status != noErr) + { + msg_Err(p_intf, "AudioHardwareGetPropertyInfo failed"); + }; + + // calculate the number of device available + UInt32 devicesAvailable = theSize / sizeof(AudioDeviceID); + // Bail if there aren't any devices + if(devicesAvailable < 1) + { + msg_Err(p_intf, "no devices found"); + } + if(DEBUG_ASYSTM) msg_Dbg(p_intf, "Have %i devices!", devicesAvailable); + + // make space for the devices we are about to get + deviceList = (AudioDeviceID*)malloc(theSize); + // get an array of AudioDeviceIDs + status = AudioHardwareGetProperty(kAudioHardwarePropertyDevices, &theSize, (void *) deviceList); + if(status != noErr) + { + msg_Err(p_intf, "could not get Device list"); + }; + + // Build a menu + NSMenuItem *newItem; + newItem = [[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:@"Sound output" action:NULL keyEquivalent:@""]; + newMenu = [[NSMenu allocWithZone:[NSMenu menuZone]] initWithTitle:@"Sound output"]; + [newItem setSubmenu:newMenu]; + [[NSApp mainMenu] addItem:newItem]; + [newItem release]; + + // check which devices can do what class of audio + // struct mosx_AudioDeviceData deviceData; + for(i=0; imNumberBuffers); + + // find details of each stream + for (i=0; i < bufferList->mNumberBuffers; i++) + { + short streamIndex=i+1; + UInt32 nActFormats; + AudioStreamBasicDescription *formatsAvailable; + + AudioStreamID streamID=[self getStreamIDForIndex:streamIndex device:deviceID]; + + // Add property listener + err=AudioStreamAddPropertyListener(streamID, 0, kAudioDevicePropertyStreams, streamListenerProc, 0); + if(err) msg_Err(p_intf, "Add Property Listener failed, err=%4.4s", &err); + err=AudioStreamAddPropertyListener(streamID, 0, kAudioDevicePropertyStreamConfiguration, streamListenerProc, 0); + if(err) msg_Err(p_intf, "Add Property Listener failed, err=%4.4s", &err); + err=AudioStreamAddPropertyListener(streamID, 0, kAudioDevicePropertyStreamFormat, streamListenerProc, 0); + if(err) msg_Err(p_intf, "Add Property Listener failed, err=%4.4s", &err); + err=AudioStreamAddPropertyListener(streamID, 0, kAudioStreamPropertyPhysicalFormat, streamListenerProc, 0); + if(err) msg_Err(p_intf, "Add Property Listener failed, err=%4.4s", &err); + + // Get the # of actual formats in the current stream + err = AudioStreamGetPropertyInfo(streamID, 0, kAudioStreamPropertyPhysicalFormats, &theSize, &outWritable); + nActFormats = theSize / sizeof(AudioStreamBasicDescription); + if(DEBUG_ASYSTM) msg_Dbg(p_intf, "stream index %i, streamID %i, nActFormats %d", streamIndex, streamID, nActFormats); + + // Get the format specifications + formatsAvailable=(AudioStreamBasicDescription*) malloc(theSize); + err = AudioStreamGetProperty(streamID, 0, kAudioStreamPropertyPhysicalFormats, &theSize, formatsAvailable); + if(err) msg_Err(p_intf, "AudioDeviceGetProperty err %d", err); + + // now classify the device and add a menu entry for each device class it matches + for(j=0; jmSampleRate, &format->mFormatID, + format->mFormatFlags, format->mBytesPerPacket, + format->mFramesPerPacket, format->mBytesPerFrame, + format->mChannelsPerFrame, format->mBitsPerChannel); +}; + + +- (AudioDeviceID)getSelectedDeviceSetToRate:(int)preferredSampleRate{ + // I know the selected device, stream, and the required format ID. Now find a format + // that comes closest to the preferred rate + // For sample size, it is assumed that 16 bits will always be enough. + // Note that the caller is not guranteed to get the rate she preferred. + AudioStreamBasicDescription *formatsAvailable; + MacOSXSoundOption *selectedOption=[selectedOutput representedObject]; + bool foundFormat=false; + UInt32 theSize; + Boolean outWritable; + OSStatus err; + UInt32 i; + intf_thread_t * p_intf = [NSApp getIntf]; + AudioDeviceID deviceID=[selectedOption deviceID]; + + // get the streamID (it might have changed) + AudioStreamID streamID=[self getStreamIDForIndex:[selectedOption streamIndex] device:deviceID]; + + // Find the actual formats + err = AudioStreamGetPropertyInfo(streamID, 0, kAudioStreamPropertyPhysicalFormats, &theSize, &outWritable); + formatsAvailable=(AudioStreamBasicDescription*) malloc(theSize); + err = AudioStreamGetProperty(streamID, 0, kAudioStreamPropertyPhysicalFormats, &theSize, formatsAvailable); + if(err) + { + msg_Err(p_intf, "Error %4.4s getting the stream formats", &err); + return 0; + }; + + UInt32 formtmp=[selectedOption mFormatID]; + if(DEBUG_ASYSTM) msg_Dbg(p_intf, "looking for: %4.4s - %d chans, %d Hz", &formtmp, + [selectedOption mChannels], preferredSampleRate); + + // Check if there's a "best match" which has our required rate + for(i=0; i100) { + msg_Err(p_intf, "bogus format! index %i", i); + return 0; + }; + + if( formatsAvailable[i].mFormatID == [selectedOption mFormatID] + && formatsAvailable[i].mChannelsPerFrame == [selectedOption mChannels] + && (int)formatsAvailable[i].mSampleRate == preferredSampleRate) + { + if(DEBUG_ASYSTM) msg_Dbg(p_intf, "Found the perfect format!!"); + foundFormat=true; + break; + }; + }; + + int rate=MAXINT, format=0; + if(!foundFormat) + { + for(i=0; i preferredSampleRate) + { + if(actrate < rate) + { + rate=actrate; + format=i; + } + }; + }; + if(rate!=MAXINT) // This means we have found a rate!! Yes! + { + if(DEBUG_ASYSTM) msg_Dbg(p_intf, "Only got a format with higher sample rate"); + foundFormat=true; + i=format; + }; + }; + + if(!foundFormat) + { + rate=0; + for(i=0; i= preferredSampleRate) // We must have done something wrong + { + if(DEBUG_ASYSTM) msg_Err(p_intf, "Found a rate that should have been selected previously."); + free(formatsAvailable); + return 0; + }; + + if(actrate > rate) + { + rate=actrate; + format=i; + } + }; + + if(rate!=0) // This means we have found a rate!! Yes! + { + if(DEBUG_ASYSTM) msg_Dbg(p_intf, "Only got a format with lower sample rate"); + foundFormat=true; + i=format; + } + else // We must have done something wrong + { + msg_Err(p_intf, "Found no rate which is equal, higher or lower to requested rate. That means our device either: a) didn't exist in the first place or b) has been removed since."); + free(formatsAvailable); + return 0; + }; + }; + AudioStreamBasicDescription desc=formatsAvailable[i]; + free(formatsAvailable); + + // Set the device stream format + Boolean isWriteable; + + err = AudioStreamGetPropertyInfo(streamID, 0, kAudioStreamPropertyPhysicalFormat, &theSize, &isWriteable); + if(err) msg_Err(p_intf, "GetPropertyInfo (stream format) error %4.4s - theSize %d", &err, theSize); + if(DEBUG_ASYSTM) msg_Dbg(p_intf, "size %d, writable %d", theSize, isWriteable); + + if(DEBUG_ASYSTM) printStreamDescription("want to set", &desc); + + err = AudioStreamSetProperty(streamID, 0, 0, kAudioStreamPropertyPhysicalFormat, theSize, &desc); + if(err) msg_Err(p_intf, "SetProperty (stream format) error %4.4s - theSize %d", &err, theSize); + + // Because of the format change, the streamID has changed! + // That's why we return the deviceID. + return deviceID; +}; + + +- (void)dealloc +{ + [main release]; +}; + + +@end diff --git a/modules/gui/macosx/intf.h b/modules/gui/macosx/intf.h index 276ef928d1..81226c57ef 100644 --- a/modules/gui/macosx/intf.h +++ b/modules/gui/macosx/intf.h @@ -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 * Christophe Massiot @@ -22,6 +22,12 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. *****************************************************************************/ +#include +#include +#include + +#include + /***************************************************************************** * 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) diff --git a/modules/gui/macosx/intf.m b/modules/gui/macosx/intf.m index e5f08eda5a..a97d22d0d5 100644 --- a/modules/gui/macosx/intf.m +++ b/modules/gui/macosx/intf.m @@ -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 * Christophe Massiot @@ -29,16 +29,12 @@ #include /* for MAXPATHLEN */ #include -#include -#include -#include - -#include #include #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 -- 2.39.5