static void jack_audio_port_mixdown (jack_port_t *port, jack_nframes_t nframes) { JSList *node; jack_port_t *input; #ifndef ARCH_X86 jack_nframes_t n; jack_default_audio_sample_t *dst, *src; #endif jack_default_audio_sample_t *buffer; /* by the time we've called this, we've already established the existence of more than one connection to this input port and allocated a mix_buffer. */ /* no need to take connection lock, since this is called from the process() callback, and the jack server ensures that no changes to connections happen during this time. */ node = port->connections; input = (jack_port_t*)node->data; buffer = port->mix_buffer; #ifndef USE_DYNSIMD memcpy (buffer, jack_output_port_buffer (input), sizeof(jack_default_audio_sample_t) * nframes); #else /* USE_DYNSIMD */ opt_copy (buffer, jack_output_port_buffer (input), nframes); #endif /* USE_DYNSIMD */ for (node = jack_slist_next (node); node; node = jack_slist_next (node)) { input = (jack_port_t*)node->data; #ifndef USE_DYNSIMD n = nframes; dst = buffer; src = jack_output_port_buffer (input); while (n--) *dst++ += *src++; #else /* USE_DYNSIMD */ opt_mix (buffer, jack_output_port_buffer (input), nframes); #endif /* USE_DYNSIMD */ } }
void * jack_port_get_buffer (jack_port_t *port, jack_nframes_t nframes) { JSList *node, *next; /* Output port. The buffer was assigned by the engine when the port was registered. */ if (port->shared->flags & JackPortIsOutput) { if (port->tied) { return jack_port_get_buffer (port->tied, nframes); } if (port->client_segment_base == NULL || *port->client_segment_base == MAP_FAILED) { return NULL; } return jack_output_port_buffer (port); } /* Input port. Since this can only be called from the process() callback, and since no connections can be made/broken during this phase (enforced by the jack server), there is no need to take the connection lock here */ if ((node = port->connections) == NULL) { if (port->client_segment_base == NULL || *port->client_segment_base == MAP_FAILED) { return NULL; } /* no connections; return a zero-filled buffer */ return (void *) (*(port->client_segment_base) + port->type_info->zero_buffer_offset); } if ((next = jack_slist_next (node)) == NULL) { /* one connection: use zero-copy mode - just pass the buffer of the connected (output) port. */ return jack_port_get_buffer (((jack_port_t *) node->data), nframes); } /* Multiple connections. Use a local buffer and mix the incoming data into that buffer. We have already established the existence of a mixdown function during the connection process. */ if (port->mix_buffer == NULL) { jack_error( "internal jack error: mix_buffer not allocated" ); return NULL; } port->fptr.mixdown (port, nframes); return (void *) port->mix_buffer; }