| @@ -44,7 +44,7 @@ | |||
| // needed for mixer->endpoint | |||
| #include "Mixer.H" | |||
| #include "Spatialization_Console.H" | |||
| #include "string_util.h" | |||
| @@ -81,25 +81,39 @@ Controller_Module::~Controller_Module ( ) | |||
| /* shutdown JACK port, if we have one */ | |||
| mode( GUI ); | |||
| // disconnect(); | |||
| } | |||
| void | |||
| Controller_Module::handle_chain_name_changed() | |||
| { | |||
| if ( type() == SPATIALIZATION ) | |||
| { | |||
| if ( Mixer::spatialization_console ) | |||
| Mixer::spatialization_console->update(); | |||
| } | |||
| // change_osc_path( generate_osc_path() ); | |||
| } | |||
| void | |||
| Controller_Module::disconnect ( void ) | |||
| Controller_Module::handle_control_disconnect ( Module::Port *p ) | |||
| { | |||
| for ( std::vector<Module::Port>::iterator i = control_output.begin(); | |||
| i != control_output.end(); | |||
| ++i ) | |||
| if ( type() == SPATIALIZATION ) | |||
| { | |||
| (*i).disconnect(); | |||
| if ( Mixer::spatialization_console ) | |||
| Mixer::spatialization_console->update(); | |||
| } | |||
| } | |||
| void | |||
| Controller_Module::disconnect ( void ) | |||
| { | |||
| for ( unsigned int i = 0; i < control_output.size(); ++i ) | |||
| control_output[i].disconnect(); | |||
| } | |||
| void | |||
| @@ -266,51 +280,53 @@ Controller_Module::connect_spatializer_to ( Module *m ) | |||
| control_output[0].connect_to( azimuth_port ); | |||
| control_output[1].connect_to( elevation_port ); | |||
| { | |||
| clear(); | |||
| clear(); | |||
| Panner *o = new Panner( 0,0, 92,92 ); | |||
| Panner *o = new Panner( 0,0, 92,92 ); | |||
| o->box(FL_FLAT_BOX); | |||
| o->color(FL_GRAY0); | |||
| o->selection_color(FL_BACKGROUND_COLOR); | |||
| o->labeltype(FL_NORMAL_LABEL); | |||
| o->labelfont(0); | |||
| o->labelcolor(FL_FOREGROUND_COLOR); | |||
| o->align(FL_ALIGN_TOP); | |||
| o->when(FL_WHEN_CHANGED); | |||
| label( "Spatialization" ); | |||
| o->box(FL_FLAT_BOX); | |||
| o->color(FL_GRAY0); | |||
| o->selection_color(FL_BACKGROUND_COLOR); | |||
| o->labeltype(FL_NORMAL_LABEL); | |||
| o->labelfont(0); | |||
| o->labelcolor(FL_FOREGROUND_COLOR); | |||
| o->align(FL_ALIGN_TOP); | |||
| o->when(FL_WHEN_CHANGED); | |||
| label( "Spatialization" ); | |||
| o->align(FL_ALIGN_TOP); | |||
| o->labelsize( 10 ); | |||
| o->align(FL_ALIGN_TOP); | |||
| o->labelsize( 10 ); | |||
| // o->callback( cb_panner_value_handle, new callback_data( this, azimuth_port_number, elevation_port_number ) ); | |||
| o->point( 0 )->azimuth( azimuth_value ); | |||
| o->point( 0 )->elevation( elevation_value ); | |||
| o->point( 0 )->azimuth( azimuth_value ); | |||
| o->point( 0 )->elevation( elevation_value ); | |||
| o->callback( cb_spatializer_handle, this ); | |||
| o->callback( cb_spatializer_handle, this ); | |||
| control = (Fl_Valuator*)o; | |||
| control = (Fl_Valuator*)o; | |||
| if ( _pad ) | |||
| { | |||
| Fl_Labelpad_Group *flg = new Fl_Labelpad_Group( o ); | |||
| flg->position( x(), y() ); | |||
| flg->set_visible_focus(); | |||
| size( flg->w(), flg->h() ); | |||
| add( flg ); | |||
| } | |||
| else | |||
| { | |||
| o->resize( x(), y(), w(), h() ); | |||
| add( o ); | |||
| resizable( o ); | |||
| init_sizes(); | |||
| } | |||
| _type = SPATIALIZATION; | |||
| return true; | |||
| if ( _pad ) | |||
| { | |||
| Fl_Labelpad_Group *flg = new Fl_Labelpad_Group( o ); | |||
| flg->position( x(), y() ); | |||
| flg->set_visible_focus(); | |||
| size( flg->w(), flg->h() ); | |||
| add( flg ); | |||
| } | |||
| else | |||
| { | |||
| o->resize( x(), y(), w(), h() ); | |||
| add( o ); | |||
| resizable( o ); | |||
| init_sizes(); | |||
| } | |||
| _type = SPATIALIZATION; | |||
| if ( Mixer::spatialization_console ) | |||
| Mixer::spatialization_console->update(); | |||
| return true; | |||
| } | |||
| void | |||
| @@ -762,6 +778,13 @@ void | |||
| Controller_Module::handle_control_changed ( Port *p ) | |||
| { | |||
| /* ignore changes initiated while mouse is over widget */ | |||
| if ( type() == SPATIALIZATION ) | |||
| { | |||
| if ( Mixer::spatialization_console ) | |||
| Mixer::spatialization_console->handle_control_changed( this ); | |||
| } | |||
| if ( contains( Fl::pushed() ) ) | |||
| return; | |||
| @@ -88,6 +88,7 @@ public: | |||
| void handle_control_changed ( Port *p ); | |||
| void handle_chain_name_changed ( void ); | |||
| void handle_control_disconnect ( Port *p ); | |||
| virtual void command_remove ( void ); | |||
| @@ -37,6 +37,7 @@ | |||
| #include <FL/Fl_File_Chooser.H> | |||
| #include <FL/Fl_Theme_Chooser.H> | |||
| #include <FL/Fl_Value_SliderX.H> | |||
| #include <Spatialization_Console.H> | |||
| #include "file.h" | |||
| #include <string.h> | |||
| @@ -62,6 +63,8 @@ extern char *instance_name; | |||
| extern NSM_Client *nsm; | |||
| Spatialization_Console *Mixer::spatialization_console = 0; | |||
| void | |||
| @@ -315,6 +318,19 @@ void Mixer::cb_menu(Fl_Widget* o) { | |||
| { | |||
| Fl::paste(*this); | |||
| } | |||
| else if ( !strcmp( picked, "&Mixer/Spatialization Console" ) ) | |||
| { | |||
| if ( ! spatialization_console ) | |||
| { | |||
| Spatialization_Console *o = new Spatialization_Console(); | |||
| spatialization_console = o; | |||
| } | |||
| if ( spatialization_console->shown() ) | |||
| spatialization_console->hide(); | |||
| else | |||
| spatialization_console->show(); | |||
| } | |||
| else if (! strcmp( picked, "&Project/Se&ttings/&Rows/One") ) | |||
| { | |||
| rows( 1 ); | |||
| @@ -501,6 +517,7 @@ Mixer::Mixer ( int X, int Y, int W, int H, const char *L ) : | |||
| o->add( "&Mixer/Add &N Strips" ); | |||
| o->add( "&Mixer/&Import Strip" ); | |||
| o->add( "&Mixer/Paste", FL_CTRL + 'v', 0, 0 ); | |||
| o->add( "&Mixer/Spatialization Console", FL_F + 8, 0, 0 ); | |||
| o->add( "&Remote Control/Start Learning", FL_F + 9, 0, 0 ); | |||
| o->add( "&Remote Control/Stop Learning", FL_F + 10, 0, 0 ); | |||
| o->add( "&Remote Control/Send State" ); | |||
| @@ -853,6 +870,12 @@ Mixer::rows ( int ideal_rows ) | |||
| } | |||
| } | |||
| int | |||
| Mixer::nstrips ( void ) const | |||
| { | |||
| return mixer_strips->children(); | |||
| } | |||
| /** retrun a pointer to the track named /name/, or NULL if no track is named /name/ */ | |||
| Mixer_Strip * | |||
| Mixer::track_by_name ( const char *name ) | |||
| @@ -31,6 +31,7 @@ | |||
| class Fl_Blink_Button; | |||
| class Fl_Flowpack; | |||
| class Fl_Menu_Bar; | |||
| class Spatialization_Console; | |||
| namespace OSC { class Endpoint; } | |||
| #include <lo/lo.h> | |||
| @@ -55,7 +56,6 @@ private: | |||
| Fl_Color system_colors[3]; | |||
| Mixer_Strip* track_by_name ( const char *name ); | |||
| Mixer_Strip* track_by_number ( int n ); | |||
| void snapshot ( void ); | |||
| static void snapshot ( void *v ) { ((Mixer*)v)->snapshot(); } | |||
| @@ -91,6 +91,11 @@ private: | |||
| public: | |||
| static Spatialization_Console *spatialization_console; | |||
| int nstrips ( void ) const; | |||
| Mixer_Strip* track_by_number ( int n ); | |||
| void update_frequency ( float f ); | |||
| void status ( const char *s ) { | |||
| @@ -688,6 +688,12 @@ Mixer_Strip::menu ( void ) const | |||
| return m; | |||
| } | |||
| Controller_Module * | |||
| Mixer_Strip::spatializer ( void ) | |||
| { | |||
| return spatialization_controller; | |||
| } | |||
| int | |||
| Mixer_Strip::handle ( int m ) | |||
| { | |||
| @@ -141,6 +141,8 @@ protected: | |||
| public: | |||
| Controller_Module *spatializer ( void ); | |||
| void send_feedback ( void ); | |||
| int number ( void ) const; | |||
| static bool import_strip ( const char *filename ); | |||
| @@ -248,7 +248,7 @@ public: | |||
| connected_port()->_module->handle_control_changed( connected_port() ); | |||
| } | |||
| float control_value ( ) const | |||
| float control_value ( void ) const | |||
| { | |||
| if ( buffer() ) | |||
| return *((float*)buffer()); | |||
| @@ -284,6 +284,10 @@ public: | |||
| if ( _connected && _connected != (void*)0x01 ) | |||
| { | |||
| _connected->_connected = NULL; | |||
| if ( _connected->_module ) | |||
| _connected->_module->handle_control_disconnect( this ); | |||
| _connected = NULL; | |||
| } | |||
| else | |||
| @@ -464,7 +468,7 @@ public: | |||
| /* called whenever the value of a control port is changed. | |||
| This can be used to take appropriate action from the GUI thread */ | |||
| virtual void handle_control_changed ( Port * ); | |||
| virtual void handle_control_disconnect ( Port * ) {} | |||
| /* called whenever the name of the chain changes (usually because | |||
| * the name of the mixer strip changed). */ | |||
| virtual void handle_chain_name_changed (); | |||
| @@ -58,12 +58,16 @@ Panner::point_bbox ( const Point *p, int *X, int *Y, int *W, int *H ) const | |||
| Panner::Point * | |||
| Panner::event_point ( void ) | |||
| { | |||
| for ( int i = _ins; i--; ) | |||
| for ( int i = _points.size(); i--; ) | |||
| { | |||
| int px, py, pw, ph; | |||
| Point *p = &_points[ i ]; | |||
| if ( ! p->visible ) | |||
| continue; | |||
| point_bbox( p, &px, &py, &pw, &ph ); | |||
| // printf( "%d, %d -- %d %d %d %d\n", Fl::event_x(), Fl::event_y(), px, py, pw, ph ); | |||
| @@ -120,7 +124,6 @@ Panner::draw ( void ) | |||
| goto done; | |||
| } | |||
| /* tx += b; */ | |||
| /* ty += b; */ | |||
| /* tw -= b * 2; */ | |||
| @@ -131,12 +134,14 @@ Panner::draw ( void ) | |||
| fl_color( FL_WHITE ); | |||
| for ( unsigned int i = 0; i < _points.size(); i++ ) | |||
| { | |||
| Point *p = &_points[0]; | |||
| Point *p = &_points[i]; | |||
| // Fl_Color c = (Fl_Color)(10 + i); | |||
| if ( ! p->visible ) | |||
| continue; | |||
| Fl_Color c = fl_color_add_alpha( fl_rgb_color( 192, 192, 206 ), 127 ); | |||
| Fl_Color c = fl_color_add_alpha( p->color, 127 ); | |||
| int px, py, pw, ph; | |||
| point_bbox( p, &px, &py, &pw, &ph ); | |||
| @@ -151,7 +156,7 @@ Panner::draw ( void ) | |||
| py - ( po * 12 ), | |||
| pw + ( po * 24 ), ph + (po * 24 )); | |||
| fl_color( fl_color_add_alpha( fl_rgb_color( 254,254,254 ), 254 ) ); | |||
| // fl_color( fl_color_add_alpha( fl_rgb_color( 254,254,254 ), 254 ) ); | |||
| fl_pie( px + 5, py + 5, pw - 10, ph - 10, 0, 360 ); | |||
| @@ -176,8 +181,8 @@ Panner::draw ( void ) | |||
| const char *s = p->label; | |||
| fl_color( fl_rgb_color( 125,125,130 ) ); | |||
| fl_font( FL_HELVETICA, ph + 2 ); | |||
| fl_color( fl_color_add_alpha( fl_rgb_color( 220,255,255 ), 127 ) ); | |||
| fl_font( FL_HELVETICA_BOLD_ITALIC, 12 ); | |||
| fl_draw( s, px + 20, py + 1, 50, ph - 1, FL_ALIGN_LEFT ); | |||
| } | |||
| @@ -221,10 +226,10 @@ Panner::handle ( int m ) | |||
| return 1; | |||
| } | |||
| case FL_RELEASE: | |||
| if ( Fl::event_button1() && drag ) | |||
| if ( drag ) | |||
| { | |||
| drag = NULL; | |||
| do_callback(); | |||
| drag = NULL; | |||
| redraw(); | |||
| return 1; | |||
| } | |||
| @@ -233,6 +238,7 @@ Panner::handle ( int m ) | |||
| case FL_MOUSEWHEEL: | |||
| { | |||
| /* TODO: place point on opposite face of sphere */ | |||
| return 0; | |||
| } | |||
| case FL_DRAG: | |||
| { | |||
| @@ -33,6 +33,7 @@ class Panner : public Fl_Widget | |||
| void draw_the_box( int, int, int, int ); | |||
| public: | |||
| struct Point | |||
| { | |||
| /* axes */ | |||
| @@ -43,9 +44,13 @@ class Panner : public Fl_Widget | |||
| float a; | |||
| const char *label; | |||
| void *userdata; | |||
| Fl_Color color; | |||
| bool visible; | |||
| Point ( ) : d( 0.0f ), a( 0.0f ), label(0) { } | |||
| Point ( float D, float A ) : d( D ), a( A ), label(0) { } | |||
| Point ( ) : d( 0.0f ), a( 0.0f ), label(0), visible(1){ } | |||
| Point ( float D, float A ) : d( D ), a( A ), label(0), visible(1) { } | |||
| /** translate angle /a/ into x/y coords and place the result in /X/ and /Y/ */ | |||
| void | |||
| @@ -125,6 +130,7 @@ class Panner : public Fl_Widget | |||
| }; | |||
| private: | |||
| /* channel configuration */ | |||
| int _ins, | |||
| @@ -183,8 +189,19 @@ public: | |||
| _points.push_back( Point( 1, 0 ) ); | |||
| } | |||
| void clear_points ( void ) { _points.clear(); } | |||
| void add_point( Panner::Point &p ) | |||
| { | |||
| _points.push_back( p ); | |||
| } | |||
| virtual ~Panner ( ) { } | |||
| Panner::Point *point ( int i ); | |||
| int points ( void ) const { return _points.size(); } | |||
| Panner::Point *pushed ( void ) { return drag; } | |||
| }; | |||
| @@ -0,0 +1,144 @@ | |||
| /*******************************************************************************/ | |||
| /* Copyright (C) 2009 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 <string.h> | |||
| #include <stdlib.h> | |||
| #include <stdio.h> | |||
| #include <math.h> | |||
| #include <FL/fl_draw.H> | |||
| #include "Module.H" | |||
| #include "Spatialization_Console.H" | |||
| #include "Controller_Module.H" | |||
| #include "Chain.H" | |||
| #include "Panner.H" | |||
| #include "Mixer_Strip.H" | |||
| #include "Mixer.H" | |||
| #include "debug.h" | |||
| Spatialization_Console::Spatialization_Console ( void ) : Fl_Double_Window( 565, 565 ) | |||
| { | |||
| _resized = false; | |||
| _min_width = 100; | |||
| label( "Spatialization Console" ); | |||
| fl_font( FL_HELVETICA, 14 ); | |||
| panner = new Panner( 25,25, 512, 512 ); | |||
| panner->callback( cb_panner_value_handle, this ); | |||
| panner->when( FL_WHEN_CHANGED ); | |||
| end(); | |||
| make_controls(); | |||
| } | |||
| Spatialization_Console::~Spatialization_Console ( ) | |||
| { | |||
| // controls_by_port.clear(); | |||
| } | |||
| void | |||
| Spatialization_Console::make_controls ( void ) | |||
| { | |||
| panner->clear_points(); | |||
| for ( int i = 0; i < mixer->nstrips(); i++ ) | |||
| { | |||
| Mixer_Strip *o = mixer->track_by_number( i ); | |||
| if ( o->spatializer() ) | |||
| { | |||
| Panner::Point p; | |||
| p.color = o->color(); | |||
| p.userdata = o->spatializer(); | |||
| p.label = o->name(); | |||
| if ( o->spatializer()->is_controlling() ) | |||
| { | |||
| p.visible = true; | |||
| p.azimuth( o->spatializer()->control_output[0].control_value() ); | |||
| p.elevation( o->spatializer()->control_output[1].control_value() ); | |||
| } | |||
| else | |||
| p.visible = false; | |||
| panner->add_point(p); | |||
| } | |||
| } | |||
| panner->redraw(); | |||
| } | |||
| void | |||
| Spatialization_Console::cb_panner_value_handle ( Fl_Widget *w, void *v ) | |||
| { | |||
| // callback_data *cd = (callback_data*)v; | |||
| Spatialization_Console *sc = (Spatialization_Console*)v; | |||
| Panner::Point *p = sc->panner->pushed(); | |||
| Controller_Module *cm = (Controller_Module*)p->userdata; | |||
| cm->control_output[0].control_value( p->azimuth() ); | |||
| cm->control_output[1].control_value( p->elevation() ); | |||
| } | |||
| /* Display changes initiated via automation or from other parts of the GUI */ | |||
| void | |||
| Spatialization_Console::handle_control_changed ( Controller_Module *m ) | |||
| { | |||
| if ( Fl::pushed() == panner ) | |||
| return; | |||
| for ( int i = 0; i < panner->points(); i++ ) | |||
| { | |||
| Panner::Point *p = panner->point(i); | |||
| if ( p->userdata == m ) | |||
| { | |||
| p->azimuth( m->control_output[0].control_value() ); | |||
| p->elevation( m->control_output[1].control_value() ); | |||
| if ( panner->visible_r() ) | |||
| panner->redraw(); | |||
| break; | |||
| } | |||
| } | |||
| } | |||
| void | |||
| Spatialization_Console::update ( void ) | |||
| { | |||
| make_controls(); | |||
| } | |||
| @@ -0,0 +1,56 @@ | |||
| /*******************************************************************************/ | |||
| /* Copyright (C) 2009 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 <Module.H> | |||
| class Fl_Pack; | |||
| class Fl_Flowpack; | |||
| class Module; | |||
| class Fl_Menu_Button; | |||
| class Panner; | |||
| class Controller_Module; | |||
| #include <vector> | |||
| class Spatialization_Console : public Fl_Double_Window | |||
| { | |||
| Panner *panner; | |||
| static void cb_panner_value_handle ( Fl_Widget *w, void *v ); | |||
| void make_controls ( void ); | |||
| bool _resized; | |||
| int _min_width; | |||
| int azimuth_port_number; | |||
| int elevation_port_number; | |||
| std::vector<Fl_Widget*> controls_by_port; | |||
| public: | |||
| void handle_control_changed ( Controller_Module *m ); | |||
| void update ( void ); | |||
| Spatialization_Console ( ); | |||
| virtual ~Spatialization_Console ( ); | |||
| }; | |||
| @@ -65,6 +65,7 @@ src/Panner.C | |||
| src/Plugin_Module.C | |||
| src/Project.C | |||
| src/main.C | |||
| src/Spatialization_Console.C | |||
| ''', | |||
| target = 'non-mixer', | |||
| includes = ['.', 'src', '..', '../nonlib'], | |||