| 
							- 
 - /*
 -  * NetJack - Packet Handling functions
 -  *
 -  * used by the driver and the jacknet_client
 -  *
 -  * Copyright (C) 2008 Marc-Olivier Barre <marco@marcochapeau.org>
 -  * Copyright (C) 2008 Pieter Palmers <pieterpalmers@users.sourceforge.net>
 -  * Copyright (C) 2006 Torben Hohn <torbenh@gmx.de>
 -  *
 -  * This program is free software; you can redistribute it and/or modify
 -  * it under the terms of the GNU General Public License as published by
 -  * the Free Software Foundation; either version 2 of the License, or
 -  * (at your option) any later version.
 -  *
 -  * This program is distributed in the hope that it will be useful,
 -  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 -  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 -  * GNU General Public License for more details.
 -  *
 -  * You should have received a copy of the GNU General Public License
 -  * along with this program; if not, write to the Free Software
 -  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 -  *
 -  * $Id: net_driver.c,v 1.16 2006/03/20 19:41:37 torbenh Exp $
 -  *
 -  */
 - 
 - //#include "config.h"
 - 
 - #ifdef __APPLE__
 - #define _DARWIN_C_SOURCE
 - #endif
 - 
 - #if HAVE_PPOLL
 - #define _GNU_SOURCE
 - #endif
 - 
 - #include <math.h>
 - #include <stdio.h>
 - #include <memory.h>
 - #include <unistd.h>
 - #include <stdlib.h>
 - #include <errno.h>
 - #include <stdarg.h>
 - 
 - #include <jack/types.h>
 - 
 - #include <sys/types.h>
 - 
 - #ifdef WIN32
 - #include <winsock2.h>
 - #define socklen_t int
 - #include <malloc.h>
 - #else
 - #include <sys/socket.h>
 - #include <netinet/in.h>
 - #include <poll.h>
 - #endif
 - 
 - #include <errno.h>
 - #include <signal.h>
 - 
 - #if HAVE_SAMPLERATE
 - #include <samplerate.h>
 - #endif
 - 
 - #if HAVE_CELT
 - #include <celt/celt.h>
 - #endif
 - 
 - #include "netjack_packet.h"
 - 
 - // JACK2 specific.
 - #include "jack/control.h"
 - 
 - #ifdef NO_JACK_ERROR
 - #define jack_error printf
 - #endif
 - 
 - int fraggo = 0;
 - 
 - packet_cache *global_packcache = NULL;
 - 
 - void
 - packet_header_hton (jacknet_packet_header *pkthdr)
 - {
 -     pkthdr->capture_channels_audio = htonl(pkthdr->capture_channels_audio);
 -     pkthdr->playback_channels_audio = htonl(pkthdr->playback_channels_audio);
 -     pkthdr->capture_channels_midi = htonl(pkthdr->capture_channels_midi);
 -     pkthdr->playback_channels_midi = htonl(pkthdr->playback_channels_midi);
 -     pkthdr->period_size = htonl(pkthdr->period_size);
 -     pkthdr->sample_rate = htonl(pkthdr->sample_rate);
 -     pkthdr->sync_state = htonl(pkthdr->sync_state);
 -     pkthdr->transport_frame = htonl(pkthdr->transport_frame);
 -     pkthdr->transport_state = htonl(pkthdr->transport_state);
 -     pkthdr->framecnt = htonl(pkthdr->framecnt);
 -     pkthdr->latency = htonl(pkthdr->latency);
 -     pkthdr->reply_port = htonl(pkthdr->reply_port);
 -     pkthdr->mtu = htonl(pkthdr->mtu);
 -     pkthdr->fragment_nr = htonl(pkthdr->fragment_nr);
 - }
 - 
 - void
 - packet_header_ntoh (jacknet_packet_header *pkthdr)
 - {
 -     pkthdr->capture_channels_audio = ntohl(pkthdr->capture_channels_audio);
 -     pkthdr->playback_channels_audio = ntohl(pkthdr->playback_channels_audio);
 -     pkthdr->capture_channels_midi = ntohl(pkthdr->capture_channels_midi);
 -     pkthdr->playback_channels_midi = ntohl(pkthdr->playback_channels_midi);
 -     pkthdr->period_size = ntohl(pkthdr->period_size);
 -     pkthdr->sample_rate = ntohl(pkthdr->sample_rate);
 -     pkthdr->sync_state = ntohl(pkthdr->sync_state);
 -     pkthdr->transport_frame = ntohl(pkthdr->transport_frame);
 -     pkthdr->transport_state = ntohl(pkthdr->transport_state);
 -     pkthdr->framecnt = ntohl(pkthdr->framecnt);
 -     pkthdr->latency = ntohl(pkthdr->latency);
 -     pkthdr->reply_port = ntohl(pkthdr->reply_port);
 -     pkthdr->mtu = ntohl(pkthdr->mtu);
 -     pkthdr->fragment_nr = ntohl(pkthdr->fragment_nr);
 - }
 - 
 - int get_sample_size (int bitdepth)
 - {
 -     if (bitdepth == 8)
 -         return sizeof (int8_t);
 -     if (bitdepth == 16)
 -         return sizeof (int16_t);
 -     //JN: why? is this for buffer sizes before or after encoding?
 -     //JN: if the former, why not int16_t, if the latter, shouldn't it depend on -c N?    
 -     if( bitdepth == CELT_MODE )
 - 	return sizeof( unsigned char );
 -     return sizeof (int32_t);
 - }
 - 
 - int jack_port_is_audio(const char *porttype)
 - {
 -     return (strncmp (porttype, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0);
 - }
 - 
 - int jack_port_is_midi(const char *porttype)
 - {
 -     return (strncmp (porttype, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0);
 - }
 - 
 - 
 - // fragment management functions.
 - 
 - packet_cache
 - *packet_cache_new (int num_packets, int pkt_size, int mtu)
 - {
 -     int fragment_payload_size = mtu - sizeof (jacknet_packet_header);
 -     int i, fragment_number;
 - 
 -     if( pkt_size == sizeof(jacknet_packet_header) )
 - 	    fragment_number = 1;
 -     else
 - 	    fragment_number = (pkt_size - sizeof (jacknet_packet_header) - 1) / fragment_payload_size + 1;
 - 
 -     packet_cache *pcache = malloc (sizeof (packet_cache));
 -     if (pcache == NULL)
 -     {
 -         jack_error ("could not allocate packet cache (1)");
 -         return NULL;
 -     }
 - 
 -     pcache->size = num_packets;
 -     pcache->packets = malloc (sizeof (cache_packet) * num_packets);
 -     pcache->master_address_valid = 0;
 -     pcache->last_framecnt_retreived = 0;
 -     pcache->last_framecnt_retreived_valid = 0;
 - 
 -     if (pcache->packets == NULL)
 -     {
 -         jack_error ("could not allocate packet cache (2)");
 -         return NULL;
 -     }
 - 
 -     for (i = 0; i < num_packets; i++)
 -     {
 -         pcache->packets[i].valid = 0;
 -         pcache->packets[i].num_fragments = fragment_number;
 -         pcache->packets[i].packet_size = pkt_size;
 -         pcache->packets[i].mtu = mtu;
 -         pcache->packets[i].framecnt = 0;
 -         pcache->packets[i].fragment_array = malloc (sizeof (char) * fragment_number);
 -         pcache->packets[i].packet_buf = malloc (pkt_size);
 -         if ((pcache->packets[i].fragment_array == NULL) || (pcache->packets[i].packet_buf == NULL))
 -         {
 -             jack_error ("could not allocate packet cache (3)");
 -             return NULL;
 -         }
 -     }
 -     pcache->mtu = mtu;
 - 
 -     return pcache;
 - }
 - 
 - void
 - packet_cache_free (packet_cache *pcache)
 - {
 -     int i;
 -     if( pcache == NULL )
 - 	return;
 - 
 -     for (i = 0; i < pcache->size; i++)
 -     {
 -         free (pcache->packets[i].fragment_array);
 -         free (pcache->packets[i].packet_buf);
 -     }
 - 
 -     free (pcache->packets);
 -     free (pcache);
 - }
 - 
 - cache_packet
 - *packet_cache_get_packet (packet_cache *pcache, jack_nframes_t framecnt)
 - {
 -     int i;
 -     cache_packet *retval;
 - 
 -     for (i = 0; i < pcache->size; i++)
 -     {
 -         if (pcache->packets[i].valid && (pcache->packets[i].framecnt == framecnt))
 -             return &(pcache->packets[i]);
 -     }
 - 
 -     // The Packet is not in the packet cache.
 -     // find a free packet.
 - 
 -     retval = packet_cache_get_free_packet (pcache);
 -     if (retval != NULL)
 -     {
 -         cache_packet_set_framecnt (retval, framecnt);
 -         return retval;
 -     }
 - 
 -     // No Free Packet available
 -     // Get The Oldest packet and reset it.
 - 
 -     retval = packet_cache_get_oldest_packet (pcache);
 -     //printf( "Dropping %d from Cache :S\n", retval->framecnt );
 -     cache_packet_reset (retval);
 -     cache_packet_set_framecnt (retval, framecnt);
 - 
 -     return retval;
 - }
 - 
 - // TODO: fix wrapping case... need to pass
 - //       current expected frame here.
 - //
 - //       or just save framecount into packet_cache.
 - 
 - cache_packet
 - *packet_cache_get_oldest_packet (packet_cache *pcache)
 - {
 -     jack_nframes_t minimal_frame = JACK_MAX_FRAMES;
 -     cache_packet *retval = &(pcache->packets[0]);
 -     int i;
 - 
 -     for (i = 0; i < pcache->size; i++)
 -     {
 -         if (pcache->packets[i].valid && (pcache->packets[i].framecnt < minimal_frame))
 -         {
 -             minimal_frame = pcache->packets[i].framecnt;
 -             retval = &(pcache->packets[i]);
 -         }
 -     }
 - 
 -     return retval;
 - }
 - 
 - cache_packet
 - *packet_cache_get_free_packet (packet_cache *pcache)
 - {
 -     int i;
 - 
 -     for (i = 0; i < pcache->size; i++)
 -     {
 -         if (pcache->packets[i].valid == 0)
 -             return &(pcache->packets[i]);
 -     }
 - 
 -     return NULL;
 - }
 - 
 - void
 - cache_packet_reset (cache_packet *pack)
 - {
 -     int i;
 -     pack->valid = 0;
 - 
 -     // XXX: i dont think this is necessary here...
 -     //      fragement array is cleared in _set_framecnt()
 - 
 -     for (i = 0; i < pack->num_fragments; i++)
 -         pack->fragment_array[i] = 0;
 - }
 - 
 - void
 - cache_packet_set_framecnt (cache_packet *pack, jack_nframes_t framecnt)
 - {
 -     int i;
 - 
 -     pack->framecnt = framecnt;
 - 
 -     for (i = 0; i < pack->num_fragments; i++)
 -         pack->fragment_array[i] = 0;
 - 
 -     pack->valid = 1;
 - }
 - 
 - void
 - cache_packet_add_fragment (cache_packet *pack, char *packet_buf, int rcv_len)
 - {
 -     jacknet_packet_header *pkthdr = (jacknet_packet_header *) packet_buf;
 -     int fragment_payload_size = pack->mtu - sizeof (jacknet_packet_header);
 -     char *packet_bufX = pack->packet_buf + sizeof (jacknet_packet_header);
 -     char *dataX = packet_buf + sizeof (jacknet_packet_header);
 - 
 -     jack_nframes_t fragment_nr = ntohl (pkthdr->fragment_nr);
 -     jack_nframes_t framecnt    = ntohl (pkthdr->framecnt);
 - 
 -     if (framecnt != pack->framecnt)
 -     {
 -         jack_error ("errror. framecnts dont match");
 -         return;
 -     }
 - 
 - 
 -     if (fragment_nr == 0)
 -     {
 -         memcpy (pack->packet_buf, packet_buf, rcv_len);
 -         pack->fragment_array[0] = 1;
 - 
 -         return;
 -     }
 - 
 -     if ((fragment_nr < pack->num_fragments) && (fragment_nr > 0))
 -     {
 -         if ((fragment_nr * fragment_payload_size + rcv_len - sizeof (jacknet_packet_header)) <= (pack->packet_size - sizeof (jacknet_packet_header)))
 -         {
 -             memcpy (packet_bufX + fragment_nr * fragment_payload_size, dataX, rcv_len - sizeof (jacknet_packet_header));
 -             pack->fragment_array[fragment_nr] = 1;
 -         }
 -         else
 -             jack_error ("too long packet received...");
 -     }
 - }
 - 
 - int
 - cache_packet_is_complete (cache_packet *pack)
 - {
 -     int i;
 -     for (i = 0; i < pack->num_fragments; i++)
 -         if (pack->fragment_array[i] == 0)
 -             return 0;
 - 
 -     return 1;
 - }
 - 
 - #ifndef WIN32
 - // new poll using nanoseconds resolution and
 - // not waiting forever.
 - int
 - netjack_poll_deadline (int sockfd, jack_time_t deadline)
 - {
 -     struct pollfd fds;
 -     int poll_err = 0;
 - #if HAVE_PPOLL
 -     struct timespec timeout_spec = { 0, 0 };
 - #else
 -     int timeout;
 - #endif
 - 
 - 
 -     jack_time_t now = jack_get_time();
 -     if( now >= deadline )
 - 	return 0;
 - 
 -     if( (deadline-now) >= 1000000 ) {
 - 	    jack_error( "deadline more than 1 second in the future, trimming it." );
 - 	    deadline = now+500000;
 -     }
 - #if HAVE_PPOLL
 -     timeout_spec.tv_nsec = (deadline - now) * 1000;
 - #else
 -     timeout = (deadline - now + 500) / 1000;
 - #endif
 - 
 - 
 -     fds.fd = sockfd;
 -     fds.events = POLLIN;
 - 
 - #if HAVE_PPOLL
 -     poll_err = ppoll (&fds, 1, &timeout_spec, NULL);
 - #else
 -     poll_err = poll (&fds, 1, timeout);
 - #endif
 - 
 -     if (poll_err == -1)
 -     {
 -         switch (errno)
 -         {
 -             case EBADF:
 -             jack_error ("Error %d: An invalid file descriptor was given in one of the sets", errno);
 -             break;
 -             case EFAULT:
 -             jack_error ("Error %d: The array given as argument was not contained in the calling program's address space", errno);
 -             break;
 -             case EINTR:
 -             jack_error ("Error %d: A signal occurred before any requested event", errno);
 -             break;
 -             case EINVAL:
 -             jack_error ("Error %d: The nfds value exceeds the RLIMIT_NOFILE value", errno);
 -             break;
 -             case ENOMEM:
 -             jack_error ("Error %d: There was no space to allocate file descriptor tables", errno);
 -             break;
 -         }
 -     }
 -     return poll_err;
 - }
 - 
 - int
 - netjack_poll (int sockfd, int timeout)
 - {
 -     struct pollfd fds;
 -     int i, poll_err = 0;
 -     sigset_t sigmask, rsigmask;
 -     struct sigaction action;
 - 
 -     sigemptyset(&sigmask);
 - 	sigaddset(&sigmask, SIGHUP);
 - 	sigaddset(&sigmask, SIGINT);
 - 	sigaddset(&sigmask, SIGQUIT);
 - 	sigaddset(&sigmask, SIGPIPE);
 - 	sigaddset(&sigmask, SIGTERM);
 - 	sigaddset(&sigmask, SIGUSR1);
 - 	sigaddset(&sigmask, SIGUSR2);
 - 
 - 	action.sa_handler = SIG_DFL;
 - 	action.sa_mask = sigmask;
 - 	action.sa_flags = SA_RESTART;
 - 
 -     for (i = 1; i < NSIG; i++)
 -         if (sigismember (&sigmask, i))
 -             sigaction (i, &action, 0);
 - 
 -     fds.fd = sockfd;
 -     fds.events = POLLIN;
 - 
 -     sigprocmask(SIG_UNBLOCK, &sigmask, &rsigmask);
 -     while (poll_err == 0)
 -     {
 -         poll_err = poll (&fds, 1, timeout);
 -     }
 -     sigprocmask(SIG_SETMASK, &rsigmask, NULL);
 - 
 -     if (poll_err == -1)
 -     {
 -         switch (errno)
 -         {
 -             case EBADF:
 -             jack_error ("Error %d: An invalid file descriptor was given in one of the sets", errno);
 -             break;
 -             case EFAULT:
 -             jack_error ("Error %d: The array given as argument was not contained in the calling program's address space", errno);
 -             break;
 -             case EINTR:
 -             jack_error ("Error %d: A signal occurred before any requested event", errno);
 -             break;
 -             case EINVAL:
 -             jack_error ("Error %d: The nfds value exceeds the RLIMIT_NOFILE value", errno);
 -             break;
 -             case ENOMEM:
 -             jack_error ("Error %d: There was no space to allocate file descriptor tables", errno);
 -             break;
 -         }
 -         return 0;
 -     }
 -     return 1;
 - }
 - 
 - #else
 - int
 - netjack_poll (int sockfd, int timeout)
 - {
 -     jack_error( "netjack_poll not implemented" );
 -     return 0;
 - }
 - int
 - netjack_poll_deadline (int sockfd, jack_time_t deadline)
 - {
 -     fd_set fds;
 -     FD_ZERO( &fds );
 -     FD_SET( sockfd, &fds );
 - 
 -     struct timeval timeout;
 -     while( 1 ) {
 -         jack_time_t now = jack_get_time();
 -         if( now >= deadline )
 -                 return 0;
 - 
 -         int timeout_usecs = (deadline - now);
 -     //jack_error( "timeout = %d", timeout_usecs );
 -         timeout.tv_sec = 0;
 -         timeout.tv_usec = (timeout_usecs < 500) ? 500 : timeout_usecs;
 -         timeout.tv_usec = (timeout_usecs > 1000000) ? 500000 : timeout_usecs;
 - 
 -         int poll_err = select (0, &fds, NULL, NULL, &timeout);
 -         if( poll_err != 0 )
 -             return poll_err;
 -     }
 - 
 -     return 0;
 - }
 - #endif
 - // This now reads all a socket has into the cache.
 - // replacing netjack_recv functions.
 - 
 - void
 - packet_cache_drain_socket( packet_cache *pcache, int sockfd )
 - {
 -     char *rx_packet = alloca (pcache->mtu);
 -     jacknet_packet_header *pkthdr = (jacknet_packet_header *) rx_packet;
 -     int rcv_len;
 -     jack_nframes_t framecnt;
 -     cache_packet *cpack;
 -     struct sockaddr_in sender_address;
 - #ifdef WIN32
 -     size_t senderlen = sizeof( struct sockaddr_in );
 -     u_long parm = 1;
 -     ioctlsocket( sockfd, FIONBIO, &parm );
 - #else
 -     socklen_t senderlen = sizeof( struct sockaddr_in );
 - #endif
 -     while (1)
 -     {
 - #ifdef WIN32
 -         rcv_len = recvfrom (sockfd, rx_packet, pcache->mtu, 0,
 - 			    (struct sockaddr*) &sender_address, &senderlen);
 - #else
 -         rcv_len = recvfrom (sockfd, rx_packet, pcache->mtu, MSG_DONTWAIT,
 - 			    (struct sockaddr*) &sender_address, &senderlen);
 - #endif
 -         if (rcv_len < 0)
 -             return;
 - 
 - 	if (pcache->master_address_valid) {
 - 	    // Verify its from our master.
 - 	    if (memcmp (&sender_address, &(pcache->master_address), senderlen) != 0)
 - 		continue;
 - 	} else {
 - 	    // Setup this one as master
 - 	    //printf( "setup master...\n" );
 - 	    memcpy ( &(pcache->master_address), &sender_address, senderlen );
 - 	    pcache->master_address_valid = 1;
 - 	}
 - 
 -         framecnt = ntohl (pkthdr->framecnt);
 - 	if( pcache->last_framecnt_retreived_valid && (framecnt <= pcache->last_framecnt_retreived ))
 - 	    continue;
 - 
 -         cpack = packet_cache_get_packet (global_packcache, framecnt);
 -         cache_packet_add_fragment (cpack, rx_packet, rcv_len);
 - 	cpack->recv_timestamp = jack_get_time();
 -     }
 - }
 - 
 - void
 - packet_cache_reset_master_address( packet_cache *pcache )
 - {
 -     pcache->master_address_valid = 0;
 -     pcache->last_framecnt_retreived = 0;
 -     pcache->last_framecnt_retreived_valid = 0;
 - }
 - 
 - void
 - packet_cache_clear_old_packets (packet_cache *pcache, jack_nframes_t framecnt )
 - {
 -     int i;
 - 
 -     for (i = 0; i < pcache->size; i++)
 -     {
 -         if (pcache->packets[i].valid && (pcache->packets[i].framecnt < framecnt))
 -         {
 -             cache_packet_reset (&(pcache->packets[i]));
 -         }
 -     }
 - }
 - 
 - int
 - packet_cache_retreive_packet_pointer( packet_cache *pcache, jack_nframes_t framecnt, char **packet_buf, int pkt_size, jack_time_t *timestamp )
 - {
 -     int i;
 -     cache_packet *cpack = NULL;
 - 
 - 
 -     for (i = 0; i < pcache->size; i++) {
 -         if (pcache->packets[i].valid && (pcache->packets[i].framecnt == framecnt)) {
 - 	    cpack = &(pcache->packets[i]);
 -             break;
 - 	}
 -     }
 - 
 -     if( cpack == NULL ) {
 - 	//printf( "retreive packet: %d....not found\n", framecnt );
 - 	return -1;
 -     }
 - 
 -     if( !cache_packet_is_complete( cpack ) ) {
 - 	return -1;
 -     }
 - 
 -     // ok. cpack is the one we want and its complete.
 -     *packet_buf = cpack->packet_buf;
 -     if( timestamp )
 - 	*timestamp = cpack->recv_timestamp;
 - 
 -     pcache->last_framecnt_retreived_valid = 1;
 -     pcache->last_framecnt_retreived = framecnt;
 - 
 -     return pkt_size;
 - }
 - 
 - int
 - packet_cache_release_packet( packet_cache *pcache, jack_nframes_t framecnt )
 - {
 -     int i;
 -     cache_packet *cpack = NULL;
 - 
 - 
 -     for (i = 0; i < pcache->size; i++) {
 -         if (pcache->packets[i].valid && (pcache->packets[i].framecnt == framecnt)) {
 - 	    cpack = &(pcache->packets[i]);
 -             break;
 - 	}
 -     }
 - 
 -     if( cpack == NULL ) {
 - 	//printf( "retreive packet: %d....not found\n", framecnt );
 - 	return -1;
 -     }
 - 
 -     if( !cache_packet_is_complete( cpack ) ) {
 - 	return -1;
 -     }
 - 
 -     cache_packet_reset (cpack);
 -     packet_cache_clear_old_packets( pcache, framecnt );
 - 
 -     return 0;
 - }
 - float
 - packet_cache_get_fill( packet_cache *pcache, jack_nframes_t expected_framecnt )
 - {
 -     int num_packets_before_us = 0;
 -     int i;
 - 
 -     for (i = 0; i < pcache->size; i++)
 -     {
 - 	cache_packet *cpack = &(pcache->packets[i]);
 -         if (cpack->valid && cache_packet_is_complete( cpack ))
 - 	    if( cpack->framecnt >= expected_framecnt )
 - 		num_packets_before_us += 1;
 -     }
 - 
 -     return 100.0 * (float)num_packets_before_us / (float)( pcache->size ) ;
 - }
 - 
 - // Returns 0 when no valid packet is inside the cache.
 - int
 - packet_cache_get_next_available_framecnt( packet_cache *pcache, jack_nframes_t expected_framecnt, jack_nframes_t *framecnt )
 - {
 -     int i;
 -     jack_nframes_t best_offset = JACK_MAX_FRAMES/2-1;
 -     int retval = 0;
 - 
 -     for (i = 0; i < pcache->size; i++)
 -     {
 - 	cache_packet *cpack = &(pcache->packets[i]);
 - 	//printf( "p%d: valid=%d, frame %d\n", i, cpack->valid, cpack->framecnt );
 - 
 -         if (!cpack->valid || !cache_packet_is_complete( cpack )) {
 - 	    //printf( "invalid\n" );
 - 	    continue;
 - 	}
 - 
 - 	if( cpack->framecnt < expected_framecnt )
 - 	    continue;
 - 
 - 	if( (cpack->framecnt - expected_framecnt) > best_offset ) {
 - 	    continue;
 - 	}
 - 
 - 	best_offset = cpack->framecnt - expected_framecnt;
 - 	retval = 1;
 - 
 - 	if( best_offset == 0 )
 - 	    break;
 -     }
 -     if( retval && framecnt )
 - 	*framecnt = expected_framecnt + best_offset;
 - 
 -     return retval;
 - }
 - 
 - int
 - packet_cache_get_highest_available_framecnt( packet_cache *pcache, jack_nframes_t *framecnt )
 - {
 -     int i;
 -     jack_nframes_t best_value = 0;
 -     int retval = 0;
 - 
 -     for (i = 0; i < pcache->size; i++)
 -     {
 - 	cache_packet *cpack = &(pcache->packets[i]);
 - 	//printf( "p%d: valid=%d, frame %d\n", i, cpack->valid, cpack->framecnt );
 - 
 -         if (!cpack->valid || !cache_packet_is_complete( cpack )) {
 - 	    //printf( "invalid\n" );
 - 	    continue;
 - 	}
 - 
 - 	if (cpack->framecnt < best_value) {
 - 	    continue;
 - 	}
 - 
 - 	best_value = cpack->framecnt;
 - 	retval = 1;
 - 
 -     }
 -     if( retval && framecnt )
 - 	*framecnt = best_value;
 - 
 -     return retval;
 - }
 - 
 - // Returns 0 when no valid packet is inside the cache.
 - int
 - packet_cache_find_latency( packet_cache *pcache, jack_nframes_t expected_framecnt, jack_nframes_t *framecnt )
 - {
 -     int i;
 -     jack_nframes_t best_offset = 0;
 -     int retval = 0;
 - 
 -     for (i = 0; i < pcache->size; i++)
 -     {
 - 	cache_packet *cpack = &(pcache->packets[i]);
 - 	//printf( "p%d: valid=%d, frame %d\n", i, cpack->valid, cpack->framecnt );
 - 
 -         if (!cpack->valid || !cache_packet_is_complete( cpack )) {
 - 	    //printf( "invalid\n" );
 - 	    continue;
 - 	}
 - 
 - 	if( (cpack->framecnt - expected_framecnt) < best_offset ) {
 - 	    continue;
 - 	}
 - 
 - 	best_offset = cpack->framecnt - expected_framecnt;
 - 	retval = 1;
 - 
 - 	if( best_offset == 0 )
 - 	    break;
 -     }
 -     if( retval && framecnt )
 - 	*framecnt = JACK_MAX_FRAMES - best_offset;
 - 
 -     return retval;
 - }
 - // fragmented packet IO
 - int
 - netjack_recvfrom (int sockfd, char *packet_buf, int pkt_size, int flags, struct sockaddr *addr, size_t *addr_size, int mtu)
 - {
 -     int retval;
 -     socklen_t from_len = *addr_size;
 -     if (pkt_size <= mtu) {
 -         retval = recvfrom (sockfd, packet_buf, pkt_size, flags, addr, &from_len);
 - 	*addr_size = from_len;
 - 	return retval;
 -     }
 - 
 -     char *rx_packet = alloca (mtu);
 -     jacknet_packet_header *pkthdr = (jacknet_packet_header *) rx_packet;
 -     int rcv_len;
 -     jack_nframes_t framecnt;
 -     cache_packet *cpack;
 -     do
 -     {
 -         rcv_len = recvfrom (sockfd, rx_packet, mtu, 0, addr, &from_len);
 -         if (rcv_len < 0)
 -             return rcv_len;
 -         framecnt = ntohl (pkthdr->framecnt);
 -         cpack = packet_cache_get_packet (global_packcache, framecnt);
 -         cache_packet_add_fragment (cpack, rx_packet, rcv_len);
 -     } while (!cache_packet_is_complete (cpack));
 -     memcpy (packet_buf, cpack->packet_buf, pkt_size);
 -     cache_packet_reset (cpack);
 -     *addr_size = from_len;
 -     return pkt_size;
 - }
 - 
 - int
 - netjack_recv (int sockfd, char *packet_buf, int pkt_size, int flags, int mtu)
 - {
 -     if (pkt_size <= mtu)
 -         return recv (sockfd, packet_buf, pkt_size, flags);
 -     char *rx_packet = alloca (mtu);
 -     jacknet_packet_header *pkthdr = (jacknet_packet_header *) rx_packet;
 -     int rcv_len;
 -     jack_nframes_t framecnt;
 -     cache_packet *cpack;
 -     do
 -     {
 -         rcv_len = recv (sockfd, rx_packet, mtu, flags);
 -         if (rcv_len < 0)
 -             return rcv_len;
 -         framecnt = ntohl (pkthdr->framecnt);
 -         cpack = packet_cache_get_packet (global_packcache, framecnt);
 -         cache_packet_add_fragment (cpack, rx_packet, rcv_len);
 -     } while (!cache_packet_is_complete (cpack));
 -     memcpy (packet_buf, cpack->packet_buf, pkt_size);
 -     cache_packet_reset (cpack);
 -     return pkt_size;
 - }
 - 
 - void
 - netjack_sendto (int sockfd, char *packet_buf, int pkt_size, int flags, struct sockaddr *addr, int addr_size, int mtu)
 - {
 -     int frag_cnt = 0;
 -     char *tx_packet, *dataX;
 -     jacknet_packet_header *pkthdr;
 - 
 -     tx_packet = alloca (mtu + 10);
 -     dataX = tx_packet + sizeof (jacknet_packet_header);
 -     pkthdr = (jacknet_packet_header *) tx_packet;
 - 
 -     int fragment_payload_size = mtu - sizeof (jacknet_packet_header);
 - 
 -     if (pkt_size <= mtu) {
 - 	int err;
 - 	pkthdr = (jacknet_packet_header *) packet_buf;
 -         pkthdr->fragment_nr = htonl (0);
 -         err = sendto(sockfd, packet_buf, pkt_size, flags, addr, addr_size);
 - 	if( err<0 ) {
 - 	    //printf( "error in send\n" );
 - 	    perror( "send" );
 - 	}
 -     }
 -     else
 -     {
 - 	int err;
 -         // Copy the packet header to the tx pack first.
 -         memcpy(tx_packet, packet_buf, sizeof (jacknet_packet_header));
 - 
 -         // Now loop and send all
 -         char *packet_bufX = packet_buf + sizeof (jacknet_packet_header);
 - 
 -         while (packet_bufX < (packet_buf + pkt_size - fragment_payload_size))
 -         {
 -             pkthdr->fragment_nr = htonl (frag_cnt++);
 -             memcpy (dataX, packet_bufX, fragment_payload_size);
 -             sendto (sockfd, tx_packet, mtu, flags, addr, addr_size);
 -             packet_bufX += fragment_payload_size;
 -         }
 - 
 -         int last_payload_size = packet_buf + pkt_size - packet_bufX;
 -         memcpy (dataX, packet_bufX, last_payload_size);
 -         pkthdr->fragment_nr = htonl (frag_cnt);
 -         //jack_log("last fragment_count = %d, payload_size = %d\n", fragment_count, last_payload_size);
 - 
 -         // sendto(last_pack_size);
 -         err = sendto(sockfd, tx_packet, last_payload_size + sizeof(jacknet_packet_header), flags, addr, addr_size);
 - 	if( err<0 ) {
 - 	    //printf( "error in send\n" );
 - 	    perror( "send" );
 - 	}
 -     }
 - }
 - 
 - 
 - void
 - decode_midi_buffer (uint32_t *buffer_uint32, unsigned int buffer_size_uint32, jack_default_audio_sample_t* buf)
 - {
 -     int i;
 -     jack_midi_clear_buffer (buf);
 -     for (i = 0; i < buffer_size_uint32 - 3;)
 -     {
 -         uint32_t payload_size;
 -         payload_size = buffer_uint32[i];
 -         payload_size = ntohl (payload_size);
 -         if (payload_size)
 -         {
 -             jack_midi_event_t event;
 -             event.time = ntohl (buffer_uint32[i+1]);
 -             event.size = ntohl (buffer_uint32[i+2]);
 -             event.buffer = (jack_midi_data_t*) (&(buffer_uint32[i+3]));
 -             jack_midi_event_write (buf, event.time, event.buffer, event.size);
 - 
 -             // skip to the next event
 -             unsigned int nb_data_quads = (((event.size-1) & ~0x3) >> 2)+1;
 -             i += 3+nb_data_quads;
 -         }
 -         else
 -             break; // no events can follow an empty event, we're done
 -     }
 - }
 - 
 - void
 - encode_midi_buffer (uint32_t *buffer_uint32, unsigned int buffer_size_uint32, jack_default_audio_sample_t* buf)
 - {
 -     int i;
 -     unsigned int written = 0;
 -     // midi port, encode midi events
 -     unsigned int nevents = jack_midi_get_event_count (buf);
 -     for (i = 0; i < nevents; ++i)
 -     {
 -         jack_midi_event_t event;
 -         jack_midi_event_get (&event, buf, i);
 -         unsigned int nb_data_quads = (((event.size - 1) & ~0x3) >> 2) + 1;
 -         unsigned int payload_size = 3 + nb_data_quads;
 -         // only write if we have sufficient space for the event
 -         // otherwise drop it
 -         if (written + payload_size < buffer_size_uint32 - 1)
 -         {
 -             // write header
 -             buffer_uint32[written]=htonl (payload_size);
 -             written++;
 -             buffer_uint32[written]=htonl (event.time);
 -             written++;
 -             buffer_uint32[written]=htonl (event.size);
 -             written++;
 - 
 -             // write data
 -             jack_midi_data_t* tmpbuff = (jack_midi_data_t*)(&(buffer_uint32[written]));
 -             memcpy (tmpbuff, event.buffer, event.size);
 -             written += nb_data_quads;
 -         }
 -         else
 -         {
 -             // buffer overflow
 -             jack_error ("midi buffer overflow");
 -             break;
 -         }
 -     }
 -     // now put a netjack_midi 'no-payload' event, signaling EOF
 -     buffer_uint32[written]=0;
 - }
 - 
 - // render functions for float
 - void
 - render_payload_to_jack_ports_float ( void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats)
 - {
 -     int chn = 0;
 -     JSList *node = capture_ports;
 - #if HAVE_SAMPLERATE
 -     JSList *src_node = capture_srcs;
 - #endif
 - 
 -     uint32_t *packet_bufX = (uint32_t *)packet_payload;
 - 
 -     if( !packet_payload )
 - 	return;
 - 
 -     while (node != NULL)
 -     {
 -         int i;
 -         int_float_t val;
 - #if HAVE_SAMPLERATE
 -         SRC_DATA src;
 - #endif
 - 
 -         jack_port_t *port = (jack_port_t *) node->data;
 -         jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes);
 - 
 -         const char *porttype = jack_port_type (port);
 - 
 -         if (jack_port_is_audio (porttype))
 -         {
 - #if HAVE_SAMPLERATE
 -             // audio port, resample if necessary
 -             if (net_period_down != nframes)
 -             {
 -                 SRC_STATE *src_state = src_node->data;
 -                 for (i = 0; i < net_period_down; i++)
 -                 {
 -                     packet_bufX[i] = ntohl (packet_bufX[i]);
 -                 }
 - 
 -                 src.data_in = (float *) packet_bufX;
 -                 src.input_frames = net_period_down;
 - 
 -                 src.data_out = buf;
 -                 src.output_frames = nframes;
 - 
 -                 src.src_ratio = (float) nframes / (float) net_period_down;
 -                 src.end_of_input = 0;
 - 
 -                 src_set_ratio (src_state, src.src_ratio);
 -                 src_process (src_state, &src);
 -                 src_node = jack_slist_next (src_node);
 -             }
 -             else
 - #endif
 -             {
 - 		if( dont_htonl_floats )
 - 		{
 - 		    memcpy( buf, packet_bufX, net_period_down*sizeof(jack_default_audio_sample_t));
 - 		}
 - 		else
 - 		{
 - 		    for (i = 0; i < net_period_down; i++)
 - 		    {
 - 			val.i = packet_bufX[i];
 - 			val.i = ntohl (val.i);
 - 			buf[i] = val.f;
 - 		    }
 - 		}
 -             }
 -         }
 -         else if (jack_port_is_midi (porttype))
 -         {
 -             // midi port, decode midi events
 -             // convert the data buffer to a standard format (uint32_t based)
 -             unsigned int buffer_size_uint32 = net_period_down;
 -             uint32_t * buffer_uint32 = (uint32_t*)packet_bufX;
 -             decode_midi_buffer (buffer_uint32, buffer_size_uint32, buf);
 -         }
 -         packet_bufX = (packet_bufX + net_period_down);
 -         node = jack_slist_next (node);
 -         chn++;
 -     }
 - }
 - 
 - void
 - render_jack_ports_to_payload_float (JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up, int dont_htonl_floats )
 - {
 -     int chn = 0;
 -     JSList *node = playback_ports;
 - #if HAVE_SAMPLERATE
 -     JSList *src_node = playback_srcs;
 - #endif
 - 
 -     uint32_t *packet_bufX = (uint32_t *) packet_payload;
 - 
 -     while (node != NULL)
 -     {
 - #if HAVE_SAMPLERATE
 -         SRC_DATA src;
 - #endif
 -         int i;
 -         int_float_t val;
 -         jack_port_t *port = (jack_port_t *) node->data;
 -         jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes);
 - 
 -         const char *porttype = jack_port_type (port);
 - 
 -         if (jack_port_is_audio (porttype))
 -         {
 -             // audio port, resample if necessary
 - 
 - #if HAVE_SAMPLERATE
 -             if (net_period_up != nframes) {
 -                 SRC_STATE *src_state = src_node->data;
 -                 src.data_in = buf;
 -                 src.input_frames = nframes;
 - 
 -                 src.data_out = (float *) packet_bufX;
 -                 src.output_frames = net_period_up;
 - 
 -                 src.src_ratio = (float) net_period_up / (float) nframes;
 -                 src.end_of_input = 0;
 - 
 -                 src_set_ratio (src_state, src.src_ratio);
 -                 src_process (src_state, &src);
 - 
 -                 for (i = 0; i < net_period_up; i++)
 -                 {
 -                     packet_bufX[i] = htonl (packet_bufX[i]);
 -                 }
 -                 src_node = jack_slist_next (src_node);
 -             }
 -             else
 - #endif
 -             {
 - 		if( dont_htonl_floats )
 - 		{
 - 		    memcpy( packet_bufX, buf, net_period_up*sizeof(jack_default_audio_sample_t) );
 - 		}
 - 		else
 - 		{
 - 		    for (i = 0; i < net_period_up; i++)
 - 		    {
 - 			val.f = buf[i];
 - 			val.i = htonl (val.i);
 - 			packet_bufX[i] = val.i;
 - 		    }
 - 		}
 -             }
 -         }
 -         else if (jack_port_is_midi (porttype))
 -         {
 -             // encode midi events from port to packet
 -             // convert the data buffer to a standard format (uint32_t based)
 -             unsigned int buffer_size_uint32 = net_period_up;
 -             uint32_t * buffer_uint32 = (uint32_t*) packet_bufX;
 -             encode_midi_buffer (buffer_uint32, buffer_size_uint32, buf);
 -         }
 -         packet_bufX = (packet_bufX + net_period_up);
 -         node = jack_slist_next (node);
 -         chn++;
 -     }
 - }
 - 
 - // render functions for 16bit
 - void
 - render_payload_to_jack_ports_16bit (void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes)
 - {
 -     int chn = 0;
 -     JSList *node = capture_ports;
 - #if HAVE_SAMPLERATE
 -     JSList *src_node = capture_srcs;
 - #endif
 - 
 -     uint16_t *packet_bufX = (uint16_t *)packet_payload;
 - 
 -     if( !packet_payload )
 - 	return;
 - 
 -     while (node != NULL)
 -     {
 -         int i;
 -         //uint32_t val;
 - #if HAVE_SAMPLERATE
 -         SRC_DATA src;
 - #endif
 - 
 -         jack_port_t *port = (jack_port_t *) node->data;
 -         jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes);
 - 
 - #if HAVE_SAMPLERATE
 -         float *floatbuf = alloca (sizeof(float) * net_period_down);
 - #endif
 -         const char *porttype = jack_port_type (port);
 - 
 -         if (jack_port_is_audio (porttype))
 -         {
 -             // audio port, resample if necessary
 - 
 - #if HAVE_SAMPLERATE
 -             if (net_period_down != nframes)
 -             {
 -                 SRC_STATE *src_state = src_node->data;
 -                 for (i = 0; i < net_period_down; i++)
 -                 {
 -                     floatbuf[i] = ((float) ntohs(packet_bufX[i])) / 32767.0 - 1.0;
 -                 }
 - 
 -                 src.data_in = floatbuf;
 -                 src.input_frames = net_period_down;
 - 
 -                 src.data_out = buf;
 -                 src.output_frames = nframes;
 - 
 -                 src.src_ratio = (float) nframes / (float) net_period_down;
 -                 src.end_of_input = 0;
 - 
 -                 src_set_ratio (src_state, src.src_ratio);
 -                 src_process (src_state, &src);
 -                 src_node = jack_slist_next (src_node);
 -             }
 -             else
 - #endif
 -                 for (i = 0; i < net_period_down; i++)
 -                     buf[i] = ((float) ntohs (packet_bufX[i])) / 32768.0 - 1.0;
 -         }
 -         else if (jack_port_is_midi (porttype))
 -         {
 -             // midi port, decode midi events
 -             // convert the data buffer to a standard format (uint32_t based)
 -             unsigned int buffer_size_uint32 = net_period_down / 2;
 -             uint32_t * buffer_uint32 = (uint32_t*) packet_bufX;
 -             decode_midi_buffer (buffer_uint32, buffer_size_uint32, buf);
 -         }
 -         packet_bufX = (packet_bufX + net_period_down);
 -         node = jack_slist_next (node);
 -         chn++;
 -     }
 - }
 - 
 - void
 - render_jack_ports_to_payload_16bit (JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up)
 - {
 -     int chn = 0;
 -     JSList *node = playback_ports;
 - #if HAVE_SAMPLERATE
 -     JSList *src_node = playback_srcs;
 - #endif
 - 
 -     uint16_t *packet_bufX = (uint16_t *)packet_payload;
 - 
 -     while (node != NULL)
 -     {
 - #if HAVE_SAMPLERATE
 -         SRC_DATA src;
 - #endif
 -         int i;
 -         jack_port_t *port = (jack_port_t *) node->data;
 -         jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes);
 -         const char *porttype = jack_port_type (port);
 - 
 -         if (jack_port_is_audio (porttype))
 -         {
 -             // audio port, resample if necessary
 - 
 - #if HAVE_SAMPLERATE
 -             if (net_period_up != nframes)
 -             {
 -                 SRC_STATE *src_state = src_node->data;
 - 
 -                 float *floatbuf = alloca (sizeof(float) * net_period_up);
 - 
 -                 src.data_in = buf;
 -                 src.input_frames = nframes;
 - 
 -                 src.data_out = floatbuf;
 -                 src.output_frames = net_period_up;
 - 
 -                 src.src_ratio = (float) net_period_up / (float) nframes;
 -                 src.end_of_input = 0;
 - 
 -                 src_set_ratio (src_state, src.src_ratio);
 -                 src_process (src_state, &src);
 - 
 -                 for (i = 0; i < net_period_up; i++)
 -                 {
 -                     packet_bufX[i] = htons (((uint16_t)((floatbuf[i] + 1.0) * 32767.0)));
 -                 }
 -                 src_node = jack_slist_next (src_node);
 -             }
 -             else
 - #endif
 -                 for (i = 0; i < net_period_up; i++)
 -                     packet_bufX[i] = htons(((uint16_t)((buf[i] + 1.0) * 32767.0)));
 -         }
 -         else if (jack_port_is_midi (porttype))
 -         {
 -             // encode midi events from port to packet
 -             // convert the data buffer to a standard format (uint32_t based)
 -             unsigned int buffer_size_uint32 = net_period_up / 2;
 -             uint32_t * buffer_uint32 = (uint32_t*) packet_bufX;
 -             encode_midi_buffer (buffer_uint32, buffer_size_uint32, buf);
 -         }
 -         packet_bufX = (packet_bufX + net_period_up);
 -         node = jack_slist_next (node);
 -         chn++;
 -     }
 - }
 - 
 - // render functions for 8bit
 - void
 - render_payload_to_jack_ports_8bit (void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes)
 - {
 -     int chn = 0;
 -     JSList *node = capture_ports;
 - 
 - #if HAVE_SAMPLERATE
 -     JSList *src_node = capture_srcs;
 - #endif
 - 
 -     int8_t *packet_bufX = (int8_t *)packet_payload;
 - 
 -     if( !packet_payload )
 - 	return;
 - 
 -     while (node != NULL)
 -     {
 -         int i;
 -         //uint32_t val;
 - #if HAVE_SAMPLERATE
 -         SRC_DATA src;
 - #endif
 - 
 -         jack_port_t *port = (jack_port_t *) node->data;
 -         jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes);
 - 
 - #if HAVE_SAMPLERATE
 -         float *floatbuf = alloca (sizeof (float) * net_period_down);
 - #endif
 -         const char *porttype = jack_port_type (port);
 - 
 -         if (jack_port_is_audio(porttype))
 -         {
 - #if HAVE_SAMPLERATE
 -             // audio port, resample if necessary
 -             if (net_period_down != nframes)
 -             {
 -                 SRC_STATE *src_state = src_node->data;
 -                 for (i = 0; i < net_period_down; i++)
 -                     floatbuf[i] = ((float) packet_bufX[i]) / 127.0;
 - 
 -                 src.data_in = floatbuf;
 -                 src.input_frames = net_period_down;
 - 
 -                 src.data_out = buf;
 -                 src.output_frames = nframes;
 - 
 -                 src.src_ratio = (float) nframes / (float) net_period_down;
 -                 src.end_of_input = 0;
 - 
 -                 src_set_ratio (src_state, src.src_ratio);
 -                 src_process (src_state, &src);
 -                 src_node = jack_slist_next (src_node);
 -             }
 -             else
 - #endif
 -                 for (i = 0; i < net_period_down; i++)
 -                     buf[i] = ((float) packet_bufX[i]) / 127.0;
 -         }
 -         else if (jack_port_is_midi (porttype))
 -         {
 -             // midi port, decode midi events
 -             // convert the data buffer to a standard format (uint32_t based)
 -             unsigned int buffer_size_uint32 = net_period_down / 2;
 -             uint32_t * buffer_uint32 = (uint32_t*) packet_bufX;
 -             decode_midi_buffer (buffer_uint32, buffer_size_uint32, buf);
 -         }
 -         packet_bufX = (packet_bufX + net_period_down);
 -         node = jack_slist_next (node);
 -         chn++;
 -     }
 - }
 - 
 - void
 - render_jack_ports_to_payload_8bit (JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up)
 - {
 -     int chn = 0;
 -     JSList *node = playback_ports;
 - #if HAVE_SAMPLERATE
 -     JSList *src_node = playback_srcs;
 - #endif
 - 
 -     int8_t *packet_bufX = (int8_t *)packet_payload;
 - 
 -     while (node != NULL)
 -     {
 - #if HAVE_SAMPLERATE
 -         SRC_DATA src;
 - #endif
 -         int i;
 -         jack_port_t *port = (jack_port_t *) node->data;
 - 
 -         jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes);
 -         const char *porttype = jack_port_type (port);
 - 
 -         if (jack_port_is_audio (porttype))
 -         {
 - #if HAVE_SAMPLERATE
 -             // audio port, resample if necessary
 -             if (net_period_up != nframes)
 -             {
 - 
 -                 SRC_STATE *src_state = src_node->data;
 - 
 -                 float *floatbuf = alloca (sizeof (float) * net_period_up);
 - 
 -                 src.data_in = buf;
 -                 src.input_frames = nframes;
 - 
 -                 src.data_out = floatbuf;
 -                 src.output_frames = net_period_up;
 - 
 -                 src.src_ratio = (float) net_period_up / (float) nframes;
 -                 src.end_of_input = 0;
 - 
 -                 src_set_ratio (src_state, src.src_ratio);
 -                 src_process (src_state, &src);
 - 
 -                 for (i = 0; i < net_period_up; i++)
 -                     packet_bufX[i] = floatbuf[i] * 127.0;
 -                 src_node = jack_slist_next (src_node);
 -             }
 -             else
 - #endif
 -                 for (i = 0; i < net_period_up; i++)
 -                     packet_bufX[i] = buf[i] * 127.0;
 -         }
 -         else if (jack_port_is_midi (porttype))
 -         {
 -             // encode midi events from port to packet
 -             // convert the data buffer to a standard format (uint32_t based)
 -             unsigned int buffer_size_uint32 = net_period_up / 4;
 -             uint32_t * buffer_uint32 = (uint32_t*) packet_bufX;
 -             encode_midi_buffer (buffer_uint32, buffer_size_uint32, buf);
 -         }
 -         packet_bufX = (packet_bufX + net_period_up);
 -         node = jack_slist_next (node);
 -         chn++;
 -     }
 - }
 - 
 - #if HAVE_CELT
 - // render functions for celt.
 - void
 - render_payload_to_jack_ports_celt (void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes)
 - {
 -     int chn = 0;
 -     JSList *node = capture_ports;
 -     JSList *src_node = capture_srcs;
 - 
 -     unsigned char *packet_bufX = (unsigned char *)packet_payload;
 - 
 -     while (node != NULL)
 -     {
 -         jack_port_t *port = (jack_port_t *) node->data;
 -         jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes);
 - 
 -         const char *porttype = jack_port_type (port);
 - 
 -         if (jack_port_is_audio (porttype))
 -         {
 -             // audio port, decode celt data.
 - 
 - 	    CELTDecoder *decoder = src_node->data;
 - 	    if( !packet_payload )
 - 		celt_decode_float( decoder, NULL, net_period_down, buf );
 - 	    else
 - 		celt_decode_float( decoder, packet_bufX, net_period_down, buf );
 - 
 - 	    src_node = jack_slist_next (src_node);
 -         }
 -         else if (jack_port_is_midi (porttype))
 -         {
 -             // midi port, decode midi events
 -             // convert the data buffer to a standard format (uint32_t based)
 -             unsigned int buffer_size_uint32 = net_period_down / 2;
 -             uint32_t * buffer_uint32 = (uint32_t*) packet_bufX;
 - 	    if( packet_payload )
 - 		decode_midi_buffer (buffer_uint32, buffer_size_uint32, buf);
 -         }
 -         packet_bufX = (packet_bufX + net_period_down);
 -         node = jack_slist_next (node);
 -         chn++;
 -     }
 - }
 - 
 - void
 - render_jack_ports_to_payload_celt (JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up)
 - {
 -     int chn = 0;
 -     JSList *node = playback_ports;
 -     JSList *src_node = playback_srcs;
 - 
 -     unsigned char *packet_bufX = (unsigned char *)packet_payload;
 - 
 -     while (node != NULL)
 -     {
 -         jack_port_t *port = (jack_port_t *) node->data;
 -         jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes);
 -         const char *porttype = jack_port_type (port);
 - 
 -         if (jack_port_is_audio (porttype))
 -         {
 -             // audio port, encode celt data.
 - 
 - 	    int encoded_bytes;
 - 	    float *floatbuf = alloca (sizeof(float) * nframes );
 - 	    memcpy( floatbuf, buf, nframes*sizeof(float) );
 - 	    CELTEncoder *encoder = src_node->data;
 - 	    encoded_bytes = celt_encode_float( encoder, floatbuf, NULL, packet_bufX, net_period_up );
 - 	    if( encoded_bytes != net_period_up )
 - 		printf( "something in celt changed. netjack needs to be changed to handle this.\n" );
 - 	    src_node = jack_slist_next( src_node );
 -         }
 -         else if (jack_port_is_midi (porttype))
 -         {
 -             // encode midi events from port to packet
 -             // convert the data buffer to a standard format (uint32_t based)
 -             unsigned int buffer_size_uint32 = net_period_up / 2;
 -             uint32_t * buffer_uint32 = (uint32_t*) packet_bufX;
 -             encode_midi_buffer (buffer_uint32, buffer_size_uint32, buf);
 -         }
 -         packet_bufX = (packet_bufX + net_period_up);
 -         node = jack_slist_next (node);
 -         chn++;
 -     }
 - }
 - 
 - #endif
 - /* Wrapper functions with bitdepth argument... */
 - void
 - render_payload_to_jack_ports (int bitdepth, void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats)
 - {
 -     if (bitdepth == 8)
 -         render_payload_to_jack_ports_8bit (packet_payload, net_period_down, capture_ports, capture_srcs, nframes);
 -     else if (bitdepth == 16)
 -         render_payload_to_jack_ports_16bit (packet_payload, net_period_down, capture_ports, capture_srcs, nframes);
 - #if HAVE_CELT
 -     else if (bitdepth == CELT_MODE)
 -         render_payload_to_jack_ports_celt (packet_payload, net_period_down, capture_ports, capture_srcs, nframes);
 - #endif
 -     else
 -         render_payload_to_jack_ports_float (packet_payload, net_period_down, capture_ports, capture_srcs, nframes, dont_htonl_floats);
 - }
 - 
 - void
 - render_jack_ports_to_payload (int bitdepth, JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up, int dont_htonl_floats)
 - {
 -     if (bitdepth == 8)
 -         render_jack_ports_to_payload_8bit (playback_ports, playback_srcs, nframes, packet_payload, net_period_up);
 -     else if (bitdepth == 16)
 -         render_jack_ports_to_payload_16bit (playback_ports, playback_srcs, nframes, packet_payload, net_period_up);
 - #if HAVE_CELT
 -     else if (bitdepth == CELT_MODE)
 -         render_jack_ports_to_payload_celt (playback_ports, playback_srcs, nframes, packet_payload, net_period_up);
 - #endif
 -     else
 -         render_jack_ports_to_payload_float (playback_ports, playback_srcs, nframes, packet_payload, net_period_up, dont_htonl_floats);
 - }
 
 
  |