simpleaudio: pulseaudio and libsndfile backends

This commit is contained in:
Kamal Mostafa 2011-05-29 22:20:28 -07:00
parent bc9c6234c7
commit fe4b47af20
7 changed files with 282 additions and 3 deletions

View File

@ -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

View File

@ -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@

90
src/simpleaudio-pulse.c Normal file
View File

@ -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;
}

74
src/simpleaudio-sndfile.c Normal file
View File

@ -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;
}

28
src/simpleaudio.c Normal file
View File

@ -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);
}

40
src/simpleaudio.h Normal file
View File

@ -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

View File

@ -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