Gamma  0.9.5
Generic Synthesis Library
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator
/Users/ljp/code/gamma/trunk/Gamma/AudioIO.h
00001 #ifndef GAMMA_AUDIOIO_H_INC
00002 #define GAMMA_AUDIOIO_H_INC
00003 
00004 /*  Gamma - Generic processing library
00005     See COPYRIGHT file for authors and license information */
00006 
00007 
00008 /*  This is a simple example demonstrating how to set up a callback
00009     and process input and output buffers.
00010     
00011     struct MyStuff{};
00012 
00013     // Simple: Using automatic indexing
00014     void audioCBSimple(AudioIOData& io){
00015         
00016         MyStuff& stuff = io.user<MyStuff>();
00017 
00018         while(io()){
00019 
00020             float inSample1 = io.in(0);
00021             float inSample2 = io.in(1);
00022 
00023             io.out(0) = -inSample1;
00024             io.out(1) = -inSample2;
00025         }
00026     }
00027 
00028     // Advanced: Using manual indexing
00029     void audioCB(AudioIOData& io){
00030         
00031         MyStuff& stuff = io.user<MyStuff>();
00032 
00033         for(unsigned i=0; i<io.framesPerBuffer(); ++i){
00034 
00035             float inSample1 = io.in(0,i);
00036             float inSample2 = io.in(1,i);
00037 
00038             io.out(0,i) = -inSample1;
00039             io.out(1,i) = -inSample2;
00040         }
00041     }
00042     
00043     int main(){
00044         MyStuff stuff;
00045         
00046         AudioIO audioIO(128, 44100, audioCB, &stuff, 2,2);
00047         audioIO.start();
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;                   // User specified data
00181     mutable int mFrame;
00182     int mFramesPerBuffer;
00183     double mFramesPerSecond;
00184     float *mBufI, *mBufO, *mBufB;   // input, output, and aux buffers
00185     float * mBufT;                  // temporary one channel buffer
00186     int mNumI, mNumO, mNumB;        // input, output, and aux channels
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);      // Returns error string.
00257 
00258 private:
00259     AudioDevice mInDevice, mOutDevice;
00260 
00261     bool mInResizeDeferred, mOutResizeDeferred;
00262     bool mZeroNANs;         // whether to zero NANs
00263     bool mClipOut;          // whether to clip output between -1 and 1
00264     bool mAutoZeroOut;      // whether to automatically zero output buffers each block
00265 
00266     void init();        // Initializes PortAudio and member variables.
00267     void deferBufferResize(bool forOutput);
00268     void reopen();      // reopen stream (restarts stream if needed)
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 } // gam::
00281 
00282 #endif