JackTools.h 7.29 KB
Newer Older
1
/*
2
  Copyright (C) 2006-2008 Grame
sletz's avatar
sletz committed
3

4
5
6
7
  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU Lesser General Public License as published by
  the Free Software Foundation; either version 2.1 of the License, or
  (at your option) any later version.
sletz's avatar
sletz committed
8

9
10
11
12
  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU Lesser General Public License for more details.
sletz's avatar
sletz committed
13

14
  You should have received a copy of the GNU Lesser General Public License
sletz's avatar
sletz committed
15
  along with this program; if not, write to the Free Software
16
17
18
19
20
21
22
23
  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

*/

#ifndef __JackTools__
#define __JackTools__

#ifdef WIN32
sletz's avatar
sletz committed
24
#include <windows.h>
25
#else
sletz's avatar
sletz committed
26
27
28
#include <sys/types.h>
#include <unistd.h>
#include <dirent.h>
29
30
#endif

sletz's avatar
sletz committed
31
#ifdef __APPLE__
sletz's avatar
sletz committed
32
#include <sys/syslimits.h>
sletz's avatar
sletz committed
33
34
#endif

35
36
37
#include <string>
#include <algorithm>
#include <vector>
38
39
#include <iostream>
#include <fstream>
40
41
#include "jslist.h"
#include "driver_interface.h"
42

43
#include "JackExports.h"
44
#include "JackError.h"
45

46
47
48
namespace Jack
{

49
50
51
52
53
54
55
56
57
58
    /*!
    \brief Utility functions.
    */

    struct EXPORT JackTools
    {
        static int GetPID();
        static int GetUID();

        static char* UserDir();
moret's avatar
moret committed
59
        static char* ServerDir ( const char* server_name, char* server_dir );
60
        static const char* DefaultServerName();
moret's avatar
moret committed
61
        static void CleanupFiles ( const char* server_name );
62
        static int GetTmpdir();
moret's avatar
moret committed
63
        static void RewriteName ( const char* name, char* new_name );
64
65
66
67
68
69
70
71
    };

    /*!
    \brief Internal cient command line parser.
    */

    class EXPORT JackArgParser
    {
moret's avatar
moret committed
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
        private:

            std::string fArgString;
            int fArgc;
            std::vector<std::string> fArgv;

        public:

            JackArgParser ( const char* arg );
            ~JackArgParser();
            std::string GetArgString();
            int GetNumArgv();
            int GetArgc();
            int GetArgv ( std::vector<std::string>& argv );
            int GetArgv ( char** argv );
            void DeleteArgv ( const char** argv );
            int ParseParams ( jack_driver_desc_t* desc, JSList** param_list );
89
90
91
92
    };

    /*!
    \brief Generic monitoring class. Saves data to GnuPlot files ('.plt' and '.log' datafile)
93
94
95
96
97
98
99
100
101
102
103
104
105

    This template class allows to manipulate monitoring records, and automatically generate the GnuPlot config and data files.
    Operations are RT safe because it uses fixed size data buffers.
    You can set the number of measure points, and the number of records.

    To use it :
    - create a JackGnuPlotMonitor, you can use the data type you want.
    - create a temporary array for your measure
    - once you have filled this array with 'measure points' value, call write() to add it to the record
    - once you've done with your measurment, just call save() to save your data file

    You can also call SetPlotFile() to automatically generate '.plt' file from an options list.

106
107
108
109
    */

    template <class T> class JackGnuPlotMonitor
    {
moret's avatar
moret committed
110
111
112
        private:
            uint32_t fMeasureCnt;
            uint32_t fMeasurePoints;
moret's avatar
Cleanup    
moret committed
113
114
            uint32_t fMeasureId;
            T* fCurrentMeasure;
moret's avatar
moret committed
115
116
117
118
119
120
            T** fMeasureTable;
            uint32_t fTablePos;
            std::string fName;

        public:
            JackGnuPlotMonitor ( uint32_t measure_cnt = 512, uint32_t measure_points = 5, std::string name = std::string ( "default" ) )
121
            {
moret's avatar
moret committed
122
                jack_log ( "JackGnuPlotMonitor::JackGnuPlotMonitor %u measure points - %u measures", measure_points, measure_cnt );
123

moret's avatar
moret committed
124
125
126
127
                fMeasureCnt = measure_cnt;
                fMeasurePoints = measure_points;
                fTablePos = 0;
                fName = name;
moret's avatar
Cleanup    
moret committed
128
                fCurrentMeasure = new T[fMeasurePoints];
moret's avatar
moret committed
129
130
131
132
133
134
135
                fMeasureTable = new T*[fMeasureCnt];
                for ( uint32_t cnt = 0; cnt < fMeasureCnt; cnt++ )
                {
                    fMeasureTable[cnt] = new T[fMeasurePoints];
                    fill_n ( fMeasureTable[cnt], fMeasurePoints, 0 );
                }
            }
136

moret's avatar
moret committed
137
            ~JackGnuPlotMonitor()
138
            {
moret's avatar
moret committed
139
                jack_log ( "JackGnuPlotMonitor::~JackGnuPlotMonitor" );
moret's avatar
moret committed
140

moret's avatar
moret committed
141
142
143
                for ( uint32_t cnt = 0; cnt < fMeasureCnt; cnt++ )
                    delete[] fMeasureTable[cnt];
                delete[] fMeasureTable;
moret's avatar
Cleanup    
moret committed
144
                delete[] fCurrentMeasure;
145
146
            }

moret's avatar
Cleanup    
moret committed
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
            T AddNew ( T measure_point )
            {
				fMeasureId = 0;
				return fCurrentMeasure[fMeasureId++] = measure_point;
            }

			uint32_t New()
			{
				return fMeasureId = 0;
			}

            T Add ( T measure_point )
            {
				return fCurrentMeasure[fMeasureId++] = measure_point;
            }

            uint32_t AddLast ( T measure_point )
            {
            	fCurrentMeasure[fMeasureId] = measure_point;
            	fMeasureId = 0;
            	return Write();
            }

            uint32_t Write()
171
172
            {
                for ( uint32_t point = 0; point < fMeasurePoints; point++ )
moret's avatar
Cleanup    
moret committed
173
                    fMeasureTable[fTablePos][point] = fCurrentMeasure[point];
moret's avatar
moret committed
174
175
176
                if ( ++fTablePos == fMeasureCnt )
                    fTablePos = 0;
                return fTablePos;
177
178
            }

moret's avatar
moret committed
179
180
181
182
            int Save ( std::string name = std::string ( "" ) )
            {
                std::string filename = ( name.empty() ) ? fName : name;
                filename += ".log";
183

moret's avatar
moret committed
184
                jack_log ( "JackGnuPlotMonitor::Save filename %s", filename.c_str() );
185

moret's avatar
moret committed
186
                std::ofstream file ( filename.c_str() );
187

moret's avatar
moret committed
188
189
190
191
192
193
                for ( uint32_t cnt = 0; cnt < fMeasureCnt; cnt++ )
                {
                    for ( uint32_t point = 0; point < fMeasurePoints; point++ )
                        file << fMeasureTable[cnt][point] << " \t";
                    file << std::endl;
                }
194

moret's avatar
moret committed
195
196
                file.close();
                return 0;
197
198
            }

moret's avatar
moret committed
199
200
201
            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 ( "" ) )
202
            {
moret's avatar
moret committed
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
                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++ )
                    file << options_list[i] << std::endl;

                file << "plot ";
                for ( uint32_t row = 1; row <= field_number; row++ )
                {
                    file << "\"" << data_filename << "\" using " << row << " title \"" << field_names[row-1] << "\" with lines";
                    file << ( ( row < field_number ) ? ", " : "\n" );
                }

moret's avatar
moret committed
223
                jack_log ( "JackGnuPlotMonitor::SetPlotFile - Save GnuPlot file to '%s'", plot_filename.c_str() );
moret's avatar
moret committed
224
225
226

                file.close();
                return 0;
227
228
            }
    };
229
230
231
}

#endif