Cleanups and commenting.
This commit is contained in:
parent
6d9a5bb1d5
commit
170b11010e
4
Makefile
4
Makefile
|
@ -63,8 +63,10 @@ TAGS: $(SRCS)
|
|||
etags $(SRCS)
|
||||
|
||||
.deps: .config $(SRCS)
|
||||
ifneq ($(CALCULATING),yes)
|
||||
@ echo -n Calculating dependencies...
|
||||
@ makedepend -f- -- $(CXXFLAGS) $(INCLUDES) -- $(SRCS) > .deps 2>/dev/null && echo $(DONE)
|
||||
@ makedepend -f- -- $(CXXFLAGS) $(INCLUDES) -- $(SRCS) 2>/dev/null > .deps && echo $(DONE)
|
||||
endif
|
||||
|
||||
clean_deps:
|
||||
@ rm -f .deps
|
||||
|
|
|
@ -57,6 +57,7 @@ static Fl_Color fl_invert_color ( Fl_Color c )
|
|||
return fl_rgb_color( 255 - r, 255 - g, 255 - b );
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
Audio_Region::get ( Log_Entry &e ) const
|
||||
|
@ -154,7 +155,6 @@ Audio_Region::Audio_Region ( Audio_File *c )
|
|||
log_create();
|
||||
}
|
||||
|
||||
|
||||
/* used when DND importing */
|
||||
Audio_Region::Audio_Region ( Audio_File *c, Sequence *t, nframes_t o )
|
||||
{
|
||||
|
@ -189,12 +189,13 @@ Audio_Region::Audio_Region ( Audio_File *c, Sequence *t, nframes_t o )
|
|||
log_create();
|
||||
}
|
||||
|
||||
const char *
|
||||
Audio_Region::source_name ( void ) const
|
||||
Audio_Region::~Audio_Region ( )
|
||||
{
|
||||
return _clip->name();
|
||||
log_destroy();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
Audio_Region::menu_cb ( Fl_Widget *w, void *v )
|
||||
{
|
||||
|
@ -309,123 +310,6 @@ Audio_Region::menu ( void )
|
|||
return m;
|
||||
}
|
||||
|
||||
int
|
||||
Audio_Region::handle ( int m )
|
||||
{
|
||||
static int ox, oy;
|
||||
|
||||
static bool copied = false;
|
||||
static nframes_t os;
|
||||
|
||||
int X = Fl::event_x();
|
||||
int Y = Fl::event_y();
|
||||
|
||||
Logger _log( this );
|
||||
|
||||
switch ( m )
|
||||
{
|
||||
case FL_FOCUS:
|
||||
case FL_UNFOCUS:
|
||||
return 1;
|
||||
case FL_KEYBOARD:
|
||||
return menu().test_shortcut() != 0;
|
||||
case FL_ENTER:
|
||||
return Sequence_Region::handle( m );
|
||||
case FL_LEAVE:
|
||||
return Sequence_Region::handle( m );
|
||||
case FL_PUSH:
|
||||
{
|
||||
/* splitting */
|
||||
if ( test_press( FL_BUTTON2 | FL_SHIFT ) )
|
||||
{
|
||||
/* split */
|
||||
if ( ! copied )
|
||||
{
|
||||
Loggable::block_start();
|
||||
|
||||
Audio_Region *copy = new Audio_Region( *this );
|
||||
|
||||
trim( RIGHT, X );
|
||||
copy->trim( LEFT, X );
|
||||
|
||||
sequence()->add( copy );
|
||||
|
||||
log_end();
|
||||
|
||||
Loggable::block_end();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ox = x() - X;
|
||||
oy = y() - Y;
|
||||
/* for panning */
|
||||
os = _r->offset;
|
||||
|
||||
if ( test_press( FL_BUTTON2 | FL_CTRL ) )
|
||||
{
|
||||
normalize();
|
||||
/* FIXME: wrong place for this? */
|
||||
sequence()->handle_widget_change( start(), length() );
|
||||
redraw();
|
||||
return 1;
|
||||
}
|
||||
else if ( test_press( FL_BUTTON3 ) )
|
||||
{
|
||||
/* context menu */
|
||||
menu_popup( &menu() );
|
||||
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
return Sequence_Region::handle( m );
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case FL_RELEASE:
|
||||
{
|
||||
Sequence_Region::handle( m );
|
||||
|
||||
copied = false;
|
||||
|
||||
return 1;
|
||||
}
|
||||
case FL_DRAG:
|
||||
if ( ! _drag )
|
||||
{
|
||||
begin_drag( Drag( x() - X, y() - Y, x_to_offset( X ) ) );
|
||||
_log.hold();
|
||||
}
|
||||
|
||||
if ( test_press( FL_BUTTON1 | FL_SHIFT | FL_CTRL ) )
|
||||
{
|
||||
/* panning */
|
||||
int d = (ox + X) - x();
|
||||
long td = timeline->x_to_ts( d );
|
||||
|
||||
if ( td > 0 && os < (nframes_t)td )
|
||||
_r->offset = 0;
|
||||
else
|
||||
_r->offset = os - td;
|
||||
|
||||
redraw();
|
||||
return 1;
|
||||
}
|
||||
|
||||
return Sequence_Region::handle( m );
|
||||
|
||||
default:
|
||||
return Sequence_Region::handle( m );
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/** Draws the curve for a single fade. /X/ and /W/ repersent the
|
||||
portion of the region covered by this draw, which may or may not
|
||||
cover the fade in question. */
|
||||
|
@ -705,7 +589,137 @@ Audio_Region::draw ( void )
|
|||
|
||||
}
|
||||
|
||||
int
|
||||
Audio_Region::handle ( int m )
|
||||
{
|
||||
static int ox, oy;
|
||||
|
||||
static bool copied = false;
|
||||
static nframes_t os;
|
||||
|
||||
int X = Fl::event_x();
|
||||
int Y = Fl::event_y();
|
||||
|
||||
Logger _log( this );
|
||||
|
||||
switch ( m )
|
||||
{
|
||||
case FL_FOCUS:
|
||||
case FL_UNFOCUS:
|
||||
return 1;
|
||||
case FL_KEYBOARD:
|
||||
return menu().test_shortcut() != 0;
|
||||
case FL_ENTER:
|
||||
return Sequence_Region::handle( m );
|
||||
case FL_LEAVE:
|
||||
return Sequence_Region::handle( m );
|
||||
case FL_PUSH:
|
||||
{
|
||||
/* splitting */
|
||||
if ( test_press( FL_BUTTON2 | FL_SHIFT ) )
|
||||
{
|
||||
/* split */
|
||||
if ( ! copied )
|
||||
{
|
||||
Loggable::block_start();
|
||||
|
||||
Audio_Region *copy = new Audio_Region( *this );
|
||||
|
||||
trim( RIGHT, X );
|
||||
copy->trim( LEFT, X );
|
||||
|
||||
sequence()->add( copy );
|
||||
|
||||
log_end();
|
||||
|
||||
Loggable::block_end();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ox = x() - X;
|
||||
oy = y() - Y;
|
||||
/* for panning */
|
||||
os = _r->offset;
|
||||
|
||||
if ( test_press( FL_BUTTON2 | FL_CTRL ) )
|
||||
{
|
||||
normalize();
|
||||
/* FIXME: wrong place for this? */
|
||||
sequence()->handle_widget_change( start(), length() );
|
||||
redraw();
|
||||
return 1;
|
||||
}
|
||||
else if ( test_press( FL_BUTTON3 ) )
|
||||
{
|
||||
/* context menu */
|
||||
menu_popup( &menu() );
|
||||
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
return Sequence_Region::handle( m );
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case FL_RELEASE:
|
||||
{
|
||||
Sequence_Region::handle( m );
|
||||
|
||||
copied = false;
|
||||
|
||||
return 1;
|
||||
}
|
||||
case FL_DRAG:
|
||||
if ( ! _drag )
|
||||
{
|
||||
begin_drag( Drag( x() - X, y() - Y, x_to_offset( X ) ) );
|
||||
_log.hold();
|
||||
}
|
||||
|
||||
if ( test_press( FL_BUTTON1 | FL_SHIFT | FL_CTRL ) )
|
||||
{
|
||||
/* panning */
|
||||
int d = (ox + X) - x();
|
||||
long td = timeline->x_to_ts( d );
|
||||
|
||||
if ( td > 0 && os < (nframes_t)td )
|
||||
_r->offset = 0;
|
||||
else
|
||||
_r->offset = os - td;
|
||||
|
||||
redraw();
|
||||
return 1;
|
||||
}
|
||||
|
||||
return Sequence_Region::handle( m );
|
||||
|
||||
default:
|
||||
return Sequence_Region::handle( m );
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**********/
|
||||
/* Public */
|
||||
/**********/
|
||||
|
||||
/** return the name of the audio source this region represents */
|
||||
const char *
|
||||
Audio_Region::source_name ( void ) const
|
||||
{
|
||||
return _clip->name();
|
||||
}
|
||||
|
||||
/** set the amplitude scaling for this region from the normalization
|
||||
* factor for the range of samples represented by this region */
|
||||
void
|
||||
Audio_Region::normalize ( void )
|
||||
{
|
||||
|
|
|
@ -111,13 +111,24 @@ private:
|
|||
static void menu_cb ( Fl_Widget *w, void *v );
|
||||
void menu_cb ( const Fl_Menu_ *m );
|
||||
|
||||
void draw_fade ( const Fade &fade, Fade::fade_dir_e dir, bool filled, int X, int W );
|
||||
|
||||
protected:
|
||||
|
||||
virtual void get ( Log_Entry &e ) const;
|
||||
virtual void set ( Log_Entry &e );
|
||||
|
||||
int handle ( int m );
|
||||
void draw_box( void );
|
||||
void draw ( void );
|
||||
void resize ( void );
|
||||
|
||||
public:
|
||||
|
||||
LOG_CREATE_FUNC( Audio_Region );
|
||||
|
||||
SEQUENCE_WIDGET_CLONE_FUNC( Audio_Region );
|
||||
|
||||
static Fl_Boxtype _box;
|
||||
static Fl_Color _selection_color;
|
||||
Fl_Color selection_color ( void ) const { return _selection_color; }
|
||||
|
@ -132,37 +143,18 @@ public:
|
|||
|
||||
bool current ( void ) const { return this == belowmouse(); }
|
||||
|
||||
public:
|
||||
|
||||
const char * source_name ( void ) const;
|
||||
|
||||
LOG_CREATE_FUNC( Audio_Region );
|
||||
|
||||
SEQUENCE_WIDGET_CLONE_FUNC( Audio_Region );
|
||||
|
||||
~Audio_Region ( )
|
||||
{
|
||||
log_destroy();
|
||||
}
|
||||
|
||||
Fl_Boxtype box ( void ) const { return Audio_Region::_box; }
|
||||
Fl_Align align ( void ) const { return (Fl_Align)(FL_ALIGN_LEFT | FL_ALIGN_BOTTOM /*| FL_ALIGN_CLIP*/ | FL_ALIGN_INSIDE); }
|
||||
|
||||
Audio_Region ( const Audio_Region & rhs );
|
||||
Audio_Region ( Audio_File *c );
|
||||
Audio_Region ( Audio_File *c, Sequence *t, nframes_t o );
|
||||
~Audio_Region ( );
|
||||
|
||||
void draw_fade ( const Fade &fade, Fade::fade_dir_e dir, bool filled, int X, int W );
|
||||
|
||||
|
||||
int handle ( int m );
|
||||
void draw_box( void );
|
||||
void draw ( void );
|
||||
void resize ( void );
|
||||
Fl_Boxtype box ( void ) const { return Audio_Region::_box; }
|
||||
Fl_Align align ( void ) const { return (Fl_Align)(FL_ALIGN_LEFT | FL_ALIGN_BOTTOM /*| FL_ALIGN_CLIP*/ | FL_ALIGN_INSIDE); }
|
||||
|
||||
void normalize ( void );
|
||||
|
||||
|
||||
/* Engine */
|
||||
nframes_t read ( sample_t *buf, nframes_t pos, nframes_t nframes, int channel ) const;
|
||||
nframes_t write ( nframes_t nframes );
|
||||
|
|
|
@ -61,7 +61,9 @@ Audio_Sequence::~Audio_Sequence ( )
|
|||
Loggable::block_end();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** return a pointer to the current capture region for this sequence */
|
||||
const Audio_Region *
|
||||
Audio_Sequence::capture_region ( void ) const
|
||||
{
|
||||
|
@ -129,7 +131,6 @@ deurlify ( char *url )
|
|||
*w = NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Audio_Sequence::handle_widget_change ( nframes_t start, nframes_t length )
|
||||
{
|
||||
|
|
|
@ -41,16 +41,17 @@ protected:
|
|||
|
||||
void handle_widget_change ( nframes_t start, nframes_t length );
|
||||
|
||||
void draw ( void );
|
||||
int handle ( int m );
|
||||
|
||||
public:
|
||||
|
||||
LOG_CREATE_FUNC( Audio_Sequence );
|
||||
|
||||
Fl_Cursor cursor ( void ) const { return FL_CURSOR_DEFAULT; }
|
||||
|
||||
|
||||
Audio_Sequence ( Track *track );
|
||||
~Audio_Sequence ( );
|
||||
|
||||
Fl_Cursor cursor ( void ) const { return FL_CURSOR_DEFAULT; }
|
||||
|
||||
Sequence * clone_empty ( void )
|
||||
{
|
||||
|
@ -59,13 +60,6 @@ public:
|
|||
return t;
|
||||
}
|
||||
|
||||
// const char *class_name ( void ) { return "Audio_Sequence"; }
|
||||
|
||||
void draw ( void );
|
||||
int handle ( int m );
|
||||
void dump ( void );
|
||||
void remove_selected ( void );
|
||||
|
||||
const Audio_Region *capture_region ( void ) const;
|
||||
|
||||
nframes_t play ( sample_t *buf, nframes_t frame, nframes_t nframes, int channels );
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
|
||||
class Control_Sequence : public Sequence
|
||||
{
|
||||
|
||||
/* not permitted */
|
||||
Control_Sequence ( const Control_Sequence &rhs );
|
||||
Control_Sequence & operator = ( const Control_Sequence &rhs );
|
||||
|
@ -47,6 +46,7 @@ private:
|
|||
|
||||
void init ( void );
|
||||
|
||||
void draw_curve ( bool flip, bool filled );
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -59,9 +59,9 @@ protected:
|
|||
init();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void draw_curve ( bool flip, bool filled );
|
||||
void draw ( void );
|
||||
int handle ( int m );
|
||||
|
||||
public:
|
||||
|
||||
|
@ -76,12 +76,6 @@ public:
|
|||
|
||||
Fl_Cursor cursor ( void ) const { return FL_CURSOR_CROSS; }
|
||||
|
||||
// const char *class_name ( void ) { return "Control_Sequence"; }
|
||||
|
||||
void draw ( void );
|
||||
int handle ( int m );
|
||||
|
||||
|
||||
/* Engine */
|
||||
void output ( Port *p ) { _output = p; }
|
||||
nframes_t play ( sample_t *buf, nframes_t frame, nframes_t nframes );
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
/*******************************************************************************/
|
||||
|
||||
|
||||
#include "../Track.H"
|
||||
// #include "Audio_Sequence.H"
|
||||
class Audio_Sequence;
|
||||
|
@ -28,6 +27,8 @@ class Audio_Sequence;
|
|||
#include "Disk_Stream.H"
|
||||
#include "dsp.h"
|
||||
|
||||
|
||||
|
||||
/**********/
|
||||
/* Engine */
|
||||
/**********/
|
||||
|
@ -40,12 +41,6 @@ class Audio_Sequence;
|
|||
that is, at startup time. The default is 5 seconds, which may or
|
||||
may not be excessive depending on various external factors. */
|
||||
|
||||
/* FIXME: deal with (jack) buffer size changes */
|
||||
/* FIXME: needs error handling everywhere! */
|
||||
/* TODO: read/write data from/to disk in larger chunks to avoid
|
||||
* excessive seeking. 256k is supposedly the sweetspot. */
|
||||
|
||||
//float Disk_Stream::seconds_to_buffer = 5.0f;
|
||||
float Disk_Stream::seconds_to_buffer = 2.0f;
|
||||
/* this is really only a rough estimate. The actual amount of data
|
||||
read depends on many factors. Overlapping regions, for example, will
|
||||
|
@ -53,6 +48,8 @@ float Disk_Stream::seconds_to_buffer = 2.0f;
|
|||
counts.*/
|
||||
size_t Disk_Stream::disk_io_kbytes = 256;
|
||||
|
||||
|
||||
|
||||
Disk_Stream::Disk_Stream ( Track *track, float frame_rate, nframes_t nframes, int channels ) : _track( track )
|
||||
{
|
||||
assert( channels );
|
||||
|
@ -85,6 +82,7 @@ Disk_Stream::~Disk_Stream ( )
|
|||
engine->unlock();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** flush buffers and reset. Must only be called from the RT thread. */
|
||||
void
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
|
||||
#include "util/Thread.H"
|
||||
|
||||
|
||||
|
||||
Engine::Engine ( ) : _thread( "RT" )
|
||||
{
|
||||
_freewheeling = false;
|
||||
|
@ -39,6 +41,8 @@ Engine::Engine ( ) : _thread( "RT" )
|
|||
_xruns = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************/
|
||||
/* Static Wrappers */
|
||||
/*******************/
|
||||
|
@ -79,15 +83,24 @@ Engine::buffer_size ( nframes_t nframes, void *arg )
|
|||
return ((Engine*)arg)->buffer_size( nframes );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Engine::thread_init ( void *arg )
|
||||
{
|
||||
((Engine*)arg)->thread_init();
|
||||
}
|
||||
|
||||
void
|
||||
Engine::request_locate ( nframes_t frame )
|
||||
Engine::shutdown ( void *arg )
|
||||
{
|
||||
if ( timeline )
|
||||
timeline->seek( frame );
|
||||
((Engine*)arg)->shutdown();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************/
|
||||
/* Callbacks */
|
||||
/*************/
|
||||
|
||||
/* THREAD: RT */
|
||||
/** This is the jack xrun callback */
|
||||
int
|
||||
|
@ -114,7 +127,6 @@ Engine::freewheel ( bool starting )
|
|||
int
|
||||
Engine::buffer_size ( nframes_t nframes )
|
||||
{
|
||||
/* TODO: inform all disktreams the the buffer size has changed */
|
||||
timeline->resize_buffers( nframes );
|
||||
|
||||
return 0;
|
||||
|
@ -166,7 +178,6 @@ Engine::sync ( jack_transport_state_t state, jack_position_t *pos )
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* THREAD: RT */
|
||||
void
|
||||
Engine::timebase ( jack_transport_state_t, jack_nframes_t, jack_position_t *pos, int )
|
||||
|
@ -189,7 +200,6 @@ Engine::timebase ( jack_transport_state_t, jack_nframes_t, jack_position_t *pos,
|
|||
|
||||
}
|
||||
|
||||
|
||||
/* THREAD: RT */
|
||||
int
|
||||
Engine::process ( nframes_t nframes )
|
||||
|
@ -235,7 +245,7 @@ Engine::process ( nframes_t nframes )
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* THREAD: RT */
|
||||
/** enter or leave freehweeling mode */
|
||||
void
|
||||
Engine::freewheeling ( bool yes )
|
||||
|
@ -244,31 +254,22 @@ Engine::freewheeling ( bool yes )
|
|||
WARNING( "Unkown error while setting freewheeling mode" );
|
||||
}
|
||||
|
||||
void
|
||||
Engine::thread_init ( void *arg )
|
||||
{
|
||||
((Engine*)arg)->thread_init();
|
||||
}
|
||||
|
||||
/* TRHEAD: RT */
|
||||
void
|
||||
Engine::thread_init ( void )
|
||||
{
|
||||
_thread.set( "RT" );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Engine::shutdown ( void *arg )
|
||||
{
|
||||
((Engine*)arg)->shutdown();
|
||||
}
|
||||
|
||||
/* THREAD: RT */
|
||||
void
|
||||
Engine::shutdown ( void )
|
||||
{
|
||||
_zombified = true;
|
||||
}
|
||||
|
||||
|
||||
/** Connect to JACK */
|
||||
int
|
||||
Engine::init ( void )
|
||||
{
|
||||
|
@ -300,3 +301,10 @@ Engine::init ( void )
|
|||
/* we don't need to create any ports until tracks are created */
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
Engine::request_locate ( nframes_t frame )
|
||||
{
|
||||
if ( timeline )
|
||||
timeline->seek( frame );
|
||||
}
|
||||
|
|
|
@ -35,23 +35,12 @@ class Engine : public Mutex
|
|||
|
||||
Thread _thread; /* only used for thread checking */
|
||||
|
||||
|
||||
/* I know locking out the process callback is cheating, even
|
||||
though we use trylock... The thing is, every other DAW does
|
||||
this too and you can hear it in the glitches Ardour and friends
|
||||
produce when reconfiguring I/O... Working out a message queue
|
||||
system would obviously be better, but a DAW isn't a performance
|
||||
instrument anyway, so I think these drop-outs are a reasonable
|
||||
compromise. Obviously, this lock should never be held during
|
||||
blocking operations. */
|
||||
|
||||
int _buffers_dropped; /* buffers dropped because of locking */
|
||||
nframes_t _sample_rate;
|
||||
volatile int _xruns;
|
||||
volatile bool _freewheeling;
|
||||
volatile bool _zombified;
|
||||
|
||||
|
||||
static void shutdown ( void *arg );
|
||||
void shutdown ( void );
|
||||
static int process ( nframes_t nframes, void *arg );
|
||||
|
@ -72,6 +61,8 @@ class Engine : public Mutex
|
|||
Engine ( const Engine &rhs );
|
||||
Engine & operator = ( const Engine &rhs );
|
||||
|
||||
void request_locate ( nframes_t frame );
|
||||
|
||||
private:
|
||||
|
||||
friend class Port;
|
||||
|
@ -85,8 +76,6 @@ public:
|
|||
|
||||
int init ( void );
|
||||
|
||||
void request_locate ( nframes_t frame );
|
||||
|
||||
nframes_t nframes ( void ) const { return jack_get_buffer_size( _client ); }
|
||||
float frame_rate ( void ) const { return jack_get_sample_rate( _client ); }
|
||||
nframes_t sample_rate ( void ) const { return _sample_rate; }
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
peakfile reading/writing.
|
||||
*/
|
||||
|
||||
/* Code for peakfile reading, resampling, generation and streaming */
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
@ -39,6 +41,7 @@
|
|||
#include "assert.h"
|
||||
#include "util/debug.h"
|
||||
#include "util/Thread.H"
|
||||
#include "util/file.h"
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
|
@ -47,6 +50,7 @@
|
|||
using std::min;
|
||||
using std::max;
|
||||
|
||||
|
||||
|
||||
/* whether to cache peaks at multiple resolutions on disk to
|
||||
* drastically improve performance */
|
||||
|
@ -56,7 +60,6 @@ const int Peaks::cache_minimum = 256; /* minimum chunksize to build pea
|
|||
const int Peaks::cache_levels = 8; /* number of sampling levels in peak cache */
|
||||
const int Peaks::cache_step = 1; /* powers of two between each level. 4 == 256, 2048, 16384, ... */
|
||||
|
||||
|
||||
Peaks::peakbuffer Peaks::_peakbuf;
|
||||
|
||||
|
||||
|
@ -72,17 +75,6 @@ peakname ( const char *filename )
|
|||
return (const char*)&file;
|
||||
}
|
||||
|
||||
/** update the modification time of file referred to by /fd/ */
|
||||
static void
|
||||
touch ( int fd )
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
fstat( fd, &st );
|
||||
|
||||
fchmod( fd, st.st_mode );
|
||||
}
|
||||
|
||||
|
||||
|
||||
Peaks::Peaks ( Audio_File *c )
|
||||
|
@ -97,6 +89,8 @@ Peaks::~Peaks ( )
|
|||
delete _peak_writer;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Prepare a buffer of peaks from /s/ to /e/ for reading. Must be
|
||||
* called before any calls to operator[] */
|
||||
int
|
||||
|
@ -389,7 +383,6 @@ Peaks::read_peakfile_peaks ( Peak *peaks, nframes_t s, int npeaks, nframes_t chu
|
|||
return _peakfile.read_peaks( peaks, s, npeaks, chunksize );
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
Peaks::read_source_peaks ( Peak *peaks, int npeaks, nframes_t chunksize ) const
|
||||
{
|
||||
|
@ -472,27 +465,9 @@ Peaks::read_peaks ( nframes_t s, int npeaks, nframes_t chunksize ) const
|
|||
bool
|
||||
Peaks::current ( void ) const
|
||||
{
|
||||
int sfd, pfd;
|
||||
|
||||
if ( ( sfd = ::open( _clip->name(), O_RDONLY ) ) < 0 )
|
||||
return true;
|
||||
|
||||
if ( ( pfd = ::open( peakname( _clip->name() ), O_RDONLY ) ) < 0 )
|
||||
return false;
|
||||
|
||||
struct stat sst, pst;
|
||||
|
||||
fstat( sfd, &sst );
|
||||
fstat( pfd, &pst );
|
||||
|
||||
close( sfd );
|
||||
close( pfd );
|
||||
|
||||
return sst.st_mtime <= pst.st_mtime;
|
||||
return ! newer( _clip->name(), peakname( _clip->name() ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
Peaks::make_peaks ( void ) const
|
||||
{
|
||||
|
@ -817,7 +792,6 @@ Peaks::Builder::make_peaks ( void )
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
Peaks::Builder::Builder ( const Peaks *peaks ) : _peaks( peaks )
|
||||
{
|
||||
fp = NULL;
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
/*******************************************************************************/
|
||||
|
||||
/* Wrapper for a JACK audio port */
|
||||
|
||||
#include "Port.H"
|
||||
|
||||
#include <string.h>
|
||||
|
@ -25,6 +27,8 @@
|
|||
|
||||
#include <stdio.h> // sprintf
|
||||
|
||||
static const char *name_for_port ( Port::type_e dir, const char *base, int n, const char *type );
|
||||
|
||||
|
||||
|
||||
/* nframes is the number of frames to buffer */
|
||||
|
@ -39,6 +43,22 @@ Port::Port ( const char *name, type_e dir )
|
|||
activate( name, dir );
|
||||
}
|
||||
|
||||
Port::Port ( type_e dir, const char *base, int n, const char *type )
|
||||
{
|
||||
const char *name = name_for_port( dir, base, n, type );
|
||||
|
||||
activate( name, dir );
|
||||
}
|
||||
|
||||
Port::~Port ( )
|
||||
{
|
||||
/* if ( _port ) */
|
||||
/* jack_port_unregister( engine->client(), _port ); */
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
static const char *
|
||||
name_for_port ( Port::type_e dir, const char *base, int n, const char *type )
|
||||
{
|
||||
|
@ -54,27 +74,6 @@ name_for_port ( Port::type_e dir, const char *base, int n, const char *type )
|
|||
return pname;
|
||||
}
|
||||
|
||||
Port::Port ( type_e dir, const char *base, int n, const char *type )
|
||||
{
|
||||
const char *name = name_for_port( dir, base, n, type );
|
||||
|
||||
activate( name, dir );
|
||||
}
|
||||
|
||||
/* Port::Port ( ) */
|
||||
/* { */
|
||||
/* _name = NULL; */
|
||||
/* _port = NULL; */
|
||||
/* } */
|
||||
|
||||
Port::~Port ( )
|
||||
{
|
||||
|
||||
/* if ( _port ) */
|
||||
/* jack_port_unregister( engine->client(), _port ); */
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
Port::activate ( const char *name, type_e dir )
|
||||
{
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
#include "Record_DS.H"
|
||||
#include "Engine.H"
|
||||
|
||||
|
||||
|
||||
/**********/
|
||||
/* Engine */
|
||||
/**********/
|
||||
|
@ -195,9 +197,6 @@ Track::resize_buffers ( nframes_t nframes )
|
|||
playback_ds->resize_buffers( nframes );
|
||||
}
|
||||
|
||||
/* #include "Audio_Region.H" */
|
||||
|
||||
|
||||
#include <time.h>
|
||||
|
||||
/** very cheap UUID generator... */
|
||||
|
|
|
@ -305,44 +305,6 @@ Loggable::do_this ( const char *s, bool reverse )
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
backwards_fgetc ( FILE *fp )
|
||||
{
|
||||
int c;
|
||||
|
||||
if ( fseek( fp, -1, SEEK_CUR ) != 0 )
|
||||
return -1;
|
||||
|
||||
c = fgetc( fp );
|
||||
|
||||
fseek( fp, -1, SEEK_CUR );
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
static char *
|
||||
backwards_fgets ( char *s, int size, FILE *fp )
|
||||
{
|
||||
if ( fseek( fp, -1, SEEK_CUR ) != 0 )
|
||||
return NULL;
|
||||
|
||||
int c;
|
||||
while ( ( c = backwards_fgetc( fp ) ) >= 0 )
|
||||
if ( '\n' == c )
|
||||
break;
|
||||
|
||||
long here = ftell( fp );
|
||||
|
||||
fseek( fp, 1, SEEK_CUR );
|
||||
|
||||
char *r = fgets( s, size, fp );
|
||||
|
||||
fseek( fp, here, SEEK_SET );
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/** Reverse the last journal transaction */
|
||||
void
|
||||
Loggable::undo ( void )
|
||||
|
@ -386,6 +348,9 @@ Loggable::undo ( void )
|
|||
_undo_offset = uo;
|
||||
}
|
||||
|
||||
/** Make all loggable ids consecutive. This invalidates any existing
|
||||
* journal or snapshot, so you *must* write out a new one after
|
||||
* performing this operation*/
|
||||
void
|
||||
Loggable::compact_ids ( void )
|
||||
{
|
||||
|
@ -406,9 +371,8 @@ Loggable::compact_ids ( void )
|
|||
_log_id = id;
|
||||
}
|
||||
|
||||
/* FIXME: we need a version of this that is fully const, right? */
|
||||
/** write a snapshot of the state of all loggable objects, sufficient
|
||||
* for later reconstruction, to /fp/ */
|
||||
/** write a snapshot of the current state of all loggable objects to
|
||||
* file handle /fp/ */
|
||||
bool
|
||||
Loggable::snapshot ( FILE *fp )
|
||||
{
|
||||
|
@ -437,6 +401,8 @@ Loggable::snapshot ( FILE *fp )
|
|||
return true;
|
||||
}
|
||||
|
||||
/** write a snapshot of the current state of all loggable objects to
|
||||
* file /name/ */
|
||||
bool
|
||||
Loggable::snapshot ( const char *name )
|
||||
{
|
||||
|
@ -575,7 +541,6 @@ Loggable::log_print( const Log_Entry *o, const Log_Entry *n ) const
|
|||
log( "\n" );
|
||||
}
|
||||
|
||||
|
||||
/** Remember current object state for later comparison. *Must* be
|
||||
* called before any user action that might change one of the object's
|
||||
* journaled properties. */
|
||||
|
|
|
@ -56,6 +56,10 @@ int Project::_lockfd = 0;
|
|||
|
||||
|
||||
|
||||
/***********/
|
||||
/* Private */
|
||||
/***********/
|
||||
|
||||
void
|
||||
Project::set_name ( const char *name )
|
||||
{
|
||||
|
@ -75,27 +79,6 @@ Project::set_name ( const char *name )
|
|||
*s = ' ';
|
||||
}
|
||||
|
||||
bool
|
||||
Project::close ( void )
|
||||
{
|
||||
if ( ! open() )
|
||||
return true;
|
||||
|
||||
tle->save_timeline_settings();
|
||||
|
||||
Loggable::close();
|
||||
|
||||
write_info();
|
||||
|
||||
_is_open = false;
|
||||
|
||||
*Project::_name = '\0';
|
||||
|
||||
release_lock( &_lockfd, ".lock" );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
Project::write_info ( void )
|
||||
{
|
||||
|
@ -139,7 +122,33 @@ Project::read_info ( void )
|
|||
return true;
|
||||
}
|
||||
|
||||
/** ensure a project is valid before opening it... */
|
||||
/**********/
|
||||
/* Public */
|
||||
/**********/
|
||||
|
||||
/** Close the project (reclaiming all memory) */
|
||||
bool
|
||||
Project::close ( void )
|
||||
{
|
||||
if ( ! open() )
|
||||
return true;
|
||||
|
||||
tle->save_timeline_settings();
|
||||
|
||||
Loggable::close();
|
||||
|
||||
write_info();
|
||||
|
||||
_is_open = false;
|
||||
|
||||
*Project::_name = '\0';
|
||||
|
||||
release_lock( &_lockfd, ".lock" );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Ensure a project is valid before opening it... */
|
||||
bool
|
||||
Project::validate ( const char *name )
|
||||
{
|
||||
|
@ -169,7 +178,8 @@ Project::validate ( const char *name )
|
|||
return r;
|
||||
}
|
||||
|
||||
/** try to open project /name/. Returns 0 if sucsessful, an error code otherwise */
|
||||
/** Try to open project /name/. Returns 0 if sucsessful, an error code
|
||||
* otherwise */
|
||||
int
|
||||
Project::open ( const char *name )
|
||||
{
|
||||
|
@ -207,6 +217,8 @@ Project::open ( const char *name )
|
|||
return 0;
|
||||
}
|
||||
|
||||
/** Create a new project /name/ from existing template
|
||||
* /template_name/ */
|
||||
bool
|
||||
Project::create ( const char *name, const char *template_name )
|
||||
{
|
||||
|
@ -251,3 +263,10 @@ Project::create ( const char *name, const char *template_name )
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/** Replace the journal with a snapshot of the current state */
|
||||
void
|
||||
Project::compact ( void )
|
||||
{
|
||||
Loggable::compact();
|
||||
}
|
||||
|
|
|
@ -28,6 +28,10 @@ class Project
|
|||
static char _name[256];
|
||||
static char _path[512];
|
||||
|
||||
static bool write_info ( void );
|
||||
static bool read_info ( void );
|
||||
static void set_name ( const char *name );
|
||||
|
||||
public:
|
||||
|
||||
enum
|
||||
|
@ -37,10 +41,8 @@ public:
|
|||
E_PERM = -3,
|
||||
};
|
||||
|
||||
static bool write_info ( void );
|
||||
static bool read_info ( void );
|
||||
static const char *name ( void ) { return Project::_name; }
|
||||
static void set_name ( const char *name );
|
||||
static void compact ( void );
|
||||
static bool close ( void );
|
||||
static bool validate ( const char *name );
|
||||
static int open ( const char *name );
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
/*******************************************************************************/
|
||||
|
||||
|
||||
#include "Sequence.H"
|
||||
#include "Timeline.H"
|
||||
|
||||
|
@ -25,12 +24,20 @@
|
|||
|
||||
#include "Track.H"
|
||||
|
||||
#include "FL/event_name.H"
|
||||
|
||||
#include "Transport.H" // for locate()
|
||||
|
||||
#include "../FL/Boxtypes.H"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
|
||||
queue <Sequence_Widget *> Sequence::_delete_queue;
|
||||
|
||||
|
||||
|
||||
Sequence::Sequence ( Track *track ) : Fl_Widget( 0, 0, 0, 0 ), Loggable( true )
|
||||
{
|
||||
init();
|
||||
|
@ -59,22 +66,6 @@ Sequence::init ( void )
|
|||
// clear_visible_focus();
|
||||
}
|
||||
|
||||
void
|
||||
Sequence::clear ( void )
|
||||
{
|
||||
for ( std::list <Sequence_Widget*>::iterator i = _widgets.begin();
|
||||
i != _widgets.end(); ++i )
|
||||
{
|
||||
Sequence_Widget *w = *i;
|
||||
|
||||
*i = NULL;
|
||||
|
||||
delete w;
|
||||
}
|
||||
|
||||
_widgets.clear();
|
||||
}
|
||||
|
||||
Sequence::~Sequence ( )
|
||||
{
|
||||
DMESSAGE( "destroying sequence" );
|
||||
|
@ -86,12 +77,37 @@ Sequence::~Sequence ( )
|
|||
FATAL( "programming error: leaf destructor must call Sequence::clear()!" );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** remove all widgets from this sequence */
|
||||
void
|
||||
Sequence::clear ( void )
|
||||
{
|
||||
Loggable::block_start();
|
||||
|
||||
for ( std::list <Sequence_Widget*>::iterator i = _widgets.begin();
|
||||
i != _widgets.end(); ++i )
|
||||
{
|
||||
Sequence_Widget *w = *i;
|
||||
|
||||
*i = NULL;
|
||||
|
||||
delete w;
|
||||
}
|
||||
|
||||
_widgets.clear();
|
||||
|
||||
Loggable::block_end();
|
||||
}
|
||||
|
||||
/** given screen pixel coordinate X, return an absolute frame offset into this sequence */
|
||||
nframes_t
|
||||
Sequence::x_to_offset ( int X )
|
||||
{
|
||||
return timeline->xoffset + timeline->x_to_ts( X - x() );
|
||||
}
|
||||
|
||||
/** sort the widgets in this sequence by position */
|
||||
void
|
||||
Sequence::sort ( void )
|
||||
{
|
||||
|
@ -112,95 +128,12 @@ Sequence::overlaps ( Sequence_Widget *r )
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
Sequence::draw ( void )
|
||||
{
|
||||
|
||||
if ( ! fl_not_clipped( x(), y(), w(), h() ) )
|
||||
return;
|
||||
|
||||
fl_push_clip( x(), y(), w(), h() );
|
||||
|
||||
/* draw the box with the ends cut off. */
|
||||
draw_box( box(), x() - Fl::box_dx( box() ) - 1, y(), w() + Fl::box_dw( box() ) + 2, h(), color() );
|
||||
|
||||
int X, Y, W, H;
|
||||
|
||||
fl_clip_box( x(), y(), w(), h(), X, Y, W, H );
|
||||
|
||||
/* if ( Sequence_Widget::pushed() && Sequence_Widget::pushed()->sequence() == this ) */
|
||||
/* { */
|
||||
/* /\* make sure the Sequence_Widget::pushed widget is above all others *\/ */
|
||||
/* remove( Sequence_Widget::pushed() ); */
|
||||
/* add( Sequence_Widget::pushed() ); */
|
||||
/* } */
|
||||
|
||||
// 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();
|
||||
|
||||
fl_pop_clip();
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
Sequence::remove ( Sequence_Widget *r )
|
||||
{
|
||||
timeline->wrlock();
|
||||
|
||||
_widgets.remove( r );
|
||||
|
||||
timeline->unlock();
|
||||
|
||||
handle_widget_change( r->start(), r->length() );
|
||||
}
|
||||
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Sequence::handle_widget_change ( nframes_t start, nframes_t length )
|
||||
{
|
||||
// timeline->update_length( start + length );
|
||||
}
|
||||
|
||||
/** calculate the length of this sequence by looking at the end of the
|
||||
* least widget it contains */
|
||||
nframes_t
|
||||
Sequence::length ( void ) const
|
||||
{
|
||||
nframes_t l = 0;
|
||||
|
||||
for ( list <Sequence_Widget *>::const_iterator r = _widgets.begin(); r != _widgets.end(); ++r )
|
||||
l = max( l, (*r)->start() + (*r)->length() );
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
Sequence_Widget *
|
||||
Sequence::widget_at ( nframes_t ts, int Y )
|
||||
{
|
||||
|
@ -212,6 +145,8 @@ Sequence::widget_at ( nframes_t ts, int Y )
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/** return a pointer to the widget under the current mouse event, or
|
||||
* NULL if no widget intersects the event coordinates */
|
||||
Sequence_Widget *
|
||||
Sequence::event_widget ( void )
|
||||
{
|
||||
|
@ -219,17 +154,6 @@ Sequence::event_widget ( void )
|
|||
return widget_at( ets, Fl::event_y() );
|
||||
}
|
||||
|
||||
void
|
||||
Sequence::select_range ( int X, int W )
|
||||
{
|
||||
nframes_t sts = x_to_offset( 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)->start() > ets || (*r)->start() + (*r)->length() < sts ) )
|
||||
(*r)->select();
|
||||
}
|
||||
|
||||
void
|
||||
Sequence::add ( Sequence_Widget *r )
|
||||
{
|
||||
|
@ -254,13 +178,25 @@ Sequence::add ( Sequence_Widget *r )
|
|||
handle_widget_change( r->start(), r->length() );
|
||||
}
|
||||
|
||||
void
|
||||
Sequence::remove ( Sequence_Widget *r )
|
||||
{
|
||||
timeline->wrlock();
|
||||
|
||||
_widgets.remove( r );
|
||||
|
||||
timeline->unlock();
|
||||
|
||||
handle_widget_change( r->start(), r->length() );
|
||||
}
|
||||
|
||||
static nframes_t
|
||||
abs_diff ( nframes_t n1, nframes_t n2 )
|
||||
{
|
||||
return n1 > n2 ? n1 - n2 : n2 - n1;
|
||||
}
|
||||
|
||||
/* snap /r/ to nearest edge */
|
||||
/** snap widget /r/ to nearest edge */
|
||||
void
|
||||
Sequence::snap ( Sequence_Widget *r )
|
||||
{
|
||||
|
@ -306,38 +242,45 @@ Sequence::snap ( Sequence_Widget *r )
|
|||
r->start( f );
|
||||
}
|
||||
|
||||
/** return the location of the next widget from frame /from/ */
|
||||
nframes_t
|
||||
Sequence::next ( nframes_t from ) const
|
||||
|
||||
void
|
||||
Sequence::draw ( void )
|
||||
{
|
||||
for ( list <Sequence_Widget*>::const_iterator i = _widgets.begin(); i != _widgets.end(); i++ )
|
||||
if ( (*i)->start() > from )
|
||||
return (*i)->start();
|
||||
|
||||
if ( _widgets.size() )
|
||||
return _widgets.back()->start();
|
||||
else
|
||||
return 0;
|
||||
if ( ! fl_not_clipped( x(), y(), w(), h() ) )
|
||||
return;
|
||||
|
||||
fl_push_clip( x(), y(), w(), h() );
|
||||
|
||||
/* draw the box with the ends cut off. */
|
||||
draw_box( box(), x() - Fl::box_dx( box() ) - 1, y(), w() + Fl::box_dw( box() ) + 2, h(), color() );
|
||||
|
||||
int X, Y, W, H;
|
||||
|
||||
fl_clip_box( x(), y(), w(), h(), X, Y, W, H );
|
||||
|
||||
/* if ( Sequence_Widget::pushed() && Sequence_Widget::pushed()->sequence() == this ) */
|
||||
/* { */
|
||||
/* /\* make sure the Sequence_Widget::pushed widget is above all others *\/ */
|
||||
/* remove( Sequence_Widget::pushed() ); */
|
||||
/* add( Sequence_Widget::pushed() ); */
|
||||
/* } */
|
||||
|
||||
// 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();
|
||||
|
||||
fl_pop_clip();
|
||||
|
||||
}
|
||||
|
||||
/** return the location of the next widget from frame /from/ */
|
||||
nframes_t
|
||||
Sequence::prev ( nframes_t from ) const
|
||||
{
|
||||
for ( list <Sequence_Widget*>::const_reverse_iterator i = _widgets.rbegin(); i != _widgets.rend(); i++ )
|
||||
if ( (*i)->start() < from )
|
||||
return (*i)->start();
|
||||
|
||||
if ( _widgets.size() )
|
||||
return _widgets.front()->start();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
#include "FL/event_name.H"
|
||||
|
||||
#include "Transport.H" // for locate()
|
||||
|
||||
int
|
||||
Sequence::handle ( int m )
|
||||
{
|
||||
|
@ -509,3 +452,85 @@ Sequence::handle ( int m )
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**********/
|
||||
/* Public */
|
||||
/**********/
|
||||
|
||||
/** calculate the length of this sequence by looking at the end of the
|
||||
* least widget it contains */
|
||||
|
||||
/** return the length in frames of this sequence calculated from the
|
||||
* right edge of the rightmost widget */
|
||||
nframes_t
|
||||
Sequence::length ( void ) const
|
||||
{
|
||||
nframes_t l = 0;
|
||||
|
||||
for ( list <Sequence_Widget *>::const_iterator r = _widgets.begin(); r != _widgets.end(); ++r )
|
||||
l = max( l, (*r)->start() + (*r)->length() );
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
/** return the location of the next widget from frame /from/ */
|
||||
nframes_t
|
||||
Sequence::next ( nframes_t from ) const
|
||||
{
|
||||
for ( list <Sequence_Widget*>::const_iterator i = _widgets.begin(); i != _widgets.end(); i++ )
|
||||
if ( (*i)->start() > from )
|
||||
return (*i)->start();
|
||||
|
||||
if ( _widgets.size() )
|
||||
return _widgets.back()->start();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** return the location of the next widget from frame /from/ */
|
||||
nframes_t
|
||||
Sequence::prev ( nframes_t from ) const
|
||||
{
|
||||
for ( list <Sequence_Widget*>::const_reverse_iterator i = _widgets.rbegin(); i != _widgets.rend(); i++ )
|
||||
if ( (*i)->start() < from )
|
||||
return (*i)->start();
|
||||
|
||||
if ( _widgets.size() )
|
||||
return _widgets.front()->start();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** delete all selected widgets in this sequence */
|
||||
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();
|
||||
}
|
||||
|
||||
/** select all widgets intersecting with the range defined by the
|
||||
* pixel coordinates X through W */
|
||||
void
|
||||
Sequence::select_range ( int X, int W )
|
||||
{
|
||||
nframes_t sts = x_to_offset( 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)->start() > ets || (*r)->start() + (*r)->length() < sts ) )
|
||||
(*r)->select();
|
||||
}
|
||||
|
|
|
@ -21,6 +21,29 @@
|
|||
|
||||
#include <FL/fl_draw.H>
|
||||
|
||||
|
||||
|
||||
Sequence_Point::Sequence_Point ( const Sequence_Point &rhs ) : Sequence_Widget( rhs )
|
||||
{
|
||||
if ( _label )
|
||||
_label = strdup( rhs._label );
|
||||
}
|
||||
|
||||
Sequence_Point::Sequence_Point ( )
|
||||
{
|
||||
_label = NULL;
|
||||
|
||||
color( FL_CYAN );
|
||||
}
|
||||
|
||||
Sequence_Point::~Sequence_Point ( )
|
||||
{
|
||||
if ( _label )
|
||||
free( _label );
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
Sequence_Point::get ( Log_Entry &e ) const
|
||||
{
|
||||
|
|
|
@ -33,11 +33,13 @@ protected:
|
|||
void get ( Log_Entry &e ) const;
|
||||
void set ( Log_Entry &e );
|
||||
|
||||
Sequence_Point ( const Sequence_Point &rhs ) : Sequence_Widget( rhs )
|
||||
{
|
||||
if ( _label )
|
||||
_label = strdup( rhs._label );
|
||||
}
|
||||
|
||||
virtual void draw_box ( void );
|
||||
virtual void draw ( void );
|
||||
|
||||
Sequence_Point ( const Sequence_Point &rhs );
|
||||
Sequence_Point ( );
|
||||
~Sequence_Point ( );
|
||||
|
||||
public:
|
||||
|
||||
|
@ -68,21 +70,4 @@ public:
|
|||
|
||||
nframes_t length ( void ) const { return timeline->x_to_ts( abs_w() ); }
|
||||
|
||||
Sequence_Point ( )
|
||||
{
|
||||
_label = NULL;
|
||||
|
||||
color( FL_CYAN );
|
||||
}
|
||||
|
||||
|
||||
virtual ~Sequence_Point ( )
|
||||
{
|
||||
if ( _label )
|
||||
free( _label );
|
||||
}
|
||||
|
||||
virtual void draw_box ( void );
|
||||
virtual void draw ( void );
|
||||
|
||||
};
|
||||
|
|
|
@ -20,6 +20,23 @@
|
|||
#include "Sequence_Region.H"
|
||||
#include "Track.H"
|
||||
|
||||
|
||||
|
||||
Sequence_Region::Sequence_Region ( )
|
||||
{
|
||||
color( FL_CYAN );
|
||||
}
|
||||
|
||||
Sequence_Region::Sequence_Region ( const Sequence_Region &rhs ) : Sequence_Widget( rhs )
|
||||
{
|
||||
}
|
||||
|
||||
Sequence_Region::~Sequence_Region ( )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
Sequence_Region::get ( Log_Entry &e ) const
|
||||
{
|
||||
|
@ -29,7 +46,6 @@ Sequence_Region::get ( Log_Entry &e ) const
|
|||
Sequence_Widget::get( e );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Sequence_Region::set ( Log_Entry &e )
|
||||
{
|
||||
|
@ -49,18 +65,6 @@ Sequence_Region::set ( Log_Entry &e )
|
|||
Sequence_Widget::set( e );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Sequence_Region::draw_box ( void )
|
||||
{
|
||||
fl_draw_box( box(), line_x(), y(), abs_w(), h(), box_color() );
|
||||
}
|
||||
|
||||
void
|
||||
Sequence_Region::draw ( void )
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Sequence_Region::trim ( enum trim_e t, int X )
|
||||
{
|
||||
|
@ -232,3 +236,14 @@ Sequence_Region::handle ( int m )
|
|||
return 0;
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
Sequence_Region::draw_box ( void )
|
||||
{
|
||||
fl_draw_box( box(), line_x(), y(), abs_w(), h(), box_color() );
|
||||
}
|
||||
|
||||
void
|
||||
Sequence_Region::draw ( void )
|
||||
{
|
||||
}
|
||||
|
|
|
@ -33,20 +33,13 @@ protected:
|
|||
virtual void get ( Log_Entry &e ) const;
|
||||
virtual void set ( Log_Entry &e );
|
||||
|
||||
Sequence_Region ( )
|
||||
{
|
||||
color( FL_CYAN );
|
||||
}
|
||||
Sequence_Region ( );
|
||||
Sequence_Region ( const Sequence_Region &rhs );
|
||||
virtual ~Sequence_Region ( );
|
||||
|
||||
virtual ~Sequence_Region ( )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Sequence_Region ( const Sequence_Region &rhs ) : Sequence_Widget( rhs )
|
||||
{
|
||||
|
||||
}
|
||||
virtual int handle ( int m );
|
||||
virtual void draw_box( void );
|
||||
virtual void draw ( void );
|
||||
|
||||
public:
|
||||
|
||||
|
@ -55,8 +48,4 @@ public:
|
|||
enum trim_e { NO, LEFT, RIGHT };
|
||||
void trim ( enum trim_e t, int X );
|
||||
|
||||
virtual int handle ( int m );
|
||||
virtual void draw_box( void );
|
||||
virtual void draw ( void );
|
||||
|
||||
};
|
||||
|
|
|
@ -63,6 +63,8 @@ Sequence_Widget::~Sequence_Widget ( )
|
|||
_selection.remove( this );
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
Sequence_Widget::get ( Log_Entry &e ) const
|
||||
{
|
||||
|
|
|
@ -230,7 +230,7 @@ if ( r < 0 )
|
|||
if ( n != 2 )
|
||||
return;
|
||||
|
||||
Loggable::compact();}
|
||||
Project::compact();} selected
|
||||
xywh {20 20 40 25}
|
||||
}
|
||||
Submenu {} {
|
||||
|
@ -868,7 +868,7 @@ while ( _window->shown() )
|
|||
Function {make_window()} {open
|
||||
} {
|
||||
Fl_Window _window {
|
||||
label {New Project} open selected
|
||||
label {New Project} open
|
||||
xywh {615 414 550 195} type Double modal xclass Non_DAW visible
|
||||
} {
|
||||
Fl_File_Input _name {
|
||||
|
|
|
@ -23,6 +23,32 @@
|
|||
|
||||
|
||||
|
||||
Tempo_Point::Tempo_Point ( )
|
||||
{
|
||||
timeline->tempo_track->add( this );
|
||||
}
|
||||
|
||||
Tempo_Point::Tempo_Point ( nframes_t when, float bpm )
|
||||
{
|
||||
_tempo = bpm;
|
||||
|
||||
_make_label();
|
||||
|
||||
timeline->tempo_track->add( this );
|
||||
|
||||
start( when );
|
||||
|
||||
log_create();
|
||||
}
|
||||
|
||||
Tempo_Point::~Tempo_Point ( )
|
||||
{
|
||||
timeline->tempo_track->remove( this );
|
||||
log_destroy();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
Tempo_Point::get ( Log_Entry &e ) const
|
||||
{
|
||||
|
@ -58,33 +84,6 @@ Tempo_Point::set ( Log_Entry &e )
|
|||
}
|
||||
|
||||
|
||||
Tempo_Point::Tempo_Point ( )
|
||||
{
|
||||
timeline->tempo_track->add( this );
|
||||
}
|
||||
|
||||
Tempo_Point::Tempo_Point ( nframes_t when, float bpm )
|
||||
{
|
||||
_tempo = bpm;
|
||||
|
||||
_make_label();
|
||||
|
||||
timeline->tempo_track->add( this );
|
||||
|
||||
start( when );
|
||||
|
||||
log_create();
|
||||
}
|
||||
|
||||
|
||||
|
||||
Tempo_Point::~Tempo_Point ( )
|
||||
{
|
||||
timeline->tempo_track->remove( this );
|
||||
log_destroy();
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
Tempo_Point::handle ( int m )
|
||||
|
|
|
@ -23,6 +23,39 @@
|
|||
|
||||
|
||||
|
||||
Time_Point::Time_Point ( ) : _time( 4, 4 )
|
||||
{
|
||||
timeline->time_track->add( this );
|
||||
}
|
||||
|
||||
Time_Point::Time_Point ( nframes_t when, int bpb, int note ) : _time( bpb, note )
|
||||
{
|
||||
_make_label();
|
||||
|
||||
timeline->time_track->add( this );
|
||||
|
||||
start( when );
|
||||
|
||||
log_create();
|
||||
}
|
||||
|
||||
Time_Point::Time_Point ( const Time_Point &rhs ) : Sequence_Point( rhs )
|
||||
{
|
||||
_time = rhs._time;
|
||||
|
||||
log_create();
|
||||
|
||||
}
|
||||
|
||||
Time_Point::~Time_Point ( )
|
||||
{
|
||||
timeline->time_track->remove( this );
|
||||
|
||||
log_destroy();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
Time_Point::get ( Log_Entry &e ) const
|
||||
{
|
||||
|
@ -60,39 +93,6 @@ Time_Point::set ( Log_Entry &e )
|
|||
_make_label();
|
||||
}
|
||||
|
||||
|
||||
Time_Point::Time_Point ( ) : _time( 4, 4 )
|
||||
{
|
||||
timeline->time_track->add( this );
|
||||
}
|
||||
|
||||
Time_Point::Time_Point ( nframes_t when, int bpb, int note ) : _time( bpb, note )
|
||||
{
|
||||
_make_label();
|
||||
|
||||
timeline->time_track->add( this );
|
||||
|
||||
start( when );
|
||||
|
||||
log_create();
|
||||
}
|
||||
|
||||
Time_Point::Time_Point ( const Time_Point &rhs ) : Sequence_Point( rhs )
|
||||
{
|
||||
_time = rhs._time;
|
||||
|
||||
log_create();
|
||||
|
||||
}
|
||||
|
||||
Time_Point::~Time_Point ( )
|
||||
{
|
||||
timeline->time_track->remove( this );
|
||||
|
||||
log_destroy();
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
Time_Point::handle ( int m )
|
||||
{
|
||||
|
@ -113,12 +113,9 @@ Time_Point::handle ( int m )
|
|||
return Sequence_Point::handle( m );
|
||||
}
|
||||
|
||||
|
||||
|
||||
#include <FL/Fl_Int_Input.H>
|
||||
#include <FL/Fl_Menu_Window.H>
|
||||
|
||||
|
||||
class Time_Point_Editor : public Fl_Menu_Window
|
||||
{
|
||||
|
||||
|
@ -196,7 +193,6 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
bool
|
||||
Time_Point::edit ( time_sig *sig )
|
||||
{
|
||||
|
|
|
@ -106,6 +106,7 @@ Timeline::adjust_vscroll ( void )
|
|||
vscroll->value( _yposition, h() - rulers->h() - hscroll->h(), 0, pack_visible_height( tracks ) );
|
||||
}
|
||||
|
||||
/** recalculate the size of horizontal scrolling area and inform scrollbar */
|
||||
void
|
||||
Timeline::adjust_hscroll ( void )
|
||||
{
|
||||
|
@ -157,6 +158,7 @@ Timeline::menu_cb ( Fl_Widget *w, void *v )
|
|||
((Timeline*)v)->menu_cb( (Fl_Menu_*)w );
|
||||
}
|
||||
|
||||
/** ensure that p1 is less than p2 */
|
||||
void
|
||||
Timeline::fix_range ( void )
|
||||
{
|
||||
|
@ -466,24 +468,6 @@ Timeline::Timeline ( int X, int Y, int W, int H, const char* L ) : Fl_Overlay_Wi
|
|||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* float */
|
||||
/* Timeline::beats_per_minute ( nframes_t when ) const */
|
||||
/* { */
|
||||
|
||||
/* /\* return tempo_track->beats_per_minute( when ); *\/ */
|
||||
|
||||
/* } */
|
||||
|
||||
/* int */
|
||||
/* Timeline::beats_per_bar ( nframes_t when ) const */
|
||||
/* { */
|
||||
/* time_sig t = time_track->time( when ); */
|
||||
|
||||
/* return t.beats_per_bar; */
|
||||
/* } */
|
||||
|
||||
void
|
||||
Timeline::beats_per_minute ( nframes_t when, float bpm )
|
||||
{
|
||||
|
@ -496,7 +480,6 @@ Timeline::time ( nframes_t when, int bpb, int note_type )
|
|||
time_track->add( new Time_Point( when, bpb, note_type ) );
|
||||
}
|
||||
|
||||
|
||||
/************/
|
||||
/* Snapping */
|
||||
/************/
|
||||
|
@ -590,7 +573,6 @@ Timeline::next_line ( nframes_t *frame, bool bar ) const
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/** Set the value pointed to by /frame/ to the frame number of the of
|
||||
the nearest measure line to *less than* /when/. Returns true if
|
||||
the new value of *frame is valid, false otherwise. */
|
||||
|
@ -612,17 +594,17 @@ Timeline::prev_line ( nframes_t *frame, bool bar ) const
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** given screen pixel coordinate /x/ return frame offset into
|
||||
* timeline, taking into account the current scroll position, widget
|
||||
* layout, etc. */
|
||||
nframes_t
|
||||
Timeline::x_to_offset ( int x ) const
|
||||
{
|
||||
return x_to_ts( max( 0, x - Track::width() ) ) + xoffset;
|
||||
}
|
||||
|
||||
|
||||
/** draws a single measure line */
|
||||
static void
|
||||
draw_measure_cb ( nframes_t frame, const BBT &bbt, void *arg )
|
||||
|
@ -647,6 +629,7 @@ draw_measure_cb ( nframes_t frame, const BBT &bbt, void *arg )
|
|||
/* FIXME: wrong place for this */
|
||||
const float ticks_per_beat = 1920.0;
|
||||
|
||||
/** re-render the unified tempomap based on the current contents of the Time and Tempo sequences */
|
||||
void
|
||||
Timeline::update_tempomap ( void )
|
||||
{
|
||||
|
@ -664,6 +647,7 @@ Timeline::update_tempomap ( void )
|
|||
_tempomap.sort( Sequence_Widget::sort_func );
|
||||
}
|
||||
|
||||
/** return a stucture containing the BBT info which applies at /frame/ */
|
||||
position_info
|
||||
Timeline::solve_tempomap ( nframes_t frame ) const
|
||||
{
|
||||
|
@ -782,6 +766,7 @@ done:
|
|||
return pos;
|
||||
}
|
||||
|
||||
/** maybe draw appropriate measure lines in rectangle defined by X, Y, W, and H, using color /color/ as a base */
|
||||
void
|
||||
Timeline::draw_measure_lines ( int X, int Y, int W, int H, Fl_Color color )
|
||||
{
|
||||
|
@ -804,36 +789,6 @@ Timeline::draw_measure_lines ( int X, int Y, int W, int H, Fl_Color color )
|
|||
|
||||
}
|
||||
|
||||
/* /\** just like draw mesure lines except that it also draws the BBT values. *\/ */
|
||||
/* void */
|
||||
/* Timeline::draw_measure_BBT ( int X, int Y, int W, int H, Fl_Color color ) */
|
||||
/* { */
|
||||
/* // render_tempomap( X, Y, W, H, color, true ); */
|
||||
/* } */
|
||||
|
||||
void
|
||||
Timeline::xposition ( int X )
|
||||
{
|
||||
// _old_xposition = xoffset;
|
||||
|
||||
/* /\* FIXME: shouldn't have to do this... *\/ */
|
||||
/* X = min( X, ts_to_x( length() ) - tracks->w() - Track::width() ); */
|
||||
|
||||
xoffset = x_to_ts( X );
|
||||
|
||||
damage( FL_DAMAGE_SCROLL );
|
||||
}
|
||||
|
||||
void
|
||||
Timeline::yposition ( int Y )
|
||||
{
|
||||
// _old_yposition = _yposition;
|
||||
|
||||
_yposition = Y;
|
||||
|
||||
damage( FL_DAMAGE_SCROLL );
|
||||
}
|
||||
|
||||
void
|
||||
Timeline::draw_clip ( void * v, int X, int Y, int W, int H )
|
||||
{
|
||||
|
@ -855,6 +810,7 @@ Timeline::draw_clip ( void * v, int X, int Y, int W, int H )
|
|||
fl_pop_clip();
|
||||
}
|
||||
|
||||
/** handle resize event */
|
||||
void
|
||||
Timeline::resize ( int X, int Y, int W, int H )
|
||||
{
|
||||
|
@ -868,6 +824,7 @@ Timeline::resize ( int X, int Y, int W, int H )
|
|||
vscroll->size( vscroll->w(), H - 18 );
|
||||
}
|
||||
|
||||
/** draw ancillary cursors (not necessarily in the overlay plane) */
|
||||
void
|
||||
Timeline::draw_cursors ( void ) const
|
||||
{
|
||||
|
@ -960,7 +917,7 @@ done:
|
|||
|
||||
}
|
||||
|
||||
|
||||
/** draw a single cursor line at /frame/ with color /color/ using symbol routine /symbol/ for the cap */
|
||||
void
|
||||
Timeline::draw_cursor ( nframes_t frame, Fl_Color color, void (*symbol)(Fl_Color) ) const
|
||||
{
|
||||
|
@ -1031,8 +988,7 @@ Timeline::redraw_playhead ( void )
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/** called so many times a second to redraw the playhead etc. */
|
||||
/** called so many times a second to redraw the playhead etc. */
|
||||
void
|
||||
Timeline::update_cb ( void *arg )
|
||||
{
|
||||
|
@ -1043,6 +999,7 @@ Timeline::update_cb ( void *arg )
|
|||
tl->redraw_playhead();
|
||||
}
|
||||
|
||||
/** draw cursors in overlay plane */
|
||||
void
|
||||
Timeline::draw_overlay ( void )
|
||||
{
|
||||
|
@ -1075,9 +1032,7 @@ Timeline::draw_overlay ( void )
|
|||
|
||||
}
|
||||
|
||||
// #include "Sequence_Widget.H"
|
||||
|
||||
/** select all widgets in inside rectangle /r/ */
|
||||
/** select sequence widgets within rectangle /r/ */
|
||||
void
|
||||
Timeline::select ( const Rectangle &r )
|
||||
{
|
||||
|
@ -1092,19 +1047,20 @@ Timeline::select ( const Rectangle &r )
|
|||
}
|
||||
}
|
||||
|
||||
/** delete all selected sequence widgets */
|
||||
void
|
||||
Timeline::delete_selected ( void )
|
||||
{
|
||||
Sequence_Widget::delete_selected();
|
||||
}
|
||||
|
||||
/** clear the selection of seqeunce widgets */
|
||||
void
|
||||
Timeline::select_none ( void )
|
||||
{
|
||||
Sequence_Widget::select_none();
|
||||
}
|
||||
|
||||
|
||||
/** An unfortunate necessity for implementing our own DND aside from
|
||||
* the (bogus) native FLTK system */
|
||||
Track *
|
||||
|
@ -1137,19 +1093,6 @@ Timeline::handle_scroll ( int m )
|
|||
return 0;
|
||||
}
|
||||
|
||||
nframes_t
|
||||
Timeline::length ( void ) const
|
||||
{
|
||||
nframes_t l = 0;
|
||||
|
||||
for ( int i = tracks->children(); i--; )
|
||||
l = max( l, ((Track*)tracks->child( i ))->sequence()->length() );
|
||||
|
||||
// adjust_hscroll();
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
int
|
||||
Timeline::handle ( int m )
|
||||
{
|
||||
|
@ -1293,13 +1236,82 @@ Timeline::handle ( int m )
|
|||
}
|
||||
}
|
||||
|
||||
/** retrun a pointer to the track named /name/, or NULL if no track is named /name/ */
|
||||
Track *
|
||||
Timeline::track_by_name ( const char *name )
|
||||
{
|
||||
for ( int i = tracks->children(); i-- ; )
|
||||
{
|
||||
Track *t = (Track*)tracks->child( i );
|
||||
|
||||
if ( ! strcmp( name, t->name() ) )
|
||||
return t;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** return a malloc'd string representing a unique name for a new track */
|
||||
char *
|
||||
Timeline::get_unique_track_name ( const char *name )
|
||||
{
|
||||
char pat[256];
|
||||
|
||||
strcpy( pat, name );
|
||||
|
||||
for ( int i = 1; track_by_name( pat ); ++i )
|
||||
snprintf( pat, sizeof( pat ), "%s.%d", name, i );
|
||||
|
||||
return strdup( pat );
|
||||
}
|
||||
|
||||
/**********/
|
||||
/* Public */
|
||||
/**********/
|
||||
|
||||
/** return the current length of the timeline, which is arrived at by
|
||||
* calculating the end frame of the rightmost audio region on an
|
||||
* active audio sequence. Control_Points, etc. do not factor into this
|
||||
* calcaulation. */
|
||||
nframes_t
|
||||
Timeline::length ( void ) const
|
||||
{
|
||||
nframes_t l = 0;
|
||||
|
||||
for ( int i = tracks->children(); i--; )
|
||||
l = max( l, ((Track*)tracks->child( i ))->sequence()->length() );
|
||||
|
||||
// adjust_hscroll();
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
/** set horizontal scroll postion to absolute pixel coordinate /X/ */
|
||||
void
|
||||
Timeline::xposition ( int X )
|
||||
{
|
||||
xoffset = x_to_ts( X );
|
||||
|
||||
damage( FL_DAMAGE_SCROLL );
|
||||
}
|
||||
|
||||
/** set vertical scroll position to absolute pixel coordinate /Y/ */
|
||||
void
|
||||
Timeline::yposition ( int Y )
|
||||
{
|
||||
_yposition = Y;
|
||||
|
||||
damage( FL_DAMAGE_SCROLL );
|
||||
}
|
||||
|
||||
/** zoom in by one zoom step */
|
||||
void
|
||||
Timeline::zoom_in ( void )
|
||||
{
|
||||
hscroll->zoom_in();
|
||||
}
|
||||
|
||||
/** zoom out by one zoom step */
|
||||
void
|
||||
Timeline::zoom_out ( void )
|
||||
{
|
||||
|
@ -1322,6 +1334,7 @@ Timeline::zoom ( float secs )
|
|||
redraw();
|
||||
}
|
||||
|
||||
/** fit the zoom to the current length of the timeline (subject to nearest power of two) */
|
||||
void
|
||||
Timeline::zoom_fit ( void )
|
||||
{
|
||||
|
@ -1329,33 +1342,7 @@ Timeline::zoom_fit ( void )
|
|||
zoom( length() / (float)sample_rate() );
|
||||
}
|
||||
|
||||
Track *
|
||||
Timeline::track_by_name ( const char *name )
|
||||
{
|
||||
for ( int i = tracks->children(); i-- ; )
|
||||
{
|
||||
Track *t = (Track*)tracks->child( i );
|
||||
|
||||
if ( ! strcmp( name, t->name() ) )
|
||||
return t;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *
|
||||
Timeline::get_unique_track_name ( const char *name )
|
||||
{
|
||||
char pat[256];
|
||||
|
||||
strcpy( pat, name );
|
||||
|
||||
for ( int i = 1; track_by_name( pat ); ++i )
|
||||
snprintf( pat, sizeof( pat ), "%s.%d", name, i );
|
||||
|
||||
return strdup( pat );
|
||||
}
|
||||
|
||||
/** add /track/ to the timeline */
|
||||
void
|
||||
Timeline::add_track ( Track *track )
|
||||
{
|
||||
|
@ -1372,6 +1359,7 @@ Timeline::add_track ( Track *track )
|
|||
|
||||
}
|
||||
|
||||
/** remove /track/ from the timeline */
|
||||
void
|
||||
Timeline::remove_track ( Track *track )
|
||||
{
|
||||
|
|
285
Timeline/Track.C
285
Timeline/Track.C
|
@ -21,8 +21,6 @@
|
|||
|
||||
#include "Transport.H"
|
||||
|
||||
/* #include "Port.H" */
|
||||
|
||||
#include "../FL/Fl_Sometimes_Input.H"
|
||||
#include <FL/fl_ask.H>
|
||||
#include <FL/Fl_Color_Chooser.H>
|
||||
|
@ -41,76 +39,54 @@ const char *Track::capture_format = "Wav 24";
|
|||
|
||||
|
||||
|
||||
void
|
||||
Track::cb_input_field ( Fl_Widget *, void *v )
|
||||
Track::Track ( const char *L, int channels ) :
|
||||
Fl_Group ( 0, 0, 0, 0, 0 )
|
||||
{
|
||||
((Track*)v)->cb_input_field();
|
||||
}
|
||||
init();
|
||||
|
||||
void
|
||||
Track::cb_button ( Fl_Widget *w, void *v )
|
||||
{
|
||||
((Track*)v)->cb_button( w );
|
||||
if ( L )
|
||||
name( L );
|
||||
|
||||
color( (Fl_Color)rand() );
|
||||
|
||||
configure_inputs( channels );
|
||||
configure_outputs( channels );
|
||||
|
||||
log_create();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Track::cb_input_field ( void )
|
||||
Track::Track ( ) : Fl_Group( 0, 0, 1, 1 )
|
||||
{
|
||||
log_start();
|
||||
init();
|
||||
|
||||
name( name_field->value() );
|
||||
|
||||
log_end();
|
||||
timeline->add_track( this );
|
||||
}
|
||||
|
||||
void
|
||||
Track::cb_button ( Fl_Widget *w )
|
||||
Track::~Track ( )
|
||||
{
|
||||
Loggable::block_start();
|
||||
|
||||
if ( w == record_button )
|
||||
{
|
||||
takes = NULL;
|
||||
control = NULL;
|
||||
annotation = NULL;
|
||||
|
||||
}
|
||||
if ( w == mute_button )
|
||||
{
|
||||
Fl_Group::clear();
|
||||
|
||||
}
|
||||
if ( w == solo_button )
|
||||
{
|
||||
if ( solo_button->value() )
|
||||
++_soloing;
|
||||
else
|
||||
--_soloing;
|
||||
}
|
||||
else
|
||||
if ( w == take_menu )
|
||||
{
|
||||
int v = take_menu->value();
|
||||
log_destroy();
|
||||
|
||||
switch ( v )
|
||||
{
|
||||
case 0: /* show all takes */
|
||||
show_all_takes( take_menu->menu()[ v ].value() );
|
||||
return;
|
||||
case 1: /* new */
|
||||
sequence( (Audio_Sequence*)sequence()->clone_empty() );
|
||||
return;
|
||||
}
|
||||
timeline->remove_track( this );
|
||||
|
||||
const char *s = take_menu->menu()[ v ].text;
|
||||
/* give up our ports */
|
||||
configure_inputs( 0 );
|
||||
configure_outputs( 0 );
|
||||
|
||||
for ( int i = takes->children(); i--; )
|
||||
{
|
||||
Audio_Sequence *t = (Audio_Sequence*)takes->child( i );
|
||||
if ( ! strcmp( s, t->name() ) )
|
||||
{
|
||||
sequence( t );
|
||||
redraw();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
_sequence = NULL;
|
||||
|
||||
if ( _name )
|
||||
free( _name );
|
||||
|
||||
Loggable::block_end();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -231,50 +207,149 @@ Track::init ( void )
|
|||
|
||||
}
|
||||
|
||||
|
||||
|
||||
Track::Track ( const char *L, int channels ) :
|
||||
Fl_Group ( 0, 0, 0, 0, 0 )
|
||||
void
|
||||
Track::set ( Log_Entry &e )
|
||||
{
|
||||
init();
|
||||
for ( int i = 0; i < e.size(); ++i )
|
||||
{
|
||||
const char *s, *v;
|
||||
|
||||
if ( L )
|
||||
name( L );
|
||||
e.get( i, &s, &v );
|
||||
|
||||
color( (Fl_Color)rand() );
|
||||
if ( ! strcmp( s, ":height" ) )
|
||||
{
|
||||
size( atoi( v ) );
|
||||
|
||||
configure_inputs( channels );
|
||||
configure_outputs( channels );
|
||||
// Fl_Widget::size( w(), height() );
|
||||
resize();
|
||||
}
|
||||
else if ( ! strcmp( s, ":selected" ) )
|
||||
_selected = atoi( v );
|
||||
// else if ( ! strcmp( s, ":armed"
|
||||
else if ( ! strcmp( s, ":name" ) )
|
||||
name( v );
|
||||
else if ( ! strcmp( s, ":inputs" ) )
|
||||
configure_inputs( atoi( v ) );
|
||||
else if ( ! strcmp( s, ":outputs" ) )
|
||||
configure_outputs( atoi( v ) );
|
||||
else if ( ! strcmp( s, ":color" ) )
|
||||
{
|
||||
color( (Fl_Color)atoll( v ) );
|
||||
redraw();
|
||||
}
|
||||
else if ( ! strcmp( s, ":sequence" ) )
|
||||
{
|
||||
int i;
|
||||
sscanf( v, "%X", &i );
|
||||
|
||||
log_create();
|
||||
if ( i )
|
||||
{
|
||||
Audio_Sequence *t = (Audio_Sequence*)Loggable::find( i );
|
||||
|
||||
/* FIXME: our track might not have been
|
||||
* defined yet... what should we do about this
|
||||
* chicken/egg problem? */
|
||||
if ( t )
|
||||
{
|
||||
// assert( t );
|
||||
|
||||
sequence( t );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Track::~Track ( )
|
||||
|
||||
void
|
||||
Track::get ( Log_Entry &e ) const
|
||||
{
|
||||
Loggable::block_start();
|
||||
|
||||
takes = NULL;
|
||||
control = NULL;
|
||||
annotation = NULL;
|
||||
|
||||
Fl_Group::clear();
|
||||
|
||||
log_destroy();
|
||||
|
||||
timeline->remove_track( this );
|
||||
|
||||
/* give up our ports */
|
||||
configure_inputs( 0 );
|
||||
configure_outputs( 0 );
|
||||
|
||||
_sequence = NULL;
|
||||
|
||||
if ( _name )
|
||||
free( _name );
|
||||
|
||||
Loggable::block_end();
|
||||
e.add( ":name", _name );
|
||||
e.add( ":sequence", sequence() );
|
||||
e.add( ":selected", _selected );
|
||||
e.add( ":height", size() );
|
||||
e.add( ":inputs", input.size() );
|
||||
e.add( ":outputs", output.size() );
|
||||
e.add( ":color", (unsigned long)color());
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Track::cb_input_field ( Fl_Widget *, 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();
|
||||
|
||||
name( name_field->value() );
|
||||
|
||||
log_end();
|
||||
}
|
||||
|
||||
void
|
||||
Track::cb_button ( Fl_Widget *w )
|
||||
{
|
||||
|
||||
if ( w == record_button )
|
||||
{
|
||||
|
||||
}
|
||||
if ( w == mute_button )
|
||||
{
|
||||
|
||||
}
|
||||
if ( w == solo_button )
|
||||
{
|
||||
if ( solo_button->value() )
|
||||
++_soloing;
|
||||
else
|
||||
--_soloing;
|
||||
}
|
||||
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 */
|
||||
sequence( (Audio_Sequence*)sequence()->clone_empty() );
|
||||
return;
|
||||
}
|
||||
|
||||
const char *s = take_menu->menu()[ v ].text;
|
||||
|
||||
for ( int i = takes->children(); i--; )
|
||||
{
|
||||
Audio_Sequence *t = (Audio_Sequence*)takes->child( i );
|
||||
if ( ! strcmp( s, t->name() ) )
|
||||
{
|
||||
sequence( t );
|
||||
redraw();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int pack_visible( Fl_Pack *p )
|
||||
{
|
||||
int v = 0;
|
||||
|
@ -342,7 +417,6 @@ Track::size ( int v )
|
|||
resize();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Track::add ( Audio_Sequence * t )
|
||||
{
|
||||
|
@ -471,22 +545,6 @@ Track::select ( int X, int Y, int W, int H,
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
Track::draw ( void )
|
||||
{
|
||||
if ( _selected )
|
||||
{
|
||||
Fl_Color c = color();
|
||||
|
||||
color( FL_RED );
|
||||
|
||||
Fl_Group::draw();
|
||||
|
||||
color( c );
|
||||
}
|
||||
else
|
||||
Fl_Group::draw();
|
||||
}
|
||||
|
||||
#include <FL/Fl_Menu_Button.H>
|
||||
|
||||
|
@ -601,6 +659,23 @@ Track::menu ( void ) const
|
|||
#include "FL/event_name.H"
|
||||
#include "FL/test_press.H"
|
||||
|
||||
void
|
||||
Track::draw ( void )
|
||||
{
|
||||
if ( _selected )
|
||||
{
|
||||
Fl_Color c = color();
|
||||
|
||||
color( FL_RED );
|
||||
|
||||
Fl_Group::draw();
|
||||
|
||||
color( c );
|
||||
}
|
||||
else
|
||||
Fl_Group::draw();
|
||||
}
|
||||
|
||||
int
|
||||
Track::handle ( int m )
|
||||
{
|
||||
|
|
|
@ -97,16 +97,14 @@ private:
|
|||
void update_port_names ( void );
|
||||
const char *name_for_port( Port::type_e type, int n );
|
||||
|
||||
|
||||
Track ( ) : Fl_Group( 0, 0, 1, 1 )
|
||||
{
|
||||
init();
|
||||
|
||||
timeline->add_track( this );
|
||||
}
|
||||
|
||||
Track ( );
|
||||
void init ( void );
|
||||
|
||||
protected:
|
||||
|
||||
void get ( Log_Entry &e ) const;
|
||||
void set ( Log_Entry &e );
|
||||
|
||||
public:
|
||||
|
||||
Fl_Input *name_field;
|
||||
|
@ -128,76 +126,6 @@ public:
|
|||
Playback_DS *playback_ds;
|
||||
Record_DS *record_ds;
|
||||
|
||||
// const char *class_name ( void ) { return "Track"; }
|
||||
|
||||
void
|
||||
set ( Log_Entry &e )
|
||||
{
|
||||
for ( int i = 0; i < e.size(); ++i )
|
||||
{
|
||||
const char *s, *v;
|
||||
|
||||
e.get( i, &s, &v );
|
||||
|
||||
if ( ! strcmp( s, ":height" ) )
|
||||
{
|
||||
size( atoi( v ) );
|
||||
|
||||
// Fl_Widget::size( w(), height() );
|
||||
resize();
|
||||
}
|
||||
else if ( ! strcmp( s, ":selected" ) )
|
||||
_selected = atoi( v );
|
||||
// else if ( ! strcmp( s, ":armed"
|
||||
else if ( ! strcmp( s, ":name" ) )
|
||||
name( v );
|
||||
else if ( ! strcmp( s, ":inputs" ) )
|
||||
configure_inputs( atoi( v ) );
|
||||
else if ( ! strcmp( s, ":outputs" ) )
|
||||
configure_outputs( atoi( v ) );
|
||||
else if ( ! strcmp( s, ":color" ) )
|
||||
{
|
||||
color( (Fl_Color)atoll( v ) );
|
||||
redraw();
|
||||
}
|
||||
else if ( ! strcmp( s, ":sequence" ) )
|
||||
{
|
||||
int i;
|
||||
sscanf( v, "%X", &i );
|
||||
|
||||
if ( i )
|
||||
{
|
||||
Audio_Sequence *t = (Audio_Sequence*)Loggable::find( i );
|
||||
|
||||
/* FIXME: our track might not have been
|
||||
* defined yet... what should we do about this
|
||||
* chicken/egg problem? */
|
||||
if ( t )
|
||||
{
|
||||
// assert( t );
|
||||
|
||||
sequence( t );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
virtual void get ( Log_Entry &e ) const
|
||||
{
|
||||
e.add( ":name", _name );
|
||||
e.add( ":sequence", sequence() );
|
||||
e.add( ":selected", _selected );
|
||||
e.add( ":height", size() );
|
||||
e.add( ":inputs", input.size() );
|
||||
e.add( ":outputs", output.size() );
|
||||
e.add( ":color", (unsigned long)color());
|
||||
}
|
||||
|
||||
/* for loggable */
|
||||
LOG_CREATE_FUNC( Track );
|
||||
|
||||
|
@ -270,7 +198,6 @@ public:
|
|||
void draw ( void );
|
||||
int handle ( int m );
|
||||
|
||||
|
||||
/* Engine */
|
||||
const Audio_Region *capture_region ( void ) const;
|
||||
|
||||
|
|
50
util/file.C
50
util/file.C
|
@ -21,6 +21,7 @@
|
|||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
unsigned long
|
||||
mtime ( const char *file )
|
||||
|
@ -86,3 +87,52 @@ release_lock ( int *lockfd, const char *filename )
|
|||
|
||||
*lockfd = 0;
|
||||
}
|
||||
|
||||
int
|
||||
backwards_fgetc ( FILE *fp )
|
||||
{
|
||||
int c;
|
||||
|
||||
if ( fseek( fp, -1, SEEK_CUR ) != 0 )
|
||||
return -1;
|
||||
|
||||
c = fgetc( fp );
|
||||
|
||||
fseek( fp, -1, SEEK_CUR );
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
char *
|
||||
backwards_fgets ( char *s, int size, FILE *fp )
|
||||
{
|
||||
if ( fseek( fp, -1, SEEK_CUR ) != 0 )
|
||||
return NULL;
|
||||
|
||||
int c;
|
||||
while ( ( c = backwards_fgetc( fp ) ) >= 0 )
|
||||
if ( '\n' == c )
|
||||
break;
|
||||
|
||||
long here = ftell( fp );
|
||||
|
||||
fseek( fp, 1, SEEK_CUR );
|
||||
|
||||
char *r = fgets( s, size, fp );
|
||||
|
||||
fseek( fp, here, SEEK_SET );
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/** update the modification time of file referred to by /fd/ */
|
||||
void
|
||||
touch ( int fd )
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
fstat( fd, &st );
|
||||
|
||||
fchmod( fd, st.st_mode );
|
||||
}
|
||||
|
|
|
@ -17,9 +17,14 @@
|
|||
/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
/*******************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
unsigned long mtime ( const char *file );
|
||||
bool newer ( const char *file1, const char *file2 );
|
||||
unsigned long size ( const char *file );
|
||||
int exists ( const char *name );
|
||||
bool acquire_lock ( int *lockfd, const char *filename );
|
||||
void release_lock ( int *lockfd, const char *filename );
|
||||
int backwards_fgetc ( FILE *fp );
|
||||
char * backwards_fgets ( char *s, int size, FILE *fp );
|
||||
void touch ( int fd );
|
||||
|
|
Loading…
Reference in New Issue