gtkIOStream  1.7.0
GTK+ << C++ IOStream operators for GTK+. Now with ORBing, numerical computation, audio client and more ...
CrossoverAudio.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 #include "DSP/CrossoverAudio.H"
18 #include <algorithm>
19 
21  gain=0.9;
22  int res=connect("CrossoverAudio");
23  if (res!=0)
24  JackDebug().evaluateError(res);
26 }
27 
29 }
30 
31 int CrossoverAudio::processAudio(jack_nframes_t nframes) { // The Jack client callback
32  int maxIdx=(audio.rows()>=nframes+samplesProcessed)?nframes:audio.rows()-samplesProcessed;
33  // put output data into the buffers, only one output vector at column 0
34  int outCh=outputPorts.size();
35  for (uint i=0; i<outCh; i++) {
36  jack_default_audio_sample_t *out = ( jack_default_audio_sample_t* ) jack_port_get_buffer ( outputPorts[i], nframes );
37  for (uint j=0; j<maxIdx; j++)
38  out[j]=audio(samplesProcessed+j,0);
39  }
40 
41  // all input data indexed after column 0
42  int numIn=((audio.cols()-1-currentInputChannel)+1 < numIn)?audio.cols()-1-currentInputChannel+1:inputPorts.size();
43  for (uint i=0; i<numIn; i++) {
44  jack_default_audio_sample_t *in = ( jack_default_audio_sample_t* ) jack_port_get_buffer ( inputPorts[i], nframes );
45  for (uint j=0; j<maxIdx; j++)
47  }
48 
49  samplesProcessed+=nframes;
50  samplesToProcess-=nframes;
51 
52  if (samplesToProcess<=0) {
53  currentInputChannel+=numIn;
54  recordLock.unLock(); // this shouldn't cause a problem because unlocking shouldn't cause waiting issues.
55  return -1;
56  }
57  return 0;
58 }
59 
60 int CrossoverAudio::startClient(int inCnt, int outCnt, bool doConnect) {
61  recordLock.lock();
62  return JackClient::startClient(inCnt, outCnt, doConnect);
63 }
64 
66  int ret=NO_ERROR;
67  if ((ret=recordLock.tryLock())!=NO_ERROR) { // if recording
68  samplesToProcess=0; // force the audio thread to stop and wait.
69  recordLock.lock();
70  }
72  samplesToProcess=audio.rows();
75  audio.block(0, 0, audio.rows(), audio.cols())=Eigen::Matrix<float,Eigen::Dynamic,Eigen::Dynamic>::Zero(audio.rows(), audio.cols());
76  audio.col(0).block(0,0,samplesToProcess-zeroSampleCnt,1)=Eigen::Matrix<float,Eigen::Dynamic, 1>::Random(samplesToProcess-zeroSampleCnt)*gain;
77  return ret;
78 }
79 
81  int ret=NO_ERROR;
82  if ((ret=recordLock.tryLock())==NO_ERROR){
83  audio.resize((unsigned int)(d*(float)getSampleRate())+zeroSampleCnt, audio.cols());
85  }
86  return ret;
87 }
88 
89 int CrossoverAudio::setChannels(int outCnt, int inCnt, int testInCnt) {
90  int ret=NO_ERROR;
91  if ((ret=destroyPorts())!=NO_ERROR)
92  return ret;
93  if ((ret=recordLock.tryLock())==NO_ERROR) {
94  createPorts("in ", inCnt, "out ", outCnt);
95  audio.resize(audio.rows(), 1+outputPorts.size()+testInCnt); // the extra one is because the output channel is first
97  }
98  return ret;
99 }
100 
101 void CrossoverAudio::getChannels(int &inCnt, int &outCnt) {
102  inCnt=inputPorts.size();
103  outCnt=outputPorts.size();
104 }
105 
107  samplesToProcess=audio.rows();
109  int res=startClient(inputPorts.size(), outputPorts.size(), true);
110  if (res!=NO_ERROR)
111  recordLock.unLock();
112  return JackDebug().evaluateError(res);
113 }
114 
117  audio.block(0, 1, audio.rows(), audio.cols()-1)=Eigen::Matrix<float,Eigen::Dynamic,Eigen::Dynamic>::Zero(audio.rows(), audio.cols()-1);
118 }
119 
121  if (recordLock.tryLock()==NO_ERROR) {
122  recordLock.unLock();
123  return 0;
124  }
125  return 1;
126 }
virtual int createPorts(string inName, int inCnt, string outName, int outCnt)
Definition: JackBase.H:277
virtual int reset()
virtual ~CrossoverAudio()
Destructor.
int currentInputChannel
The current input channel to test.
virtual int getBlockSize()
Definition: JackClient.H:140
int setDuration(float d)
virtual int evaluateError(int errorNum)
Definition: Debug.H:132
unsigned int zeroSampleCnt
The number of samples to train with zeros.
virtual int startClient()
Definition: JackClient.H:159
float gain
The gain for the output.
Mutex recordLock
The lock for when the audio is being played/recorded.
#define NO_ERROR
There is no error.
Definition: Debug.H:33
int samplesProcessed
The number of samples already processed.
void getChannels(int &inCnt, int &outCnt)
unsigned int uint
Definition: Box.H:28
CrossoverAudio()
Constructor : starts connecting to Jack audio.
int setChannels(int outCnt, int inCnt, int testInCnt)
int getSampleRate(void) const
Definition: JackBase.H:266
int tryLock()
Definition: Thread.H:310
int unLock()
Definition: Thread.H:325
virtual int connect(string clientName_)
Definition: JackClient.H:115
int samplesToProcess
The number of samples to process, matching the duration.
vector< jack_port_t * > inputPorts
The input ports.
Definition: JackBase.H:118
virtual int processAudio(jack_nframes_t nframes)
The Jack client callback.
int recordNextChannelSet()
virtual int destroyPorts()
Definition: JackBase.H:306
vector< jack_port_t * > outputPorts
The output ports.
Definition: JackBase.H:119
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 lock()
Definition: Thread.H:295
gtkIOStream: /tmp/gtkiostream/src/DSP/CrossoverAudio.C Source File
GTK+ IOStream  Beta