Service Documentation
-Copyright (C) 2004 Ushodaya Enterprises Limited
+Copyright (C) 2004-2005 Ushodaya Enterprises Limited
Authors: Charles Yates <charles.yates@pandora.be>
Dan Dennedy <dan@dennedy.org>
-Last Revision: 2004-11-07
+Last Revision: 2005-04-22
SERVICES
int in - in point
int out - out point
+ int begin - when using an image sequence, this sets the starting
+ number.
Mutable Properties
Jack, LADSPA, glib-2.0, libxml2
+ Known Bugs
+
+ Currently, due to timing and synchronisation issues, the audio
+ is distorted with repeated samples and latency clicks.
+ no encapsulated resampling and jack runs at a fixed frequency
+
+ ladspa
+
+ Description
+
+ Runs a JackRack project to process audio through a stack of
+ LADSPA filters without using Jack.
+
+ Constructor Argument
+
+ src - a JackRack file
+
+ Details
+
+ Due to audio integrity issues with the jackrack filter, this
+ filter is better for runtime, while jackrack is more suitable
+ for prototyping a rack file using the Jack Rack GUI.
+
+ Initialisation Properties
+
+ int in - in point
+ int out - out point
+
+ Read Only Properties
+
+ none
+
+ Mutable Properties
+
+ none
+
+ Dependencies
+
+ Jack, LADSPA, glib-2.0, libxml2
+ Jack is still required because this coexists with the jackrack
+ filter.
+
Known Bugs
no encapsulated resampling and jack runs at a fixed frequency
[ "$help" != "1" ] && rm -f disable-* producers.dat filters.dat transitions.dat consumers.dat
# Create the make.inc file
-echo SUBDIRS = `find . -type d -maxdepth 1 | grep -v CVS | grep -v "^.$" | sed 's/\.\///'` > make.inc
+echo SUBDIRS = `find . -maxdepth 1 -type d | grep -v CVS | grep -v "^.$" | sed 's/\.\///'` > make.inc
# Iterate through arguments
for i in "$@"
plugin_mgr.o \
plugin_settings.o \
process.o \
- ui.o \
- filter_jackrack.o
+ filter_jackrack.o \
+ filter_ladspa.o
CFLAGS += -I../.. `pkg-config --cflags jack`
CFLAGS += `xml2-config --cflags`
if [ "$disable_jack" == "0" -a "$disable_xml2" == "0" ]
then
echo "jackrack libmltjackrack$LIBSUF" >> ../filters.dat
+ echo "ladspa libmltjackrack$LIBSUF" >> ../filters.dat
else
[ "$disable_jack" == "1" ] && echo "- jackrack not found: disabling"
[ "$disable_xml2" == "1" ] && echo "- xml2 not found: disabling jackrack"
+++ /dev/null
-/*
- * JACK Rack
- *
- * Copyright (C) Robert Ham 2002, 2003 (node@users.sourceforge.net)
- *
- * 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 __JR_CONTROL_MESSAGE_H__
-#define __JR_CONTROL_MESSAGE_H__
-
-#include <glib.h>
-#include <ladspa.h>
-
-/** These are for messages between the gui and the process() callback */
-typedef enum _ctrlmsg_type
-{
- CTRLMSG_ADD,
- CTRLMSG_REMOVE,
- CTRLMSG_QUIT,
-
-} ctrlmsg_type_t;
-
-typedef struct _ctrlmsg ctrlmsg_t;
-
-struct _plugin;
-struct _plugin_desc;
-
-struct _ctrlmsg
-{
- ctrlmsg_type_t type;
- union
- {
- struct
- {
- struct _plugin * plugin;
- } add;
-
- struct
- {
- struct _plugin * plugin;
- } remove;
-
- } data;
-
-};
-
-#endif /* __JR_CONTROL_MESSAGE_H__ */
#include <string.h>
#include "filter_jackrack.h"
+#include "filter_ladspa.h"
void *mlt_create_producer( char *id, void *arg )
{
{
if ( !strcmp( id, "jackrack" ) )
return filter_jackrack_init( arg );
+ else if ( !strcmp( id, "ladspa" ) )
+ return filter_ladspa_init( arg );
return NULL;
}
#include <pthread.h>
#include <string.h>
-#include "ui.h"
+#include "jack_rack.h"
#define BUFFER_LEN 204800 * 3
-static void *jackrack_thread( void *arg )
-{
- mlt_properties properties = arg;
- ui_t *jackrack = mlt_properties_get_data( properties, "jackrack", NULL );
-
- while ( mlt_properties_get_int( properties, "_done" ) == 0 )
- if ( ui_loop_iterate( jackrack ) )
- break;
-
- ui_quit( jackrack );
- ui_destroy( jackrack );
-
- return NULL;
-}
-
static void initialise_jack_ports( mlt_properties properties )
{
int i;
// Start JackRack
if ( mlt_properties_get( properties, "src" ) )
{
- pthread_t *jackrack_pthread = mlt_pool_alloc( sizeof( pthread_t ) );
-
snprintf( rack_name, sizeof( rack_name ), "jackrack%d", getpid() );
- ui_t *jackrack = ui_new( rack_name, mlt_properties_get_int( properties, "channels" ), 0, 0 );
+ jack_rack_t *jackrack = jack_rack_new( rack_name, mlt_properties_get_int( properties, "channels" ) );
jack_rack_open_file( jackrack, mlt_properties_get( properties, "src" ) );
mlt_properties_set_data( properties, "jackrack", jackrack, 0, NULL, NULL );
mlt_properties_set( properties, "_rack_client_name", rack_name );
- mlt_properties_set_int( properties, "_done", 0 );
- mlt_properties_set_data( properties, "jackrack_pthread", jackrack_pthread, 0, NULL, NULL );
-
- pthread_create( jackrack_pthread, NULL, jackrack_thread, properties );
}
// Allocate buffers and ports
// Get the filter-specific properties
jack_ringbuffer_t **output_buffers = mlt_properties_get_data( filter_properties, "output_buffers", NULL );
jack_ringbuffer_t **input_buffers = mlt_properties_get_data( filter_properties, "input_buffers", NULL );
- pthread_mutex_t *output_lock = mlt_properties_get_data( filter_properties, "output_lock", NULL );
- pthread_cond_t *output_ready = mlt_properties_get_data( filter_properties, "output_ready", NULL );
+// pthread_mutex_t *output_lock = mlt_properties_get_data( filter_properties, "output_lock", NULL );
+// pthread_cond_t *output_ready = mlt_properties_get_data( filter_properties, "output_ready", NULL );
// Process the audio
int16_t *q = *buffer;
float sample[ 2 ][ 10000 ];
int i, j;
- struct timespec tm = { 0, 0 };
+// struct timespec tm = { 0, 0 };
// Convert to floats and write into output ringbuffer
if ( jack_ringbuffer_write_space( output_buffers[0] ) >= ( *samples * sizeof(float) ) )
}
-void filter_close( mlt_filter this )
+static void filter_close( mlt_filter this )
{
int i;
char mlt_name[20];
mlt_pool_release( mlt_properties_get_data( properties, "jack_input_buffers", NULL ) );
mlt_pool_release( mlt_properties_get_data( properties, "output_lock", NULL ) );
mlt_pool_release( mlt_properties_get_data( properties, "output_ready", NULL ) );
-
- pthread_t *jackrack_pthread = mlt_properties_get_data( properties, "jackrack_thread", NULL );
- if ( jackrack_pthread != NULL )
- {
- mlt_properties_set_int( properties, "_done", 1 );
- pthread_join( *jackrack_pthread, NULL );
- mlt_pool_release( jackrack_pthread );
- }
+
+ jack_rack_t *jackrack = mlt_properties_get_data( properties, "jackrack", NULL );
+ jack_rack_destroy( jackrack );
this->parent.close = NULL;
mlt_service_close( &this->parent );
--- /dev/null
+/*
+ * filter_ladspa.c -- filter audio through LADSPA plugins
+ * Copyright (C) 2004-2005 Ushodaya Enterprises Limited
+ * Author: Dan Dennedy <dan@dennedy.org>
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "filter_ladspa.h"
+
+#include <framework/mlt_frame.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <pthread.h>
+#include <string.h>
+
+#include "jack_rack.h"
+
+#define BUFFER_LEN 10000
+
+static void initialise_jack_rack( mlt_properties properties, int channels )
+{
+ int i;
+ char mlt_name[20];
+
+ // Propogate these for the Jack processing callback
+ mlt_properties_set_int( properties, "channels", channels );
+
+ // Start JackRack
+ if ( mlt_properties_get( properties, "src" ) )
+ {
+ // Create JackRack without Jack client name so that it only uses LADSPA
+ jack_rack_t *jackrack = jack_rack_new( NULL, channels );
+ mlt_properties_set_data( properties, "jackrack", jackrack, 0, NULL, NULL );
+ jack_rack_open_file( jackrack, mlt_properties_get( properties, "src" ) );
+ }
+
+ // Allocate buffers
+ LADSPA_Data **input_buffers = mlt_pool_alloc( sizeof( LADSPA_Data ) * channels );
+ LADSPA_Data **output_buffers = mlt_pool_alloc( sizeof( LADSPA_Data ) * channels );
+
+ // Set properties - released inside filter_close
+ mlt_properties_set_data( properties, "input_buffers", input_buffers, sizeof( LADSPA_Data *) * channels, NULL, NULL );
+ mlt_properties_set_data( properties, "output_buffers", output_buffers, sizeof( LADSPA_Data *) * channels, NULL, NULL );
+
+ // Register Jack ports
+ for ( i = 0; i < channels; i++ )
+ {
+ input_buffers[i] = mlt_pool_alloc( BUFFER_LEN * sizeof( LADSPA_Data ) );
+ snprintf( mlt_name, sizeof( mlt_name ), "ibuf%d", i );
+ mlt_properties_set_data( properties, mlt_name, input_buffers[i], BUFFER_LEN * sizeof( LADSPA_Data ), NULL, NULL );
+
+ output_buffers[i] = mlt_pool_alloc( BUFFER_LEN * sizeof( LADSPA_Data ) );
+ snprintf( mlt_name, sizeof( mlt_name ), "obuf%d", i );
+ mlt_properties_set_data( properties, mlt_name, output_buffers[i], BUFFER_LEN * sizeof( LADSPA_Data ), NULL, NULL );
+ }
+}
+
+
+/** Get the audio.
+*/
+
+static int ladspa_get_audio( mlt_frame frame, int16_t **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples )
+{
+ // Get the filter service
+ mlt_filter filter = mlt_frame_pop_audio( frame );
+
+ // Get the filter properties
+ mlt_properties filter_properties = MLT_FILTER_PROPERTIES( filter );
+
+ // Get the producer's audio
+ mlt_frame_get_audio( frame, buffer, format, frequency, channels, samples );
+
+ // Initialise LADSPA if needed
+ jack_rack_t *jackrack = mlt_properties_get_data( filter_properties, "jackrack", NULL );
+ if ( jackrack == NULL )
+ {
+ sample_rate = *frequency;
+ initialise_jack_rack( filter_properties, *channels );
+ jackrack = mlt_properties_get_data( filter_properties, "jackrack", NULL );
+ }
+
+ // Get the filter-specific properties
+ LADSPA_Data **input_buffers = mlt_properties_get_data( filter_properties, "input_buffers", NULL );
+ LADSPA_Data **output_buffers = mlt_properties_get_data( filter_properties, "output_buffers", NULL );
+
+ // Process the audio
+ int16_t *q = *buffer;
+ int i, j;
+
+ // Convert to floats and write into output ringbuffer
+ for ( i = 0; i < *samples; i++ )
+ for ( j = 0; j < *channels; j++ )
+ input_buffers[ j ][ i ] = ( float )( *q ++ ) / 32768.0;
+
+ // Do LADSPA processing
+ if ( jackrack && process_ladspa( jackrack->procinfo, *samples, input_buffers, output_buffers) == 0 )
+ {
+ // Read from output buffer and convert from floats
+ q = *buffer;
+ for ( i = 0; i < *samples; i++ )
+ for ( j = 0; j < *channels; j++ )
+ {
+ if ( output_buffers[ j ][ i ] > 1.0 )
+ output_buffers[ j ][ i ] = 1.0;
+ else if ( output_buffers[ j ][ i ] < -1.0 )
+ output_buffers[ j ][ i ] = -1.0;
+
+ if ( output_buffers[ j ][ i ] > 0 )
+ *q ++ = 32767 * output_buffers[ j ][ i ];
+ else
+ *q ++ = 32768 * output_buffers[ j ][ i ];
+ }
+ }
+
+ return 0;
+}
+
+
+/** Filter processing.
+*/
+
+static mlt_frame filter_process( mlt_filter this, mlt_frame frame )
+{
+ {
+ mlt_frame_push_audio( frame, this );
+ mlt_frame_push_audio( frame, ladspa_get_audio );
+ }
+
+ return frame;
+}
+
+
+static void filter_close( mlt_filter this )
+{
+ int i;
+ char mlt_name[20];
+ mlt_properties properties = MLT_FILTER_PROPERTIES( this );
+
+ for ( i = 0; i < mlt_properties_get_int( properties, "channels" ); i++ )
+ {
+ snprintf( mlt_name, sizeof( mlt_name ), "obuf%d", i );
+ mlt_pool_release( mlt_properties_get_data( properties, mlt_name, NULL ) );
+ snprintf( mlt_name, sizeof( mlt_name ), "ibuf%d", i );
+ mlt_pool_release( mlt_properties_get_data( properties, mlt_name, NULL ) );
+ }
+ mlt_pool_release( mlt_properties_get_data( properties, "output_buffers", NULL ) );
+ mlt_pool_release( mlt_properties_get_data( properties, "input_buffers", NULL ) );
+
+ jack_rack_t *jackrack = mlt_properties_get_data( properties, "jackrack", NULL );
+ jack_rack_destroy( jackrack );
+
+ this->parent.close = NULL;
+ mlt_service_close( &this->parent );
+}
+
+/** Constructor for the filter.
+*/
+
+mlt_filter filter_ladspa_init( char *arg )
+{
+ mlt_filter this = mlt_filter_new( );
+ if ( this != NULL )
+ {
+ mlt_properties properties = MLT_FILTER_PROPERTIES( this );
+
+ this->process = filter_process;
+ this->close = filter_close;
+
+ mlt_properties_set( properties, "src", arg );
+ }
+ return this;
+}
--- /dev/null
+/*
+ * filter_ladspa.h -- filter audio through LADSPA plugins
+ * Copyright (C) 2004-2005 Ushodaya Enterprises Limited
+ * Author: Dan Dennedy <dan@dennedy.org>
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _FILTER_LADSPA_H_
+#define _FILTER_LADSPA_H_
+
+#include <framework/mlt_filter.h>
+
+extern mlt_filter filter_ladspa_init( char *arg );
+
+#endif
#include "jack_rack.h"
#include "lock_free_fifo.h"
-#include "control_message.h"
-#include "ui.h"
#include "plugin_settings.h"
#ifndef _
#endif
jack_rack_t *
-jack_rack_new (ui_t * ui, unsigned long channels)
+jack_rack_new (const char * client_name, unsigned long channels)
{
jack_rack_t *rack;
rack = g_malloc (sizeof (jack_rack_t));
rack->saved_plugins = NULL;
- rack->ui = ui;
rack->channels = channels;
+ rack->procinfo = process_info_new (client_name, channels, FALSE, FALSE);
+ if (!rack->procinfo) {
+ g_free (rack);
+ return NULL;
+ }
+ rack->plugin_mgr = plugin_mgr_new ();
+ plugin_mgr_set_plugins (rack->plugin_mgr, channels);
return rack;
}
void
jack_rack_destroy (jack_rack_t * jack_rack)
{
+ process_quit (jack_rack->procinfo);
+ plugin_mgr_destroy (jack_rack->plugin_mgr);
+ process_info_destroy (jack_rack->procinfo);
+ g_slist_free (jack_rack->saved_plugins);
g_free (jack_rack);
}
return plugin;
}
-void
-jack_rack_send_add_plugin (jack_rack_t * jack_rack, plugin_desc_t * desc)
-{
- plugin_t * plugin;
- ctrlmsg_t ctrlmsg;
-
- plugin = jack_rack_instantiate_plugin (jack_rack, desc);
-
- if (!plugin)
- return;
-
- /* send the chain link off to the process() callback */
- ctrlmsg.type = CTRLMSG_ADD;
- ctrlmsg.data.add.plugin = plugin;
- lff_write (jack_rack->ui->ui_to_process, &ctrlmsg);
-}
void
jack_rack_add_saved_plugin (jack_rack_t * jack_rack, saved_plugin_t * saved_plugin)
{
+ plugin_t * plugin = jack_rack_instantiate_plugin (jack_rack, saved_plugin->settings->desc);
+ if (!plugin)
+ return;
jack_rack->saved_plugins = g_slist_append (jack_rack->saved_plugins, saved_plugin);
-
- jack_rack_send_add_plugin (jack_rack, saved_plugin->settings->desc);
+ process_add_plugin (jack_rack->procinfo, plugin);
+ jack_rack_add_plugin (jack_rack, plugin);
}
static void
-saved_rack_parse_plugin (saved_rack_t * saved_rack, saved_plugin_t * saved_plugin,
- ui_t * ui, const char * filename, xmlNodePtr plugin)
+saved_rack_parse_plugin (jack_rack_t * jack_rack, saved_rack_t * saved_rack, saved_plugin_t * saved_plugin,
+ const char * filename, xmlNodePtr plugin)
{
plugin_desc_t * desc;
settings_t * settings = NULL;
num = strtoul (content, NULL, 10);
xmlFree (content);
- desc = plugin_mgr_get_any_desc (ui->plugin_mgr, num);
+ desc = plugin_mgr_get_any_desc (jack_rack->plugin_mgr, num);
if (!desc)
{
fprintf (stderr, _("The file '%s' contains an unknown plugin with ID '%ld'; skipping\n"), filename, num);
}
static void
-saved_rack_parse_jackrack (saved_rack_t * saved_rack, ui_t * ui, const char * filename, xmlNodePtr jackrack)
+saved_rack_parse_jackrack (jack_rack_t * jack_rack, saved_rack_t * saved_rack, const char * filename, xmlNodePtr jackrack)
{
xmlNodePtr node;
xmlChar *content;
{
saved_plugin = g_malloc0 (sizeof (saved_plugin_t));
saved_rack->plugins = g_slist_append (saved_rack->plugins, saved_plugin);
- saved_rack_parse_plugin (saved_rack, saved_plugin, ui, filename, node);
+ saved_rack_parse_plugin (jack_rack, saved_rack, saved_plugin, filename, node);
}
}
}
static saved_rack_t *
-saved_rack_new (ui_t * ui, const char * filename, xmlDocPtr doc)
+saved_rack_new (jack_rack_t * jack_rack, const char * filename, xmlDocPtr doc)
{
xmlNodePtr node;
saved_rack_t *saved_rack;
for (node = doc->children; node; node = node->next)
{
if (strcmp (node->name, "jackrack") == 0)
- saved_rack_parse_jackrack (saved_rack, ui, filename, node);
+ saved_rack_parse_jackrack (jack_rack, saved_rack, filename, node);
}
return saved_rack;
static void
saved_rack_destroy (saved_rack_t * saved_rack)
{
-/* GSList * list;*/
-
-/* for (list = saved_rack->settings; list; list = g_slist_next (list))
- settings_destroy ((settings_t *) list->data); */
-/* g_slist_free (saved_rack->settings); */
+ GSList * list;
+ for (list = saved_rack->plugins; list; list = g_slist_next (list))
+ settings_destroy (((saved_plugin_t *) list->data)->settings);
+ g_slist_free (saved_rack->plugins);
g_free (saved_rack);
}
int
-jack_rack_open_file (ui_t * ui, const char * filename)
+jack_rack_open_file (jack_rack_t * jack_rack, const char * filename)
{
xmlDocPtr doc;
saved_rack_t * saved_rack;
return 1;
}
- saved_rack = saved_rack_new (ui, filename, doc);
+ saved_rack = saved_rack_new (jack_rack, filename, doc);
xmlFreeDoc (doc);
if (!saved_rack)
settings_set_sample_rate (saved_plugin->settings, sample_rate);
- jack_rack_add_saved_plugin (ui->jack_rack, saved_plugin);
+ jack_rack_add_saved_plugin (jack_rack, saved_plugin);
}
- g_slist_free (saved_rack->plugins);
- g_free (saved_rack);
+ saved_rack_destroy (saved_rack);
return 0;
}
#include "plugin.h"
#include "plugin_mgr.h"
#include "plugin_settings.h"
-#include "ui.h"
+#include "process.h"
typedef struct _saved_plugin saved_plugin_t;
struct _jack_rack
{
- struct _ui * ui;
-
+ plugin_mgr_t * plugin_mgr;
+ process_info_t * procinfo;
unsigned long channels;
-
GSList * saved_plugins;
};
-jack_rack_t * jack_rack_new (struct _ui * ui, unsigned long channels);
+jack_rack_t * jack_rack_new (const char * client_name, unsigned long channels);
void jack_rack_destroy (jack_rack_t * jack_rack);
-int jack_rack_open_file (struct _ui * ui, const char * filename);
-void jack_rack_send_add_plugin (jack_rack_t * jack_rack, plugin_desc_t * plugin);
+int jack_rack_open_file (jack_rack_t * jack_rack, const char * filename);
void jack_rack_add_plugin (jack_rack_t * jack_rack, plugin_t * plugin);
void jack_rack_add_saved_plugin (jack_rack_t * jack_rack, struct _saved_plugin * saved_plugin);
#include "plugin.h"
#include "jack_rack.h"
#include "process.h"
-#include "ui.h"
#define CONTROL_FIFO_SIZE 128
procinfo->chain_end = plugin->prev;
/* sort out the aux ports */
- if (plugin->desc->aux_channels > 0)
+ if (procinfo->jack_client && plugin->desc->aux_channels > 0)
{
plugin_t * other;
procinfo->chain_end = plugin;
}
- if (plugin->desc->aux_channels > 0)
+ if (procinfo->jack_client && plugin->desc->aux_channels > 0)
{
plugin_t * other;
other = up ? plugin->next : plugin->prev;
procinfo->chain_end = new_plugin;
/* sort out the aux ports */
- if (plugin->desc->aux_channels > 0)
+ if (procinfo->jack_client && plugin->desc->aux_channels > 0)
{
plugin_t * other;
aux_channel);
holder->aux_ports[i] =
- jack_port_register (jack_rack->ui->procinfo->jack_client,
+ jack_port_register (jack_rack->procinfo->jack_client,
port_name,
JACK_DEFAULT_AUDIO_TYPE,
desc->aux_are_input ? JackPortIsInput : JackPortIsOutput,
plugin->descriptor-> connect_port (instance, i, &unused_control_port_output);
}
- if (plugin->desc->aux_channels > 0)
+ if (jack_rack->procinfo->jack_client && plugin->desc->aux_channels > 0)
plugin_create_aux_ports (plugin, copy, jack_rack);
if (plugin->descriptor->activate)
plugin->next = NULL;
plugin->prev = NULL;
plugin->wet_dry_enabled = FALSE;
+ plugin->jack_rack = jack_rack;
/* create audio memory and wet/dry stuff */
plugin->audio_output_memory = g_malloc (sizeof (LADSPA_Data *) * jack_rack->channels);
void
-plugin_destroy (plugin_t * plugin, ui_t *ui)
+plugin_destroy (plugin_t * plugin)
{
unsigned long i, j;
int err;
}
/* aux ports */
- if (plugin->desc->aux_channels > 0)
+ if (plugin->jack_rack->procinfo->jack_client && plugin->desc->aux_channels > 0)
{
for (j = 0; j < plugin->desc->aux_channels; j++)
{
- err = jack_port_unregister (ui->procinfo->jack_client,
+ err = jack_port_unregister (plugin->jack_rack->procinfo->jack_client,
plugin->holders[i].aux_ports[j]);
if (err)
g_free (plugin->holders);
- for (i = 0; i < ui->jack_rack->channels; i++)
+ for (i = 0; i < plugin->jack_rack->channels; i++)
{
g_free (plugin->audio_output_memory[i]);
lff_free (plugin->wet_dry_fifos + i);
const LADSPA_Descriptor * descriptor;
void * dl_handle;
+ struct _jack_rack * jack_rack;
};
struct _ui;
plugin_t * plugin_new (plugin_desc_t * plugin_desc, struct _jack_rack * jack_rack);
-void plugin_destroy (plugin_t * plugin, struct _ui *ui);
+void plugin_destroy (plugin_t * plugin);
void plugin_connect_input_ports (plugin_t * plugin, LADSPA_Data ** inputs);
void plugin_connect_output_ports (plugin_t * plugin);
{
(*current_port_count)++;
- if (*current_port_count == 1)
+ if (*current_port_count == 0)
*indicies = g_malloc (sizeof (unsigned long) * *current_port_count);
else
*indicies = g_realloc (*indicies, sizeof (unsigned long) * *current_port_count);
continue;
pd->control_port_count++;
- if (pd->control_port_count == 1)
+ if (pd->control_port_count == 0)
pd->control_port_indicies = g_malloc (sizeof (unsigned long) * pd->control_port_count);
else
pd->control_port_indicies = g_realloc (pd->control_port_indicies,
unsigned long ** port_indicies;
unsigned long port_count;
unsigned long i, j;
-
+
if (icount > ocount)
{
pd->channels = ocount;
#include "plugin_mgr.h"
#include "plugin_desc.h"
-#include "ui.h"
static gboolean
}
static void
-plugin_mgr_get_object_file_plugins (ui_t * ui, plugin_mgr_t * plugin_mgr, const char * filename)
+plugin_mgr_get_object_file_plugins (plugin_mgr_t * plugin_mgr, const char * filename)
{
const char * dlerr;
void * dl_handle;
}
static void
-plugin_mgr_get_dir_plugins (ui_t * ui, plugin_mgr_t * plugin_mgr, const char * dir)
+plugin_mgr_get_dir_plugins (plugin_mgr_t * plugin_mgr, const char * dir)
{
DIR * dir_stream;
struct dirent * dir_entry;
strcpy (file_name + dirlen + 1, dir_entry->d_name);
}
- plugin_mgr_get_object_file_plugins (ui, plugin_mgr, file_name);
+ plugin_mgr_get_object_file_plugins (plugin_mgr, file_name);
g_free (file_name);
}
}
static void
-plugin_mgr_get_path_plugins (ui_t * ui, plugin_mgr_t * plugin_mgr)
+plugin_mgr_get_path_plugins (plugin_mgr_t * plugin_mgr)
{
char * ladspa_path, * dir;
dir = strtok (ladspa_path, ":");
do
- plugin_mgr_get_dir_plugins (ui, plugin_mgr, dir);
+ plugin_mgr_get_dir_plugins (plugin_mgr, dir);
while ((dir = strtok (NULL, ":")));
g_free (ladspa_path);
}
plugin_mgr_t *
-plugin_mgr_new (ui_t * ui)
+plugin_mgr_new ()
{
plugin_mgr_t * pm;
pm->plugins = NULL;
pm->plugin_count = 0;
- plugin_mgr_get_path_plugins (ui, pm);
+ plugin_mgr_get_path_plugins (pm);
if (!pm->all_plugins)
{
struct _ui;
-plugin_mgr_t * plugin_mgr_new (struct _ui * ui);
+plugin_mgr_t * plugin_mgr_new ();
void plugin_mgr_destroy (plugin_mgr_t * plugin_mgr);
void plugin_mgr_set_plugins (plugin_mgr_t * plugin_mgr, unsigned long rack_channels);
#include <ctype.h>
#include "process.h"
-#include "control_message.h"
#include "lock_free_fifo.h"
#include "plugin.h"
#include "jack_rack.h"
-#include "ui.h"
#ifndef _
#define _(x) x
#define USEC_PER_SEC 1000000
#define MSEC_PER_SEC 1000
#define TIME_RUN_SKIP_COUNT 5
+#define MAX_BUFFER_SIZE 4096
jack_nframes_t sample_rate;
jack_nframes_t buffer_size;
-static char * jack_client_name;
-
-int process_control_messages (process_info_t * procinfo) {
- static int quitting = 0;
- ctrlmsg_t ctrlmsg;
- int err = 0;
-
- if (quitting) return quitting;
+static void
+jack_shutdown_cb (void * data)
+{
+ process_info_t * procinfo = data;
- while (lff_read (procinfo->ui_to_process, &ctrlmsg) == 0)
- {
- switch (ctrlmsg.type)
- {
-
- /* add a link to the end of the plugin chain */
- case CTRLMSG_ADD:
- process_add_plugin (procinfo, ctrlmsg.data.add.plugin);
- err = lff_write (procinfo->process_to_ui, &ctrlmsg);
- break;
-
- /* remove a link (plugin will be sent back) */
- case CTRLMSG_REMOVE:
- ctrlmsg.data.remove.plugin =
- process_remove_plugin (procinfo, ctrlmsg.data.remove.plugin);
- err = lff_write (procinfo->process_to_ui, &ctrlmsg);
- break;
-
- case CTRLMSG_QUIT:
- quitting = 1;
- err = lff_write (procinfo->process_to_ui, &ctrlmsg);
- return 1;
- }
-
- if (err)
- {
- fprintf (stderr, "%s: gui fifo is out of space\n", __FUNCTION__);
- return err;
- }
-
- }
-
- return 0;
+ procinfo->quit = TRUE;
}
/** process messages for plugins' control ports */
plugin = first_enabled;
do
{
- if (plugin->desc->aux_channels > 0)
+ if (plugin->desc->aux_channels > 0 && plugin->enabled)
{
- if (plugin->enabled)
- for (copy = 0; copy < plugin->copies; copy++)
- for (channel = 0; channel < plugin->desc->aux_channels; channel++)
- plugin->descriptor->
- connect_port (plugin->holders[copy].instance,
- plugin->desc->audio_aux_port_indicies[channel],
- jack_port_get_buffer (plugin->holders[copy].aux_ports[channel], frames));
+ if (procinfo->jack_client)
+ {
+ for (copy = 0; copy < plugin->copies; copy++)
+ for (channel = 0; channel < plugin->desc->aux_channels; channel++)
+ plugin->descriptor->
+ connect_port (plugin->holders[copy].instance,
+ plugin->desc->audio_aux_port_indicies[channel],
+ jack_port_get_buffer (plugin->holders[copy].aux_ports[channel], frames));
+ }
+ else
+ {
+ for (copy = 0; copy < frames; copy++)
+ procinfo->silent_buffer[copy] = 0.0;
+
+ for (copy = 0; copy < plugin->copies; copy++)
+ for (channel = 0; channel < plugin->desc->aux_channels; channel++)
+ plugin->descriptor->
+ connect_port (plugin->holders[copy].instance,
+ plugin->desc->audio_aux_port_indicies[channel],
+ procinfo->silent_buffer);
+ }
}
-
}
while ( (plugin != last_enabled) && (plugin = plugin->next) );
if (first_enabled != last_enabled)
{
plugin_connect_input_ports (last_enabled, last_enabled->prev->audio_output_memory);
-
- for (plugin = first_enabled->next;
- plugin;
- plugin = plugin->next)
+ for (plugin = first_enabled->next; plugin; plugin = plugin->next)
{
if (plugin->enabled)
{
void
process_chain (process_info_t * procinfo, jack_nframes_t frames)
{
- LADSPA_Data zero_signal[frames];
plugin_t * first_enabled;
plugin_t * last_enabled = NULL;
plugin_t * plugin;
unsigned long channel;
unsigned long i;
- guint copy;
- /* set the zero signal to zero */
- for (channel = 0; channel < frames; channel++)
- zero_signal[channel] = 0.0;
+ if (procinfo->jack_client)
+ {
+ LADSPA_Data zero_signal[frames];
+ guint copy;
+
+ /* set the zero signal to zero */
+ for (channel = 0; channel < frames; channel++)
+ zero_signal[channel] = 0.0;
- /* possibly set aux output channels to zero if they're not enabled */
- for (plugin = procinfo->chain; plugin; plugin = plugin->next)
- if (!plugin->enabled &&
- plugin->desc->aux_channels > 0 &&
- !plugin->desc->aux_are_input)
- for (copy = 0; copy < plugin->copies; copy++)
- for (channel = 0; channel < plugin->desc->aux_channels; channel++)
- memcpy (jack_port_get_buffer (plugin->holders[copy].aux_ports[channel], frames),
- zero_signal, sizeof (LADSPA_Data) * frames);
+ /* possibly set aux output channels to zero if they're not enabled */
+ for (plugin = procinfo->chain; plugin; plugin = plugin->next)
+ if (!plugin->enabled &&
+ plugin->desc->aux_channels > 0 &&
+ !plugin->desc->aux_are_input)
+ for (copy = 0; copy < plugin->copies; copy++)
+ for (channel = 0; channel < plugin->desc->aux_channels; channel++)
+ memcpy (jack_port_get_buffer (plugin->holders[copy].aux_ports[channel], frames),
+ zero_signal, sizeof (LADSPA_Data) * frames);
+ }
first_enabled = get_first_enabled_plugin (procinfo);
}
-int process (jack_nframes_t frames, void * data) {
- int err, quitting;
+int process_ladspa (process_info_t * procinfo, jack_nframes_t frames,
+ LADSPA_Data ** inputs, LADSPA_Data ** outputs) {
+ unsigned long channel;
+
+ if (!procinfo)
+ {
+ fprintf (stderr, "%s: no process_info from jack!\n", __FUNCTION__);
+ return 1;
+ }
+
+ if (procinfo->quit == TRUE)
+ return 1;
+
+ process_control_port_messages (procinfo);
+
+ for (channel = 0; channel < procinfo->channels; channel++)
+ {
+ procinfo->jack_input_buffers[channel] = inputs[channel];
+ if (!procinfo->jack_input_buffers[channel])
+ {
+ fprintf (stderr, "%s: no jack buffer for input port %ld\n", __FUNCTION__, channel);
+ return 1;
+ }
+
+ procinfo->jack_output_buffers[channel] = outputs[channel];
+ if (!procinfo->jack_output_buffers[channel])
+ {
+ fprintf (stderr, "%s: no jack buffer for output port %ld\n", __FUNCTION__, channel);
+ return 1;
+ }
+ }
+
+ connect_chain (procinfo, frames);
+
+ process_chain (procinfo, frames);
+
+ return 0;
+}
+
+int process_jack (jack_nframes_t frames, void * data) {
+ int err;
process_info_t * procinfo;
procinfo = (process_info_t *) data;
if (procinfo->port_count == 0)
return 0;
- quitting = process_control_messages (procinfo);
-
- if (quitting)
+ if (procinfo->quit == TRUE)
return 1;
process_control_port_messages (procinfo);
*******************************************/
static int
-process_info_connect_jack (process_info_t * procinfo, ui_t * ui)
+process_info_connect_jack (process_info_t * procinfo)
{
- printf (_("Connecting to JACK server with client name '%s'\n"), jack_client_name);
+ printf (_("Connecting to JACK server with client name '%s'\n"), procinfo->jack_client_name);
- procinfo->jack_client = jack_client_new (jack_client_name);
+ procinfo->jack_client = jack_client_new (procinfo->jack_client_name);
if (!procinfo->jack_client)
{
printf (_("Connected to JACK server\n"));
- jack_set_process_callback (procinfo->jack_client, process, procinfo);
- jack_on_shutdown (procinfo->jack_client, jack_shutdown_cb, ui);
+ jack_set_process_callback (procinfo->jack_client, process_jack, procinfo);
+ jack_on_shutdown (procinfo->jack_client, jack_shutdown_cb, procinfo);
return 0;
}
static void
process_info_connect_port (process_info_t * procinfo,
- ui_t * ui,
gshort in,
unsigned long port_index,
const char * port_name)
if (jack_port_index != port_index)
continue;
- full_port_name = g_strdup_printf ("%s:%s", jack_client_name, port_name);
+ full_port_name = g_strdup_printf ("%s:%s", procinfo->jack_client_name, port_name);
printf (_("Connecting ports '%s' and '%s'\n"), full_port_name, jack_ports[jack_port_index]);
}
int
-process_info_set_port_count (process_info_t * procinfo, ui_t * ui,
+process_info_set_port_count (process_info_t * procinfo,
unsigned long port_count, gboolean connect_inputs, gboolean connect_outputs)
{
unsigned long i;
gshort in;
if (procinfo->port_count >= port_count)
- return;
+ return -1;
if (procinfo->port_count == 0)
{
//printf (_("Created %s port %s\n"), in ? "input" : "output", port_name);
if ((in && connect_inputs) || (!in && connect_outputs))
- process_info_connect_port (procinfo, ui, in, i, port_name);
+ process_info_connect_port (procinfo, in, i, port_name);
g_free (port_name);
}
}
void
-process_info_set_channels (process_info_t * procinfo, ui_t * ui,
+process_info_set_channels (process_info_t * procinfo,
unsigned long channels, gboolean connect_inputs, gboolean connect_outputs)
{
- process_info_set_port_count (procinfo, ui, channels, connect_inputs, connect_outputs);
+ process_info_set_port_count (procinfo, channels, connect_inputs, connect_outputs);
procinfo->channels = channels;
}
process_info_t *
-process_info_new (ui_t * ui, const char * client_name, unsigned long rack_channels,
+process_info_new (const char * client_name, unsigned long rack_channels,
gboolean connect_inputs, gboolean connect_outputs)
{
process_info_t * procinfo;
+ char * jack_client_name;
int err;
procinfo = g_malloc (sizeof (process_info_t));
procinfo->jack_input_ports = NULL;
procinfo->jack_output_ports = NULL;
procinfo->channels = rack_channels;
+ procinfo->quit = FALSE;
+ if ( client_name == NULL )
+ {
+ sample_rate = 48000; // should be set externally before calling process_ladspa
+ buffer_size = MAX_BUFFER_SIZE;
+ procinfo->silent_buffer = g_malloc (sizeof (LADSPA_Data) * buffer_size );
+ procinfo->jack_input_buffers = g_malloc (sizeof (LADSPA_Data *) * rack_channels);
+ procinfo->jack_output_buffers = g_malloc (sizeof (LADSPA_Data *) * rack_channels);
+
+ return procinfo;
+ }
+
/* sort out the client name */
- jack_client_name = strdup (client_name);
+ procinfo->jack_client_name = jack_client_name = strdup (client_name);
for (err = 0; jack_client_name[err] != '\0'; err++)
{
if (jack_client_name[err] == ' ')
jack_client_name[err] = tolower (jack_client_name[err]);
}
- err = process_info_connect_jack (procinfo, ui);
+ err = process_info_connect_jack (procinfo);
if (err)
{
/* g_free (procinfo); */
sample_rate = jack_get_sample_rate (procinfo->jack_client);
buffer_size = jack_get_sample_rate (procinfo->jack_client);
- jack_set_process_callback (procinfo->jack_client, process, procinfo);
- jack_on_shutdown (procinfo->jack_client, jack_shutdown_cb, ui);
-
- procinfo->ui_to_process = ui->ui_to_process;
- procinfo->process_to_ui = ui->process_to_ui;
+ jack_set_process_callback (procinfo->jack_client, process_jack, procinfo);
+ jack_on_shutdown (procinfo->jack_client, jack_shutdown_cb, procinfo);
jack_activate (procinfo->jack_client);
- err = process_info_set_port_count (procinfo, ui, rack_channels, connect_inputs, connect_outputs);
+ err = process_info_set_port_count (procinfo, rack_channels, connect_inputs, connect_outputs);
if (err)
return NULL;
void
process_info_destroy (process_info_t * procinfo) {
- jack_deactivate (procinfo->jack_client);
- jack_client_close (procinfo->jack_client);
+ if (procinfo->jack_client)
+ {
+ jack_deactivate (procinfo->jack_client);
+ jack_client_close (procinfo->jack_client);
+ }
+ g_free (procinfo->silent_buffer);
+ g_free (procinfo->jack_input_ports);
+ g_free (procinfo->jack_output_ports);
+ g_free (procinfo->jack_input_buffers);
+ g_free (procinfo->jack_output_buffers);
g_free (procinfo);
}
+
+void process_quit (process_info_t * procinfo) {
+ procinfo->quit = TRUE;
+}
unsigned long channels;
LADSPA_Data ** jack_input_buffers;
LADSPA_Data ** jack_output_buffers;
+ LADSPA_Data * silent_buffer;
- lff_t * ui_to_process;
- lff_t * process_to_ui;
+ char * jack_client_name;
+ int quit;
};
extern jack_nframes_t sample_rate;
extern jack_nframes_t buffer_size;
-struct _ui;
-
-process_info_t * process_info_new (struct _ui * ui, const char * client_name,
+process_info_t * process_info_new (const char * client_name,
unsigned long rack_channels, gboolean connect_inputs, gboolean connect_outputs);
void process_info_destroy (process_info_t * procinfo);
-void process_info_set_channels (process_info_t * procinfo, struct _ui * ui,
+void process_info_set_channels (process_info_t * procinfo,
unsigned long channels, gboolean connect_inputs, gboolean connect_outputs);
+int process_ladspa (process_info_t * procinfo, jack_nframes_t frames,
+ LADSPA_Data ** inputs, LADSPA_Data ** outputs);
-int process (jack_nframes_t frames, void * data);
+int process_jack (jack_nframes_t frames, void * data);
+void process_quit (process_info_t * procinfo);
#endif /* __JLH_PROCESS_H__ */
+++ /dev/null
-/*
- * JACK Rack
- *
- * Copyright (C) Robert Ham 2002, 2003 (node@users.sourceforge.net)
- *
- * 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 <stdlib.h>
-#include <strings.h>
-#include <string.h>
-#include <ctype.h>
-#include <limits.h>
-#include <stdarg.h>
-#include <unistd.h>
-
-#include <glib.h>
-#include <ladspa.h>
-
-#include "ui.h"
-#include "control_message.h"
-
-
-#define PROCESS_FIFO_SIZE 64
-#define MIDI_FIFO_SIZE 256
-
-ui_t *
-ui_new (const char * client_name, unsigned long channels,
- gboolean connect_inputs, gboolean connect_outputs)
-{
- ui_t * ui;
-
- ui = g_malloc (sizeof (ui_t));
- ui->filename = NULL;
- ui->shutdown = FALSE;
- ui->state = STATE_NORMAL;
-
- ui->ui_to_process = lff_new (PROCESS_FIFO_SIZE, sizeof (ctrlmsg_t));
- ui->process_to_ui = lff_new (PROCESS_FIFO_SIZE, sizeof (ctrlmsg_t));
-
- ui->procinfo = process_info_new (ui, client_name, channels, connect_inputs, connect_outputs);
- if (!ui->procinfo)
- return NULL;
-
- ui->plugin_mgr = plugin_mgr_new (ui);
- plugin_mgr_set_plugins (ui->plugin_mgr, channels);
- ui->jack_rack = jack_rack_new (ui, channels);
-
- return ui;
-}
-
-
-void
-ui_quit (ui_t * ui)
-{
- ctrlmsg_t ctrlmsg;
-
- ui_set_state (ui, STATE_QUITTING);
- ctrlmsg.type = CTRLMSG_QUIT;
- lff_write (ui->ui_to_process, &ctrlmsg);
-}
-
-void
-ui_destroy (ui_t * ui)
-{
- if (!ui->shutdown)
- ui_quit (ui);
- jack_rack_destroy (ui->jack_rack);
-
- g_free (ui);
-}
-
-void
-ui_set_state (ui_t * ui, ui_state_t state)
-{
- ui->state = state;
-}
-
-ui_state_t
-ui_get_state (ui_t * ui)
-{
- return ui->state;
-}
-
-void
-jack_shutdown_cb (void * data)
-{
- ui_t * ui = data;
-
- ui->shutdown = TRUE;
-}
-
-/* do the process->gui message processing */
-gboolean
-ui_loop_iterate (ui_t * ui)
-{
- ctrlmsg_t ctrlmsg;
- jack_rack_t * jack_rack = ui->jack_rack;
-
- while (lff_read (ui->process_to_ui, &ctrlmsg) == 0)
- {
- switch (ctrlmsg.type)
- {
- case CTRLMSG_ADD:
- jack_rack_add_plugin (jack_rack, ctrlmsg.data.add.plugin);
- break;
-
- case CTRLMSG_REMOVE:
- plugin_destroy (ctrlmsg.data.remove.plugin, ui);
- break;
-
- case CTRLMSG_QUIT:
- return TRUE;
- break;
-
- }
- }
-
- usleep (100000);
-
- return FALSE;
-}
-
-/* EOF */
+++ /dev/null
-/*
- * JACK Rack
- *
- * Copyright (C) Robert Ham 2002, 2003 (node@users.sourceforge.net)
- *
- * 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 __JR_UI_H__
-#define __JR_UI_H__
-
-#include <glib.h>
-
-#include "jack_rack.h"
-#include "plugin_mgr.h"
-#include "process.h"
-#include "lock_free_fifo.h"
-
-typedef struct _ui ui_t;
-
-enum _ui_state
-{
- /* nothing's happening */
- STATE_NORMAL,
-
- /* the gui is waiting for the process callback to do something */
- STATE_RACK_CHANGE,
-
- /* we're closing down */
- STATE_QUITTING
-};
-typedef enum _ui_state ui_state_t;
-
-
-struct _jack_rack;
-
-struct _ui
-{
- plugin_mgr_t * plugin_mgr;
- process_info_t * procinfo;
- struct _jack_rack * jack_rack;
-
- lff_t * ui_to_process;
- lff_t * process_to_ui;
-
- lff_t *ui_to_midi;
- lff_t *midi_to_ui;
-
- char * filename;
-
- gboolean shutdown;
- ui_state_t state;
-
-};
-
-ui_t * ui_new (const char * client_name, unsigned long channels,
- gboolean connect_inputs, gboolean connect_outputs);
-void ui_quit (ui_t * ui);
-void ui_destroy (ui_t * ui);
-
-void ui_set_state (ui_t * ui, ui_state_t state);
-ui_state_t ui_get_state (ui_t * ui);
-
-void jack_shutdown_cb (void * data);
-gboolean ui_loop_iterate (ui_t * ui);
-
-#endif /* __JR_UI_H__ */