Mixer: Implement Spatialization Console.

This commit is contained in:
Jonathan Moore Liles 2013-06-25 22:28:51 -07:00
parent aedbca82be
commit 6d2aeaf405
12 changed files with 346 additions and 58 deletions

View File

@ -44,7 +44,7 @@
// needed for mixer->endpoint
#include "Mixer.H"
#include "Spatialization_Console.H"
#include "string_util.h"
@ -81,23 +81,37 @@ 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::handle_control_disconnect ( Module::Port *p )
{
if ( type() == SPATIALIZATION )
{
if ( Mixer::spatialization_console )
Mixer::spatialization_console->update();
}
}
void
Controller_Module::disconnect ( void )
{
for ( std::vector<Module::Port>::iterator i = control_output.begin();
i != control_output.end();
++i )
{
(*i).disconnect();
}
for ( unsigned int i = 0; i < control_output.size(); ++i )
control_output[i].disconnect();
}
@ -266,7 +280,6 @@ Controller_Module::connect_spatializer_to ( Module *m )
control_output[0].connect_to( azimuth_port );
control_output[1].connect_to( elevation_port );
{
clear();
Panner *o = new Panner( 0,0, 92,92 );
@ -309,8 +322,11 @@ Controller_Module::connect_spatializer_to ( Module *m )
}
_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;

View File

@ -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 );

View File

@ -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 )

View File

@ -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 ) {

View File

@ -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 )
{

View File

@ -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 );

View File

@ -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 ();

View File

@ -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:
{

View File

@ -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;
Point ( ) : d( 0.0f ), a( 0.0f ), label(0) { }
Point ( float D, float A ) : d( D ), a( A ), label(0) { }
bool visible;
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; }
};

View File

@ -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();
}

View File

@ -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 ( );
};

View File

@ -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'],