oops, paul should remember to try an OSX build before releasing a tarball; fixed...
[jack.git] / drivers / netjack / netjack_packet_noReOrder.c
blob5d0a426a4f443b75aaa931ea6eac7bbe3e0d4fa4
2 /*
3 * NetJack - Packet Handling functions
5 * used by the driver and the jacknet_client
7 * Copyright (C) 2006 Torben Hohn <torbenh@gmx.de>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 * $Id: net_driver.c,v 1.16 2006/03/20 19:41:37 torbenh Exp $
28 #include <math.h>
29 #include <stdio.h>
30 #include <memory.h>
31 #include <unistd.h>
32 #include <stdlib.h>
33 #include <errno.h>
34 #include <stdarg.h>
36 #include <jack/types.h>
37 #include <jack/engine.h>
39 #include <sys/types.h>
40 #include <sys/socket.h>
41 #include <netinet/in.h>
43 #include <samplerate.h>
45 #include "net_driver.h"
46 #include "netjack_packet.h"
48 int fraggo = 0;
50 void
51 packet_header_hton(jacknet_packet_header *pkthdr)
53 pkthdr->channels = htonl(pkthdr->channels);
54 pkthdr->period_size = htonl(pkthdr->period_size);
55 pkthdr->sample_rate = htonl(pkthdr->sample_rate);
56 pkthdr->sync_state = htonl(pkthdr->sync_state);
57 pkthdr->transport_frame = htonl(pkthdr->transport_frame);
58 pkthdr->transport_state = htonl(pkthdr->transport_state);
59 pkthdr->framecnt = htonl(pkthdr->framecnt);
60 pkthdr->latency = htonl(pkthdr->latency);
61 pkthdr->reply_port = htonl(pkthdr->reply_port);
62 pkthdr->mtu = htonl(pkthdr->mtu);
63 pkthdr->fragment_nr = htonl(pkthdr->fragment_nr);
66 void
67 packet_header_ntoh(jacknet_packet_header *pkthdr)
69 pkthdr->channels = ntohl(pkthdr->channels);
70 pkthdr->period_size = ntohl(pkthdr->period_size);
71 pkthdr->sample_rate = ntohl(pkthdr->sample_rate);
72 pkthdr->sync_state = ntohl(pkthdr->sync_state);
73 pkthdr->transport_frame = ntohl(pkthdr->transport_frame);
74 pkthdr->transport_state = ntohl(pkthdr->transport_state);
75 pkthdr->framecnt = ntohl(pkthdr->framecnt);
76 pkthdr->latency = ntohl(pkthdr->latency);
77 pkthdr->reply_port = ntohl(pkthdr->reply_port);
78 pkthdr->mtu = ntohl(pkthdr->mtu);
79 pkthdr->fragment_nr = ntohl(pkthdr->fragment_nr);
82 int get_sample_size(int bitdepth)
84 if (bitdepth == 8)
85 return sizeof(int8_t);
86 if (bitdepth == 16)
87 return sizeof(int16_t);
89 return sizeof(int32_t);
93 // fragmented packet IO
95 int netjack_recvfrom(int sockfd, char *packet_buf, int pkt_size, int flags, struct sockaddr *addr, socklen_t *addr_size, int mtu)
97 char *rx_packet;
98 char *dataX;
100 int fragment_payload_size;
102 // Copy the packet header to the tx pack first.
103 //memcpy(tx_packet, packet_buf, sizeof(jacknet_packet_header));
105 jacknet_packet_header *pkthdr;
107 // Now loop and send all
108 char *packet_bufX;
110 // wait for fragment_nr == 0
111 int rcv_len;
113 rx_packet = alloca(mtu);
114 dataX = rx_packet + sizeof(jacknet_packet_header);
116 fragment_payload_size = mtu - sizeof(jacknet_packet_header);
118 // Copy the packet header to the tx pack first.
119 //memcpy(tx_packet, packet_buf, sizeof(jacknet_packet_header));
121 pkthdr = (jacknet_packet_header *)rx_packet;
123 // Now loop and send all
124 packet_bufX = packet_buf + sizeof(jacknet_packet_header);
127 if (pkt_size <= mtu)
129 return recvfrom(sockfd, packet_buf, pkt_size, flags, addr, addr_size);
130 } else
132 rx_again:
133 rcv_len = recvfrom(sockfd, rx_packet, mtu, 0, addr, addr_size);
134 if (rcv_len < 0)
135 return rcv_len;
137 if (rcv_len >= sizeof(jacknet_packet_header)) {
138 //printf("got fragmentooooo_nr = %d recv_len = %d\n", ntohl(pkthdr->fragment_nr), rcv_len);
139 if ((ntohl(pkthdr->fragment_nr)) != 0)
140 goto rx_again;
141 } else {
142 goto rx_again;
144 //goto rx_again;
146 //printf("ok... lets go...\n");
147 // ok... we have read a fragement 0;
148 // copy the packet header...
149 memcpy(packet_buf, rx_packet, sizeof(jacknet_packet_header));
151 int fragment_count = 0;
153 while (packet_bufX <= (packet_buf + pkt_size - fragment_payload_size)) {
155 //printf("enter loop: fragment_count = %d, pkthdr->fragment_nr = %d\n", fragment_count, pkthdr->fragment_nr);
156 // check fragment number.
157 if ((ntohl(pkthdr->fragment_nr)) != fragment_count) {
158 printf("got unexpected fragment %d (expected %d)\n", ntohl(pkthdr->fragment_nr), fragment_count);
159 return sizeof(jacknet_packet_header) + (fragment_count) * fragment_payload_size;
160 } else
161 //printf("expected fragment %d\n", fragment_count);
163 // copy the payload into the packet buffer...
164 memcpy(packet_bufX, dataX, fragment_payload_size);
166 rcv_len = recvfrom(sockfd, rx_packet, mtu, 0, addr, addr_size);
167 //printf("got fragmen_nr = %d rcv_len = %d\n", ntohl(pkthdr->fragment_nr), rcv_len);
168 //printf("got fragmen_nr = %d\n", ntohl(pkthdr->fragment_nr));
169 if (rcv_len < 0)
170 return -1;
172 packet_bufX += fragment_payload_size;
173 fragment_count++;
176 //printf("at the end rcv_len = %d\n ", rcv_len);
177 int last_payload_size = packet_bufX - packet_buf - pkt_size;
178 memcpy(packet_bufX, dataX, rcv_len - sizeof(jacknet_packet_header));
180 return pkt_size;
183 int netjack_recv(int sockfd, char *packet_buf, int pkt_size, int flags, int mtu)
185 if (pkt_size <= mtu) {
186 return recv(sockfd, packet_buf, pkt_size, flags);
187 } else {
188 char *rx_packet = alloca(mtu);
189 char *dataX = rx_packet + sizeof(jacknet_packet_header);
191 int fragment_payload_size = mtu - sizeof(jacknet_packet_header);
192 jacknet_packet_header *pkthdr = (jacknet_packet_header *)rx_packet;
194 // Now loop and send all
195 char *packet_bufX = packet_buf + sizeof(jacknet_packet_header);
197 // wait for fragment_nr == 0
198 int rcv_len;
199 rx_again:
200 rcv_len = recv(sockfd, rx_packet, mtu, flags);
201 if (rcv_len < 0)
202 return rcv_len;
204 if (rcv_len >= sizeof(jacknet_packet_header)) {
205 //printf("got fragmentooo_nr = %d\n", ntohl(pkthdr->fragment_nr));
206 if (ntohl(pkthdr->fragment_nr) != 0)
207 goto rx_again;
208 } else {
209 goto rx_again;
212 //printf("ok we got a fragment 0\n");
213 // ok... we have read a fragement 0;
214 // copy the packet header...
215 memcpy(packet_buf, rx_packet, sizeof(jacknet_packet_header));
217 int fragment_count = 0;
219 while (packet_bufX <= (packet_buf + pkt_size - fragment_payload_size)) {
221 // check fragment number.
222 if (ntohl(pkthdr->fragment_nr) != fragment_count) {
223 printf("got unexpected fragment %d (expected %d)\n", ntohl(pkthdr->fragment_nr), fragment_count);
224 return sizeof(jacknet_packet_header) + (fragment_count - 1) * fragment_payload_size;
227 // copy the payload into the packet buffer...
228 memcpy(packet_bufX, dataX, fragment_payload_size);
230 rcv_len = recv(sockfd, rx_packet, mtu, flags);
231 //printf("got fragmen_nr = %d rcv_len = %d\n", ntohl(pkthdr->fragment_nr), rcv_len);
232 if (rcv_len < 0)
233 return -1;
235 packet_bufX += fragment_payload_size;
236 fragment_count++;
239 //int last_payload_size = packet_bufX - packet_buf - pkt_size;
240 //memcpy(packet_bufX, dataX, rcv_len - sizeof(jacknet_packet_header));
242 return pkt_size;
245 void netjack_sendto(int sockfd, char *packet_buf, int pkt_size, int flags, struct sockaddr *addr, int addr_size, int mtu)
247 int frag_cnt = 0;
248 char *tx_packet, *dataX;
249 jacknet_packet_header *pkthdr;
251 tx_packet = alloca(mtu + 10);
252 dataX = tx_packet + sizeof(jacknet_packet_header);
253 pkthdr = (jacknet_packet_header *)tx_packet;
255 int fragment_payload_size = mtu - sizeof(jacknet_packet_header);
257 if (pkt_size <= mtu) {
258 sendto(sockfd, packet_buf, pkt_size, flags, addr, addr_size);
259 } else {
261 // Copy the packet header to the tx pack first.
262 memcpy(tx_packet, packet_buf, sizeof(jacknet_packet_header));
264 // Now loop and send all
265 char *packet_bufX = packet_buf + sizeof(jacknet_packet_header);
268 while (packet_bufX < (packet_buf + pkt_size - fragment_payload_size)) {
269 pkthdr->fragment_nr = htonl(frag_cnt++);
270 memcpy(dataX, packet_bufX, fragment_payload_size);
272 int err = sendto(sockfd, tx_packet, mtu, flags, addr, addr_size);
274 packet_bufX += fragment_payload_size;
277 int last_payload_size = packet_buf + pkt_size - packet_bufX;
278 memcpy(dataX, packet_bufX, last_payload_size);
279 pkthdr->fragment_nr = htonl(frag_cnt);
280 //printf("last fragment_count = %d, payload_size = %d\n", fragment_count, last_payload_size);
282 // sendto(last_pack_size);
283 sendto(sockfd, tx_packet, last_payload_size + sizeof(jacknet_packet_header), flags, addr, addr_size);
287 // render functions for float
288 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)
290 channel_t chn = 0;
291 JSList *node = capture_ports;
292 JSList *src_node = capture_srcs;
294 uint32_t *packet_bufX = (uint32_t *)packet_payload;
296 while (node != NULL) {
297 int i;
298 int_float_t val;
299 SRC_DATA src;
301 jack_port_t *port = (jack_port_t *) node->data;
302 jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes);
304 if (net_period_down != nframes) {
305 SRC_STATE *src_state = src_node->data;
306 for (i = 0; i < net_period_down; i++) {
307 packet_bufX[i] = ntohl(packet_bufX[i]);
310 src.data_in = (float *)packet_bufX;
311 src.input_frames = net_period_down;
313 src.data_out = buf;
314 src.output_frames = nframes;
316 src.src_ratio = (float) nframes / (float) net_period_down;
317 src.end_of_input = 0;
319 src_set_ratio(src_state, src.src_ratio);
320 src_process(src_state, &src);
321 src_node = jack_slist_next (src_node);
322 } else {
323 for (i = 0; i < net_period_down; i++) {
324 val.i = packet_bufX[i];
325 val.i = ntohl(val.i);
326 buf[i] = val.f;
330 packet_bufX = (packet_bufX + net_period_down);
331 node = jack_slist_next (node);
332 chn++;
336 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)
338 channel_t chn = 0;
339 JSList *node = playback_ports;
340 JSList *src_node = playback_srcs;
342 uint32_t *packet_bufX = (uint32_t *)packet_payload;
344 while (node != NULL) {
345 SRC_DATA src;
346 int i;
347 int_float_t val;
348 jack_port_t *port = (jack_port_t *) node->data;
349 jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes);
351 if (net_period_up != nframes) {
352 SRC_STATE *src_state = src_node->data;
353 src.data_in = buf;
354 src.input_frames = nframes;
356 src.data_out = (float *) packet_bufX;
357 src.output_frames = net_period_up;
359 src.src_ratio = (float) net_period_up / (float) nframes;
360 src.end_of_input = 0;
362 src_set_ratio(src_state, src.src_ratio);
363 src_process(src_state, &src);
365 for (i = 0; i < net_period_up; i++) {
366 packet_bufX[i] = htonl(packet_bufX[i]);
368 src_node = jack_slist_next (src_node);
369 } else {
370 for (i = 0; i < net_period_up; i++) {
371 val.f = buf[i];
372 val.i = htonl(val.i);
373 packet_bufX[i] = val.i;
377 packet_bufX = (packet_bufX + net_period_up);
378 node = jack_slist_next (node);
379 chn++;
383 // render functions for 16bit
384 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)
386 channel_t chn = 0;
387 JSList *node = capture_ports;
388 JSList *src_node = capture_srcs;
390 uint16_t *packet_bufX = (uint16_t *)packet_payload;
392 while (node != NULL) {
393 int i;
394 //uint32_t val;
395 SRC_DATA src;
397 jack_port_t *port = (jack_port_t *) node->data;
398 jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes);
400 float *floatbuf = alloca(sizeof(float) * net_period_down);
402 if (net_period_down != nframes) {
403 SRC_STATE *src_state = src_node->data;
404 for (i = 0; i < net_period_down; i++) {
405 floatbuf[i] = ((float) ntohs(packet_bufX[i])) / 32767.0 - 1.0;
408 src.data_in = floatbuf;
409 src.input_frames = net_period_down;
411 src.data_out = buf;
412 src.output_frames = nframes;
414 src.src_ratio = (float) nframes / (float) net_period_down;
415 src.end_of_input = 0;
417 src_set_ratio(src_state, src.src_ratio);
418 src_process(src_state, &src);
419 src_node = jack_slist_next (src_node);
420 } else {
421 for (i = 0; i < net_period_down; i++) {
422 buf[i] = ((float) ntohs(packet_bufX[i])) / 32768.0 - 1.0;
426 packet_bufX = (packet_bufX + net_period_down);
427 node = jack_slist_next (node);
428 chn++;
432 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)
434 channel_t chn = 0;
435 JSList *node = playback_ports;
436 JSList *src_node = playback_srcs;
438 uint16_t *packet_bufX = (uint16_t *)packet_payload;
440 while (node != NULL) {
441 SRC_DATA src;
442 int i;
443 jack_port_t *port = (jack_port_t *) node->data;
444 jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes);
446 if (net_period_up != nframes) {
447 SRC_STATE *src_state = src_node->data;
449 float *floatbuf = alloca(sizeof(float) * net_period_up);
451 src.data_in = buf;
452 src.input_frames = nframes;
454 src.data_out = floatbuf;
455 src.output_frames = net_period_up;
457 src.src_ratio = (float) net_period_up / (float) nframes;
458 src.end_of_input = 0;
460 src_set_ratio(src_state, src.src_ratio);
461 src_process(src_state, &src);
463 for (i = 0; i < net_period_up; i++) {
464 packet_bufX[i] = htons((floatbuf[i] + 1.0) * 32767.0);
466 src_node = jack_slist_next (src_node);
467 } else {
468 for (i = 0; i < net_period_up; i++) {
469 packet_bufX[i] = htons((buf[i] + 1.0) * 32767.0);
473 packet_bufX = (packet_bufX + net_period_up);
474 node = jack_slist_next (node);
475 chn++;
479 // render functions for 8bit
481 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)
483 channel_t chn = 0;
484 JSList *node = capture_ports;
485 JSList *src_node = capture_srcs;
487 int8_t *packet_bufX = (int8_t *)packet_payload;
489 while (node != NULL) {
490 int i;
491 //uint32_t val;
492 SRC_DATA src;
494 jack_port_t *port = (jack_port_t *) node->data;
495 jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes);
497 float *floatbuf = alloca(sizeof(float) * net_period_down);
499 if (net_period_down != nframes) {
500 SRC_STATE *src_state = src_node->data;
501 for (i = 0; i < net_period_down; i++) {
502 floatbuf[i] = ((float) packet_bufX[i]) / 127.0;
505 src.data_in = floatbuf;
506 src.input_frames = net_period_down;
508 src.data_out = buf;
509 src.output_frames = nframes;
511 src.src_ratio = (float) nframes / (float) net_period_down;
512 src.end_of_input = 0;
514 src_set_ratio(src_state, src.src_ratio);
515 src_process(src_state, &src);
516 src_node = jack_slist_next (src_node);
517 } else {
518 for (i = 0; i < net_period_down; i++) {
519 buf[i] = ((float) packet_bufX[i]) / 127.0;
523 packet_bufX = (packet_bufX + net_period_down);
524 node = jack_slist_next (node);
525 chn++;
529 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)
531 channel_t chn = 0;
532 JSList *node = playback_ports;
533 JSList *src_node = playback_srcs;
535 int8_t *packet_bufX = (int8_t *)packet_payload;
537 while (node != NULL) {
538 SRC_DATA src;
539 int i;
540 jack_port_t *port = (jack_port_t *) node->data;
541 jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes);
543 if (net_period_up != nframes) {
544 SRC_STATE *src_state = src_node->data;
546 float *floatbuf = alloca(sizeof(float) * net_period_up);
548 src.data_in = buf;
549 src.input_frames = nframes;
551 src.data_out = floatbuf;
552 src.output_frames = net_period_up;
554 src.src_ratio = (float) net_period_up / (float) nframes;
555 src.end_of_input = 0;
557 src_set_ratio(src_state, src.src_ratio);
558 src_process(src_state, &src);
560 for (i = 0; i < net_period_up; i++) {
561 packet_bufX[i] = floatbuf[i] * 127.0;
563 src_node = jack_slist_next (src_node);
564 } else {
565 for (i = 0; i < net_period_up; i++) {
566 packet_bufX[i] = buf[i] * 127.0;
570 packet_bufX = (packet_bufX + net_period_up);
571 node = jack_slist_next (node);
572 chn++;
576 // wrapper functions with bitdepth argument...
577 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)
579 if (bitdepth == 8)
580 render_payload_to_jack_ports_8bit(packet_payload, net_period_down, capture_ports, capture_srcs, nframes);
581 else if (bitdepth == 16)
582 render_payload_to_jack_ports_16bit(packet_payload, net_period_down, capture_ports, capture_srcs, nframes);
583 else
584 render_payload_to_jack_ports_float(packet_payload, net_period_down, capture_ports, capture_srcs, nframes);
587 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)
589 if (bitdepth == 8)
590 render_jack_ports_to_payload_8bit(playback_ports, playback_srcs, nframes, packet_payload, net_period_up);
591 else if (bitdepth == 16)
592 render_jack_ports_to_payload_16bit(playback_ports, playback_srcs, nframes, packet_payload, net_period_up);
593 else
594 render_jack_ports_to_payload_float(playback_ports, playback_srcs, nframes, packet_payload, net_period_up);