git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@2754 0c269be4-1314-0410-8aa9-9f06e86f4224tags/1.90
@@ -53,7 +53,8 @@ namespace Jack | |||||
#endif | #endif | ||||
JackNetDriver::JackNetDriver ( const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table, | JackNetDriver::JackNetDriver ( const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table, | ||||
const char* ip, int port, int mtu, int midi_input_ports, int midi_output_ports, const char* net_name, uint transport_sync ) | |||||
const char* ip, int port, int mtu, int midi_input_ports, int midi_output_ports, | |||||
const char* net_name, uint transport_sync, char network_master_mode, char network_slave_mode ) | |||||
: JackAudioDriver ( name, alias, engine, table ), fSocket ( ip, port ) | : JackAudioDriver ( name, alias, engine, table ), fSocket ( ip, port ) | ||||
{ | { | ||||
jack_log ( "JackNetDriver::JackNetDriver ip %s, port %d", ip, port ); | jack_log ( "JackNetDriver::JackNetDriver ip %s, port %d", ip, port ); | ||||
@@ -66,6 +67,8 @@ namespace Jack | |||||
strcpy ( fParams.fName, net_name ); | strcpy ( fParams.fName, net_name ); | ||||
fSocket.GetName ( fParams.fSlaveNetName ); | fSocket.GetName ( fParams.fSlaveNetName ); | ||||
fParams.fTransportSync = transport_sync; | fParams.fTransportSync = transport_sync; | ||||
fParams.fNetworkMasterMode = network_master_mode; | |||||
fParams.fNetworkSlaveMode = network_slave_mode; | |||||
#ifdef JACK_MONITOR | #ifdef JACK_MONITOR | ||||
fMonitor = NULL; | fMonitor = NULL; | ||||
fMeasure = NULL; | fMeasure = NULL; | ||||
@@ -523,6 +526,10 @@ namespace Jack | |||||
int JackNetDriver::Read() | int JackNetDriver::Read() | ||||
{ | { | ||||
//slow mode and first cycle : skip read | |||||
if ( ( fParams.fNetworkSlaveMode == 's' ) && ( fRxHeader.fCycle == 0 ) ) | |||||
return 0; | |||||
int rx_bytes; | int rx_bytes; | ||||
uint recvd_midi_pckt = 0; | uint recvd_midi_pckt = 0; | ||||
packet_header_t* rx_head = reinterpret_cast<packet_header_t*> ( fRxBuffer ); | packet_header_t* rx_head = reinterpret_cast<packet_header_t*> ( fRxBuffer ); | ||||
@@ -690,7 +697,7 @@ namespace Jack | |||||
{ | { | ||||
jack_driver_desc_t* desc = ( jack_driver_desc_t* ) calloc ( 1, sizeof ( jack_driver_desc_t ) ); | jack_driver_desc_t* desc = ( jack_driver_desc_t* ) calloc ( 1, sizeof ( jack_driver_desc_t ) ); | ||||
strcpy ( desc->name, "net" ); | strcpy ( desc->name, "net" ); | ||||
desc->nparams = 9; | |||||
desc->nparams = 11; | |||||
desc->params = ( jack_driver_param_desc_t* ) calloc ( desc->nparams, sizeof ( jack_driver_param_desc_t ) ); | desc->params = ( jack_driver_param_desc_t* ) calloc ( desc->nparams, sizeof ( jack_driver_param_desc_t ) ); | ||||
int i = 0; | int i = 0; | ||||
@@ -765,6 +772,24 @@ namespace Jack | |||||
strcpy ( desc->params[i].short_desc, "Sync transport with master's" ); | strcpy ( desc->params[i].short_desc, "Sync transport with master's" ); | ||||
strcpy ( desc->params[i].long_desc, desc->params[i].short_desc ); | strcpy ( desc->params[i].long_desc, desc->params[i].short_desc ); | ||||
i++; | |||||
strcpy ( desc->params[i].name, "network_master_mode" ); | |||||
desc->params[i].character = 'm'; | |||||
desc->params[i].type = JackDriverParamChar; | |||||
desc->params[i].value.ui = 's'; | |||||
strcpy ( desc->params[i].short_desc, "Slow network add 1 cycle latency" ); | |||||
strcpy ( desc->params[i].long_desc, "'s' for slow, 'f' for fast, default is slow.\ | |||||
Fast network will make the master waiting for the current cycle return data." ); | |||||
i++; | |||||
strcpy ( desc->params[i].name, "network_slave_mode" ); | |||||
desc->params[i].character = 's'; | |||||
desc->params[i].type = JackDriverParamChar; | |||||
desc->params[i].value.ui = 's'; | |||||
strcpy ( desc->params[i].short_desc, "Slow network add 1 cycle latency" ); | |||||
strcpy ( desc->params[i].long_desc, "'s' for slow, 'f' for fast, default is slow.\ | |||||
Fast network will make the slave waiting for the first cycle data." ); | |||||
return desc; | return desc; | ||||
} | } | ||||
@@ -788,6 +813,8 @@ namespace Jack | |||||
int midi_input_ports = 0; | int midi_input_ports = 0; | ||||
int midi_output_ports = 0; | int midi_output_ports = 0; | ||||
bool monitor = false; | bool monitor = false; | ||||
char network_master_mode = 's'; | |||||
char network_slave_mode = 's'; | |||||
const JSList* node; | const JSList* node; | ||||
const jack_driver_param_t* param; | const jack_driver_param_t* param; | ||||
@@ -819,14 +846,44 @@ namespace Jack | |||||
break; | break; | ||||
case 'n' : | case 'n' : | ||||
strncpy ( name, param->value.str, JACK_CLIENT_NAME_SIZE ); | strncpy ( name, param->value.str, JACK_CLIENT_NAME_SIZE ); | ||||
break; | |||||
case 't' : | case 't' : | ||||
transport_sync = param->value.ui; | transport_sync = param->value.ui; | ||||
break; | |||||
case 'm' : | |||||
switch ( param->value.ui ) | |||||
{ | |||||
case 's' : | |||||
network_master_mode = 's'; | |||||
break; | |||||
case 'f' : | |||||
network_master_mode = 'f'; | |||||
break; | |||||
default : | |||||
network_master_mode = 's'; | |||||
break; | |||||
} | |||||
break; | |||||
case 's' : | |||||
switch ( param->value.ui ) | |||||
{ | |||||
case 's' : | |||||
network_slave_mode = 's'; | |||||
break; | |||||
case 'f' : | |||||
network_slave_mode = 'f'; | |||||
break; | |||||
default : | |||||
network_slave_mode = 's'; | |||||
break; | |||||
} | |||||
break; | |||||
} | } | ||||
} | } | ||||
Jack::JackDriverClientInterface* driver = new Jack::JackWaitThreadedDriver ( | Jack::JackDriverClientInterface* driver = new Jack::JackWaitThreadedDriver ( | ||||
new Jack::JackNetDriver ( "system", "net_pcm", engine, table, multicast_ip, udp_port, mtu, | new Jack::JackNetDriver ( "system", "net_pcm", engine, table, multicast_ip, udp_port, mtu, | ||||
midi_input_ports, midi_output_ports, name, transport_sync ) ); | |||||
midi_input_ports, midi_output_ports, name, transport_sync, network_master_mode, network_slave_mode ) ); | |||||
if ( driver->Open ( period_size, sample_rate, 1, 1, audio_capture_ports, audio_playback_ports, | if ( driver->Open ( period_size, sample_rate, 1, 1, audio_capture_ports, audio_playback_ports, | ||||
monitor, "from_master_", "to_master_", 0, 0 ) == 0 ) | monitor, "from_master_", "to_master_", 0, 0 ) == 0 ) | ||||
return driver; | return driver; | ||||
@@ -99,7 +99,8 @@ namespace Jack | |||||
public: | public: | ||||
JackNetDriver ( const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table, | JackNetDriver ( const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table, | ||||
const char* ip, int port, int mtu, int midi_input_ports, int midi_output_ports, const char* master_name, uint transport_sync ); | |||||
const char* ip, int port, int mtu, int midi_input_ports, int midi_output_ports, | |||||
const char* master_name, uint transport_sync, char network_master_mode, char network_slave_mode ); | |||||
~JackNetDriver(); | ~JackNetDriver(); | ||||
int Open ( jack_nframes_t frames_per_cycle, jack_nframes_t rate, bool capturing, bool playing, | int Open ( jack_nframes_t frames_per_cycle, jack_nframes_t rate, bool capturing, bool playing, | ||||
@@ -477,8 +477,9 @@ namespace Jack | |||||
//receive -------------------------------------------------------------------------------------------------------------------- | //receive -------------------------------------------------------------------------------------------------------------------- | ||||
//sync | //sync | ||||
rx_bytes == Recv ( sizeof ( packet_header_t ), 0 ); | rx_bytes == Recv ( sizeof ( packet_header_t ), 0 ); | ||||
//if there is no data to be read, there could be stg wron with the slave, so just finish the cycle while returning 0 to start a new one | |||||
//if it's a network error, just return SOCKET_ERROR | |||||
//wait here for sync, switch network mode : | |||||
// -fast : this recv will wait for a long time (90% of cycle duration) | |||||
// -slow : just wait for a short time, then return, the data will be available at the next cycle | |||||
if ( ( rx_bytes == 0 ) || ( rx_bytes == SOCKET_ERROR ) ) | if ( ( rx_bytes == 0 ) || ( rx_bytes == SOCKET_ERROR ) ) | ||||
return rx_bytes; | return rx_bytes; | ||||
@@ -359,7 +359,13 @@ namespace Jack | |||||
EXPORT int SetRxTimeout ( JackNetSocket* socket, session_params_t* params ) | EXPORT int SetRxTimeout ( JackNetSocket* socket, session_params_t* params ) | ||||
{ | { | ||||
float time = 1250000.f * ( static_cast<float> ( params->fFramesPerPacket ) / static_cast<float> ( params->fSampleRate ) ); | |||||
float time; | |||||
//fast mode, wait for the entire cycle duration | |||||
if ( params->fNetworkMasterMode == 'f' ) | |||||
time = 900000.f * ( static_cast<float> ( params->fPeriodSize ) / static_cast<float> ( params->fSampleRate ) ); | |||||
//slow mode, just try recv during a subcycle audio packet | |||||
else | |||||
time = 1250000.f * ( static_cast<float> ( params->fFramesPerPacket ) / static_cast<float> ( params->fSampleRate ) ); | |||||
int usec = ( int ) time; | int usec = ( int ) time; | ||||
return socket->SetTimeOut ( usec ); | return socket->SetTimeOut ( usec ); | ||||
} | } | ||||
@@ -73,6 +73,8 @@ We have : | |||||
uint32_t fFramesPerPacket; //complete frames per packet | uint32_t fFramesPerPacket; //complete frames per packet | ||||
uint32_t fBitdepth; //samples bitdepth (unused) | uint32_t fBitdepth; //samples bitdepth (unused) | ||||
uint32_t fSlaveSyncMode; //is the slave in sync mode ? | uint32_t fSlaveSyncMode; //is the slave in sync mode ? | ||||
char fNetworkMasterMode; //fast or slow mode | |||||
char fNetworkSlaveMode; //fast or slow mode | |||||
}; | }; | ||||
//net status ********************************************************************************** | //net status ********************************************************************************** | ||||
@@ -266,8 +266,8 @@ namespace Jack | |||||
int JackNetWinSocket::SetTimeOut ( int& usec ) | int JackNetWinSocket::SetTimeOut ( int& usec ) | ||||
{ | { | ||||
//negative timeout, or exceeding 10s, return | //negative timeout, or exceeding 10s, return | ||||
if ( ( msec < 0 ) || ( usec > 10000000 ) ) | |||||
return -1; | |||||
if ( ( usec < 0 ) || ( usec > 10000000 ) ) | |||||
return SOCKET_ERROR; | |||||
int time = usec / 1000; | int time = usec / 1000; | ||||
return SetOption ( SOL_SOCKET, SO_RCVTIMEO, &time, sizeof ( time ) ); | return SetOption ( SOL_SOCKET, SO_RCVTIMEO, &time, sizeof ( time ) ); | ||||
} | } | ||||
@@ -17,6 +17,7 @@ | |||||
<Add option="-DBUILD_DLL" /> | <Add option="-DBUILD_DLL" /> | ||||
<Add directory="..\common" /> | <Add directory="..\common" /> | ||||
<Add directory="..\common\jack" /> | <Add directory="..\common\jack" /> | ||||
<Add directory="..\windows" /> | |||||
</Compiler> | </Compiler> | ||||
<Linker> | <Linker> | ||||
<Add library="user32" /> | <Add library="user32" /> | ||||
@@ -47,6 +48,7 @@ | |||||
<Add option="-DBUILD_DLL" /> | <Add option="-DBUILD_DLL" /> | ||||
<Add directory="..\common" /> | <Add directory="..\common" /> | ||||
<Add directory="..\common\jack" /> | <Add directory="..\common\jack" /> | ||||
<Add directory="..\windows" /> | |||||
</Compiler> | </Compiler> | ||||
<Linker> | <Linker> | ||||
<Add library="user32" /> | <Add library="user32" /> | ||||
@@ -77,6 +79,7 @@ | |||||
<Add option="-DBUILD_DLL" /> | <Add option="-DBUILD_DLL" /> | ||||
<Add directory="..\common" /> | <Add directory="..\common" /> | ||||
<Add directory="..\common\jack" /> | <Add directory="..\common\jack" /> | ||||
<Add directory="..\windows" /> | |||||
</Compiler> | </Compiler> | ||||
<Linker> | <Linker> | ||||
<Add library="kernel32" /> | <Add library="kernel32" /> | ||||
@@ -101,6 +104,7 @@ | |||||
<Add option="-Wall" /> | <Add option="-Wall" /> | ||||
<Add directory="..\common" /> | <Add directory="..\common" /> | ||||
<Add directory="..\common\jack" /> | <Add directory="..\common\jack" /> | ||||
<Add directory="..\windows" /> | |||||
</Compiler> | </Compiler> | ||||
<Linker> | <Linker> | ||||
<Add library="kernel32" /> | <Add library="kernel32" /> | ||||