| 
							- /*
 -  * Carla RtAudio Engine
 -  * Copyright (C) 2012-2013 Filipe Coelho <falktx@falktx.com>
 -  *
 -  * This program 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 2 of
 -  * the License, or 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.
 -  *
 -  * For a full copy of the GNU General Public License see the GPL.txt file
 -  */
 - 
 - #ifdef WANT_RTAUDIO
 - 
 - #include "carla_engine_internal.hpp"
 - #include "carla_backend_utils.hpp"
 - #include "carla_midi.h"
 - 
 - #include "RtAudio.h"
 - #include "RtMidi.h"
 - 
 - CARLA_BACKEND_START_NAMESPACE
 - 
 - #if 0
 - } // Fix editor indentation
 - #endif
 - 
 - // -------------------------------------------------------------------------------------------------------------------
 - // RtAudio Engine
 - 
 - class CarlaEngineRtAudio : public CarlaEngine
 - {
 - public:
 -     CarlaEngineRtAudio(RtAudio::Api api)
 -         : CarlaEngine(),
 -           audio(api)
 -     {
 -         qDebug("CarlaEngineRtAudio::CarlaEngineRtAudio(%i)", api);
 - 
 -         evIn  = nullptr;
 -         evOut = nullptr;
 - 
 -         m_audioInterleaved = false;
 -         m_inBuf1  = nullptr;
 -         m_inBuf2  = nullptr;
 -         m_outBuf1 = nullptr;
 -         m_outBuf2 = nullptr;
 - 
 -         // just to make sure
 -         fOptions.forceStereo = true;
 -         fOptions.processMode = PROCESS_MODE_CONTINUOUS_RACK;
 -     }
 - 
 -     ~CarlaEngineRtAudio()
 -     {
 -         qDebug("CarlaEngineRtAudio::~CarlaEngineRtAudio()");
 -     }
 - 
 -     // -------------------------------------
 - 
 -     bool init(const char* const clientName)
 -     {
 -         qDebug("CarlaEngineRtAudio::init(\"%s\")", clientName);
 - 
 -         if (audio.getDeviceCount() < 1)
 -         {
 -             setLastError("No audio devices available for this driver");
 -             return false;
 -         }
 - 
 -         fBufferSize = fOptions.preferredBufferSize;
 -         fSampleRate = fOptions.preferredSampleRate;
 - 
 -         RtAudio::StreamParameters iParams, oParams;
 -         iParams.deviceId = audio.getDefaultInputDevice();
 -         oParams.deviceId = audio.getDefaultOutputDevice();
 -         iParams.nChannels = 2;
 -         oParams.nChannels = 2;
 - 
 -         RtAudio::StreamOptions rtOptions;
 -         rtOptions.flags = RTAUDIO_MINIMIZE_LATENCY | RTAUDIO_HOG_DEVICE | RTAUDIO_SCHEDULE_REALTIME;
 -         rtOptions.numberOfBuffers = 2;
 -         rtOptions.streamName = clientName;
 -         rtOptions.priority = 85;
 - 
 -         if (audio.getCurrentApi() != RtAudio::LINUX_PULSE)
 -         {
 -             rtOptions.flags |= RTAUDIO_NONINTERLEAVED;
 -             m_audioInterleaved = false;
 - 
 -             if (audio.getCurrentApi() == RtAudio::LINUX_ALSA)
 -                 rtOptions.flags |= RTAUDIO_ALSA_USE_DEFAULT;
 -         }
 -         else
 -             m_audioInterleaved = true;
 - 
 -         try {
 -             audio.openStream(&oParams, &iParams, RTAUDIO_FLOAT32, fSampleRate, &fBufferSize, carla_rtaudio_process_callback, this, &rtOptions);
 -         }
 -         catch (RtError& e)
 -         {
 -             setLastError(e.what());
 -             return false;
 -         }
 - 
 -         try {
 -             audio.startStream();
 -         }
 -         catch (RtError& e)
 -         {
 -             setLastError(e.what());
 -             return false;
 -         }
 - 
 -         fSampleRate = audio.getStreamSampleRate();
 - 
 -         m_inBuf1  = new float[fBufferSize];
 -         m_inBuf2  = new float[fBufferSize];
 -         m_outBuf1 = new float[fBufferSize];
 -         m_outBuf2 = new float[fBufferSize];
 - 
 -         //midiIn = new MidiInAlsa(clientName, 512);
 -         //midiIn->openVirtualPort("control-in");
 -         //midiIn->openVirtualPort("midi-in");
 - 
 -         //midiOut = new MidiOutAlsa(clientName);
 -         //midiOut->openVirtualPort("control-out");
 -         //midiOut->openVirtualPort("midi-out");
 - 
 -         fName = clientName;
 -         fName.toBasic();
 - 
 -         CarlaEngine::init(fName);
 -         return true;
 -     }
 - 
 -     bool close()
 -     {
 -         qDebug("CarlaEngineRtAudio::close()");
 -         CarlaEngine::close();
 - 
 -         if (audio.isStreamRunning())
 -             audio.stopStream();
 - 
 -         if (audio.isStreamOpen())
 -             audio.closeStream();
 - 
 - #if 0
 -         if (midiIn)
 -         {
 -             midiIn->cancelCallback();
 -             midiIn->closePort();
 -             delete midiIn;
 -             midiIn = nullptr;
 -         }
 - 
 -         if (midiOut)
 -         {
 -             midiOut->closePort();
 -             delete midiOut;
 -             midiOut = nullptr;
 -         }
 - #endif
 - 
 -         if (m_inBuf1)
 -         {
 -             delete[] m_inBuf1;
 -             m_inBuf1 = nullptr;
 -         }
 - 
 -         if (m_inBuf2)
 -         {
 -             delete[] m_inBuf2;
 -             m_inBuf2 = nullptr;
 -         }
 - 
 -         if (m_outBuf1)
 -         {
 -             delete[] m_outBuf1;
 -             m_outBuf1 = nullptr;
 -         }
 - 
 -         if (m_outBuf2)
 -         {
 -             delete[] m_outBuf2;
 -             m_outBuf2 = nullptr;
 -         }
 - 
 -         return true;
 -     }
 - 
 -     bool isRunning() const
 -     {
 -         return audio.isStreamRunning();
 -     }
 - 
 -     bool isOffline() const
 -     {
 -         return false;
 -     }
 - 
 -     EngineType type() const
 -     {
 -         return kEngineTypeRtAudio;
 -     }
 - 
 -     // -------------------------------------
 - 
 - protected:
 -     void handleProcessCallback(void* outputBuffer, void* inputBuffer, unsigned int nframes, double streamTime, RtAudioStreamStatus status)
 -     {
 -         if (maxPluginNumber() == 0)
 -             return;
 - 
 -         // get buffers from RtAudio
 -         float* insPtr  = (float*)inputBuffer;
 -         float* outsPtr = (float*)outputBuffer;
 - 
 -         // assert buffers
 -         CARLA_ASSERT(insPtr);
 -         CARLA_ASSERT(outsPtr);
 - 
 -         // initialize audio input
 -         if (m_audioInterleaved)
 -         {
 -             for (unsigned int i=0; i < nframes*2; i++)
 -             {
 -                 if (i % 2)
 -                     m_inBuf2[i/2] = insPtr[i];
 -                 else
 -                     m_inBuf1[i/2] = insPtr[i];
 -             }
 -         }
 -         else
 -         {
 -             for (unsigned int i=0; i < nframes; i++)
 -                 m_inBuf1[i] = insPtr[i];
 - 
 -             for (unsigned int i=0, j=nframes; i < nframes; i++, j++)
 -                 m_inBuf2[i] = insPtr[j];
 -         }
 - 
 -         // create audio buffers
 -         float* inBuf[2]  = { m_inBuf1, m_inBuf2 };
 -         float* outBuf[2] = { m_outBuf1, m_outBuf2 };
 - 
 -         // initialize events input
 -         //memset(rackEventsIn, 0, sizeof(EngineEvent)*MAX_EVENTS);
 -         {
 -             // TODO
 -         }
 - 
 -         processRack(inBuf, outBuf, nframes);
 - 
 -         // output audio
 -         if (m_audioInterleaved)
 -         {
 -             for (unsigned int i=0; i < nframes*2; i++)
 -             {
 -                 if (i % 2)
 -                     outsPtr[i] = m_outBuf2[i/2];
 -                 else
 -                     outsPtr[i] = m_outBuf1[i/2];
 -             }
 -         }
 -         else
 -         {
 -             for (unsigned int i=0; i < nframes; i++)
 -                 outsPtr[i] = m_outBuf1[i];
 - 
 -             for (unsigned int i=0, j=nframes; i < nframes; i++, j++)
 -                 outsPtr[j] = m_outBuf2[i];
 -         }
 - 
 -         // output control
 -         {
 -             // TODO
 -         }
 - 
 -         // output midi
 -         {
 -             // TODO
 -         }
 - 
 -         Q_UNUSED(streamTime);
 -         Q_UNUSED(status);
 -     }
 - 
 -     // -------------------------------------
 - 
 - private:
 -     RtAudio audio;
 -     ScopedPointer<MidiInApi>  evIn;
 -     ScopedPointer<MidiOutApi> evOut;
 - 
 -     bool   m_audioInterleaved;
 -     float* m_inBuf1;
 -     float* m_inBuf2;
 -     float* m_outBuf1;
 -     float* m_outBuf2;
 - 
 -     static int carla_rtaudio_process_callback(void* outputBuffer, void* inputBuffer, unsigned int nframes, double streamTime, RtAudioStreamStatus status, void* userData)
 -     {
 -         CarlaEngineRtAudio* const _this_ = (CarlaEngineRtAudio*)userData;
 -         _this_->handleProcessCallback(outputBuffer, inputBuffer, nframes, streamTime, status);
 -         return 0;
 -     }
 - 
 -     CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineRtAudio)
 - };
 - 
 - // -----------------------------------------
 - 
 - static std::vector<RtAudio::Api> rtApis;
 - 
 - static void initRtApis()
 - {
 -     static bool initiated = false;
 - 
 -     if (! initiated)
 -     {
 -         initiated = true;
 - 
 -         RtAudio::getCompiledApi(rtApis);
 -     }
 - }
 - 
 - CarlaEngine* CarlaEngine::newRtAudio(RtAudioApi api)
 - {
 -     RtAudio::Api rtApi = RtAudio::UNSPECIFIED;
 - 
 -     switch (api)
 -     {
 -     case RTAUDIO_DUMMY:
 -         rtApi = RtAudio::RTAUDIO_DUMMY;
 -         break;
 -     case RTAUDIO_LINUX_ALSA:
 -         rtApi = RtAudio::LINUX_ALSA;
 -         break;
 -     case RTAUDIO_LINUX_PULSE:
 -         rtApi = RtAudio::LINUX_PULSE;
 -         break;
 -     case RTAUDIO_LINUX_OSS:
 -         rtApi = RtAudio::LINUX_OSS;
 -         break;
 -     case RTAUDIO_UNIX_JACK:
 -         rtApi = RtAudio::UNIX_JACK;
 -         break;
 -     case RTAUDIO_MACOSX_CORE:
 -         rtApi = RtAudio::MACOSX_CORE;
 -         break;
 -     case RTAUDIO_WINDOWS_ASIO:
 -         rtApi = RtAudio::WINDOWS_ASIO;
 -         break;
 -     case RTAUDIO_WINDOWS_DS:
 -         rtApi = RtAudio::WINDOWS_DS;
 -         break;
 -     }
 - 
 -     return new CarlaEngineRtAudio(rtApi);
 - }
 - 
 - unsigned int CarlaEngine::getRtAudioApiCount()
 - {
 -     initRtApis();
 - 
 -     return rtApis.size();
 - }
 - 
 - const char* CarlaEngine::getRtAudioApiName(unsigned int index)
 - {
 -     initRtApis();
 - 
 -     if (index < rtApis.size())
 -     {
 -         const RtAudio::Api& api(rtApis[index]);
 - 
 -         switch (api)
 -         {
 -         case RtAudio::UNSPECIFIED:
 -             return "Unspecified";
 -         case RtAudio::LINUX_ALSA:
 -             return "ALSA";
 -         case RtAudio::LINUX_PULSE:
 -             return "PulseAudio";
 -         case RtAudio::LINUX_OSS:
 -             return "OSS";
 -         case RtAudio::UNIX_JACK:
 -             return "JACK (RtAudio)";
 -         case RtAudio::MACOSX_CORE:
 -             return "CoreAudio";
 -         case RtAudio::WINDOWS_ASIO:
 -             return "ASIO";
 -         case RtAudio::WINDOWS_DS:
 -             return "DirectSound";
 -         case RtAudio::RTAUDIO_DUMMY:
 -             return "Dummy";
 -         }
 -     }
 - 
 -     return nullptr;
 - }
 - 
 - // -----------------------------------------
 - 
 - CARLA_BACKEND_END_NAMESPACE
 - 
 - #ifdef QTCREATOR_TEST
 - int main()
 - {
 -     return 0;
 - }
 - 
 - #endif
 - 
 - #endif // CARLA_ENGINE_RTAUDIO
 
 
  |