1 | //
|
---|
2 | // NJRSoundManager.m
|
---|
3 | // Pester
|
---|
4 | //
|
---|
5 | // Created by Nicholas Riley on Tue Apr 08 2003.
|
---|
6 | // Copyright (c) 2003 Nicholas Riley. All rights reserved.
|
---|
7 | //
|
---|
8 |
|
---|
9 | #import "NJRSoundManager.h"
|
---|
10 | #import <CoreAudio/CoreAudio.h>
|
---|
11 |
|
---|
12 | @implementation NJRSoundManager
|
---|
13 |
|
---|
14 | static const UInt32 kLeftChannel = 0, kRightChannel = 1;
|
---|
15 |
|
---|
16 | static AudioDeviceID deviceID;
|
---|
17 | static UInt32 stereoChannels[2];
|
---|
18 | static float channelVolume[2];
|
---|
19 | static float savedChannelVolume[2] = {-1, -1};
|
---|
20 |
|
---|
21 | + (BOOL)volumeIsNotMutedOrInvalid:(float)volume;
|
---|
22 | {
|
---|
23 | return (volume > 0 && volume <= 1);
|
---|
24 | }
|
---|
25 |
|
---|
26 | + (BOOL)_getDefaultOutputDevice;
|
---|
27 | {
|
---|
28 | UInt32 propertySize;
|
---|
29 | OSStatus err;
|
---|
30 |
|
---|
31 | propertySize = sizeof(deviceID);
|
---|
32 | err = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultSystemOutputDevice, &propertySize, &deviceID);
|
---|
33 | if (err != noErr) return NO;
|
---|
34 |
|
---|
35 | propertySize = sizeof(stereoChannels);
|
---|
36 | err = AudioDeviceGetProperty(deviceID, NULL, false, kAudioDevicePropertyPreferredChannelsForStereo, &propertySize, &stereoChannels);
|
---|
37 | if (err != noErr) return NO;
|
---|
38 | return YES;
|
---|
39 | }
|
---|
40 |
|
---|
41 | + (BOOL)getDefaultOutputVolume:(float *)volume;
|
---|
42 | {
|
---|
43 | UInt32 propertySize;
|
---|
44 | OSStatus err;
|
---|
45 |
|
---|
46 | if (![self _getDefaultOutputDevice]) return NO;
|
---|
47 |
|
---|
48 | // read the current volume scalar settings [0...1]
|
---|
49 | propertySize = sizeof(float);
|
---|
50 | err = AudioDeviceGetProperty(deviceID, stereoChannels[kLeftChannel], false, kAudioDevicePropertyVolumeScalar, &propertySize, &channelVolume[kLeftChannel]);
|
---|
51 | if (err != noErr) return NO;
|
---|
52 | err = AudioDeviceGetProperty(deviceID, stereoChannels[kRightChannel], false, kAudioDevicePropertyVolumeScalar, &propertySize, &channelVolume[kRightChannel]);
|
---|
53 | if (err != noErr) return NO;
|
---|
54 | if (volume != NULL) *volume = MAX(channelVolume[kLeftChannel], channelVolume[kRightChannel]);
|
---|
55 | return YES;
|
---|
56 | }
|
---|
57 |
|
---|
58 | + (void)_updateChannelVolume;
|
---|
59 | {
|
---|
60 | UInt32 propertySize = sizeof(channelVolume[kLeftChannel]);
|
---|
61 | // ignore errors
|
---|
62 | AudioDeviceSetProperty(deviceID, NULL, stereoChannels[kLeftChannel], false, kAudioDevicePropertyVolumeScalar, propertySize, &channelVolume[kLeftChannel]);
|
---|
63 | AudioDeviceSetProperty(deviceID, NULL, stereoChannels[kRightChannel], false, kAudioDevicePropertyVolumeScalar, propertySize, &channelVolume[kRightChannel]);
|
---|
64 | }
|
---|
65 |
|
---|
66 | + (BOOL)saveDefaultOutputVolume;
|
---|
67 | {
|
---|
68 | if (![self getDefaultOutputVolume: NULL]) return NO;
|
---|
69 | savedChannelVolume[kLeftChannel] = channelVolume[kLeftChannel];
|
---|
70 | savedChannelVolume[kRightChannel] = channelVolume[kRightChannel];
|
---|
71 | // NSLog(@"saving channel volume {%f, %f}", channelVolume[kLeftChannel],channelVolume[kRightChannel]);
|
---|
72 | return YES;
|
---|
73 | }
|
---|
74 |
|
---|
75 | + (void)setDefaultOutputVolume:(float)volume;
|
---|
76 | {
|
---|
77 | if (![self _getDefaultOutputDevice]) return;
|
---|
78 |
|
---|
79 | channelVolume[kLeftChannel] = volume;
|
---|
80 | channelVolume[kRightChannel] = volume;
|
---|
81 | [self _updateChannelVolume];
|
---|
82 | }
|
---|
83 |
|
---|
84 | + (void)restoreSavedDefaultOutputVolume;
|
---|
85 | {
|
---|
86 | if (savedChannelVolume[kLeftChannel] < 0) return;
|
---|
87 | // NSLog(@"restoring saved channel volume");
|
---|
88 | channelVolume[kLeftChannel] = savedChannelVolume[kLeftChannel];
|
---|
89 | channelVolume[kRightChannel] = savedChannelVolume[kRightChannel];
|
---|
90 | savedChannelVolume[kLeftChannel] = -1;
|
---|
91 | savedChannelVolume[kRightChannel] = -1;
|
---|
92 | [self _updateChannelVolume];
|
---|
93 | }
|
---|
94 |
|
---|
95 | + (void)restoreSavedDefaultOutputVolumeIfCurrently:(float)volume;
|
---|
96 | {
|
---|
97 | float currentVolume;
|
---|
98 | if ([self getDefaultOutputVolume: ¤tVolume] && abs(volume - currentVolume) < 0.05) {
|
---|
99 | [self restoreSavedDefaultOutputVolume];
|
---|
100 | }
|
---|
101 | }
|
---|
102 |
|
---|
103 | @end
|
---|