|  | /*
 * Carla Native Plugins
 * Copyright (C) 2012-2014 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.
 */
#include "CarlaNative.hpp"
#ifndef CARLA_OS_WIN
# include <dlfcn.h>
#endif
#define SUNVOX_MAIN
#include "sunvox/sunvox.h"
class SunVoxFilePlugin : public PluginDescriptorClass
{
public:
    SunVoxFilePlugin(const HostDescriptor* const host)
        : PluginDescriptorClass(host),
          fSlot(sLastSlot++)
    {
        sv_open_slot(fSlot);
        sv_set_autostop(fSlot, 0);
    }
    ~SunVoxFilePlugin() override
    {
        sv_close_slot(fSlot);
    }
protected:
    // -------------------------------------------------------------------
    // Plugin state calls
    void setCustomData(const char* const key, const char* const value) override
    {
        CARLA_ASSERT(key != nullptr);
        CARLA_ASSERT(value != nullptr);
        if (std::strcmp(key, "file") != 0)
            return;
        sv_load(fSlot, value);
        sv_play_from_beginning(fSlot);
    }
    // -------------------------------------------------------------------
    // Plugin process calls
    void process(float**, float** outBuf, const uint32_t frames, const uint32_t, const MidiEvent* const) override
    {
        const TimeInfo* const timePos = getTimeInfo();
        if (timePos->playing)
        {
            float svBuffer[frames*2];
            for (uint32_t i=0, j=0; i < frames; ++i)
            {
                svBuffer[j++] = outBuf[0][i];
                svBuffer[j++] = outBuf[1][i];
            }
            unsigned int ticks = sv_get_ticks();
            ticks += timePos->frame * sTicksPerFrame;
            sv_audio_callback(svBuffer, frames, 0, ticks+10000);
        }
        else
        {
           FLOAT_CLEAR(outBuf[0], frames);
           FLOAT_CLEAR(outBuf[1], frames);
        }
    }
    // -------------------------------------------------------------------
    // Plugin UI calls
    void uiShow(const bool show) override
    {
        if (! show)
            return;
        if (const char* const filename = uiOpenFile(false, "Open Audio File", "MIDI Files *.mid;*.midi;;"))
        {
            uiCustomDataChanged("file", filename);
        }
        uiClosed();
    }
private:
    int fSlot;
    static int sInstanceCount;
    static int sLastSlot;
    static double sTicksPerFrame;
public:
    static PluginHandle _instantiate(HostDescriptor* host)
    {
        if (sInstanceCount == 0)
        {
            CARLA_ASSERT(sLastSlot == 0);
            CARLA_ASSERT(sTicksPerFrame == 0);
            if (sv_load_dll() != 0)
                return nullptr;
            const double sampleRate(host->get_sample_rate(host->handle));
            if (sv_init(nullptr, (int)sampleRate, 2, SV_INIT_FLAG_USER_AUDIO_CALLBACK|SV_INIT_FLAG_AUDIO_FLOAT32|SV_INIT_FLAG_ONE_THREAD) == 0)
                return nullptr;
            sTicksPerFrame = double(sv_get_ticks_per_second())/sampleRate;
        }
        sInstanceCount++;
        return new SunVoxFilePlugin(host);
    }
    static void _cleanup(PluginHandle handle)
    {
        delete (SunVoxFilePlugin*)handle;
        if (--sInstanceCount == 0)
        {
            CARLA_ASSERT(sLastSlot > 0);
            CARLA_ASSERT(sTicksPerFrame > 0.0);
            sLastSlot = 0;
            sTicksPerFrame = 0.0;
            sv_deinit();
            sv_unload_dll();
        }
    }
    CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(SunVoxFilePlugin)
};
int    SunVoxFilePlugin::sInstanceCount = 0;
int    SunVoxFilePlugin::sLastSlot = 0;
double SunVoxFilePlugin::sTicksPerFrame = 0.0;
// -----------------------------------------------------------------------
static const PluginDescriptor sunvoxfileDesc = {
    /* category  */ PLUGIN_CATEGORY_UTILITY,
    /* hints     */ static_cast<PluginHints>(PLUGIN_HAS_GUI),
    /* supports  */ static_cast<PluginSupports>(0x0),
    /* audioIns  */ 0,
    /* audioOuts */ 2,
    /* midiIns   */ 0,
    /* midiOuts  */ 0,
    /* paramIns  */ 0,
    /* paramOuts */ 0,
    /* name      */ "SunVox File",
    /* label     */ "sunvoxfile",
    /* maker     */ "falkTX",
    /* copyright */ "GNU GPL v2+",
    PluginDescriptorFILL(SunVoxFilePlugin)
};
// -----------------------------------------------------------------------
CARLA_EXPORT
void carla_register_native_plugin_sunvoxfile()
{
    carla_register_native_plugin(&sunvoxfileDesc);
}
// -----------------------------------------------------------------------
 |