1 /* vi: set sw=4 ts=4: */
2 /*
3  * beep implementation for busybox
4  *
5  * Copyright (C) 2009 Bernhard Reutner-Fischer
6  *
7  * Licensed under GPLv2 or later, see file LICENSE in this source tree.
8  */
9 //config:config BEEP
10 //config:	bool "beep (2.4 kb)"
11 //config:	default y
12 //config:	help
13 //config:	The beep applets beeps in a given freq/Hz.
14 //config:
15 //config:config FEATURE_BEEP_FREQ
16 //config:	int "default frequency"
17 //config:	range 20 50000	# allowing 0 here breaks the build
18 //config:	default 4000
19 //config:	depends on BEEP
20 //config:	help
21 //config:	Frequency for default beep.
22 //config:
23 //config:config FEATURE_BEEP_LENGTH_MS
24 //config:	int "default length"
25 //config:	range 0 2147483647
26 //config:	default 30
27 //config:	depends on BEEP
28 //config:	help
29 //config:	Length in ms for default beep.
30 
31 //applet:IF_BEEP(APPLET(beep, BB_DIR_USR_BIN, BB_SUID_DROP))
32 
33 //kbuild:lib-$(CONFIG_BEEP) += beep.o
34 
35 //usage:#define beep_trivial_usage
36 //usage:       "-f FREQ -l LEN -d DELAY -r COUNT -n"
37 //usage:#define beep_full_usage "\n\n"
38 //usage:       "	-f	Frequency in Hz"
39 //usage:     "\n	-l	Length in ms"
40 //usage:     "\n	-d	Delay in ms"
41 //usage:     "\n	-r	Repetitions"
42 //usage:     "\n	-n	Start new tone"
43 
44 #include "libbb.h"
45 
46 #include <linux/kd.h>
47 #ifndef CLOCK_TICK_RATE
48 # define CLOCK_TICK_RATE 1193180
49 #endif
50 
51 /* defaults */
52 #ifndef CONFIG_FEATURE_BEEP_FREQ
53 # define FREQ (4000)
54 #else
55 # define FREQ (CONFIG_FEATURE_BEEP_FREQ)
56 #endif
57 #ifndef CONFIG_FEATURE_BEEP_LENGTH_MS
58 # define LENGTH (30)
59 #else
60 # define LENGTH (CONFIG_FEATURE_BEEP_LENGTH_MS)
61 #endif
62 #define DELAY (0)
63 #define REPETITIONS (1)
64 
65 int beep_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
beep_main(int argc,char ** argv)66 int beep_main(int argc, char **argv)
67 {
68 	int speaker = get_console_fd_or_die();
69 	unsigned tickrate_div_freq = tickrate_div_freq; /* for compiler */
70 	unsigned length = length;
71 	unsigned delay = delay;
72 	unsigned rep = rep;
73 	int c;
74 
75 	c = 'n';
76 	while (c != -1) {
77 		if (c == 'n') {
78 			tickrate_div_freq = CLOCK_TICK_RATE / FREQ;
79 			length = LENGTH;
80 			delay = DELAY;
81 			rep = REPETITIONS;
82 		}
83 		c = getopt(argc, argv, "f:l:d:r:n");
84 /* TODO: -s, -c:
85  * pipe stdin to stdout, but also beep after each line (-s) or char (-c)
86  */
87 		switch (c) {
88 		case 'f':
89 /* TODO: what "-f 0" should do? */
90 			tickrate_div_freq = (unsigned)CLOCK_TICK_RATE / xatou(optarg);
91 			continue;
92 		case 'l':
93 			length = xatou(optarg);
94 			continue;
95 		case 'd':
96 /* TODO:
97  * -d N, -D N
98  * specify a delay of N milliseconds between repetitions.
99  * -d specifies that this delay should only occur between beeps,
100  * that is, it should not occur after the last repetition.
101  * -D indicates that the delay should occur after every repetition
102  */
103 			delay = xatou(optarg);
104 			continue;
105 		case 'r':
106 			rep = xatou(optarg);
107 			continue;
108 		case 'n':
109 		case -1:
110 			break;
111 		default:
112 			bb_show_usage();
113 		}
114 		while (rep) {
115 //bb_error_msg("rep[%d] freq=%d, length=%d, delay=%d", rep, freq, length, delay);
116 			xioctl(speaker, KIOCSOUND, (void*)(uintptr_t)tickrate_div_freq);
117 			msleep(length);
118 			ioctl(speaker, KIOCSOUND, (void*)0);
119 			if (--rep)
120 				msleep(delay);
121 		}
122 	}
123 
124 	if (ENABLE_FEATURE_CLEAN_UP)
125 		close(speaker);
126 	return EXIT_SUCCESS;
127 }
128 /*
129  * so, e.g. Beethoven's 9th symphony "Ode an die Freude" would be
130  * something like:
131 a=$((220*3))
132 b=$((247*3))
133 c=$((262*3))
134 d=$((294*3))
135 e=$((329*3))
136 f=$((349*3))
137 g=$((392*3))
138 #./beep -f$d -l200 -r2 -n -f$e -l100 -d 10 -n -f$c -l400 -f$g -l200
139 ./beep -f$e -l200 -r2 \
140         -n -d 100 -f$f -l200 \
141         -n -f$g -l200 -r2 \
142         -n -f$f -l200 \
143         -n -f$e -l200 \
144         -n -f$d -l200 \
145         -n -f$c -l200 -r2 \
146         -n -f$d -l200 \
147         -n -f$e -l200 \
148         -n -f$e -l400 \
149         -n -f$d -l100 \
150         -n -f$d -l200 \
151 */
152