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