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