diff --git a/.gitignore b/.gitignore index af82fe0..4da4d83 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ *.o +*~ .deps Makefile Makefile.in diff --git a/INSTALL b/INSTALL index 7d1c323..d9666ab 100644 --- a/INSTALL +++ b/INSTALL @@ -12,7 +12,8 @@ without warranty of any kind. Basic Installation ================== - Briefly, the shell commands `./configure; make; make install' should + Briefly, the shell commands `./install-dependencies-linux.sh; +autoreconf --install; ./configure; make; make install' should configure, build, and install this package. The following more-detailed instructions are generic; see the `README' file for instructions specific to this package. Some packages provide this diff --git a/configure.ac b/configure.ac index 11de8ef..ee3d423 100644 --- a/configure.ac +++ b/configure.ac @@ -64,6 +64,17 @@ AS_IF([test "x$with_sndfile" = "xno"], [ AC_DEFINE_UNQUOTED([USE_SNDFILE], [$use_sndfile], [Define to 1 to enable sndfile support]) +# stdio +AC_ARG_WITH([stdio], AS_HELP_STRING([--without-stdio], + [build without stdio support])) +AS_IF([test "x$with_stdio" = "xno"], [ + use_stdio=0 +], [ + use_stdio=1 +]) +AC_DEFINE_UNQUOTED([USE_STDIO], [$use_stdio], + [Define to 1 to enable stdio support]) + # benchmarks AC_ARG_WITH([benchmarks], AS_HELP_STRING([--disable-benchmarks], [build without internal benchmarks])) @@ -81,6 +92,7 @@ option summary: benchmarks $with_benchmarks ($use_benchmarks) pulseaudio $with_pulseaudio ($use_pulseaudio) sndfile $with_sndfile ($use_sndfile) + stdio $with_stdio ($use_stdio) sndio $with_sndio ($use_sndio) ]) diff --git a/src/Makefile.am b/src/Makefile.am index fcd71cb..ec0193b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -37,7 +37,8 @@ SIMPLEAUDIO_SRC = \ simpleaudio-alsa.c \ simpleaudio-sndio.c \ simpleaudio-benchmark.c \ - simpleaudio-sndfile.c + simpleaudio-sndfile.c \ + simpleaudio-stdio.c FSK_SRC = fsk.h fsk.c diff --git a/src/minimodem.c b/src/minimodem.c index af96c70..318c433 100644 --- a/src/minimodem.c +++ b/src/minimodem.c @@ -404,6 +404,7 @@ usage() " -5, --baudot Baudot 5-N-1\n" " -u, --usos {0|1}\n" " -f, --file {filename.flac}\n" + " -O, --stdio\n" " -b, --bandwidth {rx_bandwidth}\n" " -v, --volume {amplitude or 'E'}\n" " -M, --mark {mark_freq}\n" @@ -555,8 +556,8 @@ main( int argc, char*argv[] ) /* validate the default system audio mechanism */ #if !(USE_SNDIO || USE_PULSEAUDIO || USE_ALSA) # define _MINIMODEM_NO_SYSTEM_AUDIO -# if !USE_SNDFILE -# error At least one of {USE_SNDIO,USE_PULSEAUDIO,USE_ALSA,USE_SNDFILE} must be enabled! +# if !(USE_SNDFILE || USE_STDIO) +# error At least one of {USE_SNDIO,USE_PULSEAUDIO,USE_ALSA,USE_SNDFILE,USE_STDIO} must be enabled! # endif #endif @@ -607,6 +608,7 @@ main( int argc, char*argv[] ) { "usos", 1, 0, 'u' }, { "msb-first", 0, 0, MINIMODEM_OPT_MSBFIRST }, { "file", 1, 0, 'f' }, + { "stdio", 0, 0, 'O' }, { "bandwidth", 1, 0, 'b' }, { "volume", 1, 0, 'v' }, { "mark", 1, 0, 'M' }, @@ -631,7 +633,7 @@ main( int argc, char*argv[] ) { "tx-carrier", 0, 0, MINIMODEM_OPT_TXCARRIER }, { 0 } }; - c = getopt_long(argc, argv, "Vtrc:l:ai875u:f:b:v:M:S:T:qs::A::R:", + c = getopt_long(argc, argv, "Vtrc:l:ai875u:f:Ob:v:M:S:T:qs::A::R:", long_options, &option_index); if ( c == -1 ) break; @@ -664,6 +666,16 @@ main( int argc, char*argv[] ) case 'f': filename = optarg; break; + case 'O': +#if USE_STDIO + sa_backend = SA_BACKEND_STDIO; + // Apparently the receiver wants floats, so I'mma just output floats + sample_format = SA_SAMPLE_FORMAT_FLOAT; +#else + fprintf(stderr, "E: This build of minimodem was configured without stdio support.\n"); + exit(1); +#endif + break; case '8': bfsk_n_data_bits = 8; break; diff --git a/src/simpleaudio-stdio.c b/src/simpleaudio-stdio.c new file mode 100644 index 0000000..ee476da --- /dev/null +++ b/src/simpleaudio-stdio.c @@ -0,0 +1,129 @@ +/* + * simpleaudio-stdfile.c + * + * Copyright (C) 2011-2020 Kamal Mostafa + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#if USE_STDIO + +#include +#include +#include +#include + +#include "simpleaudio.h" +#include "simpleaudio_internal.h" + + +/* + * stdio backend for simpleaudio + */ + +static ssize_t +sa_stdio_read( simpleaudio *sa, void *buf, size_t nframes ) +{ + int n; + switch ( sa->format ) { + case SA_SAMPLE_FORMAT_FLOAT: + n = fread(buf, 4, nframes, stdin); + break; + case SA_SAMPLE_FORMAT_S16: + n = fread(buf, 2, nframes, stdin); + break; + default: + assert(0); + break; + } + if ( n < 0 ) { + fprintf(stderr, "read error"); + return -1; + } + + if ( sa->rxnoise != 0.0f ) { + int i; + float *fbuf = buf; + float f = sa->rxnoise * 2; + for ( i=0; iformat ) { + case SA_SAMPLE_FORMAT_FLOAT: + n = fwrite(buf, 4, nframes, stdout); + break; + case SA_SAMPLE_FORMAT_S16: + n = fwrite(buf, 2, nframes, stdout); + break; + default: + assert(0); + break; + } + if ( n < 0 ) { + fprintf(stderr, "write error"); + return -1; + } + return n; +} + + +static void +sa_stdio_close( simpleaudio *sa ) +{ + // This is probably safe even when reading, right? + fflush(stdout); +} + +static int +sa_stdio_open_stream( + simpleaudio *sa, + const char *backend_device, + sa_direction_t sa_stream_direction, + sa_format_t sa_format, + unsigned int rate, unsigned int channels, + char *app_name, char *stream_name ) +{ + /* good or bad to override these? */ + sa->rate = rate; + sa->channels = channels; + + sa->backend_handle = NULL; + sa->backend_framesize = sa->channels * sa->samplesize; + + return 1; +} + + +const struct simpleaudio_backend simpleaudio_backend_stdio = { + sa_stdio_open_stream, + sa_stdio_read, + sa_stdio_write, + sa_stdio_close, +}; + +#endif /* USE_STDIO */ diff --git a/src/simpleaudio.c b/src/simpleaudio.c index 62286a0..4dd9290 100644 --- a/src/simpleaudio.c +++ b/src/simpleaudio.c @@ -74,6 +74,12 @@ simpleaudio_open_stream( break; #endif +#if USE_STDIO + case SA_BACKEND_STDIO: + sa->backend = &simpleaudio_backend_stdio; + break; +#endif + #if USE_BENCHMARKS case SA_BACKEND_BENCHMARK: sa->backend = &simpleaudio_backend_benchmark; diff --git a/src/simpleaudio.h b/src/simpleaudio.h index a9165ab..b363216 100644 --- a/src/simpleaudio.h +++ b/src/simpleaudio.h @@ -35,6 +35,7 @@ typedef struct simpleaudio simpleaudio; typedef enum { SA_BACKEND_SYSDEFAULT=0, SA_BACKEND_FILE, + SA_BACKEND_STDIO, SA_BACKEND_BENCHMARK, SA_BACKEND_ALSA, SA_BACKEND_PULSEAUDIO, diff --git a/src/simpleaudio_internal.h b/src/simpleaudio_internal.h index b9adfb7..e7fb6c8 100644 --- a/src/simpleaudio_internal.h +++ b/src/simpleaudio_internal.h @@ -61,6 +61,7 @@ struct simpleaudio_backend { extern const struct simpleaudio_backend simpleaudio_backend_benchmark; extern const struct simpleaudio_backend simpleaudio_backend_sndfile; +extern const struct simpleaudio_backend simpleaudio_backend_stdio; extern const struct simpleaudio_backend simpleaudio_backend_alsa; extern const struct simpleaudio_backend simpleaudio_backend_pulseaudio; extern const struct simpleaudio_backend simpleaudio_backend_sndio;