Rename interpretor to interpreter.
[Faustine.git] / interpreter / preprocessor / faust-0.9.47mr3 / architecture / audio / portaudio-dsp.h
diff --git a/interpreter/preprocessor/faust-0.9.47mr3/architecture/audio/portaudio-dsp.h b/interpreter/preprocessor/faust-0.9.47mr3/architecture/audio/portaudio-dsp.h
new file mode 100644 (file)
index 0000000..726a906
--- /dev/null
@@ -0,0 +1,192 @@
+/************************************************************************
+
+       IMPORTANT NOTE : this file contains two clearly delimited sections :
+       the ARCHITECTURE section (in two parts) and the USER section. Each section
+       is governed by its own copyright and license. Please check individually
+       each section for license and copyright information.
+*************************************************************************/
+
+/*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
+
+/************************************************************************
+    FAUST Architecture File
+       Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale
+    ---------------------------------------------------------------------
+    This Architecture section is free software; you can redistribute it
+    and/or modify it under the terms of the GNU General Public License
+       as published by the Free Software Foundation; either version 3 of
+       the License, or (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+       along with this program; If not, see <http://www.gnu.org/licenses/>.
+
+       EXCEPTION : As a special exception, you may create a larger work
+       that contains this FAUST architecture section and distribute
+       that work under terms of your choice, so long as this FAUST
+       architecture section is not modified.
+
+
+ ************************************************************************
+ ************************************************************************/
+
+
+#ifndef __portaudio_dsp__
+#define __portaudio_dsp__
+
+#include <stdio.h>
+#include <assert.h>
+#include <portaudio.h>
+
+#include "audio.h"
+#include "dsp.h"
+
+#define max(x,y) (((x)>(y)) ? (x) : (y))
+
+static int audioCallback(const void *ibuf, void *obuf, unsigned long frames, const PaStreamCallbackTimeInfo*,  PaStreamCallbackFlags, void * drv);
+//----------------------------------------------------------------------------
+static void pa_error(int err)
+{
+       if (err != paNoError) {
+               printf(  "PortAudio error: %s\n", Pa_GetErrorText( err ) );
+       }
+}
+
+/******************************************************************************
+*******************************************************************************
+
+                                                       PORT AUDIO INTERFACE
+
+*******************************************************************************
+*******************************************************************************/
+class portaudio : public audio {
+
+        dsp*                   fDsp;
+        PaStream*              fAudioStream;
+        long fSampleRate, fBufferSize;
+        //----------------------------------------------------------------------------
+        //     number of physical input and output channels of the PA device
+        //----------------------------------------------------------------------------
+        int            fDevNumInChans;
+        int            fDevNumOutChans;
+
+        //----------------------------------------------------------------------------
+        // tables of noninterleaved input and output channels for FAUST
+        //----------------------------------------------------------------------------
+        float*         fInChannel[256];
+        float*         fOutChannel[256];
+
+        //----------------------------------------------------------------------------
+        // allocated the noninterleaved input and output channels for FAUST
+        //----------------------------------------------------------------------------
+        void allocChannels (int size, int numInChan, int numOutChan)
+        {
+            assert (numInChan < 256);
+            assert (numOutChan < 256);
+
+            for (int i = 0; i < numInChan; i++) {
+                fInChannel[i] = (float*) calloc (size, sizeof(float));
+                for (int j = 0; j < size; j++)
+                    fInChannel[i][j] = 0.0;
+            }
+
+            for (int i = 0; i < numOutChan; i++) {
+                fOutChannel[i] = (float*) calloc (size, sizeof(float));
+                for (int j = 0; j < size; j++)
+                    fOutChannel[i][j] = 0.0;
+            }
+        }
+
+       public:
+                        portaudio(long srate, long bsize) : fDsp(0), fAudioStream(0),
+                               fSampleRate(srate), fBufferSize(bsize), fDevNumInChans(0), fDevNumOutChans(0) {}
+       virtual ~portaudio() { stop(); }
+
+       virtual bool init(const char* name, dsp* DSP){
+               fDsp = DSP;
+               pa_error(Pa_Initialize());
+
+               const PaDeviceInfo*     idev = Pa_GetDeviceInfo(Pa_GetDefaultInputDevice());
+               const PaDeviceInfo*     odev = Pa_GetDeviceInfo(Pa_GetDefaultOutputDevice());
+
+               fDevNumInChans = (fDsp->getNumInputs() > 0) ? idev->maxInputChannels : 0 ;
+               fDevNumOutChans = (fDsp->getNumOutputs() > 0) ? odev->maxOutputChannels : 0;
+
+               PaStreamParameters inputParameters;
+               PaStreamParameters outputParameters;
+
+               inputParameters.device = Pa_GetDefaultInputDevice();
+               inputParameters.sampleFormat = paFloat32;
+               inputParameters.channelCount = fDevNumInChans;
+               inputParameters.hostApiSpecificStreamInfo = 0;
+
+               outputParameters.device = Pa_GetDefaultOutputDevice();
+               outputParameters.sampleFormat = paFloat32;
+               outputParameters.channelCount = fDevNumOutChans;
+               outputParameters.hostApiSpecificStreamInfo = 0;
+
+               PaError err;
+               if ((err = Pa_IsFormatSupported(
+                       ((fDevNumInChans > 0) ? &inputParameters : 0),
+                       ((fDevNumOutChans > 0) ? &outputParameters : 0), fSampleRate)) != 0) {
+                       printf("stream format is not supported err = %d\n", err);
+                       return false;
+               }
+
+               allocChannels(fBufferSize, max(fDevNumInChans, fDsp->getNumInputs()), max(fDevNumOutChans, fDsp->getNumOutputs()));
+               fDsp->init(fSampleRate);
+               return true;
+       }
+
+       virtual bool start() {
+               pa_error(Pa_OpenDefaultStream(&fAudioStream, fDevNumInChans, fDevNumOutChans, paFloat32, fSampleRate, fBufferSize, audioCallback, this));
+               Pa_StartStream(fAudioStream);
+               return true;
+       }
+
+       virtual void stop() {
+               if (fAudioStream) {
+                       Pa_StopStream (fAudioStream);
+                       Pa_CloseStream(fAudioStream);
+                       fAudioStream = 0;
+               }
+       }
+
+       int processAudio(const float *ibuf, float *obuf, unsigned long frames) {
+               const float* fInputBuffer = ibuf;
+               float* fOutputBuffer = obuf;
+
+               // split input samples
+               for (unsigned long s = 0; s < frames; s++) {
+                       for (int c = 0; c < fDevNumInChans; c++) {
+                               fInChannel[c][s] = fInputBuffer[c + s*fDevNumInChans];
+                       }
+               }
+
+               // process samples
+               fDsp->compute(frames, fInChannel, fOutChannel);
+
+               // merge output samples
+               for (unsigned long s = 0; s < frames; s++) {
+                       for (int c = 0; c < fDevNumOutChans; c++) {
+                               fOutputBuffer[c + s*fDevNumOutChans] = fOutChannel[c][s];
+                       }
+               }
+               return 0;
+       }
+};
+
+//----------------------------------------------------------------------------
+// Port Audio Callback
+//----------------------------------------------------------------------------
+static int audioCallback(const void *ibuf, void *obuf, unsigned long frames, const PaStreamCallbackTimeInfo*,  PaStreamCallbackFlags, void * drv)
+{
+       portaudio * pa = (portaudio*) drv;
+       return pa->processAudio ((const float*)ibuf, (float*)obuf, frames);
+}
+
+#endif