├── .gitignore ├── Framework ├── English.lproj │ └── InfoPlist.strings ├── Info.plist ├── PACardInfo.h ├── PACardInfo.m ├── PACardInfoInternal.h ├── PAClientInfo.h ├── PAClientInfo.m ├── PAClientInfoInternal.h ├── PAElementInfo.h ├── PAElementInfo.m ├── PAElementInfoInternal.h ├── PAHelperConnection.h ├── PAHelperConnection.m ├── PAModuleInfo.h ├── PAModuleInfo.m ├── PAModuleInfoInternal.h ├── PASampleInfo.h ├── PASampleInfo.m ├── PASampleInfoInternal.h ├── PAServerConnection.h ├── PAServerConnection.m ├── PAServerConnectionAudio.h ├── PAServerConnectionAudio.m ├── PAServerConnectionImplementation.h ├── PAServerConnectionImplementation.m ├── PAServerConnectionInternal.h ├── PAServerConnectionInternal.m ├── PAServerInfo.h ├── PAServerInfo.m ├── PAServerInfoInternal.h ├── PAServiceDiscovery.h ├── PAServiceDiscovery.m ├── PASinkInfo.h ├── PASinkInfo.m ├── PASinkInfoInternal.h ├── PASinkInputInfo.h ├── PASinkInputInfo.m ├── PASinkInputInfoInternal.h ├── PASourceInfo.h ├── PASourceInfo.m ├── PASourceInfoInternal.h ├── PASourceOutputInfo.h ├── PASourceOutputInfo.m ├── PASourceOutputInfoInternal.h ├── PulseAudio.h ├── PulseAudio.xcodeproj │ └── project.pbxproj ├── PulseAudio_Prefix.pch ├── ULINetSocket.h ├── ULINetSocket.m └── install.sh ├── HALPlugin ├── HALPlugin.xcodeproj │ └── project.pbxproj ├── Resources │ ├── Info.plist │ └── version.plist ├── Source │ ├── HALPlugin.exp │ ├── HALPlugin_Prefix.h │ ├── PADevice.h │ ├── PADevice.m │ ├── PADeviceAudio.h │ ├── PADeviceAudio.m │ ├── PAObject.h │ ├── PAObject.m │ ├── PAPlugInInterface.h │ ├── PAPlugInInterface.m │ ├── PAPlugin.h │ ├── PAPlugin.m │ ├── PAStream.h │ └── PAStream.m └── install.sh ├── PreferencePane ├── AudioClients.h ├── AudioClients.m ├── English.lproj │ ├── InfoPlist.strings │ └── PAPreferencePane.nib │ │ ├── designable.nib │ │ └── keyedobjects.nib ├── Growl.h ├── Growl.m ├── Growl_512x512.png ├── Info.plist ├── LocalServer.h ├── LocalServer.m ├── LoginItemController.h ├── LoginItemController.m ├── PAPreferencePane.tiff ├── PAPreferencePane.xcodeproj │ ├── .gitignore │ └── project.pbxproj ├── PreferencePane.h ├── PreferencePane.m ├── PulseAudio_Prefix.pch └── install.sh ├── PulseAudioHelper ├── ConnectionClient.h ├── ConnectionClient.m ├── ConnectionServer.h ├── ConnectionServer.m ├── GrowlNotifications.h ├── GrowlNotifications.m ├── LoginItemController.h ├── LoginItemController.m ├── Pathes.h ├── Preferences.h ├── Preferences.m ├── PulseAudio.png ├── PulseAudioHelper-Info.plist ├── PulseAudioHelper.xcodeproj │ └── project.pbxproj ├── PulseAudioHelper_Prefix.pch ├── ServerConnection.h ├── ServerConnection.m ├── ServerTask.h ├── ServerTask.m ├── StatusBar.h ├── StatusBar.m ├── install.sh ├── logo.icns ├── main.m └── statusBar.png ├── PulseConsole ├── Credits.rtf ├── DocumentController.h ├── DocumentController.m ├── English.lproj │ ├── InfoPlist.strings │ ├── MainMenu.xib │ └── Server.xib ├── Info.plist ├── Introspect.h ├── Introspect.m ├── MeterView.h ├── MeterView.m ├── MultipleLinesTextFieldCell.h ├── MultipleLinesTextFieldCell.m ├── PulseConsole.xcodeproj │ └── project.pbxproj ├── PulseConsole_Prefix.pch ├── Server.h ├── Server.m ├── ServerDocument.h ├── ServerDocument.m ├── StreamListView.h ├── StreamListView.m ├── StreamView.h ├── StreamView.m ├── logo.icns └── main.m ├── README.md ├── deploy ├── .gitignore ├── InstallerResources │ ├── License.rtf │ ├── background.tif │ └── postinstall ├── ReleaseNotes.txt ├── bootstrap_machine.sh ├── build.sh ├── build_pulseaudio.sh ├── deploy.sh ├── fixup_framework.sh ├── updateReleaseNotes.sh └── version.inc └── legacy ├── audioDaemon ├── audioDaemon.xcodeproj │ └── project.pbxproj ├── deviceClient.c ├── deviceClient.h ├── driverClient.c ├── driverClient.h ├── main.c ├── notificationCenter.c ├── notificationCenter.h ├── pulseAudio.c ├── pulseAudio.h ├── virtualDeviceClient.c └── virtualDeviceClient.h └── kext ├── BuildNames.h ├── English.lproj └── InfoPlist.strings ├── GPL ├── Info.plist ├── PAClip.cpp ├── PADevice.cpp ├── PADevice.h ├── PADeviceUserClient.cpp ├── PADeviceUserClient.h ├── PADeviceUserClientTypes.h ├── PADriver.cpp ├── PADriver.h ├── PADriverUserClient.cpp ├── PADriverUserClient.h ├── PADriverUserClientTypes.h ├── PAEngine.cpp ├── PAEngine.h ├── PALog.h ├── PAStream.cpp ├── PAStream.h ├── PAUserClient.cpp ├── PAUserClient.h ├── PAUserClientCommonTypes.h ├── PAUserClientTypes.h ├── PAVirtualDevice.cpp ├── PAVirtualDevice.h ├── PAVirtualDeviceUserClient.cpp ├── PAVirtualDeviceUserClient.h ├── PAVirtualDeviceUserClientTypes.h ├── PulseAudioKext.xcodeproj └── project.pbxproj ├── README └── load.sh /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | *.mode1v3 3 | *.pbxuser 4 | -------------------------------------------------------------------------------- /Framework/English.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Framework/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | org.pulseaudio.PulseAudioFramework 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | FMWK 19 | CFBundleShortVersionString 20 | 0.1 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | NSPrincipalClass 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Framework/PACardInfo.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License (LGPL) as 8 | published by the Free Software Foundation; either version 2.1 of the 9 | License, or (at your option) any later version. 10 | ***/ 11 | 12 | #import 13 | #import "PAElementInfo.h" 14 | 15 | @interface PACardInfo : PAElementInfo 16 | { 17 | NSString *driver; 18 | NSDictionary *properties; 19 | } 20 | 21 | @property (nonatomic, readonly) NSString *driver; 22 | @property (nonatomic, readonly) NSDictionary *properties; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /Framework/PACardInfo.m: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License (LGPL) as 8 | published by the Free Software Foundation; either version 2.1 of the 9 | License, or (at your option) any later version. 10 | ***/ 11 | 12 | #import "PACardInfoInternal.h" 13 | #import "PAServerConnectionInternal.h" 14 | 15 | @implementation PACardInfo 16 | 17 | @synthesize driver; 18 | @synthesize properties; 19 | 20 | @end 21 | 22 | @implementation PACardInfo (internal) 23 | 24 | - (void) loadFromInfoStruct: (const pa_card_info *) info 25 | { 26 | index = info->index; 27 | 28 | if (name) 29 | [name release]; 30 | name = [[NSString stringWithCString: info->name 31 | encoding: NSUTF8StringEncoding] retain]; 32 | if (driver) 33 | [driver release]; 34 | driver = [[NSString stringWithCString: info->driver 35 | encoding: NSUTF8StringEncoding] retain]; 36 | if (properties) 37 | [properties release]; 38 | properties = [[PAServerConnection createDictionaryFromProplist: info->proplist] retain]; 39 | 40 | if (initialized) 41 | [server performSelectorOnMainThread: @selector(sendDelegateCardInfoChanged:) 42 | withObject: self 43 | waitUntilDone: NO]; 44 | 45 | initialized = YES; 46 | } 47 | 48 | - (id) initWithInfoStruct: (const pa_card_info *) info 49 | server: (PAServerConnection *) s 50 | { 51 | [super initWithServer: s]; 52 | [self loadFromInfoStruct: info]; 53 | return self; 54 | } 55 | 56 | + (PACardInfo *) createFromInfoStruct: (const pa_card_info *) info 57 | server: (PAServerConnection *) s 58 | { 59 | return [[PACardInfo alloc] initWithInfoStruct: info 60 | server: s]; 61 | } 62 | 63 | @end 64 | 65 | -------------------------------------------------------------------------------- /Framework/PACardInfoInternal.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License (LGPL) as 8 | published by the Free Software Foundation; either version 2.1 of the 9 | License, or (at your option) any later version. 10 | ***/ 11 | 12 | #import 13 | #import 14 | 15 | #import "PAServerConnection.h" 16 | #import "PACardInfo.h" 17 | 18 | @interface PACardInfo (internal) 19 | 20 | + (PACardInfo *) createFromInfoStruct: (const pa_card_info *) info 21 | server: (PAServerConnection *) s; 22 | 23 | - (void) loadFromInfoStruct: (const pa_card_info *) info; 24 | 25 | @end 26 | 27 | -------------------------------------------------------------------------------- /Framework/PAClientInfo.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License (LGPL) as 8 | published by the Free Software Foundation; either version 2.1 of the 9 | License, or (at your option) any later version. 10 | ***/ 11 | 12 | #import 13 | #import "PAElementInfo.h" 14 | 15 | @interface PAClientInfo : PAElementInfo 16 | { 17 | NSString *driver; 18 | NSDictionary *properties; 19 | } 20 | 21 | @property (nonatomic, readonly) NSString *driver; 22 | @property (nonatomic, readonly) NSDictionary *properties; 23 | 24 | @end 25 | 26 | -------------------------------------------------------------------------------- /Framework/PAClientInfo.m: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License (LGPL) as 8 | published by the Free Software Foundation; either version 2.1 of the 9 | License, or (at your option) any later version. 10 | ***/ 11 | 12 | #import 13 | #import "PAClientInfoInternal.h" 14 | #import "PAServerConnectionInternal.h" 15 | 16 | @implementation PAClientInfo 17 | 18 | @synthesize driver; 19 | @synthesize properties; 20 | 21 | @end 22 | 23 | 24 | @implementation PAClientInfo (internal) 25 | 26 | - (void) loadFromInfoStruct: (const pa_client_info *) info 27 | { 28 | index = info->index; 29 | 30 | if (name) 31 | [name release]; 32 | name = [[NSString stringWithCString: info->name 33 | encoding: NSUTF8StringEncoding] retain]; 34 | if (driver) 35 | [driver release]; 36 | driver = [[NSString stringWithCString: info->driver 37 | encoding: NSUTF8StringEncoding] retain]; 38 | if (properties) 39 | [properties release]; 40 | properties = [[PAServerConnection createDictionaryFromProplist: info->proplist] retain]; 41 | 42 | if (initialized) 43 | [server performSelectorOnMainThread: @selector(sendDelegateClientInfoChanged:) 44 | withObject: self 45 | waitUntilDone: NO]; 46 | 47 | initialized = YES; 48 | } 49 | 50 | - (id) initWithInfoStruct: (const pa_client_info *) info 51 | server: (PAServerConnection *) s 52 | { 53 | [super initWithServer: s]; 54 | [self loadFromInfoStruct: info]; 55 | return self; 56 | } 57 | 58 | + (PAClientInfo *) createFromInfoStruct: (const pa_client_info *) info 59 | server: (PAServerConnection *) s 60 | { 61 | return [[PAClientInfo alloc] initWithInfoStruct: info 62 | server: s]; 63 | } 64 | 65 | @end 66 | 67 | -------------------------------------------------------------------------------- /Framework/PAClientInfoInternal.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License (LGPL) as 8 | published by the Free Software Foundation; either version 2.1 of the 9 | License, or (at your option) any later version. 10 | ***/ 11 | 12 | #import 13 | #import 14 | 15 | #import "PAServerConnection.h" 16 | #import "PAClientInfo.h" 17 | 18 | @interface PAClientInfo (internal) 19 | 20 | + (PAClientInfo *) createFromInfoStruct: (const pa_client_info *) info 21 | server: (PAServerConnection *) s; 22 | 23 | - (void) loadFromInfoStruct: (const pa_client_info *) info; 24 | 25 | @end 26 | 27 | -------------------------------------------------------------------------------- /Framework/PAElementInfo.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License (LGPL) as 8 | published by the Free Software Foundation; either version 2.1 of the 9 | License, or (at your option) any later version. 10 | ***/ 11 | 12 | #import 13 | 14 | #define PAElementInfoChangedNotification @"PAElementInfoChangedNotification" 15 | 16 | @class PAServerConnection; 17 | 18 | @interface PAElementInfo : NSObject 19 | { 20 | UInt32 index; 21 | PAServerConnection *server; 22 | NSString *name; 23 | 24 | BOOL initialized; 25 | } 26 | 27 | - (id) initWithServer: (PAServerConnection *) s; 28 | 29 | @property (nonatomic, readonly) UInt32 index; 30 | @property (nonatomic, readonly) PAServerConnection *server; 31 | @property (nonatomic, readonly) NSString *name; 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /Framework/PAElementInfo.m: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License (LGPL) as 8 | published by the Free Software Foundation; either version 2.1 of the 9 | License, or (at your option) any later version. 10 | ***/ 11 | 12 | #import "PAElementInfo.h" 13 | 14 | @implementation PAElementInfo 15 | @synthesize index; 16 | @synthesize server; 17 | @synthesize name; 18 | 19 | - (id) initWithServer: (PAServerConnection *) s 20 | { 21 | [super init]; 22 | server = s; 23 | return self; 24 | } 25 | 26 | @end 27 | 28 | @implementation PAElementInfo (internal) 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /Framework/PAElementInfoInternal.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License (LGPL) as 8 | published by the Free Software Foundation; either version 2.1 of the 9 | License, or (at your option) any later version. 10 | ***/ 11 | 12 | #import 13 | #import "PAElementInfo.h" 14 | 15 | @interface PAElementInfo (internal) 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Framework/PAHelperConnection.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License (LGPL) as 8 | published by the Free Software Foundation; either version 2.1 of the 9 | License, or (at your option) any later version. 10 | ***/ 11 | 12 | #import 13 | #import "ULINetSocket.h" 14 | 15 | #define PAOSX_HelperSocket @"/var/tmp/PAOSX_HelperSocket" 16 | #define PAOSX_HelperMagic 0xaffedead 17 | 18 | #define PAOSX_HelperName @"org.pulseaudio.PulseAudioHelper" 19 | #define PAOSX_HelperMsgServiceStarted @"org.pulseaudio.PulseAudioHelper.serviceStarted" 20 | 21 | #define PAOSX_MessageNameKey @"MessageName" 22 | #define PAOSX_MessageDictionaryKey @"MessageDictionaryKey" 23 | #define PAOSX_MessageRegisterClient @"MessageRegisterClient" 24 | #define PAOSX_MessageAudioClientStarted @"MessageAudioClientStarted" 25 | #define PAOSX_MessageAudioClientStopped @"MessageAudioClientStopped" 26 | #define PAOSX_MessageAudioClientsUpdate @"MessageAudioClientsUpdate" 27 | #define PAOSX_MessageRequestPreferences @"MessageRequestPreferences" 28 | #define PAOSX_MessageSetPreferences @"MessageSetPreferences" 29 | #define PAOSX_MessageSetAudioDevices @"MessageSetAudioDevices" 30 | #define PAOSX_MessageSetAudioClientConfig @"MessageSetAudioClientConfig" 31 | 32 | typedef struct PAHelperProtocolHeader { 33 | UInt32 magic; 34 | UInt32 length; 35 | } PAHelperProtocolHeader; 36 | 37 | @class PAHelperConnection; 38 | 39 | @protocol PAHelperConnectionDelegate 40 | @optional 41 | - (void) PAHelperConnectionEstablished: (PAHelperConnection *) connection; 42 | - (void) PAHelperConnectionDied: (PAHelperConnection *) connection; 43 | - (void) PAHelperConnection: (PAHelperConnection *) connection 44 | receivedMessage: (NSString *) name 45 | dict: (NSDictionary *) msg; 46 | @end 47 | 48 | @interface PAHelperConnection : NSObject 49 | { 50 | NSObject *delegate; 51 | 52 | @private 53 | ULINetSocket *socket; 54 | NSMutableData *inboundData; 55 | BOOL retry; 56 | NSTimer *retryTimer; 57 | } 58 | 59 | @property (nonatomic, assign) NSObject *delegate; 60 | @property (nonatomic, readonly) ULINetSocket *socket; 61 | 62 | - (id) initWithSocket: (ULINetSocket *) socket; 63 | - (void) scheduleOnCurrentRunLoop; 64 | 65 | - (BOOL) connectWithRetry: (BOOL) retry; 66 | - (BOOL) isConnected; 67 | - (void) sendMessage: (NSString *) name 68 | dict: (NSDictionary *) msg; 69 | 70 | @end 71 | -------------------------------------------------------------------------------- /Framework/PAModuleInfo.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License (LGPL) as 8 | published by the Free Software Foundation; either version 2.1 of the 9 | License, or (at your option) any later version. 10 | ***/ 11 | 12 | #import 13 | #import "PAElementInfo.h" 14 | 15 | @interface PAModuleInfo : PAElementInfo 16 | { 17 | NSString *argument; 18 | UInt32 useCount; 19 | NSDictionary *properties; 20 | } 21 | 22 | @property (nonatomic, readonly) NSString *argument; 23 | @property (nonatomic, readonly) UInt32 useCount; 24 | @property (nonatomic, readonly) NSDictionary *properties; 25 | 26 | - (BOOL) unload; 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /Framework/PAModuleInfo.m: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License (LGPL) as 8 | published by the Free Software Foundation; either version 2.1 of the 9 | License, or (at your option) any later version. 10 | ***/ 11 | 12 | #import "PAModuleInfoInternal.h" 13 | #import "PAServerConnectionInternal.h" 14 | 15 | @implementation PAModuleInfo 16 | 17 | @synthesize argument; 18 | @synthesize useCount; 19 | @synthesize properties; 20 | 21 | - (BOOL) unload 22 | { 23 | return [server unloadModule: self]; 24 | } 25 | 26 | @end 27 | 28 | @implementation PAModuleInfo (internal) 29 | 30 | - (void) loadFromInfoStruct: (const pa_module_info *) info 31 | { 32 | index = info->index; 33 | useCount = info->n_used; 34 | 35 | if (name) 36 | [name release]; 37 | 38 | name = [[NSString stringWithCString: info->name 39 | encoding: NSUTF8StringEncoding] retain]; 40 | if (argument) { 41 | [argument release]; 42 | argument = nil; 43 | } 44 | 45 | if (info->argument) 46 | argument = [[NSString stringWithCString: info->argument 47 | encoding: NSUTF8StringEncoding] retain]; 48 | if (properties) 49 | [properties release]; 50 | 51 | properties = [[PAServerConnection createDictionaryFromProplist: info->proplist] retain]; 52 | 53 | if (initialized) 54 | [server performSelectorOnMainThread: @selector(sendDelegateModuleInfoChanged:) 55 | withObject: self 56 | waitUntilDone: NO]; 57 | } 58 | 59 | - (id) initWithInfoStruct: (const pa_module_info *) info 60 | server: (PAServerConnection *) s 61 | { 62 | [super initWithServer: s]; 63 | [self loadFromInfoStruct: info]; 64 | return self; 65 | } 66 | 67 | + (PAModuleInfo *) createFromInfoStruct: (const pa_module_info *) info 68 | server: (PAServerConnection *) s 69 | { 70 | return [[PAModuleInfo alloc] initWithInfoStruct: info 71 | server: s]; 72 | } 73 | 74 | 75 | @end 76 | 77 | -------------------------------------------------------------------------------- /Framework/PAModuleInfoInternal.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License (LGPL) as 8 | published by the Free Software Foundation; either version 2.1 of the 9 | License, or (at your option) any later version. 10 | ***/ 11 | 12 | #import 13 | #import 14 | 15 | #import "PAServerConnection.h" 16 | #import "PAModuleInfo.h" 17 | 18 | @interface PAModuleInfo (internal) 19 | 20 | + (PAModuleInfo *) createFromInfoStruct: (const pa_module_info *) info 21 | server: (PAServerConnection *) s; 22 | 23 | - (void) loadFromInfoStruct: (const pa_module_info *) info; 24 | 25 | @end 26 | 27 | -------------------------------------------------------------------------------- /Framework/PASampleInfo.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License (LGPL) as 8 | published by the Free Software Foundation; either version 2.1 of the 9 | License, or (at your option) any later version. 10 | ***/ 11 | 12 | #import 13 | #import "PAElementInfo.h" 14 | 15 | @interface PASampleInfo : PAElementInfo 16 | { 17 | NSString *sampleSpec; 18 | NSString *channelMap; 19 | NSString *fileName; 20 | 21 | UInt64 duration; 22 | UInt64 bytes; 23 | 24 | BOOL lazy; 25 | } 26 | 27 | @property (nonatomic, readonly) NSString *sampleSpec; 28 | @property (nonatomic, readonly) NSString *channelMap; 29 | @property (nonatomic, readonly) NSString *fileName; 30 | @property (nonatomic, readonly) UInt64 duration; 31 | @property (nonatomic, readonly) UInt64 bytes; 32 | @property (nonatomic, readonly) BOOL lazy; 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /Framework/PASampleInfo.m: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License (LGPL) as 8 | published by the Free Software Foundation; either version 2.1 of the 9 | License, or (at your option) any later version. 10 | ***/ 11 | 12 | #import "PASampleInfoInternal.h" 13 | #import "PAServerConnectionInternal.h" 14 | 15 | @implementation PASampleInfo 16 | 17 | @synthesize sampleSpec; 18 | @synthesize channelMap; 19 | @synthesize fileName; 20 | @synthesize duration; 21 | @synthesize bytes; 22 | @synthesize lazy; 23 | 24 | @end 25 | 26 | 27 | @implementation PASampleInfo (internal) 28 | 29 | - (void) loadFromInfoStruct: (const pa_sample_info *) info 30 | { 31 | char tmp[100]; 32 | 33 | index = info->index; 34 | duration = info->duration; 35 | bytes = info->bytes; 36 | lazy = info->lazy; 37 | 38 | if (name) 39 | [name release]; 40 | 41 | name = [[NSString stringWithCString: info->name 42 | encoding: NSUTF8StringEncoding] retain]; 43 | if (sampleSpec) 44 | [sampleSpec release]; 45 | 46 | sampleSpec = [[NSString stringWithCString: pa_sample_spec_snprint(tmp, sizeof(tmp), &info->sample_spec) 47 | encoding: NSUTF8StringEncoding] retain]; 48 | if (channelMap) 49 | [channelMap release]; 50 | 51 | channelMap = [[NSString stringWithCString: pa_channel_map_snprint(tmp, sizeof(tmp), &info->channel_map) 52 | encoding: NSUTF8StringEncoding] retain]; 53 | if (fileName) { 54 | [fileName release]; 55 | fileName = nil; 56 | } 57 | 58 | if (info->filename) 59 | fileName = [[NSString stringWithCString: info->filename 60 | encoding: NSUTF8StringEncoding] retain]; 61 | 62 | if (initialized) 63 | [server performSelectorOnMainThread: @selector(sendDelegateSampleInfoChanged:) 64 | withObject: self 65 | waitUntilDone: NO]; 66 | initialized = YES; 67 | } 68 | 69 | - (id) initWithInfoStruct: (const pa_sample_info *) info 70 | server: (PAServerConnection *) s 71 | { 72 | [super initWithServer: s]; 73 | [self loadFromInfoStruct: info]; 74 | return self; 75 | } 76 | 77 | + (PASampleInfo *) createFromInfoStruct: (const pa_sample_info *) info 78 | server: (PAServerConnection *) s 79 | { 80 | return [[PASampleInfo alloc] initWithInfoStruct: info 81 | server: s]; 82 | } 83 | 84 | @end 85 | 86 | -------------------------------------------------------------------------------- /Framework/PASampleInfoInternal.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License (LGPL) as 8 | published by the Free Software Foundation; either version 2.1 of the 9 | License, or (at your option) any later version. 10 | ***/ 11 | 12 | #import 13 | #import 14 | 15 | #import "PAServerConnection.h" 16 | #import "PASampleInfo.h" 17 | 18 | @interface PASampleInfo (internal) 19 | 20 | + (PASampleInfo *) createFromInfoStruct: (const pa_sample_info *) info 21 | server: (PAServerConnection *) s; 22 | 23 | - (void) loadFromInfoStruct: (const pa_sample_info *) info; 24 | 25 | @end 26 | 27 | -------------------------------------------------------------------------------- /Framework/PAServerConnectionAudio.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License (LGPL) as 8 | published by the Free Software Foundation; either version 2.1 of the 9 | License, or (at your option) any later version. 10 | ***/ 11 | 12 | #import 13 | 14 | @class PAServerConnectionAudio; 15 | 16 | @interface PAServerConnectionAudio : NSObject 17 | { 18 | PAServerConnection *serverConnection; 19 | pa_context *PAContext; 20 | 21 | pa_stream *PARecordStream; 22 | pa_stream *PAPlaybackStream; 23 | 24 | pa_buffer_attr bufAttr; 25 | pa_sample_spec sampleSpec; 26 | UInt32 ioBufferFrameSize; 27 | 28 | char *inputDummyBuffer; 29 | char *outputDummyBuffer; 30 | 31 | Float64 sampleRate; 32 | UInt32 ioProcBufferSize; 33 | 34 | NSString *sinkForPlayback; 35 | NSString *sourceForRecord; 36 | } 37 | 38 | @property (nonatomic, readonly) NSString *sinkForPlayback; 39 | @property (nonatomic, readonly) NSString *sourceForRecord; 40 | 41 | - (id) initWithPAServerConnection: (PAServerConnection *) serverConnection 42 | context: (pa_context *) context 43 | nPlaybackChannels: (UInt32) nPlaybackChannels 44 | nRecordChannels: (UInt32) nRecordChannels 45 | sampleRate: (Float64) sampleRate 46 | ioProcBufferSize: (UInt32) ioProcBufferSize 47 | sinkForPlayback: (NSString *) sinkForPlayback 48 | sourceForRecord: (NSString *) sourceForRecord; 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /Framework/PAServerConnectionImplementation.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License (LGPL) as 8 | published by the Free Software Foundation; either version 2.1 of the 9 | License, or (at your option) any later version. 10 | ***/ 11 | 12 | #import 13 | #import 14 | 15 | #import "PulseAudio.h" 16 | #import "PAServerConnectionAudio.h" 17 | 18 | #import "PACardInfoInternal.h" 19 | #import "PAClientInfoInternal.h" 20 | #import "PAModuleInfoInternal.h" 21 | #import "PASampleInfoInternal.h" 22 | #import "PAServerInfoInternal.h" 23 | #import "PASinkInfoInternal.h" 24 | #import "PASinkInputInfoInternal.h" 25 | #import "PASourceInfoInternal.h" 26 | #import "PASourceOutputInfoInternal.h" 27 | 28 | @interface PAServerConnectionImplementation : NSObject 29 | { 30 | PAServerConnection *server; 31 | char procName[100]; 32 | 33 | pa_threaded_mainloop *PAMainLoop; 34 | pa_context *PAContext; 35 | 36 | PAServerConnectionAudio *audio; 37 | NSString *sinkForPlayback; 38 | NSString *sourceForRecord; 39 | 40 | PAServerInfo *serverInfo; 41 | 42 | NSMutableArray *presentCards; 43 | NSMutableArray *presentSinks; 44 | NSMutableArray *presentSinkInputs; 45 | NSMutableArray *presentSources; 46 | NSMutableArray *presentSourceOutputs; 47 | NSMutableArray *presentClients; 48 | NSMutableArray *presentModules; 49 | NSMutableArray *presentSamples; 50 | 51 | NSMutableArray *publishedCards; 52 | NSMutableArray *publishedSinks; 53 | NSMutableArray *publishedSinkInputs; 54 | NSMutableArray *publishedSources; 55 | NSMutableArray *publishedSourceOutputs; 56 | NSMutableArray *publishedClients; 57 | NSMutableArray *publishedModules; 58 | NSMutableArray *publishedSamples; 59 | 60 | NSString *lastError; 61 | } 62 | 63 | @property (nonatomic, readonly) pa_threaded_mainloop *PAMainLoop; 64 | @property (nonatomic, readonly) pa_context *PAContext; 65 | @property (nonatomic, readonly) NSString *lastError; 66 | 67 | @property (nonatomic, readonly) NSArray *presentCards; 68 | @property (nonatomic, readonly) NSArray *presentSinks; 69 | @property (nonatomic, readonly) NSArray *presentSinkInputs; 70 | @property (nonatomic, readonly) NSArray *presentSources; 71 | @property (nonatomic, readonly) NSArray *presentSourceOutputs; 72 | @property (nonatomic, readonly) NSArray *presentClients; 73 | @property (nonatomic, readonly) NSArray *presentModules; 74 | @property (nonatomic, readonly) NSArray *presentSamples; 75 | 76 | @property (nonatomic, readonly) PAServerInfo *serverInfo; 77 | 78 | @property (nonatomic, readonly) NSString *sinkForPlayback; 79 | @property (nonatomic, readonly) NSString *sourceForRecord; 80 | 81 | - (id) initForServer: (PAServerConnection *) s; 82 | 83 | - (void) connectToHost: (NSString *) hostName 84 | port: (int) port; 85 | - (void) disconnect; 86 | - (BOOL) isConnected; 87 | - (BOOL) addAudioPlaybackChannels: (UInt32) nPlaybackChannels 88 | recordChannels: (UInt32) nRecordChannels 89 | sampleRate: (Float32) sampleRate 90 | ioProcBufferSize: (UInt32) ioProcBufferSize 91 | sinkForPlayback: (NSString *) sink 92 | sourceForRecord: (NSString *) source; 93 | 94 | - (NSString *) clientName; 95 | - (void) setClientName: (NSString *) name; 96 | 97 | - (BOOL) loadModuleWithName: (NSString *) name 98 | arguments: (NSString *) arguments; 99 | 100 | - (BOOL) setDefaultSink: (NSString *) name; 101 | - (BOOL) setDefaultSource: (NSString *) name; 102 | 103 | - (UInt32) protocolVersion; 104 | - (UInt32) serverProtocolVersion; 105 | 106 | - (BOOL) isLocal; 107 | - (NSString *) serverName; 108 | - (void) shutdownServer; 109 | 110 | @end 111 | -------------------------------------------------------------------------------- /Framework/PAServerConnectionInternal.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License (LGPL) as 8 | published by the Free Software Foundation; either version 2.1 of the 9 | License, or (at your option) any later version. 10 | ***/ 11 | 12 | #import 13 | 14 | #import "PulseAudio.h" 15 | #import "PAServerConnectionAudio.h" 16 | 17 | #import "PACardInfoInternal.h" 18 | #import "PAClientInfoInternal.h" 19 | #import "PAModuleInfoInternal.h" 20 | #import "PASampleInfoInternal.h" 21 | #import "PAServerInfoInternal.h" 22 | #import "PASinkInfoInternal.h" 23 | #import "PASinkInputInfoInternal.h" 24 | #import "PASourceInfoInternal.h" 25 | #import "PASourceOutputInfoInternal.h" 26 | 27 | @interface PAServerConnection (internal) 28 | 29 | + (NSDictionary *) createDictionaryFromProplist: (pa_proplist *) plist; 30 | + (NSArray *) createChannelNamesArray: (const pa_channel_map *) map; 31 | 32 | - (void) setAudioStarted; 33 | - (BOOL) unloadModule: (PAModuleInfo *) module; 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /Framework/PAServerInfo.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License (LGPL) as 8 | published by the Free Software Foundation; either version 2.1 of the 9 | License, or (at your option) any later version. 10 | ***/ 11 | 12 | #import 13 | #import "PAElementInfo.h" 14 | 15 | @interface PAServerInfo : PAElementInfo 16 | { 17 | NSString *userName; 18 | NSString *hostName; 19 | NSString *serverName; 20 | NSString *version; 21 | NSString *sampleSpec; 22 | NSString *channelMap; 23 | NSString *defaultSinkName; 24 | NSString *defaultSourceName; 25 | 26 | UInt32 cookie; 27 | } 28 | 29 | @property (nonatomic, readonly) NSString *userName; 30 | @property (nonatomic, readonly) NSString *hostName; 31 | @property (nonatomic, readonly) NSString *serverName; 32 | @property (nonatomic, readonly) NSString *version; 33 | @property (nonatomic, readonly) NSString *sampleSpec; 34 | @property (nonatomic, readonly) NSString *channelMap; 35 | @property (nonatomic, readonly) NSString *defaultSinkName; 36 | @property (nonatomic, readonly) NSString *defaultSourceName; 37 | @property (nonatomic, readonly) UInt32 cookie; 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /Framework/PAServerInfo.m: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License (LGPL) as 8 | published by the Free Software Foundation; either version 2.1 of the 9 | License, or (at your option) any later version. 10 | ***/ 11 | 12 | #import "PAServerInfoInternal.h" 13 | #import "PAServerConnectionInternal.h" 14 | 15 | 16 | @implementation PAServerInfo 17 | 18 | @synthesize userName; 19 | @synthesize hostName; 20 | @synthesize serverName; 21 | @synthesize version; 22 | @synthesize sampleSpec; 23 | @synthesize channelMap; 24 | @synthesize defaultSinkName; 25 | @synthesize defaultSourceName; 26 | @synthesize cookie; 27 | 28 | @end 29 | 30 | 31 | @implementation PAServerInfo (internal) 32 | 33 | - (void) setFromInfoStruct: (const pa_server_info *) info 34 | server: (PAServerConnection *) s 35 | { 36 | char tmp[0x100]; 37 | 38 | userName = [[NSString stringWithCString: info->user_name 39 | encoding: NSUTF8StringEncoding] retain]; 40 | hostName = [[NSString stringWithCString: info->host_name 41 | encoding: NSUTF8StringEncoding] retain]; 42 | serverName = [[NSString stringWithCString: info->server_name 43 | encoding: NSUTF8StringEncoding] retain]; 44 | version = [[NSString stringWithCString: info->server_version 45 | encoding: NSUTF8StringEncoding] retain]; 46 | sampleSpec = [[NSString stringWithCString: pa_sample_spec_snprint(tmp, sizeof(tmp), &info->sample_spec) 47 | encoding: NSUTF8StringEncoding] retain]; 48 | channelMap = [[NSString stringWithCString: pa_channel_map_snprint(tmp, sizeof(tmp), &info->channel_map) 49 | encoding: NSUTF8StringEncoding] retain]; 50 | defaultSinkName = [[NSString stringWithCString: info->default_sink_name 51 | encoding: NSUTF8StringEncoding] retain]; 52 | defaultSourceName = [[NSString stringWithCString: info->default_source_name 53 | encoding: NSUTF8StringEncoding] retain]; 54 | cookie = info->cookie; 55 | 56 | server = s; 57 | 58 | name = @"Server Information"; 59 | } 60 | 61 | @end 62 | 63 | -------------------------------------------------------------------------------- /Framework/PAServerInfoInternal.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License (LGPL) as 8 | published by the Free Software Foundation; either version 2.1 of the 9 | License, or (at your option) any later version. 10 | ***/ 11 | 12 | #import 13 | #import 14 | 15 | #import "PAServerConnection.h" 16 | #import "PAServerInfo.h" 17 | 18 | @interface PAServerInfo (internal) 19 | 20 | - (void) setFromInfoStruct: (const pa_server_info *) info 21 | server: (PAServerConnection *) s; 22 | 23 | @end 24 | 25 | -------------------------------------------------------------------------------- /Framework/PAServiceDiscovery.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License (LGPL) as 8 | published by the Free Software Foundation; either version 2.1 of the 9 | License, or (at your option) any later version. 10 | ***/ 11 | 12 | #import 13 | 14 | @class PAServiceDiscovery; 15 | 16 | @protocol PAServiceDiscoveryDelegate 17 | @optional 18 | 19 | - (void) PAServiceDiscovery: (PAServiceDiscovery *) discovery 20 | serverAppeared: (NSNetService *) service; 21 | - (void) PAServiceDiscovery: (PAServiceDiscovery *) discovery 22 | serverDisappeared: (NSNetService *) service; 23 | 24 | - (void) PAServiceDiscovery: (PAServiceDiscovery *) discovery 25 | sinkAppeared: (NSNetService *) service; 26 | - (void) PAServiceDiscovery: (PAServiceDiscovery *) discovery 27 | sinkDisappeared: (NSNetService *) service; 28 | 29 | - (void) PAServiceDiscovery: (PAServiceDiscovery *) discovery 30 | sourceAppeared: (NSNetService *) service; 31 | - (void) PAServiceDiscovery: (PAServiceDiscovery *) discovery 32 | sourceDisappeared: (NSNetService *) service; 33 | 34 | @end 35 | 36 | @interface PAServiceDiscovery : NSObject 37 | { 38 | NSNetServiceBrowser *serverBrowser; 39 | NSNetServiceBrowser *sourceBrowser; 40 | NSNetServiceBrowser *sinkBrowser; 41 | NSMutableArray *netServices; 42 | NSMutableArray *announcedServices; 43 | NSLock *lock; 44 | 45 | NSObject *delegate; 46 | } 47 | 48 | @property (nonatomic, assign) NSObject *delegate; 49 | 50 | - (void) start; 51 | + (NSString *) ipOfService: (NSNetService *) service; 52 | 53 | @end 54 | -------------------------------------------------------------------------------- /Framework/PASinkInfo.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License (LGPL) as 8 | published by the Free Software Foundation; either version 2.1 of the 9 | License, or (at your option) any later version. 10 | ***/ 11 | 12 | #import 13 | #import "PAElementInfo.h" 14 | 15 | @interface PASinkInfo : PAElementInfo 16 | { 17 | NSString *description; 18 | NSString *sampleSpec; 19 | NSString *channelMap; 20 | NSString *driver; 21 | 22 | NSArray *channelNames; 23 | 24 | UInt32 latency; 25 | UInt32 configuredLatency; 26 | UInt32 nVolumeSteps; 27 | UInt32 volume; 28 | UInt32 monitorSourceIndex; 29 | 30 | NSDictionary *properties; 31 | } 32 | 33 | @property (nonatomic, readonly) NSString *description; 34 | @property (nonatomic, readonly) NSString *sampleSpec; 35 | @property (nonatomic, readonly) NSString *channelMap; 36 | @property (nonatomic, readonly) NSString *driver; 37 | @property (nonatomic, readonly) NSArray *channelNames; 38 | @property (nonatomic, readonly) UInt32 latency; 39 | @property (nonatomic, readonly) UInt32 configuredLatency; 40 | @property (nonatomic, readonly) UInt32 nVolumeSteps; 41 | @property (nonatomic, readwrite) UInt32 volume; 42 | @property (nonatomic, readonly) UInt32 monitorSourceIndex; 43 | @property (nonatomic, readonly) NSDictionary *properties; 44 | 45 | @end 46 | 47 | -------------------------------------------------------------------------------- /Framework/PASinkInfo.m: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License (LGPL) as 8 | published by the Free Software Foundation; either version 2.1 of the 9 | License, or (at your option) any later version. 10 | ***/ 11 | 12 | #import 13 | #import "PASinkInfoInternal.h" 14 | #import "PAServerConnectionInternal.h" 15 | #import "PAServerConnectionImplementation.h" 16 | 17 | @implementation PASinkInfo 18 | 19 | @synthesize description; 20 | @synthesize sampleSpec; 21 | @synthesize channelMap; 22 | @synthesize channelNames; 23 | @synthesize driver; 24 | @synthesize latency; 25 | @synthesize configuredLatency; 26 | @synthesize nVolumeSteps; 27 | @synthesize properties; 28 | @synthesize monitorSourceIndex; 29 | 30 | - (UInt32) volume 31 | { 32 | return self->volume; 33 | } 34 | 35 | - (void) setVolume: (UInt32) v 36 | { 37 | pa_cvolume pav; 38 | pa_cvolume_init(&pav); 39 | pa_cvolume_set(&pav, [channelNames count], v); 40 | 41 | pa_threaded_mainloop_lock(server.impl.PAMainLoop); 42 | pa_context_set_sink_volume_by_index(server.impl.PAContext, index, &pav, NULL, NULL); 43 | pa_threaded_mainloop_unlock(server.impl.PAMainLoop); 44 | 45 | volume = v; 46 | } 47 | 48 | @end 49 | 50 | 51 | @implementation PASinkInfo (internal) 52 | 53 | - (void) loadFromInfoStruct: (const pa_sink_info *) info 54 | { 55 | char tmp[0x100]; 56 | 57 | index = info->index; 58 | 59 | latency = info->latency; 60 | configuredLatency = info->configured_latency; 61 | nVolumeSteps = info->n_volume_steps; 62 | volume = pa_cvolume_avg(&info->volume); 63 | monitorSourceIndex = info->monitor_source; 64 | 65 | if (name) 66 | [name release]; 67 | 68 | name = [[NSString stringWithCString: info->name 69 | encoding: NSUTF8StringEncoding] retain]; 70 | 71 | if (description) 72 | [description release]; 73 | 74 | description = [[NSString stringWithCString: info->description 75 | encoding: NSUTF8StringEncoding] retain]; 76 | if (sampleSpec) 77 | [sampleSpec release]; 78 | 79 | sampleSpec = [[NSString stringWithCString: pa_sample_spec_snprint(tmp, sizeof(tmp), &info->sample_spec) 80 | encoding: NSUTF8StringEncoding] retain]; 81 | 82 | if (channelMap) 83 | [channelMap release]; 84 | 85 | channelMap = [[NSString stringWithCString: pa_channel_map_snprint(tmp, sizeof(tmp), &info->channel_map) 86 | encoding: NSUTF8StringEncoding] retain]; 87 | if (driver) 88 | [driver release]; 89 | 90 | driver = [[NSString stringWithCString: info->driver 91 | encoding: NSUTF8StringEncoding] retain]; 92 | if (channelNames) 93 | [channelNames release]; 94 | 95 | channelNames = [[PAServerConnection createChannelNamesArray: &info->channel_map] retain]; 96 | 97 | if (properties) 98 | [properties release]; 99 | 100 | properties = [[PAServerConnection createDictionaryFromProplist: info->proplist] retain]; 101 | 102 | if (initialized) 103 | [server performSelectorOnMainThread: @selector(sendDelegateSinkInfoChanged:) 104 | withObject: self 105 | waitUntilDone: NO]; 106 | 107 | initialized = YES; 108 | } 109 | 110 | - (id) initWithInfoStruct: (const pa_sink_info *) info 111 | server: (PAServerConnection *) s 112 | { 113 | [super initWithServer: s]; 114 | [self loadFromInfoStruct: info]; 115 | return self; 116 | } 117 | 118 | + (PASinkInfo *) createFromInfoStruct: (const pa_sink_info *) info 119 | server: (PAServerConnection *) s 120 | { 121 | return [[PASinkInfo alloc] initWithInfoStruct: info 122 | server: s]; 123 | } 124 | 125 | @end 126 | 127 | -------------------------------------------------------------------------------- /Framework/PASinkInfoInternal.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License (LGPL) as 8 | published by the Free Software Foundation; either version 2.1 of the 9 | License, or (at your option) any later version. 10 | ***/ 11 | 12 | #import 13 | #import 14 | 15 | #import "PAServerConnection.h" 16 | #import "PASinkInfo.h" 17 | 18 | @interface PASinkInfo (internal) 19 | 20 | + (PASinkInfo *) createFromInfoStruct: (const pa_sink_info *) info 21 | server: (PAServerConnection *) s; 22 | 23 | - (void) loadFromInfoStruct: (const pa_sink_info *) info; 24 | 25 | @end 26 | 27 | -------------------------------------------------------------------------------- /Framework/PASinkInputInfo.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License (LGPL) as 8 | published by the Free Software Foundation; either version 2.1 of the 9 | License, or (at your option) any later version. 10 | ***/ 11 | 12 | #import 13 | #import "PAElementInfo.h" 14 | 15 | @interface PASinkInputInfo : PAElementInfo 16 | { 17 | UInt32 volume; 18 | UInt32 bufferUsec; 19 | UInt32 sinkUsec; 20 | 21 | NSString *resampleMethod; 22 | NSString *driver; 23 | 24 | NSArray *channelNames; 25 | NSDictionary *properties; 26 | 27 | BOOL muted; 28 | BOOL volumeWriteable; 29 | } 30 | 31 | @property (nonatomic, readwrite) UInt32 volume; 32 | @property (nonatomic, readonly) UInt32 bufferUsec; 33 | @property (nonatomic, readonly) UInt32 sinkUsec; 34 | 35 | @property (nonatomic, readonly) NSString *resampleMethod; 36 | @property (nonatomic, readonly) NSString *driver; 37 | 38 | @property (nonatomic, readonly) NSArray *channelNames; 39 | @property (nonatomic, readonly) NSDictionary *properties; 40 | 41 | @property (nonatomic, readwrite) BOOL muted; 42 | @property (nonatomic, readonly) BOOL volumeWriteable; 43 | 44 | @end 45 | 46 | -------------------------------------------------------------------------------- /Framework/PASinkInputInfo.m: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License (LGPL) as 8 | published by the Free Software Foundation; either version 2.1 of the 9 | License, or (at your option) any later version. 10 | ***/ 11 | 12 | #import 13 | #import "PASinkInputInfoInternal.h" 14 | #import "PAServerConnectionInternal.h" 15 | #import "PAServerConnectionImplementation.h" 16 | 17 | @implementation PASinkInputInfo 18 | 19 | @synthesize bufferUsec; 20 | @synthesize sinkUsec; 21 | 22 | @synthesize resampleMethod; 23 | @synthesize driver; 24 | 25 | @synthesize channelNames; 26 | @synthesize properties; 27 | 28 | @synthesize volumeWriteable; 29 | 30 | - (BOOL) muted 31 | { 32 | return self->muted; 33 | } 34 | 35 | - (void) setMuted: (BOOL) m 36 | { 37 | pa_threaded_mainloop_lock(server.impl.PAMainLoop); 38 | pa_context_set_sink_input_mute(server.impl.PAContext, index, m, NULL, NULL); 39 | pa_threaded_mainloop_unlock(server.impl.PAMainLoop); 40 | 41 | muted = m; 42 | } 43 | 44 | - (UInt32) volume 45 | { 46 | return self->volume; 47 | } 48 | 49 | - (void) setVolume: (UInt32) v 50 | { 51 | pa_cvolume pav; 52 | pa_cvolume_init(&pav); 53 | pa_cvolume_set(&pav, [channelNames count], v); 54 | 55 | pa_threaded_mainloop_lock(server.impl.PAMainLoop); 56 | pa_context_set_sink_input_volume(server.impl.PAContext, index, &pav, NULL, NULL); 57 | pa_threaded_mainloop_unlock(server.impl.PAMainLoop); 58 | 59 | volume = v; 60 | } 61 | 62 | @end 63 | 64 | 65 | @implementation PASinkInputInfo (internal) 66 | 67 | - (void) loadFromInfoStruct: (const pa_sink_input_info *) info 68 | { 69 | index = info->index; 70 | bufferUsec = info->buffer_usec; 71 | sinkUsec = info->sink_usec; 72 | muted = !!info->mute; 73 | volume = pa_cvolume_avg(&info->volume); 74 | volumeWriteable = !!info->volume_writable; 75 | 76 | if (name) { 77 | [name release]; 78 | name = nil; 79 | } 80 | 81 | if (info->name) 82 | name = [[NSString stringWithCString: info->name 83 | encoding: NSUTF8StringEncoding] retain]; 84 | 85 | if (driver) 86 | [driver release]; 87 | driver = [[NSString stringWithCString: info->driver 88 | encoding: NSUTF8StringEncoding] retain]; 89 | 90 | if (resampleMethod) { 91 | [resampleMethod release]; 92 | resampleMethod = nil; 93 | } 94 | 95 | if (info->resample_method) 96 | resampleMethod = [[NSString stringWithCString: info->resample_method 97 | encoding: NSUTF8StringEncoding] retain]; 98 | 99 | if (channelNames) 100 | [channelNames release]; 101 | channelNames = [[PAServerConnection createChannelNamesArray: &info->channel_map] retain]; 102 | 103 | if (properties) 104 | [properties release]; 105 | properties = [[PAServerConnection createDictionaryFromProplist: info->proplist] retain]; 106 | 107 | if (initialized) 108 | [server performSelectorOnMainThread: @selector(sendDelegateSinkInputInfoChanged:) 109 | withObject: self 110 | waitUntilDone: NO]; 111 | 112 | initialized = YES; 113 | } 114 | 115 | - (id) initWithInfoStruct: (const pa_sink_input_info *) info 116 | server: (PAServerConnection *) s 117 | { 118 | [super initWithServer: s]; 119 | [self loadFromInfoStruct: info]; 120 | return self; 121 | } 122 | 123 | + (PASinkInputInfo *) createFromInfoStruct: (const pa_sink_input_info *) info 124 | server: (PAServerConnection *) s 125 | { 126 | return [[PASinkInputInfo alloc] initWithInfoStruct: info 127 | server: s]; 128 | } 129 | 130 | @end 131 | 132 | -------------------------------------------------------------------------------- /Framework/PASinkInputInfoInternal.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License (LGPL) as 8 | published by the Free Software Foundation; either version 2.1 of the 9 | License, or (at your option) any later version. 10 | ***/ 11 | 12 | #import 13 | #import 14 | 15 | #import "PAServerConnection.h" 16 | #import "PASinkInputInfo.h" 17 | 18 | @interface PASinkInputInfo (internal) 19 | 20 | + (PASinkInputInfo *) createFromInfoStruct: (const pa_sink_input_info *) info 21 | server: (PAServerConnection *) s; 22 | 23 | - (void) loadFromInfoStruct: (const pa_sink_input_info *) info; 24 | 25 | @end 26 | 27 | -------------------------------------------------------------------------------- /Framework/PASourceInfo.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License (LGPL) as 8 | published by the Free Software Foundation; either version 2.1 of the 9 | License, or (at your option) any later version. 10 | ***/ 11 | 12 | #import 13 | #import "PAElementInfo.h" 14 | 15 | @interface PASourceInfo : PAElementInfo 16 | { 17 | NSString *description; 18 | NSString *sampleSpec; 19 | NSString *channelMap; 20 | NSString *driver; 21 | 22 | NSArray *channelNames; 23 | 24 | UInt32 latency; 25 | UInt32 configuredLatency; 26 | 27 | NSDictionary *properties; 28 | } 29 | 30 | @property (nonatomic, readonly) NSString *description; 31 | @property (nonatomic, readonly) NSString *sampleSpec; 32 | @property (nonatomic, readonly) NSString *channelMap; 33 | @property (nonatomic, readonly) NSString *driver; 34 | @property (nonatomic, readonly) NSArray *channelNames; 35 | @property (nonatomic, readonly) UInt32 latency; 36 | @property (nonatomic, readonly) UInt32 configuredLatency; 37 | @property (nonatomic, readonly) NSDictionary *properties; 38 | 39 | @end 40 | 41 | -------------------------------------------------------------------------------- /Framework/PASourceInfo.m: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License (LGPL) as 8 | published by the Free Software Foundation; either version 2.1 of the 9 | License, or (at your option) any later version. 10 | ***/ 11 | 12 | #import "PASourceInfoInternal.h" 13 | #import "PAServerConnectionInternal.h" 14 | 15 | 16 | @implementation PASourceInfo 17 | 18 | @synthesize description; 19 | @synthesize sampleSpec; 20 | @synthesize channelMap; 21 | @synthesize channelNames; 22 | @synthesize driver; 23 | @synthesize latency; 24 | @synthesize configuredLatency; 25 | @synthesize properties; 26 | 27 | @end 28 | 29 | 30 | @implementation PASourceInfo (internal) 31 | 32 | - (void) loadFromInfoStruct: (const pa_source_info *) info 33 | { 34 | char tmp[0x100]; 35 | 36 | index = info->index; 37 | latency = info->latency; 38 | configuredLatency = info->configured_latency; 39 | 40 | if (name) 41 | [name release]; 42 | name = [[NSString stringWithCString: info->name 43 | encoding: NSUTF8StringEncoding] retain]; 44 | 45 | if (description) 46 | [description release]; 47 | description = [[NSString stringWithCString: info->description 48 | encoding: NSUTF8StringEncoding] retain]; 49 | 50 | if (sampleSpec) 51 | [sampleSpec release]; 52 | sampleSpec = [[NSString stringWithCString: pa_sample_spec_snprint(tmp, sizeof(tmp), &info->sample_spec) 53 | encoding: NSUTF8StringEncoding] retain]; 54 | 55 | if (channelMap) 56 | [channelMap release]; 57 | channelMap = [[NSString stringWithCString: pa_channel_map_snprint(tmp, sizeof(tmp), &info->channel_map) 58 | encoding: NSUTF8StringEncoding] retain]; 59 | 60 | if (driver) 61 | [driver release]; 62 | driver = [[NSString stringWithCString: info->driver 63 | encoding: NSUTF8StringEncoding] retain]; 64 | 65 | if (properties) 66 | [properties release]; 67 | properties = [[PAServerConnection createDictionaryFromProplist: info->proplist] retain]; 68 | 69 | if (initialized) 70 | [server performSelectorOnMainThread: @selector(sendDelegateSourceInfoChanged:) 71 | withObject: self 72 | waitUntilDone: NO]; 73 | 74 | initialized = YES; 75 | } 76 | 77 | - (id) initWithInfoStruct: (const pa_source_info *) info 78 | server: (PAServerConnection *) s 79 | { 80 | [super initWithServer: s]; 81 | [self loadFromInfoStruct: info]; 82 | return self; 83 | } 84 | 85 | + (PASourceInfo *) createFromInfoStruct: (const pa_source_info *) info 86 | server: (PAServerConnection *) s 87 | { 88 | return [[PASourceInfo alloc] initWithInfoStruct: info 89 | server: s]; 90 | } 91 | 92 | @end 93 | 94 | -------------------------------------------------------------------------------- /Framework/PASourceInfoInternal.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License (LGPL) as 8 | published by the Free Software Foundation; either version 2.1 of the 9 | License, or (at your option) any later version. 10 | ***/ 11 | 12 | #import 13 | #import 14 | 15 | #import "PAServerConnection.h" 16 | #import "PASourceInfo.h" 17 | 18 | @interface PASourceInfo (internal) 19 | 20 | + (PASourceInfo *) createFromInfoStruct: (const pa_source_info *) info 21 | server: (PAServerConnection *) s; 22 | 23 | - (void) loadFromInfoStruct: (const pa_source_info *) info; 24 | 25 | @end 26 | 27 | -------------------------------------------------------------------------------- /Framework/PASourceOutputInfo.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License (LGPL) as 8 | published by the Free Software Foundation; either version 2.1 of the 9 | License, or (at your option) any later version. 10 | ***/ 11 | 12 | #import 13 | #import "PAElementInfo.h" 14 | 15 | @interface PASourceOutputInfo : PAElementInfo 16 | { 17 | UInt32 bufferUsec; 18 | UInt32 sourceUsec; 19 | 20 | NSString *resampleMethod; 21 | NSString *driver; 22 | 23 | NSArray *channelNames; 24 | NSDictionary *properties; 25 | 26 | BOOL corked; 27 | } 28 | 29 | @property (nonatomic, readonly) UInt32 bufferUsec; 30 | @property (nonatomic, readonly) UInt32 sourceUsec; 31 | 32 | @property (nonatomic, readonly) NSString *resampleMethod; 33 | @property (nonatomic, readonly) NSString *driver; 34 | 35 | @property (nonatomic, readonly) NSArray *channelNames; 36 | @property (nonatomic, readonly) NSDictionary *properties; 37 | 38 | @property (nonatomic, readonly) BOOL corked; 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /Framework/PASourceOutputInfo.m: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License (LGPL) as 8 | published by the Free Software Foundation; either version 2.1 of the 9 | License, or (at your option) any later version. 10 | ***/ 11 | 12 | #import "PASourceOutputInfoInternal.h" 13 | #import "PAServerConnectionInternal.h" 14 | 15 | @implementation PASourceOutputInfo 16 | 17 | @synthesize bufferUsec; 18 | @synthesize sourceUsec; 19 | 20 | @synthesize resampleMethod; 21 | @synthesize driver; 22 | 23 | @synthesize channelNames; 24 | @synthesize properties; 25 | 26 | @synthesize corked; 27 | 28 | @end 29 | 30 | 31 | @implementation PASourceOutputInfo (internal) 32 | 33 | - (void) loadFromInfoStruct: (const pa_source_output_info *) info 34 | { 35 | index = info->index; 36 | bufferUsec = info->buffer_usec; 37 | sourceUsec = info->source_usec; 38 | corked = !!info->corked; 39 | 40 | if (name) 41 | [name release]; 42 | 43 | name = [[NSString stringWithCString: info->name 44 | encoding: NSUTF8StringEncoding] retain]; 45 | 46 | if (driver) 47 | [driver release]; 48 | 49 | driver = [[NSString stringWithCString: info->driver 50 | encoding: NSUTF8StringEncoding] retain]; 51 | 52 | if (channelNames) 53 | [channelNames release]; 54 | 55 | channelNames = [[PAServerConnection createChannelNamesArray: &info->channel_map] retain]; 56 | 57 | if (resampleMethod) { 58 | [resampleMethod release]; 59 | resampleMethod = nil; 60 | } 61 | 62 | if (info->resample_method) 63 | resampleMethod = [[NSString stringWithCString: info->resample_method 64 | encoding: NSUTF8StringEncoding] retain]; 65 | if (properties) 66 | [properties release]; 67 | 68 | properties = [[PAServerConnection createDictionaryFromProplist: info->proplist] retain]; 69 | 70 | if (initialized) 71 | [server performSelectorOnMainThread: @selector(sendDelegateSourceOutputInfoChanged:) 72 | withObject: self 73 | waitUntilDone: NO]; 74 | 75 | initialized = YES; 76 | } 77 | 78 | - (id) initWithInfoStruct: (const pa_source_output_info *) info 79 | server: (PAServerConnection *) s 80 | { 81 | [super initWithServer: s]; 82 | [self loadFromInfoStruct: info]; 83 | 84 | return self; 85 | } 86 | 87 | + (PASourceOutputInfo *) createFromInfoStruct: (const pa_source_output_info *) info 88 | server: (PAServerConnection *) s 89 | { 90 | return [[PASourceOutputInfo alloc] initWithInfoStruct: info 91 | server: s]; 92 | } 93 | 94 | @end 95 | 96 | -------------------------------------------------------------------------------- /Framework/PASourceOutputInfoInternal.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License (LGPL) as 8 | published by the Free Software Foundation; either version 2.1 of the 9 | License, or (at your option) any later version. 10 | ***/ 11 | 12 | #import 13 | #import 14 | 15 | #import "PAElementInfo.h" 16 | #import "PAServerConnection.h" 17 | #import "PASourceOutputInfo.h" 18 | 19 | @interface PASourceOutputInfo (internal) 20 | 21 | + (PASourceOutputInfo *) createFromInfoStruct: (const pa_source_output_info *) info 22 | server: (PAServerConnection *) s; 23 | 24 | - (void) loadFromInfoStruct: (const pa_source_output_info *) info; 25 | 26 | @end 27 | 28 | -------------------------------------------------------------------------------- /Framework/PulseAudio.h: -------------------------------------------------------------------------------- 1 | #import "PACardInfo.h" 2 | #import "PAClientInfo.h" 3 | #import "PAModuleInfo.h" 4 | #import "PASampleInfo.h" 5 | #import "PAServerConnection.h" 6 | #import "PAServerInfo.h" 7 | #import "PASinkInfo.h" 8 | #import "PASinkInputInfo.h" 9 | #import "PASourceInfo.h" 10 | #import "PASourceOutputInfo.h" 11 | #import "PAServiceDiscovery.h" 12 | #import "PAHelperConnection.h" 13 | -------------------------------------------------------------------------------- /Framework/PulseAudio_Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'PulseAudio' target in the 'PulseAudio' project. 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | -------------------------------------------------------------------------------- /Framework/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | name=PulseAudio.framework 4 | dest=/Library/Frameworks/ 5 | config=Release 6 | 7 | test -d $dest/$name || mkdir $dest/$name 8 | cp -a build/$config/$name/* $dest/$name/ 9 | mkdir -p $dest/$name/Contents/MacOS 10 | mkdir -p $dest/$name/Contents/Resources 11 | 12 | -------------------------------------------------------------------------------- /HALPlugin/Resources/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | PulseAudio 9 | CFBundleIdentifier 10 | org.pulseaudio.HALPlugin 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | PulseAudio 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 0.1.0 23 | CFPlugInFactories 24 | 25 | 45F4645C-E875-4364-9296-95837C4B7292 26 | New_PAHAL_PlugIn 27 | 28 | CFPlugInTypes 29 | 30 | F8BB1C28-BAE8-11D6-9C31-00039315CD46 31 | 32 | 45F4645C-E875-4364-9296-95837C4B7292 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /HALPlugin/Resources/version.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildVersion 6 | 1 7 | CFBundleShortVersionString 8 | 1.0.0 9 | CFBundleVersion 10 | 1.0 11 | ProjectName 12 | CoreAudioExamples 13 | SourceVersion 14 | 570000 15 | 16 | 17 | -------------------------------------------------------------------------------- /HALPlugin/Source/HALPlugin.exp: -------------------------------------------------------------------------------- 1 | _New_PAHAL_PlugIn 2 | -------------------------------------------------------------------------------- /HALPlugin/Source/HALPlugin_Prefix.h: -------------------------------------------------------------------------------- 1 | #ifndef _PAHARDWAREPLUGINPREFIX_H_ 2 | #define _PAHARDWAREPLUGINPREFIX_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #if defined(__cplusplus) 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #endif 19 | 20 | #endif /* _PAHARDWAREPLUGINPREFIX_H_ */ 21 | -------------------------------------------------------------------------------- /HALPlugin/Source/PADeviceAudio.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License (LGPL) as 8 | published by the Free Software Foundation; either version 2.1 of the 9 | License, or (at your option) any later version. 10 | ***/ 11 | 12 | #import 13 | #import 14 | 15 | @class PADevice; 16 | 17 | typedef struct IOProcTracker IOProcTracker; 18 | 19 | @interface PADeviceAudio : NSObject 20 | { 21 | PADevice *device; 22 | IOProcTracker *tracker; 23 | NSLock *lock; 24 | UInt32 ioProcBufferSize; 25 | UInt32 bytesPerSampleFrame; 26 | Float64 sampleRate; 27 | } 28 | 29 | @property (nonatomic, assign) UInt32 ioProcBufferSize; 30 | @property (nonatomic, readonly) UInt32 bytesPerSampleFrame; 31 | @property (nonatomic, assign) Float64 sampleRate; 32 | 33 | - (id) initWithPADevice: (PADevice *) device; 34 | 35 | - (AudioDeviceIOProcID) createIOProcID: (AudioDeviceIOProc) proc 36 | clientData: (void *) clientData; 37 | - (BOOL) hasActiveProcs; 38 | - (UInt32) countActivePlaybackChannels; 39 | - (UInt32) countActiveRecordChannels; 40 | - (BOOL) channelIsActive: (UInt32) channel; 41 | - (void) setChannelActive: (UInt32) channel 42 | active: (BOOL) active; 43 | 44 | - (void) removeIOProcID: (AudioDeviceIOProcID) procID; 45 | - (void) setIOProcIDEnabled: (AudioDeviceIOProcID) procID 46 | enabled: (BOOL) enabled; 47 | - (void) setAllIOProcs: (BOOL) enabled; 48 | - (void) setStartTimeForProcID: (AudioDeviceIOProcID) procID 49 | timeStamp: (AudioTimeStamp *) timeStamp 50 | flags: (UInt32) flags; 51 | 52 | - (UInt32) PAServerConnection: (PAServerConnection *) connection 53 | hasPlaybackData: (Byte *) playbackData 54 | recordData: (const Byte *) recordData 55 | byteSize: (UInt32) byteSize; 56 | 57 | @end 58 | -------------------------------------------------------------------------------- /HALPlugin/Source/PAObject.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License (LGPL) as 8 | published by the Free Software Foundation; either version 2.1 of the 9 | License, or (at your option) any later version. 10 | ***/ 11 | 12 | #import 13 | #import 14 | 15 | #ifdef ENABLE_DEBUG 16 | #define DebugLog(format, args...) \ 17 | NSLog(@"%s, line %d: " format "\n", \ 18 | __func__, __LINE__, ## args); 19 | #else 20 | #define DebugLog(format, args...) do {} while(0) 21 | #endif 22 | 23 | @interface PAObject : NSObject { 24 | AudioHardwarePlugInRef pluginRef; 25 | AudioObjectID objectID; 26 | AudioObjectID owningObjectID; 27 | NSLock *lock; 28 | } 29 | 30 | @property (readonly) AudioHardwarePlugInRef pluginRef; 31 | @property (nonatomic, assign) AudioObjectID objectID; 32 | @property (nonatomic, assign) AudioObjectID owningObjectID; 33 | 34 | - (id) initWithPluginRef: (AudioHardwarePlugInRef) ref; 35 | 36 | - (void) lock; 37 | - (void) unlock; 38 | 39 | - (void) show; 40 | 41 | - (BOOL) hasProperty: (const AudioObjectPropertyAddress *) address; 42 | - (BOOL) isPropertySettable: (const AudioObjectPropertyAddress *) address; 43 | 44 | - (OSStatus) getPropertyDataSize: (const AudioObjectPropertyAddress *) address 45 | qualifierDataSize: (UInt32) qualifierDataSize 46 | qualifierData: (const void *) qualifierData 47 | outSize: (UInt32 *) outDataSize; 48 | 49 | - (OSStatus) getPropertyData: (const AudioObjectPropertyAddress *) address 50 | qualifierDataSize: (UInt32) qualifierDataSize 51 | qualifierData: (const void *) qualifierData 52 | ioDataSize: (UInt32 *) ioDataSize 53 | outData: (void *) outData; 54 | 55 | - (OSStatus) setPropertyData: (const AudioObjectPropertyAddress *) address 56 | qualifierDataSize: (UInt32) qualifierDataSize 57 | qualifierData: (const void *) qualifierData 58 | dataSize: (UInt32) dataSize 59 | data: (const void *) data; 60 | 61 | - (PAObject *) findObjectByID: (AudioObjectID) searchID; 62 | - (void) addOwnedObjectsToArray: (NSMutableArray *) array; 63 | - (void) publishOwnedObjects; 64 | - (void) depublishOwnedObjects; 65 | 66 | @end 67 | -------------------------------------------------------------------------------- /HALPlugin/Source/PAPlugInInterface.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License (LGPL) as 8 | published by the Free Software Foundation; either version 2.1 of the 9 | License, or (at your option) any later version. 10 | ***/ 11 | 12 | #import 13 | #import 14 | #import "PAPlugin.h" 15 | 16 | @interface PAPlugInInterface : NSObject { 17 | PAPlugin *plugin; 18 | NSAutoreleasePool *pool; 19 | @public AudioHardwarePlugInInterface *staticInterface; 20 | } 21 | 22 | @property (nonatomic, assign) PAPlugin *plugin; 23 | 24 | - (AudioHardwarePlugInRef) getInterface; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /HALPlugin/Source/PAStream.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License (LGPL) as 8 | published by the Free Software Foundation; either version 2.1 of the 9 | License, or (at your option) any later version. 10 | ***/ 11 | 12 | #import 13 | #import "PAObject.h" 14 | 15 | @class PADevice; 16 | 17 | @interface PAStream : PAObject { 18 | PADevice *owningDevice; 19 | BOOL isInput; 20 | UInt32 startingChannel; 21 | } 22 | 23 | - (id) initWithDevice: (PADevice *) device 24 | isInput: (BOOL) isInput 25 | startingChannel: (UInt32) startingChannel; 26 | 27 | #pragma mark ### properties ### 28 | 29 | - (BOOL) hasProperty: (const AudioObjectPropertyAddress *) address; 30 | - (BOOL) isPropertySettable: (const AudioObjectPropertyAddress *) address; 31 | 32 | - (OSStatus) getPropertyDataSize: (const AudioObjectPropertyAddress *) address 33 | qualifierDataSize: (UInt32) qualifierDataSize 34 | qualifierData: (const void *) qualifierData 35 | outSize: (UInt32 *) outDataSize; 36 | 37 | - (OSStatus) getPropertyData: (const AudioObjectPropertyAddress *) address 38 | qualifierDataSize: (UInt32) qualifierDataSize 39 | qualifierData: (const void *) qualifierData 40 | ioDataSize: (UInt32 *) ioDataSize 41 | outData: (void *) outData; 42 | 43 | - (OSStatus) setPropertyData: (const AudioObjectPropertyAddress *) address 44 | qualifierDataSize: (UInt32) qualifierDataSize 45 | qualifierData: (const void *) qualifierData 46 | dataSize: (UInt32) inDataSize 47 | data: (const void *) data; 48 | 49 | #pragma mark ### properties (legacy interface) ### 50 | 51 | - (OSStatus) getPropertyInfo: (UInt32) channel 52 | propertyID: (AudioDevicePropertyID) propertyID 53 | outSize: (UInt32 *) outSize 54 | outIsWritable: (BOOL *) outIsWritable; 55 | 56 | - (OSStatus) getProperty: (UInt32) channel 57 | propertyID: (AudioDevicePropertyID) propertyID 58 | ioDataSize: (UInt32 *) ioDataSize 59 | data: (void *) data; 60 | 61 | - (OSStatus) setProperty: (const AudioTimeStamp *) when 62 | channel: (UInt32) channel 63 | propertyID: (AudioDevicePropertyID) propertyID 64 | dataSize: (UInt32) dataSize 65 | data: (const void *) data; 66 | 67 | @end 68 | -------------------------------------------------------------------------------- /HALPlugin/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | cp -a build/Debug/PulseAudio.plugin /Library/Audio/Plug-Ins/HAL/ 4 | 5 | -------------------------------------------------------------------------------- /PreferencePane/AudioClients.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2.1 of the License, or 9 | (at your option) any later version. 10 | ***/ 11 | 12 | #import 13 | #import 14 | #import 15 | #import 16 | 17 | @protocol AudioClientsDelegate 18 | 19 | - (void) setAudioDeviceConfig: (NSDictionary *) config 20 | forDeviceWithUUID: (NSString *) uuid; 21 | 22 | @end 23 | 24 | 25 | @interface AudioClients : NSObject 26 | { 27 | IBOutlet NSTableView *clientTableView; 28 | IBOutlet IKImageView *imageView; 29 | IBOutlet NSTabView *clientDetailsBox; 30 | IBOutlet NSTextField *clientNameLabel; 31 | IBOutlet NSTextField *audioDeviceLabel; 32 | IBOutlet NSTextField *PIDLabel; 33 | IBOutlet NSTextField *IOBufferSizeLabel; 34 | IBOutlet NSPopUpButton *serverSelectButton; 35 | IBOutlet NSPopUpButton *sinkSelectButton; 36 | IBOutlet NSPopUpButton *sourceSelectButton; 37 | IBOutlet NSTextField *userNameField; 38 | IBOutlet NSSecureTextField *passwordField; 39 | IBOutlet NSTextField *connectionStatusTextField; 40 | IBOutlet NSButton *persistenCheckButton; 41 | 42 | NSMutableArray *clientList; 43 | PAServiceDiscovery *discovery; 44 | 45 | NSMutableArray *knownServers; 46 | NSMutableArray *knownSinks; 47 | NSMutableArray *knownSources; 48 | 49 | NSObject *delegate; 50 | } 51 | 52 | @property (nonatomic, assign) NSObject *delegate; 53 | 54 | /* Helper callbacks */ 55 | - (void) audioClientsChanged: (NSArray *) clients; 56 | 57 | /* NSTableViewDelegate */ 58 | - (void) tableView:(NSTableView *)aTableView 59 | setObjectValue:obj 60 | forTableColumn: (NSTableColumn *) col 61 | row: (int) rowIndex; 62 | - (id) tableView: (NSTableView *) tableView 63 | objectValueForTableColumn: (NSTableColumn *) col 64 | row: (int) rowIndex; 65 | - (int) numberOfRowsInTableView: (NSTableView *) tableView; 66 | 67 | /* GUI */ 68 | - (IBAction) selectClient: (id) sender; 69 | - (IBAction) selectServer: (id) sender; 70 | - (IBAction) connectClient: (id) sender; 71 | 72 | @end 73 | -------------------------------------------------------------------------------- /PreferencePane/English.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zonque/PulseAudioOSX/a45a37f7972730a9b9d82f3d04b6d9f866934d3d/PreferencePane/English.lproj/InfoPlist.strings -------------------------------------------------------------------------------- /PreferencePane/English.lproj/PAPreferencePane.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zonque/PulseAudioOSX/a45a37f7972730a9b9d82f3d04b6d9f866934d3d/PreferencePane/English.lproj/PAPreferencePane.nib/keyedobjects.nib -------------------------------------------------------------------------------- /PreferencePane/Growl.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2.1 of the License, or 9 | (at your option) any later version. 10 | ***/ 11 | 12 | #import 13 | 14 | @protocol GrowlDelegate 15 | @required 16 | - (void) setPreferences: (id) value 17 | forKey: (NSString *) key; 18 | @end 19 | 20 | 21 | @interface Growl : NSObject { 22 | IBOutlet NSTableView *tableView; 23 | IBOutlet NSButton *enabledButton; 24 | IBOutlet NSTabView *tabView; 25 | 26 | NSDistributedNotificationCenter *notificationCenter; 27 | NSArray *notifications; 28 | UInt64 notificationFlags; 29 | BOOL growlEnabled; 30 | 31 | NSObject *delegate; 32 | } 33 | 34 | @property (nonatomic, assign) NSObject *delegate; 35 | 36 | - (void) preferencesChanged: (NSDictionary *) preferences; 37 | 38 | /* NSTableViewDelegate */ 39 | - (void)tableView:(NSTableView *)aTableView 40 | setObjectValue:obj 41 | forTableColumn:(NSTableColumn *)col 42 | row:(int)rowIndex; 43 | - (id)tableView:(NSTableView *)tableView 44 | objectValueForTableColumn:(NSTableColumn *)col 45 | row:(int)rowIndex; 46 | - (int) numberOfRowsInTableView:(NSTableView *)tableView; 47 | 48 | /* GUI */ 49 | - (IBAction) setEnabled: (id) sender; 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /PreferencePane/Growl.m: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2.1 of the License, or 9 | (at your option) any later version. 10 | ***/ 11 | 12 | #import "Growl.h" 13 | 14 | @implementation Growl 15 | 16 | @synthesize delegate; 17 | 18 | - (void) preferencesChanged: (NSDictionary *) preferences 19 | { 20 | NSNumber *number = [preferences objectForKey: @"growlNotificationFlags"]; 21 | notificationFlags = [number unsignedLongLongValue]; 22 | BOOL growlReady = !!(notificationFlags & (1ULL << 63)); 23 | 24 | growlEnabled = !!(notificationFlags & (1ULL << 62)); 25 | 26 | [enabledButton setEnabled: growlEnabled]; 27 | [tableView setEnabled: growlEnabled]; 28 | 29 | /* 30 | if (growlReady) { 31 | [tabView selectTabViewItemWithIdentifier: @"active"]; 32 | [tableView reloadData]; 33 | } else 34 | [tabView selectTabViewItemWithIdentifier: @"inactive"]; 35 | */ 36 | } 37 | 38 | - (void) sendFlags 39 | { 40 | UInt64 flags = notificationFlags; 41 | 42 | if (growlEnabled) 43 | flags |= 1ULL << 62; 44 | 45 | [delegate setPreferences: [NSNumber numberWithUnsignedLongLong: flags] 46 | forKey: @"growlNotificationFlags"]; 47 | } 48 | 49 | - (void) awakeFromNib 50 | { 51 | notificationCenter = [NSDistributedNotificationCenter defaultCenter]; 52 | 53 | notifications = [NSArray arrayWithObjects: 54 | @"Server appeared", 55 | @"Server disappeared", 56 | @"Source appeared", 57 | @"Source disappeared", 58 | @"Sink appeared", 59 | @"Sink disappeared", 60 | @"Client connected", 61 | @"Client disconnected", 62 | nil]; 63 | } 64 | 65 | #pragma mark ### NSTableView ### 66 | 67 | - (void)tableView:(NSTableView *)aTableView 68 | setObjectValue:obj 69 | forTableColumn:(NSTableColumn *)col 70 | row:(int)rowIndex 71 | { 72 | if ([obj intValue]) 73 | notificationFlags |= (1ULL << rowIndex); 74 | else 75 | notificationFlags &= ~(1ULL << rowIndex); 76 | 77 | [self sendFlags]; 78 | } 79 | 80 | - (id)tableView:(NSTableView *)tableView 81 | objectValueForTableColumn:(NSTableColumn *)col 82 | row:(int)rowIndex 83 | { 84 | if ([[col identifier] isEqualToString: @"name"]) 85 | return [notifications objectAtIndex: rowIndex]; 86 | 87 | if ([[col identifier] isEqualToString: @"check"]) 88 | return [NSNumber numberWithBool: notificationFlags & (1ULL << rowIndex)]; 89 | 90 | return nil; 91 | } 92 | 93 | - (int) numberOfRowsInTableView:(NSTableView *)tableView 94 | { 95 | return [notifications count]; 96 | } 97 | 98 | #pragma mark ### GUI ### 99 | - (IBAction) setEnabled: (id) sender 100 | { 101 | growlEnabled = ([sender state] == NSOnState); 102 | [tableView setEnabled: growlEnabled]; 103 | [self sendFlags]; 104 | } 105 | 106 | @end 107 | -------------------------------------------------------------------------------- /PreferencePane/Growl_512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zonque/PulseAudioOSX/a45a37f7972730a9b9d82f3d04b6d9f866934d3d/PreferencePane/Growl_512x512.png -------------------------------------------------------------------------------- /PreferencePane/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | org.pulseaudio.PrefPane 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | BNDL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 0.1.0 25 | NSMainNibFile 26 | PAPreferencePane 27 | NSPrefPaneIconFile 28 | PAPreferencePane.tiff 29 | NSPrefPaneIconLabel 30 | PulseAudio 31 | NSPrincipalClass 32 | PreferencePane 33 | 34 | 35 | -------------------------------------------------------------------------------- /PreferencePane/LocalServer.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2.1 of the License, or 9 | (at your option) any later version. 10 | ***/ 11 | 12 | #import 13 | 14 | @protocol LocalServerDelegate 15 | @required 16 | - (void) setPreferences: (id) value 17 | forKey: (NSString *) key; 18 | @end 19 | 20 | @interface LocalServer : NSObject { 21 | IBOutlet NSButton *enabledButton; 22 | IBOutlet NSButton *networkEnabledButton; 23 | 24 | NSDistributedNotificationCenter *notificationCenter; 25 | NSObject *delegate; 26 | } 27 | 28 | @property (nonatomic, assign) NSObject *delegate; 29 | 30 | - (void) preferencesChanged: (NSDictionary *) preferences; 31 | 32 | - (IBAction) setEnabled: (id) sender; 33 | - (IBAction) setNetworkEnabled: (id) sender; 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /PreferencePane/LocalServer.m: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2.1 of the License, or 9 | (at your option) any later version. 10 | ***/ 11 | 12 | #import "LocalServer.h" 13 | 14 | @implementation LocalServer 15 | 16 | @synthesize delegate; 17 | 18 | - (void) setLocalServerEnabled: (NSNotification *) notification 19 | { 20 | NSDictionary *userInfo = [notification userInfo]; 21 | BOOL enabled = [[userInfo objectForKey: @"enabled"] boolValue]; 22 | [enabledButton setState: enabled ? NSOnState : NSOffState]; 23 | } 24 | 25 | - (void) awakeFromNib 26 | { 27 | notificationCenter = [NSDistributedNotificationCenter defaultCenter]; 28 | 29 | } 30 | 31 | - (IBAction) setEnabled: (id) sender 32 | { 33 | NSMutableDictionary *userInfo = [NSMutableDictionary dictionaryWithCapacity: 0]; 34 | BOOL enabled = ([sender state] == NSOnState); 35 | 36 | [userInfo setObject: [NSNumber numberWithBool: enabled] 37 | forKey: @"enabled"]; 38 | } 39 | 40 | - (void) preferencesChanged: (NSDictionary *) preferences 41 | { 42 | BOOL networkEnabled = [[preferences objectForKey: @"localServerNetworkEnabled"] boolValue]; 43 | [networkEnabledButton setState: networkEnabled]; 44 | } 45 | 46 | - (IBAction) setNetworkEnabled: (id) sender 47 | { 48 | [delegate setPreferences: [NSNumber numberWithBool: [sender state] == NSOnState] 49 | forKey: @"localServerNetworkEnabled"]; 50 | } 51 | 52 | @end 53 | -------------------------------------------------------------------------------- /PreferencePane/LoginItemController.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2.1 of the License, or 9 | (at your option) any later version. 10 | ***/ 11 | 12 | #import 13 | 14 | @interface LoginItemController : NSObject { 15 | IBOutlet NSButton *btnToggleLoginItem; 16 | } 17 | 18 | - (IBAction) toggleLoginItem:(id)sender; 19 | @end 20 | -------------------------------------------------------------------------------- /PreferencePane/LoginItemController.m: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2.1 of the License, or 9 | (at your option) any later version. 10 | ***/ 11 | 12 | #import "LoginItemController.h" 13 | 14 | @implementation LoginItemController 15 | 16 | - (void) awakeFromNib { 17 | } 18 | 19 | - (IBAction)toggleLoginItem:(id)sender { 20 | } 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /PreferencePane/PAPreferencePane.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zonque/PulseAudioOSX/a45a37f7972730a9b9d82f3d04b6d9f866934d3d/PreferencePane/PAPreferencePane.tiff -------------------------------------------------------------------------------- /PreferencePane/PAPreferencePane.xcodeproj/.gitignore: -------------------------------------------------------------------------------- 1 | *.pbxuser 2 | *.mode1v3 3 | -------------------------------------------------------------------------------- /PreferencePane/PreferencePane.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2.1 of the License, or 9 | (at your option) any later version. 10 | ***/ 11 | 12 | #import 13 | #import 14 | 15 | #import "LoginItemController.h" 16 | #import "AudioClients.h" 17 | #import "LocalServer.h" 18 | #import "Growl.h" 19 | 20 | @interface PreferencePane : NSPreferencePane < 21 | PAHelperConnectionDelegate, 22 | GrowlDelegate, 23 | LocalServerDelegate, 24 | AudioClientsDelegate> 25 | { 26 | IBOutlet NSButton *statusBarEnabledButton; 27 | IBOutlet LoginItemController *loginItemController; 28 | 29 | IBOutlet AudioClients *audioClients; 30 | IBOutlet Growl *growl; 31 | IBOutlet LocalServer *localServer; 32 | 33 | PAHelperConnection *helperConnection; 34 | } 35 | 36 | - (IBAction) setPulseAudioEnabled: (id) sender; 37 | - (IBAction) setStatusBarEnabled: (id) sender; 38 | 39 | #pragma mark ### PAHelperConnectionDelegate ### 40 | 41 | - (void) PAHelperConnectionDied: (PAHelperConnection *) connection; 42 | - (void) PAHelperConnection: (PAHelperConnection *) connection 43 | receivedMessage: (NSString *) name 44 | dict: (NSDictionary *) msg; 45 | 46 | #pragma mark ### GrowlDelegate/LocalServerDelegate ### 47 | 48 | - (void) setPreferences: (id) value 49 | forKey: (NSString *) key; 50 | 51 | #pragma mark ### AudioClientsDelegate ### 52 | 53 | - (void) setAudioDeviceConfig: (NSDictionary *) config 54 | forDeviceWithUUID: (NSString *) uuid; 55 | 56 | @end 57 | -------------------------------------------------------------------------------- /PreferencePane/PreferencePane.m: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2.1 of the License, or 9 | (at your option) any later version. 10 | ***/ 11 | 12 | #import "PreferencePane.h" 13 | 14 | @implementation PreferencePane 15 | 16 | - (void) didSelect 17 | { 18 | } 19 | 20 | - (void) didUnselect 21 | { 22 | } 23 | 24 | - (void) mainViewDidLoad 25 | { 26 | helperConnection = [[PAHelperConnection alloc] init]; 27 | helperConnection.delegate = self; 28 | 29 | if (![helperConnection connectWithRetry: NO]) { 30 | //FIXME 31 | [NSApp terminate: nil]; 32 | } 33 | 34 | growl.delegate = self; 35 | localServer.delegate = self; 36 | audioClients.delegate = self; 37 | 38 | /* 39 | NSArray *currentAudioDevices = [helperConnection.serverProxy currentAudioDevices]; 40 | 41 | CFShow(currentAudioDevices); 42 | 43 | [audioClients audioClientsChanged: currentAudioDevices]; 44 | 45 | NSDictionary *preferences = [helperConnection.serverProxy getPreferences]; 46 | */ 47 | } 48 | 49 | #pragma mark ### GUI ### 50 | - (IBAction) setStatusBarEnabled: (id) sender 51 | { 52 | NSButton *button = sender; 53 | BOOL enabled = ([button state] == NSOnState); 54 | 55 | NSDictionary *p = [NSDictionary dictionaryWithObject: [NSNumber numberWithBool: enabled] 56 | forKey: @"statusBarEnabled"]; 57 | [helperConnection sendMessage: PAOSX_MessageSetPreferences 58 | dict: p]; 59 | } 60 | 61 | - (IBAction) setPulseAudioEnabled: (id) sender 62 | { 63 | [loginItemController toggleLoginItem: sender]; 64 | } 65 | 66 | #pragma mark ### PAHelperConnectionDelegate ### 67 | 68 | - (void) PAHelperConnectionDied: (PAHelperConnection *) connection 69 | { 70 | NSLog(@"%s()", __func__); 71 | } 72 | 73 | /* 74 | - (void) PAHelperConnection: (PAHelperConnection *) connection 75 | audioClientsChanged: (NSArray *) array 76 | { 77 | [audioClients audioClientsChanged: array]; 78 | } 79 | 80 | - (void) PAHelperConnection: (PAHelperConnection *) connection 81 | preferencesChanged: (NSDictionary *) preferences 82 | { 83 | BOOL statusBarEnabled = [[preferences objectForKey: @"statusBarEnabled"] boolValue]; 84 | [statusBarEnabledButton setState: statusBarEnabled]; 85 | 86 | [growl preferencesChanged: preferences]; 87 | } 88 | */ 89 | 90 | - (void) PAHelperConnection: (PAHelperConnection *) connection 91 | receivedMessage: (NSString *) name 92 | dict: (NSDictionary *) msg 93 | { 94 | NSLog(@"%s() %@ -> %@", __func__, name, msg); 95 | 96 | if ([name isEqualToString: PAOSX_MessageAudioClientsUpdate]) 97 | [audioClients audioClientsChanged: [msg objectForKey: @"clients"]]; 98 | 99 | if ([name isEqualToString: PAOSX_MessageSetPreferences]) { 100 | BOOL statusBarEnabled = [[msg objectForKey: @"statusBarEnabled"] boolValue]; 101 | [statusBarEnabledButton setState: statusBarEnabled]; 102 | [growl preferencesChanged: msg]; 103 | } 104 | } 105 | 106 | #pragma mark ### GrowlDelegate ### 107 | 108 | - (void) setPreferences: (id) value 109 | forKey: (NSString *) key 110 | { 111 | [helperConnection sendMessage: PAOSX_MessageSetPreferences 112 | dict: [NSDictionary dictionaryWithObject: value 113 | forKey: key]]; 114 | } 115 | 116 | #pragma mark ### AudioClientsDelegate ### 117 | 118 | - (void) setAudioDeviceConfig: (NSDictionary *) config 119 | forDeviceWithUUID: (NSString *) uuid 120 | { 121 | NSLog(@"%s() uuid %@ config %@", __func__, uuid, config); 122 | NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithCapacity: 0]; 123 | 124 | [dict setObject: config 125 | forKey: @"config"]; 126 | [dict setObject: uuid 127 | forKey: @"uuid"]; 128 | 129 | [helperConnection sendMessage: PAOSX_MessageSetAudioClientConfig 130 | dict: dict]; 131 | } 132 | 133 | @end 134 | -------------------------------------------------------------------------------- /PreferencePane/PulseAudio_Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'PulseAudio' target in the 'PulseAudio' project. 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #import 8 | #endif 9 | -------------------------------------------------------------------------------- /PreferencePane/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | conf=$1 4 | 5 | if [ -z "$conf" ]; then 6 | conf="Release" 7 | fi 8 | 9 | dest=/Library/PreferencePanes/PulseAudio.prefPane 10 | 11 | rm -fr $dest 12 | cp -r build/${conf}/PulseAudio.prefPane /Library/PreferencePanes/ 13 | 14 | echo "now call /Applications/System\ Preferences.app/Contents/MacOS/System\ Preferences $dest" 15 | 16 | -------------------------------------------------------------------------------- /PulseAudioHelper/ConnectionClient.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2.1 of the License, or 9 | (at your option) any later version. 10 | ***/ 11 | 12 | #import 13 | #import 14 | 15 | @class ConnectionClient; 16 | @class ConnectionServer; 17 | 18 | @protocol ConnectionClientDelegate 19 | - (void) connectionClientDied: (ConnectionClient *) client; 20 | - (void) connectionClientChangedAudioClients: (ConnectionClient *) client; 21 | - (void) connectionClient: (ConnectionClient *) client 22 | changedPreferences: (NSDictionary *) changed; 23 | - (void) connectionClient: (ConnectionClient *) client 24 | setAudioClientConfig: (NSDictionary *) config 25 | forUUID: (NSString *) uuid; 26 | - (NSArray *) allAudioClients; 27 | @end 28 | 29 | @interface ConnectionClient : NSObject 30 | { 31 | ConnectionServer *server; 32 | PAHelperConnection *connection; 33 | NSMutableArray *audioClients; 34 | NSLock *lock; 35 | 36 | NSObject *delegate; 37 | } 38 | 39 | @property (nonatomic, assign) NSObject *delegate; 40 | @property (nonatomic, readonly) ULINetSocket *socket; 41 | @property (nonatomic, readonly) NSArray *audioClients; 42 | 43 | - (id) initWithSocket: (ULINetSocket *) socket 44 | forServer: (ConnectionServer *) server; 45 | - (void) sendAudioClientsChanged : (NSArray *) clients; 46 | - (void) sendPreferencesChanged : (NSDictionary *) preferences; 47 | - (void) setConfig: (NSDictionary *) config 48 | forDeviceWithUUID: (NSString *) uuid; 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /PulseAudioHelper/ConnectionServer.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2.1 of the License, or 9 | (at your option) any later version. 10 | ***/ 11 | 12 | #import 13 | #import 14 | 15 | #import "ServerConnection.h" 16 | #import "ConnectionClient.h" 17 | #import "Preferences.h" 18 | 19 | @interface ConnectionServer : NSObject < 20 | ULINetSocketDelegate, 21 | PAHelperConnectionDelegate, 22 | ConnectionClientDelegate, 23 | ServerConnectionDelegate 24 | > 25 | { 26 | NSMutableArray *clientArray; 27 | NSConnection *currentConnection; 28 | NSConnection *serviceConnection; 29 | 30 | ULINetSocket *serviceSocket; 31 | 32 | Preferences *preferences; 33 | } 34 | 35 | @property (nonatomic, assign) NSConnection *currentConnection; 36 | @property (nonatomic, retain) Preferences *preferences; 37 | 38 | - (void) start; 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /PulseAudioHelper/ConnectionServer.m: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2.1 of the License, or 9 | (at your option) any later version. 10 | ***/ 11 | 12 | #import 13 | 14 | #include 15 | #include 16 | 17 | #import "ConnectionServer.h" 18 | #import "ConnectionClient.h" 19 | 20 | @implementation ConnectionServer 21 | 22 | @synthesize currentConnection; 23 | @synthesize preferences; 24 | 25 | - (void) start 26 | { 27 | clientArray = [[NSMutableArray arrayWithCapacity: 0] retain]; 28 | 29 | serviceSocket = [[ULINetSocket alloc] init]; 30 | [serviceSocket setDelegate: self]; 31 | [serviceSocket listenOnLocalSocketPath: PAOSX_HelperSocket 32 | maxPendingConnections: 100]; 33 | /* coreaudiod runs under the _coreaudiod user's permission, so we 34 | * have to tweak the socket permissions and allow any user to connect 35 | */ 36 | chmod([PAOSX_HelperSocket cStringUsingEncoding: NSASCIIStringEncoding], S_IRUSR | S_IWUSR | 37 | S_IRGRP | S_IWGRP | 38 | S_IROTH | S_IWOTH); 39 | [serviceSocket scheduleOnCurrentRunLoop]; 40 | NSLog(@"PAOSX_HelperSocket: %@", PAOSX_HelperSocket); 41 | } 42 | 43 | #pragma mark ### ULINetSocketDelegate ### 44 | 45 | -(void) netsocketDisconnected: (ULINetSocket *) inNetSocket 46 | { 47 | for (ConnectionClient *c in clientArray) 48 | if (c.socket == inNetSocket) { 49 | NSLog(@"%s(): client %p died", __func__, c); 50 | [clientArray removeObject: c]; 51 | [c release]; 52 | return; 53 | } 54 | } 55 | 56 | -(void) netsocket: (ULINetSocket *) inNetSocket 57 | connectionTimedOut: (NSTimeInterval) inTimeout 58 | { 59 | NSLog(@"%s()", __func__); 60 | [self netsocketDisconnected: inNetSocket]; 61 | } 62 | 63 | -(void) netsocket: (ULINetSocket *) inNetSocket 64 | connectionAccepted: (ULINetSocket *) inNewNetSocket 65 | { 66 | ConnectionClient *c = [[ConnectionClient alloc] initWithSocket: inNewNetSocket 67 | forServer: self]; 68 | c.delegate = self; 69 | [clientArray addObject: c]; 70 | } 71 | 72 | #pragma mark ### ConnectionClientDelegate ### 73 | 74 | - (void) connectionClientDied: (ConnectionClient *) client 75 | { 76 | BOOL hasAudio = ([client.audioClients count] > 0); 77 | [clientArray removeObject: client]; 78 | 79 | if (hasAudio) 80 | [self connectionClientChangedAudioClients: nil]; 81 | } 82 | 83 | - (NSArray *) allAudioClients 84 | { 85 | NSMutableArray *array = [NSMutableArray arrayWithCapacity: 0]; 86 | 87 | for (ConnectionClient *c in clientArray) 88 | [array addObjectsFromArray: c.audioClients]; 89 | 90 | return array; 91 | } 92 | 93 | - (void) connectionClientChangedAudioClients: (ConnectionClient *) client 94 | { 95 | NSArray *a = [self allAudioClients]; 96 | 97 | for (ConnectionClient *c in clientArray) 98 | if (c != client) 99 | [c sendAudioClientsChanged: a]; 100 | } 101 | 102 | - (void) connectionClient: (ConnectionClient *) client 103 | changedPreferences: (NSDictionary *) changed; 104 | { 105 | for (id key in [changed allKeys]) 106 | [preferences setValue: [changed objectForKey: key] 107 | forKey: key]; 108 | 109 | for (ConnectionClient *c in clientArray) 110 | if (c != client) 111 | [c sendPreferencesChanged: preferences.preferencesDict]; 112 | } 113 | 114 | - (void) connectionClient: (ConnectionClient *) client 115 | setAudioClientConfig: (NSDictionary *) config 116 | forUUID: (NSString *) uuid 117 | { 118 | for (ConnectionClient *c in clientArray) 119 | if (c != client) 120 | [c setConfig: config 121 | forDeviceWithUUID: uuid]; 122 | } 123 | 124 | #pragma mark ### ServerConnectionDelegate ### 125 | 126 | - (void) ServerConnectionEstablished: (ServerConnection *) connection 127 | { 128 | } 129 | 130 | - (void) ServerConnectionFailed: (ServerConnection *) connection 131 | { 132 | } 133 | 134 | - (void) ServerConnectionEnded: (ServerConnection *) connection 135 | { 136 | } 137 | 138 | @end 139 | -------------------------------------------------------------------------------- /PulseAudioHelper/GrowlNotifications.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2.1 of the License, or 9 | (at your option) any later version. 10 | ***/ 11 | 12 | #import 13 | #import 14 | #import 15 | #import 16 | 17 | #import "Preferences.h" 18 | 19 | @interface GrowlNotifications : NSObject < 20 | GrowlApplicationBridgeDelegate, 21 | PAServiceDiscoveryDelegate, 22 | PAServerConnectionDelegate 23 | > 24 | { 25 | PAServiceDiscovery *discovery; 26 | NSData *logoData; 27 | BOOL growlReady; 28 | //ServerConnection *serverConnection; 29 | Preferences *preferences; 30 | } 31 | 32 | - (id) initWithPreferences: (Preferences *) p; 33 | 34 | /* GrowlApplicationBridgeDelegate */ 35 | - (NSString *) applicationNameForGrowl; 36 | - (NSDictionary *) registrationDictionaryForGrowl; 37 | - (NSData *) applicationIconDataForGrowl; 38 | - (void) growlIsReady; 39 | 40 | /* PAServiceDiscoveryDelegate */ 41 | 42 | - (void) PAServiceDiscovery: (PAServiceDiscovery *) discovery 43 | serverAppeared: (NSNetService *) service; 44 | - (void) PAServiceDiscovery: (PAServiceDiscovery *) discovery 45 | serverDisappeared: (NSNetService *) service; 46 | 47 | - (void) PAServiceDiscovery: (PAServiceDiscovery *) discovery 48 | sinkAppeared: (NSNetService *) service; 49 | - (void) PAServiceDiscovery: (PAServiceDiscovery *) discovery 50 | sinkDisappeared: (NSNetService *) service; 51 | 52 | - (void) PAServiceDiscovery: (PAServiceDiscovery *) discovery 53 | sourceAppeared: (NSNetService *) service; 54 | - (void) PAServiceDiscovery: (PAServiceDiscovery *) discovery 55 | sourceDisappeared: (NSNetService *) service; 56 | 57 | /* PAServerConnectionDelegate */ 58 | //... 59 | 60 | @end 61 | -------------------------------------------------------------------------------- /PulseAudioHelper/LoginItemController.h: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License 3 | Copyright (c) 2010 Justin Williams, Second Gear 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 17 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 18 | THE SOFTWARE. 19 | */ 20 | 21 | #import 22 | 23 | 24 | @interface LoginItemController : NSObject { 25 | } 26 | 27 | + (void)setLoginItemEnabled: (BOOL) enabled; 28 | @end 29 | 30 | @interface LoginItemController (PrivateMethods) 31 | + (void)enableLoginItemWithLoginItemsReference:(LSSharedFileListRef )theLoginItemsRefs ForPath:(NSString *)appPath; 32 | + (void)disableLoginItemWithLoginItemsReference:(LSSharedFileListRef )theLoginItemsRefs ForPath:(NSString *)appPath; 33 | + (BOOL)loginItemExistsWithLoginItemReference:(LSSharedFileListRef)theLoginItemsRefs ForPath:(NSString *)appPath; 34 | @end 35 | -------------------------------------------------------------------------------- /PulseAudioHelper/Pathes.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2.1 of the License, or 9 | (at your option) any later version. 10 | ***/ 11 | 12 | #define PAOSX_ConfigFile @"/Library/PreferencePanes/PulseAudio.prefPane" 13 | #define PAOSX_PulseConsoleBundle @"/Applications/PulseConsole.app" 14 | #define PAOSX_FrameworkBundle @"/Library/Frameworks/pulse.framework/" 15 | #define PAOSX_StatusBarIconFile @"/Library/Frameworks/pulse.framework/Resources/statusBar.png" 16 | #define PAOSX_GrowlIconFile @"/Library/Frameworks/pulse.framework/Resources/PulseAudio.png" 17 | #define PAOSX_PulseAudioControlFile @"/Library/Frameworks/pulse.framework/etc/macosx.pa" 18 | -------------------------------------------------------------------------------- /PulseAudioHelper/Preferences.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2.1 of the License, or 9 | (at your option) any later version. 10 | ***/ 11 | 12 | #import 13 | 14 | @interface Preferences : NSObject { 15 | NSMutableDictionary *preferencesDict; 16 | BOOL growlReady; 17 | } 18 | 19 | @property (nonatomic, readonly) NSDictionary *preferencesDict; 20 | 21 | - (id) valueForKey: (NSString *) key; 22 | - (void) setValue: (id) value 23 | forKey: (NSString *) key; 24 | 25 | /* Growl Notifications */ 26 | - (BOOL) isGrowlEnabled; 27 | - (UInt64) growlNotificationFlags; 28 | - (void) setGrowlReady: (BOOL) ready; 29 | 30 | /* Local Server */ 31 | - (BOOL) isLocalServerEnabled; 32 | 33 | /* Status Bar */ 34 | - (BOOL) isStatusBarEnabled; 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /PulseAudioHelper/PulseAudio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zonque/PulseAudioOSX/a45a37f7972730a9b9d82f3d04b6d9f866934d3d/PulseAudioHelper/PulseAudio.png -------------------------------------------------------------------------------- /PulseAudioHelper/PulseAudioHelper-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSUIElement 6 | 1 7 | CFBundleDevelopmentRegion 8 | English 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIconFile 12 | logo 13 | CFBundleIdentifier 14 | org.pulseaudio.${PRODUCT_NAME:rfc1034identifier} 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 0.1 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSMinimumSystemVersion 26 | ${MACOSX_DEPLOYMENT_TARGET} 27 | NSMainNibFile 28 | MainMenu 29 | NSPrincipalClass 30 | NSApplication 31 | 32 | 33 | -------------------------------------------------------------------------------- /PulseAudioHelper/PulseAudioHelper_Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'PulseAudioHelper' target in the 'PulseAudioHelper' project. 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | -------------------------------------------------------------------------------- /PulseAudioHelper/ServerConnection.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2.1 of the License, or 9 | (at your option) any later version. 10 | ***/ 11 | 12 | #import 13 | #import 14 | #import "Preferences.h" 15 | 16 | @class ServerConnection; 17 | 18 | @protocol ServerConnectionDelegate 19 | - (void) ServerConnectionEstablished: (ServerConnection *) connection; 20 | - (void) ServerConnectionFailed: (ServerConnection *) connection; 21 | - (void) ServerConnectionEnded: (ServerConnection *) connection; 22 | @end 23 | 24 | @interface ServerConnection : NSObject 25 | { 26 | PAServerConnection *connection; 27 | Preferences *preferences; 28 | BOOL networkEnabled; 29 | PAModuleInfo *networkModule; 30 | NSObject *delegate; 31 | } 32 | 33 | @property (nonatomic, assign) NSObject *delegate; 34 | 35 | - (void) connect; 36 | 37 | /* PAServerConnectionDelegate */ 38 | 39 | - (void) PAServerConnectionEstablished: (PAServerConnection *) connection; 40 | - (void) PAServerConnectionFailed: (PAServerConnection *) connection; 41 | - (void) PAServerConnectionEnded: (PAServerConnection *) connection; 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /PulseAudioHelper/ServerConnection.m: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2.1 of the License, or 9 | (at your option) any later version. 10 | ***/ 11 | 12 | #import "ServerConnection.h" 13 | 14 | static NSString *tcpModuleName = @"module-native-protocol-tcp"; 15 | 16 | @implementation ServerConnection 17 | @synthesize delegate; 18 | 19 | #pragma mark ### NSNotificationCenter ### 20 | 21 | - (void) preferencesChanged: (NSNotification *) notification 22 | { 23 | networkEnabled = [[preferences valueForKey: @"localServerNetworkEnabled"] boolValue]; 24 | 25 | if (!networkEnabled && networkModule) 26 | if ([networkModule unload]); 27 | networkModule = nil; 28 | 29 | if (networkEnabled && !networkModule) 30 | [connection loadModuleWithName: tcpModuleName 31 | arguments: @"auth-anonymous=1"]; 32 | } 33 | 34 | - (id) initWithPreferences: (Preferences *) p 35 | { 36 | [super init]; 37 | 38 | preferences = p; 39 | 40 | [[NSNotificationCenter defaultCenter] addObserver: self 41 | selector: @selector(preferencesChanged:) 42 | name: @"preferencesChanged" 43 | object: preferences]; 44 | 45 | connection = [[PAServerConnection alloc] init]; 46 | connection.delegate = self; 47 | 48 | return self; 49 | } 50 | 51 | - (void) connect 52 | { 53 | [connection connectToHost: nil 54 | port: -1]; 55 | } 56 | 57 | /* PAServerConnectionDelegate */ 58 | 59 | - (void) PAServerConnectionEstablished: (PAServerConnection *) connection 60 | { 61 | NSLog(@"%s", __func__); 62 | if (delegate && [delegate respondsToSelector: @selector(ServerConnectionEstablished:)]) 63 | [delegate ServerConnectionEstablished: self]; 64 | } 65 | 66 | - (void) PAServerConnectionFailed: (PAServerConnection *) connection 67 | { 68 | NSLog(@"%s", __func__); 69 | networkModule = nil; 70 | if (delegate && [delegate respondsToSelector: @selector(ServerConnectionFailed:)]) 71 | [delegate ServerConnectionFailed: self]; 72 | } 73 | 74 | - (void) PAServerConnectionEnded: (PAServerConnection *) connection 75 | { 76 | NSLog(@"%s", __func__); 77 | networkModule = nil; 78 | if (delegate && [delegate respondsToSelector: @selector(ServerConnectionEnded:)]) 79 | [delegate ServerConnectionEnded: self]; 80 | } 81 | 82 | - (void) PAServerConnection: (PAServerConnection *) connection 83 | moduleInfoAdded: (PAModuleInfo *) module 84 | { 85 | if ([module.name isEqualToString: tcpModuleName]) 86 | networkModule = module; 87 | } 88 | 89 | - (void) PAServerConnection: (PAServerConnection *) connection 90 | moduleInfoRemoved: (PAModuleInfo *) module; 91 | { 92 | if ([module.name isEqualToString: tcpModuleName]) 93 | networkModule = nil; 94 | } 95 | 96 | @end 97 | -------------------------------------------------------------------------------- /PulseAudioHelper/ServerTask.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2.1 of the License, or 9 | (at your option) any later version. 10 | ***/ 11 | 12 | #import 13 | #import "Preferences.h" 14 | 15 | @interface ServerTask : NSObject { 16 | NSTask *task; 17 | Preferences *preferences; 18 | } 19 | 20 | - (void) start; 21 | - (void) stop; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /PulseAudioHelper/ServerTask.m: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2.1 of the License, or 9 | (at your option) any later version. 10 | ***/ 11 | 12 | #import "ServerTask.h" 13 | #import "Pathes.h" 14 | 15 | @implementation ServerTask 16 | 17 | - (void) start 18 | { 19 | NSString *binpath = @"/Library/Frameworks/PulseAudio.framework/Contents/MacOS/bin/pulseaudio"; 20 | NSString *modpath = @"/Library/Frameworks/PulseAudio.framework/Contents/MacOS/lib/pulse-1.98/modules/"; 21 | 22 | NSArray *args = [NSArray arrayWithObjects: 23 | @"-n", 24 | @"-L", @"module-bonjour-publish", 25 | @"-L", @"module-coreaudio-detect ioproc_frames=128", 26 | @"-L", @"module-native-protocol-unix", 27 | @"-L", @"module-simple-protocol-tcp", 28 | @"-L", @"module-cli-protocol-unix", 29 | @"-L", @"module-native-protocol-tcp auth-anonymous=1", 30 | @"-p", modpath, 31 | @"--exit-idle-time=-1", 32 | nil]; 33 | task = [NSTask launchedTaskWithLaunchPath: binpath 34 | arguments: args]; 35 | } 36 | 37 | - (void) stop 38 | { 39 | if (task) { 40 | [task terminate]; 41 | [task waitUntilExit]; 42 | task = nil; 43 | } 44 | } 45 | 46 | - (void) preferencesChanged: (NSNotification *) notification 47 | { 48 | BOOL enabled = [[preferences valueForKey: @"localServerEnabled"] boolValue]; 49 | 50 | if (enabled && !task) 51 | [self start]; 52 | 53 | if (!enabled && task) 54 | [self stop]; 55 | } 56 | 57 | - (void) taskTerminated: (NSNotification *) notification 58 | { 59 | if (!task || [notification object] != task) 60 | return; 61 | 62 | NSLog(@"Server task ended."); 63 | } 64 | 65 | - (id) initWithPreferences: (Preferences *) p 66 | { 67 | [super init]; 68 | 69 | preferences = p; 70 | 71 | if ([[preferences valueForKey: @"localServerEnabled"] boolValue]) 72 | [self start]; 73 | 74 | [[NSNotificationCenter defaultCenter] addObserver: self 75 | selector: @selector(preferencesChanged:) 76 | name: @"preferencesChanged" 77 | object: preferences]; 78 | 79 | return self; 80 | } 81 | 82 | @end 83 | -------------------------------------------------------------------------------- /PulseAudioHelper/StatusBar.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2.1 of the License, or 9 | (at your option) any later version. 10 | ***/ 11 | 12 | #import 13 | #import "Preferences.h" 14 | 15 | @interface StatusBar : NSObject { 16 | NSStatusItem *statusItem; 17 | NSImage *icon; 18 | Preferences *preferences; 19 | } 20 | 21 | @property (nonatomic, retain) Preferences *preferences; 22 | 23 | - (NSMenu *) createMenu; 24 | 25 | /* NSApplicationDelegate */ 26 | - (void) applicationDidFinishLaunching: (NSNotification *) aNotification; 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /PulseAudioHelper/StatusBar.m: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2.1 of the License, or 9 | (at your option) any later version. 10 | ***/ 11 | 12 | #define PATHHACK "/Users/daniel/src/pa/PulseAudioOSX/PulseAudioHelper/" 13 | 14 | #import "StatusBar.h" 15 | #import "Pathes.h" 16 | 17 | @implementation StatusBar 18 | 19 | @synthesize preferences; 20 | 21 | #pragma mark ### NSMenuItem callback selectors ### 22 | 23 | - (void) openPreferences: (id) sender 24 | { 25 | NSString *file = PAOSX_ConfigFile; 26 | [[NSWorkspace sharedWorkspace] openFile: file]; 27 | } 28 | 29 | - (void) openPulseConsole: (id) sender 30 | { 31 | NSString *file = PAOSX_PulseConsoleBundle; 32 | [[NSWorkspace sharedWorkspace] openFile: file]; 33 | } 34 | 35 | - (NSMenu *) createMenu 36 | { 37 | NSZone *zone = [NSMenu menuZone]; 38 | NSMenu *m = [[NSMenu allocWithZone: zone] init]; 39 | 40 | NSMenuItem *item; 41 | 42 | item = [m addItemWithTitle: @"xxx" 43 | action: @selector(startGrowl:) 44 | keyEquivalent: @""]; 45 | [item setTarget: self]; 46 | [item setTag: 1]; 47 | 48 | [m addItem:[NSMenuItem separatorItem]]; 49 | 50 | item = [m addItemWithTitle: @"Open Preferences ..." 51 | action: @selector(openPreferences:) 52 | keyEquivalent: @""]; 53 | [item setTarget: self]; 54 | 55 | item = [m addItemWithTitle: @"Open PulseConsole ..." 56 | action: @selector(openPulseConsole:) 57 | keyEquivalent: @""]; 58 | [item setTarget: self]; 59 | 60 | return m; 61 | } 62 | 63 | - (BOOL) validateMenuItem: (NSMenuItem *) item 64 | { 65 | return YES; 66 | } 67 | 68 | - (void) showMenu 69 | { 70 | statusItem = [[[NSStatusBar systemStatusBar] statusItemWithLength: NSSquareStatusItemLength] retain]; 71 | 72 | NSMenu *m = [self createMenu]; 73 | [statusItem setMenu: m]; // retains m 74 | [statusItem setToolTip: @"PulseAudio"]; 75 | [statusItem setHighlightMode: YES]; 76 | [statusItem setImage: icon]; 77 | } 78 | 79 | - (void) hideMenu 80 | { 81 | if (statusItem) { 82 | [[NSStatusBar systemStatusBar] removeStatusItem: statusItem]; 83 | [statusItem release]; 84 | statusItem = nil; 85 | } 86 | } 87 | 88 | #pragma mark ### NSNotificationCenter ### 89 | 90 | - (void) preferencesChanged: (NSNotification *) notification 91 | { 92 | BOOL enabled = [[preferences valueForKey: @"statusBarEnabled"] boolValue]; 93 | 94 | if (enabled && !statusItem) 95 | [self showMenu]; 96 | 97 | if (!enabled && statusItem) 98 | [self hideMenu]; 99 | } 100 | 101 | #pragma mark ### NSApplicationDelegate ### 102 | 103 | - (void) applicationDidFinishLaunching: (NSNotification *) aNotification 104 | { 105 | icon = [NSImage imageNamed: @"statusBar.png"]; 106 | 107 | if ([[preferences valueForKey: @"statusBarEnabled"] boolValue]) 108 | [self showMenu]; 109 | 110 | [[NSNotificationCenter defaultCenter] addObserver: self 111 | selector: @selector(preferencesChanged:) 112 | name: @"preferencesChanged" 113 | object: preferences]; 114 | } 115 | 116 | @end 117 | -------------------------------------------------------------------------------- /PulseAudioHelper/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | dest=/Library/Frameworks/PulseAudio.framework/Resources/ 4 | cp -a build/Release/PulseAudioHelper.app $dest 5 | 6 | -------------------------------------------------------------------------------- /PulseAudioHelper/logo.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zonque/PulseAudioOSX/a45a37f7972730a9b9d82f3d04b6d9f866934d3d/PulseAudioHelper/logo.icns -------------------------------------------------------------------------------- /PulseAudioHelper/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | #import "StatusBar.h" 5 | #import "ServerTask.h" 6 | #import "Preferences.h" 7 | #import "GrowlNotifications.h" 8 | #import "ConnectionServer.h" 9 | #import "ServerConnection.h" 10 | 11 | static GrowlNotifications *gn; 12 | static ServerConnection *sc; 13 | 14 | int main (int argc, const char * argv[]) 15 | { 16 | NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 17 | [NSApplication sharedApplication]; 18 | 19 | Preferences *prefs = [[[Preferences alloc] init] autorelease]; 20 | 21 | ConnectionServer *server = [[[ConnectionServer alloc] init] autorelease]; 22 | server.preferences = prefs; 23 | 24 | gn = [[[GrowlNotifications alloc] initWithPreferences: prefs] autorelease]; 25 | StatusBar *bar = [[[StatusBar alloc] init] autorelease]; 26 | bar.preferences = prefs; 27 | 28 | ServerTask *task = [[[ServerTask alloc] initWithPreferences: prefs] autorelease]; 29 | 30 | sc = [[ServerConnection alloc] initWithPreferences: prefs]; 31 | sc.delegate = server; 32 | [server start]; 33 | 34 | [[NSDistributedNotificationCenter defaultCenter] postNotificationName: PAOSX_HelperMsgServiceStarted 35 | object: PAOSX_HelperName 36 | userInfo: nil 37 | deliverImmediately: YES]; 38 | 39 | 40 | [NSApp setDelegate: bar]; 41 | [NSApp run]; 42 | 43 | [task stop]; 44 | [pool drain]; 45 | 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /PulseAudioHelper/statusBar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zonque/PulseAudioOSX/a45a37f7972730a9b9d82f3d04b6d9f866934d3d/PulseAudioHelper/statusBar.png -------------------------------------------------------------------------------- /PulseConsole/Credits.rtf: -------------------------------------------------------------------------------- 1 | {\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf350 2 | {\fonttbl\f0\fnil\fcharset0 Monaco;} 3 | {\colortbl;\red255\green255\blue255;\red128\green128\blue128;} 4 | \deftab480 5 | \pard\tx480\pardeftab480\qc\pardirnatural 6 | 7 | \f0\fs20 \cf0 \CocoaLigature0 Written in 2009-2011 by Daniel Mack\ 8 | Licensed under the GPL\ 9 | \ 10 | Thanks to the world wide PulseAudio community.\ 11 | \cf2 \ 12 | \ 13 | PulseConsole is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.\ 14 | \ 15 | PulseConsole is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of\ 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\ 17 | \ 18 | You should have received a copy of the GNU General Public License along with PulseAudio; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307\ 19 | USA.\ 20 | } -------------------------------------------------------------------------------- /PulseConsole/DocumentController.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseConsole. 3 | 4 | Copyright 2009-2011 Daniel Mack 5 | 6 | PulseAudio is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as 8 | published by the Free Software Foundation; either version 2.1 of the 9 | License, or (at your option) any later version. 10 | 11 | PulseAudio is distributed in the hope that it will be useful, but 12 | WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | Lesser General Public License for more details. 15 | 16 | You should have received a copy of the GNU Lesser General Public 17 | License along with PulseAudio; if not, write to the Free Software 18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 19 | USA. 20 | ***/ 21 | 22 | #import 23 | 24 | 25 | @interface DocumentController : NSDocumentController < 26 | NSApplicationDelegate, 27 | NSWindowDelegate 28 | > 29 | { 30 | 31 | } 32 | 33 | - (IBAction) displayAbout: (id) sender; 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /PulseConsole/DocumentController.m: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseConsole. 3 | 4 | Copyright 2009-2011 Daniel Mack 5 | 6 | PulseAudio is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as 8 | published by the Free Software Foundation; either version 2.1 of the 9 | License, or (at your option) any later version. 10 | 11 | PulseAudio is distributed in the hope that it will be useful, but 12 | WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | Lesser General Public License for more details. 15 | 16 | You should have received a copy of the GNU Lesser General Public 17 | License along with PulseAudio; if not, write to the Free Software 18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 19 | USA. 20 | ***/ 21 | 22 | #import "DocumentController.h" 23 | #import "Server.h" 24 | 25 | @implementation DocumentController 26 | 27 | - (IBAction) displayAbout: (id) sender 28 | { 29 | NSMutableDictionary *d = [NSMutableDictionary dictionaryWithCapacity: 0]; 30 | [d setValue: [NSString stringWithFormat: @"pulseaudio library version %@", 31 | [PAServerConnection libraryVersion]] 32 | forKey: @"Copyright"]; 33 | 34 | [NSApp orderFrontStandardAboutPanelWithOptions: d]; 35 | } 36 | 37 | #pragma mark ### NSApplicationDelegate ### 38 | 39 | - (void) applicationDidFinishLaunching: (NSNotification *) notification 40 | { 41 | } 42 | 43 | - (BOOL) applicationShouldOpenUntitledFile: (NSApplication *) app 44 | { 45 | return YES; 46 | } 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /PulseConsole/English.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zonque/PulseAudioOSX/a45a37f7972730a9b9d82f3d04b6d9f866934d3d/PulseConsole/English.lproj/InfoPlist.strings -------------------------------------------------------------------------------- /PulseConsole/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleDocumentTypes 8 | 9 | 10 | CFBundleTypeName 11 | PulseAudioServer 12 | CFBundleTypeRole 13 | Editor 14 | LSTypeIsPackage 15 | 16 | NSDocumentClass 17 | ServerDocument 18 | NSPersistentStoreTypeKey 19 | XML 20 | 21 | 22 | CFBundleExecutable 23 | ${EXECUTABLE_NAME} 24 | CFBundleIconFile 25 | logo 26 | CFBundleIdentifier 27 | org.pulseaudio.PulseConsole 28 | CFBundleInfoDictionaryVersion 29 | 6.0 30 | CFBundleName 31 | ${PRODUCT_NAME} 32 | CFBundlePackageType 33 | APPL 34 | CFBundleSignature 35 | ???? 36 | CFBundleVersion 37 | 0.1 38 | NSMainNibFile 39 | MainMenu 40 | NSPrincipalClass 41 | NSApplication 42 | 43 | 44 | -------------------------------------------------------------------------------- /PulseConsole/Introspect.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseConsole 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseConsole is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2.1 of the License, or 9 | (at your option) any later version. 10 | 11 | PulseConsole is distributed in the hope that it will be useful, but 12 | WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with PulseAudio; if not, write to the Free Software 18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 19 | USA. 20 | ***/ 21 | 22 | #import 23 | 24 | @interface Introspect : NSObject 25 | { 26 | IBOutlet NSTableView *selectionTableView; 27 | IBOutlet NSTableView *parameterTableView; 28 | IBOutlet NSTableView *propertyTableView; 29 | 30 | NSMutableArray *outlineToplevel; 31 | NSMutableDictionary *parameters; 32 | NSMutableDictionary *properties; 33 | PAServerConnection *connection; 34 | } 35 | 36 | @property (nonatomic, retain) PAServerConnection *connection; 37 | 38 | - (void) serverReady; 39 | - (void) invalidateAll; 40 | - (void) contentChanged: (PAElementInfo *) item; 41 | - (void) enableGUI: (BOOL) enabled; 42 | - (void) repaintViews; 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /PulseConsole/MeterView.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseConsole 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseConsole is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2.1 of the License, or 9 | (at your option) any later version. 10 | 11 | PulseConsole is distributed in the hope that it will be useful, but 12 | WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with PulseAudio; if not, write to the Free Software 18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 19 | USA. 20 | ***/ 21 | 22 | #import 23 | 24 | 25 | @interface MeterView : NSView { 26 | NSInteger numChannels; 27 | NSInteger *currVal; 28 | NSInteger *lastPeak; 29 | } 30 | 31 | - (void) setNumChannels: (NSInteger) numChannels; 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /PulseConsole/MeterView.m: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseConsole 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseConsole is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2.1 of the License, or 9 | (at your option) any later version. 10 | 11 | PulseConsole is distributed in the hope that it will be useful, but 12 | WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with PulseAudio; if not, write to the Free Software 18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 19 | USA. 20 | ***/ 21 | 22 | #import "MeterView.h" 23 | 24 | 25 | @implementation MeterView 26 | 27 | - (id) initWithFrame: (NSRect) frame 28 | { 29 | self = [super initWithFrame:frame]; 30 | 31 | return self; 32 | } 33 | 34 | - (void) drawRect: (NSRect) dirtyRect 35 | { 36 | // [[NSColor blackColor] set]; 37 | // [NSBezierPath fillRect: dirtyRect]; 38 | } 39 | 40 | - (void) setNumChannels: (NSInteger) _numChannels 41 | { 42 | numChannels = _numChannels; 43 | 44 | if (currVal) { 45 | free(currVal); 46 | currVal = NULL; 47 | } 48 | 49 | if (lastPeak) { 50 | free(lastPeak); 51 | lastPeak = NULL; 52 | } 53 | 54 | lastPeak = malloc(sizeof(*lastPeak) * numChannels); 55 | currVal = malloc(sizeof(*currVal) * numChannels); 56 | } 57 | 58 | @end 59 | -------------------------------------------------------------------------------- /PulseConsole/MultipleLinesTextFieldCell.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseConsole. 3 | 4 | Copyright 2009-2011 Daniel Mack 5 | 6 | PulseAudio is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as 8 | published by the Free Software Foundation; either version 2.1 of the 9 | License, or (at your option) any later version. 10 | 11 | PulseAudio is distributed in the hope that it will be useful, but 12 | WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | Lesser General Public License for more details. 15 | 16 | You should have received a copy of the GNU Lesser General Public 17 | License along with PulseAudio; if not, write to the Free Software 18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 19 | USA. 20 | ***/ 21 | 22 | #import 23 | 24 | @interface MultipleLinesTextFieldCell : NSTextFieldCell 25 | { 26 | } 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /PulseConsole/MultipleLinesTextFieldCell.m: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseConsole. 3 | 4 | Copyright 2009-2011 Daniel Mack 5 | 6 | PulseAudio is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as 8 | published by the Free Software Foundation; either version 2.1 of the 9 | License, or (at your option) any later version. 10 | 11 | PulseAudio is distributed in the hope that it will be useful, but 12 | WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | Lesser General Public License for more details. 15 | 16 | You should have received a copy of the GNU Lesser General Public 17 | License along with PulseAudio; if not, write to the Free Software 18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 19 | USA. 20 | ***/ 21 | 22 | #import "MultipleLinesTextFieldCell.h" 23 | 24 | @implementation MultipleLinesTextFieldCell 25 | 26 | - (void) drawInteriorWithFrame: (NSRect) cellFrame 27 | inView: (NSView *) controlView 28 | { 29 | NSCharacterSet *set = [NSCharacterSet characterSetWithCharactersInString: @"|"]; 30 | NSArray *array = [[self stringValue] componentsSeparatedByCharactersInSet: set]; 31 | NSString *caption = [array objectAtIndex: 0]; 32 | NSString *details = [array objectAtIndex: 1]; 33 | NSMutableDictionary *attributes; 34 | 35 | attributes = [NSMutableDictionary dictionaryWithCapacity: 0]; 36 | [attributes setObject: [NSFont boldSystemFontOfSize: 12.0] 37 | forKey: NSFontAttributeName]; 38 | 39 | [caption drawAtPoint: NSMakePoint(cellFrame.origin.x, cellFrame.origin.y + 2) 40 | withAttributes: attributes]; 41 | 42 | attributes = [NSMutableDictionary dictionaryWithCapacity: 0]; 43 | [attributes setObject: [NSFont systemFontOfSize: 11.0] 44 | forKey: NSFontAttributeName]; 45 | [attributes setObject: [NSColor grayColor] 46 | forKey: NSForegroundColorAttributeName]; 47 | 48 | [details drawAtPoint: NSMakePoint(cellFrame.origin.x, cellFrame.origin.y + 20) 49 | withAttributes: attributes]; 50 | } 51 | 52 | @end 53 | -------------------------------------------------------------------------------- /PulseConsole/PulseConsole_Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'PulseConsole' target in the 'PulseConsole' project 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | -------------------------------------------------------------------------------- /PulseConsole/Server.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseConsole. 3 | 4 | Copyright 2009-2011 Daniel Mack 5 | 6 | PulseAudio is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as 8 | published by the Free Software Foundation; either version 2.1 of the 9 | License, or (at your option) any later version. 10 | 11 | PulseAudio is distributed in the hope that it will be useful, but 12 | WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | Lesser General Public License for more details. 15 | 16 | You should have received a copy of the GNU Lesser General Public 17 | License along with PulseAudio; if not, write to the Free Software 18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 19 | USA. 20 | ***/ 21 | 22 | #import 23 | #import 24 | #import 25 | 26 | #import "StreamListView.h" 27 | #import "StreamView.h" 28 | #import "Introspect.h" 29 | 30 | @class Server; 31 | 32 | @protocol ServerDelegate 33 | - (void) serverSignalledEnd: (Server *) server; 34 | @end 35 | 36 | 37 | @interface Server : NSObject 38 | { 39 | IBOutlet NSWindow *window; 40 | IBOutlet NSTabView *tabView; 41 | IBOutlet NSTableView *statisticsTableView; 42 | IBOutlet NSTextView *commandShell; 43 | IBOutlet NSProgressIndicator *connectionProgressIndicator; 44 | IBOutlet NSTextField *connectStatus; 45 | 46 | IBOutlet StreamListView *playbackStreamListView; 47 | IBOutlet StreamListView *recordStreamListView; 48 | IBOutlet StreamListView *sinkStreamListView; 49 | IBOutlet StreamListView *sourceStreamListView; 50 | 51 | IBOutlet Introspect *introspect; 52 | 53 | NSObject *delegate; 54 | 55 | PAServerConnection *connection; 56 | 57 | NSMutableDictionary *statisticDict; 58 | } 59 | 60 | @property (nonatomic, assign) NSObject *delegate; 61 | 62 | - (void) enableGUI: (BOOL) enabled; 63 | - (void) connectToServer: (NSString *) server; 64 | 65 | - (IBAction) reloadStatistics: (id) sender; 66 | 67 | @end 68 | -------------------------------------------------------------------------------- /PulseConsole/ServerDocument.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseConsole. 3 | 4 | Copyright 2009-2011 Daniel Mack 5 | 6 | PulseAudio is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as 8 | published by the Free Software Foundation; either version 2.1 of the 9 | License, or (at your option) any later version. 10 | 11 | PulseAudio is distributed in the hope that it will be useful, but 12 | WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | Lesser General Public License for more details. 15 | 16 | You should have received a copy of the GNU Lesser General Public 17 | License along with PulseAudio; if not, write to the Free Software 18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 19 | USA. 20 | ***/ 21 | 22 | #import 23 | #import 24 | #import "Server.h" 25 | 26 | @interface ServerDocument : NSDocument < 27 | PAServiceDiscoveryDelegate, 28 | NSTableViewDelegate, 29 | NSTableViewDataSource, 30 | ServerDelegate 31 | > 32 | { 33 | IBOutlet NSTableView *serverTableView; 34 | IBOutlet NSWindow *connectPanel; 35 | IBOutlet Server *server; 36 | 37 | NSMutableArray *serverArray; 38 | PAServiceDiscovery *discovery; 39 | } 40 | 41 | - (IBAction) connect: (id) sender; 42 | - (IBAction) cancel: (id) sender; 43 | - (IBAction) noop: (id) sender; 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /PulseConsole/StreamListView.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseConsole 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseConsole is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2.1 of the License, or 9 | (at your option) any later version. 10 | 11 | PulseConsole is distributed in the hope that it will be useful, but 12 | WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with PulseAudio; if not, write to the Free Software 18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 19 | USA. 20 | ***/ 21 | 22 | #import 23 | 24 | @interface StreamListView : NSView 25 | { 26 | NSMutableArray *streamViewItems; 27 | UInt32 streamType; 28 | } 29 | 30 | @property (nonatomic, assign) UInt32 streamType; 31 | 32 | - (void) removeAllStreams; 33 | - (void) recalcLayout; 34 | 35 | - (void) addItem: (PAElementInfo *) info 36 | name: (NSString *) name; 37 | - (void) removeItem: (PAElementInfo *) info; 38 | - (void) updateItem: (PAElementInfo *) info; 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /PulseConsole/StreamListView.m: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseConsole 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseConsole is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2.1 of the License, or 9 | (at your option) any later version. 10 | 11 | PulseConsole is distributed in the hope that it will be useful, but 12 | WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with PulseAudio; if not, write to the Free Software 18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 19 | USA. 20 | ***/ 21 | 22 | #import 23 | #import "StreamView.h" 24 | #import "StreamListView.h" 25 | 26 | @implementation StreamListView 27 | 28 | @synthesize streamType; 29 | 30 | - (id) initWithFrame: (NSRect) rect 31 | { 32 | [super initWithFrame: rect]; 33 | 34 | streamViewItems = [[NSMutableArray alloc] initWithCapacity: 0]; 35 | 36 | return self; 37 | } 38 | 39 | - (void) addStreamView: (id) info 40 | name: (NSString *) name; 41 | { 42 | NSRect frame = [self frame]; 43 | NSScrollView *enclosingScrollView = [self enclosingScrollView]; 44 | float height = 0.0f; 45 | 46 | NSLog(@"DEBUG: %s name >%@<\n", __func__, name); 47 | 48 | for (NSView *v in streamViewItems) 49 | height += [v frame].size.height; 50 | 51 | StreamView *view = [[StreamView alloc] initWithFrame: NSMakeRect(0.0, height, frame.size.width, 70.0) 52 | type: streamType 53 | name: name 54 | info: info]; 55 | 56 | // need to encapsulate in a NSDictionary 57 | [self addSubview: view]; 58 | [streamViewItems addObject: view]; 59 | 60 | height += [view frame].size.height; 61 | 62 | [self setFrameSize: NSMakeSize(frame.size.width, height)]; 63 | 64 | [enclosingScrollView setDocumentView: self]; 65 | [enclosingScrollView setNeedsDisplay: YES]; 66 | } 67 | 68 | - (void) removeStreamView: (id) info 69 | { 70 | for (StreamView *v in streamViewItems) 71 | if (v.info == info) { 72 | [streamViewItems removeObject: v]; 73 | break; 74 | } 75 | 76 | [self recalcLayout]; 77 | } 78 | 79 | - (void) recalcLayout 80 | { 81 | float y = 0.0f; 82 | 83 | for (NSView *v in streamViewItems) { 84 | NSRect rect = [v frame]; 85 | rect.origin.y = y; 86 | [v setFrameOrigin: rect.origin]; 87 | y += rect.size.height; 88 | } 89 | 90 | [super setFrameSize: NSMakeSize([self frame].size.width, y)]; 91 | [self setNeedsDisplay: YES]; 92 | } 93 | 94 | - (void) setFrameSize: (NSSize) size 95 | { 96 | for (NSView *v in streamViewItems) 97 | [v setFrameSize: NSMakeSize(size.width, [v frame].size.height)]; 98 | 99 | [self recalcLayout]; 100 | } 101 | 102 | - (BOOL) isFlipped 103 | { 104 | return YES; 105 | } 106 | 107 | - (void) removeAllStreams 108 | { 109 | [streamViewItems removeAllObjects]; 110 | [self recalcLayout]; 111 | } 112 | 113 | - (void) addItem: (PAElementInfo *) info 114 | name: (NSString *) name 115 | { 116 | [self addStreamView: info 117 | name: name]; 118 | [self recalcLayout]; 119 | } 120 | 121 | - (void) removeItem: (PAElementInfo *) info 122 | { 123 | [self removeStreamView: info]; 124 | [self recalcLayout]; 125 | } 126 | 127 | - (void) updateItem: (PAElementInfo *) info 128 | { 129 | for (StreamView *v in streamViewItems) 130 | if (v.info == info) 131 | [v update]; 132 | } 133 | 134 | @end 135 | -------------------------------------------------------------------------------- /PulseConsole/StreamView.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseConsole 3 | 4 | Copyright 2010,2011 Daniel Mack 5 | 6 | PulseConsole is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2.1 of the License, or 9 | (at your option) any later version. 10 | 11 | PulseConsole is distributed in the hope that it will be useful, but 12 | WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with PulseAudio; if not, write to the Free Software 18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 19 | USA. 20 | ***/ 21 | 22 | #import 23 | #import "MeterView.h" 24 | 25 | enum { 26 | StreamTypeUnknown, 27 | StreamTypeSource, 28 | StreamTypeSink, 29 | StreamTypePlayback, 30 | StreamTypeRecording, 31 | StreamTypeMax 32 | }; 33 | 34 | @interface StreamView : NSView { 35 | NSTextField *label; 36 | NSSlider *masterSlider; 37 | NSBox *box; 38 | NSButton *expandButton, *lockButton; 39 | NSPopUpButton *endpointSelect; 40 | MeterView *meterView; 41 | 42 | NSMutableArray *channelSliders, *channelLabels; 43 | NSInteger expandedHeight; 44 | CGFloat longestChannelLabel; 45 | 46 | PAElementInfo *info; 47 | NSInteger type; 48 | } 49 | 50 | @property (nonatomic, readonly) PAElementInfo *info; 51 | 52 | - (id) initWithFrame: (NSRect) rect 53 | type: (NSInteger) _type 54 | name: (NSString *) _name 55 | info: (PAElementInfo *) _info; 56 | 57 | - (void) update; 58 | 59 | @end 60 | -------------------------------------------------------------------------------- /PulseConsole/logo.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zonque/PulseAudioOSX/a45a37f7972730a9b9d82f3d04b6d9f866934d3d/PulseConsole/logo.icns -------------------------------------------------------------------------------- /PulseConsole/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // PulseConsole 4 | // 5 | // Created by Daniel on 10.12.09. 6 | // Copyright __MyCompanyName__ 2009. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, char *argv[]) 12 | { 13 | return NSApplicationMain(argc, (const char **) argv); 14 | } 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # IMPORTANT 2 | 3 | **This project is not currently actively maintained, as the original author lost his enthusiasm about Max OS X, and because his Apple hardware died.** 4 | 5 | The code is not up-to-date with the latest releases of XCode, and might not even be compatible with new rules declared by more recent version of OS X. 6 | 7 | Hence, if anyone is interested to move this forward and he/she is looking for a new project to maintain, please drop me a line. I'll happily hand over the maintainership. 8 | 9 | Thanks, 10 | Daniel 11 | 12 | 13 | 14 | 15 | For more, technical information, please see the Wiki on the GitHub project page: 16 | 17 | https://github.com/zonque/PulseAudioOSX/wiki 18 | 19 | -------------------------------------------------------------------------------- /deploy/.gitignore: -------------------------------------------------------------------------------- 1 | output 2 | -------------------------------------------------------------------------------- /deploy/InstallerResources/background.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zonque/PulseAudioOSX/a45a37f7972730a9b9d82f3d04b6d9f866934d3d/deploy/InstallerResources/background.tif -------------------------------------------------------------------------------- /deploy/InstallerResources/postinstall: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | open /Library/Frameworks/PulseAudio.framework/Contents/Resources/PulseAudioHelper.app 4 | 5 | -------------------------------------------------------------------------------- /deploy/ReleaseNotes.txt: -------------------------------------------------------------------------------- 1 | Version 0.2.0 2 | 3 | This package version contains the following components 4 | - PulseAudio daemon and tools: 0.1 5 | - HAL plugin: 1.0.0 6 | - Preference Pane: 0.1.0 7 | - PulseConsole: 0.1 8 | 9 | Version 0.2.0 10 | 11 | This package version contains the following components 12 | - PulseAudio daemon and tools: 0.1 13 | - HAL plugin: 1.0.0 14 | - Preference Pane: 0.1.0 15 | - PulseConsole: 0.1 16 | 17 | Version 0.2.0 18 | 19 | This package version contains the following components 20 | - PulseAudio daemon and tools: 21 | - HAL plugin: 1.0.0 22 | - Preference Pane: 0.1.0 23 | - PulseConsole: 0.1 24 | 25 | Version 0.1.1 26 | 27 | This package version contains the following components 28 | - PulseAudio daemon and tools: 1.0-dev-263-g166b 29 | - HAL plugin: 1.0.0 30 | - Preference Pane: 0.1.0 31 | - PulseConsole: 0.1 32 | 33 | Version 0.1.1 34 | 35 | This package version contains the following components 36 | - PulseAudio daemon and tools: 1.0-dev-263-g166b 37 | - HAL plugin: 1.0.0 38 | - Preference Pane: 0.1.0 39 | - PulseConsole: 0.1 40 | 41 | Version 0.1.1 42 | 43 | This package version contains the following components 44 | - PulseAudio daemon and tools: 1.0-dev-255-g9b1b3 45 | - HAL plugin: 1.0.0 46 | - Preference Pane: 0.1.0 47 | - PulseConsole: 0.1 48 | 49 | Version 0.1.1 50 | 51 | This package version contains the following components 52 | - PulseAudio daemon and tools: 1.0-dev-255-g9b1b3 53 | - HAL plugin: 1.0.0 54 | - Preference Pane: 0.1.0 55 | - PulseConsole: 0.1 56 | 57 | Version 0.1.1 58 | 59 | This package version contains the following components 60 | - PulseAudio daemon and tools: 1.0-dev-255-g9b1b3 61 | - HAL plugin: 1.0.0 62 | - Preference Pane: 0.1.0 63 | - PulseConsole: 0.1 64 | 65 | Version 0.1.1 66 | 67 | This package version contains the following components 68 | - PulseAudio daemon and tools: 1.0-dev-255-g9b1b3 69 | - HAL plugin: 1.0.0 70 | - Preference Pane: 0.1.0 71 | - PulseConsole: 0.1 72 | 73 | 74 | -------------------------------------------------------------------------------- /deploy/bootstrap_machine.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | PORTS="autoconf automake intltool libtool libsndfile speex-devel gdbm liboil json-c" 4 | 5 | for port in $PORTS; do 6 | port install $port +universal; 7 | done 8 | 9 | # we need to stage the pulseaudio binaries to /Library/Frameworks/PulseAudio.framework, hence 10 | # this path needs to be writable by the current user. This is admittedly a hack, but I lack a 11 | # better solution for now. 12 | 13 | chown $USER /Library/Frameworks 14 | 15 | -------------------------------------------------------------------------------- /deploy/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | targetdir=$1 4 | 5 | if [ -z "${targetdir}" ]; then 6 | echo "Usage: $0 [targetdir]" 7 | exit 1 8 | fi 9 | 10 | set -x 11 | set -e 12 | 13 | function XcodeBuild() 14 | { 15 | proj=$1; shift 16 | xcodebuild -project ${proj} clean 17 | xcodebuild -project ${proj} -alltargets -parallelizeTargets -configuration Release 18 | } 19 | 20 | base=$(pwd) 21 | 22 | ################################## pulseaudio source tree ################################## 23 | f=/Library/Frameworks/PulseAudio.framework 24 | test -d $f && rm -rf $f/* 25 | test -d $f || mkdir $f 26 | mkdir -p $f/Contents/MacOS 27 | mkdir -p $f/Contents/Resources 28 | cd ${base}/../../pulseaudio/ 29 | sh ${base}/build_pulseaudio.sh 30 | 31 | ################################## framework ################################## 32 | cd ${base}/../Framework 33 | XcodeBuild PulseAudio.xcodeproj 34 | sh install.sh 35 | sh ${base}/fixup_framework.sh 36 | dest=${targetdir}/Library/Frameworks 37 | mkdir -p ${dest} 38 | cp -a /Library/Frameworks/PulseAudio.framework ${dest}/ 39 | 40 | ################################## PulseAudioHelper ################################## 41 | cd ${base}/../PulseAudioHelper/ 42 | XcodeBuild PulseAudioHelper.xcodeproj 43 | dest=${targetdir}/Library/Frameworks/PulseAudio.framework/Contents/Resources 44 | mkdir -p ${dest} 45 | cp -a build/Release/PulseAudioHelper.app ${dest}/ 46 | 47 | ################################## HAL plugin ################################## 48 | cd ${base}/../HALPlugin/ 49 | XcodeBuild HALPlugin.xcodeproj 50 | dest=${targetdir}/Library/Audio/Plug-Ins/HAL 51 | mkdir -p ${dest} 52 | cp -a build/Release/PulseAudio.plugin ${dest}/ 53 | 54 | ################################## Preference Pane ################################## 55 | cd ${base}/../PreferencePane/ 56 | XcodeBuild PAPreferencePane.xcodeproj 57 | dest=${targetdir}/Library/PreferencePanes 58 | mkdir -p ${dest} 59 | cp -a build/Release/PulseAudio.prefPane ${dest}/ 60 | 61 | ################################## PulseConsole ################################## 62 | cd ${base}/../PulseConsole/ 63 | XcodeBuild PulseConsole.xcodeproj 64 | dest=${targetdir}/Applications 65 | mkdir -p ${dest} 66 | cp -a build/Release/PulseConsole.app ${dest}/ 67 | 68 | 69 | echo "Built and staged into ${targetdir}" 70 | 71 | -------------------------------------------------------------------------------- /deploy/build_pulseaudio.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # This needs to be in its own script, as the other parts of the build system 5 | # don't like to have environment variables redefined 6 | # 7 | 8 | set -x 9 | 10 | export PATH="/opt/local/bin:/opt/local/sbin:$PATH" 11 | export CC="gcc" 12 | #export CFLAGS="-I/opt/local/include -O0 -g" 13 | export CFLAGS="-I/opt/local/include -O2" 14 | export LDFLAGS="-L/opt/local/lib" 15 | staging=/Library/Frameworks/PulseAudio.framework/Contents/MacOS 16 | 17 | if [ ! -d $staging ]; then 18 | echo "$staging does not exist. Please create and make it writeable for your user" 19 | exit 1; 20 | fi 21 | 22 | ./autogen.sh \ 23 | --prefix=$staging \ 24 | --enable-mac-universal \ 25 | --disable-dependency-tracking \ 26 | --disable-jack \ 27 | --disable-glib2 \ 28 | --disable-hal \ 29 | --disable-bluez \ 30 | --disable-dbus \ 31 | --disable-avahi \ 32 | --with-mac-version-min=10.6 \ 33 | --with-mac-sysroot=/Developer/SDKs/MacOSX10.6.sdk \ 34 | $* && make clean install 35 | 36 | -------------------------------------------------------------------------------- /deploy/deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | # 6 | # Calling this script with no arguments will cause build.sh to be called 7 | # to compile the whole source tree from scratch. Mainly for development 8 | # and debugging of the package maker process, it can also be called with 9 | # an argument to reference a tree of built stuff to be packed. 10 | # 11 | 12 | source version.inc 13 | 14 | targetdir=$1 15 | 16 | if [ -z "$targetdir" ]; then 17 | rm -fr /tmp/paosx.* 18 | targetdir=$(mktemp -u /tmp/paosx.XXXXXX) 19 | ./build.sh $targetdir 20 | fi 21 | 22 | ./updateReleaseNotes.sh $targetdir $version 23 | 24 | outdir=output/ 25 | pkgname=PulseAudioOSX-Installer-${version}.pkg 26 | zipname=${pkgname/.pkg/.zip} 27 | 28 | test -d ${outdir} || mkdir ${outdir} 29 | 30 | /Developer/Applications/Utilities/PackageMaker.app/Contents/MacOS/PackageMaker \ 31 | --id org.pulseaudio.PulseAudioOSX.installer-${version} \ 32 | --title "PulseAudio for Mac OS X v${version}" \ 33 | --resources InstallerResources/ \ 34 | --out ${outdir}/${pkgname} \ 35 | --version ${version} \ 36 | --root ${targetdir} \ 37 | --root-volume-only \ 38 | --no-relocate \ 39 | --verbose 40 | 41 | cd ${outdir} 42 | zip -r -9 $zipname $pkgname 43 | 44 | -------------------------------------------------------------------------------- /deploy/fixup_framework.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # This script is intended to copy resources from the PulseAudio installation 5 | # location to the Framework bundle and make it self-contained. 6 | # Therefore, all dependencies to all binaries are resolved, the dependency libs 7 | # are copied over and install_name_tool is called to modify the library 8 | # locations inside the binary. The result is a fully encapsulated Framework 9 | # that has no dependencies other than the typical Mac OS X libraries. 10 | # 11 | # Instructions: 12 | # - use MacPorts to install the depencency libraries for PulseAudio (see the Wiki for a complete list) 13 | # - build the pulseaudio source tree and set --prefix to /Library/Frameworks/PulseAudio.framework/Contents/MacOS/ 14 | # - build the Framework sources (which will implicitly link against /Library/Frameworks/PulseAudio.framework/Contents/MacOS/) 15 | # - install the bundle to /Library/Frameworks (use the install.sh script) 16 | # - call this script 17 | # 18 | 19 | set -e 20 | 21 | framework=/Library/Frameworks/PulseAudio.framework 22 | 23 | if [ ! -d $framework ]; then 24 | echo "Huh? $framework does not exist?" 25 | exit 1 26 | fi 27 | 28 | dest=$framework/Contents/MacOS 29 | paversion="1.98" 30 | 31 | libpath=$dest/lib 32 | modpath=$dest/lib/pulse-$paversion/modules 33 | binpath=$dest/bin 34 | portlibs=/opt/local/lib 35 | 36 | function copy_with_symlinks() 37 | { 38 | source=$1 39 | dest=$2 40 | sdir=$(dirname $source) 41 | 42 | echo cp -a $source $dest 43 | cp -a $source $dest 44 | 45 | while [ "$(stat -f%T $source)" == "@" ]; do 46 | source=$sdir/$(readlink $source) 47 | echo "follow link $source" 48 | echo cp -a $source $dest 49 | cp -a $source $dest 50 | done 51 | } 52 | 53 | function relocate_libs() 54 | { 55 | pattern=$1; shift 56 | prefix=$1; shift 57 | path=$1; shift 58 | 59 | # as the resolving process can raise new dependencies, we have to do this in a loop 60 | run=1 61 | 62 | while [ $run -eq 1 ]; do 63 | run=0 64 | 65 | for file in $(find $path -type f -depth 1); do 66 | (file $file | grep -qi binary) && [ "$(basename $file)" != "PulseAudio" ] && \ 67 | install_name_tool -id $prefix/$(basename $file) $file 68 | 69 | for deplib in $(otool -L $file | grep $pattern | cut -d" " -f1); do 70 | 71 | basename=$(basename $deplib) 72 | newlib=$prefix/$basename 73 | 74 | if [ ! -e $prefix/$basename ]; then 75 | echo "Copying $deplib" 76 | copy_with_symlinks $deplib $prefix/ 77 | run=1 78 | fi 79 | 80 | #if [ -h $libpath/$baselib ]; then 81 | # rlink=$(readlink $deplib) 82 | # deplib=$(dirname $deplib)/$rlink 83 | # baselib=$rlink 84 | # echo "Redirecting to $rlink" 85 | #fi 86 | 87 | if [ -f $path/$basename ]; then 88 | echo install_name_tool -id $prefix/$basename $path/$basename 89 | install_name_tool -id $prefix/$basename $path/$basename 90 | fi 91 | 92 | echo "resolving dependency $deplib for $(basename $file) ..." 93 | 94 | echo install_name_tool -change $deplib $newlib $file 95 | install_name_tool -change $deplib $newlib $file 96 | done 97 | done 98 | done 99 | } 100 | 101 | relocate_libs $portlibs $libpath $modpath 102 | relocate_libs $portlibs $libpath $libpath 103 | relocate_libs $portlibs $libpath $binpath 104 | 105 | relocate_libs $portlibs $libpath $modpath 106 | relocate_libs $portlibs $libpath $libpath 107 | relocate_libs $portlibs $libpath $binpath 108 | 109 | echo "done." 110 | -------------------------------------------------------------------------------- /deploy/updateReleaseNotes.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | targetdir=$1 4 | version=$2 5 | 6 | if [ -z "${targetdir}" ]; then 7 | echo "Usage: $0 " 8 | exit 1 9 | fi 10 | 11 | if [ ! -d "${targetdir}" ]; then 12 | echo "${targetdir} does not exists" 13 | exit 2 14 | fi 15 | 16 | function extractXML() 17 | { 18 | file=$1 19 | key=$2 20 | 21 | grep -1 ${key} ${file} | tail -1 | cut -f2 -d\> | cut -f1 -d\< 22 | } 23 | 24 | set -e 25 | 26 | pa_version=$(extractXML ${targetdir}/Library/Frameworks/PulseAudio.framework/Resources/Info.plist CFBundleShortVersionString) 27 | pulseconsle_version=$(extractXML ${targetdir}/Applications/PulseConsole.app/Contents/Info.plist CFBundleVersion) 28 | halplugin_version=$(extractXML ${targetdir}/Library/Audio/Plug-Ins/HAL/PulseAudio.plugin/Contents/Info.plist CFBundleShortVersionString) 29 | prefpane_version=$(extractXML ${targetdir}/Library/PreferencePanes/PulseAudio.prefPane/Contents/Info.plist CFBundleVersion) 30 | 31 | cat > ${targetdir}/rn <> ${targetdir}/rn 43 | cat ${targetdir}/rn > ReleaseNotes.txt 44 | rm -f ${targetdir}/rn 45 | 46 | -------------------------------------------------------------------------------- /deploy/version.inc: -------------------------------------------------------------------------------- 1 | version=1.pre7 2 | 3 | -------------------------------------------------------------------------------- /legacy/audioDaemon/deviceClient.h: -------------------------------------------------------------------------------- 1 | #ifndef DEVICE_CLIENT_H 2 | #define DEVICE_CLIENT_H 3 | 4 | extern CFMutableArrayRef deviceArray; 5 | 6 | IOReturn deviceClientStart(void); 7 | void deviceClientStop(void); 8 | 9 | #endif /* DEVICE_CLIENT_H */ 10 | -------------------------------------------------------------------------------- /legacy/audioDaemon/driverClient.h: -------------------------------------------------------------------------------- 1 | #ifndef DRIVER_CLIENT_H 2 | #define DRIVER_CLIENT_H 3 | 4 | extern mach_port_t driver_async_port; 5 | extern io_connect_t driverDataPort; 6 | 7 | IOReturn addDeviceFromInfo (struct PAVirtualDeviceInfo *info); 8 | IOReturn driverClientStart(void); 9 | 10 | #endif /* DRIVER_CLIENT_H */ 11 | -------------------------------------------------------------------------------- /legacy/audioDaemon/main.c: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2.1 of the License, or 9 | (at your option) any later version. 10 | ***/ 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #include "../kext/PAUserClientCommonTypes.h" 20 | 21 | #include "pulseAudio.h" 22 | #include "driverClient.h" 23 | #include "notificationCenter.h" 24 | 25 | int makeRealtime(void) 26 | { 27 | struct thread_time_constraint_policy ttcpolicy; 28 | uint64_t freq = 0; 29 | size_t size = sizeof(freq); 30 | int ret; 31 | 32 | ret = sysctlbyname("hw.cpufrequency", &freq, &size, NULL, 0); 33 | if (ret < 0) { 34 | printf("Unable to read CPU frequency, acquisition of real-time scheduling failed.\n"); 35 | return -1; 36 | } 37 | 38 | printf("sysctl for hw.cpufrequency: %llu\n", freq); 39 | 40 | /* See http://developer.apple.com/library/mac/#documentation/Darwin/Conceptual/KernelProgramming/scheduler/scheduler.html */ 41 | ttcpolicy.period = freq / 160; 42 | ttcpolicy.computation = freq / 3300; 43 | ttcpolicy.constraint = freq / 2200; 44 | ttcpolicy.preemptible = 1; 45 | 46 | ret = thread_policy_set(mach_thread_self(), 47 | THREAD_TIME_CONSTRAINT_POLICY, 48 | (thread_policy_t) &ttcpolicy, 49 | THREAD_TIME_CONSTRAINT_POLICY_COUNT); 50 | if (ret) { 51 | printf("Unable to set real-time thread priority (%08x).\n", ret); 52 | return -1; 53 | } 54 | 55 | printf("Successfully acquired real-time thread priority.\n"); 56 | return 0; 57 | } 58 | 59 | int main (int argc, const char **argv) { 60 | 61 | int ret; 62 | 63 | makeRealtime(); 64 | 65 | ret = pulseAudioClientStart(); 66 | if (ret) { 67 | printf("pulseAudioClientStart() returned %d\n", ret); 68 | return -1; 69 | } 70 | 71 | ret = driverClientStart(); 72 | if (ret) { 73 | printf("driverClientStart() returned %d\n", ret); 74 | return -1; 75 | } 76 | 77 | ret = notificationCenterStart(); 78 | if (ret) { 79 | printf("deviceClientStart() returned %d\n", ret); 80 | return -1; 81 | } 82 | 83 | CFRunLoopRun(); 84 | 85 | printf("%s(): terminating ...\n", __func__); 86 | 87 | pulseAudioClientStop(); 88 | 89 | return 0; 90 | } 91 | -------------------------------------------------------------------------------- /legacy/audioDaemon/notificationCenter.h: -------------------------------------------------------------------------------- 1 | #ifndef NOTIFICATION_CENTER_H 2 | #define NOTIFICATION_CENTER_H 3 | 4 | IOReturn notificationCenterStart(void); 5 | void notificationCenterSendDeviceList (void); 6 | 7 | #endif /* NOTIFICATION_CENTER_H */ 8 | -------------------------------------------------------------------------------- /legacy/audioDaemon/pulseAudio.c: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioOSX 3 | 4 | Copyright 2010 Daniel Mack 5 | 6 | PulseAudioOSX is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2.1 of the License, or 9 | (at your option) any later version. 10 | ***/ 11 | 12 | #include 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | #include "pulseAudio.h" 19 | 20 | static pa_threaded_mainloop *loop; 21 | 22 | int pulseAudioClientStart(void) 23 | { 24 | int ret; 25 | 26 | loop = pa_threaded_mainloop_new(); 27 | if (!loop) { 28 | printf("%s(): pa_threaded_mainloop_new() failed\n", __func__); 29 | return -1; 30 | } 31 | 32 | ret = pa_threaded_mainloop_start(loop); 33 | if (ret) { 34 | printf("%s(): pa_threaded_mainloop_start() returned %d\n", __func__, ret); 35 | return ret; 36 | } 37 | 38 | return 0; 39 | } 40 | 41 | void pulseAudioClientStop(void) 42 | { 43 | if (loop) { 44 | pa_threaded_mainloop_stop(loop); 45 | pa_threaded_mainloop_free(loop); 46 | loop = NULL; 47 | } 48 | } 49 | 50 | pa_mainloop_api *pulseAudioAPI(void) 51 | { 52 | return pa_threaded_mainloop_get_api(loop); 53 | } 54 | -------------------------------------------------------------------------------- /legacy/audioDaemon/pulseAudio.h: -------------------------------------------------------------------------------- 1 | #ifndef _AD_PULSEAUDIO_H 2 | #define _AD_PULSEAUDIO_H 3 | 4 | int pulseAudioClientStart(void); 5 | void pulseAudioClientStop(void); 6 | 7 | pa_mainloop_api *pulseAudioAPI(void); 8 | 9 | #endif /* _AD_PULSEAUDIO_H */ 10 | -------------------------------------------------------------------------------- /legacy/audioDaemon/virtualDeviceClient.h: -------------------------------------------------------------------------------- 1 | #ifndef VIRTUALDEVICE_CLIENT_H 2 | #define VIRTUALDEVICE_CLIENT_H 3 | 4 | IOReturn virtualDeviceClientStart(void); 5 | void virtualDeviceClientStop(void); 6 | 7 | #endif /* VIRTUALDEVICE_CLIENT_H */ 8 | -------------------------------------------------------------------------------- /legacy/kext/BuildNames.h: -------------------------------------------------------------------------------- 1 | #ifndef BUILDNAMES_H 2 | #define BUILDNAMES_H 3 | 4 | #define PADriver org_pulseaudio_driver 5 | #define PADevice org_pulseaudio_device 6 | #define PAEngine org_pulseaudio_audioengine 7 | #define PAStream org_pulseaudio_stream 8 | #define PAVirtualDevice org_pulseaudio_virtualdevice 9 | #define PADriverUserClient org_pulseaudio_driver_userclient 10 | #define PADeviceUserClient org_pulseaudio_device_userclient 11 | #define PAVirtualDeviceUserClient org_pulseaudio_virtualdevice_userclient 12 | 13 | #define Str(x) #x 14 | #define XStr(x) Str(x) 15 | 16 | #endif /* BUILDNAMES_H */ 17 | -------------------------------------------------------------------------------- /legacy/kext/English.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zonque/PulseAudioOSX/a45a37f7972730a9b9d82f3d04b6d9f866934d3d/legacy/kext/English.lproj/InfoPlist.strings -------------------------------------------------------------------------------- /legacy/kext/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleName 10 | ${PRODUCT_NAME} 11 | CFBundleIconFile 12 | 13 | CFBundleIdentifier 14 | org.pulseaudio.driver.PulseAudioKext 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundlePackageType 18 | KEXT 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0.0d1 23 | IOKitPersonalities 24 | 25 | PAVirtualDriver 26 | 27 | IOUserClientClass 28 | org_pulseaudio_driver_userclient 29 | IOProbeScore 30 | 1000 31 | CFBundleIdentifier 32 | org.pulseaudio.driver.PulseAudioKext 33 | IOClass 34 | org_pulseaudio_driver 35 | IOMatchCategory 36 | org_pulseaudio_driver 37 | IOProviderClass 38 | IOResources 39 | IOResourceMatch 40 | IOKit 41 | 42 | 43 | OSBundleLibraries 44 | 45 | com.apple.iokit.IOAudioFamily 46 | 1.5 47 | com.apple.kpi.bsd 48 | 8.0 49 | com.apple.kpi.iokit 50 | 8.0 51 | com.apple.kpi.libkern 52 | 8.0 53 | com.apple.kpi.mach 54 | 8.0 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /legacy/kext/PAClip.cpp: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioKext 3 | 4 | Copyright (c) 2010,2011 Daniel Mack 5 | 6 | PulseAudioKext is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2.1 of the License, or 9 | (at your option) any later version. 10 | ***/ 11 | 12 | #include "PAEngine.h" 13 | 14 | #include 15 | #include 16 | 17 | IOReturn 18 | PAEngine::clipOutputSamples(const void *mixBuffer, void *targetBuffer, 19 | UInt32 firstSampleFrame, UInt32 numberFrames, 20 | const IOAudioStreamFormat *streamFormat, IOAudioStream *stream) 21 | { 22 | UInt32 sampleIndex = (firstSampleFrame * streamFormat->fNumChannels); 23 | 24 | memcpy((float *) targetBuffer + sampleIndex, 25 | (float *) mixBuffer + sampleIndex, 26 | numberFrames * streamFormat->fNumChannels * sizeof(float)); 27 | 28 | return kIOReturnSuccess; 29 | } 30 | 31 | IOReturn 32 | PAEngine::convertInputSamples(const void *sourceBuffer, void *targetBuffer, 33 | UInt32 firstSampleFrame, UInt32 numberFrames, 34 | const IOAudioStreamFormat *streamFormat, IOAudioStream *stream) 35 | { 36 | UInt32 sampleIndex = (firstSampleFrame * streamFormat->fNumChannels); 37 | 38 | memcpy(targetBuffer, (float *) sourceBuffer + sampleIndex, 39 | numberFrames * streamFormat->fNumChannels * sizeof(float)); 40 | 41 | return kIOReturnSuccess; 42 | } 43 | 44 | -------------------------------------------------------------------------------- /legacy/kext/PADevice.cpp: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioKext 3 | 4 | Copyright (c) 2010,2011 Daniel Mack 5 | 6 | PulseAudioKext is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2.1 of the License, or 9 | (at your option) any later version. 10 | ***/ 11 | 12 | #include "PAEngine.h" 13 | #include "PADevice.h" 14 | #include "PALog.h" 15 | 16 | #define super IOAudioDevice 17 | 18 | OSDefineMetaClassAndStructors(PADevice, IOAudioDevice) 19 | 20 | bool 21 | PADevice::init(OSDictionary *dictionary) 22 | { 23 | OSDictionary *newDict = NULL; 24 | 25 | if (!dictionary) 26 | newDict = dictionary = OSDictionary::withCapacity(1); 27 | 28 | dictionary->setObject("IOUserClientClass", OSString::withCString(XStr(PADeviceUserClient))); 29 | 30 | bool ret = super::init(dictionary); 31 | 32 | if (newDict) 33 | newDict->release(); 34 | 35 | return ret; 36 | } 37 | 38 | bool 39 | PADevice::initHardware(IOService *provider) 40 | { 41 | debugFunctionEnter(); 42 | 43 | PADriver *driver = OSDynamicCast(PADriver, provider); 44 | if (!driver) 45 | return false; 46 | 47 | if (!super::initHardware(provider)) 48 | return false; 49 | 50 | setDeviceName(deviceInfo.name); 51 | setDeviceShortName(deviceInfo.name); 52 | setManufacturerName("pulseaudio.org"); 53 | setDeviceModelName("virtual audio device"); 54 | setDeviceTransportType('virt'); 55 | 56 | PAEngine *audioEngine = new PAEngine; 57 | 58 | if (!audioEngine) 59 | return false; 60 | 61 | if (!audioEngine->init(NULL) || 62 | !audioEngine->setDeviceInfo(&deviceInfo)) { 63 | audioEngine->release(); 64 | audioEngine = NULL; 65 | return false; 66 | } 67 | 68 | activateAudioEngine(audioEngine); 69 | 70 | // the core is holding a reference now, so we can drop ours 71 | audioEngine->release(); 72 | 73 | return true; 74 | } 75 | 76 | void 77 | PADevice::setInfo(const struct PAVirtualDeviceInfo *info) 78 | { 79 | debugFunctionEnter(); 80 | memcpy(&deviceInfo, info, sizeof(deviceInfo)); 81 | } 82 | 83 | void 84 | PADevice::getInfo(struct PAVirtualDeviceInfo *info) 85 | { 86 | debugFunctionEnter(); 87 | memcpy(info, &deviceInfo, sizeof(deviceInfo)); 88 | } 89 | -------------------------------------------------------------------------------- /legacy/kext/PADevice.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioKext 3 | 4 | Copyright (c) 2010,2011 Daniel Mack 5 | 6 | PulseAudioKext is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2.1 of the License, or 9 | (at your option) any later version. 10 | ***/ 11 | 12 | #ifndef PADEVICE_H 13 | #define PADEVICE_H 14 | 15 | #include "BuildNames.h" 16 | 17 | #include 18 | 19 | #include "PADriver.h" 20 | #include "PAUserClientCommonTypes.h" 21 | 22 | class PADevice : public IOAudioDevice 23 | { 24 | OSDeclareDefaultStructors(PADevice) 25 | struct PAVirtualDeviceInfo deviceInfo; 26 | 27 | public: 28 | bool init(OSDictionary *dictionary); 29 | bool initHardware(IOService *provider); 30 | void setInfo(const struct PAVirtualDeviceInfo *info); 31 | void getInfo(struct PAVirtualDeviceInfo *info); 32 | }; 33 | 34 | #endif /* PADEVICE_H */ 35 | 36 | -------------------------------------------------------------------------------- /legacy/kext/PADeviceUserClient.cpp: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioKext 3 | 4 | Copyright (c) 2010,2011 Daniel Mack 5 | 6 | PulseAudioKext is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2.1 of the License, or 9 | (at your option) any later version. 10 | ***/ 11 | 12 | #include 13 | 14 | #include "PAEngine.h" 15 | #include "PADevice.h" 16 | #include "PADeviceUserClient.h" 17 | #include "PADeviceUserClientTypes.h" 18 | #include "PALog.h" 19 | 20 | #define super IOUserClient 21 | 22 | OSDefineMetaClassAndStructors(PADeviceUserClient, IOUserClient) 23 | 24 | #pragma mark ########## IOUserClient ########## 25 | 26 | bool 27 | PADeviceUserClient::initWithTask(task_t owningTask, void *securityID, UInt32 type) 28 | { 29 | if (!owningTask) 30 | return false; 31 | 32 | clientTask = owningTask; 33 | return super::initWithTask(owningTask, securityID, type); 34 | } 35 | 36 | bool 37 | PADeviceUserClient::start(IOService *provider) 38 | { 39 | debugFunctionEnter(); 40 | 41 | device = OSDynamicCast(PADevice, provider); 42 | if (!device) 43 | return false; 44 | 45 | return super::start(provider); 46 | } 47 | 48 | void 49 | PADeviceUserClient::stop(IOService *provider) 50 | { 51 | debugFunctionEnter(); 52 | super::stop(provider); 53 | } 54 | 55 | IOReturn 56 | PADeviceUserClient::clientClose(void) 57 | { 58 | debugFunctionEnter(); 59 | // DON'T call super::clientClose, which just returns notSupported 60 | return terminate(0); 61 | } 62 | 63 | bool 64 | PADeviceUserClient::terminate(IOOptionBits options) 65 | { 66 | debugFunctionEnter(); 67 | return super::terminate(options); 68 | } 69 | 70 | IOReturn 71 | PADeviceUserClient::externalMethod(uint32_t selector, IOExternalMethodArguments *args, 72 | IOExternalMethodDispatch *dispatch, OSObject *target, void *reference) 73 | { 74 | IOExternalMethodDispatch genericMethodDispatch; 75 | 76 | if (!target) 77 | target = this; 78 | 79 | genericMethodDispatch.function = (IOExternalMethodAction) &PADeviceUserClient::genericMethodDispatchAction; 80 | genericMethodDispatch.checkScalarInputCount = args->scalarInputCount; 81 | genericMethodDispatch.checkStructureInputSize = args->structureInputSize; 82 | genericMethodDispatch.checkScalarOutputCount = args->scalarOutputCount; 83 | genericMethodDispatch.checkStructureOutputSize = args->structureOutputSize; 84 | 85 | currentDispatchSelector = selector; 86 | dispatch = (IOExternalMethodDispatch *) &genericMethodDispatch; 87 | 88 | return super::externalMethod(selector, args, dispatch, target, reference); 89 | } 90 | 91 | #pragma mark ########## message dispatch ########## 92 | 93 | IOReturn 94 | PADeviceUserClient::genericMethodDispatchAction(PADeviceUserClient *target, 95 | void *reference, 96 | IOExternalMethodArguments *args) 97 | { 98 | IOReturn status = kIOReturnBadArgument; 99 | 100 | debugIOLog("%s(%p) -- currentDispatchSelector %d\n", __func__, target, target->currentDispatchSelector); 101 | //target->dumpIOExternalMethodArguments(args); 102 | 103 | if (args->asyncReferenceCount == 0) { 104 | switch (target->currentDispatchSelector) { 105 | case kPADeviceUserClientGetDeviceInfo: 106 | status = target->getDeviceInfo(args); 107 | break; 108 | default: 109 | IOLog("%s(%p): unknown selector %d!\n", __func__, target, target->currentDispatchSelector); 110 | status = kIOReturnInvalid; 111 | } // switch 112 | } 113 | 114 | return status; 115 | } 116 | 117 | #pragma mark ########## PADeviceUserClient interface ########## 118 | 119 | IOReturn 120 | PADeviceUserClient::getDeviceInfo(IOExternalMethodArguments *args) 121 | { 122 | struct PAVirtualDeviceInfo *info = (struct PAVirtualDeviceInfo *) args->structureOutput; 123 | 124 | if (!info || args->structureOutputSize != sizeof(*info)) 125 | return kIOReturnInvalid; 126 | 127 | device->getInfo(info); 128 | 129 | return kIOReturnSuccess; 130 | } 131 | 132 | -------------------------------------------------------------------------------- /legacy/kext/PADeviceUserClient.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioKext 3 | 4 | Copyright (c) 2010,2011 Daniel Mack 5 | 6 | PulseAudioKext is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2.1 of the License, or 9 | (at your option) any later version. 10 | ***/ 11 | 12 | #ifndef PADEVICEUSERCLIENT_H 13 | #define PADEVICEUSERCLIENT_H 14 | 15 | #include 16 | 17 | #include "PADevice.h" 18 | #include "BuildNames.h" 19 | 20 | class PADevice; 21 | 22 | class PADeviceUserClient : public IOUserClient 23 | { 24 | OSDeclareDefaultStructors(PADeviceUserClient) 25 | 26 | private: 27 | PADevice *device; 28 | UInt currentDispatchSelector; 29 | task_t clientTask; 30 | 31 | /* IOMethodDispatchers */ 32 | static IOReturn genericMethodDispatchAction(PADeviceUserClient *target, void *reference, IOExternalMethodArguments *args); 33 | 34 | IOReturn getDeviceInfo(IOExternalMethodArguments *args); 35 | 36 | // IOUserClient interface 37 | public: 38 | IOReturn externalMethod(uint32_t selector, IOExternalMethodArguments *arguments, 39 | IOExternalMethodDispatch *dispatch, OSObject *target, void *reference); 40 | IOReturn clientClose(void); 41 | 42 | void stop(IOService * provider); 43 | bool start(IOService * provider); 44 | bool initWithTask(task_t owningTask, void * securityID, UInt32 type); 45 | bool terminate(IOOptionBits options); 46 | }; 47 | 48 | #endif /* PADEVICEUSERCLIENT_H */ 49 | 50 | -------------------------------------------------------------------------------- /legacy/kext/PADeviceUserClientTypes.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioKext 3 | 4 | Copyright (c) 2010,2011 Daniel Mack 5 | 6 | PulseAudioKext is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2.1 of the License, or 9 | (at your option) any later version. 10 | ***/ 11 | 12 | #ifndef PA_DEVICE_USERCLIENT_TYPES_H 13 | #define PA_DEVICE_USERCLIENT_TYPES_H 14 | 15 | /* synchronous functions */ 16 | enum { 17 | kPADeviceUserClientGetDeviceInfo = 0, 18 | }; 19 | 20 | #endif /* PA_DEVICE_USERCLIENT_TYPES_H */ 21 | 22 | -------------------------------------------------------------------------------- /legacy/kext/PADriver.cpp: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioKext 3 | 4 | Copyright (c) 2010,2011 Daniel Mack 5 | 6 | PulseAudioKext is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2.1 of the License, or 9 | (at your option) any later version. 10 | ***/ 11 | 12 | #include 13 | 14 | #include "PADriver.h" 15 | #include "PADevice.h" 16 | #include "PALog.h" 17 | 18 | #include "PAUserClientCommonTypes.h" 19 | #include "PADriverUserClientTypes.h" 20 | 21 | #define super IOService 22 | 23 | OSDefineMetaClassAndStructors(PADriver, IOService) 24 | 25 | #pragma mark ########## IOService ########## 26 | 27 | bool 28 | PADriver::init(OSDictionary* dictionary) 29 | { 30 | if (!super::init(dictionary)) 31 | return false; 32 | 33 | debugFunctionEnter(); 34 | 35 | deviceArray = OSArray::withCapacity(1); 36 | if (!deviceArray) 37 | return false; 38 | 39 | return true; 40 | } 41 | 42 | void 43 | PADriver::free(void) 44 | { 45 | debugFunctionEnter(); 46 | 47 | if (!deviceArray) 48 | return; 49 | 50 | deviceArray->release(); 51 | deviceArray = NULL; 52 | 53 | super::free(); 54 | } 55 | 56 | bool 57 | PADriver::start(IOService *provider) 58 | { 59 | debugFunctionEnter(); 60 | 61 | if (!super::start(provider)) 62 | return false; 63 | 64 | registerService(); 65 | return true; 66 | } 67 | 68 | bool 69 | PADriver::terminate(IOOptionBits options) 70 | { 71 | debugFunctionEnter(); 72 | return super::terminate(options); 73 | } 74 | 75 | #pragma mark ########## proprietary methods ########## 76 | 77 | IOReturn 78 | PADriver::numberOfDevices(void) 79 | { 80 | return deviceArray->getCount(); 81 | } 82 | 83 | IOReturn 84 | PADriver::addAudioDevice(const struct PAVirtualDeviceInfo *info) 85 | { 86 | PADevice *device = new PADevice; 87 | 88 | if (!device) 89 | return kIOReturnNoMemory; 90 | 91 | if (!device->init(NULL) || 92 | !deviceArray->setObject(device)) { 93 | device->release(); 94 | return kIOReturnError; 95 | } 96 | 97 | /* find our new device in the array */ 98 | UInt index = deviceArray->getNextIndexOfObject((OSMetaClassBase *) device, 0); 99 | device->attachToParent(this, gIOServicePlane); 100 | device->setInfo(info); 101 | 102 | if (!device->start(this)) { 103 | deviceArray->removeObject(index); 104 | device->release(); 105 | return kIOReturnError; 106 | } 107 | 108 | return kIOReturnSuccess; 109 | } 110 | 111 | IOReturn 112 | PADriver::removeAudioDevice(UInt index) 113 | { 114 | PADevice *device = OSDynamicCast(PADevice, deviceArray->getObject(index)); 115 | 116 | if (!device) 117 | return kIOReturnInvalid; 118 | 119 | device->detachFromParent(this, gIOServicePlane); 120 | device->stop(this); 121 | device->terminate(0); 122 | device->release(); 123 | deviceArray->removeObject(index); 124 | 125 | return kIOReturnSuccess; 126 | } 127 | 128 | void 129 | PADriver::removeAllAudioDevices(void) 130 | { 131 | OSCollectionIterator *iter = OSCollectionIterator::withCollection(deviceArray); 132 | OSObject *obj; 133 | 134 | while ((obj = iter->getNextObject())) { 135 | PADevice *device = OSDynamicCast(PADevice, obj); 136 | 137 | if (device) { 138 | device->detachFromParent(this, gIOServicePlane); 139 | device->stop(this); 140 | device->terminate(0); 141 | device->release(); 142 | } 143 | } 144 | 145 | iter->release(); 146 | deviceArray->flushCollection(); 147 | } 148 | -------------------------------------------------------------------------------- /legacy/kext/PADriver.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioKext 3 | 4 | Copyright (c) 2010,2011 Daniel Mack 5 | 6 | PulseAudioKext is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2.1 of the License, or 9 | (at your option) any later version. 10 | ***/ 11 | 12 | #ifndef PADRIVER_H 13 | #define PADRIVER_H 14 | 15 | #include "BuildNames.h" 16 | #include "PAUserClientCommonTypes.h" 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | class PADevice; 23 | class PAEngine; 24 | 25 | class PADriver : public IOService 26 | { 27 | OSDeclareDefaultStructors(PADriver) 28 | 29 | public: 30 | bool init(OSDictionary* dictionary); 31 | void free(void); 32 | bool start(IOService *provider); 33 | bool terminate(IOOptionBits options); 34 | 35 | IOReturn numberOfDevices(void); 36 | IOReturn addAudioDevice(const struct PAVirtualDeviceInfo *info); 37 | IOReturn removeAudioDevice(UInt index); 38 | void removeAllAudioDevices(void); 39 | 40 | private: 41 | OSArray *deviceArray; 42 | }; 43 | 44 | #endif /* PADRIVER_H */ 45 | 46 | -------------------------------------------------------------------------------- /legacy/kext/PADriverUserClient.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioKext 3 | 4 | Copyright (c) 2010,2011 Daniel Mack 5 | 6 | PulseAudioKext is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2.1 of the License, or 9 | (at your option) any later version. 10 | ***/ 11 | 12 | #ifndef PAUSERCLIENT_H 13 | #define PAUSERCLIENT_H 14 | 15 | #include 16 | 17 | #include "PADriver.h" 18 | #include "BuildNames.h" 19 | 20 | class PAVirtualDevice; 21 | 22 | class PADriverUserClient : public IOUserClient 23 | { 24 | OSDeclareDefaultStructors(PADriverUserClient) 25 | 26 | private: 27 | PADriver *driver; 28 | UInt currentDispatchSelector; 29 | task_t clientTask; 30 | 31 | /* IOMethodDispatchers */ 32 | static IOReturn genericMethodDispatchAction(PADriverUserClient *target, void *reference, IOExternalMethodArguments *args); 33 | 34 | IOReturn getNumberOfDevices(IOExternalMethodArguments *args); 35 | IOReturn addDevice(IOExternalMethodArguments *args); 36 | IOReturn removeDevice(IOExternalMethodArguments *args); 37 | 38 | // IOUserClient interface 39 | public: 40 | IOReturn externalMethod(uint32_t selector, IOExternalMethodArguments *arguments, 41 | IOExternalMethodDispatch *dispatch, OSObject *target, void *reference); 42 | IOReturn clientClose(void); 43 | 44 | void stop(IOService * provider); 45 | bool start(IOService * provider); 46 | bool initWithTask(task_t owningTask, void * securityID, UInt32 type); 47 | bool terminate(IOOptionBits options); 48 | }; 49 | 50 | #endif /* PAUSERCLIENT_H */ 51 | 52 | -------------------------------------------------------------------------------- /legacy/kext/PADriverUserClientTypes.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioKext 3 | 4 | Copyright (c) 2010,2011 Daniel Mack 5 | 6 | PulseAudioKext is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2.1 of the License, or 9 | (at your option) any later version. 10 | ***/ 11 | 12 | #ifndef PA_DRIVER_USERCLIENT_TYPES_H 13 | #define PA_DRIVER_USERCLIENT_TYPES_H 14 | 15 | /* synchronous functions */ 16 | enum { 17 | kPADriverUserClientGetNumberOfDevices = 0, 18 | kPADriverUserClientAddDevice = 1, 19 | kPADriverUserClientRemoveDevice = 2, 20 | }; 21 | 22 | #endif /* PAUSERCLIENT_TYPES_H */ 23 | 24 | -------------------------------------------------------------------------------- /legacy/kext/PAEngine.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioKext 3 | 4 | Copyright (c) 2010,2011 Daniel Mack 5 | 6 | PulseAudioKext is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2.1 of the License, or 9 | (at your option) any later version. 10 | ***/ 11 | 12 | #ifndef PAENGINE_H 13 | #define PAENGINE_H 14 | 15 | #include "BuildNames.h" 16 | 17 | #include 18 | #include 19 | 20 | #include "PADevice.h" 21 | #include "PAUserClientCommonTypes.h" 22 | 23 | #define MAX_STREAMS 64 24 | 25 | class PAEngine : public IOAudioEngine 26 | { 27 | OSDeclareDefaultStructors(PAEngine) 28 | 29 | private: 30 | IOAudioStream *createNewAudioStream(IOAudioStreamDirection direction, void *sampleBuffer); 31 | UInt32 channelsIn, channelsOut, nStreams; 32 | UInt32 currentSampleRate; 33 | UInt32 samplePointer, lastSamplePointer; 34 | 35 | IOAudioStream *audioStream[MAX_STREAMS]; 36 | 37 | struct PAVirtualDeviceInfo *info; 38 | PADevice *device; 39 | IOBufferMemoryDescriptor *audioInBuf, *audioOutBuf; 40 | 41 | OSArray *virtualDeviceArray; 42 | 43 | public: 44 | void free(); 45 | bool initHardware(IOService *provider); 46 | bool setDeviceInfo(struct PAVirtualDeviceInfo *); 47 | 48 | OSString *getGlobalUniqueID(); 49 | IOReturn performAudioEngineStart(); 50 | IOReturn performAudioEngineStop(); 51 | UInt32 getCurrentSampleFrame(); 52 | IOReturn performFormatChange(IOAudioStream *inStream, 53 | const IOAudioStreamFormat *inNewFormat, 54 | const IOAudioSampleRate *inNewSampleRate); 55 | 56 | void getNextTimeStamp(UInt32 inLoopCount, AbsoluteTime* outTimeStamp); 57 | static void timerFired(OSObject *inTarget, IOTimerEventSource *inSender); 58 | 59 | IOReturn setNewSampleRate(UInt32 sampleRate); 60 | 61 | void writeSamplePointer(struct samplePointerUpdateEvent *ev); 62 | 63 | IOReturn addVirtualDevice(struct PAVirtualDeviceInfo *, 64 | IOMemoryDescriptor *inBuf, 65 | IOMemoryDescriptor *outBuf, 66 | void *refCon); 67 | 68 | void removeVirtualDeviceWithRefcon(void *refCon); 69 | 70 | void sendNotification(UInt32 notificationType, UInt32 value); 71 | 72 | /* these two are implemented in PAClip.cpp */ 73 | IOReturn clipOutputSamples(const void *inMixBuffer, void *outTargetBuffer, 74 | UInt32 inFirstFrame, UInt32 inNumberFrames, 75 | const IOAudioStreamFormat *inFormat, IOAudioStream *inStream); 76 | IOReturn convertInputSamples(const void *inSourceBuffer, void *outTargetBuffer, 77 | UInt32 inFirstFrame, UInt32 inNumberFrames, 78 | const IOAudioStreamFormat* inFormat, IOAudioStream* inStream); 79 | }; 80 | 81 | #endif /* PAENGINE_H */ 82 | 83 | -------------------------------------------------------------------------------- /legacy/kext/PALog.h: -------------------------------------------------------------------------------- 1 | #ifdef PA_DEBUG 2 | #define debugIOLog(x...) IOLog(x) 3 | #else 4 | #define debugIOLog(x...) do {} while(0) 5 | #endif 6 | 7 | #define debugFunctionEnter() debugIOLog("%s(%p)::%s @line %d\n", getName(), this, __func__, __LINE__) 8 | 9 | -------------------------------------------------------------------------------- /legacy/kext/PAStream.cpp: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioKext 3 | 4 | Copyright (c) 2010,2011 Daniel Mack 5 | 6 | PulseAudioKext is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2.1 of the License, or 9 | (at your option) any later version. 10 | ***/ 11 | 12 | #include 13 | 14 | #include "PAUserClientCommonTypes.h" 15 | #include "PAEngine.h" 16 | #include "PAStream.h" 17 | #include "PALog.h" 18 | 19 | #define super IOAudioStream 20 | 21 | OSDefineMetaClassAndStructors(PAStream, IOAudioStream) 22 | 23 | IOReturn 24 | PAStream::addClient(IOAudioClientBuffer *clientBuffer) 25 | { 26 | debugFunctionEnter(); 27 | 28 | struct PAVirtualDeviceInfo info; 29 | memcpy(&info, infoTemplate, sizeof(info)); 30 | 31 | IOReturn ret = super::addClient(clientBuffer); 32 | 33 | if (info.audioContentType == kPADeviceAudioContentMixdown) 34 | return ret; 35 | 36 | IOAudioEngineUserClient *client = clientBuffer->userClient; 37 | OSObject *prop = client->copyProperty("IOUserClientCreator"); 38 | if (!prop) 39 | return ret; 40 | 41 | OSString *str = OSDynamicCast(OSString, prop); 42 | if (!str) { 43 | prop->release(); 44 | return ret; 45 | } 46 | 47 | if (ret == kIOReturnSuccess) { 48 | IOAudioStreamDirection dir = clientBuffer->audioStream->direction; 49 | PAEngine *engine = OSDynamicCast(PAEngine, audioEngine); 50 | strncpy(info.name, str->getCStringNoCopy(), sizeof(info.name) - 1); 51 | 52 | if (dir == kIOAudioStreamDirectionInput) { 53 | info.channelsIn = clientBuffer->numChannels; 54 | info.channelsOut = 0; 55 | engine->addVirtualDevice(&info, clientBuffer->sourceBufferDescriptor, NULL, clientBuffer); 56 | } else { 57 | info.channelsIn = 0; 58 | info.channelsOut = clientBuffer->numChannels; 59 | engine->addVirtualDevice(&info, NULL, clientBuffer->sourceBufferDescriptor, clientBuffer); 60 | } 61 | } 62 | 63 | prop->release(); 64 | 65 | return ret; 66 | } 67 | 68 | void 69 | PAStream::removeClient(IOAudioClientBuffer *clientBuffer) 70 | { 71 | debugFunctionEnter(); 72 | 73 | PAEngine *engine = OSDynamicCast(PAEngine, audioEngine); 74 | if (engine) 75 | engine->removeVirtualDeviceWithRefcon(clientBuffer); 76 | 77 | super::removeClient(clientBuffer); 78 | } 79 | -------------------------------------------------------------------------------- /legacy/kext/PAStream.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioKext 3 | 4 | Copyright (c) 2010,2011 Daniel Mack 5 | 6 | PulseAudioKext is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2.1 of the License, or 9 | (at your option) any later version. 10 | ***/ 11 | 12 | #ifndef PASTREAM_H 13 | #define PASTREAM_H 14 | 15 | #include "BuildNames.h" 16 | #include "PAUserClientCommonTypes.h" 17 | 18 | #include 19 | #include 20 | 21 | class PAStream : public IOAudioStream 22 | { 23 | OSDeclareDefaultStructors(PAStream) 24 | struct PAVirtualDeviceInfo *infoTemplate; 25 | 26 | public: 27 | void setInfoTemplate(struct PAVirtualDeviceInfo *i) { infoTemplate = i; }; 28 | IOReturn addClient(IOAudioClientBuffer *clientBuffer); 29 | void removeClient(IOAudioClientBuffer *clientBuffer); 30 | }; 31 | 32 | #endif /* PASTREAM_H */ 33 | 34 | -------------------------------------------------------------------------------- /legacy/kext/PAUserClient.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioKext 3 | 4 | Copyright (c) 2010 Daniel Mack 5 | 6 | PulseAudioKext is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2.1 of the License, or 9 | (at your option) any later version. 10 | ***/ 11 | 12 | #ifndef PAUSERCLIENT_H 13 | #define PAUSERCLIENT_H 14 | 15 | #include 16 | 17 | #include "PADriver.h" 18 | #include "BuildNames.h" 19 | 20 | class PADevice; 21 | 22 | class PAUserClient : public IOUserClient 23 | { 24 | OSDeclareDefaultStructors(PAUserClient) 25 | 26 | private: 27 | PADriver *driver; 28 | UInt currentDispatchSelector; 29 | task_t clientTask; 30 | 31 | IOMemoryDescriptor *samplePointerReadDescriptor; 32 | OSAsyncReference64 samplePointerReadReference; 33 | 34 | IOMemoryDescriptor *notificationReadDescriptor; 35 | OSAsyncReference64 notificationReadReference; 36 | 37 | /* IOMethodDispatchers */ 38 | static IOReturn genericMethodDispatchAction(PAUserClient *target, void *reference, IOExternalMethodArguments *args); 39 | 40 | IOReturn getNumberOfDevices(IOExternalMethodArguments *args); 41 | IOReturn addDevice(IOExternalMethodArguments *args); 42 | IOReturn removeDevice(IOExternalMethodArguments *args); 43 | IOReturn getDeviceInfo(IOExternalMethodArguments *args); 44 | IOReturn setSamplerate(IOExternalMethodArguments *args); 45 | IOReturn readSamplePointer(IOExternalMethodArguments *args); 46 | IOReturn readNotification(IOExternalMethodArguments *args); 47 | 48 | // IOUserClient interface 49 | public: 50 | IOReturn externalMethod(uint32_t selector, IOExternalMethodArguments *arguments, 51 | IOExternalMethodDispatch *dispatch, OSObject *target, void *reference); 52 | IOReturn clientMemoryForType(UInt32 type, UInt32 *flags, IOMemoryDescriptor **memory); 53 | IOMemoryMap *removeMappingForDescriptor(IOMemoryDescriptor *memory); 54 | IOReturn message(UInt32 type, IOService *provider, void *argument = 0); 55 | IOReturn clientClose(void); 56 | 57 | void stop(IOService * provider); 58 | bool start(IOService * provider); 59 | bool initWithTask(task_t owningTask, void * securityID, UInt32 type); 60 | bool finalize(IOOptionBits options); 61 | bool terminate(IOOptionBits options); 62 | 63 | void reportSamplePointer(UInt32 index, UInt32 samplePointer); 64 | void sendNotification(UInt32 index, UInt32 notificationType, UInt32 value); 65 | }; 66 | 67 | #endif /* PAUSERCLIENT_H */ 68 | 69 | -------------------------------------------------------------------------------- /legacy/kext/PAUserClientCommonTypes.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioKext 3 | 4 | Copyright (c) 2010,2011 Daniel Mack 5 | 6 | PulseAudioKext is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2.1 of the License, or 9 | (at your option) any later version. 10 | ***/ 11 | 12 | #ifndef PA_USERCLIENT_COMMON_TYPES_H 13 | #define PA_USERCLIENT_COMMON_TYPES_H 14 | 15 | #define DEVICENAME_MAX 64 16 | #define SERVERNAME_MAX 256 17 | 18 | struct PAVirtualDeviceInfo { 19 | /* to be provided upon creation */ 20 | char name[DEVICENAME_MAX]; 21 | char server[SERVERNAME_MAX]; 22 | UInt32 channelsIn, channelsOut; 23 | UInt32 blockSize; 24 | UInt32 audioContentType; 25 | UInt32 streamCreationType; 26 | 27 | /* fields to read back from virtual device */ 28 | UInt32 index; 29 | UInt32 currentSamplerate; 30 | UInt32 nUsers; 31 | UInt32 audioBufferSize; 32 | }; 33 | 34 | /* audioContentType values */ 35 | enum { 36 | kPADeviceAudioContentMixdown = 0, 37 | kPADeviceAudioContentIndividual, 38 | }; 39 | 40 | /* streamCreationType values */ 41 | enum { 42 | kPADeviceStreamCreationPermanent = 0, 43 | kPADeviceStreamCreationOnDemand, 44 | }; 45 | 46 | #endif /* PA_USERCLIENT_COMMON_TYPES_H */ 47 | -------------------------------------------------------------------------------- /legacy/kext/PAUserClientTypes.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioKext 3 | 4 | Copyright (c) 2010 Daniel Mack 5 | 6 | PulseAudioKext is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2.1 of the License, or 9 | (at your option) any later version. 10 | ***/ 11 | 12 | #ifndef PAUSERCLIENT_TYPES_H 13 | #define PAUSERCLIENT_TYPES_H 14 | 15 | #define DEVICENAME_MAX 64 16 | 17 | /* clockDirection values */ 18 | enum { 19 | kPADeviceClockFromKernel = 0, 20 | kPADeviceClockFromClient, 21 | }; 22 | 23 | /* synchronous functions */ 24 | enum { 25 | kPAUserClientGetNumberOfDevices = 0, 26 | kPAUserClientAddDevice = 1, 27 | kPAUserClientRemoveDevice = 2, 28 | kPAUserClientGetDeviceInfo = 3, 29 | kPAUserClientSetSampleRate = 4, 30 | }; 31 | 32 | enum { 33 | kPAUserClientAsyncReadSamplePointer = 0, 34 | kPAUserClientAsyncReadNotification = 1, 35 | }; 36 | 37 | enum { 38 | kPAUserClientNotificationEngineStarted = 0, 39 | kPAUserClientNotificationEngineStopped = 1, 40 | kPAUserClientNotificationSampleRateChanged = 2, 41 | kPAUserClientNotificationMax, 42 | }; 43 | 44 | /* shared memory */ 45 | enum { 46 | kPAMemoryInputSampleData = 0, 47 | kPAMemoryOutputSampleData 48 | }; 49 | 50 | struct PAVirtualDevice { 51 | /* to be provided upon creation */ 52 | char name[DEVICENAME_MAX]; 53 | UInt32 channelsIn, channelsOut; 54 | UInt32 clockDirection; 55 | UInt32 blockSize; 56 | 57 | /* field to read back from driver */ 58 | UInt32 index; 59 | UInt32 currentSamplerate; 60 | UInt32 nUsers; 61 | UInt32 audioBufferSize; 62 | 63 | }; 64 | 65 | struct samplePointerUpdateEvent { 66 | UInt32 timeStampSec; 67 | UInt32 timeStampNanoSec; 68 | UInt32 index; 69 | UInt32 samplePointer; 70 | }; 71 | 72 | struct notificationBlock { 73 | UInt32 timeStampSec; 74 | UInt32 timeStampNanoSec; 75 | UInt32 notificationType; 76 | UInt32 value; 77 | }; 78 | 79 | #endif /* PAUSERCLIENT_TYPES_H */ 80 | 81 | -------------------------------------------------------------------------------- /legacy/kext/PAVirtualDevice.cpp: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioKext 3 | 4 | Copyright (c) 2010,2011 Daniel Mack 5 | 6 | PulseAudioKext is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2.1 of the License, or 9 | (at your option) any later version. 10 | ***/ 11 | 12 | #include "PAVirtualDeviceUserClient.h" 13 | #include "PAVirtualDeviceUserClientTypes.h" 14 | #include "PAEngine.h" 15 | #include "PAVirtualDevice.h" 16 | #include "PALog.h" 17 | 18 | #include "PAVirtualDeviceUserClientTypes.h" 19 | #include "PADriverUserClientTypes.h" 20 | 21 | #define super IOService 22 | 23 | OSDefineMetaClassAndStructors(PAVirtualDevice, IOService) 24 | 25 | bool 26 | PAVirtualDevice::init(OSDictionary *dictionary) 27 | { 28 | OSDictionary *newDict = NULL; 29 | 30 | if (!dictionary) 31 | newDict = dictionary = OSDictionary::withCapacity(1); 32 | 33 | dictionary->setObject("IOUserClientClass", OSString::withCString(XStr(PAVirtualDeviceUserClient))); 34 | 35 | bool ret = super::init(dictionary); 36 | 37 | if (newDict) 38 | newDict->release(); 39 | 40 | return ret; 41 | } 42 | 43 | bool 44 | PAVirtualDevice::start(IOService *provider) 45 | { 46 | debugFunctionEnter(); 47 | 48 | if (!super::start(provider)) 49 | return false; 50 | 51 | audioEngine = OSDynamicCast(PAEngine, provider); 52 | if (!audioEngine) 53 | return false; 54 | 55 | registerService(); 56 | return true; 57 | } 58 | 59 | void 60 | PAVirtualDevice::stop(IOService *provider) 61 | { 62 | debugFunctionEnter(); 63 | super::stop(provider); 64 | } 65 | 66 | bool 67 | PAVirtualDevice::terminate(IOOptionBits options) 68 | { 69 | debugFunctionEnter(); 70 | return super::terminate(options); 71 | } 72 | 73 | void 74 | PAVirtualDevice::free(void) 75 | { 76 | debugFunctionEnter(); 77 | super::free(); 78 | } 79 | 80 | void 81 | PAVirtualDevice::sendNotification(UInt32 notificationType, UInt32 value) 82 | { 83 | OSIterator *iter = getClientIterator(); 84 | PAVirtualDeviceUserClient *client; 85 | 86 | while ((client = OSDynamicCast(PAVirtualDeviceUserClient, iter->getNextObject()))) 87 | client->sendNotification(notificationType, value); 88 | 89 | iter->release(); 90 | } 91 | 92 | void 93 | PAVirtualDevice::setInfo(const struct PAVirtualDeviceInfo *newInfo) 94 | { 95 | memcpy(&deviceInfo, newInfo, sizeof(deviceInfo)); 96 | } 97 | 98 | void 99 | PAVirtualDevice::getInfo(struct PAVirtualDeviceInfo *info) 100 | { 101 | memcpy(info, &deviceInfo, sizeof(*info)); 102 | } 103 | 104 | IOReturn 105 | PAVirtualDevice::setSamplerate(UInt rate) 106 | { 107 | return audioEngine->setNewSampleRate(rate); 108 | } 109 | 110 | void 111 | PAVirtualDevice::writeSamplePointer(struct samplePointerUpdateEvent *ev) 112 | { 113 | audioEngine->writeSamplePointer(ev); 114 | } 115 | 116 | IOAudioEngineState 117 | PAVirtualDevice::engineState() 118 | { 119 | return audioEngine->state; 120 | } 121 | -------------------------------------------------------------------------------- /legacy/kext/PAVirtualDevice.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioKext 3 | 4 | Copyright (c) 2010,2011 Daniel Mack 5 | 6 | PulseAudioKext is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2.1 of the License, or 9 | (at your option) any later version. 10 | ***/ 11 | 12 | #ifndef PA_VIRTUALDEVICE_H 13 | #define PA_VIRTUALDEVICE_H 14 | 15 | #include "BuildNames.h" 16 | 17 | #include 18 | 19 | #include "PADriver.h" 20 | #include "PAUserClientCommonTypes.h" 21 | #include "PAVirtualDeviceUserClientTypes.h" 22 | 23 | class PAEngine; 24 | class PAUserClient; 25 | 26 | class PAVirtualDevice : public IOService 27 | { 28 | OSDeclareDefaultStructors(PAVirtualDevice) 29 | struct PAVirtualDeviceInfo deviceInfo; 30 | PAEngine *audioEngine; 31 | 32 | public: 33 | bool init(OSDictionary* dictionary); 34 | bool start(IOService *provider); 35 | void stop(IOService *provider); 36 | 37 | bool terminate(IOOptionBits options); 38 | 39 | void free(void); 40 | 41 | void reportSamplePointer(UInt32 pointer); 42 | void sendNotification(UInt32 notificationType, UInt32 value); 43 | 44 | void setInfo(const struct PAVirtualDeviceInfo *info); 45 | void getInfo(struct PAVirtualDeviceInfo *info); 46 | IOReturn setSamplerate(UInt rate); 47 | void writeSamplePointer(struct samplePointerUpdateEvent *ev); 48 | 49 | IOAudioEngineState engineState(); 50 | 51 | IOMemoryDescriptor *audioInputBuf; 52 | IOMemoryDescriptor *audioOutputBuf; 53 | void *refCon; 54 | }; 55 | 56 | #endif /* PA_VIRTUALDEVICE_H */ 57 | 58 | -------------------------------------------------------------------------------- /legacy/kext/PAVirtualDeviceUserClient.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioKext 3 | 4 | Copyright (c) 2010,2011 Daniel Mack 5 | 6 | PulseAudioKext is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2.1 of the License, or 9 | (at your option) any later version. 10 | ***/ 11 | 12 | #ifndef PA_VIRTUALDEVICE_USERCLIENT_H 13 | #define PA_VIRTUALDEVICE_USERCLIENT_H 14 | 15 | #include 16 | 17 | #include "PAVirtualDevice.h" 18 | #include "BuildNames.h" 19 | 20 | class PADevice; 21 | 22 | class PAVirtualDeviceUserClient : public IOUserClient 23 | { 24 | OSDeclareDefaultStructors(PAVirtualDeviceUserClient) 25 | 26 | private: 27 | PAVirtualDevice *device; 28 | UInt currentDispatchSelector; 29 | task_t clientTask; 30 | 31 | IOMemoryDescriptor *samplePointerReadDescriptor; 32 | OSAsyncReference64 samplePointerReadReference; 33 | 34 | IOMemoryDescriptor *notificationReadDescriptor; 35 | OSAsyncReference64 notificationReadReference; 36 | 37 | /* IOMethodDispatchers */ 38 | IOReturn getDeviceInfo(IOExternalMethodArguments *args); 39 | IOReturn setSamplerate(IOExternalMethodArguments *args); 40 | IOReturn writeSamplePointer(IOExternalMethodArguments *args); 41 | IOReturn readNotification(IOExternalMethodArguments *args); 42 | 43 | static IOReturn genericMethodDispatchAction(PAVirtualDeviceUserClient *target, 44 | void *reference, 45 | IOExternalMethodArguments *args); 46 | 47 | // IOUserClient interface 48 | public: 49 | IOReturn externalMethod(uint32_t selector, IOExternalMethodArguments *arguments, 50 | IOExternalMethodDispatch *dispatch, OSObject *target, void *reference); 51 | IOReturn clientMemoryForType(UInt32 type, UInt32 *flags, IOMemoryDescriptor **memory); 52 | IOMemoryMap *removeMappingForDescriptor(IOMemoryDescriptor *memory); 53 | IOReturn message(UInt32 type, IOService *provider, void *argument = 0); 54 | IOReturn clientClose(void); 55 | 56 | void stop(IOService * provider); 57 | bool start(IOService * provider); 58 | bool initWithTask(task_t owningTask, void * securityID, UInt32 type); 59 | bool finalize(IOOptionBits options); 60 | bool terminate(IOOptionBits options); 61 | 62 | void sendNotification(UInt32 notificationType, UInt32 value); 63 | }; 64 | 65 | #endif /* PA_VIRTUALDEVICE_USERCLIENT_H */ 66 | -------------------------------------------------------------------------------- /legacy/kext/PAVirtualDeviceUserClientTypes.h: -------------------------------------------------------------------------------- 1 | /*** 2 | This file is part of PulseAudioKext 3 | 4 | Copyright (c) 2010,2011 Daniel Mack 5 | 6 | PulseAudioKext is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2.1 of the License, or 9 | (at your option) any later version. 10 | ***/ 11 | 12 | #ifndef PA_VIRTUALDEVICE_USERCLIENT_TYPES_H 13 | #define PA_VIRTUALDEVICE_USERCLIENT_TYPES_H 14 | 15 | #define DEVICENAME_MAX 64 16 | 17 | /* synchronous functions */ 18 | enum { 19 | kPAVirtualDeviceUserClientGetDeviceInfo = 0, 20 | kPAVirtualDeviceUserClientSetSampleRate = 1, 21 | kPAVirtualDeviceUserClientWriteSamplePointer = 2, 22 | }; 23 | 24 | /* asynchronous functions */ 25 | enum { 26 | kPAVirtualDeviceUserClientAsyncReadNotification = 0, 27 | }; 28 | 29 | /* notification types */ 30 | enum { 31 | kPAVirtualDeviceUserClientNotificationEngineStarted = 0, 32 | kPAVirtualDeviceUserClientNotificationEngineStopped = 1, 33 | kPAVirtualDeviceUserClientNotificationSampleRateChanged = 2, 34 | kPAVirtualDeviceUserClientNotificationMax, 35 | }; 36 | 37 | /* shared memory */ 38 | enum { 39 | kPAMemoryInputSampleData = 0, 40 | kPAMemoryOutputSampleData 41 | }; 42 | 43 | /* types for asyncronous callback events */ 44 | struct samplePointerUpdateEvent { 45 | UInt32 timeStampSec; 46 | UInt32 timeStampNanoSec; 47 | UInt32 samplePointer; 48 | }; 49 | 50 | struct notificationBlock { 51 | UInt32 timeStampSec; 52 | UInt32 timeStampNanoSec; 53 | UInt32 notificationType; 54 | UInt32 value; 55 | }; 56 | 57 | #endif /* PA_VIRTUALDEVICE_USERCLIENT_TYPES_H */ 58 | 59 | -------------------------------------------------------------------------------- /legacy/kext/README: -------------------------------------------------------------------------------- 1 | The concept of the driver model is to have one abstract IOService object 2 | (instance of PADriver) which is the root node for all other objects. 3 | Upon creation (at load time of the driver), the PADriver will be 4 | announced to the userspace to let the audioDaemon know. 5 | 6 | A IOUserClient class named PADriverUserClient can be instanciated by 7 | the user space, and commands can be issued to create new and delete 8 | instances of PADevices. A PADevice is derived from IOAudioDevice and 9 | acts as a virtual audio device. To export audio functions, it has to 10 | have an PAEngine (derived from IOAudioEngine). 11 | 12 | Depending on the type of audio engine (one for the mixed audio stream or 13 | one for each individual user client), the PAEngine can have one or many 14 | references to PAVirtualDevices, respectively. 15 | 16 | Once a PAVirtualDevice is created, it is announced to the userspace, 17 | just like a PADriver. A userclient will create an object of type 18 | PAVirtualDeviceUserClient which can be used to issue commands specific 19 | to a PAVirtualDevice. See the header files for more details. 20 | 21 | 22 | 23 | KERNEL SPACE USER SPACE 24 | 25 | _________________________ _________________________ 26 | (ROOT NODE) (exactly one) 27 | PADriver <======> PADriverUserClient 28 | public IOService public IOUserClient 29 | _________________________ _________________________ 30 | ||| 31 | ||| 32 | __________+++____________ _________________________ 33 | (many) (exactly one for each) 34 | PADevice <======> PADeviceUserClient 35 | public IOAudioDevice public IOUserClient 36 | _________________________ _________________________ 37 | | 38 | | 39 | ___________+_____________ 40 | (exactly one) 41 | PAEngine 42 | public IOAudioEngine 43 | _________________________ 44 | ||| 45 | ||| 46 | __________+++____________ _________________________ 47 | (many) (exactly one for each) 48 | PAVirtualDevice <======> PAVirtualDeviceUserClient 49 | public IOService public IOUserClient 50 | _________________________ _________________________ 51 | 52 | -------------------------------------------------------------------------------- /legacy/kext/load.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | sync 4 | 5 | kext=PulseAudioKext.kext 6 | conf=$1 7 | 8 | if [ -z "$conf" ]; then 9 | conf=Debug 10 | fi 11 | 12 | kextunload -b org.pulseaudio.driver.PulseAudioKext 13 | 14 | mkdir /tmp/dbg 15 | 16 | cd build/$conf 17 | 18 | cp -r ${kext} /tmp/ 19 | chown -R root /tmp/PulseAudioKext.kext 20 | cd /tmp 21 | mkdir sym 22 | 23 | if test -x /usr/bin/kextutil; then 24 | kextutil -v 3 -t ${kext} 25 | else 26 | kextload -v 3 ${kext} 27 | fi 28 | 29 | --------------------------------------------------------------------------------