git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@2722 0c269be4-1314-0410-8aa9-9f06e86f4224tags/1.90
| @@ -30,24 +30,26 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||||
| #define DEFAULT_MULTICAST_IP "225.3.19.154" | #define DEFAULT_MULTICAST_IP "225.3.19.154" | ||||
| #define DEFAULT_PORT 19000 | #define DEFAULT_PORT 19000 | ||||
| using namespace std; | |||||
| namespace Jack | namespace Jack | ||||
| { | { | ||||
| #ifdef JACK_MONITOR | #ifdef JACK_MONITOR | ||||
| uint JackNetDriver::fMeasureCnt = 50; | |||||
| uint JackNetDriver::fMeasureCnt = 64; | |||||
| uint JackNetDriver::fMeasurePoints = 5; | uint JackNetDriver::fMeasurePoints = 5; | ||||
| uint JackNetDriver::fMonitorPlotOptionsCnt = 2; | uint JackNetDriver::fMonitorPlotOptionsCnt = 2; | ||||
| std::string JackNetDriver::fMonitorPlotOptions[] = | |||||
| string JackNetDriver::fMonitorPlotOptions[] = | |||||
| { | { | ||||
| std::string ( "set xlabel \"audio cycles\"" ), | |||||
| std::string ( "set ylabel \"usecs\"" ) | |||||
| string ( "set xlabel \"audio cycles\"" ), | |||||
| string ( "set ylabel \"% of audio cycle\"" ) | |||||
| }; | }; | ||||
| std::string JackNetDriver::fMonitorFieldNames[] = | |||||
| string JackNetDriver::fMonitorFieldNames[] = | |||||
| { | { | ||||
| std::string ( "cyclestart" ), | |||||
| std::string ( "read end" ), | |||||
| std::string ( "write start" ), | |||||
| std::string ( "sync end" ), | |||||
| std::string ( "send end" ) | |||||
| string ( "cyclestart" ), | |||||
| string ( "read end" ), | |||||
| string ( "write start" ), | |||||
| string ( "sync send" ), | |||||
| string ( "send end" ) | |||||
| }; | }; | ||||
| #endif | #endif | ||||
| @@ -55,6 +57,8 @@ namespace Jack | |||||
| 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 ) | ||||
| : 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 ); | |||||
| fMulticastIP = new char[strlen ( ip ) + 1]; | fMulticastIP = new char[strlen ( ip ) + 1]; | ||||
| strcpy ( fMulticastIP, ip ); | strcpy ( fMulticastIP, ip ); | ||||
| fParams.fMtu = mtu; | fParams.fMtu = mtu; | ||||
| @@ -63,15 +67,6 @@ 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; | ||||
| //monitor | |||||
| #ifdef JACK_MONITOR | |||||
| fMonitor = new NetMonitor<jack_time_t> ( JackNetDriver::fMeasureCnt, JackNetDriver::fMeasurePoints ); | |||||
| fMeasure = new jack_time_t[JackNetDriver::fMeasurePoints]; | |||||
| std::string plot_file_name = std::string ( fParams.fName ); | |||||
| fMonitor->SetPlotFile ( plot_file_name, JackNetDriver::fMonitorPlotOptions, JackNetDriver::fMonitorPlotOptionsCnt, | |||||
| JackNetDriver::fMonitorFieldNames, JackNetDriver::fMeasurePoints ); | |||||
| #endif | |||||
| } | } | ||||
| JackNetDriver::~JackNetDriver() | JackNetDriver::~JackNetDriver() | ||||
| @@ -88,6 +83,7 @@ namespace Jack | |||||
| delete[] fMidiCapturePortList; | delete[] fMidiCapturePortList; | ||||
| delete[] fMidiPlaybackPortList; | delete[] fMidiPlaybackPortList; | ||||
| #ifdef JACK_MONITOR | #ifdef JACK_MONITOR | ||||
| fMonitor->Save(); | |||||
| delete[] fMeasure; | delete[] fMeasure; | ||||
| delete fMonitor; | delete fMonitor; | ||||
| #endif | #endif | ||||
| @@ -108,16 +104,6 @@ namespace Jack | |||||
| return res; | return res; | ||||
| } | } | ||||
| #ifdef JACK_MONITOR | |||||
| int JackNetDriver::Close() | |||||
| { | |||||
| std::string filename = string ( fParams.fName ); | |||||
| fMonitor->Save ( filename ); | |||||
| return JackDriver::Close(); | |||||
| } | |||||
| #endif | |||||
| int JackNetDriver::Attach() | int JackNetDriver::Attach() | ||||
| { | { | ||||
| return 0; | return 0; | ||||
| @@ -256,22 +242,26 @@ namespace Jack | |||||
| { | { | ||||
| jack_info ( "Restarting driver..." ); | jack_info ( "Restarting driver..." ); | ||||
| delete[] fTxBuffer; | delete[] fTxBuffer; | ||||
| fTxBuffer = NULL; | |||||
| delete[] fRxBuffer; | delete[] fRxBuffer; | ||||
| fRxBuffer = NULL; | |||||
| delete fNetAudioCaptureBuffer; | delete fNetAudioCaptureBuffer; | ||||
| fNetAudioCaptureBuffer = NULL; | |||||
| delete fNetAudioPlaybackBuffer; | delete fNetAudioPlaybackBuffer; | ||||
| fNetAudioPlaybackBuffer = NULL; | |||||
| delete fNetMidiCaptureBuffer; | delete fNetMidiCaptureBuffer; | ||||
| fNetMidiCaptureBuffer = NULL; | |||||
| delete fNetMidiPlaybackBuffer; | delete fNetMidiPlaybackBuffer; | ||||
| fNetMidiPlaybackBuffer = NULL; | |||||
| FreePorts(); | FreePorts(); | ||||
| delete[] fMidiCapturePortList; | delete[] fMidiCapturePortList; | ||||
| delete[] fMidiPlaybackPortList; | |||||
| fTxBuffer = NULL; | |||||
| fRxBuffer = NULL; | |||||
| fNetAudioCaptureBuffer = NULL; | |||||
| fNetAudioPlaybackBuffer = NULL; | |||||
| fNetMidiCaptureBuffer = NULL; | |||||
| fNetMidiPlaybackBuffer = NULL; | |||||
| fMidiCapturePortList = NULL; | fMidiCapturePortList = NULL; | ||||
| delete[] fMidiPlaybackPortList; | |||||
| fMidiPlaybackPortList = NULL; | fMidiPlaybackPortList = NULL; | ||||
| delete[] fMeasure; | |||||
| fMeasure = NULL; | |||||
| delete fMonitor; | |||||
| fMonitor = NULL; | |||||
| } | } | ||||
| int JackNetDriver::SetParams() | int JackNetDriver::SetParams() | ||||
| @@ -335,6 +325,17 @@ namespace Jack | |||||
| //payload size | //payload size | ||||
| fPayloadSize = fParams.fMtu - sizeof ( packet_header_t ); | fPayloadSize = fParams.fMtu - sizeof ( packet_header_t ); | ||||
| //monitor | |||||
| #ifdef JACK_MONITOR | |||||
| string plot_name = string ( fParams.fName ); | |||||
| plot_name += string ( "_slave_" ); | |||||
| plot_name += ( fEngineControl->fSyncMode ) ? string ( "sync" ) : string ( "async" ); | |||||
| fMonitor = new JackGnuPlotMonitor<float> ( JackNetDriver::fMeasureCnt, JackNetDriver::fMeasurePoints, plot_name ); | |||||
| fMeasure = new float[JackNetDriver::fMeasurePoints]; | |||||
| fMonitor->SetPlotFile ( JackNetDriver::fMonitorPlotOptions, JackNetDriver::fMonitorPlotOptionsCnt, | |||||
| JackNetDriver::fMonitorFieldNames, JackNetDriver::fMeasurePoints ); | |||||
| #endif | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| @@ -528,8 +529,8 @@ namespace Jack | |||||
| JackDriver::CycleTakeBeginTime(); | JackDriver::CycleTakeBeginTime(); | ||||
| #ifdef JACK_MONITOR | #ifdef JACK_MONITOR | ||||
| fUsecCycleStart = GetMicroSeconds(); | |||||
| fMeasure[0] = GetMicroSeconds() - fUsecCycleStart; | |||||
| fMeasureId = 0; | |||||
| fMeasure[fMeasureId++] = ( ( (float)(GetMicroSeconds() - JackDriver::fBeginDateUst) ) / (float)fEngineControl->fPeriodUsecs ) * 100.f; | |||||
| #endif | #endif | ||||
| //audio, midi or sync if driver is late | //audio, midi or sync if driver is late | ||||
| @@ -572,7 +573,7 @@ namespace Jack | |||||
| #ifdef JACK_MONITOR | #ifdef JACK_MONITOR | ||||
| fMeasure[1] = GetMicroSeconds() - fUsecCycleStart; | |||||
| fMeasure[fMeasureId++] = ( ( (float)(GetMicroSeconds() - JackDriver::fBeginDateUst) ) / (float)fEngineControl->fPeriodUsecs ) * 100.f; | |||||
| #endif | #endif | ||||
| return 0; | return 0; | ||||
| @@ -594,7 +595,7 @@ namespace Jack | |||||
| fNetAudioPlaybackBuffer->SetBuffer(audio_port_index, GetOutputBuffer ( audio_port_index )); | fNetAudioPlaybackBuffer->SetBuffer(audio_port_index, GetOutputBuffer ( audio_port_index )); | ||||
| #ifdef JACK_MONITOR | #ifdef JACK_MONITOR | ||||
| fMeasure[2] = GetMicroSeconds() - fUsecCycleStart; | |||||
| fMeasure[fMeasureId++] = ( ( (float)(GetMicroSeconds() - JackDriver::fBeginDateUst) ) / (float)fEngineControl->fPeriodUsecs ) * 100.f; | |||||
| #endif | #endif | ||||
| //sync | //sync | ||||
| @@ -606,7 +607,7 @@ namespace Jack | |||||
| tx_bytes = Send ( fParams.fMtu, 0 ); | tx_bytes = Send ( fParams.fMtu, 0 ); | ||||
| #ifdef JACK_MONITOR | #ifdef JACK_MONITOR | ||||
| fMeasure[3] = GetMicroSeconds() - fUsecCycleStart; | |||||
| fMeasure[fMeasureId++] = ( ( (float)(GetMicroSeconds() - JackDriver::fBeginDateUst) ) / (float)fEngineControl->fPeriodUsecs ) * 100.f; | |||||
| #endif | #endif | ||||
| //midi | //midi | ||||
| @@ -642,7 +643,7 @@ namespace Jack | |||||
| } | } | ||||
| #ifdef JACK_MONITOR | #ifdef JACK_MONITOR | ||||
| fMeasure[4] = GetMicroSeconds() - fUsecCycleStart; | |||||
| fMeasure[fMeasureId++] = ( ( (float)(GetMicroSeconds() - JackDriver::fBeginDateUst) ) / (float)fEngineControl->fPeriodUsecs ) * 100.f; | |||||
| fMonitor->Write ( fMeasure ); | fMonitor->Write ( fMeasure ); | ||||
| #endif | #endif | ||||
| @@ -24,6 +24,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||||
| #include "JackAudioDriver.h" | #include "JackAudioDriver.h" | ||||
| #include "JackNetTool.h" | #include "JackNetTool.h" | ||||
| #ifdef JACK_MONITOR | |||||
| #include "JackFrameTimer.h" | |||||
| #endif | |||||
| namespace Jack | namespace Jack | ||||
| { | { | ||||
| class JackNetDriver : public JackAudioDriver | class JackNetDriver : public JackAudioDriver | ||||
| @@ -67,9 +71,9 @@ namespace Jack | |||||
| static uint fMonitorPlotOptionsCnt; | static uint fMonitorPlotOptionsCnt; | ||||
| static std::string fMonitorPlotOptions[]; | static std::string fMonitorPlotOptions[]; | ||||
| static std::string fMonitorFieldNames[]; | static std::string fMonitorFieldNames[]; | ||||
| jack_time_t* fMeasure; | |||||
| NetMonitor<jack_time_t>* fMonitor; | |||||
| jack_time_t fUsecCycleStart; | |||||
| float* fMeasure; | |||||
| int fMeasureId; | |||||
| JackGnuPlotMonitor<float>* fMonitor; | |||||
| #endif | #endif | ||||
| bool Init(); | bool Init(); | ||||
| @@ -98,10 +102,6 @@ namespace Jack | |||||
| int inchannels, int outchannels, bool monitor, const char* capture_driver_name, | int inchannels, int outchannels, bool monitor, const char* capture_driver_name, | ||||
| const char* playback_driver_name, jack_nframes_t capture_latency, jack_nframes_t playback_latency ); | const char* playback_driver_name, jack_nframes_t capture_latency, jack_nframes_t playback_latency ); | ||||
| #ifdef JACK_MONITOR | |||||
| int Close(); | |||||
| #endif | |||||
| int Attach(); | int Attach(); | ||||
| int Detach(); | int Detach(); | ||||
| @@ -31,18 +31,18 @@ namespace Jack | |||||
| uint JackNetMaster::fMeasureCnt = 50; | uint JackNetMaster::fMeasureCnt = 50; | ||||
| uint JackNetMaster::fMeasurePoints = 5; | uint JackNetMaster::fMeasurePoints = 5; | ||||
| uint JackNetMaster::fMonitorPlotOptionsCnt = 2; | uint JackNetMaster::fMonitorPlotOptionsCnt = 2; | ||||
| std::string JackNetMaster::fMonitorPlotOptions[] = | |||||
| string JackNetMaster::fMonitorPlotOptions[] = | |||||
| { | { | ||||
| std::string ( "set xlabel \"audio cycles\"" ), | |||||
| std::string ( "set ylabel \"audio frames\"" ) | |||||
| string ( "set xlabel \"audio cycles\"" ), | |||||
| string ( "set ylabel \"% of audio cycle\"" ) | |||||
| }; | }; | ||||
| std::string JackNetMaster::fMonitorFieldNames[] = | |||||
| string JackNetMaster::fMonitorFieldNames[] = | |||||
| { | { | ||||
| std::string ( "cycle start" ), | |||||
| std::string ( "sync send" ), | |||||
| std::string ( "send end" ), | |||||
| std::string ( "sync recv" ), | |||||
| std::string ( "end of cycle" ) | |||||
| string ( "cycle start" ), | |||||
| string ( "sync send" ), | |||||
| string ( "send end" ), | |||||
| string ( "sync recv" ), | |||||
| string ( "end of cycle" ) | |||||
| }; | }; | ||||
| #endif | #endif | ||||
| @@ -119,10 +119,12 @@ namespace Jack | |||||
| //monitor | //monitor | ||||
| #ifdef JACK_MONITOR | #ifdef JACK_MONITOR | ||||
| fMonitor = new NetMonitor<jack_nframes_t> ( JackNetMaster::fMeasureCnt, JackNetMaster::fMeasurePoints ); | |||||
| fMeasure = new jack_nframes_t[JackNetMaster::fMeasurePoints]; | |||||
| std::string plot_file_name = std::string ( fParams.fName ); | |||||
| fMonitor->SetPlotFile ( plot_file_name, JackNetMaster::fMonitorPlotOptions, JackNetMaster::fMonitorPlotOptionsCnt, | |||||
| string plot_name = string ( fParams.fName ); | |||||
| plot_name += string ( "_master" ); | |||||
| //plot_name += ( fEngineControl->fSyncMode ) ? string ( "sync" ) : string ( "async" ); | |||||
| fMonitor = new JackGnuPlotMonitor<float> ( JackNetMaster::fMeasureCnt, JackNetMaster::fMeasurePoints, plot_name ); | |||||
| fMeasure = new float[JackNetMaster::fMeasurePoints]; | |||||
| fMonitor->SetPlotFile ( JackNetMaster::fMonitorPlotOptions, JackNetMaster::fMonitorPlotOptionsCnt, | |||||
| JackNetMaster::fMonitorFieldNames, JackNetMaster::fMeasurePoints ); | JackNetMaster::fMonitorFieldNames, JackNetMaster::fMeasurePoints ); | ||||
| #endif | #endif | ||||
| } | } | ||||
| @@ -148,8 +150,7 @@ namespace Jack | |||||
| delete[] fTxBuffer; | delete[] fTxBuffer; | ||||
| delete[] fRxBuffer; | delete[] fRxBuffer; | ||||
| #ifdef JACK_MONITOR | #ifdef JACK_MONITOR | ||||
| std::string filename = string ( fParams.fName ); | |||||
| fMonitor->Save ( filename ); | |||||
| fMonitor->Save(); | |||||
| delete[] fMeasure; | delete[] fMeasure; | ||||
| delete fMonitor; | delete fMonitor; | ||||
| #endif | #endif | ||||
| @@ -394,7 +395,8 @@ fail: | |||||
| packet_header_t* rx_head = reinterpret_cast<packet_header_t*> ( fRxBuffer ); | packet_header_t* rx_head = reinterpret_cast<packet_header_t*> ( fRxBuffer ); | ||||
| #ifdef JACK_MONITOR | #ifdef JACK_MONITOR | ||||
| fMeasure[0] = jack_frames_since_cycle_start( fJackClient ); | |||||
| fMeasureId = 0; | |||||
| fMeasure[fMeasureId++] = ( (float)jack_frames_since_cycle_start( fJackClient ) /(float)fParams.fPeriodSize ) * 100.f; | |||||
| #endif | #endif | ||||
| //buffers | //buffers | ||||
| @@ -428,7 +430,7 @@ fail: | |||||
| return tx_bytes; | return tx_bytes; | ||||
| #ifdef JACK_MONITOR | #ifdef JACK_MONITOR | ||||
| fMeasure[1] = jack_frames_since_cycle_start( fJackClient ); | |||||
| fMeasure[fMeasureId++] = ( (float)jack_frames_since_cycle_start( fJackClient ) /(float)fParams.fPeriodSize ) * 100.f; | |||||
| #endif | #endif | ||||
| //midi | //midi | ||||
| @@ -468,7 +470,7 @@ fail: | |||||
| } | } | ||||
| #ifdef JACK_MONITOR | #ifdef JACK_MONITOR | ||||
| fMeasure[2] = jack_frames_since_cycle_start( fJackClient ); | |||||
| fMeasure[fMeasureId++] = ( (float)jack_frames_since_cycle_start( fJackClient ) /(float)fParams.fPeriodSize ) * 100.f; | |||||
| #endif | #endif | ||||
| //receive -------------------------------------------------------------------------------------------------------------------- | //receive -------------------------------------------------------------------------------------------------------------------- | ||||
| @@ -482,7 +484,7 @@ fail: | |||||
| while ( !rx_bytes && ( rx_head->fDataType != 's' ) ); | while ( !rx_bytes && ( rx_head->fDataType != 's' ) ); | ||||
| #ifdef JACK_MONITOR | #ifdef JACK_MONITOR | ||||
| fMeasure[3] = jack_frames_since_cycle_start( fJackClient ); | |||||
| fMeasure[fMeasureId++] = ( (float)jack_frames_since_cycle_start( fJackClient ) /(float)fParams.fPeriodSize ) * 100.f; | |||||
| #endif | #endif | ||||
| if ( fParams.fReturnMidiChannels || fParams.fReturnAudioChannels ) | if ( fParams.fReturnMidiChannels || fParams.fReturnAudioChannels ) | ||||
| @@ -524,7 +526,7 @@ fail: | |||||
| } | } | ||||
| #ifdef JACK_MONITOR | #ifdef JACK_MONITOR | ||||
| fMeasure[4] = jack_frames_since_cycle_start( fJackClient ); | |||||
| fMeasure[fMeasureId++] = ( (float)jack_frames_since_cycle_start( fJackClient ) /(float)fParams.fPeriodSize ) * 100.f; | |||||
| fMonitor->Write ( fMeasure ); | fMonitor->Write ( fMeasure ); | ||||
| #endif | #endif | ||||
| return 0; | return 0; | ||||
| @@ -85,8 +85,9 @@ namespace Jack | |||||
| static uint fMonitorPlotOptionsCnt; | static uint fMonitorPlotOptionsCnt; | ||||
| static std::string fMonitorPlotOptions[]; | static std::string fMonitorPlotOptions[]; | ||||
| static std::string fMonitorFieldNames[]; | static std::string fMonitorFieldNames[]; | ||||
| jack_nframes_t* fMeasure; | |||||
| NetMonitor<jack_nframes_t>* fMonitor; | |||||
| float* fMeasure; | |||||
| int fMeasureId; | |||||
| JackGnuPlotMonitor<float>* fMonitor; | |||||
| #endif | #endif | ||||
| bool Init(); | bool Init(); | ||||
| @@ -24,9 +24,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||||
| #include "JackTools.h" | #include "JackTools.h" | ||||
| #include "JackPlatformNetSocket.h" | #include "JackPlatformNetSocket.h" | ||||
| #include "types.h" | #include "types.h" | ||||
| #include <string> | |||||
| #include <algorithm> | |||||
| #include <cmath> | #include <cmath> | ||||
| using namespace std; | using namespace std; | ||||
| @@ -172,128 +169,6 @@ namespace Jack | |||||
| void SetBuffer(int index, sample_t* buffer); | void SetBuffer(int index, sample_t* buffer); | ||||
| }; | }; | ||||
| // net monitor ******************************************************************************** | |||||
| template <class T> class NetMonitor | |||||
| { | |||||
| private: | |||||
| uint fMeasureCnt; | |||||
| uint fMeasurePoints; | |||||
| T** fMeasureTable; | |||||
| uint fTablePos; | |||||
| void DisplayMeasure ( T* measure ) | |||||
| { | |||||
| string display; | |||||
| for ( uint m_id = 0; m_id < fMeasurePoints; m_id++ ) | |||||
| { | |||||
| char* value; | |||||
| sprintf ( value, "%llu ", measure[m_id] ); | |||||
| display += string ( value ); | |||||
| } | |||||
| cout << "NetMonitor:: '" << display << "'" << endl; | |||||
| } | |||||
| public: | |||||
| NetMonitor ( uint measure_cnt = 512, uint measure_points = 5 ) | |||||
| { | |||||
| jack_log ( "JackNetMonitor::JackNetMonitor measure_cnt %u measure_points %u", measure_cnt, measure_points ); | |||||
| fMeasureCnt = measure_cnt; | |||||
| fMeasurePoints = measure_points; | |||||
| fTablePos = 0; | |||||
| //allocate measure table | |||||
| fMeasureTable = new T*[fMeasureCnt]; | |||||
| for ( uint i = 0; i < fMeasureCnt; i++ ) | |||||
| fMeasureTable[i] = new T[fMeasurePoints]; | |||||
| //init measure table | |||||
| for ( uint cnt = 0; cnt < fMeasureCnt; cnt++ ) | |||||
| for ( uint point = 0; point < fMeasurePoints; point++ ) | |||||
| fMeasureTable[cnt][point] = 0; | |||||
| } | |||||
| ~NetMonitor() | |||||
| { | |||||
| jack_log ( "NetMonitor::~NetMonitor" ); | |||||
| for ( uint cnt = 0; cnt < fMeasureCnt; cnt++ ) | |||||
| delete[] fMeasureTable[cnt]; | |||||
| delete[] fMeasureTable; | |||||
| } | |||||
| void InitTable() | |||||
| { | |||||
| for ( uint cnt = 0; cnt < fMeasureCnt; cnt++ ) | |||||
| for ( uint point = 0; point < fMeasurePoints; point++ ) | |||||
| fMeasureTable[cnt][point] = 0; | |||||
| } | |||||
| uint Write ( T* measure ) | |||||
| { | |||||
| for ( uint point = 0; point < fMeasurePoints; point++ ) | |||||
| fMeasureTable[fTablePos][point] = measure[point]; | |||||
| if ( ++fTablePos == fMeasureCnt ) | |||||
| fTablePos = 0; | |||||
| return fTablePos; | |||||
| } | |||||
| int Save ( string& filename ) | |||||
| { | |||||
| filename += "_netmonitor.log"; | |||||
| jack_log ( "JackNetMonitor::Save filename %s", filename.c_str() ); | |||||
| FILE* file = fopen ( filename.c_str(), "w" ); | |||||
| //print each measure with tab separated values | |||||
| for ( uint cnt = 0; cnt < fMeasureCnt; cnt++ ) | |||||
| { | |||||
| for ( uint pt = 0; pt < fMeasurePoints; pt++ ) | |||||
| fprintf ( file, "%llu \t ", fMeasureTable[cnt][pt] ); | |||||
| fprintf ( file, "\n" ); | |||||
| } | |||||
| fclose(file); | |||||
| return 0; | |||||
| } | |||||
| int SetPlotFile ( string& name, string* options_list = NULL, uint options_number = 0, string* field_names = NULL, uint field_number = 0 ) | |||||
| { | |||||
| //names and file | |||||
| string title = name + "_netmonitor"; | |||||
| string plot_filename = title + ".plt"; | |||||
| string data_filename = title + ".log"; | |||||
| FILE* file = fopen ( plot_filename.c_str(), "w" ); | |||||
| //base options | |||||
| fprintf ( file, "set multiplot\n" ); | |||||
| fprintf ( file, "set grid\n" ); | |||||
| fprintf ( file, "set title \"%s\"\n", title.c_str() ); | |||||
| //additional options | |||||
| for ( uint i = 0; i < options_number; i++ ) | |||||
| { | |||||
| jack_log ( "JackNetMonitor::SetPlotFile - Add plot option : '%s'", options_list[i].c_str() ); | |||||
| fprintf ( file, "%s\n", options_list[i].c_str() ); | |||||
| } | |||||
| //plot | |||||
| fprintf ( file, "plot " ); | |||||
| for ( uint row = 1; row <= field_number; row++ ) | |||||
| { | |||||
| jack_log ( "JackNetMonitor::SetPlotFile - Add plot : file '%s' row '%d' title '%s' field '%s'", | |||||
| data_filename.c_str(), row, name.c_str(), field_names[row-1].c_str() ); | |||||
| fprintf ( file, "\"%s\" using %u title \"%s : %s\" with lines", data_filename.c_str(), row, name.c_str(), field_names[row-1].c_str() ); | |||||
| fprintf ( file, ( row < field_number ) ? "," : "\n" ); | |||||
| } | |||||
| jack_log ( "JackNetMonitor::SetPlotFile - Saving GnuPlot '.plt' file to '%s'", plot_filename.c_str() ); | |||||
| fclose ( file ); | |||||
| return 0; | |||||
| } | |||||
| }; | |||||
| //utility ************************************************************************************* | //utility ************************************************************************************* | ||||
| //socket API management | //socket API management | ||||
| @@ -23,7 +23,6 @@ | |||||
| #include "JackConstants.h" | #include "JackConstants.h" | ||||
| #include "JackTools.h" | #include "JackTools.h" | ||||
| #include "JackError.h" | |||||
| #include <stdlib.h> | #include <stdlib.h> | ||||
| #include <stdio.h> | #include <stdio.h> | ||||
| @@ -35,56 +35,181 @@ | |||||
| #include <string> | #include <string> | ||||
| #include <algorithm> | #include <algorithm> | ||||
| #include <vector> | #include <vector> | ||||
| #include <iostream> | |||||
| #include <fstream> | |||||
| #include <strstream> | |||||
| #include "jslist.h" | #include "jslist.h" | ||||
| #include "driver_interface.h" | #include "driver_interface.h" | ||||
| #include "JackExports.h" | #include "JackExports.h" | ||||
| #include "JackError.h" | |||||
| namespace Jack | namespace Jack | ||||
| { | { | ||||
| /*! | |||||
| \brief Utility functions. | |||||
| */ | |||||
| struct EXPORT JackTools | |||||
| { | |||||
| static int GetPID(); | |||||
| static int GetUID(); | |||||
| static char* UserDir(); | |||||
| static char* ServerDir(const char* server_name, char* server_dir); | |||||
| static const char* DefaultServerName(); | |||||
| static void CleanupFiles(const char* server_name); | |||||
| static int GetTmpdir(); | |||||
| static void RewriteName(const char* name, char* new_name); | |||||
| }; | |||||
| /*! | |||||
| \brief Internal cient command line parser. | |||||
| */ | |||||
| class EXPORT JackArgParser | |||||
| { | |||||
| /*! | |||||
| \brief Utility functions. | |||||
| */ | |||||
| struct EXPORT JackTools | |||||
| { | |||||
| static int GetPID(); | |||||
| static int GetUID(); | |||||
| static char* UserDir(); | |||||
| static char* ServerDir(const char* server_name, char* server_dir); | |||||
| static const char* DefaultServerName(); | |||||
| static void CleanupFiles(const char* server_name); | |||||
| static int GetTmpdir(); | |||||
| static void RewriteName(const char* name, char* new_name); | |||||
| }; | |||||
| /*! | |||||
| \brief Internal cient command line parser. | |||||
| */ | |||||
| class EXPORT JackArgParser | |||||
| { | |||||
| private: | private: | ||||
| std::string fArgString; | std::string fArgString; | ||||
| int fArgc; | int fArgc; | ||||
| std::vector<std::string> fArgv; | std::vector<std::string> fArgv; | ||||
| public: | public: | ||||
| JackArgParser(const char* arg); | JackArgParser(const char* arg); | ||||
| ~JackArgParser(); | ~JackArgParser(); | ||||
| std::string GetArgString(); | |||||
| std::string GetArgString(); | |||||
| int GetNumArgv(); | int GetNumArgv(); | ||||
| int GetArgc(); | int GetArgc(); | ||||
| int GetArgv(std::vector<std::string>& argv); | int GetArgv(std::vector<std::string>& argv); | ||||
| int GetArgv(char** argv); | int GetArgv(char** argv); | ||||
| void DeleteArgv(const char** argv); | void DeleteArgv(const char** argv); | ||||
| int ParseParams(jack_driver_desc_t* desc, JSList** param_list); | int ParseParams(jack_driver_desc_t* desc, JSList** param_list); | ||||
| }; | |||||
| }; | |||||
| /*! | |||||
| \brief Generic monitoring class. Saves data to GnuPlot files ('.plt' and '.log' datafile) | |||||
| */ | |||||
| template <class T> class JackGnuPlotMonitor | |||||
| { | |||||
| private: | |||||
| uint32_t fMeasureCnt; | |||||
| uint32_t fMeasurePoints; | |||||
| T** fMeasureTable; | |||||
| uint32_t fTablePos; | |||||
| std::string fName; | |||||
| void DisplayMeasure ( T* measure ) | |||||
| { | |||||
| std::string display; | |||||
| for ( uint32_t m_id = 0; m_id < fMeasurePoints; m_id++ ) | |||||
| { | |||||
| std::ostrstream value ( display, measure[m_id] ); | |||||
| display += std::string ( " " ); | |||||
| } | |||||
| std::cout << "JackGnuPlotMonitor::Display '" << display << "'" << std::endl; | |||||
| } | |||||
| public: | |||||
| JackGnuPlotMonitor ( uint32_t measure_cnt = 512, uint32_t measure_points = 5, std::string name = std::string ( "default" ) ) | |||||
| { | |||||
| jack_log ( "JackGnuPlotMonitor::JackGnuPlotMonitor measure_cnt %u measure_points %u", measure_cnt, measure_points ); | |||||
| fMeasureCnt = measure_cnt; | |||||
| fMeasurePoints = measure_points; | |||||
| fTablePos = 0; | |||||
| fName = name; | |||||
| fMeasureTable = new T*[fMeasureCnt]; | |||||
| for ( uint32_t cnt = 0; cnt < fMeasureCnt; cnt++ ) | |||||
| { | |||||
| fMeasureTable[cnt] = new T[fMeasurePoints]; | |||||
| fill_n ( fMeasureTable[cnt], fMeasurePoints, 0 ); | |||||
| } | |||||
| } | |||||
| ~JackGnuPlotMonitor() | |||||
| { | |||||
| jack_log ( "JackGnuPlotMonitor::~JackGnuPlotMonitor" ); | |||||
| for ( uint32_t cnt = 0; cnt < fMeasureCnt; cnt++ ) | |||||
| delete[] fMeasureTable[cnt]; | |||||
| delete[] fMeasureTable; | |||||
| } | |||||
| void InitTable() | |||||
| { | |||||
| for ( uint32_t cnt = 0; cnt < fMeasureCnt; cnt++ ) | |||||
| for ( uint32_t point = 0; point < fMeasurePoints; point++ ) | |||||
| fMeasureTable[cnt][point] = 0; | |||||
| } | |||||
| uint32_t Write ( T* measure ) | |||||
| { | |||||
| for ( uint32_t point = 0; point < fMeasurePoints; point++ ) | |||||
| fMeasureTable[fTablePos][point] = measure[point]; | |||||
| if ( ++fTablePos == fMeasureCnt ) | |||||
| fTablePos = 0; | |||||
| return fTablePos; | |||||
| } | |||||
| int Save ( std::string name = std::string ( "" ) ) | |||||
| { | |||||
| std::string filename = ( name.empty() ) ? fName : name; | |||||
| filename += ".log"; | |||||
| jack_log ( "JackGnuPlotMonitor::Save filename %s", filename.c_str() ); | |||||
| std::ofstream file ( filename.c_str() ); | |||||
| for ( uint32_t cnt = 0; cnt < fMeasureCnt; cnt++ ) | |||||
| { | |||||
| for ( uint32_t point = 0; point < fMeasurePoints; point++ ) | |||||
| file << fMeasureTable[cnt][point] << " \t"; | |||||
| file << std::endl; | |||||
| } | |||||
| file.close(); | |||||
| return 0; | |||||
| } | |||||
| int SetPlotFile ( std::string* options_list = NULL, uint32_t options_number = 0, | |||||
| std::string* field_names = NULL, uint32_t field_number = 0, | |||||
| std::string name = std::string ( "" ) ) | |||||
| { | |||||
| std::string title = ( name.empty() ) ? fName : name; | |||||
| std::string plot_filename = title + ".plt"; | |||||
| std::string data_filename = title + ".log"; | |||||
| std::ofstream file ( plot_filename.c_str() ); | |||||
| file << "set multiplot" << std::endl; | |||||
| file << "set grid" << std::endl; | |||||
| file << "set title \"" << title << "\"" << std::endl; | |||||
| for ( uint32_t i = 0; i < options_number; i++ ) | |||||
| { | |||||
| jack_log ( "JackGnuPlotMonitor::SetPlotFile - Add plot option : '%s'", options_list[i].c_str() ); | |||||
| file << options_list[i] << std::endl; | |||||
| } | |||||
| file << "plot "; | |||||
| for ( uint32_t row = 1; row <= field_number; row++ ) | |||||
| { | |||||
| jack_log ( "JackGnuPlotMonitor::SetPlotFile - Add plot : file '%s' row '%d' title '%s' field '%s'", | |||||
| data_filename.c_str(), row, name.c_str(), field_names[row-1].c_str() ); | |||||
| file << "\"" << data_filename << "\" using " << row << " title \"" << title << " : " << field_names[row-1] << "\" with lines"; | |||||
| file << ( ( row < field_number ) ? ", " : "\n" ); | |||||
| } | |||||
| jack_log ( "JackGnuPlotMonitor::SetPlotFile - Saving GnuPlot '.plt' file to '%s'", plot_filename.c_str() ); | |||||
| file.close(); | |||||
| return 0; | |||||
| } | |||||
| }; | |||||
| } | } | ||||
| #endif | #endif | ||||