Browse Source

Massive renames.

tags/non-daw-v1.1.0
Jonathan Moore Liles 17 years ago
parent
commit
e54f63e605
33 changed files with 1213 additions and 1213 deletions
  1. +7
    -7
      Timeline/Audio_Sequence.C
  2. +7
    -7
      Timeline/Audio_Sequence.H
  3. +6
    -6
      Timeline/Control_Point.H
  4. +9
    -9
      Timeline/Control_Sequence.H
  5. +5
    -5
      Timeline/Disk_Stream.C
  6. +5
    -5
      Timeline/Disk_Stream.H
  7. +4
    -4
      Timeline/Makefile
  8. +2
    -2
      Timeline/Playback_DS.C
  9. +1
    -1
      Timeline/Playback_DS.H
  10. +2
    -2
      Timeline/Record_DS.C
  11. +1
    -1
      Timeline/Record_DS.H
  12. +12
    -12
      Timeline/Region.C
  13. +8
    -8
      Timeline/Region.H
  14. +5
    -5
      Timeline/Ruler_Point.H
  15. +4
    -4
      Timeline/Ruler_Sequence.H
  16. +417
    -0
      Timeline/Sequence.C
  17. +131
    -0
      Timeline/Sequence.H
  18. +5
    -5
      Timeline/Sequence_Point.H
  19. +11
    -11
      Timeline/Sequence_Widget.C
  20. +30
    -30
      Timeline/Sequence_Widget.H
  21. +2
    -2
      Timeline/Tempo_Point.C
  22. +4
    -4
      Timeline/Tempo_Point.H
  23. +4
    -4
      Timeline/Tempo_Sequence.H
  24. +1
    -1
      Timeline/Time_Point.C
  25. +4
    -4
      Timeline/Time_Point.H
  26. +4
    -4
      Timeline/Time_Sequence.H
  27. +42
    -42
      Timeline/Timeline.C
  28. +10
    -10
      Timeline/Timeline.H
  29. +250
    -294
      Timeline/Track.C
  30. +213
    -59
      Timeline/Track.H
  31. +0
    -373
      Timeline/Track_Header.C
  32. +0
    -285
      Timeline/Track_Header.H
  33. +7
    -7
      Timeline/main.C

Timeline/Audio_Track.C → Timeline/Audio_Sequence.C 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 ); */
/* } */

Timeline/Audio_Track.H → Timeline/Audio_Sequence.H 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 );

+ 6
- 6
Timeline/Control_Point.H 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 )
{


Timeline/Control_Track.H → Timeline/Control_Sequence.H 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;

+ 5
- 5
Timeline/Disk_Stream.C 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 */


+ 5
- 5
Timeline/Disk_Stream.H 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 ( );



+ 4
- 4
Timeline/Makefile 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 \


+ 2
- 2
Timeline/Playback_DS.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"



+ 1
- 1
Timeline/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();


+ 2
- 2
Timeline/Record_DS.C 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"



+ 1
- 1
Timeline/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 );


+ 12
- 12
Timeline/Region.C 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;
}



+ 8
- 8
Timeline/Region.H 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 );


+ 5
- 5
Timeline/Ruler_Point.H 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 )
{


Timeline/Ruler_Track.H → Timeline/Ruler_Sequence.H 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
- 0
Timeline/Sequence.C 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
- 0
Timeline/Sequence.H 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; }

};

Timeline/Track_Point.H → Timeline/Sequence_Point.H 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() );
}

Timeline/Track_Widget.C → Timeline/Sequence_Widget.C 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 );
}


Timeline/Track_Widget.H → Timeline/Sequence_Widget.H 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;
}

+ 2
- 2
Timeline/Tempo_Point.C 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 )
{


+ 4
- 4
Timeline/Tempo_Point.H 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 );
}


Timeline/Tempo_Track.H → Timeline/Tempo_Sequence.H 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 )

+ 1
- 1
Timeline/Time_Point.C 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 **


+ 4
- 4
Timeline/Time_Point.H 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 )
{


Timeline/Time_Track.H → Timeline/Time_Sequence.H 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 )

+ 42
- 42
Timeline/Timeline.C 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;


+ 10
- 10
Timeline/Timeline.H 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:



+ 250
- 294
Timeline/Track.C View File

@@ -18,400 +18,356 @@
/*******************************************************************************/

#include "Track.H"
#include "Timeline.H"

#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;
#include "Transport.H"
#include "Playback_DS.H"
#include "Record_DS.H"

box( FL_DOWN_BOX );
color( fl_darker( FL_GRAY ) );
align( FL_ALIGN_LEFT );
#include "Engine.H"

// log_create();
}

Track::~Track ( )
{
/* FIXME: what to do with regions? */
parent()->redraw();
parent()->remove( this );
// log_destroy();
}
#include "Port.H"

void
Track::sort ( void )
Track::cb_input_field ( Fl_Widget *w, void *v )
{
_widgets.sort( Track_Widget::sort_func );
((Track*)v)->cb_input_field();
}

/** return a pointer to the widget that /r/ overlaps, or NULL if none. */
Track_Widget *
Track::overlaps ( Track_Widget *r )
void
Track::cb_button ( Fl_Widget *w, void *v )
{
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;
((Track*)v)->cb_button( w );
}


#include "Waveform.H"

void
Track::draw ( void )
Track::cb_input_field ( void )
{
log_start();

if ( ! fl_not_clipped( x(), y(), w(), h() ) )
return;

fl_push_clip( x(), y(), w(), h() );
if ( _name )
free( _name );

draw_box();
_name = strdup( name_field->value() );

int X, Y, W, H;

fl_clip_box( x(), y(), w(), h(), X, Y, W, H );
log_end();
}

void
Track::cb_button ( Fl_Widget *w )
{

if ( Track_Widget::pushed() && Track_Widget::pushed()->track() == this )
printf( "FIXME: inform mixer here\n" );
if ( w == record_button )
{
/* make sure the Track_Widget::pushed widget is above all others */
remove( Track_Widget::pushed() );
add( Track_Widget::pushed() );
/* FIXME: wrong place for this! */
if ( record_button->value() )
record_ds->start( transport.frame );
else
record_ds->stop( transport.frame );
}

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 )
else
if ( w == take_menu )
{
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 );
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;
}

fl_pop_clip();
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 )
{

// printf( "There are %d xfades\n", xfades );
_track = NULL;
_name = NULL;
_selected = false;
_show_all_takes = false;
_size = 1;

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;
char pname[40];
static int no = 0, ni = 0;

/* Fl_Color oc = o->color(); */
/* Fl_Color rc = (*r)->color(); */
snprintf( pname, sizeof( pname ), "out-%d", no++ );

/* /\* give each region a different color *\/ */
/* o->color( FL_RED ); */
/* (*r)->color( FL_GREEN ); */
output.push_back( Port( strdup( pname ), Port::Output ) );

fl_push_clip( b.x, b.y, b.w, b.h );
snprintf( pname, sizeof( pname ), "in-%d", ni++ );

o->draw();
(*r)->draw();
input.push_back( Port( strdup( pname ), Port::Input ) );

fl_pop_clip();
snprintf( pname, sizeof( pname ), "in-%d", ni++ );

Waveform::fill = true;
input.push_back( Port( strdup( pname ), Port::Input ) );

}

/* o->color( oc ); */
/* (*r)->color( rc ); */
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_color( FL_BLACK ); */
/* fl_line_style( FL_DOT, 4 ); */
Fl_Group::size( w(), height() );

/* b.x = (*r)->line_x(); */
/* b.w = min( 32767, (*r)->abs_w() ); */
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 );

/* fl_line( b.x, b.y, b.x + b.w, b.y + b.h ); */
o->callback( cb_input_field, (void*)this );
}

/* fl_line( b.x, b.y + b.h, b.x + b.w, b.y ); */
{
Fl_Group *o = controls = new Fl_Group( 2, 28, 149, 24 );

/* fl_line_style( FL_SOLID, 0 ); */
{
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 );

// fl_pop_clip();
o->add( "Show all takes", 0, 0, 0, FL_MENU_TOGGLE );
o->add( "New", 0, 0, 0, FL_MENU_DIVIDER );

}
o->end();
}
}


fl_pop_clip();
}

void
Track::remove ( Track_Widget *r )
{
// Logger _log( this );

_widgets.remove( r );
}
{
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 );

void
Track::remove_selected ( void )
{
Loggable::block_start();
{
Fl_Pack *o = control = new Fl_Pack( width(), 0, pack->w(), 115 );
o->end();
}

for ( list <Track_Widget *>::iterator r = _widgets.begin(); r != _widgets.end(); )
if ( (*r)->selected() )
{
Track_Widget *t = *r;
_widgets.erase( r++ );
delete t;
Fl_Pack *o = takes = new Fl_Pack( width(), 0, pack->w(), 115 );
o->end();
o->hide();
}
else
++r;

Loggable::block_end();
}
o->end();
}
end();

log_create();
}

Track_Widget *
Track::event_widget ( void )
Track::~Track ( )
{
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;
log_destroy();
}

void
Track::select_range ( int X, int W )

static int pack_visible( Fl_Pack *p )
{
nframes_t sts = timeline->xoffset + timeline->x_to_ts( X - x() );
nframes_t ets = sts + timeline->x_to_ts( W );
int v = 0;
for ( int i = p->children(); i--; )
if ( p->child( i )->visible() )
v++;

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

/* adjust size of widget and children */
void
Track::add ( Track_Widget *r )
Track::resize ( void )
{
// Logger _log( this );
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 ( r->track() )
if ( _show_all_takes )
{
takes->show();
Fl_Group::size( w(), height() * ( 1 + takes->children() + pack_visible( control ) ) );
}
else
{
r->redraw();
r->track()->remove( r );
// r->track()->redraw();
takes->hide();
Fl_Group::size( w(), height() * ( 1 + pack_visible( control ) ) );
}

r->track( this );
_widgets.push_back( r );
if ( track() )
track()->size( w(), height() );

sort();

if ( controls->y() + controls->h() > y() + h() )
controls->hide();
else
controls->show();

parent()->redraw();
}

/* snap /r/ to nearest edge */
void
Track::snap ( Track_Widget *r )
Track::size ( int v )
{
const int snap_pixels = 10;
if ( v < 0 || v > 3 )
return;

const int rx1 = r->x();
const int rx2 = r->x() + r->w();
_size = v;

resize();
}

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();
void
Track::track( Sequence * t )
{
// t->size( 1, h() );
if ( track() )
add( track() );

if ( abs( rx1 - wx2 ) < snap_pixels )
{
r->offset( w->offset() + w->length() + 1 );
// takes->insert( *track(), 0 );

// printf( "snap: %lu | %lu\n", w->offset() + w->length(), r->offset() );
_track = t;
pack->insert( *t, 0 );

goto done;
}
resize();
}

if ( abs( rx2 - wx1 ) < snap_pixels )
{
r->offset( ( w->offset() - r->length() ) - 1 );
void
Track::add_control( Sequence *t )
{
control->add( t );

// printf( "snap: %lu | %lu\n", r->offset() + r->length(), w->offset() );
resize();
}

goto done;
}
}

{
int nx = timeline->nearest_line( r->abs_x() );
/**********/
/* Engine */
/**********/

if ( nx >= 0 )
{
r->offset( timeline->x_to_ts( nx ) );
return;
}
/* THREAD: RT */
nframes_t
Track::process ( nframes_t nframes )
{
if ( playback_ds )
{
record_ds->process( nframes );
return playback_ds->process( nframes );
}
// r->offset( timeline->x_to_ts( r->x() ) );

done:

return;
// r->resize();
// r->position( rx1, y() );
else
return 0;
}

int
Track::handle ( int m )
/* THREAD: RT */
void
Track::seek ( nframes_t frame )
{
if ( playback_ds )
return playback_ds->seek( frame );
}

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();
/* FIXME: what about theading issues with this region/audiofile being
accessible from the UI thread? Need locking? */

while ( _delete_queue.size() )
{
#include "Region.H"

Track_Widget *t = _delete_queue.front();
_delete_queue.pop();
/* THREAD: IO */
/** create capture region and prepare to record */
void
Track::record ( nframes_t frame )
{
assert( _capture == NULL );

/* FIXME: hack */
Audio_File *af = Audio_File_SF::create( "testing.wav", 48000, input.size(), "Wav/24" );

if ( Track_Widget::pushed() == t )
Track_Widget::pushed( NULL );
if ( Track_Widget::belowmouse() == t )
{
Track_Widget::belowmouse()->handle( FL_LEAVE );
Track_Widget::belowmouse( NULL );
}
_capture = new Region( af, track(), frame );

delete t;
}
/* FIXME: wrong place for this */
_capture->_r->end = 0;
}

Loggable::block_end();
/* THREAD: IO */
/** write a block to the (already opened) capture file */
void
Track::write ( sample_t *buf, nframes_t nframes )
{
_capture->write( buf, nframes );
}

return retval;
}
else
return Fl_Widget::handle( m );
}
}
/* THREAD: IO */
void
Track::stop ( nframes_t nframes )
{
_capture = NULL;
}

+ 213
- 59
Timeline/Track.H 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"
class Track : public Fl_Group, public Loggable
{

public:

/* This is the base class for all track types. */
Track ( int X, int Y, int W, int H, const char *L = 0 );
~Track ( );

class Track : public Fl_Widget, public Loggable
{
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;

void set ( char ** ) { return; }
Region *_capture; /* capture region */

char ** get ( void )
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 )
{
// char *r;
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 );

char **sa = (char**)malloc( sizeof( char* ) * 2);
sa[0] = (char*)malloc( (_widgets.size() * ((sizeof( int ) * 2) + 3)) + 1 );
sa[1] = NULL;
track( t );
}

sa[0][0] = '\0';

/* char *s = sa[0]; */
free( s );
}

free( sa );

}

char ** get ( void )
{
char **sa = (char**)malloc( sizeof( char* ) * (1 + 5) );

int i = 0;

/* 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() ); */
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() );

/* list <Track_Widget *>::const_iterator e = i; */
/* if ( ++e != _widgets.end() ) */
/* s += sprintf( s, "," ); */
/* } */
/* 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;
}


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

const char * name ( void ) const { return _name; }
void name ( char *s ) { if ( _name ) free( _name ); _name = s; label( _name ); }
r->set( sa );

void sort ( void );
return (Loggable *)r;
}

void
draw ( void )
{
if ( _selected )
{
Fl_Color c = color();

void remove ( Track_Widget *r );
void add ( Track_Widget *r );
color( FL_RED );

void select_range ( int X, int W );
Fl_Group::draw();

void remove_selected ( void );
color( c );
}
else
Fl_Group::draw();
}

const std::list <Track_Widget *> widgets ( void ) const { return _widgets; }
void add_control( Sequence *t );

void queue_delete ( Track_Widget *r )
int size ( void ) const { return _size; }

void resize ( void );
void size ( int v );

int height ( void ) const
{
_delete_queue.push( r );
static int table[] = { 30, 80, 150, 300 };

return table[ _size ];
}

Track_Widget * overlaps ( Track_Widget *r );
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; }

virtual Track * clone ( 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 );


static int width ( void ) { return 150; }

void track( Sequence * t );
Sequence * track ( void ) { return _track; }

void add ( Sequence * 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 ( 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

+ 0
- 373
Timeline/Track_Header.C 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;
}

+ 0
- 285
Timeline/Track_Header.H 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

+ 7
- 7
Timeline/main.C 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 */



Loading…
Cancel
Save