Added output device selection through preferences...hopefully.

CQTexperiment
vspader 2007-02-20 01:02:23 +00:00
parent 055c0b29a3
commit 0b0834a7ff
15 changed files with 246 additions and 12 deletions

View File

@ -21,6 +21,8 @@
IBOutlet NSButton *playButton;
IBOutlet NSArrayController *outputDevices;
NSTimer *positionTimer;
BOOL waitingForPlay; //No sneaky changing on us

View File

@ -26,7 +26,7 @@
[volumeSlider setDoubleValue:pow(10.0, log10(0.5)/4.0)*[volumeSlider maxValue]];
}
- (IBAction)playPauseResume:(id)sender
{
DBLog(@"PLAYING");

View File

@ -26,12 +26,25 @@
SUPERCLASS = PreferencePane;
},
{CLASS = NDHotKeyControl; LANGUAGE = ObjC; SUPERCLASS = NSTextField; },
{
ACTIONS = {takeDeviceID = id; };
CLASS = OutputPane;
LANGUAGE = ObjC;
OUTLETS = {outputDevices = OutputsArrayController; };
SUPERCLASS = PreferencePane;
},
{
CLASS = OutputsArrayController;
LANGUAGE = ObjC;
SUPERCLASS = NSArrayController;
},
{
CLASS = PrefPaneController;
LANGUAGE = ObjC;
OUTLETS = {
fileDrawerPane = FileDrawerPane;
hotKeyPane = HotKeyPane;
outputPane = OutputPane;
remotePane = RemotePane;
updatesPane = UpdatesPane;
};

View File

@ -3,17 +3,19 @@
<plist version="1.0">
<dict>
<key>IBDocumentLocation</key>
<string>102 216 356 240 0 0 1024 746 </string>
<string>218 642 356 240 0 0 1680 1028 </string>
<key>IBEditorPositions</key>
<dict>
<key>10</key>
<string>259 468 506 102 0 0 1024 746 </string>
<string>587 659 506 102 0 0 1680 1028 </string>
<key>11</key>
<string>375 444 273 151 0 0 1024 746 </string>
<string>703 634 273 151 0 0 1680 1028 </string>
<key>43</key>
<string>166 564 337 96 0 0 1024 746 </string>
<string>671 662 337 96 0 0 1680 1028 </string>
<key>50</key>
<string>233 146 355 96 0 0 1024 746 </string>
<string>662 662 355 96 0 0 1680 1028 </string>
<key>58</key>
<string>634 659 411 101 0 0 1680 1028 </string>
</dict>
<key>IBFramework Version</key>
<string>446.1</string>
@ -21,10 +23,11 @@
<array>
<integer>11</integer>
<integer>10</integer>
<integer>58</integer>
<integer>50</integer>
<integer>43</integer>
</array>
<key>IBSystem Version</key>
<string>8L127</string>
<string>8L2127</string>
</dict>
</plist>

View File

@ -9,6 +9,11 @@
/* Begin PBXBuildFile section */
172D72480B891FEF00D095BB /* RemotePane.m in Sources */ = {isa = PBXBuildFile; fileRef = 172D72470B891FEF00D095BB /* RemotePane.m */; };
172D72AD0B8926CA00D095BB /* apple_remote.png in Resources */ = {isa = PBXBuildFile; fileRef = 172D72AC0B8926CA00D095BB /* apple_remote.png */; };
17C643380B8A77CC00C53518 /* OutputsArrayController.m in Sources */ = {isa = PBXBuildFile; fileRef = 17C643360B8A77CC00C53518 /* OutputsArrayController.m */; };
17C6433F0B8A783F00C53518 /* OutputPane.m in Sources */ = {isa = PBXBuildFile; fileRef = 17C6433E0B8A783F00C53518 /* OutputPane.m */; };
17C643690B8A788000C53518 /* output.png in Resources */ = {isa = PBXBuildFile; fileRef = 17C643680B8A788000C53518 /* output.png */; };
17C644330B8A791D00C53518 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 17C644310B8A791D00C53518 /* CoreAudio.framework */; };
17C644340B8A791D00C53518 /* CoreAudioKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 17C644320B8A791D00C53518 /* CoreAudioKit.framework */; };
8D5B49B0048680CD000E48DA /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C167DFE841241C02AAC07 /* InfoPlist.strings */; };
8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; };
8E07AA870AAC8EA200A4B32F /* FileDrawerPane.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E07AA7F0AAC8EA200A4B32F /* FileDrawerPane.m */; };
@ -34,6 +39,13 @@
172D72460B891FEF00D095BB /* RemotePane.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = RemotePane.h; sourceTree = "<group>"; };
172D72470B891FEF00D095BB /* RemotePane.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = RemotePane.m; sourceTree = "<group>"; };
172D72AC0B8926CA00D095BB /* apple_remote.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = apple_remote.png; path = Icons/apple_remote.png; sourceTree = "<group>"; };
17C643360B8A77CC00C53518 /* OutputsArrayController.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = OutputsArrayController.m; sourceTree = "<group>"; };
17C643370B8A77CC00C53518 /* OutputsArrayController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = OutputsArrayController.h; sourceTree = "<group>"; };
17C6433D0B8A783F00C53518 /* OutputPane.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = OutputPane.h; sourceTree = "<group>"; };
17C6433E0B8A783F00C53518 /* OutputPane.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = OutputPane.m; sourceTree = "<group>"; };
17C643680B8A788000C53518 /* output.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = output.png; path = Icons/output.png; sourceTree = "<group>"; };
17C644310B8A791D00C53518 /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = /System/Library/Frameworks/CoreAudio.framework; sourceTree = "<absolute>"; };
17C644320B8A791D00C53518 /* CoreAudioKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudioKit.framework; path = /System/Library/Frameworks/CoreAudioKit.framework; sourceTree = "<absolute>"; };
32DBCF630370AF2F00C91783 /* General_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = General_Prefix.pch; sourceTree = "<group>"; };
8D5B49B6048680CD000E48DA /* General.preferencePane */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = General.preferencePane; sourceTree = BUILT_PRODUCTS_DIR; };
8D5B49B7048680CD000E48DA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = Info.plist; sourceTree = "<group>"; };
@ -69,6 +81,8 @@
files = (
8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */,
8E6C123A0AACAEF200819171 /* Carbon.framework in Frameworks */,
17C644330B8A791D00C53518 /* CoreAudio.framework in Frameworks */,
17C644340B8A791D00C53518 /* CoreAudioKit.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -131,6 +145,8 @@
1058C7AEFEA557BF11CA2CBB /* Other Frameworks */ = {
isa = PBXGroup;
children = (
17C644310B8A791D00C53518 /* CoreAudio.framework */,
17C644320B8A791D00C53518 /* CoreAudioKit.framework */,
089C167FFE841241C02AAC07 /* AppKit.framework */,
D2F7E65807B2D6F200F64583 /* CoreData.framework */,
089C1672FE841209C02AAC07 /* Foundation.framework */,
@ -151,6 +167,8 @@
172D72470B891FEF00D095BB /* RemotePane.m */,
8E15A8340B8944C4006DC802 /* UpdatesPane.h */,
8E15A8350B8944C4006DC802 /* UpdatesPane.m */,
17C6433D0B8A783F00C53518 /* OutputPane.h */,
17C6433E0B8A783F00C53518 /* OutputPane.m */,
);
name = Panes;
sourceTree = "<group>";
@ -164,6 +182,8 @@
8E6C12150AACAE4100819171 /* NDHotKeyEvent.m */,
8E6C139E0AACBAB500819171 /* HotKeyControl.h */,
8E6C139F0AACBAB500819171 /* HotKeyControl.m */,
17C643370B8A77CC00C53518 /* OutputsArrayController.h */,
17C643360B8A77CC00C53518 /* OutputsArrayController.m */,
);
name = Custom;
sourceTree = "<group>";
@ -187,6 +207,7 @@
8E07ABD90AAC95AF00A4B32F /* Icons */ = {
isa = PBXGroup;
children = (
17C643680B8A788000C53518 /* output.png */,
8E15A86B0B894768006DC802 /* updates.png */,
172D72AC0B8926CA00D095BB /* apple_remote.png */,
8E07ABDA0AAC95BC00A4B32F /* file_drawer.png */,
@ -242,6 +263,7 @@
8E07AC050AAC968C00A4B32F /* Preferences.nib in Resources */,
172D72AD0B8926CA00D095BB /* apple_remote.png in Resources */,
8E15A86C0B894768006DC802 /* updates.png in Resources */,
17C643690B8A788000C53518 /* output.png in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -261,6 +283,8 @@
8E6C13A00AACBAB500819171 /* HotKeyControl.m in Sources */,
172D72480B891FEF00D095BB /* RemotePane.m in Sources */,
8E15A8360B8944C4006DC802 /* UpdatesPane.m in Sources */,
17C643380B8A77CC00C53518 /* OutputsArrayController.m in Sources */,
17C6433F0B8A783F00C53518 /* OutputPane.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -0,0 +1,19 @@
//
// OutputPane.h
// Preferences
//
// Created by Vincent Spader on 9/4/06.
// Copyright 2006 Vincent Spader. All rights reserved.
//
#import <Cocoa/Cocoa.h>
#import "PreferencePane.h"
#import "OutputsArrayController.h"
@interface OutputPane : PreferencePane {
IBOutlet OutputsArrayController *outputDevices;
}
- (IBAction) takeDeviceID:(id)sender;
@end

View File

@ -0,0 +1,29 @@
//
// OutputPane.m
// Preferences
//
// Created by Vincent Spader on 9/4/06.
// Copyright 2006 Vincent Spader. All rights reserved.
//
#import "OutputPane.h"
@implementation OutputPane
- (void)awakeFromNib
{
NSLog(@"AWOKEN!");
[self setName:@"Output"];
[self setIcon:@"output"];
}
- (IBAction) takeDeviceID:(id)sender
{
NSLog(@"Taking thing: %@", [outputDevices selectedObjects]);
NSDictionary *device = [[outputDevices selectedObjects] objectAtIndex:0];
[[NSUserDefaults standardUserDefaults] setObject: device forKey:@"outputDevice"];
}
@end

View File

@ -0,0 +1,10 @@
/* OutputsArrayController */
#import <Cocoa/Cocoa.h>
#import <CoreAudio/AudioHardware.h>
@interface OutputsArrayController : NSArrayController
{
}
@end

View File

@ -0,0 +1,47 @@
#import "OutputsArrayController.h"
@implementation OutputsArrayController
- (void)awakeFromNib
{
NSLog(@"initOutputDeviceList");
[self removeObjects:[self arrangedObjects]];
[self setSelectsInsertedObjects:NO];
NSLog(@"OutputCoreAudio.setup()");
UInt32 propsize;
verify_noerr(AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices, &propsize, NULL));
int nDevices = propsize / sizeof(AudioDeviceID);
AudioDeviceID *devids = malloc(propsize);
verify_noerr(AudioHardwareGetProperty(kAudioHardwarePropertyDevices, &propsize, devids));
int i;
NSLog(@"Number of devices: %d", nDevices);
for (i = 0; i < nDevices; ++i) {
char name[64];
UInt32 maxlen = 64;
verify_noerr(AudioDeviceGetProperty(devids[i], 0, false, kAudioDevicePropertyDeviceName, &maxlen, name));
NSLog(@"Device: %d %s", devids[i], name);
// Ignore devices that have no output channels:
// This tells us the size of the buffer required to hold the information about the channels
UInt32 propSize;
verify_noerr(AudioDeviceGetPropertyInfo(devids[i], 0, false, kAudioDevicePropertyStreamConfiguration, &propSize, NULL));
// Knowing the size of the required buffer, we can determine how many channels there are
// without actually allocating a buffer and requesting the information.
// (we don't care about the exact number of channels, only if there are more than zero or not)
if (propSize <= sizeof(UInt32)) continue;
NSObject *deviceInfo = [NSDictionary dictionaryWithObjectsAndKeys:
[NSString stringWithCString:name], @"name",
[NSNumber numberWithLong:devids[i]], @"deviceID",
nil];
[self addObject:deviceInfo];
[deviceInfo release];
}
free(devids);
[self setSelectionIndex:0];
}
@end

View File

@ -13,17 +13,20 @@
#import "FileDrawerPane.h"
#import "RemotePane.h"
#import "UpdatesPane.h"
#import "OutputPane.h"
@interface PrefPaneController : NSObject <SS_PreferencePaneProtocol> {
IBOutlet HotKeyPane *hotKeyPane;
IBOutlet FileDrawerPane *fileDrawerPane;
IBOutlet RemotePane *remotePane;
IBOutlet UpdatesPane *updatesPane;
IBOutlet OutputPane *outputPane;
}
- (HotKeyPane *)hotKeyPane;
- (FileDrawerPane *)fileDrawerPane;
- (RemotePane *)remotePane;
- (UpdatesPane *)updatesPane;
- (UpdatesPane *)outputPane;
@end

View File

@ -18,7 +18,7 @@
PrefPaneController *prefPaneController = [[PrefPaneController alloc] init];
loaded = [NSBundle loadNibNamed:@"Preferences" owner:prefPaneController];
return [NSArray arrayWithObjects: [prefPaneController hotKeyPane], [prefPaneController fileDrawerPane], [prefPaneController remotePane], [prefPaneController updatesPane], nil];
return [NSArray arrayWithObjects: [prefPaneController hotKeyPane], [prefPaneController fileDrawerPane], [prefPaneController remotePane], [prefPaneController updatesPane], [prefPaneController outputPane], nil];
}
- (HotKeyPane *)hotKeyPane
@ -41,4 +41,9 @@
return updatesPane;
}
- (OutputPane *)outputPane
{
return outputPane;
}
@end

View File

@ -23,7 +23,11 @@
- (id)initWithController:(id)c;
- (BOOL)setup;
- (BOOL)setOutputDevice:(AudioDeviceID)outputDevice;
- (void)start;
- (void)pause;
- (void)resume;
- (void)stop;
- (void)setVolume:(double) v;

View File

@ -18,6 +18,8 @@
{
outputController = c;
outputUnit = NULL;
[[NSUserDefaultsController sharedUserDefaultsController] addObserver:self forKeyPath:@"values.outputDevice" options:0 context:NULL];
}
return self;
@ -54,11 +56,65 @@ static OSStatus Sound_Renderer(void *inRefCon, AudioUnitRenderActionFlags *ioAc
ioData->mBuffers[0].mDataByteSize = amountRead;
return err;
}
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if ([keyPath isEqualToString:@"values.outputDevice"]) {
NSLog(@"CHANGED!");
NSDictionary *device = [[[NSUserDefaultsController sharedUserDefaultsController] defaults] objectForKey:@"outputDevice"];
NSNumber *deviceID = [device objectForKey:@"deviceID"];
NSLog(@"Selecting output device %d %@", [deviceID longValue], [device objectForKey:@"name"]);
[self setOutputDevice:[deviceID longValue]];
}
}
- (BOOL)setOutputDevice:(AudioDeviceID)outputDevice
{
// Set the output device
AudioDeviceID deviceID = outputDevice; //XXX use default if null
NSLog(@"WEEE");
NSLog(@"Using output device %d", deviceID);
OSStatus err;
if (outputDevice == -1) {
UInt32 size = sizeof(AudioDeviceID);
err = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice,
&size,
&deviceID);
if (err != noErr) {
NSLog(@"THERES NO DEFAULT OUTPUT DEVICE! GARRRGGHHH");
return NO;
}
NSLog(@"Default output device: %i", deviceID);
}
err = AudioUnitSetProperty(outputUnit,
kAudioOutputUnitProperty_CurrentDevice,
kAudioUnitScope_Global,
0,
&deviceID,
sizeof(AudioDeviceID));
if (err != noErr) {
NSLog(@"THERES NO OUTPUT DEVICE! AHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH!!!!! %i", err);
return NO;
}
return YES;
}
- (BOOL)setup
{
DBLog(@"SETUP");
if (outputUnit)
[self stop];
@ -84,6 +140,7 @@ static OSStatus Sound_Renderer(void *inRefCon, AudioUnitRenderActionFlags *ioAc
if (err != noErr)
return NO;
NSLog(@"SETUP");
UInt32 size = sizeof (AudioStreamBasicDescription);
Boolean outWritable;
@ -138,6 +195,25 @@ static OSStatus Sound_Renderer(void *inRefCon, AudioUnitRenderActionFlags *ioAc
DBLog(@"Audio output successfully initialized");
NSDictionary *device = [[[NSUserDefaultsController sharedUserDefaultsController] defaults] objectForKey:@"outputDevice"];
if (device) {
NSLog(@"THIS ONE");
BOOL ok = [self setOutputDevice:[[device objectForKey:@"deviceID"] longValue]];
if (!ok) {
//Ruh roh.
[self setOutputDevice: -1];
[[[NSUserDefaultsController sharedUserDefaultsController] defaults] removeObjectForKey:@"outputDevice"];
}
}
else {
NSLog(@"THAT ONE");
[self setOutputDevice: -1];
}
NSLog(@"DONE SETTING UP");
return (err == noErr);
}

View File

@ -14,7 +14,7 @@
- (id)initWithDelegate:(id)d
{
DBLog(@"Initializing\n");
self = [super init];
if (self)
{
@ -120,7 +120,6 @@
- (void)setNextEntry:(PlaylistEntry *)pe
{
[pe retain];
NSLog(@"Releasing: %@", [pe display]);
[nextEntry release];
nextEntry = pe;
}