@@ -292,6 +292,12 @@ LADSPAInfo::GetMenuList(void) | |||
return m_SSMMenuList; | |||
} | |||
const vector<LADSPAInfo::PluginInfo> | |||
LADSPAInfo::GetPluginInfo(void) | |||
{ | |||
return m_Plugins; | |||
} | |||
unsigned long | |||
LADSPAInfo::GetPluginListEntryByID(unsigned long unique_id) | |||
{ | |||
@@ -378,7 +384,7 @@ LADSPAInfo::DescendGroup(string prefix, | |||
pe.Depth = depth; | |||
pe.UniqueID = pi->UniqueID; | |||
pe.Name = prefix + name; | |||
plugins.push_back(pe); | |||
} | |||
plugins.sort(); | |||
@@ -599,6 +605,13 @@ LADSPAInfo::ExaminePluginLibrary(const string path, | |||
library_added = true; | |||
} | |||
if ( ! desc->Name ) | |||
{ | |||
printf( "WARNING: LADSPA Plugin with id %lu has no name!\n", desc->UniqueID ); | |||
continue; | |||
} | |||
// Add plugin info | |||
PluginInfo pi; | |||
pi.LibraryIndex = m_Libraries.size() - 1; | |||
@@ -607,19 +620,34 @@ LADSPAInfo::ExaminePluginLibrary(const string path, | |||
pi.Label = desc->Label; | |||
pi.Name = desc->Name; | |||
pi.Descriptor = NULL; | |||
m_Plugins.push_back(pi); | |||
pi.Maker = desc->Maker; | |||
pi.AudioInputs = 0; | |||
pi.AudioOutputs = 0; | |||
// Find number of input ports | |||
unsigned long in_port_count = 0; | |||
for (unsigned long p = 0; p < desc->PortCount; p++) { | |||
if (LADSPA_IS_PORT_INPUT(desc->PortDescriptors[p])) { | |||
in_port_count++; | |||
} | |||
if (LADSPA_IS_PORT_INPUT(desc->PortDescriptors[p])) { | |||
in_port_count++; | |||
if ( LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[p] ) ) | |||
pi.AudioInputs++; | |||
} | |||
} | |||
for (unsigned long p = 0; p < desc->PortCount; p++) { | |||
if (LADSPA_IS_PORT_OUTPUT(desc->PortDescriptors[p])) { | |||
if ( LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[p] ) ) | |||
pi.AudioOutputs++; | |||
} | |||
} | |||
if (in_port_count > m_MaxInputPortCount) { | |||
m_MaxInputPortCount = in_port_count; | |||
m_MaxInputPortCount = in_port_count; | |||
} | |||
m_Plugins.push_back(pi); | |||
// Add to index | |||
m_IDLookup[desc->UniqueID] = m_Plugins.size() - 1; | |||
@@ -97,8 +97,27 @@ public: | |||
} | |||
}; | |||
// For cached plugin information | |||
struct PluginInfo | |||
{ | |||
unsigned long LibraryIndex; // Index of library in m_Libraries | |||
unsigned long Index; // Plugin index in library | |||
unsigned long UniqueID; // Unique ID | |||
std::string Label; // Plugin label | |||
std::string Name; // Plugin Name | |||
std::string Maker; | |||
unsigned int AudioInputs; | |||
unsigned int AudioOutputs; | |||
const LADSPA_Descriptor *Descriptor; // Descriptor, NULL | |||
}; | |||
// Get ordered list of plugin names and IDs for plugin menu | |||
const std::vector<PluginEntry> GetMenuList(void); | |||
const std::vector<PluginInfo> GetPluginInfo(void); | |||
// Get the index in the above list for given Unique ID | |||
// If not found, this returns the size of the above list | |||
@@ -140,17 +159,6 @@ private: | |||
void *Handle; // DLL Handle, NULL | |||
}; | |||
// For cached plugin information | |||
struct PluginInfo | |||
{ | |||
unsigned long LibraryIndex; // Index of library in m_Libraries | |||
unsigned long Index; // Plugin index in library | |||
unsigned long UniqueID; // Unique ID | |||
std::string Label; // Plugin label | |||
std::string Name; // Plugin Name | |||
const LADSPA_Descriptor *Descriptor; // Descriptor, NULL | |||
}; | |||
// For cached RDF uri information | |||
struct RDFURIInfo | |||
{ | |||
@@ -39,6 +39,7 @@ | |||
#include "FL/menu_popup.H" | |||
#include "Mixer.H" | |||
#include "Plugin_Chooser.H" | |||
#include "OSC/Endpoint.H" | |||
#include "string_util.h" | |||
@@ -602,61 +603,55 @@ Module::draw_label ( void ) | |||
void | |||
Module::insert_menu_cb ( const Fl_Menu_ *m ) | |||
{ | |||
if ( ! m->mvalue() || m->mvalue()->flags & FL_SUBMENU_POINTER || m->mvalue()->flags & FL_SUBMENU ) | |||
return; | |||
void * v = m->mvalue()->user_data(); | |||
if ( v ) | |||
unsigned long id = Plugin_Chooser::plugin_chooser( this->ninputs() ); | |||
Module *mod = NULL; | |||
switch ( id ) | |||
{ | |||
unsigned long id = *((unsigned long *)v); | |||
Module *mod = NULL; | |||
switch ( id ) | |||
case 0: | |||
return; | |||
case 1: | |||
mod = new JACK_Module(); | |||
break; | |||
case 2: | |||
mod = new Gain_Module(); | |||
break; | |||
case 3: | |||
mod = new Meter_Module(); | |||
break; | |||
case 4: | |||
mod = new Mono_Pan_Module(); | |||
break; | |||
default: | |||
{ | |||
case 1: | |||
mod = new JACK_Module(); | |||
break; | |||
case 2: | |||
mod = new Gain_Module(); | |||
break; | |||
case 3: | |||
mod = new Meter_Module(); | |||
break; | |||
case 4: | |||
mod = new Mono_Pan_Module(); | |||
break; | |||
default: | |||
{ | |||
Plugin_Module *m = new Plugin_Module(); | |||
Plugin_Module *m = new Plugin_Module(); | |||
m->load( id ); | |||
m->load( id ); | |||
mod = m; | |||
} | |||
mod = m; | |||
} | |||
} | |||
if ( mod ) | |||
if ( mod ) | |||
{ | |||
if ( !strcmp( mod->name(), "JACK" ) ) | |||
{ | |||
if ( !strcmp( mod->name(), "JACK" ) ) | |||
{ | |||
DMESSAGE( "Special casing JACK module" ); | |||
JACK_Module *jm = (JACK_Module*)mod; | |||
jm->chain( chain() ); | |||
jm->configure_inputs( ninputs() ); | |||
jm->configure_outputs( ninputs() ); | |||
} | |||
if ( ! chain()->insert( this, mod ) ) | |||
{ | |||
fl_alert( "Cannot insert this module at this point in the chain" ); | |||
delete mod; | |||
return; | |||
} | |||
DMESSAGE( "Special casing JACK module" ); | |||
JACK_Module *jm = (JACK_Module*)mod; | |||
jm->chain( chain() ); | |||
jm->configure_inputs( ninputs() ); | |||
jm->configure_outputs( ninputs() ); | |||
} | |||
redraw(); | |||
if ( ! chain()->insert( this, mod ) ) | |||
{ | |||
fl_alert( "Cannot insert this module at this point in the chain" ); | |||
delete mod; | |||
return; | |||
} | |||
redraw(); | |||
} | |||
} | |||
@@ -733,7 +728,10 @@ Module::menu ( void ) const | |||
insert_menu->add( "Meter", 0, 0, new unsigned long(3) ); | |||
insert_menu->add( "Mono Pan", 0, 0, new unsigned long(4) ); | |||
Plugin_Module::add_plugins_to_menu( insert_menu ); | |||
insert_menu->add( "Plugin", 0, 0, new unsigned long(4) ); | |||
/* Plugin_Module::add_plugins_to_menu( insert_menu ); */ | |||
// menu_set_callback( insert_menu, &Module::insert_menu_cb, (void*)this ); | |||
insert_menu->callback( &Module::insert_menu_cb, (void*)this ); | |||
@@ -0,0 +1,384 @@ | |||
/*******************************************************************************/ | |||
/* Copyright (C) 2013 Jonathan Moore Liles */ | |||
/* */ | |||
/* 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; see the file COPYING. If not,write to the Free Software */ | |||
/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | |||
/*******************************************************************************/ | |||
#include <FL/Fl.H> | |||
#include <FL/Fl_Browser.H> | |||
#include <FL/Fl_Input.H> | |||
#include <FL/Fl_Scalepack.H> | |||
#include "Plugin_Chooser_UI.H" | |||
#include "Plugin_Module.H" | |||
#include "Plugin_Chooser.H" | |||
#include "stdio.h" | |||
#include <FL/Fl_Box.H> | |||
#include <FL/fl_draw.H> | |||
#include <algorithm> | |||
static std::vector <Plugin_Module::Plugin_Info*> _plugin_rows; | |||
unsigned long | |||
Plugin_Chooser::plugin_chooser ( int ninputs ) | |||
{ | |||
Plugin_Chooser *o = new Plugin_Chooser( 0,0,735,500,"Plugin Chooser"); | |||
o->ui->inputs_input->value( ninputs ); | |||
o->search( "", "", ninputs, 0, o->ui->favorites_button->value() ); | |||
o->show(); | |||
while ( o->shown() ) | |||
Fl::wait(); | |||
unsigned long picked = o->value(); | |||
delete o; | |||
return picked; | |||
} | |||
void | |||
Plugin_Chooser::search ( const char *name, const char *author, int ninputs, int noutputs, bool favorites ) | |||
{ | |||
_plugin_rows.clear(); | |||
for ( std::list<Plugin_Module::Plugin_Info>::iterator i = _plugins.begin(); i != _plugins.end(); i++ ) | |||
{ | |||
Plugin_Module::Plugin_Info *p = &(*i); | |||
if ( strcasestr( p->name, name ) && | |||
strcasestr( p->author, author ) ) | |||
{ | |||
if ( ! | |||
((( ( ninputs == 0 || ninputs == p->audio_inputs ) ) && | |||
( noutputs == 0 || noutputs == p->audio_outputs )) || | |||
( p->audio_inputs == 1 && p->audio_outputs == 1 ) ) ) | |||
continue; | |||
if ( p->audio_outputs == 0 || p->audio_inputs == 0 ) | |||
/* we don't support these */ | |||
continue; | |||
if ( favorites > 0 && ! p->favorite ) | |||
continue; | |||
_plugin_rows.push_back( p ); | |||
} | |||
} | |||
ui->table->rows( _plugin_rows.size() ); | |||
} | |||
void | |||
Plugin_Chooser::cb_handle ( Fl_Widget *w, void *v ) | |||
{ | |||
((Plugin_Chooser*)v)->cb_handle( w ); | |||
} | |||
void | |||
Plugin_Chooser::cb_handle ( Fl_Widget *w ) | |||
{ | |||
if ( w == ui->all_button ) | |||
{ | |||
ui->favorites_button->value( !ui->all_button->value() ); | |||
} | |||
{ | |||
search( ui->name_input->value(), ui->author_input->value(), ui->inputs_input->value(), ui->outputs_input->value(), ui->favorites_button->value() ); | |||
} | |||
} | |||
class Plugin_Table : public Fl_Table_Row | |||
{ | |||
protected: | |||
void draw_cell(TableContext context, // table cell drawing | |||
int R=0, int C=0, int X=0, int Y=0, int W=0, int H=0); | |||
public: | |||
Plugin_Table(int x, int y, int w, int h, const char *l=0) : Fl_Table_Row(x,y,w,h,l) | |||
{ | |||
end(); | |||
} | |||
~Plugin_Table() { } | |||
}; | |||
void Plugin_Table::draw_cell(TableContext context, | |||
int R, int C, int X, int Y, int W, int H) | |||
{ | |||
const char *headings[] = { "Fav.", "Name", "Author", "Type", "In", "Out" }; | |||
static char s[40]; | |||
switch ( context ) | |||
{ | |||
case CONTEXT_STARTPAGE: | |||
fl_font(FL_HELVETICA, 12); | |||
return; | |||
case CONTEXT_COL_HEADER: | |||
fl_push_clip(X, Y, W, H); | |||
{ | |||
fl_draw_box(FL_THIN_UP_BOX, X, Y, W, H, col_header_color()); | |||
fl_color(FL_FOREGROUND_COLOR); | |||
fl_draw(headings[C], X, Y, W, H, FL_ALIGN_CENTER); | |||
} | |||
fl_pop_clip(); | |||
return; | |||
case CONTEXT_ROW_HEADER: | |||
return; | |||
case CONTEXT_CELL: | |||
{ | |||
const char *s2 = (char*)s; | |||
Fl_Align a = FL_ALIGN_CENTER; | |||
int symbol = 0; | |||
switch ( C ) | |||
{ | |||
case 0: | |||
sprintf( s, "%s", _plugin_rows[R]->favorite ? "@circle" : "" ); | |||
symbol = 1; | |||
break; | |||
case 1: | |||
a = FL_ALIGN_LEFT; | |||
s2 = _plugin_rows[R]->name; | |||
break; | |||
case 2: | |||
a = FL_ALIGN_LEFT; | |||
s2 = _plugin_rows[R]->author; | |||
break; | |||
case 3: | |||
s2 = _plugin_rows[R]->type; | |||
break; | |||
case 4: | |||
sprintf( s, "%i", _plugin_rows[R]->audio_inputs ); | |||
break; | |||
case 5: | |||
sprintf( s, "%i", _plugin_rows[R]->audio_outputs ); | |||
break; | |||
} | |||
fl_push_clip(X, Y, W, H); | |||
{ | |||
// BG COLOR | |||
fl_color( row_selected(R) ? selection_color() : FL_DARK1); | |||
fl_rectf(X, Y, W, H); | |||
// TEXT | |||
fl_color(FL_FOREGROUND_COLOR); | |||
fl_draw(s2, X, Y, W, H, a, 0, symbol ); | |||
// BORDER | |||
fl_color(color()); | |||
fl_rect(X, Y, W, H); | |||
} | |||
fl_pop_clip(); | |||
return; | |||
} | |||
case CONTEXT_TABLE: | |||
fprintf(stderr, "TABLE CONTEXT CALLED\n"); | |||
return; | |||
case CONTEXT_ENDPAGE: | |||
case CONTEXT_RC_RESIZE: | |||
case CONTEXT_NONE: | |||
return; | |||
} | |||
} | |||
void | |||
Plugin_Chooser::cb_table ( Fl_Widget *w, void *v ) | |||
{ | |||
((Plugin_Chooser*)v)->cb_table(w); | |||
} | |||
void | |||
Plugin_Chooser::cb_table ( Fl_Widget *w ) | |||
{ | |||
Fl_Table_Row *o = (Fl_Table_Row*)w; | |||
int R = o->callback_row(); | |||
int C = o->callback_col(); | |||
Fl_Table::TableContext context = o->callback_context(); | |||
if ( context == Fl_Table::CONTEXT_CELL ) | |||
{ | |||
if ( C == 0 ) | |||
{ | |||
_plugin_rows[R]->favorite = ! _plugin_rows[R]->favorite; | |||
o->redraw(); | |||
} | |||
else | |||
{ | |||
_value = _plugin_rows[R]->id; | |||
hide(); | |||
} | |||
} | |||
} | |||
extern char *user_config_dir; | |||
static FILE *open_favorites( const char *mode ) | |||
{ | |||
char *path; | |||
asprintf( &path, "%s/%s", user_config_dir, "favorite_plugins" ); | |||
FILE *fp = fopen( path, mode ); | |||
free( path ); | |||
return fp; | |||
} | |||
int | |||
Plugin_Chooser::load_favorites ( void ) | |||
{ | |||
FILE *fp = open_favorites( "r" ); | |||
if ( !fp ) | |||
{ | |||
return 0; | |||
} | |||
unsigned long id; | |||
char *type; | |||
int favorites = 0; | |||
while ( 2 == fscanf( fp, "%a[^:]:%lu\n", &type, &id ) ) | |||
{ | |||
for ( std::list<Plugin_Module::Plugin_Info>::iterator i = _plugins.begin(); | |||
i != _plugins.end(); | |||
i++ ) | |||
{ | |||
if ( !strcmp( (*i).type, type ) && | |||
(*i).id == id ) | |||
{ | |||
(*i).favorite = 1; | |||
favorites++; | |||
} | |||
} | |||
free(type); | |||
} | |||
fclose(fp); | |||
return favorites; | |||
} | |||
void | |||
Plugin_Chooser::save_favorites ( void ) | |||
{ | |||
FILE *fp = open_favorites( "w" ); | |||
if ( !fp ) | |||
return; | |||
for ( std::list<Plugin_Module::Plugin_Info>::iterator i = _plugins.begin(); | |||
i != _plugins.end(); | |||
i++ ) | |||
{ | |||
if ( (*i).favorite ) | |||
{ | |||
fprintf( fp, "%s:%lu\n", i->type, i->id ); | |||
} | |||
} | |||
fclose( fp ); | |||
} | |||
Plugin_Chooser::Plugin_Chooser ( int X,int Y,int W,int H, const char *L ) | |||
: Fl_Double_Window ( X,Y,W,H,L ) | |||
{ | |||
set_modal(); | |||
_value = 0; | |||
_plugins = Plugin_Module::get_all_plugins(); | |||
{ | |||
Plugin_Chooser_UI *o = ui = new Plugin_Chooser_UI(X,Y,W,H); | |||
o->name_input->callback( &Plugin_Chooser::cb_handle, this ); | |||
o->name_input->when( FL_WHEN_CHANGED ); | |||
o->author_input->callback( &Plugin_Chooser::cb_handle, this ); | |||
o->author_input->when( FL_WHEN_CHANGED ); | |||
o->inputs_input->callback( &Plugin_Chooser::cb_handle, this ); | |||
o->inputs_input->when( FL_WHEN_CHANGED ); | |||
o->outputs_input->callback( &Plugin_Chooser::cb_handle, this ); | |||
o->outputs_input->when( FL_WHEN_CHANGED ); | |||
o->favorites_button->callback( &Plugin_Chooser::cb_handle, this ); | |||
o->favorites_button->when( FL_WHEN_CHANGED ); | |||
o->all_button->callback( &Plugin_Chooser::cb_handle, this ); | |||
o->all_button->when( FL_WHEN_CHANGED ); | |||
{ | |||
Plugin_Table *o = new Plugin_Table(ui->table->x(),ui->table->y(),ui->table->w(),ui->table->h() ); | |||
ui->table_group->add(o); | |||
ui->table_group->resizable(o); | |||
delete ui->table; | |||
ui->table = o; | |||
/* ui->scalepack->add( o ); */ | |||
/* ui->scalepack->resizable( o ); */ | |||
o->col_header(1); | |||
o->col_resize(1); | |||
o->row_resize(1); | |||
o->cols(6); | |||
o->col_resize_min(4); | |||
o->col_width(0,30); | |||
o->col_width(1,350 - 7); | |||
o->col_width(2,200); | |||
o->col_width(3,75); | |||
o->col_width(4,30); | |||
o->col_width(5,30); | |||
o->color(FL_BLACK); | |||
o->box(FL_NO_BOX); | |||
o->when(FL_WHEN_CHANGED); | |||
o->callback( &Plugin_Chooser::cb_table, this ); | |||
} | |||
resizable(o); | |||
} | |||
size_range( 735, 300, 735, 0 ); | |||
end(); | |||
if ( load_favorites() ) | |||
{ | |||
ui->all_button->value(0); | |||
ui->favorites_button->value(1); | |||
} | |||
} | |||
Plugin_Chooser::~Plugin_Chooser( ) | |||
{ | |||
save_favorites(); | |||
} |
@@ -0,0 +1,57 @@ | |||
/*******************************************************************************/ | |||
/* Copyright (C) 2013 Jonathan Moore Liles */ | |||
/* */ | |||
/* 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; see the file COPYING. If not,write to the Free Software */ | |||
/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | |||
/*******************************************************************************/ | |||
#pragma once | |||
#include <FL/Fl_Double_Window.H> | |||
#include "Plugin_Module.H" | |||
#include <vector> | |||
class Plugin_Chooser_UI; | |||
class Plugin_Chooser : public Fl_Double_Window | |||
{ | |||
Plugin_Chooser_UI *ui; | |||
std::list <Plugin_Module::Plugin_Info> _plugins; | |||
static void cb_handle ( Fl_Widget *w, void *v ); | |||
void cb_handle ( Fl_Widget *w ); | |||
static void cb_table ( Fl_Widget *w, void *v ); | |||
void cb_table ( Fl_Widget *w ); | |||
void search ( const char *name, const char *author, int ninputs, int noutputs, bool favorites ); | |||
unsigned long _value; | |||
int load_favorites ( void ); | |||
void save_favorites ( void ); | |||
public: | |||
unsigned long value ( void ) const { return _value; } | |||
Plugin_Chooser ( int X,int Y,int W,int H, const char *L=0 ); | |||
virtual ~Plugin_Chooser( ); | |||
static unsigned long plugin_chooser ( int ninputs ); | |||
}; | |||
@@ -0,0 +1,64 @@ | |||
# data file for the Fltk User Interface Designer (fluid) | |||
version 1.0300 | |||
header_name {.h} | |||
code_name {.cxx} | |||
decl {\#include <FL/Fl_Scalepack.H>} {public global | |||
} | |||
decl {\#include <FL/Fl_Table_Row.H>} {public global | |||
} | |||
widget_class Plugin_Chooser_UI { | |||
label {Plugin Selector} open selected | |||
xywh {821 343 735 500} type Double resizable size_range {740 0 740 0} visible | |||
} { | |||
Fl_Group {} {open | |||
xywh {10 5 155 20} | |||
} { | |||
Fl_Round_Button all_button { | |||
label All | |||
xywh {10 5 50 20} type Radio down_box ROUND_DOWN_BOX value 1 | |||
} | |||
Fl_Round_Button favorites_button { | |||
label Favorites | |||
xywh {65 5 100 20} type Radio down_box ROUND_DOWN_BOX | |||
} | |||
} | |||
Fl_Group {} {open | |||
xywh {5 29 725 77} box UP_FRAME | |||
code0 {o->resizable(0);} | |||
} { | |||
Fl_Input name_input { | |||
label {Name:} | |||
xywh {65 38 555 24} labelsize 12 textsize 13 | |||
} | |||
Fl_Input author_input { | |||
label {Author:} | |||
xywh {65 72 415 24} labelsize 12 textsize 13 | |||
} | |||
Fl_Value_Input outputs_input { | |||
label {Outputs:} | |||
xywh {693 70 30 26} labelsize 12 | |||
} | |||
Fl_Value_Input inputs_input { | |||
label {Inputs:} | |||
xywh {693 39 30 24} labelsize 12 | |||
} | |||
} | |||
Fl_Group table_group {open | |||
xywh {5 115 725 380} resizable | |||
} { | |||
Fl_Table table {open | |||
xywh {5 115 725 380} resizable | |||
} {} | |||
} | |||
Fl_Choice type_choice { | |||
label {Type:} open | |||
xywh {520 135 100 28} down_box BORDER_BOX labelsize 12 hide | |||
} { | |||
MenuItem {} { | |||
label LADSPA | |||
xywh {0 -68 34 18} | |||
} | |||
} | |||
} |
@@ -45,6 +45,8 @@ | |||
#include <dsp.h> | |||
#include <algorithm> | |||
static LADSPAInfo *ladspainfo; | |||
@@ -119,64 +121,6 @@ Plugin_Module::set ( Log_Entry &e ) | |||
void | |||
Plugin_Module::add_plugins_to_menu ( Fl_Menu_Button *menu ) | |||
{ | |||
Plugin_Module::Plugin_Info *pia = Plugin_Module::get_all_plugins(); | |||
char path[1024]; | |||
for ( Plugin_Module::Plugin_Info *pi = pia; pi->path; ++pi ) | |||
{ | |||
snprintf( path, sizeof( path ), "Plugin/%s", pi->path ); | |||
menu->add(path, 0, NULL, new unsigned long( pi->id ), 0 ); | |||
} | |||
delete[] pia; | |||
} | |||
/* allow the user to pick a plugin */ | |||
Plugin_Module * | |||
Plugin_Module::pick_plugin ( void ) | |||
{ | |||
/**************/ | |||
/* build menu */ | |||
/**************/ | |||
Fl_Menu_Button *menu = new Fl_Menu_Button( 0, 0, 400, 400 ); | |||
menu->type( Fl_Menu_Button::POPUP3 ); | |||
Plugin_Module::Plugin_Info *pia = Plugin_Module::get_all_plugins(); | |||
for ( Plugin_Module::Plugin_Info *pi = pia; pi->path; ++pi ) | |||
{ | |||
menu->add(pi->path, 0, NULL, pi, 0 ); | |||
} | |||
menu->popup(); | |||
if ( menu->value() <= 0 ) | |||
return NULL; | |||
/************************/ | |||
/* load selected plugin */ | |||
/************************/ | |||
Plugin_Module::Plugin_Info *pi = (Plugin_Module::Plugin_Info*)menu->menu()[ menu->value() ].user_data(); | |||
if ( ! pi ) | |||
return NULL; | |||
Plugin_Module *m = new Plugin_Module(); | |||
m->load( pi->id ); | |||
delete[] pia; | |||
return m; | |||
} | |||
void | |||
Plugin_Module::init ( void ) | |||
{ | |||
@@ -319,7 +263,7 @@ Plugin_Module::join_discover_thread ( void ) | |||
} | |||
/* return a list of available plugins */ | |||
Plugin_Module::Plugin_Info * | |||
std::list<Plugin_Module::Plugin_Info> | |||
Plugin_Module::get_all_plugins ( void ) | |||
{ | |||
if ( !ladspainfo ) | |||
@@ -330,19 +274,30 @@ Plugin_Module::get_all_plugins ( void ) | |||
plugin_discover_thread->join(); | |||
} | |||
std::vector<LADSPAInfo::PluginEntry> plugins = ladspainfo->GetMenuList(); | |||
std::vector<LADSPAInfo::PluginInfo> plugins = ladspainfo->GetPluginInfo(); | |||
Plugin_Info* pi = new Plugin_Info[plugins.size() + 1]; | |||
std::list<Plugin_Module::Plugin_Info> pr; | |||
int j = 0; | |||
for (std::vector<LADSPAInfo::PluginEntry>::iterator i=plugins.begin(); | |||
for (std::vector<LADSPAInfo::PluginInfo>::iterator i=plugins.begin(); | |||
i!=plugins.end(); i++, j++) | |||
{ | |||
pi[j].path = i->Name.c_str(); | |||
pi[j].id = i->UniqueID; | |||
Plugin_Info pi; | |||
// pi[j].path = i->Name.c_str(); | |||
pi.path = NULL; | |||
pi.id = i->UniqueID; | |||
pi.author = i->Maker.c_str(); | |||
pi.name = i->Name.c_str(); | |||
pi.audio_inputs = i->AudioInputs; | |||
pi.audio_outputs = i->AudioOutputs; | |||
pr.push_back( pi ); | |||
} | |||
return pi; | |||
pr.sort(); | |||
return pr; | |||
} | |||
bool | |||
@@ -35,12 +35,30 @@ public: | |||
{ | |||
const char *path; | |||
unsigned long id; | |||
const char *name; | |||
const char *author; | |||
const char *category; | |||
int audio_inputs; | |||
int audio_outputs; | |||
const char *type; | |||
bool favorite; | |||
Plugin_Info ( ) | |||
{ | |||
path = 0; | |||
id = 0; | |||
name = 0; | |||
author = 0; | |||
category = 0; | |||
audio_inputs = 0; | |||
audio_outputs = 0; | |||
type = "LADSPA"; | |||
favorite = 0; | |||
} | |||
bool operator< ( const Plugin_Info &rhs ) { | |||
return strcmp( name, rhs.name ) < 1; | |||
} | |||
}; | |||
bool load ( unsigned long id ); | |||
@@ -71,8 +89,7 @@ private: | |||
bool _crosswire; | |||
static void *discover_thread ( void * ); | |||
static Plugin_Info* get_all_plugins ( void ); | |||
void set_input_buffer ( int n, void *buf ); | |||
void set_output_buffer ( int n, void *buf ); | |||
@@ -89,15 +106,14 @@ private: | |||
public: | |||
static std::list<Plugin_Info> get_all_plugins ( void ); | |||
static void spawn_discover_thread ( void ); | |||
static void join_discover_thread ( void ); | |||
Plugin_Module ( ); | |||
virtual ~Plugin_Module(); | |||
static Plugin_Module * pick_plugin ( void ); | |||
static void add_plugins_to_menu ( Fl_Menu_Button *menu ); | |||
int plugin_ins ( void ) const { return _plugin_ins; } | |||
int plugin_outs ( void ) const { return _plugin_outs; } | |||
@@ -57,6 +57,8 @@ src/Mixer_Strip.C | |||
src/Module.C | |||
src/Module_Parameter_Editor.C | |||
src/Mono_Pan_Module.C | |||
src/Plugin_Chooser_UI.fl | |||
src/Plugin_Chooser.C | |||
src/NSM.C | |||
src/Panner.C | |||
src/Plugin_Module.C | |||