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

+ 276
- 298
common/netjack.c View File

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

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.

if( netj->expected_framecnt_valid ) {
netj->expected_framecnt += 1;
netj->expected_framecnt += 1;
} 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 );
@@ -113,26 +112,26 @@ int netjack_wait( netjack_driver_state_t *netj )
// then poll (have deadline calculated)
// then drain socket, rinse and repeat.
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.
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.
// 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 ) {

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) ) {
// 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->next_deadline += netj->period_usecs;
netj->next_deadline += netj->period_usecs;
} 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;

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 {
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;
@@ -338,19 +336,17 @@ void netjack_send_silence( netjack_driver_state_t *netj, int syncstate )
memset(packet_bufX, 0, payload_size);

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 )
{
//puts ("net_driver_attach");
@@ -359,19 +355,17 @@ void netjack_attach( netjack_driver_state_t *netj )
unsigned int chn;
int port_flags;


if( netj->bitdepth == CELT_MODE )
{
if( netj->bitdepth == CELT_MODE ) {
#if HAVE_CELT
#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
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
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
}

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

if( netj->bitdepth == CELT_MODE ) {
if( netj->bitdepth == CELT_MODE ) {
#if HAVE_CELT
#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
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
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
} else {
} else {
#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
}
}
}

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 =
jack_slist_append (netj->playback_ports, port);
if( netj->bitdepth == CELT_MODE ) {
if( netj->bitdepth == CELT_MODE ) {
#if HAVE_CELT
#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
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
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
} else {
} else {
#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
}
}
}
for (chn = netj->playback_channels_audio; chn < netj->playback_channels; chn++) {
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);
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( netj->bitdepth == CELT_MODE )
{
if( netj->bitdepth == CELT_MODE ) {
CELTDecoder * decoder = node->data;
celt_decoder_destroy(decoder);
}
else
} else
#endif
{
#if HAVE_SAMPLERATE
@@ -519,15 +510,12 @@ void netjack_detach( netjack_driver_state_t *netj )
jack_slist_free (netj->playback_ports);
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( netj->bitdepth == CELT_MODE )
{
if( netj->bitdepth == CELT_MODE ) {
CELTEncoder * encoder = node->data;
celt_encoder_destroy(encoder);
}
else
} else
#endif
{
#if HAVE_SAMPLERATE
@@ -540,32 +528,32 @@ void netjack_detach( netjack_driver_state_t *netj )
netj->playback_srcs = NULL;

#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
}


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.
@@ -600,8 +588,7 @@ netjack_driver_state_t *netjack_init (netjack_driver_state_t *netj,
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);
return NULL;
}
@@ -647,8 +634,7 @@ netjack_startup( netjack_driver_state_t *netj )
address.sin_family = AF_INET;
address.sin_port = htons(netj->listen_port);
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");
return -1;
}
@@ -664,14 +650,13 @@ netjack_startup( netjack_driver_state_t *netj )
return -1;
}
netj->srcaddress_valid = 0;
if (netj->use_autoconfig)
{
if (netj->use_autoconfig) {
jacknet_packet_header *first_packet = alloca (sizeof (jacknet_packet_header));
#ifdef WIN32
#ifdef WIN32
int address_size = sizeof( struct sockaddr_in );
#else
#else
socklen_t address_size = sizeof (struct sockaddr_in);
#endif
#endif
//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 !!!");

@@ -681,51 +666,44 @@ netjack_startup( netjack_driver_state_t *netj )
return -1;
}
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;

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

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

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 ) {
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 ) {
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...
@@ -765,15 +743,15 @@ netjack_startup( netjack_driver_state_t *netj )
* 1000000.0f);

if( netj->latency == 0 )
netj->deadline_offset = 50*netj->period_usecs;
netj->deadline_offset = 50 * netj->period_usecs;
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 ) {
// celt mode.
// 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_up = netj->resample_factor_up;
@@ -795,7 +773,7 @@ netjack_startup( netjack_driver_state_t *netj )
if( netj->latency == 0 )
netj->resync_threshold = 0;
else
netj->resync_threshold = MIN( 15, netj->latency-1 );
netj->resync_threshold = MIN( 15, netj->latency - 1 );

netj->running_free = 0;



+ 92
- 92
common/netjack.h View File

@@ -37,113 +37,113 @@ extern "C"
{
#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
SOCKET sockfd;
SOCKET outsockfd;
SOCKET sockfd;
SOCKET outsockfd;
#else
int sockfd;
int outsockfd;
int sockfd;
int outsockfd;
#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
CELTMode *celt_mode;
CELTMode *celt_mode;
#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
}


+ 187
- 279
common/netjack_packet.c View File

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

if( pkt_size == sizeof(jacknet_packet_header) )
fragment_number = 1;
fragment_number = 1;
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));
if (pcache == NULL)
{
if (pcache == NULL) {
jack_error ("could not allocate packet cache (1)");
return NULL;
}
@@ -169,14 +168,12 @@ packet_cache
pcache->last_framecnt_retreived = 0;
pcache->last_framecnt_retreived_valid = 0;

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

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

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

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

for (i = 0; i < pcache->size; i++)
{
for (i = 0; i < pcache->size; i++) {
if (pcache->packets[i].valid == 0)
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 framecnt = ntohl (pkthdr->framecnt);

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

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

return;
}

if ((fragment_nr < pack->num_fragments) && (fragment_nr > 0))
{
if ((fragment_nr * fragment_payload_size + rcv_len - sizeof (jacknet_packet_header)) <= (pack->packet_size - sizeof (jacknet_packet_header)))
{
if ((fragment_nr < pack->num_fragments) && (fragment_nr > 0)) {
if ((fragment_nr * fragment_payload_size + rcv_len - sizeof (jacknet_packet_header)) <= (pack->packet_size - sizeof (jacknet_packet_header))) {
memcpy (packet_bufX + fragment_nr * fragment_payload_size, dataX, rcv_len - sizeof (jacknet_packet_header));
pack->fragment_array[fragment_nr] = 1;
}
else
} else
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();
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
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);
#endif

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

sigemptyset(&sigmask);
sigaddset(&sigmask, SIGHUP);
sigaddset(&sigmask, SIGINT);
sigaddset(&sigmask, SIGQUIT);
sigaddset(&sigmask, SIGPIPE);
sigaddset(&sigmask, SIGTERM);
sigaddset(&sigmask, SIGUSR1);
sigaddset(&sigmask, SIGUSR2);
action.sa_handler = SIG_DFL;
action.sa_mask = sigmask;
action.sa_flags = SA_RESTART;
sigaddset(&sigmask, SIGHUP);
sigaddset(&sigmask, SIGINT);
sigaddset(&sigmask, SIGQUIT);
sigaddset(&sigmask, SIGPIPE);
sigaddset(&sigmask, SIGTERM);
sigaddset(&sigmask, SIGUSR1);
sigaddset(&sigmask, SIGUSR2);
action.sa_handler = SIG_DFL;
action.sa_mask = sigmask;
action.sa_flags = SA_RESTART;

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

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

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

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

if (pcache->master_address_valid) {
// Verify its from our master.
if (memcmp (&sender_address, &(pcache->master_address), senderlen) != 0)
continue;
} else {
// Setup this one as master
//printf( "setup master...\n" );
memcpy ( &(pcache->master_address), &sender_address, senderlen );
pcache->master_address_valid = 1;
}
if (pcache->master_address_valid) {
// Verify its from our master.
if (memcmp (&sender_address, &(pcache->master_address), senderlen) != 0)
continue;
} else {
// Setup this one as master
//printf( "setup master...\n" );
memcpy ( &(pcache->master_address), &sender_address, senderlen );
pcache->master_address_valid = 1;
}

framecnt = ntohl (pkthdr->framecnt);
if( pcache->last_framecnt_retreived_valid && (framecnt <= pcache->last_framecnt_retreived ))
continue;
if( pcache->last_framecnt_retreived_valid && (framecnt <= pcache->last_framecnt_retreived ))
continue;

cpack = packet_cache_get_packet (pcache, framecnt);
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;

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]));
}
}
@@ -654,8 +631,7 @@ packet_cache_get_fill( packet_cache *pcache, jack_nframes_t expected_framecnt )
int num_packets_before_us = 0;
int i;

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

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

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

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)
*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;
int retval = 0;

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

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

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

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

}
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;
int retval = 0;

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

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

if ((cpack->framecnt - expected_framecnt) < best_offset) {
continue;
}
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)
*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->fragment_nr = htonl (0);
err = sendto(sockfd, packet_buf, pkt_size, flags, addr, addr_size);
if( err<0 ) {
if( err < 0 ) {
//printf( "error in send\n" );
perror( "send" );
}
}
else
{
} else {
int err;
// Copy the packet header to the tx pack first.
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
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++);
memcpy (dataX, packet_bufX, fragment_payload_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);
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" );
perror( "send" );
}
@@ -826,24 +796,21 @@ decode_midi_buffer (uint32_t *buffer_uint32, unsigned int buffer_size_uint32, ja
{
int i;
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;
payload_size = buffer_uint32[i];
payload_size = ntohl (payload_size);
if (payload_size)
{
if (payload_size) {
jack_midi_event_t event;
event.time = ntohl (buffer_uint32[i+1]);
event.size = ntohl (buffer_uint32[i+2]);
event.buffer = (jack_midi_data_t*) (&(buffer_uint32[i+3]));
event.time = ntohl (buffer_uint32[i + 1]);
event.size = ntohl (buffer_uint32[i + 2]);
event.buffer = (jack_midi_data_t*) (&(buffer_uint32[i + 3]));
jack_midi_event_write (buf, event.time, event.buffer, event.size);

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

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

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

while (node != NULL)
{
while (node != NULL) {
int i;
int_float_t val;
#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);

if (jack_port_is_audio (porttype))
{
if (jack_port_is_audio (porttype)) {
#if HAVE_SAMPLERATE
// audio port, resample if necessary
if (net_period_down != nframes)
{
if (net_period_down != nframes) {
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]);
}

@@ -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_process (src_state, &src);
src_node = jack_slist_next (src_node);
}
else
} else
#endif
{
if( dont_htonl_floats )
{
memcpy( buf, packet_bufX, net_period_down*sizeof(jack_default_audio_sample_t));
}
else
{
for (i = 0; i < net_period_down; i++)
{
val.i = packet_bufX[i];
val.i = ntohl (val.i);
buf[i] = val.f;
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
// convert the data buffer to a standard format (uint32_t based)
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;

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

const char *porttype = jack_port_type (port);

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

#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_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]);
}
src_node = jack_slist_next (src_node);
}
else
} else
#endif
{
if( dont_htonl_floats )
{
memcpy( packet_bufX, buf, net_period_up*sizeof(jack_default_audio_sample_t) );
}
else
{
for (i = 0; i < net_period_up; i++)
{
val.f = buf[i];
val.i = htonl (val.i);
packet_bufX[i] = val.i;
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
// convert the data buffer to a standard format (uint32_t based)
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;

if( !packet_payload )
return;
return;

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

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

#if HAVE_SAMPLERATE
if (net_period_down != nframes)
{
if (net_period_down != nframes) {
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;
}

@@ -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_process (src_state, &src);
src_node = jack_slist_next (src_node);
}
else
} else
#endif
for (i = 0; i < net_period_down; i++)
buf[i] = ((float) ntohs (packet_bufX[i])) / 32768.0 - 1.0;
}
else if (jack_port_is_midi (porttype))
{
} else if (jack_port_is_midi (porttype)) {
// midi port, decode midi events
// convert the data buffer to a standard format (uint32_t based)
unsigned int buffer_size_uint32 = net_period_down / 2;
@@ -1141,8 +1076,7 @@ render_jack_ports_to_payload_16bit (JSList *playback_ports, JSList *playback_src

uint16_t *packet_bufX = (uint16_t *)packet_payload;

while (node != NULL)
{
while (node != NULL) {
#if HAVE_SAMPLERATE
SRC_DATA src;
#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);
const char *porttype = jack_port_type (port);

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

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

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

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

if (jack_port_is_audio(porttype))
{
if (jack_port_is_audio(porttype)) {
#if HAVE_SAMPLERATE
// audio port, resample if necessary
if (net_period_down != nframes)
{
if (net_period_down != nframes) {
SRC_STATE *src_state = src_node->data;
for (i = 0; i < net_period_down; i++)
floatbuf[i] = ((float) packet_bufX[i]) / 127.0;
@@ -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_process (src_state, &src);
src_node = jack_slist_next (src_node);
}
else
} else
#endif
for (i = 0; i < net_period_down; i++)
buf[i] = ((float) packet_bufX[i]) / 127.0;
}
else if (jack_port_is_midi (porttype))
{
} else if (jack_port_is_midi (porttype)) {
// midi port, decode midi events
// convert the data buffer to a standard format (uint32_t based)
unsigned int buffer_size_uint32 = net_period_down / 2;
@@ -1284,8 +1206,7 @@ render_jack_ports_to_payload_8bit (JSList *playback_ports, JSList *playback_srcs

int8_t *packet_bufX = (int8_t *)packet_payload;

while (node != NULL)
{
while (node != NULL) {
#if HAVE_SAMPLERATE
SRC_DATA src;
#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);
const char *porttype = jack_port_type (port);

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

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++)
packet_bufX[i] = floatbuf[i] * 127.0;
src_node = jack_slist_next (src_node);
}
else
} else
#endif
for (i = 0; i < net_period_up; i++)
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
// convert the data buffer to a standard format (uint32_t based)
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;

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

const char *porttype = jack_port_type (port);

if (jack_port_is_audio (porttype))
{
if (jack_port_is_audio (porttype)) {
// audio port, decode celt 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 )
celt_decode_float( decoder, NULL, net_period_down, buf, nframes );
else
celt_decode_float( decoder, packet_bufX, net_period_down, buf, nframes );
#else
#else
if( !packet_payload )
celt_decode_float( decoder, NULL, net_period_down, buf );
else
celt_decode_float( decoder, packet_bufX, net_period_down, buf );
#endif
#endif

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
// convert the data buffer to a standard format (uint32_t based)
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;

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

if (jack_port_is_audio (porttype))
{
if (jack_port_is_audio (porttype)) {
// audio port, encode celt data.

int encoded_bytes;
float *floatbuf = alloca (sizeof(float) * nframes );
memcpy( floatbuf, buf, nframes*sizeof(float) );
CELTEncoder *encoder = src_node->data;
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
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
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
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
// convert the data buffer to a standard format (uint32_t based)
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__

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

#include <jack/jack.h>
@@ -42,115 +42,106 @@
#define CELT_MODE 1000 // Magic bitdepth value that indicates CELT compression
#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
}
}
#endif
#endif


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

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

int quit=0;
int quit = 0;


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

capture_ports = NULL;
/* 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);
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);
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 );
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 );
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 );
capture_srcs = jack_slist_append(capture_srcs, celt_decoder_create( celt_mode ) );
#endif
#endif
#endif
#endif
} 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);
}

/* 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);
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);
break;
}
@@ -174,43 +170,39 @@ alloc_ports (int n_capture_audio, int n_playback_audio, int n_capture_midi, int
/* Allocate audio playback channels */
port_flags = JackPortIsInput;
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);
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);
break;
}
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 );
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 );
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 );
playback_srcs = jack_slist_append(playback_srcs, celt_encoder_create( celt_mode ) );
#endif
#endif
#endif
#endif
} else {
#if HAVE_SAMPLERATE
#if HAVE_SAMPLERATE
playback_srcs = jack_slist_append (playback_srcs, src_new (SRC_LINEAR, 1, NULL));
#endif
#endif
}
playback_ports = jack_slist_append (playback_ports, port);
}

/* 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);
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);
break;
}
@@ -237,8 +229,7 @@ sync_cb (jack_transport_state_t state, jack_position_t *pos, void *arg)
retval = 0;
}

else if (state == JackTransportStarting && last_transport_state != JackTransportStarting)
{
else if (state == JackTransportStarting && last_transport_state != JackTransportStarting) {
retval = 0;
latency_count = latency - 1;
}
@@ -250,10 +241,10 @@ sync_cb (jack_transport_state_t state, jack_position_t *pos, void *arg)
void
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.
* 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;

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
net_period = (float) nframes / (float) factor;

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

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;

// 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.
while(1) {
jack_nframes_t got_frame;
if ( ! netjack_poll_deadline( input_fd, deadline ) )
break;
break;

packet_cache_drain_socket(packcache, input_fd);

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 {
// 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 );
/* First alternative : we received what we expected. Render the data
* 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;
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);
@@ -389,13 +377,12 @@ process (jack_nframes_t nframes, void *arg)
deadline_goodness = recv_time_offset - (int)pkthdr_rx->latency;
//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);
cont_miss = 0;
}
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_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
* as big as expected or we missed a packet. We render silence
* to the ouput ports */
else
{
else {
jack_nframes_t latency_estimate;
if( packet_cache_find_latency( packcache, framecnt, &latency_estimate ) )
//if( (state_latency == 0) || (latency_estimate < state_latency) )
@@ -423,8 +409,7 @@ process (jack_nframes_t nframes, void *arg)
cont_miss += 1;
chn = 0;
node = capture_ports;
while (node != NULL)
{
while (node != NULL) {
port = (jack_port_t *) node->data;
buf = jack_port_get_buffer (port, nframes);
porttype = jack_port_type (port);
@@ -438,47 +423,45 @@ process (jack_nframes_t nframes, void *arg)
}
}
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++;
@@ -502,20 +485,18 @@ init_sockaddr_in (struct sockaddr_in *name , const char *hostname , uint16_t por
{
name->sin_family = AF_INET ;
name->sin_port = htons (port);
if (hostname)
{
if (hostname) {
struct hostent *hostinfo = gethostbyname (hostname);
if (hostinfo == NULL) {
fprintf (stderr, "init_sockaddr_in: unknown host: %s.\n", hostname);
fflush( stderr );
}
fflush( stderr );
}
#ifdef WIN32
name->sin_addr.s_addr = inet_addr( hostname );
#else
name->sin_addr = *(struct in_addr *) hostinfo->h_addr ;
#endif
}
else
} else
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
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
sigterm_handler( int signal )
{
quit = 1;
quit = 1;
}

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

if (argc < 3)
{
if (argc < 3) {
printUsage ();
return 1;
}
@@ -583,17 +563,15 @@ main (int argc, char *argv[])
sprintf(client_name, "netjack");
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':
printUsage();
exit (0);
break;
case 'H':
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);
break;
case 'o':
@@ -647,11 +625,11 @@ main (int argc, char *argv[])
break;
case 'N':
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);
break;
case 's':
server_name = (char *) malloc (sizeof (char) * strlen (optarg)+1);
server_name = (char *) malloc (sizeof (char) * strlen (optarg) + 1);
strcpy (server_name, optarg);
options |= JackServerName;
break;
@@ -664,8 +642,7 @@ main (int argc, char *argv[])
errflg++;
}
}
if (errflg)
{
if (errflg) {
printUsage ();
exit (2);
}
@@ -688,8 +665,7 @@ main (int argc, char *argv[])
fprintf (stderr, "bind failure\n" );
}
}
if (reply_port)
{
if (reply_port) {
init_sockaddr_in ((struct sockaddr_in *) &bindaddr, NULL, reply_port);
if( bind (insockfd, &bindaddr, sizeof (bindaddr)) ) {
fprintf (stderr, "bind failure\n" );
@@ -698,10 +674,9 @@ main (int argc, char *argv[])

/* try to become a client of the JACK server */
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"
"Is the JACK server running ?\n", status);
"Is the JACK server running ?\n", status);
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);

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

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

while ( !quit )
{
while ( !quit ) {
#ifdef WIN32
Sleep (1000);
#else
sleep(1);
#endif
if (statecopy_connected != state_connected)
{
if (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
printf ("Connected :-)\n");
}
else
} else
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 "JackError.h"
#include "JackTime.h"
#include <assert.h>
#include <stdio.h>

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

JackWinThread::JackWinThread(JackRunnableInterface* runnable)
: JackThreadInterface(runnable, 0, false, 0)
: JackMMCSS(), JackThreadInterface(runnable, 0, false, 0)
{
fEvent = CreateEvent(NULL, FALSE, FALSE, 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);

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;
} 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)
{
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;
} else {
jack_error("Cannot set thread priority = %d", GetLastError());


+ 2
- 3
windows/JackWinThread.h View File

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

*/



#ifndef __JackWinThread__
#define __JackWinThread__

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

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

private:


+ 2
- 2
windows/jackd.workspace View File

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


+ 11
- 10
windows/libjack.cbp View File

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


+ 7
- 6
windows/libjacknet.cbp View File

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


+ 1
- 0
windows/libjackserver.cbp View File

@@ -289,6 +289,7 @@
<Unit filename="..\common\shm.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="JackMMCSS.cpp" />
<Unit filename="JackNetWinSocket.cpp" />
<Unit filename="JackWinNamedPipe.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->fOutputBuffer = (jack_default_audio_sample_t**)outputBuffer;

MMCSSAcquireRealTime(GetCurrentThread());

if (statusFlags) {
if (statusFlags & 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 "JackPortAudioDevices.h"
#include "JackMMCSS.h"

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

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

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

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)
{
fPaDevices = pa_devices;


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

@@ -60,7 +60,7 @@ JackWinMMEDriver::Attach()
// Inputs
for (int i = 0; i < fCaptureChannels; i++) {
JackWinMMEInputPort *input_port = input_ports[i];
name = input_port->GetName();
name = input_port->GetName();
if (fEngine->PortRegister(fClientControl.fRefNum, name,
JACK_DEFAULT_MIDI_TYPE,
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 "JackTime.h"
#include "JackWinMMEOutputPort.h"
#include "JackWinMMEOutputPort.h"
#include "JackGlobals.h"
#include "JackEngineControl.h"

using Jack::JackWinMMEOutputPort;

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

JackWinMMEOutputPort::JackWinMMEOutputPort(const char *alias_name,
const char *client_name,
const char *driver_name, UINT index,
const char *driver_name,
UINT index,
size_t max_bytes,
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);
read_queue_ptr.release();
thread_queue_ptr.release();
thread_ptr.release();
thread_ptr.release();
return;

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


Loading…
Cancel
Save