@@ -1,5 +1,7 @@ | |||||
# -*- mode: makefile; -*- | # -*- mode: makefile; -*- | ||||
all: FL | |||||
FL_SRCS := $(wildcard FL/*.C FL/*.fl) | FL_SRCS := $(wildcard FL/*.C FL/*.fl) | ||||
FL_SRCS:=$(FL_SRCS:.fl=.C) | FL_SRCS:=$(FL_SRCS:.fl=.C) | ||||
@@ -25,7 +25,7 @@ | |||||
VERSION := 0.5.0 | VERSION := 0.5.0 | ||||
all: .config FL Timeline | |||||
all: .config | |||||
.config: configure | .config: configure | ||||
@ ./configure | @ ./configure | ||||
@@ -58,10 +58,10 @@ CFLAGS+=-DVERSION=\"$(VERSION)\" \ | |||||
-DDOCUMENT_PATH=\"$(DOCUMENT_PATH)\" \ | -DDOCUMENT_PATH=\"$(DOCUMENT_PATH)\" \ | ||||
-DPIXMAP_PATH=\"$(PIXMAP_PATH)\" | -DPIXMAP_PATH=\"$(PIXMAP_PATH)\" | ||||
CXXFLAGS += $(SNDFILE_CFLAGS) $(LASH_CFLAGS) $(FLTK_CFLAGS) | |||||
CXXFLAGS += $(SNDFILE_CFLAGS) $(LASH_CFLAGS) $(FLTK_CFLAGS) $(JACK_CFLAGS) | |||||
CXXFLAGS := $(CFLAGS) $(CXXFLAGS) | CXXFLAGS := $(CFLAGS) $(CXXFLAGS) | ||||
INCLUDES := -I. -Iutil -IFL | |||||
INCLUDES := -I. -Iutil -IFL -Inonlib | |||||
include scripts/colors | include scripts/colors | ||||
@@ -81,10 +81,11 @@ endif | |||||
DONE := $(BOLD)$(GREEN)done$(SGR0) | DONE := $(BOLD)$(GREEN)done$(SGR0) | ||||
include FL/makefile.inc | include FL/makefile.inc | ||||
include nonlib/makefile.inc | |||||
include Timeline/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? | # FIXME: isn't there a better way? | ||||
$(OBJS): .config Makefile | $(OBJS): .config Makefile | ||||
@@ -120,7 +121,7 @@ clean_deps: | |||||
.PHONEY: clean config depend clean_deps | .PHONEY: clean config depend clean_deps | ||||
clean: FL_clean Timeline_clean | |||||
clean: FL_clean nonlib_clean Timeline_clean | |||||
dist: | dist: | ||||
git archive --prefix=non-daw-$(VERSION)/ v$(VERSION) | bzip2 > non-daw-$(VERSION).tar.bz2 | git archive --prefix=non-daw-$(VERSION)/ v$(VERSION) | bzip2 > non-daw-$(VERSION).tar.bz2 | ||||
@@ -21,7 +21,6 @@ | |||||
#include "Control_Sequence.H" | #include "Control_Sequence.H" | ||||
#include "Track.H" | #include "Track.H" | ||||
#include "Engine/Port.H" | |||||
#include "Engine/Engine.H" // for lock() | #include "Engine/Engine.H" // for lock() | ||||
@@ -42,7 +41,7 @@ Control_Sequence::Control_Sequence ( Track *track ) : Sequence( 0 ) | |||||
_track = track; | _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 ) | if ( track ) | ||||
track->add( this ); | track->add( this ); | ||||
@@ -111,7 +110,7 @@ Control_Sequence::set ( Log_Entry &e ) | |||||
assert( t ); | 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 ); | t->add( this ); | ||||
} | } | ||||
@@ -23,8 +23,9 @@ | |||||
#include "Sequence.H" | #include "Sequence.H" | ||||
#include "Control_Point.H" | #include "Control_Point.H" | ||||
#include "JACK/Port.H" | |||||
#include "Engine/Port.H" | |||||
// class JACK::Port; | |||||
class Control_Sequence : public Sequence | class Control_Sequence : public Sequence | ||||
{ | { | ||||
@@ -38,7 +39,7 @@ public: | |||||
private: | private: | ||||
Port *_output; | |||||
JACK::Port *_output; | |||||
bool _highlighted; | bool _highlighted; | ||||
@@ -77,7 +78,7 @@ public: | |||||
Fl_Cursor cursor ( void ) const { return FL_CURSOR_CROSS; } | Fl_Cursor cursor ( void ) const { return FL_CURSOR_CROSS; } | ||||
/* Engine */ | /* 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 play ( sample_t *buf, nframes_t frame, nframes_t nframes ); | ||||
nframes_t process ( nframes_t nframes ); | nframes_t process ( nframes_t nframes ); | ||||
@@ -23,10 +23,7 @@ | |||||
#include "../Timeline.H" // for process() | #include "../Timeline.H" // for process() | ||||
#include "../Sequence_Widget.H" // for BBT and position info. | #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 "const.h" | ||||
#include "util/debug.h" | #include "util/debug.h" | ||||
@@ -36,71 +33,11 @@ | |||||
Engine::Engine ( ) : _thread( "RT" ) | Engine::Engine ( ) : _thread( "RT" ) | ||||
{ | { | ||||
_freewheeling = false; | |||||
_zombified = false; | |||||
_client = NULL; | |||||
_buffers_dropped = 0; | _buffers_dropped = 0; | ||||
_xruns = 0; | |||||
} | } | ||||
Engine::~Engine ( ) | 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 | int | ||||
Engine::xrun ( void ) | Engine::xrun ( void ) | ||||
{ | { | ||||
++_xruns; | |||||
return 0; | return 0; | ||||
} | } | ||||
@@ -123,8 +58,6 @@ Engine::xrun ( void ) | |||||
void | void | ||||
Engine::freewheel ( bool starting ) | Engine::freewheel ( bool starting ) | ||||
{ | { | ||||
_freewheeling = starting; | |||||
if ( starting ) | if ( starting ) | ||||
DMESSAGE( "entering freewheeling mode" ); | DMESSAGE( "entering freewheeling mode" ); | ||||
else | else | ||||
@@ -252,14 +185,6 @@ Engine::process ( nframes_t nframes ) | |||||
return 0; | 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 */ | /* TRHEAD: RT */ | ||||
void | void | ||||
@@ -272,43 +197,6 @@ Engine::thread_init ( void ) | |||||
void | void | ||||
Engine::shutdown ( 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 | void | ||||
@@ -21,41 +21,26 @@ | |||||
#include "util/Mutex.H" | #include "util/Mutex.H" | ||||
#include <jack/jack.h> | |||||
typedef jack_nframes_t nframes_t; | |||||
class Port; | class Port; | ||||
#include "JACK/Client.H" | |||||
#include "Thread.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 */ | Thread _thread; /* only used for thread checking */ | ||||
int _buffers_dropped; /* buffers dropped because of locking */ | 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 ); | void shutdown ( void ); | ||||
static int process ( nframes_t nframes, void *arg ); | |||||
int process ( nframes_t nframes ); | 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 ); | int sync ( jack_transport_state_t state, jack_position_t *pos ); | ||||
static int xrun ( void *arg ); | |||||
int xrun ( void ); | 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 ); | 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 ); | void freewheel ( bool yes ); | ||||
static int buffer_size ( nframes_t nframes, void *arg ); | |||||
int buffer_size ( nframes_t nframes ); | int buffer_size ( nframes_t nframes ); | ||||
static void thread_init ( void *arg ); | |||||
void thread_init ( void ); | void thread_init ( void ); | ||||
Engine ( const Engine &rhs ); | Engine ( const Engine &rhs ); | ||||
@@ -67,34 +52,20 @@ private: | |||||
friend class Port; | friend class Port; | ||||
friend class Transport; | friend class Transport; | ||||
jack_client_t * client ( void ) { return _client; } | |||||
public: | public: | ||||
Engine ( ); | Engine ( ); | ||||
~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; } | 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(); } | 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 ) | float frames_to_milliseconds ( nframes_t frames ) | ||||
{ | { | ||||
return ( frames * 1000 ) / (float)frame_rate(); | return ( frames * 1000 ) / (float)frame_rate(); | ||||
} | } | ||||
}; | }; | ||||
extern Engine * engine; | extern Engine * engine; |
@@ -25,7 +25,7 @@ | |||||
#include "../Audio_Sequence.H" | #include "../Audio_Sequence.H" | ||||
#include "../Track.H" | #include "../Track.H" | ||||
#include "Port.H" | |||||
// #include "Port.H" | |||||
#include "Playback_DS.H" | #include "Playback_DS.H" | ||||
#include "Engine.H" | #include "Engine.H" | ||||
#include "dsp.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 "../Audio_Sequence.H" | ||||
#include "../Track.H" | #include "../Track.H" | ||||
#include "Port.H" | |||||
// #include "Port.H" | |||||
#include "Record_DS.H" | #include "Record_DS.H" | ||||
#include "Engine.H" | #include "Engine.H" | ||||
#include "dsp.h" | #include "dsp.h" | ||||
@@ -77,7 +77,7 @@ Track::configure_outputs ( int n ) | |||||
{ | { | ||||
for ( int i = on; i < n; ++i ) | 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() ) | if ( p.valid() ) | ||||
output.push_back( p ); | output.push_back( p ); | ||||
@@ -124,7 +124,7 @@ Track::configure_inputs ( int n ) | |||||
{ | { | ||||
for ( int i = on; i < n; ++i ) | 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() ) | if ( p.valid() ) | ||||
input.push_back( p ); | 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. */ | /* 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 | /* 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 | * need--when we need it--we just punt and only use LASH to save and | ||||
* load the path to the *real* project data. */ | * load the path to the *real* project data. */ | ||||
#include "LASH.H" | |||||
#include "LASH_Engine.H" | |||||
#include "Project.H" | #include "Project.H" | ||||
#include "TLE.H" // all this just for quit() | #include "TLE.H" // all this just for quit() | ||||
@@ -37,24 +37,24 @@ extern TLE *tle; | |||||
const float lash_poll_interval = 0.2f; | const float lash_poll_interval = 0.2f; | ||||
void | 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 | bool | ||||
LASH::handle_save_file ( const char *path ) | |||||
LASH_Engine::handle_save_file ( const char *path ) | |||||
{ | { | ||||
MESSAGE( "LASH wants us to save \"%s\"", path ); | MESSAGE( "LASH wants us to save \"%s\"", path ); | ||||
@@ -84,7 +84,7 @@ LASH::handle_save_file ( const char *path ) | |||||
} | } | ||||
bool | bool | ||||
LASH::handle_restore_file ( const char *path ) | |||||
LASH_Engine::handle_restore_file ( const char *path ) | |||||
{ | { | ||||
MESSAGE( "LASH wants us to load \"%s\"", path ); | MESSAGE( "LASH wants us to load \"%s\"", path ); | ||||
@@ -112,7 +112,7 @@ LASH::handle_restore_file ( const char *path ) | |||||
} | } | ||||
void | void | ||||
LASH::handle_quit ( void ) | |||||
LASH_Engine::handle_quit ( void ) | |||||
{ | { | ||||
MESSAGE( "LASH wants us to quit" ); | MESSAGE( "LASH wants us to quit" ); | ||||
tle->quit(); | tle->quit(); |
@@ -19,17 +19,17 @@ | |||||
#pragma once | #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 ); | static void timer_cb ( void *v ); | ||||
public: | public: | ||||
LASH ( ); | |||||
~LASH ( ); | |||||
LASH_Engine ( ); | |||||
~LASH_Engine ( ); | |||||
bool handle_save_file ( const char *path ); | bool handle_save_file ( const char *path ); | ||||
bool handle_restore_file ( const char *path ); | bool handle_restore_file ( const char *path ); |
@@ -45,9 +45,6 @@ | |||||
extern TLE *tle; | extern TLE *tle; | ||||
/* FIXME: wrong place for this */ | |||||
#define APP_TITLE "Non-DAW" | |||||
const int PROJECT_VERSION = 1; | const int PROJECT_VERSION = 1; | ||||
@@ -1,5 +1,5 @@ | |||||
# data file for the Fltk User Interface Designer (fluid) | # data file for the Fltk User Interface Designer (fluid) | ||||
version 1.0108 | |||||
version 1.0108 | |||||
header_name {.H} | header_name {.H} | ||||
code_name {.C} | code_name {.C} | ||||
comment {// | comment {// | ||||
@@ -24,7 +24,7 @@ comment {// | |||||
decl {const float STATUS_UPDATE_FREQ = 0.5f;} {} | decl {const float STATUS_UPDATE_FREQ = 0.5f;} {} | ||||
decl {\#include "LASH.H"} {} | |||||
decl {\#include "LASH_Engine.H"} {} | |||||
decl {\#include "Fl_Menu_Settings.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 char *user_config_dir;} {global | ||||
} | } | ||||
decl {extern LASH *lash;} {global | |||||
decl {extern LASH_Engine *lash;} {global | |||||
} | } | ||||
class TLE {open | class TLE {open | ||||
@@ -36,7 +36,7 @@ | |||||
#include <vector> | #include <vector> | ||||
using std::vector; | using std::vector; | ||||
#include "Engine/Port.H" | |||||
#include "JACK/Port.H" | |||||
#include "Timeline.H" | #include "Timeline.H" | ||||
@@ -44,7 +44,7 @@ class Control_Sequence; | |||||
class Annotation_Sequence; | class Annotation_Sequence; | ||||
class Playback_DS; | class Playback_DS; | ||||
class Record_DS; | class Record_DS; | ||||
class Port; | |||||
// class JACK::Port; | |||||
class Audio_Region; | class Audio_Region; | ||||
class Audio_File; | class Audio_File; | ||||
@@ -94,7 +94,7 @@ private: | |||||
bool configure_inputs ( int n ); | bool configure_inputs ( int n ); | ||||
void update_port_names ( void ); | 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 ); | void update_take_menu ( void ); | ||||
Track ( ); | Track ( ); | ||||
@@ -124,8 +124,8 @@ public: | |||||
Fl_Pack *takes; | 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; | Playback_DS *playback_ds; | ||||
Record_DS *record_ds; | Record_DS *record_ds; | ||||
@@ -17,4 +17,6 @@ | |||||
/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | /* 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" | #define __MODULE__ "non-daw" |
@@ -43,7 +43,7 @@ | |||||
#include "../FL/Boxtypes.H" | #include "../FL/Boxtypes.H" | ||||
#include "Project.H" | #include "Project.H" | ||||
#include "LASH.H" | |||||
#include "LASH_Engine.H" | |||||
#include "Transport.H" | #include "Transport.H" | ||||
#include "Engine/Engine.H" | #include "Engine/Engine.H" | ||||
@@ -52,7 +52,7 @@ | |||||
Engine *engine; | Engine *engine; | ||||
Timeline *timeline; | Timeline *timeline; | ||||
Transport *transport; | Transport *transport; | ||||
LASH *lash; | |||||
LASH_Engine *lash; | |||||
TLE *tle; | TLE *tle; | ||||
/* TODO: put these in a header */ | /* TODO: put these in a header */ | ||||
@@ -138,15 +138,17 @@ main ( int argc, char **argv ) | |||||
const char *jack_name; | const char *jack_name; | ||||
if ( ! ( jack_name = engine->init() ) ) | |||||
if ( ! ( jack_name = engine->init( APP_NAME ) ) ) | |||||
FATAL( "Could not connect to JACK!" ); | FATAL( "Could not connect to JACK!" ); | ||||
timeline->sample_rate( engine->sample_rate() ); | |||||
/* always start stopped (please imagine for me a realistic | /* always start stopped (please imagine for me a realistic | ||||
* scenario requiring otherwise */ | * scenario requiring otherwise */ | ||||
transport->stop(); | transport->stop(); | ||||
MESSAGE( "Initializing LASH" ); | MESSAGE( "Initializing LASH" ); | ||||
lash = new LASH; | |||||
lash = new LASH_Engine; | |||||
if ( argc > 1 && ! strcmp( argv[1], "--no-lash" ) ) | if ( argc > 1 && ! strcmp( argv[1], "--no-lash" ) ) | ||||
{ | { | ||||
@@ -1,5 +1,7 @@ | |||||
# -*- mode: makefile; -*- | # -*- mode: makefile; -*- | ||||
all: Timeline | |||||
Timeline_VERSION := 0.5.0 | Timeline_VERSION := 0.5.0 | ||||
Timeline_SRCS := $(wildcard Timeline/*.C Timeline/*.fl Timeline/Engine/*.C) | 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 | Timeline/timeline: $(Timeline_OBJS) FL | ||||
@ echo -n Linking timeline... | @ 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 | 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,33 +19,35 @@ | |||||
#pragma once | #pragma once | ||||
#include <jack/jack.h> | |||||
// #include <jack/jack.h> | |||||
#include "Client.H" | |||||
#include "types.h" | |||||
class Port | |||||
namespace JACK | |||||
{ | { | ||||
jack_port_t *_port; | |||||
const char *_name; | |||||
class Port | |||||
{ | |||||
jack_port_t *_port; | |||||
const char *_name; | |||||
jack_client_t *_client; | |||||
/* FIXME: reference count? */ | |||||
/* FIXME: reference count? */ | |||||
/* /\* not permitted *\/ */ | /* /\* not permitted *\/ */ | ||||
/* Port ( const Port &rhs ); */ | /* Port ( const Port &rhs ); */ | ||||
/* Port & operator= ( const Port &rhs ); */ | /* Port & operator= ( const Port &rhs ); */ | ||||
public: | |||||
public: | |||||
enum type_e { Output, Input }; | |||||
enum type_e { Output, Input }; | |||||
static int max_name ( void ); | |||||
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 ( ); | ||||
~Port ( ); | |||||
~Port ( ); | |||||
/* Port ( const Port & rhs ) */ | /* Port ( const Port & rhs ) */ | ||||
/* { */ | /* { */ | ||||
@@ -54,23 +56,26 @@ public: | |||||
/* } */ | /* } */ | ||||
bool valid ( void ) const { return _port; } | |||||
bool connected ( void ) const { return jack_port_connected( _port ); } | |||||
type_e type ( void ) const | |||||
{ | |||||
return jack_port_flags( _port ) == JackPortIsOutput ? Output : Input; | |||||
} | |||||
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 ); | |||||
void activate ( const char *name, type_e dir ); | |||||
void shutdown ( void ); | |||||
void write ( sample_t *buf, nframes_t nframes ); | |||||
void read ( sample_t *buf, nframes_t nframes ); | |||||
void *buffer ( nframes_t nframes ); | |||||
void silence ( nframes_t nframes ); | |||||
}; | |||||
bool valid ( void ) const { return _port; } | |||||
bool connected ( void ) const { return jack_port_connected( _port ); } | |||||
type_e type ( void ) const | |||||
{ | |||||
return jack_port_flags( _port ) == JackPortIsOutput ? Output : Input; | |||||
} | |||||
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 ); | |||||
void activate ( const char *name, type_e dir ); | |||||
void shutdown ( void ); | |||||
void write ( sample_t *buf, nframes_t nframes ); | |||||
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,29 +21,32 @@ | |||||
#pragma once | #pragma once | ||||
class LASH_Client | |||||
namespace LASH | |||||
{ | { | ||||
/* to avoid including the lash header here... */ | |||||
void *_void; | |||||
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; | |||||
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 ); | |||||
void poll ( void ); | |||||
bool init ( const char *jack_name, const char *full_name, int *argc, char ***argv ); | |||||
bool enabled ( void ); | |||||
void poll ( void ); | |||||
void project_save ( void ); | |||||
void project_quit ( void ); | |||||
void project_save ( void ); | |||||
void project_quit ( void ); | |||||
/* TODO: project_add, project_remove, project_dir, project_name, percentage */ | |||||
/* TODO: project_add, project_remove, project_dir, project_name, percentage */ | |||||
}; | |||||
}; | |||||
} |
@@ -19,7 +19,7 @@ | |||||
#include "Log_Entry.H" | #include "Log_Entry.H" | ||||
#include "const.h" | |||||
// #include "const.h" | |||||
#include "util/debug.h" | #include "util/debug.h" | ||||
Log_Entry::Log_Entry ( ) | Log_Entry::Log_Entry ( ) |
@@ -20,6 +20,7 @@ | |||||
#pragma once | #pragma once | ||||
#include "Loggable.H" | #include "Loggable.H" | ||||
#include "types.h" | #include "types.h" | ||||
class Log_Entry | class Log_Entry |
@@ -33,7 +33,7 @@ | |||||
#include "util/file.h" | #include "util/file.h" | ||||
#include "const.h" | |||||
// #include "const.h" | |||||
#include "util/debug.h" | #include "util/debug.h" | ||||
#include <algorithm> | #include <algorithm> | ||||
@@ -66,7 +66,6 @@ Loggable::~Loggable ( ) | |||||
_loggables[ _id ].loggable = NULL; | _loggables[ _id ].loggable = NULL; | ||||
} | } | ||||
void | void | ||||
@@ -92,7 +91,6 @@ Loggable::find ( unsigned int id ) | |||||
return _loggables[ id ].loggable; | return _loggables[ id ].loggable; | ||||
} | } | ||||
/** Open the journal /filename/ and replay it, bringing the end state back into RAM */ | /** Open the journal /filename/ and replay it, bringing the end state back into RAM */ | ||||
bool | bool | ||||
Loggable::open ( const char *filename ) | Loggable::open ( const char *filename ) | ||||
@@ -161,6 +159,17 @@ Loggable::load_unjournaled_state ( void ) | |||||
#include <sys/stat.h> | #include <sys/stat.h> | ||||
#include <unistd.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 */ | /** replay journal or snapshot */ | ||||
bool | bool | ||||
Loggable::replay ( FILE *fp ) | Loggable::replay ( FILE *fp ) |
@@ -31,7 +31,7 @@ | |||||
#include <string> | #include <string> | ||||
#include <queue> | #include <queue> | ||||
#include "types.h" | |||||
// #include "types.h" | |||||
typedef void (progress_func)( int, void * ); | typedef void (progress_func)( int, void * ); | ||||
typedef void (snapshot_func)( void * ); | typedef void (snapshot_func)( void * ); | ||||
@@ -102,9 +102,6 @@ private: | |||||
static void flush ( void ); | 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 ) | void init ( bool loggable=true ) | ||||
{ | { | ||||
@@ -129,8 +126,15 @@ private: | |||||
void record_unjournaled ( void ) const; | void record_unjournaled ( void ) const; | ||||
static bool load_unjournaled_state ( void ); | static bool load_unjournaled_state ( void ); | ||||
static bool replay ( FILE *fp ); | |||||
static bool replay ( const char *name ); | |||||
public: | 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 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 void progress_callback ( progress_func *p, void *arg ) { _progress_callback = p; _progress_callback_arg = arg;} | ||||
static const char *escape ( const char *s ); | static const char *escape ( const char *s ); |
@@ -33,28 +33,35 @@ buffer_apply_gain ( sample_t *buf, nframes_t nframes, float g ) | |||||
} | } | ||||
void | 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-- ) | while ( nframes-- ) | ||||
*(buf++) *= *(gainbuf++); | *(buf++) *= *(gainbuf++); | ||||
} | } | ||||
void | 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-- ) | while ( nframes-- ) | ||||
*(dst++) += *(src++); | *(dst++) += *(src++); | ||||
} | } | ||||
void | 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-- ) | while ( nframes-- ) | ||||
*(dst++) += *(src++) * g; | *(dst++) += *(src++) * g; | ||||
} | } | ||||
void | 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; | dst += channel; | ||||
@@ -66,7 +73,7 @@ buffer_interleave_one_channel ( sample_t *dst, sample_t *src, int channel, int c | |||||
} | } | ||||
void | 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; | dst += channel; | ||||
@@ -78,7 +85,7 @@ buffer_interleave_one_channel_and_mix ( sample_t *dst, sample_t *src, int channe | |||||
} | } | ||||
void | 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; | src += channel; | ||||
@@ -107,3 +114,16 @@ buffer_is_digital_black ( sample_t *buf, nframes_t nframes ) | |||||
return true; | 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 | #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; |