simpleaudio: pulseaudio and libsndfile backends
This commit is contained in:
parent
bc9c6234c7
commit
fe4b47af20
|
@ -5,8 +5,13 @@ INCLUDES = $(DEPS_CFLAGS)
|
|||
|
||||
bin_PROGRAMS = minimodem tscope
|
||||
|
||||
SIMPLEAUDIO_SRC=\
|
||||
simpleaudio.c \
|
||||
simpleaudio-pulse.c \
|
||||
simpleaudio-sndfile.c
|
||||
|
||||
minimodem_LDADD = $(DEPS_LIBS)
|
||||
minimodem_SOURCES = minimodem.c tscope_print.c
|
||||
minimodem_SOURCES = minimodem.c tscope_print.c $(SIMPLEAUDIO_SRC)
|
||||
|
||||
tscope_LDADD = $(DEPS_LIBS)
|
||||
tscope_SOURCES = tscope.c tscope_print.c
|
||||
|
|
|
@ -45,7 +45,10 @@ CONFIG_CLEAN_FILES =
|
|||
CONFIG_CLEAN_VPATH_FILES =
|
||||
am__installdirs = "$(DESTDIR)$(bindir)"
|
||||
PROGRAMS = $(bin_PROGRAMS)
|
||||
am_minimodem_OBJECTS = minimodem.$(OBJEXT) tscope_print.$(OBJEXT)
|
||||
am__objects_1 = simpleaudio.$(OBJEXT) simpleaudio-pulse.$(OBJEXT) \
|
||||
simpleaudio-sndfile.$(OBJEXT)
|
||||
am_minimodem_OBJECTS = minimodem.$(OBJEXT) tscope_print.$(OBJEXT) \
|
||||
$(am__objects_1)
|
||||
minimodem_OBJECTS = $(am_minimodem_OBJECTS)
|
||||
am__DEPENDENCIES_1 =
|
||||
minimodem_DEPENDENCIES = $(am__DEPENDENCIES_1)
|
||||
|
@ -155,8 +158,13 @@ top_builddir = @top_builddir@
|
|||
top_srcdir = @top_srcdir@
|
||||
AM_CFLAGS = -Wall -Werror
|
||||
INCLUDES = $(DEPS_CFLAGS)
|
||||
SIMPLEAUDIO_SRC = \
|
||||
simpleaudio.c \
|
||||
simpleaudio-pulse.c \
|
||||
simpleaudio-sndfile.c
|
||||
|
||||
minimodem_LDADD = $(DEPS_LIBS)
|
||||
minimodem_SOURCES = minimodem.c tscope_print.c
|
||||
minimodem_SOURCES = minimodem.c tscope_print.c $(SIMPLEAUDIO_SRC)
|
||||
tscope_LDADD = $(DEPS_LIBS)
|
||||
tscope_SOURCES = tscope.c tscope_print.c
|
||||
all: all-am
|
||||
|
@ -244,6 +252,9 @@ distclean-compile:
|
|||
-rm -f *.tab.c
|
||||
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/minimodem.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simpleaudio-pulse.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simpleaudio-sndfile.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simpleaudio.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tscope.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tscope_print.Po@am__quote@
|
||||
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <malloc.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <pulse/simple.h>
|
||||
#include <pulse/error.h>
|
||||
#include <pulse/gccmacro.h>
|
||||
|
||||
#include "simpleaudio.h"
|
||||
#include "simpleaudio_internal.h"
|
||||
|
||||
|
||||
/*
|
||||
* pulseaudio[pa_simple] backend for simpleaudio
|
||||
*/
|
||||
|
||||
|
||||
static size_t
|
||||
sa_pulse_read( simpleaudio *sa, float *buf, size_t nframes )
|
||||
{
|
||||
int error;
|
||||
pa_simple *s = (pa_simple *)sa->backend_handle;
|
||||
size_t nbytes = nframes * sa->backend_framesize;
|
||||
int n;
|
||||
if ((n = pa_simple_read(s, buf, nbytes, &error)) < 0) {
|
||||
fprintf(stderr, "pa_simple_read: %s\n", pa_strerror(error));
|
||||
return -1;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sa_pulse_close( simpleaudio *sa )
|
||||
{
|
||||
pa_simple_free(sa->backend_handle);
|
||||
}
|
||||
|
||||
|
||||
static const struct simpleaudio_backend simpleaudio_backend_pulse = {
|
||||
sa_pulse_read,
|
||||
sa_pulse_close,
|
||||
};
|
||||
|
||||
simpleaudio *
|
||||
simpleaudio_open_source_pulseaudio(
|
||||
// unsigned int rate, unsigned int channels,
|
||||
char *app_name, char *stream_name )
|
||||
{
|
||||
int error;
|
||||
|
||||
// FIXME - use source for something
|
||||
// just take the default pulseaudio source for now
|
||||
|
||||
/* The sample type to use */
|
||||
pa_sample_spec ss = {
|
||||
.format = PA_SAMPLE_FLOAT32,
|
||||
// .rate = rate,
|
||||
.rate = 48000,
|
||||
// .channels = channels,
|
||||
.channels = 1,
|
||||
};
|
||||
|
||||
/* Create the recording stream */
|
||||
pa_simple *s;
|
||||
s = pa_simple_new(NULL, app_name, PA_STREAM_RECORD, NULL, stream_name,
|
||||
&ss, NULL, NULL, &error);
|
||||
if ( !s ) {
|
||||
fprintf(stderr, "pa_simple_new: %s\n", pa_strerror(error));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
simpleaudio *sa = malloc(sizeof(simpleaudio));
|
||||
if ( !sa ) {
|
||||
perror("malloc");
|
||||
pa_simple_free(s);
|
||||
return NULL;
|
||||
}
|
||||
sa->rate = ss.rate;
|
||||
sa->channels = ss.channels;
|
||||
sa->backend = &simpleaudio_backend_pulse;
|
||||
sa->backend_handle = s;
|
||||
sa->backend_framesize = pa_frame_size(&ss);
|
||||
|
||||
assert( sa->backend_framesize == ss.channels * sizeof(float) );
|
||||
|
||||
return sa;
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <malloc.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <sndfile.h>
|
||||
|
||||
#include "simpleaudio.h"
|
||||
#include "simpleaudio_internal.h"
|
||||
|
||||
|
||||
/*
|
||||
* sndfile backend for simpleaudio
|
||||
*/
|
||||
|
||||
|
||||
static size_t
|
||||
sa_sndfile_read( simpleaudio *sa, float *buf, size_t nframes )
|
||||
{
|
||||
SNDFILE *s = (SNDFILE *)sa->backend_handle;
|
||||
int n;
|
||||
if ((n = sf_readf_float(s, buf, nframes)) < 0) {
|
||||
fprintf(stderr, "sf_read_float: ");
|
||||
sf_perror(s);
|
||||
return -1;
|
||||
}
|
||||
//fprintf(stderr, "sf_read_float: nframes=%ld n=%d\n", nframes, n);
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sa_sndfile_close( simpleaudio *sa )
|
||||
{
|
||||
sf_close(sa->backend_handle);
|
||||
}
|
||||
|
||||
|
||||
static const struct simpleaudio_backend simpleaudio_backend_pulse = {
|
||||
sa_sndfile_read,
|
||||
sa_sndfile_close,
|
||||
};
|
||||
|
||||
simpleaudio *
|
||||
simpleaudio_open_source_sndfile(char *path)
|
||||
{
|
||||
SF_INFO sfinfo = {
|
||||
.format = 0
|
||||
};
|
||||
|
||||
/* Create the recording stream */
|
||||
SNDFILE *s;
|
||||
s = sf_open(path, SFM_READ, &sfinfo);
|
||||
if ( !s ) {
|
||||
fprintf(stderr, "%s: ", path);
|
||||
sf_perror(s);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
simpleaudio *sa = malloc(sizeof(simpleaudio));
|
||||
if ( !sa ) {
|
||||
perror("malloc");
|
||||
sf_close(s);
|
||||
return NULL;
|
||||
}
|
||||
sa->rate = sfinfo.samplerate;
|
||||
sa->channels = sfinfo.channels;
|
||||
sa->backend = &simpleaudio_backend_pulse;
|
||||
sa->backend_handle = s;
|
||||
sa->backend_framesize = sa->channels * sizeof(float);
|
||||
|
||||
return sa;
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
#include "simpleaudio.h"
|
||||
#include "simpleaudio_internal.h"
|
||||
#include "malloc.h"
|
||||
|
||||
unsigned int
|
||||
simpleaudio_get_rate( simpleaudio *sa )
|
||||
{
|
||||
return sa->rate;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
simpleaudio_get_channels( simpleaudio *sa )
|
||||
{
|
||||
return sa->channels;
|
||||
}
|
||||
|
||||
size_t
|
||||
simpleaudio_read( simpleaudio *sa, float *buf, size_t nframes )
|
||||
{
|
||||
return sa->backend->simpleaudio_read(sa, buf, nframes);
|
||||
}
|
||||
|
||||
void
|
||||
simpleaudio_close( simpleaudio *sa )
|
||||
{
|
||||
sa->backend->simpleaudio_close(sa);
|
||||
free(sa);
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
#ifndef SIMPLEAUDIO_H
|
||||
#define SIMPLEAUDIO_H
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
struct simpleaudio;
|
||||
typedef struct simpleaudio simpleaudio;
|
||||
|
||||
/*
|
||||
* simpleaudio_open_source_XXXX() routines which return a (simpleaudio *)
|
||||
* are provided by the separate backend modules.
|
||||
*
|
||||
*/
|
||||
|
||||
simpleaudio *
|
||||
simpleaudio_open_source_pulseaudio(
|
||||
// unsigned int rate, unsigned int channels,
|
||||
char *app_name, char *stream_name );
|
||||
|
||||
simpleaudio *
|
||||
simpleaudio_open_source_sndfile(char *path);
|
||||
|
||||
/*
|
||||
* common simpleaudio_ API routines available to any backend:
|
||||
*/
|
||||
|
||||
unsigned int
|
||||
simpleaudio_get_rate( simpleaudio *sa );
|
||||
|
||||
unsigned int
|
||||
simpleaudio_get_channels( simpleaudio *sa );
|
||||
|
||||
size_t
|
||||
simpleaudio_read( simpleaudio *sa, float *buf, size_t nframes );
|
||||
|
||||
void
|
||||
simpleaudio_close( simpleaudio *sa );
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,31 @@
|
|||
#ifndef SIMPLEAUDIO_INTERNAL_H
|
||||
#define SIMPLEAUDIO_INTERNAL_H
|
||||
|
||||
|
||||
#include "simpleaudio.h"
|
||||
|
||||
/*
|
||||
* Backend modules must provide an "open" routine which returns a
|
||||
* (simpleaudio *) to the caller.
|
||||
*/
|
||||
|
||||
struct simpleaudio_backend;
|
||||
typedef struct simpleaudio_backend simpleaudio_backend;
|
||||
|
||||
struct simpleaudio {
|
||||
const struct simpleaudio_backend *backend;
|
||||
unsigned int rate;
|
||||
unsigned int channels;
|
||||
void * backend_handle;
|
||||
unsigned int backend_framesize;
|
||||
};
|
||||
|
||||
struct simpleaudio_backend {
|
||||
size_t
|
||||
(*simpleaudio_read)( simpleaudio *sa, float *buf, size_t nframes );
|
||||
void
|
||||
(*simpleaudio_close)( simpleaudio *sa );
|
||||
};
|
||||
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue