mirror of
https://github.com/DrBeef/QuestZDoom.git
synced 2025-05-05 07:21:28 +00:00
169 lines
3.7 KiB
C
169 lines
3.7 KiB
C
/* Pulse Audio sound handler
|
|
*
|
|
* Copyright 2008 Chris Bagwell And Sundry Contributors
|
|
*/
|
|
|
|
#include "sox_i.h"
|
|
|
|
#include <pulse/simple.h>
|
|
#include <pulse/error.h>
|
|
|
|
typedef struct {
|
|
pa_simple *pasp;
|
|
} priv_t;
|
|
|
|
static int setup(sox_format_t *ft, int is_input)
|
|
{
|
|
priv_t *pa = (priv_t *)ft->priv;
|
|
char *server;
|
|
pa_stream_direction_t dir;
|
|
char *app_str;
|
|
char *dev;
|
|
pa_sample_spec spec;
|
|
int error;
|
|
|
|
/* TODO: If user specified device of type "server:dev" then
|
|
* break up and override server.
|
|
*/
|
|
server = NULL;
|
|
|
|
if (is_input)
|
|
{
|
|
dir = PA_STREAM_RECORD;
|
|
app_str = "record";
|
|
}
|
|
else
|
|
{
|
|
dir = PA_STREAM_PLAYBACK;
|
|
app_str = "playback";
|
|
}
|
|
|
|
if (strncmp(ft->filename, "default", (size_t)7) == 0)
|
|
dev = NULL;
|
|
else
|
|
dev = ft->filename;
|
|
|
|
/* If user doesn't specify, default to some reasonable values.
|
|
* Since this is mainly for recording case, default to typical
|
|
* 16-bit values to prevent saving larger files then average user
|
|
* wants. Power users can override to 32-bit if they wish.
|
|
*/
|
|
if (ft->signal.channels == 0)
|
|
ft->signal.channels = 2;
|
|
if (ft->signal.rate == 0)
|
|
ft->signal.rate = 44100;
|
|
if (ft->encoding.bits_per_sample == 0)
|
|
{
|
|
ft->encoding.bits_per_sample = 16;
|
|
ft->encoding.encoding = SOX_ENCODING_SIGN2;
|
|
}
|
|
|
|
spec.format = PA_SAMPLE_S32NE;
|
|
spec.rate = ft->signal.rate;
|
|
spec.channels = ft->signal.channels;
|
|
|
|
pa->pasp = pa_simple_new(server, "SoX", dir, dev, app_str, &spec,
|
|
NULL, NULL, &error);
|
|
|
|
if (pa->pasp == NULL)
|
|
{
|
|
lsx_fail_errno(ft, SOX_EPERM, "can not open audio device: %s", pa_strerror(error));
|
|
return SOX_EOF;
|
|
}
|
|
|
|
/* TODO: Is it better to convert format/rates in SoX or in
|
|
* always let Pulse Audio do it? Since we don't know what
|
|
* hardware prefers, assume it knows best and give it
|
|
* what user specifies.
|
|
*/
|
|
|
|
return SOX_SUCCESS;
|
|
}
|
|
|
|
static int startread(sox_format_t *ft)
|
|
{
|
|
return setup(ft, 1);
|
|
}
|
|
|
|
static int stopread(sox_format_t * ft)
|
|
{
|
|
priv_t *pa = (priv_t *)ft->priv;
|
|
|
|
pa_simple_free(pa->pasp);
|
|
|
|
return SOX_SUCCESS;
|
|
}
|
|
|
|
static size_t read_samples(sox_format_t *ft, sox_sample_t *buf, size_t nsamp)
|
|
{
|
|
priv_t *pa = (priv_t *)ft->priv;
|
|
size_t len;
|
|
int rc, error;
|
|
|
|
/* Pulse Audio buffer lengths are true buffer lengths and not
|
|
* count of samples. */
|
|
len = nsamp * sizeof(sox_sample_t);
|
|
|
|
rc = pa_simple_read(pa->pasp, buf, len, &error);
|
|
|
|
if (rc < 0)
|
|
{
|
|
lsx_fail_errno(ft, SOX_EPERM, "error reading from pulse audio device: %s", pa_strerror(error));
|
|
return SOX_EOF;
|
|
}
|
|
else
|
|
return nsamp;
|
|
}
|
|
|
|
static int startwrite(sox_format_t * ft)
|
|
{
|
|
return setup(ft, 0);
|
|
}
|
|
|
|
static size_t write_samples(sox_format_t *ft, const sox_sample_t *buf, size_t nsamp)
|
|
{
|
|
priv_t *pa = (priv_t *)ft->priv;
|
|
size_t len;
|
|
int rc, error;
|
|
|
|
/* Pulse Audio buffer lengths are true buffer lengths and not
|
|
* count of samples. */
|
|
len = nsamp * sizeof(sox_sample_t);
|
|
|
|
rc = pa_simple_write(pa->pasp, buf, len, &error);
|
|
|
|
if (rc < 0)
|
|
{
|
|
lsx_fail_errno(ft, SOX_EPERM, "error writing to pulse audio device: %s", pa_strerror(error));
|
|
return SOX_EOF;
|
|
}
|
|
|
|
return nsamp;
|
|
}
|
|
|
|
static int stopwrite(sox_format_t * ft)
|
|
{
|
|
priv_t *pa = (priv_t *)ft->priv;
|
|
int error;
|
|
|
|
pa_simple_drain(pa->pasp, &error);
|
|
pa_simple_free(pa->pasp);
|
|
|
|
return SOX_SUCCESS;
|
|
}
|
|
|
|
LSX_FORMAT_HANDLER(pulseaudio)
|
|
{
|
|
static char const *const names[] = { "pulseaudio", NULL };
|
|
static unsigned const write_encodings[] = {
|
|
SOX_ENCODING_SIGN2, 32, 0,
|
|
0};
|
|
static sox_format_handler_t const handler = {SOX_LIB_VERSION_CODE,
|
|
"Pulse Audio client",
|
|
names, SOX_FILE_DEVICE | SOX_FILE_NOSTDIO,
|
|
startread, read_samples, stopread,
|
|
startwrite, write_samples, stopwrite,
|
|
NULL, write_encodings, NULL, sizeof(priv_t)
|
|
};
|
|
return &handler;
|
|
}
|