gtkIOStream  1.7.0
GTK+ << C++ IOStream operators for GTK+. Now with ORBing, numerical computation, audio client and more ...
IIOSox.C
Go to the documentation of this file.
1 /* Copyright 2000-2018 Matt Flax <flatmax@flatmax.org>
2  This file is part of GTK+ IOStream class set
3 
4  GTK+ IOStream is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or
7  (at your option) any later version.
8 
9  GTK+ IOStream is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You have received a copy of the GNU General Public License
15  along with GTK+ IOStream
16 */
17 
18 // compile from the top directory (gtkiostream) with :
19 // g++ -g -I include -I /usr/include/eigen3 -I include/IIO src/IIO/IIO.C src/IIO/IIODevice.C test/IIOTest.C -o test/IIOTest
20 
21 #include "OptionParser.H"
22 
23 #include "IIO/IIOThreaded.H"
24 #include <values.h>
25 
26 #define FP_TYPE unsigned short int
27 #include "Sox.H"
28 
29 #include <iomanip>
30 
31 int printUsage(string name, int N, string chip, int chCnt, float T, float fs) {
32  cout<<name<<" : An application to stream input from IIO devices to file."<<endl;
33  cout<<"Usage:"<<endl;
34  cout<<"\t "<<name<<" [options] outFileName"<<endl;
35  cout<<"\t -p : The number of samples to read each time from the IIO devices : (-p"<<N<<")"<<endl;
36  cout<<"\t -C : The name of the chip to look for in the available IIO devices : (-C "<<chip<<")"<<endl;
37  cout<<"\t -i : The number of channels to open, if the available number is less, then it is reduced to the available : (-i"<<chCnt<<")"<<endl;
38  cout<<"\t -t : The duration to sample for : (-t"<<T<<")"<<endl;
39  cout<<"\t -f : The sample rate to use : (-f"<<fixed<<setprecision(2)<<fs<<")"<<endl;
40  cout<<resetiosflags(ios::showbase);
41 
42  Sox sox;
43  vector<string> formats=sox.availableFormats();
44  cout<<"The known output file extensions (output file formats) are the following :"<<endl;
45  for (int i=0; i<formats.size(); i++)
46  cout<<formats[i]<<' ';
47  cout<<endl;
48  return 0;
49 }
50 
51 int main(int argc, char *argv[]) {
52  // defaults
53  int N=2048; // the number of samples per read
54  string chip("AD7476A"); // the chip to search for
55  int chCnt=MAXINT;
56  float T=40.; // seconds
57  float fs=1.e6; // sample rate in Hz
58 
59  OptionParser op;
60 
61  int i=0;
62  string help;
63  if (op.getArg<string>("h", argc, argv, help, i=0)!=0)
64  return printUsage(argv[0], N, chip, chCnt, T, fs);
65  if (op.getArg<string>("help", argc, argv, help, i=0)!=0)
66  return printUsage(argv[0], N, chip, chCnt, T, fs);
67  if (argc<2)
68  return printUsage(argv[0], N, chip, chCnt, T, fs);
69 
70  if (op.getArg<int>("p", argc, argv, N, i=0)!=0)
71  ;
72 
73  if (op.getArg<string>("C", argc, argv, chip, i=0)!=0)
74  ;
75 
76  if (op.getArg<int>("i", argc, argv, chCnt, i=0)!=0)
77  ;
78 
79  if (op.getArg<float>("t", argc, argv, T, i=0)!=0)
80  ;
81 
82  if (op.getArg<float>("f", argc, argv, fs, i=0)!=0)
83  ;
84 
85  int M=T*1e6/N;
86 
87  IIOThreaded iio;
88  iio.findDevicesByChipName(chip);
89 
90  iio.printInfo(); // print out detail about the devices which were found ...
91 
92  if (iio.getChCnt()<chCnt)
93  chCnt=iio.getChCnt();
94 
95  cout<<"Number of samples p="<<N<<"\nNumber of channels available i="<<chCnt<<"\nChip name C="<<chip<<endl;
96  cout<<"Duration t="<<T<<"\nSample rate f="<<fs<<endl;
97  cout<<endl;
98 
99  cout<<"Reading "<<M<<" times "<<N<<" samples, resulting in a processing time of "<<M*N/1e6<<" or "<<M*N<<" samples per channel."<<endl;
100 
101  // open sox
102  Sox sox;
103  int ret=sox.openWrite(argv[argc-1], fs, chCnt/iio[0].getChCnt(), MAXSHORT);
104  if (ret!=NO_ERROR)
105  return ret;
106 
107  Eigen::Matrix<unsigned short, Eigen::Dynamic, Eigen::Dynamic> data;
108  data.resize(M*N*2, 2);
109 
110  ret=iio.setSampleCountChannelCount(N, chCnt);
111  if (ret!=NO_ERROR)
112  return ret;
113  int expectedWriteCnt=N*chCnt;
114 
115  if ((ret=iio.open())!=NO_ERROR) // try to open all devices
116  return ret;
117 
118  if ((ret=iio.enable(true))!=NO_ERROR) // start the DMA
119  return ret;
120 
121  if ((ret=iio.run())!=NO_ERROR) { // start the reading thread
122  iio.enable(false); // stop the DMA
123  return ret;
124  }
125 
126 // if ((ret=iio.unLock())!=NO_ERROR) { // ensure started in an unlocked state
127 // iio.enable(false); // stop the DMA
128 // iio.stop(); // stop the reading thread
129 // return ret;
130 // }
131 
132  struct timespec start, stop, lockStart, lockStop;
133 
134  if( clock_gettime( CLOCK_REALTIME, &start) == -1 ) {
135  cout<<"clock start get time error"<<endl;
136  exit(-1);
137  }
138 
139 // if ((ret=iio.lock())!=NO_ERROR) { // lock so I can't read until unlocked.
140 // iio.enable(false); // stop the DMA
141 // iio.stop(); // stop the reading thread
142 // return ret;
143 // }
144 
145  // try to read from the devices.
146 //
147 // // first generate a matrix big enough to hold the data we will request
148 // Eigen::Array<unsigned short int, Eigen::Dynamic, Eigen::Dynamic> data;
149 // ret=iio.getReadArray(N, data); // resize the array to be able to read enough memory
150 // if (ret!=NO_ERROR)
151 // ;
152 // else {
153 //
154 
155 // cout<<" spent "<< (driver->engine->get_microseconds()-driver->debug_last_time)<<" us waiting for lock\n";
156  double durations[M];
157  for (int i=0; i<M; i++) {
158  if( clock_gettime( CLOCK_REALTIME, &lockStart) == -1 ) {
159  cout<<"clock lockStart get time error"<<endl;
160  exit(-1);
161  }
162 //
163 // cout<<"mutex unlock 1\n";
164 // iio.emptyRegionLock(false);
165 // usleep(1000);
166 // cout<<"mutex lock 1\n";
167 // iio.lock(); // Wait until iio has finished reading this round
168 // cout<<"mutex lock 1\n";
169 // iio.lock(); // Wait until iio has finished reading this round
170  //cout<<"mutex lock 2\n";
171  //iio.lock(); // Wait until iio has finished reading this round
172 // iio.emptyRegionLock(true);
173 // iio.fillRegionLock();
174 // iio.emptyRegionLock(false);
175 
176 
177 // int written=sox.write(*iio.getFullBuffer());
178 // if (written!=expectedWriteCnt) {
179 // if (written>0)
180 // cout<<"Attempted to write "<<N<<" samples (per channel) to the audio file, however only "<<written<<" samples were written. Exiting!"<<endl;
181 // else {
182 // cout<<SoxDebug().evaluateError(written)<<endl;
183 // cout<<"Output matrix size (rows, cols) = ("<<iio.getFullBuffer()->rows()<<", "<<iio.getFullBuffer()->cols()<<")"<<endl;
184 // cout<<"Error writing, exiting."<<endl;
185 // }
186 // break;
187 // }
188 
189  iio.lock();
190  while (!iio.bufFull)
191  iio.wait();
192 
193  data.block(i*N*2, 0, N*2, 2)=*iio.getFullBuffer();
194 
195  iio.bufFull=false; // inidcate that the buffer has been emptied
196  iio.unLock();
197 
198  //if (durations[i]<2000)
199 // usleep(2000);
200 
201  if( clock_gettime( CLOCK_REALTIME, &lockStop) == -1 ) {
202  cout<<"clock lockStop get time error"<<endl;
203  exit(-1);
204  }
205  durations[i] = 1.e3*( lockStop.tv_sec - lockStart.tv_sec ) + (double)( lockStop.tv_nsec - lockStart.tv_nsec )/1.e6;
206  cout<<"Lock duration "<<durations[i]<<" ms\n";
207 
208  //usleep(1000);
209 
210  }
211 
212  iio.enable(false); // stop the DMA
213  iio.stop(); // stop the reading thread
214  iio.close();
215 
216  if( clock_gettime( CLOCK_REALTIME, &stop) == -1 ) {
217  cout<<"clock stop get time error"<<endl;
218  exit(-1);
219  }
220 
221 // ofstream output("/tmp/data.txt");
222 // output<<data;
223 // output.close();
224  int written=sox.write(data);
225 
226  ofstream outputd("/tmp/durations.txt");
227  for (int i=0; i<M; i++)
228  outputd<<durations[i]<<'\n';
229  outputd.close();
230 
231  double duration = 1.e3*( stop.tv_sec - start.tv_sec ) + (double)( stop.tv_nsec - start.tv_nsec )/1.e6;
232  cout<<"Duration "<<duration<<" ms\n";
233 
234  double expected = (float)(N*M)/1.e6*1.e3;
235  cout<<"Expected "<<expected<<" ms\n";
236 
237  cout<<"Difference "<<duration-expected<<" ms"<<endl;
238 
239 // }
240 
241  sox.closeWrite();
242 
243  return 0;
244 }
245 
int open(void)
Definition: IIO.H:156
virtual int openWrite(const string &fileName, double fs, int channels, double maxVal)
Definition: Sox.H:174
bool bufFull
Indicates when the read has completed and a buffer is full.
Definition: IIOThreaded.H:105
int N
int getArg(string key, int argc, char *argv[], TYPE &ret, int i)
Definition: OptionParser.H:43
Eigen::Array< unsigned short int, Eigen::Dynamic, Eigen::Dynamic > * getFullBuffer()
Definition: IIOThreaded.H:130
int setSampleCountChannelCount(uint N, uint ch)
Definition: IIOThreaded.H:117
void printInfo()
Definition: IIO.H:146
int closeWrite(void)
Definition: Sox.C:232
int printUsage(string name, int N, string chip, int chCnt, float T, float fs, int periodCount)
Definition: IIOSox.C:31
vector< string > availableFormats(void)
Definition: Sox.C:238
int findDevicesByChipName(std::string chipName)
Definition: IIO.H:97
#define NO_ERROR
There is no error.
Definition: Debug.H:33
Definition: Sox.H:95
uint getChCnt()
Definition: IIO.H:137
int main(int argc, char *argv[])
Definition: IIOSox.C:51
virtual int run(int priority=0)
Definition: Thread.H:263
int enable(bool enable)
Definition: IIO.H:290
int unLock()
Definition: Thread.H:325
int close(void)
Definition: IIO.H:179
void * stop(void)
Definition: Thread.H:107
void wait()
Definition: Thread.H:361
int lock()
Definition: Thread.H:295
virtual int write(const vector< vector< FP_TYPE_ > > &audioData)
Definition: Sox.C:203
gtkIOStream: /tmp/gtkiostream/applications/old/IIOSox.C Source File
GTK+ IOStream  Beta