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