a4e47267e6111ecd5e730bad009c3a86fcd1c7cc
[asterisk/asterisk.git] / apps / app_jack.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2007 - 2008, Russell Bryant
5  *
6  * Russell Bryant <russell@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*!
20  * \file
21  * \brief Jack Application
22  *
23  * \author Russell Bryant <russell@digium.com>
24  *
25  * This is an application to connect an Asterisk channel to an input
26  * and output jack port so that the audio can be processed through
27  * another application, or to play audio from another application.
28  *
29  * \extref http://www.jackaudio.org/
30  *
31  * \note To install libresample, check it out of the following repository:
32  * <code>$ svn co http://svn.digium.com/svn/thirdparty/libresample/trunk</code>
33  *
34  * \ingroup applications
35  */
36
37 /*** MODULEINFO
38         <depend>jack</depend>
39         <depend>resample</depend>
40         <support_level>extended</support_level>
41  ***/
42
43 #include "asterisk.h"
44
45 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
46
47 #include <limits.h>
48
49 #include <jack/jack.h>
50 #include <jack/ringbuffer.h>
51
52 #include <libresample.h>
53
54 #include "asterisk/module.h"
55 #include "asterisk/channel.h"
56 #include "asterisk/strings.h"
57 #include "asterisk/lock.h"
58 #include "asterisk/app.h"
59 #include "asterisk/pbx.h"
60 #include "asterisk/audiohook.h"
61 #include "asterisk/format_cache.h"
62
63 #define RESAMPLE_QUALITY 1
64
65 /* The number of frames the ringbuffers can store. The actual size is RINGBUFFER_FRAME_CAPACITY * jack_data->frame_datalen */
66 #define RINGBUFFER_FRAME_CAPACITY 100
67
68 /*! \brief Common options between the Jack() app and JACK_HOOK() function */
69 #define COMMON_OPTIONS \
70 "    s(<name>) - Connect to the specified jack server name.\n" \
71 "    i(<name>) - Connect the output port that gets created to the specified\n" \
72 "                jack input port.\n" \
73 "    o(<name>) - Connect the input port that gets created to the specified\n" \
74 "                jack output port.\n" \
75 "    n         - Do not automatically start the JACK server if it is not already\n" \
76 "                running.\n" \
77 "    c(<name>) - By default, Asterisk will use the channel name for the jack client\n" \
78 "                name.  Use this option to specify a custom client name.\n"
79 /*** DOCUMENTATION
80         <application name="JACK" language="en_US">
81                 <synopsis>
82                         Jack Audio Connection Kit
83                 </synopsis>
84                 <syntax>
85                         <parameter name="options" required="false">
86                                 <optionlist>
87                                         <option name="s">
88                                                 <argument name="name" required="true">
89                                                         <para>Connect to the specified jack server name</para>
90                                                 </argument>
91                                         </option>
92                                         <option name="i">
93                                                 <argument name="name" required="true">
94                                                         <para>Connect the output port that gets created to the specified jack input port</para>
95                                                 </argument>
96                                         </option>
97                                         <option name="o">
98                                                 <argument name="name" required="true">
99                                                         <para>Connect the input port that gets created to the specified jack output port</para>
100                                                 </argument>
101                                         </option>
102                                         <option name="c">
103                                                 <argument name="name" required="true">
104                                                         <para>By default, Asterisk will use the channel name for the jack client name.</para>
105                                                         <para>Use this option to specify a custom client name.</para>
106                                                 </argument>
107                                         </option>
108                                 </optionlist>
109                         </parameter>
110                 </syntax>
111                 <description>
112                         <para>When executing this application, two jack ports will be created;
113                         one input and one output. Other applications can be hooked up to
114                         these ports to access audio coming from, or being send to the channel.</para>
115                 </description>
116         </application>
117  ***/
118
119 static const char jack_app[] = "JACK";
120
121 struct jack_data {
122         AST_DECLARE_STRING_FIELDS(
123                 AST_STRING_FIELD(server_name);
124                 AST_STRING_FIELD(client_name);
125                 AST_STRING_FIELD(connect_input_port);
126                 AST_STRING_FIELD(connect_output_port);
127         );
128         jack_client_t *client;
129         jack_port_t *input_port;
130         jack_port_t *output_port;
131         jack_ringbuffer_t *input_rb;
132         jack_ringbuffer_t *output_rb;
133         struct ast_format *audiohook_format;
134         unsigned int audiohook_rate;
135         unsigned int frame_datalen;
136         void *output_resampler;
137         double output_resample_factor;
138         void *input_resampler;
139         double input_resample_factor;
140         unsigned int stop:1;
141         unsigned int has_audiohook:1;
142         unsigned int no_start_server:1;
143         /*! Only used with JACK_HOOK */
144         struct ast_audiohook audiohook;
145 };
146
147 static const struct {
148         jack_status_t status;
149         const char *str;
150 } jack_status_table[] = {
151         { JackFailure,        "Failure" },
152         { JackInvalidOption,  "Invalid Option" },
153         { JackNameNotUnique,  "Name Not Unique" },
154         { JackServerStarted,  "Server Started" },
155         { JackServerFailed,   "Server Failed" },
156         { JackServerError,    "Server Error" },
157         { JackNoSuchClient,   "No Such Client" },
158         { JackLoadFailure,    "Load Failure" },
159         { JackInitFailure,    "Init Failure" },
160         { JackShmFailure,     "Shared Memory Access Failure" },
161         { JackVersionError,   "Version Mismatch" },
162 };
163
164 static const char *jack_status_to_str(jack_status_t status)
165 {
166         int i;
167
168         for (i = 0; i < ARRAY_LEN(jack_status_table); i++) {
169                 if (jack_status_table[i].status == status)
170                         return jack_status_table[i].str;
171         }
172
173         return "Unknown Error";
174 }
175
176 static void log_jack_status(const char *prefix, jack_status_t status)
177 {
178         struct ast_str *str = ast_str_alloca(512);
179         int i, first = 0;
180
181         for (i = 0; i < (sizeof(status) * 8); i++) {
182                 if (!(status & (1 << i)))
183                         continue;
184
185                 if (!first) {
186                         ast_str_set(&str, 0, "%s", jack_status_to_str((1 << i)));
187                         first = 1;
188                 } else
189                         ast_str_append(&str, 0, ", %s", jack_status_to_str((1 << i)));
190         }
191
192         ast_log(LOG_NOTICE, "%s: %s\n", prefix, ast_str_buffer(str));
193 }
194
195 static int alloc_resampler(struct jack_data *jack_data, int input)
196 {
197         double from_srate, to_srate, jack_srate;
198         void **resampler;
199         double *resample_factor;
200
201         if (input && jack_data->input_resampler)
202                 return 0;
203
204         if (!input && jack_data->output_resampler)
205                 return 0;
206
207         jack_srate = jack_get_sample_rate(jack_data->client);
208
209         to_srate = input ? jack_data->audiohook_rate : jack_srate;
210         from_srate = input ? jack_srate : jack_data->audiohook_rate;
211
212         resample_factor = input ? &jack_data->input_resample_factor :
213                 &jack_data->output_resample_factor;
214
215         if (from_srate == to_srate) {
216                 /* Awesome!  The jack sample rate is the same as ours.
217                  * Resampling isn't needed. */
218                 *resample_factor = 1.0;
219                 return 0;
220         }
221
222         *resample_factor = to_srate / from_srate;
223
224         resampler = input ? &jack_data->input_resampler :
225                 &jack_data->output_resampler;
226
227         if (!(*resampler = resample_open(RESAMPLE_QUALITY,
228                 *resample_factor, *resample_factor))) {
229                 ast_log(LOG_ERROR, "Failed to open %s resampler\n",
230                         input ? "input" : "output");
231                 return -1;
232         }
233
234         return 0;
235 }
236
237 /*!
238  * \brief Handle jack input port
239  *
240  * Read nframes number of samples from the input buffer, resample it
241  * if necessary, and write it into the appropriate ringbuffer.
242  */
243 static void handle_input(void *buf, jack_nframes_t nframes,
244         struct jack_data *jack_data)
245 {
246         short s_buf[nframes];
247         float *in_buf = buf;
248         size_t res;
249         int i;
250         size_t write_len = sizeof(s_buf);
251
252         if (jack_data->input_resampler) {
253                 int total_in_buf_used = 0;
254                 int total_out_buf_used = 0;
255                 float f_buf[nframes + 1];
256
257                 memset(f_buf, 0, sizeof(f_buf));
258
259                 while (total_in_buf_used < nframes) {
260                         int in_buf_used;
261                         int out_buf_used;
262
263                         out_buf_used = resample_process(jack_data->input_resampler,
264                                 jack_data->input_resample_factor,
265                                 &in_buf[total_in_buf_used], nframes - total_in_buf_used,
266                                 0, &in_buf_used,
267                                 &f_buf[total_out_buf_used], ARRAY_LEN(f_buf) - total_out_buf_used);
268
269                         if (out_buf_used < 0)
270                                 break;
271
272                         total_out_buf_used += out_buf_used;
273                         total_in_buf_used += in_buf_used;
274
275                         if (total_out_buf_used == ARRAY_LEN(f_buf)) {
276                                 ast_log(LOG_ERROR, "Output buffer filled ... need to increase its size, "
277                                         "nframes '%d', total_out_buf_used '%d'\n", nframes, total_out_buf_used);
278                                 break;
279                         }
280                 }
281
282                 for (i = 0; i < total_out_buf_used; i++)
283                         s_buf[i] = f_buf[i] * (SHRT_MAX / 1.0);
284
285                 write_len = total_out_buf_used * sizeof(int16_t);
286         } else {
287                 /* No resampling needed */
288
289                 for (i = 0; i < nframes; i++)
290                         s_buf[i] = in_buf[i] * (SHRT_MAX / 1.0);
291         }
292
293         res = jack_ringbuffer_write(jack_data->input_rb, (const char *) s_buf, write_len);
294         if (res != write_len) {
295                 ast_log(LOG_WARNING, "Tried to write %d bytes to the ringbuffer, but only wrote %d\n",
296                         (int) sizeof(s_buf), (int) res);
297         }
298 }
299
300 /*!
301  * \brief Handle jack output port
302  *
303  * Read nframes number of samples from the ringbuffer and write it out to the
304  * output port buffer.
305  */
306 static void handle_output(void *buf, jack_nframes_t nframes,
307         struct jack_data *jack_data)
308 {
309         size_t res, len;
310
311         len = nframes * sizeof(float);
312
313         res = jack_ringbuffer_read(jack_data->output_rb, buf, len);
314
315         if (len != res) {
316                 ast_debug(2, "Wanted %d bytes to send to the output port, "
317                         "but only got %d\n", (int) len, (int) res);
318         }
319 }
320
321 static int jack_process(jack_nframes_t nframes, void *arg)
322 {
323         struct jack_data *jack_data = arg;
324         void *input_port_buf, *output_port_buf;
325
326         if (!jack_data->input_resample_factor)
327                 alloc_resampler(jack_data, 1);
328
329         input_port_buf = jack_port_get_buffer(jack_data->input_port, nframes);
330         handle_input(input_port_buf, nframes, jack_data);
331
332         output_port_buf = jack_port_get_buffer(jack_data->output_port, nframes);
333         handle_output(output_port_buf, nframes, jack_data);
334
335         return 0;
336 }
337
338 static void jack_shutdown(void *arg)
339 {
340         struct jack_data *jack_data = arg;
341
342         jack_data->stop = 1;
343 }
344
345 static struct jack_data *destroy_jack_data(struct jack_data *jack_data)
346 {
347         if (jack_data->input_port) {
348                 jack_port_unregister(jack_data->client, jack_data->input_port);
349                 jack_data->input_port = NULL;
350         }
351
352         if (jack_data->output_port) {
353                 jack_port_unregister(jack_data->client, jack_data->output_port);
354                 jack_data->output_port = NULL;
355         }
356
357         if (jack_data->client) {
358                 jack_client_close(jack_data->client);
359                 jack_data->client = NULL;
360         }
361
362         if (jack_data->input_rb) {
363                 jack_ringbuffer_free(jack_data->input_rb);
364                 jack_data->input_rb = NULL;
365         }
366
367         if (jack_data->output_rb) {
368                 jack_ringbuffer_free(jack_data->output_rb);
369                 jack_data->output_rb = NULL;
370         }
371
372         if (jack_data->output_resampler) {
373                 resample_close(jack_data->output_resampler);
374                 jack_data->output_resampler = NULL;
375         }
376
377         if (jack_data->input_resampler) {
378                 resample_close(jack_data->input_resampler);
379                 jack_data->input_resampler = NULL;
380         }
381
382         if (jack_data->has_audiohook)
383                 ast_audiohook_destroy(&jack_data->audiohook);
384
385         ast_string_field_free_memory(jack_data);
386
387         ast_free(jack_data);
388
389         return NULL;
390 }
391
392 static int init_jack_data(struct ast_channel *chan, struct jack_data *jack_data)
393 {
394         const char *client_name;
395         jack_status_t status = 0;
396         jack_options_t jack_options = JackNullOption;
397
398         unsigned int channel_rate;
399
400         unsigned int ringbuffer_size;
401
402         /* Deducing audiohook sample rate from channel format
403            ATTENTION: Might be problematic, if channel has different sampling than used by audiohook!
404         */
405         channel_rate = ast_format_get_sample_rate(ast_channel_readformat(chan));
406         jack_data->audiohook_format = ast_format_cache_get_slin_by_rate(channel_rate);
407         jack_data->audiohook_rate = ast_format_get_sample_rate(jack_data->audiohook_format);
408
409         /* Guessing frame->datalen assuming a ptime of 20ms */
410         jack_data->frame_datalen = jack_data->audiohook_rate / 50;
411
412         ringbuffer_size = jack_data->frame_datalen * RINGBUFFER_FRAME_CAPACITY;
413
414         ast_debug(1, "Audiohook parameters: slin-format:%s, rate:%d, frame-len:%d, ringbuffer_size: %d\n",
415             ast_format_get_name(jack_data->audiohook_format), jack_data->audiohook_rate, jack_data->frame_datalen, ringbuffer_size);
416
417         if (!ast_strlen_zero(jack_data->client_name)) {
418                 client_name = jack_data->client_name;
419         } else {
420                 ast_channel_lock(chan);
421                 client_name = ast_strdupa(ast_channel_name(chan));
422                 ast_channel_unlock(chan);
423         }
424
425         if (!(jack_data->output_rb = jack_ringbuffer_create(ringbuffer_size)))
426                 return -1;
427
428         if (!(jack_data->input_rb = jack_ringbuffer_create(ringbuffer_size)))
429                 return -1;
430
431         if (jack_data->no_start_server)
432                 jack_options |= JackNoStartServer;
433
434         if (!ast_strlen_zero(jack_data->server_name)) {
435                 jack_options |= JackServerName;
436                 jack_data->client = jack_client_open(client_name, jack_options, &status,
437                         jack_data->server_name);
438         } else {
439                 jack_data->client = jack_client_open(client_name, jack_options, &status);
440         }
441
442         if (status)
443                 log_jack_status("Client Open Status", status);
444
445         if (!jack_data->client)
446                 return -1;
447
448         jack_data->input_port = jack_port_register(jack_data->client, "input",
449                 JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput | JackPortIsTerminal, 0);
450         if (!jack_data->input_port) {
451                 ast_log(LOG_ERROR, "Failed to create input port for jack port\n");
452                 return -1;
453         }
454
455         jack_data->output_port = jack_port_register(jack_data->client, "output",
456                 JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput | JackPortIsTerminal, 0);
457         if (!jack_data->output_port) {
458                 ast_log(LOG_ERROR, "Failed to create output port for jack port\n");
459                 return -1;
460         }
461
462         if (jack_set_process_callback(jack_data->client, jack_process, jack_data)) {
463                 ast_log(LOG_ERROR, "Failed to register process callback with jack client\n");
464                 return -1;
465         }
466
467         jack_on_shutdown(jack_data->client, jack_shutdown, jack_data);
468
469         if (jack_activate(jack_data->client)) {
470                 ast_log(LOG_ERROR, "Unable to activate jack client\n");
471                 return -1;
472         }
473
474         while (!ast_strlen_zero(jack_data->connect_input_port)) {
475                 const char **ports;
476                 int i;
477
478                 ports = jack_get_ports(jack_data->client, jack_data->connect_input_port,
479                         NULL, JackPortIsInput);
480
481                 if (!ports) {
482                         ast_log(LOG_ERROR, "No input port matching '%s' was found\n",
483                                 jack_data->connect_input_port);
484                         break;
485                 }
486
487                 for (i = 0; ports[i]; i++) {
488                         ast_debug(1, "Found port '%s' that matched specified input port '%s'\n",
489                                 ports[i], jack_data->connect_input_port);
490                 }
491
492                 if (jack_connect(jack_data->client, jack_port_name(jack_data->output_port), ports[0])) {
493                         ast_log(LOG_ERROR, "Failed to connect '%s' to '%s'\n", ports[0],
494                                 jack_port_name(jack_data->output_port));
495                 } else {
496                         ast_debug(1, "Connected '%s' to '%s'\n", ports[0],
497                                 jack_port_name(jack_data->output_port));
498                 }
499
500                 jack_free(ports);
501
502                 break;
503         }
504
505         while (!ast_strlen_zero(jack_data->connect_output_port)) {
506                 const char **ports;
507                 int i;
508
509                 ports = jack_get_ports(jack_data->client, jack_data->connect_output_port,
510                         NULL, JackPortIsOutput);
511
512                 if (!ports) {
513                         ast_log(LOG_ERROR, "No output port matching '%s' was found\n",
514                                 jack_data->connect_output_port);
515                         break;
516                 }
517
518                 for (i = 0; ports[i]; i++) {
519                         ast_debug(1, "Found port '%s' that matched specified output port '%s'\n",
520                                 ports[i], jack_data->connect_output_port);
521                 }
522
523                 if (jack_connect(jack_data->client, ports[0], jack_port_name(jack_data->input_port))) {
524                         ast_log(LOG_ERROR, "Failed to connect '%s' to '%s'\n", ports[0],
525                                 jack_port_name(jack_data->input_port));
526                 } else {
527                         ast_debug(1, "Connected '%s' to '%s'\n", ports[0],
528                                 jack_port_name(jack_data->input_port));
529                 }
530
531                 jack_free(ports);
532
533                 break;
534         }
535
536         return 0;
537 }
538
539 static int queue_voice_frame(struct jack_data *jack_data, struct ast_frame *f)
540 {
541         float f_buf[f->samples * 8];
542         size_t f_buf_used = 0;
543         int i;
544         int16_t *s_buf = f->data.ptr;
545         size_t res;
546
547         memset(f_buf, 0, sizeof(f_buf));
548
549         if (!jack_data->output_resample_factor)
550                 alloc_resampler(jack_data, 0);
551
552         if (jack_data->output_resampler) {
553                 float in_buf[f->samples];
554                 int total_in_buf_used = 0;
555                 int total_out_buf_used = 0;
556
557                 memset(in_buf, 0, sizeof(in_buf));
558
559                 for (i = 0; i < f->samples; i++)
560                         in_buf[i] = s_buf[i] * (1.0 / SHRT_MAX);
561
562                 while (total_in_buf_used < ARRAY_LEN(in_buf)) {
563                         int in_buf_used;
564                         int out_buf_used;
565
566                         out_buf_used = resample_process(jack_data->output_resampler,
567                                 jack_data->output_resample_factor,
568                                 &in_buf[total_in_buf_used], ARRAY_LEN(in_buf) - total_in_buf_used,
569                                 0, &in_buf_used,
570                                 &f_buf[total_out_buf_used], ARRAY_LEN(f_buf) - total_out_buf_used);
571
572                         if (out_buf_used < 0)
573                                 break;
574
575                         total_out_buf_used += out_buf_used;
576                         total_in_buf_used += in_buf_used;
577
578                         if (total_out_buf_used == ARRAY_LEN(f_buf)) {
579                                 ast_log(LOG_ERROR, "Output buffer filled ... need to increase its size\n");
580                                 break;
581                         }
582                 }
583
584                 f_buf_used = total_out_buf_used;
585                 if (f_buf_used > ARRAY_LEN(f_buf))
586                         f_buf_used = ARRAY_LEN(f_buf);
587         } else {
588                 /* No resampling needed */
589
590                 for (i = 0; i < f->samples; i++)
591                         f_buf[i] = s_buf[i] * (1.0 / SHRT_MAX);
592
593                 f_buf_used = f->samples;
594         }
595
596         res = jack_ringbuffer_write(jack_data->output_rb, (const char *) f_buf, f_buf_used * sizeof(float));
597         if (res != (f_buf_used * sizeof(float))) {
598                 ast_log(LOG_WARNING, "Tried to write %d bytes to the ringbuffer, but only wrote %d\n",
599                         (int) (f_buf_used * sizeof(float)), (int) res);
600         }
601         return 0;
602 }
603
604 /*!
605  * \brief handle jack audio
606  *
607  * \param[in]  chan The Asterisk channel to write the frames to if no output frame
608  *             is provided.
609  * \param[in]  jack_data This is the jack_data struct that contains the input
610  *             ringbuffer that audio will be read from.
611  * \param[out] out_frame If this argument is non-NULL, then assuming there is
612  *             enough data avilable in the ringbuffer, the audio in this frame
613  *             will get replaced with audio from the input buffer.  If there is
614  *             not enough data available to read at this time, then the frame
615  *             data gets zeroed out.
616  *
617  * Read data from the input ringbuffer, which is the properly resampled audio
618  * that was read from the jack input port.  Write it to the channel in 20 ms frames,
619  * or fill up an output frame instead if one is provided.
620  *
621  * \return Nothing.
622  */
623 static void handle_jack_audio(struct ast_channel *chan, struct jack_data *jack_data,
624         struct ast_frame *out_frame)
625 {
626         short buf[jack_data->frame_datalen];
627         struct ast_frame f = {
628                 .frametype = AST_FRAME_VOICE,
629                 .subclass.format = jack_data->audiohook_format,
630                 .src = "JACK",
631                 .data.ptr = buf,
632                 .datalen = sizeof(buf),
633                 .samples = ARRAY_LEN(buf),
634         };
635
636         for (;;) {
637                 size_t res, read_len;
638                 char *read_buf;
639
640                 read_len = out_frame ? out_frame->datalen : sizeof(buf);
641                 read_buf = out_frame ? out_frame->data.ptr : buf;
642
643                 res = jack_ringbuffer_read_space(jack_data->input_rb);
644
645                 if (res < read_len) {
646                         /* Not enough data ready for another frame, move on ... */
647                         if (out_frame) {
648                                 ast_debug(1, "Sending an empty frame for the JACK_HOOK\n");
649                                 memset(out_frame->data.ptr, 0, out_frame->datalen);
650                         }
651                         break;
652                 }
653
654                 res = jack_ringbuffer_read(jack_data->input_rb, (char *) read_buf, read_len);
655
656                 if (res < read_len) {
657                         ast_log(LOG_ERROR, "Error reading from ringbuffer, even though it said there was enough data\n");
658                         break;
659                 }
660
661                 if (out_frame) {
662                         /* If an output frame was provided, then we just want to fill up the
663                          * buffer in that frame and return. */
664                         break;
665                 }
666
667                 ast_write(chan, &f);
668         }
669 }
670
671 enum {
672         OPT_SERVER_NAME =    (1 << 0),
673         OPT_INPUT_PORT =     (1 << 1),
674         OPT_OUTPUT_PORT =    (1 << 2),
675         OPT_NOSTART_SERVER = (1 << 3),
676         OPT_CLIENT_NAME =    (1 << 4),
677 };
678
679 enum {
680         OPT_ARG_SERVER_NAME,
681         OPT_ARG_INPUT_PORT,
682         OPT_ARG_OUTPUT_PORT,
683         OPT_ARG_CLIENT_NAME,
684
685         /* Must be the last element */
686         OPT_ARG_ARRAY_SIZE,
687 };
688
689 AST_APP_OPTIONS(jack_exec_options, BEGIN_OPTIONS
690         AST_APP_OPTION_ARG('s', OPT_SERVER_NAME, OPT_ARG_SERVER_NAME),
691         AST_APP_OPTION_ARG('i', OPT_INPUT_PORT, OPT_ARG_INPUT_PORT),
692         AST_APP_OPTION_ARG('o', OPT_OUTPUT_PORT, OPT_ARG_OUTPUT_PORT),
693         AST_APP_OPTION('n', OPT_NOSTART_SERVER),
694         AST_APP_OPTION_ARG('c', OPT_CLIENT_NAME, OPT_ARG_CLIENT_NAME),
695 END_OPTIONS );
696
697 static struct jack_data *jack_data_alloc(void)
698 {
699         struct jack_data *jack_data;
700
701         if (!(jack_data = ast_calloc_with_stringfields(1, struct jack_data, 32))) {
702                 return NULL;
703         }
704
705         return jack_data;
706 }
707
708 /*!
709  * \note This must be done before calling init_jack_data().
710  */
711 static int handle_options(struct jack_data *jack_data, const char *__options_str)
712 {
713         struct ast_flags options = { 0, };
714         char *option_args[OPT_ARG_ARRAY_SIZE];
715         char *options_str;
716
717         options_str = ast_strdupa(__options_str);
718
719         ast_app_parse_options(jack_exec_options, &options, option_args, options_str);
720
721         if (ast_test_flag(&options, OPT_SERVER_NAME)) {
722                 if (!ast_strlen_zero(option_args[OPT_ARG_SERVER_NAME]))
723                         ast_string_field_set(jack_data, server_name, option_args[OPT_ARG_SERVER_NAME]);
724                 else {
725                         ast_log(LOG_ERROR, "A server name must be provided with the s() option\n");
726                         return -1;
727                 }
728         }
729
730         if (ast_test_flag(&options, OPT_CLIENT_NAME)) {
731                 if (!ast_strlen_zero(option_args[OPT_ARG_CLIENT_NAME]))
732                         ast_string_field_set(jack_data, client_name, option_args[OPT_ARG_CLIENT_NAME]);
733                 else {
734                         ast_log(LOG_ERROR, "A client name must be provided with the c() option\n");
735                         return -1;
736                 }
737         }
738
739         if (ast_test_flag(&options, OPT_INPUT_PORT)) {
740                 if (!ast_strlen_zero(option_args[OPT_ARG_INPUT_PORT]))
741                         ast_string_field_set(jack_data, connect_input_port, option_args[OPT_ARG_INPUT_PORT]);
742                 else {
743                         ast_log(LOG_ERROR, "A name must be provided with the i() option\n");
744                         return -1;
745                 }
746         }
747
748         if (ast_test_flag(&options, OPT_OUTPUT_PORT)) {
749                 if (!ast_strlen_zero(option_args[OPT_ARG_OUTPUT_PORT]))
750                         ast_string_field_set(jack_data, connect_output_port, option_args[OPT_ARG_OUTPUT_PORT]);
751                 else {
752                         ast_log(LOG_ERROR, "A name must be provided with the o() option\n");
753                         return -1;
754                 }
755         }
756
757         jack_data->no_start_server = ast_test_flag(&options, OPT_NOSTART_SERVER) ? 1 : 0;
758
759         return 0;
760 }
761
762 static int jack_exec(struct ast_channel *chan, const char *data)
763 {
764         struct jack_data *jack_data;
765
766         if (!(jack_data = jack_data_alloc()))
767                 return -1;
768
769         if (!ast_strlen_zero(data) && handle_options(jack_data, data)) {
770                 destroy_jack_data(jack_data);
771                 return -1;
772         }
773
774         if (init_jack_data(chan, jack_data)) {
775                 destroy_jack_data(jack_data);
776                 return -1;
777         }
778
779         if (ast_set_read_format(chan, jack_data->audiohook_format)) {
780                 destroy_jack_data(jack_data);
781                 return -1;
782         }
783
784         if (ast_set_write_format(chan, jack_data->audiohook_format)) {
785                 destroy_jack_data(jack_data);
786                 return -1;
787         }
788
789         while (!jack_data->stop) {
790                 struct ast_frame *f;
791
792                 if (ast_waitfor(chan, -1) < 0) {
793                         break;
794                 }
795
796                 f = ast_read(chan);
797                 if (!f) {
798                         jack_data->stop = 1;
799                         continue;
800                 }
801
802                 switch (f->frametype) {
803                 case AST_FRAME_CONTROL:
804                         if (f->subclass.integer == AST_CONTROL_HANGUP)
805                                 jack_data->stop = 1;
806                         break;
807                 case AST_FRAME_VOICE:
808                         queue_voice_frame(jack_data, f);
809                 default:
810                         break;
811                 }
812
813                 ast_frfree(f);
814
815                 handle_jack_audio(chan, jack_data, NULL);
816         }
817
818         jack_data = destroy_jack_data(jack_data);
819
820         return 0;
821 }
822
823 static void jack_hook_ds_destroy(void *data)
824 {
825         struct jack_data *jack_data = data;
826
827         destroy_jack_data(jack_data);
828 }
829
830 static const struct ast_datastore_info jack_hook_ds_info = {
831         .type = "JACK_HOOK",
832         .destroy = jack_hook_ds_destroy,
833 };
834
835 static int jack_hook_callback(struct ast_audiohook *audiohook, struct ast_channel *chan,
836         struct ast_frame *frame, enum ast_audiohook_direction direction)
837 {
838         struct ast_datastore *datastore;
839         struct jack_data *jack_data;
840
841         if (audiohook->status == AST_AUDIOHOOK_STATUS_DONE)
842                 return 0;
843
844         if (direction != AST_AUDIOHOOK_DIRECTION_READ)
845                 return 0;
846
847         if (frame->frametype != AST_FRAME_VOICE)
848                 return 0;
849
850         ast_channel_lock(chan);
851
852         if (!(datastore = ast_channel_datastore_find(chan, &jack_hook_ds_info, NULL))) {
853                 ast_log(LOG_ERROR, "JACK_HOOK datastore not found for '%s'\n", ast_channel_name(chan));
854                 ast_channel_unlock(chan);
855                 return -1;
856         }
857
858         jack_data = datastore->data;
859
860         if (ast_format_cmp(frame->subclass.format, jack_data->audiohook_format) == AST_FORMAT_CMP_NOT_EQUAL) {
861                 ast_log(LOG_WARNING, "Expected frame in %s for the audiohook, but got format %s\n",
862                         ast_format_get_name(jack_data->audiohook_format),
863                         ast_format_get_name(frame->subclass.format));
864                 ast_channel_unlock(chan);
865                 return 0;
866         }
867
868         queue_voice_frame(jack_data, frame);
869
870         handle_jack_audio(chan, jack_data, frame);
871
872         ast_channel_unlock(chan);
873
874         return 0;
875 }
876
877 static int enable_jack_hook(struct ast_channel *chan, char *data)
878 {
879         struct ast_datastore *datastore;
880         struct jack_data *jack_data = NULL;
881         AST_DECLARE_APP_ARGS(args,
882                 AST_APP_ARG(mode);
883                 AST_APP_ARG(options);
884         );
885
886         AST_STANDARD_APP_ARGS(args, data);
887
888         ast_channel_lock(chan);
889
890         if ((datastore = ast_channel_datastore_find(chan, &jack_hook_ds_info, NULL))) {
891                 ast_log(LOG_ERROR, "JACK_HOOK already enabled for '%s'\n", ast_channel_name(chan));
892                 goto return_error;
893         }
894
895         if (ast_strlen_zero(args.mode) || strcasecmp(args.mode, "manipulate")) {
896                 ast_log(LOG_ERROR, "'%s' is not a supported mode.  Only manipulate is supported.\n",
897                         S_OR(args.mode, "<none>"));
898                 goto return_error;
899         }
900
901         if (!(jack_data = jack_data_alloc()))
902                 goto return_error;
903
904         if (!ast_strlen_zero(args.options) && handle_options(jack_data, args.options))
905                 goto return_error;
906
907         if (init_jack_data(chan, jack_data))
908                 goto return_error;
909
910         if (!(datastore = ast_datastore_alloc(&jack_hook_ds_info, NULL)))
911                 goto return_error;
912
913         jack_data->has_audiohook = 1;
914         ast_audiohook_init(&jack_data->audiohook, AST_AUDIOHOOK_TYPE_MANIPULATE, "JACK_HOOK", AST_AUDIOHOOK_MANIPULATE_ALL_RATES);
915         jack_data->audiohook.manipulate_callback = jack_hook_callback;
916
917         datastore->data = jack_data;
918
919         if (ast_audiohook_attach(chan, &jack_data->audiohook))
920                 goto return_error;
921
922         if (ast_channel_datastore_add(chan, datastore))
923                 goto return_error;
924
925         ast_channel_unlock(chan);
926
927         return 0;
928
929 return_error:
930         ast_channel_unlock(chan);
931
932         if (jack_data) {
933                 destroy_jack_data(jack_data);
934         }
935
936         if (datastore) {
937                 datastore->data = NULL;
938                 ast_datastore_free(datastore);
939         }
940
941         return -1;
942 }
943
944 static int disable_jack_hook(struct ast_channel *chan)
945 {
946         struct ast_datastore *datastore;
947         struct jack_data *jack_data;
948
949         ast_channel_lock(chan);
950
951         if (!(datastore = ast_channel_datastore_find(chan, &jack_hook_ds_info, NULL))) {
952                 ast_channel_unlock(chan);
953                 ast_log(LOG_WARNING, "No JACK_HOOK found to disable\n");
954                 return -1;
955         }
956
957         ast_channel_datastore_remove(chan, datastore);
958
959         jack_data = datastore->data;
960         ast_audiohook_detach(&jack_data->audiohook);
961
962         /* Keep the channel locked while we destroy the datastore, so that we can
963          * ensure that all of the jack stuff is stopped just in case another frame
964          * tries to come through the audiohook callback. */
965         ast_datastore_free(datastore);
966
967         ast_channel_unlock(chan);
968
969         return 0;
970 }
971
972 static int jack_hook_write(struct ast_channel *chan, const char *cmd, char *data,
973         const char *value)
974 {
975         int res;
976
977         if (!chan) {
978                 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
979                 return -1;
980         }
981
982         if (!strcasecmp(value, "on"))
983                 res = enable_jack_hook(chan, data);
984         else if (!strcasecmp(value, "off"))
985                 res = disable_jack_hook(chan);
986         else {
987                 ast_log(LOG_ERROR, "'%s' is not a valid value for JACK_HOOK()\n", value);
988                 res = -1;
989         }
990
991         return res;
992 }
993
994 static struct ast_custom_function jack_hook_function = {
995         .name = "JACK_HOOK",
996         .synopsis = "Enable a jack hook on a channel",
997         .syntax = "JACK_HOOK(<mode>,[options])",
998         .desc =
999         "   The JACK_HOOK allows turning on or off jack connectivity to this channel.\n"
1000         "When the JACK_HOOK is turned on, jack ports will get created that allow\n"
1001         "access to the audio stream for this channel.  The mode specifies which mode\n"
1002         "this hook should run in.  A mode must be specified when turning the JACK_HOOK.\n"
1003         "on.  However, all arguments are optional when turning it off.\n"
1004         "\n"
1005         "   Valid modes are:\n"
1006 #if 0
1007         /* XXX TODO */
1008         "    spy -        Create a read-only audio hook.  Only an output jack port will\n"
1009         "                 get created.\n"
1010         "    whisper -    Create a write-only audio hook.  Only an input jack port will\n"
1011         "                 get created.\n"
1012 #endif
1013         "    manipulate - Create a read/write audio hook.  Both an input and an output\n"
1014         "                 jack port will get created.  Audio from the channel will be\n"
1015         "                 sent out the output port and will be replaced by the audio\n"
1016         "                 coming in on the input port as it gets passed on.\n"
1017         "\n"
1018         "   Valid options are:\n"
1019         COMMON_OPTIONS
1020         "\n"
1021         " Examples:\n"
1022         "   To turn on the JACK_HOOK,\n"
1023         "     Set(JACK_HOOK(manipulate,i(pure_data_0:input0)o(pure_data_0:output0))=on)\n"
1024         "   To turn off the JACK_HOOK,\n"
1025         "     Set(JACK_HOOK()=off)\n"
1026         "",
1027         .write = jack_hook_write,
1028 };
1029
1030 static int unload_module(void)
1031 {
1032         int res;
1033
1034         res = ast_unregister_application(jack_app);
1035         res |= ast_custom_function_unregister(&jack_hook_function);
1036
1037         return res;
1038 }
1039
1040 static int load_module(void)
1041 {
1042         if (ast_register_application_xml(jack_app, jack_exec)) {
1043                 return AST_MODULE_LOAD_DECLINE;
1044         }
1045
1046         if (ast_custom_function_register(&jack_hook_function)) {
1047                 ast_unregister_application(jack_app);
1048                 return AST_MODULE_LOAD_DECLINE;
1049         }
1050
1051         return AST_MODULE_LOAD_SUCCESS;
1052 }
1053
1054 AST_MODULE_INFO_STANDARD_EXTENDED(ASTERISK_GPL_KEY, "JACK Interface");
1055