f7c69d6b4cd5d23f2593f2df7333c6957895b1ac
[profile/ivi/pulseaudio-panda.git] / polyp / protocol-simple.c
1 /* $Id$ */
2
3 /***
4   This file is part of polypaudio.
5  
6   polypaudio is free software; you can redistribute it and/or modify
7   it under the terms of the GNU Lesser General Public License as published
8   by the Free Software Foundation; either version 2 of the License,
9   or (at your option) any later version.
10  
11   polypaudio is distributed in the hope that it will be useful, but
12   WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14   General Public License for more details.
15  
16   You should have received a copy of the GNU Lesser General Public License
17   along with polypaudio; if not, write to the Free Software
18   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19   USA.
20 ***/
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <assert.h>
27 #include <stdlib.h>
28 #include <limits.h>
29 #include <stdio.h>
30 #include <errno.h>
31 #include <string.h>
32
33 #include "sink-input.h"
34 #include "source-output.h"
35 #include "protocol-simple.h"
36 #include "client.h"
37 #include "sample-util.h"
38 #include "namereg.h"
39 #include "xmalloc.h"
40 #include "log.h"
41
42 struct connection {
43     struct pa_protocol_simple *protocol;
44     struct pa_iochannel *io;
45     struct pa_sink_input *sink_input;
46     struct pa_source_output *source_output;
47     struct pa_client *client;
48     struct pa_memblockq *input_memblockq, *output_memblockq;
49     struct pa_defer_event *defer_event;
50
51     struct {
52         struct pa_memblock *current_memblock;
53         size_t memblock_index, fragment_size;
54     } playback;
55 };
56
57 struct pa_protocol_simple {
58     struct pa_module *module;
59     struct pa_core *core;
60     struct pa_socket_server*server;
61     struct pa_idxset *connections;
62     enum {
63         RECORD = 1,
64         PLAYBACK = 2,
65         DUPLEX = 3
66     } mode;
67     struct pa_sample_spec sample_spec;
68     char *source_name, *sink_name;
69 };
70
71 #define PLAYBACK_BUFFER_SECONDS (.5)
72 #define PLAYBACK_BUFFER_FRAGMENTS (10)
73 #define RECORD_BUFFER_SECONDS (5)
74 #define RECORD_BUFFER_FRAGMENTS (100)
75
76 static void connection_free(struct connection *c) {
77     assert(c);
78
79     pa_idxset_remove_by_data(c->protocol->connections, c, NULL);
80
81     if (c->playback.current_memblock)
82         pa_memblock_unref(c->playback.current_memblock);
83     if (c->sink_input) {
84         pa_sink_input_disconnect(c->sink_input);
85         pa_sink_input_unref(c->sink_input);
86     }
87     if (c->source_output) {
88         pa_source_output_disconnect(c->source_output);
89         pa_source_output_unref(c->source_output);
90     }
91     if (c->client)
92         pa_client_free(c->client);
93     if (c->io)
94         pa_iochannel_free(c->io);
95     if (c->input_memblockq)
96         pa_memblockq_free(c->input_memblockq);
97     if (c->output_memblockq)
98         pa_memblockq_free(c->output_memblockq);
99     if (c->defer_event)
100         c->protocol->core->mainloop->defer_free(c->defer_event);
101     pa_xfree(c);
102 }
103
104 static int do_read(struct connection *c) {
105     struct pa_memchunk chunk;
106     ssize_t r;
107     size_t l;
108
109     if (!c->sink_input || !(l = pa_memblockq_missing(c->input_memblockq)))
110         return 0;
111
112     if (l > c->playback.fragment_size)
113         l = c->playback.fragment_size;
114
115     if (c->playback.current_memblock) 
116         if (c->playback.current_memblock->length - c->playback.memblock_index < l) {
117             pa_memblock_unref(c->playback.current_memblock);
118             c->playback.current_memblock = NULL;
119             c->playback.memblock_index = 0;
120         }
121
122     if (!c->playback.current_memblock) {
123         c->playback.current_memblock = pa_memblock_new(c->playback.fragment_size*2, c->protocol->core->memblock_stat);
124         assert(c->playback.current_memblock && c->playback.current_memblock->length >= l);
125         c->playback.memblock_index = 0;
126     }
127     
128     if ((r = pa_iochannel_read(c->io, (uint8_t*) c->playback.current_memblock->data+c->playback.memblock_index, l)) <= 0) {
129         pa_log(__FILE__": read() failed: %s\n", r == 0 ? "EOF" : strerror(errno));
130         return -1;
131     }
132
133     chunk.memblock = c->playback.current_memblock;
134     chunk.index = c->playback.memblock_index;
135     chunk.length = r;
136     assert(chunk.memblock);
137
138     c->playback.memblock_index += r;
139     
140     assert(c->input_memblockq);
141     pa_memblockq_push_align(c->input_memblockq, &chunk, 0);
142     assert(c->sink_input);
143     pa_sink_notify(c->sink_input->sink);
144     
145     return 0;
146 }
147
148 static int do_write(struct connection *c) {
149     struct pa_memchunk chunk;
150     ssize_t r;
151
152     if (!c->source_output)
153         return 0;    
154
155     assert(c->output_memblockq);
156     if (pa_memblockq_peek(c->output_memblockq, &chunk) < 0)
157         return 0;
158     
159     assert(chunk.memblock && chunk.length);
160     
161     if ((r = pa_iochannel_write(c->io, (uint8_t*) chunk.memblock->data+chunk.index, chunk.length)) < 0) {
162         pa_memblock_unref(chunk.memblock);
163         pa_log(__FILE__": write(): %s\n", strerror(errno));
164         return -1;
165     }
166     
167     pa_memblockq_drop(c->output_memblockq, &chunk, r);
168     pa_memblock_unref(chunk.memblock);
169     
170     return 0;
171 }
172
173
174 static void do_work(struct connection *c) {
175     assert(c);
176
177     assert(c->protocol && c->protocol->core && c->protocol->core->mainloop && c->protocol->core->mainloop->defer_enable);
178     c->protocol->core->mainloop->defer_enable(c->defer_event, 0);
179
180     if (pa_iochannel_is_hungup(c->io))
181         goto fail;
182     
183     if (pa_iochannel_is_writable(c->io))
184         if (do_write(c) < 0)
185             goto fail;
186     
187     if (pa_iochannel_is_readable(c->io))
188         if (do_read(c) < 0)
189             goto fail;
190
191     return;
192
193 fail:
194     connection_free(c);
195 }
196
197 /*** sink_input callbacks ***/
198
199 static int sink_input_peek_cb(struct pa_sink_input *i, struct pa_memchunk *chunk) {
200     struct connection*c;
201     assert(i && i->userdata && chunk);
202     c = i->userdata;
203     
204     if (pa_memblockq_peek(c->input_memblockq, chunk) < 0)
205         return -1;
206
207     return 0;
208 }
209
210 static void sink_input_drop_cb(struct pa_sink_input *i, const struct pa_memchunk *chunk, size_t length) {
211     struct connection*c = i->userdata;
212     assert(i && c && length);
213
214     pa_memblockq_drop(c->input_memblockq, chunk, length);
215
216     /* do something */
217     assert(c->protocol && c->protocol->core && c->protocol->core->mainloop && c->protocol->core->mainloop->defer_enable);
218     c->protocol->core->mainloop->defer_enable(c->defer_event, 1);
219 }
220
221 static void sink_input_kill_cb(struct pa_sink_input *i) {
222     assert(i && i->userdata);
223     connection_free((struct connection *) i->userdata);
224 }
225
226
227 static pa_usec_t sink_input_get_latency_cb(struct pa_sink_input *i) {
228     struct connection*c = i->userdata;
229     assert(i && c);
230     return pa_bytes_to_usec(pa_memblockq_get_length(c->input_memblockq), &c->sink_input->sample_spec);
231 }
232
233 /*** source_output callbacks ***/
234
235 static void source_output_push_cb(struct pa_source_output *o, const struct pa_memchunk *chunk) {
236     struct connection *c = o->userdata;
237     assert(o && c && chunk);
238
239     pa_memblockq_push(c->output_memblockq, chunk, 0);
240
241     /* do something */
242     assert(c->protocol && c->protocol->core && c->protocol->core->mainloop && c->protocol->core->mainloop->defer_enable);
243     c->protocol->core->mainloop->defer_enable(c->defer_event, 1);
244 }
245
246 static void source_output_kill_cb(struct pa_source_output *o) {
247     assert(o && o->userdata);
248     connection_free((struct connection *) o->userdata);
249 }
250
251 static pa_usec_t source_output_get_latency_cb(struct pa_source_output *o) {
252     struct connection*c = o->userdata;
253     assert(o && c);
254     return pa_bytes_to_usec(pa_memblockq_get_length(c->output_memblockq), &c->source_output->sample_spec);
255 }
256
257 /*** client callbacks ***/
258
259 static void client_kill_cb(struct pa_client *c) {
260     assert(c && c->userdata);
261     connection_free((struct connection *) c->userdata);
262 }
263
264 /*** pa_iochannel callbacks ***/
265
266 static void io_callback(struct pa_iochannel*io, void *userdata) {
267     struct connection *c = userdata;
268     assert(io && c && c->io == io);
269
270     do_work(c);
271 }
272
273 /*** fixed callback ***/
274
275 static void defer_callback(struct pa_mainloop_api*a, struct pa_defer_event *e, void *userdata) {
276     struct connection *c = userdata;
277     assert(a && c && c->defer_event == e);
278
279     do_work(c);
280 }
281
282 /*** socket_server callbacks ***/
283
284 static void on_connection(struct pa_socket_server*s, struct pa_iochannel *io, void *userdata) {
285     struct pa_protocol_simple *p = userdata;
286     struct connection *c = NULL;
287     char cname[256];
288     assert(s && io && p);
289
290     c = pa_xmalloc(sizeof(struct connection));
291     c->io = io;
292     c->sink_input = NULL;
293     c->source_output = NULL;
294     c->defer_event = NULL;
295     c->input_memblockq = c->output_memblockq = NULL;
296     c->protocol = p;
297     c->playback.current_memblock = NULL;
298     c->playback.memblock_index = 0;
299     c->playback.fragment_size = 0;
300     
301     pa_iochannel_socket_peer_to_string(io, cname, sizeof(cname));
302     c->client = pa_client_new(p->core, "SIMPLE", cname);
303     assert(c->client);
304     c->client->owner = p->module;
305     c->client->kill = client_kill_cb;
306     c->client->userdata = c;
307
308     if (p->mode & PLAYBACK) {
309         struct pa_sink *sink;
310         size_t l;
311
312         if (!(sink = pa_namereg_get(p->core, p->sink_name, PA_NAMEREG_SINK, 1))) {
313             pa_log(__FILE__": Failed to get sink.\n");
314             goto fail;
315         }
316
317         if (!(c->sink_input = pa_sink_input_new(sink, c->client->name, &p->sample_spec, 0, -1))) {
318             pa_log(__FILE__": Failed to create sink input.\n");
319             goto fail;
320         }
321         
322         c->sink_input->owner = p->module;
323         c->sink_input->client = c->client;
324         
325         c->sink_input->peek = sink_input_peek_cb;
326         c->sink_input->drop = sink_input_drop_cb;
327         c->sink_input->kill = sink_input_kill_cb;
328         c->sink_input->get_latency = sink_input_get_latency_cb;
329         c->sink_input->userdata = c;
330
331         l = (size_t) (pa_bytes_per_second(&p->sample_spec)*PLAYBACK_BUFFER_SECONDS);
332         c->input_memblockq = pa_memblockq_new(l, 0, pa_frame_size(&p->sample_spec), l/2, l/PLAYBACK_BUFFER_FRAGMENTS, p->core->memblock_stat);
333         assert(c->input_memblockq);
334         pa_iochannel_socket_set_rcvbuf(io, l/PLAYBACK_BUFFER_FRAGMENTS*5);
335         c->playback.fragment_size = l/10;
336     }
337
338     if (p->mode & RECORD) {
339         struct pa_source *source;
340         size_t l;
341
342         if (!(source = pa_namereg_get(p->core, p->source_name, PA_NAMEREG_SOURCE, 1))) {
343             pa_log(__FILE__": Failed to get source.\n");
344             goto fail;
345         }
346
347         c->source_output = pa_source_output_new(source, c->client->name, &p->sample_spec, -1);
348         if (!c->source_output) {
349             pa_log(__FILE__": Failed to create source output.\n");
350             goto fail;
351         }
352         c->source_output->owner = p->module;
353         c->source_output->client = c->client;
354         
355         c->source_output->push = source_output_push_cb;
356         c->source_output->kill = source_output_kill_cb;
357         c->source_output->get_latency = source_output_get_latency_cb;
358         c->source_output->userdata = c;
359
360         l = (size_t) (pa_bytes_per_second(&p->sample_spec)*RECORD_BUFFER_SECONDS);
361         c->output_memblockq = pa_memblockq_new(l, 0, pa_frame_size(&p->sample_spec), 0, 0, p->core->memblock_stat);
362         pa_iochannel_socket_set_sndbuf(io, l/RECORD_BUFFER_FRAGMENTS*2);
363     }
364
365     pa_iochannel_set_callback(c->io, io_callback, c);
366     pa_idxset_put(p->connections, c, NULL);
367
368     c->defer_event = p->core->mainloop->defer_new(p->core->mainloop, defer_callback, c);
369     assert(c->defer_event);
370     p->core->mainloop->defer_enable(c->defer_event, 0);
371     
372     return;
373     
374 fail:
375     if (c)
376         connection_free(c);
377 }
378
379 struct pa_protocol_simple* pa_protocol_simple_new(struct pa_core *core, struct pa_socket_server *server, struct pa_module *m, struct pa_modargs *ma) {
380     struct pa_protocol_simple* p = NULL;
381     int enable;
382     assert(core && server && ma);
383
384     p = pa_xmalloc0(sizeof(struct pa_protocol_simple));
385     p->module = m;
386     p->core = core;
387     p->server = server;
388     p->connections = pa_idxset_new(NULL, NULL);
389
390     p->sample_spec = core->default_sample_spec;
391     if (pa_modargs_get_sample_spec(ma, &p->sample_spec) < 0) {
392         pa_log(__FILE__": Failed to parse sample type specification.\n");
393         goto fail;
394     }
395
396     p->source_name = pa_xstrdup(pa_modargs_get_value(ma, "source", NULL));
397     p->sink_name = pa_xstrdup(pa_modargs_get_value(ma, "sink", NULL));
398     
399     enable = 0;
400     if (pa_modargs_get_value_boolean(ma, "record", &enable) < 0) {
401         pa_log(__FILE__": record= expects a numeric argument.\n");
402         goto fail;
403     }
404     p->mode = enable ? RECORD : 0;
405
406     enable = 1;
407     if (pa_modargs_get_value_boolean(ma, "playback", &enable) < 0) {
408         pa_log(__FILE__": playback= expects a numeric argument.\n");
409         goto fail;
410     }
411     p->mode |= enable ? PLAYBACK : 0;
412
413     if ((p->mode & (RECORD|PLAYBACK)) == 0) {
414         pa_log(__FILE__": neither playback nor recording enabled for protocol.\n");
415         goto fail;
416     }
417     
418     pa_socket_server_set_callback(p->server, on_connection, p);
419     
420     return p;
421
422 fail:
423     if (p)
424         pa_protocol_simple_free(p);
425     return NULL;
426 }
427
428
429 void pa_protocol_simple_free(struct pa_protocol_simple *p) {
430     struct connection *c;
431     assert(p);
432
433     if (p->connections) {
434         while((c = pa_idxset_first(p->connections, NULL)))
435             connection_free(c);
436         
437         pa_idxset_free(p->connections, NULL, NULL);
438     }
439
440     if (p->server)
441         pa_socket_server_unref(p->server);
442     pa_xfree(p);
443 }
444