busybox/miscutils/beep.c
<<
>>
Prefs
   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
  65int beep_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  66int 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:
 131a=$((220*3))
 132b=$((247*3))
 133c=$((262*3))
 134d=$((294*3))
 135e=$((329*3))
 136f=$((349*3))
 137g=$((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