git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3939 0c269be4-1314-0410-8aa9-9f06e86f4224tags/1.9.8
| @@ -262,7 +262,9 @@ struct JackNetExtMaster : public JackNetMasterInterface { | |||
| return -1; | |||
| // Set global parameters | |||
| SetParams(); | |||
| if (!SetParams()) | |||
| return -1; | |||
| AllocPorts(); | |||
| return 0; | |||
| } | |||
| @@ -465,12 +467,12 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf | |||
| int Open(jack_master_t* result) | |||
| { | |||
| // Init network connection | |||
| if (!JackNetSlaveInterface::InitConnection()){ | |||
| if (!JackNetSlaveInterface::InitConnection()) | |||
| return -1; | |||
| } | |||
| // Then set global parameters | |||
| SetParams(); | |||
| if (!SetParams()) | |||
| return -1; | |||
| // Set result | |||
| if (result != NULL) { | |||
| @@ -494,7 +496,8 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf | |||
| return -1; | |||
| // Then set global parameters | |||
| SetParams(); | |||
| if (!SetParams()) | |||
| return -1; | |||
| // We need to notify possibly new buffer size and sample rate (see Execute) | |||
| if (fBufferSizeCallback) | |||
| @@ -514,6 +517,7 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf | |||
| return 0; | |||
| } | |||
| void AllocPorts() | |||
| { | |||
| unsigned int port_index; | |||
| @@ -939,7 +943,7 @@ SERVER_EXPORT void jack_log(const char *fmt, ...) | |||
| { | |||
| va_list ap; | |||
| va_start(ap, fmt); | |||
| //jack_format_and_log(LOG_LEVEL_INFO, "Jack: ", fmt, ap); | |||
| jack_format_and_log(LOG_LEVEL_INFO, "Jack: ", fmt, ap); | |||
| va_end(ap); | |||
| } | |||
| @@ -142,11 +142,12 @@ namespace Jack | |||
| ( fParams.fSlaveSyncMode ) ? "sync" : "async", ( fParams.fTransportSync ) ? "with" : "without" ); | |||
| //init network | |||
| if ( !JackNetSlaveInterface::Init() ) | |||
| if (!JackNetSlaveInterface::Init()) | |||
| return false; | |||
| //set global parameters | |||
| SetParams(); | |||
| if (!SetParams()) | |||
| return false; | |||
| //allocate midi ports lists | |||
| fMidiCapturePortList = new jack_port_id_t [fParams.fSendMidiChannels]; | |||
| @@ -89,88 +89,45 @@ namespace Jack | |||
| delete fNetMidiPlaybackBuffer; | |||
| } | |||
| void JackNetInterface::SetFramesPerPacket() | |||
| { | |||
| jack_log ( "JackNetInterface::SetFramesPerPacket" ); | |||
| if (fParams.fSendAudioChannels == 0 && fParams.fReturnAudioChannels == 0) { | |||
| fParams.fFramesPerPacket = fParams.fPeriodSize; | |||
| } else { | |||
| jack_nframes_t period = ( int ) powf ( 2.f, ( int ) ( log (float (PACKET_AVAILABLE_SIZE) | |||
| / ( max ( fParams.fReturnAudioChannels, fParams.fSendAudioChannels ) * sizeof ( sample_t ) ) ) / log ( 2. ) ) ); | |||
| fParams.fFramesPerPacket = ( period > fParams.fPeriodSize ) ? fParams.fPeriodSize : period; | |||
| } | |||
| } | |||
| int JackNetInterface::SetNetBufferSize() | |||
| { | |||
| float audio_size, midi_size; | |||
| int bufsize; | |||
| //audio | |||
| audio_size = fParams.fMtu * ( fParams.fPeriodSize / fParams.fFramesPerPacket ); | |||
| float audio_size = (fNetAudioCaptureBuffer) | |||
| ? fNetAudioCaptureBuffer->GetCycleSize() | |||
| : (fNetAudioPlaybackBuffer) ? fNetAudioPlaybackBuffer->GetCycleSize() : 0; | |||
| jack_log ("audio_size %f", audio_size); | |||
| //midi | |||
| midi_size = fParams.fMtu * ( max ( fParams.fSendMidiChannels, fParams.fReturnMidiChannels ) * | |||
| fParams.fPeriodSize * sizeof(sample_t) / PACKET_AVAILABLE_SIZE); | |||
| float midi_size = (fNetMidiCaptureBuffer) | |||
| ? fNetMidiCaptureBuffer->GetCycleSize() | |||
| : (fNetMidiPlaybackBuffer) ? fNetMidiPlaybackBuffer->GetCycleSize() : 0; | |||
| jack_log ("midi_size %f", midi_size); | |||
| //bufsize = sync + audio + midi | |||
| bufsize = MAX_LATENCY * (fParams.fMtu + ( int ) audio_size + ( int ) midi_size); | |||
| int bufsize = MAX_LATENCY * (fParams.fMtu + (int)audio_size + (int) midi_size); | |||
| jack_log("SetNetBufferSize bufsize = %d", bufsize); | |||
| //tx buffer | |||
| if ( fSocket.SetOption ( SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof ( bufsize ) ) == SOCKET_ERROR ) | |||
| if (fSocket.SetOption(SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof(bufsize)) == SOCKET_ERROR) | |||
| return SOCKET_ERROR; | |||
| //rx buffer | |||
| if ( fSocket.SetOption ( SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof ( bufsize ) ) == SOCKET_ERROR ) | |||
| if (fSocket.SetOption(SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof(bufsize)) == SOCKET_ERROR) | |||
| return SOCKET_ERROR; | |||
| return 0; | |||
| } | |||
| int JackNetInterface::GetNMidiPckt() | |||
| { | |||
| //even if there is no midi data, jack need an empty buffer to know there is no event to read | |||
| //99% of the cases : all data in one packet | |||
| if (fTxHeader.fMidiDataSize <= PACKET_AVAILABLE_SIZE) { | |||
| return 1; | |||
| } else { //get the number of needed packets (simply slice the biiig buffer) | |||
| return (fTxHeader.fMidiDataSize % PACKET_AVAILABLE_SIZE) | |||
| ? (fTxHeader.fMidiDataSize / PACKET_AVAILABLE_SIZE + 1) | |||
| : fTxHeader.fMidiDataSize / PACKET_AVAILABLE_SIZE; | |||
| } | |||
| } | |||
| bool JackNetInterface::IsNextPacket() | |||
| { | |||
| packet_header_t* rx_head = reinterpret_cast<packet_header_t*> ( fRxBuffer ); | |||
| //ignore first cycle | |||
| if ( fRxHeader.fCycle <= 1 ) { | |||
| return true; | |||
| } | |||
| //same PcktID (cycle), next SubPcktID (subcycle) | |||
| if ( ( fRxHeader.fSubCycle < ( fNSubProcess - 1 ) ) && ( rx_head->fCycle == fRxHeader.fCycle ) && ( rx_head->fSubCycle == ( fRxHeader.fSubCycle + 1 ) ) ) { | |||
| return true; | |||
| } | |||
| //next PcktID (cycle), SubPcktID reset to 0 (first subcyle) | |||
| if ( ( rx_head->fCycle == ( fRxHeader.fCycle + 1 ) ) && ( fRxHeader.fSubCycle == ( fNSubProcess - 1 ) ) && ( rx_head->fSubCycle == 0 ) ) { | |||
| return true; | |||
| } | |||
| //else, packet(s) missing, return false | |||
| return false; | |||
| } | |||
| void JackNetInterface::SetParams() | |||
| bool JackNetInterface::SetParams() | |||
| { | |||
| //number of audio subcycles (packets) | |||
| fNSubProcess = fParams.fPeriodSize / fParams.fFramesPerPacket; | |||
| //TX header init | |||
| strcpy ( fTxHeader.fPacketType, "header" ); | |||
| fTxHeader.fID = fParams.fID; | |||
| fTxHeader.fCycle = 0; | |||
| fTxHeader.fSubCycle = 0; | |||
| fTxHeader.fMidiDataSize = 0; | |||
| fTxHeader.fBitdepth = fParams.fBitdepth; | |||
| fTxHeader.fIsLastPckt = 0; | |||
| @@ -179,7 +136,6 @@ namespace Jack | |||
| fRxHeader.fID = fParams.fID; | |||
| fRxHeader.fCycle = 0; | |||
| fRxHeader.fSubCycle = 0; | |||
| fRxHeader.fMidiDataSize = 0; | |||
| fRxHeader.fBitdepth = fParams.fBitdepth; | |||
| fRxHeader.fIsLastPckt = 0; | |||
| @@ -192,6 +148,8 @@ namespace Jack | |||
| //net audio/midi buffers'addresses | |||
| fTxData = fTxBuffer + HEADER_SIZE; | |||
| fRxData = fRxBuffer + HEADER_SIZE; | |||
| return true; | |||
| } | |||
| // JackNetMasterInterface ************************************************************************************ | |||
| @@ -220,11 +178,8 @@ namespace Jack | |||
| return false; | |||
| } | |||
| //set the number of complete audio frames we can put in a packet | |||
| SetFramesPerPacket(); | |||
| //send 'SLAVE_SETUP' until 'START_MASTER' received | |||
| jack_info ( "Sending parameters to %s ...", fParams.fSlaveNetName ); | |||
| jack_info ( "Sending parameters to %s...", fParams.fSlaveNetName ); | |||
| do | |||
| { | |||
| session_params_t net_params; | |||
| @@ -250,18 +205,6 @@ namespace Jack | |||
| return false; | |||
| } | |||
| //set the new timeout for the socket | |||
| if ( SetRxTimeout() == SOCKET_ERROR ) { | |||
| jack_error ( "Can't set rx timeout : %s", StrError ( NET_ERROR_CODE ) ); | |||
| return false; | |||
| } | |||
| //set the new rx buffer size | |||
| if ( SetNetBufferSize() == SOCKET_ERROR ) { | |||
| jack_error ( "Can't set net buffer sizes : %s", StrError ( NET_ERROR_CODE ) ); | |||
| return false; | |||
| } | |||
| return true; | |||
| } | |||
| @@ -270,16 +213,22 @@ namespace Jack | |||
| jack_log ( "JackNetMasterInterface::SetRxTimeout" ); | |||
| float time = 0; | |||
| //slow or normal mode, short timeout on recv (2 audio subcycles) | |||
| if ( ( fParams.fNetworkMode == 's' ) || ( fParams.fNetworkMode == 'n' ) ) | |||
| time = 2000000.f * ( static_cast<float> ( fParams.fFramesPerPacket ) / static_cast<float> ( fParams.fSampleRate ) ); | |||
| if ((fParams.fNetworkMode == 's') || (fParams.fNetworkMode == 'n')) { | |||
| time = 2000000.f * ((fNetAudioCaptureBuffer) | |||
| ? fNetAudioCaptureBuffer->GetCycleDuration() | |||
| : (fNetAudioPlaybackBuffer) ? fNetAudioPlaybackBuffer->GetCycleDuration() : 0); | |||
| } | |||
| //fast mode, wait for 75% of the entire cycle duration | |||
| else if ( fParams.fNetworkMode == 'f' ) | |||
| time = 750000.f * ( static_cast<float> ( fParams.fPeriodSize ) / static_cast<float> ( fParams.fSampleRate ) ); | |||
| return fSocket.SetTimeOut ( static_cast<int> ( time ) ); | |||
| else if (fParams.fNetworkMode == 'f') { | |||
| time = 750000.f * (static_cast<float>(fParams.fPeriodSize) / static_cast<float>(fParams.fSampleRate)); | |||
| } | |||
| return fSocket.SetTimeOut (static_cast<int>(time)); | |||
| } | |||
| void JackNetMasterInterface::SetParams() | |||
| bool JackNetMasterInterface::SetParams() | |||
| { | |||
| jack_log ( "JackNetMasterInterface::SetParams" ); | |||
| @@ -303,6 +252,28 @@ namespace Jack | |||
| assert ( fNetAudioCaptureBuffer ); | |||
| assert ( fNetAudioPlaybackBuffer ); | |||
| //set the new timeout for the socket | |||
| if ( SetRxTimeout() == SOCKET_ERROR ) { | |||
| jack_error ( "Can't set rx timeout : %s", StrError ( NET_ERROR_CODE ) ); | |||
| goto error; | |||
| } | |||
| //set the new rx buffer size | |||
| if ( SetNetBufferSize() == SOCKET_ERROR ) { | |||
| jack_error ( "Can't set net buffer sizes : %s", StrError ( NET_ERROR_CODE ) ); | |||
| goto error; | |||
| } | |||
| return true; | |||
| error: | |||
| delete fNetMidiCaptureBuffer; | |||
| delete fNetMidiPlaybackBuffer; | |||
| delete fNetAudioCaptureBuffer; | |||
| delete fNetAudioPlaybackBuffer; | |||
| return false; | |||
| } | |||
| void JackNetMasterInterface::Exit() | |||
| @@ -402,18 +373,21 @@ namespace Jack | |||
| int JackNetMasterInterface::DataSend() | |||
| { | |||
| uint subproc; | |||
| uint data_size; | |||
| //midi | |||
| if ( fParams.fSendMidiChannels > 0) | |||
| { | |||
| //set global header fields and get the number of midi packets | |||
| fTxHeader.fDataType = 'm'; | |||
| fTxHeader.fMidiDataSize = fNetMidiCaptureBuffer->RenderFromJackPorts(); | |||
| fTxHeader.fNMidiPckt = GetNMidiPckt(); | |||
| for ( subproc = 0; subproc < fTxHeader.fNMidiPckt; subproc++ ) | |||
| data_size = fNetMidiCaptureBuffer->RenderFromJackPorts(); | |||
| fTxHeader.fNumPacket = fNetMidiCaptureBuffer->GetNumPackets(); | |||
| for ( subproc = 0; subproc < fTxHeader.fNumPacket; subproc++ ) | |||
| { | |||
| fTxHeader.fSubCycle = subproc; | |||
| fTxHeader.fIsLastPckt = (( subproc == (fTxHeader.fNMidiPckt - 1)) && (fParams.fSendAudioChannels == 0)) ? 1 : 0; | |||
| fTxHeader.fPacketSize = HEADER_SIZE + fNetMidiCaptureBuffer->RenderToNetwork(subproc, fTxHeader.fMidiDataSize); | |||
| fTxHeader.fIsLastPckt = ((subproc == (fTxHeader.fNumPacket - 1)) && (fParams.fSendAudioChannels == 0)) ? 1 : 0; | |||
| fTxHeader.fPacketSize = HEADER_SIZE + fNetMidiCaptureBuffer->RenderToNetwork(subproc, data_size); | |||
| memcpy ( fTxBuffer, &fTxHeader, HEADER_SIZE); | |||
| if (Send (fTxHeader.fPacketSize, 0) == SOCKET_ERROR) | |||
| return SOCKET_ERROR; | |||
| @@ -424,15 +398,15 @@ namespace Jack | |||
| if ( fParams.fSendAudioChannels > 0) | |||
| { | |||
| fTxHeader.fDataType = 'a'; | |||
| fTxHeader.fMidiDataSize = 0; | |||
| fTxHeader.fNMidiPckt = 0; | |||
| for (subproc = 0; subproc < fNSubProcess; subproc++) | |||
| data_size = fNetAudioCaptureBuffer->RenderFromJackPorts(); | |||
| fTxHeader.fNumPacket = fNetAudioCaptureBuffer->GetNumPackets(); | |||
| for (subproc = 0; subproc < fTxHeader.fNumPacket; subproc++) | |||
| { | |||
| fTxHeader.fSubCycle = subproc; | |||
| fTxHeader.fIsLastPckt = (subproc == (fNSubProcess - 1)) ? 1 : 0; | |||
| fTxHeader.fPacketSize = HEADER_SIZE + fNetAudioPlaybackBuffer->GetSize(); | |||
| fTxHeader.fIsLastPckt = (subproc == (fTxHeader.fNumPacket - 1)) ? 1 : 0; | |||
| fTxHeader.fPacketSize = HEADER_SIZE + fNetAudioCaptureBuffer->RenderToNetwork(subproc, data_size); | |||
| memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE); | |||
| fNetAudioCaptureBuffer->RenderFromJackPorts(subproc); | |||
| if (Send(fTxHeader.fPacketSize, 0) == SOCKET_ERROR) | |||
| return SOCKET_ERROR; | |||
| } | |||
| @@ -506,8 +480,8 @@ namespace Jack | |||
| int JackNetMasterInterface::DataRecv() | |||
| { | |||
| int rx_bytes = 0; | |||
| int last_cycle = 0; | |||
| uint recvd_midi_pckt = 0; | |||
| uint recvd_audio_pckt = 0; | |||
| packet_header_t* rx_head = reinterpret_cast<packet_header_t*> ( fRxBuffer ); | |||
| @@ -530,34 +504,30 @@ namespace Jack | |||
| fRxHeader.fCycle = rx_head->fCycle; | |||
| fRxHeader.fIsLastPckt = rx_head->fIsLastPckt; | |||
| fNetMidiPlaybackBuffer->RenderFromNetwork(rx_head->fSubCycle, rx_bytes - HEADER_SIZE); | |||
| // Last midi packet is received, so finish rendering... | |||
| if ( ++recvd_midi_pckt == rx_head->fNMidiPckt ) | |||
| // Last midi packet is received, so finish rendering... | |||
| if (++recvd_midi_pckt == rx_head->fNumPacket) | |||
| fNetMidiPlaybackBuffer->RenderToJackPorts(); | |||
| break; | |||
| case 'a': //audio | |||
| rx_bytes = Recv ( rx_head->fPacketSize, 0 ); | |||
| if (!IsNextPacket()) { | |||
| jack_error("Packet(s) missing from '%s'...", fParams.fMasterNetName); | |||
| } | |||
| fRxHeader.fCycle = rx_head->fCycle; | |||
| fRxHeader.fSubCycle = rx_head->fSubCycle; | |||
| fRxHeader.fIsLastPckt = rx_head->fIsLastPckt; | |||
| fNetAudioPlaybackBuffer->RenderToJackPorts ( rx_head->fCycle, rx_head->fSubCycle); | |||
| last_cycle = rx_head->fCycle; | |||
| fNetAudioPlaybackBuffer->RenderFromNetwork (rx_head->fCycle, rx_head->fSubCycle, rx_bytes - HEADER_SIZE); | |||
| // Last audio packet is received, so finish rendering... | |||
| if (fRxHeader.fIsLastPckt) | |||
| fNetAudioPlaybackBuffer->RenderToJackPorts(); | |||
| break; | |||
| case 's': //sync | |||
| jack_info("NetMaster : overloaded, skipping receive from '%s'", fParams.fName); | |||
| // Finish rendering (copy to JACK ports) | |||
| fNetAudioPlaybackBuffer->FinishRenderToJackPorts(last_cycle); | |||
| // TODO : finish midi and audio rendering ? | |||
| return 0; | |||
| } | |||
| } | |||
| } | |||
| // Finish rendering (copy to JACK ports) | |||
| fNetAudioPlaybackBuffer->FinishRenderToJackPorts(last_cycle); | |||
| return rx_bytes; | |||
| } | |||
| @@ -727,18 +697,11 @@ namespace Jack | |||
| SessionParamsDisplay(&host_params); | |||
| fParams = host_params; | |||
| //set the new buffer sizes | |||
| if ( SetNetBufferSize() == SOCKET_ERROR ) { | |||
| jack_error ( "Can't set net buffer sizes : %s", StrError ( NET_ERROR_CODE ) ); | |||
| return NET_SOCKET_ERROR; | |||
| } | |||
| //connect the socket | |||
| if ( fSocket.Connect() == SOCKET_ERROR ) { | |||
| jack_error ( "Error in connect : %s", StrError ( NET_ERROR_CODE ) ); | |||
| return NET_CONNECT_ERROR; | |||
| } | |||
| return NET_CONNECTED; | |||
| } | |||
| @@ -759,7 +722,7 @@ namespace Jack | |||
| return NET_ROLLING; | |||
| } | |||
| void JackNetSlaveInterface::SetParams() | |||
| bool JackNetSlaveInterface::SetParams() | |||
| { | |||
| jack_log ( "JackNetSlaveInterface::SetParams" ); | |||
| @@ -783,6 +746,21 @@ namespace Jack | |||
| assert ( fNetAudioCaptureBuffer ); | |||
| assert ( fNetAudioPlaybackBuffer ); | |||
| //set the new buffer sizes | |||
| if ( SetNetBufferSize() == SOCKET_ERROR ) { | |||
| jack_error ( "Can't set net buffer sizes : %s", StrError ( NET_ERROR_CODE ) ); | |||
| goto error; | |||
| } | |||
| return true; | |||
| error: | |||
| delete fNetMidiCaptureBuffer; | |||
| delete fNetMidiPlaybackBuffer; | |||
| delete fNetAudioCaptureBuffer; | |||
| delete fNetAudioPlaybackBuffer; | |||
| return false; | |||
| } | |||
| int JackNetSlaveInterface::Recv ( size_t size, int flags ) | |||
| @@ -852,8 +830,9 @@ namespace Jack | |||
| int JackNetSlaveInterface::DataRecv() | |||
| { | |||
| int rx_bytes = 0; | |||
| int last_cycle = 0; | |||
| //int last_cycle = 0; | |||
| uint recvd_midi_pckt = 0; | |||
| uint recvd_audio_pckt = 0; | |||
| packet_header_t* rx_head = reinterpret_cast<packet_header_t*> ( fRxBuffer ); | |||
| @@ -876,33 +855,29 @@ namespace Jack | |||
| fRxHeader.fIsLastPckt = rx_head->fIsLastPckt; | |||
| fNetMidiCaptureBuffer->RenderFromNetwork(rx_head->fSubCycle, rx_bytes - HEADER_SIZE); | |||
| // Last midi packet is received, so finish rendering... | |||
| if ( ++recvd_midi_pckt == rx_head->fNMidiPckt ) | |||
| if ( ++recvd_midi_pckt == rx_head->fNumPacket ) | |||
| fNetMidiCaptureBuffer->RenderToJackPorts(); | |||
| break; | |||
| case 'a': //audio | |||
| rx_bytes = Recv ( rx_head->fPacketSize, 0 ); | |||
| if (!IsNextPacket()) { | |||
| jack_error("Packet(s) missing from '%s'...", fParams.fMasterNetName); | |||
| } | |||
| fRxHeader.fCycle = rx_head->fCycle; | |||
| fRxHeader.fSubCycle = rx_head->fSubCycle; | |||
| fRxHeader.fIsLastPckt = rx_head->fIsLastPckt; | |||
| fNetAudioCaptureBuffer->RenderToJackPorts ( rx_head->fCycle, rx_head->fSubCycle); | |||
| last_cycle = rx_head->fCycle; | |||
| fNetAudioCaptureBuffer->RenderFromNetwork (rx_head->fCycle, rx_head->fSubCycle, rx_bytes - HEADER_SIZE); | |||
| if (fRxHeader.fIsLastPckt) { | |||
| fNetAudioCaptureBuffer->RenderToJackPorts(); | |||
| } | |||
| break; | |||
| case 's': //sync | |||
| jack_info ( "NetSlave : overloaded, skipping receive." ); | |||
| // Finish rendering (copy to JACK ports) | |||
| fNetAudioCaptureBuffer->FinishRenderToJackPorts(last_cycle); | |||
| // TODO : finish midi and audio rendering ? | |||
| return 0; | |||
| } | |||
| } | |||
| } | |||
| // Finish rendering (copy to JACK ports) | |||
| fNetAudioCaptureBuffer->FinishRenderToJackPorts(last_cycle); | |||
| fRxHeader.fCycle = rx_head->fCycle; | |||
| return 0; | |||
| } | |||
| @@ -927,19 +902,20 @@ namespace Jack | |||
| int JackNetSlaveInterface::DataSend() | |||
| { | |||
| uint subproc; | |||
| uint data_size; | |||
| //midi | |||
| if (fParams.fReturnMidiChannels > 0) | |||
| { | |||
| //set global header fields and get the number of midi packets | |||
| fTxHeader.fDataType = 'm'; | |||
| fTxHeader.fMidiDataSize = fNetMidiPlaybackBuffer->RenderFromJackPorts(); | |||
| fTxHeader.fNMidiPckt = GetNMidiPckt(); | |||
| for ( subproc = 0; subproc < fTxHeader.fNMidiPckt; subproc++ ) | |||
| data_size = fNetMidiPlaybackBuffer->RenderFromJackPorts(); | |||
| fTxHeader.fNumPacket = fNetMidiPlaybackBuffer->GetNumPackets(); | |||
| for ( subproc = 0; subproc < fTxHeader.fNumPacket; subproc++ ) | |||
| { | |||
| fTxHeader.fSubCycle = subproc; | |||
| fTxHeader.fIsLastPckt = ((subproc == (fTxHeader.fNMidiPckt - 1)) && !fParams.fReturnAudioChannels) ? 1 : 0; | |||
| fTxHeader.fPacketSize = HEADER_SIZE + fNetMidiPlaybackBuffer->RenderToNetwork(subproc, fTxHeader.fMidiDataSize); | |||
| fTxHeader.fIsLastPckt = ((subproc == (fTxHeader.fNumPacket - 1)) && !fParams.fReturnAudioChannels) ? 1 : 0; | |||
| fTxHeader.fPacketSize = HEADER_SIZE + fNetMidiPlaybackBuffer->RenderToNetwork(subproc, data_size); | |||
| memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE); | |||
| if (Send(fTxHeader.fPacketSize, 0) == SOCKET_ERROR) | |||
| return SOCKET_ERROR; | |||
| @@ -950,15 +926,14 @@ namespace Jack | |||
| if ( fParams.fReturnAudioChannels > 0) | |||
| { | |||
| fTxHeader.fDataType = 'a'; | |||
| fTxHeader.fMidiDataSize = 0; | |||
| fTxHeader.fNMidiPckt = 0; | |||
| for ( subproc = 0; subproc < fNSubProcess; subproc++ ) | |||
| data_size = fNetAudioPlaybackBuffer->RenderFromJackPorts(); | |||
| fTxHeader.fNumPacket = fNetAudioPlaybackBuffer->GetNumPackets(); | |||
| for ( subproc = 0; subproc < fTxHeader.fNumPacket; subproc++ ) | |||
| { | |||
| fTxHeader.fSubCycle = subproc; | |||
| fTxHeader.fIsLastPckt = (subproc == (fNSubProcess - 1)) ? 1 : 0; | |||
| fTxHeader.fPacketSize = HEADER_SIZE + fNetAudioCaptureBuffer->GetSize(); | |||
| fTxHeader.fIsLastPckt = (subproc == (fTxHeader.fNumPacket - 1)) ? 1 : 0; | |||
| fTxHeader.fPacketSize = HEADER_SIZE + fNetAudioPlaybackBuffer->RenderToNetwork(subproc, data_size); | |||
| memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE); | |||
| fNetAudioPlaybackBuffer->RenderFromJackPorts (subproc); | |||
| if (Send(fTxHeader.fPacketSize, 0) == SOCKET_ERROR) | |||
| return SOCKET_ERROR; | |||
| } | |||
| @@ -35,8 +35,7 @@ namespace Jack | |||
| session_params_t fParams; | |||
| JackNetSocket fSocket; | |||
| char fMulticastIP[32]; | |||
| uint fNSubProcess; | |||
| //headers | |||
| packet_header_t fTxHeader; | |||
| packet_header_t fRxHeader; | |||
| @@ -58,13 +57,10 @@ namespace Jack | |||
| NetAudioBuffer* fNetAudioPlaybackBuffer; | |||
| //utility methods | |||
| void SetFramesPerPacket(); | |||
| int SetNetBufferSize(); | |||
| int GetNMidiPckt(); | |||
| bool IsNextPacket(); | |||
| //virtual methods : depends on the sub class master/slave | |||
| virtual void SetParams(); | |||
| virtual bool SetParams(); | |||
| virtual bool Init() = 0; | |||
| //transport | |||
| @@ -103,7 +99,7 @@ namespace Jack | |||
| bool Init(); | |||
| int SetRxTimeout(); | |||
| void SetParams(); | |||
| bool SetParams(); | |||
| void Exit(); | |||
| @@ -149,7 +145,7 @@ namespace Jack | |||
| net_status_t SendAvailableToMaster(); | |||
| net_status_t SendStartToMaster(); | |||
| void SetParams(); | |||
| bool SetParams(); | |||
| int SyncRecv(); | |||
| int SyncSend(); | |||
| @@ -113,11 +113,12 @@ namespace Jack | |||
| bool JackNetMaster::Init(bool auto_connect) | |||
| { | |||
| //network init | |||
| if ( !JackNetMasterInterface::Init() ) | |||
| if (!JackNetMasterInterface::Init()) | |||
| return false; | |||
| //set global parameters | |||
| SetParams(); | |||
| if (!SetParams()) | |||
| return false; | |||
| //jack client and process | |||
| jack_status_t status; | |||
| @@ -415,7 +416,7 @@ namespace Jack | |||
| for ( port_index = 0; port_index < fParams.fReturnMidiChannels; port_index++ ) | |||
| fNetMidiPlaybackBuffer->SetBuffer ( port_index, static_cast<JackMidiBuffer*> ( jack_port_get_buffer ( fMidiPlaybackPorts[port_index], | |||
| fParams.fPeriodSize ) ) ); | |||
| for ( port_index = 0; port_index < fParams.fReturnAudioChannels; port_index++ ) | |||
| for ( port_index = 0; port_index < fParams.fReturnAudioChannels; port_index++ ) | |||
| fNetAudioPlaybackBuffer->SetBuffer ( port_index, static_cast<sample_t*> ( jack_port_get_buffer ( fAudioPlaybackPorts[port_index], | |||
| fParams.fPeriodSize ) ) ); | |||
| @@ -601,7 +602,7 @@ namespace Jack | |||
| if ( fSocket.SetTimeOut ( 2000000 ) == SOCKET_ERROR ) | |||
| jack_error ( "Can't set timeout : %s", StrError ( NET_ERROR_CODE ) ); | |||
| jack_info ( "Waiting for a slave..." ); | |||
| jack_log ( "sizeof (session_params_t) %d", sizeof (session_params_t) ); | |||
| //main loop, wait for data, deal with it and wait again | |||
| do | |||
| @@ -35,6 +35,9 @@ namespace Jack | |||
| for ( int port_index = 0; port_index < fNPorts; port_index++ ) | |||
| fPortBuffer[port_index] = NULL; | |||
| fNetBuffer = net_buffer; | |||
| fCycleSize = params->fMtu * (max(params->fSendMidiChannels, params->fReturnMidiChannels) * | |||
| params->fPeriodSize * sizeof(sample_t) / (params->fMtu - sizeof(packet_header_t))); | |||
| } | |||
| NetMidiBuffer::~NetMidiBuffer() | |||
| @@ -47,6 +50,23 @@ namespace Jack | |||
| { | |||
| return fMaxBufsize; | |||
| } | |||
| size_t NetMidiBuffer::GetCycleSize() | |||
| { | |||
| return fCycleSize; | |||
| } | |||
| int NetMidiBuffer::GetNumPackets() | |||
| { | |||
| /* | |||
| return (data_size % PACKET_AVAILABLE_SIZE) | |||
| ? (data_size / PACKET_AVAILABLE_SIZE + 1) | |||
| : data_size / PACKET_AVAILABLE_SIZE; | |||
| */ | |||
| //TODO | |||
| return 0; | |||
| } | |||
| void NetMidiBuffer::SetBuffer ( int index, JackMidiBuffer* buffer ) | |||
| { | |||
| @@ -124,10 +144,8 @@ namespace Jack | |||
| return copy_size; | |||
| } | |||
| // net audio buffer ********************************************************************************* | |||
| NetSingleAudioBuffer::NetSingleAudioBuffer ( session_params_t* params, uint32_t nports, char* net_buffer ) | |||
| : fPortBuffer(params, nports), fNetBuffer(net_buffer) | |||
| {} | |||
| @@ -139,6 +157,11 @@ namespace Jack | |||
| { | |||
| return fPortBuffer.GetSize(); | |||
| } | |||
| size_t NetSingleAudioBuffer::GetCycleSize() | |||
| { | |||
| return fPortBuffer.GetCycleSize(); | |||
| } | |||
| void NetSingleAudioBuffer::SetBuffer ( int index, sample_t* buffer ) | |||
| { | |||
| @@ -150,18 +173,30 @@ namespace Jack | |||
| return fPortBuffer.GetBuffer(index); | |||
| } | |||
| void NetSingleAudioBuffer::RenderFromJackPorts (int subcycle) | |||
| int NetSingleAudioBuffer::RenderFromJackPorts () | |||
| { | |||
| fPortBuffer.RenderFromJackPorts(fNetBuffer, subcycle); | |||
| return fPortBuffer.RenderFromJackPorts(); | |||
| } | |||
| void NetSingleAudioBuffer::RenderToJackPorts (int cycle, int subcycle) | |||
| int NetSingleAudioBuffer::RenderToJackPorts () | |||
| { | |||
| return fPortBuffer.RenderToJackPorts(); | |||
| } | |||
| //network<->buffer | |||
| int NetSingleAudioBuffer::RenderFromNetwork ( int cycle, int subcycle, size_t copy_size ) | |||
| { | |||
| return fPortBuffer.RenderFromNetwork(fNetBuffer, cycle, subcycle, copy_size); | |||
| } | |||
| int NetSingleAudioBuffer::RenderToNetwork (int subcycle, size_t total_size ) | |||
| { | |||
| fPortBuffer.RenderToJackPorts(fNetBuffer, subcycle); | |||
| return fPortBuffer.RenderToNetwork(fNetBuffer, subcycle, total_size); | |||
| } | |||
| // Buffered | |||
| /* | |||
| NetBufferedAudioBuffer::NetBufferedAudioBuffer ( session_params_t* params, uint32_t nports, char* net_buffer ) | |||
| { | |||
| fMaxCycle = 0; | |||
| @@ -172,7 +207,7 @@ namespace Jack | |||
| } | |||
| fJackPortBuffer = new sample_t* [nports]; | |||
| for ( int port_index = 0; port_index < nports; port_index++ ) | |||
| for ( uint32_t port_index = 0; port_index < nports; port_index++ ) | |||
| fJackPortBuffer[port_index] = NULL; | |||
| } | |||
| @@ -185,6 +220,11 @@ namespace Jack | |||
| { | |||
| return fPortBuffer[0].GetSize(); | |||
| } | |||
| size_t NetBufferedAudioBuffer::GetCycleSize() | |||
| { | |||
| return fPortBuffer[0].GetCycleSize(); | |||
| } | |||
| void NetBufferedAudioBuffer::SetBuffer ( int index, sample_t* buffer ) | |||
| { | |||
| @@ -214,6 +254,7 @@ namespace Jack | |||
| fMaxCycle = std::max(fMaxCycle, cycle); | |||
| fPortBuffer[(cycle + 1) % AUDIO_BUFFER_SIZE].Copy(fJackPortBuffer); // Copy internal buffer in JACK ports | |||
| } | |||
| */ | |||
| // SessionParams ************************************************************************************ | |||
| @@ -230,7 +271,6 @@ namespace Jack | |||
| dst_params->fReturnMidiChannels = htonl ( src_params->fReturnMidiChannels ); | |||
| dst_params->fSampleRate = htonl ( src_params->fSampleRate ); | |||
| dst_params->fPeriodSize = htonl ( src_params->fPeriodSize ); | |||
| dst_params->fFramesPerPacket = htonl ( src_params->fFramesPerPacket ); | |||
| dst_params->fBitdepth = htonl ( src_params->fBitdepth ); | |||
| dst_params->fSlaveSyncMode = htonl ( src_params->fSlaveSyncMode ); | |||
| } | |||
| @@ -248,7 +288,6 @@ namespace Jack | |||
| dst_params->fReturnMidiChannels = ntohl ( src_params->fReturnMidiChannels ); | |||
| dst_params->fSampleRate = ntohl ( src_params->fSampleRate ); | |||
| dst_params->fPeriodSize = ntohl ( src_params->fPeriodSize ); | |||
| dst_params->fFramesPerPacket = ntohl ( src_params->fFramesPerPacket ); | |||
| dst_params->fBitdepth = ntohl ( src_params->fBitdepth ); | |||
| dst_params->fSlaveSyncMode = ntohl ( src_params->fSlaveSyncMode ); | |||
| } | |||
| @@ -282,8 +321,6 @@ namespace Jack | |||
| jack_info ( "Return channels (audio - midi) : %d - %d", params->fReturnAudioChannels, params->fReturnMidiChannels ); | |||
| jack_info ( "Sample rate : %u frames per second", params->fSampleRate ); | |||
| jack_info ( "Period size : %u frames per period", params->fPeriodSize ); | |||
| jack_info ( "Frames per packet : %u", params->fFramesPerPacket ); | |||
| jack_info ( "Packet per period : %u", (params->fFramesPerPacket != 0) ? params->fPeriodSize / params->fFramesPerPacket : 0); | |||
| jack_info ( "Bitdepth : %s", bitdepth ); | |||
| jack_info ( "Slave mode : %s", ( params->fSlaveSyncMode ) ? "sync" : "async" ); | |||
| jack_info ( "Network mode : %s", mode ); | |||
| @@ -338,9 +375,8 @@ namespace Jack | |||
| { | |||
| memcpy(dst_header, src_header, sizeof(packet_header_t)); | |||
| dst_header->fID = htonl ( src_header->fID ); | |||
| dst_header->fMidiDataSize = htonl ( src_header->fMidiDataSize ); | |||
| dst_header->fBitdepth = htonl ( src_header->fBitdepth ); | |||
| dst_header->fNMidiPckt = htonl ( src_header->fNMidiPckt ); | |||
| dst_header->fNumPacket = htonl ( src_header->fNumPacket ); | |||
| dst_header->fPacketSize = htonl ( src_header->fPacketSize ); | |||
| dst_header->fCycle = htonl ( src_header->fCycle ); | |||
| dst_header->fSubCycle = htonl ( src_header->fSubCycle ); | |||
| @@ -351,9 +387,8 @@ namespace Jack | |||
| { | |||
| memcpy(dst_header, src_header, sizeof(packet_header_t)); | |||
| dst_header->fID = ntohl ( src_header->fID ); | |||
| dst_header->fMidiDataSize = ntohl ( src_header->fMidiDataSize ); | |||
| dst_header->fBitdepth = ntohl ( src_header->fBitdepth ); | |||
| dst_header->fNMidiPckt = ntohl ( src_header->fNMidiPckt ); | |||
| dst_header->fNumPacket = ntohl ( src_header->fNumPacket ); | |||
| dst_header->fPacketSize = ntohl ( src_header->fPacketSize ); | |||
| dst_header->fCycle = ntohl ( src_header->fCycle ); | |||
| dst_header->fSubCycle = ntohl ( src_header->fSubCycle ); | |||
| @@ -370,8 +405,7 @@ namespace Jack | |||
| jack_info ( "ID : %u", header->fID ); | |||
| jack_info ( "Cycle : %u", header->fCycle ); | |||
| jack_info ( "SubCycle : %u", header->fSubCycle ); | |||
| jack_info ( "Midi packets : %u", header->fNMidiPckt ); | |||
| jack_info ( "Midi data size : %u", header->fMidiDataSize ); | |||
| jack_info ( "Midi packets : %u", header->fNumPacket ); | |||
| jack_info ( "Last packet : '%s'", ( header->fIsLastPckt ) ? "yes" : "no" ); | |||
| jack_info ( "Bitdepth : %s", bitdepth ); | |||
| jack_info ( "**********************************************" ); | |||
| @@ -67,8 +67,8 @@ namespace Jack | |||
| are kept in LITTLE_ENDIAN format (to avoid 2 conversions in the more common LITTLE_ENDIAN <==> LITTLE_ENDIAN connection case). | |||
| */ | |||
| #define MASTER_PROTOCOL 1 | |||
| #define SLAVE_PROTOCOL 1 | |||
| #define MASTER_PROTOCOL 2 | |||
| #define SLAVE_PROTOCOL 2 | |||
| struct _session_params | |||
| { | |||
| @@ -87,7 +87,6 @@ namespace Jack | |||
| uint32_t fReturnMidiChannels; //number of slave->master midi channels | |||
| uint32_t fSampleRate; //session sample rate | |||
| uint32_t fPeriodSize; //period size | |||
| uint32_t fFramesPerPacket; //complete frames per packet | |||
| uint32_t fBitdepth; //samples bitdepth (unused) | |||
| uint32_t fSlaveSyncMode; //is the slave in sync mode ? | |||
| char fNetworkMode; //fast, normal or slow mode | |||
| @@ -159,14 +158,11 @@ namespace Jack | |||
| char fDataStream; //s for send, r for return | |||
| uint32_t fID; //unique ID of the slave | |||
| uint32_t fBitdepth; //bitdepth of the data samples | |||
| uint32_t fMidiDataSize; //size of midi data in bytes | |||
| uint32_t fNMidiPckt; //number of midi packets of the cycle | |||
| uint32_t fNumPacket; //number of data packets of the cycle | |||
| uint32_t fPacketSize; //packet size in bytes | |||
| uint32_t fCycle; //process cycle counter | |||
| uint32_t fSubCycle; //midi/audio subcycle counter | |||
| uint32_t fIsLastPckt; //is it the last packet of a given cycle ('y' or 'n') | |||
| char fASyncWrongCycle; //is the current async cycle wrong (slave's side; 'y' or 'n') | |||
| char fFree[26]; //unused | |||
| }; | |||
| //net timebase master | |||
| @@ -199,8 +195,8 @@ namespace Jack | |||
| int32_t fState; //current cycle state | |||
| jack_position_t fPosition; //current cycle position | |||
| }; | |||
| //midi data *********************************************************************************** | |||
| //midi data *********************************************************************************** | |||
| /** | |||
| \Brief Midi buffer and operations class | |||
| @@ -226,6 +222,8 @@ namespace Jack | |||
| char* fBuffer; | |||
| char* fNetBuffer; | |||
| JackMidiBuffer** fPortBuffer; | |||
| size_t fCycleSize; // needed size in bytes ofr an entire cycle | |||
| public: | |||
| NetMidiBuffer ( session_params_t* params, uint32_t nports, char* net_buffer ); | |||
| @@ -234,6 +232,11 @@ namespace Jack | |||
| void Reset(); | |||
| size_t GetSize(); | |||
| // needed size in bytes for an entire cycle | |||
| size_t GetCycleSize(); | |||
| int GetNumPackets(); | |||
| //utility | |||
| void DisplayEvents(); | |||
| @@ -262,14 +265,21 @@ namespace Jack | |||
| virtual size_t GetSize() = 0; | |||
| // needed syze in bytes ofr an entire cycle | |||
| virtual size_t GetCycleSize() = 0; | |||
| // cycle duration in sec | |||
| virtual float GetCycleDuration() = 0; | |||
| virtual int GetNumPackets() = 0; | |||
| //jack<->buffer | |||
| virtual void RenderFromJackPorts (int subcycle ) = 0; | |||
| virtual void RenderToJackPorts ( int cycle, int subcycle) = 0; | |||
| virtual void FinishRenderToJackPorts (int cycle) = 0; | |||
| virtual int RenderFromJackPorts () = 0; | |||
| virtual int RenderToJackPorts () = 0; | |||
| //network<->buffer | |||
| //int RenderFromNetwork ( int subcycle, size_t copy_size ) = 0; | |||
| //int RenderToNetwork ( int subcycle, size_t total_size ) = 0; | |||
| virtual int RenderFromNetwork ( int cycle, int subcycle, size_t copy_size ) = 0; | |||
| virtual int RenderToNetwork (int subcycle, size_t total_size ) = 0; | |||
| virtual void SetBuffer ( int index, sample_t* buffer ) = 0; | |||
| virtual sample_t* GetBuffer ( int index ) = 0; | |||
| @@ -292,16 +302,39 @@ namespace Jack | |||
| size_t fSubPeriodBytesSize; | |||
| sample_t** fPortBuffer; | |||
| int fNPorts; | |||
| size_t fCycleSize; // needed size in bytes for an entire cycle | |||
| float fCycleDuration; // in dec | |||
| int fLastSubCycle; | |||
| JackPortList(session_params_t* params, uint32_t nports) | |||
| { | |||
| fNPorts = nports; | |||
| fPeriodSize = params->fPeriodSize; | |||
| fSubPeriodSize = params->fFramesPerPacket; | |||
| if (params->fSendAudioChannels == 0 && params->fReturnAudioChannels == 0) { | |||
| fSubPeriodSize = params->fPeriodSize; | |||
| } else { | |||
| jack_nframes_t period = ( int ) powf ( 2.f, ( int ) ( log (float ((params->fMtu - sizeof(packet_header_t))) | |||
| / ( max ( params->fReturnAudioChannels, params->fSendAudioChannels ) * sizeof ( sample_t ) ) ) / log ( 2. ) ) ); | |||
| fSubPeriodSize = ( period > params->fPeriodSize ) ? params->fPeriodSize : period; | |||
| } | |||
| fSubPeriodBytesSize = fSubPeriodSize * sizeof ( sample_t ); | |||
| fPortBuffer = new sample_t* [fNPorts]; | |||
| for ( int port_index = 0; port_index < fNPorts; port_index++ ) | |||
| fPortBuffer[port_index] = NULL; | |||
| fCycleDuration = float(fSubPeriodSize) / float(params->fSampleRate); | |||
| fCycleSize = params->fMtu * ( fPeriodSize / fSubPeriodBytesSize ); | |||
| fLastSubCycle = -1; | |||
| } | |||
| int GetNumPackets() | |||
| { | |||
| return fPeriodSize / fSubPeriodSize; | |||
| } | |||
| JackPortList() | |||
| @@ -338,7 +371,19 @@ namespace Jack | |||
| { | |||
| return fNPorts * fSubPeriodBytesSize; | |||
| } | |||
| // needed syze in bytes ofr an entire cycle | |||
| size_t GetCycleSize() | |||
| { | |||
| return fCycleSize; | |||
| } | |||
| // cycle duration in sec | |||
| float GetCycleDuration() | |||
| { | |||
| return fCycleDuration; | |||
| } | |||
| #ifdef __BIG_ENDIAN__ | |||
| static inline float SwapFloat(float f) | |||
| @@ -357,40 +402,75 @@ namespace Jack | |||
| return dat2.f; | |||
| } | |||
| void RenderFromJackPorts (char* net_buffer, int subcycle ) | |||
| int RenderFromJackPorts () | |||
| { | |||
| for ( int port_index = 0; port_index < fNPorts; port_index++ ) { | |||
| float* src = (float*)(fPortBuffer[port_index] + subcycle * fSubPeriodSize); | |||
| float* dst = (float*)(net_buffer + port_index * fSubPeriodBytesSize); | |||
| for (unsigned int sample = 0; sample < fSubPeriodBytesSize / sizeof(float); sample++) { | |||
| dst[sample] = SwapFloat(src[sample]); | |||
| } | |||
| } | |||
| return fNPorts * fSubPeriodBytesSize; // in bytes | |||
| } | |||
| void RenderToJackPorts (char* net_buffer, int subcycle) | |||
| int RenderToJackPorts () | |||
| { | |||
| for ( int port_index = 0; port_index < fNPorts; port_index++ ) { | |||
| return fPeriodSize * sizeof(sample_t); // in bytes TODO | |||
| } | |||
| //network<->buffer | |||
| int RenderFromNetwork (char* net_buffer, int cycle, int subcycle, size_t copy_size ) | |||
| { | |||
| for ( int port_index = 0; port_index < fNPorts; port_index++ ) { | |||
| float* src = (float*)(net_buffer + port_index * fSubPeriodBytesSize); | |||
| float* dst = (float*)(fPortBuffer[port_index] + subcycle * fSubPeriodSize); | |||
| for (unsigned int sample = 0; sample < fSubPeriodBytesSize / sizeof(float); sample++) { | |||
| dst[sample] = SwapFloat(src[sample]); | |||
| } | |||
| } | |||
| } | |||
| return copy_size; | |||
| } | |||
| int RenderToNetwork (char* net_buffer, int subcycle, size_t total_size ) | |||
| { | |||
| for ( int port_index = 0; port_index < fNPorts; port_index++ ) { | |||
| float* src = (float*)(fPortBuffer[port_index] + subcycle * fSubPeriodSize); | |||
| float* dst = (float*)(net_buffer + port_index * fSubPeriodBytesSize); | |||
| for (unsigned int sample = 0; sample < fSubPeriodBytesSize / sizeof(float); sample++) { | |||
| dst[sample] = SwapFloat(src[sample]); | |||
| } | |||
| } | |||
| return fNPorts * fSubPeriodBytesSize; | |||
| } | |||
| #else | |||
| void RenderFromJackPorts (char* net_buffer, int subcycle ) | |||
| int RenderFromJackPorts () | |||
| { | |||
| for ( int port_index = 0; port_index < fNPorts; port_index++ ) | |||
| memcpy ( net_buffer + port_index * fSubPeriodBytesSize, fPortBuffer[port_index] + subcycle * fSubPeriodSize, fSubPeriodBytesSize ); | |||
| return fNPorts * fSubPeriodBytesSize; // in bytes | |||
| } | |||
| void RenderToJackPorts (char* net_buffer, int subcycle) | |||
| int RenderToJackPorts () | |||
| { | |||
| fLastSubCycle = -1; | |||
| return fPeriodSize * sizeof(sample_t); // in bytes; TODO | |||
| } | |||
| //network<->buffer | |||
| int RenderFromNetwork (char* net_buffer, int cycle, int subcycle, size_t copy_size ) | |||
| { | |||
| for ( int port_index = 0; port_index < fNPorts; port_index++ ) | |||
| memcpy ( fPortBuffer[port_index] + subcycle * fSubPeriodSize, net_buffer + port_index * fSubPeriodBytesSize, fSubPeriodBytesSize ); | |||
| if (subcycle != fLastSubCycle + 1) { | |||
| jack_error("Packet(s) missing from... %d %d", fLastSubCycle, subcycle); | |||
| } | |||
| fLastSubCycle = subcycle; | |||
| return copy_size; | |||
| } | |||
| int RenderToNetwork (char* net_buffer,int subcycle, size_t total_size ) | |||
| { | |||
| for ( int port_index = 0; port_index < fNPorts; port_index++ ) | |||
| memcpy ( net_buffer + port_index * fSubPeriodBytesSize, fPortBuffer[port_index] + subcycle * fSubPeriodSize, fSubPeriodBytesSize ); | |||
| return fNPorts * fSubPeriodBytesSize; | |||
| } | |||
| #endif | |||
| @@ -419,7 +499,15 @@ namespace Jack | |||
| { | |||
| fNPorts = nports; | |||
| fPeriodSize = params->fPeriodSize; | |||
| fSubPeriodSize = params->fFramesPerPacket; | |||
| if (params->fSendAudioChannels == 0 && params->fReturnAudioChannels == 0) { | |||
| fSubPeriodSize = params->fPeriodSize; | |||
| } else { | |||
| jack_nframes_t period = ( int ) powf ( 2.f, ( int ) ( log (float ((params->fMtu - sizeof(packet_header_t))) | |||
| / ( max ( params->fReturnAudioChannels, params->fSendAudioChannels ) * sizeof ( sample_t ) ) ) / log ( 2. ) ) ); | |||
| fSubPeriodSize = ( period > params->fPeriodSize ) ? params->fPeriodSize : period; | |||
| } | |||
| fSubPeriodBytesSize = fSubPeriodSize * sizeof ( sample_t ); | |||
| fPortBuffer = new sample_t* [fNPorts]; | |||
| for ( int port_index = 0; port_index < fNPorts; port_index++ ) | |||
| @@ -439,18 +527,36 @@ namespace Jack | |||
| ~NetSingleAudioBuffer(); | |||
| size_t GetSize(); | |||
| // needed size in bytes for an entire cycle | |||
| size_t GetCycleSize(); | |||
| // cycle duration in sec | |||
| float GetCycleDuration() | |||
| { | |||
| return fPortBuffer.GetCycleDuration(); | |||
| } | |||
| int GetNumPackets() | |||
| { | |||
| return fPortBuffer.GetNumPackets(); | |||
| } | |||
| //jack<->buffer | |||
| void RenderFromJackPorts (int subcycle ); | |||
| void RenderToJackPorts (int cycle, int subcycle); | |||
| int RenderFromJackPorts (); | |||
| int RenderToJackPorts (); | |||
| void SetBuffer ( int index, sample_t* buffer ); | |||
| sample_t* GetBuffer ( int index ); | |||
| void FinishRenderToJackPorts (int cycle) {} | |||
| //network<->buffer | |||
| int RenderFromNetwork ( int cycle, int subcycle, size_t copy_size ); | |||
| int RenderToNetwork (int subcycle, size_t total_size ); | |||
| }; | |||
| #define AUDIO_BUFFER_SIZE 8 | |||
| /* | |||
| class SERVER_EXPORT NetBufferedAudioBuffer : public NetAudioBuffer | |||
| { | |||
| @@ -465,14 +571,36 @@ namespace Jack | |||
| ~NetBufferedAudioBuffer(); | |||
| size_t GetSize(); | |||
| // needed syze in bytes ofr an entire cycle | |||
| size_t GetCycleSize(); | |||
| // cycle duration in sec | |||
| float GetCycleDuration() | |||
| { | |||
| return fPortBuffer[0].GetCycleDuration(); | |||
| } | |||
| //jack<->buffer | |||
| void RenderFromJackPorts (int subcycle ); | |||
| void RenderToJackPorts ( int cycle, int subcycle); | |||
| void FinishRenderToJackPorts (int cycle); | |||
| int RenderFromJackPorts (int subcycle ); | |||
| int RenderToJackPorts ( int cycle, int subcycle); | |||
| //void FinishRenderToJackPorts (int cycle); | |||
| //network<->buffer | |||
| int RenderFromNetwork ( int subcycle, size_t copy_size ) | |||
| { | |||
| // TODO | |||
| return 0; | |||
| } | |||
| int RenderToNetwork ( int subcycle, size_t total_size ) | |||
| { | |||
| // TODO | |||
| return 0; | |||
| } | |||
| void SetBuffer ( int index, sample_t* buffer ); | |||
| sample_t* GetBuffer ( int index ); | |||
| }; | |||
| */ | |||
| //utility ************************************************************************************* | |||
| @@ -33,7 +33,7 @@ static int net_process(jack_nframes_t buffer_size, | |||
| void* data) | |||
| { | |||
| //jack_adapter_pull_and_push(adapter, audio_output_buffer, audio_input_buffer, buffer_size); | |||
| jack_adapter_pull_and_push(adapter, audio_output_buffer, audio_input_buffer, buffer_size); | |||
| // Process input, produce output | |||
| if (audio_input == audio_output) { | |||
| @@ -47,7 +47,7 @@ static int net_process(jack_nframes_t buffer_size, | |||
| static void SlaveAudioCallback(int frames, float** inputs, float** outputs, void* arg) | |||
| { | |||
| //jack_adapter_push_and_pull(adapter, inputs, outputs, frames); | |||
| jack_adapter_push_and_pull(adapter, inputs, outputs, frames); | |||
| } | |||
| //http://www.securityfocus.com/infocus/1884 | |||
| @@ -62,8 +62,8 @@ int main(int argc, char *argv[]) { | |||
| jack_slave_t request = { NUM_INPUT, NUM_OUTPUT, 0, 0, WIFI_MTU, -1, JackSlowMode }; | |||
| jack_master_t result; | |||
| //if ((net = jack_net_slave_open("169.254.121.189", DEFAULT_PORT, "iPhone", &request, &result)) == 0) { | |||
| if ((net = jack_net_slave_open(DEFAULT_MULTICAST_IP, DEFAULT_PORT, "iPhone", &request, &result)) == 0) { | |||
| if ((net = jack_net_slave_open("169.254.46.132", DEFAULT_PORT, "iPhone", &request, &result)) == 0) { | |||
| //if ((net = jack_net_slave_open(DEFAULT_MULTICAST_IP, DEFAULT_PORT, "iPhone", &request, &result)) == 0) { | |||
| return -1; | |||
| } | |||
| @@ -77,6 +77,7 @@ int main(int argc, char *argv[]) { | |||
| return -1; | |||
| } | |||
| TiPhoneCoreAudioRenderer audio_device(NUM_INPUT, NUM_OUTPUT); | |||
| jack_set_net_slave_process_callback(net, net_process, NULL); | |||