|  | /*
 * Carla Plugin Host
 * Copyright (C) 2011-2018 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 doc/GPL.txt file.
 */
#ifndef CARLA_ENGINE_GRAPH_HPP_INCLUDED
#define CARLA_ENGINE_GRAPH_HPP_INCLUDED
#include "CarlaEngine.hpp"
#include "CarlaMutex.hpp"
#include "CarlaPatchbayUtils.hpp"
#include "CarlaStringList.hpp"
#include "CarlaThread.hpp"
#include "water/processors/AudioProcessorGraph.h"
#include "water/text/StringArray.h"
using water::AudioProcessorGraph;
using water::AudioSampleBuffer;
using water::MidiBuffer;
CARLA_BACKEND_START_NAMESPACE
// -----------------------------------------------------------------------
// External Graph stuff
enum ExternalGraphGroupIds {
    kExternalGraphGroupNull     = 0,
    kExternalGraphGroupCarla    = 1,
    kExternalGraphGroupAudioIn  = 2,
    kExternalGraphGroupAudioOut = 3,
    kExternalGraphGroupMidiIn   = 4,
    kExternalGraphGroupMidiOut  = 5,
    kExternalGraphGroupMax      = 6
};
enum ExternalGraphCarlaPortIds {
    kExternalGraphCarlaPortNull      = 0,
    kExternalGraphCarlaPortAudioIn1  = 1,
    kExternalGraphCarlaPortAudioIn2  = 2,
    kExternalGraphCarlaPortAudioOut1 = 3,
    kExternalGraphCarlaPortAudioOut2 = 4,
    kExternalGraphCarlaPortMidiIn    = 5,
    kExternalGraphCarlaPortMidiOut   = 6,
    kExternalGraphCarlaPortMax       = 7
};
enum ExternalGraphConnectionType {
    kExternalGraphConnectionNull       = 0,
    kExternalGraphConnectionAudioIn1   = 1,
    kExternalGraphConnectionAudioIn2   = 2,
    kExternalGraphConnectionAudioOut1  = 3,
    kExternalGraphConnectionAudioOut2  = 4,
    kExternalGraphConnectionMidiInput  = 5,
    kExternalGraphConnectionMidiOutput = 6
};
struct ExternalGraphPorts {
    LinkedList<PortNameToId> ins;
    LinkedList<PortNameToId> outs;
    const char* getName(const bool isInput, const uint portId) const noexcept;
    uint getPortId(const bool isInput, const char portName[], bool* const ok = nullptr) const noexcept;
    ExternalGraphPorts() noexcept;
    CARLA_PREVENT_HEAP_ALLOCATION
    CARLA_DECLARE_NON_COPY_CLASS(ExternalGraphPorts)
};
struct ExternalGraph {
    PatchbayConnectionList connections;
    ExternalGraphPorts audioPorts, midiPorts;
    mutable CharStringListPtr retCon;
    ExternalGraph(CarlaEngine* const engine) noexcept;
    void clear() noexcept;
    bool connect(const bool sendHost, const bool sendOSC,
                 const uint groupA, const uint portA, const uint groupB, const uint portB) noexcept;
    bool disconnect(const bool sendHost, const bool sendOSC,
                    const uint connectionId) noexcept;
    void refresh(const bool sendHost, const bool sendOSC,
                 const char* const deviceName);
    const char* const* getConnections() const noexcept;
    bool getGroupAndPortIdFromFullName(const char* const fullPortName, uint& groupId, uint& portId) const noexcept;
    CarlaEngine* const kEngine;
    CARLA_PREVENT_HEAP_ALLOCATION
    CARLA_DECLARE_NON_COPY_CLASS(ExternalGraph)
};
// -----------------------------------------------------------------------
// RackGraph
struct RackGraph {
    ExternalGraph extGraph;
    const uint32_t inputs;
    const uint32_t outputs;
    bool isOffline;
    struct Buffers {
        CarlaRecursiveMutex mutex;
        LinkedList<uint> connectedIn1;
        LinkedList<uint> connectedIn2;
        LinkedList<uint> connectedOut1;
        LinkedList<uint> connectedOut2;
        float* inBuf[2];
        float* inBufTmp[2];
        float* outBuf[2];
        float* unusedBuf;
        Buffers() noexcept;
        ~Buffers() noexcept;
        void setBufferSize(const uint32_t bufferSize, const bool createBuffers) noexcept;
        CARLA_PREVENT_HEAP_ALLOCATION
        CARLA_DECLARE_NON_COPY_CLASS(Buffers)
    } audioBuffers;
    RackGraph(CarlaEngine* const engine, const uint32_t inputs, const uint32_t outputs) noexcept;
    ~RackGraph() noexcept;
    void setBufferSize(const uint32_t bufferSize) noexcept;
    void setOffline(const bool offline) noexcept;
    bool connect(const uint groupA, const uint portA, const uint groupB, const uint portB) noexcept;
    bool disconnect(const uint connectionId) noexcept;
    void refresh(const bool sendHost, const bool sendOsc, const bool ignored, const char* const deviceName);
    const char* const* getConnections() const noexcept;
    bool getGroupAndPortIdFromFullName(const char* const fullPortName, uint& groupId, uint& portId) const noexcept;
    // the base, where plugins run
    void process(CarlaEngine::ProtectedData* const data, const float* inBuf[2], float* outBuf[2], const uint32_t frames);
    // extended, will call process() in the middle
    void processHelper(CarlaEngine::ProtectedData* const data, const float* const* const inBuf, float* const* const outBuf, const uint32_t frames);
    CarlaEngine* const kEngine;
    CARLA_DECLARE_NON_COPY_CLASS(RackGraph)
};
// -----------------------------------------------------------------------
// PatchbayGraph
class PatchbayGraph : private CarlaThread {
public:
    PatchbayConnectionList connections;
    AudioProcessorGraph graph;
    AudioSampleBuffer audioBuffer;
    AudioSampleBuffer cvInBuffer;
    AudioSampleBuffer cvOutBuffer;
    MidiBuffer midiBuffer;
    const uint32_t numAudioIns;
    const uint32_t numAudioOuts;
    const uint32_t numCVIns;
    const uint32_t numCVOuts;
    mutable CharStringListPtr retCon;
    bool usingExternalHost;
    bool usingExternalOSC;
    ExternalGraph extGraph;
    PatchbayGraph(CarlaEngine* const engine,
                  const uint32_t audioIns, const uint32_t audioOuts,
                  const uint32_t cvIns, const uint32_t cvOuts);
    ~PatchbayGraph();
    void setBufferSize(const uint32_t bufferSize);
    void setSampleRate(const double sampleRate);
    void setOffline(const bool offline);
    void addPlugin(CarlaPlugin* const plugin);
    void replacePlugin(CarlaPlugin* const oldPlugin, CarlaPlugin* const newPlugin);
    void renamePlugin(CarlaPlugin* const plugin, const char* const newName);
    void removePlugin(CarlaPlugin* const plugin);
    void removeAllPlugins();
    bool connect(const bool external, const uint groupA, const uint portA, const uint groupB, const uint portB);
    bool disconnect(const bool external, const uint connectionId);
    void disconnectInternalGroup(const uint groupId) noexcept;
    void refresh(const bool sendHost, const bool sendOsc, const bool external, const char* const deviceName);
    const char* const* getConnections(const bool external) const;
    bool getGroupAndPortIdFromFullName(const bool external, const char* const fullPortName, uint& groupId, uint& portId) const;
    void process(CarlaEngine::ProtectedData* const data,
                 const float* const* const inBuf,
                 float* const* const outBuf,
                 const uint32_t frames);
private:
    void run() override;
    CarlaEngine* const kEngine;
    CARLA_DECLARE_NON_COPY_CLASS(PatchbayGraph)
};
// -----------------------------------------------------------------------
CARLA_BACKEND_END_NAMESPACE
#endif // CARLA_ENGINE_GRAPH_HPP_INCLUDED
 |