Browse Source

Big push of the new plugins (experimental)

tags/1.9.6
falkTX 10 years ago
parent
commit
b23a391c3a
81 changed files with 6627 additions and 381 deletions
  1. +0
    -3
      Makefile
  2. BIN
      resources/bitmaps/zita-rev/redzita.png
  3. +0
    -7
      resources/resources.qrc
  4. +0
    -150
      resources/ui/carla_plugin_zita.ui
  5. +2
    -1
      source/Makefile.mk
  6. +0
    -147
      source/carla_skin.py
  7. +1
    -1
      source/includes/CarlaNativeExtUI.hpp
  8. +77
    -14
      source/includes/CarlaNativeJack.h
  9. +13
    -1
      source/native-plugins/Makefile
  10. +4
    -0
      source/native-plugins/_all.c
  11. BIN
      source/native-plugins/resources/at1/ctrlsect.png
  12. BIN
      source/native-plugins/resources/at1/hmeter0.png
  13. BIN
      source/native-plugins/resources/at1/hmeter1.png
  14. BIN
      source/native-plugins/resources/at1/hscale.png
  15. BIN
      source/native-plugins/resources/at1/midi.png
  16. BIN
      source/native-plugins/resources/at1/note.png
  17. BIN
      source/native-plugins/resources/at1/notesect.png
  18. +0
    -0
      source/native-plugins/resources/rev1/ambsect.png
  19. +0
    -0
      source/native-plugins/resources/rev1/eq1sect.png
  20. +0
    -0
      source/native-plugins/resources/rev1/eq2sect.png
  21. +0
    -0
      source/native-plugins/resources/rev1/mixsect.png
  22. +0
    -0
      source/native-plugins/resources/rev1/revsect.png
  23. +453
    -0
      source/native-plugins/zita-at1.cpp
  24. +140
    -0
      source/native-plugins/zita-at1/button.cc
  25. +97
    -0
      source/native-plugins/zita-at1/button.h
  26. +32
    -0
      source/native-plugins/zita-at1/global.h
  27. +186
    -0
      source/native-plugins/zita-at1/guiclass.cc
  28. +145
    -0
      source/native-plugins/zita-at1/guiclass.h
  29. +162
    -0
      source/native-plugins/zita-at1/jclient.cc
  30. +82
    -0
      source/native-plugins/zita-at1/jclient.h
  31. +359
    -0
      source/native-plugins/zita-at1/mainwin.cc
  32. +99
    -0
      source/native-plugins/zita-at1/mainwin.h
  33. +129
    -0
      source/native-plugins/zita-at1/png2img.cc
  34. +35
    -0
      source/native-plugins/zita-at1/png2img.h
  35. +449
    -0
      source/native-plugins/zita-at1/retuner.cc
  36. +133
    -0
      source/native-plugins/zita-at1/retuner.h
  37. +211
    -0
      source/native-plugins/zita-at1/rotary.cc
  38. +119
    -0
      source/native-plugins/zita-at1/rotary.h
  39. +163
    -0
      source/native-plugins/zita-at1/styles.cc
  40. +70
    -0
      source/native-plugins/zita-at1/styles.h
  41. +86
    -0
      source/native-plugins/zita-at1/tmeter.cc
  42. +59
    -0
      source/native-plugins/zita-at1/tmeter.h
  43. +39
    -33
      source/native-plugins/zita-bls1.cpp
  44. +5
    -0
      source/native-plugins/zita-bls1/guiclass.cc
  45. +4
    -0
      source/native-plugins/zita-bls1/guiclass.h
  46. +5
    -0
      source/native-plugins/zita-bls1/hp3filt.cc
  47. +4
    -0
      source/native-plugins/zita-bls1/hp3filt.h
  48. +3
    -0
      source/native-plugins/zita-bls1/jclient.cc
  49. +4
    -0
      source/native-plugins/zita-bls1/jclient.h
  50. +4
    -0
      source/native-plugins/zita-bls1/lfshelf2.cc
  51. +4
    -0
      source/native-plugins/zita-bls1/lfshelf2.h
  52. +5
    -1
      source/native-plugins/zita-bls1/mainwin.cc
  53. +7
    -1
      source/native-plugins/zita-bls1/mainwin.h
  54. +4
    -0
      source/native-plugins/zita-bls1/png2img.cc
  55. +2
    -0
      source/native-plugins/zita-bls1/png2img.h
  56. +3
    -0
      source/native-plugins/zita-bls1/rotary.cc
  57. +4
    -0
      source/native-plugins/zita-bls1/rotary.h
  58. +5
    -0
      source/native-plugins/zita-bls1/shuffler.cc
  59. +4
    -0
      source/native-plugins/zita-bls1/shuffler.h
  60. +25
    -19
      source/native-plugins/zita-bls1/styles.cc
  61. +6
    -2
      source/native-plugins/zita-bls1/styles.h
  62. +129
    -0
      source/native-plugins/zita-common.hpp
  63. +577
    -0
      source/native-plugins/zita-rev1.cpp
  64. +32
    -0
      source/native-plugins/zita-rev1/global.h
  65. +161
    -0
      source/native-plugins/zita-rev1/guiclass.cc
  66. +103
    -0
      source/native-plugins/zita-rev1/guiclass.h
  67. +140
    -0
      source/native-plugins/zita-rev1/jclient.cc
  68. +72
    -0
      source/native-plugins/zita-rev1/jclient.h
  69. +245
    -0
      source/native-plugins/zita-rev1/mainwin.cc
  70. +88
    -0
      source/native-plugins/zita-rev1/mainwin.h
  71. +200
    -0
      source/native-plugins/zita-rev1/pareq.cc
  72. +81
    -0
      source/native-plugins/zita-rev1/pareq.h
  73. +136
    -0
      source/native-plugins/zita-rev1/png2img.cc
  74. +35
    -0
      source/native-plugins/zita-rev1/png2img.h
  75. +380
    -0
      source/native-plugins/zita-rev1/reverb.cc
  76. +228
    -0
      source/native-plugins/zita-rev1/reverb.h
  77. +207
    -0
      source/native-plugins/zita-rev1/rotary.cc
  78. +119
    -0
      source/native-plugins/zita-rev1/rotary.h
  79. +177
    -0
      source/native-plugins/zita-rev1/styles.cc
  80. +73
    -0
      source/native-plugins/zita-rev1/styles.h
  81. +1
    -1
      source/utils/CarlaExternalUI.hpp

+ 0
- 3
Makefile View File

@@ -284,7 +284,6 @@ RES = \
bin/resources/ui_carla_plugin_calf.py \
bin/resources/ui_carla_plugin_default.py \
bin/resources/ui_carla_plugin_sf2.py \
bin/resources/ui_carla_plugin_zita.py \
bin/resources/ui_carla_plugin_zynfx.py \
bin/resources/ui_carla_refresh.py \
bin/resources/ui_carla_settings.py \
@@ -330,7 +329,6 @@ UIs = \
source/ui_carla_plugin_calf.py \
source/ui_carla_plugin_default.py \
source/ui_carla_plugin_sf2.py \
source/ui_carla_plugin_zita.py \
source/ui_carla_plugin_zynfx.py \
source/ui_carla_refresh.py \
source/ui_carla_settings.py \
@@ -552,7 +550,6 @@ install:
$(LINK) $(PREFIX)/share/carla/ui_carla_plugin_calf.py $(DESTDIR)$(PREFIX)/share/carla/resources/
$(LINK) $(PREFIX)/share/carla/ui_carla_plugin_default.py $(DESTDIR)$(PREFIX)/share/carla/resources/
$(LINK) $(PREFIX)/share/carla/ui_carla_plugin_sf2.py $(DESTDIR)$(PREFIX)/share/carla/resources/
$(LINK) $(PREFIX)/share/carla/ui_carla_plugin_zita.py $(DESTDIR)$(PREFIX)/share/carla/resources/
$(LINK) $(PREFIX)/share/carla/ui_carla_plugin_zynfx.py $(DESTDIR)$(PREFIX)/share/carla/resources/
$(LINK) $(PREFIX)/share/carla/ui_carla_refresh.py $(DESTDIR)$(PREFIX)/share/carla/resources/
$(LINK) $(PREFIX)/share/carla/ui_carla_settings.py $(DESTDIR)$(PREFIX)/share/carla/resources/


BIN
resources/bitmaps/zita-rev/redzita.png View File

Before After
Width: 35  |  Height: 75  |  Size: 1.2KB

+ 0
- 7
resources/resources.qrc View File

@@ -130,13 +130,6 @@
<file>bitmaps/style/arrow.png</file>
<file>bitmaps/style/groupbox.png</file>

<file>bitmaps/zita-rev/ambsect.png</file>
<file>bitmaps/zita-rev/eq1sect.png</file>
<file>bitmaps/zita-rev/eq2sect.png</file>
<file>bitmaps/zita-rev/mixsect.png</file>
<file>bitmaps/zita-rev/redzita.png</file>
<file>bitmaps/zita-rev/revsect.png</file>

<file>scalable/pb_generic.svg</file>
<file>scalable/pb_hardware.svg</file>
<file>scalable/pb_plugin.svg</file>


+ 0
- 150
resources/ui/carla_plugin_zita.ui View File

@@ -1,150 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PluginWidget</class>
<widget class="QFrame" name="PluginWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>640</width>
<height>75</height>
</rect>
</property>
<property name="contextMenuPolicy">
<enum>Qt::CustomContextMenu</enum>
</property>
<property name="windowTitle">
<string>Frame</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="QWidget" name="w_revsect" native="true">
<property name="minimumSize">
<size>
<width>315</width>
<height>75</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>315</width>
<height>75</height>
</size>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<number>0</number>
</property>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="w_eq1sect" native="true">
<property name="minimumSize">
<size>
<width>110</width>
<height>75</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>110</width>
<height>75</height>
</size>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<number>0</number>
</property>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="w_eq2sect" native="true">
<property name="minimumSize">
<size>
<width>110</width>
<height>75</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>110</width>
<height>75</height>
</size>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<number>0</number>
</property>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="w_ambmixsect" native="true">
<property name="minimumSize">
<size>
<width>70</width>
<height>75</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>70</width>
<height>75</height>
</size>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<number>0</number>
</property>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="w_redzita" native="true">
<property name="minimumSize">
<size>
<width>35</width>
<height>75</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>35</width>
<height>75</height>
</size>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<number>0</number>
</property>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

+ 2
- 1
source/Makefile.mk View File

@@ -385,7 +385,8 @@ endif

ifeq ($(EXPERIMENTAL_PLUGINS),true)
NATIVE_PLUGINS_FLAGS += -DHAVE_EXPERIMENTAL_PLUGINS
NATIVE_PLUGINS_LIBS += -lzita-convolver $(shell pkg-config --libs cairo fftw3f libpng12 x11 xft) -lclthreads -lclxclient
NATIVE_PLUGINS_LIBS += -lclthreads -lclxclient -lzita-convolver -lzita-resampler
NATIVE_PLUGINS_LIBS += $(shell pkg-config --libs cairo fftw3f libpng12 x11 xft)
endif

ifeq ($(HAVE_ZYN_DEPS),true)


+ 0
- 147
source/carla_skin.py View File

@@ -39,7 +39,6 @@ import ui_carla_plugin_default
import ui_carla_plugin_basic_fx
import ui_carla_plugin_calf
import ui_carla_plugin_sf2
import ui_carla_plugin_zita
import ui_carla_plugin_zynfx

from carla_widgets import *
@@ -1578,150 +1577,6 @@ class PluginSlot_SF2(AbstractPluginSlot):

# ------------------------------------------------------------------------------------------------------------

class PluginSlot_ZitaRev(AbstractPluginSlot):
def __init__(self, parent, host, pluginId):
AbstractPluginSlot.__init__(self, parent, host, pluginId)
self.ui = ui_carla_plugin_zita.Ui_PluginWidget()
self.ui.setupUi(self)

# -------------------------------------------------------------
# Internal stuff

audioCount = self.host.get_audio_port_count_info(self.fPluginId)

# -------------------------------------------------------------
# Set-up GUI

self.setMinimumWidth(640)

self.setStyleSheet("""
PluginSlot_ZitaRev#PluginWidget {
background-color: #404040;
border: 2px solid transparent;
}
QWidget#w_revsect {
background-image: url(:/bitmaps/zita-rev/revsect.png);
}
QWidget#w_eq1sect {
background-image: url(:/bitmaps/zita-rev/eq1sect.png);
}
QWidget#w_eq2sect {
background-image: url(:/bitmaps/zita-rev/eq2sect.png);
}
QWidget#w_ambmixsect {
background-image: url(:/bitmaps/zita-rev/%s.png);
}
QWidget#w_redzita {
background-image: url(:/bitmaps/zita-rev/redzita.png);
}
""" % ("mixsect" if audioCount['outs'] == 2 else "ambsect"))

# -------------------------------------------------------------
# Set-up Knobs

self.fKnobDelay = PixmapDial(self, 0)
self.fKnobDelay.setPixmap(6)
self.fKnobDelay.setCustomPaintMode(PixmapDial.CUSTOM_PAINT_MODE_ZITA)
self.fKnobDelay.setMinimum(0.02)
self.fKnobDelay.setMaximum(0.10)

self.fKnobXover = PixmapDial(self, 1)
self.fKnobXover.setPixmap(6)
self.fKnobXover.setCustomPaintMode(PixmapDial.CUSTOM_PAINT_MODE_ZITA)
self.fKnobXover.setMinimum(50.0)
self.fKnobXover.setMaximum(1000.0)

self.fKnobRtLow = PixmapDial(self, 2)
self.fKnobRtLow.setPixmap(6)
self.fKnobRtLow.setCustomPaintMode(PixmapDial.CUSTOM_PAINT_MODE_ZITA)
self.fKnobRtLow.setMinimum(1.0)
self.fKnobRtLow.setMaximum(8.0)

self.fKnobRtMid = PixmapDial(self, 3)
self.fKnobRtMid.setPixmap(6)
self.fKnobRtMid.setCustomPaintMode(PixmapDial.CUSTOM_PAINT_MODE_ZITA)
self.fKnobRtMid.setMinimum(1.0)
self.fKnobRtMid.setMaximum(8.0)

self.fKnobDamping = PixmapDial(self, 4)
self.fKnobDamping.setPixmap(6)
self.fKnobDamping.setCustomPaintMode(PixmapDial.CUSTOM_PAINT_MODE_ZITA)
self.fKnobDamping.setMinimum(1500.0)
self.fKnobDamping.setMaximum(24000.0)

self.fKnobEq1Freq = PixmapDial(self, 5)
self.fKnobEq1Freq.setPixmap(6)
self.fKnobEq1Freq.setCustomPaintMode(PixmapDial.CUSTOM_PAINT_MODE_ZITA)
self.fKnobEq1Freq.setMinimum(40.0)
self.fKnobEq1Freq.setMaximum(10000.0)

self.fKnobEq1Gain = PixmapDial(self, 6)
self.fKnobEq1Gain.setPixmap(6)
self.fKnobEq1Gain.setCustomPaintMode(PixmapDial.CUSTOM_PAINT_MODE_ZITA)
self.fKnobEq1Gain.setMinimum(-20.0)
self.fKnobEq1Gain.setMaximum(20.0)

self.fKnobEq2Freq = PixmapDial(self, 7)
self.fKnobEq2Freq.setPixmap(6)
self.fKnobEq2Freq.setCustomPaintMode(PixmapDial.CUSTOM_PAINT_MODE_ZITA)
self.fKnobEq2Freq.setMinimum(40.0)
self.fKnobEq2Freq.setMaximum(10000.0)

self.fKnobEq2Gain = PixmapDial(self, 8)
self.fKnobEq2Gain.setPixmap(6)
self.fKnobEq2Gain.setCustomPaintMode(PixmapDial.CUSTOM_PAINT_MODE_ZITA)
self.fKnobEq2Gain.setMinimum(-20.0)
self.fKnobEq2Gain.setMaximum(20.0)

self.fKnobMix = PixmapDial(self, 9)
self.fKnobMix.setPixmap(6)
self.fKnobMix.setCustomPaintMode(PixmapDial.CUSTOM_PAINT_MODE_ZITA)
self.fKnobMix.setMinimum(0.0)
self.fKnobMix.setMaximum(1.0)

self.fParameterList.append([0, self.fKnobDelay])
self.fParameterList.append([1, self.fKnobXover])
self.fParameterList.append([2, self.fKnobRtLow])
self.fParameterList.append([3, self.fKnobRtMid])
self.fParameterList.append([4, self.fKnobDamping])
self.fParameterList.append([5, self.fKnobEq1Freq])
self.fParameterList.append([6, self.fKnobEq1Gain])
self.fParameterList.append([7, self.fKnobEq2Freq])
self.fParameterList.append([8, self.fKnobEq2Gain])
self.fParameterList.append([9, self.fKnobMix])

# -------------------------------------------------------------

self.ready()

self.customContextMenuRequested.connect(self.slot_showDefaultCustomMenu)

#------------------------------------------------------------------

def getFixedHeight(self):
return 79

#------------------------------------------------------------------

def paintEvent(self, event):
AbstractPluginSlot.paintEvent(self, event)
self.drawOutline()

def resizeEvent(self, event):
self.fKnobDelay.move(self.ui.w_revsect.x()+31, self.ui.w_revsect.y()+33)
self.fKnobXover.move(self.ui.w_revsect.x()+93, self.ui.w_revsect.y()+18)
self.fKnobRtLow.move(self.ui.w_revsect.x()+148, self.ui.w_revsect.y()+18)
self.fKnobRtMid.move(self.ui.w_revsect.x()+208, self.ui.w_revsect.y()+18)
self.fKnobDamping.move(self.ui.w_revsect.x()+268, self.ui.w_revsect.y()+18)
self.fKnobEq1Freq.move(self.ui.w_eq1sect.x()+20, self.ui.w_eq1sect.y()+33)
self.fKnobEq1Gain.move(self.ui.w_eq1sect.x()+69, self.ui.w_eq1sect.y()+18)
self.fKnobEq2Freq.move(self.ui.w_eq2sect.x()+20, self.ui.w_eq2sect.y()+33)
self.fKnobEq2Gain.move(self.ui.w_eq2sect.x()+69, self.ui.w_eq2sect.y()+18)
self.fKnobMix.move(self.ui.w_ambmixsect.x()+24, self.ui.w_ambmixsect.y()+33)
AbstractPluginSlot.resizeEvent(self, event)

# ------------------------------------------------------------------------------------------------------------

class PluginSlot_ZynFX(AbstractPluginSlot):
def __init__(self, parent, host, pluginId):
AbstractPluginSlot.__init__(self, parent, host, pluginId)
@@ -1968,8 +1823,6 @@ def createPluginSlot(parent, host, pluginId, useSkins):
return PluginSlot_ZynFX(parent, host, pluginId)

elif pluginInfo['type'] == PLUGIN_LADSPA:
if (pluginLabel == "zita-reverb" and uniqueId == 3701) or (pluginLabel == "zita-reverb-amb" and uniqueId == 3702):
return PluginSlot_ZitaRev(parent, host, pluginId)
if pluginLabel.startswith("Zyn") and pluginMaker.startswith("Josep Andreu"):
return PluginSlot_ZynFX(parent, host, pluginId)



+ 1
- 1
source/includes/CarlaNativeExtUI.hpp View File

@@ -39,7 +39,7 @@ public:
fExtUiPath(extUiPath),
leakDetector_NativePluginAndUiClass() {}

~NativePluginAndUiClass() noexcept override {}
//~NativePluginAndUiClass() noexcept override {}

protected:
// -------------------------------------------------------------------


+ 77
- 14
source/includes/CarlaNativeJack.h View File

@@ -31,18 +31,27 @@ extern "C" {
/* ------------------------------------------------------------------------------------------------------------
* Macros */

#define JACK_DEFAULT_AUDIO_TYPE "audio"
#define JACK_DEFAULT_MIDI_TYPE "midi"
#define JACK_DEFAULT_AUDIO_TYPE "32 bit float mono audio"
#define JACK_DEFAULT_MIDI_TYPE "8 bit raw midi"

/* ------------------------------------------------------------------------------------------------------------
* Basic types */

typedef float jack_default_audio_sample_t;
typedef uint8_t jack_midi_data_t;
typedef uint32_t jack_nframes_t;

typedef void (*jack_shutdown_callback)(void* ptr);
typedef int (*jack_process_callback)(jack_nframes_t nframes, void* ptr);

/*
* Helper struct for midi events.
*/
typedef struct {
uint32_t count;
NativeMidiEvent* events;
} NativeMidiEventsBuffer;

/* ------------------------------------------------------------------------------------------------------------
* Enums */

@@ -81,15 +90,20 @@ enum JackStatus {
};

typedef enum JackOptions jack_options_t;
typedef enum JackStatus jack_status_t;
typedef enum JackStatus jack_status_t;

/* ------------------------------------------------------------------------------------------------------------
* Structs */

typedef struct {
bool registered;
bool isAudio;
uint flags;
void* buffer;

union {
void* audio;
NativeMidiEventsBuffer midi;
} buffer;
} jack_port_t;

typedef struct {
@@ -104,10 +118,18 @@ typedef struct {
void* processPtr;

// ports
jack_port_t portsAudioIn[8];
jack_port_t portsAudioOut[8];
jack_port_t portsAudioIn [16];
jack_port_t portsAudioOut[16];
jack_port_t portsMidiIn [16];
jack_port_t portsMidiOut [16];
} jack_client_t;

typedef struct {
uint32_t time;
uint32_t size;
uint8_t* buffer;
} jack_midi_event_t;

/* ------------------------------------------------------------------------------------------------------------
* Client functions */

@@ -163,18 +185,31 @@ int jack_set_process_callback(jack_client_t* client, jack_process_callback callb
static inline
jack_port_t* jack_port_register(jack_client_t* client, const char* name, const char* type, ulong flags, ulong buffersize)
{
jack_port_t* const ports = (flags & JackPortIsInput) ? client->portsAudioIn : client->portsAudioOut;
const bool isAudio = strcmp(type, JACK_DEFAULT_AUDIO_TYPE) == 0;
const bool isMIDI = strcmp(type, JACK_DEFAULT_MIDI_TYPE ) == 0;

for (int i=0; i<8; ++i)
if (! (isAudio || isMIDI))
return NULL;

jack_port_t* ports;

if (isAudio)
ports = (flags & JackPortIsInput) ? client->portsAudioIn : client->portsAudioOut;
else
ports = (flags & JackPortIsInput) ? client->portsMidiIn : client->portsMidiOut;

for (int i=0; i<16; ++i)
{
jack_port_t* const port = &ports[i];

if (port->registered)
continue;

memset(port, 0, sizeof(jack_port_t));

port->registered = true;
port->isAudio = isAudio;
port->flags = flags;
port->buffer = NULL;

return port;
}
@@ -196,9 +231,7 @@ int jack_port_unregister(jack_client_t* client, jack_port_t* port)
{
if (&ports[i] == port)
{
port->registered = false;
port->flags = 0x0;
port->buffer = NULL;
memset(port, 0, sizeof(jack_port_t));
return 0;
}
}
@@ -207,14 +240,44 @@ int jack_port_unregister(jack_client_t* client, jack_port_t* port)
}

static inline
void* jack_port_get_buffer(const jack_port_t* port, jack_nframes_t nframes)
void* jack_port_get_buffer(jack_port_t* port, jack_nframes_t nframes)
{
return port->buffer;
return port->isAudio ? port->buffer.audio : &port->buffer.midi;

// unused
(void)nframes;
}

/* ------------------------------------------------------------------------------------------------------------
* MIDI functions */

static inline
uint32_t jack_midi_get_event_count(void* port_buffer)
{
NativeMidiEventsBuffer* const midi_buffer = (NativeMidiEventsBuffer*)port_buffer;

return midi_buffer->count;
}

static inline
int jack_midi_event_get(jack_midi_event_t* event, void* port_buffer, uint32_t event_index)
{
NativeMidiEventsBuffer* const midi_buffer = (NativeMidiEventsBuffer*)port_buffer;

if (midi_buffer->count == 0)
return ENODATA;
if (event_index >= midi_buffer->count)
return 1; // FIXME

NativeMidiEvent* const midiEvent = &midi_buffer->events[event_index];

event->time = midiEvent->time;
event->size = midiEvent->size;
event->buffer = midiEvent->data;

return 0;
}

/* ------------------------------------------------------------------------------------------------------------
* [De/]Activate */



+ 13
- 1
source/native-plugins/Makefile View File

@@ -147,7 +147,9 @@ endif

ifeq ($(EXPERIMENTAL_PLUGINS),true)
OBJS += \
$(OBJDIR)/zita-bls1.cpp.o
$(OBJDIR)/zita-at1.cpp.o \
$(OBJDIR)/zita-bls1.cpp.o \
$(OBJDIR)/zita-rev1.cpp.o
endif

# ----------------------------------------------------------------------------------------------------------------------------
@@ -250,11 +252,21 @@ $(OBJDIR)/zynaddsubfx-ui.cpp.o: zynaddsubfx-ui.cpp $(ZYN_UI_FILES_H) $(ZYN_UI_FI

# ----------------------------------------------------------------------------------------------------------------------------

$(OBJDIR)/zita-at1.cpp.o: zita-at1.cpp
-@mkdir -p $(OBJDIR)
@echo "Compiling $<"
@$(CXX) $< $(BUILD_CXX_FLAGS) $(shell pkg-config --cflags fftw3f x11 xft) -Wno-unused-parameter -Wno-unused-result -c -o $@

$(OBJDIR)/zita-bls1.cpp.o: zita-bls1.cpp
-@mkdir -p $(OBJDIR)
@echo "Compiling $<"
@$(CXX) $< $(BUILD_CXX_FLAGS) $(shell pkg-config --cflags cairo fftw3f libpng12 x11 xft) -Wno-unused-parameter -Wno-unused-result -c -o $@

$(OBJDIR)/zita-rev1.cpp.o: zita-rev1.cpp
-@mkdir -p $(OBJDIR)
@echo "Compiling $<"
@$(CXX) $< $(BUILD_CXX_FLAGS) $(shell pkg-config --cflags fftw3f x11 xft) -Wno-unused-parameter -Wno-unused-result -c -o $@

# ----------------------------------------------------------------------------------------------------------------------------

$(OBJDIR)/%.cpp.o: %.cpp


+ 4
- 0
source/native-plugins/_all.c View File

@@ -61,7 +61,9 @@ extern void carla_register_native_plugin_zynaddsubfx_synth(void);

#ifdef WANT_EXPERIMENTAL_PLUGINS
// Experimental plugins
extern void carla_register_native_plugin_zita_at1(void);
extern void carla_register_native_plugin_zita_bls1(void);
extern void carla_register_native_plugin_zita_rev1(void);
#endif

// -----------------------------------------------------------------------
@@ -110,7 +112,9 @@ void carla_register_all_plugins(void)

#ifdef WANT_EXPERIMENTAL_PLUGINS
// Experimental plugins
carla_register_native_plugin_zita_at1();
carla_register_native_plugin_zita_bls1();
carla_register_native_plugin_zita_rev1();
#endif
}



BIN
source/native-plugins/resources/at1/ctrlsect.png View File

Before After
Width: 315  |  Height: 75  |  Size: 7.7KB

BIN
source/native-plugins/resources/at1/hmeter0.png View File

Before After
Width: 173  |  Height: 7  |  Size: 245B

BIN
source/native-plugins/resources/at1/hmeter1.png View File

Before After
Width: 173  |  Height: 7  |  Size: 241B

BIN
source/native-plugins/resources/at1/hscale.png View File

Before After
Width: 173  |  Height: 11  |  Size: 284B

BIN
source/native-plugins/resources/at1/midi.png View File

Before After
Width: 40  |  Height: 96  |  Size: 1.6KB

BIN
source/native-plugins/resources/at1/note.png View File

Before After
Width: 16  |  Height: 64  |  Size: 643B

BIN
source/native-plugins/resources/at1/notesect.png View File

Before After
Width: 190  |  Height: 75  |  Size: 504B

resources/bitmaps/zita-rev/ambsect.png → source/native-plugins/resources/rev1/ambsect.png View File


resources/bitmaps/zita-rev/eq1sect.png → source/native-plugins/resources/rev1/eq1sect.png View File


resources/bitmaps/zita-rev/eq2sect.png → source/native-plugins/resources/rev1/eq2sect.png View File


resources/bitmaps/zita-rev/mixsect.png → source/native-plugins/resources/rev1/mixsect.png View File


resources/bitmaps/zita-rev/revsect.png → source/native-plugins/resources/rev1/revsect.png View File


+ 453
- 0
source/native-plugins/zita-at1.cpp View File

@@ -0,0 +1,453 @@
/*
* Carla Native Plugins
* Copyright (C) 2012-2015 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"
#include "CarlaMathUtils.hpp"
#include "CarlaJuceUtils.hpp"

#include "juce_audio_basics.h"

#include "zita-common.hpp"
#include "zita-at1/button.cc"
#include "zita-at1/guiclass.cc"
#include "zita-at1/jclient.cc"
#include "zita-at1/mainwin.cc"
#include "zita-at1/png2img.cc"
#include "zita-at1/retuner.cc"
#include "zita-at1/rotary.cc"
#include "zita-at1/styles.cc"
#include "zita-at1/tmeter.cc"

using juce::FloatVectorOperations;
using juce::ScopedPointer;

using namespace AT1;

// -----------------------------------------------------------------------
// AT1 Plugin

class AT1Plugin : public NativePluginClass,
private Mainwin::ValueChangedCallback
{
public:
enum Parameters {
// rotary knobs
kParameterR_TUNE,
kParameterR_FILT,
kParameterR_BIAS,
kParameterR_CORR,
kParameterR_OFFS,
// knob count
kParameterNROTARY,
// midi channel
kParameterM_CHANNEL = kParameterNROTARY,
// final count
kNumParameters
};

AT1Plugin(const NativeHostDescriptor* const host)
: NativePluginClass(host),
fJackClient(),
xresman(),
jclient(nullptr),
display(nullptr),
rootwin(nullptr),
mainwin(nullptr),
handler(nullptr),
handlerThread(),
leakDetector_AT1Plugin()
{
CARLA_SAFE_ASSERT(host != nullptr);

carla_zeroStruct(fJackClient);

fJackClient.clientName = "at1";
fJackClient.bufferSize = getBufferSize();
fJackClient.sampleRate = getSampleRate();

int argc = 1;
char* argv[] = { (char*)"at1" };
xresman.init(&argc, argv, (char*)"at1", nullptr, 0);

jclient = new Jclient(xresman.rname(), &fJackClient);

// set initial values
fParameters[kParameterR_TUNE] = 440.0f;
fParameters[kParameterR_FILT] = 0.1f;
fParameters[kParameterR_BIAS] = 0.5f;
fParameters[kParameterR_CORR] = 1.0f;
fParameters[kParameterR_OFFS] = 0.0f;

fParameters[kParameterM_CHANNEL] = 0.0f;

Retuner* const retuner(jclient->retuner());

jclient->set_midichan(-1);
retuner->set_refpitch(fParameters[kParameterR_TUNE]);
retuner->set_corrfilt(fParameters[kParameterR_FILT]);
retuner->set_notebias(fParameters[kParameterR_BIAS]);
retuner->set_corrgain(fParameters[kParameterR_CORR]);
retuner->set_corroffs(fParameters[kParameterR_OFFS]);
}

// -------------------------------------------------------------------
// Plugin parameter calls

uint32_t getParameterCount() const override
{
return kNumParameters;
}

const NativeParameter* getParameterInfo(const uint32_t index) const override
{
CARLA_SAFE_ASSERT_RETURN(index < kNumParameters, nullptr);

static NativeParameter param;
static NativeParameterScalePoint scalePoints[17];

int hints = NATIVE_PARAMETER_IS_ENABLED|NATIVE_PARAMETER_IS_AUTOMABLE;

// reset
param.name = nullptr;
param.unit = nullptr;
param.ranges.def = 0.0f;
param.ranges.min = 0.0f;
param.ranges.max = 1.0f;
param.ranges.step = 1.0f;
param.ranges.stepSmall = 1.0f;
param.ranges.stepLarge = 1.0f;
param.scalePointCount = 0;
param.scalePoints = nullptr;

switch (index)
{
case kParameterR_TUNE:
param.name = "Tuning";
param.ranges.def = 440.0f;
param.ranges.min = 400.0f;
param.ranges.max = 480.0f;
break;
case kParameterR_FILT:
hints |= NATIVE_PARAMETER_IS_LOGARITHMIC;
param.name = "Filter";
param.ranges.def = 0.1f;
param.ranges.min = 0.02f;
param.ranges.max = 0.5f;
break;
case kParameterR_BIAS:
param.name = "Bias";
param.ranges.def = 0.5f;
param.ranges.min = 0.0f;
param.ranges.max = 1.0f;
break;
case kParameterR_CORR:
param.name = "Correction";
param.ranges.def = 1.0f;
param.ranges.min = 0.0f;
param.ranges.max = 1.0f;
break;
case kParameterR_OFFS:
param.name = "OfOfset";
param.ranges.def = 0.0f;
param.ranges.min = -2.0f;
param.ranges.max = 2.0f;
break;
case kParameterM_CHANNEL:
hints |= NATIVE_PARAMETER_USES_SCALEPOINTS;
param.name = "MIDI Channel";
param.ranges.def = 0.0f;
param.ranges.min = 0.0f;
param.ranges.max = 16.0f;
param.scalePointCount = 17;
param.scalePoints = scalePoints;
scalePoints[ 0].value = 0.0f;
scalePoints[ 0].label = "Omni";
scalePoints[ 1].value = 1.0f;
scalePoints[ 1].label = "1";
scalePoints[ 2].value = 2.0f;
scalePoints[ 2].label = "2";
scalePoints[ 3].value = 3.0f;
scalePoints[ 3].label = "3";
scalePoints[ 4].value = 4.0f;
scalePoints[ 4].label = "4";
scalePoints[ 5].value = 5.0f;
scalePoints[ 5].label = "5";
scalePoints[ 6].value = 6.0f;
scalePoints[ 6].label = "6";
scalePoints[ 7].value = 7.0f;
scalePoints[ 7].label = "7";
scalePoints[ 8].value = 8.0f;
scalePoints[ 8].label = "8";
scalePoints[ 9].value = 9.0f;
scalePoints[ 9].label = "9";
scalePoints[10].value = 10.0f;
scalePoints[10].label = "10";
scalePoints[11].value = 11.0f;
scalePoints[11].label = "11";
scalePoints[12].value = 12.0f;
scalePoints[12].label = "12";
scalePoints[13].value = 13.0f;
scalePoints[13].label = "13";
scalePoints[14].value = 14.0f;
scalePoints[14].label = "14";
scalePoints[15].value = 15.0f;
scalePoints[15].label = "15";
scalePoints[16].value = 16.0f;
scalePoints[16].label = "16";
break;
}

param.hints = static_cast<NativeParameterHints>(hints);

return &param;
}

float getParameterValue(const uint32_t index) const override
{
CARLA_SAFE_ASSERT_RETURN(index < kNumParameters, 0.0f);

return fParameters[index];
}

// -------------------------------------------------------------------
// Plugin state calls

void setParameterValue(const uint32_t index, const float value) override
{
CARLA_SAFE_ASSERT_RETURN(index < kNumParameters,);

fParameters[index] = value;

Retuner* const retuner(jclient->retuner());

switch (index)
{
case kParameterR_TUNE:
retuner->set_refpitch(value);
break;
case kParameterR_FILT:
retuner->set_corrfilt(value);
break;
case kParameterR_BIAS:
retuner->set_notebias(value);
break;
case kParameterR_CORR:
retuner->set_corrgain(value);
break;
case kParameterR_OFFS:
retuner->set_corroffs(value);
break;
case kParameterM_CHANNEL:
jclient->set_midichan(value-1.0f);
break;
}
}

// -------------------------------------------------------------------
// Plugin process calls

void process(float** const inBuffer, float** const outBuffer, const uint32_t frames,
const NativeMidiEvent* const midiEvents, const uint32_t midiEventCount) override
{
if (! fJackClient.active)
{
FloatVectorOperations::clear(outBuffer[0], static_cast<int>(frames));
return;
}

fJackClient.portsAudioIn [0].buffer.audio = inBuffer [0];
fJackClient.portsAudioOut[0].buffer.audio = outBuffer[0];

fJackClient.portsMidiIn[0].buffer.midi.count = midiEventCount;
fJackClient.portsMidiIn[0].buffer.midi.events = const_cast<NativeMidiEvent*>(midiEvents);

fJackClient.processCallback(frames, fJackClient.processPtr);
}

// -------------------------------------------------------------------
// Plugin UI calls

void uiShow(const bool show) override
{
if (show)
{
if (display != nullptr)
return;

display = new X_display(nullptr);

if (display->dpy() == nullptr)
return hostUiUnavailable();

styles_init(display, &xresman, getResourceDir());

rootwin = new X_rootwin(display);
mainwin = new Mainwin(rootwin, &xresman, 0, 0, jclient, this);
rootwin->handle_event();
mainwin->x_set_title(getUiName());

handler = new X_handler(display, mainwin, EV_X11);

if (const uintptr_t winId = getUiParentId())
XSetTransientForHint(display->dpy(), mainwin->win(), static_cast<Window>(winId));

handler->next_event();
XFlush(display->dpy());

handlerThread.setupAndRun(handler, rootwin, mainwin);
}
else
{
if (handlerThread.isThreadRunning())
handlerThread.stopThread();

handler = nullptr;
mainwin = nullptr;
rootwin = nullptr;
display = nullptr;
}
}

void uiIdle() override
{
if (mainwin == nullptr)
return;

if (handlerThread.wasClosed())
{
{
const CarlaMutexLocker cml(handlerThread.getLock());
handler = nullptr;
mainwin = nullptr;
rootwin = nullptr;
display = nullptr;
}
uiClosed();
}
}

void uiSetParameterValue(const uint32_t index, const float value) override
{
CARLA_SAFE_ASSERT_RETURN(index < kNumParameters,);

if (mainwin == nullptr)
return;

const CarlaMutexLocker cml(handlerThread.getLock());

if (index < kParameterNROTARY)
{
mainwin->_rotary[index]->set_value(value);
return;
}
if (index == kParameterM_CHANNEL)
{
mainwin->setchan_ui(value);
return;
}
}

// -------------------------------------------------------------------
// Plugin dispatcher calls

void bufferSizeChanged(const uint32_t bufferSize) override
{
fJackClient.bufferSize = bufferSize;
}

void sampleRateChanged(const double sampleRate) override
{
fJackClient.sampleRate = sampleRate;
}

void uiNameChanged(const char* const uiName) override
{
CARLA_SAFE_ASSERT_RETURN(uiName != nullptr && uiName[0] != '\0',);

if (mainwin == nullptr)
return;

const CarlaMutexLocker cml(handlerThread.getLock());

mainwin->x_set_title(uiName);
}

// -------------------------------------------------------------------
// Mainwin callbacks

void valueChangedCallback(uint index, float value) override
{
fParameters[index] = value;
uiParameterChanged(index, value);
}

// -------------------------------------------------------------------

private:
// Fake jack client
jack_client_t fJackClient;

// Zita stuff (core)
X_resman xresman;
ScopedPointer<Jclient> jclient;
ScopedPointer<X_display> display;
ScopedPointer<X_rootwin> rootwin;
ScopedPointer<Mainwin> mainwin;
ScopedPointer<X_handler> handler;
X_handler_thread<Mainwin> handlerThread;

float fParameters[kNumParameters];

PluginClassEND(AT1Plugin)
CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(AT1Plugin)
};

// -----------------------------------------------------------------------

static const NativePluginDescriptor at1Desc = {
/* category */ NATIVE_PLUGIN_CATEGORY_MODULATOR,
/* hints */ static_cast<NativePluginHints>(NATIVE_PLUGIN_IS_RTSAFE
|NATIVE_PLUGIN_HAS_UI
|NATIVE_PLUGIN_NEEDS_FIXED_BUFFERS
|NATIVE_PLUGIN_NEEDS_UI_MAIN_THREAD
|NATIVE_PLUGIN_USES_PARENT_ID),
/* supports */ static_cast<NativePluginSupports>(0x0),
/* audioIns */ 1,
/* audioOuts */ 1,
/* midiIns */ 1,
/* midiOuts */ 0,
/* paramIns */ AT1Plugin::kNumParameters,
/* paramOuts */ 0,
/* name */ "AT1",
/* label */ "at1",
/* maker */ "falkTX, Fons Adriaensen",
/* copyright */ "GPL v2+",
PluginDescriptorFILL(AT1Plugin)
};

// -----------------------------------------------------------------------

CARLA_EXPORT
void carla_register_native_plugin_zita_at1();

CARLA_EXPORT
void carla_register_native_plugin_zita_at1()
{
carla_register_native_plugin(&at1Desc);
}

// -----------------------------------------------------------------------

+ 140
- 0
source/native-plugins/zita-at1/button.cc View File

@@ -0,0 +1,140 @@
// ----------------------------------------------------------------------
//
// Copyright (C) 2010 Fons Adriaensen <fons@linuxaudio.org>
// Modified by falkTX on Jan 2015 for inclusion in Carla
//
// 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
// (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, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// ----------------------------------------------------------------------


#include <cairo/cairo.h>
#include <cairo/cairo-xlib.h>
#include <math.h>
#include "button.h"

namespace AT1 {


int PushButton::_keymod = 0;
int PushButton::_button = 0;


PushButton::PushButton (X_window *parent,
X_callback *cbobj,
ButtonImg *image,
int xp,
int yp,
int cbind) :

X_window (parent,
image->_x0 + xp, image->_y0 + yp,
image->_dx, image->_dy,
image->_backg->pixel),
_cbobj (cbobj),
_cbind (cbind),
_image (image),
_state (0)
{
x_add_events (ExposureMask | ButtonPressMask | ButtonReleaseMask);
}


PushButton::~PushButton (void)
{
}


void PushButton::init (X_display *disp)
{
}


void PushButton::fini (void)
{
}


void PushButton::handle_event (XEvent *E)
{
switch (E->type)
{
case Expose:
render ();
break;
case ButtonPress:
bpress ((XButtonEvent *) E);
break;

case ButtonRelease:
brelse ((XButtonEvent *) E);
break;

default:
fprintf (stderr, "PushButton: event %d\n", E->type );
}
}


void PushButton::bpress (XButtonEvent *E)
{
int r = 0;

if (E->button < 4)
{
_keymod = E->state;
_button = E->button;
r = handle_press ();
}
render ();
if (r) callback (r);
}


void PushButton::brelse (XButtonEvent *E)
{
int r = 0;

if (E->button < 4)
{
_keymod = E->state;
_button = E->button;
r = handle_relse ();
}
render ();
if (r) callback (r);
}


void PushButton::set_state (int s)
{
if (_state != s)
{
_state = s;
render ();
}
}


void PushButton::render (void)
{
XPutImage (dpy (), win (), dgc (), _image->_ximage,
_image->_x0, _image->_y0 + _state * _image->_dy, 0, 0, _image->_dx, _image->_dy);
}



}

+ 97
- 0
source/native-plugins/zita-at1/button.h View File

@@ -0,0 +1,97 @@
// ----------------------------------------------------------------------
//
// Copyright (C) 2010 Fons Adriaensen <fons@linuxaudio.org>
// Modified by falkTX on Jan 2015 for inclusion in Carla
//
// 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
// (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, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// ----------------------------------------------------------------------


#ifndef __BUTTON_H
#define __BUTTON_H


#include <cairo/cairo.h>
#include <cairo/cairo-xlib.h>
#include <clxclient.h>

namespace AT1 {


class ButtonImg
{
public:

XftColor *_backg;
XImage *_ximage;
int _x0;
int _y0;
int _dx;
int _dy;
};



class PushButton : public X_window
{
public:

PushButton (X_window *parent,
X_callback *cbobj,
ButtonImg *image,
int xp,
int yp,
int cbind = 0);

virtual ~PushButton (void);

enum { NOP = 100, PRESS, RELSE };

int cbind (void) { return _cbind; }
int state (void) { return _state; }

virtual void set_state (int s);

static void init (X_display *disp);
static void fini (void);

protected:

X_callback *_cbobj;
int _cbind;
ButtonImg *_image;
int _state;

void render (void);
void callback (int k) { _cbobj->handle_callb (k, this, 0); }

private:

void handle_event (XEvent *E);
void bpress (XButtonEvent *E);
void brelse (XButtonEvent *E);

virtual int handle_press (void) = 0;
virtual int handle_relse (void) = 0;

static int _keymod;
static int _button;
};


}

#endif

+ 32
- 0
source/native-plugins/zita-at1/global.h View File

@@ -0,0 +1,32 @@
// ----------------------------------------------------------------------
//
// Copyright (C) 2010 Fons Adriaensen <fons@linuxaudio.org>
// Modified by falkTX on Jan 2015 for inclusion in Carla
//
// 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
// (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, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// ----------------------------------------------------------------------


#ifndef __GLOBAL_H
#define __GLOBAL_H


#define PROGNAME "zita-at1"
#define EV_X11 16
#define EV_EXIT 31


#endif

+ 186
- 0
source/native-plugins/zita-at1/guiclass.cc View File

@@ -0,0 +1,186 @@
// ----------------------------------------------------------------------
//
// Copyright (C) 2010-2014 Fons Adriaensen <fons@linuxaudio.org>
// Modified by falkTX on Jan 2015 for inclusion in Carla
//
// 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
// (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, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// ----------------------------------------------------------------------


#include <math.h>
#include "guiclass.h"

namespace AT1 {


int Pbutt0::handle_press (void)
{
_state |= 2;
return PRESS;
}

int Pbutt0::handle_relse (void)
{
_state &= ~2;
return NOP;
}


int Pbutt1::handle_press (void)
{
_state ^= 1;
return PRESS;
}

int Pbutt1::handle_relse (void)
{
return NOP;
}



Rlinctl::Rlinctl (X_window *parent,
X_callback *cbobj,
int cbind,
RotaryGeom *rgeom,
int xp,
int yp,
int cm,
int dd,
double vmin,
double vmax,
double vini) :
RotaryCtl (parent, cbobj, cbind, rgeom, xp, yp),
_cm (cm),
_dd (dd),
_vmin (vmin),
_vmax (vmax),
_form (0)
{
_count = -1;
set_value (vini);
}

void Rlinctl::get_string (char *p, int n)
{
if (_form) snprintf (p, n, _form, _value);
else *p = 0;
}

void Rlinctl::set_value (double v)
{
set_count ((int) floor (_cm * (v - _vmin) / (_vmax - _vmin) + 0.5));
render ();
}

int Rlinctl::handle_button (void)
{
return PRESS;
}

int Rlinctl::handle_motion (int dx, int dy)
{
return set_count (_rcount + dx - dy);
}

int Rlinctl::handle_mwheel (int dw)
{
if (! (_keymod & ShiftMask)) dw *= _dd;
return set_count (_count + dw);
}

int Rlinctl::set_count (int u)
{
if (u < 0) u= 0;
if (u > _cm) u = _cm;
if (u != _count)
{
_count = u;
_value = _vmin + u * (_vmax - _vmin) / _cm;
_angle = 270.0 * ((double) u / _cm - 0.5);
return DELTA;
}
return 0;
}



Rlogctl::Rlogctl (X_window *parent,
X_callback *cbobj,
int cbind,
RotaryGeom *rgeom,
int xp,
int yp,
int cm,
int dd,
double vmin,
double vmax,
double vini) :
RotaryCtl (parent, cbobj, cbind, rgeom, xp, yp),
_cm (cm),
_dd (dd),
_form (0)
{
_count = -1;
_vmin = log (vmin);
_vmax = log (vmax);
set_value (vini);
}

void Rlogctl::get_string (char *p, int n)
{
if (_form) snprintf (p, n, _form, _value);
else *p = 0;
}

void Rlogctl::set_value (double v)
{
set_count ((int) floor (_cm * (log (v) - _vmin) / (_vmax - _vmin) + 0.5));
render ();
}

int Rlogctl::handle_button (void)
{
return PRESS;
}

int Rlogctl::handle_motion (int dx, int dy)
{
return set_count (_rcount + dx - dy);
}

int Rlogctl::handle_mwheel (int dw)
{
if (! (_keymod & ShiftMask)) dw *= _dd;
return set_count (_count + dw);
}

int Rlogctl::set_count (int u)
{
if (u < 0) u= 0;
if (u > _cm) u = _cm;
if (u != _count)
{
_count = u;
_value = exp (_vmin + u * (_vmax - _vmin) / _cm);
_angle = 270.0 * ((double) u / _cm - 0.5);
return DELTA;
}
return 0;
}


}

+ 145
- 0
source/native-plugins/zita-at1/guiclass.h View File

@@ -0,0 +1,145 @@
// ----------------------------------------------------------------------
//
// Copyright (C) 2010-2014 Fons Adriaensen <fons@linuxaudio.org>
// Modified by falkTX on Jan 2015 for inclusion in Carla
//
// 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
// (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, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// ----------------------------------------------------------------------


#ifndef __GUICLASS_H
#define __GUICLASS_H


#include "button.h"
#include "rotary.h"

namespace AT1 {


class Pbutt0 : public PushButton
{
public:

Pbutt0 (X_window *parent,
X_callback *cbobj,
ButtonImg *image,
int xp,
int yp,
int cbind = 0) :
PushButton (parent, cbobj, image, xp, yp, cbind)
{
}

private:

virtual int handle_press (void);
virtual int handle_relse (void);
};


class Pbutt1 : public PushButton
{
public:

Pbutt1 (X_window *parent,
X_callback *cbobj,
ButtonImg *image,
int xp,
int yp,
int cbind = 0) :
PushButton (parent, cbobj, image, xp, yp, cbind)
{
}

private:

virtual int handle_press (void);
virtual int handle_relse (void);
};


class Rlinctl : public RotaryCtl
{
public:

Rlinctl (X_window *parent,
X_callback *cbobj,
int cbind,
RotaryGeom *rgeom,
int xp,
int yp,
int cm,
int dd,
double vmin,
double vmax,
double vini);

virtual void set_value (double v);
virtual void get_string (char *p, int n);

private:

virtual int handle_button (void);
virtual int handle_motion (int dx, int dy);
virtual int handle_mwheel (int dw);
int set_count (int u);

int _cm;
int _dd;
double _vmin;
double _vmax;
const char *_form;
};


class Rlogctl : public RotaryCtl
{
public:

Rlogctl (X_window *parent,
X_callback *cbobj,
int cbind,
RotaryGeom *rgeom,
int xp,
int yp,
int cm,
int dd,
double vmin,
double vmax,
double vini);

virtual void set_value (double v);
virtual void get_string (char *p, int n);

private:

virtual int handle_button (void);
virtual int handle_motion (int dx, int dy);
virtual int handle_mwheel (int dw);
int set_count (int u);

int _cm;
int _dd;
double _vmin;
double _vmax;
const char *_form;
};


}

#endif

+ 162
- 0
source/native-plugins/zita-at1/jclient.cc View File

@@ -0,0 +1,162 @@
// -----------------------------------------------------------------------
//
// Copyright (C) 2010 Fons Adriaensen <fons@linuxaudio.org>
// Modified by falkTX on Jan 2015 for inclusion in Carla
//
// 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
// (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, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// -----------------------------------------------------------------------


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "jclient.h"
#include "global.h"

namespace AT1 {


Jclient::Jclient (const char *jname, jack_client_t *jclient) :
A_thread ("jclient"),
_jack_client (jclient),
_active (false),
_jname (0)
{
init_jack (jname);
}


Jclient::~Jclient (void)
{
if (_jack_client) close_jack ();
}


void Jclient::init_jack (const char *jname)
{
jack_on_shutdown (_jack_client, jack_static_shutdown, (void *) this);
jack_set_process_callback (_jack_client, jack_static_process, (void *) this);
if (jack_activate (_jack_client))
{
fprintf(stderr, "Can't activate JACK.\n");
exit (1);
}

_jname = jack_get_client_name (_jack_client);
_fsamp = jack_get_sample_rate (_jack_client);
_fsize = jack_get_buffer_size (_jack_client);

_ainp_port = jack_port_register (_jack_client, "in", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
_aout_port = jack_port_register (_jack_client, "out", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
_midi_port = jack_port_register (_jack_client, "pitch", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0);
_retuner = new Retuner (_fsamp);
_notemask = 0xFFF;
_midichan = -1;
clr_midimask ();

_active = true;
}


void Jclient::close_jack ()
{
jack_deactivate (_jack_client);
jack_client_close (_jack_client);
delete _retuner;
}


void Jclient::jack_static_shutdown (void *arg)
{
((Jclient *) arg)->jack_shutdown ();
}


int Jclient::jack_static_process (jack_nframes_t nframes, void *arg)
{
return ((Jclient *) arg)->jack_process (nframes);
}


void Jclient::jack_shutdown (void)
{
send_event (EV_EXIT, 1);
}


void Jclient::clr_midimask (void)
{
int i;

for (i = 0; i < 12; i++) _notes [i] = 0;
_midimask = 0;
}


void Jclient::midi_process (int nframes)
{
int i, b, n, t, v;
void *p;
jack_midi_event_t E;

p = jack_port_get_buffer (_midi_port, nframes);
i = 0;
while (jack_midi_event_get (&E, p, i) == 0)
{
t = E.buffer [0];
n = E.buffer [1];
v = E.buffer [2];
if ((_midichan < 0) || ((t & 0x0F) == _midichan))
{
switch (t & 0xF0)
{
case 0x80:
case 0x90:
if (v && (t & 0x10))_notes [n % 12] += 1;
else _notes [n % 12] -= 1;
break;
}
}
i++;
}
_midimask = 0;
for (i = 0, b = 1; i < 12; i++, b <<= 1)
{
if (_notes [i]) _midimask |= b;
}
}


int Jclient::jack_process (int nframes)
{
float *inpp;
float *outp;

if (!_active) return 0;

inpp = (float *) jack_port_get_buffer (_ainp_port, nframes);
outp = (float *) jack_port_get_buffer (_aout_port, nframes);
midi_process (nframes);
_retuner->set_notemask (_midimask ? _midimask : _notemask);
_retuner->process (nframes, inpp, outp);
return 0;
}


}

+ 82
- 0
source/native-plugins/zita-at1/jclient.h View File

@@ -0,0 +1,82 @@
// -----------------------------------------------------------------------
//
// Copyright (C) 2010 Fons Adriaensen <fons@linuxaudio.org>
// Modified by falkTX on Jan 2015 for inclusion in Carla
//
// 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
// (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, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// -----------------------------------------------------------------------


#ifndef __JCLIENT_H
#define __JCLIENT_H


#include "CarlaNativeJack.h"
#include <clthreads.h>
#include "retuner.h"

namespace AT1 {


class Jclient : public A_thread
{
public:

Jclient (const char *jname, jack_client_t *jclient);
~Jclient (void);

const char *jname (void) { return _jname; }
unsigned int fsize (void) const { return _fsize; }
unsigned int fsamp (void) const { return _fsamp; }
Retuner *retuner (void) { return _retuner; }
void set_notemask (int m) { _notemask = m; }
void set_midichan (int c) { _midichan = c; }
void clr_midimask (void);
int get_noteset (void) { return _retuner->get_noteset (); }
int get_midiset (void) { return _midimask; }

private:

virtual void thr_main (void) {}

void init_jack (const char *jname);
void close_jack (void);
void jack_shutdown (void);
int jack_process (int nframes);
void midi_process (int nframes);

jack_client_t *_jack_client;
jack_port_t *_ainp_port;
jack_port_t *_aout_port;
jack_port_t *_midi_port;
bool _active;
const char *_jname;
unsigned int _fsamp;
unsigned int _fsize;
Retuner *_retuner;
int _notes [12];
int _notemask;
int _midimask;
int _midichan;

static void jack_static_shutdown (void *arg);
static int jack_static_process (jack_nframes_t nframes, void *arg);
};


}

#endif

+ 359
- 0
source/native-plugins/zita-at1/mainwin.cc View File

@@ -0,0 +1,359 @@
// ----------------------------------------------------------------------
//
// Copyright (C) 2010-2014 Fons Adriaensen <fons@linuxaudio.org>
// Modified by falkTX on Jan 2015 for inclusion in Carla
//
// 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
// (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, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// ----------------------------------------------------------------------


#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "styles.h"
#include "global.h"
#include "mainwin.h"

namespace AT1 {


Mainwin::Mainwin (X_rootwin *parent, X_resman *xres, int xp, int yp, Jclient *jclient, ValueChangedCallback* valuecb) :
A_thread ("Main"),
X_window (parent, xp, yp, XSIZE, YSIZE, XftColors [C_MAIN_BG]->pixel),
_stop (false),
_xres (xres),
_jclient (jclient),
_valuecb (valuecb)
{
X_hints H;
char s [256];
int i, j, x, y;

_atom = XInternAtom (dpy (), "WM_DELETE_WINDOW", True);
XSetWMProtocols (dpy (), win (), &_atom, 1);
_atom = XInternAtom (dpy (), "WM_PROTOCOLS", True);

sprintf (s, "%s", jclient->jname ());
x_set_title (s);
H.position (xp, yp);
H.minsize (XSIZE, YSIZE);
H.maxsize (XSIZE, YSIZE);
H.rname (xres->rname ());
H.rclas (xres->rclas ());
x_apply (&H);

x = 20;
_bmidi = new Pbutt0 (this, this, &b_midi_img, x, 12, B_MIDI);
_bmidi->x_map ();

bstyle1.size.x = 50;
bstyle1.size.y = 20;
_bchan = new X_tbutton (this, this, &bstyle1, x - 5, 40, "Omni", 0, B_CHAN);
_bchan->x_map ();
_midich = 0;

x = 100;
y = 23;
_tmeter = new Tmeter (this, x - 20, 53);
_tmeter->x_map ();
for (i = j = 0; i < 12; i++, j++)
{
_bnote [i] = new Pbutt1 (this, this, &b_note_img, x, y, i);
_bnote [i]->set_state (1);
_bnote [i]->x_map ();
if (j == 4)
{
x += 20;
j++;
}
else
{
x += 10;
if (j & 1) y += 18;
else y -= 18;
}
}


RotaryCtl::init (disp ());
x = 270;
_rotary [R_TUNE] = new Rlinctl (this, this, R_TUNE, &r_tune_geom, x, 0, 400, 5, 400.0, 480.0, 440.0);
_rotary [R_BIAS] = new Rlinctl (this, this, R_BIAS, &r_bias_geom, x, 0, 270, 5, 0.0, 1.0, 0.5);
_rotary [R_FILT] = new Rlogctl (this, this, R_FILT, &r_filt_geom, x, 0, 200, 5, 0.50, 0.02, 0.1);
_rotary [R_CORR] = new Rlinctl (this, this, R_CORR, &r_corr_geom, x, 0, 270, 5, 0.0, 1.0, 1.0);
_rotary [R_OFFS] = new Rlinctl (this, this, R_OFFS, &r_offs_geom, x, 0, 400, 10, -2.0, 2.0, 0.0);
for (i = 0; i < NROTARY; i++) _rotary [i]->x_map ();

_textln = new X_textip (this, 0, &tstyle1, 0, 0, 50, 15, 15);
_textln->set_align (0);
_ttimer = 0;
_notes = 0xFFF;

x_add_events (ExposureMask);
x_map ();
set_time (0);
inc_time (500000);
}

Mainwin::~Mainwin (void)
{
RotaryCtl::fini ();
}

int Mainwin::process (void)
{
int e;

if (_stop) handle_stop ();

e = get_event_timed ();
switch (e)
{
case EV_TIME:
handle_time ();
break;
}
return e;
}


void Mainwin::setchan_ui (int chan)
{
char s [16];

_midich = chan;

if (_midich)
{
sprintf (s, "Ch %d\n", _midich);
_bchan->set_text (s, 0);
}
else _bchan->set_text ("Omni", 0);
}


void Mainwin::handle_event (XEvent *E)
{
switch (E->type)
{
case Expose:
expose ((XExposeEvent *) E);
break;
case ClientMessage:
clmesg ((XClientMessageEvent *) E);
break;
}
}


void Mainwin::expose (XExposeEvent *E)
{
if (E->count) return;
redraw ();
}


void Mainwin::clmesg (XClientMessageEvent *E)
{
if (E->message_type == _atom) _stop = true;
}


void Mainwin::handle_time (void)
{
int i, k, s;
float v;

v = _jclient->retuner ()->get_error ();
_tmeter->update (v, v);
k = _jclient->retuner ()->get_noteset ();
for (i = 0; i < 12; i++)
{
s = _bnote [i]->state ();
if (k & 1) s |= 2;
else s &= ~2;
_bnote [i]->set_state (s);
k >>= 1;
}
k = _jclient->get_midiset();
if (k) _bmidi->set_state (_bmidi->state () | 1);
else _bmidi->set_state (_bmidi->state () & ~1);
if (_ttimer)
{
if (--_ttimer == 0) _textln->x_unmap ();
}
inc_time (50000);
XFlush (dpy ());
}


void Mainwin::handle_stop (void)
{
put_event (EV_EXIT, 1);
}


void Mainwin::handle_callb (int type, X_window *W, XEvent *E)
{
PushButton *B;
RotaryCtl *R;
int k;
float v;

switch (type)
{
case X_callback::BUTTON | X_button::PRESS:
{
X_button *Z = (X_button *) W;
XButtonEvent *X = (XButtonEvent *) E;
switch (Z->cbid ())
{
case B_CHAN:
switch (X->button)
{
case 1:
case 4:
setchan (1);
break;
case 3:
case 5:
setchan (-1);
break;
}
break;
}
break;
}
case PushButton::PRESS:
B = (PushButton *) W;
k = B->cbind ();
if (k < B_MIDI)
{
k = 1 << k;
if (B->state () & 1) _notes |= k;
else _notes &= ~k;
_jclient->set_notemask (_notes);
}
else if (k == B_MIDI)
{
_jclient->clr_midimask ();
}
break;

case RotaryCtl::PRESS:
R = (RotaryCtl *) W;
k = R->cbind ();
switch (k)
{
case R_TUNE:
case R_OFFS:
showval (k);
break;
}
break;

case RotaryCtl::DELTA:
R = (RotaryCtl *) W;
k = R->cbind ();
switch (k)
{
case R_TUNE:
v = _rotary [R_TUNE]->value ();
_jclient->retuner ()->set_refpitch (v);
_valuecb->valueChangedCallback (R_TUNE, v);
showval (k);
break;
case R_BIAS:
v = _rotary [R_BIAS]->value ();
_jclient->retuner ()->set_notebias (v);
_valuecb->valueChangedCallback (R_BIAS, v);
break;
case R_FILT:
v = _rotary [R_FILT]->value ();
_jclient->retuner ()->set_corrfilt (v);
_valuecb->valueChangedCallback (R_FILT, v);
break;
case R_CORR:
v = _rotary [R_CORR]->value ();
_jclient->retuner ()->set_corrgain (v);
_valuecb->valueChangedCallback (R_CORR, v);
break;
case R_OFFS:
v = _rotary [R_OFFS]->value ();
_jclient->retuner ()->set_corroffs (v);
_valuecb->valueChangedCallback (R_OFFS, v);
showval (k);
break;
}
break;
}
}


void Mainwin::setchan (int d)
{
char s [16];

_midich += d;
if (_midich < 0) _midich = 0;
if (_midich > 16) _midich = 16;
if (_midich)
{
sprintf (s, "Ch %d\n", _midich);
_bchan->set_text (s, 0);
}
else _bchan->set_text ("Omni", 0);
_jclient->set_midichan (_midich - 1);
_valuecb->valueChangedCallback (NROTARY, _midich);
}


void Mainwin::showval (int k)
{
char s [16];

switch (k)
{
case R_TUNE:
sprintf (s, "%5.1lf", _rotary [R_TUNE]->value ());
_textln->x_move (222, 58);
break;
case R_OFFS:
sprintf (s, "%5.2lf", _rotary [R_OFFS]->value ());
_textln->x_move (463, 58);
break;
}
_textln->set_text (s);
_textln->x_map ();
_ttimer = 40;
}


void Mainwin::redraw (void)
{
int x;

x = 80;
XPutImage (dpy (), win (), dgc (), notesect_img, 0, 0, x, 0, 190, 75);
x += 190;
XPutImage (dpy (), win (), dgc (), ctrlsect_img, 0, 0, x, 0, 315, 75);
}


}

+ 99
- 0
source/native-plugins/zita-at1/mainwin.h View File

@@ -0,0 +1,99 @@
// ----------------------------------------------------------------------
//
// Copyright (C) 2010-2014 Fons Adriaensen <fons@linuxaudio.org>
// Modified by falkTX on Jan 2015 for inclusion in Carla
//
// 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
// (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, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// ----------------------------------------------------------------------


#ifndef __MAINWIN_H
#define __MAINWIN_H


#include <clxclient.h>
#include "guiclass.h"
#include "jclient.h"
#include "tmeter.h"
#include "global.h"

class AT1Plugin;

namespace AT1 {


class Mainwin : public A_thread, public X_window, public X_callback
{
public:

struct ValueChangedCallback {
virtual ~ValueChangedCallback() {}
virtual void valueChangedCallback(uint, float) = 0;
};

enum { XSIZE = 600, YSIZE = 75 };

Mainwin (X_rootwin *parent, X_resman *xres, int xp, int yp, Jclient *jclient, ValueChangedCallback* valuecb);
~Mainwin (void);
Mainwin (const Mainwin&);
Mainwin& operator=(const Mainwin&);

void stop (void) { _stop = true; }
int process (void);

void setchan_ui (int chan);

private:

enum { B_MIDI = 12, B_CHAN = 13 };
enum { R_TUNE, R_FILT, R_BIAS, R_CORR, R_OFFS, NROTARY };
virtual void thr_main (void) {}

void handle_time (void);
void handle_stop (void);
void handle_event (XEvent *);
void handle_callb (int type, X_window *W, XEvent *E);
void showval (int k);
void expose (XExposeEvent *E);
void clmesg (XClientMessageEvent *E);
void redraw (void);
void setchan (int d);

Atom _atom;
bool _stop;
bool _ambis;
X_resman *_xres;
Jclient *_jclient;
int _notes;
PushButton *_bmidi;
PushButton *_bnote [12];
RotaryCtl *_rotary [NROTARY];
Tmeter *_tmeter;
X_textip *_textln;
X_tbutton *_bchan;
int _midich;
int _ttimer;

ValueChangedCallback* _valuecb;

friend class ::AT1Plugin;
};


}

#endif

+ 129
- 0
source/native-plugins/zita-at1/png2img.cc View File

@@ -0,0 +1,129 @@
// ----------------------------------------------------------------------
//
// Copyright (C) 2007-2010 Fons Adriaensen <fons@linuxaudio.org>
// Modified by falkTX on Jan 2015 for inclusion in Carla
//
// 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
// (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, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// ----------------------------------------------------------------------


#include <png.h>
#include <clxclient.h>

namespace AT1 {


XImage *png2img (const char *file, X_display *disp, XftColor *bgnd)
{
FILE *F;
png_byte hdr [8];
png_structp png_ptr;
png_infop png_info;
const unsigned char **data, *p;
int r, dx, dy, x, y, dp;
float vr, vg, vb, va, br, bg, bb;
unsigned long mr, mg, mb, pix;
XImage *image;

F = fopen (file, "r");
if (!F)
{
fprintf (stderr, "Can't open '%s'\n", file);
return 0;
}
r = fread (hdr, 8, 1, F );
if ((r != 1) || png_sig_cmp (hdr, 0, 8))
{
fprintf (stderr, "'%s' is not a PNG file\n", file);
return 0;
}
fseek (F, 0, SEEK_SET);

png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, 0, 0, 0);
if (! png_ptr)
{
fclose (F);
return 0;
}
png_info = png_create_info_struct (png_ptr);
if (! png_info)
{
png_destroy_read_struct (&png_ptr, 0, 0);
fclose (F);
return 0;
}
if (setjmp (png_jmpbuf (png_ptr)))
{
png_destroy_read_struct (&png_ptr, &png_info, 0);
fclose (F);
fprintf (stderr, "png:longjmp()\n");
return 0;
}

png_init_io (png_ptr, F);
png_read_png (png_ptr, png_info,
PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_PACKING | PNG_TRANSFORM_EXPAND,
0);

dx = png_get_image_width (png_ptr, png_info);
dy = png_get_image_height (png_ptr, png_info);
dp = (png_get_color_type (png_ptr, png_info) & PNG_COLOR_MASK_ALPHA) ? 4 : 3;

data = (const unsigned char **)(png_get_rows (png_ptr, png_info));

image = XCreateImage (disp->dpy (),
disp->dvi (),
DefaultDepth (disp->dpy (), disp->dsn ()),
ZPixmap, 0, 0, dx, dy, 32, 0);
image->data = new char [image->height * image->bytes_per_line];

mr = image->red_mask;
mg = image->green_mask;
mb = image->blue_mask;

vr = mr / 255.0f;
vg = mg / 255.0f;
vb = mb / 255.0f;
if (bgnd)
{
br = bgnd->color.red >> 8;
bg = bgnd->color.green >> 8;
bb = bgnd->color.blue >> 8;
}
else br = bg = bb = 0;

for (y = 0; y < dy; y++)
{
p = data [y];
for (x = 0; x < dx; x++)
{
va = (dp == 4) ? (p [3] / 255.0f) : 1;
pix = ((unsigned long)((p [0] * va + (1 - va) * br) * vr) & mr)
| ((unsigned long)((p [1] * va + (1 - va) * bg) * vg) & mg)
| ((unsigned long)((p [2] * va + (1 - va) * bb) * vb) & mb);
XPutPixel (image, x, y, pix);
p += dp;
}
}

png_destroy_read_struct (&png_ptr, &png_info, 0);
fclose (F);

return image;
}


}

+ 35
- 0
source/native-plugins/zita-at1/png2img.h View File

@@ -0,0 +1,35 @@
// ----------------------------------------------------------------------
//
// Copyright (C) 2007-2010 Fons Adriaensen <fons@linuxaudio.org>
// Modified by falkTX on Jan 2015 for inclusion in Carla
//
// 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
// (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, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// ----------------------------------------------------------------------


#ifndef __PNG2IMG_H
#define __PNG2IMG_H


#include <clxclient.h>

namespace AT1 {

extern XImage *png2img (const char *file, X_display *disp, XftColor *bgnd);

}

#endif

+ 449
- 0
source/native-plugins/zita-at1/retuner.cc View File

@@ -0,0 +1,449 @@
// -----------------------------------------------------------------------
//
// Copyright (C) 2009-2011 Fons Adriaensen <fons@linuxaudio.org>
// Modified by falkTX on Jan 2015 for inclusion in Carla
//
// 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
// (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, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// -----------------------------------------------------------------------


#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <math.h>
#include "retuner.h"

namespace AT1 {


Retuner::Retuner (int fsamp) :
_fsamp (fsamp),
_refpitch (440.0f),
_notebias (0.0f),
_corrfilt (1.0f),
_corrgain (1.0f),
_corroffs (0.0f),
_notemask (0xFFF)
{
int i, h;
float t, x, y;

if (_fsamp < 64000)
{
// At 44.1 and 48 kHz resample to double rate.
_upsamp = true;
_ipsize = 4096;
_fftlen = 2048;
_frsize = 128;
_resampler.setup (1, 2, 1, 32); // 32 is medium quality.
// Prefeed some input samples to remove delay.
_resampler.inp_count = _resampler.filtlen () - 1;
_resampler.inp_data = 0;
_resampler.out_count = 0;
_resampler.out_data = 0;
_resampler.process ();
}
else if (_fsamp < 128000)
{
// 88.2 or 96 kHz.
_upsamp = false;
_ipsize = 4096;
_fftlen = 4096;
_frsize = 256;
}
else
{
// 192 kHz, double time domain buffers sizes.
_upsamp = false;
_ipsize = 8192;
_fftlen = 8192;
_frsize = 512;
}

// Accepted correlation peak range, corresponding to 60..1200 Hz.
_ifmin = _fsamp / 1200;
_ifmax = _fsamp / 60;

// Various buffers
_ipbuff = new float[_ipsize + 3]; // Resampled or filtered input
_xffunc = new float[_frsize]; // Crossfade function
_fftTwind = (float *) fftwf_malloc (_fftlen * sizeof (float)); // Window function
_fftWcorr = (float *) fftwf_malloc (_fftlen * sizeof (float)); // Autocorrelation of window
_fftTdata = (float *) fftwf_malloc (_fftlen * sizeof (float)); // Time domain data for FFT
_fftFdata = (fftwf_complex *) fftwf_malloc ((_fftlen / 2 + 1) * sizeof (fftwf_complex));

// FFTW3 plans
_fwdplan = fftwf_plan_dft_r2c_1d (_fftlen, _fftTdata, _fftFdata, FFTW_ESTIMATE);
_invplan = fftwf_plan_dft_c2r_1d (_fftlen, _fftFdata, _fftTdata, FFTW_ESTIMATE);

// Clear input buffer.
memset (_ipbuff, 0, (_ipsize + 1) * sizeof (float));

// Create crossfade function, half of raised cosine.
for (i = 0; i < _frsize; i++)
{
_xffunc [i] = 0.5 * (1 - cosf (M_PI * i / _frsize));
}

// Create window, raised cosine.
for (i = 0; i < _fftlen; i++)
{
_fftTwind [i] = 0.5 * (1 - cosf (2 * M_PI * i / _fftlen));
}

// Compute window autocorrelation and normalise it.
fftwf_execute_dft_r2c (_fwdplan, _fftTwind, _fftFdata);
h = _fftlen / 2;
for (i = 0; i < h; i++)
{
x = _fftFdata [i][0];
y = _fftFdata [i][1];
_fftFdata [i][0] = x * x + y * y;
_fftFdata [i][1] = 0;
}
_fftFdata [h][0] = 0;
_fftFdata [h][1] = 0;
fftwf_execute_dft_c2r (_invplan, _fftFdata, _fftWcorr);
t = _fftWcorr [0];
for (i = 0; i < _fftlen; i++)
{
_fftWcorr [i] /= t;
}

// Initialise all counters and other state.
_notebits = 0;
_lastnote = -1;
_count = 0;
_cycle = _frsize;
_error = 0.0f;
_ratio = 1.0f;
_xfade = false;
_ipindex = 0;
_frindex = 0;
_frcount = 0;
_rindex1 = _ipsize / 2;
_rindex2 = 0;
}


Retuner::~Retuner (void)
{
delete[] _ipbuff;
delete[] _xffunc;
fftwf_free (_fftTwind);
fftwf_free (_fftWcorr);
fftwf_free (_fftTdata);
fftwf_free (_fftFdata);
fftwf_destroy_plan (_fwdplan);
fftwf_destroy_plan (_invplan);
}


int Retuner::process (int nfram, float *inp, float *out)
{
int i, k, fi;
float ph, dp, r1, r2, dr, u1, u2, v;

// Pitch shifting is done by resampling the input at the
// required ratio, and eventually jumping forward or back
// by one or more pitch period(s). Processing is done in
// fragments of '_frsize' frames, and the decision to jump
// forward or back is taken at the start of each fragment.
// If a jump happens we crossfade over one fragment size.
// Every 4 fragments a new pitch estimate is made. Since
// _fftsize = 16 * _frsize, the estimation window moves
// by 1/4 of the FFT length.

fi = _frindex; // Write index in current fragment.
r1 = _rindex1; // Read index for current input frame.
r2 = _rindex2; // Second read index while crossfading.

// No assumptions are made about fragments being aligned
// with process() calls, so we may be in the middle of
// a fragment here.

while (nfram)
{
// Don't go past the end of the current fragment.
k = _frsize - fi;
if (nfram < k) k = nfram;
nfram -= k;

// At 44.1 and 48 kHz upsample by 2.
if (_upsamp)
{
_resampler.inp_count = k;
_resampler.inp_data = inp;
_resampler.out_count = 2 * k;
_resampler.out_data = _ipbuff + _ipindex;
_resampler.process ();
_ipindex += 2 * k;
}
// At higher sample rates apply lowpass filter.
else
{
// Not implemented yet, just copy.
memcpy (_ipbuff + _ipindex, inp, k * sizeof (float));
_ipindex += k;
}

// Extra samples for interpolation.
_ipbuff [_ipsize + 0] = _ipbuff [0];
_ipbuff [_ipsize + 1] = _ipbuff [1];
_ipbuff [_ipsize + 2] = _ipbuff [2];
inp += k;
if (_ipindex == _ipsize) _ipindex = 0;

// Process available samples.
dr = _ratio;
if (_upsamp) dr *= 2;
if (_xfade)
{
// Interpolate and crossfade.
while (k--)
{
i = (int) r1;
u1 = cubic (_ipbuff + i, r1 - i);
i = (int) r2;
u2 = cubic (_ipbuff + i, r2 - i);
v = _xffunc [fi++];
*out++ = (1 - v) * u1 + v * u2;
r1 += dr;
if (r1 >= _ipsize) r1 -= _ipsize;
r2 += dr;
if (r2 >= _ipsize) r2 -= _ipsize;
}
}
else
{
// Interpolation only.
fi += k;
while (k--)
{
i = (int) r1;
*out++ = cubic (_ipbuff + i, r1 - i);
r1 += dr;
if (r1 >= _ipsize) r1 -= _ipsize;
}
}
// If at end of fragment check for jump.
if (fi == _frsize)
{
fi = 0;
// Estimate the pitch every 4th fragment.
if (++_frcount == 4)
{
_frcount = 0;
findcycle ();
if (_cycle)
{
// If the pitch estimate succeeds, find the
// nearest note and required resampling ratio.
_count = 0;
finderror ();
}
else if (++_count > 5)
{
// If the pitch estimate fails, the current
// ratio is kept for 5 fragments. After that
// the signal is considered unvoiced and the
// pitch error is reset.
_count = 5;
_cycle = _frsize;
_error = 0;
}
else if (_count == 2)
{
// Bias is removed after two unvoiced fragments.
_lastnote = -1;
}
_ratio = powf (2.0f, _corroffs / 12.0f - _error * _corrgain);
}

// If the previous fragment was crossfading,
// the end of the new fragment that was faded
// in becomes the current read position.
if (_xfade) r1 = r2;

// A jump must correspond to an integer number
// of pitch periods, and to avoid reading outside
// the circular input buffer limits it must be at
// least one fragment size.
dr = _cycle * (int)(ceilf (_frsize / _cycle));
dp = dr / _frsize;
ph = r1 - _ipindex;
if (ph < 0) ph += _ipsize;
if (_upsamp)
{
ph /= 2;
dr *= 2;
}
ph = ph / _frsize + 2 * _ratio - 10;
if (ph > 0.5f)
{
// Jump back by 'dr' frames and crossfade.
_xfade = true;
r2 = r1 - dr;
if (r2 < 0) r2 += _ipsize;
}
else if (ph + dp < 0.5f)
{
// Jump forward by 'dr' frames and crossfade.
_xfade = true;
r2 = r1 + dr;
if (r2 >= _ipsize) r2 -= _ipsize;
}
else _xfade = false;
}
}

// Save local state.
_frindex = fi;
_rindex1 = r1;
_rindex2 = r2;

return 0;
}


void Retuner::findcycle (void)
{
int d, h, i, j, k;
float f, m, t, x, y, z;

d = _upsamp ? 2 : 1;
h = _fftlen / 2;
j = _ipindex;
k = _ipsize - 1;
for (i = 0; i < _fftlen; i++)
{
_fftTdata [i] = _fftTwind [i] * _ipbuff [j & k];
j += d;
}
fftwf_execute_dft_r2c (_fwdplan, _fftTdata, _fftFdata);
f = _fsamp / (_fftlen * 3e3f);
for (i = 0; i < h; i++)
{
x = _fftFdata [i][0];
y = _fftFdata [i][1];
m = i * f;
_fftFdata [i][0] = (x * x + y * y) / (1 + m * m);
_fftFdata [i][1] = 0;
}
_fftFdata [h][0] = 0;
_fftFdata [h][1] = 0;
fftwf_execute_dft_c2r (_invplan, _fftFdata, _fftTdata);
t = _fftTdata [0] + 0.1f;
for (i = 0; i < h; i++) _fftTdata [i] /= (t * _fftWcorr [i]);
x = _fftTdata [0];
for (i = 4; i < _ifmax; i += 4)
{
y = _fftTdata [i];
if (y > x) break;
x = y;
}
i -= 4;
_cycle = 0;
if (i >= _ifmax) return;
if (i < _ifmin) i = _ifmin;
x = _fftTdata [--i];
y = _fftTdata [++i];
m = 0;
j = 0;
while (i <= _ifmax)
{
t = y * _fftWcorr [i];
z = _fftTdata [++i];
if ((t > m) && (y >= x) && (y >= z) && (y > 0.8f))
{
j = i - 1;
m = t;
}
x = y;
y = z;
}
if (j)
{
x = _fftTdata [j - 1];
y = _fftTdata [j];
z = _fftTdata [j + 1];
_cycle = j + 0.5f * (x - z) / (z - 2 * y + x - 1e-9f);
}
}


void Retuner::finderror (void)
{
int i, m, im;
float a, am, d, dm, f;

if (!_notemask)
{
_error = 0;
_lastnote = -1;
return;
}

f = log2f (_fsamp / (_cycle * _refpitch));
dm = 0;
am = 1;
im = -1;
for (i = 0, m = 1; i < 12; i++, m <<= 1)
{
if (_notemask & m)
{
d = f - (i - 9) / 12.0f;
d -= floorf (d + 0.5f);
a = fabsf (d);
if (i == _lastnote) a -= _notebias;
if (a < am)
{
am = a;
dm = d;
im = i;
}
}
}
if (_lastnote == im)
{
_error += _corrfilt * (dm - _error);
}
else
{
_error = dm;
_lastnote = im;
}

// For display only.
_notebits |= 1 << im;
}


float Retuner::cubic (float *v, float a)
{
float b, c;

b = 1 - a;
c = a * b;
return (1.0f + 1.5f * c) * (v[1] * b + v[2] * a)
- 0.5f * c * (v[0] * b + v[1] + v[2] + v[3] * a);
}


}

+ 133
- 0
source/native-plugins/zita-at1/retuner.h View File

@@ -0,0 +1,133 @@
// -----------------------------------------------------------------------
//
// Copyright (C) 2009-2011 Fons Adriaensen <fons@linuxaudio.org>
// Modified by falkTX on Jan 2015 for inclusion in Carla
//
// 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
// (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, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// -----------------------------------------------------------------------


#ifndef __RETUNER_H
#define __RETUNER_H


#include <fftw3.h>
#include <zita-resampler/resampler.h>

namespace AT1 {


class Retuner
{
public:

Retuner (int fsamp);
~Retuner (void);

int process (int nfram, float *inp, float *out);

void set_refpitch (float v)
{
_refpitch = v;
}

void set_notebias (float v)
{
_notebias = v / 13.0f;
}

void set_corrfilt (float v)
{
_corrfilt = (4 * _frsize) / (v * _fsamp);
}

void set_corrgain (float v)
{
_corrgain = v;
}

void set_corroffs (float v)
{
_corroffs = v;
}

void set_notemask (int k)
{
_notemask = k;
}
int get_noteset (void)
{
int k;

k = _notebits;
_notebits = 0;
return k;
}

float get_error (void)
{
return 12.0f * _error;
}


private:

void findcycle (void);
void finderror (void);
float cubic (float *v, float a);

int _fsamp;
int _ifmin;
int _ifmax;
bool _upsamp;
int _fftlen;
int _ipsize;
int _frsize;
int _ipindex;
int _frindex;
int _frcount;
float _refpitch;
float _notebias;
float _corrfilt;
float _corrgain;
float _corroffs;
int _notemask;
int _notebits;
int _lastnote;
int _count;
float _cycle;
float _error;
float _ratio;
float _phase;
bool _xfade;
float _rindex1;
float _rindex2;
float *_ipbuff;
float *_xffunc;
float *_fftTwind;
float *_fftWcorr;
float *_fftTdata;
fftwf_complex *_fftFdata;
fftwf_plan _fwdplan;
fftwf_plan _invplan;
Resampler _resampler;
};


}

#endif

+ 211
- 0
source/native-plugins/zita-at1/rotary.cc View File

@@ -0,0 +1,211 @@
// ----------------------------------------------------------------------
//
// Copyright (C) 2010-2012 Fons Adriaensen <fons@linuxaudio.org>
// Modified by falkTX on Jan 2015 for inclusion in Carla
//
// 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
// (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, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// ----------------------------------------------------------------------


#include <cairo/cairo.h>
#include <cairo/cairo-xlib.h>
#include <math.h>
#include "rotary.h"

namespace AT1 {


cairo_t *RotaryCtl::_cairotype = 0;
cairo_surface_t *RotaryCtl::_cairosurf = 0;


int RotaryCtl::_wb_up = 4;
int RotaryCtl::_wb_dn = 5;
int RotaryCtl::_keymod = 0;
int RotaryCtl::_button = 0;
int RotaryCtl::_rcount = 0;
int RotaryCtl::_rx = 0;
int RotaryCtl::_ry = 0;


RotaryCtl::RotaryCtl (X_window *parent,
X_callback *cbobj,
int cbind,
RotaryGeom *rgeom,
int xp,
int yp) :

X_window (parent,
rgeom->_x0 + xp, rgeom->_y0 + yp,
rgeom->_dx, rgeom->_dy,
rgeom->_backg->pixel),
_cbobj (cbobj),
_cbind (cbind),
_rgeom (rgeom),
_state (0),
_count (0),
_value (0),
_angle (0)
{
x_add_events ( ExposureMask
| Button1MotionMask | ButtonPressMask | ButtonReleaseMask);
}


RotaryCtl::~RotaryCtl (void)
{
}


void RotaryCtl::init (X_display *disp)
{
_cairosurf = cairo_xlib_surface_create (disp->dpy (), 0, disp->dvi (), 50, 50);
_cairotype = cairo_create (_cairosurf);
}


void RotaryCtl::fini (void)
{
cairo_destroy (_cairotype);
cairo_surface_destroy (_cairosurf);
}


void RotaryCtl::handle_event (XEvent *E)
{
switch (E->type)
{
case Expose:
render ();
break;
case ButtonPress:
bpress ((XButtonEvent *) E);
break;

case ButtonRelease:
brelse ((XButtonEvent *) E);
break;

case MotionNotify:
motion ((XMotionEvent *) E);
break;

default:
fprintf (stderr, "RotaryCtl: event %d\n", E->type );
}
}


void RotaryCtl::bpress (XButtonEvent *E)
{
int r = 0;
double d;

d = hypot (E->x - _rgeom->_xref, E->y - _rgeom->_yref);
if (d > _rgeom->_rad + 3) return;
_keymod = E->state;
if (E->button < 4)
{
_rx = E->x;
_ry = E->y;
_button = E->button;
r = handle_button ();
_rcount = _count;
}
else if (_button) return;
else if ((int)E->button == _wb_up)
{
r = handle_mwheel (1);
}
else if ((int)E->button == _wb_dn)
{
r = handle_mwheel (-1);
}
if (r)
{
callback (r);
render ();
}
}


void RotaryCtl::brelse (XButtonEvent *E)
{
if (_button == (int)E->button)
{
_button = 0;
callback (RELSE);
}
}


void RotaryCtl::motion (XMotionEvent *E)
{
int dx, dy, r;

if (_button)
{
_keymod = E->state;
dx = E->x - _rx;
dy = E->y - _ry;
r = handle_motion (dx, dy);
if (r)
{
callback (r);
render ();
}
}
}


void RotaryCtl::set_state (int s)
{
if (_state != s)
{
_state = s;
render ();
}
}


void RotaryCtl::render (void)
{
XImage *I;
double a, c, r, x, y;

I = _rgeom->_image [_state];
XPutImage (dpy (), win (), dgc (), I,
_rgeom->_x0, _rgeom->_y0, 0, 0, _rgeom->_dx, _rgeom->_dy);
cairo_xlib_surface_set_drawable (_cairosurf, win(),
_rgeom->_dx, _rgeom->_dy);
c = _rgeom->_lncol [_state] ? 1.0 : 0.0;
a = _angle * M_PI / 180;
r = _rgeom->_rad;
x = _rgeom->_xref;
y = _rgeom->_yref;
cairo_new_path (_cairotype);
cairo_move_to (_cairotype, x, y);
x += r * sin (a);
y -= r * cos (a);
cairo_line_to (_cairotype, x, y);
cairo_set_source_rgb (_cairotype, c, c, c);
cairo_set_line_width (_cairotype, 2.2);
cairo_stroke (_cairotype);
}


}

+ 119
- 0
source/native-plugins/zita-at1/rotary.h View File

@@ -0,0 +1,119 @@
// ----------------------------------------------------------------------
//
// Copyright (C) 2010-2012 Fons Adriaensen <fons@linuxaudio.org>
// Modified by falkTX on Jan 2015 for inclusion in Carla
//
// 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
// (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, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// ----------------------------------------------------------------------


#ifndef __ROTARY_H
#define __ROTARY_H


#include <cairo/cairo.h>
#include <cairo/cairo-xlib.h>
#include <clxclient.h>

namespace AT1 {


class RotaryGeom
{
public:

XftColor *_backg;
XImage *_image [4];
char _lncol [4];
int _x0;
int _y0;
int _dx;
int _dy;
double _xref;
double _yref;
double _rad;
};



class RotaryCtl : public X_window
{
public:

RotaryCtl (X_window *parent,
X_callback *cbobj,
int cbind,
RotaryGeom *rgeom,
int xp,
int yp);

virtual ~RotaryCtl (void);

enum { NOP = 200, PRESS, RELSE, DELTA };

int cbind (void) { return _cbind; }
int state (void) { return _state; }
double value (void) { return _value; }

virtual void set_state (int s);
virtual void set_value (double v) = 0;
virtual void get_string (char *p, int n) {}

static void init (X_display *disp);
static void fini (void);

static int _wb_up;
static int _wb_dn;

protected:

X_callback *_cbobj;
int _cbind;
RotaryGeom *_rgeom;
int _state;
int _count;
int _range;
double _value;
double _angle;

void render (void);
void callback (int k) { _cbobj->handle_callb (k, this, 0); }

static int _keymod;
static int _button;
static int _rcount;
static int _rx;
static int _ry;

private:

void handle_event (XEvent *E);
void bpress (XButtonEvent *E);
void brelse (XButtonEvent *E);
void motion (XMotionEvent *E);

virtual int handle_button (void) = 0;
virtual int handle_motion (int dx, int dy) = 0;
virtual int handle_mwheel (int dw) = 0;

static cairo_t *_cairotype;
static cairo_surface_t *_cairosurf;
};


}

#endif

+ 163
- 0
source/native-plugins/zita-at1/styles.cc View File

@@ -0,0 +1,163 @@
// ----------------------------------------------------------------------
//
// Copyright (C) 2010-2014 Fons Adriaensen <fons@linuxaudio.org>
// Modified by falkTX on Jan 2015 for inclusion in Carla
//
// 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
// (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, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// ----------------------------------------------------------------------


#include "styles.h"
#include "tmeter.h"
#include "png2img.h"

#include "CarlaString.hpp"

namespace AT1 {


XftColor *XftColors [NXFTCOLORS];
XftFont *XftFonts [NXFTFONTS];

X_textln_style tstyle1;
X_button_style bstyle1;

XImage *notesect_img;
XImage *ctrlsect_img;
XImage *redzita_img;

ButtonImg b_note_img;
ButtonImg b_midi_img;

RotaryGeom r_tune_geom;
RotaryGeom r_filt_geom;
RotaryGeom r_bias_geom;
RotaryGeom r_corr_geom;
RotaryGeom r_offs_geom;


int styles_init (X_display *disp, X_resman *xrm, const char *resdir)
{
XftColors [C_MAIN_BG] = disp->alloc_xftcolor (0.25f, 0.25f, 0.25f, 1.0f);
XftColors [C_MAIN_FG] = disp->alloc_xftcolor (1.0f, 1.0f, 1.0f, 1.0f);
XftColors [C_TEXT_BG] = disp->alloc_xftcolor (1.0f, 1.0f, 1.0f, 1.0f);
XftColors [C_TEXT_FG] = disp->alloc_xftcolor (0.1f, 0.1f, 0.1f, 1.0f);

XftFonts [F_TEXT] = disp->alloc_xftfont (xrm->get (".font.text", "luxi:bold::pixelsize=11"));
XftFonts [F_BUTT] = disp->alloc_xftfont (xrm->get (".font.butt", "luxi:bold::pixelsize=11"));

tstyle1.font = XftFonts [F_TEXT];
tstyle1.color.normal.bgnd = XftColors [C_TEXT_BG]->pixel;
tstyle1.color.normal.text = XftColors [C_TEXT_FG];

bstyle1.font = XftFonts [F_BUTT];
bstyle1.color.bg[0] = XftColors [C_MAIN_BG]->pixel;
bstyle1.color.fg[0] = XftColors [C_MAIN_FG];
bstyle1.type = X_button_style::PLAIN | X_button_style::ALEFT;

const CarlaString SHARED = CarlaString(resdir)+"/at1";
notesect_img = png2img (SHARED+"/notesect.png", disp, XftColors [C_MAIN_BG]);
ctrlsect_img = png2img (SHARED+"/ctrlsect.png", disp, XftColors [C_MAIN_BG]);
Tmeter::_scale = png2img (SHARED+"/hscale.png", disp, XftColors [C_MAIN_BG]);
Tmeter::_imag0 = png2img (SHARED+"/hmeter0.png", disp, XftColors [C_MAIN_BG]);
Tmeter::_imag1 = png2img (SHARED+"/hmeter1.png", disp, XftColors [C_MAIN_BG]);

if ( !notesect_img || !ctrlsect_img
|| !Tmeter::_scale || !Tmeter::_imag0 || !Tmeter::_imag1)
{
fprintf (stderr, "Can't load images from '%s'.\n", SHARED.buffer());
return 1;
}

b_midi_img._backg = XftColors [C_MAIN_BG];
b_midi_img._ximage = png2img (SHARED+"/midi.png", disp, XftColors [C_MAIN_BG]);
b_midi_img._x0 = 0;
b_midi_img._y0 = 0;
b_midi_img._dx = 40;
b_midi_img._dy = 24;

b_note_img._backg = XftColors [C_MAIN_BG];
b_note_img._ximage = png2img (SHARED+"/note.png", disp, XftColors [C_MAIN_BG]);
b_note_img._x0 = 0;
b_note_img._y0 = 0;
b_note_img._dx = 16;
b_note_img._dy = 16;

r_tune_geom._backg = XftColors [C_MAIN_BG];
r_tune_geom._image [0] = ctrlsect_img;
r_tune_geom._lncol [0] = 1;
r_tune_geom._x0 = 26;
r_tune_geom._y0 = 17;
r_tune_geom._dx = 23;
r_tune_geom._dy = 23;
r_tune_geom._xref = 11.5;
r_tune_geom._yref = 11.5;
r_tune_geom._rad = 11;

r_bias_geom._backg = XftColors [C_MAIN_BG];
r_bias_geom._image [0] = ctrlsect_img;
r_bias_geom._lncol [0] = 0;
r_bias_geom._x0 = 86;
r_bias_geom._y0 = 17;
r_bias_geom._dx = 23;
r_bias_geom._dy = 23;
r_bias_geom._xref = 11.5;
r_bias_geom._yref = 11.5;
r_bias_geom._rad = 11;

r_filt_geom._backg = XftColors [C_MAIN_BG];
r_filt_geom._image [0] = ctrlsect_img;
r_filt_geom._lncol [0] = 0;
r_filt_geom._x0 = 146;
r_filt_geom._y0 = 17;
r_filt_geom._dx = 23;
r_filt_geom._dy = 23;
r_filt_geom._xref = 11.5;
r_filt_geom._yref = 11.5;
r_filt_geom._rad = 11;

r_corr_geom._backg = XftColors [C_MAIN_BG];
r_corr_geom._image [0] = ctrlsect_img;
r_corr_geom._lncol [0] = 0;
r_corr_geom._x0 = 206;
r_corr_geom._y0 = 17;
r_corr_geom._dx = 23;
r_corr_geom._dy = 23;
r_corr_geom._xref = 11.5;
r_corr_geom._yref = 11.5;
r_corr_geom._rad = 11;

r_offs_geom._backg = XftColors [C_MAIN_BG];
r_offs_geom._image [0] = ctrlsect_img;
r_offs_geom._lncol [0] = 0;
r_offs_geom._x0 = 266;
r_offs_geom._y0 = 17;
r_offs_geom._dx = 23;
r_offs_geom._dy = 23;
r_offs_geom._xref = 11.5;
r_offs_geom._yref = 11.5;
r_offs_geom._rad = 11;

return 0;
}


void styles_fini (X_display *disp)
{
}


}

+ 70
- 0
source/native-plugins/zita-at1/styles.h View File

@@ -0,0 +1,70 @@
// ----------------------------------------------------------------------
//
// Copyright (C) 2010-2014 Fons Adriaensen <fons@linuxaudio.org>
// Modified by falkTX on Jan 2015 for inclusion in Carla
//
// 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
// (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, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// ----------------------------------------------------------------------


#ifndef __STYLES_H
#define __STYLES_H

#include <clxclient.h>
#include "button.h"
#include "rotary.h"

namespace AT1 {


enum
{
C_MAIN_BG, C_MAIN_FG,
C_TEXT_BG, C_TEXT_FG,
NXFTCOLORS
};

enum
{
F_TEXT,
F_BUTT,
NXFTFONTS
};


extern int styles_init (X_display *disp, X_resman *xrm, const char *resdir);
extern void styles_fini (X_display *disp);

extern XftColor *XftColors [NXFTCOLORS];
extern XftFont *XftFonts [NXFTFONTS];

extern X_textln_style tstyle1;
extern X_button_style bstyle1;

extern XImage *notesect_img;
extern XImage *ctrlsect_img;
extern ButtonImg b_midi_img;
extern ButtonImg b_note_img;
extern RotaryGeom r_tune_geom;
extern RotaryGeom r_filt_geom;
extern RotaryGeom r_bias_geom;
extern RotaryGeom r_corr_geom;
extern RotaryGeom r_offs_geom;


}

#endif

+ 86
- 0
source/native-plugins/zita-at1/tmeter.cc View File

@@ -0,0 +1,86 @@
/*
Copyright (C) 2009-2010 Fons Adriaensen <fons@linuxaudio.org>
Modified by falkTX on Jan 2015 for inclusion in Carla

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
(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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/


#include <math.h>
#include "tmeter.h"

namespace AT1 {


XImage *Tmeter::_scale = 0;
XImage *Tmeter::_imag0 = 0;
XImage *Tmeter::_imag1 = 0;


Tmeter::Tmeter (X_window *parent, int xpos, int ypos) :
X_window (parent, xpos, ypos, XS + 2 * XM, YS + 2 * YM, 0),
_k0 (86),
_k1 (86)
{
if (!_imag0 || !_imag1 || !_scale) return;
x_add_events (ExposureMask);
}


Tmeter::~Tmeter (void)
{
}


void Tmeter::handle_event (XEvent *E)
{
switch (E->type)
{
case Expose:
expose ((XExposeEvent *) E);
break;
}
}


void Tmeter::expose (XExposeEvent *E)
{
if (E->count) return;
XSetFunction (dpy (), dgc (), GXcopy);
XPutImage (dpy (), win (), dgc (), _imag0, 0, 0, XM, YM, XS, Y1);
XPutImage (dpy (), win (), dgc (), _imag1, _k0 - 2, 0, XM + _k0 - 2, YM, 5 + _k1 - _k0, Y1);
XPutImage (dpy (), win (), dgc (), _scale, 0, 0, XM, YM + Y1, XS, Y2);
}


void Tmeter::update (float v0, float v1)
{
int k0, k1;

k0 = (int)(floorf (86.0f + 80.0f * v0 + 0.5f));
k1 = (int)(floorf (86.0f + 80.0f * v1 + 0.5f));
if (k0 < 4) k0 = 4;
if (k0 > 168) k0 = 168;
if (k1 < 4) k1 = 4;
if (k1 > 168) k1 = 168;
XSetFunction (dpy (), dgc (), GXcopy);
XPutImage (dpy (), win (), dgc (), _imag0, _k0 - 2, 0, XM + _k0 - 2, YM, 5 + _k1 - _k0, Y1);
_k0 = k0;
_k1 = k1;
XPutImage (dpy (), win (), dgc (), _imag1, _k0 - 2, 0, XM + _k0 - 2, YM, 5 + _k1 - _k0, Y1);
}


}

+ 59
- 0
source/native-plugins/zita-at1/tmeter.h View File

@@ -0,0 +1,59 @@
/*
Copyright (C) 2009-2010 Fons Adriaensen <fons@linuxaudio.org>
Modified by falkTX on Jan 2015 for inclusion in Carla

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
(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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/


#ifndef __TMETER_H
#define __TMETER_H


#include <clxclient.h>

namespace AT1 {


class Tmeter : public X_window
{
public:

Tmeter (X_window *parent, int xpos, int ypos);
~Tmeter (void);
Tmeter (const Tmeter&);
Tmeter& operator=(const Tmeter&);

void update (float v0, float v1);

static XImage *_scale;
static XImage *_imag0;
static XImage *_imag1;

private:

enum { XS = 173, YS = 17, XM = 0, YM = 0, Y1 = 7, Y2 = 10 };

void handle_event (XEvent *E);
void expose (XExposeEvent *E);

int _k0;
int _k1;
};


}

#endif

+ 39
- 33
source/native-plugins/zita-bls1.cpp View File

@@ -16,20 +16,18 @@
*/

#include "CarlaNative.hpp"
#include "CarlaMutex.hpp"
#include "CarlaMathUtils.hpp"
#include "CarlaJuceUtils.hpp"

#include "juce_audio_basics.h"

// this one needs to be first
#include "zita-bls1/png2img.cc"

#include "zita-common.hpp"
#include "zita-bls1/guiclass.cc"
#include "zita-bls1/hp3filt.cc"
#include "zita-bls1/jclient.cc"
#include "zita-bls1/lfshelf2.cc"
#include "zita-bls1/mainwin.cc"
#include "zita-bls1/png2img.cc"
#include "zita-bls1/rotary.cc"
#include "zita-bls1/shuffler.cc"
#include "zita-bls1/styles.cc"
@@ -37,6 +35,8 @@
using juce::FloatVectorOperations;
using juce::ScopedPointer;

using namespace BLS1;

// -----------------------------------------------------------------------
// BLS1 Plugin

@@ -66,6 +66,7 @@ public:
rootwin(nullptr),
mainwin(nullptr),
handler(nullptr),
handlerThread(),
leakDetector_BLS1Plugin()
{
CARLA_SAFE_ASSERT(host != nullptr);
@@ -228,10 +229,10 @@ public:
}

for (uint32_t i=0; i<kNumInputs; ++i)
fJackClient.portsAudioIn[i].buffer = inBuffer[i];
fJackClient.portsAudioIn[i].buffer.audio = inBuffer[i];

for (uint32_t i=0; i<kNumOutputs; ++i)
fJackClient.portsAudioOut[i].buffer = outBuffer[i];
fJackClient.portsAudioOut[i].buffer.audio = outBuffer[i];

fJackClient.processCallback(frames, fJackClient.processPtr);
}
@@ -243,31 +244,36 @@ public:
{
if (show)
{
if (display == nullptr)
{
display = new X_display(nullptr);
if (display != nullptr)
return;

display = new X_display(nullptr);

if (display->dpy() == nullptr)
return hostUiUnavailable();
if (display->dpy() == nullptr)
return hostUiUnavailable();

styles_init(display, &xresman, getResourceDir());
styles_init(display, &xresman, getResourceDir());

rootwin = new X_rootwin(display);
mainwin = new Mainwin(rootwin, &xresman, 0, 0, jclient, this);
rootwin->handle_event();
mainwin->x_set_title(getUiName());
rootwin = new X_rootwin(display);
mainwin = new Mainwin(rootwin, &xresman, 0, 0, jclient, this);
rootwin->handle_event();
mainwin->x_set_title(getUiName());

handler = new X_handler(display, mainwin, EV_X11);
handler = new X_handler(display, mainwin, EV_X11);

if (const uintptr_t winId = getUiParentId())
XSetTransientForHint(display->dpy(), mainwin->win(), static_cast<Window>(winId));
}
if (const uintptr_t winId = getUiParentId())
XSetTransientForHint(display->dpy(), mainwin->win(), static_cast<Window>(winId));

handler->next_event();
XFlush(display->dpy());

handlerThread.setupAndRun(handler, rootwin, mainwin);
}
else
{
if (handlerThread.isThreadRunning())
handlerThread.stopThread();

handler = nullptr;
mainwin = nullptr;
rootwin = nullptr;
@@ -280,20 +286,15 @@ public:
if (mainwin == nullptr)
return;

int ev;

for (; (ev = mainwin->process()) == EV_X11;)
{
rootwin->handle_event();
handler->next_event();
}

if (ev == EV_EXIT)
if (handlerThread.wasClosed())
{
handler = nullptr;
mainwin = nullptr;
rootwin = nullptr;
display = nullptr;
{
const CarlaMutexLocker cml(handlerThread.getLock());
handler = nullptr;
mainwin = nullptr;
rootwin = nullptr;
display = nullptr;
}
uiClosed();
}
}
@@ -305,6 +306,8 @@ public:
if (mainwin == nullptr)
return;

const CarlaMutexLocker cml(handlerThread.getLock());

mainwin->_rotary[index]->set_value(value);
}

@@ -328,6 +331,8 @@ public:
if (mainwin == nullptr)
return;

const CarlaMutexLocker cml(handlerThread.getLock());

mainwin->x_set_title(uiName);
}

@@ -353,6 +358,7 @@ private:
ScopedPointer<X_rootwin> rootwin;
ScopedPointer<Mainwin> mainwin;
ScopedPointer<X_handler> handler;
X_handler_thread<Mainwin> handlerThread;

float fParameters[kParameterNROTARY];



+ 5
- 0
source/native-plugins/zita-bls1/guiclass.cc View File

@@ -23,6 +23,8 @@
#include <math.h>
#include "guiclass.h"

namespace BLS1 {


Rlinctl::Rlinctl (X_window *parent,
X_callback *cbobj,
@@ -153,3 +155,6 @@ int Rlogctl::set_count (int u)
}
return 0;
}


}

+ 4
- 0
source/native-plugins/zita-bls1/guiclass.h View File

@@ -26,6 +26,8 @@

#include "rotary.h"

namespace BLS1 {


class Rlinctl : public RotaryCtl
{
@@ -95,4 +97,6 @@ private:
};


}

#endif

+ 5
- 0
source/native-plugins/zita-bls1/hp3filt.cc View File

@@ -24,6 +24,8 @@
#include <math.h>
#include "hp3filt.h"

namespace BLS1 {


HP3filt::HP3filt (void) :
_touch0 (0),
@@ -177,3 +179,6 @@ void HP3filt::process1 (int nsamp, int nchan, float *data[])
}
if (_state == FADING) _a = a;
}


}

+ 4
- 0
source/native-plugins/zita-bls1/hp3filt.h View File

@@ -27,6 +27,8 @@
#include <stdint.h>
#include "global.h"

namespace BLS1 {


class HP3filt
{
@@ -69,4 +71,6 @@ private:
};


}

#endif

+ 3
- 0
source/native-plugins/zita-bls1/jclient.cc View File

@@ -23,6 +23,8 @@
#include <string.h>
#include "jclient.h"

namespace BLS1 {


Jclient::Jclient (const char *jname, jack_client_t *jclient) :
A_thread ("Jclient"),
@@ -185,3 +187,4 @@ int Jclient::jack_process (int frames)
}


}

+ 4
- 0
source/native-plugins/zita-bls1/jclient.h View File

@@ -34,6 +34,8 @@
#include "lfshelf2.h"
#include "global.h"

namespace BLS1 {


class Jclient : public A_thread
{
@@ -95,4 +97,6 @@ private:
};


}

#endif

+ 4
- 0
source/native-plugins/zita-bls1/lfshelf2.cc View File

@@ -24,6 +24,8 @@
#include <string.h>
#include "lfshelf2.h"

namespace BLS1 {


LFshelf2::LFshelf2 (void) :
_touch0 (0),
@@ -247,3 +249,5 @@ void LFshelf2::process1 (int nsamp, int nchan, float *data[])
}
}


}

+ 4
- 0
source/native-plugins/zita-bls1/lfshelf2.h View File

@@ -27,6 +27,8 @@
#include <stdint.h>
#include "global.h"

namespace BLS1 {


class LFshelf2
{
@@ -86,4 +88,6 @@ private:
};


}

#endif

+ 5
- 1
source/native-plugins/zita-bls1/mainwin.cc View File

@@ -27,10 +27,12 @@
#include "global.h"
#include "mainwin.h"

namespace BLS1 {


Mainwin::Mainwin (X_rootwin *parent, X_resman *xres, int xp, int yp, Jclient *jclient, ValueChangedCallback* valuecb) :
A_thread ("Main"),
X_window (parent, xp, yp, XSIZE, YSIZE, XftColors_bls1 [C_MAIN_BG]->pixel),
X_window (parent, xp, yp, XSIZE, YSIZE, XftColors [C_MAIN_BG]->pixel),
_stop (false),
_xres (xres),
_jclient (jclient),
@@ -260,3 +262,5 @@ void Mainwin::fmtfreq (int k)
_numtext->set_text (t);
}


}

+ 7
- 1
source/native-plugins/zita-bls1/mainwin.h View File

@@ -29,6 +29,10 @@
#include "jclient.h"
#include "global.h"

class BLS1Plugin;

namespace BLS1 {


class Mainwin : public A_thread, public X_window, public X_callback
{
@@ -77,8 +81,10 @@ private:

ValueChangedCallback* _valuecb;

friend class BLS1Plugin;
friend class ::BLS1Plugin;
};


}

#endif

+ 4
- 0
source/native-plugins/zita-bls1/png2img.cc View File

@@ -23,6 +23,7 @@
#include <png.h>
#include <clxclient.h>

namespace BLS1 {


XImage *png2img (const char *file, X_display *disp, XftColor *bgnd)
@@ -130,3 +131,6 @@ XImage *png2img (const char *file, X_display *disp, XftColor *bgnd)

return image;
}


}

+ 2
- 0
source/native-plugins/zita-bls1/png2img.h View File

@@ -26,8 +26,10 @@

#include <clxclient.h>

namespace BLS1 {

extern XImage *png2img (const char *file, X_display *disp, XftColor *bgnd);

}

#endif

+ 3
- 0
source/native-plugins/zita-bls1/rotary.cc View File

@@ -25,6 +25,8 @@
#include <math.h>
#include "rotary.h"

namespace BLS1 {


cairo_t *RotaryCtl::_cairotype = 0;
cairo_surface_t *RotaryCtl::_cairosurf = 0;
@@ -202,3 +204,4 @@ void RotaryCtl::render (void)
}


}

+ 4
- 0
source/native-plugins/zita-bls1/rotary.h View File

@@ -28,6 +28,8 @@
#include <cairo/cairo-xlib.h>
#include <clxclient.h>

namespace BLS1 {


class RotaryImg
{
@@ -113,4 +115,6 @@ private:
};


}

#endif

+ 5
- 0
source/native-plugins/zita-bls1/shuffler.cc View File

@@ -26,6 +26,8 @@
#include <math.h>
#include "shuffler.h"

namespace BLS1 {


Shuffler::Shuffler (void) :
_fsamp (0),
@@ -181,3 +183,6 @@ void Shuffler::process (int nsamp, float *inp [], float *out [])

_del_wind = wi;
}


}

+ 4
- 0
source/native-plugins/zita-bls1/shuffler.h View File

@@ -27,6 +27,8 @@
#include <zita-convolver.h>
#include "global.h"

namespace BLS1 {


class Shuffler
{
@@ -65,4 +67,6 @@ private:
};


}

#endif

+ 25
- 19
source/native-plugins/zita-bls1/styles.cc View File

@@ -25,8 +25,11 @@

#include "CarlaString.hpp"

XftColor *XftColors_bls1 [NXFTCOLORS];
XftFont *XftFonts_bls1 [NXFTFONTS];
namespace BLS1 {


XftColor *XftColors [NXFTCOLORS];
XftFont *XftFonts [NXFTFONTS];

X_textln_style tstyle1;

@@ -44,24 +47,24 @@ RotaryImg lfgain_img;

int styles_init (X_display *disp, X_resman *xrm, const char *resdir)
{
XftColors_bls1 [C_MAIN_BG] = disp->alloc_xftcolor (0.25f, 0.25f, 0.25f, 1.0f);
XftColors_bls1 [C_MAIN_FG] = disp->alloc_xftcolor (1.0f, 1.0f, 1.0f, 1.0f);
XftColors_bls1 [C_TEXT_BG] = disp->alloc_xftcolor (1.0f, 1.0f, 0.0f, 1.0f);
XftColors_bls1 [C_TEXT_FG] = disp->alloc_xftcolor (0.0f, 0.0f, 0.0f, 1.0f);
XftColors [C_MAIN_BG] = disp->alloc_xftcolor (0.25f, 0.25f, 0.25f, 1.0f);
XftColors [C_MAIN_FG] = disp->alloc_xftcolor (1.0f, 1.0f, 1.0f, 1.0f);
XftColors [C_TEXT_BG] = disp->alloc_xftcolor (1.0f, 1.0f, 0.0f, 1.0f);
XftColors [C_TEXT_FG] = disp->alloc_xftcolor (0.0f, 0.0f, 0.0f, 1.0f);

XftFonts_bls1 [F_TEXT] = disp->alloc_xftfont (xrm->get (".font.text", "luxi:bold::pixelsize=11"));
XftFonts [F_TEXT] = disp->alloc_xftfont (xrm->get (".font.text", "luxi:bold::pixelsize=11"));

tstyle1.font = XftFonts_bls1 [F_TEXT];
tstyle1.color.normal.bgnd = XftColors_bls1 [C_TEXT_BG]->pixel;
tstyle1.color.normal.text = XftColors_bls1 [C_TEXT_FG];
tstyle1.font = XftFonts [F_TEXT];
tstyle1.color.normal.bgnd = XftColors [C_TEXT_BG]->pixel;
tstyle1.color.normal.text = XftColors [C_TEXT_FG];

const CarlaString SHARED = CarlaString(resdir)+"/bls1";
inputsect = png2img (SHARED+"/inputsect.png", disp, XftColors_bls1 [C_MAIN_BG]);
shuffsect = png2img (SHARED+"/shuffsect.png", disp, XftColors_bls1 [C_MAIN_BG]);
lfshfsect = png2img (SHARED+"/lfshfsect.png", disp, XftColors_bls1 [C_MAIN_BG]);
inputsect = png2img (SHARED+"/inputsect.png", disp, XftColors [C_MAIN_BG]);
shuffsect = png2img (SHARED+"/shuffsect.png", disp, XftColors [C_MAIN_BG]);
lfshfsect = png2img (SHARED+"/lfshfsect.png", disp, XftColors [C_MAIN_BG]);
if (!inputsect || !shuffsect || !lfshfsect) return 1;

inpbal_img._backg = XftColors_bls1 [C_MAIN_BG];
inpbal_img._backg = XftColors [C_MAIN_BG];
inpbal_img._image [0] = inputsect;
inpbal_img._lncol [0] = 1;
inpbal_img._x0 = 28;
@@ -72,7 +75,7 @@ int styles_init (X_display *disp, X_resman *xrm, const char *resdir)
inpbal_img._yref = 12.5;
inpbal_img._rad = 12;

hpfilt_img._backg = XftColors_bls1 [C_MAIN_BG];
hpfilt_img._backg = XftColors [C_MAIN_BG];
hpfilt_img._image [0] = inputsect;
hpfilt_img._lncol [0] = 0;
hpfilt_img._x0 = 87;
@@ -83,7 +86,7 @@ int styles_init (X_display *disp, X_resman *xrm, const char *resdir)
hpfilt_img._yref = 12.5;
hpfilt_img._rad = 12;

shgain_img._backg = XftColors_bls1 [C_MAIN_BG];
shgain_img._backg = XftColors [C_MAIN_BG];
shgain_img._image [0] = shuffsect;
shgain_img._lncol [0] = 0;
shgain_img._x0 = 68;
@@ -94,7 +97,7 @@ int styles_init (X_display *disp, X_resman *xrm, const char *resdir)
shgain_img._yref = 12.5;
shgain_img._rad = 12;
shfreq_img._backg = XftColors_bls1 [C_MAIN_BG];
shfreq_img._backg = XftColors [C_MAIN_BG];
shfreq_img._image [0] = shuffsect;
shfreq_img._lncol [0] = 0;
shfreq_img._x0 = 127;
@@ -105,7 +108,7 @@ int styles_init (X_display *disp, X_resman *xrm, const char *resdir)
shfreq_img._yref = 12.5;
shfreq_img._rad = 12;
lffreq_img._backg = XftColors_bls1 [C_MAIN_BG];
lffreq_img._backg = XftColors [C_MAIN_BG];
lffreq_img._image [0] = lfshfsect;
lffreq_img._lncol [0] = 0;
lffreq_img._x0 = 14;
@@ -116,7 +119,7 @@ int styles_init (X_display *disp, X_resman *xrm, const char *resdir)
lffreq_img._yref = 12.5;
lffreq_img._rad = 12;

lfgain_img._backg = XftColors_bls1 [C_MAIN_BG];
lfgain_img._backg = XftColors [C_MAIN_BG];
lfgain_img._image [0] = lfshfsect;
lfgain_img._lncol [0] = 1;
lfgain_img._x0 = 63;
@@ -134,3 +137,6 @@ int styles_init (X_display *disp, X_resman *xrm, const char *resdir)
void styles_fini (X_display *disp)
{
}


}

+ 6
- 2
source/native-plugins/zita-bls1/styles.h View File

@@ -26,6 +26,8 @@
#include <clxclient.h>
#include "rotary.h"

namespace BLS1 {


enum
{
@@ -44,8 +46,8 @@ enum
extern int styles_init (X_display *disp, X_resman *xrm, const char *resdir);
extern void styles_fini (X_display *disp);

extern XftColor *XftColors_bls1 [NXFTCOLORS];
extern XftFont *XftFonts_bls1 [NXFTFONTS];
extern XftColor *XftColors [NXFTCOLORS];
extern XftFont *XftFonts [NXFTFONTS];

extern X_textln_style tstyle1;

@@ -60,4 +62,6 @@ extern RotaryImg lffreq_img;
extern RotaryImg lfgain_img;


}

#endif

+ 129
- 0
source/native-plugins/zita-common.hpp View File

@@ -0,0 +1,129 @@
/*
* Carla Native Plugins
* Copyright (C) 2012-2015 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_ZITA_COMMON_HPP_INCLUDED
#define CARLA_ZITA_COMMON_HPP_INCLUDED

#include "CarlaMutex.hpp"
#include "CarlaThread.hpp"

#include <png.h>
#include <clxclient.h>

#define EV_X11 16
#define EV_EXIT 31

// -----------------------------------------------------------------------

template<class MainwinType>
class X_handler_thread : public CarlaThread
{
public:
X_handler_thread()
: CarlaThread("X_handler"),
fMutex(),
fHandler(nullptr),
fRootwin(nullptr),
fMainwin(nullptr),
fClosed(false) {}

void setupAndRun(X_handler* const h, X_rootwin* const r, MainwinType* const m) noexcept
{
const CarlaMutexLocker cml(fMutex);

fHandler = h;
fRootwin = r;
fMainwin = m;

startThread();
}

void stopThread() noexcept
{
signalThreadShouldExit();

{
const CarlaMutexLocker cml(fMutex);
fHandler = nullptr;
fRootwin = nullptr;
fMainwin = nullptr;
}

CarlaThread::stopThread(1000);
}

CarlaMutex& getLock() noexcept
{
return fMutex;
}

bool wasClosed() noexcept
{
if (fClosed)
{
fClosed = false;
return true;
}
return false;
}

private:
CarlaMutex fMutex;
X_handler* fHandler;
X_rootwin* fRootwin;
MainwinType* fMainwin;
volatile bool fClosed;

void run() override
{
for (; ! shouldThreadExit();)
{
int ev;

{
const CarlaMutexLocker cml(fMutex);

CARLA_SAFE_ASSERT_RETURN(fMainwin != nullptr,);

for (; (ev = fMainwin->process()) == EV_X11;)
{
fRootwin->handle_event();
fHandler->next_event();
}

if (ev == Esync::EV_TIME)
{
fRootwin->handle_event();
}
else if (ev == EV_EXIT)
{
fClosed = true;
fHandler = nullptr;
fMainwin = nullptr;
fRootwin = nullptr;
return;
}
}

carla_msleep(10);
}
}
};

// -----------------------------------------------------------------------

#endif // CARLA_ZITA_COMMON_HPP_INCLUDED

+ 577
- 0
source/native-plugins/zita-rev1.cpp View File

@@ -0,0 +1,577 @@
/*
* Carla Native Plugins
* Copyright (C) 2012-2015 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"
#include "CarlaMathUtils.hpp"
#include "CarlaJuceUtils.hpp"

#include "juce_audio_basics.h"

#include "zita-common.hpp"
#include "zita-rev1/guiclass.cc"
#include "zita-rev1/jclient.cc"
#include "zita-rev1/mainwin.cc"
#include "zita-rev1/pareq.cc"
#include "zita-rev1/png2img.cc"
#include "zita-rev1/reverb.cc"
#include "zita-rev1/rotary.cc"
#include "zita-rev1/styles.cc"

using juce::FloatVectorOperations;
using juce::ScopedPointer;

using namespace REV1;

// -----------------------------------------------------------------------
// REV1 Plugin

class REV1Plugin : public NativePluginClass,
private Mainwin::ValueChangedCallback
{
public:
enum Parameters {
kParameterDELAY,
kParameterXOVER,
kParameterRTLOW,
kParameterRTMID,
kParameterFDAMP,
kParameterEQ1FR,
kParameterEQ1GN,
kParameterEQ2FR,
kParameterEQ2GN,
kParameterOPMIXorRGXYZ,
kParameterNROTARY
};

REV1Plugin(const NativeHostDescriptor* const host, const bool isAmbisonic)
: NativePluginClass(host),
kIsAmbisonic(isAmbisonic),
kNumInputs(2),
kNumOutputs(isAmbisonic ? 4 : 2),
fJackClient(),
xresman(),
jclient(nullptr),
display(nullptr),
rootwin(nullptr),
mainwin(nullptr),
handler(nullptr),
handlerThread(),
leakDetector_REV1Plugin()
{
CARLA_SAFE_ASSERT(host != nullptr);

carla_zeroStruct(fJackClient);

fJackClient.clientName = "rev1";
fJackClient.bufferSize = getBufferSize();
fJackClient.sampleRate = getSampleRate();

int argc = 1;
char* argv[] = { (char*)"rev1" };
xresman.init(&argc, argv, (char*)"rev1", nullptr, 0);

jclient = new Jclient(xresman.rname(), &fJackClient, isAmbisonic);

// set initial values
fParameters[kParameterDELAY] = 0.04f;
fParameters[kParameterXOVER] = 200.0f;
fParameters[kParameterRTLOW] = 3.0f;
fParameters[kParameterRTMID] = 2.0f;
fParameters[kParameterFDAMP] = 6.0e3;
fParameters[kParameterEQ1FR] = 160.0f;
fParameters[kParameterEQ1GN] = 0.0f;
fParameters[kParameterEQ2FR] = 2.5e3;
fParameters[kParameterEQ2GN] = 0.0f;

if (isAmbisonic)
fParameters[kParameterOPMIXorRGXYZ] = 0.0f;
else
fParameters[kParameterOPMIXorRGXYZ] = 0.5f;

Reverb* const reverb(jclient->reverb());

reverb->set_delay(fParameters[kParameterDELAY]);
reverb->set_xover(fParameters[kParameterXOVER]);
reverb->set_rtlow(fParameters[kParameterRTLOW]);
reverb->set_rtmid(fParameters[kParameterRTMID]);
reverb->set_fdamp(fParameters[kParameterFDAMP]);

if (isAmbisonic)
{
reverb->set_opmix(0.5);
reverb->set_rgxyz(fParameters[kParameterOPMIXorRGXYZ]);
}
else
{
reverb->set_opmix(fParameters[kParameterOPMIXorRGXYZ]);
reverb->set_rgxyz(0.0);
}

reverb->set_eq1(fParameters[kParameterEQ1FR], fParameters[kParameterEQ1GN]);
reverb->set_eq2(fParameters[kParameterEQ2FR], fParameters[kParameterEQ2GN]);
}

// -------------------------------------------------------------------
// Plugin parameter calls

uint32_t getParameterCount() const override
{
return kParameterNROTARY;
}

const NativeParameter* getParameterInfo(const uint32_t index) const override
{
CARLA_SAFE_ASSERT_RETURN(index < kParameterNROTARY, nullptr);

static NativeParameter param;

int hints = NATIVE_PARAMETER_IS_ENABLED|NATIVE_PARAMETER_IS_AUTOMABLE;

// reset
param.name = nullptr;
param.unit = nullptr;
param.ranges.def = 0.0f;
param.ranges.min = 0.0f;
param.ranges.max = 1.0f;
param.ranges.step = 1.0f;
param.ranges.stepSmall = 1.0f;
param.ranges.stepLarge = 1.0f;
param.scalePointCount = 0;
param.scalePoints = nullptr;

switch (index)
{
case kParameterDELAY:
param.name = "Delay";
param.ranges.def = 0.04f;
param.ranges.min = 0.02f;
param.ranges.max = 0.100f;
break;
case kParameterXOVER:
hints |= NATIVE_PARAMETER_IS_LOGARITHMIC;
param.name = "Crossover";
param.ranges.def = 200.0f;
param.ranges.min = 50.0f;
param.ranges.max = 1000.0f;
break;
case kParameterRTLOW:
hints |= NATIVE_PARAMETER_IS_LOGARITHMIC;
param.name = "RT60 Low";
param.ranges.def = 3.0f;
param.ranges.min = 1.0f;
param.ranges.max = 8.0f;
break;
case kParameterRTMID:
hints |= NATIVE_PARAMETER_IS_LOGARITHMIC;
param.name = "RT60 Mid";
param.ranges.def = 2.0f;
param.ranges.min = 1.0f;
param.ranges.max = 8.0f;
break;
case kParameterFDAMP:
hints |= NATIVE_PARAMETER_IS_LOGARITHMIC;
param.name = "HF Damping";
param.ranges.def = 6.0e3;
param.ranges.min = 1.5e3;
param.ranges.max = 24.0e3;
break;
case kParameterEQ1FR:
hints |= NATIVE_PARAMETER_IS_LOGARITHMIC;
param.name = "Eq1 Frequency";
param.ranges.def = 160.0f;
param.ranges.min = 40.0f;
param.ranges.max = 2.5e3;
break;
case kParameterEQ1GN:
param.name = "Eq1 Gain";
param.ranges.def = 0.0f;
param.ranges.min = -15.0;
param.ranges.max = 15.0f;
break;
case kParameterEQ2FR:
hints |= NATIVE_PARAMETER_IS_LOGARITHMIC;
param.name = "Eq2 Frequency";
param.ranges.def = 2.5e3;
param.ranges.min = 160.0;
param.ranges.max = 10e3;
break;
case kParameterEQ2GN:
param.name = "Eq2 Gain";
param.ranges.def = 0.0f;
param.ranges.min = -15.0;
param.ranges.max = 15.0f;
break;
case kParameterOPMIXorRGXYZ:
if (kIsAmbisonic)
{
param.name = "XYZ gain";
param.ranges.def = 0.0f;
param.ranges.min = -9.0f;
param.ranges.max = 9.0f;
}
else
{
param.name = "Dry/wet mix";
param.ranges.def = 0.5f;
param.ranges.min = 0.0f;
param.ranges.max = 1.0f;
}
break;
}

param.hints = static_cast<NativeParameterHints>(hints);

return &param;
}

float getParameterValue(const uint32_t index) const override
{
CARLA_SAFE_ASSERT_RETURN(index < kParameterNROTARY, 0.0f);

return fParameters[index];
}

// -------------------------------------------------------------------
// Plugin state calls

void setParameterValue(const uint32_t index, const float value) override
{
CARLA_SAFE_ASSERT_RETURN(index < kParameterNROTARY,);

Reverb* const reverb(jclient->reverb());

fParameters[index] = value;

switch (index)
{
case kParameterDELAY:
reverb->set_delay(value);
break;
case kParameterXOVER:
reverb->set_xover(value);
break;
case kParameterRTLOW:
reverb->set_rtlow(value);
break;
case kParameterRTMID:
reverb->set_rtmid(value);
break;
case kParameterFDAMP:
reverb->set_fdamp(value);
break;
case kParameterEQ1FR:
reverb->set_eq1(value, fParameters[kParameterEQ1GN]);
break;
case kParameterEQ1GN:
reverb->set_eq1(fParameters[kParameterEQ1FR], value);
break;
case kParameterEQ2FR:
reverb->set_eq2(value, fParameters[kParameterEQ2GN]);
break;
case kParameterEQ2GN:
reverb->set_eq2(fParameters[kParameterEQ2FR], value);
break;
case kParameterOPMIXorRGXYZ:
if (kIsAmbisonic)
reverb->set_rgxyz(value);
else
reverb->set_opmix(value);
break;
}
}

// -------------------------------------------------------------------
// Plugin process calls

void process(float** const inBuffer, float** const outBuffer, const uint32_t frames, const NativeMidiEvent* const, const uint32_t) override
{
if (! fJackClient.active)
{
const int iframes(static_cast<int>(frames));

for (uint32_t i=0; i<kNumInputs; ++i)
FloatVectorOperations::clear(outBuffer[i], iframes);

return;
}

for (uint32_t i=0; i<kNumInputs; ++i)
fJackClient.portsAudioIn[i].buffer.audio = inBuffer[i];

for (uint32_t i=0; i<kNumOutputs; ++i)
fJackClient.portsAudioOut[i].buffer.audio = outBuffer[i];

fJackClient.processCallback(frames, fJackClient.processPtr);
}

// -------------------------------------------------------------------
// Plugin UI calls

void uiShow(const bool show) override
{
if (show)
{
if (display != nullptr)
return;

display = new X_display(nullptr);

if (display->dpy() == nullptr)
return hostUiUnavailable();

styles_init(display, &xresman, getResourceDir());

rootwin = new X_rootwin(display);
mainwin = new Mainwin(rootwin, &xresman, 0, 0, jclient, this);
rootwin->handle_event();
mainwin->x_set_title(getUiName());

handler = new X_handler(display, mainwin, EV_X11);

if (const uintptr_t winId = getUiParentId())
XSetTransientForHint(display->dpy(), mainwin->win(), static_cast<Window>(winId));

handler->next_event();
XFlush(display->dpy());

handlerThread.setupAndRun(handler, rootwin, mainwin);
}
else
{
if (handlerThread.isThreadRunning())
handlerThread.stopThread();

handler = nullptr;
mainwin = nullptr;
rootwin = nullptr;
display = nullptr;
}
}

void uiIdle() override
{
if (mainwin == nullptr)
return;

if (handlerThread.wasClosed())
{
{
const CarlaMutexLocker cml(handlerThread.getLock());
handler = nullptr;
mainwin = nullptr;
rootwin = nullptr;
display = nullptr;
}
uiClosed();
}
}

void uiSetParameterValue(const uint32_t index, const float value) override
{
CARLA_SAFE_ASSERT_RETURN(index < kParameterNROTARY,);

if (mainwin == nullptr)
return;

uint32_t rindex = index;

if (kIsAmbisonic && index == kParameterOPMIXorRGXYZ)
rindex += 1;

const CarlaMutexLocker cml(handlerThread.getLock());

mainwin->_rotary[rindex]->set_value(value);
}

// -------------------------------------------------------------------
// Plugin dispatcher calls

void bufferSizeChanged(const uint32_t bufferSize) override
{
fJackClient.bufferSize = bufferSize;
}

void sampleRateChanged(const double sampleRate) override
{
fJackClient.sampleRate = sampleRate;
}

void uiNameChanged(const char* const uiName) override
{
CARLA_SAFE_ASSERT_RETURN(uiName != nullptr && uiName[0] != '\0',);

if (mainwin == nullptr)
return;

const CarlaMutexLocker cml(handlerThread.getLock());

mainwin->x_set_title(uiName);
}

// -------------------------------------------------------------------
// Mainwin callbacks

void valueChangedCallback(uint rindex, double value) override
{
uint32_t index = rindex;

if (kIsAmbisonic && rindex == Mainwin::NROTARY)
index = kParameterOPMIXorRGXYZ;

fParameters[index] = value;
uiParameterChanged(index, value);
}

// -------------------------------------------------------------------

private:
const bool kIsAmbisonic;
const uint32_t kNumInputs;
const uint32_t kNumOutputs;

// Fake jack client
jack_client_t fJackClient;

// Zita stuff (core)
X_resman xresman;
ScopedPointer<Jclient> jclient;
ScopedPointer<X_display> display;
ScopedPointer<X_rootwin> rootwin;
ScopedPointer<Mainwin> mainwin;
ScopedPointer<X_handler> handler;
X_handler_thread<Mainwin> handlerThread;

float fParameters[kParameterNROTARY];

public:
static NativePluginHandle _instantiateAmbisonic(const NativeHostDescriptor* host)
{
return (host != nullptr) ? new REV1Plugin(host, true) : nullptr;
}

static NativePluginHandle _instantiateStereo(const NativeHostDescriptor* host)
{
return (host != nullptr) ? new REV1Plugin(host, false) : nullptr;
}

static void _cleanup(NativePluginHandle handle)
{
delete (REV1Plugin*)handle;
}

CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(REV1Plugin)
};

// -----------------------------------------------------------------------

static const NativePluginDescriptor rev1AmbisonicDesc = {
/* category */ NATIVE_PLUGIN_CATEGORY_DELAY,
/* hints */ static_cast<NativePluginHints>(NATIVE_PLUGIN_IS_RTSAFE
|NATIVE_PLUGIN_HAS_UI
|NATIVE_PLUGIN_NEEDS_FIXED_BUFFERS
|NATIVE_PLUGIN_NEEDS_UI_MAIN_THREAD
|NATIVE_PLUGIN_USES_PARENT_ID),
/* supports */ static_cast<NativePluginSupports>(0x0),
/* audioIns */ 2,
/* audioOuts */ 4,
/* midiIns */ 0,
/* midiOuts */ 0,
/* paramIns */ REV1Plugin::kParameterNROTARY,
/* paramOuts */ 0,
/* name */ "REV1 (Ambisonic)",
/* label */ "rev1-ambisonic",
/* maker */ "falkTX, Fons Adriaensen",
/* copyright */ "GPL v2+",
REV1Plugin::_instantiateAmbisonic,
REV1Plugin::_cleanup,
REV1Plugin::_get_parameter_count,
REV1Plugin::_get_parameter_info,
REV1Plugin::_get_parameter_value,
REV1Plugin::_get_parameter_text,
REV1Plugin::_get_midi_program_count,
REV1Plugin::_get_midi_program_info,
REV1Plugin::_set_parameter_value,
REV1Plugin::_set_midi_program,
REV1Plugin::_set_custom_data,
REV1Plugin::_ui_show,
REV1Plugin::_ui_idle,
REV1Plugin::_ui_set_parameter_value,
REV1Plugin::_ui_set_midi_program,
REV1Plugin::_ui_set_custom_data,
REV1Plugin::_activate,
REV1Plugin::_deactivate,
REV1Plugin::_process,
REV1Plugin::_get_state,
REV1Plugin::_set_state,
REV1Plugin::_dispatcher
};

static const NativePluginDescriptor rev1StereoDesc = {
/* category */ NATIVE_PLUGIN_CATEGORY_DELAY,
/* hints */ static_cast<NativePluginHints>(NATIVE_PLUGIN_IS_RTSAFE
|NATIVE_PLUGIN_HAS_UI
|NATIVE_PLUGIN_NEEDS_FIXED_BUFFERS
|NATIVE_PLUGIN_NEEDS_UI_MAIN_THREAD
|NATIVE_PLUGIN_USES_PARENT_ID),
/* supports */ static_cast<NativePluginSupports>(0x0),
/* audioIns */ 2,
/* audioOuts */ 2,
/* midiIns */ 0,
/* midiOuts */ 0,
/* paramIns */ REV1Plugin::kParameterNROTARY,
/* paramOuts */ 0,
/* name */ "REV1 (Stereo)",
/* label */ "rev1-stereo",
/* maker */ "falkTX, Fons Adriaensen",
/* copyright */ "GPL v2+",
REV1Plugin::_instantiateStereo,
REV1Plugin::_cleanup,
REV1Plugin::_get_parameter_count,
REV1Plugin::_get_parameter_info,
REV1Plugin::_get_parameter_value,
REV1Plugin::_get_parameter_text,
REV1Plugin::_get_midi_program_count,
REV1Plugin::_get_midi_program_info,
REV1Plugin::_set_parameter_value,
REV1Plugin::_set_midi_program,
REV1Plugin::_set_custom_data,
REV1Plugin::_ui_show,
REV1Plugin::_ui_idle,
REV1Plugin::_ui_set_parameter_value,
REV1Plugin::_ui_set_midi_program,
REV1Plugin::_ui_set_custom_data,
REV1Plugin::_activate,
REV1Plugin::_deactivate,
REV1Plugin::_process,
REV1Plugin::_get_state,
REV1Plugin::_set_state,
REV1Plugin::_dispatcher
};

// -----------------------------------------------------------------------

CARLA_EXPORT
void carla_register_native_plugin_zita_rev1();

CARLA_EXPORT
void carla_register_native_plugin_zita_rev1()
{
carla_register_native_plugin(&rev1AmbisonicDesc);
carla_register_native_plugin(&rev1StereoDesc);
}

// -----------------------------------------------------------------------

+ 32
- 0
source/native-plugins/zita-rev1/global.h View File

@@ -0,0 +1,32 @@
// ----------------------------------------------------------------------
//
// Copyright (C) 2010 Fons Adriaensen <fons@kokkinizita.net>
// Modified by falkTX on Jan 2015 for inclusion in Carla
//
// 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
// (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, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// ----------------------------------------------------------------------


#ifndef __GLOBAL_H
#define __GLOBAL_H


#define PROGNAME "zita-rev1"
#define EV_X11 16
#define EV_EXIT 31


#endif

+ 161
- 0
source/native-plugins/zita-rev1/guiclass.cc View File

@@ -0,0 +1,161 @@
// ----------------------------------------------------------------------
//
// Copyright (C) 2010 Fons Adriaensen <fons@linuxaudio.org>
// Modified by falkTX on Jan 2015 for inclusion in Carla
//
// 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
// (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, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// ----------------------------------------------------------------------


#include <math.h>
#include "guiclass.h"

namespace REV1 {


Rlinctl::Rlinctl (X_window *parent,
X_callback *cbobj,
RotaryImg *image,
int xp,
int yp,
int cm,
int dd,
double vmin,
double vmax,
double vini,
int cbind) :
RotaryCtl (parent, cbobj, image, xp, yp, cbind),
_cm (cm),
_dd (dd),
_vmin (vmin),
_vmax (vmax),
_form (0)
{
_count = -1;
set_value (vini);
}

void Rlinctl::get_string (char *p, int n)
{
if (_form) snprintf (p, n, _form, _value);
else *p = 0;
}

void Rlinctl::set_value (double v)
{
set_count ((int) floor (_cm * (v - _vmin) / (_vmax - _vmin) + 0.5));
render ();
}

int Rlinctl::handle_button (void)
{
return PRESS;
}

int Rlinctl::handle_motion (int dx, int dy)
{
return set_count (_rcount + dx - dy);
}

int Rlinctl::handle_mwheel (int dw)
{
if (! (_keymod & ShiftMask)) dw *= _dd;
return set_count (_count + dw);
}

int Rlinctl::set_count (int u)
{
if (u < 0) u= 0;
if (u > _cm) u = _cm;
if (u != _count)
{
_count = u;
_value = _vmin + u * (_vmax - _vmin) / _cm;
_angle = 270.0 * ((double) u / _cm - 0.5);
return DELTA;
}
return 0;
}



Rlogctl::Rlogctl (X_window *parent,
X_callback *cbobj,
RotaryImg *image,
int xp,
int yp,
int cm,
int dd,
double vmin,
double vmax,
double vini,
int cbind) :
RotaryCtl (parent, cbobj, image, xp, yp, cbind),
_cm (cm),
_dd (dd),
_form (0)
{
_count = -1;
_vmin = log (vmin);
_vmax = log (vmax);
set_value (vini);
}

void Rlogctl::get_string (char *p, int n)
{
if (_form) snprintf (p, n, _form, _value);
else *p = 0;
}

void Rlogctl::set_value (double v)
{
set_count ((int) floor (_cm * (log (v) - _vmin) / (_vmax - _vmin) + 0.5));
render ();
}

int Rlogctl::handle_button (void)
{
return PRESS;
}

int Rlogctl::handle_motion (int dx, int dy)
{
return set_count (_rcount + dx - dy);
}

int Rlogctl::handle_mwheel (int dw)
{
if (! (_keymod & ShiftMask)) dw *= _dd;
return set_count (_count + dw);
}

int Rlogctl::set_count (int u)
{
if (u < 0) u= 0;
if (u > _cm) u = _cm;
if (u != _count)
{
_count = u;
_value = exp (_vmin + u * (_vmax - _vmin) / _cm);
_angle = 270.0 * ((double) u / _cm - 0.5);
return DELTA;
}
return 0;
}


}


+ 103
- 0
source/native-plugins/zita-rev1/guiclass.h View File

@@ -0,0 +1,103 @@
// ----------------------------------------------------------------------
//
// Copyright (C) 2010 Fons Adriaensen <fons@linuxaudio.org>
// Modified by falkTX on Jan 2015 for inclusion in Carla
//
// 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
// (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, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// ----------------------------------------------------------------------


#ifndef __GUICLASS_H
#define __GUICLASS_H


#include "rotary.h"

namespace REV1 {


class Rlinctl : public RotaryCtl
{
public:

Rlinctl (X_window *parent,
X_callback *cbobj,
RotaryImg *image,
int xp,
int yp,
int cm,
int dd,
double vmin,
double vmax,
double vini,
int cbind = 0);

virtual void set_value (double v);
virtual void get_string (char *p, int n);

private:

virtual int handle_button (void);
virtual int handle_motion (int dx, int dy);
virtual int handle_mwheel (int dw);
int set_count (int u);

int _cm;
int _dd;
double _vmin;
double _vmax;
const char *_form;
};


class Rlogctl : public RotaryCtl
{
public:

Rlogctl (X_window *parent,
X_callback *cbobj,
RotaryImg *image,
int xp,
int yp,
int cm,
int dd,
double vmin,
double vmax,
double vini,
int cbind = 0);

virtual void set_value (double v);
virtual void get_string (char *p, int n);

private:

virtual int handle_button (void);
virtual int handle_motion (int dx, int dy);
virtual int handle_mwheel (int dw);
int set_count (int u);

int _cm;
int _dd;
double _vmin;
double _vmax;
const char *_form;
};


}


#endif

+ 140
- 0
source/native-plugins/zita-rev1/jclient.cc View File

@@ -0,0 +1,140 @@
// ----------------------------------------------------------------------
//
// Copyright (C) 2010 Fons Adriaensen <fons@linuxaudio.org>
// Modified by falkTX on Jan 2015 for inclusion in Carla
//
// 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
// (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, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// ----------------------------------------------------------------------


#include "jclient.h"

namespace REV1 {


Jclient::Jclient (const char *jname, jack_client_t *jclient, bool ambis) :
A_thread ("Jclient"),
_jack_client (jclient),
_active (false),
_jname (0),
_ambis (ambis)
{
init_jack (jname);
}


Jclient::~Jclient (void)
{
if (_jack_client) close_jack ();
}


void Jclient::init_jack (const char *jname)
{
jack_set_process_callback (_jack_client, jack_static_process, (void *) this);
jack_on_shutdown (_jack_client, jack_static_shutdown, (void *) this);
if (jack_activate (_jack_client))
{
fprintf(stderr, "Can't activate JACK.\n");
exit (1);
}
_jname = jack_get_client_name (_jack_client);
_fsamp = jack_get_sample_rate (_jack_client);

_fragm = 1024;
_nsamp = 0;

if (_ambis)
{
_inpports [0] = jack_port_register (_jack_client, "in.L", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
_inpports [1] = jack_port_register (_jack_client, "in.R", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
_outports [0] = jack_port_register (_jack_client, "out.W", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
_outports [1] = jack_port_register (_jack_client, "out.X", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
_outports [2] = jack_port_register (_jack_client, "out.Y", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
_outports [3] = jack_port_register (_jack_client, "out.Z", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
}
else
{
_inpports [0] = jack_port_register (_jack_client, "in.L", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
_inpports [1] = jack_port_register (_jack_client, "in.R", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
_outports [0] = jack_port_register (_jack_client, "out.L", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
_outports [1] = jack_port_register (_jack_client, "out.R", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
}

_reverb.init (_fsamp, _ambis);
_active = true;
}


void Jclient::close_jack ()
{
jack_deactivate (_jack_client);
jack_client_close (_jack_client);
}


void Jclient::jack_static_shutdown (void *arg)
{
((Jclient *) arg)->jack_shutdown ();
}


int Jclient::jack_static_process (jack_nframes_t nframes, void *arg)
{
return ((Jclient *) arg)->jack_process (nframes);
}


void Jclient::jack_shutdown (void)
{
send_event (EV_EXIT, 1);
}


int Jclient::jack_process (int frames)
{
int i, k, n_inp, n_out;
float *inp [2];
float *out [4];

if (!_active) return 0;

n_inp = 2;
n_out = _ambis ? 4 : 2;
for (i = 0; i < n_inp; i++) inp [i] = (float *) jack_port_get_buffer (_inpports [i], frames);
for (i = 0; i < n_out; i++) out [i] = (float *) jack_port_get_buffer (_outports [i], frames);

while (frames)
{
if (!_nsamp)
{
_reverb.prepare (_fragm);
_nsamp = _fragm;
}
k = (_nsamp < frames) ? _nsamp : frames;
_reverb.process (k, inp, out);
for (i = 0; i < n_inp; i++) inp [i] += k;
for (i = 0; i < n_out; i++) out [i] += k;
frames -= k;
_nsamp -= k;
}


return 0;
}


}

+ 72
- 0
source/native-plugins/zita-rev1/jclient.h View File

@@ -0,0 +1,72 @@
// ----------------------------------------------------------------------
//
// Copyright (C) 2010 Fons Adriaensen <fons@linuxaudio.org>
// Modified by falkTX on Jan 2015 for inclusion in Carla
//
// 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
// (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, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// ----------------------------------------------------------------------


#ifndef __JCLIENT_H
#define __JCLIENT_H


#include <clthreads.h>
#include "CarlaNativeJack.h"
#include "global.h"
#include "reverb.h"

namespace REV1 {


class Jclient : public A_thread
{
public:

Jclient (const char *jname, jack_client_t *jclient, bool ambis);
~Jclient (void);

const char *jname (void) const { return _jname; }
Reverb *reverb (void) const { return (Reverb *) &_reverb; }

private:

void init_jack (const char *jname);
void close_jack (void);
void jack_shutdown (void);
int jack_process (int nframes);

virtual void thr_main (void) {}

jack_client_t *_jack_client;
jack_port_t *_inpports [2];
jack_port_t *_outports [4];
bool _active;
const char *_jname;
unsigned int _fsamp;
bool _ambis;
int _fragm;
int _nsamp;
Reverb _reverb;

static void jack_static_shutdown (void *arg);
static int jack_static_process (jack_nframes_t nframes, void *arg);
};


}

#endif

+ 245
- 0
source/native-plugins/zita-rev1/mainwin.cc View File

@@ -0,0 +1,245 @@
// ----------------------------------------------------------------------
//
// Copyright (C) 2010 Fons Adriaensen <fons@linuxaudio.org>
// Modified by falkTX on Jan 2015 for inclusion in Carla
//
// 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
// (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, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// ----------------------------------------------------------------------


#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "styles.h"
#include "global.h"
#include "mainwin.h"

namespace REV1 {


Mainwin::Mainwin (X_rootwin *parent, X_resman *xres, int xp, int yp, Jclient *jclient, ValueChangedCallback* valuecb) :
A_thread ("Main"),
X_window (parent, xp, yp, XSIZE, YSIZE, XftColors [C_MAIN_BG]->pixel),
_stop (false),
_xres (xres),
_jclient (jclient),
_valuecb (valuecb)
{
X_hints H;
char s [256];
int i, x;

_atom = XInternAtom (dpy (), "WM_DELETE_WINDOW", True);
XSetWMProtocols (dpy (), win (), &_atom, 1);
_atom = XInternAtom (dpy (), "WM_PROTOCOLS", True);

sprintf (s, "%s", jclient->jname ());
x_set_title (s);
H.position (xp, yp);
H.minsize (XSIZE, YSIZE);
H.maxsize (XSIZE, YSIZE);
H.rname (xres->rname ());
H.rclas (xres->rclas ());
x_apply (&H);

_ambis = xres->getb (".ambisonic", false);
RotaryCtl::init (disp ());
x = 0;
_rotary [R_DELAY] = new Rlinctl (this, this, &r_delay_img, x, 0, 160, 5, 0.02, 0.100, 0.04, R_DELAY);
_rotary [R_XOVER] = new Rlogctl (this, this, &r_xover_img, x, 0, 200, 5, 50.0, 1000.0, 200.0, R_XOVER);
_rotary [R_RTLOW] = new Rlogctl (this, this, &r_rtlow_img, x, 0, 200, 5, 1.0, 8.0, 3.0, R_RTLOW);
_rotary [R_RTMID] = new Rlogctl (this, this, &r_rtmid_img, x, 0, 200, 5, 1.0, 8.0, 2.0, R_RTMID);
_rotary [R_FDAMP] = new Rlogctl (this, this, &r_fdamp_img, x, 0, 200, 5, 1.5e3, 24.0e3, 6.0e3, R_FDAMP);
x += 315;
_rotary [R_EQ1FR] = new Rlogctl (this, this, &r_parfr_img, x, 0, 180, 5, 40.0, 2.5e3, 160.0, R_EQ1FR);
_rotary [R_EQ1GN] = new Rlinctl (this, this, &r_pargn_img, x, 0, 150, 5, -15.0, 15.0, 0.0, R_EQ1GN);
x += 110;
_rotary [R_EQ2FR] = new Rlogctl (this, this, &r_parfr_img, x, 0, 180, 5, 160.0, 10e3, 2.5e3, R_EQ2FR);
_rotary [R_EQ2GN] = new Rlinctl (this, this, &r_pargn_img, x, 0, 150, 5, -15.0, 15.0, 0.0, R_EQ2GN);
x += 110;
_rotary [R_OPMIX] = new Rlinctl (this, this, &r_opmix_img, x, 0, 180, 5, 0.0 , 1.0, 0.5, R_OPMIX);
_rotary [R_RGXYZ] = new Rlinctl (this, this, &r_rgxyz_img, x, 0, 180, 5, -9.0 , 9.0, 0.0, R_RGXYZ);
for (i = 0; i < R_OPMIX; i++) _rotary [i]->x_map ();
if (_ambis) _rotary [R_RGXYZ]->x_map ();
else _rotary [R_OPMIX]->x_map ();

x_add_events (ExposureMask);
x_map ();
set_time (0);
inc_time (500000);
}

Mainwin::~Mainwin (void)
{
RotaryCtl::fini ();
}

int Mainwin::process (void)
{
int e;

if (_stop) handle_stop ();

e = get_event_timed ();
switch (e)
{
case EV_TIME:
handle_time ();
break;
}
return e;
}


void Mainwin::handle_event (XEvent *E)
{
switch (E->type)
{
case Expose:
expose ((XExposeEvent *) E);
break;
case ClientMessage:
clmesg ((XClientMessageEvent *) E);
break;
}
}


void Mainwin::expose (XExposeEvent *E)
{
if (E->count) return;
redraw ();
}


void Mainwin::clmesg (XClientMessageEvent *E)
{
if (E->message_type == _atom) _stop = true;
}


void Mainwin::handle_time (void)
{
inc_time (500000);
// XFlush (dpy ());
}


void Mainwin::handle_stop (void)
{
put_event (EV_EXIT, 1);
}


void Mainwin::handle_callb (int type, X_window *W, XEvent *E)
{
RotaryCtl *R;
int k;
double v, v2;

switch (type)
{
case RotaryCtl::PRESS:
R = (RotaryCtl *) W;
k = R->cbind ();
switch (k)
{
default:
;
}
break;

case RotaryCtl::DELTA:
R = (RotaryCtl *) W;
k = R->cbind ();
switch (k)
{
case R_DELAY:
v = _rotary [R_DELAY]->value ();
_jclient->reverb ()->set_delay (v);
_valuecb->valueChangedCallback (R_DELAY, v);
break;
case R_XOVER:
v = _rotary [R_XOVER]->value ();
_jclient->reverb ()->set_xover (v);
_valuecb->valueChangedCallback (R_XOVER, v);
break;
case R_RTLOW:
v = _rotary [R_RTLOW]->value ();
_jclient->reverb ()->set_rtlow (v);
_valuecb->valueChangedCallback (R_RTLOW, v);
break;
case R_RTMID:
v = _rotary [R_RTMID]->value ();
_jclient->reverb ()->set_rtmid (v);
_valuecb->valueChangedCallback (R_RTMID, v);
break;
case R_FDAMP:
v = _rotary [R_FDAMP]->value ();
_jclient->reverb ()->set_fdamp (v);
_valuecb->valueChangedCallback (R_FDAMP, v);
break;
case R_OPMIX:
v = _rotary [R_OPMIX]->value ();
_jclient->reverb ()->set_opmix (v);
_valuecb->valueChangedCallback (R_OPMIX, v);
break;
case R_RGXYZ:
v = _rotary [R_RGXYZ]->value ();
_jclient->reverb ()->set_rgxyz (v);
_valuecb->valueChangedCallback (R_RGXYZ, v);
break;
case R_EQ1FR:
case R_EQ1GN:
v = _rotary [R_EQ1FR]->value (), v2 = _rotary [R_EQ1GN]->value ();
_jclient->reverb ()->set_eq1 (v, v2);
_valuecb->valueChangedCallback (R_EQ1FR, v);
_valuecb->valueChangedCallback (R_EQ1GN, v2);
break;
case R_EQ2FR:
case R_EQ2GN:
v = _rotary [R_EQ2FR]->value (), v2 = _rotary [R_EQ2GN]->value ();
_jclient->reverb ()->set_eq2 (v, v2);
_valuecb->valueChangedCallback (R_EQ2FR, v);
_valuecb->valueChangedCallback (R_EQ2GN, v2);
break;
}
break;
}
}


void Mainwin::redraw (void)
{
int x;

x = 0;
XPutImage (dpy (), win (), dgc (), revsect_img, 0, 0, x, 0, 310, 75);
x += 315;
XPutImage (dpy (), win (), dgc (), eq1sect_img, 0, 0, x, 0, 110, 75);
x += 110;
XPutImage (dpy (), win (), dgc (), eq2sect_img, 0, 0, x, 0, 110, 75);
x += 110;
if (_ambis) XPutImage (dpy (), win (), dgc (), ambsect_img, 0, 0, x, 0, 70, 75);
else XPutImage (dpy (), win (), dgc (), mixsect_img, 0, 0, x, 0, 70, 75);
x += 70;
}


}

+ 88
- 0
source/native-plugins/zita-rev1/mainwin.h View File

@@ -0,0 +1,88 @@
// ----------------------------------------------------------------------
//
// Copyright (C) 2010 Fons Adriaensen <fons@linuxaudio.org>
// Modified by falkTX on Jan 2015 for inclusion in Carla
//
// 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
// (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, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// ----------------------------------------------------------------------


#ifndef __MAINWIN_H
#define __MAINWIN_H


#include <clxclient.h>
#include "guiclass.h"
#include "jclient.h"
#include "global.h"

class REV1Plugin;

namespace REV1 {


class Mainwin : public A_thread, public X_window, public X_callback
{
public:

struct ValueChangedCallback {
virtual ~ValueChangedCallback() {}
virtual void valueChangedCallback(uint, double) = 0;
};


enum { XSIZE = 540, YSIZE = 75 };

Mainwin (X_rootwin *parent, X_resman *xres, int xp, int yp, Jclient *jclient, ValueChangedCallback* valuecb);
~Mainwin (void);
Mainwin (const Mainwin&);
Mainwin& operator=(const Mainwin&);

void stop (void) { _stop = true; }
int process (void);

private:

enum { R_DELAY, R_XOVER, R_RTLOW, R_RTMID, R_FDAMP,
R_EQ1FR, R_EQ1GN, R_EQ2FR, R_EQ2GN,
R_OPMIX, R_RGXYZ, NROTARY };
virtual void thr_main (void) {}

void handle_time (void);
void handle_stop (void);
void handle_event (XEvent *);
void handle_callb (int type, X_window *W, XEvent *E);
void expose (XExposeEvent *E);
void clmesg (XClientMessageEvent *E);
void redraw (void);

Atom _atom;
bool _stop;
bool _ambis;
X_resman *_xres;
Jclient *_jclient;
RotaryCtl *_rotary [NROTARY];

ValueChangedCallback* _valuecb;

friend class ::REV1Plugin;
};


}

#endif

+ 200
- 0
source/native-plugins/zita-rev1/pareq.cc View File

@@ -0,0 +1,200 @@
// ----------------------------------------------------------------------
//
// Copyright (C) 2010 Fons Adriaensen <fons@linuxaudio.org>
// Modified by falkTX on Jan 2015 for inclusion in Carla
//
// 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
// (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, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// ----------------------------------------------------------------------


#include <math.h>
#include <string.h>
#include "pareq.h"

namespace REV1 {


Pareq::Pareq (void) :
_touch0 (0),
_touch1 (0),
_state (BYPASS),
_g0 (1),
_g1 (1),
_f0 (1e3f),
_f1 (1e3f)
{
setfsamp (0.0f);
}


Pareq::~Pareq (void)
{
}


void Pareq::setfsamp (float fsamp)
{
_fsamp = fsamp;
reset ();
}


void Pareq::reset (void)
{
memset (_z1, 0, sizeof (float) * MAXCH);
memset (_z2, 0, sizeof (float) * MAXCH);
}


void Pareq::prepare (int nsamp)
{
bool upd = false;
float g, f;

if (_touch1 != _touch0)
{
g = _g0;
f = _f0;
if (g != _g1)
{
upd = true;
if (g > 2 * _g1) _g1 *= 2;
else if (_g1 > 2 * g) _g1 /= 2;
else _g1 = g;
}
if (f != _f1)
{
upd = true;
if (f > 2 * _f1) _f1 *= 2;
else if (_f1 > 2 * f) _f1 /= 2;
else _f1 = f;
}
if (upd)
{
if ((_state == BYPASS) && (_g1 == 1))
{
calcpar1 (0, _g1, _f1);
}
else
{
_state = SMOOTH;
calcpar1 (nsamp, _g1, _f1);
}
}
else
{
_touch1 = _touch0;
if (fabs (_g1 - 1) < 0.001f)
{
_state = BYPASS;
reset ();
}
else
{
_state = STATIC;
}
}
}
}


void Pareq::calcpar1 (int nsamp, float g, float f)
{
float b, c1, c2, gg;

f *= float (M_PI) / _fsamp;
b = 2 * f / sqrtf (g);
gg = 0.5f * (g - 1);
c1 = -cosf (2 * f);
c2 = (1 - b) / (1 + b);
if (nsamp)
{
_dc1 = (c1 - _c1) / nsamp + 1e-30f;
_dc2 = (c2 - _c2) / nsamp + 1e-30f;
_dgg = (gg - _gg) / nsamp + 1e-30f;
}
else
{
_c1 = c1;
_c2 = c2;
_gg = gg;
}
}


void Pareq::process1 (int nsamp, int nchan, float *data[])
{
int i, j;
float c1, c2, gg;
float x, y, z1, z2;
float *p;

c1 = _c1;
c2 = _c2;
gg = _gg;
if (_state == SMOOTH)
{
for (i = 0; i < nchan; i++)
{
p = data [i];
z1 = _z1 [i];
z2 = _z2 [i];
c1 = _c1;
c2 = _c2;
gg = _gg;
for (j = 0; j < nsamp; j++)
{
c1 += _dc1;
c2 += _dc2;
gg += _dgg;
x = *p;
y = x - c2 * z2;
*p++ = x - gg * (z2 + c2 * y - x);
y -= c1 * z1;
z2 = z1 + c1 * y;
z1 = y + 1e-20f;
}
_z1 [i] = z1;
_z2 [i] = z2;
}
_c1 = c1;
_c2 = c2;
_gg = gg;
}
else
{
for (i = 0; i < nchan; i++)
{
p = data [i];
z1 = _z1 [i];
z2 = _z2 [i];
for (j = 0; j < nsamp; j++)
{
x = *p;
y = x - c2 * z2;
*p++ = x - gg * (z2 + c2 * y - x);
y -= c1 * z1;
z2 = z1 + c1 * y;
z1 = y + 1e-20f;
}
_z1 [i] = z1;
_z2 [i] = z2;
}
}
}


}

+ 81
- 0
source/native-plugins/zita-rev1/pareq.h View File

@@ -0,0 +1,81 @@
// ----------------------------------------------------------------------
//
// Copyright (C) 2010 Fons Adriaensen <fons@linuxaudio.org>
// Modified by falkTX on Jan 2015 for inclusion in Carla
//
// 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
// (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, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// ----------------------------------------------------------------------


#ifndef __PAREQ_H
#define __PAREQ_H


#include <stdint.h>
#include <math.h>
#include "global.h"

namespace REV1 {


class Pareq
{
public:

Pareq (void);
~Pareq (void);
void setfsamp (float fsamp);
void setparam (float f, float g)
{
_f0 = f;
_g0 = powf (10.0f, 0.05f * g);
_touch0++;
}
void reset (void);
void prepare (int nsamp);
void process (int nsamp, int nchan, float *data[])
{
if (_state != BYPASS) process1 (nsamp, nchan, data);
}

private:

enum { BYPASS, STATIC, SMOOTH, MAXCH = 4 };

void calcpar1 (int nsamp, float g, float f);
void process1 (int nsamp, int nchan, float *data[]);

volatile int16_t _touch0;
volatile int16_t _touch1;
bool _bypass;
int _state;
float _fsamp;

float _g0, _g1;
float _f0, _f1;
float _c1, _dc1;
float _c2, _dc2;
float _gg, _dgg;

float _z1 [MAXCH];
float _z2 [MAXCH];
};


}

#endif

+ 136
- 0
source/native-plugins/zita-rev1/png2img.cc View File

@@ -0,0 +1,136 @@
// ----------------------------------------------------------------------
//
// Copyright (C) 2007-2010 Fons Adriaensen <fons@linuxaudio.org>
// Modified by falkTX on Jan 2015 for inclusion in Carla
//
// 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
// (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, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// ----------------------------------------------------------------------


#include <png.h>
#include <clxclient.h>

namespace REV1 {


XImage *png2img (const char *file, X_display *disp, XftColor *bgnd)
{
FILE *F;
png_byte hdr [8];
png_structp png_ptr;
png_infop png_info;
const unsigned char **data, *p;
int dx, dy, x, y, dp;
float vr, vg, vb, va, br, bg, bb;
unsigned long mr, mg, mb, pix;
XImage *image;

F = fopen (file, "r");
if (!F)
{
fprintf (stderr, "Can't open '%s'\n", file);
return 0;
}
fread (hdr, 1, 8, F);
if (png_sig_cmp (hdr, 0, 8))
{
fprintf (stderr, "'%s' is not a PNG file\n", file);
return 0;
}
fseek (F, 0, SEEK_SET);

png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, 0, 0, 0);
if (! png_ptr)
{
fclose (F);
return 0;
}
png_info = png_create_info_struct (png_ptr);
if (! png_info)
{
png_destroy_read_struct (&png_ptr, 0, 0);
fclose (F);
return 0;
}
if (setjmp (png_jmpbuf (png_ptr)))
{
png_destroy_read_struct (&png_ptr, &png_info, 0);
fclose (F);
fprintf (stderr, "png:longjmp()\n");
return 0;
}

png_init_io (png_ptr, F);
png_read_png (png_ptr, png_info,
PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_PACKING | PNG_TRANSFORM_EXPAND,
0);

// This requires libpng14 or later. If you still have an
// older version, use the three commented lines instead.

dx = png_get_image_width (png_ptr, png_info);
dy = png_get_image_height (png_ptr, png_info);
dp = (png_get_color_type (png_ptr, png_info) & PNG_COLOR_MASK_ALPHA) ? 4 : 3;

// dx = png_info->width;
// dy = png_info->height;
// dp = (png_info->color_type & PNG_COLOR_MASK_ALPHA) ? 4 : 3;

data = (const unsigned char **)(png_get_rows (png_ptr, png_info));

image = XCreateImage (disp->dpy (),
disp->dvi (),
DefaultDepth (disp->dpy (), disp->dsn ()),
ZPixmap, 0, 0, dx, dy, 32, 0);
image->data = new char [image->height * image->bytes_per_line];

mr = image->red_mask;
mg = image->green_mask;
mb = image->blue_mask;

vr = mr / 255.0f;
vg = mg / 255.0f;
vb = mb / 255.0f;
if (bgnd)
{
br = bgnd->color.red >> 8;
bg = bgnd->color.green >> 8;
bb = bgnd->color.blue >> 8;
}
else br = bg = bb = 0;

for (y = 0; y < dy; y++)
{
p = data [y];
for (x = 0; x < dx; x++)
{
va = (dp == 4) ? (p [3] / 255.0f) : 1;
pix = ((unsigned long)((p [0] * va + (1 - va) * br) * vr) & mr)
| ((unsigned long)((p [1] * va + (1 - va) * bg) * vg) & mg)
| ((unsigned long)((p [2] * va + (1 - va) * bb) * vb) & mb);
XPutPixel (image, x, y, pix);
p += dp;
}
}

png_destroy_read_struct (&png_ptr, &png_info, 0);
fclose (F);

return image;
}


}

+ 35
- 0
source/native-plugins/zita-rev1/png2img.h View File

@@ -0,0 +1,35 @@
// ----------------------------------------------------------------------
//
// Copyright (C) 2007-2010 Fons Adriaensen <fons@linuxaudio.org>
// Modified by falkTX on Jan 2015 for inclusion in Carla
//
// 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
// (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, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// ----------------------------------------------------------------------


#ifndef __PNG2IMG_H
#define __PNG2IMG_H


#include <clxclient.h>

namespace REV1 {

extern XImage *png2img (const char *file, X_display *disp, XftColor *bgnd);

}

#endif

+ 380
- 0
source/native-plugins/zita-rev1/reverb.cc View File

@@ -0,0 +1,380 @@
// -----------------------------------------------------------------------
//
// Copyright (C) 2003-2010 Fons Adriaensen <fons@linuxaudio.org>
// Modified by falkTX on Jan 2015 for inclusion in Carla
//
// 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
// (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, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// -----------------------------------------------------------------------


#include <stdio.h>
#include <string.h>
#include <math.h>
#include "reverb.h"

namespace REV1 {


// -----------------------------------------------------------------------


Diff1::Diff1 (void) :
_size (0),
_line (0)
{
}


Diff1::~Diff1 (void)
{
fini ();
}


void Diff1::init (int size, float c)
{
_size = size;
_line = new float [size];
memset (_line, 0, size * sizeof (float));
_i = 0;
_c = c;
}


void Diff1::fini (void)
{
delete[] _line;
_size = 0;
_line = 0;
}


// -----------------------------------------------------------------------


Delay::Delay (void) :
_size (0),
_line (0)
{
}


Delay::~Delay (void)
{
fini ();
}


void Delay::init (int size)
{
_size = size;
_line = new float [size];
memset (_line, 0, size * sizeof (float));
_i = 0;
}


void Delay::fini (void)
{
delete[] _line;
_size = 0;
_line = 0;
}


// -----------------------------------------------------------------------


Vdelay::Vdelay (void) :
_size (0),
_line (0)
{
}


Vdelay::~Vdelay (void)
{
fini ();
}


void Vdelay::init (int size)
{
_size = size;
_line = new float [size];
memset (_line, 0, size * sizeof (float));
_ir = 0;
_iw = 0;
}


void Vdelay::fini (void)
{
delete[] _line;
_size = 0;
_line = 0;
}


void Vdelay::set_delay (int del)
{
_ir = _iw - del;
if (_ir < 0) _ir += _size;
}


// -----------------------------------------------------------------------


void Filt1::set_params (float del, float tmf, float tlo, float wlo, float thi, float chi)
{
float g, t;

_gmf = powf (0.001f, del / tmf);
_glo = powf (0.001f, del / tlo) / _gmf - 1.0f;
_wlo = wlo;
g = powf (0.001f, del / thi) / _gmf;
t = (1 - g * g) / (2 * g * g * chi);
_whi = (sqrtf (1 + 4 * t) - 1) / (2 * t);
}

// -----------------------------------------------------------------------


float Reverb::_tdiff1 [8] =
{
20346e-6f,
24421e-6f,
31604e-6f,
27333e-6f,
22904e-6f,
29291e-6f,
13458e-6f,
19123e-6f
};


float Reverb::_tdelay [8] =
{
153129e-6f,
210389e-6f,
127837e-6f,
256891e-6f,
174713e-6f,
192303e-6f,
125000e-6f,
219991e-6f
};


Reverb::Reverb (void)
{
}


Reverb::~Reverb (void)
{
fini ();
}


void Reverb::init (float fsamp, bool ambis)
{
int i, k1, k2;

_fsamp = fsamp;
_ambis = ambis;
_cntA1 = 1;
_cntA2 = 0;
_cntB1 = 1;
_cntB2 = 0;
_cntC1 = 1;
_cntC2 = 0;

_ipdel = 0.04f;
_xover = 200.0f;
_rtlow = 3.0f;
_rtmid = 2.0f;
_fdamp = 3e3f;
_opmix = 0.5f;
_rgxyz = 0.0f;

_g0 = _d0 = 0;
_g1 = _d1 = 0;

_vdelay0.init ((int)(0.1f * _fsamp));
_vdelay1.init ((int)(0.1f * _fsamp));
for (i = 0; i < 8; i++)
{
k1 = (int)(floorf (_tdiff1 [i] * _fsamp + 0.5f));
k2 = (int)(floorf (_tdelay [i] * _fsamp + 0.5f));
_diff1 [i].init (k1, (i & 1) ? -0.6f : 0.6f);
_delay [i].init (k2 - k1);
}

_pareq1.setfsamp (fsamp);
_pareq2.setfsamp (fsamp);
}


void Reverb::fini (void)
{
for (int i = 0; i < 8; i++) _delay [i].fini ();
}


void Reverb::prepare (int nfram)
{
int a, b, c, i, k;
float t0, t1, wlo, chi;

a = _cntA1;
b = _cntB1;
c = _cntC1;
_d0 = _d1 = 0;

if (a != _cntA2)
{
k = (int)(floorf ((_ipdel - 0.020f) * _fsamp + 0.5f));
_vdelay0.set_delay (k);
_vdelay1.set_delay (k);
_cntA2 = a;
}

if (b != _cntB2)
{
wlo = 6.2832f * _xover / _fsamp;
if (_fdamp > 0.49f * _fsamp) chi = 2;
else chi = 1 - cosf (6.2832f * _fdamp / _fsamp);
for (i = 0; i < 8; i++)
{
_filt1 [i].set_params (_tdelay [i], _rtmid, _rtlow, wlo, 0.5f * _rtmid, chi);
}
_cntB2 = b;
}

if (c != _cntC2)
{
if (_ambis)
{
t0 = 1.0f / sqrtf (_rtmid);
t1 = t0 * powf (10.0f, 0.05f * _rgxyz);
}
else
{
t0 = (1 - _opmix) * (1 + _opmix);
t1 = 0.7f * _opmix * (2 - _opmix) / sqrtf (_rtmid);
}
_d0 = (t0 - _g0) / nfram;
_d1 = (t1 - _g1) / nfram;
_cntC2 = c;
}

_pareq1.prepare (nfram);
_pareq2.prepare (nfram);
}


void Reverb::process (int nfram, float *inp [], float *out [])
{
int i, n;
float *p0, *p1;
float *q0, *q1, *q2, *q3;
float t, g, x0, x1, x2, x3, x4, x5, x6, x7;

g = sqrtf (0.125f);

p0 = inp [0];
p1 = inp [1];
q0 = out [0];
q1 = out [1];
q2 = out [2];
q3 = out [3];

for (i = 0; i < nfram; i++)
{
_vdelay0.write (p0 [i]);
_vdelay1.write (p1 [i]);

t = 0.3f * _vdelay0.read ();
x0 = _diff1 [0].process (_delay [0].read () + t);
x1 = _diff1 [1].process (_delay [1].read () + t);
x2 = _diff1 [2].process (_delay [2].read () - t);
x3 = _diff1 [3].process (_delay [3].read () - t);
t = 0.3f * _vdelay1.read ();
x4 = _diff1 [4].process (_delay [4].read () + t);
x5 = _diff1 [5].process (_delay [5].read () + t);
x6 = _diff1 [6].process (_delay [6].read () - t);
x7 = _diff1 [7].process (_delay [7].read () - t);

t = x0 - x1; x0 += x1; x1 = t;
t = x2 - x3; x2 += x3; x3 = t;
t = x4 - x5; x4 += x5; x5 = t;
t = x6 - x7; x6 += x7; x7 = t;
t = x0 - x2; x0 += x2; x2 = t;
t = x1 - x3; x1 += x3; x3 = t;
t = x4 - x6; x4 += x6; x6 = t;
t = x5 - x7; x5 += x7; x7 = t;
t = x0 - x4; x0 += x4; x4 = t;
t = x1 - x5; x1 += x5; x5 = t;
t = x2 - x6; x2 += x6; x6 = t;
t = x3 - x7; x3 += x7; x7 = t;

if (_ambis)
{
_g0 += _d0;
_g1 += _d1;
q0 [i] = _g0 * x0;
q1 [i] = _g1 * x1;
q2 [i] = _g1 * x4;
q3 [i] = _g1 * x2;
}
else
{
_g1 += _d1;
q0 [i] = _g1 * (x1 + x2);
q1 [i] = _g1 * (x1 - x2);
}

_delay [0].write (_filt1 [0].process (g * x0));
_delay [1].write (_filt1 [1].process (g * x1));
_delay [2].write (_filt1 [2].process (g * x2));
_delay [3].write (_filt1 [3].process (g * x3));
_delay [4].write (_filt1 [4].process (g * x4));
_delay [5].write (_filt1 [5].process (g * x5));
_delay [6].write (_filt1 [6].process (g * x6));
_delay [7].write (_filt1 [7].process (g * x7));
}

n = _ambis ? 4 : 2;
_pareq1.process (nfram, n, out);
_pareq2.process (nfram, n, out);
if (!_ambis)
{
for (i = 0; i < nfram; i++)
{
_g0 += _d0;
q0 [i] += _g0 * p0 [i];
q1 [i] += _g0 * p1 [i];
}
}
}


// -----------------------------------------------------------------------

}

+ 228
- 0
source/native-plugins/zita-rev1/reverb.h View File

@@ -0,0 +1,228 @@
// -----------------------------------------------------------------------
//
// Copyright (C) 2003-2011 Fons Adriaensen <fons@linuxaudio.org>
// Modified by falkTX on Jan 2015 for inclusion in Carla
//
// 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
// (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, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// -----------------------------------------------------------------------


#ifndef __REVERB_H
#define __REVERB_H

#include "pareq.h"

namespace REV1 {


// -----------------------------------------------------------------------


class Diff1
{
private:

friend class Reverb;
Diff1 (void);
~Diff1 (void);

void init (int size, float c);
void fini (void);

float process (float x)
{
float z = _line [_i];
x -= _c * z;
_line [_i] = x;
if (++_i == _size) _i = 0;
return z + _c * x;
}

int _i;
float _c;
int _size;
float *_line;
};


// -----------------------------------------------------------------------


class Filt1
{
private:

friend class Reverb;
Filt1 (void) : _slo (0), _shi (0) {}
~Filt1 (void) {}

void set_params (float del, float tmf, float tlo, float wlo, float thi, float chi);

float process (float x)
{
_slo += _wlo * (x - _slo) + 1e-10f;
x += _glo * _slo;
_shi += _whi * (x - _shi);
return _gmf * _shi;
}
float _gmf;
float _glo;
float _wlo;
float _whi;
float _slo;
float _shi;
};


// -----------------------------------------------------------------------


class Delay
{
private:

friend class Reverb;
Delay (void);
~Delay (void);

void init (int size);
void fini (void);

float read (void)
{
return _line [_i];
}

void write (float x)
{
_line [_i++] = x;
if (_i == _size) _i = 0;
}

int _i;
int _size;
float *_line;
};


// -----------------------------------------------------------------------


class Vdelay
{
private:

friend class Reverb;
Vdelay (void);
~Vdelay (void);

void init (int size);
void fini (void);
void set_delay (int del);

float read (void)
{
float x = _line [_ir++];
if (_ir == _size) _ir = 0;
return x;
}

void write (float x)
{
_line [_iw++] = x;
if (_iw == _size) _iw = 0;
}

int _ir;
int _iw;
int _size;
float *_line;
};


// -----------------------------------------------------------------------


class Reverb
{
public:

Reverb (void);
~Reverb (void);

void init (float fsamp, bool ambis);
void fini (void);

void prepare (int n);
void process (int n, float *inp [], float *out []);

void set_delay (float v) { _ipdel = v; _cntA1++; }
void set_xover (float v) { _xover = v; _cntB1++; }
void set_rtlow (float v) { _rtlow = v; _cntB1++; }
void set_rtmid (float v) { _rtmid = v; _cntB1++; _cntC1++; }
void set_fdamp (float v) { _fdamp = v; _cntB1++; }
void set_opmix (float v) { _opmix = v; _cntC1++; }
void set_rgxyz (float v) { _rgxyz = v; _cntC1++; }
void set_eq1 (float f, float g) { _pareq1.setparam (f, g); }
void set_eq2 (float f, float g) { _pareq2.setparam (f, g); }

private:


float _fsamp;
bool _ambis;

Vdelay _vdelay0;
Vdelay _vdelay1;
Diff1 _diff1 [8];
Filt1 _filt1 [8];
Delay _delay [8];
volatile int _cntA1;
volatile int _cntB1;
volatile int _cntC1;
int _cntA2;
int _cntB2;
int _cntC2;

float _ipdel;
float _xover;
float _rtlow;
float _rtmid;
float _fdamp;
float _opmix;
float _rgxyz;

float _g0, _d0;
float _g1, _d1;

Pareq _pareq1;
Pareq _pareq2;

static float _tdiff1 [8];
static float _tdelay [8];
};


// -----------------------------------------------------------------------

}

#endif

+ 207
- 0
source/native-plugins/zita-rev1/rotary.cc View File

@@ -0,0 +1,207 @@
// ----------------------------------------------------------------------
//
// Copyright (C) 2010 Fons Adriaensen <fons@linuxaudio.org>
// Modified by falkTX on Jan 2015 for inclusion in Carla
//
// 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
// (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, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// ----------------------------------------------------------------------


#include <cairo/cairo.h>
#include <cairo/cairo-xlib.h>
#include <math.h>
#include "rotary.h"

namespace REV1 {


cairo_t *RotaryCtl::_cairotype = 0;
cairo_surface_t *RotaryCtl::_cairosurf = 0;

int RotaryCtl::_wb_up = 4;
int RotaryCtl::_wb_dn = 5;
int RotaryCtl::_keymod = 0;
int RotaryCtl::_button = 0;
int RotaryCtl::_rcount = 0;
int RotaryCtl::_rx = 0;
int RotaryCtl::_ry = 0;


RotaryCtl::RotaryCtl (X_window *parent,
X_callback *cbobj,
RotaryImg *image,
int xp,
int yp,
int cbind) :

X_window (parent,
image->_x0 + xp, image->_y0 + yp,
image->_dx, image->_dy,
image->_backg->pixel),
_cbobj (cbobj),
_cbind (cbind),
_image (image),
_state (0),
_count (0),
_value (0),
_angle (0)
{
x_add_events ( ExposureMask
| Button1MotionMask | ButtonPressMask | ButtonReleaseMask);
}


RotaryCtl::~RotaryCtl (void)
{
}


void RotaryCtl::init (X_display *disp)
{
_cairosurf = cairo_xlib_surface_create (disp->dpy (), 0, disp->dvi (), 50, 50);
_cairotype = cairo_create (_cairosurf);
}


void RotaryCtl::fini (void)
{
cairo_destroy (_cairotype);
cairo_surface_destroy (_cairosurf);
}


void RotaryCtl::handle_event (XEvent *E)
{
switch (E->type)
{
case Expose:
render ();
break;
case ButtonPress:
bpress ((XButtonEvent *) E);
break;

case ButtonRelease:
brelse ((XButtonEvent *) E);
break;

case MotionNotify:
motion ((XMotionEvent *) E);
break;

default:
fprintf (stderr, "RotaryCtl: event %d\n", E->type );
}
}


void RotaryCtl::bpress (XButtonEvent *E)
{
int r = 0;
double d;

d = hypot (E->x - _image->_xref, E->y - _image->_yref);
if (d > _image->_rad + 3) return;
_keymod = E->state;
if (E->button < 4)
{
_rx = E->x;
_ry = E->y;
_button = E->button;
r = handle_button ();
_rcount = _count;
}
else if (_button) return;
else if ((int)E->button == _wb_up)
{
r = handle_mwheel (1);
}
else if ((int)E->button == _wb_dn)
{
r = handle_mwheel (-1);
}
if (r)
{
callback (r);
render ();
}
}


void RotaryCtl::brelse (XButtonEvent *E)
{
if (_button == (int)E->button)
{
_button = 0;
callback (RELSE);
}
}


void RotaryCtl::motion (XMotionEvent *E)
{
int dx, dy, r;

if (_button)
{
_keymod = E->state;
dx = E->x - _rx;
dy = E->y - _ry;
r = handle_motion (dx, dy);
if (r)
{
callback (r);
render ();
}
}
}


void RotaryCtl::set_state (int s)
{
_state = s;
render ();
}


void RotaryCtl::render (void)
{
XImage *I;
double a, c, r, x, y;

I = _image->_image [_state];
XPutImage (dpy (), win (), dgc (), I,
_image->_x0, _image->_y0, 0, 0, _image->_dx, _image->_dy);
cairo_xlib_surface_set_drawable (_cairosurf, win(),
_image->_dx, _image->_dy);
c = _image->_lncol [_state] ? 1.0 : 0.0;
a = _angle * M_PI / 180;
r = _image->_rad;
x = _image->_xref;
y = _image->_yref;
cairo_new_path (_cairotype);
cairo_move_to (_cairotype, x, y);
x += r * sin (a);
y -= r * cos (a);
cairo_line_to (_cairotype, x, y);
cairo_set_source_rgb (_cairotype, c, c, c);
cairo_set_line_width (_cairotype, 1.8);
cairo_stroke (_cairotype);
}


}

+ 119
- 0
source/native-plugins/zita-rev1/rotary.h View File

@@ -0,0 +1,119 @@
// ----------------------------------------------------------------------
//
// Copyright (C) 2010 Fons Adriaensen <fons@linuxaudio.org>
// Modified by falkTX on Jan 2015 for inclusion in Carla
//
// 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
// (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, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// ----------------------------------------------------------------------


#ifndef __ROTARY_H
#define __ROTARY_H


#include <cairo/cairo.h>
#include <cairo/cairo-xlib.h>
#include <clxclient.h>


namespace REV1 {


class RotaryImg
{
public:

XftColor *_backg;
XImage *_image [4];
char _lncol [4];
int _x0;
int _y0;
int _dx;
int _dy;
double _xref;
double _yref;
double _rad;
};



class RotaryCtl : public X_window
{
public:

RotaryCtl (X_window *parent,
X_callback *cbobj,
RotaryImg *image,
int xp, int yp,
int cbind = 0);

virtual ~RotaryCtl (void);

enum { NOP = 200, PRESS, RELSE, DELTA };

int cbind (void) { return _cbind; }
int state (void) { return _state; }
double value (void) { return _value; }

virtual void set_state (int s);
virtual void set_value (double v) = 0;
virtual void get_string (char *p, int n) {}

static void init (X_display *disp);
static void fini (void);

static int _wb_up;
static int _wb_dn;

protected:

X_callback *_cbobj;
int _cbind;
RotaryImg *_image;
int _state;
int _count;
int _range;
double _value;
double _angle;

void render (void);
void callback (int k) { _cbobj->handle_callb (k, this, 0); }

static int _keymod;
static int _button;
static int _rcount;
static int _rx;
static int _ry;

private:

void handle_event (XEvent *E);
void bpress (XButtonEvent *E);
void brelse (XButtonEvent *E);
void motion (XMotionEvent *E);

virtual int handle_button (void) = 0;
virtual int handle_motion (int dx, int dy) = 0;
virtual int handle_mwheel (int dw) = 0;

static cairo_t *_cairotype;
static cairo_surface_t *_cairosurf;
};


}

#endif

+ 177
- 0
source/native-plugins/zita-rev1/styles.cc View File

@@ -0,0 +1,177 @@
// ----------------------------------------------------------------------
//
// Copyright (C) 2010 Fons Adriaensen <fons@linuxaudio.org>
// Modified by falkTX on Jan 2015 for inclusion in Carla
//
// 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
// (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, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// ----------------------------------------------------------------------


#include "styles.h"
#include "png2img.h"

#include "CarlaString.hpp"

namespace REV1 {


XftColor *XftColors [NXFTCOLORS];

XImage *revsect_img;
XImage *eq1sect_img;
XImage *eq2sect_img;
XImage *mixsect_img;
XImage *ambsect_img;

RotaryImg r_delay_img;
RotaryImg r_xover_img;
RotaryImg r_rtlow_img;
RotaryImg r_rtmid_img;
RotaryImg r_fdamp_img;
RotaryImg r_parfr_img;
RotaryImg r_pargn_img;
RotaryImg r_opmix_img;
RotaryImg r_rgxyz_img;


int styles_init (X_display *disp, X_resman *xrm, const char *resdir)
{
XftColors [C_MAIN_BG] = disp->alloc_xftcolor (0.25f, 0.25f, 0.25f, 1.0f);
XftColors [C_MAIN_FG] = disp->alloc_xftcolor (1.0f, 1.0f, 1.0f, 1.0f);

const CarlaString SHARED = CarlaString(resdir)+"/rev1";
revsect_img = png2img (SHARED+"/revsect.png", disp, XftColors [C_MAIN_BG]);
eq1sect_img = png2img (SHARED+"/eq1sect.png", disp, XftColors [C_MAIN_BG]);
eq2sect_img = png2img (SHARED+"/eq2sect.png", disp, XftColors [C_MAIN_BG]);
mixsect_img = png2img (SHARED+"/mixsect.png", disp, XftColors [C_MAIN_BG]);
ambsect_img = png2img (SHARED+"/ambsect.png", disp, XftColors [C_MAIN_BG]);

if (!revsect_img || !mixsect_img || !ambsect_img
|| !eq1sect_img || !eq2sect_img)
{
fprintf (stderr, "Can't load images from '%s'.\n", SHARED.buffer());
return 1;
}

r_delay_img._backg = XftColors [C_MAIN_BG];
r_delay_img._image [0] = revsect_img;
r_delay_img._lncol [0] = 0;
r_delay_img._x0 = 30;
r_delay_img._y0 = 32;
r_delay_img._dx = 23;
r_delay_img._dy = 23;
r_delay_img._xref = 11.5;
r_delay_img._yref = 11.5;
r_delay_img._rad = 11;

r_xover_img._backg = XftColors [C_MAIN_BG];
r_xover_img._image [0] = revsect_img;
r_xover_img._lncol [0] = 0;
r_xover_img._x0 = 92;
r_xover_img._y0 = 17;
r_xover_img._dx = 23;
r_xover_img._dy = 23;
r_xover_img._xref = 11.5;
r_xover_img._yref = 11.5;
r_xover_img._rad = 11;

r_rtlow_img._backg = XftColors [C_MAIN_BG];
r_rtlow_img._image [0] = revsect_img;
r_rtlow_img._lncol [0] = 0;
r_rtlow_img._x0 = 147;
r_rtlow_img._y0 = 17;
r_rtlow_img._dx = 23;
r_rtlow_img._dy = 23;
r_rtlow_img._xref = 11.5;
r_rtlow_img._yref = 11.5;
r_rtlow_img._rad = 11;

r_rtmid_img._backg = XftColors [C_MAIN_BG];
r_rtmid_img._image [0] = revsect_img;
r_rtmid_img._lncol [0] = 0;
r_rtmid_img._x0 = 207;
r_rtmid_img._y0 = 17;
r_rtmid_img._dx = 23;
r_rtmid_img._dy = 23;
r_rtmid_img._xref = 11.5;
r_rtmid_img._yref = 11.5;
r_rtmid_img._rad = 11;

r_fdamp_img._backg = XftColors [C_MAIN_BG];
r_fdamp_img._image [0] = revsect_img;
r_fdamp_img._lncol [0] = 0;
r_fdamp_img._x0 = 267;
r_fdamp_img._y0 = 17;
r_fdamp_img._dx = 23;
r_fdamp_img._dy = 23;
r_fdamp_img._xref = 11.5;
r_fdamp_img._yref = 11.5;
r_fdamp_img._rad = 11;

r_parfr_img._backg = XftColors [C_MAIN_BG];
r_parfr_img._image [0] = eq1sect_img;
r_parfr_img._lncol [0] = 0;
r_parfr_img._x0 = 19;
r_parfr_img._y0 = 32;
r_parfr_img._dx = 23;
r_parfr_img._dy = 23;
r_parfr_img._xref = 11.5;
r_parfr_img._yref = 11.5;
r_parfr_img._rad = 11;

r_pargn_img._backg = XftColors [C_MAIN_BG];
r_pargn_img._image [0] = eq1sect_img;
r_pargn_img._lncol [0] = 1;
r_pargn_img._x0 = 68;
r_pargn_img._y0 = 17;
r_pargn_img._dx = 23;
r_pargn_img._dy = 23;
r_pargn_img._xref = 11.5;
r_pargn_img._yref = 11.5;
r_pargn_img._rad = 11;

r_opmix_img._backg = XftColors [C_MAIN_BG];
r_opmix_img._image [0] = mixsect_img;
r_opmix_img._lncol [0] = 0;
r_opmix_img._x0 = 23;
r_opmix_img._y0 = 32;
r_opmix_img._dx = 23;
r_opmix_img._dy = 23;
r_opmix_img._xref = 11.5;
r_opmix_img._yref = 11.5;
r_opmix_img._rad = 11;

r_rgxyz_img._backg = XftColors [C_MAIN_BG];
r_rgxyz_img._image [0] = ambsect_img;
r_rgxyz_img._lncol [0] = 0;
r_rgxyz_img._x0 = 23;
r_rgxyz_img._y0 = 32;
r_rgxyz_img._dx = 23;
r_rgxyz_img._dy = 23;
r_rgxyz_img._xref = 11.5;
r_rgxyz_img._yref = 11.5;
r_rgxyz_img._rad = 11;

return 0;
}


void styles_fini (X_display *disp)
{
}


}

+ 73
- 0
source/native-plugins/zita-rev1/styles.h View File

@@ -0,0 +1,73 @@
// ----------------------------------------------------------------------
//
// Copyright (C) 2010 Fons Adriaensen <fons@linuxaudio.org>
// Modified by falkTX on Jan 2015 for inclusion in Carla
//
// 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
// (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, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// ----------------------------------------------------------------------


#ifndef __STYLES_H
#define __STYLES_H

#include <clxclient.h>
#include "rotary.h"

namespace REV1 {


enum
{
C_MAIN_BG, C_MAIN_FG,
// C_TEXT_BG, C_TEXT_FG,
NXFTCOLORS
};

enum
{
// F_TEXT, F_FILE,
NXFTFONTS
};


extern int styles_init (X_display *disp, X_resman *xrm, const char *resdir);
extern void styles_fini (X_display *disp);

extern XftColor *XftColors [NXFTCOLORS];
//extern XftFont *XftFonts [NXFTFONTS];

extern X_textln_style tstyle1;

extern XImage *revsect_img;
extern XImage *eq1sect_img;
extern XImage *eq2sect_img;
extern XImage *mixsect_img;
extern XImage *ambsect_img;

extern RotaryImg r_delay_img;
extern RotaryImg r_xover_img;
extern RotaryImg r_rtlow_img;
extern RotaryImg r_rtmid_img;
extern RotaryImg r_fdamp_img;
extern RotaryImg r_parfr_img;
extern RotaryImg r_pargn_img;
extern RotaryImg r_opmix_img;
extern RotaryImg r_rgxyz_img;


}

#endif

+ 1
- 1
source/utils/CarlaExternalUI.hpp View File

@@ -40,7 +40,7 @@ public:
fUiState(UiNone),
leakDetector_CarlaExternalUI() {}

~CarlaExternalUI() noexcept override
~CarlaExternalUI() /*noexcept*/ override
{
CARLA_SAFE_ASSERT_INT(fUiState == UiNone, fUiState);
}


Loading…
Cancel
Save