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