Implement sndio backend

This commit is contained in:
José Miguel Sánchez García 2018-01-27 00:06:11 +00:00
parent 9a1e8769ab
commit 947d2db4b8
8 changed files with 169 additions and 4 deletions

View File

@ -39,6 +39,19 @@ AS_IF([test "x$with_pulseaudio" == "xno"], [
AC_DEFINE_UNQUOTED([USE_PULSEAUDIO], [$use_pulseaudio],
[Define to 1 to enable pulseaudio support])
# sndio
AC_ARG_WITH([sndio], AS_HELP_STRING([--without-sndio],
[build without sndio support]))
AS_IF([test "x$with_sndio" == "xno"], [
use_sndio=0
], [
use_sndio=1
AC_LANG_PUSH(C)
AC_CHECK_LIB(sndio, sio_start)
])
AC_DEFINE_UNQUOTED([USE_SNDIO], [$use_sndio],
[Define to 1 to enable sndio support])
# sndfile
AC_ARG_WITH([sndfile], AS_HELP_STRING([--without-sndfile],
[build without sndfile support]))
@ -68,6 +81,7 @@ option summary:
benchmarks $with_benchmarks ($use_benchmarks)
pulseaudio $with_pulseaudio ($use_pulseaudio)
sndfile $with_sndfile ($use_sndfile)
sndio $with_sndio ($use_sndio)
])
# Checks for libraries.

View File

@ -35,6 +35,7 @@ SIMPLEAUDIO_SRC = \
simple-tone-generator.c \
simpleaudio-pulse.c \
simpleaudio-alsa.c \
simpleaudio-sndio.c \
simpleaudio-benchmark.c \
simpleaudio-sndfile.c

View File

@ -157,6 +157,10 @@ device alias "default" is used, if a specific device is not specified.
For example, the following options all select ALSA device #1, sub-device #0:
\-\-alsa=plughw:1,0 \-\-alsa=1,0 \-A1
.TP
.B \-s, \-\-sndio[=device]
Use sndio as the audio output system. The default device is used if no
device is not specified.
.TP
.B \-\-lut={tx_sin_table_len}
Minimodem uses a precomputed sine wave lookup table of 1024 elements,
or the size specified here. Use \-\-lut=0 to disable the use of

View File

@ -414,6 +414,7 @@ usage()
" -R, --samplerate {rate}\n"
" -V, --version\n"
" -A, --alsa[=plughw:X,Y]\n"
" -s, --sndio[=device]\n"
" --lut={tx_sin_table_len}\n"
" --float-samples\n"
" --rx-one\n"
@ -550,10 +551,10 @@ main( int argc, char*argv[] )
bfsk_databits_encode = databits_encode_ascii8;
/* validate the default system audio mechanism */
#if !(USE_PULSEAUDIO || USE_ALSA)
#if !(USE_SNDIO || USE_PULSEAUDIO || USE_ALSA)
# define _MINIMODEM_NO_SYSTEM_AUDIO
# if !USE_SNDFILE
# error At least one of {USE_PULSEAUDIO,USE_ALSA,USE_SNDFILE} must be enabled!
# error At least one of {USE_SNDIO,USE_PULSEAUDIO,USE_ALSA,USE_SNDFILE} must be enabled!
# endif
#endif
@ -613,6 +614,7 @@ main( int argc, char*argv[] )
{ "sync-byte", 1, 0, MINIMODEM_OPT_SYNC_BYTE },
{ "quiet", 0, 0, 'q' },
{ "alsa", 2, 0, 'A' },
{ "sndio", 2, 0, 's' },
{ "samplerate", 1, 0, 'R' },
{ "lut", 1, 0, MINIMODEM_OPT_LUT },
{ "float-samples", 0, 0, MINIMODEM_OPT_FLOAT_SAMPLES },
@ -626,7 +628,7 @@ main( int argc, char*argv[] )
{ "tx-carrier", 0, 0, MINIMODEM_OPT_TXCARRIER },
{ 0 }
};
c = getopt_long(argc, argv, "Vtrc:l:ai875f:b:v:M:S:T:qA::R:",
c = getopt_long(argc, argv, "Vtrc:l:ai875f:b:v:M:S:T:qs::A::R:",
long_options, &option_index);
if ( c == -1 )
break;
@ -725,6 +727,16 @@ main( int argc, char*argv[] )
#else
fprintf(stderr, "E: This build of minimodem was configured without alsa support.\n");
exit(1);
#endif
break;
case 's':
#if USE_SNDIO
sa_backend = SA_BACKEND_SNDIO;
if ( optarg )
sa_backend_device = optarg;
#else
fprintf(stderr, "E: This build of minimodem was configured without sndio support.\n");
exit(1);
#endif
break;
case MINIMODEM_OPT_LUT:

124
src/simpleaudio-sndio.c Normal file
View File

@ -0,0 +1,124 @@
/*
* simpleaudio-sndio.c
*
* Copyright (C) 2011-2012 Kamal Mostafa <kamal@whence.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#if USE_SNDIO
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <sndio.h>
#include "simpleaudio.h"
#include "simpleaudio_internal.h"
/*
* sndio backend for simpleaudio
*/
static ssize_t
sa_sndio_read( simpleaudio *sa, void *buf, size_t nframes )
{
size_t nbytes = nframes * sa->backend_framesize;
sio_read((struct sio_hdl *)sa->backend_handle, buf, nbytes);
return nframes;
}
static ssize_t
sa_sndio_write( simpleaudio *sa, void *buf, size_t nframes )
{
size_t nbytes = nframes * sa->backend_framesize;
sio_write((struct sio_hdl *)sa->backend_handle, buf, nbytes);
return nframes;
}
static void
sa_sndio_close( simpleaudio *sa )
{
sio_stop(sa->backend_handle);
}
static int
sa_sndio_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 )
{
struct sio_hdl *hdl;
struct sio_par par;
const char *be_device;
if ( ! backend_device )
be_device = SIO_DEVANY;
else
be_device = backend_device;
hdl = sio_open(
be_device,
sa_stream_direction == SA_STREAM_RECORD ? SIO_REC : SIO_PLAY,
0 /* nbio_flag */);
sio_initpar(&par);
switch ( sa->format ) {
case SA_SAMPLE_FORMAT_S16:
par.bits = 16;
par.sig = 1;
par.le = SIO_LE_NATIVE;
par.rate = rate;
par.xrun = SIO_IGNORE;
if ( SA_STREAM_RECORD )
par.rchan = channels;
else
par.pchan = channels;
break;
default:
assert(0);
}
par.bps = SIO_BPS(par.bits);
sio_setpar(hdl, &par);
sio_start(hdl);
sa->backend_handle = hdl;
sa->backend_framesize = sa->channels * sa->samplesize;
return 1;
}
const struct simpleaudio_backend simpleaudio_backend_sndio = {
sa_sndio_open_stream,
sa_sndio_read,
sa_sndio_write,
sa_sndio_close,
};
#endif /* USE_SNDIO */

View File

@ -80,7 +80,9 @@ simpleaudio_open_stream(
#endif
case SA_BACKEND_SYSDEFAULT:
#if USE_PULSEAUDIO
#if USE_SNDIO
sa->backend = &simpleaudio_backend_sndio;
#elif USE_PULSEAUDIO
sa->backend = &simpleaudio_backend_pulseaudio;
#elif USE_ALSA
sa->backend = &simpleaudio_backend_alsa;
@ -102,6 +104,12 @@ simpleaudio_open_stream(
break;
#endif
#if USE_SNDIO
case SA_BACKEND_SNDIO:
sa->backend = &simpleaudio_backend_sndio;
break;
#endif
default:
fprintf(stderr, "simpleaudio_open_stream: no such sa_backend (%d). not configured at build?\n", sa_backend);
goto err_out;

View File

@ -38,6 +38,7 @@ typedef enum {
SA_BACKEND_BENCHMARK,
SA_BACKEND_ALSA,
SA_BACKEND_PULSEAUDIO,
SA_BACKEND_SNDIO,
} sa_backend_t;
/* sa_stream_direction */

View File

@ -63,5 +63,6 @@ extern const struct simpleaudio_backend simpleaudio_backend_benchmark;
extern const struct simpleaudio_backend simpleaudio_backend_sndfile;
extern const struct simpleaudio_backend simpleaudio_backend_alsa;
extern const struct simpleaudio_backend simpleaudio_backend_pulseaudio;
extern const struct simpleaudio_backend simpleaudio_backend_sndio;
#endif