gtkIOStream  1.7.0
GTK+ << C++ IOStream operators for GTK+. Now with ORBing, numerical computation, audio client and more ...
FullDuplex.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 FULLDUPLEX_H
18 #define CAPTURE_H
19 
20 #include <ALSA/ALSA.H>
21 
22 namespace ALSA {
49  template<typename FRAME_TYPE>
50  class FullDuplex : public Capture, public Playback {
56  if (ret==0)
58  if (ret==0)
59  ret=process();
60  return ret;
61  }
62 
69  virtual int process()=0;
70 protected:
72  Eigen::Array<FRAME_TYPE, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> inputAudio;
74  Eigen::Array<FRAME_TYPE, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> outputAudio;
75 
76  public:
80  FullDuplex(const char *devName) : Capture(devName), Playback(devName) {}
81 
86  FullDuplex(const char *playDevName, const char *captureDevName) : Capture(captureDevName), Playback(playDevName) {}
87 
90  virtual ~FullDuplex(void){}
91 
95  int link(){
96  return snd_pcm_link(Playback::getPCM(), Capture::getPCM());
97  }
98 
102  int unLink(){
103  return snd_pcm_unlink(Capture::getPCM());
104  }
105 
112  virtual int go(){
113  int ret=process(), ret2; // call the user's process method to initialise mamber variables.
114  if (ret<0)
116 
117  if (inputAudio.rows()!=outputAudio.rows()) // check for frames mismatch
118  return ALSADebug().evaluateError(ALSA_FRAME_MISMATCH_ERROR, "Your process method didn't initialise the inputAudio and outputAudio member variables with the same number of frames.");
119  if (inputAudio.cols()==0 || outputAudio.cols()==0) // check for no channels
120  return ALSADebug().evaluateError(ALSA_NO_CHANNELS_ERROR, "Your process method didn't initialise the inputAudio and outputAudio member variables with any channels.");
121 
122  if (!Playback::prepared()){
123  // set the playback and capture channels and period sizes accordingly and set the parameters
124  if ((ret=Playback::setChannels(outputAudio.cols()))<0)
125  return ALSADebug().evaluateError(ret);
126  if ((ret=Capture::setChannels(inputAudio.cols()))<0)
127  return ALSADebug().evaluateError(ret);
128  if ((ret=Playback::setBufSize(outputAudio.rows()))<0)
129  return ALSADebug().evaluateError(ret);
130  if ((ret=Capture::setBufSize(inputAudio.rows()))<0)
131  return ALSADebug().evaluateError(ret);
132 
133  if (sizeof(FRAME_TYPE)!=Playback::getFormatPhysicalWidth()/8){
134  printf("sizeof(FRAME_TYPE) = %d, Playback::getFormatPhysicalWidth()/8 = %ld\n", sizeof(FRAME_TYPE), Playback::getFormatPhysicalWidth()/8);
135  return ALSADebug().evaluateError(ALSA_FORMAT_MISMATCH_ERROR, " When comparing the FullDuplex sample type template word against the ALSA format word. ");
136  }
137 
140  }
141  // Capture::enableLog();
142  // std::cout<<"status"<<std::endl;
143  // Capture::dumpStatus();
144  // std::cout<<"PCM"<<std::endl;
145  // Capture::dumpPCM();
146  // std::cout<<"setup"<<std::endl;
147  // Capture::dumpSetup();
148  // std::cout<<"\n\nHW setup"<<std::endl;
149  // Capture::dumpHWSetup();
150  // std::cout<<"\nHW params"<<std::endl;
151  // Capture::dumpHWParams();
152  // std::cout<<"\n\nSW setup"<<std::endl;
153  // Capture::dumpSWSetup();
154  // std::cout<<"\nSW params"<<std::endl;
155  // Capture::dumpSWParams();
156 
157  if ((ret=link())<0)
158  return ALSADebug().evaluateError(ret);
159 
160  while ((ret=writeReadProcess())==0)
161  ;
162  if (Playback::running())
163  Playback::drop(); // stop the pcm
164  if ((ret2=unLink())<0)
165  if (ret>=0)
166  return ALSADebug().evaluateError(ret2);
167  else
168  ALSADebug().evaluateError(ret2);
169  return ret;
170  }
171 
176  int resetParams() {
177  int ret=0;
178  if (ret=Playback::resetParams()<0)
179  return ret;
180  return Capture::resetParams();
181  }
182 
186  int setFormat(snd_pcm_format_t format) {
187  int ret=0;
188  if (ret=Playback::setFormat(format)<0)
189  return ret;
190  return Capture::setFormat(format);
191  }
192 
196  int setAccess(snd_pcm_access_t access) {
197  int ret=0;
198  if (ret=Playback::setAccess(access)<0)
199  return ret;
200  return Capture::setAccess(access);
201  };
202 
209  int setSampleRate(unsigned int rrate, int dir=0) {
210  int ret=0;
211  if (ret=Playback::setSampleRate(rrate, dir)<0)
212  return ret;
213  return Capture::setSampleRate(rrate, dir);
214  }
215 
220  int setBufSize(snd_pcm_uframes_t bufSize) {
221  int ret=0;
222  if (ret=Playback::setBufSize(bufSize)<0)
223  return ret;
224  return Capture::setBufSize(bufSize);
225  }
226 
231  int setChannels(unsigned int cnt) {
232  int ret=0;
233  if (ret=Playback::setChannels(cnt)<0)
234  return ret;
235  return Capture::setChannels(cnt);
236  }
237  };
238 }
239 #endif //FULLDUPLEX_H
int setSampleRate(unsigned int rrate, int dir=0)
Definition: Hardware.H:248
int setSampleRate(unsigned int rrate, int dir=0)
Definition: FullDuplex.H:209
#define ALSA_FRAME_MISMATCH_ERROR
error when frame sizes are incorrect
Definition: ALSADebug.H:28
int setAccess(snd_pcm_access_t access)
Definition: FullDuplex.H:196
int setBufSize(snd_pcm_uframes_t bufSize)
Definition: FullDuplex.H:220
virtual int go()
Definition: FullDuplex.H:112
int setBufSize(snd_pcm_uframes_t bufSize)
Definition: Hardware.H:303
int setChannels(unsigned int cnt)
Definition: FullDuplex.H:231
int setFormat(snd_pcm_format_t format)
Definition: FullDuplex.H:186
FullDuplex(const char *devName)
Definition: FullDuplex.H:80
#define ALSA_FORMAT_MISMATCH_ERROR
error when comparing bits sizes of two words
Definition: ALSADebug.H:31
virtual snd_pcm_t * getPCM()
Definition: PCM.H:42
int readBuf(char *buffer, size_t len)
Definition: Capture.H:51
Definition: ALSA.H:26
Eigen::Array< FRAME_TYPE, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor > outputAudio
The output audio variable, columns are channels, rows are frames (samples).
Definition: FullDuplex.H:74
bool prepared()
Definition: PCM.H:182
#define ALSA_YOUR_PROCESS_FN_ERROR
error when calling the user&#39;s process function
Definition: ALSADebug.H:30
int setAccess(snd_pcm_access_t access)
Definition: Hardware.H:105
virtual int process()=0
virtual int evaluateError(int errorNum)
Definition: ALSADebug.H:61
int setParams()
Definition: Stream.H:101
int drop()
Definition: PCM.H:83
int getFormatPhysicalWidth()
Definition: Hardware.H:202
#define ALSA_NO_CHANNELS_ERROR
error when channel cnt is zero
Definition: ALSADebug.H:29
Eigen::Array< FRAME_TYPE, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor > inputAudio
The input audio variable, columns are channels, rows are frames (samples).
Definition: FullDuplex.H:72
FullDuplex(const char *playDevName, const char *captureDevName)
Definition: FullDuplex.H:86
bool running()
Definition: PCM.H:203
int setFormat(snd_pcm_format_t format)
Definition: Hardware.H:182
int resetParams()
Definition: Hardware.H:63
virtual ~FullDuplex(void)
Definition: FullDuplex.H:90
int setChannels(unsigned int cnt)
Definition: Hardware.H:214
int writeReadProcess()
Definition: FullDuplex.H:54
int writeBuf(void **buffers, size_t len, int ch)
Definition: Playback.H:54
gtkIOStream: /tmp/gtkiostream/include/ALSA/FullDuplex.H Source File
GTK+ IOStream  Beta