Browse Source

allow multiple plugins in a channel / add semaphore for port operations

carla_vst
Alex 5 years ago
parent
commit
4f7bd6d20d
  1. 1
      .gitignore
  2. 4
      README.md
  3. 2
      inc/audio/engine.h
  4. 8
      inc/gui/widgets/channel.h
  5. 2
      inc/plugins/lv2_plugin.h
  6. 0
      inc/sem.h
  7. 76
      resources/ui/channel.ui
  8. 2
      resources/ui/main-window.ui
  9. 6
      src/audio/channel.c
  10. 10
      src/audio/engine.c
  11. 53
      src/gui/widgets/channel.c
  12. 5
      src/gui/widgets/mixer.c
  13. 2
      src/plugins/lv2/worker.h
  14. 5
      src/plugins/plugin.c

1
.gitignore vendored

@ -51,6 +51,7 @@ Session.vim @@ -51,6 +51,7 @@ Session.vim
# Temporary
.netrwhist
*~
*.ui#
# Auto-generated tag files
tags
# Persistent undo

4
README.md

@ -6,10 +6,10 @@ It is written in C and it uses the GTK+3 toolkit. @@ -6,10 +6,10 @@ It is written in C and it uses the GTK+3 toolkit.
## Currently supported protocols:
- LV2
Some code and ideas come from Ardour so big thanks to them.
Some code, ideas and help come from Ardour so big thanks to them.
## Why another DAW?
Hard to answer. Partly because of curiosity, partly because I want to work with GTK/C, partly because I wanted an easily customizable UI, and also because current Free, GNU/Linux DAWs don't offer usability features I got used to from proprietary programs like Bitwig/Cubase.
Partly because of curiosity, partly because I want to work with GTK/C, partly because I wanted an easily customizable UI, and also because current Free, GNU/Linux DAWs don't offer usability features I got used to from proprietary programs like Bitwig/Cubase.
## Contributing
For installation instructions see INSTALL

2
inc/audio/engine.h

@ -26,6 +26,7 @@ @@ -26,6 +26,7 @@
#define MIDI_BUF_SIZE 1024 // should be set by backend
#include "zrythm_app.h"
#include "sem.h"
#include <jack/jack.h>
#include <jack/midiport.h>
@ -59,6 +60,7 @@ typedef struct Audio_Engine @@ -59,6 +60,7 @@ typedef struct Audio_Engine
nframes_t nframes; ///< nframes for current cycle
//MIDI_Controller * midi_controller; ///< the midi input on JACK
//Port_Manager * port_manager; ///< manages all ports created for/by plugins
ZixSem port_operation_lock; ///< semaphore for blocking DSP while plugin and its ports are deleted
} Audio_Engine;
void

8
inc/gui/widgets/channel.h

@ -51,6 +51,7 @@ typedef struct ChannelWidget @@ -51,6 +51,7 @@ typedef struct ChannelWidget
KnobWidget * phase_knob;
GtkBox * slots_box;
GtkBox * slots[MAX_PLUGINS]; ///< array of slot boxes (1 per plugin)
//GtkWidget * slot_on_off_images[MAX_PLUGINS][2]; ///< 0 is off, 1 is on
GtkToggleButton * toggles[MAX_PLUGINS]; ///< toggle buttons (per slot)
GtkLabel * labels[MAX_PLUGINS]; ///< labels (per slot)
//int num_slots; ///< counter
@ -79,6 +80,13 @@ typedef struct ChannelWidgetClass @@ -79,6 +80,13 @@ typedef struct ChannelWidgetClass
GtkGridClass parent_class;
} ChannelWidgetClass;
/**
* Updates the slots.
*/
void
channel_update_slots (ChannelWidget * self);
/**
* Creates a channel widget using the given channel data.
*/

2
inc/plugins/lv2_plugin.h

@ -39,7 +39,7 @@ @@ -39,7 +39,7 @@
#include "plugins/lv2/symap.h"
#include "plugins/lv2/worker.h"
#include "plugins/lv2/zix/ring.h"
#include "plugins/lv2/zix/sem.h"
#include "sem.h"
#include "plugins/lv2/zix/thread.h"
#include <lilv/lilv.h>

0
src/plugins/lv2/zix/sem.h → inc/sem.h

76
resources/ui/channel.ui

@ -46,82 +46,10 @@ @@ -46,82 +46,10 @@
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkBox" id="slot1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkToggleButton" id="slot1b">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="halign">start</property>
<property name="valign">center</property>
<property name="relief">none</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="slot_name1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">Delay</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
<placeholder/>
</child>
<child>
<object class="GtkBox" id="slot2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkToggleButton" id="slot2b">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="halign">start</property>
<property name="valign">center</property>
<property name="relief">none</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="slot_name2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">Reverb</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
<placeholder/>
</child>
<child>
<object class="GtkButton" id="add_slot">

2
resources/ui/main-window.ui

@ -918,7 +918,7 @@ @@ -918,7 +918,7 @@
</object>
<packing>
<property name="resize">False</property>
<property name="shrink">False</property>
<property name="shrink">True</property>
</packing>
</child>
</object>

6
src/audio/channel.c

@ -347,6 +347,7 @@ channel_add_plugin (Channel * channel, ///< the channel @@ -347,6 +347,7 @@ channel_add_plugin (Channel * channel, ///< the channel
Plugin * plugin ///< the plugin to add
)
{
zix_sem_wait (&AUDIO_ENGINE->port_operation_lock);
/* free current plugin */
if (channel->strip[pos])
{
@ -416,9 +417,9 @@ channel_add_plugin (Channel * channel, ///< the channel @@ -416,9 +417,9 @@ channel_add_plugin (Channel * channel, ///< the channel
* ------------------------------------------------------*/
Plugin * next_plugin = NULL;
for (int i = 1; i < MAX_PLUGINS; i++)
for (int i = pos + 1; i < MAX_PLUGINS; i++)
{
next_plugin = channel->strip[pos + i];
next_plugin = channel->strip[i];
if (next_plugin)
break;
}
@ -467,6 +468,7 @@ channel_add_plugin (Channel * channel, ///< the channel @@ -467,6 +468,7 @@ channel_add_plugin (Channel * channel, ///< the channel
break;
}
}
zix_sem_post (&AUDIO_ENGINE->port_operation_lock);
}
/**

10
src/audio/engine.c

@ -113,10 +113,13 @@ jack_process_cb (nframes_t nframes, ///< the number of frames to fill @@ -113,10 +113,13 @@ jack_process_cb (nframes_t nframes, ///< the number of frames to fill
sample_t * stereo_out_l, * stereo_out_r;
int i = 0;
zix_sem_wait (&AUDIO_ENGINE->port_operation_lock);
/* reset all buffers */
for (i = 0; i < AUDIO_ENGINE->num_ports; i++)
{
port_clear_buffer (AUDIO_ENGINE->ports[i]);
if (AUDIO_ENGINE->ports[i])
port_clear_buffer (AUDIO_ENGINE->ports[i]);
}
/*g_message ("jack start");*/
@ -195,6 +198,8 @@ jack_process_cb (nframes_t nframes, ///< the number of frames to fill @@ -195,6 +198,8 @@ jack_process_cb (nframes_t nframes, ///< the number of frames to fill
stereo_out_r[i] = MIXER->master->stereo_out->r->buf[i];
}
zix_sem_post (&AUDIO_ENGINE->port_operation_lock);
/*g_message ("jack end");*/
/*
@ -338,6 +343,9 @@ init_audio_engine() @@ -338,6 +343,9 @@ init_audio_engine()
/* initialize mixer, which handles the processing */
mixer_init ();
/* init semaphore */
zix_sem_init (&AUDIO_ENGINE->port_operation_lock, 1);
/* Tell the JACK server that we are ready to roll. Our
* process() callback will start running now. */
if (jack_activate (engine->client))

53
src/gui/widgets/channel.c

@ -98,8 +98,9 @@ on_drag_data_received (GtkWidget *widget, @@ -98,8 +98,9 @@ on_drag_data_received (GtkWidget *widget,
plugin_instantiate (plugin);
/* TODO add to specific channel */
channel_add_plugin (channel, index, plugin);
channel_add_plugin (channel, index + 1, plugin);
channel_widget_add_plugin (CHANNEL_WIDGET (user_data), plugin, index);
channel_update_slots (CHANNEL_WIDGET (user_data));
}
static void
@ -127,10 +128,6 @@ channel_widget_class_init (ChannelWidgetClass * klass) @@ -127,10 +128,6 @@ channel_widget_class_init (ChannelWidgetClass * klass)
ChannelWidget, phase_controls);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (klass),
ChannelWidget, slots_box);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (klass),
ChannelWidget, slot1b);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (klass),
ChannelWidget, slot2b);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (klass),
ChannelWidget, add_slot);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (klass),
@ -215,8 +212,41 @@ setup_meter (ChannelWidget * self) @@ -215,8 +212,41 @@ setup_meter (ChannelWidget * self)
1, 1, 0);
}
/**
* Updates the slots.
*/
void
channel_update_slots (ChannelWidget * self)
{
for (int i = 0; i < MAX_PLUGINS; i++)
{
if (self->channel->strip[i])
{
gtk_label_set_text (self->labels[i],
self->channel->strip[i]->descr->name);
gtk_button_set_image (GTK_BUTTON (self->toggles[i]),
gtk_image_new_from_resource (
"/online/alextee/zrythm/slot-on.svg"));
}
else
{
gtk_label_set_text (self->labels[i],
"");
gtk_button_set_image (GTK_BUTTON (self->toggles[i]),
gtk_image_new_from_resource (
"/online/alextee/zrythm/slot-off.svg"));
}
}
}
/**
* Sets up the slots.
*
* First removes the add button, then creates each slot.
*/
static void
create_slots (ChannelWidget * self)
setup_slots (ChannelWidget * self)
{
gtk_container_remove (GTK_CONTAINER (self->slots_box),
GTK_WIDGET (self->add_slot));
@ -226,10 +256,10 @@ create_slots (ChannelWidget * self) @@ -226,10 +256,10 @@ create_slots (ChannelWidget * self)
self->toggles[i]= GTK_TOGGLE_BUTTON (gtk_toggle_button_new ());
self->labels[i]= GTK_LABEL (gtk_label_new (""));
/* set on/off icon */
GtkWidget * image = gtk_image_new_from_resource (
"/online/alextee/zrythm/slot-off.svg");
gtk_button_set_image (GTK_BUTTON (self->toggles[i]), image);
/* set on/off icons */
gtk_button_set_image (GTK_BUTTON (self->toggles[i]),
gtk_image_new_from_resource (
"/online/alextee/zrythm/slot-off.svg"));
gtk_box_pack_start (self->slots[i],
GTK_WIDGET (self->toggles[i]),
@ -257,6 +287,7 @@ channel_widget_new (Channel * channel) @@ -257,6 +287,7 @@ channel_widget_new (Channel * channel)
setup_color (self);
setup_phase_panel (self);
/*setup_pan (self);*/
setup_slots (self);
setup_fader (self);
setup_meter (self);
@ -306,6 +337,8 @@ channel_widget_new (Channel * channel) @@ -306,6 +337,8 @@ channel_widget_new (Channel * channel)
/* add dummy box for dnd */
self->dummy_slot_box = GTK_BOX (
gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0));
gtk_widget_set_size_request (GTK_WIDGET (self->dummy_slot_box),
-1, 20);
gtk_box_pack_start (self->slots_box,
GTK_WIDGET (self->dummy_slot_box),
1, 1, 0);

5
src/gui/widgets/mixer.c

@ -73,7 +73,10 @@ on_drag_data_received (GtkWidget *widget, @@ -73,7 +73,10 @@ on_drag_data_received (GtkWidget *widget,
GTK_WIDGET (MAIN_WINDOW->channels_add),
0, 0, 0);
/* readd dummy box for dnd */
/* update the slots on the channel to show correct names */
channel_update_slots (new_channel->widget);
/* re-add dummy box for dnd */
gtk_box_pack_start (MAIN_WINDOW->channels,
GTK_WIDGET (MAIN_WINDOW->dummy_mixer_box),
1, 1, 0);

2
src/plugins/lv2/worker.h

@ -18,7 +18,7 @@ @@ -18,7 +18,7 @@
#define __PLUGINS_LV2_WORKER_H__
#include "plugins/lv2/zix/ring.h"
#include "plugins/lv2/zix/sem.h"
#include "sem.h"
#include "plugins/lv2/zix/thread.h"
#include <lilv/lilv.h>

5
src/plugins/plugin.c

@ -359,7 +359,7 @@ clean_ports (Port ** array, int * size) @@ -359,7 +359,7 @@ clean_ports (Port ** array, int * size)
port_disconnect (port, port->dests[j]);
}
}
free (port);
port_delete (port);
}
(* size) = 0;
}
@ -372,6 +372,8 @@ clean_ports (Port ** array, int * size) @@ -372,6 +372,8 @@ clean_ports (Port ** array, int * size)
void
plugin_free (Plugin *plugin)
{
zix_sem_wait (&AUDIO_ENGINE->port_operation_lock);
/* disconnect all ports and free them */
clean_ports (plugin->in_ports, &plugin->num_in_ports);
clean_ports (plugin->out_ports, &plugin->num_out_ports);
@ -379,4 +381,5 @@ plugin_free (Plugin *plugin) @@ -379,4 +381,5 @@ plugin_free (Plugin *plugin)
/* TODO other cleanup work */
free (plugin);
zix_sem_post (&AUDIO_ENGINE->port_operation_lock);
}

Loading…
Cancel
Save