@@ -1,5 +1,7 @@ | |||
# -*- mode: makefile; -*- | |||
all: FL | |||
FL_SRCS := $(wildcard FL/*.C FL/*.fl) | |||
FL_SRCS:=$(FL_SRCS:.fl=.C) | |||
@@ -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; | |||
@@ -1,5 +1,5 @@ | |||
# data file for the Fltk User Interface Designer (fluid) | |||
version 1.0108 | |||
version 1.0108 | |||
header_name {.H} | |||
code_name {.C} | |||
comment {// | |||
@@ -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,33 +19,35 @@ | |||
#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 *\/ */ | |||
/* Port ( 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 ( 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 | |||
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 "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; |