1 #include "engine/declarations.h"
2 
3 #include <fcntl.h>
4 #include <dirent.h>
5 #include <sys/ioctl.h>
6 
7 #if defined(__FreeBSD__)
8 #include <sys/soundcard.h>
9 #endif
10 
11 #if defined(HAVE_SYS_SYSCTL_H)
12 #include <sys/sysctl.h>
13 #endif
14 
15 #include "declarations_app.h"
16 #include "mixer.h"
17 
18 #include "engine/widget_helper.h"
19 
20 
21 
bsd_prepare(unsigned int h)22 int bsd_prepare(unsigned int h) {
23 	struct w_stack *w;
24 
25 	if((w = window_get_widget_by_handle(h)) == NULL) return(-1);
26 
27 	win_s = w;
28 
29 	/* Spawn audio thread for test noise */
30 #if ! defined(PROG_DISABLE_AUDIO)
31 	if(thread_spawn(NULL, (void *) worker_play, NULL, NULL) == NULL) return(-1);
32 #endif
33 	/* Open mixer and read mixer capabilities and settings... */
34 	if((mix_h = bsd_list()) == 0) return(-1);
35 
36 	/* ...then create widgets based on mixer settings */
37 	return(bsd_prepare_op(w, mix_h));
38 }
39 
bsd_prepare_op(struct w_stack * w,int r)40 static int bsd_prepare_op(struct w_stack *w, int r) {
41 	int e;
42 #if defined(HAVE_SYSCTLBYNAME) && defined(HAVE_SYS_SYSCTL_H)
43 	size_t t;
44 #endif
45 	label_c.pixel.p = 0xffffff00;
46 
47 	/* Create mixer name label... */
48 	if(bsd_prepare_mixer_lab(w, &label_c) != 0) return(-1);
49 
50 	/* ...mixer selection knob... */
51 	if(bsd_prepare_mixer_sel(w, &label_c) != 0) return(-1);
52 
53 	/* ...mixer sliders... */
54 	if(bsd_prepare_mixer_mix(r, w, &label_c) != 0) return(-1);
55 
56 	/* ...tone and gain controls... */
57 	if(bsd_prepare_mixer_ext(r, w, &label_c) != 0) return(-1);
58 
59 	/* ...recording source knob... */
60 	if(bsd_prepare_mixer_rec(w, &label_c) != 0) return(-1);
61 
62 	/* ...and test noise buttons, we live in hope that audio thread is running at this point */
63 	if(bsd_prepare_mixer_tst(w, &label_c) != 0) return(-1);
64 #if defined(HAVE_SYSCTLBYNAME) && defined(HAVE_SYS_SYSCTL_H)
65 	t = sizeof(e);
66 
67 	/* Do not drop error message here as MIB may not be available, and its okay */
68 	if(sysctlbyname("hw.snd.default_unit", (void *) &e, &t, NULL, 0) != 0) e = 0;
69 #else
70 	e = 0;
71 #endif
72 	(void) bsd_prepare_sd(w, (unsigned int) e);
73 
74 	return(0);
75 }
76 
bsd_prepare_at(struct w_stack * w,int r)77 static void bsd_prepare_at(struct w_stack *w, int r) {
78 	/* Update mixer sliders... */
79 	(void) bsd_update_mixer_mix(r, w);
80 
81 	/* ...and tone and gain controls */
82 	(void) bsd_update_mixer_ext(r, w);
83 }
84 
bsd_prepare_sd(struct w_stack * w,unsigned int c)85 static void bsd_prepare_sd(struct w_stack *w, unsigned int c) {
86 	(void) bsd_mixer_sel("mixer_sel", 0, c);
87 
88 	(void) widget_step_set(w, "mixer_sel", c);
89 }
90 
bsd_disperse(void)91 void bsd_disperse(void) {
92 	if(mix_h != 0) {
93 		(void) bsd_close(mix_h);
94 
95 		mix_h = 0;
96 	}
97 
98 	(void) bsd_list_free();
99 }
100 
101 /**
102  *
103  * Create mixer name label.
104  *
105  */
106 
bsd_prepare_mixer_lab(struct w_stack * w,struct pixel_rgba_8 * c)107 static int bsd_prepare_mixer_lab(struct w_stack *w, struct pixel_rgba_8 *c) {
108 	if(widget_create_label(w, "mixer_lab", c_c_lab.x, c_c_lab.y) != 0) return(-1);
109 
110 	if(widget_update_label(w, "mixer_lab", "",
111 		NULL, NULL, 0, 0,
112 		WIDGET_TITLE_JUSTIFICATION_LEFT, c) != 0) return(-1);
113 
114 	(void) bsd_update_mixer_lab(win_s);
115 
116 	return(0);
117 }
118 
bsd_update_mixer_lab(struct w_stack * w)119 static void bsd_update_mixer_lab(struct w_stack *w) {
120 	char n[(128 * 2) + 1];
121 
122 	(void) snprintf(
123 		n, sizeof(n),
124 		"%s [%s]",
125 		mixer_card_t[mixer_card_d].name_l, mixer_card_t[mixer_card_d].name_s);
126 
127 	(void) widget_update_label(w, "mixer_lab", n,
128 		NULL, NULL, 0, 0,
129 		WIDGET_TITLE_JUSTIFICATION_NONE, NULL);
130 }
131 
132 /**
133  *
134  * Create mixer selection knob.
135  *
136  */
137 
bsd_prepare_mixer_sel(struct w_stack * w,struct pixel_rgba_8 * c)138 static int bsd_prepare_mixer_sel(struct w_stack *w, struct pixel_rgba_8 *c) {
139 	int n;
140 
141 	double a, b, d;
142 
143 	n = 1;
144 
145 	if(mixer_card_c != 0) n = mixer_card_c;
146 
147 	d = (double) (n - 1) * 30.0;
148 	a = 180.0 - (d / 2.0);
149 	b = 180.0 + (d / 2.0);
150 
151 	if(a < 25.0) a = 25.0;
152 	if(b > 335.0) b = 335.0;
153 
154 	if(widget_create_turnswitch(w, "mixer_sel",
155 		c_c_sel.x, c_c_sel.y,
156 		WIDGET_TURNSWITCH_SUBTYPE_SMALL_CHICKEN,
157 		WIDGET_TITLE_POSITION_ABOVE,
158 		0, -30, (unsigned int) floor(a), (unsigned int) ceil(b),
159 		(unsigned int) n - 1, (unsigned int) mixer_card_d) != 0) return(-1);
160 
161 	if(widget_cb_add_turnswitch_turn(w, "mixer_sel",
162 		"cb_turn_mixer_sel") != 0) return(-1);
163 
164 	if(widget_trigger_set(w, "mixer_sel",
165 		WIDGET_TRIGGER_RELEASE) != 0) return(-1);
166 
167 	if(widget_update_label(w, "mixer_sel", _(c_c_sel.n),
168 		NULL, NULL, 0, 0,
169 		WIDGET_TITLE_JUSTIFICATION_CENTER, c) != 0) return(-1);
170 
171 	if(widget_enable(w, "mixer_sel") != 0) return(-1);
172 
173 	if(widget_update_scale_nude(w, "mixer_sel",
174 		NULL, NULL, 8, 0, NULL,
175 		1, mixer_card_c, mixer_card_c, c) != 0) return(-1);
176 
177 	return(0);
178 }
179 
180 /**
181  *
182  * Create mixer sliders.
183  *
184  */
185 
bsd_prepare_mixer_mix(int r,struct w_stack * w,struct pixel_rgba_8 * c)186 static int bsd_prepare_mixer_mix(int r, struct w_stack *w, struct pixel_rgba_8 *c) {
187 #if defined(__FreeBSD__)
188 	int i, j, k;
189 
190 	int v[2];
191 
192 	char n[32];
193 
194 	for(j = 0, k = 0; ; j++) {
195 		if(c_c_mix[j].c == NULL) break;
196 
197 		for(i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
198 			if(str_len(mixer_n[i], STRING_ASCII) != c_c_mix[j].t) continue;
199 
200 			if(strncmp((const char *) mixer_n[i], (const char *) c_c_mix[j].c, c_c_mix[j].t) != 0) {
201 				continue;
202 			}
203 
204 			k = -1;
205 
206 			/* Create slider for this control... */
207 			c_c_mix[j].i = -1;
208 
209 			(void) snprintf(n, sizeof(n), "mixer_mix_%s", mixer_n[i]);
210 
211 			if(bsd_get_p_level(r, i, v) == 0) {
212 				/* ...and store slider order number for later use */
213 				c_c_mix[j].i = i;
214 
215 				if(bsd_prepare_mixer_mix_op(w, c, n, i, j, c_c_mix[j].x, c_c_mix[j].y, 1, (unsigned int) v[0]) != 0) {
216 					break;
217 				}
218 			}
219 			else {
220 				if(bsd_prepare_mixer_mix_op(w, c, n, i, j, c_c_mix[j].x, c_c_mix[j].y, 0, 0) != 0) {
221 					break;
222 				}
223 			}
224 
225 			k = 0;
226 
227 			break;
228 		}
229 
230 		if(k != 0) break;
231 	}
232 
233 	return(k);
234 #else
235 	(void) r;
236 	(void) w;
237 	(void) c;
238 
239 	return(0);
240 #endif
241 }
242 #if defined(__FreeBSD__)
bsd_prepare_mixer_mix_op(struct w_stack * w,struct pixel_rgba_8 * c,char * n,int i,int j,int x,int y,int z,unsigned int v)243 static int bsd_prepare_mixer_mix_op(struct w_stack *w, struct pixel_rgba_8 *c, char *n, int i, int j, int x, int y, int z, unsigned int v) {
244 	char m[32];
245 
246 	/* Create slider for this control */
247 	if(widget_create_slideswitch(w, n,
248 		x, y,
249 		WIDGET_SLIDESWITCH_SUBTYPE_VERT_SLIDER,
250 		WIDGET_TITLE_POSITION_ABOVE,
251 		0, -10, 200, 100, v) != 0) return(-1);
252 
253 	if(widget_cb_add_slideswitch_slide(w, n,
254 		"cb_turn_mixer_mix") != 0) return(-1);
255 
256 	if(widget_trigger_set(w, n,
257 		WIDGET_TRIGGER_CONSTANT) != 0) return(-1);
258 
259 	if(widget_update_label(w, n, _(c_c_mix[j].n),
260 		NULL, NULL, 0, 0,
261 		WIDGET_TITLE_JUSTIFICATION_CENTER, c) != 0) return(-1);
262 
263 	if(widget_enable(w, n) != 0) return(-1);
264 
265 	if(widget_update_scale_bars(w, n,
266 		NULL, NULL, 8, 0, NULL,
267 		0, 10, 11, c) != 0) return(-1);
268 
269 	/* Create on/off led for this slider */
270 	(void) snprintf(m, sizeof(m), "mixer_mix_%s_on", mixer_n[i]);
271 
272 	if(bsd_get_r_source(i) == 0) {
273 		if(widget_create_led_1(w, m,
274 			x + 16, y + 296,
275 			WIDGET_LED_SUBTYPE_YELLOW, 0, 0, 0) != 0) return(-1);
276 	}
277 	else {
278 		if(widget_create_led_1(w, m,
279 			x + 16, y + 296,
280 			WIDGET_LED_SUBTYPE_GREEN, 0, 0, 0) != 0) return(-1);
281 	}
282 
283 	if(widget_enable(w, m) != 0) return(-1);
284 
285 	/* Light the led if this control is present */
286 	if(z != 0) {
287 		if(widget_step_set(w, m, 1) != 0) return(-1);
288 	}
289 
290 	return(0);
291 }
292 #endif
bsd_update_mixer_mix(int r,struct w_stack * w)293 static void bsd_update_mixer_mix(int r, struct w_stack *w) {
294 #if defined(__FreeBSD__)
295 	int i, j, k;
296 
297 	unsigned int o;
298 
299 	int v[2];
300 
301 	char n[32];
302 	char m[32];
303 
304 	for(j = 0, k = 0, o = 0; ; j++) {
305 		if(c_c_mix[j].c == NULL) break;
306 
307 		/* This control is not recording source by default */
308 		c_c_mix[j].r = 0;
309 
310 		for(i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
311 			if(str_len(mixer_n[i], STRING_ASCII) != c_c_mix[j].t) continue;
312 
313 			if(strncmp((const char *) mixer_n[i], (const char *) c_c_mix[j].c, c_c_mix[j].t) != 0) {
314 				continue;
315 			}
316 
317 			/* Tag this control if it supports recording */
318 			if((1 << i) & mixer_r[MIXER_CAP_REC]) {
319 				c_c_mix[j].r = i;
320 
321 				++o;
322 			}
323 
324 			k = -1;
325 
326 			(void) snprintf(n, sizeof(n), "mixer_mix_%s", mixer_n[i]);
327 			(void) snprintf(m, sizeof(m), "mixer_mix_%s_on", mixer_n[i]);
328 
329 			/* Set knobs and change leds according to recording sources */
330 			if(widget_disable(w, m) != 0) break;
331 			if(widget_delete(w, m) != 0) break;
332 
333 			if(bsd_get_r_source(i) == 0) {
334 				if(widget_create_led_1(w, m,
335 					c_c_mix[j].x + 16, c_c_mix[j].y + 296,
336 					WIDGET_LED_SUBTYPE_YELLOW, 0, 0, 0) != 0) break;
337 
338 					mixer_card_r = o - 1;
339 			}
340 			else {
341 				if(widget_create_led_1(w, m,
342 					c_c_mix[j].x + 16, c_c_mix[j].y + 296,
343 					WIDGET_LED_SUBTYPE_GREEN, 0, 0, 0) != 0) break;
344 			}
345 
346 			if(widget_enable(w, m) != 0) break;
347 
348 			c_c_mix[j].i = -1;
349 
350 			if(bsd_get_p_level(r, i, v) == 0) {
351 				c_c_mix[j].i = i;
352 
353 				(void) widget_step_set(w, n, (unsigned int) v[0]);
354 				(void) widget_step_set(w, m, 1);
355 			}
356 			else {
357 				(void) widget_step_set(w, n, 0);
358 				(void) widget_step_set(w, m, 0);
359 			}
360 
361 			k = 0;
362 
363 			break;
364 		}
365 
366 		if(k != 0) break;
367 	}
368 
369 	(void) bsd_update_mixer_rec(w);
370 
371 	(void) widget_refresh(w);
372 #else
373 	(void) r;
374 	(void) w;
375 #endif
376 }
377 
378 /**
379  *
380  * Create tone and gain controls.
381  *
382  */
383 
bsd_prepare_mixer_ext(int r,struct w_stack * w,struct pixel_rgba_8 * c)384 static int bsd_prepare_mixer_ext(int r, struct w_stack *w, struct pixel_rgba_8 *c) {
385 #if defined(__FreeBSD__)
386 	int i, j, k;
387 
388 	int v[2];
389 
390 	char n[32];
391 
392 	for(j = 0, k = 0; ; j++) {
393 		if(c_c_ext[j].c == NULL) break;
394 
395 		for(i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
396 			if(str_len(mixer_n[i], STRING_ASCII) != c_c_ext[j].t) continue;
397 
398 			if(strncmp((const char *) mixer_n[i], (const char *) c_c_ext[j].c, c_c_ext[j].t) != 0) {
399 				continue;
400 			}
401 
402 			k = -1;
403 
404 			/* Create knob for this control... */
405 			c_c_ext[j].i = -1;
406 
407 			(void) snprintf(n, sizeof(n), "mixer_ext_%s", mixer_n[i]);
408 
409 			if(bsd_get_p_level(r, i, v) == 0) {
410 				/* ...and store knob order number for later use */
411 				c_c_ext[j].i = i;
412 
413 				if(bsd_prepare_mixer_ext_op(w, c, n, i, j, c_c_ext[j].x, c_c_ext[j].y, 1, (unsigned int) v[0]) != 0) {
414 					break;
415 				}
416 			}
417 			else {
418 				if(bsd_prepare_mixer_ext_op(w, c, n, i, j, c_c_ext[j].x, c_c_ext[j].y, 0, 0) != 0) {
419 					break;
420 				}
421 			}
422 
423 			k = 0;
424 
425 			break;
426 		}
427 
428 		if(k != 0) break;
429 	}
430 
431 	return(k);
432 #else
433 	(void) r;
434 	(void) w;
435 	(void) c;
436 
437 	return(0);
438 #endif
439 }
440 #if defined(__FreeBSD__)
bsd_prepare_mixer_ext_op(struct w_stack * w,struct pixel_rgba_8 * c,char * n,int i,int j,int x,int y,int z,unsigned int v)441 static int bsd_prepare_mixer_ext_op(struct w_stack *w, struct pixel_rgba_8 *c, char *n, int i, int j, int x, int y, int z, unsigned int v) {
442 	char m[32];
443 
444 	char *s_ext[] = {
445 		_("Min"), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, _("Max")
446 	};
447 
448 	/* Create knob for this control */
449 	if(widget_create_turnswitch(w, n,
450 		x, y,
451 		WIDGET_TURNSWITCH_SUBTYPE_SMALL_ROUND,
452 		WIDGET_TITLE_POSITION_BELOW,
453 		0, 30, 45, 315, 100, v) != 0) return(-1);
454 
455 	if(widget_cb_add_turnswitch_turn(w, n,
456 		"cb_turn_mixer_ext") != 0) return(-1);
457 
458 	if(widget_trigger_set(w, n,
459 		WIDGET_TRIGGER_CONSTANT) != 0) return(-1);
460 
461 	if(widget_update_label(w, n, _(c_c_ext[j].n),
462 		NULL, NULL, 0, 0,
463 		WIDGET_TITLE_JUSTIFICATION_CENTER, c) != 0) return(-1);
464 
465 	if(widget_enable(w, n) != 0) return(-1);
466 
467 	if(widget_update_scale_bars(w, n,
468 		NULL, NULL, 7, 0, s_ext,
469 		0, 11, 12, c) != 0) return(-1);
470 
471 	/* Create on/off led for this knob */
472 	(void) snprintf(m, sizeof(m), "mixer_ext_%s_on", mixer_n[i]);
473 
474 	if(widget_create_led_1(w, m,
475 		x + 22, y - 54,
476 		WIDGET_LED_SUBTYPE_GREEN, 0, 0, 0) != 0) return(-1);
477 
478 	if(widget_enable(w, m) != 0) return(-1);
479 
480 	/* Light the led if this control is present */
481 	if(z != 0) {
482 		if(widget_step_set(w, m, 1) != 0) return(-1);
483 	}
484 
485 	return(0);
486 }
487 #endif
bsd_update_mixer_ext(int r,struct w_stack * w)488 static void bsd_update_mixer_ext(int r, struct w_stack *w) {
489 #if defined(__FreeBSD__)
490 	int i, j;
491 
492 	int v[2];
493 
494 	char n[32];
495 	char m[32];
496 
497 	for(j = 0; ; j++) {
498 		if(c_c_ext[j].c == NULL) break;
499 
500 		for(i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
501 			if(str_len(mixer_n[i], STRING_ASCII) != c_c_ext[j].t) continue;
502 
503 			if(strncmp((const char *) mixer_n[i], (const char *) c_c_ext[j].c, c_c_ext[j].t) != 0) {
504 				continue;
505 			}
506 
507 			c_c_ext[j].i = -1;
508 
509 			(void) snprintf(n, sizeof(n), "mixer_ext_%s", mixer_n[i]);
510 			(void) snprintf(m, sizeof(m), "mixer_ext_%s_on", mixer_n[i]);
511 
512 			if(bsd_get_p_level(r, i, v) == 0) {
513 				c_c_ext[j].i = i;
514 
515 				(void) widget_step_set(w, n, (unsigned int) v[0]);
516 				(void) widget_step_set(w, m, 1);
517 			}
518 			else {
519 				(void) widget_step_set(w, n, 0);
520 				(void) widget_step_set(w, m, 0);
521 			}
522 
523 			break;
524 		}
525 	}
526 
527 	(void) widget_refresh(w);
528 #else
529 	(void) r;
530 	(void) w;
531 #endif
532 }
533 
534 /**
535  *
536  * Create recording source knob.
537  *
538  */
539 
bsd_prepare_mixer_rec(struct w_stack * w,struct pixel_rgba_8 * c)540 static int bsd_prepare_mixer_rec(struct w_stack *w, struct pixel_rgba_8 *c) {
541 	int i, k, n;
542 
543 	double a, b, d;
544 
545 	for(i = 0, k = 0; ; i++) {
546 		if(c_c_mix[i].c == NULL) break;
547 
548 		if(c_c_mix[i].r != 0) ++k;
549 	}
550 
551 	n = 1;
552 
553 	if(k != 0) n = k;
554 
555 	d = (double) (n - 1) * 30.0;
556 	a = 180.0 - (d / 2.0);
557 	b = 180.0 + (d / 2.0);
558 
559 	if(a < 25.0) a = 25.0;
560 	if(b > 335.0) b = 335.0;
561 
562 	if(widget_create_turnswitch(w, "mixer_rec",
563 		c_c_rec.x, c_c_rec.y,
564 		WIDGET_TURNSWITCH_SUBTYPE_SMALL_CHICKEN,
565 		WIDGET_TITLE_POSITION_ABOVE,
566 		0, -30, (unsigned int) floor(a), (unsigned int) ceil(b),
567 		(unsigned int) n - 1, mixer_card_r) != 0) return(-1);
568 
569 	if(widget_cb_add_turnswitch_turn(w, "mixer_rec",
570 		"cb_turn_mixer_rec") != 0) return(-1);
571 
572 	if(widget_trigger_set(w, "mixer_rec",
573 		WIDGET_TRIGGER_RELEASE) != 0) return(-1);
574 
575 	if(widget_update_label(w, "mixer_rec", _(c_c_rec.n),
576 		NULL, NULL, 0, 0,
577 		WIDGET_TITLE_JUSTIFICATION_CENTER, c) != 0) return(-1);
578 
579 	if(widget_enable(w, "mixer_rec") != 0) return(-1);
580 
581 	if(k != 0) {
582 		if(widget_update_scale_nude(w, "mixer_rec",
583 			NULL, NULL, 8, 0, NULL,
584 			1, (unsigned int) k, (unsigned int) k, c) != 0) return(-1);
585 	}
586 
587 	return(0);
588 }
589 
bsd_update_mixer_rec(struct w_stack * w)590 static void bsd_update_mixer_rec(struct w_stack *w) {
591 	if(widget_disable(w, "mixer_rec") != 0) return;
592 	if(widget_delete(w, "mixer_rec") != 0) return;
593 
594 	(void) bsd_prepare_mixer_rec(w, &label_c);
595 }
596 
597 /**
598  *
599  * Create test noise knobs and buttons.
600  *
601  */
602 
bsd_prepare_mixer_tst(struct w_stack * w,struct pixel_rgba_8 * c)603 static int bsd_prepare_mixer_tst(struct w_stack *w, struct pixel_rgba_8 *c) {
604 #if ! defined(PROG_DISABLE_AUDIO)
605 	/* Create test noise knobs */
606 	if(bsd_prepare_mixer_tst_kn(w, c) != 0) return(-1);
607 
608 	/* Create test noise buttons */
609 	if(bsd_prepare_mixer_tst_bt(w, c) != 0) return(-1);
610 #else
611 	(void) w;
612 	(void) c;
613 #endif
614 	return(0);
615 }
616 #if ! defined(PROG_DISABLE_AUDIO)
bsd_prepare_mixer_tst_kn(struct w_stack * w,struct pixel_rgba_8 * c)617 static int bsd_prepare_mixer_tst_kn(struct w_stack *w, struct pixel_rgba_8 *c) {
618 	char *s_vol[] = {
619 		_("Min"), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, _("Max")
620 	};
621 
622 	char *s_pan[] = {
623 		_("LT"), NULL, NULL, NULL, NULL, _("CT"), NULL, NULL, NULL, NULL, _("RT")
624 	};
625 
626 	if(widget_create_turnswitch(w, "mixer_tst_vol",
627 		c_c_nse[0].x, c_c_nse[0].y,
628 		WIDGET_TURNSWITCH_SUBTYPE_SMALL_ROUND,
629 		WIDGET_TITLE_POSITION_ABOVE,
630 		0, -44, 45, 315, 100, 50) != 0) return(-1);
631 
632 	if(widget_create_turnswitch(w, "mixer_tst_pan",
633 		c_c_nse[1].x, c_c_nse[1].y,
634 		WIDGET_TURNSWITCH_SUBTYPE_SMALL_ROUND,
635 		WIDGET_TITLE_POSITION_ABOVE,
636 		0, -44, 45, 315, 100, 50) != 0) return(-1);
637 
638 	if(widget_cb_add_turnswitch_turn(w, "mixer_tst_vol",
639 		"cb_turn_mixer_tst_vol") != 0) return(-1);
640 
641 	if(widget_cb_add_turnswitch_turn(w, "mixer_tst_pan",
642 		"cb_turn_mixer_tst_pan") != 0) return(-1);
643 
644 	if(widget_trigger_set(w, "mixer_tst_vol",
645 		WIDGET_TRIGGER_CONSTANT) != 0) return(-1);
646 
647 	if(widget_trigger_set(w, "mixer_tst_pan",
648 		WIDGET_TRIGGER_CONSTANT) != 0) return(-1);
649 
650 	if(widget_update_label(w, "mixer_tst_vol", _(c_c_nse[0].n),
651 		NULL, NULL, 0, 0,
652 		WIDGET_TITLE_JUSTIFICATION_CENTER, c) != 0) return(-1);
653 
654 	if(widget_update_label(w, "mixer_tst_pan", _(c_c_nse[1].n),
655 		NULL, NULL, 0, 0,
656 		WIDGET_TITLE_JUSTIFICATION_CENTER, c) != 0) return(-1);
657 
658 	if(widget_enable(w, "mixer_tst_vol") != 0) return(-1);
659 	if(widget_enable(w, "mixer_tst_pan") != 0) return(-1);
660 
661 	if(widget_update_scale_bars(w, "mixer_tst_vol",
662 		NULL, NULL, 7, 0, s_vol,
663 		0, 11, 12, c) != 0) return(-1);
664 
665 	if(widget_update_scale_bars(w, "mixer_tst_pan",
666 		NULL, NULL, 7, 0, s_pan,
667 		-50, 50, 11, c) != 0) return(-1);
668 
669 	return(0);
670 }
671 
bsd_prepare_mixer_tst_bt(struct w_stack * w,struct pixel_rgba_8 * c)672 static int bsd_prepare_mixer_tst_bt(struct w_stack *w, struct pixel_rgba_8 *c) {
673 	if(widget_create_pushbutton_1(w, "mixer_tst_white",
674 		c_c_nse[2].x, c_c_nse[2].y,
675 		WIDGET_PUSHBUTTON_SUBTYPE_WHITE,
676 		WIDGET_TITLE_POSITION_BELOW,
677 		0, 10, IS_YES) != 0) return(-1);
678 
679 	if(widget_cb_add_pushbutton_push(w, "mixer_tst_white",
680 		"cb_push_mixer_tst") != 0) return(-1);
681 
682 	if(widget_update_label(w, "mixer_tst_white", _(c_c_nse[2].n),
683 		NULL, NULL, 0, 0,
684 		WIDGET_TITLE_JUSTIFICATION_CENTER, c) != 0) return(-1);
685 
686 	if(widget_enable(w, "mixer_tst_white") != 0) return(-1);
687 
688 	return(0);
689 }
690 #endif
691 
692 /**
693  *
694  * Callback for mixer selection knob.
695  *
696  */
697 
bsd_mixer_sel(__UNUSED__ char * s,__UNUSED__ unsigned int steps,unsigned int step)698 __VISIBILITY_DEFAULT__ void bsd_mixer_sel(__UNUSED__ char *s, __UNUSED__ unsigned int steps, unsigned int step) {
699 #if defined(__FreeBSD__)
700 	int r;
701 #endif
702 	(void) bsd_close(mix_h);
703 
704 	mix_h = 0;
705 
706 	mixer_card_d = (int) step;
707 #if defined(__FreeBSD__)
708 	if((r = bsd_list_freebsd_op(mixer_card_d)) == -1) return;
709 
710 	mix_h = r;
711 #endif
712 	(void) bsd_prepare_at(win_s, mix_h);
713 	(void) bsd_update_mixer_lab(win_s);
714 }
715 
716 /**
717  *
718  * Callback for recording source knob.
719  *
720  */
721 
bsd_mixer_rec(__UNUSED__ char * s,__UNUSED__ unsigned int steps,unsigned int step)722 __VISIBILITY_DEFAULT__ void bsd_mixer_rec(__UNUSED__ char *s, __UNUSED__ unsigned int steps, unsigned int step) {
723 #if defined(__FreeBSD__)
724 	int i, r;
725 
726 	unsigned int k;
727 
728 	for(i = 0, k = 0; ; i++) {
729 		if(c_c_mix[i].c == NULL) return;
730 		if(c_c_mix[i].r == 0) continue;
731 
732 		if(k++ == step) {
733 			r = (1 << c_c_mix[i].r);
734 
735 			if(ioctl(mix_h, SOUND_MIXER_WRITE_RECSRC, &r) == -1) {
736 				(void) bsd_mixer_er(_("Failed to send control command to mixer"));
737 
738 				return;
739 			}
740 
741 			if(ioctl(mix_h, SOUND_MIXER_READ_RECSRC, &r) == -1) {
742 				(void) bsd_mixer_er(_("Failed to send control command to mixer"));
743 
744 				return;
745 			}
746 
747 			mixer_card_r = step;
748 
749 			/* Update mixer sliders and leds */
750 			if(bsd_open_mixer_freebsd(mix_h) != 0) return;
751 
752 			(void) bsd_update_mixer_mix(mix_h, win_s);
753 
754 			break;
755 		}
756 	}
757 #else
758 	(void) s;
759 	(void) steps;
760 	(void) step;
761 #endif
762 }
763 
764 /**
765  *
766  * Callback for mixer sliders.
767  *
768  */
769 
bsd_mixer_mix(char * s,unsigned int steps,unsigned int step)770 __VISIBILITY_DEFAULT__ void bsd_mixer_mix(char *s, unsigned int steps, unsigned int step) {
771 	/* Keep in sync with c_c_mix */
772 	const void *f[] = {
773 		bsd_mixer_mix_monitor,
774 		bsd_mixer_mix_line,
775 		bsd_mixer_mix_mic,
776 		bsd_mixer_mix_mix,
777 		bsd_mixer_mix_rec,
778 		bsd_mixer_mix_aux,
779 		bsd_mixer_mix_pcm,
780 		bsd_mixer_mix_vol
781 	};
782 
783 	(void) bsd_mixer_mix_op("mixer_mix", s, steps, step, c_c_mix, f);
784 }
785 
bsd_mixer_mix_monitor(int i,unsigned int n,unsigned int v)786 static void bsd_mixer_mix_monitor(int i, unsigned int n, unsigned int v) {
787 	if(i != -1) (void) bsd_set_p_level(mix_h, i, n, v);
788 }
789 
bsd_mixer_mix_line(int i,unsigned int n,unsigned int v)790 static void bsd_mixer_mix_line(int i, unsigned int n, unsigned int v) {
791 	if(i != -1) (void) bsd_set_p_level(mix_h, i, n, v);
792 }
793 
bsd_mixer_mix_mic(int i,unsigned int n,unsigned int v)794 static void bsd_mixer_mix_mic(int i, unsigned int n, unsigned int v) {
795 	if(i != -1) (void) bsd_set_p_level(mix_h, i, n, v);
796 }
797 
bsd_mixer_mix_mix(int i,unsigned int n,unsigned int v)798 static void bsd_mixer_mix_mix(int i, unsigned int n, unsigned int v) {
799 	if(i != -1) (void) bsd_set_p_level(mix_h, i, n, v);
800 }
801 
bsd_mixer_mix_rec(int i,unsigned int n,unsigned int v)802 static void bsd_mixer_mix_rec(int i, unsigned int n, unsigned int v) {
803 	if(i != -1) (void) bsd_set_p_level(mix_h, i, n, v);
804 }
805 
bsd_mixer_mix_aux(int i,unsigned int n,unsigned int v)806 static void bsd_mixer_mix_aux(int i, unsigned int n, unsigned int v) {
807 	if(i != -1) (void) bsd_set_p_level(mix_h, i, n, v);
808 }
809 
bsd_mixer_mix_pcm(int i,unsigned int n,unsigned int v)810 static void bsd_mixer_mix_pcm(int i, unsigned int n, unsigned int v) {
811 	if(i != -1) (void) bsd_set_p_level(mix_h, i, n, v);
812 }
813 
bsd_mixer_mix_vol(int i,unsigned int n,unsigned int v)814 static void bsd_mixer_mix_vol(int i, unsigned int n, unsigned int v) {
815 	if(i != -1) (void) bsd_set_p_level(mix_h, i, n, v);
816 }
817 
818 /**
819  *
820  * Callback for tone and gain controls.
821  *
822  */
823 
bsd_mixer_ext(char * s,unsigned int steps,unsigned int step)824 __VISIBILITY_DEFAULT__ void bsd_mixer_ext(char *s, unsigned int steps, unsigned int step) {
825 	/* Keep in sync with c_c_ext */
826 	const void *f[] = {
827 		bsd_mixer_ext_bass,
828 		bsd_mixer_ext_treble,
829 		bsd_mixer_ext_igain,
830 		bsd_mixer_ext_ogain,
831 		bsd_mixer_ext_dig1,
832 		bsd_mixer_ext_dig2,
833 		bsd_mixer_ext_dig3
834 	};
835 
836 	(void) bsd_mixer_mix_op("mixer_ext", s, steps, step, c_c_ext, f);
837 }
838 
bsd_mixer_ext_bass(int i,unsigned int n,unsigned int v)839 static void bsd_mixer_ext_bass(int i, unsigned int n, unsigned int v) {
840 	if(i != -1) (void) bsd_set_p_level(mix_h, i, n, v);
841 }
842 
bsd_mixer_ext_treble(int i,unsigned int n,unsigned int v)843 static void bsd_mixer_ext_treble(int i, unsigned int n, unsigned int v) {
844 	if(i != -1) (void) bsd_set_p_level(mix_h, i, n, v);
845 }
846 
bsd_mixer_ext_igain(int i,unsigned int n,unsigned int v)847 static void bsd_mixer_ext_igain(int i, unsigned int n, unsigned int v) {
848 	if(i != -1) (void) bsd_set_p_level(mix_h, i, n, v);
849 }
850 
bsd_mixer_ext_ogain(int i,unsigned int n,unsigned int v)851 static void bsd_mixer_ext_ogain(int i, unsigned int n, unsigned int v) {
852 	if(i != -1) (void) bsd_set_p_level(mix_h, i, n, v);
853 }
854 
bsd_mixer_ext_dig1(int i,unsigned int n,unsigned int v)855 static void bsd_mixer_ext_dig1(int i, unsigned int n, unsigned int v) {
856 	if(i != -1) (void) bsd_set_p_level(mix_h, i, n, v);
857 }
858 
bsd_mixer_ext_dig2(int i,unsigned int n,unsigned int v)859 static void bsd_mixer_ext_dig2(int i, unsigned int n, unsigned int v) {
860 	if(i != -1) (void) bsd_set_p_level(mix_h, i, n, v);
861 }
862 
bsd_mixer_ext_dig3(int i,unsigned int n,unsigned int v)863 static void bsd_mixer_ext_dig3(int i, unsigned int n, unsigned int v) {
864 	if(i != -1) (void) bsd_set_p_level(mix_h, i, n, v);
865 }
866 
867 /**
868  *
869  * Callback for test noise knobs and buttons.
870  *
871  */
872 
bsd_mixer_tst(char * s,unsigned int steps,unsigned int step)873 __VISIBILITY_DEFAULT__ void bsd_mixer_tst(char *s, unsigned int steps, unsigned int step) {
874 #if ! defined(PROG_DISABLE_AUDIO)
875 	/* Keep in sync with c_c_tst */
876 	const void *f[] = {
877 		bsd_mixer_tst_white
878 	};
879 
880 	(void) bsd_mixer_mix_op("mixer_tst", s, steps, step, c_c_tst, f);
881 #else
882 	(void) s;
883 	(void) steps;
884 	(void) step;
885 #endif
886 }
887 #if ! defined(PROG_DISABLE_AUDIO)
bsd_mixer_tst_white(__UNUSED__ int i,__UNUSED__ unsigned int n,unsigned int v)888 static void bsd_mixer_tst_white(__UNUSED__ int i, __UNUSED__ unsigned int n, unsigned int v) {
889 	switch(v) {
890 		case 0:
891 			(void) mixer_cancel(mix_tst_w);
892 
893 			break;
894 		case 1:
895 			if(mix_tst_w == 0) {
896 				if((mix_tst_w = mixer_create_noise_white(1.0)) == 0) break;
897 			}
898 
899 			(void) bsd_mixer_tst_op(mix_tst_w);
900 
901 			break;
902 		default:
903 			break;
904 	}
905 }
906 
bsd_mixer_tst_op(unsigned int h)907 static void bsd_mixer_tst_op(unsigned int h) {
908 	float e, f;
909 
910 	e = bsd_mixer_tst_at("mixer_tst_vol", 0, 100, 0.0, 1.0);
911 	f = bsd_mixer_tst_at("mixer_tst_pan", 0, 100, -1.0, 1.0);
912 
913 	(void) mixer_play(h, e, f);
914 	(void) mixer_loop(h);
915 }
916 
bsd_mixer_tst_at(char * s,unsigned int b,unsigned int c,float e,float f)917 static float bsd_mixer_tst_at(char *s, unsigned int b, unsigned int c, float e, float f) {
918 	unsigned int a;
919 
920 	float v;
921 
922 	if(widget_step_get(win_s, s, &a) != 0) return(0.0);
923 
924 	v = (float) maths_map((double) a, (double) b, (double) c, (double) e, (double) f);
925 
926 	return(v);
927 }
928 #endif
bsd_mixer_tst_vol(__UNUSED__ char * s,unsigned int steps,unsigned int step)929 __VISIBILITY_DEFAULT__ void bsd_mixer_tst_vol(__UNUSED__ char *s, unsigned int steps, unsigned int step) {
930 #if ! defined(PROG_DISABLE_AUDIO)
931 	float v;
932 
933 	v = (float) maths_map((double) step, 0.0, (double) steps, 0.0, 1.0);
934 
935 	(void) mixer_vol_set(mix_tst_w, v);
936 #else
937 	(void) steps;
938 	(void) step;
939 #endif
940 }
941 
bsd_mixer_tst_pan(__UNUSED__ char * s,unsigned int steps,unsigned int step)942 __VISIBILITY_DEFAULT__ void bsd_mixer_tst_pan(__UNUSED__ char *s, unsigned int steps, unsigned int step) {
943 #if ! defined(PROG_DISABLE_AUDIO)
944 	float v;
945 
946 	v = (float) maths_map((double) step, 0.0, (double) steps, -1.0, 1.0);
947 
948 	(void) mixer_pan_set(mix_tst_w, v);
949 #else
950 	(void) steps;
951 	(void) step;
952 #endif
953 }
954 
bsd_mixer_mix_op(char * p,char * s,unsigned int steps,unsigned int step,struct c_c * c,const void * fnc_t[])955 static void bsd_mixer_mix_op(char *p, char *s, unsigned int steps, unsigned int step, struct c_c *c, const void *fnc_t[]) {
956 	unsigned int i;
957 
958 	size_t t, u;
959 
960 	char n[32];
961 
962 	void (*f)(int, unsigned int, unsigned int);
963 
964 	t = str_len(s, STRING_ASCII);
965 
966 	for(i = 0; ; i++) {
967 		if(c[i].c == NULL) break;
968 
969 		u = (size_t) snprintf(n, sizeof(n), "%s_%s", p, c[i].c);
970 
971 		if(t == u) {
972 			if(strncmp((const char *) s, (const char *) n, t) != 0) {
973 				continue;
974 			}
975 
976 			f = fnc_t[i];
977 
978 			(void) (*f)(c[i].i, steps, step);
979 
980 			break;
981 		}
982 	}
983 }
984 
bsd_open_mixer(char * s)985 static int bsd_open_mixer(char *s) {
986 	int h;
987 
988 	if((h = open((const char *) s, O_RDWR)) == -1) {
989 		(void) bsd_mixer_er(_("Failed to open mixer"));
990 
991 		return(-1);
992 	}
993 #if defined(__FreeBSD__)
994 	if(bsd_open_mixer_freebsd(h) != 0) return(-1);
995 #endif
996 	return(h);
997 }
998 #if defined(__FreeBSD__)
bsd_open_mixer_freebsd(int h)999 static int bsd_open_mixer_freebsd(int h) {
1000 	int i;
1001 
1002 	for(i = 0; i < MIXER_CAP_CMD; i++) {
1003 		if(ioctl(h, mixer_c[i], &mixer_r[i]) == -1) {
1004 			(void) bsd_mixer_er(_("Failed to send control command to mixer"));
1005 			(void) bsd_close(h);
1006 
1007 			return(-1);
1008 		}
1009 	}
1010 
1011 	return(0);
1012 }
1013 #endif
bsd_mixer_er(char * s)1014 static void bsd_mixer_er(char *s) {
1015 	(void) fprintf(stderr, "%s: %s.%c", s, strerror(errno), CONFIG_LINE_FEED);
1016 }
1017 
bsd_close(int r)1018 static void bsd_close(int r) {
1019 	if(r != -1) (void) close(r);
1020 }
1021 
bsd_list(void)1022 static int bsd_list(void) {
1023 #if defined(__FreeBSD__)
1024 	return(bsd_list_freebsd());
1025 #endif
1026 	return(0);
1027 }
1028 #if defined(__FreeBSD__)
bsd_list_freebsd(void)1029 static int bsd_list_freebsd(void) {
1030 	int r;
1031 
1032 	size_t t;
1033 
1034 	char *f, *s;
1035 
1036 	char n[CONFIG_PATH_LENGTH];
1037 
1038 	DIR *d;
1039 
1040 	struct dirent *e;
1041 
1042 	oss_sysinfo si;
1043 
1044 	mixer_card_c = 0;
1045 	mixer_card_d = 0;
1046 
1047 	/* Try to open default mixer... */
1048 	if((s = env_get("OSS_MIXERDEV")) == NULL) {
1049 		if((s = env_get("MIXERDEVICE")) == NULL) {
1050 #if defined(HAVE_PATHS_H) && defined(_PATH_MIXER)
1051 			f = _PATH_MIXER;
1052 #else
1053 			f = MIXER_NAME_DIR MIXER_NAME_PRE;
1054 #endif
1055 		}
1056 		else f = s;
1057 	}
1058 	else f = s;
1059 
1060 	/* ...or try to open mixer devices until one succeeds */
1061 	if((r = bsd_open_mixer(f)) == -1) {
1062 		if((d = opendir((const char *) MIXER_NAME_DIR)) == NULL) {
1063 			(void) env_free(s);
1064 
1065 			return(0);
1066 		}
1067 
1068 		t = str_len(MIXER_NAME_PRE, STRING_ASCII);
1069 
1070 		while((e = readdir(d)) != NULL) {
1071 			/* Try to open this device if it looks okay */
1072 			if(strncmp(e->d_name, MIXER_NAME_PRE, t) != 0) continue;
1073 
1074 			(void) snprintf(n, sizeof(n), MIXER_NAME_DIR "%s", e->d_name);
1075 
1076 			if((r = bsd_open_mixer(n)) != -1) break;
1077 
1078 			break;
1079 		}
1080 
1081 		(void) closedir(d);
1082 
1083 		if(r == -1) {
1084 			(void) bsd_mixer_er(_("Failed to find any mixers, try setting $OSS_MIXERDEV or $MIXERDEVICE"));
1085 			(void) env_free(s);
1086 
1087 			return(0);
1088 		}
1089 	}
1090 
1091 	(void) env_free(s);
1092 
1093 	/* Get the audio system info */
1094 	(void) memset((void *) &si, 0, sizeof(si));
1095 
1096 	if(ioctl(r, SNDCTL_SYSINFO, &si) == -1) {
1097 		(void) bsd_mixer_er(_("Failed to send control command to mixer"));
1098 		(void) bsd_close(r);
1099 
1100 		return(0);
1101 	}
1102 
1103 	(void) bsd_close(r);
1104 
1105 	if(bsd_list_op(si.nummixers) != 0) return(0);
1106 
1107 	/* Open current mixer and get its settings */
1108 	mixer_card_a = si.numaudios;
1109 	mixer_card_c = si.nummixers;
1110 
1111 	(void) flush_error();
1112 
1113 	LOGINFO(
1114 		ERROR_NOERROR, SUBSYSTEM,
1115 		_("OSS product is %s, version %s with %d audios, %d cards and %d mixers"),
1116 		si.product, si.version, si.numaudios, si.numcards, si.nummixers
1117 	);
1118 
1119 	return(bsd_list_freebsd_op(mixer_card_d));
1120 }
1121 
bsd_list_freebsd_op(int i)1122 static int bsd_list_freebsd_op(int i) {
1123 	int r;
1124 
1125 	char n[CONFIG_PATH_LENGTH];
1126 
1127 	oss_mixerinfo mi;
1128 	oss_card_info ci;
1129 
1130 	(void) snprintf(n, sizeof(n), MIXER_NAME_DIR MIXER_NAME_PRE "%d", i);
1131 
1132 	if((r = bsd_open_mixer(n)) == -1) return(-1);
1133 
1134 	/* Get the mixer info... */
1135 	(void) memset((void *) &mi, 0, sizeof(mi));
1136 
1137 	mi.dev = i;
1138 
1139 	if(ioctl(r, SNDCTL_MIXERINFO, &mi) == -1) {
1140 		(void) bsd_mixer_er(_("Failed to send control command to mixer"));
1141 		(void) bsd_close(r);
1142 
1143 		return(-1);
1144 	}
1145 
1146 	if(mi.enabled == 0) return(-1);
1147 
1148 	/* ...and the soundcard info where this mixer is... */
1149 	(void) memset((void *) &ci, 0, sizeof(ci));
1150 
1151 	ci.card = mi.card_number;
1152 
1153 	if(ioctl(r, SNDCTL_CARDINFO, &ci) == -1) {
1154 		(void) bsd_mixer_er(_("Failed to send control command to mixer"));
1155 		(void) bsd_close(r);
1156 
1157 		return(-1);
1158 	}
1159 
1160 	/* ...and store them for later use */
1161 	mixer_card_t[i].mixer = mi.dev;
1162 	mixer_card_t[i].card = ci.card;
1163 
1164 	(void) snprintf(
1165 		mixer_card_t[i].name, sizeof(mixer_card_t[i].name),
1166 		"%s", mi.id);
1167 
1168 	(void) snprintf(
1169 		mixer_card_t[i].name_s, sizeof(mixer_card_t[i].name_s),
1170 		"%s", ci.shortname);
1171 
1172 	(void) snprintf(
1173 		mixer_card_t[i].name_l, sizeof(mixer_card_t[i].name_l),
1174 		"%s", ci.longname);
1175 
1176 	return(r);
1177 }
1178 #endif
bsd_list_op(int n)1179 static int bsd_list_op(int n) {
1180 	(void) bsd_list_free();
1181 
1182 	if((mixer_card_t = (struct mixer_card *) malloc(sizeof(struct mixer_card) * n)) == NULL) {
1183 		(void) fprintf(
1184 			stderr,
1185 			_("Failed to allocate %lu bytes of memory: %s.%c"),
1186 			(unsigned long) sizeof(struct mixer_card) * n, strerror(errno), CONFIG_LINE_FEED
1187 		);
1188 
1189 		return(-1);
1190 	}
1191 
1192 	return(0);
1193 }
1194 
bsd_list_free(void)1195 static void bsd_list_free(void) {
1196 	if(mixer_card_t != NULL) (void) free(mixer_card_t);
1197 
1198 	mixer_card_c = 0;
1199 	mixer_card_t = NULL;
1200 }
1201 
bsd_get_p_level(int r,int i,int * k)1202 static int bsd_get_p_level(int r, int i, int *k) {
1203 #if defined(__FreeBSD__)
1204 	int v;
1205 
1206 	if((mixer_r[MIXER_CAP_DEV] == 0) || (!((1 << i) & mixer_r[MIXER_CAP_DEV]))) {
1207 		return(-1);
1208 	}
1209 
1210 	if(ioctl(r, MIXER_READ(i), &v) == -1) {
1211 		(void) bsd_mixer_er(_("Failed to send control command to mixer"));
1212 
1213 		return(-1);
1214 	}
1215 
1216 	k[0] = v & 0x7f;
1217 	k[1] = (v >> 8) & 0x7f;
1218 #else
1219 	(void) r;
1220 	(void) i;
1221 	(void) k;
1222 #endif
1223 	return(0);
1224 }
1225 
bsd_set_p_level(int r,int i,int n,int v)1226 static int bsd_set_p_level(int r, int i, int n, int v) {
1227 #if defined(__FreeBSD__)
1228 	v = (int) round(maths_map((double) v, 0.0, (double) n, 0.0, 100.0));
1229 
1230 	if(v < 0) {
1231 		v = 0;
1232 	}
1233 	else if(v > 100) v = 100;
1234 
1235 	v |= (v << 8);
1236 
1237 	if(ioctl(r, MIXER_WRITE(i), &v) == -1) {
1238 		(void) bsd_mixer_er(_("Failed to send control command to mixer"));
1239 
1240 		return(-1);
1241 	}
1242 #else
1243 	(void) r;
1244 	(void) i;
1245 	(void) n;
1246 	(void) v;
1247 #endif
1248 	return(0);
1249 }
1250 
bsd_get_r_source(int i)1251 static int bsd_get_r_source(int i) {
1252 #if defined(__FreeBSD__)
1253 	if((mixer_r[MIXER_CAP_REC] == 0) || (!((1 << i) & mixer_r[MIXER_CAP_SRC]))) {
1254 		return(-1);
1255 	}
1256 #else
1257 	(void) i;
1258 #endif
1259 	return(0);
1260 }
1261