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
16extern const char *__progname;
17static const char *sProgramName = __progname;
18
19
20// without parameters to get the actual mute status
21int
22handleMute(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
35int
36main(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