|
|
|
@@ -54,36 +54,36 @@ namespace Jack |
|
|
|
{ |
|
|
|
jack_log ( "JackNetOneDriver::JackNetOneDriver port %d", port ); |
|
|
|
|
|
|
|
#ifdef WIN32 |
|
|
|
WSADATA wsa; |
|
|
|
int rc = WSAStartup(MAKEWORD(2,0),&wsa); |
|
|
|
#endif |
|
|
|
|
|
|
|
netjack_init( & (this->netj), |
|
|
|
NULL, // client |
|
|
|
name, |
|
|
|
capture_ports, |
|
|
|
playback_ports, |
|
|
|
midi_input_ports, |
|
|
|
midi_output_ports, |
|
|
|
sample_rate, |
|
|
|
period_size, |
|
|
|
port, |
|
|
|
transport_sync, |
|
|
|
resample_factor, |
|
|
|
0, |
|
|
|
bitdepth, |
|
|
|
use_autoconfig, |
|
|
|
latency, |
|
|
|
redundancy, |
|
|
|
dont_htonl_floats, |
|
|
|
always_deadline, |
|
|
|
jitter_val); |
|
|
|
#ifdef WIN32 |
|
|
|
WSADATA wsa; |
|
|
|
int rc = WSAStartup(MAKEWORD(2,0),&wsa); |
|
|
|
#endif |
|
|
|
|
|
|
|
netjack_init( & (this->netj), |
|
|
|
NULL, // client |
|
|
|
name, |
|
|
|
capture_ports, |
|
|
|
playback_ports, |
|
|
|
midi_input_ports, |
|
|
|
midi_output_ports, |
|
|
|
sample_rate, |
|
|
|
period_size, |
|
|
|
port, |
|
|
|
transport_sync, |
|
|
|
resample_factor, |
|
|
|
0, |
|
|
|
bitdepth, |
|
|
|
use_autoconfig, |
|
|
|
latency, |
|
|
|
redundancy, |
|
|
|
dont_htonl_floats, |
|
|
|
always_deadline, |
|
|
|
jitter_val); |
|
|
|
} |
|
|
|
|
|
|
|
JackNetOneDriver::~JackNetOneDriver() |
|
|
|
{ |
|
|
|
// No destructor yet. |
|
|
|
// No destructor yet. |
|
|
|
} |
|
|
|
|
|
|
|
//open, close, attach and detach------------------------------------------------------ |
|
|
|
@@ -135,49 +135,49 @@ namespace Jack |
|
|
|
|
|
|
|
int JackNetOneDriver::AllocPorts() |
|
|
|
{ |
|
|
|
jack_port_id_t port_id; |
|
|
|
char buf[64]; |
|
|
|
unsigned int chn; |
|
|
|
jack_port_id_t port_id; |
|
|
|
char buf[64]; |
|
|
|
unsigned int chn; |
|
|
|
|
|
|
|
//if (netj.handle_transport_sync) |
|
|
|
// jack_set_sync_callback(netj.client, (JackSyncCallback) net_driver_sync_cb, NULL); |
|
|
|
//if (netj.handle_transport_sync) |
|
|
|
// jack_set_sync_callback(netj.client, (JackSyncCallback) net_driver_sync_cb, NULL); |
|
|
|
|
|
|
|
for (chn = 0; chn < netj.capture_channels_audio; chn++) { |
|
|
|
snprintf (buf, sizeof(buf) - 1, "system:capture_%u", chn + 1); |
|
|
|
for (chn = 0; chn < netj.capture_channels_audio; chn++) { |
|
|
|
snprintf (buf, sizeof(buf) - 1, "system:capture_%u", chn + 1); |
|
|
|
|
|
|
|
if ( ( port_id = fGraphManager->AllocatePort ( fClientControl.fRefNum, buf, JACK_DEFAULT_AUDIO_TYPE, |
|
|
|
CaptureDriverFlags, fEngineControl->fBufferSize ) ) == NO_PORT ) |
|
|
|
{ |
|
|
|
jack_error ( "driver: cannot register port for %s", buf ); |
|
|
|
return -1; |
|
|
|
if ( ( port_id = fGraphManager->AllocatePort ( fClientControl.fRefNum, buf, JACK_DEFAULT_AUDIO_TYPE, |
|
|
|
CaptureDriverFlags, fEngineControl->fBufferSize ) ) == NO_PORT ) |
|
|
|
{ |
|
|
|
jack_error ( "driver: cannot register port for %s", buf ); |
|
|
|
return -1; |
|
|
|
} |
|
|
|
//port = fGraphManager->GetPort ( port_id ); |
|
|
|
|
|
|
|
netj.capture_ports = |
|
|
|
jack_slist_append (netj.capture_ports, (void *)(intptr_t)port_id); |
|
|
|
|
|
|
|
if( netj.bitdepth == CELT_MODE ) { |
|
|
|
#if HAVE_CELT |
|
|
|
#if HAVE_CELT_API_0_7 |
|
|
|
celt_int32 lookahead; |
|
|
|
CELTMode *celt_mode = celt_mode_create( netj.sample_rate, netj.period_size, NULL ); |
|
|
|
netj.capture_srcs = jack_slist_append(netj.capture_srcs, celt_decoder_create( celt_mode, 1, NULL ) ); |
|
|
|
#else |
|
|
|
celt_int32_t lookahead; |
|
|
|
CELTMode *celt_mode = celt_mode_create( netj.sample_rate, 1, netj.period_size, NULL ); |
|
|
|
netj.capture_srcs = jack_slist_append(netj.capture_srcs, celt_decoder_create( celt_mode ) ); |
|
|
|
#endif |
|
|
|
celt_mode_info( celt_mode, CELT_GET_LOOKAHEAD, &lookahead ); |
|
|
|
netj.codec_latency = 2*lookahead; |
|
|
|
#endif |
|
|
|
} else { |
|
|
|
#if HAVE_SAMPLERATE |
|
|
|
netj.capture_srcs = jack_slist_append(netj.capture_srcs, (void *)src_new(SRC_LINEAR, 1, NULL)); |
|
|
|
#endif |
|
|
|
} |
|
|
|
//port = fGraphManager->GetPort ( port_id ); |
|
|
|
|
|
|
|
netj.capture_ports = |
|
|
|
jack_slist_append (netj.capture_ports, (void *)(intptr_t)port_id); |
|
|
|
|
|
|
|
if( netj.bitdepth == CELT_MODE ) { |
|
|
|
#if HAVE_CELT |
|
|
|
#if HAVE_CELT_API_0_7 |
|
|
|
celt_int32 lookahead; |
|
|
|
CELTMode *celt_mode = celt_mode_create( netj.sample_rate, netj.period_size, NULL ); |
|
|
|
netj.capture_srcs = jack_slist_append(netj.capture_srcs, celt_decoder_create( celt_mode, 1, NULL ) ); |
|
|
|
#else |
|
|
|
celt_int32_t lookahead; |
|
|
|
CELTMode *celt_mode = celt_mode_create( netj.sample_rate, 1, netj.period_size, NULL ); |
|
|
|
netj.capture_srcs = jack_slist_append(netj.capture_srcs, celt_decoder_create( celt_mode ) ); |
|
|
|
#endif |
|
|
|
celt_mode_info( celt_mode, CELT_GET_LOOKAHEAD, &lookahead ); |
|
|
|
netj.codec_latency = 2*lookahead; |
|
|
|
#endif |
|
|
|
} else { |
|
|
|
#if HAVE_SAMPLERATE |
|
|
|
netj.capture_srcs = jack_slist_append(netj.capture_srcs, (void *)src_new(SRC_LINEAR, 1, NULL)); |
|
|
|
#endif |
|
|
|
} |
|
|
|
} |
|
|
|
for (chn = netj.capture_channels_audio; chn < netj.capture_channels; chn++) { |
|
|
|
snprintf (buf, sizeof(buf) - 1, "system:capture_%u", chn + 1); |
|
|
|
} |
|
|
|
for (chn = netj.capture_channels_audio; chn < netj.capture_channels; chn++) { |
|
|
|
snprintf (buf, sizeof(buf) - 1, "system:capture_%u", chn + 1); |
|
|
|
|
|
|
|
if ( ( port_id = fGraphManager->AllocatePort ( fClientControl.fRefNum, buf, JACK_DEFAULT_MIDI_TYPE, |
|
|
|
CaptureDriverFlags, fEngineControl->fBufferSize ) ) == NO_PORT ) |
|
|
|
@@ -187,12 +187,12 @@ namespace Jack |
|
|
|
} |
|
|
|
//port = fGraphManager->GetPort ( port_id ); |
|
|
|
|
|
|
|
netj.capture_ports = |
|
|
|
jack_slist_append (netj.capture_ports, (void *)(intptr_t)port_id); |
|
|
|
} |
|
|
|
netj.capture_ports = |
|
|
|
jack_slist_append (netj.capture_ports, (void *)(intptr_t)port_id); |
|
|
|
} |
|
|
|
|
|
|
|
for (chn = 0; chn < netj.playback_channels_audio; chn++) { |
|
|
|
snprintf (buf, sizeof(buf) - 1, "system:playback_%u", chn + 1); |
|
|
|
for (chn = 0; chn < netj.playback_channels_audio; chn++) { |
|
|
|
snprintf (buf, sizeof(buf) - 1, "system:playback_%u", chn + 1); |
|
|
|
|
|
|
|
if ( ( port_id = fGraphManager->AllocatePort ( fClientControl.fRefNum, buf, JACK_DEFAULT_AUDIO_TYPE, |
|
|
|
PlaybackDriverFlags, fEngineControl->fBufferSize ) ) == NO_PORT ) |
|
|
|
@@ -202,27 +202,27 @@ namespace Jack |
|
|
|
} |
|
|
|
//port = fGraphManager->GetPort ( port_id ); |
|
|
|
|
|
|
|
netj.playback_ports = |
|
|
|
jack_slist_append (netj.playback_ports, (void *)(intptr_t)port_id); |
|
|
|
|
|
|
|
if( netj.bitdepth == CELT_MODE ) { |
|
|
|
#if HAVE_CELT |
|
|
|
#if HAVE_CELT_API_0_7 |
|
|
|
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 ) ); |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
} else { |
|
|
|
#if HAVE_SAMPLERATE |
|
|
|
netj.playback_srcs = jack_slist_append(netj.playback_srcs, (void *)src_new(SRC_LINEAR, 1, NULL)); |
|
|
|
#endif |
|
|
|
} |
|
|
|
} |
|
|
|
for (chn = netj.playback_channels_audio; chn < netj.playback_channels; chn++) { |
|
|
|
snprintf (buf, sizeof(buf) - 1, "system:playback_%u", chn + 1); |
|
|
|
netj.playback_ports = |
|
|
|
jack_slist_append (netj.playback_ports, (void *)(intptr_t)port_id); |
|
|
|
|
|
|
|
if( netj.bitdepth == CELT_MODE ) { |
|
|
|
#if HAVE_CELT |
|
|
|
#if HAVE_CELT_API_0_7 |
|
|
|
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 ) ); |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
} else { |
|
|
|
#if HAVE_SAMPLERATE |
|
|
|
netj.playback_srcs = jack_slist_append(netj.playback_srcs, (void *)src_new(SRC_LINEAR, 1, NULL)); |
|
|
|
#endif |
|
|
|
} |
|
|
|
} |
|
|
|
for (chn = netj.playback_channels_audio; chn < netj.playback_channels; chn++) { |
|
|
|
snprintf (buf, sizeof(buf) - 1, "system:playback_%u", chn + 1); |
|
|
|
|
|
|
|
if ( ( port_id = fGraphManager->AllocatePort ( fClientControl.fRefNum, buf, JACK_DEFAULT_MIDI_TYPE, |
|
|
|
PlaybackDriverFlags, fEngineControl->fBufferSize ) ) == NO_PORT ) |
|
|
|
@@ -232,10 +232,10 @@ namespace Jack |
|
|
|
} |
|
|
|
//port = fGraphManager->GetPort ( port_id ); |
|
|
|
|
|
|
|
netj.playback_ports = |
|
|
|
jack_slist_append (netj.playback_ports, (void *)(intptr_t)port_id); |
|
|
|
} |
|
|
|
return 0; |
|
|
|
netj.playback_ports = |
|
|
|
jack_slist_append (netj.playback_ports, (void *)(intptr_t)port_id); |
|
|
|
} |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
//init and restart-------------------------------------------------------------------- |
|
|
|
@@ -243,16 +243,16 @@ namespace Jack |
|
|
|
{ |
|
|
|
jack_log ( "JackNetOneDriver::Init()" ); |
|
|
|
|
|
|
|
if( global_packcache != NULL ) { |
|
|
|
FreePorts(); |
|
|
|
netjack_release( &netj ); |
|
|
|
} |
|
|
|
if( global_packcache != NULL ) { |
|
|
|
FreePorts(); |
|
|
|
netjack_release( &netj ); |
|
|
|
} |
|
|
|
|
|
|
|
//display some additional infos |
|
|
|
jack_info ( "NetOne driver started" ); |
|
|
|
if( netjack_startup( &netj ) ) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
if( netjack_startup( &netj ) ) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
//register jack ports |
|
|
|
if ( AllocPorts() != 0 ) |
|
|
|
@@ -261,7 +261,6 @@ namespace Jack |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//monitor |
|
|
|
//driver parametering |
|
|
|
JackAudioDriver::SetBufferSize ( netj.period_size ); |
|
|
|
@@ -281,161 +280,160 @@ namespace Jack |
|
|
|
//driver processes-------------------------------------------------------------------- |
|
|
|
int JackNetOneDriver::Read() |
|
|
|
{ |
|
|
|
int delay; |
|
|
|
delay = netjack_wait( &netj ); |
|
|
|
if( delay ) { |
|
|
|
NotifyXRun(fBeginDateUst, (float) delay); |
|
|
|
jack_error( "netxruns... duration: %dms", delay/1000 ); |
|
|
|
} |
|
|
|
int delay; |
|
|
|
delay = netjack_wait( &netj ); |
|
|
|
if( delay ) { |
|
|
|
NotifyXRun(fBeginDateUst, (float) delay); |
|
|
|
jack_error( "netxruns... duration: %dms", delay/1000 ); |
|
|
|
} |
|
|
|
|
|
|
|
if( (netj.num_lost_packets * netj.period_size / netj.sample_rate) > 2 ) |
|
|
|
JackTools::ThrowJackNetException(); |
|
|
|
if( (netj.num_lost_packets * netj.period_size / netj.sample_rate) > 2 ) |
|
|
|
JackTools::ThrowJackNetException(); |
|
|
|
|
|
|
|
//netjack_read( &netj, netj.period_size ); |
|
|
|
//netjack_read( &netj, netj.period_size ); |
|
|
|
JackDriver::CycleTakeBeginTime(); |
|
|
|
|
|
|
|
jack_position_t local_trans_pos; |
|
|
|
jack_transport_state_t local_trans_state; |
|
|
|
jack_position_t local_trans_pos; |
|
|
|
jack_transport_state_t local_trans_state; |
|
|
|
|
|
|
|
unsigned int *packet_buf, *packet_bufX; |
|
|
|
unsigned int *packet_buf, *packet_bufX; |
|
|
|
|
|
|
|
if( ! netj.packet_data_valid ) { |
|
|
|
if( ! netj.packet_data_valid ) { |
|
|
|
jack_log( "data not valid" ); |
|
|
|
render_payload_to_jack_ports (netj.bitdepth, NULL, netj.net_period_down, netj.capture_ports, netj.capture_srcs, netj.period_size, netj.dont_htonl_floats ); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
packet_buf = netj.rx_buf; |
|
|
|
render_payload_to_jack_ports (netj.bitdepth, NULL, netj.net_period_down, netj.capture_ports, netj.capture_srcs, netj.period_size, netj.dont_htonl_floats ); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
packet_buf = netj.rx_buf; |
|
|
|
|
|
|
|
jacknet_packet_header *pkthdr = (jacknet_packet_header *)packet_buf; |
|
|
|
jacknet_packet_header *pkthdr = (jacknet_packet_header *)packet_buf; |
|
|
|
|
|
|
|
packet_bufX = packet_buf + sizeof(jacknet_packet_header) / sizeof(jack_default_audio_sample_t); |
|
|
|
packet_bufX = packet_buf + sizeof(jacknet_packet_header) / sizeof(jack_default_audio_sample_t); |
|
|
|
|
|
|
|
netj.reply_port = pkthdr->reply_port; |
|
|
|
netj.latency = pkthdr->latency; |
|
|
|
netj.reply_port = pkthdr->reply_port; |
|
|
|
netj.latency = pkthdr->latency; |
|
|
|
|
|
|
|
// Special handling for latency=0 |
|
|
|
if( netj.latency == 0 ) |
|
|
|
netj.resync_threshold = 0; |
|
|
|
else |
|
|
|
netj.resync_threshold = MIN( 15, pkthdr->latency-1 ); |
|
|
|
// Special handling for latency=0 |
|
|
|
if( netj.latency == 0 ) |
|
|
|
netj.resync_threshold = 0; |
|
|
|
else |
|
|
|
netj.resync_threshold = MIN( 15, pkthdr->latency-1 ); |
|
|
|
|
|
|
|
// check whether, we should handle the transport sync stuff, or leave trnasports untouched. |
|
|
|
if (netj.handle_transport_sync) { |
|
|
|
#if 1 |
|
|
|
unsigned int compensated_tranport_pos = (pkthdr->transport_frame + (pkthdr->latency * netj.period_size) + netj.codec_latency); |
|
|
|
// check whether, we should handle the transport sync stuff, or leave trnasports untouched. |
|
|
|
if (netj.handle_transport_sync) { |
|
|
|
#if 1 |
|
|
|
unsigned int compensated_tranport_pos = (pkthdr->transport_frame + (pkthdr->latency * netj.period_size) + netj.codec_latency); |
|
|
|
|
|
|
|
// read local transport info.... |
|
|
|
//local_trans_state = jack_transport_query(netj.client, &local_trans_pos); |
|
|
|
// read local transport info.... |
|
|
|
//local_trans_state = jack_transport_query(netj.client, &local_trans_pos); |
|
|
|
|
|
|
|
local_trans_state = fEngineControl->fTransport.Query ( &local_trans_pos ); |
|
|
|
|
|
|
|
// Now check if we have to start or stop local transport to sync to remote... |
|
|
|
switch (pkthdr->transport_state) { |
|
|
|
case JackTransportStarting: |
|
|
|
// the master transport is starting... so we set our reply to the sync_callback; |
|
|
|
if (local_trans_state == JackTransportStopped) { |
|
|
|
fEngineControl->fTransport.SetCommand ( TransportCommandStart ); |
|
|
|
//jack_transport_start(netj.client); |
|
|
|
//last_transport_state = JackTransportStopped; |
|
|
|
netj.sync_state = 0; |
|
|
|
jack_info("locally stopped... starting..."); |
|
|
|
} |
|
|
|
|
|
|
|
if (local_trans_pos.frame != compensated_tranport_pos) |
|
|
|
{ |
|
|
|
jack_position_t new_pos = local_trans_pos; |
|
|
|
new_pos.frame = compensated_tranport_pos + 2*netj.period_size; |
|
|
|
new_pos.valid = (jack_position_bits_t) 0; |
|
|
|
|
|
|
|
|
|
|
|
fEngineControl->fTransport.RequestNewPos ( &new_pos ); |
|
|
|
//jack_transport_locate(netj.client, compensated_tranport_pos); |
|
|
|
//last_transport_state = JackTransportRolling; |
|
|
|
netj.sync_state = 0; |
|
|
|
jack_info("starting locate to %d", compensated_tranport_pos ); |
|
|
|
} |
|
|
|
break; |
|
|
|
case JackTransportStopped: |
|
|
|
netj.sync_state = 1; |
|
|
|
if (local_trans_pos.frame != (pkthdr->transport_frame)) { |
|
|
|
jack_position_t new_pos = local_trans_pos; |
|
|
|
new_pos.frame = pkthdr->transport_frame; |
|
|
|
new_pos.valid = (jack_position_bits_t)0; |
|
|
|
fEngineControl->fTransport.RequestNewPos ( &new_pos ); |
|
|
|
//jack_transport_locate(netj.client, (pkthdr->transport_frame)); |
|
|
|
jack_info("transport is stopped locate to %d", pkthdr->transport_frame); |
|
|
|
} |
|
|
|
if (local_trans_state != JackTransportStopped) |
|
|
|
//jack_transport_stop(netj.client); |
|
|
|
fEngineControl->fTransport.SetCommand ( TransportCommandStop ); |
|
|
|
break; |
|
|
|
case JackTransportRolling: |
|
|
|
netj.sync_state = 1; |
|
|
|
// if(local_trans_pos.frame != (pkthdr->transport_frame + (pkthdr->latency) * netj.period_size)) { |
|
|
|
// jack_transport_locate(netj.client, (pkthdr->transport_frame + (pkthdr->latency + 2) * netj.period_size)); |
|
|
|
// jack_info("running locate to %d", pkthdr->transport_frame + (pkthdr->latency)*netj.period_size); |
|
|
|
// } |
|
|
|
if (local_trans_state != JackTransportRolling) |
|
|
|
fEngineControl->fTransport.SetState ( JackTransportRolling ); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case JackTransportLooping: |
|
|
|
break; |
|
|
|
} |
|
|
|
// Now check if we have to start or stop local transport to sync to remote... |
|
|
|
switch (pkthdr->transport_state) { |
|
|
|
case JackTransportStarting: |
|
|
|
// the master transport is starting... so we set our reply to the sync_callback; |
|
|
|
if (local_trans_state == JackTransportStopped) { |
|
|
|
fEngineControl->fTransport.SetCommand ( TransportCommandStart ); |
|
|
|
//jack_transport_start(netj.client); |
|
|
|
//last_transport_state = JackTransportStopped; |
|
|
|
netj.sync_state = 0; |
|
|
|
jack_info("locally stopped... starting..."); |
|
|
|
} |
|
|
|
|
|
|
|
if (local_trans_pos.frame != compensated_tranport_pos) |
|
|
|
{ |
|
|
|
jack_position_t new_pos = local_trans_pos; |
|
|
|
new_pos.frame = compensated_tranport_pos + 2*netj.period_size; |
|
|
|
new_pos.valid = (jack_position_bits_t) 0; |
|
|
|
|
|
|
|
|
|
|
|
fEngineControl->fTransport.RequestNewPos ( &new_pos ); |
|
|
|
//jack_transport_locate(netj.client, compensated_tranport_pos); |
|
|
|
//last_transport_state = JackTransportRolling; |
|
|
|
netj.sync_state = 0; |
|
|
|
jack_info("starting locate to %d", compensated_tranport_pos ); |
|
|
|
} |
|
|
|
break; |
|
|
|
case JackTransportStopped: |
|
|
|
netj.sync_state = 1; |
|
|
|
if (local_trans_pos.frame != (pkthdr->transport_frame)) { |
|
|
|
jack_position_t new_pos = local_trans_pos; |
|
|
|
new_pos.frame = pkthdr->transport_frame; |
|
|
|
new_pos.valid = (jack_position_bits_t)0; |
|
|
|
fEngineControl->fTransport.RequestNewPos ( &new_pos ); |
|
|
|
//jack_transport_locate(netj.client, (pkthdr->transport_frame)); |
|
|
|
jack_info("transport is stopped locate to %d", pkthdr->transport_frame); |
|
|
|
} |
|
|
|
if (local_trans_state != JackTransportStopped) |
|
|
|
//jack_transport_stop(netj.client); |
|
|
|
fEngineControl->fTransport.SetCommand ( TransportCommandStop ); |
|
|
|
break; |
|
|
|
case JackTransportRolling: |
|
|
|
netj.sync_state = 1; |
|
|
|
// if(local_trans_pos.frame != (pkthdr->transport_frame + (pkthdr->latency) * netj.period_size)) { |
|
|
|
// jack_transport_locate(netj.client, (pkthdr->transport_frame + (pkthdr->latency + 2) * netj.period_size)); |
|
|
|
// jack_info("running locate to %d", pkthdr->transport_frame + (pkthdr->latency)*netj.period_size); |
|
|
|
// } |
|
|
|
if (local_trans_state != JackTransportRolling) |
|
|
|
fEngineControl->fTransport.SetState ( JackTransportRolling ); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case JackTransportLooping: |
|
|
|
break; |
|
|
|
} |
|
|
|
#endif |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
render_payload_to_jack_ports (netj.bitdepth, packet_bufX, netj.net_period_down, netj.capture_ports, netj.capture_srcs, netj.period_size, netj.dont_htonl_floats ); |
|
|
|
packet_cache_release_packet(global_packcache, netj.expected_framecnt ); |
|
|
|
return 0; |
|
|
|
render_payload_to_jack_ports (netj.bitdepth, packet_bufX, netj.net_period_down, netj.capture_ports, netj.capture_srcs, netj.period_size, netj.dont_htonl_floats ); |
|
|
|
packet_cache_release_packet(global_packcache, netj.expected_framecnt ); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
int JackNetOneDriver::Write() |
|
|
|
{ |
|
|
|
int syncstate = netj.sync_state | ((fEngineControl->fTransport.GetState() == JackTransportNetStarting) ? 1 : 0 ); |
|
|
|
uint32_t *packet_buf, *packet_bufX; |
|
|
|
|
|
|
|
int packet_size = get_sample_size(netj.bitdepth) * netj.playback_channels * netj.net_period_up + sizeof(jacknet_packet_header); |
|
|
|
jacknet_packet_header *pkthdr; |
|
|
|
int syncstate = netj.sync_state | ((fEngineControl->fTransport.GetState() == JackTransportNetStarting) ? 1 : 0 ); |
|
|
|
uint32_t *packet_buf, *packet_bufX; |
|
|
|
|
|
|
|
packet_buf = (uint32_t *) alloca(packet_size); |
|
|
|
pkthdr = (jacknet_packet_header *)packet_buf; |
|
|
|
int packet_size = get_sample_size(netj.bitdepth) * netj.playback_channels * netj.net_period_up + sizeof(jacknet_packet_header); |
|
|
|
jacknet_packet_header *pkthdr; |
|
|
|
|
|
|
|
if( netj.running_free ) { |
|
|
|
return 0; |
|
|
|
} |
|
|
|
packet_buf = (uint32_t *) alloca(packet_size); |
|
|
|
pkthdr = (jacknet_packet_header *)packet_buf; |
|
|
|
|
|
|
|
// offset packet_bufX by the packetheader. |
|
|
|
packet_bufX = packet_buf + sizeof(jacknet_packet_header) / sizeof(jack_default_audio_sample_t); |
|
|
|
if( netj.running_free ) { |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
pkthdr->sync_state = syncstate;; |
|
|
|
pkthdr->latency = netj.time_to_deadline; |
|
|
|
//printf( "time to deadline = %d goodness=%d\n", (int)netj.time_to_deadline, netj.deadline_goodness ); |
|
|
|
pkthdr->framecnt = netj.expected_framecnt; |
|
|
|
// offset packet_bufX by the packetheader. |
|
|
|
packet_bufX = packet_buf + sizeof(jacknet_packet_header) / sizeof(jack_default_audio_sample_t); |
|
|
|
|
|
|
|
pkthdr->sync_state = syncstate;; |
|
|
|
pkthdr->latency = netj.time_to_deadline; |
|
|
|
//printf( "time to deadline = %d goodness=%d\n", (int)netj.time_to_deadline, netj.deadline_goodness ); |
|
|
|
pkthdr->framecnt = netj.expected_framecnt; |
|
|
|
|
|
|
|
render_jack_ports_to_payload(netj.bitdepth, netj.playback_ports, netj.playback_srcs, netj.period_size, packet_bufX, netj.net_period_up, netj.dont_htonl_floats ); |
|
|
|
render_jack_ports_to_payload(netj.bitdepth, netj.playback_ports, netj.playback_srcs, netj.period_size, packet_bufX, netj.net_period_up, netj.dont_htonl_floats ); |
|
|
|
|
|
|
|
packet_header_hton(pkthdr); |
|
|
|
if (netj.srcaddress_valid) |
|
|
|
{ |
|
|
|
unsigned int r; |
|
|
|
packet_header_hton(pkthdr); |
|
|
|
if (netj.srcaddress_valid) |
|
|
|
{ |
|
|
|
unsigned int r; |
|
|
|
|
|
|
|
#ifdef __APPLE__ |
|
|
|
static const int flag = 0; |
|
|
|
#else |
|
|
|
static const int flag = 0; |
|
|
|
#endif |
|
|
|
#ifdef __APPLE__ |
|
|
|
static const int flag = 0; |
|
|
|
#else |
|
|
|
static const int flag = 0; |
|
|
|
#endif |
|
|
|
|
|
|
|
if (netj.reply_port) |
|
|
|
netj.syncsource_address.sin_port = htons(netj.reply_port); |
|
|
|
if (netj.reply_port) |
|
|
|
netj.syncsource_address.sin_port = htons(netj.reply_port); |
|
|
|
|
|
|
|
for( r=0; r<netj.redundancy; r++ ) |
|
|
|
netjack_sendto(netj.sockfd, (char *)packet_buf, packet_size, |
|
|
|
flag, (struct sockaddr*)&(netj.syncsource_address), sizeof(struct sockaddr_in), netj.mtu); |
|
|
|
} |
|
|
|
return 0; |
|
|
|
for( r=0; r<netj.redundancy; r++ ) |
|
|
|
netjack_sendto(netj.sockfd, (char *)packet_buf, packet_size, |
|
|
|
flag, (struct sockaddr*)&(netj.syncsource_address), sizeof(struct sockaddr_in), netj.mtu); |
|
|
|
} |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
void |
|
|
|
@@ -444,21 +442,21 @@ JackNetOneDriver::FreePorts () |
|
|
|
JSList *node = netj.capture_ports; |
|
|
|
|
|
|
|
while( node != NULL ) { |
|
|
|
JSList *this_node = node; |
|
|
|
jack_port_id_t port_id = (jack_port_id_t)(intptr_t) node->data; |
|
|
|
node = jack_slist_remove_link( node, this_node ); |
|
|
|
jack_slist_free_1( this_node ); |
|
|
|
fGraphManager->ReleasePort( fClientControl.fRefNum, port_id ); |
|
|
|
JSList *this_node = node; |
|
|
|
jack_port_id_t port_id = (jack_port_id_t)(intptr_t) node->data; |
|
|
|
node = jack_slist_remove_link( node, this_node ); |
|
|
|
jack_slist_free_1( this_node ); |
|
|
|
fGraphManager->ReleasePort( fClientControl.fRefNum, port_id ); |
|
|
|
} |
|
|
|
netj.capture_ports = NULL; |
|
|
|
|
|
|
|
node = netj.playback_ports; |
|
|
|
while( node != NULL ) { |
|
|
|
JSList *this_node = node; |
|
|
|
jack_port_id_t port_id = (jack_port_id_t)(intptr_t) node->data; |
|
|
|
node = jack_slist_remove_link( node, this_node ); |
|
|
|
jack_slist_free_1( this_node ); |
|
|
|
fGraphManager->ReleasePort( fClientControl.fRefNum, port_id ); |
|
|
|
JSList *this_node = node; |
|
|
|
jack_port_id_t port_id = (jack_port_id_t)(intptr_t) node->data; |
|
|
|
node = jack_slist_remove_link( node, this_node ); |
|
|
|
jack_slist_free_1( this_node ); |
|
|
|
fGraphManager->ReleasePort( fClientControl.fRefNum, port_id ); |
|
|
|
} |
|
|
|
netj.playback_ports = NULL; |
|
|
|
|
|
|
|
@@ -523,7 +521,7 @@ JackNetOneDriver::render_payload_to_jack_ports_float ( void *packet_payload, jac |
|
|
|
uint32_t *packet_bufX = (uint32_t *)packet_payload; |
|
|
|
|
|
|
|
if( !packet_payload ) |
|
|
|
return; |
|
|
|
return; |
|
|
|
|
|
|
|
while (node != NULL) |
|
|
|
{ |
|
|
|
@@ -532,9 +530,8 @@ JackNetOneDriver::render_payload_to_jack_ports_float ( void *packet_payload, jac |
|
|
|
#if HAVE_SAMPLERATE |
|
|
|
SRC_DATA src; |
|
|
|
#endif |
|
|
|
|
|
|
|
jack_port_id_t port_id = (jack_port_id_t)(intptr_t) node->data; |
|
|
|
JackPort *port = fGraphManager->GetPort( port_id ); |
|
|
|
jack_port_id_t port_id = (jack_port_id_t)(intptr_t) node->data; |
|
|
|
JackPort *port = fGraphManager->GetPort( port_id ); |
|
|
|
|
|
|
|
jack_default_audio_sample_t* buf = |
|
|
|
(jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_id, fEngineControl->fBufferSize); |
|
|
|
@@ -569,19 +566,19 @@ JackNetOneDriver::render_payload_to_jack_ports_float ( void *packet_payload, jac |
|
|
|
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 (strncmp (porttype, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0) |
|
|
|
@@ -616,8 +613,8 @@ JackNetOneDriver::render_jack_ports_to_payload_float (JSList *playback_ports, JS |
|
|
|
#endif |
|
|
|
unsigned int i; |
|
|
|
int_float_t val; |
|
|
|
jack_port_id_t port_id = (jack_port_id_t)(intptr_t) node->data; |
|
|
|
JackPort *port = fGraphManager->GetPort( port_id ); |
|
|
|
jack_port_id_t port_id = (jack_port_id_t)(intptr_t) node->data; |
|
|
|
JackPort *port = fGraphManager->GetPort( port_id ); |
|
|
|
|
|
|
|
jack_default_audio_sample_t* buf = |
|
|
|
(jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_id, fEngineControl->fBufferSize); |
|
|
|
@@ -652,19 +649,19 @@ JackNetOneDriver::render_jack_ports_to_payload_float (JSList *playback_ports, JS |
|
|
|
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 (strncmp(porttype, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0) |
|
|
|
@@ -694,26 +691,24 @@ JackNetOneDriver::render_payload_to_jack_ports_celt (void *packet_payload, jack_ |
|
|
|
|
|
|
|
while (node != NULL) |
|
|
|
{ |
|
|
|
jack_port_id_t port_id = (jack_port_id_t) (intptr_t)node->data; |
|
|
|
JackPort *port = fGraphManager->GetPort( port_id ); |
|
|
|
jack_port_id_t port_id = (jack_port_id_t) (intptr_t)node->data; |
|
|
|
JackPort *port = fGraphManager->GetPort( port_id ); |
|
|
|
|
|
|
|
jack_default_audio_sample_t* buf = |
|
|
|
(jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_id, fEngineControl->fBufferSize); |
|
|
|
|
|
|
|
const char *portname = port->GetType(); |
|
|
|
|
|
|
|
|
|
|
|
if (strncmp(portname, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0) |
|
|
|
{ |
|
|
|
// audio port, decode celt data. |
|
|
|
CELTDecoder *decoder = (CELTDecoder *)src_node->data; |
|
|
|
if( !packet_payload ) |
|
|
|
celt_decode_float( decoder, NULL, net_period_down, buf ); |
|
|
|
else |
|
|
|
celt_decode_float( decoder, packet_bufX, net_period_down, buf ); |
|
|
|
|
|
|
|
CELTDecoder *decoder = (CELTDecoder *)src_node->data; |
|
|
|
if( !packet_payload ) |
|
|
|
celt_decode_float( decoder, NULL, net_period_down, buf ); |
|
|
|
else |
|
|
|
celt_decode_float( decoder, packet_bufX, net_period_down, buf ); |
|
|
|
|
|
|
|
src_node = jack_slist_next (src_node); |
|
|
|
src_node = jack_slist_next (src_node); |
|
|
|
} |
|
|
|
else if (strncmp(portname, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0) |
|
|
|
{ |
|
|
|
@@ -722,7 +717,7 @@ JackNetOneDriver::render_payload_to_jack_ports_celt (void *packet_payload, jack_ |
|
|
|
unsigned int buffer_size_uint32 = net_period_down / 2; |
|
|
|
uint32_t * buffer_uint32 = (uint32_t*) packet_bufX; |
|
|
|
if( packet_payload ) |
|
|
|
decode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); |
|
|
|
decode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); |
|
|
|
} |
|
|
|
packet_bufX = (packet_bufX + net_period_down); |
|
|
|
node = jack_slist_next (node); |
|
|
|
@@ -741,8 +736,8 @@ JackNetOneDriver::render_jack_ports_to_payload_celt (JSList *playback_ports, JSL |
|
|
|
|
|
|
|
while (node != NULL) |
|
|
|
{ |
|
|
|
jack_port_id_t port_id = (jack_port_id_t) (intptr_t) node->data; |
|
|
|
JackPort *port = fGraphManager->GetPort( port_id ); |
|
|
|
jack_port_id_t port_id = (jack_port_id_t) (intptr_t) node->data; |
|
|
|
JackPort *port = fGraphManager->GetPort( port_id ); |
|
|
|
|
|
|
|
jack_default_audio_sample_t* buf = |
|
|
|
(jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_id, fEngineControl->fBufferSize); |
|
|
|
@@ -800,8 +795,6 @@ JackNetOneDriver::render_jack_ports_to_payload (int bitdepth, JSList *playback_p |
|
|
|
render_jack_ports_to_payload_float (playback_ports, playback_srcs, nframes, packet_payload, net_period_up, dont_htonl_floats); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//driver loader----------------------------------------------------------------------- |
|
|
|
|
|
|
|
#ifdef __cplusplus |
|
|
|
@@ -982,28 +975,25 @@ JackNetOneDriver::render_jack_ports_to_payload (int bitdepth, JSList *playback_p |
|
|
|
|
|
|
|
SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize ( Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params ) |
|
|
|
{ |
|
|
|
jack_nframes_t sample_rate = 48000; |
|
|
|
jack_nframes_t resample_factor = 1; |
|
|
|
jack_nframes_t period_size = 1024; |
|
|
|
unsigned int capture_ports = 2; |
|
|
|
unsigned int playback_ports = 2; |
|
|
|
unsigned int capture_ports_midi = 1; |
|
|
|
unsigned int playback_ports_midi = 1; |
|
|
|
unsigned int listen_port = 3000; |
|
|
|
unsigned int resample_factor_up = 0; |
|
|
|
unsigned int bitdepth = 0; |
|
|
|
unsigned int handle_transport_sync = 1; |
|
|
|
unsigned int use_autoconfig = 1; |
|
|
|
unsigned int latency = 5; |
|
|
|
unsigned int redundancy = 1; |
|
|
|
unsigned int mtu = 1400; |
|
|
|
int dont_htonl_floats = 0; |
|
|
|
int always_deadline = 0; |
|
|
|
int jitter_val = 0; |
|
|
|
const JSList * node; |
|
|
|
const jack_driver_param_t * param; |
|
|
|
|
|
|
|
|
|
|
|
jack_nframes_t sample_rate = 48000; |
|
|
|
jack_nframes_t resample_factor = 1; |
|
|
|
jack_nframes_t period_size = 1024; |
|
|
|
unsigned int capture_ports = 2; |
|
|
|
unsigned int playback_ports = 2; |
|
|
|
unsigned int capture_ports_midi = 1; |
|
|
|
unsigned int playback_ports_midi = 1; |
|
|
|
unsigned int listen_port = 3000; |
|
|
|
unsigned int bitdepth = 0; |
|
|
|
unsigned int handle_transport_sync = 1; |
|
|
|
unsigned int use_autoconfig = 1; |
|
|
|
unsigned int latency = 5; |
|
|
|
unsigned int redundancy = 1; |
|
|
|
unsigned int mtu = 1400; |
|
|
|
int dont_htonl_floats = 0; |
|
|
|
int always_deadline = 0; |
|
|
|
int jitter_val = 0; |
|
|
|
const JSList * node; |
|
|
|
const jack_driver_param_t * param; |
|
|
|
|
|
|
|
for ( node = params; node; node = jack_slist_next ( node ) ) |
|
|
|
{ |
|
|
|
@@ -1102,7 +1092,6 @@ JackNetOneDriver::render_jack_ports_to_payload (int bitdepth, JSList *playback_p |
|
|
|
|
|
|
|
try |
|
|
|
{ |
|
|
|
|
|
|
|
Jack::JackDriverClientInterface* driver = |
|
|
|
new Jack::JackWaitThreadedDriver ( |
|
|
|
new Jack::JackNetOneDriver ( "system", "net_pcm", engine, table, listen_port, mtu, |
|
|
|
|