2 Copyright (C) 2001-2003 Paul Davis
3 Copyright (C) 2005 Jussi Laako
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 #include <jack/jack.h>
28 #include <jack/types.h>
29 #include <jack/internal.h>
30 #include <jack/engine.h>
31 #include <jack/pool.h>
32 #include <jack/port.h>
33 #include <jack/midiport.h>
34 #include <jack/jslist.h>
35 #include <jack/intsimd.h>
39 static void jack_generic_buffer_init(void *port_buffer
,
41 jack_nframes_t nframes
);
43 static void jack_audio_port_mixdown (jack_port_t
*port
,
44 jack_nframes_t nframes
);
46 /* These function pointers are local to each address space. For
47 * internal clients they reside within jackd; for external clients in
48 * the application process. */
49 jack_port_functions_t jack_builtin_audio_functions
= {
50 .buffer_init
= jack_generic_buffer_init
,
51 .mixdown
= jack_audio_port_mixdown
,
54 extern jack_port_functions_t jack_builtin_midi_functions
;
56 jack_port_functions_t jack_builtin_NULL_functions
= {
57 .buffer_init
= jack_generic_buffer_init
,
61 /* Only the Audio and MIDI port types are currently built in. */
62 jack_port_type_info_t jack_builtin_port_types
[] = {
63 { .type_name
= JACK_DEFAULT_AUDIO_TYPE
,
64 .buffer_scale_factor
= 1,
66 { .type_name
= JACK_DEFAULT_MIDI_TYPE
,
67 .buffer_scale_factor
= 1,
72 /* these functions have been taken from libDSP X86.c -jl */
76 static void (*opt_copy
) (float *, const float *, int);
77 static void (*opt_mix
) (float *, const float *, int);
80 gen_copyf (float *dest
, const float *src
, int length
)
82 memcpy(dest
, src
, length
* sizeof(float));
86 gen_mixf (float *dest
, const float *src
, int length
)
93 /*for (iSample = 0; iSample < iDataLength; iSample++)
94 fpDest[iSample] += fpSrc[iSample];*/
99 void jack_port_set_funcs ()
101 if (ARCH_X86_HAVE_SSE2(cpu_type
)) {
102 opt_copy
= x86_sse_copyf
;
103 opt_mix
= x86_sse_add2f
;
105 else if (ARCH_X86_HAVE_3DNOW(cpu_type
)) {
106 opt_copy
= x86_3dnow_copyf
;
107 opt_mix
= x86_3dnow_add2f
;
110 opt_copy
= gen_copyf
;
117 void jack_port_set_funcs ()
119 opt_copy
= gen_copyf
;
123 #endif /* ARCH_X86 */
125 #endif /* USE_DYNSIMD */
128 jack_port_name_equals (jack_port_shared_t
* port
, const char* target
)
130 char buf
[JACK_PORT_NAME_SIZE
+1];
132 /* this nasty, nasty kludge is here because between 0.109.0 and 0.109.1,
133 the ALSA audio backend had the name "ALSA", whereas as before and
134 after it, it was called "alsa_pcm". this stops breakage for
135 any setups that have saved "alsa_pcm" or "ALSA" in their connection
139 if (strncmp (target
, "ALSA:capture", 12) == 0 || strncmp (target
, "ALSA:playback", 13) == 0) {
140 snprintf (buf
, sizeof (buf
), "alsa_pcm%s", target
+4);
144 return (strcmp (port
->name
, target
) == 0 ||
145 strcmp (port
->alias1
, target
) == 0 ||
146 strcmp (port
->alias2
, target
) == 0);
149 jack_port_functions_t
*
150 jack_get_port_functions(jack_port_type_id_t ptid
)
153 case JACK_AUDIO_PORT_TYPE
:
154 return &jack_builtin_audio_functions
;
155 case JACK_MIDI_PORT_TYPE
:
156 return &jack_builtin_midi_functions
;
157 /* no other builtin functions */
164 * Fills buffer with zeroes. For audio ports, engine->silent_buffer relies on it.
167 jack_generic_buffer_init(void *buffer
, size_t size
, jack_nframes_t nframes
)
169 memset(buffer
, 0, size
);
174 jack_port_new (const jack_client_t
*client
, jack_port_id_t port_id
,
175 jack_control_t
*control
)
177 jack_port_shared_t
*shared
= &control
->ports
[port_id
];
178 jack_port_type_id_t ptid
= shared
->ptype_id
;
179 jack_port_t
*port
= (jack_port_t
*) malloc (sizeof (jack_port_t
));
181 port
->mix_buffer
= NULL
;
182 port
->client_segment_base
= NULL
;
183 port
->shared
= shared
;
184 port
->type_info
= &client
->engine
->port_types
[ptid
];
185 pthread_mutex_init (&port
->connection_lock
, NULL
);
186 port
->connections
= 0;
189 if (client
->control
->id
== port
->shared
->client_id
) {
191 /* It's our port, so initialize the pointers to port
192 * functions within this address space. These builtin
193 * definitions can be overridden by the client.
195 jack_port_functions_t
*port_functions
= jack_get_port_functions(ptid
);
196 if (port_functions
== NULL
)
197 port_functions
= &jack_builtin_NULL_functions
;
198 port
->fptr
= *port_functions
;
199 port
->shared
->has_mixdown
= (port
->fptr
.mixdown
? TRUE
: FALSE
);
202 /* set up a base address so that port->offset can be used to
203 compute the correct location. we don't store the location
204 directly, because port->client_segment_base and/or
205 port->offset can change if the buffer size or port counts
209 port
->client_segment_base
=
210 (void **) &client
->port_segment
[ptid
].attached_at
;
216 jack_port_register (jack_client_t
*client
,
217 const char *port_name
,
218 const char *port_type
,
220 unsigned long buffer_size
)
223 jack_port_t
*port
= 0;
226 req
.type
= RegisterPort
;
228 length
= strlen ((const char *) client
->control
->name
)
229 + 1 + strlen (port_name
);
230 if ( length
>= sizeof (req
.x
.port_info
.name
) ) {
231 jack_error ("\"%s:%s\" is too long to be used as a JACK port name.\n"
232 "Please use %lu characters or less.",
233 client
->control
->name
,
235 sizeof (req
.x
.port_info
.name
) - 1);
239 strcpy ((char *) req
.x
.port_info
.name
,
240 (const char *) client
->control
->name
);
241 strcat ((char *) req
.x
.port_info
.name
, ":");
242 strcat ((char *) req
.x
.port_info
.name
, port_name
);
244 snprintf (req
.x
.port_info
.type
, sizeof (req
.x
.port_info
.type
),
246 req
.x
.port_info
.flags
= flags
;
247 req
.x
.port_info
.buffer_size
= buffer_size
;
248 req
.x
.port_info
.client_id
= client
->control
->id
;
250 if (jack_client_deliver_request (client
, &req
)) {
251 jack_error ("cannot deliver port registration request");
255 if ((port
= jack_port_new (client
, req
.x
.port_info
.port_id
,
256 client
->engine
)) == NULL
) {
257 jack_error ("cannot allocate client side port structure");
261 client
->ports
= jack_slist_prepend (client
->ports
, port
);
267 jack_port_unregister (jack_client_t
*client
, jack_port_t
*port
)
271 req
.type
= UnRegisterPort
;
272 req
.x
.port_info
.port_id
= port
->shared
->id
;
273 req
.x
.port_info
.client_id
= client
->control
->id
;
275 return jack_client_deliver_request (client
, &req
);
278 /* LOCAL (in-client) connection querying only */
281 jack_port_connected (const jack_port_t
*port
)
283 return jack_slist_length (port
->connections
);
287 jack_port_connected_to (const jack_port_t
*port
, const char *portname
)
292 /* XXX this really requires a cross-process lock
293 so that ports/connections cannot go away
294 while we are checking for them. that's hard,
295 and has a non-trivial performance impact
299 pthread_mutex_lock (&((jack_port_t
*) port
)->connection_lock
);
301 for (node
= port
->connections
; node
; node
= jack_slist_next (node
)) {
302 jack_port_t
*other_port
= (jack_port_t
*) node
->data
;
304 if (jack_port_name_equals (other_port
->shared
, portname
)) {
310 pthread_mutex_unlock (&((jack_port_t
*) port
)->connection_lock
);
315 jack_port_get_connections (const jack_port_t
*port
)
317 const char **ret
= NULL
;
321 /* XXX this really requires a cross-process lock
322 so that ports/connections cannot go away
323 while we are checking for them. that's hard,
324 and has a non-trivial performance impact
328 pthread_mutex_lock (&((jack_port_t
*) port
)->connection_lock
);
330 if (port
->connections
!= NULL
) {
332 ret
= (const char **)
333 malloc (sizeof (char *)
334 * (jack_slist_length (port
->connections
) + 1));
335 for (n
= 0, node
= port
->connections
; node
;
336 node
= jack_slist_next (node
), ++n
) {
337 jack_port_t
* other
=(jack_port_t
*) node
->data
;
338 ret
[n
] = other
->shared
->name
;
343 pthread_mutex_unlock (&((jack_port_t
*) port
)->connection_lock
);
347 /* SERVER-SIDE (all) connection querying */
350 jack_port_get_all_connections (const jack_client_t
*client
,
351 const jack_port_t
*port
)
357 int need_free
= FALSE
;
363 req
.type
= GetPortConnections
;
365 req
.x
.port_info
.name
[0] = '\0';
366 req
.x
.port_info
.type
[0] = '\0';
367 req
.x
.port_info
.flags
= 0;
368 req
.x
.port_info
.buffer_size
= 0;
369 req
.x
.port_info
.client_id
= 0;
370 req
.x
.port_info
.port_id
= port
->shared
->id
;
372 jack_client_deliver_request (client
, &req
);
374 if (req
.status
!= 0 || req
.x
.port_connections
.nports
== 0) {
378 if (client
->request_fd
< 0) {
379 /* internal client, .ports is in our own address space */
380 return req
.x
.port_connections
.ports
;
383 ret
= (const char **)
384 malloc (sizeof (char *) * (req
.x
.port_connections
.nports
+ 1));
386 for (i
= 0; i
< req
.x
.port_connections
.nports
; ++i
) {
387 jack_port_id_t port_id
;
389 if (read (client
->request_fd
, &port_id
, sizeof (port_id
))
390 != sizeof (port_id
)) {
391 jack_error ("cannot read port id from server");
394 tmp
= jack_port_by_id_int (client
, port_id
, &need_free
);
395 ret
[i
] = tmp
->shared
->name
;
408 jack_port_by_id_int (const jack_client_t
*client
, jack_port_id_t id
, int* free
)
412 for (node
= client
->ports
; node
; node
= jack_slist_next (node
)) {
413 if (((jack_port_t
*) node
->data
)->shared
->id
== id
) {
415 return (jack_port_t
*) node
->data
;
419 if (id
>= client
->engine
->port_max
)
422 if (client
->engine
->ports
[id
].in_use
) {
424 return jack_port_new (client
, id
, client
->engine
);
431 jack_port_by_id (jack_client_t
*client
, jack_port_id_t id
)
435 int need_free
= FALSE
;
436 for (node
= client
->ports_ext
; node
; node
= jack_slist_next (node
)) {
438 if (port
->shared
->id
== id
) { // Found port, return the cached structure
443 // Otherwise possibly allocate a new port structure, keep it in the ports_ext list for later use
444 port
= jack_port_by_id_int (client
,id
,&need_free
);
445 if (port
!= NULL
&& need_free
)
447 jack_slist_prepend (client
->ports_ext
, port
);
452 jack_port_by_name_int (jack_client_t
*client
, const char *port_name
)
454 unsigned long i
, limit
;
455 jack_port_shared_t
*port
;
457 limit
= client
->engine
->port_max
;
458 port
= &client
->engine
->ports
[0];
460 for (i
= 0; i
< limit
; i
++) {
461 if (port
[i
].in_use
&& jack_port_name_equals (&port
[i
], port_name
)) {
462 return jack_port_new (client
, port
[i
].id
,
471 jack_port_by_name (jack_client_t
*client
, const char *port_name
)
475 for (node
= client
->ports_ext
; node
; node
= jack_slist_next (node
)) {
477 if (jack_port_name_equals (port
->shared
, port_name
)) {
478 /* Found port, return the cached structure. */
483 /* Otherwise allocate a new port structure, keep it in the
484 * ports_ext list for later use. */
485 port
= jack_port_by_name_int (client
, port_name
);
488 jack_slist_prepend (client
->ports_ext
, port
);
493 jack_port_get_latency (jack_port_t
*port
)
495 return port
->shared
->latency
;
499 jack_port_get_total_latency (jack_client_t
*client
, jack_port_t
*port
)
501 return port
->shared
->total_latency
;
505 jack_port_set_latency (jack_port_t
*port
, jack_nframes_t nframes
)
507 port
->shared
->latency
= nframes
;
511 jack_port_get_buffer (jack_port_t
*port
, jack_nframes_t nframes
)
515 /* Output port. The buffer was assigned by the engine
516 when the port was registered.
518 if (port
->shared
->flags
& JackPortIsOutput
) {
520 return jack_port_get_buffer (port
->tied
, nframes
);
523 return jack_output_port_buffer (port
);
526 /* Input port. Since this can only be called from the
527 process() callback, and since no connections can be
528 made/broken during this phase (enforced by the jack
529 server), there is no need to take the connection lock here
531 if ((node
= port
->connections
) == NULL
) {
533 /* no connections; return a zero-filled buffer */
534 return (void *) (*(port
->client_segment_base
) + port
->type_info
->zero_buffer_offset
);
537 if ((next
= jack_slist_next (node
)) == NULL
) {
539 /* one connection: use zero-copy mode - just pass
540 the buffer of the connected (output) port.
542 return jack_port_get_buffer (((jack_port_t
*) node
->data
),
546 /* Multiple connections. Use a local buffer and mix the
547 incoming data into that buffer. We have already
548 established the existence of a mixdown function during the
551 if (port
->mix_buffer
== NULL
) {
553 port
->type_info
->buffer_scale_factor
554 * sizeof (jack_default_audio_sample_t
)
556 port
->mix_buffer
= jack_pool_alloc (buffer_size
);
557 port
->fptr
.buffer_init (port
->mix_buffer
, buffer_size
, nframes
);
559 port
->fptr
.mixdown (port
, nframes
);
560 return (void *) port
->mix_buffer
;
564 jack_port_tie (jack_port_t
*src
, jack_port_t
*dst
)
567 if (dst
->shared
->client_id
!= src
->shared
->client_id
) {
568 jack_error ("cannot tie ports not owned by the same client");
572 if (dst
->shared
->flags
& JackPortIsOutput
) {
573 jack_error ("cannot tie an input port");
582 jack_port_untie (jack_port_t
*port
)
584 if (port
->tied
== NULL
) {
585 jack_error ("port \"%s\" is not tied", port
->shared
->name
);
593 jack_port_request_monitor (jack_port_t
*port
, int onoff
)
597 port
->shared
->monitor_requests
++;
598 } else if (port
->shared
->monitor_requests
) {
599 port
->shared
->monitor_requests
--;
602 if ((port
->shared
->flags
& JackPortIsOutput
) == 0) {
606 /* this port is for input, so recurse over each of the
610 pthread_mutex_lock (&port
->connection_lock
);
611 for (node
= port
->connections
; node
;
612 node
= jack_slist_next (node
)) {
614 /* drop the lock because if there is a feedback loop,
615 we will deadlock. XXX much worse things will
616 happen if there is a feedback loop !!!
619 pthread_mutex_unlock (&port
->connection_lock
);
620 jack_port_request_monitor ((jack_port_t
*) node
->data
,
622 pthread_mutex_lock (&port
->connection_lock
);
624 pthread_mutex_unlock (&port
->connection_lock
);
631 jack_port_request_monitor_by_name (jack_client_t
*client
,
632 const char *port_name
, int onoff
)
636 unsigned long i
, limit
;
637 jack_port_shared_t
*ports
;
639 limit
= client
->engine
->port_max
;
640 ports
= &client
->engine
->ports
[0];
642 for (i
= 0; i
< limit
; i
++) {
643 if (ports
[i
].in_use
&&
644 strcmp (ports
[i
].name
, port_name
) == 0) {
645 port
= jack_port_new (client
, ports
[i
].id
,
647 return jack_port_request_monitor (port
, onoff
);
657 jack_port_ensure_monitor (jack_port_t
*port
, int yn
)
660 if (port
->shared
->monitor_requests
== 0) {
661 port
->shared
->monitor_requests
++;
664 if (port
->shared
->monitor_requests
> 0) {
665 port
->shared
->monitor_requests
= 0;
673 jack_port_monitoring_input (jack_port_t
*port
)
675 return port
->shared
->monitor_requests
> 0;
679 jack_port_name (const jack_port_t
*port
)
681 return port
->shared
->name
;
685 jack_port_get_aliases (const jack_port_t
*port
, char* const aliases
[2])
689 if (port
->shared
->alias1
[0] != '\0') {
690 snprintf (aliases
[0], JACK_CLIENT_NAME_SIZE
+JACK_PORT_NAME_SIZE
, "%s", port
->shared
->alias1
);
694 if (port
->shared
->alias2
[0] != '\0') {
695 snprintf (aliases
[1], JACK_CLIENT_NAME_SIZE
+JACK_PORT_NAME_SIZE
, "%s", port
->shared
->alias2
);
703 jack_port_short_name (const jack_port_t
*port
)
705 /* we know there is always a colon, because we put
709 return strchr (port
->shared
->name
, ':') + 1;
713 jack_port_is_mine (const jack_client_t
*client
, const jack_port_t
*port
)
715 return port
->shared
->client_id
== client
->control
->id
;
719 jack_port_flags (const jack_port_t
*port
)
721 return port
->shared
->flags
;
725 jack_port_type (const jack_port_t
*port
)
727 return port
->type_info
->type_name
;
731 jack_port_set_name (jack_port_t
*port
, const char *new_name
)
736 colon
= strchr (port
->shared
->name
, ':');
737 len
= sizeof (port
->shared
->name
) -
738 ((int) (colon
- port
->shared
->name
)) - 2;
739 snprintf (colon
+1, len
, "%s", new_name
);
745 jack_port_set_alias (jack_port_t
*port
, const char *alias
)
747 if (port
->shared
->alias1
[0] == '\0') {
748 snprintf (port
->shared
->alias1
, sizeof (port
->shared
->alias1
), "%s", alias
);
749 } else if (port
->shared
->alias2
[0] == '\0') {
750 snprintf (port
->shared
->alias2
, sizeof (port
->shared
->alias2
), "%s", alias
);
759 jack_port_unset_alias (jack_port_t
*port
, const char *alias
)
761 if (strcmp (port
->shared
->alias1
, alias
) == 0) {
762 port
->shared
->alias1
[0] = '\0';
763 } else if (strcmp (port
->shared
->alias2
, alias
) == 0) {
764 port
->shared
->alias2
[0] = '\0';
773 /* AUDIO PORT SUPPORT */
775 static inline float f_max(float x
, float a
)
786 jack_audio_port_mixdown (jack_port_t
*port
, jack_nframes_t nframes
)
792 jack_default_audio_sample_t
*dst
, *src
;
794 jack_default_audio_sample_t
*buffer
;
796 /* by the time we've called this, we've already established
797 the existence of more than one connection to this input
798 port and allocated a mix_buffer.
801 /* no need to take connection lock, since this is called
802 from the process() callback, and the jack server
803 ensures that no changes to connections happen
807 node
= port
->connections
;
808 input
= (jack_port_t
*) node
->data
;
809 buffer
= port
->mix_buffer
;
812 memcpy (buffer
, jack_output_port_buffer (input
),
813 sizeof (jack_default_audio_sample_t
) * nframes
);
814 #else /* USE_DYNSIMD */
815 opt_copy (buffer
, jack_output_port_buffer (input
), nframes
);
816 #endif /* USE_DYNSIMD */
818 for (node
= jack_slist_next (node
); node
;
819 node
= jack_slist_next (node
)) {
821 input
= (jack_port_t
*) node
->data
;
826 src
= jack_output_port_buffer (input
);
831 #else /* USE_DYNSIMD */
832 opt_mix (buffer
, jack_output_port_buffer (input
), nframes
);
833 #endif /* USE_DYNSIMD */