gtkIOStream  1.7.0
GTK+ << C++ IOStream operators for GTK+. Now with ORBing, numerical computation, audio client and more ...
WSOLAJack.H
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 #ifndef WSOLAJACK_H_
18 #define WSOLAJACK_H_
19 
20 #include <JackClient.H>
21 
22 typedef float FP_TYPE;
23 
26 class WSOLAJack : public WSOLA, public JackClient {
28 
30 
31  Matrix<FP_TYPE, Dynamic, Dynamic> audioData;
32 
33  int N;
34 
35  jack_default_audio_sample_t **outs;
36 
44  int processAudio(jack_nframes_t nframes) {
45  if (nframes%getOutputSize()) { // if we are asked to process a number of frames which isn't divisible by our output block size, print the error and exit.
46  ostringstream oss;
47  oss<<"jack wants "<<nframes<<" to process which doesn't divide by the number of frames which WSOLA can process in one step "<<getOutputSize()<<'\t';
49  }
50 
51  int ret=0;
52  for (uint i=0; i<outputPorts.size(); i++)
53  outs[i] = ( jack_default_audio_sample_t* ) jack_port_get_buffer (outputPorts[i] , nframes);
54 
55  int processed=0;
56  while (processed!=nframes) {
57  //cout<<processed<<'\t'<<outputPorts.size()<<'\t'<<output.rows()<<'\t'<<output.cols()<<endl;
58  // output the audio data
59  for (uint i=0; i<outputPorts.size(); i++)
60  for (int j=0; j<getOutputSize(); j++)
61  outs[i][processed+j]=output(i, j);
62 
63  N=process(timeScale, audioData);
64 
65  // read more audio data
66  ret=readAudio(N);
67  if (ret!=N) {
68  cerr<<"couldn't read audio, wanted "<<N<<" got "<<ret<<" rolling out"<<endl;
69  if (noMoreAudio()<=0)
70  return N; // returns a non zero number to stop
71  } else
72  ret=NO_ERROR;
73 
74 // cout<<"read audo returns "<<audioData.rows()<< '\t'<<audioData.cols()<<endl;
75 
76  processed+=getOutputSize();
77  }
78  return ret;
79  }
80 
81  int readAudio(int sampleCount){
82  Matrix<FP_TYPE, Dynamic, Dynamic> output;
83  int ret=sox.read(audioData, sampleCount); // sox read
84  audioData.transposeInPlace();
85  if (audioData.cols()!=sampleCount){
86  cout<<"couldn't read "<<sampleCount<<" samples only read "<<ret<<endl;
87  cout<<"readAudio "<<audioData.rows()<<'\t'<<audioData.cols()<<endl;
88  // TODO: Zero audioData which wasn't read here.
89  //Matrix<FP_TYPE, Dynamic, Dynamic>::Zeros(audioData.rows(),sampleCount-audioData.cols());
90  }
91  return audioData.cols();
92  }
93 
94 public:
95 
101  WSOLAJack(string fileName) {
102  outs=NULL;
103  timeScale=1.;
104 
105  int ret;
106  if ((ret=sox.openRead(fileName))<0 && ret!=SOX_READ_MAXSCALE_ERROR)
107  exit(WSOLADebug().evaluateError(ret, fileName));
108  sox.setMaxVal(1.0);
109 
110  ret=connect("WSOLA");
111  if (ret!=NO_ERROR)
112  exit(JackDebug().evaluateError(ret));
113 
114  reset(sox.getChCntIn()); // set wsola to use the correct channel count.
115  cout<<getSampleRate()<<endl;
116  setFS(getSampleRate()); // set the WSOLA sample rate
117  N=getSamplesRequired();
118  ret=readAudio(N);
119  if (ret!=N) {
120  cerr<<"couldn't read audio, wanted "<<N<<" got "<<ret<<endl;
121  exit(ret);
122  }
123 
124  cout<<"Jack : sample rate set to : "<<getSampleRate()<<" Hz"<<endl;
125  cout<<"Jack : block size set to : "<<getBlockSize()<<" samples"<<endl;
126 
127  outs = new jack_default_audio_sample_t*[sox.getChCntIn()];
128 
129  if ((ret=createPorts("in ", 0, "out ", sox.getChCntIn()))!=NO_ERROR)
130  exit(JackDebug().evaluateError(ret));
131 
132  // process the first frame of audio data - the rest will happen in the processAudio method
133  N=process(timeScale, audioData);
134 
135  // read more audio data
136  ret=readAudio(N);
137  if (ret!=N) {
138  cerr<<"couldn't read audio, wanted "<<N<<" got "<<ret<<endl;
139  exit(ret);
140  }
141 
142  // ensure that the block size is as required.
143  if (getBlockSize()%getOutputSize())
145  if (ret<0)
146  exit(JackDebug().evaluateError(ret));
147 
148  if ((ret=startClient(0, sox.getChCntIn(), true))!=NO_ERROR)
149  exit(JackDebug().evaluateError(ret));
150  }
151 
153  ~WSOLAJack(void) {
154  sox.closeRead();
155  if (outs)
156  delete [] outs;
157  }
158 
160  timeScale=ts;
161  }
162 };
163 
164 #endif // WSOLAJACK_H_
#define SOX_READ_MAXSCALE_ERROR
Sox couldn&#39;t open the filename.max to read the rescale value for the audio file.
Definition: Sox.H:36
float FP_TYPE
Definition: audioMasker.C:25
~WSOLAJack(void)
Destructor.
Definition: WSOLAJack.H:153
virtual int createPorts(string inName, int inCnt, string outName, int outCnt)
Definition: JackBase.H:277
int N
The number of audio samples required by WSOLA from the audio file.
Definition: WSOLAJack.H:33
int openRead(string fileName)
Definition: Sox.C:70
void setTimeScale(FP_TYPE ts)
Definition: WSOLAJack.H:159
virtual int getBlockSize()
Definition: JackClient.H:140
virtual int evaluateError(int errorNum)
Definition: Debug.H:132
virtual int startClient()
Definition: JackClient.H:159
WSOLAJack(string fileName)
Definition: WSOLAJack.H:101
int setBlockSize(int size)
Definition: JackClient.H:148
#define NO_ERROR
There is no error.
Definition: Debug.H:33
jack_default_audio_sample_t ** outs
The number of output port created for this audio stream.
Definition: WSOLAJack.H:35
Sox< FP_TYPE > sox
Audio file reading class.
Definition: WSOLAJack.H:29
unsigned int uint
Definition: Box.H:28
int noMoreAudio()
Definition: WSOLA.H:233
FP_TYPE timeScale
The time scale to use for speed scaling the audio.
Definition: WSOLAJack.H:27
void reset(int chCnt)
Definition: WSOLA.C:135
int getChCntIn(void)
Definition: Sox.H:333
int readAudio(int sampleCount)
Definition: WSOLAJack.H:81
int getSampleRate(void) const
Definition: JackBase.H:266
int processAudio(jack_nframes_t nframes)
Definition: WSOLAJack.H:44
int getSamplesRequired(void)
Definition: WSOLA.H:214
void setMaxVal(double newMax)
Definition: Sox.H:300
virtual int connect(string clientName_)
Definition: JackClient.H:115
Array< FP_TYPE, Dynamic, Dynamic > output
The output vector, each row is a channel.
Definition: WSOLA.H:141
void setFS(float fsIn)
Definition: WSOLA.C:162
int closeRead(void)
Definition: Sox.C:226
#define WSOLA_NFRAMES_JACK_ERROR
Occurs when jack wants to process nframes which is not divisible by N/2.
Definition: WSOLA.H:41
int process(FP_TYPE timeScale, const DenseBase< Derived > &input)
Definition: WSOLA.H:169
float FP_TYPE
Definition: WSOLAJack.H:22
Matrix< FP_TYPE, Dynamic, Dynamic > audioData
The audio data which has been read from the sox file.
Definition: WSOLAJack.H:31
vector< jack_port_t * > outputPorts
The output ports.
Definition: JackBase.H:119
Definition: WSOLA.H:82
int getOutputSize(void)
Definition: WSOLA.H:220
int read(Eigen::DenseBase< Derived > &audioData, int count=0)
Definition: Sox.H:135
gtkIOStream: /tmp/gtkiostream/include/WSOLAJack.H Source File
GTK+ IOStream  Beta