xref: /haiku/src/bin/setvolume.cpp (revision ed24eb5ff12640d052171c6a7feba37fab8a75d1)
1 /*
2  * Copyright 2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 
7 #include <Application.h>
8 #include <MediaRoster.h>
9 #include <ParameterWeb.h>
10 
11 #include <stdlib.h>
12 #include <stdio.h>
13 #include <string.h>
14 
15 
16 extern const char *__progname;
17 static const char *sProgramName = __progname;
18 
19 
20 // without parameters to get the actual mute status
21 int
22 handleMute(BParameter *muteParameter, int mute = 2, bool toggle = false) {
23 	int32 muted = 0;
24 	bigtime_t lastChange = 0;
25 	size_t size = sizeof(int32);
26 	muteParameter->GetValue(&muted, &size, &lastChange);
27 	if (toggle)
28 		mute = 1 - muted;
29 	if (muted != mute && mute < 2)
30 		muteParameter->SetValue(&mute, sizeof(int32), system_time());
31 	return muted;
32 }
33 
34 
35 int
36 main(int argc, char **argv)
37 {
38 	BApplication app("application/x-vnd.haiku.setvolume");
39 
40 	BMediaRoster *roster = BMediaRoster::Roster();
41 	if (roster == NULL) {
42 		fprintf(stderr, "%s: media roster not available\n", sProgramName);
43 		return 1;
44 	}
45 
46 	media_node mixer;
47 	status_t status = roster->GetAudioMixer(&mixer);
48 	if (status != B_OK) {
49 		fprintf(stderr, "%s: cannot get audio mixer: %s\n", sProgramName, strerror(status));
50 		return 1;
51 	}
52 
53 	BParameterWeb *web;
54 	status = roster->GetParameterWebFor(mixer, &web);
55 
56 	roster->ReleaseNode(mixer);
57 		// the web is all we need :-)
58 
59 	if (status != B_OK) {
60 		fprintf(stderr, "%s: cannot get parameter web for audio mixer: %s\n",
61 			sProgramName, strerror(status));
62 		return 1;
63 	}
64 
65 	BContinuousParameter *gain = NULL;
66 	BParameter *mute = NULL;
67 
68 	BParameter *parameter;
69 	for (int32 index = 0; (parameter = web->ParameterAt(index)) != NULL; index++) {
70 		// assume the mute preceeding master gain control
71 		if (!strcmp(parameter->Kind(), B_MUTE))
72 			mute = parameter;
73 
74 		if (!strcmp(parameter->Kind(), B_MASTER_GAIN)) {
75 			gain = dynamic_cast<BContinuousParameter *>(parameter);
76 			break;
77 		}
78 	}
79 
80 	if (gain == NULL) {
81 		fprintf(stderr, "%s: could not found master gain!\n", sProgramName);
82 		delete web;
83 		return 1;
84 	}
85 
86 	float volume = 0.0;
87 
88 	if (argc > 1) {
89 		if (strcmp(argv[1], "-m") == 0 || strcmp(argv[1], "--mute") == 0) {
90 			handleMute(mute, 1);
91 			printf("Muted\n");
92 			return 0;
93 		} else if (strcmp(argv[1], "-u") == 0 || strcmp(argv[1], "--unmute") == 0) {
94 			handleMute(mute, 0);
95 			printf("Unmuted\n");
96 			return 0;
97 		} else if (strcmp(argv[1], "-t") == 0 || strcmp(argv[1], "--togglemute") == 0) {
98 			int32 muted = handleMute(mute, 0, true);
99 			printf("%s\n", muted ? "Muted" : "Unmuted");
100 			return 0;
101 		} else {
102 			if (strcmp(argv[1], "-i") == 0 || strcmp(argv[1], "-d") == 0
103 				|| strcmp(argv[1], "--increase") == 0 || strcmp(argv[1], "--decrease") == 0) {
104 				bigtime_t when;
105 				size_t size = sizeof(volume);
106 				gain->GetValue(&volume, &size, &when);
107 				size_t step = 3;
108 				if (argc > 2)
109 					step = atoi(argv[2]);
110 				if (strcmp(argv[1], "-i") == 0 || strcmp(argv[1], "--increase") == 0) {
111 					// make sure it's unmuted
112 					int muted = handleMute(mute, 0);
113 					if (muted == 0 || volume <= gain->MinValue())
114 						volume += step;
115 				} else if (handleMute(mute) == 0) {
116 					// not already muted
117 					volume -= step;
118 					// make sure it's muted
119 					if (volume <= gain->MinValue())
120 						handleMute(mute, 1);
121 				}
122 			} else {
123 				char *end;
124 				volume = strtod(argv[1], &end);
125 				if (end == argv[1]) {
126 					fprintf(stderr,
127 						"Usage: %s <volume> | [options]\n"
128 						"Sets the system volume to the specified value in dB.\n"
129 						"Alternatively there are these options:\n"
130 						"  -m  --mute\n"
131 						"  -u  --unmute\n"
132 						"  -t  --togglemute\ttoggles muting\n"
133 						"  -i  --increase x\tincreases volume by x dB\n"
134 						"  -d  --decrease x\tdecreases volume by x dB\n"
135 						"\t\t\tx defaults to 3 if not supplied\n" ,
136 						sProgramName);
137 					exit(1);
138 				}
139 			}
140 
141 			// make sure our parameter is in range
142 			if (volume > gain->MaxValue())
143 				volume = gain->MaxValue();
144 			else if (volume < gain->MinValue())
145 				volume = gain->MinValue();
146 
147 			gain->SetValue(&volume, sizeof(volume), system_time());
148 		}
149 	}
150 	bigtime_t when;
151 	size_t size = sizeof(volume);
152 	gain->GetValue(&volume, &size, &when);
153 
154 	printf("Current volume: %g (min = %g, max = %g)\n", volume, gain->MinValue(), gain->MaxValue());
155 
156 	delete web;
157 	return 0;
158 }
159 
160