From 2b32f77957288e8558747f6498b25e8293476a33 Mon Sep 17 00:00:00 2001 From: Daniel Ponte Date: Sun, 11 Apr 2021 08:56:52 -0400 Subject: [PATCH] Convert to pulseaudio --- Makefile | 2 +- README | 3 + beepbeep.c | 459 +++++++++++++++++++++++++---------------------------- 3 files changed, 223 insertions(+), 241 deletions(-) diff --git a/Makefile b/Makefile index 4991b0d..349ae79 100755 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ BIN = ./beepbeep CC = gcc LD = $(CC) CFLAGS = -Wall -g -LIBS = -lm +LIBS = -lm -lpulse-simple -lpulse all: $(BIN) @echo "All done" diff --git a/README b/README index 65dbd8b..3ea8b87 100644 --- a/README +++ b/README @@ -1,3 +1,6 @@ +Originally by Andreas Everberg +Converted to use PulseAudio by Daniel Ponte + The use of this software on telephone lines without the permission of the owners of these lines is illegal. diff --git a/beepbeep.c b/beepbeep.c index 15568b5..8a34900 100755 --- a/beepbeep.c +++ b/beepbeep.c @@ -1,240 +1,219 @@ -/*****************************************************************************\ -** ** -** BEEP-BEEP ** -** ** -**---------------------------------------------------------------------------** -** Copyright: Andreas Eversberg ** -** ** -** minimal blueboxing software ** -** ** -\*****************************************************************************/ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define SAMPLE_RATE 8000 -#define DSP_DEVICE "/dev/dsp" -#define PI 3.14159265 - -struct ccitt5 { - char digit; - int f1, f2; - int duration, delay; -} ccitt5[] = { - {'A', 2400, 0, 150, 100}, - {'B', 2600, 0, 850, 100}, - {'C', 2400, 2600, 70, 100}, - {'1', 700, 900, 55, 50}, - {'2', 700, 1100, 55, 50}, - {'3', 900, 1100, 55, 50}, - {'4', 700, 1300, 55, 50}, - {'5', 900, 1300, 55, 50}, - {'6', 1100, 1300, 55, 50}, - {'7', 700, 1500, 55, 50}, - {'8', 900, 1500, 55, 50}, - {'9', 1100, 1500, 55, 50}, - {'0', 1300, 1500, 55, 50}, - {'d', 700, 1700, 55, 50}, - {'e', 900, 1700, 55, 50}, - {'a', 1100, 1700, 100, 50}, - {'b', 1300, 1700, 100, 50}, - {'c', 1500, 1700, 55, 50}, - {0, 0, 0, 0, 0} -}; - -/* - * stream bell sound - */ -void dial_dsp(int dsp, char *dial) -{ - int i, j, len; - double k1, k2; - unsigned char buffer[SAMPLE_RATE]; /* one second */ - - if (dsp < 0) - return; - - while(*dial) { - i = 0; - while(ccitt5[i].digit) { - if (ccitt5[i].digit == *dial) - break; - i++; - } - if (ccitt5[i].digit) { - /* send tone */ - len = ccitt5[i].duration * SAMPLE_RATE / 1000; - k1 = 2.0 * PI * ccitt5[i].f1 / SAMPLE_RATE; - k2 = 2.0 * PI * ccitt5[i].f2 / SAMPLE_RATE; - for (j = 0; j < len; j++) - buffer[j] = 64.0 * (2.0 + sin(k1 * j) + sin(k2 * j)); - write(dsp, buffer, len); - /* send pause */ - len = ccitt5[i].delay * SAMPLE_RATE / 1000; - memset(buffer, 128, len); - write(dsp, buffer, len); - } - dial++; - } - - ioctl(dsp, SOUND_PCM_SYNC, 0); -} - - -/* - * open dsp - */ -int open_dsp(char *device, int rate) -{ - int dsp; - unsigned long arg; -// audio_buf_info info; - - if ((dsp=open(device, O_WRONLY)) < 0) { - fprintf(stderr, "cannot open '%s'\n", device); - return -errno; - } -#if 0 - if (ioctl(dsp, SNDCTL_DSP_RESET, NULL) < 0) { - fprintf(stderr, "ioctl failed with SOUND_DSP_RESET\n"); - close(dsp); - return -errno; - } -#endif - arg = 8; - if (ioctl(dsp, SOUND_PCM_WRITE_BITS, &arg) < 0) { - fprintf(stderr, "ioctl failed with SOUND_PCM_WRITE_BITS = %lu\n", arg); - close(dsp); - return -errno; - } - if ((int)arg != 8) { - fprintf(stderr, "ioctl cannot set correct sample size\n"); - close(dsp); - return -errno; - } - - arg = 1; - if (ioctl(dsp, SOUND_PCM_WRITE_CHANNELS, &arg) < 0) { - fprintf(stderr, "ioctl failed with SOUND_PCM_WRITE_CHANNELS = %lu\n", arg); - close(dsp); - return -errno; - } - if ((int)arg != 1) { - fprintf(stderr, "ioctl cannot set correct channel number\n"); - close(dsp); - return -errno; - } - - arg = rate; - if (ioctl(dsp, SOUND_PCM_WRITE_RATE,&arg) < 0) { - fprintf(stderr, "ioctl failed with SOUND_PCM_WRITE_RATE = %lu\n", arg); - close(dsp); - return -errno; - } - if ((int)arg != rate) { - fprintf(stderr, "ioctl cannot set correct sample rate (got %lu)\n",arg); - close(dsp); - return -errno; - } - - return dsp; -} - -void close_dsp(int dsp) -{ - if (dsp >= 0) { -#if 0 - if (ioctl(dsp, SNDCTL_DSP_RESET, NULL) < 0) - fprintf(stderr, "ioctl failed with SOUND_DSP_RESET\n"); -#endif - close(dsp); - } -} - -int main(int argc, char *argv[]) -{ - int dsp; - char *dial = ""; - int ch; - char digit[2] = "x"; - struct termios orig, now; - - if (argc > 1 && !strcmp(argv[1], "--help")) { - printf("Usage: %s []\n\n", argv[0]); - printf("Runs with with the given dial string.\n"); - printf("For KP1, KP2, ST, use characters a, b, c instead.\n"); - return 0; - } - - if (argc > 1) - dial = argv[1]; - - dsp = open_dsp(DSP_DEVICE, SAMPLE_RATE); - if (dsp < 0) - return dsp; - - printf("Welcome to Beep-Beep, your simple bluebox!\n"); - printf("------------------------------------------\n"); - printf("y or z = clear-forward\n"); - printf("x = seize\n"); - printf("0-9 = Digits\n"); - printf("a = KP1\n"); - printf("b = KP2\n"); - printf("c = ST\n"); - printf("d = Code 11\n"); - printf("e = Code 12\n"); - printf("f = forward transfer\n"); - if (dial[0]) - printf(". = dial %s\n", dial); - printf("Escape to exit.\n"); - - tcgetattr(0, &orig); - now = orig; - now.c_lflag &= ~(ISIG|ICANON|ECHO); - now.c_cc[VMIN]=1; - now.c_cc[VTIME]=2; - - tcsetattr(0, TCSANOW, &now); - while ((ch = getc(stdin)) != 27) { - switch(ch) { - case 'y': case 'z': - dial_dsp(dsp, "C"); - break; - case 'x': - dial_dsp(dsp, "A"); - break; - case 'f': - dial_dsp(dsp, "B"); - break; - case '1': case '2': case '3': case '4': case '5': - case '6': case '7': case '8': case '9': case '0': - case 'a': case 'b': case 'c': case 'd': case 'e': - digit[0] = ch; - dial_dsp(dsp, digit); - break; - case '.': - if (dial[0]) - dial_dsp(dsp, dial); - break; - } - if (ch == 3) - break; - } - tcsetattr(0, TCSANOW, &orig); - - close_dsp(dsp); - - return 0; -} - - +/*****************************************************************************\ +** ** +** BEEP-BEEP ** +** ** +**---------------------------------------------------------------------------** +** Copyright: Andreas Eversberg ** +** Converted to use PulseAudio by Daniel Ponte ** +** ** +** minimal blueboxing software ** +** ** +\*****************************************************************************/ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define SAMPLE_RATE 8000 +#define PI 3.14159265 + +struct ccitt5 { + char digit; + int f1, f2; + int duration, delay; +} ccitt5[] = { + {'A', 2400, 0, 150, 100}, + {'B', 2600, 0, 850, 100}, + {'C', 2400, 2600, 70, 100}, + {'1', 700, 900, 55, 50}, + {'2', 700, 1100, 55, 50}, + {'3', 900, 1100, 55, 50}, + {'4', 700, 1300, 55, 50}, + {'5', 900, 1300, 55, 50}, + {'6', 1100, 1300, 55, 50}, + {'7', 700, 1500, 55, 50}, + {'8', 900, 1500, 55, 50}, + {'9', 1100, 1500, 55, 50}, + {'0', 1300, 1500, 55, 50}, + {'d', 700, 1700, 55, 50}, + {'e', 900, 1700, 55, 50}, + {'a', 1100, 1700, 100, 50}, + {'b', 1300, 1700, 100, 50}, + {'c', 1500, 1700, 55, 50}, + {0, 0, 0, 0, 0} +}; + +void close_pa(pa_simple *s) +{ + if (s) + pa_simple_free(s); +} + + +/* + * stream bell sound + */ +void dial_pa(pa_simple *s, char *dial) +{ + int i, j, len; + int error; + double k1, k2; + unsigned char buffer[SAMPLE_RATE]; /* one second */ + + if(!s) + return; + + while(*dial) { + i = 0; + while(ccitt5[i].digit) { + if (ccitt5[i].digit == *dial) + break; + i++; + } + if (ccitt5[i].digit) { + /* send tone */ + len = ccitt5[i].duration * SAMPLE_RATE / 1000; + k1 = 2.0 * PI * ccitt5[i].f1 / SAMPLE_RATE; + k2 = 2.0 * PI * ccitt5[i].f2 / SAMPLE_RATE; + for (j = 0; j < len; j++) + buffer[j] = 64.0 * (2.0 + sin(k1 * j) + sin(k2 * j)); + if (pa_simple_write(s, buffer, (size_t) len, &error) < 0) { + fprintf(stderr, __FILE__": pa_simple_write() failed: %s\n", pa_strerror(error)); + close_pa(s); + exit(-1); + } + /* send pause */ + len = ccitt5[i].delay * SAMPLE_RATE / 1000; + memset(buffer, 128, len); + if (pa_simple_write(s, buffer, (size_t) len, &error) < 0) { + fprintf(stderr, __FILE__": pa_simple_write() failed: %s\n", pa_strerror(error)); + close_pa(s); + exit(-1); + } + + } + dial++; + } + + if (pa_simple_drain(s, &error) < 0) { + fprintf(stderr, __FILE__": pa_simple_drain() failed: %s\n", pa_strerror(error)); + close_pa(s); + exit(-1); + } +} + + +/* + * open pulse + */ +pa_simple* open_pa(char *pname) +{ + int error; + + static const pa_sample_spec ss = { + .format = PA_SAMPLE_U8, + .rate = SAMPLE_RATE, + .channels = 1 + }; + pa_simple *s = NULL; + + if (!(s = pa_simple_new(NULL, pname, PA_STREAM_PLAYBACK, NULL, "playback", &ss, NULL, NULL, &error))) { + fprintf(stderr, __FILE__": pa_simple_new() failed: %s\n", pa_strerror(error)); + return NULL; + } + + return s; +} + +int main(int argc, char *argv[]) +{ + pa_simple *s; + char *dial = ""; + int ch; + char digit[2] = "x"; + struct termios orig, now; + + if (argc > 1 && !strcmp(argv[1], "--help")) { + printf("Usage: %s []\n\n", argv[0]); + printf("Runs with with the given dial string.\n"); + printf("For KP1, KP2, ST, use characters a, b, c instead.\n"); + return 0; + } + + if (argc > 1) + dial = argv[1]; + + s = open_pa(argv[0]); + if (s == NULL) { + fprintf(stderr, "cannot open pulse\n"); + return 1; + } + + printf("Welcome to Beep-Beep, your simple bluebox!\n"); + printf("------------------------------------------\n"); + printf("y or z = clear-forward\n"); + printf("x = seize\n"); + printf("0-9 = Digits\n"); + printf("a = KP1\n"); + printf("b = KP2\n"); + printf("c = ST\n"); + printf("d = Code 11\n"); + printf("e = Code 12\n"); + printf("f = forward transfer\n"); + if (dial[0]) + printf(". = dial %s\n", dial); + printf("Escape to exit.\n"); + + tcgetattr(0, &orig); + now = orig; + now.c_lflag &= ~(ISIG|ICANON|ECHO); + now.c_cc[VMIN]=1; + now.c_cc[VTIME]=2; + + tcsetattr(0, TCSANOW, &now); + while ((ch = getc(stdin)) != 27) { + switch(ch) { + case 'y': case 'z': + dial_pa(s, "C"); + break; + case 'x': + dial_pa(s, "A"); + break; + case 'f': + dial_pa(s, "B"); + break; + case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': case '0': + case 'a': case 'b': case 'c': case 'd': case 'e': + digit[0] = ch; + dial_pa(s, digit); + break; + case '.': + if (dial[0]) + dial_pa(s, dial); + break; + } + if (ch == 3) + break; + } + tcsetattr(0, TCSANOW, &orig); + + close_pa(s); + + return 0; +} + +