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