Browse Source

Merge branch 'master' into export-fixes

tags/1.9.8
Stephane Letz 14 years ago
parent
commit
d2830a5816
18 changed files with 1040 additions and 1027 deletions
  1. +1
    -0
      common/JackNetOneDriver.h
  2. +276
    -298
      common/netjack.c
  3. +92
    -92
      common/netjack.h
  4. +187
    -279
      common/netjack_packet.c
  5. +100
    -109
      common/netjack_packet.h
  6. +180
    -214
      example-clients/netsource.c
  7. +80
    -0
      windows/JackMMCSS.cpp
  8. +72
    -0
      windows/JackMMCSS.h
  9. +15
    -6
      windows/JackWinThread.cpp
  10. +2
    -3
      windows/JackWinThread.h
  11. +2
    -2
      windows/jackd.workspace
  12. +11
    -10
      windows/libjack.cbp
  13. +7
    -6
      windows/libjacknet.cbp
  14. +1
    -0
      windows/libjackserver.cbp
  15. +2
    -0
      windows/portaudio/JackPortAudioDriver.cpp
  16. +3
    -2
      windows/portaudio/JackPortAudioDriver.h
  17. +1
    -1
      windows/winmme/JackWinMMEDriver.cpp
  18. +8
    -5
      windows/winmme/JackWinMMEOutputPort.cpp

+ 1
- 0
common/JackNetOneDriver.h View File

@@ -90,6 +90,7 @@ class JackNetOneDriver : public JackAudioDriver
} }


}; };

} }


#endif #endif

+ 276
- 298
common/netjack.c View File

@@ -86,26 +86,25 @@ int netjack_wait( netjack_driver_state_t *netj )
jacknet_packet_header *pkthdr; jacknet_packet_header *pkthdr;


if( !netj->next_deadline_valid ) { if( !netj->next_deadline_valid ) {
netj->next_deadline = jack_get_time() + netj->period_usecs;
netj->next_deadline_valid = 1;
netj->next_deadline = jack_get_time() + netj->period_usecs;
netj->next_deadline_valid = 1;
} }


// Increment expected frame here. // Increment expected frame here.


if( netj->expected_framecnt_valid ) { if( netj->expected_framecnt_valid ) {
netj->expected_framecnt += 1;
netj->expected_framecnt += 1;
} else { } else {
// starting up.... lets look into the packetcache, and fetch the highest packet.
packet_cache_drain_socket( netj->packcache, netj->sockfd );
if( packet_cache_get_highest_available_framecnt( netj->packcache, &next_frame_avail ) ) {
netj->expected_framecnt = next_frame_avail;
netj->expected_framecnt_valid = 1;
} else {
// no packets there... start normally.
netj->expected_framecnt = 0;
netj->expected_framecnt_valid = 1;
}

// starting up.... lets look into the packetcache, and fetch the highest packet.
packet_cache_drain_socket( netj->packcache, netj->sockfd );
if( packet_cache_get_highest_available_framecnt( netj->packcache, &next_frame_avail ) ) {
netj->expected_framecnt = next_frame_avail;
netj->expected_framecnt_valid = 1;
} else {
// no packets there... start normally.
netj->expected_framecnt = 0;
netj->expected_framecnt_valid = 1;
}
} }


//jack_log( "expect %d", netj->expected_framecnt ); //jack_log( "expect %d", netj->expected_framecnt );
@@ -113,26 +112,26 @@ int netjack_wait( netjack_driver_state_t *netj )
// then poll (have deadline calculated) // then poll (have deadline calculated)
// then drain socket, rinse and repeat. // then drain socket, rinse and repeat.
while(1) { while(1) {
if( packet_cache_get_next_available_framecnt( netj->packcache, netj->expected_framecnt, &next_frame_avail) ) {
if( next_frame_avail == netj->expected_framecnt ) {
we_have_the_expected_frame = 1;
if( !netj->always_deadline )
break;
}
}
if( ! netjack_poll_deadline( netj->sockfd, netj->next_deadline ) ) {
break;
}
packet_cache_drain_socket( netj->packcache, netj->sockfd );
if( packet_cache_get_next_available_framecnt( netj->packcache, netj->expected_framecnt, &next_frame_avail) ) {
if( next_frame_avail == netj->expected_framecnt ) {
we_have_the_expected_frame = 1;
if( !netj->always_deadline )
break;
}
}
if( ! netjack_poll_deadline( netj->sockfd, netj->next_deadline ) ) {
break;
}
packet_cache_drain_socket( netj->packcache, netj->sockfd );
} }


// check if we know who to send our packets too. // check if we know who to send our packets too.
if (!netj->srcaddress_valid) if (!netj->srcaddress_valid)
if( netj->packcache->master_address_valid ) {
memcpy (&(netj->syncsource_address), &(netj->packcache->master_address), sizeof( struct sockaddr_in ) );
netj->srcaddress_valid = 1;
}
if( netj->packcache->master_address_valid ) {
memcpy (&(netj->syncsource_address), &(netj->packcache->master_address), sizeof( struct sockaddr_in ) );
netj->srcaddress_valid = 1;
}


// XXX: switching mode unconditionally is stupid. // XXX: switching mode unconditionally is stupid.
// if we were running free perhaps we like to behave differently // if we were running free perhaps we like to behave differently
@@ -146,169 +145,168 @@ int netjack_wait( netjack_driver_state_t *netj )


if( we_have_the_expected_frame ) { if( we_have_the_expected_frame ) {


jack_time_t now = jack_get_time();
if( now < netj->next_deadline )
netj->time_to_deadline = netj->next_deadline - now;
else
netj->time_to_deadline = 0;
packet_cache_retreive_packet_pointer( netj->packcache, netj->expected_framecnt, (char **) &(netj->rx_buf), netj->rx_bufsize , &packet_recv_time_stamp);
pkthdr = (jacknet_packet_header *) netj->rx_buf;
packet_header_ntoh(pkthdr);
netj->deadline_goodness = (int)pkthdr->sync_state;
netj->packet_data_valid = 1;
int want_deadline;
if( netj->jitter_val != 0 )
want_deadline = netj->jitter_val;
else if( netj->latency < 4 )
want_deadline = -netj->period_usecs/2;
else
want_deadline = (netj->period_usecs/4+10*(int)netj->period_usecs*netj->latency/100);
if( netj->deadline_goodness != MASTER_FREEWHEELS ) {
if( netj->deadline_goodness < want_deadline ) {
netj->next_deadline -= netj->period_usecs/100;
//jack_log( "goodness: %d, Adjust deadline: --- %d\n", netj->deadline_goodness, (int) netj->period_usecs*netj->latency/100 );
}
if( netj->deadline_goodness > want_deadline ) {
netj->next_deadline += netj->period_usecs/100;
//jack_log( "goodness: %d, Adjust deadline: +++ %d\n", netj->deadline_goodness, (int) netj->period_usecs*netj->latency/100 );
}
}
jack_time_t now = jack_get_time();
if( now < netj->next_deadline )
netj->time_to_deadline = netj->next_deadline - now;
else
netj->time_to_deadline = 0;
packet_cache_retreive_packet_pointer( netj->packcache, netj->expected_framecnt, (char **) & (netj->rx_buf), netj->rx_bufsize , &packet_recv_time_stamp);
pkthdr = (jacknet_packet_header *) netj->rx_buf;
packet_header_ntoh(pkthdr);
netj->deadline_goodness = (int)pkthdr->sync_state;
netj->packet_data_valid = 1;
int want_deadline;
if( netj->jitter_val != 0 )
want_deadline = netj->jitter_val;
else if( netj->latency < 4 )
want_deadline = -netj->period_usecs / 2;
else
want_deadline = (netj->period_usecs / 4 + 10 * (int)netj->period_usecs * netj->latency / 100);
if( netj->deadline_goodness != MASTER_FREEWHEELS ) {
if( netj->deadline_goodness < want_deadline ) {
netj->next_deadline -= netj->period_usecs / 100;
//jack_log( "goodness: %d, Adjust deadline: --- %d\n", netj->deadline_goodness, (int) netj->period_usecs*netj->latency/100 );
}
if( netj->deadline_goodness > want_deadline ) {
netj->next_deadline += netj->period_usecs / 100;
//jack_log( "goodness: %d, Adjust deadline: +++ %d\n", netj->deadline_goodness, (int) netj->period_usecs*netj->latency/100 );
}
}
// if( netj->next_deadline < (netj->period_usecs*70/100) ) { // if( netj->next_deadline < (netj->period_usecs*70/100) ) {
// jack_error( "master is forcing deadline_offset to below 70%% of period_usecs... increase latency setting on master" ); // jack_error( "master is forcing deadline_offset to below 70%% of period_usecs... increase latency setting on master" );
// netj->deadline_offset = (netj->period_usecs*90/100); // netj->deadline_offset = (netj->period_usecs*90/100);
// } // }


netj->next_deadline += netj->period_usecs;
netj->next_deadline += netj->period_usecs;
} else { } else {
netj->time_to_deadline = 0;
netj->next_deadline += netj->period_usecs;
// bah... the packet is not there.
// either
// - it got lost.
// - its late
// - sync source is not sending anymore.

// lets check if we have the next packets, we will just run a cycle without data.
// in that case.

if( packet_cache_get_next_available_framecnt( netj->packcache, netj->expected_framecnt, &next_frame_avail) )
{
jack_nframes_t offset = next_frame_avail - netj->expected_framecnt;

//XXX: hmm... i need to remember why resync_threshold wasnt right.
//if( offset < netj->resync_threshold )
if( offset < 10 ) {
// ok. dont do nothing. we will run without data.
// this seems to be one or 2 lost packets.
//
// this can also be reordered packet jitter.
// (maybe this is not happening in real live)
// but it happens in netem.

netj->packet_data_valid = 0;

// I also found this happening, when the packet queue, is too full.
// but wtf ? use a smaller latency. this link can handle that ;S
if( packet_cache_get_fill( netj->packcache, netj->expected_framecnt ) > 80.0 )
netj->next_deadline -= netj->period_usecs/2;


} else {
// the diff is too high. but we have a packet in the future.
// lets resync.
netj->expected_framecnt = next_frame_avail;
packet_cache_retreive_packet_pointer( netj->packcache, netj->expected_framecnt, (char **) &(netj->rx_buf), netj->rx_bufsize, NULL );
pkthdr = (jacknet_packet_header *) netj->rx_buf;
packet_header_ntoh(pkthdr);
//netj->deadline_goodness = 0;
netj->deadline_goodness = (int)pkthdr->sync_state - (int)netj->period_usecs * offset;
netj->next_deadline_valid = 0;
netj->packet_data_valid = 1;
}

} else {
// no packets in buffer.
netj->packet_data_valid = 0;

//printf( "frame %d No Packet in queue. num_lost_packets = %d \n", netj->expected_framecnt, netj->num_lost_packets );
if( netj->num_lost_packets < 5 ) {
// ok. No Packet in queue. The packet was either lost,
// or we are running too fast.
//
// Adjusting the deadline unconditionally resulted in
// too many xruns on master.
// But we need to adjust for the case we are running too fast.
// So lets check if the last packet is there now.
//
// It would not be in the queue anymore, if it had been
// retrieved. This might break for redundancy, but
// i will make the packet cache drop redundant packets,
// that have already been retreived.
//
if( packet_cache_get_highest_available_framecnt( netj->packcache, &next_frame_avail) ) {
if( next_frame_avail == (netj->expected_framecnt - 1) ) {
// Ok. the last packet is there now.
// and it had not been retrieved.
//
// TODO: We are still dropping 2 packets.
// perhaps we can adjust the deadline
// when (num_packets lost == 0)

// This might still be too much.
netj->next_deadline += netj->period_usecs;
}
}
} else if( (netj->num_lost_packets <= 100) ) {
// lets try adjusting the deadline harder, for some packets, we might have just ran 2 fast.
netj->next_deadline += netj->period_usecs*netj->latency/8;
} else {

// But now we can check for any new frame available.
//
if( packet_cache_get_highest_available_framecnt( netj->packcache, &next_frame_avail) ) {
netj->expected_framecnt = next_frame_avail;
packet_cache_retreive_packet_pointer( netj->packcache, netj->expected_framecnt, (char **) &(netj->rx_buf), netj->rx_bufsize, NULL );
pkthdr = (jacknet_packet_header *) netj->rx_buf;
packet_header_ntoh(pkthdr);
netj->deadline_goodness = pkthdr->sync_state;
netj->next_deadline_valid = 0;
netj->packet_data_valid = 1;
netj->running_free = 0;
jack_info( "resync after freerun... %d", netj->expected_framecnt );
} else {
if( netj->num_lost_packets == 101 ) {
jack_info( "master seems gone... entering freerun mode", netj->expected_framecnt );
}

netj->running_free = 1;

// when we really dont see packets.
// reset source address. and open possibility for new master.
// maybe dsl reconnect. Also restart of netsource without fix
// reply address changes port.
if (netj->num_lost_packets > 200 ) {
netj->srcaddress_valid = 0;
packet_cache_reset_master_address( netj->packcache );
}
}
}
}
netj->time_to_deadline = 0;
netj->next_deadline += netj->period_usecs;
// bah... the packet is not there.
// either
// - it got lost.
// - its late
// - sync source is not sending anymore.

// lets check if we have the next packets, we will just run a cycle without data.
// in that case.

if( packet_cache_get_next_available_framecnt( netj->packcache, netj->expected_framecnt, &next_frame_avail) ) {
jack_nframes_t offset = next_frame_avail - netj->expected_framecnt;

//XXX: hmm... i need to remember why resync_threshold wasnt right.
//if( offset < netj->resync_threshold )
if( offset < 10 ) {
// ok. dont do nothing. we will run without data.
// this seems to be one or 2 lost packets.
//
// this can also be reordered packet jitter.
// (maybe this is not happening in real live)
// but it happens in netem.

netj->packet_data_valid = 0;

// I also found this happening, when the packet queue, is too full.
// but wtf ? use a smaller latency. this link can handle that ;S
if( packet_cache_get_fill( netj->packcache, netj->expected_framecnt ) > 80.0 )
netj->next_deadline -= netj->period_usecs / 2;


} else {
// the diff is too high. but we have a packet in the future.
// lets resync.
netj->expected_framecnt = next_frame_avail;
packet_cache_retreive_packet_pointer( netj->packcache, netj->expected_framecnt, (char **) & (netj->rx_buf), netj->rx_bufsize, NULL );
pkthdr = (jacknet_packet_header *) netj->rx_buf;
packet_header_ntoh(pkthdr);
//netj->deadline_goodness = 0;
netj->deadline_goodness = (int)pkthdr->sync_state - (int)netj->period_usecs * offset;
netj->next_deadline_valid = 0;
netj->packet_data_valid = 1;
}

} else {
// no packets in buffer.
netj->packet_data_valid = 0;

//printf( "frame %d No Packet in queue. num_lost_packets = %d \n", netj->expected_framecnt, netj->num_lost_packets );
if( netj->num_lost_packets < 5 ) {
// ok. No Packet in queue. The packet was either lost,
// or we are running too fast.
//
// Adjusting the deadline unconditionally resulted in
// too many xruns on master.
// But we need to adjust for the case we are running too fast.
// So lets check if the last packet is there now.
//
// It would not be in the queue anymore, if it had been
// retrieved. This might break for redundancy, but
// i will make the packet cache drop redundant packets,
// that have already been retreived.
//
if( packet_cache_get_highest_available_framecnt( netj->packcache, &next_frame_avail) ) {
if( next_frame_avail == (netj->expected_framecnt - 1) ) {
// Ok. the last packet is there now.
// and it had not been retrieved.
//
// TODO: We are still dropping 2 packets.
// perhaps we can adjust the deadline
// when (num_packets lost == 0)

// This might still be too much.
netj->next_deadline += netj->period_usecs;
}
}
} else if( (netj->num_lost_packets <= 100) ) {
// lets try adjusting the deadline harder, for some packets, we might have just ran 2 fast.
netj->next_deadline += netj->period_usecs * netj->latency / 8;
} else {

// But now we can check for any new frame available.
//
if( packet_cache_get_highest_available_framecnt( netj->packcache, &next_frame_avail) ) {
netj->expected_framecnt = next_frame_avail;
packet_cache_retreive_packet_pointer( netj->packcache, netj->expected_framecnt, (char **) & (netj->rx_buf), netj->rx_bufsize, NULL );
pkthdr = (jacknet_packet_header *) netj->rx_buf;
packet_header_ntoh(pkthdr);
netj->deadline_goodness = pkthdr->sync_state;
netj->next_deadline_valid = 0;
netj->packet_data_valid = 1;
netj->running_free = 0;
jack_info( "resync after freerun... %d", netj->expected_framecnt );
} else {
if( netj->num_lost_packets == 101 ) {
jack_info( "master seems gone... entering freerun mode", netj->expected_framecnt );
}

netj->running_free = 1;

// when we really dont see packets.
// reset source address. and open possibility for new master.
// maybe dsl reconnect. Also restart of netsource without fix
// reply address changes port.
if (netj->num_lost_packets > 200 ) {
netj->srcaddress_valid = 0;
packet_cache_reset_master_address( netj->packcache );
}
}
}
}
} }


int retval = 0; int retval = 0;


if( !netj->packet_data_valid ) { if( !netj->packet_data_valid ) {
netj->num_lost_packets += 1;
if( netj->num_lost_packets == 1 )
retval = netj->period_usecs;
netj->num_lost_packets += 1;
if( netj->num_lost_packets == 1 )
retval = netj->period_usecs;
} else { } else {
if( (netj->num_lost_packets>1) && !netj->running_free )
retval = (netj->num_lost_packets-1) * netj->period_usecs;
if( (netj->num_lost_packets > 1) && !netj->running_free )
retval = (netj->num_lost_packets - 1) * netj->period_usecs;


netj->num_lost_packets = 0;
netj->num_lost_packets = 0;
} }


return retval; return retval;
@@ -338,19 +336,17 @@ void netjack_send_silence( netjack_driver_state_t *netj, int syncstate )
memset(packet_bufX, 0, payload_size); memset(packet_bufX, 0, payload_size);


packet_header_hton(tx_pkthdr); packet_header_hton(tx_pkthdr);
if (netj->srcaddress_valid)
{
int r;
if (netj->reply_port)
netj->syncsource_address.sin_port = htons(netj->reply_port);

for( r=0; r<netj->redundancy; r++ )
netjack_sendto(netj->outsockfd, (char *)packet_buf, tx_size,
0, (struct sockaddr*)&(netj->syncsource_address), sizeof(struct sockaddr_in), netj->mtu);
if (netj->srcaddress_valid) {
int r;
if (netj->reply_port)
netj->syncsource_address.sin_port = htons(netj->reply_port);

for( r = 0; r < netj->redundancy; r++ )
netjack_sendto(netj->outsockfd, (char *)packet_buf, tx_size,
0, (struct sockaddr*) & (netj->syncsource_address), sizeof(struct sockaddr_in), netj->mtu);
} }
} }



void netjack_attach( netjack_driver_state_t *netj ) void netjack_attach( netjack_driver_state_t *netj )
{ {
//puts ("net_driver_attach"); //puts ("net_driver_attach");
@@ -359,19 +355,17 @@ void netjack_attach( netjack_driver_state_t *netj )
unsigned int chn; unsigned int chn;
int port_flags; int port_flags;



if( netj->bitdepth == CELT_MODE )
{
if( netj->bitdepth == CELT_MODE ) {
#if HAVE_CELT #if HAVE_CELT
#if HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8 || HAVE_CELT_API_0_11 #if HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8 || HAVE_CELT_API_0_11
celt_int32 lookahead;
netj->celt_mode = celt_mode_create( netj->sample_rate, netj->period_size, NULL );
celt_int32 lookahead;
netj->celt_mode = celt_mode_create( netj->sample_rate, netj->period_size, NULL );
#else #else
celt_int32_t lookahead;
netj->celt_mode = celt_mode_create( netj->sample_rate, 1, netj->period_size, NULL );
celt_int32_t lookahead;
netj->celt_mode = celt_mode_create( netj->sample_rate, 1, netj->period_size, NULL );
#endif #endif
celt_mode_info( netj->celt_mode, CELT_GET_LOOKAHEAD, &lookahead );
netj->codec_latency = 2*lookahead;
celt_mode_info( netj->celt_mode, CELT_GET_LOOKAHEAD, &lookahead );
netj->codec_latency = 2 * lookahead;
#endif #endif
} }


@@ -394,21 +388,21 @@ void netjack_attach( netjack_driver_state_t *netj )
netj->capture_ports = netj->capture_ports =
jack_slist_append (netj->capture_ports, port); jack_slist_append (netj->capture_ports, port);


if( netj->bitdepth == CELT_MODE ) {
if( netj->bitdepth == CELT_MODE ) {
#if HAVE_CELT #if HAVE_CELT
#if HAVE_CELT_API_0_11 #if HAVE_CELT_API_0_11
netj->capture_srcs = jack_slist_append(netj->capture_srcs, celt_decoder_create_custom( netj->celt_mode, 1, NULL ) );
netj->capture_srcs = jack_slist_append(netj->capture_srcs, celt_decoder_create_custom( netj->celt_mode, 1, NULL ) );
#elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8 #elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8
netj->capture_srcs = jack_slist_append(netj->capture_srcs, celt_decoder_create( netj->celt_mode, 1, NULL ) );
netj->capture_srcs = jack_slist_append(netj->capture_srcs, celt_decoder_create( netj->celt_mode, 1, NULL ) );
#else #else
netj->capture_srcs = jack_slist_append(netj->capture_srcs, celt_decoder_create( netj->celt_mode ) );
netj->capture_srcs = jack_slist_append(netj->capture_srcs, celt_decoder_create( netj->celt_mode ) );
#endif #endif
#endif #endif
} else {
} else {
#if HAVE_SAMPLERATE #if HAVE_SAMPLERATE
netj->capture_srcs = jack_slist_append(netj->capture_srcs, src_new(SRC_LINEAR, 1, NULL));
netj->capture_srcs = jack_slist_append(netj->capture_srcs, src_new(SRC_LINEAR, 1, NULL));
#endif #endif
}
}
} }


for (chn = netj->capture_channels_audio; chn < netj->capture_channels; chn++) { for (chn = netj->capture_channels_audio; chn < netj->capture_channels; chn++) {
@@ -442,24 +436,24 @@ void netjack_attach( netjack_driver_state_t *netj )


netj->playback_ports = netj->playback_ports =
jack_slist_append (netj->playback_ports, port); jack_slist_append (netj->playback_ports, port);
if( netj->bitdepth == CELT_MODE ) {
if( netj->bitdepth == CELT_MODE ) {
#if HAVE_CELT #if HAVE_CELT
#if HAVE_CELT_API_0_11 #if HAVE_CELT_API_0_11
CELTMode *celt_mode = celt_mode_create( netj->sample_rate, netj->period_size, NULL );
netj->playback_srcs = jack_slist_append(netj->playback_srcs, celt_decoder_create_custom( celt_mode, 1, NULL ) );
CELTMode *celt_mode = celt_mode_create( netj->sample_rate, netj->period_size, NULL );
netj->playback_srcs = jack_slist_append(netj->playback_srcs, celt_decoder_create_custom( celt_mode, 1, NULL ) );
#elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8 #elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8
CELTMode *celt_mode = celt_mode_create( netj->sample_rate, netj->period_size, NULL );
netj->playback_srcs = jack_slist_append(netj->playback_srcs, celt_encoder_create( celt_mode, 1, NULL ) );
CELTMode *celt_mode = celt_mode_create( netj->sample_rate, netj->period_size, NULL );
netj->playback_srcs = jack_slist_append(netj->playback_srcs, celt_encoder_create( celt_mode, 1, NULL ) );
#else #else
CELTMode *celt_mode = celt_mode_create( netj->sample_rate, 1, netj->period_size, NULL );
netj->playback_srcs = jack_slist_append(netj->playback_srcs, celt_encoder_create( celt_mode ) );
CELTMode *celt_mode = celt_mode_create( netj->sample_rate, 1, netj->period_size, NULL );
netj->playback_srcs = jack_slist_append(netj->playback_srcs, celt_encoder_create( celt_mode ) );
#endif #endif
#endif #endif
} else {
} else {
#if HAVE_SAMPLERATE #if HAVE_SAMPLERATE
netj->playback_srcs = jack_slist_append(netj->playback_srcs, src_new(SRC_LINEAR, 1, NULL));
netj->playback_srcs = jack_slist_append(netj->playback_srcs, src_new(SRC_LINEAR, 1, NULL));
#endif #endif
}
}
} }
for (chn = netj->playback_channels_audio; chn < netj->playback_channels; chn++) { for (chn = netj->playback_channels_audio; chn < netj->playback_channels; chn++) {
snprintf (buf, sizeof(buf) - 1, "playback_%u", chn + 1); snprintf (buf, sizeof(buf) - 1, "playback_%u", chn + 1);
@@ -492,15 +486,12 @@ void netjack_detach( netjack_driver_state_t *netj )
jack_slist_free (netj->capture_ports); jack_slist_free (netj->capture_ports);
netj->capture_ports = NULL; netj->capture_ports = NULL;


for (node = netj->capture_srcs; node; node = jack_slist_next (node))
{
for (node = netj->capture_srcs; node; node = jack_slist_next (node)) {
#if HAVE_CELT #if HAVE_CELT
if( netj->bitdepth == CELT_MODE )
{
if( netj->bitdepth == CELT_MODE ) {
CELTDecoder * decoder = node->data; CELTDecoder * decoder = node->data;
celt_decoder_destroy(decoder); celt_decoder_destroy(decoder);
}
else
} else
#endif #endif
{ {
#if HAVE_SAMPLERATE #if HAVE_SAMPLERATE
@@ -519,15 +510,12 @@ void netjack_detach( netjack_driver_state_t *netj )
jack_slist_free (netj->playback_ports); jack_slist_free (netj->playback_ports);
netj->playback_ports = NULL; netj->playback_ports = NULL;


for (node = netj->playback_srcs; node; node = jack_slist_next (node))
{
for (node = netj->playback_srcs; node; node = jack_slist_next (node)) {
#if HAVE_CELT #if HAVE_CELT
if( netj->bitdepth == CELT_MODE )
{
if( netj->bitdepth == CELT_MODE ) {
CELTEncoder * encoder = node->data; CELTEncoder * encoder = node->data;
celt_encoder_destroy(encoder); celt_encoder_destroy(encoder);
}
else
} else
#endif #endif
{ {
#if HAVE_SAMPLERATE #if HAVE_SAMPLERATE
@@ -540,32 +528,32 @@ void netjack_detach( netjack_driver_state_t *netj )
netj->playback_srcs = NULL; netj->playback_srcs = NULL;


#if HAVE_CELT #if HAVE_CELT
if( netj->bitdepth == CELT_MODE )
celt_mode_destroy(netj->celt_mode);
if( netj->bitdepth == CELT_MODE )
celt_mode_destroy(netj->celt_mode);
#endif #endif
} }




netjack_driver_state_t *netjack_init (netjack_driver_state_t *netj, netjack_driver_state_t *netjack_init (netjack_driver_state_t *netj,
jack_client_t * client,
const char *name,
unsigned int capture_ports,
unsigned int playback_ports,
unsigned int capture_ports_midi,
unsigned int playback_ports_midi,
jack_nframes_t sample_rate,
jack_nframes_t period_size,
unsigned int listen_port,
unsigned int transport_sync,
unsigned int resample_factor,
unsigned int resample_factor_up,
unsigned int bitdepth,
unsigned int use_autoconfig,
unsigned int latency,
unsigned int redundancy,
int dont_htonl_floats,
int always_deadline,
int jitter_val )
jack_client_t * client,
const char *name,
unsigned int capture_ports,
unsigned int playback_ports,
unsigned int capture_ports_midi,
unsigned int playback_ports_midi,
jack_nframes_t sample_rate,
jack_nframes_t period_size,
unsigned int listen_port,
unsigned int transport_sync,
unsigned int resample_factor,
unsigned int resample_factor_up,
unsigned int bitdepth,
unsigned int use_autoconfig,
unsigned int latency,
unsigned int redundancy,
int dont_htonl_floats,
int always_deadline,
int jitter_val )
{ {


// Fill in netj values. // Fill in netj values.
@@ -600,8 +588,7 @@ netjack_driver_state_t *netjack_init (netjack_driver_state_t *netj,
netj->client = client; netj->client = client;




if ((bitdepth != 0) && (bitdepth != 8) && (bitdepth != 16) && (bitdepth != CELT_MODE))
{
if ((bitdepth != 0) && (bitdepth != 8) && (bitdepth != 16) && (bitdepth != CELT_MODE)) {
jack_info ("Invalid bitdepth: %d (8, 16 or 0 for float) !!!", bitdepth); jack_info ("Invalid bitdepth: %d (8, 16 or 0 for float) !!!", bitdepth);
return NULL; return NULL;
} }
@@ -647,8 +634,7 @@ netjack_startup( netjack_driver_state_t *netj )
address.sin_family = AF_INET; address.sin_family = AF_INET;
address.sin_port = htons(netj->listen_port); address.sin_port = htons(netj->listen_port);
address.sin_addr.s_addr = htonl(INADDR_ANY); address.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind (netj->sockfd, (struct sockaddr *) &address, sizeof (address)) < 0)
{
if (bind (netj->sockfd, (struct sockaddr *) &address, sizeof (address)) < 0) {
jack_info("bind error"); jack_info("bind error");
return -1; return -1;
} }
@@ -664,14 +650,13 @@ netjack_startup( netjack_driver_state_t *netj )
return -1; return -1;
} }
netj->srcaddress_valid = 0; netj->srcaddress_valid = 0;
if (netj->use_autoconfig)
{
if (netj->use_autoconfig) {
jacknet_packet_header *first_packet = alloca (sizeof (jacknet_packet_header)); jacknet_packet_header *first_packet = alloca (sizeof (jacknet_packet_header));
#ifdef WIN32
#ifdef WIN32
int address_size = sizeof( struct sockaddr_in ); int address_size = sizeof( struct sockaddr_in );
#else
#else
socklen_t address_size = sizeof (struct sockaddr_in); socklen_t address_size = sizeof (struct sockaddr_in);
#endif
#endif
//jack_info ("Waiting for an incoming packet !!!"); //jack_info ("Waiting for an incoming packet !!!");
//jack_info ("*** IMPORTANT *** Dont connect a client to jackd until the driver is attached to a clock source !!!"); //jack_info ("*** IMPORTANT *** Dont connect a client to jackd until the driver is attached to a clock source !!!");


@@ -681,51 +666,44 @@ netjack_startup( netjack_driver_state_t *netj )
return -1; return -1;
} }
first_pack_len = recvfrom (netj->sockfd, (char *)first_packet, sizeof (jacknet_packet_header), 0, (struct sockaddr*) & netj->syncsource_address, &address_size); first_pack_len = recvfrom (netj->sockfd, (char *)first_packet, sizeof (jacknet_packet_header), 0, (struct sockaddr*) & netj->syncsource_address, &address_size);
#ifdef WIN32
if( first_pack_len == -1 ) {
first_pack_len = sizeof(jacknet_packet_header);
break;
}
#else
if (first_pack_len == sizeof (jacknet_packet_header))
break;
#endif
#ifdef WIN32
if( first_pack_len == -1 ) {
first_pack_len = sizeof(jacknet_packet_header);
break;
}
#else
if (first_pack_len == sizeof (jacknet_packet_header))
break;
#endif
} }
netj->srcaddress_valid = 1; netj->srcaddress_valid = 1;


if (first_pack_len == sizeof (jacknet_packet_header))
{
if (first_pack_len == sizeof (jacknet_packet_header)) {
packet_header_ntoh (first_packet); packet_header_ntoh (first_packet);


jack_info ("AutoConfig Override !!!"); jack_info ("AutoConfig Override !!!");
if (netj->sample_rate != first_packet->sample_rate)
{
if (netj->sample_rate != first_packet->sample_rate) {
jack_info ("AutoConfig Override: Master JACK sample rate = %d", first_packet->sample_rate); jack_info ("AutoConfig Override: Master JACK sample rate = %d", first_packet->sample_rate);
netj->sample_rate = first_packet->sample_rate; netj->sample_rate = first_packet->sample_rate;
}
}


if (netj->period_size != first_packet->period_size)
{
if (netj->period_size != first_packet->period_size) {
jack_info ("AutoConfig Override: Master JACK period size is %d", first_packet->period_size); jack_info ("AutoConfig Override: Master JACK period size is %d", first_packet->period_size);
netj->period_size = first_packet->period_size; netj->period_size = first_packet->period_size;
}
if (netj->capture_channels_audio != first_packet->capture_channels_audio)
{
}
if (netj->capture_channels_audio != first_packet->capture_channels_audio) {
jack_info ("AutoConfig Override: capture_channels_audio = %d", first_packet->capture_channels_audio); jack_info ("AutoConfig Override: capture_channels_audio = %d", first_packet->capture_channels_audio);
netj->capture_channels_audio = first_packet->capture_channels_audio; netj->capture_channels_audio = first_packet->capture_channels_audio;
} }
if (netj->capture_channels_midi != first_packet->capture_channels_midi)
{
if (netj->capture_channels_midi != first_packet->capture_channels_midi) {
jack_info ("AutoConfig Override: capture_channels_midi = %d", first_packet->capture_channels_midi); jack_info ("AutoConfig Override: capture_channels_midi = %d", first_packet->capture_channels_midi);
netj->capture_channels_midi = first_packet->capture_channels_midi; netj->capture_channels_midi = first_packet->capture_channels_midi;
} }
if (netj->playback_channels_audio != first_packet->playback_channels_audio)
{
if (netj->playback_channels_audio != first_packet->playback_channels_audio) {
jack_info ("AutoConfig Override: playback_channels_audio = %d", first_packet->playback_channels_audio); jack_info ("AutoConfig Override: playback_channels_audio = %d", first_packet->playback_channels_audio);
netj->playback_channels_audio = first_packet->playback_channels_audio; netj->playback_channels_audio = first_packet->playback_channels_audio;
}
if (netj->playback_channels_midi != first_packet->playback_channels_midi)
{
}
if (netj->playback_channels_midi != first_packet->playback_channels_midi) {
jack_info ("AutoConfig Override: playback_channels_midi = %d", first_packet->playback_channels_midi); jack_info ("AutoConfig Override: playback_channels_midi = %d", first_packet->playback_channels_midi);
netj->playback_channels_midi = first_packet->playback_channels_midi; netj->playback_channels_midi = first_packet->playback_channels_midi;
} }
@@ -739,24 +717,24 @@ netjack_startup( netjack_driver_state_t *netj )
netj->playback_channels = netj->playback_channels_audio + netj->playback_channels_midi; netj->playback_channels = netj->playback_channels_audio + netj->playback_channels_midi;


if( (netj->capture_channels * netj->period_size * netj->latency * 4) > 100000000 ) { if( (netj->capture_channels * netj->period_size * netj->latency * 4) > 100000000 ) {
jack_error( "autoconfig requests more than 100MB packet cache... bailing out" );
exit(1);
jack_error( "autoconfig requests more than 100MB packet cache... bailing out" );
exit(1);
} }


if( netj->playback_channels > 1000 ) { if( netj->playback_channels > 1000 ) {
jack_error( "autoconfig requests more than 1000 playback channels... bailing out" );
exit(1);
jack_error( "autoconfig requests more than 1000 playback channels... bailing out" );
exit(1);
} }




if( netj->mtu < (2*sizeof( jacknet_packet_header )) ) {
jack_error( "bullshit mtu requested by autoconfig" );
exit(1);
if( netj->mtu < (2 * sizeof( jacknet_packet_header )) ) {
jack_error( "bullshit mtu requested by autoconfig" );
exit(1);
} }


if( netj->sample_rate == 0 ) { if( netj->sample_rate == 0 ) {
jack_error( "sample_rate 0 requested by autoconfig" );
exit(1);
jack_error( "sample_rate 0 requested by autoconfig" );
exit(1);
} }


// After possible Autoconfig: do all calculations... // After possible Autoconfig: do all calculations...
@@ -765,15 +743,15 @@ netjack_startup( netjack_driver_state_t *netj )
* 1000000.0f); * 1000000.0f);


if( netj->latency == 0 ) if( netj->latency == 0 )
netj->deadline_offset = 50*netj->period_usecs;
netj->deadline_offset = 50 * netj->period_usecs;
else else
netj->deadline_offset = netj->period_usecs + 10*netj->latency*netj->period_usecs/100;
netj->deadline_offset = netj->period_usecs + 10 * netj->latency * netj->period_usecs / 100;


if( netj->bitdepth == CELT_MODE ) { if( netj->bitdepth == CELT_MODE ) {
// celt mode. // celt mode.
// TODO: this is a hack. But i dont want to change the packet header. // TODO: this is a hack. But i dont want to change the packet header.
netj->resample_factor = (netj->resample_factor * netj->period_size * 1024 / netj->sample_rate / 8)&(~1);
netj->resample_factor_up = (netj->resample_factor_up * netj->period_size * 1024 / netj->sample_rate / 8)&(~1);
netj->resample_factor = (netj->resample_factor * netj->period_size * 1024 / netj->sample_rate / 8) & (~1);
netj->resample_factor_up = (netj->resample_factor_up * netj->period_size * 1024 / netj->sample_rate / 8) & (~1);


netj->net_period_down = netj->resample_factor; netj->net_period_down = netj->resample_factor;
netj->net_period_up = netj->resample_factor_up; netj->net_period_up = netj->resample_factor_up;
@@ -795,7 +773,7 @@ netjack_startup( netjack_driver_state_t *netj )
if( netj->latency == 0 ) if( netj->latency == 0 )
netj->resync_threshold = 0; netj->resync_threshold = 0;
else else
netj->resync_threshold = MIN( 15, netj->latency-1 );
netj->resync_threshold = MIN( 15, netj->latency - 1 );


netj->running_free = 0; netj->running_free = 0;




+ 92
- 92
common/netjack.h View File

@@ -37,113 +37,113 @@ extern "C"
{ {
#endif #endif


struct _packet_cache;
struct _packet_cache;


typedef struct _netjack_driver_state netjack_driver_state_t;
typedef struct _netjack_driver_state netjack_driver_state_t;


struct _netjack_driver_state {
jack_nframes_t net_period_up;
jack_nframes_t net_period_down;
struct _netjack_driver_state {
jack_nframes_t net_period_up;
jack_nframes_t net_period_down;


jack_nframes_t sample_rate;
jack_nframes_t bitdepth;
jack_nframes_t period_size;
jack_time_t period_usecs;
int dont_htonl_floats;
int always_deadline;
jack_nframes_t sample_rate;
jack_nframes_t bitdepth;
jack_nframes_t period_size;
jack_time_t period_usecs;
int dont_htonl_floats;
int always_deadline;


jack_nframes_t codec_latency;
jack_nframes_t codec_latency;


unsigned int listen_port;
unsigned int listen_port;


unsigned int capture_channels;
unsigned int playback_channels;
unsigned int capture_channels_audio;
unsigned int playback_channels_audio;
unsigned int capture_channels_midi;
unsigned int playback_channels_midi;
unsigned int capture_channels;
unsigned int playback_channels;
unsigned int capture_channels_audio;
unsigned int playback_channels_audio;
unsigned int capture_channels_midi;
unsigned int playback_channels_midi;


JSList *capture_ports;
JSList *playback_ports;
JSList *playback_srcs;
JSList *capture_srcs;
JSList *capture_ports;
JSList *playback_ports;
JSList *playback_srcs;
JSList *capture_srcs;


jack_client_t *client;
jack_client_t *client;


#ifdef WIN32 #ifdef WIN32
SOCKET sockfd;
SOCKET outsockfd;
SOCKET sockfd;
SOCKET outsockfd;
#else #else
int sockfd;
int outsockfd;
int sockfd;
int outsockfd;
#endif #endif


struct sockaddr_in syncsource_address;
int reply_port;
int srcaddress_valid;
int sync_state;
unsigned int handle_transport_sync;
unsigned int *rx_buf;
unsigned int rx_bufsize;
//unsigned int tx_bufsize;
unsigned int mtu;
unsigned int latency;
unsigned int redundancy;
jack_nframes_t expected_framecnt;
int expected_framecnt_valid;
unsigned int num_lost_packets;
jack_time_t next_deadline;
jack_time_t deadline_offset;
int next_deadline_valid;
int packet_data_valid;
int resync_threshold;
int running_free;
int deadline_goodness;
jack_time_t time_to_deadline;
unsigned int use_autoconfig;
unsigned int resample_factor;
unsigned int resample_factor_up;
int jitter_val;
struct _packet_cache * packcache;
struct sockaddr_in syncsource_address;
int reply_port;
int srcaddress_valid;
int sync_state;
unsigned int handle_transport_sync;
unsigned int *rx_buf;
unsigned int rx_bufsize;
//unsigned int tx_bufsize;
unsigned int mtu;
unsigned int latency;
unsigned int redundancy;
jack_nframes_t expected_framecnt;
int expected_framecnt_valid;
unsigned int num_lost_packets;
jack_time_t next_deadline;
jack_time_t deadline_offset;
int next_deadline_valid;
int packet_data_valid;
int resync_threshold;
int running_free;
int deadline_goodness;
jack_time_t time_to_deadline;
unsigned int use_autoconfig;
unsigned int resample_factor;
unsigned int resample_factor_up;
int jitter_val;
struct _packet_cache * packcache;
#if HAVE_CELT #if HAVE_CELT
CELTMode *celt_mode;
CELTMode *celt_mode;
#endif #endif
};
int netjack_wait( netjack_driver_state_t *netj );
void netjack_send_silence( netjack_driver_state_t *netj, int syncstate );
void netjack_read( netjack_driver_state_t *netj, jack_nframes_t nframes ) ;
void netjack_write( netjack_driver_state_t *netj, jack_nframes_t nframes, int syncstate );
void netjack_attach( netjack_driver_state_t *netj );
void netjack_detach( netjack_driver_state_t *netj );
netjack_driver_state_t *netjack_init (netjack_driver_state_t *netj,
jack_client_t * client,
const char *name,
unsigned int capture_ports,
unsigned int playback_ports,
unsigned int capture_ports_midi,
unsigned int playback_ports_midi,
jack_nframes_t sample_rate,
jack_nframes_t period_size,
unsigned int listen_port,
unsigned int transport_sync,
unsigned int resample_factor,
unsigned int resample_factor_up,
unsigned int bitdepth,
unsigned int use_autoconfig,
unsigned int latency,
unsigned int redundancy,
int dont_htonl_floats,
int always_deadline,
int jitter_val );
void netjack_release( netjack_driver_state_t *netj );
int netjack_startup( netjack_driver_state_t *netj );
};
int netjack_wait( netjack_driver_state_t *netj );
void netjack_send_silence( netjack_driver_state_t *netj, int syncstate );
void netjack_read( netjack_driver_state_t *netj, jack_nframes_t nframes ) ;
void netjack_write( netjack_driver_state_t *netj, jack_nframes_t nframes, int syncstate );
void netjack_attach( netjack_driver_state_t *netj );
void netjack_detach( netjack_driver_state_t *netj );
netjack_driver_state_t *netjack_init (netjack_driver_state_t *netj,
jack_client_t * client,
const char *name,
unsigned int capture_ports,
unsigned int playback_ports,
unsigned int capture_ports_midi,
unsigned int playback_ports_midi,
jack_nframes_t sample_rate,
jack_nframes_t period_size,
unsigned int listen_port,
unsigned int transport_sync,
unsigned int resample_factor,
unsigned int resample_factor_up,
unsigned int bitdepth,
unsigned int use_autoconfig,
unsigned int latency,
unsigned int redundancy,
int dont_htonl_floats,
int always_deadline,
int jitter_val );
void netjack_release( netjack_driver_state_t *netj );
int netjack_startup( netjack_driver_state_t *netj );


#ifdef __cplusplus #ifdef __cplusplus
} }


+ 187
- 279
common/netjack_packet.c View File

@@ -152,13 +152,12 @@ packet_cache
int i, fragment_number; int i, fragment_number;


if( pkt_size == sizeof(jacknet_packet_header) ) if( pkt_size == sizeof(jacknet_packet_header) )
fragment_number = 1;
fragment_number = 1;
else else
fragment_number = (pkt_size - sizeof (jacknet_packet_header) - 1) / fragment_payload_size + 1;
fragment_number = (pkt_size - sizeof (jacknet_packet_header) - 1) / fragment_payload_size + 1;


packet_cache *pcache = malloc (sizeof (packet_cache)); packet_cache *pcache = malloc (sizeof (packet_cache));
if (pcache == NULL)
{
if (pcache == NULL) {
jack_error ("could not allocate packet cache (1)"); jack_error ("could not allocate packet cache (1)");
return NULL; return NULL;
} }
@@ -169,14 +168,12 @@ packet_cache
pcache->last_framecnt_retreived = 0; pcache->last_framecnt_retreived = 0;
pcache->last_framecnt_retreived_valid = 0; pcache->last_framecnt_retreived_valid = 0;


if (pcache->packets == NULL)
{
if (pcache->packets == NULL) {
jack_error ("could not allocate packet cache (2)"); jack_error ("could not allocate packet cache (2)");
return NULL; return NULL;
} }


for (i = 0; i < num_packets; i++)
{
for (i = 0; i < num_packets; i++) {
pcache->packets[i].valid = 0; pcache->packets[i].valid = 0;
pcache->packets[i].num_fragments = fragment_number; pcache->packets[i].num_fragments = fragment_number;
pcache->packets[i].packet_size = pkt_size; pcache->packets[i].packet_size = pkt_size;
@@ -184,8 +181,7 @@ packet_cache
pcache->packets[i].framecnt = 0; pcache->packets[i].framecnt = 0;
pcache->packets[i].fragment_array = malloc (sizeof (char) * fragment_number); pcache->packets[i].fragment_array = malloc (sizeof (char) * fragment_number);
pcache->packets[i].packet_buf = malloc (pkt_size); pcache->packets[i].packet_buf = malloc (pkt_size);
if ((pcache->packets[i].fragment_array == NULL) || (pcache->packets[i].packet_buf == NULL))
{
if ((pcache->packets[i].fragment_array == NULL) || (pcache->packets[i].packet_buf == NULL)) {
jack_error ("could not allocate packet cache (3)"); jack_error ("could not allocate packet cache (3)");
return NULL; return NULL;
} }
@@ -200,10 +196,9 @@ packet_cache_free (packet_cache *pcache)
{ {
int i; int i;
if( pcache == NULL ) if( pcache == NULL )
return;
return;


for (i = 0; i < pcache->size; i++)
{
for (i = 0; i < pcache->size; i++) {
free (pcache->packets[i].fragment_array); free (pcache->packets[i].fragment_array);
free (pcache->packets[i].packet_buf); free (pcache->packets[i].packet_buf);
} }
@@ -218,8 +213,7 @@ cache_packet
int i; int i;
cache_packet *retval; cache_packet *retval;


for (i = 0; i < pcache->size; i++)
{
for (i = 0; i < pcache->size; i++) {
if (pcache->packets[i].valid && (pcache->packets[i].framecnt == framecnt)) if (pcache->packets[i].valid && (pcache->packets[i].framecnt == framecnt))
return &(pcache->packets[i]); return &(pcache->packets[i]);
} }
@@ -228,8 +222,7 @@ cache_packet
// find a free packet. // find a free packet.


retval = packet_cache_get_free_packet (pcache); retval = packet_cache_get_free_packet (pcache);
if (retval != NULL)
{
if (retval != NULL) {
cache_packet_set_framecnt (retval, framecnt); cache_packet_set_framecnt (retval, framecnt);
return retval; return retval;
} }
@@ -257,10 +250,8 @@ cache_packet
cache_packet *retval = &(pcache->packets[0]); cache_packet *retval = &(pcache->packets[0]);
int i; int i;


for (i = 0; i < pcache->size; i++)
{
if (pcache->packets[i].valid && (pcache->packets[i].framecnt < minimal_frame))
{
for (i = 0; i < pcache->size; i++) {
if (pcache->packets[i].valid && (pcache->packets[i].framecnt < minimal_frame)) {
minimal_frame = pcache->packets[i].framecnt; minimal_frame = pcache->packets[i].framecnt;
retval = &(pcache->packets[i]); retval = &(pcache->packets[i]);
} }
@@ -274,8 +265,7 @@ cache_packet
{ {
int i; int i;


for (i = 0; i < pcache->size; i++)
{
for (i = 0; i < pcache->size; i++) {
if (pcache->packets[i].valid == 0) if (pcache->packets[i].valid == 0)
return &(pcache->packets[i]); return &(pcache->packets[i]);
} }
@@ -320,28 +310,23 @@ cache_packet_add_fragment (cache_packet *pack, char *packet_buf, int rcv_len)
jack_nframes_t fragment_nr = ntohl (pkthdr->fragment_nr); jack_nframes_t fragment_nr = ntohl (pkthdr->fragment_nr);
jack_nframes_t framecnt = ntohl (pkthdr->framecnt); jack_nframes_t framecnt = ntohl (pkthdr->framecnt);


if (framecnt != pack->framecnt)
{
if (framecnt != pack->framecnt) {
jack_error ("errror. framecnts dont match"); jack_error ("errror. framecnts dont match");
return; return;
} }


if (fragment_nr == 0)
{
if (fragment_nr == 0) {
memcpy (pack->packet_buf, packet_buf, rcv_len); memcpy (pack->packet_buf, packet_buf, rcv_len);
pack->fragment_array[0] = 1; pack->fragment_array[0] = 1;


return; 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)))
{
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)); memcpy (packet_bufX + fragment_nr * fragment_payload_size, dataX, rcv_len - sizeof (jacknet_packet_header));
pack->fragment_array[fragment_nr] = 1; pack->fragment_array[fragment_nr] = 1;
}
else
} else
jack_error ("too long packet received..."); jack_error ("too long packet received...");
} }
} }
@@ -373,11 +358,11 @@ netjack_poll_deadline (int sockfd, jack_time_t deadline)


jack_time_t now = jack_get_time(); jack_time_t now = jack_get_time();
if( now >= deadline ) if( now >= deadline )
return 0;
return 0;


if( (deadline-now) >= 1000000 ) {
jack_error( "deadline more than 1 second in the future, trimming it." );
deadline = now+500000;
if( (deadline - now) >= 1000000 ) {
jack_error( "deadline more than 1 second in the future, trimming it." );
deadline = now + 500000;
} }
#if HAVE_PPOLL #if HAVE_PPOLL
timeout_spec.tv_nsec = (deadline - now) * 1000; timeout_spec.tv_nsec = (deadline - now) * 1000;
@@ -394,25 +379,23 @@ netjack_poll_deadline (int sockfd, jack_time_t deadline)
poll_err = poll (&fds, 1, timeout); poll_err = poll (&fds, 1, timeout);
#endif #endif


if (poll_err == -1)
{
switch (errno)
{
if (poll_err == -1) {
switch (errno) {
case EBADF: case EBADF:
jack_error ("Error %d: An invalid file descriptor was given in one of the sets", errno);
break;
jack_error ("Error %d: An invalid file descriptor was given in one of the sets", errno);
break;
case EFAULT: case EFAULT:
jack_error ("Error %d: The array given as argument was not contained in the calling program's address space", errno);
break;
jack_error ("Error %d: The array given as argument was not contained in the calling program's address space", errno);
break;
case EINTR: case EINTR:
jack_error ("Error %d: A signal occurred before any requested event", errno);
break;
jack_error ("Error %d: A signal occurred before any requested event", errno);
break;
case EINVAL: case EINVAL:
jack_error ("Error %d: The nfds value exceeds the RLIMIT_NOFILE value", errno);
break;
jack_error ("Error %d: The nfds value exceeds the RLIMIT_NOFILE value", errno);
break;
case ENOMEM: case ENOMEM:
jack_error ("Error %d: There was no space to allocate file descriptor tables", errno);
break;
jack_error ("Error %d: There was no space to allocate file descriptor tables", errno);
break;
} }
} }
return poll_err; return poll_err;
@@ -427,17 +410,17 @@ netjack_poll (int sockfd, int timeout)
struct sigaction action; struct sigaction action;


sigemptyset(&sigmask); 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;
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++) for (i = 1; i < NSIG; i++)
if (sigismember (&sigmask, i)) if (sigismember (&sigmask, i))
@@ -447,31 +430,28 @@ netjack_poll (int sockfd, int timeout)
fds.events = POLLIN; fds.events = POLLIN;


sigprocmask(SIG_UNBLOCK, &sigmask, &rsigmask); sigprocmask(SIG_UNBLOCK, &sigmask, &rsigmask);
while (poll_err == 0)
{
while (poll_err == 0) {
poll_err = poll (&fds, 1, timeout); poll_err = poll (&fds, 1, timeout);
} }
sigprocmask(SIG_SETMASK, &rsigmask, NULL); sigprocmask(SIG_SETMASK, &rsigmask, NULL);


if (poll_err == -1)
{
switch (errno)
{
if (poll_err == -1) {
switch (errno) {
case EBADF: case EBADF:
jack_error ("Error %d: An invalid file descriptor was given in one of the sets", errno);
break;
jack_error ("Error %d: An invalid file descriptor was given in one of the sets", errno);
break;
case EFAULT: case EFAULT:
jack_error ("Error %d: The array given as argument was not contained in the calling program's address space", errno);
break;
jack_error ("Error %d: The array given as argument was not contained in the calling program's address space", errno);
break;
case EINTR: case EINTR:
jack_error ("Error %d: A signal occurred before any requested event", errno);
break;
jack_error ("Error %d: A signal occurred before any requested event", errno);
break;
case EINVAL: case EINVAL:
jack_error ("Error %d: The nfds value exceeds the RLIMIT_NOFILE value", errno);
break;
jack_error ("Error %d: The nfds value exceeds the RLIMIT_NOFILE value", errno);
break;
case ENOMEM: case ENOMEM:
jack_error ("Error %d: There was no space to allocate file descriptor tables", errno);
break;
jack_error ("Error %d: There was no space to allocate file descriptor tables", errno);
break;
} }
return 0; return 0;
} }
@@ -496,10 +476,10 @@ netjack_poll_deadline (int sockfd, jack_time_t deadline)
while( 1 ) { while( 1 ) {
jack_time_t now = jack_get_time(); jack_time_t now = jack_get_time();
if( now >= deadline ) if( now >= deadline )
return 0;
return 0;


int timeout_usecs = (deadline - now); int timeout_usecs = (deadline - now);
//jack_error( "timeout = %d", timeout_usecs );
//jack_error( "timeout = %d", timeout_usecs );
timeout.tv_sec = 0; timeout.tv_sec = 0;
timeout.tv_usec = (timeout_usecs < 500) ? 500 : timeout_usecs; timeout.tv_usec = (timeout_usecs < 500) ? 500 : timeout_usecs;
timeout.tv_usec = (timeout_usecs > 1000000) ? 500000 : timeout_usecs; timeout.tv_usec = (timeout_usecs > 1000000) ? 500000 : timeout_usecs;
@@ -531,36 +511,35 @@ packet_cache_drain_socket( packet_cache *pcache, int sockfd )
#else #else
socklen_t senderlen = sizeof( struct sockaddr_in ); socklen_t senderlen = sizeof( struct sockaddr_in );
#endif #endif
while (1)
{
while (1) {
#ifdef WIN32 #ifdef WIN32
rcv_len = recvfrom (sockfd, rx_packet, pcache->mtu, 0, rcv_len = recvfrom (sockfd, rx_packet, pcache->mtu, 0,
(struct sockaddr*) &sender_address, &senderlen);
(struct sockaddr*) &sender_address, &senderlen);
#else #else
rcv_len = recvfrom (sockfd, rx_packet, pcache->mtu, MSG_DONTWAIT, rcv_len = recvfrom (sockfd, rx_packet, pcache->mtu, MSG_DONTWAIT,
(struct sockaddr*) &sender_address, &senderlen);
(struct sockaddr*) &sender_address, &senderlen);
#endif #endif
if (rcv_len < 0) if (rcv_len < 0)
return; 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;
}
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); framecnt = ntohl (pkthdr->framecnt);
if( pcache->last_framecnt_retreived_valid && (framecnt <= pcache->last_framecnt_retreived ))
continue;
if( pcache->last_framecnt_retreived_valid && (framecnt <= pcache->last_framecnt_retreived ))
continue;


cpack = packet_cache_get_packet (pcache, framecnt); cpack = packet_cache_get_packet (pcache, framecnt);
cache_packet_add_fragment (cpack, rx_packet, rcv_len); cache_packet_add_fragment (cpack, rx_packet, rcv_len);
cpack->recv_timestamp = jack_get_time();
cpack->recv_timestamp = jack_get_time();
} }
} }


@@ -577,10 +556,8 @@ packet_cache_clear_old_packets (packet_cache *pcache, jack_nframes_t framecnt )
{ {
int i; int i;


for (i = 0; i < pcache->size; i++)
{
if (pcache->packets[i].valid && (pcache->packets[i].framecnt < framecnt))
{
for (i = 0; i < pcache->size; i++) {
if (pcache->packets[i].valid && (pcache->packets[i].framecnt < framecnt)) {
cache_packet_reset (&(pcache->packets[i])); cache_packet_reset (&(pcache->packets[i]));
} }
} }
@@ -654,8 +631,7 @@ packet_cache_get_fill( packet_cache *pcache, jack_nframes_t expected_framecnt )
int num_packets_before_us = 0; int num_packets_before_us = 0;
int i; int i;


for (i = 0; i < pcache->size; i++)
{
for (i = 0; i < pcache->size; i++) {
cache_packet *cpack = &(pcache->packets[i]); cache_packet *cpack = &(pcache->packets[i]);
if (cpack->valid && cache_packet_is_complete( cpack )) if (cpack->valid && cache_packet_is_complete( cpack ))
if( cpack->framecnt >= expected_framecnt ) if( cpack->framecnt >= expected_framecnt )
@@ -670,11 +646,10 @@ int
packet_cache_get_next_available_framecnt( packet_cache *pcache, jack_nframes_t expected_framecnt, jack_nframes_t *framecnt ) packet_cache_get_next_available_framecnt( packet_cache *pcache, jack_nframes_t expected_framecnt, jack_nframes_t *framecnt )
{ {
int i; int i;
jack_nframes_t best_offset = JACK_MAX_FRAMES/2-1;
jack_nframes_t best_offset = JACK_MAX_FRAMES / 2 - 1;
int retval = 0; int retval = 0;


for (i = 0; i < pcache->size; i++)
{
for (i = 0; i < pcache->size; i++) {
cache_packet *cpack = &(pcache->packets[i]); cache_packet *cpack = &(pcache->packets[i]);
//printf( "p%d: valid=%d, frame %d\n", i, cpack->valid, cpack->framecnt ); //printf( "p%d: valid=%d, frame %d\n", i, cpack->valid, cpack->framecnt );


@@ -688,13 +663,13 @@ packet_cache_get_next_available_framecnt( packet_cache *pcache, jack_nframes_t e


if( (cpack->framecnt - expected_framecnt) > best_offset ) { if( (cpack->framecnt - expected_framecnt) > best_offset ) {
continue; continue;
}
}


best_offset = cpack->framecnt - expected_framecnt;
retval = 1;
best_offset = cpack->framecnt - expected_framecnt;
retval = 1;


if (best_offset == 0)
break;
if (best_offset == 0)
break;
} }
if (retval && framecnt) if (retval && framecnt)
*framecnt = expected_framecnt + best_offset; *framecnt = expected_framecnt + best_offset;
@@ -709,22 +684,21 @@ packet_cache_get_highest_available_framecnt( packet_cache *pcache, jack_nframes_
jack_nframes_t best_value = 0; jack_nframes_t best_value = 0;
int retval = 0; int retval = 0;


for (i = 0; i < pcache->size; i++)
{
for (i = 0; i < pcache->size; i++) {
cache_packet *cpack = &(pcache->packets[i]); cache_packet *cpack = &(pcache->packets[i]);
//printf( "p%d: valid=%d, frame %d\n", i, cpack->valid, cpack->framecnt ); //printf( "p%d: valid=%d, frame %d\n", i, cpack->valid, cpack->framecnt );


if (!cpack->valid || !cache_packet_is_complete( cpack )) { if (!cpack->valid || !cache_packet_is_complete( cpack )) {
//printf( "invalid\n" ); //printf( "invalid\n" );
continue; continue;
}
}


if (cpack->framecnt < best_value) {
continue;
}
if (cpack->framecnt < best_value) {
continue;
}


best_value = cpack->framecnt;
retval = 1;
best_value = cpack->framecnt;
retval = 1;


} }
if (retval && framecnt) if (retval && framecnt)
@@ -741,25 +715,24 @@ packet_cache_find_latency( packet_cache *pcache, jack_nframes_t expected_framecn
jack_nframes_t best_offset = 0; jack_nframes_t best_offset = 0;
int retval = 0; int retval = 0;


for (i = 0; i < pcache->size; i++)
{
for (i = 0; i < pcache->size; i++) {
cache_packet *cpack = &(pcache->packets[i]); cache_packet *cpack = &(pcache->packets[i]);
//printf( "p%d: valid=%d, frame %d\n", i, cpack->valid, cpack->framecnt ); //printf( "p%d: valid=%d, frame %d\n", i, cpack->valid, cpack->framecnt );


if (!cpack->valid || !cache_packet_is_complete( cpack )) { if (!cpack->valid || !cache_packet_is_complete( cpack )) {
//printf( "invalid\n" ); //printf( "invalid\n" );
continue; continue;
}
}


if ((cpack->framecnt - expected_framecnt) < best_offset) {
continue;
}
if ((cpack->framecnt - expected_framecnt) < best_offset) {
continue;
}


best_offset = cpack->framecnt - expected_framecnt;
retval = 1;
best_offset = cpack->framecnt - expected_framecnt;
retval = 1;


if( best_offset == 0 )
break;
if( best_offset == 0 )
break;
} }
if (retval && framecnt) if (retval && framecnt)
*framecnt = JACK_MAX_FRAMES - best_offset; *framecnt = JACK_MAX_FRAMES - best_offset;
@@ -785,13 +758,11 @@ netjack_sendto (int sockfd, char *packet_buf, int pkt_size, int flags, struct so
pkthdr = (jacknet_packet_header *) packet_buf; pkthdr = (jacknet_packet_header *) packet_buf;
pkthdr->fragment_nr = htonl (0); pkthdr->fragment_nr = htonl (0);
err = sendto(sockfd, packet_buf, pkt_size, flags, addr, addr_size); err = sendto(sockfd, packet_buf, pkt_size, flags, addr, addr_size);
if( err<0 ) {
if( err < 0 ) {
//printf( "error in send\n" ); //printf( "error in send\n" );
perror( "send" ); perror( "send" );
} }
}
else
{
} else {
int err; int err;
// Copy the packet header to the tx pack first. // Copy the packet header to the tx pack first.
memcpy(tx_packet, packet_buf, sizeof (jacknet_packet_header)); memcpy(tx_packet, packet_buf, sizeof (jacknet_packet_header));
@@ -799,8 +770,7 @@ netjack_sendto (int sockfd, char *packet_buf, int pkt_size, int flags, struct so
// Now loop and send all // Now loop and send all
char *packet_bufX = packet_buf + sizeof (jacknet_packet_header); char *packet_bufX = packet_buf + sizeof (jacknet_packet_header);


while (packet_bufX < (packet_buf + pkt_size - fragment_payload_size))
{
while (packet_bufX < (packet_buf + pkt_size - fragment_payload_size)) {
pkthdr->fragment_nr = htonl (frag_cnt++); pkthdr->fragment_nr = htonl (frag_cnt++);
memcpy (dataX, packet_bufX, fragment_payload_size); memcpy (dataX, packet_bufX, fragment_payload_size);
sendto (sockfd, tx_packet, mtu, flags, addr, addr_size); sendto (sockfd, tx_packet, mtu, flags, addr, addr_size);
@@ -814,7 +784,7 @@ netjack_sendto (int sockfd, char *packet_buf, int pkt_size, int flags, struct so


// sendto(last_pack_size); // sendto(last_pack_size);
err = sendto(sockfd, tx_packet, last_payload_size + sizeof(jacknet_packet_header), flags, addr, addr_size); err = sendto(sockfd, tx_packet, last_payload_size + sizeof(jacknet_packet_header), flags, addr, addr_size);
if( err<0 ) {
if( err < 0 ) {
//printf( "error in send\n" ); //printf( "error in send\n" );
perror( "send" ); perror( "send" );
} }
@@ -826,24 +796,21 @@ decode_midi_buffer (uint32_t *buffer_uint32, unsigned int buffer_size_uint32, ja
{ {
int i; int i;
jack_midi_clear_buffer (buf); jack_midi_clear_buffer (buf);
for (i = 0; i < buffer_size_uint32 - 3;)
{
for (i = 0; i < buffer_size_uint32 - 3;) {
uint32_t payload_size; uint32_t payload_size;
payload_size = buffer_uint32[i]; payload_size = buffer_uint32[i];
payload_size = ntohl (payload_size); payload_size = ntohl (payload_size);
if (payload_size)
{
if (payload_size) {
jack_midi_event_t event; 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]));
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); jack_midi_event_write (buf, event.time, event.buffer, event.size);


// skip to the next event // skip to the next event
unsigned int nb_data_quads = (((event.size-1) & ~0x3) >> 2)+1;
i += 3+nb_data_quads;
}
else
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 break; // no events can follow an empty event, we're done
} }
} }
@@ -855,38 +822,34 @@ encode_midi_buffer (uint32_t *buffer_uint32, unsigned int buffer_size_uint32, ja
unsigned int written = 0; unsigned int written = 0;
// midi port, encode midi events // midi port, encode midi events
unsigned int nevents = jack_midi_get_event_count (buf); unsigned int nevents = jack_midi_get_event_count (buf);
for (i = 0; i < nevents; ++i)
{
for (i = 0; i < nevents; ++i) {
jack_midi_event_t event; jack_midi_event_t event;
jack_midi_event_get (&event, buf, i); jack_midi_event_get (&event, buf, i);
unsigned int nb_data_quads = (((event.size - 1) & ~0x3) >> 2) + 1; unsigned int nb_data_quads = (((event.size - 1) & ~0x3) >> 2) + 1;
unsigned int payload_size = 3 + nb_data_quads; unsigned int payload_size = 3 + nb_data_quads;
// only write if we have sufficient space for the event // only write if we have sufficient space for the event
// otherwise drop it // otherwise drop it
if (written + payload_size < buffer_size_uint32 - 1)
{
if (written + payload_size < buffer_size_uint32 - 1) {
// write header // write header
buffer_uint32[written]=htonl (payload_size);
buffer_uint32[written] = htonl (payload_size);
written++; written++;
buffer_uint32[written]=htonl (event.time);
buffer_uint32[written] = htonl (event.time);
written++; written++;
buffer_uint32[written]=htonl (event.size);
buffer_uint32[written] = htonl (event.size);
written++; written++;


// write data // write data
jack_midi_data_t* tmpbuff = (jack_midi_data_t*)(&(buffer_uint32[written])); jack_midi_data_t* tmpbuff = (jack_midi_data_t*)(&(buffer_uint32[written]));
memcpy (tmpbuff, event.buffer, event.size); memcpy (tmpbuff, event.buffer, event.size);
written += nb_data_quads; written += nb_data_quads;
}
else
{
} else {
// buffer overflow // buffer overflow
jack_error ("midi buffer overflow"); jack_error ("midi buffer overflow");
break; break;
} }
} }
// now put a netjack_midi 'no-payload' event, signaling EOF // now put a netjack_midi 'no-payload' event, signaling EOF
buffer_uint32[written]=0;
buffer_uint32[written] = 0;
} }


// render functions for float // render functions for float
@@ -904,8 +867,7 @@ render_payload_to_jack_ports_float ( void *packet_payload, jack_nframes_t net_pe
if (!packet_payload) if (!packet_payload)
return; return;


while (node != NULL)
{
while (node != NULL) {
int i; int i;
int_float_t val; int_float_t val;
#if HAVE_SAMPLERATE #if HAVE_SAMPLERATE
@@ -917,15 +879,12 @@ render_payload_to_jack_ports_float ( void *packet_payload, jack_nframes_t net_pe


const char *porttype = jack_port_type (port); const char *porttype = jack_port_type (port);


if (jack_port_is_audio (porttype))
{
if (jack_port_is_audio (porttype)) {
#if HAVE_SAMPLERATE #if HAVE_SAMPLERATE
// audio port, resample if necessary // audio port, resample if necessary
if (net_period_down != nframes)
{
if (net_period_down != nframes) {
SRC_STATE *src_state = src_node->data; SRC_STATE *src_state = src_node->data;
for (i = 0; i < net_period_down; i++)
{
for (i = 0; i < net_period_down; i++) {
packet_bufX[i] = ntohl (packet_bufX[i]); packet_bufX[i] = ntohl (packet_bufX[i]);
} }


@@ -941,27 +900,20 @@ render_payload_to_jack_ports_float ( void *packet_payload, jack_nframes_t net_pe
src_set_ratio (src_state, src.src_ratio); src_set_ratio (src_state, src.src_ratio);
src_process (src_state, &src); src_process (src_state, &src);
src_node = jack_slist_next (src_node); src_node = jack_slist_next (src_node);
}
else
} else
#endif #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;
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))
{
} else if (jack_port_is_midi (porttype)) {
// midi port, decode midi events // midi port, decode midi events
// convert the data buffer to a standard format (uint32_t based) // convert the data buffer to a standard format (uint32_t based)
unsigned int buffer_size_uint32 = net_period_down; unsigned int buffer_size_uint32 = net_period_down;
@@ -985,8 +937,7 @@ render_jack_ports_to_payload_float (JSList *playback_ports, JSList *playback_src


uint32_t *packet_bufX = (uint32_t *) packet_payload; uint32_t *packet_bufX = (uint32_t *) packet_payload;


while (node != NULL)
{
while (node != NULL) {
#if HAVE_SAMPLERATE #if HAVE_SAMPLERATE
SRC_DATA src; SRC_DATA src;
#endif #endif
@@ -997,8 +948,7 @@ render_jack_ports_to_payload_float (JSList *playback_ports, JSList *playback_src


const char *porttype = jack_port_type (port); const char *porttype = jack_port_type (port);


if (jack_port_is_audio (porttype))
{
if (jack_port_is_audio (porttype)) {
// audio port, resample if necessary // audio port, resample if necessary


#if HAVE_SAMPLERATE #if HAVE_SAMPLERATE
@@ -1016,32 +966,24 @@ render_jack_ports_to_payload_float (JSList *playback_ports, JSList *playback_src
src_set_ratio (src_state, src.src_ratio); src_set_ratio (src_state, src.src_ratio);
src_process (src_state, &src); src_process (src_state, &src);


for (i = 0; i < net_period_up; i++)
{
for (i = 0; i < net_period_up; i++) {
packet_bufX[i] = htonl (packet_bufX[i]); packet_bufX[i] = htonl (packet_bufX[i]);
} }
src_node = jack_slist_next (src_node); src_node = jack_slist_next (src_node);
}
else
} else
#endif #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;
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))
{
} else if (jack_port_is_midi (porttype)) {
// encode midi events from port to packet // encode midi events from port to packet
// convert the data buffer to a standard format (uint32_t based) // convert the data buffer to a standard format (uint32_t based)
unsigned int buffer_size_uint32 = net_period_up; unsigned int buffer_size_uint32 = net_period_up;
@@ -1067,10 +1009,9 @@ render_payload_to_jack_ports_16bit (void *packet_payload, jack_nframes_t net_per
uint16_t *packet_bufX = (uint16_t *)packet_payload; uint16_t *packet_bufX = (uint16_t *)packet_payload;


if( !packet_payload ) if( !packet_payload )
return;
return;


while (node != NULL)
{
while (node != NULL) {
int i; int i;
//uint32_t val; //uint32_t val;
#if HAVE_SAMPLERATE #if HAVE_SAMPLERATE
@@ -1085,16 +1026,13 @@ render_payload_to_jack_ports_16bit (void *packet_payload, jack_nframes_t net_per
#endif #endif
const char *porttype = jack_port_type (port); const char *porttype = jack_port_type (port);


if (jack_port_is_audio (porttype))
{
if (jack_port_is_audio (porttype)) {
// audio port, resample if necessary // audio port, resample if necessary


#if HAVE_SAMPLERATE #if HAVE_SAMPLERATE
if (net_period_down != nframes)
{
if (net_period_down != nframes) {
SRC_STATE *src_state = src_node->data; SRC_STATE *src_state = src_node->data;
for (i = 0; i < net_period_down; i++)
{
for (i = 0; i < net_period_down; i++) {
floatbuf[i] = ((float) ntohs(packet_bufX[i])) / 32767.0 - 1.0; floatbuf[i] = ((float) ntohs(packet_bufX[i])) / 32767.0 - 1.0;
} }


@@ -1110,14 +1048,11 @@ render_payload_to_jack_ports_16bit (void *packet_payload, jack_nframes_t net_per
src_set_ratio (src_state, src.src_ratio); src_set_ratio (src_state, src.src_ratio);
src_process (src_state, &src); src_process (src_state, &src);
src_node = jack_slist_next (src_node); src_node = jack_slist_next (src_node);
}
else
} else
#endif #endif
for (i = 0; i < net_period_down; i++) for (i = 0; i < net_period_down; i++)
buf[i] = ((float) ntohs (packet_bufX[i])) / 32768.0 - 1.0; buf[i] = ((float) ntohs (packet_bufX[i])) / 32768.0 - 1.0;
}
else if (jack_port_is_midi (porttype))
{
} else if (jack_port_is_midi (porttype)) {
// midi port, decode midi events // midi port, decode midi events
// convert the data buffer to a standard format (uint32_t based) // convert the data buffer to a standard format (uint32_t based)
unsigned int buffer_size_uint32 = net_period_down / 2; unsigned int buffer_size_uint32 = net_period_down / 2;
@@ -1141,8 +1076,7 @@ render_jack_ports_to_payload_16bit (JSList *playback_ports, JSList *playback_src


uint16_t *packet_bufX = (uint16_t *)packet_payload; uint16_t *packet_bufX = (uint16_t *)packet_payload;


while (node != NULL)
{
while (node != NULL) {
#if HAVE_SAMPLERATE #if HAVE_SAMPLERATE
SRC_DATA src; SRC_DATA src;
#endif #endif
@@ -1151,13 +1085,11 @@ render_jack_ports_to_payload_16bit (JSList *playback_ports, JSList *playback_src
jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes); jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes);
const char *porttype = jack_port_type (port); const char *porttype = jack_port_type (port);


if (jack_port_is_audio (porttype))
{
if (jack_port_is_audio (porttype)) {
// audio port, resample if necessary // audio port, resample if necessary


#if HAVE_SAMPLERATE #if HAVE_SAMPLERATE
if (net_period_up != nframes)
{
if (net_period_up != nframes) {
SRC_STATE *src_state = src_node->data; SRC_STATE *src_state = src_node->data;


float *floatbuf = alloca (sizeof(float) * net_period_up); float *floatbuf = alloca (sizeof(float) * net_period_up);
@@ -1174,19 +1106,15 @@ render_jack_ports_to_payload_16bit (JSList *playback_ports, JSList *playback_src
src_set_ratio (src_state, src.src_ratio); src_set_ratio (src_state, src.src_ratio);
src_process (src_state, &src); src_process (src_state, &src);


for (i = 0; i < net_period_up; i++)
{
for (i = 0; i < net_period_up; i++) {
packet_bufX[i] = htons (((uint16_t)((floatbuf[i] + 1.0) * 32767.0))); packet_bufX[i] = htons (((uint16_t)((floatbuf[i] + 1.0) * 32767.0)));
} }
src_node = jack_slist_next (src_node); src_node = jack_slist_next (src_node);
}
else
} else
#endif #endif
for (i = 0; i < net_period_up; i++) for (i = 0; i < net_period_up; i++)
packet_bufX[i] = htons(((uint16_t)((buf[i] + 1.0) * 32767.0))); packet_bufX[i] = htons(((uint16_t)((buf[i] + 1.0) * 32767.0)));
}
else if (jack_port_is_midi (porttype))
{
} else if (jack_port_is_midi (porttype)) {
// encode midi events from port to packet // encode midi events from port to packet
// convert the data buffer to a standard format (uint32_t based) // convert the data buffer to a standard format (uint32_t based)
unsigned int buffer_size_uint32 = net_period_up / 2; unsigned int buffer_size_uint32 = net_period_up / 2;
@@ -1215,8 +1143,7 @@ render_payload_to_jack_ports_8bit (void *packet_payload, jack_nframes_t net_peri
if (!packet_payload) if (!packet_payload)
return; return;


while (node != NULL)
{
while (node != NULL) {
int i; int i;
//uint32_t val; //uint32_t val;
#if HAVE_SAMPLERATE #if HAVE_SAMPLERATE
@@ -1231,12 +1158,10 @@ render_payload_to_jack_ports_8bit (void *packet_payload, jack_nframes_t net_peri
#endif #endif
const char *porttype = jack_port_type (port); const char *porttype = jack_port_type (port);


if (jack_port_is_audio(porttype))
{
if (jack_port_is_audio(porttype)) {
#if HAVE_SAMPLERATE #if HAVE_SAMPLERATE
// audio port, resample if necessary // audio port, resample if necessary
if (net_period_down != nframes)
{
if (net_period_down != nframes) {
SRC_STATE *src_state = src_node->data; SRC_STATE *src_state = src_node->data;
for (i = 0; i < net_period_down; i++) for (i = 0; i < net_period_down; i++)
floatbuf[i] = ((float) packet_bufX[i]) / 127.0; floatbuf[i] = ((float) packet_bufX[i]) / 127.0;
@@ -1253,14 +1178,11 @@ render_payload_to_jack_ports_8bit (void *packet_payload, jack_nframes_t net_peri
src_set_ratio (src_state, src.src_ratio); src_set_ratio (src_state, src.src_ratio);
src_process (src_state, &src); src_process (src_state, &src);
src_node = jack_slist_next (src_node); src_node = jack_slist_next (src_node);
}
else
} else
#endif #endif
for (i = 0; i < net_period_down; i++) for (i = 0; i < net_period_down; i++)
buf[i] = ((float) packet_bufX[i]) / 127.0; buf[i] = ((float) packet_bufX[i]) / 127.0;
}
else if (jack_port_is_midi (porttype))
{
} else if (jack_port_is_midi (porttype)) {
// midi port, decode midi events // midi port, decode midi events
// convert the data buffer to a standard format (uint32_t based) // convert the data buffer to a standard format (uint32_t based)
unsigned int buffer_size_uint32 = net_period_down / 2; unsigned int buffer_size_uint32 = net_period_down / 2;
@@ -1284,8 +1206,7 @@ render_jack_ports_to_payload_8bit (JSList *playback_ports, JSList *playback_srcs


int8_t *packet_bufX = (int8_t *)packet_payload; int8_t *packet_bufX = (int8_t *)packet_payload;


while (node != NULL)
{
while (node != NULL) {
#if HAVE_SAMPLERATE #if HAVE_SAMPLERATE
SRC_DATA src; SRC_DATA src;
#endif #endif
@@ -1295,12 +1216,10 @@ render_jack_ports_to_payload_8bit (JSList *playback_ports, JSList *playback_srcs
jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes); jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes);
const char *porttype = jack_port_type (port); const char *porttype = jack_port_type (port);


if (jack_port_is_audio (porttype))
{
if (jack_port_is_audio (porttype)) {
#if HAVE_SAMPLERATE #if HAVE_SAMPLERATE
// audio port, resample if necessary // audio port, resample if necessary
if (net_period_up != nframes)
{
if (net_period_up != nframes) {


SRC_STATE *src_state = src_node->data; SRC_STATE *src_state = src_node->data;


@@ -1321,14 +1240,11 @@ render_jack_ports_to_payload_8bit (JSList *playback_ports, JSList *playback_srcs
for (i = 0; i < net_period_up; i++) for (i = 0; i < net_period_up; i++)
packet_bufX[i] = floatbuf[i] * 127.0; packet_bufX[i] = floatbuf[i] * 127.0;
src_node = jack_slist_next (src_node); src_node = jack_slist_next (src_node);
}
else
} else
#endif #endif
for (i = 0; i < net_period_up; i++) for (i = 0; i < net_period_up; i++)
packet_bufX[i] = buf[i] * 127.0; packet_bufX[i] = buf[i] * 127.0;
}
else if (jack_port_is_midi (porttype))
{
} else if (jack_port_is_midi (porttype)) {
// encode midi events from port to packet // encode midi events from port to packet
// convert the data buffer to a standard format (uint32_t based) // convert the data buffer to a standard format (uint32_t based)
unsigned int buffer_size_uint32 = net_period_up / 4; unsigned int buffer_size_uint32 = net_period_up / 4;
@@ -1352,33 +1268,29 @@ render_payload_to_jack_ports_celt (void *packet_payload, jack_nframes_t net_peri


unsigned char *packet_bufX = (unsigned char *)packet_payload; unsigned char *packet_bufX = (unsigned char *)packet_payload;


while (node != NULL)
{
while (node != NULL) {
jack_port_t *port = (jack_port_t *) node->data; jack_port_t *port = (jack_port_t *) node->data;
jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes); jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes);


const char *porttype = jack_port_type (port); const char *porttype = jack_port_type (port);


if (jack_port_is_audio (porttype))
{
if (jack_port_is_audio (porttype)) {
// audio port, decode celt data. // audio port, decode celt data.
CELTDecoder *decoder = src_node->data; CELTDecoder *decoder = src_node->data;
#if HAVE_CELT_API_0_8 || HAVE_CELT_API_0_11
#if HAVE_CELT_API_0_8 || HAVE_CELT_API_0_11
if( !packet_payload ) if( !packet_payload )
celt_decode_float( decoder, NULL, net_period_down, buf, nframes ); celt_decode_float( decoder, NULL, net_period_down, buf, nframes );
else else
celt_decode_float( decoder, packet_bufX, net_period_down, buf, nframes ); celt_decode_float( decoder, packet_bufX, net_period_down, buf, nframes );
#else
#else
if( !packet_payload ) if( !packet_payload )
celt_decode_float( decoder, NULL, net_period_down, buf ); celt_decode_float( decoder, NULL, net_period_down, buf );
else else
celt_decode_float( decoder, packet_bufX, net_period_down, buf ); celt_decode_float( decoder, packet_bufX, net_period_down, buf );
#endif
#endif


src_node = jack_slist_next (src_node); src_node = jack_slist_next (src_node);
}
else if (jack_port_is_midi (porttype))
{
} else if (jack_port_is_midi (porttype)) {
// midi port, decode midi events // midi port, decode midi events
// convert the data buffer to a standard format (uint32_t based) // convert the data buffer to a standard format (uint32_t based)
unsigned int buffer_size_uint32 = net_period_down / 2; unsigned int buffer_size_uint32 = net_period_down / 2;
@@ -1401,31 +1313,27 @@ render_jack_ports_to_payload_celt (JSList *playback_ports, JSList *playback_srcs


unsigned char *packet_bufX = (unsigned char *)packet_payload; unsigned char *packet_bufX = (unsigned char *)packet_payload;


while (node != NULL)
{
while (node != NULL) {
jack_port_t *port = (jack_port_t *) node->data; jack_port_t *port = (jack_port_t *) node->data;
jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes); jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes);
const char *porttype = jack_port_type (port); const char *porttype = jack_port_type (port);


if (jack_port_is_audio (porttype))
{
if (jack_port_is_audio (porttype)) {
// audio port, encode celt data. // 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;
int encoded_bytes;
float *floatbuf = alloca (sizeof(float) * nframes );
memcpy( floatbuf, buf, nframes * sizeof(float) );
CELTEncoder *encoder = src_node->data;
#if HAVE_CELT_API_0_8 || HAVE_CELT_API_0_11 #if HAVE_CELT_API_0_8 || HAVE_CELT_API_0_11
encoded_bytes = celt_encode_float( encoder, floatbuf, nframes, packet_bufX, net_period_up );
encoded_bytes = celt_encode_float( encoder, floatbuf, nframes, packet_bufX, net_period_up );
#else #else
encoded_bytes = celt_encode_float( encoder, floatbuf, NULL, packet_bufX, net_period_up );
encoded_bytes = celt_encode_float( encoder, floatbuf, NULL, packet_bufX, net_period_up );
#endif #endif
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))
{
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 // encode midi events from port to packet
// convert the data buffer to a standard format (uint32_t based) // convert the data buffer to a standard format (uint32_t based)
unsigned int buffer_size_uint32 = net_period_up / 2; unsigned int buffer_size_uint32 = net_period_up / 2;


+ 100
- 109
common/netjack_packet.h View File

@@ -28,8 +28,8 @@
#define __JACK_NET_PACKET_H__ #define __JACK_NET_PACKET_H__


#ifdef __cplusplus #ifdef __cplusplus
extern "C"
{
extern "C"
{
#endif #endif


#include <jack/jack.h> #include <jack/jack.h>
@@ -42,115 +42,106 @@
#define CELT_MODE 1000 // Magic bitdepth value that indicates CELT compression #define CELT_MODE 1000 // Magic bitdepth value that indicates CELT compression
#define MASTER_FREEWHEELS 0x80000000 #define MASTER_FREEWHEELS 0x80000000


typedef struct _jacknet_packet_header jacknet_packet_header;

struct _jacknet_packet_header
{
// General AutoConf Data
jack_nframes_t capture_channels_audio;
jack_nframes_t playback_channels_audio;
jack_nframes_t capture_channels_midi;
jack_nframes_t playback_channels_midi;
jack_nframes_t period_size;
jack_nframes_t sample_rate;

// Transport Sync
jack_nframes_t sync_state;
jack_nframes_t transport_frame;
jack_nframes_t transport_state;

// Packet loss Detection, and latency reduction
jack_nframes_t framecnt;
jack_nframes_t latency;

jack_nframes_t reply_port;
jack_nframes_t mtu;
jack_nframes_t fragment_nr;
};

typedef union _int_float int_float_t;

union _int_float
{
uint32_t i;
float f;
};

// fragment reorder cache.
typedef struct _cache_packet cache_packet;

struct _cache_packet
{
int valid;
int num_fragments;
int packet_size;
int mtu;
jack_time_t recv_timestamp;
jack_nframes_t framecnt;
char * fragment_array;
char * packet_buf;
};

typedef struct _packet_cache packet_cache;

struct _packet_cache
{
int size;
cache_packet *packets;
int mtu;
struct sockaddr_in master_address;
int master_address_valid;
jack_nframes_t last_framecnt_retreived;
int last_framecnt_retreived_valid;
};

// fragment cache function prototypes
// XXX: Some of these are private.
packet_cache *packet_cache_new(int num_packets, int pkt_size, int mtu);
void packet_cache_free(packet_cache *pkt_cache);

cache_packet *packet_cache_get_packet(packet_cache *pkt_cache, jack_nframes_t framecnt);
cache_packet *packet_cache_get_oldest_packet(packet_cache *pkt_cache);
cache_packet *packet_cache_get_free_packet(packet_cache *pkt_cache);

void cache_packet_reset(cache_packet *pack);
void cache_packet_set_framecnt(cache_packet *pack, jack_nframes_t framecnt);
void cache_packet_add_fragment(cache_packet *pack, char *packet_buf, int rcv_len);
int cache_packet_is_complete(cache_packet *pack);

void packet_cache_drain_socket( packet_cache *pcache, int sockfd );
void packet_cache_reset_master_address( packet_cache *pcache );
float packet_cache_get_fill( packet_cache *pcache, jack_nframes_t expected_framecnt );
int packet_cache_retreive_packet_pointer( packet_cache *pcache, jack_nframes_t framecnt, char **packet_buf, int pkt_size, jack_time_t *timestamp );
int packet_cache_release_packet( packet_cache *pcache, jack_nframes_t framecnt );
int packet_cache_get_next_available_framecnt( packet_cache *pcache, jack_nframes_t expected_framecnt, jack_nframes_t *framecnt );
int packet_cache_get_highest_available_framecnt( packet_cache *pcache, jack_nframes_t *framecnt );
int packet_cache_find_latency( packet_cache *pcache, jack_nframes_t expected_framecnt, jack_nframes_t *framecnt );
// Function Prototypes

int netjack_poll_deadline (int sockfd, jack_time_t deadline);

void netjack_sendto(int sockfd, char *packet_buf, int pkt_size, int flags, struct sockaddr *addr, int addr_size, int mtu);


int get_sample_size(int bitdepth);
void packet_header_hton(jacknet_packet_header *pkthdr);

void packet_header_ntoh(jacknet_packet_header *pkthdr);

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 );

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 );


// XXX: This is sort of deprecated:
// This one waits forever. an is not using ppoll
int netjack_poll(int sockfd, int timeout);
typedef struct _jacknet_packet_header jacknet_packet_header;

struct _jacknet_packet_header {
// General AutoConf Data
jack_nframes_t capture_channels_audio;
jack_nframes_t playback_channels_audio;
jack_nframes_t capture_channels_midi;
jack_nframes_t playback_channels_midi;
jack_nframes_t period_size;
jack_nframes_t sample_rate;

// Transport Sync
jack_nframes_t sync_state;
jack_nframes_t transport_frame;
jack_nframes_t transport_state;

// Packet loss Detection, and latency reduction
jack_nframes_t framecnt;
jack_nframes_t latency;

jack_nframes_t reply_port;
jack_nframes_t mtu;
jack_nframes_t fragment_nr;
};

typedef union _int_float int_float_t;

union _int_float {
uint32_t i;
float f;
};

// fragment reorder cache.
typedef struct _cache_packet cache_packet;

struct _cache_packet {
int valid;
int num_fragments;
int packet_size;
int mtu;
jack_time_t recv_timestamp;
jack_nframes_t framecnt;
char * fragment_array;
char * packet_buf;
};

typedef struct _packet_cache packet_cache;

struct _packet_cache {
int size;
cache_packet *packets;
int mtu;
struct sockaddr_in master_address;
int master_address_valid;
jack_nframes_t last_framecnt_retreived;
int last_framecnt_retreived_valid;
};

// fragment cache function prototypes
// XXX: Some of these are private.
packet_cache *packet_cache_new(int num_packets, int pkt_size, int mtu);
void packet_cache_free(packet_cache *pkt_cache);

cache_packet *packet_cache_get_packet(packet_cache *pkt_cache, jack_nframes_t framecnt);
cache_packet *packet_cache_get_oldest_packet(packet_cache *pkt_cache);
cache_packet *packet_cache_get_free_packet(packet_cache *pkt_cache);

void cache_packet_reset(cache_packet *pack);
void cache_packet_set_framecnt(cache_packet *pack, jack_nframes_t framecnt);
void cache_packet_add_fragment(cache_packet *pack, char *packet_buf, int rcv_len);
int cache_packet_is_complete(cache_packet *pack);

void packet_cache_drain_socket( packet_cache *pcache, int sockfd );
void packet_cache_reset_master_address( packet_cache *pcache );
float packet_cache_get_fill( packet_cache *pcache, jack_nframes_t expected_framecnt );
int packet_cache_retreive_packet_pointer( packet_cache *pcache, jack_nframes_t framecnt, char **packet_buf, int pkt_size, jack_time_t *timestamp );
int packet_cache_release_packet( packet_cache *pcache, jack_nframes_t framecnt );
int packet_cache_get_next_available_framecnt( packet_cache *pcache, jack_nframes_t expected_framecnt, jack_nframes_t *framecnt );
int packet_cache_get_highest_available_framecnt( packet_cache *pcache, jack_nframes_t *framecnt );
int packet_cache_find_latency( packet_cache *pcache, jack_nframes_t expected_framecnt, jack_nframes_t *framecnt );

// Function Prototypes

int netjack_poll_deadline (int sockfd, jack_time_t deadline);
void netjack_sendto(int sockfd, char *packet_buf, int pkt_size, int flags, struct sockaddr *addr, int addr_size, int mtu);
int get_sample_size(int bitdepth);
void packet_header_hton(jacknet_packet_header *pkthdr);
void packet_header_ntoh(jacknet_packet_header *pkthdr);
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 );
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 );

// XXX: This is sort of deprecated:
// This one waits forever. an is not using ppoll
int netjack_poll(int sockfd, int timeout);

void decode_midi_buffer (uint32_t *buffer_uint32, unsigned int buffer_size_uint32, jack_default_audio_sample_t* buf);
void encode_midi_buffer (uint32_t *buffer_uint32, unsigned int buffer_size_uint32, jack_default_audio_sample_t* buf);


void decode_midi_buffer (uint32_t *buffer_uint32, unsigned int buffer_size_uint32, jack_default_audio_sample_t* buf);
void encode_midi_buffer (uint32_t *buffer_uint32, unsigned int buffer_size_uint32, jack_default_audio_sample_t* buf);
#ifdef __cplusplus #ifdef __cplusplus
}
}
#endif #endif
#endif #endif



+ 180
- 214
example-clients/netsource.c View File

@@ -92,7 +92,7 @@ int state_netxruns = 0;
int state_currentframe = 0; int state_currentframe = 0;
int state_recv_packet_queue_time = 0; int state_recv_packet_queue_time = 0;


int quit=0;
int quit = 0;




int outsockfd; int outsockfd;
@@ -128,43 +128,39 @@ alloc_ports (int n_capture_audio, int n_playback_audio, int n_capture_midi, int


capture_ports = NULL; capture_ports = NULL;
/* Allocate audio capture channels */ /* Allocate audio capture channels */
for (chn = 0; chn < n_capture_audio; chn++)
{
for (chn = 0; chn < n_capture_audio; chn++) {
snprintf (buf, sizeof (buf) - 1, "capture_%u", chn + 1); snprintf (buf, sizeof (buf) - 1, "capture_%u", chn + 1);
port = jack_port_register (client, buf, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0); port = jack_port_register (client, buf, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0);
if (!port)
{
if (!port) {
printf( "jack_netsource: cannot register %s port\n", buf); printf( "jack_netsource: cannot register %s port\n", buf);
break; break;
} }
if (bitdepth == 1000) {
#if HAVE_CELT
#if HAVE_CELT_API_0_11
if (bitdepth == 1000) {
#if HAVE_CELT
#if HAVE_CELT_API_0_11
CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate( client ), jack_get_buffer_size(client), NULL ); CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate( client ), jack_get_buffer_size(client), NULL );
capture_srcs = jack_slist_append(capture_srcs, celt_decoder_create_custom( celt_mode, 1, NULL ) ); capture_srcs = jack_slist_append(capture_srcs, celt_decoder_create_custom( celt_mode, 1, NULL ) );
#elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8
#elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8
CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate( client ), jack_get_buffer_size(client), NULL ); CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate( client ), jack_get_buffer_size(client), NULL );
capture_srcs = jack_slist_append(capture_srcs, celt_decoder_create( celt_mode, 1, NULL ) ); capture_srcs = jack_slist_append(capture_srcs, celt_decoder_create( celt_mode, 1, NULL ) );
#else
#else
CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate( client ), 1, jack_get_buffer_size(client), NULL ); CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate( client ), 1, jack_get_buffer_size(client), NULL );
capture_srcs = jack_slist_append(capture_srcs, celt_decoder_create( celt_mode ) ); capture_srcs = jack_slist_append(capture_srcs, celt_decoder_create( celt_mode ) );
#endif
#endif
#endif
#endif
} else { } else {
#if HAVE_SAMPLERATE
capture_srcs = jack_slist_append (capture_srcs, src_new (SRC_LINEAR, 1, NULL));
#endif
#if HAVE_SAMPLERATE
capture_srcs = jack_slist_append (capture_srcs, src_new (SRC_LINEAR, 1, NULL));
#endif
} }
capture_ports = jack_slist_append (capture_ports, port); capture_ports = jack_slist_append (capture_ports, port);
} }


/* Allocate midi capture channels */ /* Allocate midi capture channels */
for (chn = n_capture_audio; chn < n_capture_midi + n_capture_audio; chn++)
{
for (chn = n_capture_audio; chn < n_capture_midi + n_capture_audio; chn++) {
snprintf (buf, sizeof (buf) - 1, "capture_%u", chn + 1); snprintf (buf, sizeof (buf) - 1, "capture_%u", chn + 1);
port = jack_port_register (client, buf, JACK_DEFAULT_MIDI_TYPE, port_flags, 0); port = jack_port_register (client, buf, JACK_DEFAULT_MIDI_TYPE, port_flags, 0);
if (!port)
{
if (!port) {
printf ("jack_netsource: cannot register %s port\n", buf); printf ("jack_netsource: cannot register %s port\n", buf);
break; break;
} }
@@ -174,43 +170,39 @@ alloc_ports (int n_capture_audio, int n_playback_audio, int n_capture_midi, int
/* Allocate audio playback channels */ /* Allocate audio playback channels */
port_flags = JackPortIsInput; port_flags = JackPortIsInput;
playback_ports = NULL; playback_ports = NULL;
for (chn = 0; chn < n_playback_audio; chn++)
{
for (chn = 0; chn < n_playback_audio; chn++) {
snprintf (buf, sizeof (buf) - 1, "playback_%u", chn + 1); snprintf (buf, sizeof (buf) - 1, "playback_%u", chn + 1);
port = jack_port_register (client, buf, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0); port = jack_port_register (client, buf, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0);
if (!port)
{
if (!port) {
printf ("jack_netsource: cannot register %s port\n", buf); printf ("jack_netsource: cannot register %s port\n", buf);
break; break;
} }
if( bitdepth == 1000 ) { if( bitdepth == 1000 ) {
#if HAVE_CELT
#if HAVE_CELT_API_0_11
#if HAVE_CELT
#if HAVE_CELT_API_0_11
CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate (client), jack_get_buffer_size(client), NULL ); CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate (client), jack_get_buffer_size(client), NULL );
playback_srcs = jack_slist_append(playback_srcs, celt_encoder_create_custom( celt_mode, 1, NULL ) ); playback_srcs = jack_slist_append(playback_srcs, celt_encoder_create_custom( celt_mode, 1, NULL ) );
#elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8
#elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8
CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate (client), jack_get_buffer_size(client), NULL ); CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate (client), jack_get_buffer_size(client), NULL );
playback_srcs = jack_slist_append(playback_srcs, celt_encoder_create( celt_mode, 1, NULL ) ); playback_srcs = jack_slist_append(playback_srcs, celt_encoder_create( celt_mode, 1, NULL ) );
#else
#else
CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate (client), 1, jack_get_buffer_size(client), NULL ); CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate (client), 1, jack_get_buffer_size(client), NULL );
playback_srcs = jack_slist_append(playback_srcs, celt_encoder_create( celt_mode ) ); playback_srcs = jack_slist_append(playback_srcs, celt_encoder_create( celt_mode ) );
#endif
#endif
#endif
#endif
} else { } else {
#if HAVE_SAMPLERATE
#if HAVE_SAMPLERATE
playback_srcs = jack_slist_append (playback_srcs, src_new (SRC_LINEAR, 1, NULL)); playback_srcs = jack_slist_append (playback_srcs, src_new (SRC_LINEAR, 1, NULL));
#endif
#endif
} }
playback_ports = jack_slist_append (playback_ports, port); playback_ports = jack_slist_append (playback_ports, port);
} }


/* Allocate midi playback channels */ /* Allocate midi playback channels */
for (chn = n_playback_audio; chn < n_playback_midi + n_playback_audio; chn++)
{
for (chn = n_playback_audio; chn < n_playback_midi + n_playback_audio; chn++) {
snprintf (buf, sizeof (buf) - 1, "playback_%u", chn + 1); snprintf (buf, sizeof (buf) - 1, "playback_%u", chn + 1);
port = jack_port_register (client, buf, JACK_DEFAULT_MIDI_TYPE, port_flags, 0); port = jack_port_register (client, buf, JACK_DEFAULT_MIDI_TYPE, port_flags, 0);
if (!port)
{
if (!port) {
printf ("jack_netsource: cannot register %s port\n", buf); printf ("jack_netsource: cannot register %s port\n", buf);
break; break;
} }
@@ -237,8 +229,7 @@ sync_cb (jack_transport_state_t state, jack_position_t *pos, void *arg)
retval = 0; retval = 0;
} }


else if (state == JackTransportStarting && last_transport_state != JackTransportStarting)
{
else if (state == JackTransportStarting && last_transport_state != JackTransportStarting) {
retval = 0; retval = 0;
latency_count = latency - 1; latency_count = latency - 1;
} }
@@ -250,10 +241,10 @@ sync_cb (jack_transport_state_t state, jack_position_t *pos, void *arg)
void void
freewheel_cb (int starting, void *arg) freewheel_cb (int starting, void *arg)
{ {
freewheeling = starting;
freewheeling = starting;
} }


int deadline_goodness=0;
int deadline_goodness = 0;
/** /**
* The process callback for this JACK application. * The process callback for this JACK application.
* It is called by JACK at the appropriate times. * It is called by JACK at the appropriate times.
@@ -279,7 +270,7 @@ process (jack_nframes_t nframes, void *arg)
jack_time_t packet_recv_timestamp; jack_time_t packet_recv_timestamp;


if( bitdepth == 1000 ) if( bitdepth == 1000 )
net_period = (factor * jack_get_buffer_size(client) * 1024 / jack_get_sample_rate(client) / 8)&(~1) ;
net_period = (factor * jack_get_buffer_size(client) * 1024 / jack_get_sample_rate(client) / 8) & (~1) ;
else else
net_period = (float) nframes / (float) factor; net_period = (float) nframes / (float) factor;


@@ -299,47 +290,45 @@ process (jack_nframes_t nframes, void *arg)
*/ */


if( latency == 0 ) { if( latency == 0 ) {
/* reset packet_bufX... */
packet_bufX = packet_buf_tx + sizeof (jacknet_packet_header) / sizeof (jack_default_audio_sample_t);

/* ---------- Send ---------- */
render_jack_ports_to_payload (bitdepth, playback_ports, playback_srcs, nframes,
packet_bufX, net_period, dont_htonl_floats);

/* fill in packet hdr */
pkthdr_tx->transport_state = jack_transport_query (client, &local_trans_pos);
pkthdr_tx->transport_frame = local_trans_pos.frame;
pkthdr_tx->framecnt = framecnt;
pkthdr_tx->latency = latency;
pkthdr_tx->reply_port = reply_port;
pkthdr_tx->sample_rate = jack_get_sample_rate (client);
pkthdr_tx->period_size = nframes;

/* playback for us is capture on the other side */
pkthdr_tx->capture_channels_audio = playback_channels_audio;
pkthdr_tx->playback_channels_audio = capture_channels_audio;
pkthdr_tx->capture_channels_midi = playback_channels_midi;
pkthdr_tx->playback_channels_midi = capture_channels_midi;
pkthdr_tx->mtu = mtu;
if( freewheeling!= 0 )
pkthdr_tx->sync_state = (jack_nframes_t)MASTER_FREEWHEELS;
else
pkthdr_tx->sync_state = (jack_nframes_t)deadline_goodness;
//printf("goodness=%d\n", deadline_goodness );

packet_header_hton (pkthdr_tx);
if (cont_miss < 3*latency+5) {
int r;
for( r=0; r<redundancy; r++ )
netjack_sendto (outsockfd, (char *) packet_buf_tx, tx_bufsize, 0, &destaddr, sizeof (destaddr), mtu);
}
else if (cont_miss > 50+5*latency)
{
state_connected = 0;
packet_cache_reset_master_address( packcache );
//printf ("Frame %d \tRealy too many packets missed (%d). Let's reset the counter\n", framecnt, cont_miss);
cont_miss = 0;
}
/* reset packet_bufX... */
packet_bufX = packet_buf_tx + sizeof (jacknet_packet_header) / sizeof (jack_default_audio_sample_t);

/* ---------- Send ---------- */
render_jack_ports_to_payload (bitdepth, playback_ports, playback_srcs, nframes,
packet_bufX, net_period, dont_htonl_floats);

/* fill in packet hdr */
pkthdr_tx->transport_state = jack_transport_query (client, &local_trans_pos);
pkthdr_tx->transport_frame = local_trans_pos.frame;
pkthdr_tx->framecnt = framecnt;
pkthdr_tx->latency = latency;
pkthdr_tx->reply_port = reply_port;
pkthdr_tx->sample_rate = jack_get_sample_rate (client);
pkthdr_tx->period_size = nframes;

/* playback for us is capture on the other side */
pkthdr_tx->capture_channels_audio = playback_channels_audio;
pkthdr_tx->playback_channels_audio = capture_channels_audio;
pkthdr_tx->capture_channels_midi = playback_channels_midi;
pkthdr_tx->playback_channels_midi = capture_channels_midi;
pkthdr_tx->mtu = mtu;
if( freewheeling != 0 )
pkthdr_tx->sync_state = (jack_nframes_t)MASTER_FREEWHEELS;
else
pkthdr_tx->sync_state = (jack_nframes_t)deadline_goodness;
//printf("goodness=%d\n", deadline_goodness );

packet_header_hton (pkthdr_tx);
if (cont_miss < 3 * latency + 5) {
int r;
for( r = 0; r < redundancy; r++ )
netjack_sendto (outsockfd, (char *) packet_buf_tx, tx_bufsize, 0, &destaddr, sizeof (destaddr), mtu);
} else if (cont_miss > 50 + 5 * latency) {
state_connected = 0;
packet_cache_reset_master_address( packcache );
//printf ("Frame %d \tRealy too many packets missed (%d). Let's reset the counter\n", framecnt, cont_miss);
cont_miss = 0;
}
} }


/* /*
@@ -354,19 +343,19 @@ process (jack_nframes_t nframes, void *arg)
input_fd = outsockfd; input_fd = outsockfd;


// for latency == 0 we can poll. // for latency == 0 we can poll.
if( (latency == 0) || (freewheeling!=0) ) {
jack_time_t deadline = jack_get_time() + 1000000 * jack_get_buffer_size(client)/jack_get_sample_rate(client);
if( (latency == 0) || (freewheeling != 0) ) {
jack_time_t deadline = jack_get_time() + 1000000 * jack_get_buffer_size(client) / jack_get_sample_rate(client);
// Now loop until we get the right packet. // Now loop until we get the right packet.
while(1) { while(1) {
jack_nframes_t got_frame; jack_nframes_t got_frame;
if ( ! netjack_poll_deadline( input_fd, deadline ) ) if ( ! netjack_poll_deadline( input_fd, deadline ) )
break;
break;


packet_cache_drain_socket(packcache, input_fd); packet_cache_drain_socket(packcache, input_fd);


if (packet_cache_get_next_available_framecnt( packcache, framecnt - latency, &got_frame )) if (packet_cache_get_next_available_framecnt( packcache, framecnt - latency, &got_frame ))
if( got_frame == (framecnt - latency) )
break;
if( got_frame == (framecnt - latency) )
break;
} }
} else { } else {
// normally: // normally:
@@ -377,8 +366,7 @@ process (jack_nframes_t nframes, void *arg)
size = packet_cache_retreive_packet_pointer( packcache, framecnt - latency, (char**)&rx_packet_ptr, rx_bufsize, &packet_recv_timestamp ); size = packet_cache_retreive_packet_pointer( packcache, framecnt - latency, (char**)&rx_packet_ptr, rx_bufsize, &packet_recv_timestamp );
/* First alternative : we received what we expected. Render the data /* First alternative : we received what we expected. Render the data
* to the JACK ports so it can be played. */ * to the JACK ports so it can be played. */
if (size == rx_bufsize)
{
if (size == rx_bufsize) {
uint32_t *packet_buf_rx = rx_packet_ptr; uint32_t *packet_buf_rx = rx_packet_ptr;
jacknet_packet_header *pkthdr_rx = (jacknet_packet_header *) packet_buf_rx; jacknet_packet_header *pkthdr_rx = (jacknet_packet_header *) packet_buf_rx;
packet_bufX = packet_buf_rx + sizeof (jacknet_packet_header) / sizeof (jack_default_audio_sample_t); packet_bufX = packet_buf_rx + sizeof (jacknet_packet_header) / sizeof (jack_default_audio_sample_t);
@@ -389,13 +377,12 @@ process (jack_nframes_t nframes, void *arg)
deadline_goodness = recv_time_offset - (int)pkthdr_rx->latency; deadline_goodness = recv_time_offset - (int)pkthdr_rx->latency;
//printf( "deadline goodness = %d ---> off: %d\n", deadline_goodness, recv_time_offset ); //printf( "deadline goodness = %d ---> off: %d\n", deadline_goodness, recv_time_offset );


if (cont_miss)
{
if (cont_miss) {
//printf("Frame %d \tRecovered from dropouts\n", framecnt); //printf("Frame %d \tRecovered from dropouts\n", framecnt);
cont_miss = 0; cont_miss = 0;
} }
render_payload_to_jack_ports (bitdepth, packet_bufX, net_period, render_payload_to_jack_ports (bitdepth, packet_bufX, net_period,
capture_ports, capture_srcs, nframes, dont_htonl_floats);
capture_ports, capture_srcs, nframes, dont_htonl_floats);


state_currentframe = framecnt; state_currentframe = framecnt;
state_recv_packet_queue_time = recv_time_offset; state_recv_packet_queue_time = recv_time_offset;
@@ -406,8 +393,7 @@ process (jack_nframes_t nframes, void *arg)
/* Second alternative : we've received something that's not /* Second alternative : we've received something that's not
* as big as expected or we missed a packet. We render silence * as big as expected or we missed a packet. We render silence
* to the ouput ports */ * to the ouput ports */
else
{
else {
jack_nframes_t latency_estimate; jack_nframes_t latency_estimate;
if( packet_cache_find_latency( packcache, framecnt, &latency_estimate ) ) if( packet_cache_find_latency( packcache, framecnt, &latency_estimate ) )
//if( (state_latency == 0) || (latency_estimate < state_latency) ) //if( (state_latency == 0) || (latency_estimate < state_latency) )
@@ -423,8 +409,7 @@ process (jack_nframes_t nframes, void *arg)
cont_miss += 1; cont_miss += 1;
chn = 0; chn = 0;
node = capture_ports; node = capture_ports;
while (node != NULL)
{
while (node != NULL) {
port = (jack_port_t *) node->data; port = (jack_port_t *) node->data;
buf = jack_port_get_buffer (port, nframes); buf = jack_port_get_buffer (port, nframes);
porttype = jack_port_type (port); porttype = jack_port_type (port);
@@ -438,47 +423,45 @@ process (jack_nframes_t nframes, void *arg)
} }
} }
if (latency != 0) { if (latency != 0) {
/* reset packet_bufX... */
packet_bufX = packet_buf_tx + sizeof (jacknet_packet_header) / sizeof (jack_default_audio_sample_t);

/* ---------- Send ---------- */
render_jack_ports_to_payload (bitdepth, playback_ports, playback_srcs, nframes,
packet_bufX, net_period, dont_htonl_floats);

/* fill in packet hdr */
pkthdr_tx->transport_state = jack_transport_query (client, &local_trans_pos);
pkthdr_tx->transport_frame = local_trans_pos.frame;
pkthdr_tx->framecnt = framecnt;
pkthdr_tx->latency = latency;
pkthdr_tx->reply_port = reply_port;
pkthdr_tx->sample_rate = jack_get_sample_rate (client);
pkthdr_tx->period_size = nframes;

/* playback for us is capture on the other side */
pkthdr_tx->capture_channels_audio = playback_channels_audio;
pkthdr_tx->playback_channels_audio = capture_channels_audio;
pkthdr_tx->capture_channels_midi = playback_channels_midi;
pkthdr_tx->playback_channels_midi = capture_channels_midi;
pkthdr_tx->mtu = mtu;
if( freewheeling!= 0 )
pkthdr_tx->sync_state = (jack_nframes_t)MASTER_FREEWHEELS;
else
pkthdr_tx->sync_state = (jack_nframes_t)deadline_goodness;
//printf("goodness=%d\n", deadline_goodness );

packet_header_hton (pkthdr_tx);
if (cont_miss < 3*latency+5) {
int r;
for( r=0; r<redundancy; r++ )
netjack_sendto (outsockfd, (char *) packet_buf_tx, tx_bufsize, 0, &destaddr, sizeof (destaddr), mtu);
}
else if (cont_miss > 50+5*latency)
{
state_connected = 0;
packet_cache_reset_master_address( packcache );
//printf ("Frame %d \tRealy too many packets missed (%d). Let's reset the counter\n", framecnt, cont_miss);
cont_miss = 0;
}
/* reset packet_bufX... */
packet_bufX = packet_buf_tx + sizeof (jacknet_packet_header) / sizeof (jack_default_audio_sample_t);

/* ---------- Send ---------- */
render_jack_ports_to_payload (bitdepth, playback_ports, playback_srcs, nframes,
packet_bufX, net_period, dont_htonl_floats);

/* fill in packet hdr */
pkthdr_tx->transport_state = jack_transport_query (client, &local_trans_pos);
pkthdr_tx->transport_frame = local_trans_pos.frame;
pkthdr_tx->framecnt = framecnt;
pkthdr_tx->latency = latency;
pkthdr_tx->reply_port = reply_port;
pkthdr_tx->sample_rate = jack_get_sample_rate (client);
pkthdr_tx->period_size = nframes;

/* playback for us is capture on the other side */
pkthdr_tx->capture_channels_audio = playback_channels_audio;
pkthdr_tx->playback_channels_audio = capture_channels_audio;
pkthdr_tx->capture_channels_midi = playback_channels_midi;
pkthdr_tx->playback_channels_midi = capture_channels_midi;
pkthdr_tx->mtu = mtu;
if( freewheeling != 0 )
pkthdr_tx->sync_state = (jack_nframes_t)MASTER_FREEWHEELS;
else
pkthdr_tx->sync_state = (jack_nframes_t)deadline_goodness;
//printf("goodness=%d\n", deadline_goodness );

packet_header_hton (pkthdr_tx);
if (cont_miss < 3 * latency + 5) {
int r;
for( r = 0; r < redundancy; r++ )
netjack_sendto (outsockfd, (char *) packet_buf_tx, tx_bufsize, 0, &destaddr, sizeof (destaddr), mtu);
} else if (cont_miss > 50 + 5 * latency) {
state_connected = 0;
packet_cache_reset_master_address( packcache );
//printf ("Frame %d \tRealy too many packets missed (%d). Let's reset the counter\n", framecnt, cont_miss);
cont_miss = 0;
}
} }


framecnt++; framecnt++;
@@ -502,20 +485,18 @@ init_sockaddr_in (struct sockaddr_in *name , const char *hostname , uint16_t por
{ {
name->sin_family = AF_INET ; name->sin_family = AF_INET ;
name->sin_port = htons (port); name->sin_port = htons (port);
if (hostname)
{
if (hostname) {
struct hostent *hostinfo = gethostbyname (hostname); struct hostent *hostinfo = gethostbyname (hostname);
if (hostinfo == NULL) { if (hostinfo == NULL) {
fprintf (stderr, "init_sockaddr_in: unknown host: %s.\n", hostname); fprintf (stderr, "init_sockaddr_in: unknown host: %s.\n", hostname);
fflush( stderr );
}
fflush( stderr );
}
#ifdef WIN32 #ifdef WIN32
name->sin_addr.s_addr = inet_addr( hostname ); name->sin_addr.s_addr = inet_addr( hostname );
#else #else
name->sin_addr = *(struct in_addr *) hostinfo->h_addr ; name->sin_addr = *(struct in_addr *) hostinfo->h_addr ;
#endif #endif
}
else
} else
name->sin_addr.s_addr = htonl (INADDR_ANY) ; name->sin_addr.s_addr = htonl (INADDR_ANY) ;


} }
@@ -523,32 +504,32 @@ init_sockaddr_in (struct sockaddr_in *name , const char *hostname , uint16_t por
void void
printUsage () printUsage ()
{ {
fprintf (stderr, "usage: jack_netsource [options]\n"
"\n"
" -h this help text\n"
" -H <slave host> - Host name of the slave JACK\n"
" -o <num channels> - Number of audio playback channels\n"
" -i <num channels> - Number of audio capture channels\n"
" -O <num channels> - Number of midi playback channels\n"
" -I <num channels> - Number of midi capture channels\n"
" -n <periods> - Network latency in JACK periods\n"
" -p <port> - UDP port that the slave is listening on\n"
" -r <reply port> - UDP port that we are listening on\n"
" -B <bind port> - reply port, for use in NAT environments\n"
" -b <bitdepth> - Set transport to use 16bit or 8bit\n"
" -c <kbits> - Use CELT encoding with <kbits> kbits per channel\n"
" -m <mtu> - Assume this mtu for the link\n"
" -R <N> - Redundancy: send out packets N times.\n"
" -e - skip host-to-network endianness conversion\n"
" -N <jack name> - Reports a different name to jack\n"
" -s <server name> - The name of the local jack server\n"
"\n");
fprintf (stderr, "usage: jack_netsource [options]\n"
"\n"
" -h this help text\n"
" -H <slave host> - Host name of the slave JACK\n"
" -o <num channels> - Number of audio playback channels\n"
" -i <num channels> - Number of audio capture channels\n"
" -O <num channels> - Number of midi playback channels\n"
" -I <num channels> - Number of midi capture channels\n"
" -n <periods> - Network latency in JACK periods\n"
" -p <port> - UDP port that the slave is listening on\n"
" -r <reply port> - UDP port that we are listening on\n"
" -B <bind port> - reply port, for use in NAT environments\n"
" -b <bitdepth> - Set transport to use 16bit or 8bit\n"
" -c <kbits> - Use CELT encoding with <kbits> kbits per channel\n"
" -m <mtu> - Assume this mtu for the link\n"
" -R <N> - Redundancy: send out packets N times.\n"
" -e - skip host-to-network endianness conversion\n"
" -N <jack name> - Reports a different name to jack\n"
" -s <server name> - The name of the local jack server\n"
"\n");
} }


void void
sigterm_handler( int signal ) sigterm_handler( int signal )
{ {
quit = 1;
quit = 1;
} }


int int
@@ -561,7 +542,7 @@ main (int argc, char *argv[])
jack_status_t status; jack_status_t status;
#ifdef WIN32 #ifdef WIN32
WSADATA wsa; WSADATA wsa;
int rc = WSAStartup(MAKEWORD(2,0),&wsa);
int rc = WSAStartup(MAKEWORD(2, 0), &wsa);
#endif #endif
/* Torben's famous state variables, aka "the reporting API" ! */ /* Torben's famous state variables, aka "the reporting API" ! */
/* heh ? these are only the copies of them ;) */ /* heh ? these are only the copies of them ;) */
@@ -570,10 +551,9 @@ main (int argc, char *argv[])
/* Argument parsing stuff */ /* Argument parsing stuff */
extern char *optarg; extern char *optarg;
extern int optind, optopt; extern int optind, optopt;
int errflg=0, c;
int errflg = 0, c;


if (argc < 3)
{
if (argc < 3) {
printUsage (); printUsage ();
return 1; return 1;
} }
@@ -583,17 +563,15 @@ main (int argc, char *argv[])
sprintf(client_name, "netjack"); sprintf(client_name, "netjack");
sprintf(peer_ip, "localhost"); sprintf(peer_ip, "localhost");


while ((c = getopt (argc, argv, ":h:H:o:i:O:I:n:p:r:B:b:c:m:R:e:N:s:")) != -1)
{
switch (c)
{
while ((c = getopt (argc, argv, ":h:H:o:i:O:I:n:p:r:B:b:c:m:R:e:N:s:")) != -1) {
switch (c) {
case 'h': case 'h':
printUsage(); printUsage();
exit (0); exit (0);
break; break;
case 'H': case 'H':
free(peer_ip); free(peer_ip);
peer_ip = (char *) malloc (sizeof (char) * strlen (optarg)+1);
peer_ip = (char *) malloc (sizeof (char) * strlen (optarg) + 1);
strcpy (peer_ip, optarg); strcpy (peer_ip, optarg);
break; break;
case 'o': case 'o':
@@ -647,11 +625,11 @@ main (int argc, char *argv[])
break; break;
case 'N': case 'N':
free(client_name); free(client_name);
client_name = (char *) malloc (sizeof (char) * strlen (optarg)+1);
client_name = (char *) malloc (sizeof (char) * strlen (optarg) + 1);
strcpy (client_name, optarg); strcpy (client_name, optarg);
break; break;
case 's': case 's':
server_name = (char *) malloc (sizeof (char) * strlen (optarg)+1);
server_name = (char *) malloc (sizeof (char) * strlen (optarg) + 1);
strcpy (server_name, optarg); strcpy (server_name, optarg);
options |= JackServerName; options |= JackServerName;
break; break;
@@ -664,8 +642,7 @@ main (int argc, char *argv[])
errflg++; errflg++;
} }
} }
if (errflg)
{
if (errflg) {
printUsage (); printUsage ();
exit (2); exit (2);
} }
@@ -688,8 +665,7 @@ main (int argc, char *argv[])
fprintf (stderr, "bind failure\n" ); fprintf (stderr, "bind failure\n" );
} }
} }
if (reply_port)
{
if (reply_port) {
init_sockaddr_in ((struct sockaddr_in *) &bindaddr, NULL, reply_port); init_sockaddr_in ((struct sockaddr_in *) &bindaddr, NULL, reply_port);
if( bind (insockfd, &bindaddr, sizeof (bindaddr)) ) { if( bind (insockfd, &bindaddr, sizeof (bindaddr)) ) {
fprintf (stderr, "bind failure\n" ); fprintf (stderr, "bind failure\n" );
@@ -698,10 +674,9 @@ main (int argc, char *argv[])


/* try to become a client of the JACK server */ /* try to become a client of the JACK server */
client = jack_client_open (client_name, options, &status, server_name); client = jack_client_open (client_name, options, &status, server_name);
if (client == NULL)
{
if (client == NULL) {
fprintf (stderr, "jack_client_open() failed, status = 0x%2.0x\n" fprintf (stderr, "jack_client_open() failed, status = 0x%2.0x\n"
"Is the JACK server running ?\n", status);
"Is the JACK server running ?\n", status);
return 1; return 1;
} }


@@ -714,7 +689,7 @@ main (int argc, char *argv[])
alloc_ports (capture_channels_audio, playback_channels_audio, capture_channels_midi, playback_channels_midi); alloc_ports (capture_channels_audio, playback_channels_audio, capture_channels_midi, playback_channels_midi);


if( bitdepth == 1000 ) if( bitdepth == 1000 )
net_period = (factor * jack_get_buffer_size(client) * 1024 / jack_get_sample_rate(client) / 8)&(~1) ;
net_period = (factor * jack_get_buffer_size(client) * 1024 / jack_get_sample_rate(client) / 8) & (~1) ;
else else
net_period = ceilf((float) jack_get_buffer_size (client) / (float) factor); net_period = ceilf((float) jack_get_buffer_size (client) / (float) factor);


@@ -722,8 +697,7 @@ main (int argc, char *argv[])
packcache = packet_cache_new (latency + 50, rx_bufsize, mtu); packcache = packet_cache_new (latency + 50, rx_bufsize, mtu);


/* tell the JACK server that we are ready to roll */ /* tell the JACK server that we are ready to roll */
if (jack_activate (client))
{
if (jack_activate (client)) {
fprintf (stderr, "Cannot activate client"); fprintf (stderr, "Cannot activate client");
return 1; return 1;
} }
@@ -737,49 +711,41 @@ main (int argc, char *argv[])
statecopy_latency = state_latency; statecopy_latency = state_latency;
statecopy_netxruns = state_netxruns; statecopy_netxruns = state_netxruns;


while ( !quit )
{
while ( !quit ) {
#ifdef WIN32 #ifdef WIN32
Sleep (1000); Sleep (1000);
#else #else
sleep(1); sleep(1);
#endif #endif
if (statecopy_connected != state_connected)
{
if (statecopy_connected != state_connected) {
statecopy_connected = state_connected; statecopy_connected = state_connected;
if (statecopy_connected)
{
if (statecopy_connected) {
state_netxruns = 1; // We want to reset the netxrun count on each new connection state_netxruns = 1; // We want to reset the netxrun count on each new connection
printf ("Connected :-)\n"); printf ("Connected :-)\n");
}
else
} else
printf ("Not Connected\n"); printf ("Not Connected\n");


fflush(stdout);
fflush(stdout);
} }


if (statecopy_connected)
{
if (statecopy_netxruns != state_netxruns) {
statecopy_netxruns = state_netxruns;
printf ("%s: at frame %06d -> total netxruns %d (%d%%) queue time= %d\n",
client_name,
state_currentframe,
statecopy_netxruns,
100*statecopy_netxruns/state_currentframe,
state_recv_packet_queue_time);

fflush(stdout);
if (statecopy_connected) {
if (statecopy_netxruns != state_netxruns) {
statecopy_netxruns = state_netxruns;
printf ("%s: at frame %06d -> total netxruns %d (%d%%) queue time= %d\n",
client_name,
state_currentframe,
statecopy_netxruns,
100 * statecopy_netxruns / state_currentframe,
state_recv_packet_queue_time);

fflush(stdout);
} }
}
else
{
if (statecopy_latency != state_latency)
{
statecopy_latency = state_latency;
if (statecopy_latency > 1)
printf ("current latency %d\n", statecopy_latency);
fflush(stdout);
} else {
if (statecopy_latency != state_latency) {
statecopy_latency = state_latency;
if (statecopy_latency > 1)
printf ("current latency %d\n", statecopy_latency);
fflush(stdout);
} }
} }
} }


+ 80
- 0
windows/JackMMCSS.cpp View File

@@ -0,0 +1,80 @@
/*
Copyright (C) 2004-2008 Grame

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

*/

#include "JackMMCSS.h"
#include "JackError.h"
#include <assert.h>
#include <stdio.h>

namespace Jack
{
avSetMmThreadCharacteristics JackMMCSS::ffMMCSSFun1 = NULL;
avSetMmThreadPriority JackMMCSS::ffMMCSSFun2 = NULL;
avRevertMmThreadCharacteristics JackMMCSS::ffMMCSSFun3 = NULL;
JACK_HANDLE JackMMCSS::fAvrtDll;
std::map<jack_native_thread_t, HANDLE> JackMMCSS::fHandleTable;

JackMMCSS::JackMMCSS()
{
fAvrtDll = LoadJackModule("avrt.dll");
if (fAvrtDll != NULL) {
ffMMCSSFun1 = (avSetMmThreadCharacteristics)GetJackProc(fAvrtDll, "AvSetMmThreadCharacteristicsA");
ffMMCSSFun2 = (avSetMmThreadPriority)GetJackProc(fAvrtDll, "AvSetMmThreadPriority");
ffMMCSSFun3 = (avRevertMmThreadCharacteristics)GetJackProc(fAvrtDll, "AvRevertMmThreadCharacteristics");
}
}

JackMMCSS::~JackMMCSS()
{}

int JackMMCSS::MMCSSAcquireRealTime(jack_native_thread_t thread)
{
if (fHandleTable.find(thread) != fHandleTable.end()) {
return 0;
}
if (ffMMCSSFun1) {
DWORD dummy = 0;
HANDLE task = ffMMCSSFun1("Pro Audio", &dummy);
if (task == NULL) {
jack_error("Cannot use MMCSS %d", GetLastError());
} else if (ffMMCSSFun2(task, AVRT_PRIORITY_CRITICAL)) {
fHandleTable[thread] = task;
return 0;
}
}
return -1;
}
int JackMMCSS::MMCSSDropRealTime(jack_native_thread_t thread)
{
if (fHandleTable.find(thread) != fHandleTable.end()) {
HANDLE task = fHandleTable[thread];
ffMMCSSFun3(task);
return 0;
} else {
return -1;
}
}
}

+ 72
- 0
windows/JackMMCSS.h View File

@@ -0,0 +1,72 @@
/*
Copyright (C) 2004-2008 Grame
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __JackMMCSS__
#define __JackMMCSS__
#include "JackSystemDeps.h"
#include "JackCompilerDeps.h"
#include <windows.h>
#include <map>
namespace Jack
{
typedef enum _AVRT_PRIORITY {
AVRT_PRIORITY_LOW = -1,
AVRT_PRIORITY_NORMAL, /* 0 */
AVRT_PRIORITY_HIGH, /* 1 */
AVRT_PRIORITY_CRITICAL /* 2 */
} AVRT_PRIORITY, *PAVRT_PRIORITY;

typedef HANDLE (WINAPI *avSetMmThreadCharacteristics)(LPCTSTR, LPDWORD);
typedef BOOL (WINAPI *avRevertMmThreadCharacteristics)(HANDLE);
typedef BOOL (WINAPI *avSetMmThreadPriority)(HANDLE, AVRT_PRIORITY);
/*!
\brief MMCSS services.
*/
class SERVER_EXPORT JackMMCSS
{
private:
static JACK_HANDLE fAvrtDll;
static avSetMmThreadCharacteristics ffMMCSSFun1;
static avSetMmThreadPriority ffMMCSSFun2;
static avRevertMmThreadCharacteristics ffMMCSSFun3;
static std::map<jack_native_thread_t, HANDLE> fHandleTable;
public:
JackMMCSS();
~JackMMCSS();
static int MMCSSAcquireRealTime(jack_native_thread_t thread);
static int MMCSSDropRealTime(jack_native_thread_t thread);
};
} // end of namespace
#endif

+ 15
- 6
windows/JackWinThread.cpp View File

@@ -17,11 +17,11 @@


*/ */



#include "JackWinThread.h" #include "JackWinThread.h"
#include "JackError.h" #include "JackError.h"
#include "JackTime.h" #include "JackTime.h"
#include <assert.h> #include <assert.h>
#include <stdio.h>


namespace Jack namespace Jack
{ {
@@ -55,7 +55,7 @@ DWORD WINAPI JackWinThread::ThreadHandler(void* arg)
} }


JackWinThread::JackWinThread(JackRunnableInterface* runnable) JackWinThread::JackWinThread(JackRunnableInterface* runnable)
: JackThreadInterface(runnable, 0, false, 0)
: JackMMCSS(), JackThreadInterface(runnable, 0, false, 0)
{ {
fEvent = CreateEvent(NULL, FALSE, FALSE, NULL); fEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
fThread = (HANDLE)NULL; fThread = (HANDLE)NULL;
@@ -202,11 +202,17 @@ int JackWinThread::AcquireRealTimeImp(jack_native_thread_t thread, int priority)
{ {
jack_log("JackWinThread::AcquireRealTimeImp priority = %d", THREAD_PRIORITY_TIME_CRITICAL); jack_log("JackWinThread::AcquireRealTimeImp priority = %d", THREAD_PRIORITY_TIME_CRITICAL);


if (SetThreadPriority(thread, THREAD_PRIORITY_TIME_CRITICAL)) {
if (priority >= 90 && MMCSSAcquireRealTime(thread) == 0) {
jack_info("MMCSS API used to acquire RT for thread: %x", thread);
return 0; return 0;
} else { } else {
jack_error("Cannot set thread priority = %d", GetLastError());
return -1;
jack_info("MMCSS API not used...");
if (SetThreadPriority(thread, THREAD_PRIORITY_TIME_CRITICAL)) {
return 0;
} else {
jack_error("Cannot set thread priority = %d", GetLastError());
return -1;
}
} }
} }


@@ -222,7 +228,10 @@ int JackWinThread::DropSelfRealTime()


int JackWinThread::DropRealTimeImp(jack_native_thread_t thread) int JackWinThread::DropRealTimeImp(jack_native_thread_t thread)
{ {
if (SetThreadPriority(thread, THREAD_PRIORITY_NORMAL)) {
if (MMCSSDropRealTime(thread) == 0 ) {
jack_info("MMCSS API used to drop RT for thread: %x", thread);
return 0;
} else if (SetThreadPriority(thread, THREAD_PRIORITY_NORMAL)) {
return 0; return 0;
} else { } else {
jack_error("Cannot set thread priority = %d", GetLastError()); jack_error("Cannot set thread priority = %d", GetLastError());


+ 2
- 3
windows/JackWinThread.h View File

@@ -17,12 +17,11 @@


*/ */




#ifndef __JackWinThread__ #ifndef __JackWinThread__
#define __JackWinThread__ #define __JackWinThread__


#include "JackThread.h" #include "JackThread.h"
#include "JackMMCSS.h"
#include "JackCompilerDeps.h" #include "JackCompilerDeps.h"
#include "JackSystemDeps.h" #include "JackSystemDeps.h"
#include <windows.h> #include <windows.h>
@@ -36,7 +35,7 @@ typedef DWORD (WINAPI *ThreadCallback)(void *arg);
\brief Windows threads. \brief Windows threads.
*/ */


class SERVER_EXPORT JackWinThread : public detail::JackThreadInterface
class SERVER_EXPORT JackWinThread : public JackMMCSS, public detail::JackThreadInterface
{ {


private: private:


+ 2
- 2
windows/jackd.workspace View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> <?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_workspace_file> <CodeBlocks_workspace_file>
<Workspace title="jack"> <Workspace title="jack">
<Project filename="libjackserver.cbp" />
<Project filename="libjackserver.cbp" active="1" />
<Project filename="jack_portaudio.cbp" /> <Project filename="jack_portaudio.cbp" />
<Project filename="jack_netdriver.cbp" /> <Project filename="jack_netdriver.cbp" />
<Project filename="jack_netonedriver.cbp" /> <Project filename="jack_netonedriver.cbp" />
@@ -18,7 +18,7 @@
<Project filename="jack_disconnect.cbp" /> <Project filename="jack_disconnect.cbp" />
<Project filename="jack_test.cbp" /> <Project filename="jack_test.cbp" />
<Project filename="multiple_metro.cbp" /> <Project filename="multiple_metro.cbp" />
<Project filename="jack_winmme.cbp" active="1" />
<Project filename="jack_winmme.cbp" />
<Project filename="jack_loopback.cbp" /> <Project filename="jack_loopback.cbp" />
<Project filename="jackd.cbp" /> <Project filename="jackd.cbp" />
<Project filename="jack_midi_latency_test.cbp" /> <Project filename="jack_midi_latency_test.cbp" />


+ 11
- 10
windows/libjack.cbp View File

@@ -133,7 +133,7 @@
<Add library="odbccp32" /> <Add library="odbccp32" />
</Linker> </Linker>
</Target> </Target>
<Target title="Win32 Release 32bits">
<Target title="Win32 Release 32bits">
<Option output="Release\bin\libjack" prefix_auto="1" extension_auto="1" /> <Option output="Release\bin\libjack" prefix_auto="1" extension_auto="1" />
<Option object_output="Release" /> <Option object_output="Release" />
<Option type="3" /> <Option type="3" />
@@ -143,7 +143,7 @@
<Compiler> <Compiler>
<Add option="-O2" /> <Add option="-O2" />
<Add option="-Wall" /> <Add option="-Wall" />
<Add option="-m32" />
<Add option="-m32" />
<Add option="-DWIN32" /> <Add option="-DWIN32" />
<Add option="-DNDEBUG" /> <Add option="-DNDEBUG" />
<Add option="-D_WINDOWS" /> <Add option="-D_WINDOWS" />
@@ -162,7 +162,7 @@
<Add directory="tre-0.8.0\lib" /> <Add directory="tre-0.8.0\lib" />
</Compiler> </Compiler>
<Linker> <Linker>
<Add option="-m32" />
<Add option="-m32" />
<Add library="kernel32" /> <Add library="kernel32" />
<Add library="user32" /> <Add library="user32" />
<Add library="gdi32" /> <Add library="gdi32" />
@@ -176,7 +176,7 @@
<Add library="odbc32" /> <Add library="odbc32" />
<Add library="odbccp32" /> <Add library="odbccp32" />
</Linker> </Linker>
<ExtraCommands>
<ExtraCommands>
<Add before="windres -F pe-i386 -O coff -o Release/libjack.res libjack.rc" /> <Add before="windres -F pe-i386 -O coff -o Release/libjack.res libjack.rc" />
</ExtraCommands> </ExtraCommands>
</Target> </Target>
@@ -190,7 +190,7 @@
<Compiler> <Compiler>
<Add option="-Wall" /> <Add option="-Wall" />
<Add option="-g" /> <Add option="-g" />
<Add option="-m32" />
<Add option="-m32" />
<Add option="-DWIN32" /> <Add option="-DWIN32" />
<Add option="-D_DEBUG" /> <Add option="-D_DEBUG" />
<Add option="-D_WINDOWS" /> <Add option="-D_WINDOWS" />
@@ -209,7 +209,7 @@
<Add directory="tre-0.8.0\lib" /> <Add directory="tre-0.8.0\lib" />
</Compiler> </Compiler>
<Linker> <Linker>
<Add option="-m32" />
<Add option="-m32" />
<Add library="kernel32" /> <Add library="kernel32" />
<Add library="user32" /> <Add library="user32" />
<Add library="gdi32" /> <Add library="gdi32" />
@@ -223,7 +223,7 @@
<Add library="odbc32" /> <Add library="odbc32" />
<Add library="odbccp32" /> <Add library="odbccp32" />
</Linker> </Linker>
<ExtraCommands>
<ExtraCommands>
<Add before="windres -F pe-i386 -O coff -o Debug/libjack.res libjack.rc" /> <Add before="windres -F pe-i386 -O coff -o Debug/libjack.res libjack.rc" />
</ExtraCommands> </ExtraCommands>
</Target> </Target>
@@ -237,7 +237,7 @@
<Compiler> <Compiler>
<Add option="-O2" /> <Add option="-O2" />
<Add option="-Wall" /> <Add option="-Wall" />
<Add option="-m32" />
<Add option="-m32" />
<Add option="-DWIN32" /> <Add option="-DWIN32" />
<Add option="-DNDEBUG" /> <Add option="-DNDEBUG" />
<Add option="-D_WINDOWS" /> <Add option="-D_WINDOWS" />
@@ -257,7 +257,7 @@
<Add directory="tre-0.8.0\lib" /> <Add directory="tre-0.8.0\lib" />
</Compiler> </Compiler>
<Linker> <Linker>
<Add option="-m32" />
<Add option="-m32" />
<Add library="kernel32" /> <Add library="kernel32" />
<Add library="user32" /> <Add library="user32" />
<Add library="gdi32" /> <Add library="gdi32" />
@@ -271,7 +271,7 @@
<Add library="odbc32" /> <Add library="odbc32" />
<Add library="odbccp32" /> <Add library="odbccp32" />
</Linker> </Linker>
<ExtraCommands>
<ExtraCommands>
<Add before="windres -F pe-i386 -O coff -o Release/libjack.res libjack.rc" /> <Add before="windres -F pe-i386 -O coff -o Release/libjack.res libjack.rc" />
</ExtraCommands> </ExtraCommands>
</Target> </Target>
@@ -322,6 +322,7 @@
<Unit filename="..\common\shm.c"> <Unit filename="..\common\shm.c">
<Option compilerVar="CC" /> <Option compilerVar="CC" />
</Unit> </Unit>
<Unit filename="JackMMCSS.cpp" />
<Unit filename="JackWinNamedPipe.cpp" /> <Unit filename="JackWinNamedPipe.cpp" />
<Unit filename="JackWinNamedPipeClientChannel.cpp" /> <Unit filename="JackWinNamedPipeClientChannel.cpp" />
<Unit filename="JackWinProcessSync.cpp" /> <Unit filename="JackWinProcessSync.cpp" />


+ 7
- 6
windows/libjacknet.cbp View File

@@ -32,8 +32,8 @@
<Add directory="..\common" /> <Add directory="..\common" />
</Compiler> </Compiler>
<Linker> <Linker>
<Add directory="Release64\bin" />
<Add library="libsamplerate_x86_64" /> <Add library="libsamplerate_x86_64" />
<Add directory="Release64\bin" />
</Linker> </Linker>
</Target> </Target>
<Target title="Win32 Debug 64bits"> <Target title="Win32 Debug 64bits">
@@ -62,8 +62,8 @@
<Add directory="..\common" /> <Add directory="..\common" />
</Compiler> </Compiler>
<Linker> <Linker>
<Add directory="Debug64\bin" />
<Add library="libsamplerate_x86_64" /> <Add library="libsamplerate_x86_64" />
<Add directory="Debug64\bin" />
</Linker> </Linker>
</Target> </Target>
<Target title="Win32 Profiling 64bits"> <Target title="Win32 Profiling 64bits">
@@ -93,8 +93,8 @@
<Add directory="..\common" /> <Add directory="..\common" />
</Compiler> </Compiler>
<Linker> <Linker>
<Add directory="Release64\bin" />
<Add library="libsamplerate_x86_64" /> <Add library="libsamplerate_x86_64" />
<Add directory="Release64\bin" />
</Linker> </Linker>
</Target> </Target>
<Target title="Win32 Release 32bits"> <Target title="Win32 Release 32bits">
@@ -125,8 +125,8 @@
</Compiler> </Compiler>
<Linker> <Linker>
<Add option="-m32" /> <Add option="-m32" />
<Add directory="Release\bin" />
<Add library="libsamplerate_x86" /> <Add library="libsamplerate_x86" />
<Add directory="Release\bin" />
</Linker> </Linker>
<ExtraCommands> <ExtraCommands>
<Add before="windres -F pe-i386 -O coff -o Release/libjacknet.res libjacknet.rc" /> <Add before="windres -F pe-i386 -O coff -o Release/libjacknet.res libjacknet.rc" />
@@ -160,8 +160,8 @@
</Compiler> </Compiler>
<Linker> <Linker>
<Add option="-m32" /> <Add option="-m32" />
<Add directory="Debug\bin" />
<Add library="libsamplerate_x86" /> <Add library="libsamplerate_x86" />
<Add directory="Debug\bin" />
</Linker> </Linker>
<ExtraCommands> <ExtraCommands>
<Add before="windres -F pe-i386 -O coff -o Debug/libjacknet.res libjacknet.rc" /> <Add before="windres -F pe-i386 -O coff -o Debug/libjacknet.res libjacknet.rc" />
@@ -196,8 +196,8 @@
</Compiler> </Compiler>
<Linker> <Linker>
<Add option="-m32" /> <Add option="-m32" />
<Add directory="Release\bin" />
<Add library="libsamplerate_x86" /> <Add library="libsamplerate_x86" />
<Add directory="Release\bin" />
</Linker> </Linker>
<ExtraCommands> <ExtraCommands>
<Add before="windres -F pe-i386 -O coff -o Release/libjacknet.res libjacknet.rc" /> <Add before="windres -F pe-i386 -O coff -o Release/libjacknet.res libjacknet.rc" />
@@ -235,6 +235,7 @@
<Unit filename="..\common\ringbuffer.c"> <Unit filename="..\common\ringbuffer.c">
<Option compilerVar="CC" /> <Option compilerVar="CC" />
</Unit> </Unit>
<Unit filename="JackMMCSS.cpp" />
<Unit filename="JackNetWinSocket.cpp" /> <Unit filename="JackNetWinSocket.cpp" />
<Unit filename="JackWinThread.cpp" /> <Unit filename="JackWinThread.cpp" />
<Unit filename="JackWinTime.c"> <Unit filename="JackWinTime.c">


+ 1
- 0
windows/libjackserver.cbp View File

@@ -289,6 +289,7 @@
<Unit filename="..\common\shm.c"> <Unit filename="..\common\shm.c">
<Option compilerVar="CC" /> <Option compilerVar="CC" />
</Unit> </Unit>
<Unit filename="JackMMCSS.cpp" />
<Unit filename="JackNetWinSocket.cpp" /> <Unit filename="JackNetWinSocket.cpp" />
<Unit filename="JackWinNamedPipe.cpp" /> <Unit filename="JackWinNamedPipe.cpp" />
<Unit filename="JackWinNamedPipeClientChannel.cpp" /> <Unit filename="JackWinNamedPipeClientChannel.cpp" />


+ 2
- 0
windows/portaudio/JackPortAudioDriver.cpp View File

@@ -41,6 +41,8 @@ namespace Jack
driver->fInputBuffer = (jack_default_audio_sample_t**)inputBuffer; driver->fInputBuffer = (jack_default_audio_sample_t**)inputBuffer;
driver->fOutputBuffer = (jack_default_audio_sample_t**)outputBuffer; driver->fOutputBuffer = (jack_default_audio_sample_t**)outputBuffer;


MMCSSAcquireRealTime(GetCurrentThread());

if (statusFlags) { if (statusFlags) {
if (statusFlags & paOutputUnderflow) if (statusFlags & paOutputUnderflow)
jack_error("JackPortAudioDriver::Render paOutputUnderflow"); jack_error("JackPortAudioDriver::Render paOutputUnderflow");


+ 3
- 2
windows/portaudio/JackPortAudioDriver.h View File

@@ -22,6 +22,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.


#include "JackAudioDriver.h" #include "JackAudioDriver.h"
#include "JackPortAudioDevices.h" #include "JackPortAudioDevices.h"
#include "JackMMCSS.h"


namespace Jack namespace Jack
{ {
@@ -30,7 +31,7 @@ namespace Jack
\brief The PortAudio driver. \brief The PortAudio driver.
*/ */


class JackPortAudioDriver : public JackAudioDriver
class JackPortAudioDriver : public JackMMCSS, public JackAudioDriver
{ {


private: private:
@@ -54,7 +55,7 @@ class JackPortAudioDriver : public JackAudioDriver
public: public:


JackPortAudioDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table, PortAudioDevices* pa_devices) JackPortAudioDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table, PortAudioDevices* pa_devices)
: JackAudioDriver(name, alias, engine, table), fStream(NULL), fInputBuffer(NULL), fOutputBuffer(NULL),
: JackMMCSS(), JackAudioDriver(name, alias, engine, table), fStream(NULL), fInputBuffer(NULL), fOutputBuffer(NULL),
fInputDevice(paNoDevice), fOutputDevice(paNoDevice) fInputDevice(paNoDevice), fOutputDevice(paNoDevice)
{ {
fPaDevices = pa_devices; fPaDevices = pa_devices;


+ 1
- 1
windows/winmme/JackWinMMEDriver.cpp View File

@@ -60,7 +60,7 @@ JackWinMMEDriver::Attach()
// Inputs // Inputs
for (int i = 0; i < fCaptureChannels; i++) { for (int i = 0; i < fCaptureChannels; i++) {
JackWinMMEInputPort *input_port = input_ports[i]; JackWinMMEInputPort *input_port = input_ports[i];
name = input_port->GetName();
name = input_port->GetName();
if (fEngine->PortRegister(fClientControl.fRefNum, name, if (fEngine->PortRegister(fClientControl.fRefNum, name,
JACK_DEFAULT_MIDI_TYPE, JACK_DEFAULT_MIDI_TYPE,
CaptureDriverFlags, buffer_size, &index) < 0) { CaptureDriverFlags, buffer_size, &index) < 0) {


+ 8
- 5
windows/winmme/JackWinMMEOutputPort.cpp View File

@@ -22,7 +22,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.


#include "JackMidiUtil.h" #include "JackMidiUtil.h"
#include "JackTime.h" #include "JackTime.h"
#include "JackWinMMEOutputPort.h"
#include "JackWinMMEOutputPort.h"
#include "JackGlobals.h"
#include "JackEngineControl.h"


using Jack::JackWinMMEOutputPort; using Jack::JackWinMMEOutputPort;


@@ -44,7 +46,8 @@ JackWinMMEOutputPort::HandleMessageEvent(HMIDIOUT handle, UINT message,


JackWinMMEOutputPort::JackWinMMEOutputPort(const char *alias_name, JackWinMMEOutputPort::JackWinMMEOutputPort(const char *alias_name,
const char *client_name, const char *client_name,
const char *driver_name, UINT index,
const char *driver_name,
UINT index,
size_t max_bytes, size_t max_bytes,
size_t max_messages) size_t max_messages)
{ {
@@ -86,7 +89,7 @@ JackWinMMEOutputPort::JackWinMMEOutputPort(const char *alias_name,
snprintf(name, sizeof(name) - 1, "%s:playback_%d", client_name, index + 1); snprintf(name, sizeof(name) - 1, "%s:playback_%d", client_name, index + 1);
read_queue_ptr.release(); read_queue_ptr.release();
thread_queue_ptr.release(); thread_queue_ptr.release();
thread_ptr.release();
thread_ptr.release();
return; return;


destroy_thread_queue_semaphore: destroy_thread_queue_semaphore:
@@ -132,7 +135,7 @@ JackWinMMEOutputPort::Execute()
for (;;) { for (;;) {
if (! Wait(thread_queue_semaphore)) { if (! Wait(thread_queue_semaphore)) {
jack_log("JackWinMMEOutputPort::Execute BREAK"); jack_log("JackWinMMEOutputPort::Execute BREAK");
break; break;
} }
jack_midi_event_t *event = thread_queue->DequeueEvent(); jack_midi_event_t *event = thread_queue->DequeueEvent();
@@ -274,7 +277,7 @@ JackWinMMEOutputPort::Init()
set_threaded_log_function(); set_threaded_log_function();
// XX: Can more be done? Ideally, this thread should have the JACK server // XX: Can more be done? Ideally, this thread should have the JACK server
// thread priority + 1. // thread priority + 1.
if (thread->AcquireSelfRealTime()) {
if (thread->AcquireSelfRealTime(GetEngineControl()->fServerPriority)) {
jack_error("JackWinMMEOutputPort::Init - could not acquire realtime " jack_error("JackWinMMEOutputPort::Init - could not acquire realtime "
"scheduling. Continuing anyway."); "scheduling. Continuing anyway.");
} }


Loading…
Cancel
Save