gtkIOStream  1.7.0
GTK+ << C++ IOStream operators for GTK+. Now with ORBing, numerical computation, audio client and more ...
CrossoverTester.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 /*
19 Author: Matt Flax <flatmax@flatmax.org>
20 Date: 2013.08.05
21 */
22 
23 #include "JackClient.H"
24 #include <iostream>
25 using namespace std;
26 #include "OptionParser.H"
27 #include "Sox.H"
28 #include "DSP/CrossoverAudio.H"
29 #include <unistd.h>
30 
31 typedef float FP_TYPE;
32 
33 int printUsage(string name) {
34  cout<<"\nUseage: \n"<<endl;
35  cout<<name<<" [-t duration] [-o num] [-i num] [-I num] [-g num] outputFileName.ext : the output file name with ext replaced by a known output format extension (see below)"<<endl;
36  cout<<name<<" -t num : duration in seconds"<<endl;
37  cout<<name<<" -o num : number of output channels to open at the same time on the audio device"<<endl;
38  cout<<name<<" -i num : number of input channels to open at the same time on the audio device"<<endl;
39  cout<<name<<" -I num : total number of test input channels to record"<<endl;
40  cout<<name<<" -g num : the output gain"<<endl;
41  Sox<FP_TYPE> sox;
42  vector<string> formats=sox.availableFormats();
43  cout<<"The known output file extensions (output file formats) are the following :"<<endl;
44  for (int i=0; i<formats.size(); i++)
45  cout<<formats[i]<<' ';
46  cout<<endl;
47 
48  return 0;
49 }
50 
51 int saveAudioToFile(const char *fn, const CrossoverAudio& crossAudio, const int chCnt) {
52  // open sox
53  Sox<FP_TYPE> sox;
54  int ret=sox.openWrite(fn, crossAudio.getSampleRate(), chCnt, 1.0);
55  if (ret!=NO_ERROR)
56  return SoxDebug().evaluateError(ret);
57  int written=sox.write(crossAudio.audio);
58  if (written!=crossAudio.audio.rows()*crossAudio.audio.cols()) {
59  cout<<SoxDebug().evaluateError(written)<<endl;
60  cout<<"written "<<written<<endl;
61  cout<<"Output matrix size (rows, cols) = ("<<crossAudio.audio.rows()<<", "<<crossAudio.audio.cols()<<")"<<endl;
62  cout<<"Matrix is a total of "<<crossAudio.audio.rows()*crossAudio.audio.cols()<<" samples"<<endl;
63  cout<<"Error writing, exiting."<<endl;
64  }
65  sox.closeWrite();
66  return ret;
67 }
68 
69 
70 int main(int argc, char *argv[]) {
71  OptionParser op;
72 
73  int i=0;
74  string help;
75  if (op.getArg<string>("h", argc, argv, help, i=0)!=0)
76  return printUsage(argv[0]);
77 
78  CrossoverAudio crossAudio; // init the crossover tester
79 
80  float t=10.0;
81  op.getArg<float>("t", argc, argv, t, i=0);
82  cout<<"running for "<<t<<" seconds"<<endl;
83  crossAudio.setDuration(t);
84 
85  float g=1.0;
86  op.getArg<float>("g", argc, argv, g, i=0);
87  cout<<"using a gain="<<g<<endl;
88  crossAudio.setGain(g);
89 
90  int inChCnt=2;
91  op.getArg<int>("i", argc, argv, inChCnt, i=0);
92  cout<<"recording "<<inChCnt<<" channels of physical input audio to record each time"<<endl;
93 
94  int inTestChCnt=2;
95  op.getArg<int>("I", argc, argv, inTestChCnt, i=0);
96  cout<<"recording "<<inTestChCnt<<" channels of input audio total, maximum of "<<inChCnt<<" channels each run."<<endl;
97 
98  int outChCnt=1;
99  op.getArg<int>("o", argc, argv, outChCnt, i=0);
100  cout<<"playing "<<outChCnt<<" channels of output random noise"<<endl;
101 
102  crossAudio.setChannels(outChCnt, inChCnt, inTestChCnt);
103 
104  cout<<"Jack : sample rate set to : "<<crossAudio.getSampleRate()<<" Hz"<<endl;
105  cout<<"Jack : block size set to : "<<crossAudio.getBlockSize()<<" samples"<<endl;
106 
107  crossAudio.reset();
108 
109  cout<<"Please press enter to start."<<endl;
110  while (1){
111  string userInput;
112  while (crossAudio.getNumberOfRecordedChannels()<inTestChCnt+outChCnt){
113  if (crossAudio.getNumberOfRecordedChannels()<outChCnt)
114  cout<<"\r"<<crossAudio.getNumberOfRecordedChannels()<<" channels already recorded, press enter to record the "<<crossAudio.getNumberOfRecordedChannels()+1<<" channel, output calibration channel."<<endl;
115  else if (crossAudio.getNumberOfRecordedChannels()==outChCnt)
116  cout<<"\r"<<crossAudio.getNumberOfRecordedChannels()<<" channels already recorded, please plug in the device to test NOW !!!! press enter to record the "<<crossAudio.getNumberOfRecordedChannels()-outChCnt+1<<" channel, device under test input channel."<<endl;
117  else
118  cout<<"\r"<<crossAudio.getNumberOfRecordedChannels()<<" channels already recorded, press enter to record the "<<crossAudio.getNumberOfRecordedChannels()-outChCnt+1<<" channel, device under test input channel."<<endl;
119 
120  getline(cin, userInput);
121  int ret=crossAudio.recordNextChannelSet();
122  if (ret!=NO_ERROR)
123  exit(ret);
124  sleep(t+1); // sleep for duration seconds
125  while (crossAudio.isRecording()) // whilst still recording, sleep for half a second, allowing time to finish.
126  sleep(1);
127  cout<<"done"<<endl;
128  }
129  cout<<"\rDone, now going to write to the file "<<argv[argc-1]<<endl;
130 
131  if (saveAudioToFile(argv[argc-1], crossAudio, inTestChCnt+outChCnt+1)!=NO_ERROR)
132  break;
133 
134  cout<<"\n\nStart the analysis and press any key to record a new crossover\n"<<endl;
135  crossAudio.nextCrossover(); // keep the recorded loopback channel and start again with the crossover channels.
136  break;
137  }
138 
139  return 0;
140 }
virtual int openWrite(const string &fileName, double fs, int channels, double maxVal)
Definition: Sox.H:174
virtual int reset()
int getArg(string key, int argc, char *argv[], TYPE &ret, int i)
Definition: OptionParser.H:43
virtual int getBlockSize()
Definition: JackClient.H:140
int setDuration(float d)
virtual int evaluateError(int errorNum)
Definition: Debug.H:132
int closeWrite(void)
Definition: Sox.C:232
STL namespace.
int main(int argc, char *argv[])
vector< string > availableFormats(void)
Definition: Sox.C:238
#define NO_ERROR
There is no error.
Definition: Debug.H:33
int printUsage(string name)
virtual int getNumberOfRecordedChannels()
Definition: Sox.H:54
int setChannels(int outCnt, int inCnt, int testInCnt)
int getSampleRate(void) const
Definition: JackBase.H:266
void setGain(float g)
int recordNextChannelSet()
Eigen::Matrix< float, Eigen::Dynamic, Eigen::Dynamic > audio
The first channel is the same data sent over each output channel, then the output channels...
int saveAudioToFile(const char *fn, const CrossoverAudio &crossAudio, const int chCnt)
virtual int write(const vector< vector< FP_TYPE_ > > &audioData)
Definition: Sox.C:203
float FP_TYPE
gtkIOStream: /tmp/gtkiostream/applications/CrossoverTester.C Source File
GTK+ IOStream  Beta