00001 #ifndef GAMMA_AUDIOIO_H_INC
00002 #define GAMMA_AUDIOIO_H_INC
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 #include <string>
00052
00053 namespace gam{
00054
00055 class AudioIOData;
00056
00057
00059 typedef void (* audioCallback)(AudioIOData& io);
00060
00061
00063 class AudioDevice{
00064 public:
00065
00067 AudioDevice(int deviceNum);
00068
00072 AudioDevice(const std::string& nameKeyword, bool input=true, bool output=true);
00073
00074 ~AudioDevice();
00075
00076 bool valid() const { return 0!=mImpl; }
00077 int id() const { return mID; }
00078 const char * name() const;
00079 int channelsInMax() const;
00080 int channelsOutMax() const;
00081 double defaultSampleRate() const;
00082
00083 bool hasInput() const;
00084 bool hasOutput() const;
00085
00086 void print() const;
00087
00088 static AudioDevice defaultInput();
00089 static AudioDevice defaultOutput();
00090 static int numDevices();
00091 static void printAll();
00092
00093 private:
00094 void setImpl(int deviceNum);
00095 static void initDevices();
00096 int mID;
00097 const void * mImpl;
00098 };
00099
00100
00101
00103 class AudioIOData {
00104 public:
00106 AudioIOData(void * user);
00107
00108 virtual ~AudioIOData();
00109
00110
00112 bool operator()() const { return (++mFrame)<framesPerBuffer(); }
00113
00115 int frame() const { return mFrame; }
00116
00118 float& bus(int chan) const { return bus(chan, frame()); }
00119
00121 float& bus(int chan, int frame) const;
00122
00124 float * busBuffer(int chan=0) const { return &bus(chan,0); }
00125
00127 const float& in(int chan) const { return in (chan, frame()); }
00128
00130 const float& in (int chan, int frame) const;
00131
00133 const float * inBuffer(int chan=0) const { return &in(chan,0); }
00134
00136 float& out(int chan) const { return out(chan, frame()); }
00137
00139 float& out(int chan, int frame) const;
00140
00142 float * outBuffer(int chan=0) const { return &out(chan,0); }
00143
00145 void sum(float v, int chan) const { out(chan)+=v; }
00146
00148 void sum(float v, int ch1, int ch2) const { sum(v, ch1); sum(v,ch2); }
00149
00151 float& temp(int frame) const;
00152
00154 float * tempBuffer() const { return &temp(0); }
00155
00156 void * user() const{ return mUser; }
00157
00158 template<class UserDataType>
00159 UserDataType& user() const { return *(static_cast<UserDataType *>(mUser)); }
00160
00161 int channelsIn () const;
00162 int channelsOut() const;
00163 int channelsBus() const;
00164 int channelsInDevice() const;
00165 int channelsOutDevice() const;
00166 int framesPerBuffer() const;
00167 double framesPerSecond() const;
00168 double fps() const { return framesPerSecond(); }
00169 double secondsPerBuffer() const;
00170 double time() const;
00171 double time(int frame) const;
00172
00173
00174 void frame(int v){ mFrame=v-1; }
00175 void zeroBus();
00176 void zeroOut();
00177
00178 protected:
00179 class Impl; Impl * mImpl;
00180 void * mUser;
00181 mutable int mFrame;
00182 int mFramesPerBuffer;
00183 double mFramesPerSecond;
00184 float *mBufI, *mBufO, *mBufB;
00185 float * mBufT;
00186 int mNumI, mNumO, mNumB;
00187 };
00188
00189
00190
00192
00195 class AudioIO : public AudioIOData {
00196 public:
00197
00208 AudioIO(
00209 int framesPerBuf=64, double framesPerSec=44100.0,
00210 void (* callback)(AudioIOData &) = 0, void * userData = 0,
00211 int outChans = 2, int inChans = 0 );
00212
00213 virtual ~AudioIO();
00214
00215 using AudioIOData::channelsIn;
00216 using AudioIOData::channelsOut;
00217 using AudioIOData::framesPerBuffer;
00218 using AudioIOData::framesPerSecond;
00219
00220 audioCallback callback;
00221
00222 bool autoZeroOut() const { return mAutoZeroOut; }
00223 int channels(bool forOutput) const;
00224 bool clipOut() const { return mClipOut; }
00225 double cpu() const;
00226 bool supportsFPS(double fps) const;
00227 bool zeroNANs() const;
00228
00229 void operator()();
00230 bool open();
00231 bool close();
00232 bool start();
00233 bool stop();
00234
00235 void autoZeroOut(bool v){ mAutoZeroOut=v; }
00236
00238
00242 void channels(int num, bool forOutput);
00243
00244 void channelsIn(int n){channels(n,false);}
00245 void channelsOut(int n){channels(n,true);}
00246 void channelsBus(int num);
00247 void clipOut(bool v){ mClipOut=v; }
00248 void deviceIn(const AudioDevice& v);
00249 void deviceOut(const AudioDevice& v);
00250 void framesPerSecond(double v);
00251 void framesPerBuffer(int n);
00252 void zeroNANs(bool v){ mZeroNANs=v; }
00253
00254 void print();
00255
00256 static const char * errorText(int errNum);
00257
00258 private:
00259 AudioDevice mInDevice, mOutDevice;
00260
00261 bool mInResizeDeferred, mOutResizeDeferred;
00262 bool mZeroNANs;
00263 bool mClipOut;
00264 bool mAutoZeroOut;
00265
00266 void init();
00267 void deferBufferResize(bool forOutput);
00268 void reopen();
00269 void resizeBuffer(bool forOutput);
00270 };
00271
00272
00273
00274
00275 inline float& AudioIOData::bus(int c, int f) const { return mBufB[c*framesPerBuffer() + f]; }
00276 inline const float& AudioIOData::in (int c, int f) const { return mBufI[c*framesPerBuffer() + f]; }
00277 inline float& AudioIOData::out(int c, int f) const { return mBufO[c*framesPerBuffer() + f]; }
00278 inline float& AudioIOData::temp(int f) const { return mBufT[f]; }
00279
00280 }
00281
00282 #endif