gtkIOStream  1.7.0
GTK+ << C++ IOStream operators for GTK+. Now with ORBing, numerical computation, audio client and more ...
JackFullDuplex.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: 2017.04.03
21 */
22 
23 #include "JackClient.H"
24 #include <iostream>
25 using namespace std;
26 #include "OptionParser.H"
27 #include "Sox.H"
28 
29 #include <math.h>
30 #include <unistd.h> // for sleep, find something different on Microsoft
31 
32 int printUsage(string name) {
33  cout<<"\nUseage: \n"<<endl;
34  cout<<name<<" [-t duration] outputFileName.ext : the output file name with ext replaced by a known output format extension (see below)"<<endl;
35  cout<<name<<" -t num : duration in seconds"<<endl;
37  vector<string> formats=sox.availableFormats();
38  cout<<"The known output file extensions (output file formats) are the following :"<<endl;
39  for (int i=0; i<formats.size(); i++)
40  cout<<formats[i]<<' ';
41  cout<<endl;
42 
43  return 0;
44 }
45 
46 
49 class FullDuplexTones : public JackClient, public Sox<jack_default_audio_sample_t> {
50  float phase;
51  vector<vector<jack_default_audio_sample_t> > audioData;
52 
53  int processAudio(jack_nframes_t nframes) {
54  float w=2.*M_PI*1.e3/(float)getSampleRate(); //*(float)(i+1); // the frequency
55 
56  // put output data into the buffers
57  for (uint i=0; i<outputPorts.size(); i++) {
58  jack_default_audio_sample_t *out = ( jack_default_audio_sample_t* ) jack_port_get_buffer ( outputPorts[i], nframes );
59  for (uint j=0; j<nframes; j++)
60  audioData[i][j]=out[j]=sin((i+1)*w*(float)j+phase);
61  }
62 
63  float rms=0.;
64  // print input data rms power to std out per channel
65  for (uint i=0; i<inputPorts.size(); i++) {
66  jack_default_audio_sample_t *in = ( jack_default_audio_sample_t* ) jack_port_get_buffer ( inputPorts[i], nframes );
67  for (uint j=0; j<nframes; j++)
68  audioData[outputPorts.size()+i][j]=in[j];
69  }
70  phase=fmod(phase+w*(float)(nframes), 2.*M_PI); // wrap the phase
71 
72  write(audioData); // write to file
73  cout<<"nframes "<<nframes<<'\n';
74  return 0;
75  }
76 public:
77 
80  phase=0.;
81  }
82 
83  virtual int openWrite(const string &fileName){
84  int inChCnt, outChCnt;
85  getPhysicalPortCount(inChCnt, outChCnt);
86  int chCnt=inChCnt+outChCnt;
87  int ret=Sox<jack_default_audio_sample_t>::openWrite(fileName, getSampleRate(), chCnt, 1.0);
88  if (ret<0)
89  return SoxDebug().evaluateError(ret);
90 
91  audioData.resize(chCnt); // set the number of channels
92  for (int i=0; i<chCnt; i++) // set the vector length
93  audioData[i].resize(getBlockSize());
94  }
95 };
96 
97 int main(int argc, char *argv[]) {
98 
99  OptionParser op;
100 
101  int i=0;
102  string help;
103  if (op.getArg<string>("h", argc, argv, help, i=0)!=0 || argc < 2)
104  return printUsage(argv[0]);
105 
106  FullDuplexTones jackClient; // init the jack client
107 
108  // connect to the jack server
109  int res=jackClient.connect("jack test client");
110  if (res!=0)
111  return JackDebug().evaluateError(res);
112 
113  cout<<"Jack : sample rate set to : "<<jackClient.getSampleRate()<<" Hz"<<endl;
114  cout<<"Jack : block size set to : "<<jackClient.getBlockSize()<<" samples"<<endl;
115 
116  // open the audio file
117  jackClient.openWrite(argv[argc-1]);
118 
119  int inChCnt, outChCnt;
120  jackClient.getPhysicalPortCount(inChCnt, outChCnt);
121  cout<<"Jack : "<<inChCnt<<" physical input channels"<<endl;
122  cout<<"Jack : "<<outChCnt<<" physical output channels"<<endl;
123  res=jackClient.createPorts("in ", inChCnt, "out ", outChCnt);
124  if (res!=0)
125  return JackDebug().evaluateError(res);
126 
127  // start the client
128  res=jackClient.startClient(inChCnt, outChCnt, true);
129  if (res!=0)
130  return JackDebug().evaluateError(res);
131 
132  float t=2.0;
133  op.getArg<float>("t", argc, argv, t, i=0);
134  cout<<"running for "<<t<<" seconds"<<endl;
135  sleep(t); // sleep for 10 seconds ... Microsoft users may have to use a different sleep function
136  return 0;
137 }
138 
virtual int openWrite(const string &fileName, double fs, int channels, double maxVal)
Definition: Sox.H:174
FullDuplexTones()
Constructor.
virtual int createPorts(string inName, int inCnt, string outName, int outCnt)
Definition: JackBase.H:277
int getArg(string key, int argc, char *argv[], TYPE &ret, int i)
Definition: OptionParser.H:43
virtual int getBlockSize()
Definition: JackClient.H:140
virtual int evaluateError(int errorNum)
Definition: Debug.H:132
STL namespace.
void getPhysicalPortCount(int &in, int &out)
Definition: JackBase.H:344
virtual int startClient()
Definition: JackClient.H:159
vector< string > availableFormats(void)
Definition: Sox.C:238
float phase
The tone phase.
int main(int argc, char *argv[])
int processAudio(jack_nframes_t nframes)
vector< vector< jack_default_audio_sample_t > > audioData
unsigned int uint
Definition: Box.H:28
Definition: Sox.H:54
int printUsage(string name)
int getSampleRate(void) const
Definition: JackBase.H:266
virtual int connect(string clientName_)
Definition: JackClient.H:115
virtual int openWrite(const string &fileName)
gtkIOStream: /tmp/gtkiostream/applications/old/JackFullDuplex.C Source File
GTK+ IOStream  Beta