Refactor common components of Timeline and Mixer into nonlib/
This commit is contained in:
parent
537f874417
commit
48698780d9
|
@ -1,5 +1,7 @@
|
|||
# -*- mode: makefile; -*-
|
||||
|
||||
all: FL
|
||||
|
||||
FL_SRCS := $(wildcard FL/*.C FL/*.fl)
|
||||
|
||||
FL_SRCS:=$(FL_SRCS:.fl=.C)
|
||||
|
|
13
Makefile
13
Makefile
|
@ -25,7 +25,7 @@
|
|||
|
||||
VERSION := 0.5.0
|
||||
|
||||
all: .config FL Timeline
|
||||
all: .config
|
||||
|
||||
.config: configure
|
||||
@ ./configure
|
||||
|
@ -58,10 +58,10 @@ CFLAGS+=-DVERSION=\"$(VERSION)\" \
|
|||
-DDOCUMENT_PATH=\"$(DOCUMENT_PATH)\" \
|
||||
-DPIXMAP_PATH=\"$(PIXMAP_PATH)\"
|
||||
|
||||
CXXFLAGS += $(SNDFILE_CFLAGS) $(LASH_CFLAGS) $(FLTK_CFLAGS)
|
||||
CXXFLAGS += $(SNDFILE_CFLAGS) $(LASH_CFLAGS) $(FLTK_CFLAGS) $(JACK_CFLAGS)
|
||||
CXXFLAGS := $(CFLAGS) $(CXXFLAGS)
|
||||
|
||||
INCLUDES := -I. -Iutil -IFL
|
||||
INCLUDES := -I. -Iutil -IFL -Inonlib
|
||||
|
||||
include scripts/colors
|
||||
|
||||
|
@ -81,10 +81,11 @@ endif
|
|||
DONE := $(BOLD)$(GREEN)done$(SGR0)
|
||||
|
||||
include FL/makefile.inc
|
||||
include nonlib/makefile.inc
|
||||
include Timeline/makefile.inc
|
||||
|
||||
SRCS:=$(Timeline_SRCS) $(FL_SRCS)
|
||||
OBJS:=$(FL_OBJS) $(Timeline_OBJS)
|
||||
SRCS:=$(FL_SRCS) $(nonlib_SRCS) $(Timeline_SRCS)
|
||||
OBJS:=$(FL_OBJS) $(nonlib_OBJS) $(Timeline_OBJS)
|
||||
|
||||
# FIXME: isn't there a better way?
|
||||
$(OBJS): .config Makefile
|
||||
|
@ -120,7 +121,7 @@ clean_deps:
|
|||
|
||||
.PHONEY: clean config depend clean_deps
|
||||
|
||||
clean: FL_clean Timeline_clean
|
||||
clean: FL_clean nonlib_clean Timeline_clean
|
||||
|
||||
dist:
|
||||
git archive --prefix=non-daw-$(VERSION)/ v$(VERSION) | bzip2 > non-daw-$(VERSION).tar.bz2
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
|
||||
#include "Control_Sequence.H"
|
||||
#include "Track.H"
|
||||
#include "Engine/Port.H"
|
||||
|
||||
#include "Engine/Engine.H" // for lock()
|
||||
|
||||
|
@ -42,7 +41,7 @@ Control_Sequence::Control_Sequence ( Track *track ) : Sequence( 0 )
|
|||
|
||||
_track = track;
|
||||
|
||||
_output = new Port( Port::Output, track->name(), track->ncontrols(), "cv" );
|
||||
_output = new JACK::Port( engine->client(), JACK::Port::Output, track->name(), track->ncontrols(), "cv" );
|
||||
|
||||
if ( track )
|
||||
track->add( this );
|
||||
|
@ -111,7 +110,7 @@ Control_Sequence::set ( Log_Entry &e )
|
|||
|
||||
assert( t );
|
||||
|
||||
_output = new Port( Port::Output, t->name(), t->ncontrols(), "cv" );
|
||||
_output = new JACK::Port( engine->client(), JACK::Port::Output, t->name(), t->ncontrols(), "cv" );
|
||||
|
||||
t->add( this );
|
||||
}
|
||||
|
|
|
@ -23,8 +23,9 @@
|
|||
#include "Sequence.H"
|
||||
#include "Control_Point.H"
|
||||
|
||||
#include "JACK/Port.H"
|
||||
|
||||
#include "Engine/Port.H"
|
||||
// class JACK::Port;
|
||||
|
||||
class Control_Sequence : public Sequence
|
||||
{
|
||||
|
@ -38,7 +39,7 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
Port *_output;
|
||||
JACK::Port *_output;
|
||||
|
||||
bool _highlighted;
|
||||
|
||||
|
@ -77,7 +78,7 @@ public:
|
|||
Fl_Cursor cursor ( void ) const { return FL_CURSOR_CROSS; }
|
||||
|
||||
/* Engine */
|
||||
void output ( Port *p ) { _output = p; }
|
||||
void output ( JACK::Port *p ) { _output = p; }
|
||||
nframes_t play ( sample_t *buf, nframes_t frame, nframes_t nframes );
|
||||
nframes_t process ( nframes_t nframes );
|
||||
|
||||
|
|
|
@ -23,10 +23,7 @@
|
|||
#include "../Timeline.H" // for process()
|
||||
#include "../Sequence_Widget.H" // for BBT and position info.
|
||||
|
||||
#define APP_NAME "Non-DAW" // FIXME: wrong place for this!
|
||||
|
||||
/* This is the home of the JACK process callback (does this *really*
|
||||
need to be a class?) */
|
||||
/* This is the home of the JACK process callback */
|
||||
|
||||
#include "const.h"
|
||||
#include "util/debug.h"
|
||||
|
@ -36,71 +33,11 @@
|
|||
|
||||
Engine::Engine ( ) : _thread( "RT" )
|
||||
{
|
||||
_freewheeling = false;
|
||||
_zombified = false;
|
||||
_client = NULL;
|
||||
_buffers_dropped = 0;
|
||||
_xruns = 0;
|
||||
}
|
||||
|
||||
Engine::~Engine ( )
|
||||
{
|
||||
jack_deactivate( _client );
|
||||
jack_client_close( _client );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************/
|
||||
/* Static Wrappers */
|
||||
/*******************/
|
||||
|
||||
int
|
||||
Engine::process ( nframes_t nframes, void *arg )
|
||||
{
|
||||
return ((Engine*)arg)->process( nframes );
|
||||
}
|
||||
|
||||
int
|
||||
Engine::sync ( jack_transport_state_t state, jack_position_t *pos, void *arg )
|
||||
{
|
||||
return ((Engine*)arg)->sync( state, pos );
|
||||
}
|
||||
|
||||
int
|
||||
Engine::xrun ( void *arg )
|
||||
{
|
||||
return ((Engine*)arg)->xrun();
|
||||
}
|
||||
|
||||
void
|
||||
Engine::timebase ( jack_transport_state_t state, jack_nframes_t nframes, jack_position_t *pos, int new_pos, void *arg )
|
||||
{
|
||||
((Engine*)arg)->timebase( state, nframes, pos, new_pos );
|
||||
}
|
||||
|
||||
void
|
||||
Engine::freewheel ( int starting, void *arg )
|
||||
{
|
||||
((Engine*)arg)->freewheel( starting );
|
||||
}
|
||||
|
||||
int
|
||||
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::shutdown ( void *arg )
|
||||
{
|
||||
((Engine*)arg)->shutdown();
|
||||
}
|
||||
|
||||
|
||||
|
@ -114,8 +51,6 @@ Engine::shutdown ( void *arg )
|
|||
int
|
||||
Engine::xrun ( void )
|
||||
{
|
||||
++_xruns;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -123,8 +58,6 @@ Engine::xrun ( void )
|
|||
void
|
||||
Engine::freewheel ( bool starting )
|
||||
{
|
||||
_freewheeling = starting;
|
||||
|
||||
if ( starting )
|
||||
DMESSAGE( "entering freewheeling mode" );
|
||||
else
|
||||
|
@ -252,14 +185,6 @@ Engine::process ( nframes_t nframes )
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* THREAD: RT */
|
||||
/** enter or leave freehweeling mode */
|
||||
void
|
||||
Engine::freewheeling ( bool yes )
|
||||
{
|
||||
if ( jack_set_freewheel( _client, yes ) )
|
||||
WARNING( "Unkown error while setting freewheeling mode" );
|
||||
}
|
||||
|
||||
/* TRHEAD: RT */
|
||||
void
|
||||
|
@ -272,43 +197,6 @@ Engine::thread_init ( void )
|
|||
void
|
||||
Engine::shutdown ( void )
|
||||
{
|
||||
_zombified = true;
|
||||
}
|
||||
|
||||
|
||||
/** Connect to JACK */
|
||||
const char *
|
||||
Engine::init ( void )
|
||||
{
|
||||
if (( _client = jack_client_open ( APP_NAME, (jack_options_t)0, NULL )) == 0 )
|
||||
return NULL;
|
||||
|
||||
#define set_callback( name ) jack_set_ ## name ## _callback( _client, &Engine:: name , this )
|
||||
|
||||
set_callback( thread_init );
|
||||
set_callback( process );
|
||||
set_callback( xrun );
|
||||
set_callback( freewheel );
|
||||
set_callback( buffer_size );
|
||||
|
||||
/* FIXME: should we wait to register this until after the project
|
||||
has been loaded (and we have disk threads running)? */
|
||||
set_callback( sync );
|
||||
|
||||
jack_set_timebase_callback( _client, 0, &Engine::timebase, this );
|
||||
|
||||
jack_on_shutdown( _client, &Engine::shutdown, this );
|
||||
|
||||
jack_activate( _client );
|
||||
|
||||
_sample_rate = frame_rate();
|
||||
|
||||
MESSAGE( "Jack sample rate is %lu", (unsigned long)_sample_rate );
|
||||
|
||||
timeline->_sample_rate = frame_rate();
|
||||
|
||||
/* we don't need to create any ports until tracks are created */
|
||||
return jack_get_client_name( _client );
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -21,41 +21,26 @@
|
|||
|
||||
#include "util/Mutex.H"
|
||||
|
||||
#include <jack/jack.h>
|
||||
|
||||
typedef jack_nframes_t nframes_t;
|
||||
|
||||
class Port;
|
||||
|
||||
#include "JACK/Client.H"
|
||||
|
||||
#include "Thread.H"
|
||||
|
||||
class Engine : public Mutex
|
||||
class Engine : public JACK::Client, public Mutex
|
||||
{
|
||||
jack_client_t *_client;
|
||||
|
||||
Thread _thread; /* only used for thread checking */
|
||||
|
||||
int _buffers_dropped; /* buffers dropped because of locking */
|
||||
nframes_t _sample_rate;
|
||||
volatile int _xruns;
|
||||
volatile bool _freewheeling;
|
||||
volatile bool _zombified;
|
||||
/* int _buffers_dropped; /\* buffers dropped because of locking *\/ */
|
||||
|
||||
static void shutdown ( void *arg );
|
||||
void shutdown ( void );
|
||||
static int process ( nframes_t nframes, void *arg );
|
||||
int process ( nframes_t nframes );
|
||||
static int sync ( jack_transport_state_t state, jack_position_t *pos, void *arg );
|
||||
int sync ( jack_transport_state_t state, jack_position_t *pos );
|
||||
static int xrun ( void *arg );
|
||||
int xrun ( void );
|
||||
static void timebase ( jack_transport_state_t state, jack_nframes_t nframes, jack_position_t *pos, int new_pos, void *arg );
|
||||
void timebase ( jack_transport_state_t state, jack_nframes_t nframes, jack_position_t *pos, int new_pos );
|
||||
static void freewheel ( int yes, void *arg );
|
||||
void freewheel ( bool yes );
|
||||
static int buffer_size ( nframes_t nframes, void *arg );
|
||||
int buffer_size ( nframes_t nframes );
|
||||
static void thread_init ( void *arg );
|
||||
void thread_init ( void );
|
||||
|
||||
Engine ( const Engine &rhs );
|
||||
|
@ -67,34 +52,20 @@ private:
|
|||
|
||||
friend class Port;
|
||||
friend class Transport;
|
||||
jack_client_t * client ( void ) { return _client; }
|
||||
|
||||
|
||||
public:
|
||||
|
||||
Engine ( );
|
||||
~Engine ( );
|
||||
|
||||
const char * init ( void );
|
||||
|
||||
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; }
|
||||
int xruns ( void ) const { return _xruns; };
|
||||
int dropped ( void ) const { return _buffers_dropped; }
|
||||
bool freewheeling ( void ) const { return _freewheeling; }
|
||||
void freewheeling ( bool yes );
|
||||
bool zombified ( void ) const { return _zombified; }
|
||||
|
||||
nframes_t system_latency ( void ) const { return nframes(); }
|
||||
|
||||
float cpu_load ( void ) const { return jack_cpu_load( _client ); }
|
||||
|
||||
float frames_to_milliseconds ( nframes_t frames )
|
||||
{
|
||||
return ( frames * 1000 ) / (float)frame_rate();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
extern Engine * engine;
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include "../Audio_Sequence.H"
|
||||
#include "../Track.H"
|
||||
|
||||
#include "Port.H"
|
||||
// #include "Port.H"
|
||||
#include "Playback_DS.H"
|
||||
#include "Engine.H"
|
||||
#include "dsp.h"
|
||||
|
|
|
@ -1,169 +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. */
|
||||
/*******************************************************************************/
|
||||
|
||||
/* Wrapper for a JACK audio port */
|
||||
|
||||
#include "Port.H"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "Engine.H"
|
||||
|
||||
#include <stdio.h> // sprintf
|
||||
|
||||
static const char *name_for_port ( Port::type_e dir, const char *base, int n, const char *type );
|
||||
|
||||
|
||||
|
||||
int
|
||||
Port::max_name ( void )
|
||||
{
|
||||
return jack_port_name_size() - jack_client_name_size() - 6;
|
||||
}
|
||||
|
||||
/* nframes is the number of frames to buffer */
|
||||
Port::Port ( jack_port_t *port )
|
||||
{
|
||||
_port = port;
|
||||
_name = jack_port_name( _port );
|
||||
}
|
||||
|
||||
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 )
|
||||
{
|
||||
static char pname[ 512 ];
|
||||
|
||||
const char *dir_s = dir == Port::Output ? "out" : "in";
|
||||
|
||||
strncpy( pname, base, Port::max_name() );
|
||||
pname[ Port::max_name() - 1 ] = '\0';
|
||||
|
||||
int l = strlen( pname );
|
||||
|
||||
if ( type )
|
||||
snprintf( pname + l, sizeof( pname ) - l, "/%s-%s-%d", type, dir_s, n + 1 );
|
||||
else
|
||||
snprintf( pname + l, sizeof( pname ) - l, "/%s-%d", dir_s, n + 1 );
|
||||
|
||||
return pname;
|
||||
}
|
||||
|
||||
void
|
||||
Port::activate ( const char *name, type_e dir )
|
||||
{
|
||||
_name = name;
|
||||
_port = jack_port_register( engine->client(), _name,
|
||||
JACK_DEFAULT_AUDIO_TYPE,
|
||||
dir == Output ? JackPortIsOutput : JackPortIsInput,
|
||||
0 );
|
||||
}
|
||||
|
||||
/** returns the sum of latency of all ports between this one and a
|
||||
terminal port. */
|
||||
/* FIMXE: how does JACK know that input A of client Foo connects to
|
||||
output Z of the same client in order to draw the line through Z to a
|
||||
terminal port? And, if this determination cannot be made, what use is
|
||||
this function? */
|
||||
|
||||
nframes_t
|
||||
Port::total_latency ( void ) const
|
||||
{
|
||||
return jack_port_get_total_latency( engine->client(), _port );
|
||||
}
|
||||
|
||||
/** returns the number of frames of latency assigned to this port */
|
||||
nframes_t
|
||||
Port::latency ( void ) const
|
||||
{
|
||||
return jack_port_get_latency( _port );
|
||||
}
|
||||
|
||||
/** inform JACK that port has /frames/ frames of latency */
|
||||
void
|
||||
Port::latency ( nframes_t frames )
|
||||
{
|
||||
jack_port_set_latency( _port, frames );
|
||||
}
|
||||
|
||||
void
|
||||
Port::shutdown ( void )
|
||||
{
|
||||
if ( _port )
|
||||
jack_port_unregister( engine->client(), _port );
|
||||
}
|
||||
|
||||
/** rename port */
|
||||
bool
|
||||
Port::name ( const char *name )
|
||||
{
|
||||
_name = name;
|
||||
|
||||
return 0 == jack_port_set_name( _port, name );
|
||||
}
|
||||
|
||||
bool
|
||||
Port::name ( const char *base, int n, const char *type )
|
||||
{
|
||||
return name( name_for_port( this->type(), base, n, type ) );
|
||||
}
|
||||
|
||||
void
|
||||
Port::write ( sample_t *buf, nframes_t nframes )
|
||||
{
|
||||
memcpy( buffer( nframes ), buf, nframes * sizeof( sample_t ) );
|
||||
}
|
||||
|
||||
void
|
||||
Port::read ( sample_t *buf, nframes_t nframes )
|
||||
{
|
||||
memcpy( buf, buffer( nframes ), nframes * sizeof( sample_t ) );
|
||||
}
|
||||
|
||||
void *
|
||||
Port::buffer ( nframes_t nframes )
|
||||
{
|
||||
return jack_port_get_buffer( _port, nframes );
|
||||
}
|
||||
|
||||
void
|
||||
Port::silence ( nframes_t nframes )
|
||||
{
|
||||
memset( buffer( nframes ), 0, nframes * sizeof( sample_t ) );
|
||||
}
|
|
@ -24,7 +24,7 @@
|
|||
#include "../Audio_Sequence.H"
|
||||
#include "../Track.H"
|
||||
|
||||
#include "Port.H"
|
||||
// #include "Port.H"
|
||||
#include "Record_DS.H"
|
||||
#include "Engine.H"
|
||||
#include "dsp.h"
|
||||
|
|
|
@ -77,7 +77,7 @@ Track::configure_outputs ( int n )
|
|||
{
|
||||
for ( int i = on; i < n; ++i )
|
||||
{
|
||||
Port p( Port::Output, name(), i );
|
||||
JACK::Port p( engine->client(), JACK::Port::Output, name(), i );
|
||||
|
||||
if ( p.valid() )
|
||||
output.push_back( p );
|
||||
|
@ -124,7 +124,7 @@ Track::configure_inputs ( int n )
|
|||
{
|
||||
for ( int i = on; i < n; ++i )
|
||||
{
|
||||
Port p( Port::Input, name(), i );
|
||||
JACK::Port p( engine->client(), JACK::Port::Input, name(), i );
|
||||
|
||||
if ( p.valid() )
|
||||
input.push_back( p );
|
||||
|
|
|
@ -1,129 +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. */
|
||||
/*******************************************************************************/
|
||||
|
||||
/* Handler based wrapper for LASH */
|
||||
|
||||
#include "LASH_Client.H"
|
||||
|
||||
#include "const.h"
|
||||
#include "util/debug.h"
|
||||
|
||||
|
||||
|
||||
LASH_Client::LASH_Client ( )
|
||||
{
|
||||
_void = 0;
|
||||
}
|
||||
|
||||
LASH_Client::~LASH_Client ( )
|
||||
{
|
||||
/* TODO: anything? */
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef HAVE_LASH
|
||||
|
||||
#include <lash/lash.h>
|
||||
|
||||
#define _client (static_cast<lash_client_t*>(_void))
|
||||
|
||||
bool
|
||||
LASH_Client::init ( const char *jack_name, const char *long_name, int *argc, char ***argv )
|
||||
{
|
||||
if ( ! ( _void = lash_init( lash_extract_args( argc, argv ), jack_name,
|
||||
LASH_Config_File, LASH_PROTOCOL( 2, 0 ) ) ) )
|
||||
return false;
|
||||
|
||||
/* register name */
|
||||
lash_jack_client_name( _client, jack_name );
|
||||
|
||||
lash_event_t *e = lash_event_new_with_type( LASH_Client_Name );
|
||||
lash_event_set_string( e, long_name );
|
||||
lash_send_event( _client, e );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
LASH_Client::enabled ( void )
|
||||
{
|
||||
return lash_enabled( _client );
|
||||
}
|
||||
|
||||
/** process any queued events */
|
||||
void
|
||||
LASH_Client::poll ( void )
|
||||
{
|
||||
if ( ! _client )
|
||||
return;
|
||||
|
||||
lash_event_t *e;
|
||||
|
||||
while ( ( e = lash_get_event( _client ) ) )
|
||||
{
|
||||
const char *name = lash_event_get_string( e );
|
||||
|
||||
switch ( lash_event_get_type( e ) )
|
||||
{
|
||||
case LASH_Save_File:
|
||||
handle_save_file( name );
|
||||
|
||||
lash_send_event( _client, lash_event_new_with_type( LASH_Save_File ) );
|
||||
|
||||
break;
|
||||
case LASH_Restore_File:
|
||||
if ( ! handle_restore_file( name ) )
|
||||
/* FIXME: should we tell lash that we couldn't load the song? */;
|
||||
|
||||
lash_send_event( _client, lash_event_new_with_type( LASH_Restore_File ) );
|
||||
|
||||
break;
|
||||
case LASH_Quit:
|
||||
handle_quit();
|
||||
break;
|
||||
default:
|
||||
WARNING( "unhandled LASH event" );
|
||||
break;
|
||||
}
|
||||
|
||||
lash_event_destroy( e );
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
bool
|
||||
LASH_Client::init ( const char *jack_name, const char *long_name, int *argc, char ***argv )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
LASH_Client::enabled ( void )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
LASH_Client::poll ( void )
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
|
@ -17,13 +17,13 @@
|
|||
/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
/*******************************************************************************/
|
||||
|
||||
/* Actual implementation of our side of the LASH protocol */
|
||||
/* Actual implementation of our side of the LASH_Engine protocol */
|
||||
|
||||
/* NOTES: Since LASH doesn't provide us with the information we
|
||||
* need--when we need it--we just punt and only use LASH to save and
|
||||
* load the path to the *real* project data. */
|
||||
|
||||
#include "LASH.H"
|
||||
#include "LASH_Engine.H"
|
||||
#include "Project.H"
|
||||
#include "TLE.H" // all this just for quit()
|
||||
|
||||
|
@ -37,24 +37,24 @@ extern TLE *tle;
|
|||
const float lash_poll_interval = 0.2f;
|
||||
|
||||
void
|
||||
LASH::timer_cb ( void *v )
|
||||
LASH_Engine::timer_cb ( void *v )
|
||||
{
|
||||
((LASH*)v)->poll();
|
||||
Fl::repeat_timeout( lash_poll_interval, &LASH::timer_cb, v );
|
||||
((LASH_Engine*)v)->poll();
|
||||
Fl::repeat_timeout( lash_poll_interval, &LASH_Engine::timer_cb, v );
|
||||
}
|
||||
|
||||
LASH::LASH ( )
|
||||
LASH_Engine::LASH_Engine ( )
|
||||
{
|
||||
Fl::add_timeout( lash_poll_interval, &LASH::timer_cb, this );
|
||||
Fl::add_timeout( lash_poll_interval, &LASH_Engine::timer_cb, this );
|
||||
}
|
||||
|
||||
LASH::~LASH ( )
|
||||
LASH_Engine::~LASH_Engine ( )
|
||||
{
|
||||
Fl::remove_timeout( &LASH::timer_cb );
|
||||
Fl::remove_timeout( &LASH_Engine::timer_cb );
|
||||
}
|
||||
|
||||
bool
|
||||
LASH::handle_save_file ( const char *path )
|
||||
LASH_Engine::handle_save_file ( const char *path )
|
||||
{
|
||||
MESSAGE( "LASH wants us to save \"%s\"", path );
|
||||
|
||||
|
@ -84,7 +84,7 @@ LASH::handle_save_file ( const char *path )
|
|||
}
|
||||
|
||||
bool
|
||||
LASH::handle_restore_file ( const char *path )
|
||||
LASH_Engine::handle_restore_file ( const char *path )
|
||||
{
|
||||
MESSAGE( "LASH wants us to load \"%s\"", path );
|
||||
|
||||
|
@ -112,7 +112,7 @@ LASH::handle_restore_file ( const char *path )
|
|||
}
|
||||
|
||||
void
|
||||
LASH::handle_quit ( void )
|
||||
LASH_Engine::handle_quit ( void )
|
||||
{
|
||||
MESSAGE( "LASH wants us to quit" );
|
||||
tle->quit();
|
|
@ -19,17 +19,17 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "LASH_Client.H"
|
||||
#include "LASH/Client.H"
|
||||
|
||||
class LASH : public LASH_Client
|
||||
class LASH_Engine : public LASH::Client
|
||||
{
|
||||
|
||||
static void timer_cb ( void *v );
|
||||
|
||||
public:
|
||||
|
||||
LASH ( );
|
||||
~LASH ( );
|
||||
LASH_Engine ( );
|
||||
~LASH_Engine ( );
|
||||
|
||||
bool handle_save_file ( const char *path );
|
||||
bool handle_restore_file ( const char *path );
|
|
@ -45,9 +45,6 @@
|
|||
|
||||
extern TLE *tle;
|
||||
|
||||
/* FIXME: wrong place for this */
|
||||
#define APP_TITLE "Non-DAW"
|
||||
|
||||
const int PROJECT_VERSION = 1;
|
||||
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ comment {//
|
|||
|
||||
decl {const float STATUS_UPDATE_FREQ = 0.5f;} {}
|
||||
|
||||
decl {\#include "LASH.H"} {}
|
||||
decl {\#include "LASH_Engine.H"} {}
|
||||
|
||||
decl {\#include "Fl_Menu_Settings.H"} {}
|
||||
|
||||
|
@ -67,7 +67,7 @@ decl {extern char project_display_name[256];} {global
|
|||
decl {extern char *user_config_dir;} {global
|
||||
}
|
||||
|
||||
decl {extern LASH *lash;} {global
|
||||
decl {extern LASH_Engine *lash;} {global
|
||||
}
|
||||
|
||||
class TLE {open
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
#include <vector>
|
||||
using std::vector;
|
||||
|
||||
#include "Engine/Port.H"
|
||||
#include "JACK/Port.H"
|
||||
|
||||
#include "Timeline.H"
|
||||
|
||||
|
@ -44,7 +44,7 @@ class Control_Sequence;
|
|||
class Annotation_Sequence;
|
||||
class Playback_DS;
|
||||
class Record_DS;
|
||||
class Port;
|
||||
// class JACK::Port;
|
||||
class Audio_Region;
|
||||
class Audio_File;
|
||||
|
||||
|
@ -94,7 +94,7 @@ private:
|
|||
bool configure_inputs ( int n );
|
||||
|
||||
void update_port_names ( void );
|
||||
const char *name_for_port( Port::type_e type, int n );
|
||||
const char *name_for_port( JACK::Port::type_e type, int n );
|
||||
void update_take_menu ( void );
|
||||
|
||||
Track ( );
|
||||
|
@ -124,8 +124,8 @@ public:
|
|||
Fl_Pack *takes;
|
||||
|
||||
|
||||
vector<Port> input; /* input ports... */
|
||||
vector<Port> output; /* output ports... */
|
||||
vector<JACK::Port> input; /* input ports... */
|
||||
vector<JACK::Port> output; /* output ports... */
|
||||
|
||||
Playback_DS *playback_ds;
|
||||
Record_DS *record_ds;
|
||||
|
|
|
@ -17,4 +17,6 @@
|
|||
/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
/*******************************************************************************/
|
||||
|
||||
#define APP_NAME "Non-DAW"
|
||||
#define APP_TITLE "The Non-DAW"
|
||||
#define __MODULE__ "non-daw"
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
#include "../FL/Boxtypes.H"
|
||||
|
||||
#include "Project.H"
|
||||
#include "LASH.H"
|
||||
#include "LASH_Engine.H"
|
||||
#include "Transport.H"
|
||||
#include "Engine/Engine.H"
|
||||
|
||||
|
@ -52,7 +52,7 @@
|
|||
Engine *engine;
|
||||
Timeline *timeline;
|
||||
Transport *transport;
|
||||
LASH *lash;
|
||||
LASH_Engine *lash;
|
||||
TLE *tle;
|
||||
|
||||
/* TODO: put these in a header */
|
||||
|
@ -138,15 +138,17 @@ main ( int argc, char **argv )
|
|||
|
||||
const char *jack_name;
|
||||
|
||||
if ( ! ( jack_name = engine->init() ) )
|
||||
if ( ! ( jack_name = engine->init( APP_NAME ) ) )
|
||||
FATAL( "Could not connect to JACK!" );
|
||||
|
||||
timeline->sample_rate( engine->sample_rate() );
|
||||
|
||||
/* always start stopped (please imagine for me a realistic
|
||||
* scenario requiring otherwise */
|
||||
transport->stop();
|
||||
|
||||
MESSAGE( "Initializing LASH" );
|
||||
lash = new LASH;
|
||||
lash = new LASH_Engine;
|
||||
|
||||
if ( argc > 1 && ! strcmp( argv[1], "--no-lash" ) )
|
||||
{
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
# -*- mode: makefile; -*-
|
||||
|
||||
all: Timeline
|
||||
|
||||
Timeline_VERSION := 0.5.0
|
||||
|
||||
Timeline_SRCS := $(wildcard Timeline/*.C Timeline/*.fl Timeline/Engine/*.C)
|
||||
|
@ -14,7 +16,7 @@ Timeline_LIBS := $(FLTK_LIBS) $(JACK_LIBS) $(SNDFILE_LIBS) $(LASH_LIBS)
|
|||
|
||||
Timeline/timeline: $(Timeline_OBJS) FL
|
||||
@ echo -n Linking timeline...
|
||||
@ $(CXX) $(CXXFLAGS) $(INCLUDES) $(Timeline_LIBS) $(Timeline_OBJS) -o $@ -LFL -lfl_widgets && echo $(DONE)
|
||||
@ $(CXX) $(CXXFLAGS) $(INCLUDES) $(Timeline_LIBS) $(Timeline_OBJS) -o $@ -LFL -lfl_widgets -Lnonlib -lnonlib && echo $(DONE)
|
||||
|
||||
Timeline: Timeline/timeline
|
||||
|
||||
|
|
|
@ -0,0 +1,143 @@
|
|||
|
||||
/*******************************************************************************/
|
||||
/* 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 "Client.H"
|
||||
|
||||
|
||||
|
||||
namespace JACK
|
||||
{
|
||||
|
||||
Client::Client ( )
|
||||
{
|
||||
_freewheeling = false;
|
||||
_zombified = false;
|
||||
_client = NULL;
|
||||
_xruns = 0;
|
||||
}
|
||||
|
||||
Client::~Client ( )
|
||||
{
|
||||
jack_deactivate( _client );
|
||||
jack_client_close( _client );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************/
|
||||
/* Static Wrappers */
|
||||
/*******************/
|
||||
|
||||
int
|
||||
Client::process ( nframes_t nframes, void *arg )
|
||||
{
|
||||
return ((Client*)arg)->process( nframes );
|
||||
}
|
||||
|
||||
int
|
||||
Client::sync ( jack_transport_state_t state, jack_position_t *pos, void *arg )
|
||||
{
|
||||
return ((Client*)arg)->sync( state, pos );
|
||||
}
|
||||
|
||||
int
|
||||
Client::xrun ( void *arg )
|
||||
{
|
||||
++((Client*)arg)->_xruns;
|
||||
return ((Client*)arg)->xrun();
|
||||
}
|
||||
|
||||
void
|
||||
Client::timebase ( jack_transport_state_t state, jack_nframes_t nframes, jack_position_t *pos, int new_pos, void *arg )
|
||||
{
|
||||
((Client*)arg)->timebase( state, nframes, pos, new_pos );
|
||||
}
|
||||
|
||||
void
|
||||
Client::freewheel ( int starting, void *arg )
|
||||
{
|
||||
((Client*)arg)->_freewheeling = starting;
|
||||
((Client*)arg)->freewheel( starting );
|
||||
}
|
||||
|
||||
int
|
||||
Client::buffer_size ( nframes_t nframes, void *arg )
|
||||
{
|
||||
return ((Client*)arg)->buffer_size( nframes );
|
||||
}
|
||||
|
||||
void
|
||||
Client::thread_init ( void *arg )
|
||||
{
|
||||
((Client*)arg)->thread_init();
|
||||
}
|
||||
|
||||
void
|
||||
Client::shutdown ( void *arg )
|
||||
{
|
||||
((Client*)arg)->_zombified = true;
|
||||
((Client*)arg)->shutdown();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Connect to JACK using client name /client_name/. Return a static
|
||||
* pointer to actual name as reported by JACK */
|
||||
const char *
|
||||
Client::init ( const char *client_name )
|
||||
{
|
||||
if (( _client = jack_client_open ( client_name, (jack_options_t)0, NULL )) == 0 )
|
||||
return NULL;
|
||||
|
||||
#define set_callback( name ) jack_set_ ## name ## _callback( _client, &Client:: name , this )
|
||||
|
||||
set_callback( thread_init );
|
||||
set_callback( process );
|
||||
set_callback( xrun );
|
||||
set_callback( freewheel );
|
||||
set_callback( buffer_size );
|
||||
|
||||
/* FIXME: should we wait to register this until after the project
|
||||
has been loaded (and we have disk threads running)? */
|
||||
set_callback( sync );
|
||||
|
||||
jack_set_timebase_callback( _client, 0, &Client::timebase, this );
|
||||
|
||||
jack_on_shutdown( _client, &Client::shutdown, this );
|
||||
|
||||
jack_activate( _client );
|
||||
|
||||
_sample_rate = frame_rate();
|
||||
|
||||
return jack_get_client_name( _client );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* THREAD: RT */
|
||||
/** enter or leave freehweeling mode */
|
||||
void
|
||||
Client::freewheeling ( bool yes )
|
||||
{
|
||||
if ( jack_set_freewheel( _client, yes ) )
|
||||
;
|
||||
// WARNING( "Unkown error while setting freewheeling mode" );
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
|
||||
/*******************************************************************************/
|
||||
/* 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 <jack/jack.h>
|
||||
|
||||
typedef jack_nframes_t nframes_t;
|
||||
typedef float sample_t;
|
||||
|
||||
namespace JACK
|
||||
{
|
||||
class Client
|
||||
{
|
||||
jack_client_t *_client;
|
||||
|
||||
nframes_t _sample_rate;
|
||||
volatile int _xruns;
|
||||
volatile bool _freewheeling;
|
||||
volatile bool _zombified;
|
||||
|
||||
static void shutdown ( void *arg );
|
||||
virtual void shutdown ( void ) = 0;
|
||||
static int process ( nframes_t nframes, void *arg );
|
||||
virtual int process ( nframes_t nframes ) = 0;
|
||||
static int sync ( jack_transport_state_t state, jack_position_t *pos, void *arg );
|
||||
virtual int sync ( jack_transport_state_t state, jack_position_t *pos ) = 0;
|
||||
static int xrun ( void *arg );
|
||||
virtual int xrun ( void ) = 0;
|
||||
static void timebase ( jack_transport_state_t state, jack_nframes_t nframes, jack_position_t *pos, int new_pos, void *arg );
|
||||
virtual void timebase ( jack_transport_state_t state, jack_nframes_t nframes, jack_position_t *pos, int new_pos ) = 0;
|
||||
static void freewheel ( int yes, void *arg );
|
||||
virtual void freewheel ( bool yes ) = 0;
|
||||
static int buffer_size ( nframes_t nframes, void *arg );
|
||||
virtual int buffer_size ( nframes_t nframes ) = 0;
|
||||
static void thread_init ( void *arg );
|
||||
virtual void thread_init ( void ) = 0;
|
||||
|
||||
Client ( const Client &rhs );
|
||||
Client & operator = ( const Client &rhs );
|
||||
|
||||
private:
|
||||
|
||||
friend class Port;
|
||||
friend class Transport;
|
||||
|
||||
public:
|
||||
|
||||
jack_client_t * client ( void ) { return _client; }
|
||||
|
||||
Client ( );
|
||||
virtual ~Client ( );
|
||||
|
||||
const char * init ( const char *client_name );
|
||||
|
||||
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; }
|
||||
int xruns ( void ) const { return _xruns; };
|
||||
bool freewheeling ( void ) const { return _freewheeling; }
|
||||
void freewheeling ( bool yes );
|
||||
bool zombified ( void ) const { return _zombified; }
|
||||
float cpu_load ( void ) const { return jack_cpu_load( _client ); }
|
||||
|
||||
};
|
||||
}
|
|
@ -0,0 +1,173 @@
|
|||
|
||||
/*******************************************************************************/
|
||||
/* 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. */
|
||||
/*******************************************************************************/
|
||||
|
||||
/* Wrapper for a JACK audio port */
|
||||
|
||||
#include "Port.H"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h> // sprintf
|
||||
|
||||
namespace JACK
|
||||
{
|
||||
|
||||
static const char *name_for_port ( Port::type_e dir, const char *base, int n, const char *type );
|
||||
|
||||
int
|
||||
Port::max_name ( void )
|
||||
{
|
||||
return jack_port_name_size() - jack_client_name_size() - 6;
|
||||
}
|
||||
|
||||
/* nframes is the number of frames to buffer */
|
||||
Port::Port ( jack_client_t *client, jack_port_t *port )
|
||||
{
|
||||
_client = client;
|
||||
_port = port;
|
||||
_name = jack_port_name( _port );
|
||||
}
|
||||
|
||||
Port::Port ( jack_client_t *client, const char *name, type_e dir )
|
||||
{
|
||||
_client = client;
|
||||
activate( name, dir );
|
||||
}
|
||||
|
||||
Port::Port ( jack_client_t *client, type_e dir, const char *base, int n, const char *type )
|
||||
{
|
||||
_client = client;
|
||||
|
||||
const char *name = name_for_port( dir, base, n, type );
|
||||
|
||||
activate( name, dir );
|
||||
}
|
||||
|
||||
Port::~Port ( )
|
||||
{
|
||||
/* if ( _port ) */
|
||||
/* jack_port_unregister( _client, _port ); */
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
static const char *
|
||||
name_for_port ( Port::type_e dir, const char *base, int n, const char *type )
|
||||
{
|
||||
static char pname[ 512 ];
|
||||
|
||||
const char *dir_s = dir == Port::Output ? "out" : "in";
|
||||
|
||||
strncpy( pname, base, Port::max_name() );
|
||||
pname[ Port::max_name() - 1 ] = '\0';
|
||||
|
||||
int l = strlen( pname );
|
||||
|
||||
if ( type )
|
||||
snprintf( pname + l, sizeof( pname ) - l, "/%s-%s-%d", type, dir_s, n + 1 );
|
||||
else
|
||||
snprintf( pname + l, sizeof( pname ) - l, "/%s-%d", dir_s, n + 1 );
|
||||
|
||||
return pname;
|
||||
}
|
||||
|
||||
void
|
||||
Port::activate ( const char *name, type_e dir )
|
||||
{
|
||||
_name = name;
|
||||
_port = jack_port_register( _client, _name,
|
||||
JACK_DEFAULT_AUDIO_TYPE,
|
||||
dir == Output ? JackPortIsOutput : JackPortIsInput,
|
||||
0 );
|
||||
}
|
||||
|
||||
/** returns the sum of latency of all ports between this one and a
|
||||
terminal port. */
|
||||
/* FIMXE: how does JACK know that input A of client Foo connects to
|
||||
output Z of the same client in order to draw the line through Z to a
|
||||
terminal port? And, if this determination cannot be made, what use is
|
||||
this function? */
|
||||
|
||||
nframes_t
|
||||
Port::total_latency ( void ) const
|
||||
{
|
||||
return jack_port_get_total_latency( _client, _port );
|
||||
}
|
||||
|
||||
/** returns the number of frames of latency assigned to this port */
|
||||
nframes_t
|
||||
Port::latency ( void ) const
|
||||
{
|
||||
return jack_port_get_latency( _port );
|
||||
}
|
||||
|
||||
/** inform JACK that port has /frames/ frames of latency */
|
||||
void
|
||||
Port::latency ( nframes_t frames )
|
||||
{
|
||||
jack_port_set_latency( _port, frames );
|
||||
}
|
||||
|
||||
void
|
||||
Port::shutdown ( void )
|
||||
{
|
||||
if ( _port )
|
||||
jack_port_unregister( _client, _port );
|
||||
}
|
||||
|
||||
/** rename port */
|
||||
bool
|
||||
Port::name ( const char *name )
|
||||
{
|
||||
_name = name;
|
||||
|
||||
return 0 == jack_port_set_name( _port, name );
|
||||
}
|
||||
|
||||
bool
|
||||
Port::name ( const char *base, int n, const char *type )
|
||||
{
|
||||
return name( name_for_port( this->type(), base, n, type ) );
|
||||
}
|
||||
|
||||
void
|
||||
Port::write ( sample_t *buf, nframes_t nframes )
|
||||
{
|
||||
memcpy( buffer( nframes ), buf, nframes * sizeof( sample_t ) );
|
||||
}
|
||||
|
||||
void
|
||||
Port::read ( sample_t *buf, nframes_t nframes )
|
||||
{
|
||||
memcpy( buf, buffer( nframes ), nframes * sizeof( sample_t ) );
|
||||
}
|
||||
|
||||
void *
|
||||
Port::buffer ( nframes_t nframes )
|
||||
{
|
||||
return jack_port_get_buffer( _port, nframes );
|
||||
}
|
||||
|
||||
void
|
||||
Port::silence ( nframes_t nframes )
|
||||
{
|
||||
memset( buffer( nframes ), 0, nframes * sizeof( sample_t ) );
|
||||
}
|
||||
|
||||
}
|
|
@ -19,14 +19,16 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <jack/jack.h>
|
||||
// #include <jack/jack.h>
|
||||
#include "Client.H"
|
||||
|
||||
#include "types.h"
|
||||
|
||||
class Port
|
||||
namespace JACK
|
||||
{
|
||||
class Port
|
||||
{
|
||||
jack_port_t *_port;
|
||||
const char *_name;
|
||||
jack_client_t *_client;
|
||||
|
||||
/* FIXME: reference count? */
|
||||
|
||||
|
@ -34,15 +36,15 @@ class Port
|
|||
/* Port ( const Port &rhs ); */
|
||||
/* Port & operator= ( const Port &rhs ); */
|
||||
|
||||
public:
|
||||
public:
|
||||
|
||||
enum type_e { Output, Input };
|
||||
|
||||
static int max_name ( void );
|
||||
|
||||
Port ( jack_port_t *port );
|
||||
Port ( const char *name, type_e dir );
|
||||
Port ( type_e dir, const char *base, int n, const char *type=0 );
|
||||
Port ( jack_client_t *client, jack_port_t *port );
|
||||
Port ( jack_client_t *client, const char *name, type_e dir );
|
||||
Port ( jack_client_t *client, type_e dir, const char *base, int n, const char *type=0 );
|
||||
|
||||
// Port ( );
|
||||
~Port ( );
|
||||
|
@ -63,6 +65,7 @@ public:
|
|||
const char * name ( void ) const { return _name; }
|
||||
bool name ( const char *name );
|
||||
bool name ( const char *base, int n, const char *type=0 );
|
||||
|
||||
nframes_t total_latency ( void ) const;
|
||||
nframes_t latency ( void ) const;
|
||||
void latency ( nframes_t frames );
|
||||
|
@ -73,4 +76,6 @@ public:
|
|||
void read ( sample_t *buf, nframes_t nframes );
|
||||
void *buffer ( nframes_t nframes );
|
||||
void silence ( nframes_t nframes );
|
||||
};
|
||||
};
|
||||
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
# -*- mode: makefile; -*-
|
||||
|
||||
nonlib_SRCS := $(wildcard JACK/*.C LASH/*.C)
|
||||
|
||||
nonlib_SRCS:=$(sort $(nonlib_SRCS))
|
||||
nonlib_OBJS:=$(nonlib_SRCS:.C=.o)
|
||||
|
||||
all: nonlib/libnonlib.a
|
||||
|
||||
nonlib/libnonlib.a: $(nonlib_OBJS)
|
||||
@ ar rcs $@ $(nonlib_OBJS)
|
||||
|
||||
.PHONEY: nonlib
|
||||
nonlib: nonlib/libnonlib.a
|
||||
|
||||
nonlib_clean:
|
||||
rm -f $(nonlib_OBJS) nonlib/libnonlib.a
|
|
@ -0,0 +1,134 @@
|
|||
|
||||
/*******************************************************************************/
|
||||
/* 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. */
|
||||
/*******************************************************************************/
|
||||
|
||||
/* Handler based wrapper for LASH */
|
||||
|
||||
#include "Client.H"
|
||||
|
||||
/* #include "const.h" */
|
||||
/* #include "util/debug.h" */
|
||||
|
||||
|
||||
|
||||
namespace LASH
|
||||
{
|
||||
|
||||
Client::Client ( )
|
||||
{
|
||||
_void = 0;
|
||||
}
|
||||
|
||||
Client::~Client ( )
|
||||
{
|
||||
/* TODO: anything? */
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef HAVE_LASH
|
||||
|
||||
#include <lash/lash.h>
|
||||
|
||||
#define _client (static_cast<lash_client_t*>(_void))
|
||||
|
||||
bool
|
||||
Client::init ( const char *jack_name, const char *long_name, int *argc, char ***argv )
|
||||
{
|
||||
if ( ! ( _void = lash_init( lash_extract_args( argc, argv ), jack_name,
|
||||
LASH_Config_File, LASH_PROTOCOL( 2, 0 ) ) ) )
|
||||
return false;
|
||||
|
||||
/* register name */
|
||||
lash_jack_client_name( _client, jack_name );
|
||||
|
||||
lash_event_t *e = lash_event_new_with_type( LASH_Client_Name );
|
||||
lash_event_set_string( e, long_name );
|
||||
lash_send_event( _client, e );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
Client::enabled ( void )
|
||||
{
|
||||
return lash_enabled( _client );
|
||||
}
|
||||
|
||||
/** process any queued events */
|
||||
void
|
||||
Client::poll ( void )
|
||||
{
|
||||
if ( ! _client )
|
||||
return;
|
||||
|
||||
lash_event_t *e;
|
||||
|
||||
while ( ( e = lash_get_event( _client ) ) )
|
||||
{
|
||||
const char *name = lash_event_get_string( e );
|
||||
|
||||
switch ( lash_event_get_type( e ) )
|
||||
{
|
||||
case LASH_Save_File:
|
||||
handle_save_file( name );
|
||||
|
||||
lash_send_event( _client, lash_event_new_with_type( LASH_Save_File ) );
|
||||
|
||||
break;
|
||||
case LASH_Restore_File:
|
||||
if ( ! handle_restore_file( name ) )
|
||||
/* FIXME: should we tell lash that we couldn't load the song? */;
|
||||
|
||||
lash_send_event( _client, lash_event_new_with_type( LASH_Restore_File ) );
|
||||
|
||||
break;
|
||||
case LASH_Quit:
|
||||
handle_quit();
|
||||
break;
|
||||
default:
|
||||
// WARNING( "unhandled LASH event" );
|
||||
break;
|
||||
}
|
||||
|
||||
lash_event_destroy( e );
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
bool
|
||||
Client::init ( const char *jack_name, const char *long_name, int *argc, char ***argv )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
Client::enabled ( void )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
Client::poll ( void )
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
|
@ -21,21 +21,23 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
class LASH_Client
|
||||
namespace LASH
|
||||
{
|
||||
class Client
|
||||
{
|
||||
/* to avoid including the lash header here... */
|
||||
void *_void;
|
||||
|
||||
protected:
|
||||
protected:
|
||||
|
||||
virtual bool handle_save_file ( const char *path ) = 0;
|
||||
virtual bool handle_restore_file ( const char *path ) = 0;
|
||||
virtual void handle_quit ( void ) = 0;
|
||||
|
||||
public:
|
||||
public:
|
||||
|
||||
LASH_Client ( );
|
||||
virtual ~LASH_Client ( );
|
||||
Client ( );
|
||||
virtual ~Client ( );
|
||||
|
||||
bool init ( const char *jack_name, const char *full_name, int *argc, char ***argv );
|
||||
bool enabled ( void );
|
||||
|
@ -46,4 +48,5 @@ public:
|
|||
|
||||
/* TODO: project_add, project_remove, project_dir, project_name, percentage */
|
||||
|
||||
};
|
||||
};
|
||||
}
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
#include "Log_Entry.H"
|
||||
|
||||
#include "const.h"
|
||||
// #include "const.h"
|
||||
#include "util/debug.h"
|
||||
|
||||
Log_Entry::Log_Entry ( )
|
|
@ -20,6 +20,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "Loggable.H"
|
||||
|
||||
#include "types.h"
|
||||
|
||||
class Log_Entry
|
|
@ -33,7 +33,7 @@
|
|||
|
||||
#include "util/file.h"
|
||||
|
||||
#include "const.h"
|
||||
// #include "const.h"
|
||||
#include "util/debug.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
@ -66,7 +66,6 @@ Loggable::~Loggable ( )
|
|||
_loggables[ _id ].loggable = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void
|
||||
|
@ -92,7 +91,6 @@ Loggable::find ( unsigned int id )
|
|||
return _loggables[ id ].loggable;
|
||||
}
|
||||
|
||||
|
||||
/** Open the journal /filename/ and replay it, bringing the end state back into RAM */
|
||||
bool
|
||||
Loggable::open ( const char *filename )
|
||||
|
@ -161,6 +159,17 @@ Loggable::load_unjournaled_state ( void )
|
|||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/** replay journal or snapshot */
|
||||
bool
|
||||
Loggable::replay ( const char *file )
|
||||
{
|
||||
FILE *fp = fopen( file, "r" );
|
||||
|
||||
replay( fp );
|
||||
|
||||
fclose( fp );
|
||||
}
|
||||
|
||||
/** replay journal or snapshot */
|
||||
bool
|
||||
Loggable::replay ( FILE *fp )
|
|
@ -31,7 +31,7 @@
|
|||
#include <string>
|
||||
#include <queue>
|
||||
|
||||
#include "types.h"
|
||||
// #include "types.h"
|
||||
|
||||
typedef void (progress_func)( int, void * );
|
||||
typedef void (snapshot_func)( void * );
|
||||
|
@ -102,9 +102,6 @@ private:
|
|||
|
||||
static void flush ( void );
|
||||
|
||||
static bool snapshot ( FILE * fp );
|
||||
static bool snapshot ( const char *name );
|
||||
static bool replay ( FILE *fp );
|
||||
|
||||
void init ( bool loggable=true )
|
||||
{
|
||||
|
@ -129,8 +126,15 @@ private:
|
|||
void record_unjournaled ( void ) const;
|
||||
static bool load_unjournaled_state ( void );
|
||||
|
||||
static bool replay ( FILE *fp );
|
||||
static bool replay ( const char *name );
|
||||
|
||||
public:
|
||||
|
||||
|
||||
static bool snapshot( FILE * fp );
|
||||
static bool snapshot( const char *name );
|
||||
|
||||
static void snapshot_callback ( snapshot_func *p, void *arg ) { _snapshot_callback = p; _snapshot_callback_arg = arg; }
|
||||
static void progress_callback ( progress_func *p, void *arg ) { _progress_callback = p; _progress_callback_arg = arg;}
|
||||
static const char *escape ( const char *s );
|
|
@ -33,28 +33,35 @@ buffer_apply_gain ( sample_t *buf, nframes_t nframes, float g )
|
|||
}
|
||||
|
||||
void
|
||||
buffer_apply_gain_buffer ( sample_t *buf, sample_t *gainbuf, nframes_t nframes )
|
||||
buffer_apply_gain_buffer ( sample_t *buf, const sample_t *gainbuf, nframes_t nframes )
|
||||
{
|
||||
while ( nframes-- )
|
||||
*(buf++) *= *(gainbuf++);
|
||||
}
|
||||
|
||||
void
|
||||
buffer_mix ( sample_t *dst, sample_t *src, nframes_t nframes )
|
||||
buffer_copy_and_apply_gain_buffer ( sample_t *dst, const sample_t *src, const sample_t *gainbuf, nframes_t nframes )
|
||||
{
|
||||
while ( nframes-- )
|
||||
*(dst++) = *(src++) * *(gainbuf++);
|
||||
}
|
||||
|
||||
void
|
||||
buffer_mix ( sample_t *dst, const sample_t *src, nframes_t nframes )
|
||||
{
|
||||
while ( nframes-- )
|
||||
*(dst++) += *(src++);
|
||||
}
|
||||
|
||||
void
|
||||
buffer_mix_with_gain ( sample_t *dst, sample_t *src, nframes_t nframes, float g )
|
||||
buffer_mix_with_gain ( sample_t *dst, const sample_t *src, nframes_t nframes, float g )
|
||||
{
|
||||
while ( nframes-- )
|
||||
*(dst++) += *(src++) * g;
|
||||
}
|
||||
|
||||
void
|
||||
buffer_interleave_one_channel ( sample_t *dst, sample_t *src, int channel, int channels, nframes_t nframes )
|
||||
buffer_interleave_one_channel ( sample_t *dst, const sample_t *src, int channel, int channels, nframes_t nframes )
|
||||
{
|
||||
dst += channel;
|
||||
|
||||
|
@ -66,7 +73,7 @@ buffer_interleave_one_channel ( sample_t *dst, sample_t *src, int channel, int c
|
|||
}
|
||||
|
||||
void
|
||||
buffer_interleave_one_channel_and_mix ( sample_t *dst, sample_t *src, int channel, int channels, nframes_t nframes )
|
||||
buffer_interleave_one_channel_and_mix ( sample_t *dst, const sample_t *src, int channel, int channels, nframes_t nframes )
|
||||
{
|
||||
dst += channel;
|
||||
|
||||
|
@ -78,7 +85,7 @@ buffer_interleave_one_channel_and_mix ( sample_t *dst, sample_t *src, int channe
|
|||
}
|
||||
|
||||
void
|
||||
buffer_deinterleave_one_channel ( sample_t *dst, sample_t *src, int channel, int channels, nframes_t nframes )
|
||||
buffer_deinterleave_one_channel ( sample_t *dst, const sample_t *src, int channel, int channels, nframes_t nframes )
|
||||
{
|
||||
src += channel;
|
||||
|
||||
|
@ -107,3 +114,16 @@ buffer_is_digital_black ( sample_t *buf, nframes_t nframes )
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
buffer_copy ( sample_t *dst, const sample_t *src, nframes_t nframes )
|
||||
{
|
||||
memcpy( dst, src, nframes * sizeof( sample_t ) );
|
||||
}
|
||||
|
||||
void
|
||||
buffer_copy_and_apply_gain ( sample_t *dst, const sample_t *src, nframes_t nframes, float gain )
|
||||
{
|
||||
memcpy( dst, src, nframes * sizeof( sample_t ) );
|
||||
buffer_apply_gain( dst, nframes, gain );
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
|
||||
/*******************************************************************************/
|
||||
/* 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 "JACK/Client.H"
|
||||
#include <math.h>
|
||||
|
||||
void buffer_apply_gain ( sample_t *buf, nframes_t nframes, float g );
|
||||
void buffer_apply_gain_buffer ( sample_t *buf, const sample_t *gainbuf, nframes_t nframes );
|
||||
void buffer_copy_and_apply_gain_buffer ( sample_t *dst, const sample_t *src, const sample_t *gainbuf, nframes_t nframes );
|
||||
void buffer_mix ( sample_t *dst, const sample_t *src, nframes_t nframes );
|
||||
void buffer_mix_with_gain ( sample_t *dst, const sample_t *src, nframes_t nframes, float g );
|
||||
void buffer_interleave_one_channel ( sample_t *dst, const sample_t *src, int channel, int channels, nframes_t nframes );
|
||||
void buffer_interleave_one_channel_and_mix ( sample_t *dst, const sample_t *src, int channel, int channels, nframes_t nframes );
|
||||
void buffer_deinterleave_one_channel ( sample_t *dst, const sample_t *src, int channel, int channels, nframes_t nframes );
|
||||
void buffer_fill_with_silence ( sample_t *buf, nframes_t nframes );
|
||||
bool buffer_is_digital_black ( sample_t *buf, nframes_t nframes );
|
||||
void buffer_copy ( sample_t *dst, const sample_t *src, nframes_t nframes );
|
||||
void buffer_copy_and_apply_gain ( sample_t *dst, const sample_t *src, nframes_t nframes, float gain );
|
||||
|
||||
// from SWH plugins.
|
||||
// Convert a value in dB's to a coefficent
|
||||
#define DB_CO(g) ((g) > -90.0f ? powf(10.0f, (g) * 0.05f) : 0.0f)
|
||||
#define CO_DB(v) (20.0f * log10f(v))
|
|
@ -0,0 +1,17 @@
|
|||
# -*- mode: makefile; -*-
|
||||
|
||||
nonlib_SRCS := $(wildcard nonlib/*.C nonlib/JACK/*.C nonlib/LASH/*.C)
|
||||
|
||||
nonlib_SRCS:=$(sort $(nonlib_SRCS))
|
||||
nonlib_OBJS:=$(nonlib_SRCS:.C=.o)
|
||||
|
||||
all: nonlib/libnonlib.a
|
||||
|
||||
nonlib/libnonlib.a: $(nonlib_OBJS)
|
||||
@ ar rcs $@ $(nonlib_OBJS)
|
||||
|
||||
.PHONEY: nonlib
|
||||
nonlib: nonlib/libnonlib.a
|
||||
|
||||
nonlib_clean:
|
||||
rm -f $(nonlib_OBJS) nonlib/libnonlib.a
|
|
@ -19,14 +19,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "types.h"
|
||||
#include <jack/jack.h>
|
||||
|
||||
void buffer_apply_gain ( sample_t *buf, nframes_t nframes, float g );
|
||||
void buffer_apply_gain_buffer ( sample_t *buf, sample_t *gainbuf, nframes_t nframes );
|
||||
void buffer_mix ( sample_t *dst, sample_t *src, nframes_t nframes );
|
||||
void buffer_mix_with_gain ( sample_t *dst, sample_t *src, nframes_t nframes, float g );
|
||||
void buffer_interleave_one_channel ( sample_t *dst, sample_t *src, int channel, int channels, nframes_t nframes );
|
||||
void buffer_interleave_one_channel_and_mix ( sample_t *dst, sample_t *src, int channel, int channels, nframes_t nframes );
|
||||
void buffer_deinterleave_one_channel ( sample_t *dst, sample_t *src, int channel, int channels, nframes_t nframes );
|
||||
void buffer_fill_with_silence ( sample_t *buf, nframes_t nframes );
|
||||
bool buffer_is_digital_black ( sample_t *buf, nframes_t nframes );
|
||||
typedef jack_nframes_t nframes_t;
|
||||
typedef float sample_t;
|
Loading…
Reference in New Issue