formats: clarify setting of reverse_bytes
[sox.git] / src / pulseaudio.c
blob76589477d2132d46b864afaaebf96f120235f8cf
1 /* Pulse Audio sound handler
3 * Copyright 2008 Chris Bagwell And Sundry Contributors
4 */
6 #include "sox_i.h"
8 #include <pulse/simple.h>
9 #include <pulse/error.h>
11 typedef struct {
12 pa_simple *pasp;
13 } priv_t;
15 static int setup(sox_format_t *ft, int is_input)
17 priv_t *pa = (priv_t *)ft->priv;
18 char *server;
19 pa_stream_direction_t dir;
20 char *app_str;
21 char *dev;
22 pa_sample_spec spec;
23 int error;
25 /* TODO: If user specified device of type "server:dev" then
26 * break up and override server.
28 server = NULL;
30 if (is_input)
32 dir = PA_STREAM_RECORD;
33 app_str = "record";
35 else
37 dir = PA_STREAM_PLAYBACK;
38 app_str = "playback";
41 if (strncmp(ft->filename, "default", (size_t)7) == 0)
42 dev = NULL;
43 else
44 dev = ft->filename;
46 /* If user doesn't specify, default to some reasonable values.
47 * Since this is mainly for recording case, default to typical
48 * 16-bit values to prevent saving larger files then average user
49 * wants. Power users can override to 32-bit if they wish.
51 if (ft->signal.channels == 0)
52 ft->signal.channels = 2;
53 if (ft->signal.rate == 0)
54 ft->signal.rate = 44100;
55 if (ft->encoding.bits_per_sample == 0)
57 ft->encoding.bits_per_sample = 16;
58 ft->encoding.encoding = SOX_ENCODING_SIGN2;
61 spec.format = PA_SAMPLE_S32NE;
62 spec.rate = ft->signal.rate;
63 spec.channels = ft->signal.channels;
65 pa->pasp = pa_simple_new(server, "SoX", dir, dev, app_str, &spec,
66 NULL, NULL, &error);
68 if (pa->pasp == NULL)
70 lsx_fail_errno(ft, SOX_EPERM, "can not open audio device: %s", pa_strerror(error));
71 return SOX_EOF;
74 /* TODO: Is it better to convert format/rates in SoX or in
75 * always let Pulse Audio do it? Since we don't know what
76 * hardware prefers, assume it knows best and give it
77 * what user specifies.
80 return SOX_SUCCESS;
83 static int startread(sox_format_t *ft)
85 return setup(ft, 1);
88 static int stopread(sox_format_t * ft)
90 priv_t *pa = (priv_t *)ft->priv;
92 pa_simple_free(pa->pasp);
94 return SOX_SUCCESS;
97 static size_t read_samples(sox_format_t *ft, sox_sample_t *buf, size_t nsamp)
99 priv_t *pa = (priv_t *)ft->priv;
100 size_t len;
101 int rc, error;
103 /* Pulse Audio buffer lengths are true buffer lengths and not
104 * count of samples. */
105 len = nsamp * sizeof(sox_sample_t);
107 rc = pa_simple_read(pa->pasp, buf, len, &error);
109 if (rc < 0)
111 lsx_fail_errno(ft, SOX_EPERM, "error reading from pulse audio device: %s", pa_strerror(error));
112 return SOX_EOF;
114 else
115 return nsamp;
118 static int startwrite(sox_format_t * ft)
120 return setup(ft, 0);
123 static size_t write_samples(sox_format_t *ft, const sox_sample_t *buf, size_t nsamp)
125 priv_t *pa = (priv_t *)ft->priv;
126 size_t len;
127 int rc, error;
129 if (!nsamp)
130 return 0;
132 /* Pulse Audio buffer lengths are true buffer lengths and not
133 * count of samples. */
134 len = nsamp * sizeof(sox_sample_t);
136 rc = pa_simple_write(pa->pasp, buf, len, &error);
138 if (rc < 0)
140 lsx_fail_errno(ft, SOX_EPERM, "error writing to pulse audio device: %s", pa_strerror(error));
141 return SOX_EOF;
144 return nsamp;
147 static int stopwrite(sox_format_t * ft)
149 priv_t *pa = (priv_t *)ft->priv;
150 int error;
152 pa_simple_drain(pa->pasp, &error);
153 pa_simple_free(pa->pasp);
155 return SOX_SUCCESS;
158 LSX_FORMAT_HANDLER(pulseaudio)
160 static char const *const names[] = { "pulseaudio", NULL };
161 static unsigned const write_encodings[] = {
162 SOX_ENCODING_SIGN2, 32, 0,
164 static sox_format_handler_t const handler = {SOX_LIB_VERSION_CODE,
165 "Pulse Audio client",
166 names, SOX_FILE_DEVICE | SOX_FILE_NOSTDIO,
167 startread, read_samples, stopread,
168 startwrite, write_samples, stopwrite,
169 NULL, write_encodings, NULL, sizeof(priv_t)
171 return &handler;