Massive renames.

pull/3/head
Jonathan Moore Liles 2008-04-18 23:16:21 -05:00
parent feb777a050
commit e54f63e605
33 changed files with 1304 additions and 1304 deletions

View File

@ -17,7 +17,7 @@
/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/*******************************************************************************/
#include "Audio_Track.H"
#include "Audio_Sequence.H"
#include "dsp.h"
@ -54,13 +54,13 @@ deurlify ( char *url )
/** event handler that supports DND of audio clips */
int
Audio_Track::handle ( int m )
Audio_Sequence::handle ( int m )
{
switch ( m )
{
case FL_DND_DRAG:
return Track::handle( m ) | 1;
return Sequence::handle( m ) | 1;
/* case FL_DND_ENTER: */
/* case FL_DND_LEAVE: */
@ -110,7 +110,7 @@ Audio_Track::handle ( int m )
return 1;
}
default:
return Track::handle( m );
return Sequence::handle( m );
}
}
@ -123,14 +123,14 @@ Audio_Track::handle ( int m )
/** determine region coverage and fill /buf/ with interleaved samples
* from /frame/ to /nframes/ for exactly /channels/ channels. */
nframes_t
Audio_Track::play ( sample_t *buf, nframes_t frame, nframes_t nframes, int channels )
Audio_Sequence::play ( sample_t *buf, nframes_t frame, nframes_t nframes, int channels )
{
sample_t *cbuf = new sample_t[ nframes ];
memset( cbuf, 0, nframes * sizeof( sample_t ) );
/* quick and dirty--let the regions figure out coverage for themselves */
for ( list <Track_Widget *>::const_iterator i = _widgets.begin();
for ( list <Sequence_Widget *>::const_iterator i = _widgets.begin();
i != _widgets.end(); i++ )
{
const Region *r = (Region*)(*i);
@ -158,7 +158,7 @@ Audio_Track::play ( sample_t *buf, nframes_t frame, nframes_t nframes, int chann
/* /\* THREAD: RT *\/ */
/* nframes_t */
/* Audio_Track::process ( nframes_t nframes ) */
/* Audio_Sequence::process ( nframes_t nframes ) */
/* { */
/* return disktream->process( nframes ); */
/* } */

View File

@ -19,36 +19,36 @@
#pragma once
#include "Track.H"
#include "Sequence.H"
#include "Region.H"
#include <FL/Fl_Input.H>
class Audio_Track : public Track
class Audio_Sequence : public Sequence
{
public:
Audio_Track ( int X, int Y, int W, int H ) : Track( X, Y, W, H )
Audio_Sequence ( int X, int Y, int W, int H ) : Sequence( X, Y, W, H )
{
log_create();
}
~Audio_Track ( )
~Audio_Sequence ( )
{
log_destroy();
}
Track * clone_empty ( void )
Sequence * clone_empty ( void )
{
Audio_Track *t = new Audio_Track( x(), y(), w(), h() );
Audio_Sequence *t = new Audio_Sequence( x(), y(), w(), h() );
return t;
}
const char *class_name ( void ) { return "Audio_Track"; }
const char *class_name ( void ) { return "Audio_Sequence"; }
int handle ( int m );
void dump ( void );

View File

@ -19,9 +19,9 @@
#pragma once
#include "Track_Point.H"
#include "Sequence_Point.H"
class Control_Point : public Track_Point
class Control_Point : public Sequence_Point
{
float _y;
@ -74,7 +74,7 @@ protected:
{
int i;
sscanf( v, "%X", &i );
Track *t = (Track*)Loggable::find( i );
Sequence *t = (Sequence*)Loggable::find( i );
assert( t );
@ -113,7 +113,7 @@ public:
}
Control_Point ( Track *t, nframes_t when, float y )
Control_Point ( Sequence *t, nframes_t when, float y )
{
_track = t;
_y = y;
@ -130,7 +130,7 @@ public:
_y = rhs._y;
}
Track_Widget *clone ( const Track_Widget *r )
Sequence_Widget *clone ( const Sequence_Widget *r )
{
return new Control_Point( *(Control_Point*)r );
}
@ -147,7 +147,7 @@ public:
int
handle ( int m )
{
int r = Track_Widget::handle( m );
int r = Sequence_Widget::handle( m );
switch ( m )
{

View File

@ -19,28 +19,28 @@
#pragma once
#include "Track.H"
#include "Sequence.H"
#include "Control_Point.H"
class Control_Track : public Track
class Control_Sequence : public Sequence
{
public:
Control_Track ( int X, int Y, int W, int H ) : Track( X, Y, W, H )
Control_Sequence ( int X, int Y, int W, int H ) : Sequence( X, Y, W, H )
{
color( fl_darker( FL_GREEN ) );
log_create();
}
~Control_Track ( )
~Control_Sequence ( )
{
log_destroy();
}
const char *class_name ( void ) { return "Control_Track"; }
const char *class_name ( void ) { return "Control_Sequence"; }
void
draw ( void )
@ -63,11 +63,11 @@ public:
fl_begin_complex_polygon();
list <Track_Widget *>::const_iterator e = _widgets.end();
list <Sequence_Widget *>::const_iterator e = _widgets.end();
e--;
if ( _widgets.size() )
for ( list <Track_Widget *>::const_iterator r = _widgets.begin(); ; r++ )
for ( list <Sequence_Widget *>::const_iterator r = _widgets.begin(); ; r++ )
{
if ( r == _widgets.begin() )
{
@ -92,7 +92,7 @@ public:
timeline->draw_measure_lines( x(), y(), w(), h(), color() );
for ( list <Track_Widget *>::const_iterator r = _widgets.begin(); r != _widgets.end(); r++ )
for ( list <Sequence_Widget *>::const_iterator r = _widgets.begin(); r != _widgets.end(); r++ )
(*r)->draw_box();
fl_pop_clip();
@ -101,7 +101,7 @@ public:
int
handle ( int m )
{
int r = Track::handle( m );
int r = Sequence::handle( m );
if ( r )
return r;

View File

@ -18,8 +18,8 @@
/*******************************************************************************/
#include "Disk_Stream.H"
#include "Track_Header.H"
#include "Audio_Track.H"
#include "Track.H"
#include "Audio_Sequence.H"
#include "Port.H"
#include "Engine.H" // for locking.
@ -53,7 +53,7 @@
float Disk_Stream::seconds_to_buffer = 5.0f;
// size_t Disk_Stream::disk_block_frames = 2048;
Disk_Stream::Disk_Stream ( Track_Header *th, float frame_rate, nframes_t nframes, int channels ) : _th( th )
Disk_Stream::Disk_Stream ( Track *th, float frame_rate, nframes_t nframes, int channels ) : _th( th )
{
_frame = 0;
_thread = 0;
@ -99,10 +99,10 @@ Disk_Stream::shutdown ( void )
pthread_join( _thread, NULL );
}
Audio_Track *
Audio_Sequence *
Disk_Stream::track ( void )
{
return (Audio_Track*)_th->track();
return (Audio_Sequence*)_th->track();
}
/** start Disk_Stream thread */

View File

@ -32,8 +32,8 @@
#include <vector>
using std::vector;
class Track_Header;
class Audio_Track;
class Track;
class Audio_Sequence;
class Disk_Stream : public Mutex
{
@ -42,7 +42,7 @@ protected:
pthread_t _thread; /* io thread */
Track_Header *_th; /* Track_Header we belong to */
Track *_th; /* Track we belong to */
nframes_t _nframes; /* buffer size */
@ -59,7 +59,7 @@ protected:
int channels ( void ) const { return _rb.size(); }
Audio_Track * track ( void );
Audio_Sequence * track ( void );
static void *disk_thread ( void *arg );
@ -84,7 +84,7 @@ public:
/* must be set before any Disk_Streams are created */
static float seconds_to_buffer;
Disk_Stream ( Track_Header *th, float frame_rate, nframes_t nframes, int channels );
Disk_Stream ( Track *th, float frame_rate, nframes_t nframes, int channels );
virtual ~Disk_Stream ( );

View File

@ -3,11 +3,11 @@ SRCS= \
Waveform.C \
Region.C \
main.C \
Track.C \
Audio_Track.C \
Sequence.C \
Audio_Sequence.C \
Timeline.C \
Track_Header.C \
Track_Widget.C \
Track.C \
Sequence_Widget.C \
Tempo_Point.C \
Time_Point.C \
Peaks.C \

View File

@ -23,8 +23,8 @@
/* FIXME: we shouldn't depend on these */
#include "Timeline.H"
#include "Engine.H"
#include "Audio_Track.H"
#include "Track_Header.H"
#include "Audio_Sequence.H"
#include "Track.H"
#include "Port.H"
#include "Playback_DS.H"

View File

@ -27,7 +27,7 @@ class Playback_DS : public Disk_Stream
public:
Playback_DS ( Track_Header *th, float frame_rate, nframes_t nframes, int channels ) :
Playback_DS ( Track *th, float frame_rate, nframes_t nframes, int channels ) :
Disk_Stream( th, frame_rate, nframes, channels )
{
run();

View File

@ -22,8 +22,8 @@
/* FIXME: we shouldn't depend on these */
#include "Timeline.H"
#include "Engine.H"
#include "Audio_Track.H"
#include "Track_Header.H"
#include "Audio_Sequence.H"
#include "Track.H"
#include "Port.H"
#include "Record_DS.H"

View File

@ -37,7 +37,7 @@ class Record_DS : public Disk_Stream
public:
Record_DS ( Track_Header *th, float frame_rate, nframes_t nframes, int channels ) :
Record_DS ( Track *th, float frame_rate, nframes_t nframes, int channels ) :
Disk_Stream( th, frame_rate, nframes, channels )
{
sem_destroy( &_blocks );

View File

@ -17,7 +17,7 @@
/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/*******************************************************************************/
#include "Track.H"
#include "Sequence.H"
#include "Region.H"
#include "Timeline.H"
#include "Waveform.H"
@ -103,7 +103,7 @@ Region::init ( void )
/* copy constructor */
Region::Region ( const Region & rhs )
{
*((Track_Widget*)this) = (Track_Widget &)rhs;
*((Sequence_Widget*)this) = (Sequence_Widget &)rhs;
_clip = rhs._clip;
_scale = rhs._scale;
@ -114,8 +114,8 @@ Region::Region ( const Region & rhs )
log_create();
}
Track_Widget *
Region::clone ( const Track_Widget *r )
Sequence_Widget *
Region::clone ( const Sequence_Widget *r )
{
return new Region( *(Region*)r );
}
@ -132,7 +132,7 @@ Region::Region ( Audio_File *c )
/* used when DND importing */
Region::Region ( Audio_File *c, Track *t, nframes_t o )
Region::Region ( Audio_File *c, Sequence *t, nframes_t o )
{
init();
_clip = c;
@ -242,11 +242,11 @@ Region::handle ( int m )
switch ( m )
{
case FL_ENTER:
Track_Widget::handle( m );
Sequence_Widget::handle( m );
redraw();
break;
case FL_LEAVE:
Track_Widget::handle( m );
Sequence_Widget::handle( m );
redraw();
break;
case FL_KEYBOARD:
@ -335,7 +335,7 @@ Region::handle ( int m )
normalize();
else
{
if ( Track_Widget::current() == this )
if ( Sequence_Widget::current() == this )
{
if ( selected() )
deselect();
@ -390,14 +390,14 @@ Region::handle ( int m )
}
else
return Track_Widget::handle( m );
return Sequence_Widget::handle( m );
}
break;
}
case FL_RELEASE:
{
Track_Widget::handle( m );
Sequence_Widget::handle( m );
copied = false;
if ( trimming != NO )
@ -470,10 +470,10 @@ Region::handle ( int m )
}
}
ret = Track_Widget::handle( m );
ret = Sequence_Widget::handle( m );
return ret | 1;
default:
return Track_Widget::handle( m );
return Sequence_Widget::handle( m );
break;
}

View File

@ -19,18 +19,18 @@
#pragma once
#include "Audio_File.H"
#include "Track.H"
#include "Sequence.H"
#include "Timeline.H"
/* Regions are "virtual" FLTK widgets; this is necessary because the
* dimensions of real FLTK widgets are limited to 16-bits, which is
* far too little for our purposes */
#include "Track_Widget.H"
#include "Sequence_Widget.H"
#include "Loggable.H"
class Region : public Track_Widget
class Region : public Sequence_Widget
{
public:
@ -98,7 +98,7 @@ private:
Fade _fade_in;
Fade _fade_out;
friend class Track_Header; /* for _clip */
friend class Track; /* for _clip */
protected:
const char *class_name ( void ) { return "Region"; }
@ -166,7 +166,7 @@ protected:
{
int i;
sscanf( v, "%X", &i );
Track *t = (Track*)Loggable::find( i );
Sequence *t = (Sequence*)Loggable::find( i );
assert( t );
@ -200,7 +200,7 @@ public:
bool current ( void ) const { return this == belowmouse(); }
friend class Track_Header; /* for _clip in Track_Header::write() */
friend class Track; /* for _clip in Track::write() */
public:
@ -216,7 +216,7 @@ public:
}
Track_Widget *clone ( const Track_Widget *r );
Sequence_Widget *clone ( const Sequence_Widget *r );
~Region ( )
{
@ -228,7 +228,7 @@ public:
Region ( const Region & rhs );
Region ( Audio_File *c );
Region ( Audio_File *c, Track *t, nframes_t o );
Region ( Audio_File *c, Sequence *t, nframes_t o );
int handle ( int m );
void draw_fade ( const Fade &fade, Fade::fade_dir_e dir, bool filled, int X, int W );

View File

@ -20,9 +20,9 @@
#pragma once
#include "Loggable.H"
#include "Track_Point.H"
#include "Sequence_Point.H"
class Ruler_Point : public Track_Point
class Ruler_Point : public Sequence_Point
{
public:
@ -73,7 +73,7 @@ protected:
{
int i;
sscanf( v, "%X", &i );
Track *t = (Track*)Loggable::find( i );
Sequence *t = (Sequence*)Loggable::find( i );
assert( t );
@ -123,7 +123,7 @@ public:
_label = strdup( rhs._label );
}
Track_Widget *clone ( const Track_Widget *r )
Sequence_Widget *clone ( const Sequence_Widget *r )
{
return new Ruler_Point( *(Ruler_Point*)r );
}
@ -138,7 +138,7 @@ public:
int
handle ( int m )
{
int r = Track_Widget::handle( m );
int r = Sequence_Widget::handle( m );
if ( m == FL_RELEASE )
{

View File

@ -19,16 +19,16 @@
#pragma once
#include "Track.H"
#include "Sequence.H"
#include "Ruler_Point.H"
#include "Timeline.H"
class Ruler_Track : public Track
class Ruler_Sequence : public Sequence
{
public:
Ruler_Track ( int X, int Y, int W, int H ) : Track ( X, Y, W, H )
Ruler_Sequence ( int X, int Y, int W, int H ) : Sequence ( X, Y, W, H )
{
box( FL_UP_BOX );
}
@ -36,7 +36,7 @@ public:
void
draw ( void )
{
Track::draw();
Sequence::draw();
timeline->draw_measure_BBT( x(), y(), w(), h(), FL_WHITE );
}

417
Timeline/Sequence.C Normal file
View File

@ -0,0 +1,417 @@
/*******************************************************************************/
/* Copyright (C) 2008 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 "Sequence.H"
#include "Timeline.H"
#include "Region.H"
#include <FL/fl_draw.H>
queue <Sequence_Widget *> Sequence::_delete_queue;
Sequence::Sequence ( int X, int Y, int W, int H ) : Fl_Widget( X, Y, W, H )
{
_name = NULL;
box( FL_DOWN_BOX );
color( fl_darker( FL_GRAY ) );
align( FL_ALIGN_LEFT );
// log_create();
}
Sequence::~Sequence ( )
{
/* FIXME: what to do with regions? */
parent()->redraw();
parent()->remove( this );
// log_destroy();
}
void
Sequence::sort ( void )
{
_widgets.sort( Sequence_Widget::sort_func );
}
/** return a pointer to the widget that /r/ overlaps, or NULL if none. */
Sequence_Widget *
Sequence::overlaps ( Sequence_Widget *r )
{
for ( list <Sequence_Widget *>::const_iterator i = _widgets.begin(); i != _widgets.end(); i++ )
{
if ( *i == r ) continue;
if ( ! ( (*i)->offset() > r->offset() + r->length() || (*i)->offset() + (*i)->length() < r->offset() ) )
return *i;
}
return NULL;
}
#include "Waveform.H"
void
Sequence::draw ( void )
{
if ( ! fl_not_clipped( x(), y(), w(), h() ) )
return;
fl_push_clip( x(), y(), w(), h() );
draw_box();
int X, Y, W, H;
fl_clip_box( x(), y(), w(), h(), X, Y, W, H );
if ( Sequence_Widget::pushed() && Sequence_Widget::pushed()->track() == this )
{
/* make sure the Sequence_Widget::pushed widget is above all others */
remove( Sequence_Widget::pushed() );
add( Sequence_Widget::pushed() );
}
int xfades = 0;
// printf( "track::draw %d,%d %dx%d\n", X,Y,W,H );
timeline->draw_measure_lines( x(), y(), w(), h(), color() );
for ( list <Sequence_Widget *>::const_iterator r = _widgets.begin(); r != _widgets.end(); r++ )
(*r)->draw_box();
for ( list <Sequence_Widget *>::const_iterator r = _widgets.begin(); r != _widgets.end(); r++ )
(*r)->draw();
/* draw crossfades */
for ( list <Sequence_Widget *>::const_iterator r = _widgets.begin(); r != _widgets.end(); r++ )
{
Sequence_Widget *o = overlaps( *r );
if ( o )
{
if ( *o <= **r )
{
/* if ( o->x() == (*r)->x() && o->w() == (*r)->w() ) */
/* printf( "complete superposition\n" ); */
if ( (*r)->x() >= o->x() && (*r)->x() + (*r)->w() <= o->x() + o->w() )
/* completely inside */
continue;
++xfades;
Rectangle b( (*r)->x(),
o->y(),
(o->x() + o->w()) - (*r)->x(),
o->h() );
Fl_Color c = fl_color_average( o->box_color(), (*r)->box_color(), 0.50f );
c = fl_color_average( c, FL_YELLOW, 0.30f );
fl_push_clip( b.x, b.y, b.w, b.h );
draw_box( FL_FLAT_BOX, b.x - 100, b.y, b.w + 200, b.h, c );
draw_box( FL_UP_FRAME, b.x - 100, b.y, b.w + 200, b.h, c );
fl_pop_clip();
}
}
}
// printf( "There are %d xfades\n", xfades );
for ( list <Sequence_Widget *>::const_iterator r = _widgets.begin(); r != _widgets.end(); r++ )
{
Sequence_Widget *o = overlaps( *r );
if ( o )
{
if ( *o <= **r )
{
if ( (*r)->x() >= o->x() && (*r)->x() + (*r)->w() <= o->x() + o->w() )
/* completely inside */
continue;
Rectangle b( (*r)->x(), o->y(), (o->x() + o->w()) - (*r)->x(), o->h() );
/* draw overlapping waveforms in X-ray style. */
Waveform::fill = false;
/* Fl_Color oc = o->color(); */
/* Fl_Color rc = (*r)->color(); */
/* /\* give each region a different color *\/ */
/* o->color( FL_RED ); */
/* (*r)->color( FL_GREEN ); */
fl_push_clip( b.x, b.y, b.w, b.h );
o->draw();
(*r)->draw();
fl_pop_clip();
Waveform::fill = true;
/* o->color( oc ); */
/* (*r)->color( rc ); */
/* fl_color( FL_BLACK ); */
/* fl_line_style( FL_DOT, 4 ); */
/* b.x = (*r)->line_x(); */
/* b.w = min( 32767, (*r)->abs_w() ); */
/* fl_line( b.x, b.y, b.x + b.w, b.y + b.h ); */
/* fl_line( b.x, b.y + b.h, b.x + b.w, b.y ); */
/* fl_line_style( FL_SOLID, 0 ); */
// fl_pop_clip();
}
}
}
fl_pop_clip();
}
void
Sequence::remove ( Sequence_Widget *r )
{
// Logger _log( this );
_widgets.remove( r );
}
void
Sequence::remove_selected ( void )
{
Loggable::block_start();
for ( list <Sequence_Widget *>::iterator r = _widgets.begin(); r != _widgets.end(); )
if ( (*r)->selected() )
{
Sequence_Widget *t = *r;
_widgets.erase( r++ );
delete t;
}
else
++r;
Loggable::block_end();
}
Sequence_Widget *
Sequence::event_widget ( void )
{
nframes_t ets = timeline->xoffset + timeline->x_to_ts( Fl::event_x() - x() );
for ( list <Sequence_Widget *>::const_reverse_iterator r = _widgets.rbegin(); r != _widgets.rend(); r++ )
if ( ets > (*r)->offset() && ets < (*r)->offset() + (*r)->length() )
return (*r);
return NULL;
}
void
Sequence::select_range ( int X, int W )
{
nframes_t sts = timeline->xoffset + timeline->x_to_ts( X - x() );
nframes_t ets = sts + timeline->x_to_ts( W );
for ( list <Sequence_Widget *>::const_reverse_iterator r = _widgets.rbegin(); r != _widgets.rend(); r++ )
if ( ! ( (*r)->offset() > ets || (*r)->offset() + (*r)->length() < sts ) )
(*r)->select();
}
void
Sequence::add ( Sequence_Widget *r )
{
// Logger _log( this );
if ( r->track() )
{
r->redraw();
r->track()->remove( r );
// r->track()->redraw();
}
r->track( this );
_widgets.push_back( r );
sort();
}
/* snap /r/ to nearest edge */
void
Sequence::snap ( Sequence_Widget *r )
{
const int snap_pixels = 10;
const int rx1 = r->x();
const int rx2 = r->x() + r->w();
for ( list <Sequence_Widget*>::iterator i = _widgets.begin(); i != _widgets.end(); i++ )
{
const Sequence_Widget *w = (*i);
if ( w == r )
continue;
const int wx1 = w->x();
const int wx2 = w->x() + w->w();
if ( abs( rx1 - wx2 ) < snap_pixels )
{
r->offset( w->offset() + w->length() + 1 );
// printf( "snap: %lu | %lu\n", w->offset() + w->length(), r->offset() );
goto done;
}
if ( abs( rx2 - wx1 ) < snap_pixels )
{
r->offset( ( w->offset() - r->length() ) - 1 );
// printf( "snap: %lu | %lu\n", r->offset() + r->length(), w->offset() );
goto done;
}
}
{
int nx = timeline->nearest_line( r->abs_x() );
if ( nx >= 0 )
{
r->offset( timeline->x_to_ts( nx ) );
return;
}
}
// r->offset( timeline->x_to_ts( r->x() ) );
done:
return;
// r->resize();
// r->position( rx1, y() );
}
int
Sequence::handle ( int m )
{
switch ( m )
{
case FL_FOCUS:
return 1;
case FL_UNFOCUS:
return 1;
case FL_DND_ENTER:
printf( "enter\n" );
if ( Sequence_Widget::pushed() && Sequence_Widget::pushed()->track()->class_name() == class_name() )
{
add( Sequence_Widget::pushed() );
redraw();
}
case FL_DND_LEAVE:
return 1;
case FL_MOVE:
{
Sequence_Widget *r = event_widget();
if ( r != Sequence_Widget::belowmouse() )
{
if ( Sequence_Widget::belowmouse() )
Sequence_Widget::belowmouse()->handle( FL_LEAVE );
Sequence_Widget::belowmouse( r );
if ( r )
r->handle( FL_ENTER );
}
return 0;
}
default:
{
Sequence_Widget *r = Sequence_Widget::pushed() ? Sequence_Widget::pushed() : event_widget();
if ( r )
{
int retval = r->dispatch( m );
if ( retval && m == FL_PUSH )
{
take_focus();
Sequence_Widget::pushed( r );
}
if ( retval && m == FL_RELEASE )
Sequence_Widget::pushed( NULL );
Loggable::block_start();
while ( _delete_queue.size() )
{
Sequence_Widget *t = _delete_queue.front();
_delete_queue.pop();
if ( Sequence_Widget::pushed() == t )
Sequence_Widget::pushed( NULL );
if ( Sequence_Widget::belowmouse() == t )
{
Sequence_Widget::belowmouse()->handle( FL_LEAVE );
Sequence_Widget::belowmouse( NULL );
}
delete t;
}
Loggable::block_end();
return retval;
}
else
return Fl_Widget::handle( m );
}
}
}

131
Timeline/Sequence.H Normal file
View File

@ -0,0 +1,131 @@
/*******************************************************************************/
/* Copyright (C) 2008 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_Widget.H>
#include <FL/Fl_Group.H>
#include <FL/Fl.H>
// #include "Region.H"
#include <stdio.h>
#include "Loggable.H"
#include <assert.h>
#include <list>
// using namespace std;
class Region;
class Sequence_Widget;
#include "types.h"
/* This is the base class for all track types. */
class Sequence : public Fl_Widget, public Loggable
{
char *_name;
static queue <Sequence_Widget *> _delete_queue;
protected:
std::list <Sequence_Widget *> _widgets;
Sequence_Widget *event_widget ( void );
virtual const char *class_name ( void ) { return "Sequence"; }
void set ( char ** ) { return; }
char ** get ( void )
{
// char *r;
char **sa = (char**)malloc( sizeof( char* ) * 2);
sa[0] = (char*)malloc( (_widgets.size() * ((sizeof( int ) * 2) + 3)) + 1 );
sa[1] = NULL;
sa[0][0] = '\0';
/* char *s = sa[0]; */
/* s += sprintf( s, ":items " ); */
/* for ( list <Sequence_Widget *>::const_iterator i = _widgets.begin(); i != _widgets.end(); i++ ) */
/* { */
/* s += sprintf( s, "0x%X", ((Loggable*)(*i))->id() ); */
/* list <Sequence_Widget *>::const_iterator e = i; */
/* if ( ++e != _widgets.end() ) */
/* s += sprintf( s, "," ); */
/* } */
return sa;
}
public:
Sequence ( int X, int Y, int W, int H );
virtual ~Sequence ( );
const char * name ( void ) const { return _name; }
void name ( char *s ) { if ( _name ) free( _name ); _name = s; label( _name ); }
void sort ( void );
void remove ( Sequence_Widget *r );
void add ( Sequence_Widget *r );
void select_range ( int X, int W );
void remove_selected ( void );
const std::list <Sequence_Widget *> widgets ( void ) const { return _widgets; }
void queue_delete ( Sequence_Widget *r )
{
_delete_queue.push( r );
}
Sequence_Widget * overlaps ( Sequence_Widget *r );
virtual Sequence * clone ( void )
{
assert( 0 );
}
virtual Sequence * clone_empty ( void )
{
return NULL;
}
virtual void snap ( Sequence_Widget *r );
virtual int handle ( int m );
virtual void draw ( void );
virtual nframes_t process ( nframes_t nframes ) { return 0; }
};

View File

@ -19,9 +19,9 @@
#pragma once
#include "Track_Widget.H"
#include "Sequence_Widget.H"
class Track_Point : public Track_Widget
class Sequence_Point : public Sequence_Widget
{
protected:
@ -38,20 +38,20 @@ public:
int abs_w ( void ) const { return 10; }
nframes_t length ( void ) const { return timeline->x_to_ts( abs_w() ); }
Track_Point ( )
Sequence_Point ( )
{
_label = NULL;
}
virtual ~Track_Point ( )
virtual ~Sequence_Point ( )
{
}
virtual void
draw ( void )
{
Track_Widget::draw();
Sequence_Widget::draw();
draw_label( _label, align() );
}

View File

@ -25,15 +25,15 @@
the original?
*/
#include "Track_Widget.H"
#include "Sequence_Widget.H"
list <Track_Widget *> Track_Widget::_selection;
Track_Widget * Track_Widget::_current = NULL;
Track_Widget * Track_Widget::_pushed = NULL;
Track_Widget * Track_Widget::_belowmouse = NULL;
list <Sequence_Widget *> Sequence_Widget::_selection;
Sequence_Widget * Sequence_Widget::_current = NULL;
Sequence_Widget * Sequence_Widget::_pushed = NULL;
Sequence_Widget * Sequence_Widget::_belowmouse = NULL;
void
Track_Widget::draw_label ( const char *label, Fl_Align align, Fl_Color color )
Sequence_Widget::draw_label ( const char *label, Fl_Align align, Fl_Color color )
{
int X, Y;
@ -109,9 +109,9 @@ Track_Widget::draw_label ( const char *label, Fl_Align align, Fl_Color color )
}
int
Track_Widget::dispatch ( int m )
Sequence_Widget::dispatch ( int m )
{
Track_Widget::_current = this;
Sequence_Widget::_current = this;
if ( selected() )
{
@ -120,7 +120,7 @@ Track_Widget::dispatch ( int m )
int r = 0;
for ( list <Track_Widget *>::iterator i = _selection.begin(); i != _selection.end(); i++ )
for ( list <Sequence_Widget *>::iterator i = _selection.begin(); i != _selection.end(); i++ )
if ( *i != this )
r |= (*i)->handle( m );
@ -136,7 +136,7 @@ Track_Widget::dispatch ( int m )
/* base hanlde just does basic dragging */
int
Track_Widget::handle ( int m )
Sequence_Widget::handle ( int m )
{
int X = Fl::event_x();
int Y = Fl::event_y();
@ -199,7 +199,7 @@ Track_Widget::handle ( int m )
// _r->offset = timeline->x_to_ts( nx ) + timeline->xoffset;
offset( timeline->x_to_ts( nx ) + timeline->xoffset );
if ( Track_Widget::_current == this )
if ( Sequence_Widget::_current == this )
_track->snap( this );
}

View File

@ -19,14 +19,14 @@
#pragma once
#include "Track.H"
#include "Sequence.H"
#include "Loggable.H"
#include "Timeline.H"
#include <list>
#include <algorithm>
using namespace std;
class Track_Widget;
class Sequence_Widget;
struct Drag
{
@ -35,7 +35,7 @@ struct Drag
int y;
int state;
Track_Widget *original;
Sequence_Widget *original;
Drag( int X, int Y ) : x( X ), y( Y ) { state = 0; }
};
@ -48,25 +48,25 @@ struct Range
};
/* Base class for virtual widget on a track */
class Track_Widget : public Loggable
class Sequence_Widget : public Loggable
{
static list <Track_Widget *> _selection; /* all the widgets making up the selection */
static list <Sequence_Widget *> _selection; /* all the widgets making up the selection */
/* FIXME: is this not the same as /pushed/? */
static Track_Widget * _current; /* the widget initiating events that affect the selection */
static Sequence_Widget * _current; /* the widget initiating events that affect the selection */
/* these are actually managed in the Track classes */
static Track_Widget * _pushed; /* the widget receiving drag events (a copy) */
static Track_Widget * _original; /* the original of the /pushed/ widget */
static Track_Widget * _belowmouse; /* the widget below the mouse cursor */
/* these are actually managed in the Sequence classes */
static Sequence_Widget * _pushed; /* the widget receiving drag events (a copy) */
static Sequence_Widget * _original; /* the original of the /pushed/ widget */
static Sequence_Widget * _belowmouse; /* the widget below the mouse cursor */
/* can't have this */
Track_Widget ( const Track_Widget &rhs );
Sequence_Widget ( const Sequence_Widget &rhs );
protected:
Track *_track; /* track this region belongs to */
Sequence *_track; /* track this region belongs to */
Range _range; /* range for playback */
Range *_r; /* range for editing / display (points to the same thing as above, except for when dragging etc) */
@ -78,7 +78,7 @@ protected:
public:
Track_Widget ( )
Sequence_Widget ( )
{
_track = NULL;
@ -89,7 +89,7 @@ public:
_drag = NULL;
}
virtual ~Track_Widget ( )
virtual ~Sequence_Widget ( )
{
redraw();
@ -98,8 +98,8 @@ public:
_selection.remove( this );
}
const Track_Widget &
operator= ( const Track_Widget &rhs )
const Sequence_Widget &
operator= ( const Sequence_Widget &rhs )
{
if ( this == &rhs )
return *this;
@ -114,12 +114,12 @@ public:
}
/* Track_Widget ( const Track_Widget &rhs ) */
/* Sequence_Widget ( const Sequence_Widget &rhs ) */
/* { */
/* *this = rhs; */
/* } */
virtual Track_Widget *clone ( const Track_Widget *r ) = 0;
virtual Sequence_Widget *clone ( const Sequence_Widget *r ) = 0;
bool selected ( void )
{
@ -151,15 +151,15 @@ public:
delete _selection.front();
}
static Track_Widget *current ( void ) { return Track_Widget::_current; }
static Sequence_Widget *current ( void ) { return Sequence_Widget::_current; }
static Track_Widget *pushed ( void ) { return Track_Widget::_pushed; }
static Track_Widget *belowmouse ( void ) { return Track_Widget::_belowmouse; }
static Sequence_Widget *pushed ( void ) { return Sequence_Widget::_pushed; }
static Sequence_Widget *belowmouse ( void ) { return Sequence_Widget::_belowmouse; }
static void pushed ( Track_Widget *w ) { Track_Widget::_pushed = w; }
static void belowmouse ( Track_Widget *w ) { Track_Widget::_belowmouse = w; }
static void pushed ( Sequence_Widget *w ) { Sequence_Widget::_pushed = w; }
static void belowmouse ( Sequence_Widget *w ) { Sequence_Widget::_belowmouse = w; }
// static void pushed ( Track_Widget *w ) { Track_Widget::_pushed = w; }
// static void pushed ( Sequence_Widget *w ) { Sequence_Widget::_pushed = w; }
void begin_drag ( const Drag &d )
{
@ -190,7 +190,7 @@ public:
{
long d = where - _r->offset;
for ( list <Track_Widget *>::iterator i = _selection.begin(); i != _selection.end(); i++ )
for ( list <Sequence_Widget *>::iterator i = _selection.begin(); i != _selection.end(); i++ )
{
(*i)->redraw();
@ -243,8 +243,8 @@ public:
void color ( Fl_Color v ) { _color = v; }
Fl_Color box_color ( void ) { return _box_color; }
Track * track ( void ) const { return _track; }
void track ( Track *t ) { _track = t; }
Sequence * track ( void ) const { return _track; }
void track ( Sequence *t ) { _track = t; }
nframes_t offset ( void ) const { return _r->offset; }
// void offset ( nframes_t o ) { _r->offset = o; }
@ -285,13 +285,13 @@ public:
}
bool
operator< ( const Track_Widget & rhs )
operator< ( const Sequence_Widget & rhs )
{
return _r->offset < rhs._r->offset;
}
bool
operator<=( const Track_Widget & rhs )
operator<=( const Sequence_Widget & rhs )
{
return _r->offset <= rhs._r->offset;
}
@ -300,7 +300,7 @@ public:
virtual int handle ( int m );
static bool
sort_func ( Track_Widget *lhs, Track_Widget *rhs )
sort_func ( Sequence_Widget *lhs, Sequence_Widget *rhs )
{
return *lhs < *rhs;
}

View File

@ -19,7 +19,7 @@
#include "Tempo_Point.H"
#include "Tempo_Track.H"
#include "Tempo_Sequence.H"
#include "Timeline.H" // for timeline->tempo_track
char **
@ -101,7 +101,7 @@ Tempo_Point::~Tempo_Point ( )
int
Tempo_Point::handle ( int m )
{
int r = Track_Widget::handle( m );
int r = Sequence_Widget::handle( m );
if ( m == FL_RELEASE )
{

View File

@ -19,10 +19,10 @@
#pragma once
#include "Track_Point.H"
// #include "Tempo_Track.H"
#include "Sequence_Point.H"
// #include "Tempo_Sequence.H"
class Tempo_Point : public Track_Point
class Tempo_Point : public Sequence_Point
{
float _tempo;
@ -60,7 +60,7 @@ public:
_tempo = rhs._tempo;
}
Track_Widget *clone ( const Track_Widget *r )
Sequence_Widget *clone ( const Sequence_Widget *r )
{
return new Tempo_Point( *(Tempo_Point*)r );
}

View File

@ -19,17 +19,17 @@
#pragma once
#include "Track.H"
#include "Sequence.H"
#include "Tempo_Point.H"
#include <list>
class Tempo_Track : public Track
class Tempo_Sequence : public Sequence
{
public:
Tempo_Track ( int X, int Y, int W, int H ) : Track ( X, Y, W, H )
Tempo_Sequence ( int X, int Y, int W, int H ) : Sequence ( X, Y, W, H )
{
box( FL_UP_BOX );
}
@ -39,7 +39,7 @@ public:
{
// sort();
for ( std::list <Track_Widget *>::const_reverse_iterator i = _widgets.rbegin();
for ( std::list <Sequence_Widget *>::const_reverse_iterator i = _widgets.rbegin();
i != _widgets.rend(); i++ )
{
if ( (*i)->offset() < when )

View File

@ -18,7 +18,7 @@
/*******************************************************************************/
#include "Time_Point.H"
#include "Time_Track.H"
#include "Time_Sequence.H"
#include "Timeline.H" // for timeline->time_track
char **

View File

@ -19,7 +19,7 @@
#pragma once
#include "Track_Point.H"
#include "Sequence_Point.H"
#include "Loggable.H"
struct time_sig
@ -43,7 +43,7 @@ struct time_sig
#define __CLASS__ "Time_Point"
class Time_Point : public Track_Point
class Time_Point : public Sequence_Point
{
time_sig _time;
@ -96,7 +96,7 @@ public:
_time = rhs._time;
}
Track_Widget *clone ( const Track_Widget *r )
Sequence_Widget *clone ( const Sequence_Widget *r )
{
return new Time_Point( *(Time_Point*)r );
}
@ -116,7 +116,7 @@ public:
int
handle ( int m )
{
int r = Track_Widget::handle( m );
int r = Sequence_Widget::handle( m );
if ( m == FL_RELEASE )
{

View File

@ -19,18 +19,18 @@
#pragma once
#include "Track.H"
#include "Sequence.H"
#include "Time_Point.H"
#include <list>
using std::list;
class Time_Track : public Track
class Time_Sequence : public Sequence
{
public:
Time_Track ( int X, int Y, int W, int H ) : Track ( X, Y, W, H )
Time_Sequence ( int X, int Y, int W, int H ) : Sequence ( X, Y, W, H )
{
box( FL_UP_BOX );
}
@ -38,7 +38,7 @@ public:
time_sig
time ( nframes_t when )
{
for ( list <Track_Widget *>::const_reverse_iterator i = _widgets.rbegin();
for ( list <Sequence_Widget *>::const_reverse_iterator i = _widgets.rbegin();
i != _widgets.rend(); i++ )
{
if ( (*i)->offset() < when )

View File

@ -18,18 +18,18 @@
/*******************************************************************************/
#include "Timeline.H"
#include "Tempo_Track.H"
#include "Time_Track.H"
#include "Audio_Track.H"
#include "Control_Track.H"
#include "Tempo_Sequence.H"
#include "Time_Sequence.H"
#include "Audio_Sequence.H"
#include "Control_Sequence.H"
#include <FL/Fl_Scrollbar.H>
#include "Ruler_Track.H"
#include "Ruler_Sequence.H"
// #include <FL/Fl_Image.H>
// #include <FL/Fl_RGB_Image.H> // needed for alpha blending
#include "Track_Header.H"
#include "Track.H"
const float UPDATE_FREQ = 0.02f;
@ -107,11 +107,11 @@ Timeline::Timeline ( int X, int Y, int W, int H, const char* L ) : Fl_Overlay_Wi
}
{
Fl_Pack *o = new Fl_Pack( X + Track_Header::width(), Y, (W - Track_Header::width()) - vscroll->w(), H - hscroll->h(), "rulers" );
Fl_Pack *o = new Fl_Pack( X + Track::width(), Y, (W - Track::width()) - vscroll->w(), H - hscroll->h(), "rulers" );
o->type( Fl_Pack::VERTICAL );
{
Tempo_Track *o = new Tempo_Track( 0, 0, 800, 24 );
Tempo_Sequence *o = new Tempo_Sequence( 0, 0, 800, 24 );
o->color( FL_RED );
@ -127,7 +127,7 @@ Timeline::Timeline ( int X, int Y, int W, int H, const char* L ) : Fl_Overlay_Wi
}
{
Time_Track *o = new Time_Track( 0, 24, 800, 24 );
Time_Sequence *o = new Time_Sequence( 0, 24, 800, 24 );
o->color( fl_color_average( FL_RED, FL_WHITE, 0.50f ) );
@ -143,7 +143,7 @@ Timeline::Timeline ( int X, int Y, int W, int H, const char* L ) : Fl_Overlay_Wi
}
{
Ruler_Track *o = new Ruler_Track( 0, 24, 800, 24 );
Ruler_Sequence *o = new Ruler_Sequence( 0, 24, 800, 24 );
o->color( FL_GREEN );
@ -180,14 +180,14 @@ Timeline::Timeline ( int X, int Y, int W, int H, const char* L ) : Fl_Overlay_Wi
/* for ( int i = 1; i--; ) */
/* { */
/* // Track_Header *t = new Track_Header( 0, 0, W, 75 ); */
/* Track_Header *t = new Track_Header( 0, 0, W, 30 ); */
/* Track *o = new Audio_Track( 0, 0, 1, 100 ); */
/* // Track *t = new Track( 0, 0, W, 75 ); */
/* Track *t = new Track( 0, 0, W, 30 ); */
/* Sequence *o = new Audio_Sequence( 0, 0, 1, 100 ); */
/* t->track( o ); */
/* t->add( new Audio_Track( 0, 0, 1, 100 ) ); */
/* t->add( new Audio_Track( 0, 0, 1, 100 ) ); */
/* t->add_control( new Control_Track( 0, 0, 1, 100 ) ); */
/* t->add( new Audio_Sequence( 0, 0, 1, 100 ) ); */
/* t->add( new Audio_Sequence( 0, 0, 1, 100 ) ); */
/* t->add_control( new Control_Sequence( 0, 0, 1, 100 ) ); */
/* t->color( (Fl_Color)rand() ); */
/* } */
@ -250,11 +250,11 @@ struct BBT
BBT
Timeline::bbt ( nframes_t when )
{
Tempo_Track *tempo = (Tempo_Track*)rulers->child( 0 );
Tempo_Sequence *tempo = (Tempo_Sequence*)rulers->child( 0 );
BBT bbt;
for ( list <Track_Widget *>::const_iterator i = tempo.widgets.begin();
for ( list <Sequence_Widget *>::const_iterator i = tempo.widgets.begin();
i != tempo.widgets.end(); ++i )
{
Tempo_Point *p = *i;
@ -272,7 +272,7 @@ Timeline::nearest_line ( int ix )
{
for ( int x = ix - 10; x < ix + 10; ++x )
{
const int measure = ts_to_x( (double)(_sample_rate * 60) / beats_per_minute( x_to_ts( x - Track_Header::width() ) + xoffset ));
const int measure = ts_to_x( (double)(_sample_rate * 60) / beats_per_minute( x_to_ts( x - Track::width() ) + xoffset ));
// const int abs_x = ts_to_x( xoffset ) + x;
@ -304,13 +304,13 @@ Timeline::draw_measure ( int X, int Y, int W, int H, Fl_Color color, bool BBT )
for ( int x = X; x < X + W; ++x )
{
measure = ts_to_x( (double)(_sample_rate * 60) / beats_per_minute( x_to_ts( x - Track_Header::width() ) + xoffset ) );
measure = ts_to_x( (double)(_sample_rate * 60) / beats_per_minute( x_to_ts( x - Track::width() ) + xoffset ) );
const int abs_x = ts_to_x( xoffset ) + x - Track_Header::width();
const int abs_x = ts_to_x( xoffset ) + x - Track::width();
if ( 0 == abs_x % measure )
{
int bpb = beats_per_bar( x_to_ts( x -Track_Header::width() ) + xoffset );
int bpb = beats_per_bar( x_to_ts( x -Track::width() ) + xoffset );
if ( 0 == (abs_x / measure) % bpb )
{
@ -419,12 +419,12 @@ Timeline::draw_clip ( void * v, int X, int Y, int W, int H )
tl->draw_child( *tl->rulers );
/* headers */
fl_push_clip( tl->tracks->x(), tl->rulers->y() + tl->rulers->h(), Track_Header::width(), tl->h() - tl->rulers->h() - tl->hscroll->h() );
fl_push_clip( tl->tracks->x(), tl->rulers->y() + tl->rulers->h(), Track::width(), tl->h() - tl->rulers->h() - tl->hscroll->h() );
tl->draw_child( *tl->tracks );
fl_pop_clip();
/* track bodies */
fl_push_clip( tl->tracks->x() + Track_Header::width(), tl->rulers->y() + tl->rulers->h(), tl->tracks->w() - Track_Header::width(), tl->h() - tl->rulers->h() - tl->hscroll->h() );
fl_push_clip( tl->tracks->x() + Track::width(), tl->rulers->y() + tl->rulers->h(), tl->tracks->w() - Track::width(), tl->h() - tl->rulers->h() - tl->hscroll->h() );
tl->draw_child( *tl->tracks );
fl_pop_clip();
@ -541,13 +541,13 @@ Timeline::draw ( void )
int dy = _old_yposition - _yposition;
if ( ! dy )
fl_scroll( X + Track_Header::width(), rulers->y(), rulers->w() - Fl::box_dw( rulers->child(0)->box() ), rulers->h(), dx, 0, draw_clip, this );
fl_scroll( X + Track::width(), rulers->y(), rulers->w() - Fl::box_dw( rulers->child(0)->box() ), rulers->h(), dx, 0, draw_clip, this );
Y = rulers->y() + rulers->h();
H = h() - rulers->h() - hscroll->h();
if ( dy == 0 )
fl_scroll( X + Track_Header::width(), Y, W - Track_Header::width(), H, dx, dy, draw_clip, this );
fl_scroll( X + Track::width(), Y, W - Track::width(), H, dx, dy, draw_clip, this );
else
fl_scroll( X, Y, W, H, dx, dy, draw_clip, this );
@ -561,9 +561,9 @@ Timeline::draw ( void )
void
Timeline::draw_playhead ( void )
{
int x = ( ts_to_x( transport.frame ) - ts_to_x( xoffset ) ) + tracks->x() + Track_Header::width();
int x = ( ts_to_x( transport.frame ) - ts_to_x( xoffset ) ) + tracks->x() + Track::width();
if ( x < tracks->x() + Track_Header::width() || x > tracks->x() + tracks->w() )
if ( x < tracks->x() + Track::width() || x > tracks->x() + tracks->w() )
return;
fl_color( FL_RED );
@ -609,7 +609,7 @@ Timeline::draw_overlay ( void )
if ( ! ( _selection.w && _selection.h ) )
return;
fl_push_clip( tracks->x() + Track_Header::width(), rulers->y() + rulers->h(), tracks->w() - Track_Header::width(), h() - rulers->h() - hscroll->h() );
fl_push_clip( tracks->x() + Track::width(), rulers->y() + rulers->h(), tracks->w() - Track::width(), h() - rulers->h() - hscroll->h() );
const Rectangle &r = _selection;
@ -659,7 +659,7 @@ Timeline::draw_overlay ( void )
}
// #include "Track_Widget.H"
// #include "Sequence_Widget.H"
/** select all widgets in inside rectangle /r/ */
void
@ -669,7 +669,7 @@ Timeline::select( const Rectangle &r )
for ( int i = tracks->children(); i-- ; )
{
Track_Header *t = (Track_Header*)tracks->child( i );
Track *t = (Track*)tracks->child( i );
if ( ! ( t->y() > Y + r.h || t->y() + t->h() < Y ) )
t->track()->select_range( r.x, r.w );
@ -689,7 +689,7 @@ Timeline::handle ( int m )
{
case FL_Delete:
{
Track_Widget::delete_selected();
Sequence_Widget::delete_selected();
return 1;
}
@ -740,16 +740,16 @@ Timeline::handle ( int m )
/* FIXME: prompt for I/O config? */
/* add audio track */
Track_Header *t = new Track_Header( 0, 0, tracks->w(), 30 );
Track *t = new Track( 0, 0, tracks->w(), 30 );
add_track( t );
Track *o = new Audio_Track( 0, 0, 1, 100 );
Sequence *o = new Audio_Sequence( 0, 0, 1, 100 );
t->track( o );
// t->add( new Audio_Track( 0, 0, 1, 100 ) );
// t->add( new Audio_Track( 0, 0, 1, 100 ) );
t->add_control( new Control_Track( 0, 0, 1, 100 ) );
// t->add( new Audio_Sequence( 0, 0, 1, 100 ) );
// t->add( new Audio_Sequence( 0, 0, 1, 100 ) );
t->add_control( new Control_Sequence( 0, 0, 1, 100 ) );
t->color( (Fl_Color)rand() );
}
@ -798,7 +798,7 @@ Timeline::handle ( int m )
void
Timeline::add_track ( Track_Header *track )
Timeline::add_track ( Track *track )
{
printf( "added new track to the timeline\n" );
/* FIXME: do locking */
@ -810,7 +810,7 @@ Timeline::add_track ( Track_Header *track )
}
void
Timeline::remove_track ( Track_Header *track )
Timeline::remove_track ( Track *track )
{
printf( "removed track from the timeline\n" );
@ -833,7 +833,7 @@ Timeline::process ( nframes_t nframes )
{
for ( int i = tracks->children(); i-- ; )
{
Track_Header *t = (Track_Header*)tracks->child( i );
Track *t = (Track*)tracks->child( i );
t->process( nframes );
}
@ -848,7 +848,7 @@ Timeline::seek ( nframes_t frame )
{
for ( int i = tracks->children(); i-- ; )
{
Track_Header *t = (Track_Header*)tracks->child( i );
Track *t = (Track*)tracks->child( i );
t->seek( frame );
}
@ -862,7 +862,7 @@ Timeline::seek_pending ( void )
for ( int i = tracks->children(); i-- ; )
{
Track_Header *t = (Track_Header*)tracks->child( i );
Track *t = (Track*)tracks->child( i );
if ( t->playback_ds )
r += t->playback_ds->buffer_percent() < 50;

View File

@ -40,12 +40,12 @@
class Timeline;
extern Timeline *timeline;
#include "Track.H"
#include "Sequence.H"
class Tempo_Track;
class Time_Track;
class Ruler_Track;
class Track_Header;
class Tempo_Sequence;
class Time_Sequence;
class Ruler_Sequence;
class Track;
// disables double-buffering to make unnecessary redrawing more apparent
// #define DEBUG_TIMELINE_DRAWING
@ -113,9 +113,9 @@ class Timeline : public Fl_Overlay_Window, public RWLock
public:
Tempo_Track *tempo_track;
Time_Track *time_track;
Ruler_Track *ruler_track;
Tempo_Sequence *tempo_track;
Time_Sequence *time_track;
Ruler_Sequence *ruler_track;
nframes_t xoffset;
@ -150,8 +150,8 @@ public:
void select( const Rectangle &r );
void add_track ( Track_Header *track );
void remove_track ( Track_Header *track );
void add_track ( Track *track );
void remove_track ( Track *track );
private:

View File

@ -18,400 +18,356 @@
/*******************************************************************************/
#include "Track.H"
#include "Timeline.H"
#include "Transport.H"
#include "Playback_DS.H"
#include "Record_DS.H"
#include "Engine.H"
#include "Port.H"
void
Track::cb_input_field ( Fl_Widget *w, void *v )
{
((Track*)v)->cb_input_field();
}
void
Track::cb_button ( Fl_Widget *w, void *v )
{
((Track*)v)->cb_button( w );
}
void
Track::cb_input_field ( void )
{
log_start();
if ( _name )
free( _name );
_name = strdup( name_field->value() );
log_end();
}
void
Track::cb_button ( Fl_Widget *w )
{
printf( "FIXME: inform mixer here\n" );
if ( w == record_button )
{
/* FIXME: wrong place for this! */
if ( record_button->value() )
record_ds->start( transport.frame );
else
record_ds->stop( transport.frame );
}
else
if ( w == take_menu )
{
int v = take_menu->value();
switch ( v )
{
case 0: /* show all takes */
show_all_takes( take_menu->menu()[ v ].value() );
return;
case 1: /* new */
track( track()->clone_empty() );
return;
}
const char *s = take_menu->menu()[ v ].text;
for ( int i = takes->children(); i--; )
{
Sequence *t = (Sequence*)takes->child( i );
if ( ! strcmp( s, t->name() ) )
{
track( t );
redraw();
break;
}
}
}
}
Track::Track ( int X, int Y, int W, int H, const char *L ) :
Fl_Group ( X, Y, W, H, L )
{
_track = NULL;
_name = NULL;
_selected = false;
_show_all_takes = false;
_size = 1;
{
char pname[40];
static int no = 0, ni = 0;
snprintf( pname, sizeof( pname ), "out-%d", no++ );
output.push_back( Port( strdup( pname ), Port::Output ) );
snprintf( pname, sizeof( pname ), "in-%d", ni++ );
input.push_back( Port( strdup( pname ), Port::Input ) );
snprintf( pname, sizeof( pname ), "in-%d", ni++ );
input.push_back( Port( strdup( pname ), Port::Input ) );
}
playback_ds = new Playback_DS( this, engine->frame_rate(), engine->nframes(), 1 );
record_ds = new Record_DS( this, engine->frame_rate(), engine->nframes(), 2 );
Fl_Group::size( w(), height() );
Track *o = this;
o->box( FL_THIN_UP_BOX );
{
Fl_Group *o = new Fl_Group( 2, 2, 149, 70 );
o->color( ( Fl_Color ) 53 );
{
Fl_Input *o = name_field = new Fl_Input( 2, 2, 144, 24 );
o->color( ( Fl_Color ) 33 );
o->labeltype( FL_NO_LABEL );
o->labelcolor( FL_GRAY0 );
o->textcolor( 32 );
o->callback( cb_input_field, (void*)this );
}
{
Fl_Group *o = controls = new Fl_Group( 2, 28, 149, 24 );
{
Fl_Button *o = record_button =
new Fl_Button( 6, 28, 26, 24, "@circle" );
o->type( 1 );
o->box( FL_THIN_UP_BOX );
o->color( FL_LIGHT1 );
o->selection_color( FL_RED );
o->labelsize( 8 );
o->callback( cb_button, this );
}
{
Fl_Button *o = mute_button =
new Fl_Button( 35, 28, 26, 24, "m" );
o->type( 1 );
o->box( FL_THIN_UP_BOX );
o->color( FL_LIGHT1 );
o->labelsize( 11 );
o->callback( cb_button, this );
}
{
Fl_Button *o = solo_button =
new Fl_Button( 66, 28, 26, 24, "s" );
o->type( 1 );
o->box( FL_THIN_UP_BOX );
o->color( FL_LIGHT1 );
o->labelsize( 11 );
o->callback( cb_button, this );
}
{
Fl_Menu_Button *o = take_menu =
new Fl_Menu_Button( 97, 28, 47, 24, "T" );
o->box( FL_THIN_UP_BOX );
o->color( FL_LIGHT1 );
o->align( FL_ALIGN_LEFT | FL_ALIGN_INSIDE );
o->callback( cb_button, this );
o->add( "Show all takes", 0, 0, 0, FL_MENU_TOGGLE );
o->add( "New", 0, 0, 0, FL_MENU_DIVIDER );
}
o->end();
}
{
Fl_Box *o = new Fl_Box( 0, 76, 149, 38 );
o->box( FL_FLAT_BOX );
Fl_Group::current()->resizable( o );
}
o->size( Track::width(), h() );
o->end();
}
{
Fl_Pack *o = pack = new Fl_Pack( width(), 0, 1006, 115 );
o->labeltype( FL_NO_LABEL );
o->resize( x() + width(), y(), w() - width(), h() );
Fl_Group::current()->resizable( o );
{
Fl_Pack *o = control = new Fl_Pack( width(), 0, pack->w(), 115 );
o->end();
}
{
Fl_Pack *o = takes = new Fl_Pack( width(), 0, pack->w(), 115 );
o->end();
o->hide();
}
o->end();
}
end();
log_create();
}
Track::~Track ( )
{
log_destroy();
}
static int pack_visible( Fl_Pack *p )
{
int v = 0;
for ( int i = p->children(); i--; )
if ( p->child( i )->visible() )
v++;
return v;
}
/* adjust size of widget and children */
void
Track::resize ( void )
{
for ( int i = takes->children(); i--; )
takes->child( i )->size( w(), height() );
for ( int i = control->children(); i--; )
control->child( i )->size( w(), height() );
if ( _show_all_takes )
{
takes->show();
Fl_Group::size( w(), height() * ( 1 + takes->children() + pack_visible( control ) ) );
}
else
{
takes->hide();
Fl_Group::size( w(), height() * ( 1 + pack_visible( control ) ) );
}
if ( track() )
track()->size( w(), height() );
if ( controls->y() + controls->h() > y() + h() )
controls->hide();
else
controls->show();
parent()->redraw();
}
void
Track::size ( int v )
{
if ( v < 0 || v > 3 )
return;
_size = v;
resize();
}
void
Track::track( Sequence * t )
{
// t->size( 1, h() );
if ( track() )
add( track() );
// takes->insert( *track(), 0 );
_track = t;
pack->insert( *t, 0 );
resize();
}
void
Track::add_control( Sequence *t )
{
control->add( t );
resize();
}
/**********/
/* Engine */
/**********/
/* THREAD: RT */
nframes_t
Track::process ( nframes_t nframes )
{
if ( playback_ds )
{
record_ds->process( nframes );
return playback_ds->process( nframes );
}
else
return 0;
}
/* THREAD: RT */
void
Track::seek ( nframes_t frame )
{
if ( playback_ds )
return playback_ds->seek( frame );
}
/* FIXME: what about theading issues with this region/audiofile being
accessible from the UI thread? Need locking? */
#include "Region.H"
#include <FL/fl_draw.H>
queue <Track_Widget *> Track::_delete_queue;
Track::Track ( int X, int Y, int W, int H ) : Fl_Widget( X, Y, W, H )
{
_name = NULL;
box( FL_DOWN_BOX );
color( fl_darker( FL_GRAY ) );
align( FL_ALIGN_LEFT );
// log_create();
}
Track::~Track ( )
{
/* FIXME: what to do with regions? */
parent()->redraw();
parent()->remove( this );
// log_destroy();
}
/* THREAD: IO */
/** create capture region and prepare to record */
void
Track::sort ( void )
Track::record ( nframes_t frame )
{
_widgets.sort( Track_Widget::sort_func );
assert( _capture == NULL );
/* FIXME: hack */
Audio_File *af = Audio_File_SF::create( "testing.wav", 48000, input.size(), "Wav/24" );
_capture = new Region( af, track(), frame );
/* FIXME: wrong place for this */
_capture->_r->end = 0;
}
/** return a pointer to the widget that /r/ overlaps, or NULL if none. */
Track_Widget *
Track::overlaps ( Track_Widget *r )
{
for ( list <Track_Widget *>::const_iterator i = _widgets.begin(); i != _widgets.end(); i++ )
{
if ( *i == r ) continue;
if ( ! ( (*i)->offset() > r->offset() + r->length() || (*i)->offset() + (*i)->length() < r->offset() ) )
return *i;
}
return NULL;
}
#include "Waveform.H"
/* THREAD: IO */
/** write a block to the (already opened) capture file */
void
Track::draw ( void )
Track::write ( sample_t *buf, nframes_t nframes )
{
if ( ! fl_not_clipped( x(), y(), w(), h() ) )
return;
fl_push_clip( x(), y(), w(), h() );
draw_box();
int X, Y, W, H;
fl_clip_box( x(), y(), w(), h(), X, Y, W, H );
if ( Track_Widget::pushed() && Track_Widget::pushed()->track() == this )
{
/* make sure the Track_Widget::pushed widget is above all others */
remove( Track_Widget::pushed() );
add( Track_Widget::pushed() );
}
int xfades = 0;
// printf( "track::draw %d,%d %dx%d\n", X,Y,W,H );
timeline->draw_measure_lines( x(), y(), w(), h(), color() );
for ( list <Track_Widget *>::const_iterator r = _widgets.begin(); r != _widgets.end(); r++ )
(*r)->draw_box();
for ( list <Track_Widget *>::const_iterator r = _widgets.begin(); r != _widgets.end(); r++ )
(*r)->draw();
/* draw crossfades */
for ( list <Track_Widget *>::const_iterator r = _widgets.begin(); r != _widgets.end(); r++ )
{
Track_Widget *o = overlaps( *r );
if ( o )
{
if ( *o <= **r )
{
/* if ( o->x() == (*r)->x() && o->w() == (*r)->w() ) */
/* printf( "complete superposition\n" ); */
if ( (*r)->x() >= o->x() && (*r)->x() + (*r)->w() <= o->x() + o->w() )
/* completely inside */
continue;
++xfades;
Rectangle b( (*r)->x(),
o->y(),
(o->x() + o->w()) - (*r)->x(),
o->h() );
Fl_Color c = fl_color_average( o->box_color(), (*r)->box_color(), 0.50f );
c = fl_color_average( c, FL_YELLOW, 0.30f );
fl_push_clip( b.x, b.y, b.w, b.h );
draw_box( FL_FLAT_BOX, b.x - 100, b.y, b.w + 200, b.h, c );
draw_box( FL_UP_FRAME, b.x - 100, b.y, b.w + 200, b.h, c );
fl_pop_clip();
}
}
}
// printf( "There are %d xfades\n", xfades );
for ( list <Track_Widget *>::const_iterator r = _widgets.begin(); r != _widgets.end(); r++ )
{
Track_Widget *o = overlaps( *r );
if ( o )
{
if ( *o <= **r )
{
if ( (*r)->x() >= o->x() && (*r)->x() + (*r)->w() <= o->x() + o->w() )
/* completely inside */
continue;
Rectangle b( (*r)->x(), o->y(), (o->x() + o->w()) - (*r)->x(), o->h() );
/* draw overlapping waveforms in X-ray style. */
Waveform::fill = false;
/* Fl_Color oc = o->color(); */
/* Fl_Color rc = (*r)->color(); */
/* /\* give each region a different color *\/ */
/* o->color( FL_RED ); */
/* (*r)->color( FL_GREEN ); */
fl_push_clip( b.x, b.y, b.w, b.h );
o->draw();
(*r)->draw();
fl_pop_clip();
Waveform::fill = true;
/* o->color( oc ); */
/* (*r)->color( rc ); */
/* fl_color( FL_BLACK ); */
/* fl_line_style( FL_DOT, 4 ); */
/* b.x = (*r)->line_x(); */
/* b.w = min( 32767, (*r)->abs_w() ); */
/* fl_line( b.x, b.y, b.x + b.w, b.y + b.h ); */
/* fl_line( b.x, b.y + b.h, b.x + b.w, b.y ); */
/* fl_line_style( FL_SOLID, 0 ); */
// fl_pop_clip();
}
}
}
fl_pop_clip();
_capture->write( buf, nframes );
}
/* THREAD: IO */
void
Track::remove ( Track_Widget *r )
Track::stop ( nframes_t nframes )
{
// Logger _log( this );
_widgets.remove( r );
}
void
Track::remove_selected ( void )
{
Loggable::block_start();
for ( list <Track_Widget *>::iterator r = _widgets.begin(); r != _widgets.end(); )
if ( (*r)->selected() )
{
Track_Widget *t = *r;
_widgets.erase( r++ );
delete t;
}
else
++r;
Loggable::block_end();
}
Track_Widget *
Track::event_widget ( void )
{
nframes_t ets = timeline->xoffset + timeline->x_to_ts( Fl::event_x() - x() );
for ( list <Track_Widget *>::const_reverse_iterator r = _widgets.rbegin(); r != _widgets.rend(); r++ )
if ( ets > (*r)->offset() && ets < (*r)->offset() + (*r)->length() )
return (*r);
return NULL;
}
void
Track::select_range ( int X, int W )
{
nframes_t sts = timeline->xoffset + timeline->x_to_ts( X - x() );
nframes_t ets = sts + timeline->x_to_ts( W );
for ( list <Track_Widget *>::const_reverse_iterator r = _widgets.rbegin(); r != _widgets.rend(); r++ )
if ( ! ( (*r)->offset() > ets || (*r)->offset() + (*r)->length() < sts ) )
(*r)->select();
}
void
Track::add ( Track_Widget *r )
{
// Logger _log( this );
if ( r->track() )
{
r->redraw();
r->track()->remove( r );
// r->track()->redraw();
}
r->track( this );
_widgets.push_back( r );
sort();
}
/* snap /r/ to nearest edge */
void
Track::snap ( Track_Widget *r )
{
const int snap_pixels = 10;
const int rx1 = r->x();
const int rx2 = r->x() + r->w();
for ( list <Track_Widget*>::iterator i = _widgets.begin(); i != _widgets.end(); i++ )
{
const Track_Widget *w = (*i);
if ( w == r )
continue;
const int wx1 = w->x();
const int wx2 = w->x() + w->w();
if ( abs( rx1 - wx2 ) < snap_pixels )
{
r->offset( w->offset() + w->length() + 1 );
// printf( "snap: %lu | %lu\n", w->offset() + w->length(), r->offset() );
goto done;
}
if ( abs( rx2 - wx1 ) < snap_pixels )
{
r->offset( ( w->offset() - r->length() ) - 1 );
// printf( "snap: %lu | %lu\n", r->offset() + r->length(), w->offset() );
goto done;
}
}
{
int nx = timeline->nearest_line( r->abs_x() );
if ( nx >= 0 )
{
r->offset( timeline->x_to_ts( nx ) );
return;
}
}
// r->offset( timeline->x_to_ts( r->x() ) );
done:
return;
// r->resize();
// r->position( rx1, y() );
}
int
Track::handle ( int m )
{
switch ( m )
{
case FL_FOCUS:
return 1;
case FL_UNFOCUS:
return 1;
case FL_DND_ENTER:
printf( "enter\n" );
if ( Track_Widget::pushed() && Track_Widget::pushed()->track()->class_name() == class_name() )
{
add( Track_Widget::pushed() );
redraw();
}
case FL_DND_LEAVE:
return 1;
case FL_MOVE:
{
Track_Widget *r = event_widget();
if ( r != Track_Widget::belowmouse() )
{
if ( Track_Widget::belowmouse() )
Track_Widget::belowmouse()->handle( FL_LEAVE );
Track_Widget::belowmouse( r );
if ( r )
r->handle( FL_ENTER );
}
return 0;
}
default:
{
Track_Widget *r = Track_Widget::pushed() ? Track_Widget::pushed() : event_widget();
if ( r )
{
int retval = r->dispatch( m );
if ( retval && m == FL_PUSH )
{
take_focus();
Track_Widget::pushed( r );
}
if ( retval && m == FL_RELEASE )
Track_Widget::pushed( NULL );
Loggable::block_start();
while ( _delete_queue.size() )
{
Track_Widget *t = _delete_queue.front();
_delete_queue.pop();
if ( Track_Widget::pushed() == t )
Track_Widget::pushed( NULL );
if ( Track_Widget::belowmouse() == t )
{
Track_Widget::belowmouse()->handle( FL_LEAVE );
Track_Widget::belowmouse( NULL );
}
delete t;
}
Loggable::block_end();
return retval;
}
else
return Fl_Widget::handle( m );
}
}
_capture = NULL;
}

View File

@ -17,115 +17,269 @@
/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/*******************************************************************************/
#pragma once
#include <FL/Fl_Widget.H>
#include <FL/Fl_Group.H>
#ifndef Track_H
#define Track_H
#include <FL/Fl.H>
// #include "Region.H"
#include <stdio.h>
#include "Sequence.H"
#include <FL/Fl_Group.H>
#include <FL/Fl_Input.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Menu_Button.H>
#include <FL/Fl_Pack.H>
#include <FL/Fl_Box.H>
#include "Loggable.H"
#include <assert.h>
// #include "Port.H"
#include <list>
/* TODO: rename this to Audio_Sequence_Header or something since it's clearly audio specific. */
// using namespace std;
#include <vector>
using std::vector;
class Region;
class Track_Widget;
class Playback_DS;
class Record_DS;
class Port;
#include "types.h"
/* This is the base class for all track types. */
class Track : public Fl_Widget, public Loggable
class Track : public Fl_Group, public Loggable
{
public:
Track ( int X, int Y, int W, int H, const char *L = 0 );
~Track ( );
private:
// Sequence * _track;
char *_name;
static queue <Track_Widget *> _delete_queue;
bool _selected;
protected:
bool _show_all_takes;
std::list <Track_Widget *> _widgets;
Track_Widget *event_widget ( void );
int _size;
virtual const char *class_name ( void ) { return "Track"; }
enum { AUDIO } _type;
Sequence *_track;
Region *_capture; /* capture region */
public:
Fl_Input * name_field;
Fl_Button *record_button;
Fl_Button *mute_button;
Fl_Button *solo_button;
Fl_Menu_Button *take_menu;
Fl_Group *controls;
Fl_Pack *pack;
Fl_Pack *control;
Fl_Pack *takes;
vector <Port> input;
vector <Port> output; /* output ports... */
Playback_DS *playback_ds;
Record_DS *record_ds;
const char *class_name ( void ) { return "Track"; }
void set ( char **sa )
{
for ( int i = 0; sa[i]; ++i )
{
char *s = sa[i];
strtok( s, " " );
char *v = s + strlen( s ) + 1;
if ( *v == '"' )
{
v++;
v[ strlen( v ) - 2 ] = '\0';
}
if ( ! strcmp( s, ":h" ) )
{
size( atoi( v ) );
Fl_Widget::size( w(), height() );
}
else if ( ! strcmp( s, ":selected" ) )
_selected = atoi( v );
// else if ( ! strcmp( s, ":armed"
else if ( ! strcmp( s, ":name" ) )
{
_name = strdup( v );
name_field->value( _name );
}
else if ( ! strcmp( s, ":track" ) )
{
int i;
sscanf( v, "%X", &i );
Sequence *t = (Sequence*)Loggable::find( i );
assert( t );
track( t );
}
void set ( char ** ) { return; }
free( s );
}
free( sa );
}
char ** get ( void )
{
// char *r;
char **sa = (char**)malloc( sizeof( char* ) * (1 + 5) );
char **sa = (char**)malloc( sizeof( char* ) * 2);
sa[0] = (char*)malloc( (_widgets.size() * ((sizeof( int ) * 2) + 3)) + 1 );
sa[1] = NULL;
int i = 0;
sa[0][0] = '\0';
asprintf( &sa[ i++ ], ":name \"%s\"", _name ? _name : "" );
asprintf( &sa[ i++ ], ":track 0x%X", track() ? track()->id() : 0 );
asprintf( &sa[ i++ ], ":selected %d", _selected );
// asprintf( &sa[ i++ ], ":record %d", record_button->value() );
/* char *s = sa[0]; */
/* asprintf( &sa[ i++ ], ":solo %d", solo_button->value() ); */
/* asprintf( &sa[ i++ ], ":mute %d", mute_button->value() ); */
asprintf( &sa[ i++ ], ":h %d", size() );
// asprintf( &sa[ i++ ], ":gain %f", _scale );
/* s += sprintf( s, ":items " ); */
/* for ( list <Track_Widget *>::const_iterator i = _widgets.begin(); i != _widgets.end(); i++ ) */
/* { */
/* s += sprintf( s, "0x%X", ((Loggable*)(*i))->id() ); */
/* list <Track_Widget *>::const_iterator e = i; */
/* if ( ++e != _widgets.end() ) */
/* s += sprintf( s, "," ); */
/* } */
sa[ i ] = NULL;
return sa;
}
public:
Track ( int X, int Y, int W, int H );
virtual ~Track ( );
/* for loggable */
static Loggable *
create ( char **sa )
{
Track *r = new Track( 0, 0, 1, 1 );
r->set( sa );
return (Loggable *)r;
}
void
draw ( void )
{
if ( _selected )
{
Fl_Color c = color();
color( FL_RED );
Fl_Group::draw();
color( c );
}
else
Fl_Group::draw();
}
void add_control( Sequence *t );
int size ( void ) const { return _size; }
void resize ( void );
void size ( int v );
int height ( void ) const
{
static int table[] = { 30, 80, 150, 300 };
return table[ _size ];
}
void show_all_takes ( bool b )
{
_show_all_takes = b;
resize();
}
const char * name ( void ) const { return _name; }
void name ( char *s ) { if ( _name ) free( _name ); _name = s; label( _name ); }
bool mute ( void ) const { return mute_button->value(); }
bool solo ( void ) const { return solo_button->value(); }
bool armed ( void ) const { return record_button->value(); }
bool selected ( void ) const { return _selected; }
void sort ( void );
static void cb_input_field ( Fl_Widget *w, void *v );
void cb_input_field ( void );
static void cb_button ( Fl_Widget *w, void *v );
void cb_button ( Fl_Widget *w );
void remove ( Track_Widget *r );
void add ( Track_Widget *r );
void select_range ( int X, int W );
static int width ( void ) { return 150; }
void remove_selected ( void );
void track( Sequence * t );
Sequence * track ( void ) { return _track; }
const std::list <Track_Widget *> widgets ( void ) const { return _widgets; }
void queue_delete ( Track_Widget *r )
void add ( Sequence * t )
{
_delete_queue.push( r );
takes->insert( *t, 0 );
if ( ! t->name() )
{
char pat[20];
snprintf( pat, sizeof( pat ), "%d", takes->children() );
t->name( strdup( pat ) );
take_menu->add( t->name() );
}
}
Track_Widget * overlaps ( Track_Widget *r );
virtual Track * clone ( void )
void remote ( Sequence *t )
{
assert( 0 );
takes->remove( t );
// take_menu->remove( t->name() );
}
virtual Track * clone_empty ( void )
int handle ( int m )
{
return NULL;
switch ( m )
{
case FL_MOUSEWHEEL:
{
if ( ! Fl::event_shift() )
return 0;
int d = Fl::event_dy();
printf( "%d\n", d );
if ( d < 0 )
size( size() - 1 );
else
size( size() + 1 );
return 1;
}
default:
return Fl_Group::handle( m );
}
}
virtual void snap ( Track_Widget *r );
virtual int handle ( int m );
virtual void draw ( void );
virtual nframes_t process ( nframes_t nframes ) { return 0; }
/* Engine */
nframes_t process ( nframes_t nframes );
void seek ( nframes_t frame );
void record ( nframes_t nframes );
void write ( sample_t *buf, nframes_t nframes );
void stop ( nframes_t nframes );
};
#endif

View File

@ -1,373 +0,0 @@
/*******************************************************************************/
/* Copyright (C) 2008 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 "Track_Header.H"
#include "Transport.H"
#include "Playback_DS.H"
#include "Record_DS.H"
#include "Engine.H"
#include "Port.H"
void
Track_Header::cb_input_field ( Fl_Widget *w, void *v )
{
((Track_Header*)v)->cb_input_field();
}
void
Track_Header::cb_button ( Fl_Widget *w, void *v )
{
((Track_Header*)v)->cb_button( w );
}
void
Track_Header::cb_input_field ( void )
{
log_start();
if ( _name )
free( _name );
_name = strdup( name_field->value() );
log_end();
}
void
Track_Header::cb_button ( Fl_Widget *w )
{
printf( "FIXME: inform mixer here\n" );
if ( w == record_button )
{
/* FIXME: wrong place for this! */
if ( record_button->value() )
record_ds->start( transport.frame );
else
record_ds->stop( transport.frame );
}
else
if ( w == take_menu )
{
int v = take_menu->value();
switch ( v )
{
case 0: /* show all takes */
show_all_takes( take_menu->menu()[ v ].value() );
return;
case 1: /* new */
track( track()->clone_empty() );
return;
}
const char *s = take_menu->menu()[ v ].text;
for ( int i = takes->children(); i--; )
{
Track *t = (Track*)takes->child( i );
if ( ! strcmp( s, t->name() ) )
{
track( t );
redraw();
break;
}
}
}
}
Track_Header::Track_Header ( int X, int Y, int W, int H, const char *L ) :
Fl_Group ( X, Y, W, H, L )
{
_track = NULL;
_name = NULL;
_selected = false;
_show_all_takes = false;
_size = 1;
{
char pname[40];
static int no = 0, ni = 0;
snprintf( pname, sizeof( pname ), "out-%d", no++ );
output.push_back( Port( strdup( pname ), Port::Output ) );
snprintf( pname, sizeof( pname ), "in-%d", ni++ );
input.push_back( Port( strdup( pname ), Port::Input ) );
snprintf( pname, sizeof( pname ), "in-%d", ni++ );
input.push_back( Port( strdup( pname ), Port::Input ) );
}
playback_ds = new Playback_DS( this, engine->frame_rate(), engine->nframes(), 1 );
record_ds = new Record_DS( this, engine->frame_rate(), engine->nframes(), 2 );
Fl_Group::size( w(), height() );
Track_Header *o = this;
o->box( FL_THIN_UP_BOX );
{
Fl_Group *o = new Fl_Group( 2, 2, 149, 70 );
o->color( ( Fl_Color ) 53 );
{
Fl_Input *o = name_field = new Fl_Input( 2, 2, 144, 24 );
o->color( ( Fl_Color ) 33 );
o->labeltype( FL_NO_LABEL );
o->labelcolor( FL_GRAY0 );
o->textcolor( 32 );
o->callback( cb_input_field, (void*)this );
}
{
Fl_Group *o = controls = new Fl_Group( 2, 28, 149, 24 );
{
Fl_Button *o = record_button =
new Fl_Button( 6, 28, 26, 24, "@circle" );
o->type( 1 );
o->box( FL_THIN_UP_BOX );
o->color( FL_LIGHT1 );
o->selection_color( FL_RED );
o->labelsize( 8 );
o->callback( cb_button, this );
}
{
Fl_Button *o = mute_button =
new Fl_Button( 35, 28, 26, 24, "m" );
o->type( 1 );
o->box( FL_THIN_UP_BOX );
o->color( FL_LIGHT1 );
o->labelsize( 11 );
o->callback( cb_button, this );
}
{
Fl_Button *o = solo_button =
new Fl_Button( 66, 28, 26, 24, "s" );
o->type( 1 );
o->box( FL_THIN_UP_BOX );
o->color( FL_LIGHT1 );
o->labelsize( 11 );
o->callback( cb_button, this );
}
{
Fl_Menu_Button *o = take_menu =
new Fl_Menu_Button( 97, 28, 47, 24, "T" );
o->box( FL_THIN_UP_BOX );
o->color( FL_LIGHT1 );
o->align( FL_ALIGN_LEFT | FL_ALIGN_INSIDE );
o->callback( cb_button, this );
o->add( "Show all takes", 0, 0, 0, FL_MENU_TOGGLE );
o->add( "New", 0, 0, 0, FL_MENU_DIVIDER );
}
o->end();
}
{
Fl_Box *o = new Fl_Box( 0, 76, 149, 38 );
o->box( FL_FLAT_BOX );
Fl_Group::current()->resizable( o );
}
o->size( Track_Header::width(), h() );
o->end();
}
{
Fl_Pack *o = pack = new Fl_Pack( width(), 0, 1006, 115 );
o->labeltype( FL_NO_LABEL );
o->resize( x() + width(), y(), w() - width(), h() );
Fl_Group::current()->resizable( o );
{
Fl_Pack *o = control = new Fl_Pack( width(), 0, pack->w(), 115 );
o->end();
}
{
Fl_Pack *o = takes = new Fl_Pack( width(), 0, pack->w(), 115 );
o->end();
o->hide();
}
o->end();
}
end();
log_create();
}
Track_Header::~Track_Header ( )
{
log_destroy();
}
static int pack_visible( Fl_Pack *p )
{
int v = 0;
for ( int i = p->children(); i--; )
if ( p->child( i )->visible() )
v++;
return v;
}
/* adjust size of widget and children */
void
Track_Header::resize ( void )
{
for ( int i = takes->children(); i--; )
takes->child( i )->size( w(), height() );
for ( int i = control->children(); i--; )
control->child( i )->size( w(), height() );
if ( _show_all_takes )
{
takes->show();
Fl_Group::size( w(), height() * ( 1 + takes->children() + pack_visible( control ) ) );
}
else
{
takes->hide();
Fl_Group::size( w(), height() * ( 1 + pack_visible( control ) ) );
}
if ( track() )
track()->size( w(), height() );
if ( controls->y() + controls->h() > y() + h() )
controls->hide();
else
controls->show();
parent()->redraw();
}
void
Track_Header::size ( int v )
{
if ( v < 0 || v > 3 )
return;
_size = v;
resize();
}
void
Track_Header::track( Track * t )
{
// t->size( 1, h() );
if ( track() )
add( track() );
// takes->insert( *track(), 0 );
_track = t;
pack->insert( *t, 0 );
resize();
}
void
Track_Header::add_control( Track *t )
{
control->add( t );
resize();
}
/**********/
/* Engine */
/**********/
/* THREAD: RT */
nframes_t
Track_Header::process ( nframes_t nframes )
{
if ( playback_ds )
{
record_ds->process( nframes );
return playback_ds->process( nframes );
}
else
return 0;
}
/* THREAD: RT */
void
Track_Header::seek ( nframes_t frame )
{
if ( playback_ds )
return playback_ds->seek( frame );
}
/* FIXME: what about theading issues with this region/audiofile being
accessible from the UI thread? Need locking? */
#include "Region.H"
/* THREAD: IO */
/** create capture region and prepare to record */
void
Track_Header::record ( nframes_t frame )
{
assert( _capture == NULL );
/* FIXME: hack */
Audio_File *af = Audio_File_SF::create( "testing.wav", 48000, input.size(), "Wav/24" );
_capture = new Region( af, track(), frame );
/* FIXME: wrong place for this */
_capture->_r->end = 0;
}
/* THREAD: IO */
/** write a block to the (already opened) capture file */
void
Track_Header::write ( sample_t *buf, nframes_t nframes )
{
_capture->write( buf, nframes );
}
/* THREAD: IO */
void
Track_Header::stop ( nframes_t nframes )
{
_capture = NULL;
}

View File

@ -1,285 +0,0 @@
/*******************************************************************************/
/* Copyright (C) 2008 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. */
/*******************************************************************************/
#ifndef Track_Header_H
#define Track_Header_H
#include <FL/Fl.H>
#include "Track.H"
#include <FL/Fl_Group.H>
#include <FL/Fl_Input.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Menu_Button.H>
#include <FL/Fl_Pack.H>
#include <FL/Fl_Box.H>
#include "Loggable.H"
// #include "Port.H"
/* TODO: rename this to Audio_Track_Header or something since it's audio specific. */
#include <vector>
using std::vector;
class Playback_DS;
class Record_DS;
class Port;
class Track_Header : public Fl_Group, public Loggable
{
public:
Track_Header ( int X, int Y, int W, int H, const char *L = 0 );
~Track_Header ( );
private:
// Track * _track;
char *_name;
bool _selected;
bool _show_all_takes;
int _size;
enum { AUDIO } _type;
Track *_track;
Region *_capture; /* capture region */
public:
Fl_Input * name_field;
Fl_Button *record_button;
Fl_Button *mute_button;
Fl_Button *solo_button;
Fl_Menu_Button *take_menu;
Fl_Group *controls;
Fl_Pack *pack;
Fl_Pack *control;
Fl_Pack *takes;
vector <Port> input;
vector <Port> output; /* output ports... */
Playback_DS *playback_ds;
Record_DS *record_ds;
const char *class_name ( void ) { return "Track_Header"; }
void set ( char **sa )
{
for ( int i = 0; sa[i]; ++i )
{
char *s = sa[i];
strtok( s, " " );
char *v = s + strlen( s ) + 1;
if ( *v == '"' )
{
v++;
v[ strlen( v ) - 2 ] = '\0';
}
if ( ! strcmp( s, ":h" ) )
{
size( atoi( v ) );
Fl_Widget::size( w(), height() );
}
else if ( ! strcmp( s, ":selected" ) )
_selected = atoi( v );
// else if ( ! strcmp( s, ":armed"
else if ( ! strcmp( s, ":name" ) )
{
_name = strdup( v );
name_field->value( _name );
}
else if ( ! strcmp( s, ":track" ) )
{
int i;
sscanf( v, "%X", &i );
Track *t = (Track*)Loggable::find( i );
assert( t );
track( t );
}
free( s );
}
free( sa );
}
char ** get ( void )
{
char **sa = (char**)malloc( sizeof( char* ) * (1 + 5) );
int i = 0;
asprintf( &sa[ i++ ], ":name \"%s\"", _name ? _name : "" );
asprintf( &sa[ i++ ], ":track 0x%X", track() ? track()->id() : 0 );
asprintf( &sa[ i++ ], ":selected %d", _selected );
// asprintf( &sa[ i++ ], ":record %d", record_button->value() );
/* asprintf( &sa[ i++ ], ":solo %d", solo_button->value() ); */
/* asprintf( &sa[ i++ ], ":mute %d", mute_button->value() ); */
asprintf( &sa[ i++ ], ":h %d", size() );
// asprintf( &sa[ i++ ], ":gain %f", _scale );
sa[ i ] = NULL;
return sa;
}
/* for loggable */
static Loggable *
create ( char **sa )
{
Track_Header *r = new Track_Header( 0, 0, 1, 1 );
r->set( sa );
return (Loggable *)r;
}
void
draw ( void )
{
if ( _selected )
{
Fl_Color c = color();
color( FL_RED );
Fl_Group::draw();
color( c );
}
else
Fl_Group::draw();
}
void add_control( Track *t );
int size ( void ) const { return _size; }
void resize ( void );
void size ( int v );
int height ( void ) const
{
static int table[] = { 30, 80, 150, 300 };
return table[ _size ];
}
void show_all_takes ( bool b )
{
_show_all_takes = b;
resize();
}
const char * name ( void ) const { return _name; }
bool mute ( void ) const { return mute_button->value(); }
bool solo ( void ) const { return solo_button->value(); }
bool armed ( void ) const { return record_button->value(); }
bool selected ( void ) const { return _selected; }
static void cb_input_field ( Fl_Widget *w, void *v );
void cb_input_field ( void );
static void cb_button ( Fl_Widget *w, void *v );
void cb_button ( Fl_Widget *w );
static int width ( void ) { return 150; }
void track( Track * t );
Track * track ( void ) { return _track; }
void add ( Track * t )
{
takes->insert( *t, 0 );
if ( ! t->name() )
{
char pat[20];
snprintf( pat, sizeof( pat ), "%d", takes->children() );
t->name( strdup( pat ) );
take_menu->add( t->name() );
}
}
void remote ( Track *t )
{
takes->remove( t );
// take_menu->remove( t->name() );
}
int handle ( int m )
{
switch ( m )
{
case FL_MOUSEWHEEL:
{
if ( ! Fl::event_shift() )
return 0;
int d = Fl::event_dy();
printf( "%d\n", d );
if ( d < 0 )
size( size() - 1 );
else
size( size() + 1 );
return 1;
}
default:
return Fl_Group::handle( m );
}
}
/* Engine */
nframes_t process ( nframes_t nframes );
void seek ( nframes_t frame );
void record ( nframes_t nframes );
void write ( sample_t *buf, nframes_t nframes );
void stop ( nframes_t nframes );
};
#endif

View File

@ -40,15 +40,15 @@
#include <stdlib.h>
#include <string.h>
#include "Track.H"
#include "Audio_Track.H"
#include "Sequence.H"
#include "Audio_Sequence.H"
#include "Timeline.H"
#include "Tempo_Track.H"
#include "Time_Track.H"
#include "Control_Track.H"
#include "Tempo_Sequence.H"
#include "Time_Sequence.H"
#include "Control_Sequence.H"
#include "Loggable.H"
#include "Track_Header.H"
#include "Track.H"
// #include "const.h"
#include "Engine.H"
@ -77,7 +77,7 @@ main ( int argc, char **argv )
Loggable::register_create( "Tempo_Point", &Tempo_Point::create );
Loggable::register_create( "Time_Point", &Time_Point::create );
Loggable::register_create( "Control_Point", &Control_Point::create );
Loggable::register_create( "Track_Header", &Track_Header::create );
Loggable::register_create( "Track", &Track::create );
/* TODO: change to seesion dir */