Convert to pulseaudio

This commit is contained in:
Daniel Ponte 2021-04-11 08:56:52 -04:00
parent b5a39e5849
commit 2b32f77957
3 changed files with 223 additions and 241 deletions

View File

@ -9,7 +9,7 @@ BIN = ./beepbeep
CC = gcc CC = gcc
LD = $(CC) LD = $(CC)
CFLAGS = -Wall -g CFLAGS = -Wall -g
LIBS = -lm LIBS = -lm -lpulse-simple -lpulse
all: $(BIN) all: $(BIN)
@echo "All done" @echo "All done"

3
README
View File

@ -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 The use of this software on telephone lines without the permission of the
owners of these lines is illegal. owners of these lines is illegal.

View File

@ -1,240 +1,219 @@
/*****************************************************************************\ /*****************************************************************************\
** ** ** **
** BEEP-BEEP ** ** BEEP-BEEP **
** ** ** **
**---------------------------------------------------------------------------** **---------------------------------------------------------------------------**
** Copyright: Andreas Eversberg ** ** Copyright: Andreas Eversberg **
** ** ** Converted to use PulseAudio by Daniel Ponte **
** minimal blueboxing software ** ** **
** ** ** minimal blueboxing software **
\*****************************************************************************/ ** **
\*****************************************************************************/
#include <stdio.h>
#include <termios.h> #include <stdio.h>
#include <unistd.h> #include <termios.h>
#include <string.h> #include <unistd.h>
#include <math.h> #include <string.h>
#include <sys/types.h> #include <math.h>
#include <sys/stat.h> #include <sys/types.h>
#include <fcntl.h> #include <sys/stat.h>
#include <sys/ioctl.h> #include <fcntl.h>
#include <errno.h> #include <sys/ioctl.h>
#include <linux/soundcard.h> #include <errno.h>
#include <stdlib.h>
#define SAMPLE_RATE 8000
#define DSP_DEVICE "/dev/dsp" #include <pulse/simple.h>
#define PI 3.14159265 #include <pulse/error.h>
#include <pulse/gccmacro.h>
struct ccitt5 {
char digit; #define SAMPLE_RATE 8000
int f1, f2; #define PI 3.14159265
int duration, delay;
} ccitt5[] = { struct ccitt5 {
{'A', 2400, 0, 150, 100}, char digit;
{'B', 2600, 0, 850, 100}, int f1, f2;
{'C', 2400, 2600, 70, 100}, int duration, delay;
{'1', 700, 900, 55, 50}, } ccitt5[] = {
{'2', 700, 1100, 55, 50}, {'A', 2400, 0, 150, 100},
{'3', 900, 1100, 55, 50}, {'B', 2600, 0, 850, 100},
{'4', 700, 1300, 55, 50}, {'C', 2400, 2600, 70, 100},
{'5', 900, 1300, 55, 50}, {'1', 700, 900, 55, 50},
{'6', 1100, 1300, 55, 50}, {'2', 700, 1100, 55, 50},
{'7', 700, 1500, 55, 50}, {'3', 900, 1100, 55, 50},
{'8', 900, 1500, 55, 50}, {'4', 700, 1300, 55, 50},
{'9', 1100, 1500, 55, 50}, {'5', 900, 1300, 55, 50},
{'0', 1300, 1500, 55, 50}, {'6', 1100, 1300, 55, 50},
{'d', 700, 1700, 55, 50}, {'7', 700, 1500, 55, 50},
{'e', 900, 1700, 55, 50}, {'8', 900, 1500, 55, 50},
{'a', 1100, 1700, 100, 50}, {'9', 1100, 1500, 55, 50},
{'b', 1300, 1700, 100, 50}, {'0', 1300, 1500, 55, 50},
{'c', 1500, 1700, 55, 50}, {'d', 700, 1700, 55, 50},
{0, 0, 0, 0, 0} {'e', 900, 1700, 55, 50},
}; {'a', 1100, 1700, 100, 50},
{'b', 1300, 1700, 100, 50},
/* {'c', 1500, 1700, 55, 50},
* stream bell sound {0, 0, 0, 0, 0}
*/ };
void dial_dsp(int dsp, char *dial)
{ void close_pa(pa_simple *s)
int i, j, len; {
double k1, k2; if (s)
unsigned char buffer[SAMPLE_RATE]; /* one second */ pa_simple_free(s);
}
if (dsp < 0)
return;
/*
while(*dial) { * stream bell sound
i = 0; */
while(ccitt5[i].digit) { void dial_pa(pa_simple *s, char *dial)
if (ccitt5[i].digit == *dial) {
break; int i, j, len;
i++; int error;
} double k1, k2;
if (ccitt5[i].digit) { unsigned char buffer[SAMPLE_RATE]; /* one second */
/* send tone */
len = ccitt5[i].duration * SAMPLE_RATE / 1000; if(!s)
k1 = 2.0 * PI * ccitt5[i].f1 / SAMPLE_RATE; return;
k2 = 2.0 * PI * ccitt5[i].f2 / SAMPLE_RATE;
for (j = 0; j < len; j++) while(*dial) {
buffer[j] = 64.0 * (2.0 + sin(k1 * j) + sin(k2 * j)); i = 0;
write(dsp, buffer, len); while(ccitt5[i].digit) {
/* send pause */ if (ccitt5[i].digit == *dial)
len = ccitt5[i].delay * SAMPLE_RATE / 1000; break;
memset(buffer, 128, len); i++;
write(dsp, buffer, len); }
} if (ccitt5[i].digit) {
dial++; /* send tone */
} len = ccitt5[i].duration * SAMPLE_RATE / 1000;
k1 = 2.0 * PI * ccitt5[i].f1 / SAMPLE_RATE;
ioctl(dsp, SOUND_PCM_SYNC, 0); 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));
* open dsp close_pa(s);
*/ exit(-1);
int open_dsp(char *device, int rate) }
{ /* send pause */
int dsp; len = ccitt5[i].delay * SAMPLE_RATE / 1000;
unsigned long arg; memset(buffer, 128, len);
// audio_buf_info info; if (pa_simple_write(s, buffer, (size_t) len, &error) < 0) {
fprintf(stderr, __FILE__": pa_simple_write() failed: %s\n", pa_strerror(error));
if ((dsp=open(device, O_WRONLY)) < 0) { close_pa(s);
fprintf(stderr, "cannot open '%s'\n", device); exit(-1);
return -errno; }
}
#if 0 }
if (ioctl(dsp, SNDCTL_DSP_RESET, NULL) < 0) { dial++;
fprintf(stderr, "ioctl failed with SOUND_DSP_RESET\n"); }
close(dsp);
return -errno; if (pa_simple_drain(s, &error) < 0) {
} fprintf(stderr, __FILE__": pa_simple_drain() failed: %s\n", pa_strerror(error));
#endif close_pa(s);
arg = 8; exit(-1);
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) { * open pulse
fprintf(stderr, "ioctl cannot set correct sample size\n"); */
close(dsp); pa_simple* open_pa(char *pname)
return -errno; {
} int error;
arg = 1; static const pa_sample_spec ss = {
if (ioctl(dsp, SOUND_PCM_WRITE_CHANNELS, &arg) < 0) { .format = PA_SAMPLE_U8,
fprintf(stderr, "ioctl failed with SOUND_PCM_WRITE_CHANNELS = %lu\n", arg); .rate = SAMPLE_RATE,
close(dsp); .channels = 1
return -errno; };
} pa_simple *s = NULL;
if ((int)arg != 1) {
fprintf(stderr, "ioctl cannot set correct channel number\n"); if (!(s = pa_simple_new(NULL, pname, PA_STREAM_PLAYBACK, NULL, "playback", &ss, NULL, NULL, &error))) {
close(dsp); fprintf(stderr, __FILE__": pa_simple_new() failed: %s\n", pa_strerror(error));
return -errno; return NULL;
} }
arg = rate; return s;
if (ioctl(dsp, SOUND_PCM_WRITE_RATE,&arg) < 0) { }
fprintf(stderr, "ioctl failed with SOUND_PCM_WRITE_RATE = %lu\n", arg);
close(dsp); int main(int argc, char *argv[])
return -errno; {
} pa_simple *s;
if ((int)arg != rate) { char *dial = "";
fprintf(stderr, "ioctl cannot set correct sample rate (got %lu)\n",arg); int ch;
close(dsp); char digit[2] = "x";
return -errno; struct termios orig, now;
}
if (argc > 1 && !strcmp(argv[1], "--help")) {
return dsp; printf("Usage: %s [<dial string>]\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");
void close_dsp(int dsp) return 0;
{ }
if (dsp >= 0) {
#if 0 if (argc > 1)
if (ioctl(dsp, SNDCTL_DSP_RESET, NULL) < 0) dial = argv[1];
fprintf(stderr, "ioctl failed with SOUND_DSP_RESET\n");
#endif s = open_pa(argv[0]);
close(dsp); if (s == NULL) {
} fprintf(stderr, "cannot open pulse\n");
} return 1;
}
int main(int argc, char *argv[])
{ printf("Welcome to Beep-Beep, your simple bluebox!\n");
int dsp; printf("------------------------------------------\n");
char *dial = ""; printf("y or z = clear-forward\n");
int ch; printf("x = seize\n");
char digit[2] = "x"; printf("0-9 = Digits\n");
struct termios orig, now; printf("a = KP1\n");
printf("b = KP2\n");
if (argc > 1 && !strcmp(argv[1], "--help")) { printf("c = ST\n");
printf("Usage: %s [<dial string>]\n\n", argv[0]); printf("d = Code 11\n");
printf("Runs with with the given dial string.\n"); printf("e = Code 12\n");
printf("For KP1, KP2, ST, use characters a, b, c instead.\n"); printf("f = forward transfer\n");
return 0; if (dial[0])
} printf(". = dial %s\n", dial);
printf("Escape to exit.\n");
if (argc > 1)
dial = argv[1]; tcgetattr(0, &orig);
now = orig;
dsp = open_dsp(DSP_DEVICE, SAMPLE_RATE); now.c_lflag &= ~(ISIG|ICANON|ECHO);
if (dsp < 0) now.c_cc[VMIN]=1;
return dsp; now.c_cc[VTIME]=2;
printf("Welcome to Beep-Beep, your simple bluebox!\n"); tcsetattr(0, TCSANOW, &now);
printf("------------------------------------------\n"); while ((ch = getc(stdin)) != 27) {
printf("y or z = clear-forward\n"); switch(ch) {
printf("x = seize\n"); case 'y': case 'z':
printf("0-9 = Digits\n"); dial_pa(s, "C");
printf("a = KP1\n"); break;
printf("b = KP2\n"); case 'x':
printf("c = ST\n"); dial_pa(s, "A");
printf("d = Code 11\n"); break;
printf("e = Code 12\n"); case 'f':
printf("f = forward transfer\n"); dial_pa(s, "B");
if (dial[0]) break;
printf(". = dial %s\n", dial); case '1': case '2': case '3': case '4': case '5':
printf("Escape to exit.\n"); case '6': case '7': case '8': case '9': case '0':
case 'a': case 'b': case 'c': case 'd': case 'e':
tcgetattr(0, &orig); digit[0] = ch;
now = orig; dial_pa(s, digit);
now.c_lflag &= ~(ISIG|ICANON|ECHO); break;
now.c_cc[VMIN]=1; case '.':
now.c_cc[VTIME]=2; if (dial[0])
dial_pa(s, dial);
tcsetattr(0, TCSANOW, &now); break;
while ((ch = getc(stdin)) != 27) { }
switch(ch) { if (ch == 3)
case 'y': case 'z': break;
dial_dsp(dsp, "C"); }
break; tcsetattr(0, TCSANOW, &orig);
case 'x':
dial_dsp(dsp, "A"); close_pa(s);
break;
case 'f': return 0;
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;
}