summaryrefslogtreecommitdiff
path: root/libs/ardour/ardour
diff options
context:
space:
mode:
Diffstat (limited to 'libs/ardour/ardour')
-rw-r--r--libs/ardour/ardour/.cvsignore1
-rw-r--r--libs/ardour/ardour/ardour.h80
-rw-r--r--libs/ardour/ardour/audio_library.h90
-rw-r--r--libs/ardour/ardour/audio_track.h162
-rw-r--r--libs/ardour/ardour/audioengine.h242
-rw-r--r--libs/ardour/ardour/audiofilter.h53
-rw-r--r--libs/ardour/ardour/audioplaylist.h121
-rw-r--r--libs/ardour/ardour/audioregion.h229
-rw-r--r--libs/ardour/ardour/auditioner.h73
-rw-r--r--libs/ardour/ardour/automation_event.h247
-rw-r--r--libs/ardour/ardour/click.h46
-rw-r--r--libs/ardour/ardour/config.h57
-rw-r--r--libs/ardour/ardour/configuration.h253
-rw-r--r--libs/ardour/ardour/connection.h94
-rw-r--r--libs/ardour/ardour/constsource.h60
-rw-r--r--libs/ardour/ardour/crossfade.h182
-rw-r--r--libs/ardour/ardour/crossfade_compare.h43
-rw-r--r--libs/ardour/ardour/curve.h86
-rw-r--r--libs/ardour/ardour/cycle_timer.h53
-rw-r--r--libs/ardour/ardour/cycles.h221
-rw-r--r--libs/ardour/ardour/dB.h34
-rw-r--r--libs/ardour/ardour/diskstream.h433
-rw-r--r--libs/ardour/ardour/export.h88
-rw-r--r--libs/ardour/ardour/filesource.h163
-rw-r--r--libs/ardour/ardour/gain.h44
-rw-r--r--libs/ardour/ardour/gdither.h93
-rw-r--r--libs/ardour/ardour/gdither_types.h49
-rw-r--r--libs/ardour/ardour/gdither_types_internal.h75
-rw-r--r--libs/ardour/ardour/history.h153
-rw-r--r--libs/ardour/ardour/insert.h183
-rw-r--r--libs/ardour/ardour/io.h408
-rw-r--r--libs/ardour/ardour/ladspa.h606
-rw-r--r--libs/ardour/ardour/ladspa_plugin.h142
-rw-r--r--libs/ardour/ardour/location.h193
-rw-r--r--libs/ardour/ardour/logcurve.h133
-rw-r--r--libs/ardour/ardour/mix.h74
-rw-r--r--libs/ardour/ardour/named_selection.h55
-rw-r--r--libs/ardour/ardour/noise.h19
-rw-r--r--libs/ardour/ardour/panner.h331
-rw-r--r--libs/ardour/ardour/peak.h17
-rw-r--r--libs/ardour/ardour/playlist.h278
-rw-r--r--libs/ardour/ardour/playlist_templates.h49
-rw-r--r--libs/ardour/ardour/plugin.h194
-rw-r--r--libs/ardour/ardour/plugin_manager.h63
-rw-r--r--libs/ardour/ardour/plugin_state.h14
-rw-r--r--libs/ardour/ardour/port.h213
-rw-r--r--libs/ardour/ardour/recent_sessions.h39
-rw-r--r--libs/ardour/ardour/redirect.h153
-rw-r--r--libs/ardour/ardour/region.h259
-rw-r--r--libs/ardour/ardour/region_factory.h22
-rw-r--r--libs/ardour/ardour/reverse.h38
-rw-r--r--libs/ardour/ardour/route.h359
-rw-r--r--libs/ardour/ardour/route_group.h111
-rw-r--r--libs/ardour/ardour/route_group_specialized.h22
-rw-r--r--libs/ardour/ardour/send.h63
-rw-r--r--libs/ardour/ardour/seqsource.h55
-rw-r--r--libs/ardour/ardour/session.h1754
-rw-r--r--libs/ardour/ardour/session_connection.h40
-rw-r--r--libs/ardour/ardour/session_diskstream.h42
-rw-r--r--libs/ardour/ardour/session_playlist.h47
-rw-r--r--libs/ardour/ardour/session_region.h19
-rw-r--r--libs/ardour/ardour/session_route.h89
-rw-r--r--libs/ardour/ardour/session_selection.h40
-rw-r--r--libs/ardour/ardour/silentsource.h56
-rw-r--r--libs/ardour/ardour/slave.h151
-rw-r--r--libs/ardour/ardour/sndfile_helpers.h37
-rw-r--r--libs/ardour/ardour/sndfilesource.h63
-rw-r--r--libs/ardour/ardour/soundseq.h54
-rw-r--r--libs/ardour/ardour/source.h182
-rw-r--r--libs/ardour/ardour/spline.h90
-rw-r--r--libs/ardour/ardour/state_manager.h48
-rw-r--r--libs/ardour/ardour/stateful.h51
-rw-r--r--libs/ardour/ardour/tempo.h323
-rw-r--r--libs/ardour/ardour/timestamps.h13
-rw-r--r--libs/ardour/ardour/types.h243
-rw-r--r--libs/ardour/ardour/utils.h59
-rw-r--r--libs/ardour/ardour/vst_plugin.h112
77 files changed, 11131 insertions, 0 deletions
diff --git a/libs/ardour/ardour/.cvsignore b/libs/ardour/ardour/.cvsignore
new file mode 100644
index 0000000000..67020331ba
--- /dev/null
+++ b/libs/ardour/ardour/.cvsignore
@@ -0,0 +1 @@
+version.h
diff --git a/libs/ardour/ardour/ardour.h b/libs/ardour/ardour/ardour.h
new file mode 100644
index 0000000000..31bd22590e
--- /dev/null
+++ b/libs/ardour/ardour/ardour.h
@@ -0,0 +1,80 @@
+/*
+ Copyright (C) 1999 Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __ardour_ardour_h__
+#define __ardour_ardour_h__
+
+#include <limits.h>
+#include <string>
+#include <signal.h>
+
+#include <pbd/error.h>
+#include <pbd/lockmonitor.h>
+#include <pbd/failed_constructor.h>
+
+#include <ardour/configuration.h>
+#include <ardour/types.h>
+
+using namespace PBD;
+
+namespace MIDI {
+ class MachineControl;
+ class Port;
+}
+
+namespace ARDOUR {
+
+ class AudioEngine;
+
+ static const jack_nframes_t max_frames = JACK_MAX_FRAMES;
+
+ int init (AudioEngine&, bool with_vst, bool try_optimization, void (*sighandler)(int,siginfo_t*,void*) = 0);
+ int cleanup ();
+ std::string find_config_file (std::string name);
+ std::string find_data_file (std::string name);
+
+ const layer_t max_layer = UCHAR_MAX;
+
+ id_t new_id();
+
+ Change new_change ();
+
+ extern Change StartChanged;
+ extern Change LengthChanged;
+ extern Change PositionChanged;
+ extern Change NameChanged;
+ extern Change BoundsChanged;
+
+ struct LocaleGuard {
+ LocaleGuard (const char*);
+ ~LocaleGuard ();
+ const char* old;
+ };
+
+};
+
+/* how do we make these be within the Ardour namespace? */
+
+extern MIDI::Port* default_mmc_port;
+extern MIDI::Port* default_mtc_port;
+extern MIDI::Port* default_midi_port;
+
+#endif /* __ardour_ardour_h__ */
+
diff --git a/libs/ardour/ardour/audio_library.h b/libs/ardour/ardour/audio_library.h
new file mode 100644
index 0000000000..3aab3993b9
--- /dev/null
+++ b/libs/ardour/ardour/audio_library.h
@@ -0,0 +1,90 @@
+/*
+ Copyright (C) 2003 Paul Davis
+ Author: Taybin Rutkin
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __ardour_audio_library_h__
+#define __ardour_audio_library_h__
+
+#include <list>
+#include <string>
+#include <map>
+
+#include <sigc++/signal.h>
+
+using std::list;
+using std::string;
+using std::map;
+
+namespace ARDOUR {
+
+class AudioLibrary
+{
+ public:
+ AudioLibrary ();
+ ~AudioLibrary ();
+
+ // add_group returns the URI of the created group
+ string add_group (string group, string parent_uri = "");
+ void remove_group (string uri);
+ void get_groups (list<string>& groups, string parent_uri = "");
+
+ // add_member returns the URI of the created group
+ string add_member (string member, string parent_uri = "");
+ void remove_member (string uri);
+ void get_members (list<string>& members, string parent_uri = "");
+ string get_member_filename (string uri);
+
+ void search_members_and (list<string>& results,
+ const map<string,string>& fields);
+ void search_members_or (list<string>& results,
+ const map<string,string>& fields);
+
+ void add_field (string field);
+ void get_fields (list<string>& fields);
+ void remove_field (string field);
+ string get_field (string uri, string field);
+ void set_field (string uri, string field, string literal);
+
+ string get_label (string uri);
+ void set_label (string uri, string label);
+
+ sigc::signal<void, string, string> added_group; // group, parent
+ sigc::signal<void, string, string> added_member;// member, parent
+ sigc::signal<void, string> removed_group;
+ sigc::signal<void, string> removed_member;
+ sigc::signal<void> fields_changed;
+
+ private:
+ void save_changes ();
+ string field_uri (string name);
+
+ bool is_rdf_type (string uri, string type);
+ void remove_uri (string uri);
+
+ string src;
+
+ void initialize_db();
+};
+
+extern AudioLibrary* Library;
+
+} // ARDOUR namespace
+
+#endif // __ardour_audio_library_h__
diff --git a/libs/ardour/ardour/audio_track.h b/libs/ardour/ardour/audio_track.h
new file mode 100644
index 0000000000..e7ba315e45
--- /dev/null
+++ b/libs/ardour/ardour/audio_track.h
@@ -0,0 +1,162 @@
+/*
+ Copyright (C) 2002 Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __ardour_audio_track_h__
+#define __ardour_audio_track_h__
+
+#include <ardour/route.h>
+
+namespace ARDOUR {
+
+class Session;
+class DiskStream;
+class AudioPlaylist;
+
+class AudioTrack : public Route
+{
+ public:
+ AudioTrack (Session&, string name, Route::Flag f = Route::Flag (0));
+ AudioTrack (Session&, const XMLNode&);
+ ~AudioTrack ();
+
+ int set_name (string str, void *src);
+
+ int roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame,
+
+ jack_nframes_t offset, int declick, bool can_record, bool rec_monitors_input);
+ int no_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame,
+ jack_nframes_t offset, bool state_changing, bool can_record, bool rec_monitors_input);
+ int silent_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame,
+ jack_nframes_t offset, bool can_record, bool rec_monitors_input);
+
+ void toggle_monitor_input ();
+
+ bool can_record() const { return true; }
+ void set_record_enable (bool yn, void *src);
+
+ DiskStream& disk_stream() const { return *diskstream; }
+ int set_diskstream (DiskStream&, void *);
+ int use_diskstream (string name);
+ int use_diskstream (id_t id);
+
+ jack_nframes_t update_total_latency();
+ void set_latency_delay (jack_nframes_t);
+
+ int export_stuff (vector<Sample*>& buffers, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t end_frame);
+
+ sigc::signal<void,void*> diskstream_changed;
+
+ enum FreezeState {
+ NoFreeze,
+ Frozen,
+ UnFrozen
+ };
+
+ FreezeState freeze_state() const;
+
+ sigc::signal<void> FreezeChange;
+
+ void freeze (InterThreadInfo&);
+ void unfreeze ();
+
+ void bounce (InterThreadInfo&);
+ void bounce_range (jack_nframes_t start, jack_nframes_t end, InterThreadInfo&);
+
+ XMLNode& get_state();
+ int set_state(const XMLNode& node);
+
+ MIDI::Controllable& midi_rec_enable_control() {
+ return _midi_rec_enable_control;
+ }
+
+ void reset_midi_control (MIDI::Port*, bool);
+ void send_all_midi_feedback ();
+
+ bool record_enabled() const;
+ void set_meter_point (MeterPoint, void* src);
+
+ protected:
+ DiskStream *diskstream;
+ MeterPoint _saved_meter_point;
+
+ void passthru_silence (jack_nframes_t start_frame, jack_nframes_t end_frame,
+ jack_nframes_t nframes, jack_nframes_t offset, int declick,
+ bool meter);
+
+ uint32_t n_process_buffers ();
+
+ private:
+ struct FreezeRecordInsertInfo {
+ FreezeRecordInsertInfo(XMLNode& st)
+ : state (st), insert (0) {}
+
+ XMLNode state;
+ Insert* insert;
+ id_t id;
+ UndoAction memento;
+ };
+
+ struct FreezeRecord {
+ FreezeRecord() {
+ playlist = 0;
+ have_mementos = false;
+ }
+
+ ~FreezeRecord();
+
+ AudioPlaylist* playlist;
+ vector<FreezeRecordInsertInfo*> insert_info;
+ bool have_mementos;
+ FreezeState state;
+ };
+
+ FreezeRecord _freeze_record;
+ XMLNode* pending_state;
+
+ void diskstream_record_enable_changed (void *src);
+ void diskstream_input_channel_changed (void *src);
+
+ void input_change_handler (void *src);
+
+ sigc::connection recenable_connection;
+ sigc::connection ic_connection;
+
+ XMLNode& state(bool);
+
+ int deprecated_use_diskstream_connections ();
+ void set_state_part_two ();
+ void set_state_part_three ();
+
+ struct MIDIRecEnableControl : public MIDI::Controllable {
+ MIDIRecEnableControl (AudioTrack&, MIDI::Port *);
+ void set_value (float);
+ void send_feedback (bool);
+ MIDI::byte* write_feedback (MIDI::byte* buf, int32_t& bufsize, bool val, bool force = false);
+ AudioTrack& track;
+ bool setting;
+ bool last_written;
+ };
+
+ MIDIRecEnableControl _midi_rec_enable_control;
+};
+
+}; /* namespace ARDOUR*/
+
+#endif /* __ardour_audio_track_h__ */
diff --git a/libs/ardour/ardour/audioengine.h b/libs/ardour/ardour/audioengine.h
new file mode 100644
index 0000000000..d349f5bae5
--- /dev/null
+++ b/libs/ardour/ardour/audioengine.h
@@ -0,0 +1,242 @@
+/*
+ Copyright (C) 2002-2004 Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __ardour_audioengine_h__
+#define __ardour_audioengine_h__
+
+#include <list>
+#include <set>
+#include <cmath>
+#include <exception>
+#include <string>
+
+#include <sigc++/signal.h>
+#include <pthread.h>
+#include <ardour/ardour.h>
+#include <jack/jack.h>
+#include <jack/transport.h>
+
+namespace ARDOUR {
+
+class Session;
+class Port;
+
+class AudioEngine : public sigc::trackable
+{
+ public:
+ AudioEngine (std::string client_name);
+ virtual ~AudioEngine ();
+
+ jack_client_t* jack() const { return _jack; }
+ bool connected() const { return _jack != 0; }
+
+ std::string client_name() const { return jack_client_name; }
+
+ int reconnect_to_jack ();
+ int disconnect_from_jack();
+
+ bool will_reconnect_at_halt ();
+ void set_reconnect_at_halt (bool);
+
+ int stop ();
+ int start ();
+ bool running() const { return _running; }
+
+ PBD::NonBlockingLock& process_lock() { return _process_lock; }
+
+ jack_nframes_t frame_rate();
+ jack_nframes_t frames_per_cycle();
+
+ int usecs_per_cycle () const { return _usecs_per_cycle; }
+
+ jack_nframes_t frames_since_cycle_start () {
+ if (!_running || !_jack) return 0;
+ return jack_frames_since_cycle_start (_jack);
+ }
+ jack_nframes_t frame_time () {
+ if (!_running || !_jack) return 0;
+ return jack_frame_time (_jack);
+ }
+
+ jack_nframes_t transport_frame () const {
+ if (!_running || !_jack) return 0;
+ return jack_get_current_transport_frame (_jack);
+ }
+
+ int request_buffer_size (jack_nframes_t);
+
+ jack_nframes_t set_monitor_check_interval (jack_nframes_t);
+
+ float get_cpu_load() {
+ if (!_running || !_jack) return 0;
+ return jack_cpu_load (_jack);
+ }
+
+ void set_session (Session *);
+ void remove_session ();
+
+ class PortRegistrationFailure : public std::exception {
+ public:
+ virtual const char *what() const throw() { return "failed port registration"; }
+ };
+
+ class NoBackendAvailable : public std::exception {
+ public:
+ virtual const char *what() const throw() { return "could not connect to engine backend"; }
+ };
+
+ Port *register_audio_input_port (const string& portname);
+ Port *register_audio_output_port (const string& portname);
+ int unregister_port (Port *);
+
+ int connect (const string& source, const string& destination);
+ int disconnect (const string& source, const string& destination);
+ int disconnect (Port *);
+
+ const char ** get_ports (const string& port_name_pattern, const string& type_name_pattern, uint32_t flags);
+
+ uint32_t n_physical_outputs () const;
+ uint32_t n_physical_inputs () const;
+
+ string get_nth_physical_output (uint32_t n) {
+ return get_nth_physical (n, JackPortIsInput);
+ }
+
+ string get_nth_physical_input (uint32_t n) {
+ return get_nth_physical (n, JackPortIsOutput);
+ }
+
+ jack_nframes_t get_port_total_latency (const Port&);
+ void update_total_latencies ();
+
+ /* the caller may not delete the object pointed to by
+ the return value
+ */
+
+ Port *get_port_by_name (const string& name, bool keep = true);
+
+ enum TransportState {
+ TransportStopped = JackTransportStopped,
+ TransportRolling = JackTransportRolling,
+ TransportLooping = JackTransportLooping,
+ TransportStarting = JackTransportStarting
+ };
+
+ void transport_start ();
+ void transport_stop ();
+ void transport_locate (jack_nframes_t);
+ TransportState transport_state ();
+
+ int reset_timebase ();
+
+ /* start/stop freewheeling */
+
+ int freewheel (bool onoff);
+ bool freewheeling() const { return _freewheeling; }
+
+ /* this signal is sent for every process() cycle while freewheeling.
+ the regular process() call to session->process() is not made.
+ */
+
+ sigc::signal<int,jack_nframes_t> Freewheel;
+
+ sigc::signal<void> Xrun;
+
+ /* this signal is if JACK notifies us of a graph order event */
+
+ sigc::signal<void> GraphReordered;
+
+ /* this signal is emitted if the sample rate changes */
+
+ sigc::signal<void,jack_nframes_t> SampleRateChanged;
+
+ /* this signal is sent if JACK ever disconnects us */
+
+ sigc::signal<void> Halted;
+
+ /* these two are emitted when the engine itself is
+ started and stopped
+ */
+
+ sigc::signal<void> Running;
+ sigc::signal<void> Stopped;
+
+ std::string make_port_name_relative (std::string);
+ std::string make_port_name_non_relative (std::string);
+
+ private:
+ ARDOUR::Session *session;
+ jack_client_t *_jack;
+ std::string jack_client_name;
+ PBD::NonBlockingLock port_lock;
+ PBD::NonBlockingLock _process_lock;
+ PBD::Lock session_remove_lock;
+ pthread_cond_t session_removed;
+ bool session_remove_pending;
+ bool _running;
+ bool _has_run;
+ jack_nframes_t _buffer_size;
+ jack_nframes_t _frame_rate;
+ jack_nframes_t monitor_check_interval;
+ jack_nframes_t last_monitor_check;
+ jack_nframes_t _processed_frames;
+ bool _freewheeling;
+ bool _freewheel_thread_registered;
+ sigc::slot<int,jack_nframes_t> freewheel_action;
+ bool reconnect_on_halt;
+ int _usecs_per_cycle;
+
+ typedef std::set<Port*> Ports;
+ Ports ports;
+
+ int process_callback (jack_nframes_t nframes);
+ void remove_all_ports ();
+
+ typedef std::pair<std::string,std::string> PortConnection;
+ typedef std::list<PortConnection> PortConnections;
+
+ PortConnections port_connections;
+ void remove_connections_for (Port*);
+
+ string get_nth_physical (uint32_t which, int flags);
+
+ static int _xrun_callback (void *arg);
+ static int _graph_order_callback (void *arg);
+ static int _process_callback (jack_nframes_t nframes, void *arg);
+ static int _sample_rate_callback (jack_nframes_t nframes, void *arg);
+ static int _bufsize_callback (jack_nframes_t nframes, void *arg);
+ static void _jack_timebase_callback (jack_transport_state_t, jack_nframes_t, jack_position_t*, int, void*);
+ static int _jack_sync_callback (jack_transport_state_t, jack_position_t*, void *arg);
+ static void _freewheel_callback (int , void *arg);
+
+ void jack_timebase_callback (jack_transport_state_t, jack_nframes_t, jack_position_t*, int);
+ int jack_sync_callback (jack_transport_state_t, jack_position_t*);
+ int jack_bufsize_callback (jack_nframes_t);
+ int jack_sample_rate_callback (jack_nframes_t);
+
+ static void halted (void *);
+ static void meter (Port *port, jack_nframes_t nframes);
+
+ int connect_to_jack (std::string client_name);
+};
+
+}; /* namespace ARDOUR */
+
+#endif /* __ardour_audioengine_h__ */
diff --git a/libs/ardour/ardour/audiofilter.h b/libs/ardour/ardour/audiofilter.h
new file mode 100644
index 0000000000..d0fc275cf6
--- /dev/null
+++ b/libs/ardour/ardour/audiofilter.h
@@ -0,0 +1,53 @@
+/*
+ Copyright (C) 2004 Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __ardour_audiofilter_h__
+#define __ardour_audiofilter_h__
+
+#include <vector>
+#include <ardour/audioregion.h>
+
+namespace ARDOUR {
+
+class AudioRegion;
+class Session;
+class FileSource;
+
+class AudioFilter {
+
+ public:
+ AudioFilter (ARDOUR::Session& s)
+ : session (s){}
+ virtual ~AudioFilter() {}
+
+
+ virtual int run (ARDOUR::AudioRegion&) = 0;
+ std::vector<ARDOUR::AudioRegion*> results;
+
+ protected:
+ ARDOUR::Session& session;
+
+ int make_new_sources (ARDOUR::AudioRegion&, ARDOUR::AudioRegion::SourceList&);
+ int finish (ARDOUR::AudioRegion&, ARDOUR::AudioRegion::SourceList&);
+};
+
+} /* namespace */
+
+#endif /* __ardour_audiofilter_h__ */
diff --git a/libs/ardour/ardour/audioplaylist.h b/libs/ardour/ardour/audioplaylist.h
new file mode 100644
index 0000000000..26cce91b12
--- /dev/null
+++ b/libs/ardour/ardour/audioplaylist.h
@@ -0,0 +1,121 @@
+/*
+ Copyright (C) 2003 Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __ardour_audio_playlist_h__
+#define __ardour_audio_playlist_h__
+
+#include <vector>
+#include <list>
+
+#include <ardour/ardour.h>
+#include <ardour/playlist.h>
+
+namespace ARDOUR {
+
+class Session;
+class Region;
+class AudioRegion;
+class Source;
+
+class AudioPlaylist : public ARDOUR::Playlist
+{
+ public:
+ typedef std::list<Crossfade*> Crossfades;
+
+ private:
+
+ struct State : public ARDOUR::StateManager::State {
+ RegionList regions;
+ std::list<UndoAction> region_states;
+
+ Crossfades crossfades;
+ std::list<UndoAction> crossfade_states;
+
+ State (std::string why) : ARDOUR::StateManager::State (why) {}
+ ~State ();
+ };
+
+ public:
+ AudioPlaylist (Session&, const XMLNode&, bool hidden = false);
+ AudioPlaylist (Session&, string name, bool hidden = false);
+ AudioPlaylist (const AudioPlaylist&, string name, bool hidden = false);
+ AudioPlaylist (const AudioPlaylist&, jack_nframes_t start, jack_nframes_t cnt, string name, bool hidden = false);
+
+ void clear (bool with_delete = false, bool with_save = true);
+
+ jack_nframes_t read (Sample *dst, Sample *mixdown, float *gain_buffer, jack_nframes_t start, jack_nframes_t cnt, uint32_t chan_n=0);
+
+ int set_state (const XMLNode&);
+ UndoAction get_memento() const;
+
+ sigc::signal<void,Crossfade *> NewCrossfade;
+
+ template<class T> void foreach_crossfade (T *t, void (T::*func)(Crossfade *));
+ void crossfades_at (jack_nframes_t frame, Crossfades&);
+
+ template<class T> void apply_to_history (T& obj, void (T::*method)(const ARDOUR::StateManager::StateMap&, state_id_t)) {
+ RegionLock rlock (this);
+ (obj.*method) (states, _current_state_id);
+ }
+
+ bool destroy_region (Region*);
+
+ void get_equivalent_regions (const AudioRegion&, std::vector<AudioRegion*>&);
+ void get_region_list_equivalent_regions (const AudioRegion&, std::vector<AudioRegion*>&);
+
+ void drop_all_states ();
+
+ protected:
+
+ /* state management */
+
+ StateManager::State* state_factory (std::string) const;
+ Change restore_state (StateManager::State&);
+ void send_state_change (Change);
+
+ /* playlist "callbacks" */
+ void notify_crossfade_added (Crossfade *);
+ void flush_notifications ();
+
+ void refresh_dependents (Region& region);
+ void check_dependents (Region& region, bool norefresh);
+ void remove_dependents (Region& region);
+
+ protected:
+ ~AudioPlaylist (); /* public should use unref() */
+
+ private:
+ Crossfades _crossfades;
+ Crossfades _pending_xfade_adds;
+
+ void crossfade_invalidated (Crossfade*);
+ XMLNode& state (bool full_state);
+ void dump () const;
+
+ bool region_changed (Change, Region*);
+ void crossfade_changed (Change);
+ void add_crossfade (Crossfade&);
+};
+
+} /* namespace ARDOUR */
+
+#endif /* __ardour_audio_playlist_h__ */
+
+
diff --git a/libs/ardour/ardour/audioregion.h b/libs/ardour/ardour/audioregion.h
new file mode 100644
index 0000000000..44159f73f5
--- /dev/null
+++ b/libs/ardour/ardour/audioregion.h
@@ -0,0 +1,229 @@
+/*
+ Copyright (C) 2000-2001 Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __ardour_audio_region_h__
+#define __ardour_audio_region_h__
+
+#include <vector>
+
+#include <pbd/fastlog.h>
+#include <pbd/undo.h>
+
+#include <ardour/ardour.h>
+#include <ardour/source.h>
+#include <ardour/gain.h>
+#include <ardour/region.h>
+#include <ardour/export.h>
+
+class XMLNode;
+
+namespace ARDOUR {
+
+class Route;
+class Playlist;
+class Session;
+class AudioFilter;
+
+struct AudioRegionState : public RegionState
+{
+ AudioRegionState (std::string why);
+
+ Curve _fade_in;
+ Curve _fade_out;
+ Curve _envelope;
+ gain_t _scale_amplitude;
+ uint32_t _fade_in_disabled;
+ uint32_t _fade_out_disabled;
+};
+
+class AudioRegion : public Region
+{
+ public:
+ typedef vector<Source *> SourceList;
+
+ static Change FadeInChanged;
+ static Change FadeOutChanged;
+ static Change FadeInActiveChanged;
+ static Change FadeOutActiveChanged;
+ static Change EnvelopeActiveChanged;
+ static Change ScaleAmplitudeChanged;
+ static Change EnvelopeChanged;
+
+ AudioRegion (Source&, jack_nframes_t start, jack_nframes_t length, bool announce = true);
+ AudioRegion (Source&, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true);
+ AudioRegion (SourceList &, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true);
+ AudioRegion (const AudioRegion&, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true);
+ AudioRegion (const AudioRegion&);
+ AudioRegion (Source&, const XMLNode&);
+ AudioRegion (SourceList &, const XMLNode&);
+ ~AudioRegion();
+
+ bool region_list_equivalent (const AudioRegion&);
+ bool source_equivalent (const AudioRegion&);
+ bool equivalent (const AudioRegion&);
+ bool size_equivalent (const AudioRegion&);
+
+ void lock_sources ();
+ void unlock_sources ();
+ Source& source (uint32_t n=0) const { if (n < sources.size()) return *sources[n]; else return *sources[0]; }
+
+ void set_scale_amplitude (gain_t);
+ gain_t scale_amplitude() const { return _scale_amplitude; }
+
+ void normalize_to (float target_in_dB = 0.0f);
+
+ uint32_t n_channels() { return sources.size(); }
+ vector<string> master_source_names();
+
+ bool envelope_active () const { return _flags & Region::EnvelopeActive; }
+ bool fade_in_active () const { return _flags & Region::FadeIn; }
+ bool fade_out_active () const { return _flags & Region::FadeOut; }
+ bool captured() const { return !(_flags & (Region::Flag (Region::Import|Region::External))); }
+
+ Curve& fade_in() { return _fade_in; }
+ Curve& fade_out() { return _fade_out; }
+ Curve& envelope() { return _envelope; }
+
+ jack_nframes_t read_peaks (PeakData *buf, jack_nframes_t npeaks, jack_nframes_t offset, jack_nframes_t cnt, uint32_t chan_n=0, double samples_per_unit= 1.0) const;
+
+ virtual jack_nframes_t read_at (Sample *buf, Sample *mixdown_buffer,
+ float *gain_buffer, jack_nframes_t position, jack_nframes_t cnt,
+ uint32_t chan_n = 0,
+ jack_nframes_t read_frames = 0,
+ jack_nframes_t skip_frames = 0) const;
+
+ jack_nframes_t master_read_at (Sample *buf, Sample *mixdown_buffer,
+ float *gain_buffer, jack_nframes_t position, jack_nframes_t cnt, uint32_t chan_n=0) const;
+
+
+ XMLNode& state (bool);
+ XMLNode& get_state ();
+ int set_state (const XMLNode&);
+
+ static void set_default_fade (float steepness, jack_nframes_t len);
+
+ enum FadeShape {
+ Linear,
+ Fast,
+ Slow,
+ LogA,
+ LogB,
+
+ };
+
+ void set_fade_in_active (bool yn);
+ void set_fade_in_shape (FadeShape);
+ void set_fade_in_length (jack_nframes_t);
+ void set_fade_in (FadeShape, jack_nframes_t);
+
+ void set_fade_out_active (bool yn);
+ void set_fade_out_shape (FadeShape);
+ void set_fade_out_length (jack_nframes_t);
+ void set_fade_out (FadeShape, jack_nframes_t);
+
+ void set_envelope_active (bool yn);
+
+ int separate_by_channel (ARDOUR::Session&, vector<AudioRegion*>&) const;
+
+ uint32_t read_data_count() const { return _read_data_count; }
+
+ ARDOUR::Playlist* playlist() const { return _playlist; }
+
+ UndoAction get_memento() const;
+
+ /* filter */
+
+ int apply (AudioFilter&);
+
+ /* export */
+
+ int exportme (ARDOUR::Session&, ARDOUR::AudioExportSpecification&);
+
+ Region* get_parent();
+
+ /* xfade/fade interactions */
+
+ void suspend_fade_in ();
+ void suspend_fade_out ();
+ void resume_fade_in ();
+ void resume_fade_out ();
+
+ private:
+ friend class Playlist;
+
+ private:
+ SourceList sources;
+ SourceList master_sources; /* used when timefx are applied, so
+ we can always use the original
+ source.
+ */
+ mutable Curve _fade_in;
+ FadeShape _fade_in_shape;
+ mutable Curve _fade_out;
+ FadeShape _fade_out_shape;
+ mutable Curve _envelope;
+ gain_t _scale_amplitude;
+ uint32_t _fade_in_disabled;
+ uint32_t _fade_out_disabled;
+
+ void set_default_fades ();
+ void set_default_fade_in ();
+ void set_default_fade_out ();
+ void set_default_envelope ();
+
+ StateManager::State* state_factory (std::string why) const;
+ Change restore_state (StateManager::State&);
+
+ void recompute_gain_at_end ();
+ void recompute_gain_at_start ();
+
+ bool copied() const { return _flags & Copied; }
+ void maybe_uncopy ();
+ void rename_after_first_edit ();
+
+ jack_nframes_t _read_at (const SourceList&, Sample *buf, Sample *mixdown_buffer,
+ float *gain_buffer, jack_nframes_t position, jack_nframes_t cnt,
+ uint32_t chan_n = 0,
+ jack_nframes_t read_frames = 0,
+ jack_nframes_t skip_frames = 0) const;
+
+ bool verify_start (jack_nframes_t position);
+ bool verify_length (jack_nframes_t position);
+ bool verify_start_mutable (jack_nframes_t& start);
+ bool verify_start_and_length (jack_nframes_t start, jack_nframes_t length);
+ void recompute_at_start ();
+ void recompute_at_end ();
+
+ void envelope_changed (Change);
+
+ void source_deleted (Source*);
+};
+
+} /* namespace ARDOUR */
+
+/* access from C objects */
+
+extern "C" {
+ int region_read_peaks_from_c (void *arg, uint32_t npeaks, uint32_t start, uint32_t length, intptr_t data, uint32_t n_chan, double samples_per_unit);
+ uint32_t region_length_from_c (void *arg);
+ uint32_t sourcefile_length_from_c (void *arg);
+}
+
+#endif /* __ardour_audio_region_h__ */
diff --git a/libs/ardour/ardour/auditioner.h b/libs/ardour/ardour/auditioner.h
new file mode 100644
index 0000000000..b79620eaa2
--- /dev/null
+++ b/libs/ardour/ardour/auditioner.h
@@ -0,0 +1,73 @@
+/*
+ Copyright (C) 2001 Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __ardour_auditioner_h__
+#define __ardour_auditioner_h__
+
+#include <string>
+#include <pthread.h>
+
+#include <pbd/lockmonitor.h>
+#include <pbd/atomic.h>
+
+#include <ardour/ardour.h>
+#include <ardour/audio_track.h>
+
+namespace ARDOUR {
+
+class Session;
+class AudioRegion;
+class AudioPlaylist;
+
+class Auditioner : public AudioTrack
+{
+ public:
+ Auditioner (Session&);
+ ~Auditioner ();
+
+ void audition_region (AudioRegion&);
+
+ ARDOUR::AudioPlaylist& prepare_playlist ();
+ void audition_current_playlist ();
+
+ int play_audition (jack_nframes_t nframes);
+
+ void cancel_audition () {
+ atomic_set (&_active, 0);
+ }
+
+ bool active() const { return atomic_read (&_active); }
+
+ private:
+ AudioRegion *the_region;
+ jack_nframes_t current_frame;
+ atomic_t _active;
+ PBD::Lock lock;
+ jack_nframes_t length;
+
+ void drop_ports ();
+ static void *_drop_ports (void *);
+ void actually_drop_ports ();
+ void output_changed (IOChange, void*);
+};
+
+}; /* namespace ARDOUR */
+
+#endif /* __ardour_auditioner_h__ */
diff --git a/libs/ardour/ardour/automation_event.h b/libs/ardour/ardour/automation_event.h
new file mode 100644
index 0000000000..562a424cc7
--- /dev/null
+++ b/libs/ardour/ardour/automation_event.h
@@ -0,0 +1,247 @@
+/*
+ Copyright (C) 2002 Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __ardour_automation_event_h__
+#define __ardour_automation_event_h__
+
+#include <stdint.h>
+#include <list>
+#include <cmath>
+
+#include <sigc++/signal.h>
+#include <pbd/lockmonitor.h>
+#include <pbd/undo.h>
+#include <pbd/xml++.h>
+#include <ardour/ardour.h>
+#include <ardour/state_manager.h>
+
+namespace ARDOUR {
+
+struct ControlEvent {
+ double when;
+ double value;
+
+ ControlEvent (double w, double v)
+ : when (w), value (v) { }
+ ControlEvent (const ControlEvent& other)
+ : when (other.when), value (other.value) {}
+
+ virtual ~ControlEvent() {}
+
+// bool operator==(const ControlEvent& other) {
+// return value == other.value && when == other.when;
+// }
+
+};
+
+class AutomationList : public StateManager
+{
+ public:
+ typedef std::list<ControlEvent*> AutomationEventList;
+ typedef AutomationEventList::iterator iterator;
+ typedef AutomationEventList::const_iterator const_iterator;
+
+ AutomationList(double default_value, bool no_state = false);
+ ~AutomationList();
+
+ AutomationList (const AutomationList&);
+ AutomationList (const AutomationList&, double start, double end);
+ AutomationList& operator= (const AutomationList&);
+ bool operator== (const AutomationList&);
+
+ void freeze();
+ void thaw ();
+
+ AutomationEventList::size_type size() const { return events.size(); }
+ bool empty() const { return events.empty(); }
+
+ void reset_default (double val) {
+ default_value = val;
+ }
+
+ void clear ();
+ void x_scale (double factor);
+ bool extend_to (double);
+
+ void reposition_for_rt_add (double when);
+ void rt_add (double when, double value);
+ iterator add (double when, double value, iterator, bool ignore_mode = false);
+ void add (double when, double value, bool for_loading = false);
+
+ void erase_range (double start, double end);
+ void erase (iterator);
+ void erase (iterator, iterator);
+ void move_range (iterator start, iterator end, double, double);
+ void modify (iterator, double, double);
+
+ AutomationList* cut (double, double);
+ AutomationList* copy (double, double);
+ void clear (double, double);
+
+ AutomationList* cut (iterator, iterator);
+ AutomationList* copy (iterator, iterator);
+ void clear (iterator, iterator);
+
+ bool paste (AutomationList&, double position, float times);
+
+ void set_automation_state (AutoState);
+ AutoState automation_state() const { return _state; }
+ sigc::signal<void> automation_style_changed;
+
+ void set_automation_style (AutoStyle m);
+ AutoStyle automation_style() const { return _style; }
+ sigc::signal<void> automation_state_changed;
+
+ bool automation_playback() {
+ return (_state & Play) || ((_state & Touch) && !_touching);
+ }
+ bool automation_write () {
+ return (_state & Write) || ((_state & Touch) && _touching);
+ }
+
+ void start_touch ();
+ void stop_touch ();
+ bool touching() const { return _touching; }
+
+ void set_yrange (double min, double max) {
+ min_yval = min;
+ max_yval = max;
+ }
+
+ double get_max_y() const { return max_yval; }
+ double get_min_y() const { return min_yval; }
+
+ void truncate_end (double length);
+ void truncate_start (double length);
+
+ iterator begin() { return events.begin(); }
+ iterator end() { return events.end(); }
+
+ ControlEvent* back() { return events.back(); }
+ ControlEvent* front() { return events.front(); }
+
+ const_iterator const_begin() const { return events.begin(); }
+ const_iterator const_end() const { return events.end(); }
+
+ std::pair<AutomationList::iterator,AutomationList::iterator> control_points_adjacent (double when);
+
+ template<class T> void apply_to_points (T& obj, void (T::*method)(const AutomationList&)) {
+ LockMonitor lm (lock, __LINE__, __FILE__);
+ (obj.*method)(*this);
+ }
+
+ UndoAction get_memento () const;
+
+ virtual void store_state (XMLNode& node) const;
+ virtual void load_state (const XMLNode&);
+
+ void set_max_xval (double);
+ double get_max_xval() const { return max_xval; }
+
+ double eval (double where) {
+ LockMonitor lm (lock, __LINE__, __FILE__);
+ return unlocked_eval (where);
+ }
+
+ double rt_safe_eval (double where, bool& ok) {
+
+ TentativeLockMonitor lm (lock, __LINE__, __FILE__);
+
+ if ((ok = lm.locked())) {
+ return unlocked_eval (where);
+ } else {
+ return 0.0;
+ }
+ }
+
+ struct TimeComparator {
+ bool operator() (const ControlEvent* a, const ControlEvent* b) {
+ return a->when < b->when;
+ }
+ };
+
+ protected:
+ struct State : public ARDOUR::StateManager::State {
+ AutomationEventList events;
+
+ State (std::string why) : ARDOUR::StateManager::State (why) {}
+ };
+
+ AutomationEventList events;
+ mutable PBD::NonBlockingLock lock;
+ bool _frozen;
+ bool changed_when_thawed;
+ bool _dirty;
+
+ struct LookupCache {
+ double left; /* leftmost x coordinate used when finding "range" */
+ std::pair<AutomationList::iterator,AutomationList::iterator> range;
+ };
+
+ LookupCache lookup_cache;
+
+ AutoState _state;
+ AutoStyle _style;
+ bool _touching;
+ bool _new_touch;
+ double max_xval;
+ double min_yval;
+ double max_yval;
+ double default_value;
+ bool no_state;
+
+ iterator rt_insertion_point;
+ double rt_pos;
+
+ void maybe_signal_changed ();
+ void mark_dirty ();
+ void _x_scale (double factor);
+
+ /* called by type-specific unlocked_eval() to handle
+ common case of 0, 1 or 2 control points.
+ */
+
+ double shared_eval (double x);
+
+ /* called by shared_eval() to handle any case of
+ 3 or more control points.
+ */
+
+ virtual double multipoint_eval (double x);
+
+ /* called by locked entry point and various private
+ locations where we already hold the lock.
+ */
+
+ virtual double unlocked_eval (double where);
+
+ Change restore_state (StateManager::State&);
+ StateManager::State* state_factory (std::string why) const;
+
+ virtual ControlEvent* point_factory (double,double) const;
+ virtual ControlEvent* point_factory (const ControlEvent&) const;
+
+
+ AutomationList* cut_copy_clear (double, double, int op);
+};
+
+} // namespace
+
+#endif /* __ardour_automation_event_h__ */
diff --git a/libs/ardour/ardour/click.h b/libs/ardour/ardour/click.h
new file mode 100644
index 0000000000..71214978a5
--- /dev/null
+++ b/libs/ardour/ardour/click.h
@@ -0,0 +1,46 @@
+/*
+ Copyright (C) 2004 Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __ardour_click_h__
+#define __ardour_click_h__
+
+#include <ardour/io.h>
+
+namespace ARDOUR {
+
+class ClickIO : public IO
+{
+ public:
+ ClickIO (Session& s, const string& name,
+
+ int input_min = -1, int input_max = -1,
+
+ int output_min = -1, int output_max = -1)
+ : IO (s, name, input_min, input_max, output_min, output_max) {}
+
+ ~ClickIO() {}
+
+ protected:
+ uint32_t pans_required () const { return 1; }
+};
+
+}; /* namespace ARDOUR */
+
+#endif /*__ardour_click_h__ */
diff --git a/libs/ardour/ardour/config.h b/libs/ardour/ardour/config.h
new file mode 100644
index 0000000000..45bf2bac6d
--- /dev/null
+++ b/libs/ardour/ardour/config.h
@@ -0,0 +1,57 @@
+/* config.h. Generated automatically by configure. */
+/* config.h.in. Generated automatically from configure.in by autoheader. */
+
+/* Define if you don't have vprintf but do have _doprnt. */
+/* #undef HAVE_DOPRNT */
+
+/* Define if you have the vprintf function. */
+/* #undef HAVE_VPRINTF */
+
+/* Define if you have the ANSI C header files. */
+/* #undef STDC_HEADERS */
+
+/* Define if your <sys/time.h> declares struct tm. */
+/* #undef TM_IN_SYS_TIME */
+
+/* Define if you have the regcomp function. */
+/* #undef HAVE_REGCOMP */
+
+/* Define if you have the strerror function. */
+/* #undef HAVE_STRERROR */
+
+/* Define if you have the <dirent.h> header file. */
+#define HAVE_DIRENT_H 1
+
+/* Define if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define if you have the <ladspa.h> header file. */
+#define HAVE_LADSPA_H 1
+
+/* Define if you have the <limits.h> header file. */
+#define HAVE_LIMITS_H 1
+
+/* Define if you have the <ndir.h> header file. */
+/* #undef HAVE_NDIR_H */
+
+/* Define if you have the <sys/dir.h> header file. */
+/* #undef HAVE_SYS_DIR_H */
+
+/* Define if you have the <sys/ndir.h> header file. */
+/* #undef HAVE_SYS_NDIR_H */
+
+/* Define if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define if you have the gdbm library (-lgdbm). */
+#define HAVE_LIBGDBM 1
+
+/* Define if you have the sndfile library (-lsndfile). */
+#define HAVE_LIBSNDFILE 1
+
+/* Name of package */
+#define PACKAGE "ardour"
+
+/* Version number of package */
+#define VERSION "0.107.3"
+
diff --git a/libs/ardour/ardour/configuration.h b/libs/ardour/ardour/configuration.h
new file mode 100644
index 0000000000..0c42027646
--- /dev/null
+++ b/libs/ardour/ardour/configuration.h
@@ -0,0 +1,253 @@
+/*
+ Copyright (C) 1999 Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __ardour_configuration_h__
+#define __ardour_configuration_h__
+
+#include <map>
+
+#include <sys/types.h>
+#include <string>
+
+#include <ardour/types.h>
+#include <ardour/stateful.h>
+
+using std::string;
+
+class XMLNode;
+
+namespace ARDOUR {
+
+class Configuration : public Stateful
+{
+ public:
+ Configuration();
+ virtual ~Configuration();
+
+ struct MidiPortDescriptor {
+ string tag;
+ string device;
+ string type;
+ string mode;
+
+ MidiPortDescriptor (const XMLNode&);
+ XMLNode& get_state();
+ };
+
+ std::map<string,MidiPortDescriptor *> midi_ports;
+
+ int load_state ();
+ int save_state ();
+
+ XMLNode& option_node (const string &, const string &);
+
+ int set_state (const XMLNode&);
+ XMLNode& get_state (void);
+
+ XMLNode * get_keys() const;
+ void set_keys(XMLNode *);
+
+ void set_use_vst (bool yn);
+ bool get_use_vst();
+
+ bool get_trace_midi_input ();
+ void set_trace_midi_input (bool);
+
+ bool get_trace_midi_output ();
+ void set_trace_midi_output (bool);
+
+ string get_raid_path();
+ void set_raid_path(string);
+
+ uint32_t get_minimum_disk_io();
+ void set_minimum_disk_io(uint32_t);
+
+ float get_track_buffer();
+ void set_track_buffer(float);
+
+ bool does_hiding_groups_deactivates_groups();
+ void set_hiding_groups_deactivates_groups(bool);
+
+ string get_auditioner_output_left();
+ void set_auditioner_output_left(string);
+
+ string get_auditioner_output_right();
+ void set_auditioner_output_right(string);
+
+ bool get_mute_affects_pre_fader();
+ void set_mute_affects_pre_fader (bool);
+
+ bool get_mute_affects_post_fader();
+ void set_mute_affects_post_fader (bool);
+
+ bool get_mute_affects_control_outs ();
+ void set_mute_affects_control_outs (bool);
+
+ bool get_mute_affects_main_outs ();
+ void set_mute_affects_main_outs (bool);
+
+ bool get_solo_latch ();
+ void set_solo_latch (bool);
+
+ uint32_t get_disk_choice_space_threshold();
+ void set_disk_choice_space_threshold (uint32_t);
+
+ string get_mmc_port_name();
+ void set_mmc_port_name(string);
+
+ string get_mtc_port_name();
+ void set_mtc_port_name(string);
+
+ string get_midi_port_name();
+ void set_midi_port_name(string);
+
+ bool get_use_hardware_monitoring();
+ void set_use_hardware_monitoring(bool);
+
+ bool get_jack_time_master();
+ void set_jack_time_master(bool);
+
+ bool get_native_format_is_bwf();
+ void set_native_format_is_bwf(bool);
+
+ bool get_plugins_stop_with_transport();
+ void set_plugins_stop_with_transport(bool);
+
+ bool get_no_sw_monitoring();
+ void set_no_sw_monitoring(bool);
+
+ bool get_stop_recording_on_xrun();
+ void set_stop_recording_on_xrun(bool);
+
+ bool get_verify_remove_last_capture();
+ void set_verify_remove_last_capture(bool);
+
+ bool get_stop_at_session_end();
+ void set_stop_at_session_end(bool);
+
+ bool get_seamless_looping();
+ void set_seamless_looping(bool);
+
+ bool get_auto_xfade();
+ void set_auto_xfade (bool);
+
+ bool get_no_new_session_dialog();
+ void set_no_new_session_dialog(bool);
+
+ uint32_t get_timecode_skip_limit ();
+ void set_timecode_skip_limit (uint32_t);
+
+ bool get_timecode_source_is_synced ();
+ void set_timecode_source_is_synced (bool);
+
+ string get_user_ardour_path ();
+ string get_system_ardour_path ();
+
+ gain_t get_quieten_at_speed ();
+ void set_quieten_at_speed (gain_t);
+
+ private:
+ void set_defaults ();
+ string get_system_path();
+ string get_user_path();
+
+ /* this is subject to wordexp, so we need
+ to keep the original (user-entered) form
+ around. e.g. ~/blah-> /home/foo/blah
+ */
+
+ string raid_path;
+ bool raid_path_is_user;
+ string orig_raid_path;
+
+ uint32_t minimum_disk_io_bytes;
+ bool minimum_disk_io_bytes_is_user;
+ float track_buffer_seconds;
+ bool track_buffer_seconds_is_user;
+ bool hiding_groups_deactivates_groups;
+ bool hiding_groups_deactivates_groups_is_user;
+ string auditioner_output_left;
+ bool auditioner_output_left_is_user;
+ string auditioner_output_right;
+ bool auditioner_output_right_is_user;
+ bool mute_affects_pre_fader;
+ bool mute_affects_pre_fader_is_user;
+ bool mute_affects_post_fader;
+ bool mute_affects_post_fader_is_user;
+ bool mute_affects_control_outs;
+ bool mute_affects_control_outs_is_user;
+ bool mute_affects_main_outs;
+ bool mute_affects_main_outs_is_user;
+ bool solo_latch;
+ bool solo_latch_is_user;
+ uint32_t disk_choice_space_threshold;
+ bool disk_choice_space_threshold_is_user;
+ string mtc_port_name;
+ bool mtc_port_name_is_user;
+ string mmc_port_name;
+ bool mmc_port_name_is_user;
+ string midi_port_name;
+ bool midi_port_name_is_user;
+ bool use_hardware_monitoring;
+ bool use_hardware_monitoring_is_user;
+ bool be_jack_time_master;
+ bool be_jack_time_master_is_user;
+ bool native_format_is_bwf;
+ bool native_format_is_bwf_is_user;
+ bool trace_midi_input;
+ bool trace_midi_input_is_user;
+ bool trace_midi_output;
+ bool trace_midi_output_is_user;
+ bool plugins_stop_with_transport;
+ bool plugins_stop_with_transport_is_user;
+ bool no_sw_monitoring;
+ bool no_sw_monitoring_is_user;
+ bool stop_recording_on_xrun;
+ bool stop_recording_on_xrun_is_user;
+ bool verify_remove_last_capture;
+ bool verify_remove_last_capture_is_user;
+ bool stop_at_session_end;
+ bool stop_at_session_end_is_user;
+ bool seamless_looping;
+ bool seamless_looping_is_user;
+ bool auto_xfade;
+ bool auto_xfade_is_user;
+ bool no_new_session_dialog;
+ bool no_new_session_dialog_is_user;
+ uint32_t timecode_skip_limit;
+ bool timecode_skip_limit_is_user;
+ bool timecode_source_is_synced;
+ bool timecode_source_is_synced_is_user;
+ bool use_vst; /* always per-user */
+ bool quieten_at_speed;
+ bool quieten_at_speed_is_user;
+
+ XMLNode *key_node;
+ bool user_configuration;
+
+ XMLNode& state (bool user_only);
+};
+
+extern Configuration *Config;
+extern gain_t speed_quietning; /* see comment in configuration.cc */
+
+}; /* namespace ARDOUR */
+
+#endif /* __ardour_configuration_h__ */
diff --git a/libs/ardour/ardour/connection.h b/libs/ardour/ardour/connection.h
new file mode 100644
index 0000000000..b33af9cb21
--- /dev/null
+++ b/libs/ardour/ardour/connection.h
@@ -0,0 +1,94 @@
+/*
+ Copyright (C) 2002 Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __ardour_connection_h__
+#define __ardour_connection_h__
+
+#include <vector>
+#include <string>
+#include <sigc++/signal.h>
+#include <pbd/lockmonitor.h>
+#include <ardour/stateful.h>
+
+using std::vector;
+using std::string;
+
+namespace ARDOUR {
+
+class Connection : public Stateful, public sigc::trackable {
+ public:
+ Connection (string name, bool sdep = false) : _name (name), _sysdep(sdep) {}
+ ~Connection() {}
+
+ typedef vector<string> PortList;
+
+ void set_name (string name, void *src);
+ string name() const { return _name; }
+
+ bool system_dependent() const { return _sysdep; }
+
+ uint32_t nports () const { return _ports.size(); }
+ const PortList& port_connections (int port) const;
+
+ void add_connection (int port, string portname);
+ void remove_connection (int port, string portname);
+
+ void add_port ();
+ void remove_port (int port);
+ void clear ();
+
+ sigc::signal<void,void*> NameChanged;
+ sigc::signal<void> ConfigurationChanged;
+ sigc::signal<void,int> ConnectionsChanged;
+
+ bool operator==(const Connection& other) const;
+
+ XMLNode& get_state (void);
+ int set_state (const XMLNode&);
+
+ protected:
+ Connection (const XMLNode&);
+
+ private:
+ mutable PBD::Lock port_lock;
+ vector<PortList> _ports;
+ string _name;
+ bool _sysdep;
+
+ int set_connections (const string& str);
+ int parse_io_string (const string& str, vector<string>& ports);
+};
+
+class InputConnection : public Connection {
+ public:
+ InputConnection (string name, bool sdep = false) : Connection (name, sdep) {}
+ InputConnection (const XMLNode&);
+};
+
+class OutputConnection : public Connection {
+ public:
+ OutputConnection (string name, bool sdep = false) : Connection (name, sdep) {}
+ OutputConnection (const XMLNode&);
+};
+
+}
+
+#endif /* __ardour_connection_h__ */
+
diff --git a/libs/ardour/ardour/constsource.h b/libs/ardour/ardour/constsource.h
new file mode 100644
index 0000000000..d000afb347
--- /dev/null
+++ b/libs/ardour/ardour/constsource.h
@@ -0,0 +1,60 @@
+/*
+ Copyright (C) 2000 Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __playlist_const_buffer_h__
+#define __playlist_const_buffer_h__
+
+#include <string>
+#include <cstdlib>
+
+#include "edl.h"
+
+namespace EDL {
+
+class ConstSource : public Source {
+ public:
+ ConstSource (const gchar *id) {
+ _type = Source::Const;
+ value = strtod (id, 0);
+ strncpy (idstr, id, 15);
+ idstr[15] = '\0';
+ }
+
+ const gchar * const id() { return idstr; }
+
+ uint32_t length() { return ~0U; }
+
+ uint32_t read (Source::Data *dst, uint32_t start, uint32_t cnt) {
+ uint32_t n = cnt;
+ while (n--) *dst++ = value;
+ return cnt;
+ }
+ void peak (guint8 *max, guint8 *min, uint32_t start, uint32_t cnt) {
+ *max = *min = (guint8) value;
+ }
+
+ private:
+ Source::Data value;
+ gchar idstr[16];
+};
+
+}; /* namespace EDL */
+
+#endif /* __playlist_const_buffer_h__ */
diff --git a/libs/ardour/ardour/crossfade.h b/libs/ardour/ardour/crossfade.h
new file mode 100644
index 0000000000..419b980a83
--- /dev/null
+++ b/libs/ardour/ardour/crossfade.h
@@ -0,0 +1,182 @@
+/*
+ Copyright (C) 2000 Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __ardour_overlap_h__
+#define __ardour_overlap_h__
+
+#include <vector>
+#include <algorithm>
+
+#include <sigc++/signal.h>
+
+#include <pbd/undo.h>
+
+#include <ardour/ardour.h>
+#include <ardour/curve.h>
+#include <ardour/audioregion.h>
+#include <ardour/state_manager.h>
+#include <ardour/crossfade_compare.h>
+
+namespace ARDOUR {
+
+class AudioRegion;
+class Playlist;
+
+struct CrossfadeState : public StateManager::State {
+ CrossfadeState (std::string reason) : StateManager::State (reason) {}
+
+ UndoAction fade_in_memento;
+ UndoAction fade_out_memento;
+ jack_nframes_t position;
+ jack_nframes_t length;
+ AnchorPoint anchor_point;
+ bool follow_overlap;
+ bool active;
+};
+
+class Crossfade : public Stateful, public StateManager
+{
+ public:
+
+ class NoCrossfadeHere: std::exception {
+ public:
+ virtual const char *what() const throw() { return "no crossfade should be constructed here"; }
+ };
+
+ /* constructor for "fixed" xfades at each end of an internal overlap */
+
+ Crossfade (ARDOUR::AudioRegion& in, ARDOUR::AudioRegion& out,
+ jack_nframes_t position,
+ jack_nframes_t initial_length,
+ AnchorPoint);
+
+ /* constructor for xfade between two regions that are overlapped in any way
+ except the "internal" case.
+ */
+
+ Crossfade (ARDOUR::AudioRegion& in, ARDOUR::AudioRegion& out, CrossfadeModel, bool active);
+
+ /* the usual XML constructor */
+
+ Crossfade (const ARDOUR::Playlist&, XMLNode&);
+ virtual ~Crossfade();
+
+ bool operator== (const ARDOUR::Crossfade&);
+
+ XMLNode& get_state (void);
+ int set_state (const XMLNode&);
+
+ ARDOUR::AudioRegion& in() const { return *_in; }
+ ARDOUR::AudioRegion& out() const { return *_out; }
+
+ jack_nframes_t read_at (Sample *buf, Sample *mixdown_buffer,
+ float *gain_buffer, jack_nframes_t position, jack_nframes_t cnt,
+ uint32_t chan_n,
+ jack_nframes_t read_frames = 0,
+ jack_nframes_t skip_frames = 0);
+
+ bool refresh ();
+
+ uint32_t upper_layer () const {
+ return std::max (_in->layer(), _out->layer());
+ }
+
+ uint32_t lower_layer () const {
+ return std::min (_in->layer(), _out->layer());
+ }
+
+ bool involves (ARDOUR::AudioRegion& region) const {
+ return _in == &region || _out == &region;
+ }
+
+ bool involves (ARDOUR::AudioRegion& a, ARDOUR::AudioRegion& b) const {
+ return (_in == &a && _out == &b) || (_in == &b && _out == &a);
+ }
+
+ jack_nframes_t length() const { return _length; }
+ jack_nframes_t overlap_length() const;
+ jack_nframes_t position() const { return _position; }
+
+ sigc::signal<void,Crossfade*> Invalidated;
+ sigc::signal<void> GoingAway;
+
+ bool covers (jack_nframes_t frame) const {
+ return _position <= frame && frame < _position + _length;
+ }
+
+ OverlapType coverage (jack_nframes_t start, jack_nframes_t end) const;
+
+ UndoAction get_memento() const;
+
+ static void set_buffer_size (jack_nframes_t);
+
+ bool active () const { return _active; }
+ void set_active (bool yn);
+
+ bool following_overlap() const { return _follow_overlap; }
+ bool can_follow_overlap() const;
+ void set_follow_overlap (bool yn);
+
+ Curve& fade_in() { return _fade_in; }
+ Curve& fade_out() { return _fade_out; }
+
+ jack_nframes_t set_length (jack_nframes_t);
+
+ static jack_nframes_t short_xfade_length() { return _short_xfade_length; }
+ static void set_short_xfade_length (jack_nframes_t n);
+
+ static Change ActiveChanged;
+
+ private:
+ friend struct CrossfadeComparePtr;
+
+ static jack_nframes_t _short_xfade_length;
+
+ ARDOUR::AudioRegion* _in;
+ ARDOUR::AudioRegion* _out;
+ bool _active;
+ bool _in_update;
+ OverlapType overlap_type;
+ jack_nframes_t _length;
+ jack_nframes_t _position;
+ AnchorPoint _anchor_point;
+ bool _follow_overlap;
+ bool _fixed;
+ Curve _fade_in;
+ Curve _fade_out;
+
+ static Sample* crossfade_buffer_out;
+ static Sample* crossfade_buffer_in;
+
+ void initialize ();
+ int compute (ARDOUR::AudioRegion&, ARDOUR::AudioRegion&, CrossfadeModel);
+ bool update (bool force);
+
+ StateManager::State* state_factory (std::string why) const;
+ Change restore_state (StateManager::State&);
+
+ void member_changed (ARDOUR::Change);
+
+};
+
+
+} // namespace ARDOUR
+
+#endif /* __ardour_overlap_h__ */
diff --git a/libs/ardour/ardour/crossfade_compare.h b/libs/ardour/ardour/crossfade_compare.h
new file mode 100644
index 0000000000..2ecf79c04c
--- /dev/null
+++ b/libs/ardour/ardour/crossfade_compare.h
@@ -0,0 +1,43 @@
+/*
+ Copyright (C) 2003 Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __ardour_crossfade_compare_h__
+#define __ardour_crossfade_compare_h__
+
+/* this exists so that playlist.h doesn't have to include crossfade.h
+ */
+
+namespace ARDOUR {
+
+class Crossfade;
+
+struct CrossfadeComparePtr {
+ bool operator() (const Crossfade *a, const Crossfade *b) const;
+};
+
+enum AnchorPoint {
+ StartOfIn,
+ EndOfIn,
+ EndOfOut
+};
+
+}
+
+#endif /* __ardour_crossfade_compare_h__ */
diff --git a/libs/ardour/ardour/curve.h b/libs/ardour/ardour/curve.h
new file mode 100644
index 0000000000..1c6a4c5bc4
--- /dev/null
+++ b/libs/ardour/ardour/curve.h
@@ -0,0 +1,86 @@
+/*
+ Copyright (C) 2001-2003 Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __ardour_curve_h__
+#define __ardour_curve_h__
+
+#include <sys/types.h>
+#include <sigc++/signal.h>
+#include <pbd/lockmonitor.h>
+#include <pbd/undo.h>
+#include <list>
+#include <algorithm>
+#include <pthread.h>
+#include <ardour/automation_event.h>
+
+namespace ARDOUR {
+
+struct CurvePoint : public ControlEvent
+{
+ double coeff[4];
+
+ CurvePoint (double w, double v)
+ : ControlEvent (w, v) {
+
+ coeff[0] = coeff[1] = coeff[2] = coeff[3] = 0.0;
+ }
+
+ ~CurvePoint() {}
+};
+
+class Curve : public AutomationList
+{
+ public:
+ Curve (double min_yval, double max_yval, double defaultvalue, bool nostate = false);
+ ~Curve ();
+ Curve (const Curve& other);
+ Curve (const Curve& other, double start, double end);
+
+ bool rt_safe_get_vector (double x0, double x1, float *arg, int32_t veclen);
+ void get_vector (double x0, double x1, float *arg, int32_t veclen);
+
+ AutomationEventList::iterator closest_control_point_before (double xval);
+ AutomationEventList::iterator closest_control_point_after (double xval);
+
+ void solve ();
+
+ protected:
+ ControlEvent* point_factory (double,double) const;
+ ControlEvent* point_factory (const ControlEvent&) const;
+
+ Change restore_state (StateManager::State&);
+
+ private:
+ AutomationList::iterator last_bound;
+
+ double unlocked_eval (double where);
+ double multipoint_eval (double x);
+
+ void _get_vector (double x0, double x1, float *arg, int32_t veclen);
+
+};
+
+}; /* namespace ARDOUR */
+
+extern "C" {
+ void curve_get_vector_from_c (void *arg, double, double, float*, int32_t);
+}
+
+#endif /* __ardour_curve_h__ */
diff --git a/libs/ardour/ardour/cycle_timer.h b/libs/ardour/ardour/cycle_timer.h
new file mode 100644
index 0000000000..1ec7c74903
--- /dev/null
+++ b/libs/ardour/ardour/cycle_timer.h
@@ -0,0 +1,53 @@
+/*
+ Copyright (C) 2002 Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __ardour_cycle_timer_h__
+#define __ardour_cycle_timer_h__
+
+#include <string>
+#include <cstdio>
+
+#include <ardour/cycles.h>
+
+using std::string;
+
+class CycleTimer {
+ private:
+ static float cycles_per_usec;
+ uint32_t long entry;
+ uint32_t long exit;
+ string _name;
+
+ public:
+ CycleTimer(string name) : _name (name){
+ if (cycles_per_usec == 0) {
+ cycles_per_usec = get_mhz ();
+ }
+ entry = get_cycles();
+ }
+ ~CycleTimer() {
+ exit = get_cycles();
+ printf ("%s: %.9f usecs (%lu-%lu)\n", _name.c_str(), (float) (exit - entry) / cycles_per_usec, entry, exit);
+ }
+
+ static float get_mhz ();
+};
+
+#endif /* __ardour_cycle_timer_h__ */
diff --git a/libs/ardour/ardour/cycles.h b/libs/ardour/ardour/cycles.h
new file mode 100644
index 0000000000..f194988da9
--- /dev/null
+++ b/libs/ardour/ardour/cycles.h
@@ -0,0 +1,221 @@
+/*
+ Copyright (C) 2001 Paul Davis
+ Code derived from various headers from the Linux kernel
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __ardour_cycles_h__
+#define __ardour_cycles_h__
+
+#include <stdint.h>
+
+#if defined(__i386__) || defined(__x86_64__)
+
+/*
+ * Standard way to access the cycle counter on i586+ CPUs.
+ * Currently only used on SMP.
+ *
+ * If you really have a SMP machine with i486 chips or older,
+ * compile for that, and this will just always return zero.
+ * That's ok, it just means that the nicer scheduling heuristics
+ * won't work for you.
+ *
+ * We only use the low 32 bits, and we'd simply better make sure
+ * that we reschedule before that wraps. Scheduling at least every
+ * four billion cycles just basically sounds like a good idea,
+ * regardless of how fast the machine is.
+ */
+typedef uint64_t cycles_t;
+
+extern cycles_t cacheflush_time;
+
+#define rdtscll(val) \
+ __asm__ __volatile__("rdtsc" : "=A" (val))
+
+static inline cycles_t get_cycles (void)
+{
+ uint32_t long ret;
+
+ rdtscll(ret);
+ return ret;
+}
+
+#elif defined(__powerpc__)
+
+#define CPU_FTR_601 0x00000100
+
+typedef uint32_t cycles_t;
+
+/*
+ * For the "cycle" counter we use the timebase lower half.
+ * Currently only used on SMP.
+ */
+
+extern cycles_t cacheflush_time;
+
+static inline cycles_t get_cycles(void)
+{
+ cycles_t ret = 0;
+
+ __asm__ __volatile__(
+ "98: mftb %0\n"
+ "99:\n"
+ ".section __ftr_fixup,\"a\"\n"
+ " .long %1\n"
+ " .long 0\n"
+ " .long 98b\n"
+ " .long 99b\n"
+ ".previous"
+ : "=r" (ret) : "i" (CPU_FTR_601));
+ return ret;
+}
+
+#elif defined(__ia64__)
+/* ia64 */
+
+typedef uint32_t cycles_t;
+static inline cycles_t
+get_cycles (void)
+{
+ cycles_t ret;
+ __asm__ __volatile__ ("mov %0=ar.itc" : "=r"(ret));
+ return ret;
+}
+
+#elif defined(__alpha__)
+/* alpha */
+
+/*
+ * Standard way to access the cycle counter.
+ * Currently only used on SMP for scheduling.
+ *
+ * Only the low 32 bits are available as a continuously counting entity.
+ * But this only means we'll force a reschedule every 8 seconds or so,
+ * which isn't an evil thing.
+ */
+
+typedef uint32_t cycles_t;
+static inline cycles_t get_cycles (void)
+{
+ cycles_t ret;
+ __asm__ __volatile__ ("rpcc %0" : "=r"(ret));
+ return ret;
+}
+
+#elif defined(__s390__)
+/* s390 */
+
+typedef uint32_t long cycles_t;
+static inline cycles_t get_cycles(void)
+{
+ cycles_t cycles;
+ __asm__("stck 0(%0)" : : "a" (&(cycles)) : "memory", "cc");
+ return cycles >> 2;
+}
+
+#elif defined(__hppa__)
+/* hppa/parisc */
+
+#define mfctl(reg) ({ \
+ uint32_t cr; \
+ __asm__ __volatile__( \
+ "mfctl " #reg ",%0" : \
+ "=r" (cr) \
+ ); \
+ cr; \
+})
+
+typedef uint32_t cycles_t;
+static inline cycles_t get_cycles (void)
+{
+ return mfctl(16);
+}
+
+#elif defined(__mips__)
+/* mips/mipsel */
+
+/*
+ * Standard way to access the cycle counter.
+ * Currently only used on SMP for scheduling.
+ *
+ * Only the low 32 bits are available as a continuously counting entity.
+ * But this only means we'll force a reschedule every 8 seconds or so,
+ * which isn't an evil thing.
+ *
+ * We know that all SMP capable CPUs have cycle counters.
+ */
+
+#define __read_32bit_c0_register(source, sel) \
+({ int __res; \
+ if (sel == 0) \
+ __asm__ __volatile__( \
+ "mfc0\t%0, " #source "\n\t" \
+ : "=r" (__res)); \
+ else \
+ __asm__ __volatile__( \
+ ".set\tmips32\n\t" \
+ "mfc0\t%0, " #source ", " #sel "\n\t" \
+ ".set\tmips0\n\t" \
+ : "=r" (__res)); \
+ __res; \
+})
+
+/* #define CP0_COUNT $9 */
+#define read_c0_count() __read_32bit_c0_register($9, 0)
+
+typedef uint32_t cycles_t;
+static inline cycles_t get_cycles (void)
+{
+ return read_c0_count();
+}
+
+/* begin mach */
+#elif defined(__APPLE__)
+#include <CoreAudio/CoreAudioTypes.h>
+#include <CoreAudio/HostTime.h>
+typedef UInt64 cycles_t;
+static inline cycles_t get_cycles (void)
+{
+ UInt64 time = AudioGetCurrentHostTime();
+ return AudioConvertHostTimeToNanos(time);
+}
+/* end mach */
+
+#else
+
+/* debian: sparc, arm, m68k */
+
+#warning You are compiling libardour on a platform for which ardour/cycles.h needs work
+
+#include <sys/time.h>
+
+typedef long cycles_t;
+
+extern cycles_t cacheflush_time;
+
+static inline cycles_t get_cycles(void)
+{
+ struct timeval tv;
+ gettimeofday (&tv, NULL);
+
+ return tv.tv_usec;
+}
+
+#endif
+
+#endif /* __ardour_cycles_h__ */
diff --git a/libs/ardour/ardour/dB.h b/libs/ardour/ardour/dB.h
new file mode 100644
index 0000000000..703de6fb1a
--- /dev/null
+++ b/libs/ardour/ardour/dB.h
@@ -0,0 +1,34 @@
+/*
+ Copyright (C) 2001 Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __ardour_dB_h__
+#define __ardour_dB_h__
+
+#include <pbd/fastlog.h>
+
+static inline float dB_to_coefficient (float dB) {
+ return dB > -318.8f ? pow (10.0f, dB * 0.05f) : 0.0f;
+}
+
+static inline float coefficient_to_dB (float coeff) {
+ return 20.0f * fast_log10 (coeff);
+}
+
+#endif /* __ardour_dB_h__ */
diff --git a/libs/ardour/ardour/diskstream.h b/libs/ardour/ardour/diskstream.h
new file mode 100644
index 0000000000..9028f0d9e0
--- /dev/null
+++ b/libs/ardour/ardour/diskstream.h
@@ -0,0 +1,433 @@
+/*
+ Copyright (C) 2000 Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __ardour_diskstream_h__
+#define __ardour_diskstream_h__
+
+#include <sigc++/signal.h>
+
+#include <cmath>
+#include <string>
+#include <queue>
+#include <map>
+#include <vector>
+
+#include <time.h>
+
+#include <pbd/fastlog.h>
+#include <pbd/ringbufferNPT.h>
+#include <pbd/atomic.h>
+
+#include <ardour/ardour.h>
+#include <ardour/configuration.h>
+#include <ardour/session.h>
+#include <ardour/route_group.h>
+#include <ardour/route.h>
+#include <ardour/port.h>
+#include <ardour/utils.h>
+#include <ardour/stateful.h>
+
+struct tm;
+
+namespace ARDOUR {
+
+class AudioEngine;
+class Send;
+class Session;
+class AudioPlaylist;
+class FileSource;
+class IO;
+
+class DiskStream : public Stateful, public sigc::trackable
+{
+ public:
+ enum Flag {
+ Recordable = 0x1,
+ Hidden = 0x2
+ };
+
+ DiskStream (Session &, const string& name, Flag f = Recordable);
+ DiskStream (Session &, const XMLNode&);
+
+ string name() const { return _name; }
+
+ ARDOUR::IO* io() const { return _io; }
+ void set_io (ARDOUR::IO& io);
+
+ DiskStream& ref() { _refcnt++; return *this; }
+ void unref() { if (_refcnt) _refcnt--; if (_refcnt == 0) delete this; }
+ uint32_t refcnt() const { return _refcnt; }
+
+ float playback_buffer_load() const;
+ float capture_buffer_load() const;
+
+ void set_flag (Flag f) {
+ _flags |= f;
+ }
+
+ void unset_flag (Flag f) {
+ _flags &= ~f;
+ }
+
+ AlignStyle alignment_style() const { return _alignment_style; }
+ void set_align_style (AlignStyle);
+ void set_persistent_align_style (AlignStyle);
+
+ bool hidden() const { return _flags & Hidden; }
+ bool recordable() const { return _flags & Recordable; }
+
+ jack_nframes_t roll_delay() const { return _roll_delay; }
+ void set_roll_delay (jack_nframes_t);
+
+ void set_name (string str, void* src);
+
+ string input_source (uint32_t n=0) const {
+ if (n < channels.size()) {
+ return channels[n].source ? channels[n].source->name() : "";
+ } else {
+ return "";
+ }
+ }
+
+ Port *input_source_port (uint32_t n=0) const {
+ if (n < channels.size()) return channels[n].source; return 0;
+ }
+
+ void set_record_enabled (bool yn, void *src);
+ bool record_enabled() const { return atomic_read (&_record_enabled); }
+ void punch_in ();
+ void punch_out ();
+
+ bool reversed() const { return _actual_speed < 0.0f; }
+ float speed() const { return _visible_speed; }
+ void set_speed (float);
+
+ float peak_power(uint32_t n=0) {
+ float x = channels[n].peak_power;
+ channels[n].peak_power = 0.0f;
+ if (x > 0.0f) {
+ return 20.0f * fast_log10(x);
+ } else {
+ return minus_infinity();
+ }
+ }
+
+ int use_playlist (AudioPlaylist *);
+ int use_new_playlist ();
+ int use_copy_playlist ();
+
+ void start_scrub (jack_nframes_t where);
+ void end_scrub ();
+
+ Sample *playback_buffer (uint32_t n=0) {
+ if (n < channels.size())
+ return channels[n].current_playback_buffer;
+ return 0;
+ }
+
+ Sample *capture_buffer (uint32_t n=0) {
+ if (n < channels.size())
+ return channels[n].current_capture_buffer;
+ return 0;
+ }
+
+ AudioPlaylist *playlist () { return _playlist; }
+
+ FileSource *fades_source (uint32_t n=0) {
+ if (n < channels.size())
+ return channels[n].fades_source;
+ return 0;
+ }
+ FileSource *write_source (uint32_t n=0) {
+ if (n < channels.size())
+ return channels[n].write_source;
+ return 0;
+ }
+
+ jack_nframes_t current_capture_start() const { return capture_start_frame; }
+ jack_nframes_t current_capture_end() const { return capture_start_frame + capture_captured; }
+ jack_nframes_t get_capture_start_frame (uint32_t n=0);
+ jack_nframes_t get_captured_frames (uint32_t n=0);
+
+ uint32_t n_channels() { return _n_channels; }
+
+ int add_channel ();
+ int remove_channel ();
+
+ static void set_disk_io_chunk_frames (uint32_t n) {
+ disk_io_chunk_frames = n;
+ }
+
+ static jack_nframes_t disk_io_frames() { return disk_io_chunk_frames; }
+
+ sigc::signal<void,void*> record_enable_changed;
+ sigc::signal<void> speed_changed;
+ sigc::signal<void,void*> reverse_changed;
+ sigc::signal<void> PlaylistChanged;
+ sigc::signal<void> AlignmentStyleChanged;
+
+ static sigc::signal<void> DiskOverrun;
+ static sigc::signal<void> DiskUnderrun;
+ static sigc::signal<void,DiskStream*> DiskStreamCreated; // XXX use a ref with sigc2
+ static sigc::signal<void,DiskStream*> CannotRecordNoInput; // XXX use a ref with sigc2
+ static sigc::signal<void,list<Source*>*> DeleteSources;
+
+ /* stateful */
+
+ XMLNode& get_state(void);
+ int set_state(const XMLNode& node);
+
+ void monitor_input (bool);
+
+ jack_nframes_t capture_offset() const { return _capture_offset; }
+ void set_capture_offset ();
+
+ static void swap_by_ptr (Sample *first, Sample *last) {
+ while (first < last) {
+ Sample tmp = *first;
+ *first++ = *last;
+ *last-- = tmp;
+ }
+ }
+
+ static void swap_by_ptr (Sample *first, Sample *last, jack_nframes_t n) {
+ while (n--) {
+ Sample tmp = *first;
+ *first++ = *last;
+ *last-- = tmp;
+ }
+ }
+
+ bool slaved() const { return _slaved; }
+ void set_slaved(bool yn) { _slaved = yn; }
+
+ int set_loop (Location *loc);
+ sigc::signal<void,Location *> LoopSet;
+
+ std::list<Region*>& last_capture_regions () {
+ return _last_capture_regions;
+ }
+
+ void handle_input_change (IOChange, void *src);
+
+ id_t id() const { return _id; }
+
+ XMLNode* deprecated_io_node;
+
+ protected:
+ friend class Session;
+
+ /* the Session is the only point of access for these
+ because they require that the Session is "inactive"
+ while they are called.
+ */
+
+ void set_pending_overwrite (bool);
+ int overwrite_existing_buffers ();
+ void reverse_scrub_buffer (bool to_forward);
+ void set_block_size (jack_nframes_t);
+ int internal_playback_seek (jack_nframes_t distance);
+ int can_internal_playback_seek (jack_nframes_t distance);
+ void reset_write_sources (bool);
+ void non_realtime_input_change ();
+
+ uint32_t read_data_count() const { return _read_data_count; }
+ uint32_t write_data_count() const { return _write_data_count; }
+
+ protected:
+ friend class Auditioner;
+ int seek (jack_nframes_t which_sample, bool complete_refill = false);
+
+ protected:
+ friend class AudioTrack;
+
+ void prepare ();
+ int process (jack_nframes_t transport_frame, jack_nframes_t nframes, jack_nframes_t offset, bool can_record, bool rec_monitors_input);
+ bool commit (jack_nframes_t nframes);
+ void recover (); /* called if commit will not be called, but process was */
+
+ private:
+
+ /* use unref() to destroy a diskstream */
+
+ ~DiskStream();
+
+ struct ChannelInfo {
+
+ Sample *playback_wrap_buffer;
+ Sample *capture_wrap_buffer;
+ Sample *speed_buffer;
+
+ float peak_power;
+
+ FileSource *fades_source;
+ FileSource *write_source;
+
+ Port *source;
+ Sample *current_capture_buffer;
+ Sample *current_playback_buffer;
+
+ RingBufferNPT<Sample> *playback_buf;
+ RingBufferNPT<Sample> *capture_buf;
+
+ Sample* scrub_buffer;
+ Sample* scrub_forward_buffer;
+ Sample* scrub_reverse_buffer;
+
+ RingBufferNPT<Sample>::rw_vector playback_vector;
+ RingBufferNPT<Sample>::rw_vector capture_vector;
+ };
+
+ typedef vector<ChannelInfo> ChannelList;
+
+ string _name;
+ ARDOUR::Session& _session;
+ ARDOUR::IO* _io;
+ ChannelList channels;
+ uint32_t _n_channels;
+ id_t _id;
+
+ atomic_t _record_enabled;
+ bool rec_monitoring_off_for_roll;
+ AudioPlaylist* _playlist;
+ float _visible_speed;
+ float _actual_speed;
+ /* items needed for speed change logic */
+ bool _buffer_reallocation_required;
+ bool _seek_required;
+
+ bool force_refill;
+ jack_nframes_t capture_start_frame;
+ jack_nframes_t capture_captured;
+ bool was_recording;
+ jack_nframes_t adjust_capture_position;
+ jack_nframes_t _capture_offset;
+ jack_nframes_t _roll_delay;
+ jack_nframes_t first_recordable_frame;
+ jack_nframes_t last_recordable_frame;
+ int last_possibly_recording;
+ AlignStyle _alignment_style;
+ bool _scrubbing;
+ bool _slaved;
+ bool _processed;
+ Location* loop_location;
+ jack_nframes_t overwrite_frame;
+ off_t overwrite_offset;
+ bool pending_overwrite;
+ bool overwrite_queued;
+ IOChange input_change_pending;
+ jack_nframes_t wrap_buffer_size;
+ jack_nframes_t speed_buffer_size;
+
+ uint64_t last_phase;
+ uint64_t phi;
+
+ jack_nframes_t file_frame;
+ jack_nframes_t playback_sample;
+ jack_nframes_t playback_distance;
+
+ uint32_t _read_data_count;
+ uint32_t _write_data_count;
+
+ bool in_set_state;
+ AlignStyle _persistent_alignment_style;
+ bool first_input_change;
+
+ PBD::NonBlockingLock state_lock;
+
+ jack_nframes_t scrub_start;
+ jack_nframes_t scrub_buffer_size;
+ jack_nframes_t scrub_offset;
+ uint32_t _refcnt;
+
+ sigc::connection ports_created_c;
+ sigc::connection plmod_connection;
+ sigc::connection plstate_connection;
+ sigc::connection plgone_connection;
+
+ /* the two central butler operations */
+
+ int do_flush (bool force = false);
+ int do_refill (Sample *mixdown_buffer, float *gain_buffer);
+
+ int read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer, jack_nframes_t& start, jack_nframes_t cnt,
+ ChannelInfo& channel_info, int channel, bool reversed);
+
+ uint32_t i_am_the_modifier;
+
+ /* XXX fix this redundancy ... */
+
+ void playlist_changed (Change);
+ void playlist_modified ();
+ void playlist_deleted (Playlist*);
+ void session_controls_changed (Session::ControlType);
+
+ void finish_capture (bool rec_monitors_input);
+ void clean_up_capture (struct tm&, time_t, bool abort);
+ void transport_stopped (struct tm&, time_t, bool abort);
+
+ struct CaptureInfo {
+ uint32_t start;
+ uint32_t frames;
+ };
+
+ vector<CaptureInfo*> capture_info;
+ PBD::Lock capture_info_lock;
+
+ void init (Flag);
+
+ void init_channel (ChannelInfo &chan);
+ void destroy_channel (ChannelInfo &chan);
+
+ static jack_nframes_t disk_io_chunk_frames;
+
+ int use_new_write_source (uint32_t n=0);
+ int use_new_fade_source (uint32_t n=0);
+
+ int find_and_use_playlist (const string&);
+
+ void allocate_temporary_buffers ();
+
+ unsigned char _flags;
+
+ int create_input_port ();
+ int connect_input_port ();
+ int seek_unlocked (jack_nframes_t which_sample);
+
+ int ports_created ();
+
+ bool realtime_set_speed (float, bool global_change);
+ void non_realtime_set_speed ();
+
+ std::list<Region*> _last_capture_regions;
+ std::vector<FileSource*> capturing_sources;
+ int use_pending_capture_data (XMLNode& node);
+
+ void get_input_sources ();
+
+ void check_record_status (jack_nframes_t transport_frame, jack_nframes_t nframes, bool can_record);
+
+ void set_align_style_from_io();
+
+};
+
+}; /* namespace ARDOUR */
+
+#endif /* __ardour_diskstream_h__ */
diff --git a/libs/ardour/ardour/export.h b/libs/ardour/ardour/export.h
new file mode 100644
index 0000000000..9a6da1592b
--- /dev/null
+++ b/libs/ardour/ardour/export.h
@@ -0,0 +1,88 @@
+#ifndef __ardour_export_h__
+#define __ardour_export_h__
+
+#include <map>
+#include <vector>
+#include <string>
+
+#include <sigc++/signal.h>
+
+#include <sndfile.h>
+#include <samplerate.h>
+
+#include <ardour/ardour.h>
+#include <ardour/gdither.h>
+
+using std::map;
+using std::vector;
+using std::string;
+using std::pair;
+
+namespace ARDOUR
+{
+ class Port;
+
+ typedef pair<Port *, uint32_t> PortChannelPair;
+ typedef map<uint32_t, vector<PortChannelPair> > AudioExportPortMap;
+
+ struct AudioExportSpecification : public SF_INFO, public sigc::trackable {
+
+ AudioExportSpecification();
+ ~AudioExportSpecification ();
+
+ void init ();
+ void clear ();
+
+
+ int prepare (jack_nframes_t blocksize, jack_nframes_t frame_rate);
+
+ int process (jack_nframes_t nframes);
+
+ /* set by the user */
+
+ string path;
+ jack_nframes_t sample_rate;
+
+ int src_quality;
+ SNDFILE* out;
+ uint32_t channels;
+ AudioExportPortMap port_map;
+ jack_nframes_t start_frame;
+ jack_nframes_t end_frame;
+ GDitherType dither_type;
+ bool do_freewheel;
+
+ /* used exclusively during export */
+
+ jack_nframes_t frame_rate;
+ GDither dither;
+ float* dataF;
+ float* dataF2;
+ float* leftoverF;
+ jack_nframes_t leftover_frames;
+ jack_nframes_t max_leftover_frames;
+ void* output_data;
+ jack_nframes_t out_samples_max;
+ uint32_t sample_bytes;
+ uint32_t data_width;
+
+ jack_nframes_t total_frames;
+ SF_INFO sfinfo;
+ SRC_DATA src_data;
+ SRC_STATE* src_state;
+ jack_nframes_t pos;
+
+ sigc::connection freewheel_connection;
+
+ /* shared between UI thread and audio thread */
+
+ float progress; /* audio thread sets this */
+ bool stop; /* UI sets this */
+ bool running; /* audio thread sets to false when export is done */
+
+ int status;
+
+ };
+};
+
+#endif /* __ardour_export_h__ */
diff --git a/libs/ardour/ardour/filesource.h b/libs/ardour/ardour/filesource.h
new file mode 100644
index 0000000000..2c24d87793
--- /dev/null
+++ b/libs/ardour/ardour/filesource.h
@@ -0,0 +1,163 @@
+/*
+ Copyright (C) 2000 Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __playlist_file_buffer_h__
+#define __playlist_file_buffer_h__
+
+// darwin supports 64 by default and doesn't provide wrapper functions.
+#if defined (__APPLE__)
+typedef off_t off64_t;
+#define open64 open
+#define close64 close
+#define lseek64 lseek
+#define pread64 pread
+#define pwrite64 pwrite
+#endif
+
+#include <vector>
+#include <string>
+
+#include <ardour/source.h>
+
+struct tm;
+
+using std::string;
+
+namespace ARDOUR {
+
+class FileSource : public Source {
+ public:
+ FileSource (string path, jack_nframes_t rate, bool repair_first = false);
+ FileSource (const XMLNode&, jack_nframes_t rate);
+ ~FileSource ();
+
+ jack_nframes_t length() const { return _length; }
+ jack_nframes_t read (Sample *dst, jack_nframes_t start, jack_nframes_t cnt) const;
+ jack_nframes_t write (Sample *src, jack_nframes_t cnt);
+ void mark_for_remove();
+ string peak_path(string audio_path);
+ string old_peak_path(string audio_path);
+ string path() const { return _path; }
+
+ int update_header (jack_nframes_t when, struct tm&, time_t);
+
+ int move_to_trash (const string trash_dir_name);
+
+ static bool is_empty (string path);
+ void mark_streaming_write_completed ();
+
+ void mark_take (string);
+ string take_id() const { return _take_id; }
+
+ static void set_bwf_country_code (string x);
+ static void set_bwf_organization_code (string x);
+ static void set_bwf_serial_number (int);
+
+ static void set_search_path (string);
+
+ private:
+ int fd;
+ string _path;
+ bool remove_at_unref;
+ bool is_bwf;
+ off64_t data_offset;
+ string _take_id;
+
+ static char bwf_country_code[3];
+ static char bwf_organization_code[4];
+ static char bwf_serial_number[13];
+
+ struct GenericChunk {
+ char id[4];
+ int32_t size;
+ };
+
+ struct WAVEChunk : public GenericChunk {
+ char text[4]; /* wave pseudo-chunk id "WAVE" */
+ };
+
+ struct FMTChunk : public GenericChunk {
+ int16_t formatTag; /* format tag; currently pcm */
+ int16_t nChannels; /* number of channels */
+ uint32_t nSamplesPerSec; /* sample rate in hz */
+ int32_t nAvgBytesPerSec; /* average bytes per second */
+ int16_t nBlockAlign; /* number of bytes per sample */
+ int16_t nBitsPerSample; /* number of bits in a sample */
+ };
+
+ struct BroadcastChunk : public GenericChunk {
+ char description[256];
+ char originator[32];
+ char originator_reference[32];
+ char origination_date[10];
+ char origination_time[8];
+ int32_t time_reference_low;
+ int32_t time_reference_high;
+ int16_t version; /* 1.0 because we have umid and 190 bytes of "reserved" */
+ char umid[64];
+ char reserved[190];
+ /* we don't treat coding history as part of the struct */
+ };
+
+ struct ChunkInfo {
+ string name;
+ uint32_t size;
+ off64_t offset;
+
+ ChunkInfo (string s, uint32_t sz, off64_t o)
+ : name (s), size (sz), offset (o) {}
+ };
+
+ vector<ChunkInfo> chunk_info;
+
+ struct {
+ WAVEChunk wave;
+ FMTChunk format;
+ GenericChunk data;
+ BroadcastChunk bext;
+ vector<string> coding_history;
+ } header;
+
+ int init (string, bool must_exist, jack_nframes_t);
+ jack_nframes_t read_unlocked (Sample *dst, jack_nframes_t start, jack_nframes_t cnt) const;
+
+ int discover_chunks (bool silent);
+ ChunkInfo* lookup_chunk (string name);
+
+ int write_header ();
+ int read_header (bool silent);
+
+ int check_header (jack_nframes_t rate, bool silent);
+ int fill_header (jack_nframes_t rate);
+
+ int read_broadcast_data (ChunkInfo&);
+ void compute_header_size ();
+
+ static const int32_t wave_header_size = sizeof (WAVEChunk) + sizeof (FMTChunk) + sizeof (GenericChunk);
+ static const int32_t bwf_header_size = wave_header_size + sizeof (BroadcastChunk);
+
+ static string search_path;
+
+ int repair (string, jack_nframes_t);
+};
+
+}
+
+#endif /* __playlist_file_buffer_h__ */
diff --git a/libs/ardour/ardour/gain.h b/libs/ardour/ardour/gain.h
new file mode 100644
index 0000000000..3bd2d3be61
--- /dev/null
+++ b/libs/ardour/ardour/gain.h
@@ -0,0 +1,44 @@
+/*
+ Copyright (C) 2000 Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __ardour_gain_h__
+#define __ardour_gain_h__
+
+#include "ardour.h"
+#include "curve.h"
+
+namespace ARDOUR {
+
+struct Gain : public Curve {
+
+ Gain();
+ Gain (const Gain&);
+ Gain& operator= (const Gain&);
+
+ static void fill_linear_fade_in (Gain& curve, jack_nframes_t frames);
+ static void fill_linear_volume_fade_in (Gain& curve, jack_nframes_t frames);
+ static void fill_linear_fade_out (Gain& curve, jack_nframes_t frames);
+ static void fill_linear_volume_fade_out (Gain& curve, jack_nframes_t frames);
+
+};
+
+} /* namespace ARDOUR */
+
+#endif /* __ardour_gain_h__ */
diff --git a/libs/ardour/ardour/gdither.h b/libs/ardour/ardour/gdither.h
new file mode 100644
index 0000000000..51343b13c4
--- /dev/null
+++ b/libs/ardour/ardour/gdither.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2002 Steve Harris <steve@plugin.org.uk>
+ *
+ * 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; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id$
+ */
+
+#ifndef GDITHER_H
+#define GDITHER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "gdither_types.h"
+
+/* Create and initialise a state structure, takes a dither type, a number of
+ * channels and a bit depth as input
+ *
+ * The Dither type is one of
+ *
+ * GDitherNone - straight nearest neighbour rounding. Theres no pressing
+ * reason to do this at 8 or 16 bit, but you might want to at 24, for some
+ * reason. At the lest it will save you writing int->float conversion code,
+ * which is arder than it sounds.
+ *
+ * GDitherRect - mathematically most accurate, lowest noise floor, but not
+ * that good for audio. It is the fastest though.
+ *
+ * GDitherTri - a happy medium between Rectangular and Shaped, reasonable
+ * noise floor, not too obvious, quite fast.
+ *
+ * GDitherShaped - should have the least audible impact, but has the highest
+ * noise floor, fairly CPU intensive. Not advisible if your going to apply
+ * any frequency manipulation afterwards.
+ *
+ * channels, sets the number of channels in the output data, output data will
+ * be written interleaved into the area given to gdither_run(). Set to 1
+ * if you are not working with interleaved buffers.
+ *
+ * bit depth, sets the bit width of the output sample data, it can be one of:
+ *
+ * GDither8bit - 8 bit unsiged
+ * GDither16bit - 16 bit signed
+ * GDither32bit - 24+bits in upper bits of a 32 bit word
+ * GDitherFloat - IEEE floating point (32bits)
+ * GDitherDouble - Double precision IEEE floating point (64bits)
+ *
+ * dither_depth, set the number of bits before the signal will be truncated to,
+ * eg. 16 will produce an output stream with 16bits-worth of signal. Setting to
+ * zero or greater than the width of the output format will dither to the
+ * maximum precision allowed by the output format.
+ */
+GDither gdither_new(GDitherType type, uint32_t channels,
+
+ GDitherSize bit_depth, int dither_depth);
+
+/* Frees memory used by gdither_new.
+ */
+void gdither_free(GDither s);
+
+/* Applies dithering to the supplied signal.
+ *
+ * channel is the channel number you are processing (0 - channles-1), length is
+ * the length of the input, in samples, x is the input samples (float), y is
+ * where the output samples will be written, it should have the approaprate
+ * type for the chosen bit depth
+ */
+void gdither_runf(GDither s, uint32_t channel, uint32_t length,
+ float *x, void *y);
+
+/* see gdither_runf, vut input argument is double format */
+void gdither_run(GDither s, uint32_t channel, uint32_t length,
+ double *x, void *y);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/ardour/ardour/gdither_types.h b/libs/ardour/ardour/gdither_types.h
new file mode 100644
index 0000000000..46feb55fbc
--- /dev/null
+++ b/libs/ardour/ardour/gdither_types.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2002 Steve Harris <steve@plugin.org.uk>
+ *
+ * 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; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id$
+ */
+
+#ifndef GDITHER_TYPES_H
+#define GDITHER_TYPES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ GDitherNone = 0,
+ GDitherRect,
+ GDitherTri,
+ GDitherShaped
+} GDitherType;
+
+typedef enum {
+ GDither8bit = 8,
+ GDither16bit = 16,
+ GDither32bit = 32,
+ GDitherFloat = 25,
+ GDitherDouble = 54
+} GDitherSize;
+
+typedef void *GDither;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/ardour/ardour/gdither_types_internal.h b/libs/ardour/ardour/gdither_types_internal.h
new file mode 100644
index 0000000000..55d5792833
--- /dev/null
+++ b/libs/ardour/ardour/gdither_types_internal.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2002 Steve Harris <steve@plugin.org.uk>
+ *
+ * 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; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id$
+ */
+
+#ifndef GDITHER_TYPES_H
+#define GDITHER_TYPES_H
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define GDITHER_SH_BUF_SIZE 8
+#define GDITHER_SH_BUF_MASK 7
+
+/* this must agree with whats in gdither_types.h */
+typedef enum {
+ GDitherNone = 0,
+ GDitherRect,
+ GDitherTri,
+ GDitherShaped
+} GDitherType;
+
+typedef enum {
+ GDither8bit = 8,
+ GDither16bit = 16,
+ GDither32bit = 32,
+ GDitherFloat = 25,
+ GDitherDouble = 54
+} GDitherSize;
+
+typedef struct {
+ uint32_t phase;
+ float buffer[GDITHER_SH_BUF_SIZE];
+} GDitherShapedState;
+
+typedef struct GDither_s {
+ GDitherType type;
+ uint32_t channels;
+ uint32_t bit_depth;
+ uint32_t dither_depth;
+ float scale;
+ uint32_t post_scale;
+ float post_scale_fp;
+ float bias;
+
+ int clamp_u;
+
+ int clamp_l;
+ float *tri_state;
+ GDitherShapedState *shaped_state;
+} *GDither;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/ardour/ardour/history.h b/libs/ardour/ardour/history.h
new file mode 100644
index 0000000000..91a89d5ac2
--- /dev/null
+++ b/libs/ardour/ardour/history.h
@@ -0,0 +1,153 @@
+/*
+ Copyright (C) 2001 Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __ardour_history_h__
+#define __ardour_history_h__
+
+#include <list>
+#include <sigc++/signal.h>
+
+template<class T>
+//struct History : public SigC::Object
+struct History : public sigc::trackable
+{
+ typedef list<T *> StateList;
+
+ StateList states;
+ StateList::iterator current;
+
+ History() { current = states.end(); }
+ ~History() { states.erase (states.begin(), states.end()); }
+
+ sigc::signal<void> CurrentChanged;
+
+ void clear () {
+ for (StateList::iterator i = states.begin(); i != states.end(); i++) {
+ delete *i;
+ }
+ states.clear ();
+ current = states.end();
+ CurrentChanged();
+ }
+
+ void push (T *state) {
+ /* remove any "undone" history above the current location
+ in the history, before pushing new state.
+ */
+ if (current != states.begin() && current != states.end()) {
+ states.erase (states.begin(), current);
+ }
+ current = states.insert (states.begin(), state);
+ CurrentChanged ();
+ }
+
+ T *top() {
+ if (current != states.end()) {
+ return *current;
+ } else {
+ return 0;
+ }
+ }
+
+ T *pop (bool remove) {
+ if (current == states.end()) {
+ return 0;
+ }
+
+ if (current == states.begin()) {
+ return *current;
+ }
+
+ current--;
+ T *state = *current;
+
+ if (remove) {
+ states.erase (current);
+ }
+
+ CurrentChanged ();
+ return state;
+ }
+
+ T *earlier (uint32_t n) {
+ StateList::iterator i;
+
+ if (current == states.end()) {
+ return 0;
+ }
+
+ if (n == 0) {
+ return *current;
+ }
+
+ /* the list is in LIFO order, so move toward the end to go "earlier" */
+
+ for (i = current; n && i != states.end(); i++, n--);
+
+ if (i == states.end()) {
+ return 0;
+ } else {
+ current = i;
+ CurrentChanged ();
+ return *i;
+ }
+ }
+
+ T *later (uint32_t n) {
+ StateList::iterator i;
+
+ if (current == states.end()) {
+ return 0;
+ }
+
+ if (n == 0) {
+ return *current;
+ }
+
+ /* the list is in LIFO order, so move toward the beginning to go "later" */
+
+ for (i = current; n && i != states.begin(); i--, n--);
+ if (i != current) {
+ current = i;
+ CurrentChanged();
+ }
+ return *i;
+ }
+
+ T *nth (uint32_t n) {
+ StateList::iterator i;
+
+ for (i = states.begin(); n && i != states.end(); n--, i++);
+
+ if (i != states.end()) {
+ if (i != current) {
+ current = i;
+ CurrentChanged ();
+ }
+ return *i;
+ } else {
+ return 0;
+ }
+ }
+
+};
+
+#endif /* __ardour_history_h__ */
+
diff --git a/libs/ardour/ardour/insert.h b/libs/ardour/ardour/insert.h
new file mode 100644
index 0000000000..803e16497d
--- /dev/null
+++ b/libs/ardour/ardour/insert.h
@@ -0,0 +1,183 @@
+/*
+ Copyright (C) 2000 Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __ardour_insert_h__
+#define __ardour_insert_h__
+
+#include <vector>
+#include <string>
+#include <exception>
+
+#include <sigc++/signal.h>
+#include <ardour/ardour.h>
+#include <ardour/redirect.h>
+#include <ardour/plugin_state.h>
+
+class XMLNode;
+
+namespace MIDI {
+ class Port;
+}
+
+namespace ARDOUR {
+
+class Session;
+class Plugin;
+class Route;
+
+class Insert : public Redirect
+{
+ public:
+ Insert(Session& s, Placement p);
+ Insert(Session& s, string name, Placement p);
+
+ Insert(Session& s, Placement p, int imin, int imax, int omin, int omax);
+
+ virtual ~Insert() { }
+
+ virtual void run (vector<Sample *>& bufs, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset) = 0;
+ virtual void activate () {}
+ virtual void deactivate () {}
+
+ virtual int32_t can_support_input_configuration (int32_t in) const = 0;
+ virtual int32_t configure_io (int32_t magic, int32_t in, int32_t out) = 0;
+ virtual int32_t compute_output_streams (int32_t cnt) const = 0;
+};
+
+class PortInsert : public Insert
+{
+ public:
+ PortInsert (Session&, Placement);
+ PortInsert (Session&, const XMLNode&);
+ PortInsert (const PortInsert&);
+ ~PortInsert ();
+
+ XMLNode& state(bool full);
+ XMLNode& get_state(void);
+ int set_state(const XMLNode&);
+
+ void init ();
+ void run (vector<Sample *>& bufs, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset);
+
+ jack_nframes_t latency();
+
+ uint32_t output_streams() const;
+ uint32_t input_streams() const;
+
+ int32_t can_support_input_configuration (int32_t) const;
+ int32_t configure_io (int32_t magic, int32_t in, int32_t out);
+ int32_t compute_output_streams (int32_t cnt) const;
+};
+
+struct PluginInsertState : public RedirectState
+{
+ PluginInsertState (std::string why)
+ : RedirectState (why) {}
+ ~PluginInsertState() {}
+
+ PluginState plugin_state;
+};
+
+class PluginInsert : public Insert
+{
+ public:
+ PluginInsert (Session&, Plugin&, Placement);
+ PluginInsert (Session&, const XMLNode&);
+ PluginInsert (const PluginInsert&);
+ ~PluginInsert ();
+
+ static const string port_automation_node_name;
+
+ XMLNode& state(bool);
+ XMLNode& get_state(void);
+ int set_state(const XMLNode&);
+
+ StateManager::State* state_factory (std::string why) const;
+ Change restore_state (StateManager::State&);
+
+ void run (vector<Sample *>& bufs, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset);
+ void silence (jack_nframes_t nframes, jack_nframes_t offset);
+ void activate ();
+ void deactivate ();
+
+ void set_block_size (jack_nframes_t nframes);
+
+ uint32_t output_streams() const;
+ uint32_t input_streams() const;
+ uint32_t natural_output_streams() const;
+ uint32_t natural_input_streams() const;
+
+ int set_count (uint32_t num);
+ uint32_t get_count () const { return _plugins.size(); }
+
+ int32_t can_support_input_configuration (int32_t) const;
+ int32_t configure_io (int32_t magic, int32_t in, int32_t out);
+ int32_t compute_output_streams (int32_t cnt) const;
+
+ bool is_generator() const;
+
+ void reset_midi_control (MIDI::Port*, bool);
+ void send_all_midi_feedback ();
+
+ void set_parameter (uint32_t port, float val);
+
+ AutoState get_port_automation_state (uint32_t port);
+ void set_port_automation_state (uint32_t port, AutoState);
+ void protect_automation ();
+
+ float default_parameter_value (uint32_t which);
+
+ Plugin& plugin(uint32_t num=0) const {
+ if (num < _plugins.size()) {
+ return *_plugins[num];
+ } else {
+ return *_plugins[0]; // we always have one
+ }
+ }
+
+ string describe_parameter (uint32_t);
+
+ jack_nframes_t latency();
+
+ void transport_stopped (jack_nframes_t now);
+ void automation_snapshot (jack_nframes_t now);
+
+ protected:
+ void store_state (PluginInsertState&) const;
+
+ private:
+
+ void parameter_changed (uint32_t, float);
+
+ vector<Plugin*> _plugins;
+ void automation_run (vector<Sample *>& bufs, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset);
+ void connect_and_run (vector<Sample *>& bufs, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset, bool with_auto, jack_nframes_t now = 0);
+
+ void init ();
+ void set_automatable ();
+ void auto_state_changed (uint32_t which);
+ void automation_list_creation_callback (uint32_t, AutomationList&);
+
+ Plugin* plugin_factory (Plugin&);
+};
+
+}; /* namespace ARDOUR */
+
+#endif /* __ardour_insert_h__ */
diff --git a/libs/ardour/ardour/io.h b/libs/ardour/ardour/io.h
new file mode 100644
index 0000000000..c67473dcc0
--- /dev/null
+++ b/libs/ardour/ardour/io.h
@@ -0,0 +1,408 @@
+/*
+ Copyright (C) 2000 Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __ardour_io_h__
+#define __ardour_io_h__
+
+#include <string>
+#include <vector>
+#include <cmath>
+#include <sigc++/signal.h>
+#include <jack/jack.h>
+
+#include <pbd/lockmonitor.h>
+#include <pbd/fastlog.h>
+#include <pbd/undo.h>
+#include <pbd/atomic.h>
+#include <midi++/controllable.h>
+
+#include <ardour/ardour.h>
+#include <ardour/stateful.h>
+#include <ardour/utils.h>
+#include <ardour/state_manager.h>
+#include <ardour/curve.h>
+
+using std::string;
+using std::vector;
+
+class XMLNode;
+
+namespace ARDOUR {
+
+class Session;
+class AudioEngine;
+class Port;
+class Connection;
+class Panner;
+
+class IO : public Stateful, public ARDOUR::StateManager
+{
+
+ public:
+ static const string state_node_name;
+
+ IO (Session&, string name,
+ int input_min = -1, int input_max = -1,
+ int output_min = -1, int output_max = -1);
+
+ virtual ~IO();
+
+ int input_minimum() const { return _input_minimum; }
+ int input_maximum() const { return _input_maximum; }
+ int output_minimum() const { return _output_minimum; }
+ int output_maximum() const { return _output_maximum; }
+
+ void set_input_minimum (int n);
+ void set_input_maximum (int n);
+ void set_output_minimum (int n);
+ void set_output_maximum (int n);
+
+ const string& name() const { return _name; }
+ virtual int set_name (string str, void *src);
+
+ virtual void silence (jack_nframes_t, jack_nframes_t offset);
+
+ void pan (vector<Sample*>& bufs, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset, gain_t gain_coeff);
+ void pan_automated (vector<Sample*>& bufs, uint32_t nbufs, jack_nframes_t start_frame, jack_nframes_t end_frame,
+ jack_nframes_t nframes, jack_nframes_t offset);
+ void collect_input (vector<Sample*>&, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset);
+ void deliver_output (vector<Sample *>&, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset);
+ void deliver_output_no_pan (vector<Sample *>&, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset);
+ void just_meter_input (jack_nframes_t start_frame, jack_nframes_t end_frame,
+ jack_nframes_t nframes, jack_nframes_t offset);
+
+ virtual uint32_t n_process_buffers () { return 0; }
+
+ virtual void set_gain (gain_t g, void *src);
+ void inc_gain (gain_t delta, void *src);
+ gain_t gain () const { return _desired_gain; }
+ virtual gain_t effective_gain () const;
+
+ Panner& panner() { return *_panner; }
+
+ int ensure_io (uint32_t, uint32_t, bool clear, void *src);
+
+ int use_input_connection (Connection&, void *src);
+ int use_output_connection (Connection&, void *src);
+
+ Connection *input_connection() const { return _input_connection; }
+ Connection *output_connection() const { return _output_connection; }
+
+ int add_input_port (string source, void *src);
+ int add_output_port (string destination, void *src);
+
+ int remove_input_port (Port *, void *src);
+ int remove_output_port (Port *, void *src);
+
+ int set_input (Port *, void *src);
+
+ int connect_input (Port *our_port, string other_port, void *src);
+ int connect_output (Port *our_port, string other_port, void *src);
+
+ int disconnect_input (Port *our_port, string other_port, void *src);
+ int disconnect_output (Port *our_port, string other_port, void *src);
+
+ int disconnect_inputs (void *src);
+ int disconnect_outputs (void *src);
+
+ jack_nframes_t output_latency() const;
+ jack_nframes_t input_latency() const;
+ void set_port_latency (jack_nframes_t);
+
+ Port *output (uint32_t n) const {
+ if (n < _noutputs) {
+ return _outputs[n];
+ } else {
+ return 0;
+ }
+ }
+
+ Port *input (uint32_t n) const {
+ if (n < _ninputs) {
+ return _inputs[n];
+ } else {
+ return 0;
+ }
+ }
+
+ uint32_t n_inputs () const { return _ninputs; }
+ uint32_t n_outputs () const { return _noutputs; }
+
+ sigc::signal<void,IOChange,void*> input_changed;
+ sigc::signal<void,IOChange,void*> output_changed;
+
+ sigc::signal<void,void*> gain_changed;
+ sigc::signal<void,void*> name_changed;
+
+ virtual XMLNode& state (bool full);
+ XMLNode& get_state (void);
+ int set_state (const XMLNode&);
+
+ virtual UndoAction get_memento() const;
+
+
+ static int disable_connecting (void);
+
+ static int enable_connecting (void);
+
+ static int disable_ports (void);
+
+ static int enable_ports (void);
+
+ static int disable_panners (void);
+
+ static int reset_panners (void);
+
+ static sigc::signal<int> PortsLegal;
+ static sigc::signal<int> PannersLegal;
+ static sigc::signal<int> ConnectingLegal;
+ static sigc::signal<void,uint32_t> MoreOutputs;
+ static sigc::signal<int> PortsCreated;
+
+ /* MIDI control */
+
+ void set_midi_to_gain_function (gain_t (*function)(double val)) {
+ _midi_gain_control.midi_to_gain = function;
+ }
+
+ void set_gain_to_midi_function (double (*function)(gain_t gain)) {
+ _midi_gain_control.gain_to_midi = function;
+ }
+
+ MIDI::Controllable& midi_gain_control() {
+ return _midi_gain_control;
+ }
+
+ virtual void reset_midi_control (MIDI::Port*, bool on);
+
+ virtual void send_all_midi_feedback ();
+ virtual MIDI::byte* write_midi_feedback (MIDI::byte*, int32_t& bufsize);
+
+ /* Peak metering */
+
+ float peak_input_power (uint32_t n) {
+ if (n < std::max(_ninputs, _noutputs)) {
+ float x = _stored_peak_power[n];
+ if(x > 0.0) {
+ return 20 * fast_log10(x);
+ } else {
+ return minus_infinity();
+ }
+ } else {
+ return minus_infinity();
+ }
+ }
+
+ static sigc::signal<void> GrabPeakPower;
+
+ /* automation */
+
+ void clear_automation ();
+
+ bool gain_automation_recording() const {
+ return (_gain_automation_curve.automation_state() & (Write|Touch));
+ }
+
+ bool gain_automation_playback() const {
+ return (_gain_automation_curve.automation_state() & Play) ||
+ ((_gain_automation_curve.automation_state() & Touch) &&
+ !_gain_automation_curve.touching());
+ }
+
+ virtual void set_gain_automation_state (AutoState);
+ AutoState gain_automation_state() const { return _gain_automation_curve.automation_state(); }
+ sigc::signal<void> gain_automation_state_changed;
+
+ virtual void set_gain_automation_style (AutoStyle);
+ AutoStyle gain_automation_style () const { return _gain_automation_curve.automation_style(); }
+ sigc::signal<void> gain_automation_style_changed;
+
+ static void set_automation_interval (jack_nframes_t frames) {
+ _automation_interval = frames;
+ }
+
+ static jack_nframes_t automation_interval() {
+ return _automation_interval;
+ }
+
+ virtual void transport_stopped (jack_nframes_t now);
+ virtual void automation_snapshot (jack_nframes_t now);
+
+ ARDOUR::Curve& gain_automation_curve () { return _gain_automation_curve; }
+
+ void start_gain_touch ();
+ void end_gain_touch ();
+
+ void start_pan_touch (uint32_t which);
+ void end_pan_touch (uint32_t which);
+
+ id_t id() const { return _id; }
+
+ void defer_pan_reset ();
+ void allow_pan_reset ();
+
+ /* the session calls this for master outs before
+ anyone else. controls outs too, at some point.
+ */
+
+ XMLNode *pending_state_node;
+ int ports_became_legal ();
+
+ private:
+ mutable PBD::Lock io_lock;
+
+ protected:
+ Session& _session;
+ Panner* _panner;
+ gain_t _gain;
+ gain_t _effective_gain;
+ gain_t _desired_gain;
+ PBD::NonBlockingLock declick_lock;
+ vector<Port*> _outputs;
+ vector<Port*> _inputs;
+ vector<float> _peak_power;
+ vector<float> _stored_peak_power;
+ string _name;
+ Connection* _input_connection;
+ Connection* _output_connection;
+ id_t _id;
+ bool no_panner_reset;
+ XMLNode* deferred_state;
+
+ virtual void set_deferred_state() {}
+
+ void reset_peak_meters();
+ void reset_panner ();
+
+ virtual uint32_t pans_required() const { return _ninputs; }
+
+ static void apply_declick (vector<Sample*>&, uint32_t nbufs, jack_nframes_t nframes,
+ gain_t initial, gain_t target, bool invert_polarity);
+
+ struct MIDIGainControl : public MIDI::Controllable {
+ MIDIGainControl (IO&, MIDI::Port *);
+ void set_value (float);
+
+ void send_feedback (gain_t);
+ MIDI::byte* write_feedback (MIDI::byte* buf, int32_t& bufsize, gain_t val, bool force = false);
+
+ IO& io;
+ bool setting;
+ MIDI::byte last_written;
+
+ gain_t (*midi_to_gain) (double val);
+ double (*gain_to_midi) (gain_t gain);
+ };
+
+ MIDIGainControl _midi_gain_control;
+
+ /* state management */
+
+ Change restore_state (State&);
+ StateManager::State* state_factory (std::string why) const;
+ void send_state_changed();
+
+ bool get_midi_node_info (XMLNode * node, MIDI::eventType & ev, MIDI::channel_t & chan, MIDI::byte & additional);
+ bool set_midi_node_info (XMLNode * node, MIDI::eventType ev, MIDI::channel_t chan, MIDI::byte additional);
+
+ /* automation */
+
+ jack_nframes_t last_automation_snapshot;
+ static jack_nframes_t _automation_interval;
+
+ AutoState _gain_automation_state;
+ AutoStyle _gain_automation_style;
+
+ bool apply_gain_automation;
+ Curve _gain_automation_curve;
+
+ int save_automation (const string&);
+ int load_automation (const string&);
+
+ PBD::NonBlockingLock automation_lock;
+
+ /* AudioTrack::deprecated_use_diskstream_connections() needs these */
+
+ int set_inputs (const string& str);
+ int set_outputs (const string& str);
+
+ static bool connecting_legal;
+ static bool ports_legal;
+
+ private:
+
+ uint32_t _ninputs;
+ uint32_t _noutputs;
+
+ /* are these the best variable names ever, or what? */
+
+ sigc::connection input_connection_configuration_connection;
+ sigc::connection output_connection_configuration_connection;
+ sigc::connection input_connection_connection_connection;
+ sigc::connection output_connection_connection_connection;
+
+ static bool panners_legal;
+
+ int connecting_became_legal ();
+ int panners_became_legal ();
+ sigc::connection connection_legal_c;
+ sigc::connection port_legal_c;
+ sigc::connection panner_legal_c;
+
+ int _input_minimum;
+ int _input_maximum;
+ int _output_minimum;
+ int _output_maximum;
+
+
+ static int parse_io_string (const string&, vector<string>& chns);
+
+ static int parse_gain_string (const string&, vector<string>& chns);
+
+ int set_sources (vector<string>&, void *src, bool add);
+ int set_destinations (vector<string>&, void *src, bool add);
+
+ int ensure_inputs (uint32_t, bool clear, bool lockit, void *src);
+ int ensure_outputs (uint32_t, bool clear, bool lockit, void *src);
+
+ void drop_input_connection ();
+ void drop_output_connection ();
+
+ void input_connection_configuration_changed ();
+ void input_connection_connection_changed (int);
+ void output_connection_configuration_changed ();
+ void output_connection_connection_changed (int);
+
+ int create_ports (const XMLNode&);
+ int make_connections (const XMLNode&);
+
+ void setup_peak_meters ();
+ void grab_peak_power ();
+
+ bool ensure_inputs_locked (uint32_t, bool clear, void *src);
+ bool ensure_outputs_locked (uint32_t, bool clear, void *src);
+
+ int32_t find_input_port_hole ();
+ int32_t find_output_port_hole ();
+};
+
+}; /* namespace ARDOUR */
+
+#endif /*__ardour_io_h__ */
diff --git a/libs/ardour/ardour/ladspa.h b/libs/ardour/ardour/ladspa.h
new file mode 100644
index 0000000000..e552f35bb5
--- /dev/null
+++ b/libs/ardour/ardour/ladspa.h
@@ -0,0 +1,606 @@
+/* ladspa.h
+
+ Linux Audio Developer's Simple Plugin API Version 1.1[LGPL].
+ Copyright (C) 2000-2002 Richard W.E. Furse, Paul Barton-Davis,
+ Stefan Westerfeld.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License
+ as published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA. */
+
+#ifndef LADSPA_INCLUDED
+#define LADSPA_INCLUDED
+
+#define LADSPA_VERSION "1.1"
+#define LADSPA_VERSION_MAJOR 1
+#define LADSPA_VERSION_MINOR 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*****************************************************************************/
+
+/* Overview:
+
+ There is a large number of synthesis packages in use or development
+ on the Linux platform at this time. This API (`The Linux Audio
+ Developer's Simple Plugin API') attempts to give programmers the
+ ability to write simple `plugin' audio processors in C/C++ and link
+ them dynamically (`plug') into a range of these packages (`hosts').
+ It should be possible for any host and any plugin to communicate
+ completely through this interface.
+
+ This API is deliberately short and simple. To achieve compatibility
+ with a range of promising Linux sound synthesis packages it
+ attempts to find the `greatest common divisor' in their logical
+ behaviour. Having said this, certain limiting decisions are
+ implicit, notably the use of a fixed type (LADSPA_Data) for all
+ data transfer and absence of a parameterised `initialisation'
+ phase. See below for the LADSPA_Data typedef.
+
+ Plugins are expected to distinguish between control and audio
+ data. Plugins have `ports' that are inputs or outputs for audio or
+ control data and each plugin is `run' for a `block' corresponding
+ to a short time interval measured in samples. Audio data is
+ communicated using arrays of LADSPA_Data, allowing a block of audio
+ to be processed by the plugin in a single pass. Control data is
+ communicated using single LADSPA_Data values. Control data has a
+ single value at the start of a call to the `run()' or `run_adding()'
+ function, and may be considered to remain this value for its
+ duration. The plugin may assume that all its input and output ports
+ have been connected to the relevant data location (see the
+ `connect_port()' function below) before it is asked to run.
+
+ Plugins will reside in shared object files suitable for dynamic
+ linking by dlopen() and family. The file will provide a number of
+ `plugin types' that can be used to instantiate actual plugins
+ (sometimes known as `plugin instances') that can be connected
+ together to perform tasks.
+
+ This API contains very limited error-handling. */
+
+/*****************************************************************************/
+
+/* Fundamental data type passed in and out of plugin. This data type
+ is used to communicate audio samples and control values. It is
+ assumed that the plugin will work sensibly given any numeric input
+ value although it may have a preferred range (see hints below).
+
+ For audio it is generally assumed that 1.0f is the `0dB' reference
+ amplitude and is a `normal' signal level. */
+
+typedef float LADSPA_Data;
+
+/*****************************************************************************/
+
+/* Special Plugin Properties:
+
+ Optional features of the plugin type are encapsulated in the
+ LADSPA_Properties type. This is assembled by ORing individual
+ properties together. */
+
+
+typedef int LADSPA_Properties;
+
+/* Property LADSPA_PROPERTY_REALTIME indicates that the plugin has a
+ real-time dependency (e.g. listens to a MIDI device) and so its
+ output must not be cached or subject to significant latency. */
+#define LADSPA_PROPERTY_REALTIME 0x1
+
+/* Property LADSPA_PROPERTY_INPLACE_BROKEN indicates that the plugin
+ may cease to work correctly if the host elects to use the same data
+ location for both input and output (see connect_port()). This
+ should be avoided as enabling this flag makes it impossible for
+ hosts to use the plugin to process audio `in-place.' */
+#define LADSPA_PROPERTY_INPLACE_BROKEN 0x2
+
+/* Property LADSPA_PROPERTY_HARD_RT_CAPABLE indicates that the plugin
+ is capable of running not only in a conventional host but also in a
+ `hard real-time' environment. To qualify for this the plugin must
+ satisfy all of the following:
+
+ (1) The plugin must not use malloc(), free() or other heap memory
+ management within its run() or run_adding() functions. All new
+ memory used in run() must be managed via the stack. These
+ restrictions only apply to the run() function.
+
+ (2) The plugin will not attempt to make use of any library
+ functions with the exceptions of functions in the ANSI standard C
+ and C maths libraries, which the host is expected to provide.
+
+ (3) The plugin will not access files, devices, pipes, sockets, IPC
+ or any other mechanism that might result in process or thread
+ blocking.
+
+ (4) The plugin will take an amount of time to execute a run() or
+ run_adding() call approximately of form (A+B*SampleCount) where A
+ and B depend on the machine and host in use. This amount of time
+ may not depend on input signals or plugin state. The host is left
+ the responsibility to perform timings to estimate upper bounds for
+ A and B. */
+#define LADSPA_PROPERTY_HARD_RT_CAPABLE 0x4
+
+#define LADSPA_IS_REALTIME(x) ((x) & LADSPA_PROPERTY_REALTIME)
+#define LADSPA_IS_INPLACE_BROKEN(x) ((x) & LADSPA_PROPERTY_INPLACE_BROKEN)
+#define LADSPA_IS_HARD_RT_CAPABLE(x) ((x) & LADSPA_PROPERTY_HARD_RT_CAPABLE)
+
+/*****************************************************************************/
+
+/* Plugin Ports:
+
+ Plugins have `ports' that are inputs or outputs for audio or
+ data. Ports can communicate arrays of LADSPA_Data (for audio
+ inputs/outputs) or single LADSPA_Data values (for control
+ input/outputs). This information is encapsulated in the
+ LADSPA_PortDescriptor type which is assembled by ORing individual
+ properties together.
+
+ Note that a port must be an input or an output port but not both
+ and that a port must be a control or audio port but not both. */
+
+
+typedef int LADSPA_PortDescriptor;
+
+/* Property LADSPA_PORT_INPUT indicates that the port is an input. */
+#define LADSPA_PORT_INPUT 0x1
+
+/* Property LADSPA_PORT_OUTPUT indicates that the port is an output. */
+#define LADSPA_PORT_OUTPUT 0x2
+
+/* Property LADSPA_PORT_CONTROL indicates that the port is a control
+ port. */
+#define LADSPA_PORT_CONTROL 0x4
+
+/* Property LADSPA_PORT_AUDIO indicates that the port is a audio
+ port. */
+#define LADSPA_PORT_AUDIO 0x8
+
+#define LADSPA_IS_PORT_INPUT(x) ((x) & LADSPA_PORT_INPUT)
+#define LADSPA_IS_PORT_OUTPUT(x) ((x) & LADSPA_PORT_OUTPUT)
+#define LADSPA_IS_PORT_CONTROL(x) ((x) & LADSPA_PORT_CONTROL)
+#define LADSPA_IS_PORT_AUDIO(x) ((x) & LADSPA_PORT_AUDIO)
+
+/*****************************************************************************/
+
+/* Plugin Port Range Hints:
+
+ The host may wish to provide a representation of data entering or
+ leaving a plugin (e.g. to generate a GUI automatically). To make
+ this more meaningful, the plugin should provide `hints' to the host
+ describing the usual values taken by the data.
+
+ Note that these are only hints. The host may ignore them and the
+ plugin must not assume that data supplied to it is meaningful. If
+ the plugin receives invalid input data it is expected to continue
+ to run without failure and, where possible, produce a sensible
+ output (e.g. a high-pass filter given a negative cutoff frequency
+ might switch to an all-pass mode).
+
+ Hints are meaningful for all input and output ports but hints for
+ input control ports are expected to be particularly useful.
+
+ More hint information is encapsulated in the
+ LADSPA_PortRangeHintDescriptor type which is assembled by ORing
+ individual hint types together. Hints may require further
+ LowerBound and UpperBound information.
+
+ All the hint information for a particular port is aggregated in the
+ LADSPA_PortRangeHint structure. */
+
+
+typedef int LADSPA_PortRangeHintDescriptor;
+
+/* Hint LADSPA_HINT_BOUNDED_BELOW indicates that the LowerBound field
+ of the LADSPA_PortRangeHint should be considered meaningful. The
+ value in this field should be considered the (inclusive) lower
+ bound of the valid range. If LADSPA_HINT_SAMPLE_RATE is also
+ specified then the value of LowerBound should be multiplied by the
+ sample rate. */
+#define LADSPA_HINT_BOUNDED_BELOW 0x1
+
+/* Hint LADSPA_HINT_BOUNDED_ABOVE indicates that the UpperBound field
+ of the LADSPA_PortRangeHint should be considered meaningful. The
+ value in this field should be considered the (inclusive) upper
+ bound of the valid range. If LADSPA_HINT_SAMPLE_RATE is also
+ specified then the value of UpperBound should be multiplied by the
+ sample rate. */
+#define LADSPA_HINT_BOUNDED_ABOVE 0x2
+
+/* Hint LADSPA_HINT_TOGGLED indicates that the data item should be
+ considered a Boolean toggle. Data less than or equal to zero should
+ be considered `off' or `false,' and data above zero should be
+ considered `on' or `true.' LADSPA_HINT_TOGGLED may not be used in
+ conjunction with any other hint except LADSPA_HINT_DEFAULT_0 or
+ LADSPA_HINT_DEFAULT_1. */
+#define LADSPA_HINT_TOGGLED 0x4
+
+/* Hint LADSPA_HINT_SAMPLE_RATE indicates that any bounds specified
+ should be interpreted as multiples of the sample rate. For
+ instance, a frequency range from 0Hz to the Nyquist frequency (half
+ the sample rate) could be requested by this hint in conjunction
+ with LowerBound = 0 and UpperBound = 0.5. Hosts that support bounds
+ at all must support this hint to retain meaning. */
+#define LADSPA_HINT_SAMPLE_RATE 0x8
+
+/* Hint LADSPA_HINT_LOGARITHMIC indicates that it is likely that the
+ user will find it more intuitive to view values using a logarithmic
+ scale. This is particularly useful for frequencies and gains. */
+#define LADSPA_HINT_LOGARITHMIC 0x10
+
+/* Hint LADSPA_HINT_INTEGER indicates that a user interface would
+ probably wish to provide a stepped control taking only integer
+ values. Any bounds set should be slightly wider than the actual
+ integer range required to avoid floating point rounding errors. For
+ instance, the integer set {0,1,2,3} might be described as [-0.1,
+ 3.1]. */
+#define LADSPA_HINT_INTEGER 0x20
+
+/* The various LADSPA_HINT_HAS_DEFAULT_* hints indicate a `normal'
+ value for the port that is sensible as a default. For instance,
+ this value is suitable for use as an initial value in a user
+ interface or as a value the host might assign to a control port
+ when the user has not provided one. Defaults are encoded using a
+ mask so only one default may be specified for a port. Some of the
+ hints make use of lower and upper bounds, in which case the
+ relevant bound or bounds must be available and
+ LADSPA_HINT_SAMPLE_RATE must be applied as usual. The resulting
+ default must be rounded if LADSPA_HINT_INTEGER is present. Default
+ values were introduced in LADSPA v1.1. */
+#define LADSPA_HINT_DEFAULT_MASK 0x3C0
+
+/* This default values indicates that no default is provided. */
+#define LADSPA_HINT_DEFAULT_NONE 0x0
+
+/* This default hint indicates that the suggested lower bound for the
+ port should be used. */
+#define LADSPA_HINT_DEFAULT_MINIMUM 0x40
+
+/* This default hint indicates that a low value between the suggested
+ lower and upper bounds should be chosen. For ports with
+ LADSPA_HINT_LOGARITHMIC, this should be exp(log(lower) * 0.75 +
+ log(upper) * 0.25). Otherwise, this should be (lower * 0.75 + upper
+ * 0.25). */
+#define LADSPA_HINT_DEFAULT_LOW 0x80
+
+/* This default hint indicates that a middle value between the
+ suggested lower and upper bounds should be chosen. For ports with
+ LADSPA_HINT_LOGARITHMIC, this should be exp(log(lower) * 0.5 +
+ log(upper) * 0.5). Otherwise, this should be (lower * 0.5 + upper *
+ 0.5). */
+#define LADSPA_HINT_DEFAULT_MIDDLE 0xC0
+
+/* This default hint indicates that a high value between the suggested
+ lower and upper bounds should be chosen. For ports with
+ LADSPA_HINT_LOGARITHMIC, this should be exp(log(lower) * 0.25 +
+ log(upper) * 0.75). Otherwise, this should be (lower * 0.25 + upper
+ * 0.75). */
+#define LADSPA_HINT_DEFAULT_HIGH 0x100
+
+/* This default hint indicates that the suggested upper bound for the
+ port should be used. */
+#define LADSPA_HINT_DEFAULT_MAXIMUM 0x140
+
+/* This default hint indicates that the number 0 should be used. Note
+ that this default may be used in conjunction with
+ LADSPA_HINT_TOGGLED. */
+#define LADSPA_HINT_DEFAULT_0 0x200
+
+/* This default hint indicates that the number 1 should be used. Note
+ that this default may be used in conjunction with
+ LADSPA_HINT_TOGGLED. */
+#define LADSPA_HINT_DEFAULT_1 0x240
+
+/* This default hint indicates that the number 100 should be used. */
+#define LADSPA_HINT_DEFAULT_100 0x280
+
+/* This default hint indicates that the Hz frequency of `concert A'
+ should be used. This will be 440 unless the host uses an unusual
+ tuning convention, in which case it may be within a few Hz. */
+#define LADSPA_HINT_DEFAULT_440 0x2C0
+
+#define LADSPA_IS_HINT_BOUNDED_BELOW(x) ((x) & LADSPA_HINT_BOUNDED_BELOW)
+#define LADSPA_IS_HINT_BOUNDED_ABOVE(x) ((x) & LADSPA_HINT_BOUNDED_ABOVE)
+#define LADSPA_IS_HINT_TOGGLED(x) ((x) & LADSPA_HINT_TOGGLED)
+#define LADSPA_IS_HINT_SAMPLE_RATE(x) ((x) & LADSPA_HINT_SAMPLE_RATE)
+#define LADSPA_IS_HINT_LOGARITHMIC(x) ((x) & LADSPA_HINT_LOGARITHMIC)
+#define LADSPA_IS_HINT_INTEGER(x) ((x) & LADSPA_HINT_INTEGER)
+
+#define LADSPA_IS_HINT_HAS_DEFAULT(x) ((x) & LADSPA_HINT_DEFAULT_MASK)
+#define LADSPA_IS_HINT_DEFAULT_MINIMUM(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \
+ == LADSPA_HINT_DEFAULT_MINIMUM)
+#define LADSPA_IS_HINT_DEFAULT_LOW(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \
+ == LADSPA_HINT_DEFAULT_LOW)
+#define LADSPA_IS_HINT_DEFAULT_MIDDLE(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \
+ == LADSPA_HINT_DEFAULT_MIDDLE)
+#define LADSPA_IS_HINT_DEFAULT_HIGH(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \
+ == LADSPA_HINT_DEFAULT_HIGH)
+#define LADSPA_IS_HINT_DEFAULT_MAXIMUM(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \
+ == LADSPA_HINT_DEFAULT_MAXIMUM)
+#define LADSPA_IS_HINT_DEFAULT_0(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \
+ == LADSPA_HINT_DEFAULT_0)
+#define LADSPA_IS_HINT_DEFAULT_1(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \
+ == LADSPA_HINT_DEFAULT_1)
+#define LADSPA_IS_HINT_DEFAULT_100(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \
+ == LADSPA_HINT_DEFAULT_100)
+#define LADSPA_IS_HINT_DEFAULT_440(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \
+ == LADSPA_HINT_DEFAULT_440)
+
+typedef struct _LADSPA_PortRangeHint {
+
+ /* Hints about the port. */
+ LADSPA_PortRangeHintDescriptor HintDescriptor;
+
+ /* Meaningful when hint LADSPA_HINT_BOUNDED_BELOW is active. When
+ LADSPA_HINT_SAMPLE_RATE is also active then this value should be
+ multiplied by the relevant sample rate. */
+ LADSPA_Data LowerBound;
+
+ /* Meaningful when hint LADSPA_HINT_BOUNDED_ABOVE is active. When
+ LADSPA_HINT_SAMPLE_RATE is also active then this value should be
+ multiplied by the relevant sample rate. */
+ LADSPA_Data UpperBound;
+
+} LADSPA_PortRangeHint;
+
+/*****************************************************************************/
+
+/* Plugin Handles:
+
+ This plugin handle indicates a particular instance of the plugin
+ concerned. It is valid to compare this to NULL (0 for C++) but
+ otherwise the host should not attempt to interpret it. The plugin
+ may use it to reference internal instance data. */
+
+typedef void * LADSPA_Handle;
+
+/*****************************************************************************/
+
+/* Descriptor for a Type of Plugin:
+
+ This structure is used to describe a plugin type. It provides a
+ number of functions to examine the type, instantiate it, link it to
+ buffers and workspaces and to run it. */
+
+typedef struct _LADSPA_Descriptor {
+
+ /* This numeric identifier indicates the plugin type
+ uniquely. Plugin programmers may reserve ranges of IDs from a
+ central body to avoid clashes. Hosts may assume that IDs are
+ below 0x1000000. */
+ unsigned long UniqueID;
+
+ /* This identifier can be used as a unique, case-sensitive
+ identifier for the plugin type within the plugin file. Plugin
+ types should be identified by file and label rather than by index
+ or plugin name, which may be changed in new plugin
+ versions. Labels must not contain white-space characters. */
+ const char * Label;
+
+ /* This indicates a number of properties of the plugin. */
+ LADSPA_Properties Properties;
+
+ /* This member points to the null-terminated name of the plugin
+ (e.g. "Sine Oscillator"). */
+ const char * Name;
+
+ /* This member points to the null-terminated string indicating the
+ maker of the plugin. This can be an empty string but not NULL. */
+ const char * Maker;
+
+ /* This member points to the null-terminated string indicating any
+ copyright applying to the plugin. If no Copyright applies the
+ string "None" should be used. */
+ const char * Copyright;
+
+ /* This indicates the number of ports (input AND output) present on
+ the plugin. */
+ unsigned long PortCount;
+
+ /* This member indicates an array of port descriptors. Valid indices
+ vary from 0 to PortCount-1. */
+ const LADSPA_PortDescriptor * PortDescriptors;
+
+ /* This member indicates an array of null-terminated strings
+ describing ports (e.g. "Frequency (Hz)"). Valid indices vary from
+ 0 to PortCount-1. */
+ const char * const * PortNames;
+
+ /* This member indicates an array of range hints for each port (see
+ above). Valid indices vary from 0 to PortCount-1. */
+ const LADSPA_PortRangeHint * PortRangeHints;
+
+ /* This may be used by the plugin developer to pass any custom
+ implementation data into an instantiate call. It must not be used
+ or interpreted by the host. It is expected that most plugin
+ writers will not use this facility as LADSPA_Handle should be
+ used to hold instance data. */
+ void * ImplementationData;
+
+ /* This member is a function pointer that instantiates a plugin. A
+ handle is returned indicating the new plugin instance. The
+ instantiation function accepts a sample rate as a parameter. The
+ plugin descriptor from which this instantiate function was found
+ must also be passed. This function must return NULL if
+ instantiation fails.
+
+ Note that instance initialisation should generally occur in
+ activate() rather than here. */
+ LADSPA_Handle (*instantiate)(const struct _LADSPA_Descriptor * Descriptor,
+ unsigned long SampleRate);
+
+ /* This member is a function pointer that connects a port on an
+ instantiated plugin to a memory location at which a block of data
+ for the port will be read/written. The data location is expected
+ to be an array of LADSPA_Data for audio ports or a single
+ LADSPA_Data value for control ports. Memory issues will be
+ managed by the host. The plugin must read/write the data at these
+ locations every time run() or run_adding() is called and the data
+ present at the time of this connection call should not be
+ considered meaningful.
+
+ connect_port() may be called more than once for a plugin instance
+ to allow the host to change the buffers that the plugin is
+ reading or writing. These calls may be made before or after
+ activate() or deactivate() calls.
+
+ connect_port() must be called at least once for each port before
+ run() or run_adding() is called. When working with blocks of
+ LADSPA_Data the plugin should pay careful attention to the block
+ size passed to the run function as the block allocated may only
+ just be large enough to contain the block of samples.
+
+ Plugin writers should be aware that the host may elect to use the
+ same buffer for more than one port and even use the same buffer
+ for both input and output (see LADSPA_PROPERTY_INPLACE_BROKEN).
+ However, overlapped buffers or use of a single buffer for both
+ audio and control data may result in unexpected behaviour. */
+ void (*connect_port)(LADSPA_Handle Instance,
+ unsigned long Port,
+ LADSPA_Data * DataLocation);
+
+ /* This member is a function pointer that initialises a plugin
+ instance and activates it for use. This is separated from
+ instantiate() to aid real-time support and so that hosts can
+ reinitialise a plugin instance by calling deactivate() and then
+ activate(). In this case the plugin instance must reset all state
+ information dependent on the history of the plugin instance
+ except for any data locations provided by connect_port() and any
+ gain set by set_run_adding_gain(). If there is nothing for
+ activate() to do then the plugin writer may provide a NULL rather
+ than an empty function.
+
+ When present, hosts must call this function once before run() (or
+ run_adding()) is called for the first time. This call should be
+ made as close to the run() call as possible and indicates to
+ real-time plugins that they are now live. Plugins should not rely
+ on a prompt call to run() after activate(). activate() may not be
+ called again unless deactivate() is called first. Note that
+ connect_port() may be called before or after a call to
+ activate(). */
+ void (*activate)(LADSPA_Handle Instance);
+
+ /* This method is a function pointer that runs an instance of a
+ plugin for a block. Two parameters are required: the first is a
+ handle to the particular instance to be run and the second
+ indicates the block size (in samples) for which the plugin
+ instance may run.
+
+ Note that if an activate() function exists then it must be called
+ before run() or run_adding(). If deactivate() is called for a
+ plugin instance then the plugin instance may not be reused until
+ activate() has been called again.
+
+ If the plugin has the property LADSPA_PROPERTY_HARD_RT_CAPABLE
+ then there are various things that the plugin should not do
+ within the run() or run_adding() functions (see above). */
+ void (*run)(LADSPA_Handle Instance,
+ unsigned long SampleCount);
+
+ /* This method is a function pointer that runs an instance of a
+ plugin for a block. This has identical behaviour to run() except
+ in the way data is output from the plugin. When run() is used,
+ values are written directly to the memory areas associated with
+ the output ports. However when run_adding() is called, values
+ must be added to the values already present in the memory
+ areas. Furthermore, output values written must be scaled by the
+ current gain set by set_run_adding_gain() (see below) before
+ addition.
+
+ run_adding() is optional. When it is not provided by a plugin,
+ this function pointer must be set to NULL. When it is provided,
+ the function set_run_adding_gain() must be provided also. */
+ void (*run_adding)(LADSPA_Handle Instance,
+ unsigned long SampleCount);
+
+ /* This method is a function pointer that sets the output gain for
+ use when run_adding() is called (see above). If this function is
+ never called the gain is assumed to default to 1. Gain
+ information should be retained when activate() or deactivate()
+ are called.
+
+ This function should be provided by the plugin if and only if the
+ run_adding() function is provided. When it is absent this
+ function pointer must be set to NULL. */
+ void (*set_run_adding_gain)(LADSPA_Handle Instance,
+ LADSPA_Data Gain);
+
+ /* This is the counterpart to activate() (see above). If there is
+ nothing for deactivate() to do then the plugin writer may provide
+ a NULL rather than an empty function.
+
+ Hosts must deactivate all activated units after they have been
+ run() (or run_adding()) for the last time. This call should be
+ made as close to the last run() call as possible and indicates to
+ real-time plugins that they are no longer live. Plugins should
+ not rely on prompt deactivation. Note that connect_port() may be
+ called before or after a call to deactivate().
+
+ Deactivation is not similar to pausing as the plugin instance
+ will be reinitialised when activate() is called to reuse it. */
+ void (*deactivate)(LADSPA_Handle Instance);
+
+ /* Once an instance of a plugin has been finished with it can be
+ deleted using the following function. The instance handle passed
+ ceases to be valid after this call.
+
+ If activate() was called for a plugin instance then a
+ corresponding call to deactivate() must be made before cleanup()
+ is called. */
+ void (*cleanup)(LADSPA_Handle Instance);
+
+} LADSPA_Descriptor;
+
+/**********************************************************************/
+
+/* Accessing a Plugin: */
+
+/* The exact mechanism by which plugins are loaded is host-dependent,
+ however all most hosts will need to know is the name of shared
+ object file containing the plugin types. To allow multiple hosts to
+ share plugin types, hosts may wish to check for environment
+ variable LADSPA_PATH. If present, this should contain a
+ colon-separated path indicating directories that should be searched
+ (in order) when loading plugin types.
+
+ A plugin programmer must include a function called
+ "ladspa_descriptor" with the following function prototype within
+ the shared object file. This function will have C-style linkage (if
+ you are using C++ this is taken care of by the `extern "C"' clause
+ at the top of the file).
+
+ A host will find the plugin shared object file by one means or
+ another, find the ladspa_descriptor() function, call it, and
+ proceed from there.
+
+ Plugin types are accessed by index (not ID) using values from 0
+ upwards. Out of range indexes must result in this function
+ returning NULL, so the plugin count can be determined by checking
+ for the least index that results in NULL being returned. */
+
+const LADSPA_Descriptor * ladspa_descriptor(unsigned long Index);
+
+/* Datatype corresponding to the ladspa_descriptor() function. */
+typedef const LADSPA_Descriptor *
+(*LADSPA_Descriptor_Function)(unsigned long Index);
+
+/**********************************************************************/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LADSPA_INCLUDED */
+
+/* EOF */
diff --git a/libs/ardour/ardour/ladspa_plugin.h b/libs/ardour/ardour/ladspa_plugin.h
new file mode 100644
index 0000000000..2451953ce5
--- /dev/null
+++ b/libs/ardour/ardour/ladspa_plugin.h
@@ -0,0 +1,142 @@
+/*
+ Copyright (C) 2000 Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __ardour_ladspa_plugin_h__
+#define __ardour_ladspa_plugin_h__
+
+#include <list>
+#include <set>
+#include <vector>
+#include <string>
+#include <dlfcn.h>
+
+#include <midi++/controllable.h>
+#include <sigc++/signal.h>
+
+#include <jack/types.h>
+#include <ardour/ladspa.h>
+#include <ardour/stateful.h>
+#include <ardour/plugin_state.h>
+#include <ardour/plugin.h>
+#include <ardour/ladspa_plugin.h>
+
+using std::string;
+using std::vector;
+using std::list;
+
+namespace ARDOUR {
+class AudioEngine;
+class Session;
+
+class LadspaPlugin : public ARDOUR::Plugin
+{
+ public:
+ LadspaPlugin (void *module, ARDOUR::AudioEngine&, ARDOUR::Session&, uint32_t index, jack_nframes_t sample_rate);
+ LadspaPlugin (const LadspaPlugin &);
+ ~LadspaPlugin ();
+
+ /* Plugin interface */
+
+ uint32_t unique_id() const { return descriptor->UniqueID; }
+ const char * label() const { return descriptor->Label; }
+ const char * name() const { return descriptor->Name; }
+ const char * maker() const { return descriptor->Maker; }
+ uint32_t parameter_count() const { return descriptor->PortCount; }
+ float default_value (uint32_t port);
+ jack_nframes_t latency() const;
+ void set_parameter (uint32_t port, float val);
+ float get_parameter (uint32_t port) const;
+ int get_parameter_descriptor (uint32_t which, ParameterDescriptor&) const;
+ std::set<uint32_t> automatable() const;
+ uint32_t nth_parameter (uint32_t port, bool& ok) const;
+ void activate () {
+ if (descriptor->activate) {
+ descriptor->activate (handle);
+ }
+ was_activated = true;
+ }
+ void deactivate () {
+ if (descriptor->deactivate)
+ descriptor->deactivate (handle);
+ }
+ void cleanup () {
+ if (was_activated && descriptor->cleanup) {
+ descriptor->cleanup (handle);
+ }
+ }
+ void set_block_size (jack_nframes_t nframes) {}
+
+ int connect_and_run (vector<Sample*>& bufs, uint32_t maxbuf, int32_t& in, int32_t& out, jack_nframes_t nframes, jack_nframes_t offset);
+ void store_state (ARDOUR::PluginState&);
+ void restore_state (ARDOUR::PluginState&);
+ string describe_parameter (uint32_t);
+ string state_node_name() const { return "ladspa"; }
+ void print_parameter (uint32_t, char*, uint32_t len) const;
+
+ bool parameter_is_audio(uint32_t) const;
+ bool parameter_is_control(uint32_t) const;
+ bool parameter_is_input(uint32_t) const;
+ bool parameter_is_output(uint32_t) const;
+ bool parameter_is_toggled(uint32_t) const;
+
+ XMLNode& get_state();
+ int set_state(const XMLNode& node);
+ bool save_preset(string name);
+
+ bool has_editor() const { return false; }
+
+ int require_output_streams (uint32_t);
+
+ /* LADSPA extras */
+
+ LADSPA_Properties properties() const { return descriptor->Properties; }
+ uint32_t index() const { return _index; }
+ const char * copyright() const { return descriptor->Copyright; }
+ LADSPA_PortDescriptor port_descriptor(uint32_t i) const { return descriptor->PortDescriptors[i]; }
+ const LADSPA_PortRangeHint * port_range_hints() const { return descriptor->PortRangeHints; }
+ const char * const * port_names() const { return descriptor->PortNames; }
+ void set_gain (float gain) {
+ descriptor->set_run_adding_gain (handle, gain);
+ }
+ void run_adding (uint32_t nsamples) {
+ descriptor->run_adding (handle, nsamples);
+ }
+ void connect_port (uint32_t port, float *ptr) {
+ descriptor->connect_port (handle, port, ptr);
+ }
+
+ private:
+ void *module;
+ const LADSPA_Descriptor *descriptor;
+ LADSPA_Handle handle;
+ jack_nframes_t sample_rate;
+ LADSPA_Data *control_data;
+ LADSPA_Data *shadow_data;
+ LADSPA_Data *latency_control_port;
+ uint32_t _index;
+ bool was_activated;
+
+ void init (void *mod, uint32_t index, jack_nframes_t rate);
+ void run (jack_nframes_t nsamples);
+ void latency_compute_run ();
+};
+}
+
+#endif /* __ardour_ladspa_plugin_h__ */
diff --git a/libs/ardour/ardour/location.h b/libs/ardour/ardour/location.h
new file mode 100644
index 0000000000..1da67c78da
--- /dev/null
+++ b/libs/ardour/ardour/location.h
@@ -0,0 +1,193 @@
+/*
+ Copyright (C) 2000 Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __ardour_location_h__
+#define __ardour_location_h__
+
+#include <string>
+#include <list>
+#include <iostream>
+#include <map>
+
+#include <sys/types.h>
+#include <pthread.h>
+#include <sigc++/signal.h>
+
+#include <pbd/lockmonitor.h>
+#include <pbd/undo.h>
+
+#include "ardour.h"
+#include "stateful.h"
+#include "state_manager.h"
+
+using std::string;
+
+namespace ARDOUR {
+
+class Location : public Stateful, public sigc::trackable
+{
+ public:
+ enum Flags {
+ IsMark = 0x1,
+ IsAutoPunch = 0x2,
+ IsAutoLoop = 0x4,
+ IsHidden = 0x8,
+ IsCDMarker = 0x10,
+ IsEnd = 0x20
+ };
+
+ Location (jack_nframes_t sample_start,
+ jack_nframes_t sample_end,
+ const string &name,
+ Flags bits = Flags(0))
+
+ : _name (name),
+ _start (sample_start),
+ _end (sample_end),
+ _flags (bits) { }
+
+ Location () {
+ _start = 0;
+ _end = 0;
+ _flags = 0;
+ }
+
+ Location (const Location& other);
+ Location* operator= (const Location& other);
+
+ jack_nframes_t start() { return _start; }
+ jack_nframes_t end() { return _end; }
+ jack_nframes_t length() { return _end - _start; }
+
+ int set_start (jack_nframes_t s);
+ int set_end (jack_nframes_t e);
+ int set (jack_nframes_t start, jack_nframes_t end);
+
+ const string& name() { return _name; }
+ void set_name (const string &str) { _name = str; name_changed(this); }
+
+ void set_auto_punch (bool yn, void *src);
+ void set_auto_loop (bool yn, void *src);
+ void set_hidden (bool yn, void *src);
+ void set_cd (bool yn, void *src);
+ void set_is_end (bool yn, void* src);
+
+ bool is_auto_punch () { return _flags & IsAutoPunch; }
+ bool is_auto_loop () { return _flags & IsAutoLoop; }
+ bool is_mark () { return _flags & IsMark; }
+ bool is_hidden () { return _flags & IsHidden; }
+ bool is_cd_marker () { return _flags & IsCDMarker; }
+ bool is_end() { return _flags & IsEnd; }
+
+ sigc::signal<void,Location*> name_changed;
+ sigc::signal<void,Location*> end_changed;
+ sigc::signal<void,Location*> start_changed;
+
+ sigc::signal<void,Location*,void*> FlagsChanged;
+
+ /* this is sent only when both start&end change at the same time */
+
+ sigc::signal<void,Location*> changed;
+
+ /* CD Track / CD-Text info */
+
+ std::map<string, string> cd_info;
+ XMLNode& cd_info_node (const string &, const string &);
+
+ XMLNode& get_state (void);
+ int set_state (const XMLNode&);
+
+ private:
+ string _name;
+ jack_nframes_t _start;
+ jack_nframes_t _end;
+ uint32_t _flags;
+
+ void set_mark (bool yn);
+ bool set_flag_internal (bool yn, Flags flag);
+};
+
+class Locations : public Stateful, public StateManager
+{
+ public:
+ typedef std::list<Location *> LocationList;
+
+ Locations ();
+ ~Locations ();
+
+ void add (Location *, bool make_current = false);
+ void remove (Location *);
+ void clear ();
+ void clear_markers ();
+ void clear_ranges ();
+
+ XMLNode& get_state (void);
+ int set_state (const XMLNode&);
+
+ Location* auto_loop_location () const;
+ Location* auto_punch_location () const;
+ Location* end_location() const;
+
+ int set_current (Location *, bool want_lock = true);
+ Location *current () const { return current_location; }
+
+ Location *first_location_before (jack_nframes_t);
+ Location *first_location_after (jack_nframes_t);
+
+ sigc::signal<void,Location*> current_changed;
+ sigc::signal<void> changed;
+ sigc::signal<void,Location*> added;
+ sigc::signal<void,Location*> removed;
+
+ template<class T> void apply (T& obj, void (T::*method)(LocationList&)) {
+ LockMonitor lm (lock, __LINE__, __FILE__);
+ (obj.*method)(locations);
+ }
+
+ template<class T1, class T2> void apply (T1& obj, void (T1::*method)(LocationList&, T2& arg), T2& arg) {
+ LockMonitor lm (lock, __LINE__, __FILE__);
+ (obj.*method)(locations, arg);
+ }
+
+ UndoAction get_memento () const;
+
+ private:
+
+ struct State : public ARDOUR::StateManager::State {
+ LocationList locations;
+ LocationList states;
+
+ State (std::string why) : ARDOUR::StateManager::State (why) {}
+ };
+
+ LocationList locations;
+ Location *current_location;
+ PBD::Lock lock;
+
+ int set_current_unlocked (Location *);
+ void location_changed (Location*);
+
+ Change restore_state (StateManager::State&);
+ StateManager::State* state_factory (std::string why) const;
+};
+
+}; /* namespace ARDOUR */
+
+#endif /* __ardour_location_h__ */
diff --git a/libs/ardour/ardour/logcurve.h b/libs/ardour/ardour/logcurve.h
new file mode 100644
index 0000000000..84911b0369
--- /dev/null
+++ b/libs/ardour/ardour/logcurve.h
@@ -0,0 +1,133 @@
+/*
+ Copyright (C) 2001 Steve Harris & Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __ardour_logcurve_h__
+#define __ardour_logcurve_h__
+
+#include <pbd/fastlog.h>
+#include <pbd/lockmonitor.h>
+
+namespace ARDOUR {
+
+class LogCurve {
+ public:
+ LogCurve (float steepness = 0.2, uint32_t len = 0) {
+ l = len;
+ S = steepness;
+ a = log(S);
+ b = 1.0f / log(1.0f + (1.0f / S));
+ }
+
+ bool operator== (const LogCurve& other) const {
+ return S == other.S && l == other.l;
+ }
+
+ bool operator!= (const LogCurve& other) const {
+ return S != other.S || l != other.l;
+ }
+
+ float value (float frac) const {
+ return (fast_log(frac + S) - a) * b;
+ }
+
+ float value (uint32_t pos) const {
+ return (fast_log(((float) pos/l) + S) - a) * b;
+ }
+
+ float invert_value (float frac) const {
+ return (a - fast_log(frac + S)) * b;
+ }
+
+ float invert_value (uint32_t pos) const {
+ return (a - fast_log(((float) pos/l) + S)) * b;
+ }
+
+ void fill (float *vec, uint32_t veclen, bool invert) const {
+ float dx = 1.0f/veclen;
+ float x;
+ uint32_t i;
+
+ if (!invert) {
+
+ vec[0] = 0.0;
+ vec[veclen-1] = 1.0;
+
+ for (i = 1, x = 0; i < veclen - 1; x += dx, i++) {
+ vec[i] = value (x);
+ }
+
+ } else {
+
+ vec[0] = 1.0;
+ vec[veclen-1] = 0.0;
+
+ for (i = veclen-2, x = 0.0f; i > 0; x += dx, i--) {
+ vec[i] = value (x);
+ }
+ }
+ }
+
+ float steepness() const { return S; }
+ uint32_t length() const { return l; }
+
+ void set_steepness (float steepness) {
+ S = steepness;
+ a = log(S);
+ b = 1.0f / log(1.0f + (1.0f / S));
+ }
+ void set_length (uint32_t len) { l = len; }
+
+ mutable PBD::NonBlockingLock lock;
+
+ protected:
+ float a;
+ float b;
+ float S;
+ uint32_t l;
+};
+
+class LogCurveIn : public LogCurve
+{
+ public:
+ LogCurveIn (float steepness = 0.2, uint32_t len = 0)
+ : LogCurve (steepness, len) {}
+
+ float value (float frac) const {
+ return (fast_log(frac + S) - a) * b;
+ }
+
+ float value (uint32_t pos) const {
+ return (fast_log(((float) pos/l) + S) - a) * b;
+ }
+};
+
+class LogCurveOut : public LogCurve
+{
+ public:
+ LogCurveOut (float steepness = 0.2, uint32_t len = 0)
+ : LogCurve (steepness, len) {}
+
+};
+
+}; /* namespace ARDOUR */
+
+#endif /* __ardour_logcurve_h__ */
+
+
diff --git a/libs/ardour/ardour/mix.h b/libs/ardour/ardour/mix.h
new file mode 100644
index 0000000000..b351e3ef17
--- /dev/null
+++ b/libs/ardour/ardour/mix.h
@@ -0,0 +1,74 @@
+/*
+ Copyright (C) 2005 Sampo Savolainen
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+#ifndef __ardour_mix_h__
+#define __ardour_mix_h__
+
+#include <ardour/types.h>
+#include <ardour/utils.h>
+#include <ardour/io.h>
+
+#if defined (ARCH_X86) && defined (BUILD_SSE_OPTIMIZATIONS)
+
+extern "C" {
+/* SSE functions */
+ float x86_sse_compute_peak (ARDOUR::Sample *buf, jack_nframes_t nsamples, float current);
+
+ void x86_sse_apply_gain_to_buffer (ARDOUR::Sample *buf, jack_nframes_t nframes, float gain);
+
+ void x86_sse_mix_buffers_with_gain (ARDOUR::Sample *dst, ARDOUR::Sample *src, jack_nframes_t nframes, float gain);
+
+ void x86_sse_mix_buffers_no_gain (ARDOUR::Sample *dst, ARDOUR::Sample *src, jack_nframes_t nframes);
+}
+
+/* debug wrappers for SSE functions */
+
+float debug_compute_peak (ARDOUR::Sample *buf, jack_nframes_t nsamples, float current);
+
+void debug_apply_gain_to_buffer (ARDOUR::Sample *buf, jack_nframes_t nframes, float gain);
+
+void debug_mix_buffers_with_gain (ARDOUR::Sample *dst, ARDOUR::Sample *src, jack_nframes_t nframes, float gain);
+
+void debug_mix_buffers_no_gain (ARDOUR::Sample *dst, ARDOUR::Sample *src, jack_nframes_t nframes);
+
+#endif
+
+#if defined (__APPLE__)
+
+float veclib_compute_peak (ARDOUR::Sample *buf, jack_nframes_t nsamples, float current);
+
+void veclib_apply_gain_to_buffer (ARDOUR::Sample *buf, jack_nframes_t nframes, float gain);
+
+void veclib_mix_buffers_with_gain (ARDOUR::Sample *dst, ARDOUR::Sample *src, jack_nframes_t nframes, float gain);
+
+void veclib_mix_buffers_no_gain (ARDOUR::Sample *dst, ARDOUR::Sample *src, jack_nframes_t nframes);
+
+#endif
+
+/* non-optimized functions */
+
+float compute_peak (ARDOUR::Sample *buf, jack_nframes_t nsamples, float current);
+
+void apply_gain_to_buffer (ARDOUR::Sample *buf, jack_nframes_t nframes, float gain);
+
+void mix_buffers_with_gain (ARDOUR::Sample *dst, ARDOUR::Sample *src, jack_nframes_t nframes, float gain);
+
+void mix_buffers_no_gain (ARDOUR::Sample *dst, ARDOUR::Sample *src, jack_nframes_t nframes);
+
+#endif /* __ardour_mix_h__ */
diff --git a/libs/ardour/ardour/named_selection.h b/libs/ardour/ardour/named_selection.h
new file mode 100644
index 0000000000..91bb816181
--- /dev/null
+++ b/libs/ardour/ardour/named_selection.h
@@ -0,0 +1,55 @@
+/*
+ Copyright (C) 2003 Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __ardour_named_selection_h__
+#define __ardour_named_selection_h__
+
+#include <string>
+#include <list>
+
+#include <ardour/stateful.h>
+
+class XMLNode;
+
+namespace ARDOUR
+{
+class Session;
+class Playlist;
+
+struct NamedSelection : public Stateful
+{
+ NamedSelection (std::string, std::list<Playlist*>&);
+ NamedSelection (Session&, const XMLNode&);
+ virtual ~NamedSelection ();
+
+ std::string name;
+ std::list<Playlist*> playlists;
+
+ XMLNode& get_state (void);
+
+ int set_state (const XMLNode&);
+
+ static sigc::signal<void,NamedSelection*> NamedSelectionCreated;
+};
+
+}/* namespace ARDOUR */
+
+#endif /* __ardour_named_selection_h__ */
+
diff --git a/libs/ardour/ardour/noise.h b/libs/ardour/ardour/noise.h
new file mode 100644
index 0000000000..b06b02399b
--- /dev/null
+++ b/libs/ardour/ardour/noise.h
@@ -0,0 +1,19 @@
+#ifndef NOISE_H
+#define NOISE_H
+
+/* Can be overrriden with any code that produces whitenoise between 0.0f and
+ * 1.0f, eg (random() / (float)RAND_MAX) should be a good source of noise, but
+ * its expensive */
+#ifndef GDITHER_NOISE
+#define GDITHER_NOISE gdither_noise()
+#endif
+
+inline static float gdither_noise()
+{
+ static uint32_t rnd = 23232323;
+ rnd = (rnd * 196314165) + 907633515;
+
+ return rnd * 2.3283064365387e-10f;
+}
+
+#endif
diff --git a/libs/ardour/ardour/panner.h b/libs/ardour/ardour/panner.h
new file mode 100644
index 0000000000..806f350e03
--- /dev/null
+++ b/libs/ardour/ardour/panner.h
@@ -0,0 +1,331 @@
+/*
+ Copyright (C) 2004 Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __ardour_panner_h__
+#define __ardour_panner_h__
+
+#include <cmath>
+#include <vector>
+#include <string>
+#include <iostream>
+#include <sigc++/signal.h>
+
+#include <midi++/controllable.h>
+
+#include <ardour/types.h>
+#include <ardour/stateful.h>
+#include <ardour/curve.h>
+
+using std::istream;
+using std::ostream;
+
+namespace ARDOUR {
+
+class Session;
+class Panner;
+
+class StreamPanner : public sigc::trackable, public Stateful
+{
+ public:
+ StreamPanner (Panner& p);
+ ~StreamPanner ();
+
+ void set_muted (bool yn);
+ bool muted() const { return _muted; }
+
+ void set_position (float x, bool link_call = false);
+ void set_position (float x, float y, bool link_call = false);
+ void set_position (float x, float y, float z, bool link_call = false);
+
+ void get_position (float& xpos) const { xpos = x; }
+ void get_position (float& xpos, float& ypos) const { xpos = x; ypos = y; }
+ void get_position (float& xpos, float& ypos, float& zpos) const { xpos = x; ypos = y; zpos = z; }
+
+ void get_effective_position (float& xpos) const { xpos = effective_x; }
+ void get_effective_position (float& xpos, float& ypos) const { xpos = effective_x; ypos = effective_y; }
+ void get_effective_position (float& xpos, float& ypos, float& zpos) const { xpos = effective_x; ypos = effective_y; zpos = effective_z; }
+
+ /* the basic panner API */
+
+ virtual void distribute (Sample* src, Sample** obufs, gain_t gain_coeff, jack_nframes_t nframes) = 0;
+ virtual void distribute_automated (Sample* src, Sample** obufs,
+ jack_nframes_t start, jack_nframes_t end, jack_nframes_t nframes, pan_t** buffers) = 0;
+
+ /* automation */
+
+ virtual void snapshot (jack_nframes_t now) = 0;
+ virtual void transport_stopped (jack_nframes_t frame) = 0;
+ virtual void set_automation_state (AutoState) = 0;
+ virtual void set_automation_style (AutoStyle) = 0;
+
+ /* MIDI control */
+
+ struct MIDIControl : public MIDI::Controllable {
+ MIDIControl (StreamPanner&, MIDI::Port *);
+ void set_value (float);
+ void send_feedback (gain_t);
+ MIDI::byte* write_feedback (MIDI::byte* buf, int32_t& bufsize, gain_t val, bool force = false);
+
+ pan_t (*midi_to_pan)(double val);
+ double (*pan_to_midi)(pan_t p);
+
+ StreamPanner& sp;
+ bool setting;
+ gain_t last_written;
+ };
+
+ MIDIControl& midi_control() { return _midi_control; }
+ void reset_midi_control (MIDI::Port *, bool);
+
+ /* XXX this is wrong. for multi-dimensional panners, there
+ must surely be more than 1 automation curve.
+ */
+
+ virtual Curve& automation() = 0;
+
+
+ virtual int load (istream&, string path, uint32_t&) = 0;
+
+ virtual int save (ostream&) const = 0;
+
+ sigc::signal<void> Changed; /* for position */
+ sigc::signal<void> StateChanged; /* for mute */
+
+ int set_state (const XMLNode&);
+ virtual XMLNode& state (bool full_state) = 0;
+
+ Panner & get_parent() { return parent; }
+
+ protected:
+ friend class Panner;
+ Panner& parent;
+
+ float x;
+ float y;
+ float z;
+
+ /* these are for automation. they store the last value
+ used by the most recent process() cycle.
+ */
+
+ float effective_x;
+ float effective_y;
+ float effective_z;
+
+ bool _muted;
+ MIDIControl _midi_control;
+
+ void add_state (XMLNode&);
+ bool get_midi_node_info (XMLNode * node, MIDI::eventType & ev, MIDI::channel_t & chan, MIDI::byte & additional);
+ bool set_midi_node_info (XMLNode * node, MIDI::eventType ev, MIDI::channel_t chan, MIDI::byte additional);
+
+ virtual void update () = 0;
+};
+
+class BaseStereoPanner : public StreamPanner
+{
+ public:
+ BaseStereoPanner (Panner&);
+ ~BaseStereoPanner ();
+
+ /* this class just leaves the pan law itself to be defined
+ by the update(), distribute_automated()
+ methods. derived classes also need a factory method
+ and a type name. See EqualPowerStereoPanner as an example.
+ */
+
+ void distribute (Sample* src, Sample** obufs, gain_t gain_coeff, jack_nframes_t nframes);
+
+ int load (istream&, string path, uint32_t&);
+ int save (ostream&) const;
+ void snapshot (jack_nframes_t now);
+ void transport_stopped (jack_nframes_t frame);
+ void set_automation_state (AutoState);
+ void set_automation_style (AutoStyle);
+
+ Curve& automation() { return _automation; }
+
+ protected:
+ float left;
+ float right;
+ float desired_left;
+ float desired_right;
+ float left_interp;
+ float right_interp;
+
+ Curve _automation;
+};
+
+class EqualPowerStereoPanner : public BaseStereoPanner
+{
+ public:
+ EqualPowerStereoPanner (Panner&);
+ ~EqualPowerStereoPanner ();
+
+ void distribute_automated (Sample* src, Sample** obufs,
+ jack_nframes_t start, jack_nframes_t end, jack_nframes_t nframes, pan_t** buffers);
+
+ void get_current_coefficients (pan_t*) const;
+ void get_desired_coefficients (pan_t*) const;
+
+ static StreamPanner* factory (Panner&);
+ static string name;
+
+ XMLNode& state (bool full_state);
+ XMLNode& get_state (void);
+ int set_state (const XMLNode&);
+
+ private:
+ void update ();
+};
+
+class Multi2dPanner : public StreamPanner
+{
+ public:
+ Multi2dPanner (Panner& parent);
+ ~Multi2dPanner ();
+
+ void snapshot (jack_nframes_t now);
+ void transport_stopped (jack_nframes_t frame);
+ void set_automation_state (AutoState);
+ void set_automation_style (AutoStyle);
+
+ /* XXX this is wrong. for multi-dimensional panners, there
+ must surely be more than 1 automation curve.
+ */
+
+ Curve& automation() { return _automation; }
+
+ void distribute (Sample* src, Sample** obufs, gain_t gain_coeff, jack_nframes_t nframes);
+ void distribute_automated (Sample* src, Sample** obufs,
+ jack_nframes_t start, jack_nframes_t end, jack_nframes_t nframes, pan_t** buffers);
+
+ int load (istream&, string path, uint32_t&);
+ int save (ostream&) const;
+
+ static StreamPanner* factory (Panner&);
+ static string name;
+
+ XMLNode& state (bool full_state);
+ XMLNode& get_state (void);
+ int set_state (const XMLNode&);
+
+ private:
+ Curve _automation;
+ void update ();
+};
+
+class Panner : public std::vector<StreamPanner*>, public Stateful, public sigc::trackable
+{
+ public:
+ struct Output {
+ float x;
+ float y;
+ pan_t current_pan;
+ pan_t desired_pan;
+
+ Output (float xp, float yp)
+ : x (xp), y (yp), current_pan (0.0f), desired_pan (0.f) {}
+
+ };
+
+ Panner (string name, Session&);
+ virtual ~Panner ();
+
+ void set_name (string);
+
+ bool bypassed() const { return _bypassed; }
+ void set_bypassed (bool yn);
+
+ StreamPanner* add ();
+ void remove (uint32_t which);
+ void clear ();
+ void reset (uint32_t noutputs, uint32_t npans);
+
+ void snapshot (jack_nframes_t now);
+ void transport_stopped (jack_nframes_t frame);
+
+ void clear_automation ();
+
+ void set_automation_state (AutoState);
+ AutoState automation_state() const;
+ void set_automation_style (AutoStyle);
+ AutoStyle automation_style() const;
+ bool touching() const;
+
+ int load ();
+ int save () const;
+
+ XMLNode& get_state (void);
+ XMLNode& state (bool full);
+ int set_state (const XMLNode&);
+
+ sigc::signal<void> Changed;
+
+ static bool equivalent (pan_t a, pan_t b) {
+ return fabsf (a - b) < 0.002; // about 1 degree of arc for a stereo panner
+ }
+
+ void move_output (uint32_t, float x, float y);
+ uint32_t nouts() const { return outputs.size(); }
+ Output& output (uint32_t n) { return outputs[n]; }
+
+ std::vector<Output> outputs;
+ Session& session() const { return _session; }
+
+ void reset_midi_control (MIDI::Port *, bool);
+ void send_all_midi_feedback ();
+ MIDI::byte* write_midi_feedback (MIDI::byte*, int32_t& bufsize);
+
+ enum LinkDirection {
+ SameDirection,
+ OppositeDirection
+ };
+
+ LinkDirection link_direction() const { return _link_direction; }
+ void set_link_direction (LinkDirection);
+
+ bool linked() const { return _linked; }
+ void set_linked (bool yn);
+
+ sigc::signal<void> LinkStateChanged;
+ sigc::signal<void> StateChanged; /* for bypass */
+
+ /* only StreamPanner should call these */
+
+ void set_position (float x, StreamPanner& orig);
+ void set_position (float x, float y, StreamPanner& orig);
+ void set_position (float x, float y, float z, StreamPanner& orig);
+
+ private:
+
+ string automation_path;
+ Session& _session;
+ uint32_t current_outs;
+ bool _linked;
+ bool _bypassed;
+ LinkDirection _link_direction;
+
+ static float current_automation_version_number;
+};
+
+}; /* namespace ARDOUR */
+
+#endif /*__ardour_panner_h__ */
diff --git a/libs/ardour/ardour/peak.h b/libs/ardour/ardour/peak.h
new file mode 100644
index 0000000000..d08357024b
--- /dev/null
+++ b/libs/ardour/ardour/peak.h
@@ -0,0 +1,17 @@
+#ifndef __ardour_peak_h__
+#define __ardour_peak_h__
+
+#include <cmath>
+#include <ardour/types.h>
+#include <ardour/utils.h>
+
+static inline float
+compute_peak (ARDOUR::Sample *buf, jack_nframes_t nsamples, float current)
+{
+ for (jack_nframes_t i = 0; i < nsamples; ++i) {
+ current = f_max (current, fabsf (buf[i]));
+ }
+ return current;
+}
+
+#endif /* __ardour_peak_h__ */
diff --git a/libs/ardour/ardour/playlist.h b/libs/ardour/ardour/playlist.h
new file mode 100644
index 0000000000..a5451c30d5
--- /dev/null
+++ b/libs/ardour/ardour/playlist.h
@@ -0,0 +1,278 @@
+/*
+ Copyright (C) 2000 Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __ardour_playlist_h__
+#define __ardour_playlist_h__
+
+#include <string>
+#include <set>
+#include <map>
+#include <list>
+
+#include <sys/stat.h>
+
+#include <sigc++/signal.h>
+#include <pbd/atomic.h>
+#include <pbd/undo.h>
+
+#include <ardour/ardour.h>
+#include <ardour/crossfade_compare.h>
+#include <ardour/location.h>
+#include <ardour/stateful.h>
+#include <ardour/source.h>
+#include <ardour/state_manager.h>
+
+namespace ARDOUR {
+
+class Session;
+class Region;
+
+class Playlist : public Stateful, public StateManager {
+ public:
+ typedef list<Region*> RegionList;
+
+ Playlist (Session&, const XMLNode&, bool hidden = false);
+ Playlist (Session&, string name, bool hidden = false);
+ Playlist (const Playlist&, string name, bool hidden = false);
+ Playlist (const Playlist&, jack_nframes_t start, jack_nframes_t cnt, string name, bool hidden = false);
+
+ virtual jack_nframes_t read (Sample *dst, Sample *mixdown, float *gain_buffer, jack_nframes_t start, jack_nframes_t cnt, uint32_t chan_n=0) = 0;
+ virtual void clear (bool with_delete = false, bool with_save = true);
+ virtual void dump () const;
+ virtual UndoAction get_memento() const = 0;
+
+ void ref();
+ void unref();
+ uint32_t refcnt() const { return _refcnt; }
+
+ const string& name() const { return _name; }
+ void set_name (const string& str);
+
+ bool frozen() const { return _frozen; }
+ void set_frozen (bool yn);
+
+ bool hidden() const { return _hidden; }
+ bool empty() const;
+ jack_nframes_t get_maximum_extent () const;
+ layer_t top_layer() const;
+
+ EditMode get_edit_mode() const { return _edit_mode; }
+ void set_edit_mode (EditMode);
+
+ /* Editing operations */
+
+ void add_region (const Region&, jack_nframes_t position, float times = 1, bool with_save = true);
+ void remove_region (Region *);
+ void replace_region (Region& old, Region& newr, jack_nframes_t pos);
+ void split_region (Region&, jack_nframes_t position);
+ void partition (jack_nframes_t start, jack_nframes_t end, bool just_top_level);
+ void duplicate (Region&, jack_nframes_t position, float times);
+ void nudge_after (jack_nframes_t start, jack_nframes_t distance, bool forwards);
+
+ Region* find_region (id_t) const;
+
+ Playlist* cut (list<AudioRange>&, bool result_is_hidden = true);
+ Playlist* copy (list<AudioRange>&, bool result_is_hidden = true);
+ int paste (Playlist&, jack_nframes_t position, float times);
+
+ uint32_t read_data_count() { return _read_data_count; }
+
+ RegionList* regions_at (jack_nframes_t frame);
+ RegionList* regions_touched (jack_nframes_t start, jack_nframes_t end);
+ Region* top_region_at (jack_nframes_t frame);
+
+ Region* find_next_region (jack_nframes_t frame, RegionPoint point, int dir);
+
+ template<class T> void foreach_region (T *t, void (T::*func)(Region *, void *), void *arg);
+ template<class T> void foreach_region (T *t, void (T::*func)(Region *));
+
+ XMLNode& get_state ();
+ int set_state (const XMLNode&);
+ XMLNode& get_template ();
+
+ sigc::signal<void,Region *> RegionAdded;
+ sigc::signal<void,Region *> RegionRemoved;
+
+ sigc::signal<void,Playlist*,bool> InUse;
+ sigc::signal<void> Modified;
+ sigc::signal<void> NameChanged;
+ sigc::signal<void> LengthChanged;
+ sigc::signal<void> LayeringChanged;
+ sigc::signal<void,Playlist *> GoingAway;
+ sigc::signal<void> StatePushed;
+
+ static sigc::signal<void,Playlist*> PlaylistCreated;
+
+ static string bump_name (string old_name, Session&);
+ static string bump_name_once (string old_name);
+
+ void freeze ();
+ void thaw ();
+
+ void raise_region (Region&);
+ void lower_region (Region&);
+ void raise_region_to_top (Region&);
+ void lower_region_to_bottom (Region&);
+
+ uint32_t read_data_count() const { return _read_data_count; }
+
+ Session& session() { return _session; }
+
+ id_t get_orig_diskstream_id () const { return _orig_diskstream_id; }
+ void set_orig_diskstream_id (id_t did) { _orig_diskstream_id = did; }
+
+ /* destructive editing */
+
+ virtual bool destroy_region (Region *) = 0;
+
+ protected:
+ friend class Session;
+ virtual ~Playlist (); /* members of the public use unref() */
+
+ protected:
+ struct RegionLock {
+ RegionLock (Playlist *pl, bool do_block_notify = true) : playlist (pl), block_notify (do_block_notify) {
+ playlist->region_lock.lock();
+ if (block_notify) {
+ playlist->delay_notifications();
+ }
+ }
+ ~RegionLock() {
+ playlist->region_lock.unlock();
+ if (block_notify) {
+ playlist->release_notifications ();
+ }
+ }
+ Playlist *playlist;
+ bool block_notify;
+ };
+
+ friend class RegionLock;
+
+ RegionList regions;
+ string _name;
+ Session& _session;
+ atomic_t block_notifications;
+ atomic_t ignore_state_changes;
+ mutable PBD::NonBlockingLock region_lock;
+ RegionList pending_removals;
+ RegionList pending_adds;
+ RegionList pending_bounds;
+ bool pending_modified;
+ bool pending_length;
+ bool save_on_thaw;
+ string last_save_reason;
+ bool in_set_state;
+ bool _hidden;
+ bool _splicing;
+ bool _nudging;
+ uint32_t _refcnt;
+ EditMode _edit_mode;
+ bool in_flush;
+ bool in_partition;
+ bool _frozen;
+ uint32_t subcnt;
+ uint32_t _read_data_count;
+ id_t _orig_diskstream_id;
+ uint64_t layer_op_counter;
+ jack_nframes_t freeze_length;
+
+ void init (bool hide);
+
+ bool holding_state () const {
+ return atomic_read (&block_notifications) != 0 ||
+ atomic_read (&ignore_state_changes) != 0;
+ }
+
+ /* prevent the compiler from ever generating these */
+
+ Playlist (const Playlist&);
+ Playlist (Playlist&);
+
+ void delay_notifications ();
+ void release_notifications ();
+ virtual void flush_notifications ();
+
+ void notify_region_removed (Region *);
+ void notify_region_added (Region *);
+ void notify_length_changed ();
+ void notify_layering_changed ();
+ void notify_modified ();
+ void notify_state_changed (Change);
+
+ void mark_session_dirty();
+
+ void region_changed_proxy (Change, Region*);
+ virtual bool region_changed (Change, Region*);
+
+ void region_bounds_changed (Change, Region *);
+ void region_deleted (Region *);
+
+ void sort_regions ();
+
+ void possibly_splice ();
+ void possibly_splice_unlocked();
+ void core_splice ();
+ void splice_locked ();
+ void splice_unlocked ();
+
+ virtual void check_dependents (Region& region, bool norefresh) {}
+ virtual void refresh_dependents (Region& region) {}
+ virtual void remove_dependents (Region& region) {}
+
+ virtual XMLNode& state (bool);
+
+ /* override state_manager::save_state so we can check in_set_state() */
+
+ void save_state (std::string why);
+ void maybe_save_state (std::string why);
+
+ void add_region_internal (Region *, jack_nframes_t position, bool delay_sort = false);
+
+ int remove_region_internal (Region *, bool delay_sort = false);
+ RegionList *find_regions_at (jack_nframes_t frame);
+ void copy_regions (RegionList&) const;
+ void partition_internal (jack_nframes_t start, jack_nframes_t end, bool cutting, RegionList& thawlist);
+
+ jack_nframes_t _get_maximum_extent() const;
+
+ Playlist* cut_copy (Playlist* (Playlist::*pmf)(jack_nframes_t, jack_nframes_t, bool),
+ list<AudioRange>& ranges, bool result_is_hidden);
+ Playlist *cut (jack_nframes_t start, jack_nframes_t cnt, bool result_is_hidden);
+ Playlist *copy (jack_nframes_t start, jack_nframes_t cnt, bool result_is_hidden);
+
+
+ int move_region_to_layer (layer_t, Region& r, int dir);
+ void relayer ();
+
+ static Playlist* copyPlaylist (const Playlist&, jack_nframes_t start, jack_nframes_t length,
+ string name, bool result_is_hidden);
+
+ void unset_freeze_parent (Playlist*);
+ void unset_freeze_child (Playlist*);
+
+ void timestamp_layer_op (Region&);
+};
+
+} /* namespace ARDOUR */
+
+#endif /* __ardour_playlist_h__ */
+
+
diff --git a/libs/ardour/ardour/playlist_templates.h b/libs/ardour/ardour/playlist_templates.h
new file mode 100644
index 0000000000..d3d682b8c5
--- /dev/null
+++ b/libs/ardour/ardour/playlist_templates.h
@@ -0,0 +1,49 @@
+/*
+ Copyright (C) 2003 Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __ardour_playlist_templates_h__
+#define __ardour_playlist_templates_h__
+
+namespace ARDOUR {
+
+template<class T> void AudioPlaylist::foreach_crossfade (T *t, void (T::*func)(Crossfade *)) {
+ RegionLock rlock (this, false);
+ for (Crossfades::iterator i = _crossfades.begin(); i != _crossfades.end(); i++) {
+ (t->*func) (*i);
+ }
+}
+
+template<class T> void Playlist::foreach_region (T *t, void (T::*func)(Region *, void *), void *arg) {
+ RegionLock rlock (this, false);
+ for (RegionList::iterator i = regions.begin(); i != regions.end(); i++) {
+ (t->*func) ((*i), arg);
+ }
+ }
+
+template<class T> void Playlist::foreach_region (T *t, void (T::*func)(Region *)) {
+ RegionLock rlock (this, false);
+ for (RegionList::const_iterator i = regions.begin(); i != regions.end(); i++) {
+ (t->*func) (*i);
+ }
+}
+
+}
+
+#endif /* __ardour_playlist_templates_h__ */
diff --git a/libs/ardour/ardour/plugin.h b/libs/ardour/ardour/plugin.h
new file mode 100644
index 0000000000..8839393b72
--- /dev/null
+++ b/libs/ardour/ardour/plugin.h
@@ -0,0 +1,194 @@
+/*
+ Copyright (C) 2000 Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __ardour_ladspa_h__
+#define __ardour_ladspa_h__
+
+#include <midi++/controllable.h>
+#include <sigc++/signal.h>
+
+#include <jack/types.h>
+#include <ardour/types.h>
+#include <ardour/stateful.h>
+#include <ardour/plugin_state.h>
+#include <ardour/cycles.h>
+
+#include <list>
+#include <vector>
+#include <set>
+#include <map>
+
+using std::string;
+using std::vector;
+using std::list;
+using std::set;
+using std::map;
+
+namespace ARDOUR {
+
+class AudioEngine;
+class Session;
+
+class PluginInfo {
+ public:
+ enum Type {
+ LADSPA,
+ VST
+ };
+
+ PluginInfo () { };
+ PluginInfo (const PluginInfo &o)
+ : name(o.name), n_inputs(o.n_inputs), n_outputs(o.n_outputs),
+ path (o.path), index(o.index) {}
+ ~PluginInfo () { };
+ string name;
+ string category;
+ uint32_t n_inputs;
+ uint32_t n_outputs;
+ Type type;
+
+ private:
+ friend class PluginManager;
+ string path;
+ uint32_t index;
+};
+
+class Plugin : public Stateful, public sigc::trackable
+
+{
+ public:
+ Plugin (ARDOUR::AudioEngine&, ARDOUR::Session&);
+ Plugin (const Plugin&);
+ ~Plugin ();
+
+ struct ParameterDescriptor {
+
+ /* essentially a union of LADSPA and VST info */
+
+ bool integer_step;
+ bool toggled;
+ bool logarithmic;
+ bool sr_dependent;
+ string label;
+ float lower;
+ float upper;
+ float step;
+ float smallstep;
+ float largestep;
+
+ bool min_unbound;
+ bool max_unbound;
+ };
+
+ virtual uint32_t unique_id() const = 0;
+ virtual const char * label() const = 0;
+ virtual const char * name() const = 0;
+ virtual const char * maker() const = 0;
+ virtual uint32_t parameter_count () const = 0;
+ virtual float default_value (uint32_t port) = 0;
+ virtual jack_nframes_t latency() const = 0;
+ virtual void set_parameter (uint32_t which, float val) = 0;
+ virtual float get_parameter(uint32_t which) const = 0;
+
+ virtual int get_parameter_descriptor (uint32_t which, ParameterDescriptor&) const = 0;
+ virtual uint32_t nth_parameter (uint32_t which, bool& ok) const = 0;
+ virtual void activate () = 0;
+ virtual void deactivate () = 0;
+ virtual void set_block_size (jack_nframes_t nframes) = 0;
+
+ virtual int connect_and_run (vector<Sample*>& bufs, uint32_t maxbuf, int32_t& in, int32_t& out, jack_nframes_t nframes, jack_nframes_t offset) = 0;
+ virtual std::set<uint32_t> automatable() const = 0;
+ virtual void store_state (ARDOUR::PluginState&) = 0;
+ virtual void restore_state (ARDOUR::PluginState&) = 0;
+ virtual string describe_parameter (uint32_t) = 0;
+ virtual string state_node_name() const = 0;
+ virtual void print_parameter (uint32_t, char*, uint32_t len) const = 0;
+
+ virtual bool parameter_is_audio(uint32_t) const = 0;
+ virtual bool parameter_is_control(uint32_t) const = 0;
+ virtual bool parameter_is_input(uint32_t) const = 0;
+ virtual bool parameter_is_output(uint32_t) const = 0;
+
+ virtual bool save_preset(string name) = 0;
+ virtual bool load_preset (const string preset_label);
+ virtual list<string> get_presets();
+
+ virtual bool has_editor() const = 0;
+
+ sigc::signal<void,uint32_t,float> ParameterChanged;
+ sigc::signal<void,Plugin *> GoingAway;
+
+ void reset_midi_control (MIDI::Port*, bool);
+ void send_all_midi_feedback ();
+ MIDI::byte* write_midi_feedback (MIDI::byte*, int32_t& bufsize);
+ MIDI::Controllable *get_nth_midi_control (uint32_t);
+
+ PluginInfo & get_info() { return _info; }
+ void set_info (const PluginInfo &inf) { _info = inf; }
+
+ ARDOUR::AudioEngine& engine() const { return _engine; }
+ ARDOUR::Session& session() const { return _session; }
+
+ void set_cycles (uint32_t c) { _cycles = c; }
+ cycles_t cycles() const { return _cycles; }
+
+ protected:
+ ARDOUR::AudioEngine& _engine;
+ ARDOUR::Session& _session;
+ PluginInfo _info;
+ uint32_t _cycles;
+ map<string,string> presets;
+ bool save_preset(string name, string domain /* vst, ladspa etc. */);
+
+ void setup_midi_controls ();
+
+
+ struct MIDIPortControl : public MIDI::Controllable {
+ MIDIPortControl (Plugin&, uint32_t abs_port_id, MIDI::Port *,
+ float lower, float upper, bool toggled, bool logarithmic);
+
+ void set_value (float);
+ void send_feedback (float);
+ MIDI::byte* write_feedback (MIDI::byte* buf, int32_t& bufsize, float val, bool force = false);
+
+ Plugin& plugin;
+ uint32_t absolute_port;
+ float upper;
+ float lower;
+ float range;
+ bool toggled;
+ bool logarithmic;
+
+ bool setting;
+ float last_written;
+ };
+
+ vector<MIDIPortControl*> midi_controls;
+
+
+};
+
+/* this is actually defined in plugin_manager.cc */
+
+Plugin * find_plugin(ARDOUR::Session&, string name, PluginInfo::Type);
+
+} // namespace ARDOUR
+
+#endif /* __ardour_plugin_h__ */
diff --git a/libs/ardour/ardour/plugin_manager.h b/libs/ardour/ardour/plugin_manager.h
new file mode 100644
index 0000000000..1a07c67c8d
--- /dev/null
+++ b/libs/ardour/ardour/plugin_manager.h
@@ -0,0 +1,63 @@
+#ifndef __ardour_plugin_manager_h__
+#define __ardour_plugin_manager_h__
+
+#include <list>
+#include <map>
+#include <string>
+
+#include <ardour/types.h>
+
+namespace ARDOUR {
+
+class PluginInfo;
+class Plugin;
+class Session;
+class AudioEngine;
+
+class PluginManager {
+ public:
+ PluginManager (ARDOUR::AudioEngine&);
+ ~PluginManager ();
+
+ std::list<PluginInfo*> &vst_plugin_info () { return _vst_plugin_info; }
+ std::list<PluginInfo*> &ladspa_plugin_info () { return _ladspa_plugin_info; }
+ void refresh ();
+
+ int add_ladspa_directory (std::string dirpath);
+ int add_vst_directory (std::string dirpath);
+
+ Plugin *load (ARDOUR::Session& s, PluginInfo* info);
+
+ static PluginManager* the_manager() { return _manager; }
+
+ private:
+ ARDOUR::AudioEngine& _engine;
+ std::list<PluginInfo*> _vst_plugin_info;
+ std::list<PluginInfo*> _ladspa_plugin_info;
+ std::map<uint32_t, std::string> rdf_type;
+
+ std::string ladspa_path;
+ std::string vst_path;
+
+ void ladspa_refresh ();
+ void vst_refresh ();
+
+ void add_lrdf_data (const std::string &path);
+ void add_ladspa_presets ();
+ void add_vst_presets ();
+ void add_presets (std::string domain);
+
+ int vst_discover_from_path (std::string path);
+ int vst_discover (std::string path);
+
+ int ladspa_discover_from_path (std::string path);
+ int ladspa_discover (std::string path);
+
+ std::string get_ladspa_category (uint32_t id);
+
+ static PluginManager* _manager; // singleton
+};
+
+} /* namespace ARDOUR */
+
+#endif /* __ardour_plugin_manager_h__ */
diff --git a/libs/ardour/ardour/plugin_state.h b/libs/ardour/ardour/plugin_state.h
new file mode 100644
index 0000000000..bd499e2b90
--- /dev/null
+++ b/libs/ardour/ardour/plugin_state.h
@@ -0,0 +1,14 @@
+#ifndef __ardour_plugin_state_h__
+#define __ardour_plugin_state_h__
+
+#include <map>
+
+namespace ARDOUR {
+
+struct PluginState {
+ std::map<uint32_t,float> parameters;
+};
+
+}
+
+#endif /* __ardour_plugin_state_h__ */
diff --git a/libs/ardour/ardour/port.h b/libs/ardour/ardour/port.h
new file mode 100644
index 0000000000..e5edcf72ac
--- /dev/null
+++ b/libs/ardour/ardour/port.h
@@ -0,0 +1,213 @@
+/*
+ Copyright (C) 2002 Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __ardour_port_h__
+#define __ardour_port_h__
+
+#include <sigc++/signal.h>
+#include <pbd/failed_constructor.h>
+#include <ardour/ardour.h>
+#include <jack/jack.h>
+
+namespace ARDOUR {
+
+class AudioEngine;
+
+class Port : public sigc::trackable {
+ public:
+ virtual ~Port() {
+ free (port);
+ }
+
+ Sample *get_buffer (jack_nframes_t nframes) {
+ if (_flags & JackPortIsOutput) {
+ return _buffer;
+ } else {
+ return (Sample *) jack_port_get_buffer (port, nframes);
+ }
+ }
+
+ void reset_buffer () {
+ if (_flags & JackPortIsOutput) {
+ _buffer = (Sample *) jack_port_get_buffer (port, 0);
+ } else {
+ _buffer = 0; /* catch illegal attempts to use it */
+ }
+ silent = false;
+ }
+
+ string name() {
+ return _name;
+ }
+
+ string short_name() {
+ return jack_port_short_name (port);
+ }
+
+ int set_name (string str);
+
+ JackPortFlags flags() const {
+ return _flags;
+ }
+
+ bool is_mine (jack_client_t *client) {
+ return jack_port_is_mine (client, port);
+ }
+
+ const char* type() const {
+ return _type.c_str();
+ }
+
+ int connected () const {
+ return jack_port_connected (port);
+ }
+
+ bool connected_to (const string& portname) const {
+ return jack_port_connected_to (port, portname.c_str());
+ }
+
+ const char ** get_connections () const {
+ return jack_port_get_connections (port);
+ }
+
+ void reset_overs () {
+ _short_overs = 0;
+ _long_overs = 0;
+ overlen = 0;
+ }
+
+ void reset_peak_meter () {
+ _peak = 0;
+ }
+
+ void reset_meters () {
+ reset_peak_meter ();
+ reset_overs ();
+ }
+
+ void enable_metering() {
+ metering++;
+ }
+
+ void disable_metering () {
+ if (metering) { metering--; }
+ }
+
+ float peak_db() const { return _peak_db; }
+ jack_default_audio_sample_t peak() const { return _peak; }
+
+ uint32_t short_overs () const { return _short_overs; }
+ uint32_t long_overs () const { return _long_overs; }
+
+ static void set_short_over_length (jack_nframes_t);
+ static void set_long_over_length (jack_nframes_t);
+
+ bool receives_input() const {
+ return _flags & JackPortIsInput;
+ }
+
+ bool sends_output () const {
+ return _flags & JackPortIsOutput;
+ }
+
+ bool monitoring_input () const {
+ return jack_port_monitoring_input (port);
+ }
+
+ bool can_monitor () const {
+ return _flags & JackPortCanMonitor;
+ }
+
+ void ensure_monitor_input (bool yn) {
+ jack_port_request_monitor (port, yn);
+ }
+
+ void request_monitor_input (bool yn) {
+ jack_port_request_monitor (port, yn);
+ }
+
+ jack_nframes_t latency () const {
+ return jack_port_get_latency (port);
+ }
+
+ void set_latency (jack_nframes_t nframes) {
+ jack_port_set_latency (port, nframes);
+ }
+
+ sigc::signal<void,bool> MonitorInputChanged;
+ sigc::signal<void,bool> ClockSyncChanged;
+
+ bool is_silent() const { return silent; }
+
+ void silence (jack_nframes_t nframes, jack_nframes_t offset) {
+ /* assumes that the port is an output port */
+
+ if (!silent) {
+ memset (_buffer + offset, 0, sizeof (Sample) * nframes);
+ if (offset == 0) {
+ /* XXX this isn't really true, but i am not sure
+ how to set this correctly. we really just
+ want to set it true when the entire port
+ buffer has been overrwritten.
+ */
+ silent = true;
+ }
+ }
+ }
+
+ void mark_silence (bool yn) {
+ silent = yn;
+ }
+
+ private:
+ friend class AudioEngine;
+
+ Port (jack_port_t *port);
+ void reset ();
+
+ /* engine isn't supposed to below here */
+
+ Sample *_buffer;
+
+ /* cache these 3 from JACK so that we can
+ access them for reconnecting.
+ */
+
+ JackPortFlags _flags;
+ string _type;
+ string _name;
+
+ bool last_monitor : 1;
+ bool silent : 1;
+ jack_port_t *port;
+ jack_nframes_t overlen;
+ jack_default_audio_sample_t _peak;
+ float _peak_db;
+ uint32_t _short_overs;
+ uint32_t _long_overs;
+ unsigned short metering;
+
+ static jack_nframes_t long_over_length;
+ static jack_nframes_t short_over_length;
+};
+
+}; /* namespace ARDOUR */
+
+#endif /* __ardour_port_h__ */
diff --git a/libs/ardour/ardour/recent_sessions.h b/libs/ardour/ardour/recent_sessions.h
new file mode 100644
index 0000000000..9b1beea4af
--- /dev/null
+++ b/libs/ardour/ardour/recent_sessions.h
@@ -0,0 +1,39 @@
+/*
+ Copyright (C) 2004 Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef __ardour_recent_sessions_h__
+#define __ardour_recent_sessions__h__
+
+#include <deque>
+#include <utility>
+#include <string>
+
+using std::deque;
+using std::pair;
+using std::string;
+
+namespace ARDOUR {
+ typedef deque<pair<string,string> > RecentSessions;
+
+ int read_recent_sessions (RecentSessions& rs);
+ int store_recent_sessions (string name, string path);
+ int write_recent_sessions (RecentSessions& rs);
+}; // namespace ARDOUR
+
+#endif // __ardour_recent_sessions_h__
diff --git a/libs/ardour/ardour/redirect.h b/libs/ardour/ardour/redirect.h
new file mode 100644
index 0000000000..fc7de9d814
--- /dev/null
+++ b/libs/ardour/ardour/redirect.h
@@ -0,0 +1,153 @@
+/*
+ Copyright (C) 2001 Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __ardour_redirect_h__
+#define __ardour_redirect_h__
+
+#include <string>
+#include <vector>
+#include <set>
+#include <map>
+#include <sigc++/signal.h>
+
+#include <pbd/lockmonitor.h>
+#include <pbd/undo.h>
+
+#include <ardour/ardour.h>
+#include <ardour/io.h>
+#include <ardour/automation_event.h>
+
+using std::map;
+using std::set;
+using std::string;
+using std::vector;
+
+class XMLNode;
+
+namespace ARDOUR {
+
+class Session;
+
+struct RedirectState : public StateManager::State {
+ RedirectState (string why)
+ : StateManager::State (why) {}
+ ~RedirectState () {}
+
+ bool active;
+};
+
+class Redirect : public IO
+{
+ public:
+ static const string state_node_name;
+
+ Redirect (Session&, const string& name, Placement,
+ int input_min = -1, int input_max = -1, int output_min = -1, int output_max = -1);
+ Redirect (const Redirect&);
+ virtual ~Redirect ();
+
+ static Redirect *clone (const Redirect&);
+
+ bool active () const { return _active; }
+ void set_active (bool yn, void *src);
+
+ virtual uint32_t output_streams() const { return n_outputs(); }
+ virtual uint32_t input_streams () const { return n_inputs(); }
+ virtual uint32_t natural_output_streams() const { return n_outputs(); }
+ virtual uint32_t natural_input_streams () const { return n_inputs(); }
+
+ uint32_t sort_key() const { return _sort_key; }
+ void set_sort_key (uint32_t sk,void *src) { _sort_key = sk; sort_key_changed (this, src); }
+
+ Placement placement() const { return _placement; }
+ void set_placement (Placement, void *src);
+
+ virtual void run (vector<Sample *>& ibufs, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset) = 0;
+ virtual void activate () = 0;
+ virtual void deactivate () = 0;
+ virtual jack_nframes_t latency() { return 0; }
+
+ virtual void set_block_size (jack_nframes_t nframes) {}
+
+ sigc::signal<void,Redirect*,void*> active_changed;
+ sigc::signal<void,Redirect*,void*> sort_key_changed;
+ sigc::signal<void,Redirect*,void*> placement_changed;
+ sigc::signal<void,Redirect*,bool> AutomationPlaybackChanged;
+ sigc::signal<void,Redirect*,uint32_t> AutomationChanged;
+ sigc::signal<void,Redirect*> GoingAway;
+
+ static sigc::signal<void,Redirect*> RedirectCreated;
+
+ XMLNode& state (bool full);
+ XMLNode& get_state (void);
+ int set_state (const XMLNode&);
+
+ StateManager::State* state_factory (string why) const;
+ Change restore_state (StateManager::State&);
+
+ void *get_gui () const { return _gui; }
+ void set_gui (void *p) { _gui = p; }
+
+ virtual string describe_parameter (uint32_t which);
+ virtual float default_parameter_value (uint32_t which) {
+ return 1.0f;
+ }
+
+ int load_automation (string path);
+ int save_automation (string path);
+
+ void what_has_automation (set<uint32_t>&) const;
+ void what_has_visible_automation (set<uint32_t>&) const;
+ const set<uint32_t>& what_can_be_automated () const { return can_automate_list; }
+
+ void mark_automation_visible (uint32_t, bool);
+
+ AutomationList& automation_list (uint32_t);
+ bool find_next_event (jack_nframes_t, jack_nframes_t, ControlEvent&) const;
+
+ virtual void transport_stopped (jack_nframes_t frame) {};
+
+ protected:
+ void set_placement (const string&, void *src);
+
+ /* children may use this stuff as they see fit */
+
+ map<uint32_t,AutomationList*> parameter_automation;
+ set<uint32_t> visible_parameter_automation;
+
+ mutable PBD::NonBlockingLock _automation_lock;
+
+ void can_automate (uint32_t);
+ set<uint32_t> can_automate_list;
+
+ void store_state (RedirectState&) const;
+
+ virtual void automation_list_creation_callback (uint32_t, AutomationList&) {}
+
+ private:
+ bool _active;
+ Placement _placement;
+ uint32_t _sort_key;
+ void* _gui; /* generic, we don't know or care what this is */
+};
+
+}; /* namespace ARDOUR */
+
+#endif /* __ardour_redirect_h__ */
diff --git a/libs/ardour/ardour/region.h b/libs/ardour/ardour/region.h
new file mode 100644
index 0000000000..e067f56f44
--- /dev/null
+++ b/libs/ardour/ardour/region.h
@@ -0,0 +1,259 @@
+/*
+ Copyright (C) 2000-2001 Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __ardour_region_h__
+#define __ardour_region_h__
+
+#include <pbd/undo.h>
+
+#include <ardour/ardour.h>
+#include <ardour/logcurve.h>
+#include <ardour/state_manager.h>
+
+class XMLNode;
+
+namespace ARDOUR {
+
+class Playlist;
+class Source;
+
+enum RegionEditState {
+ EditChangesNothing = 0,
+ EditChangesName = 1,
+ EditChangesID = 2
+};
+
+struct RegionState : public StateManager::State {
+
+ RegionState (std::string why) : StateManager::State (why) {}
+
+ jack_nframes_t _start;
+ jack_nframes_t _length;
+ jack_nframes_t _position;
+ uint32_t _flags;
+ jack_nframes_t _sync_position;
+ layer_t _layer;
+ string _name;
+ mutable RegionEditState _first_edit;
+};
+
+class Region : public Stateful, public StateManager
+{
+ public:
+ enum Flag {
+ Muted = 0x1,
+ Opaque = 0x2,
+ EnvelopeActive = 0x4,
+ DefaultFadeIn = 0x8,
+ DefaultFadeOut = 0x10,
+ Locked = 0x20,
+ Automatic = 0x40,
+ WholeFile = 0x80,
+ FadeIn = 0x100,
+ FadeOut = 0x200,
+ Copied = 0x400,
+ Import = 0x800,
+ External = 0x1000,
+ SyncMarked = 0x2000,
+ LeftOfSplit = 0x4000,
+ RightOfSplit = 0x8000,
+ Hidden = 0x10000,
+ DoNotSaveState = 0x20000,
+ //
+ range_guarantoor = USHRT_MAX
+ };
+
+ static const Flag DefaultFlags = Flag (Opaque|DefaultFadeIn|DefaultFadeOut|FadeIn|FadeOut);
+
+ static Change FadeChanged;
+ static Change SyncOffsetChanged;
+ static Change MuteChanged;
+ static Change OpacityChanged;
+ static Change LockChanged;
+ static Change LayerChanged;
+ static Change HiddenChanged;
+
+ Region (jack_nframes_t start, jack_nframes_t length,
+ const string& name, layer_t = 0, Flag flags = DefaultFlags);
+ Region (const Region&, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t = 0, Flag flags = DefaultFlags);
+ Region (const Region&);
+ Region (const XMLNode&);
+ ~Region();
+
+ ARDOUR::id_t id() const { return _id; }
+
+ /* Note: changing the name of a Region does not constitute an edit */
+
+ string name() const { return _name; }
+ void set_name (string str);
+
+ jack_nframes_t position () const { return _position; }
+ jack_nframes_t start () const { return _start; }
+ jack_nframes_t length() const { return _length; }
+ layer_t layer () const { return _layer; }
+ jack_nframes_t sync_offset(int& dir) const;
+ jack_nframes_t sync_position() const;
+
+ jack_nframes_t adjust_to_sync (jack_nframes_t);
+
+ /* first_frame() is an alias; last_frame() just hides some math */
+
+ jack_nframes_t first_frame() const { return _position; }
+ jack_nframes_t last_frame() const { return _position + _length - 1; }
+
+ bool hidden() const { return _flags & Hidden; }
+ bool muted() const { return _flags & Muted; }
+ bool opaque () const { return _flags & Opaque; }
+ bool envelope_active () const { return _flags & EnvelopeActive; }
+ bool locked() const { return _flags & Locked; }
+ bool automatic() const { return _flags & Automatic; }
+ bool whole_file() const { return _flags & WholeFile ; }
+ Flag flags() const { return _flags; }
+
+ virtual bool should_save_state () const { return !(_flags & DoNotSaveState); };
+
+ void freeze ();
+ void thaw (const string& why);
+
+ bool covers (jack_nframes_t frame) const {
+ return _position <= frame && frame < _position + _length;
+ }
+
+ OverlapType coverage (jack_nframes_t start, jack_nframes_t end) const {
+ return ARDOUR::coverage (_position, _position + _length - 1, start, end);
+ }
+
+ virtual jack_nframes_t read_at (Sample *buf, Sample *mixdown_buffer,
+ float *gain_buffer, jack_nframes_t position, jack_nframes_t cnt,
+ uint32_t chan_n = 0,
+ jack_nframes_t read_frames = 0,
+ jack_nframes_t skip_frames = 0) const = 0;
+
+ /* EDITING OPERATIONS */
+
+ void set_length (jack_nframes_t, void *src);
+ void set_start (jack_nframes_t, void *src);
+ void set_position (jack_nframes_t, void *src);
+ void set_position_on_top (jack_nframes_t, void *src);
+ void special_set_position (jack_nframes_t);
+ void nudge_position (long, void *src);
+
+ void move_to_natural_position (void *src);
+
+ void trim_start (jack_nframes_t new_position, void *src);
+ void trim_front (jack_nframes_t new_position, void *src);
+ void trim_end (jack_nframes_t new_position, void *src);
+ void trim_to (jack_nframes_t position, jack_nframes_t length, void *src);
+
+ void set_layer (layer_t l); /* ONLY Playlist can call this */
+ void raise ();
+ void lower ();
+ void raise_to_top ();
+ void lower_to_bottom ();
+
+ void set_sync_position (jack_nframes_t n);
+ void clear_sync_position ();
+ void set_hidden (bool yn);
+ void set_muted (bool yn);
+ void set_opaque (bool yn);
+ void set_envelope_active (bool yn);
+ void set_locked (bool yn);
+
+ virtual uint32_t read_data_count() const { return _read_data_count; }
+
+ ARDOUR::Playlist* playlist() const { return _playlist; }
+
+ virtual UndoAction get_memento() const = 0;
+
+ void set_playlist (ARDOUR::Playlist*);
+
+ virtual void lock_sources () {}
+ virtual void unlock_sources () {}
+
+ /* serialization */
+
+ virtual XMLNode& state (bool);
+ XMLNode& get_state ();
+ int set_state (const XMLNode&);
+
+ sigc::signal<void,Region*> GoingAway;
+
+ /* This is emitted only when a new id is assigned. Therefore,
+ in a pure Region copy, it will not be emitted.
+
+ It must be emitted by derived classes, not Region
+ itself, to permit dynamic_cast<> to be used to
+ infer the type of Region.
+ */
+
+ static sigc::signal<void,Region*> CheckNewRegion;
+
+ virtual Region* get_parent() = 0;
+
+ uint64_t last_layer_op() const { return _last_layer_op; }
+ void set_last_layer_op (uint64_t when);
+
+ protected:
+
+ jack_nframes_t _start;
+ jack_nframes_t _length;
+ jack_nframes_t _position;
+ Flag _flags;
+ jack_nframes_t _sync_position;
+ layer_t _layer;
+ string _name;
+ mutable RegionEditState _first_edit;
+ int _frozen;
+ PBD::Lock lock;
+ ARDOUR::id_t _id;
+ ARDOUR::Playlist* _playlist;
+ mutable uint32_t _read_data_count; // modified in read()
+ Change pending_changed;
+ uint64_t _last_layer_op; // timestamp
+
+ XMLNode& get_short_state (); /* used only by Session */
+
+ /* state management */
+
+ void send_change (Change);
+ void send_state_changed ();
+
+ /* derived classes need these during their own state management calls */
+
+ void store_state (RegionState&) const;
+ Change restore_and_return_flags (RegionState&);
+
+ void trim_to_internal (jack_nframes_t position, jack_nframes_t length, void *src);
+
+ bool copied() const { return _flags & Copied; }
+ void maybe_uncopy ();
+ void first_edit ();
+
+ virtual bool verify_start (jack_nframes_t) = 0;
+ virtual bool verify_start_and_length (jack_nframes_t, jack_nframes_t) = 0;
+ virtual bool verify_start_mutable (jack_nframes_t&_start) = 0;
+ virtual bool verify_length (jack_nframes_t) = 0;
+ virtual void recompute_at_start () = 0;
+ virtual void recompute_at_end () = 0;
+};
+
+} /* namespace ARDOUR */
+
+#endif /* __ardour_region_h__ */
diff --git a/libs/ardour/ardour/region_factory.h b/libs/ardour/ardour/region_factory.h
new file mode 100644
index 0000000000..f72c0a52d8
--- /dev/null
+++ b/libs/ardour/ardour/region_factory.h
@@ -0,0 +1,22 @@
+#ifndef __ardour_region_factory_h__
+#define __ardour_region_factory_h__
+
+#include <ardour/types.h>
+#include <ardour/region.h>
+
+class XMLNode;
+
+namespace ARDOUR {
+
+class Session;
+
+Region* createRegion (const Region&, jack_nframes_t start,
+ jack_nframes_t length, std::string name,
+ layer_t = 0, Region::Flag flags = Region::DefaultFlags);
+// Region* createRegion (const Region&, std::string name);
+Region* createRegion (const Region&);
+Region* createRegion (Session&, XMLNode&, bool);
+
+}
+
+#endif /* __ardour_region_factory_h__ */
diff --git a/libs/ardour/ardour/reverse.h b/libs/ardour/ardour/reverse.h
new file mode 100644
index 0000000000..05ea8a1353
--- /dev/null
+++ b/libs/ardour/ardour/reverse.h
@@ -0,0 +1,38 @@
+/*
+ Copyright (C) 2004 Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __ardour_reverse_h__
+#define __ardour_reverse_h__
+
+#include <ardour/audiofilter.h>
+
+namespace ARDOUR {
+
+class Reverse : public AudioFilter {
+ public:
+ Reverse (ARDOUR::Session&);
+ ~Reverse ();
+
+ int run (ARDOUR::AudioRegion&);
+};
+
+} /* namespace */
+
+#endif /* __ardour_reverse_h__ */
diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h
new file mode 100644
index 0000000000..8f4028c99f
--- /dev/null
+++ b/libs/ardour/ardour/route.h
@@ -0,0 +1,359 @@
+/*
+ Copyright (C) 2000-2002 Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __ardour_route_h__
+#define __ardour_route_h__
+
+#include <cmath>
+#include <list>
+#include <set>
+#include <map>
+#include <string>
+
+#include <pthread.h>
+
+#include <pbd/atomic.h>
+#include <pbd/fastlog.h>
+#include <pbd/lockmonitor.h>
+#include <pbd/xml++.h>
+#include <pbd/undo.h>
+#include <midi++/controllable.h>
+
+#include <ardour/ardour.h>
+#include <ardour/stateful.h>
+#include <ardour/io.h>
+#include <ardour/session.h>
+#include <ardour/redirect.h>
+
+namespace ARDOUR {
+
+class Insert;
+class Send;
+class RouteGroup;
+
+enum mute_type {
+ PRE_FADER = 0x1,
+ POST_FADER = 0x2,
+ CONTROL_OUTS = 0x4,
+ MAIN_OUTS = 0x8
+};
+
+class Route : public IO
+{
+ private:
+ typedef list<Redirect *> RedirectList;
+
+ public:
+
+ enum Flag {
+ Hidden = 0x1,
+ MasterOut = 0x2,
+ ControlOut = 0x4,
+ };
+
+
+ Route (Session&, std::string name, int input_min, int input_max, int output_min, int output_max, Flag flags = Flag(0));
+ Route (Session&, const XMLNode&);
+ virtual ~Route();
+
+ std::string comment() { return _comment; }
+ void set_comment (std::string str, void *src);
+
+ long order_key(std::string name) const;
+ void set_order_key (std::string name, long n);
+
+ bool hidden() const { return _flags & Hidden; }
+ bool master() const { return _flags & MasterOut; }
+ bool control() const { return _flags & ControlOut; }
+
+ /* these are the core of the API of a Route. see the protected sections as well */
+
+
+ virtual int roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame,
+ jack_nframes_t offset, int declick, bool can_record, bool rec_monitors_input);
+
+ virtual int no_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame,
+ jack_nframes_t offset, bool state_changing, bool can_record, bool rec_monitors_input);
+
+ virtual int silent_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame,
+ jack_nframes_t offset, bool can_record, bool rec_monitors_input);
+ virtual void toggle_monitor_input ();
+ virtual bool can_record() const { return false; }
+ virtual void set_record_enable (bool yn, void *src) {}
+ virtual bool record_enabled() const { return false; }
+ virtual void transport_stopped (bool abort, bool did_locate, bool flush_redirects);
+ virtual void set_pending_declick (int);
+
+ /* end of vfunc-based API */
+
+ /* override IO::set_gain() to provide group control */
+
+ void set_gain (gain_t val, void *src);
+ void inc_gain (gain_t delta, void *src);
+
+ bool active() const { return _active; }
+ void set_active (bool yn);
+
+ void set_solo (bool yn, void *src);
+ bool soloed() const { return _soloed; }
+
+ void set_solo_safe (bool yn, void *src);
+ bool solo_safe() const { return _solo_safe; }
+
+ void set_mute (bool yn, void *src);
+ bool muted() const { return _muted; }
+
+ void set_mute_config (mute_type, bool, void *src);
+ bool get_mute_config (mute_type);
+
+ void set_phase_invert (bool yn, void *src);
+ bool phase_invert() const { return _phase_invert; }
+
+ void set_edit_group (RouteGroup *, void *);
+ RouteGroup *edit_group () { return _edit_group; }
+
+ void set_mix_group (RouteGroup *, void *);
+ RouteGroup *mix_group () { return _mix_group; }
+
+ virtual void set_meter_point (MeterPoint, void *src);
+ MeterPoint meter_point() const { return _meter_point; }
+
+ /* Redirects */
+
+ void flush_redirects ();
+
+ template<class T> void foreach_redirect (T *obj, void (T::*func)(Redirect *)) {
+ LockMonitor lm (redirect_lock, __LINE__, __FILE__);
+ for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
+ (obj->*func) (*i);
+ }
+ }
+
+ Redirect *nth_redirect (uint32_t n) {
+ LockMonitor lm (redirect_lock, __LINE__, __FILE__);
+ RedirectList::iterator i;
+ for (i = _redirects.begin(); i != _redirects.end() && n; ++i, --n);
+ if (i == _redirects.end()) {
+ return 0;
+ } else {
+ return *i;
+ }
+ }
+
+ uint32_t max_redirect_outs () const { return redirect_max_outs; }
+
+ int add_redirect (Redirect *, void *src, uint32_t* err_streams = 0);
+ int add_redirects (const RedirectList&, void *src, uint32_t* err_streams = 0);
+ int remove_redirect (Redirect *, void *src, uint32_t* err_streams = 0);
+ int copy_redirects (const Route&, Placement, uint32_t* err_streams = 0);
+ int sort_redirects (uint32_t* err_streams = 0);
+
+ void clear_redirects (void *src);
+ void all_redirects_flip();
+ void all_redirects_active (bool state);
+
+ virtual jack_nframes_t update_total_latency();
+ jack_nframes_t signal_latency() const { return _own_latency; }
+ virtual void set_latency_delay (jack_nframes_t);
+
+ sigc::signal<void,void*> solo_changed;
+ sigc::signal<void,void*> solo_safe_changed;
+ sigc::signal<void,void*> comment_changed;
+ sigc::signal<void,void*> mute_changed;
+ sigc::signal<void,void*> pre_fader_changed;
+ sigc::signal<void,void*> post_fader_changed;
+ sigc::signal<void,void*> control_outs_changed;
+ sigc::signal<void,void*> main_outs_changed;
+ sigc::signal<void,void*> redirects_changed;
+ sigc::signal<void,void*> record_enable_changed;
+ sigc::signal<void,void*> edit_group_changed;
+ sigc::signal<void,void*> mix_group_changed;
+ sigc::signal<void> active_changed;
+ sigc::signal<void,void*> meter_change;
+
+ sigc::signal<void> GoingAway;
+
+ /* gui's call this for their own purposes. */
+
+ sigc::signal<void,std::string,void*> gui_changed;
+
+ /* stateful */
+
+ XMLNode& get_state();
+ int set_state(const XMLNode& node);
+ XMLNode& get_template();
+
+ sigc::signal<void,void*> SelectedChanged;
+
+ /* undo */
+
+ UndoAction get_memento() const;
+ void set_state (state_id_t);
+
+ int set_control_outs (const vector<std::string>& ports);
+ IO* control_outs() { return _control_outs; }
+
+ bool feeds (Route *);
+ set<Route *> fed_by;
+
+ struct MIDIToggleControl : public MIDI::Controllable {
+ enum ToggleType {
+ MuteControl = 0,
+ SoloControl
+ };
+
+ MIDIToggleControl (Route&, ToggleType, MIDI::Port *);
+ void set_value (float);
+ void send_feedback (bool);
+ MIDI::byte* write_feedback (MIDI::byte* buf, int32_t& bufsize, bool val, bool force = false);
+
+ Route& route;
+ ToggleType type;
+ bool setting;
+ bool last_written;
+ };
+
+ MIDI::Controllable& midi_solo_control() {
+ return _midi_solo_control;
+ }
+ MIDI::Controllable& midi_mute_control() {
+ return _midi_mute_control;
+ }
+
+ virtual void reset_midi_control (MIDI::Port*, bool);
+ virtual void send_all_midi_feedback ();
+ virtual MIDI::byte* write_midi_feedback (MIDI::byte*, int32_t& bufsize);
+
+ void automation_snapshot (jack_nframes_t now);
+
+ void protect_automation ();
+
+ protected:
+ friend class Session;
+
+ void set_solo_mute (bool yn);
+ void set_block_size (jack_nframes_t nframes);
+ bool has_external_redirects() const;
+ void curve_reallocate ();
+
+ protected:
+ unsigned char _flags;
+
+ /* tight cache-line access here is more important than sheer speed of
+ access.
+ */
+
+ bool _muted : 1;
+ bool _soloed : 1;
+ bool _solo_muted : 1;
+ bool _solo_safe : 1;
+ bool _phase_invert : 1;
+ bool _recordable : 1;
+ bool _active : 1;
+ bool _mute_affects_pre_fader : 1;
+ bool _mute_affects_post_fader : 1;
+ bool _mute_affects_control_outs : 1;
+ bool _mute_affects_main_outs : 1;
+ bool _silent : 1;
+ bool _declickable : 1;
+ int _pending_declick;
+
+ MeterPoint _meter_point;
+
+ gain_t solo_gain;
+ gain_t mute_gain;
+ gain_t desired_solo_gain;
+ gain_t desired_mute_gain;
+
+ jack_nframes_t check_initial_delay (jack_nframes_t, jack_nframes_t&, jack_nframes_t&);
+
+ jack_nframes_t _initial_delay;
+ jack_nframes_t _roll_delay;
+ jack_nframes_t _own_latency;
+ RedirectList _redirects;
+ PBD::NonBlockingLock redirect_lock;
+ IO *_control_outs;
+ PBD::NonBlockingLock control_outs_lock;
+ RouteGroup *_edit_group;
+ RouteGroup *_mix_group;
+ std::string _comment;
+ bool _have_internal_generator;
+
+ MIDIToggleControl _midi_solo_control;
+ MIDIToggleControl _midi_mute_control;
+
+ void passthru (jack_nframes_t start_frame, jack_nframes_t end_frame,
+ jack_nframes_t nframes, jack_nframes_t offset, int declick, bool meter_inputs);
+
+ void process_output_buffers (vector<Sample*>& bufs, uint32_t nbufs,
+ jack_nframes_t start_frame, jack_nframes_t end_frame,
+ jack_nframes_t nframes, jack_nframes_t offset, bool with_redirects, int declick,
+ bool meter);
+
+ protected:
+ /* for derived classes */
+
+ virtual XMLNode& state(bool);
+
+ void silence (jack_nframes_t nframes, jack_nframes_t offset);
+ sigc::connection input_signal_connection;
+
+ state_id_t _current_state_id;
+ uint32_t redirect_max_outs;
+
+ uint32_t pans_required() const;
+ uint32_t n_process_buffers ();
+
+ private:
+ void init ();
+
+ static uint32_t order_key_cnt;
+ typedef std::map<std::string,long> OrderKeys;
+ OrderKeys order_keys;
+
+ void input_change_handler (IOChange, void *src);
+ void output_change_handler (IOChange, void *src);
+
+ bool legal_redirect (Redirect&);
+ int reset_plugin_counts (uint32_t*); /* locked */
+ int _reset_plugin_counts (uint32_t*); /* unlocked */
+
+ /* plugin count handling */
+
+ struct InsertCount {
+ ARDOUR::Insert& insert;
+ int32_t cnt;
+ int32_t in;
+ int32_t out;
+
+ InsertCount (ARDOUR::Insert& ins) : insert (ins), cnt (-1) {}
+ };
+
+ int32_t apply_some_plugin_counts (std::list<InsertCount>& iclist);
+ int32_t check_some_plugin_counts (std::list<InsertCount>& iclist, int32_t required_inputs, uint32_t* err_streams);
+
+ void set_deferred_state ();
+ void add_redirect_from_xml (const XMLNode&);
+ void redirect_active_proxy (Redirect*, void*);
+};
+
+}; /* namespace ARDOUR*/
+
+#endif /* __ardour_route_h__ */
diff --git a/libs/ardour/ardour/route_group.h b/libs/ardour/ardour/route_group.h
new file mode 100644
index 0000000000..910500ccf8
--- /dev/null
+++ b/libs/ardour/ardour/route_group.h
@@ -0,0 +1,111 @@
+/*
+ Copyright (C) 2000 Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __ardour_route_group_h__
+#define __ardour_route_group_h__
+
+#include <list>
+#include <string>
+#include <stdint.h>
+#include <sigc++/signal.h>
+#include <ardour/stateful.h>
+#include <ardour/types.h>
+
+using std::string;
+using std::list;
+
+namespace ARDOUR {
+
+class Route;
+class AudioTrack;
+
+class RouteGroup : public Stateful, public sigc::trackable {
+ public:
+ enum Flag {
+ Relative = 0x1,
+ Active = 0x2,
+ Hidden = 0x4,
+ };
+
+ RouteGroup(const string &n, Flag f = Flag(0)) : _name (n), _flags (f) {}
+
+ const string& name() { return _name; }
+
+ bool is_active () const { return _flags & Active; }
+ bool is_relative () const { return _flags & Relative; }
+ bool is_hidden () const { return _flags & Hidden; }
+ bool empty() const {return routes.empty();}
+
+ gain_t get_max_factor(gain_t factor);
+ gain_t get_min_factor(gain_t factor);
+
+ int size() { return routes.size();}
+ ARDOUR::Route * first () const { return *routes.begin();}
+
+ void set_active (bool yn, void *src);
+ void set_relative (bool yn, void *src);
+ void set_hidden (bool yn, void *src);
+
+
+ int add (Route *);
+
+ int remove (Route *);
+
+ template<class T> void apply (void (Route::*func)(T, void *), T val, void *src) {
+ for (list<Route *>::iterator i = routes.begin(); i != routes.end(); i++) {
+ ((*i)->*func)(val, this);
+ }
+ }
+
+ template<class T> void foreach_route (T *obj, void (T::*func)(Route&)) {
+ for (list<Route *>::iterator i = routes.begin(); i != routes.end(); i++) {
+ (obj->*func)(**i);
+ }
+ }
+
+ /* to use these, #include <ardour/route_group_specialized.h> */
+
+ template<class T> void apply (void (AudioTrack::*func)(T, void *), T val, void *src);
+
+ void clear () {
+ routes.clear ();
+ changed();
+ }
+
+ const list<Route*>& route_list() { return routes; }
+
+ sigc::signal<void> changed;
+ sigc::signal<void,void*> FlagsChanged;
+
+ XMLNode& get_state (void);
+
+ int set_state (const XMLNode&);
+
+ private:
+ list<Route *> routes;
+ string _name;
+ uint32_t _flags;
+
+ void remove_when_going_away (Route*);
+};
+
+} /* namespace */
+
+#endif /* __ardour_route_group_h__ */
diff --git a/libs/ardour/ardour/route_group_specialized.h b/libs/ardour/ardour/route_group_specialized.h
new file mode 100644
index 0000000000..32c627eb7a
--- /dev/null
+++ b/libs/ardour/ardour/route_group_specialized.h
@@ -0,0 +1,22 @@
+#ifndef __ardour_route_group_specialized_h__
+#define __ardour_route_group_specialized_h__
+
+#include <ardour/route_group.h>
+#include <ardour/audio_track.h>
+
+namespace ARDOUR {
+
+template<class T> void
+RouteGroup::apply (void (AudioTrack::*func)(T, void *), T val, void *src)
+{
+ for (list<Route *>::iterator i = routes.begin(); i != routes.end(); i++) {
+ AudioTrack *at;
+ if ((at = dynamic_cast<AudioTrack*>(*i)) != 0) {
+ (at->*func)(val, this);
+ }
+ }
+}
+
+} /* namespace ARDOUR */
+
+#endif /* __ardour_route_group_specialized_h__ */
diff --git a/libs/ardour/ardour/send.h b/libs/ardour/ardour/send.h
new file mode 100644
index 0000000000..a94318f2a5
--- /dev/null
+++ b/libs/ardour/ardour/send.h
@@ -0,0 +1,63 @@
+/*
+ Copyright (C) 2000 Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __ardour_send_h__
+#define __ardour_send_h__
+
+#include <sigc++/signal.h>
+#include <string>
+
+#include <ardour/ardour.h>
+#include <ardour/audioengine.h>
+
+#include "io.h"
+#include "stateful.h"
+#include "redirect.h"
+
+namespace ARDOUR {
+
+class Send : public Redirect {
+ public:
+ Send (Session&, Placement);
+ Send (Session&, const XMLNode&);
+ Send (const Send&);
+ ~Send ();
+
+ void run (vector<Sample *> &bufs, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset);
+ void activate() {}
+ void deactivate () {}
+
+ void set_metering (bool yn);
+
+ XMLNode& state(bool full);
+ XMLNode& get_state(void);
+ int set_state(const XMLNode& node);
+
+ uint32_t pans_required() const { return expected_inputs; }
+ void expect_inputs (uint32_t);
+
+ private:
+ bool _metering;
+ uint32_t expected_inputs;
+};
+
+}; /* namespace ARDOUR */
+
+#endif /* __ardour_send_h__ */
diff --git a/libs/ardour/ardour/seqsource.h b/libs/ardour/ardour/seqsource.h
new file mode 100644
index 0000000000..7e38d27915
--- /dev/null
+++ b/libs/ardour/ardour/seqsource.h
@@ -0,0 +1,55 @@
+/*
+ Copyright (C) 2000 Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __playlist_seqsource_h__
+#define __playlist_seqsource_h__
+
+#include <string>
+
+#include "edl.h"
+
+namespace EDL {
+
+class PlaylistSource : public Source {
+ public:
+ PlaylistSource (Playlist&);
+ ~PlaylistSource ();
+
+ const gchar * const id() { return playlist.name().c_str(); }
+ uint32_t length() { return playlist.length(); }
+ uint32_t read (Source::Data *dst, uint32_t start, uint32_t cnt) {
+ return playlist.read (dst, start, cnt, false);
+ }
+ uint32_t write (Source::Data *src, uint32_t where, uint32_t cnt) {
+ return playlist.write (src, where, cnt);
+ }
+
+// int read_peaks (peak_data_t *, uint32_t npeaks, uint32_t start, uint32_t cnt);
+// int build_peak (uint32_t first_frame, uint32_t cnt);
+
+ protected:
+
+ private:
+ Playlist& playlist;
+};
+
+}; /* namespace EDL */
+
+#endif /* __playlist_seqsource_h__ */
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
new file mode 100644
index 0000000000..b58b0a926b
--- /dev/null
+++ b/libs/ardour/ardour/session.h
@@ -0,0 +1,1754 @@
+/*
+ Copyright (C) 2000 Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __ardour_session_h__
+#define __ardour_session_h__
+
+#include <string>
+#if __GNUC__ >= 3
+#include <ext/slist>
+using __gnu_cxx::slist;
+#else
+#include <slist.h>
+#endif
+#include <map>
+#include <vector>
+#include <set>
+#include <stack>
+#include <stdint.h>
+
+#include <sndfile.h>
+
+#include <pbd/error.h>
+#include <pbd/atomic.h>
+#include <pbd/lockmonitor.h>
+#include <pbd/undo.h>
+#include <pbd/pool.h>
+
+#include <midi++/types.h>
+#include <midi++/mmc.h>
+
+#include <ardour/ardour.h>
+#include <ardour/configuration.h>
+#include <ardour/location.h>
+#include <ardour/stateful.h>
+#include <ardour/gain.h>
+#include <ardour/io.h>
+
+class XMLTree;
+class XMLNode;
+class AEffect;
+
+namespace MIDI {
+ class Port;
+}
+
+namespace ARDOUR {
+
+class Port;
+class AudioEngine;
+class Slave;
+class DiskStream;
+class Route;
+class AuxInput;
+class Source;
+class FileSource;
+class Auditioner;
+class Insert;
+class Send;
+class Redirect;
+class PortInsert;
+class PluginInsert;
+class Connection;
+class TempoMap;
+class AudioTrack;
+class NamedSelection;
+class AudioRegion;
+class Region;
+class Playlist;
+class VSTPlugin;
+
+struct AudioExportSpecification;
+struct RouteGroup;
+
+using std::vector;
+using std::string;
+using std::list;
+using std::map;
+using std::set;
+
+class Session : public sigc::trackable, public Stateful
+
+{
+ private:
+ typedef std::pair<Route*,bool> RouteBooleanState;
+ typedef vector<RouteBooleanState> GlobalRouteBooleanState;
+ typedef std::pair<Route*,MeterPoint> RouteMeterState;
+ typedef vector<RouteMeterState> GlobalRouteMeterState;
+
+ public:
+ enum RecordState {
+ Disabled = 0,
+ Enabled = 1,
+ Recording = 2
+ };
+
+ enum SlaveSource {
+ None = 0,
+ MTC,
+ JACK,
+ };
+
+ enum AutoConnectOption {
+ AutoConnectPhysical = 0x1,
+ AutoConnectMaster = 0x2
+ };
+
+ struct Event {
+ enum Type {
+ SetTransportSpeed,
+ SetDiskstreamSpeed,
+ Locate,
+ LocateRoll,
+ SetLoop,
+ PunchIn,
+ PunchOut,
+ RangeStop,
+ RangeLocate,
+ Overwrite,
+ SetSlaveSource,
+ Audition,
+ InputConfigurationChange,
+ SetAudioRange,
+ SetPlayRange,
+
+ /* only one of each of these events
+ can be queued at any one time
+ */
+
+ StopOnce,
+ AutoLoop,
+ };
+
+ enum Action {
+ Add,
+ Remove,
+ Replace,
+ Clear
+ };
+
+ Type type;
+ Action action;
+ jack_nframes_t action_frame;
+ jack_nframes_t target_frame;
+ float speed;
+
+ union {
+ void* ptr;
+ bool yes_or_no;
+ Session::SlaveSource slave;
+ };
+
+ list<AudioRange> audio_range;
+ list<MusicRange> music_range;
+
+ Event(Type t, Action a, jack_nframes_t when, jack_nframes_t where, float spd, bool yn = false)
+ : type (t),
+ action (a),
+ action_frame (when),
+ target_frame (where),
+ speed (spd),
+ yes_or_no (yn) {}
+
+ void set_ptr (void* p) {
+ ptr = p;
+ }
+
+ bool before (const Event& other) const {
+ return action_frame < other.action_frame;
+ }
+
+ bool after (const Event& other) const {
+ return action_frame > other.action_frame;
+ }
+
+ static bool compare (const Event *e1, const Event *e2) {
+ return e1->before (*e2);
+ }
+
+ void *operator new (size_t ignored) {
+ return pool.alloc ();
+ }
+
+ void operator delete(void *ptr, size_t size) {
+ pool.release (ptr);
+ }
+
+ static const jack_nframes_t Immediate = 0;
+
+ private:
+ static MultiAllocSingleReleasePool pool;
+ };
+
+ /* creating from an XML file */
+
+ Session (AudioEngine&,
+ string fullpath,
+ string snapshot_name,
+ string* mix_template = 0);
+
+ /* creating a new Session */
+
+ Session (AudioEngine&,
+ string fullpath,
+ string snapshot_name,
+ AutoConnectOption input_auto_connect,
+ AutoConnectOption output_auto_connect,
+ uint32_t control_out_channels,
+ uint32_t master_out_channels,
+ uint32_t n_physical_in,
+ uint32_t n_physical_out,
+ jack_nframes_t initial_length);
+
+ virtual ~Session ();
+
+
+ static int find_session (string str, string& path, string& snapshot, bool& isnew);
+
+ string path() const { return _path; }
+ string name() const { return _name; }
+ string snap_name() const { return _current_snapshot_name; }
+
+ void set_snap_name ();
+
+ void set_dirty ();
+ void set_clean ();
+ bool dirty() const { return _state_of_the_state & Dirty; }
+ sigc::signal<void> DirtyChanged;
+
+ string sound_dir () const;
+ string peak_dir () const;
+ string dead_sound_dir () const;
+ string automation_dir () const;
+
+ static string template_path ();
+ static string template_dir ();
+ static void get_template_list (list<string>&);
+
+ static string peak_path_from_audio_path (string);
+ static string old_peak_path_from_audio_path (string);
+
+ void process (jack_nframes_t nframes);
+
+ vector<Sample*>& get_passthru_buffers() { return _passthru_buffers; }
+ vector<Sample*>& get_silent_buffers (uint32_t howmany);
+
+ DiskStream *diskstream_by_id (id_t id);
+ DiskStream *diskstream_by_name (string name);
+
+ bool have_captured() const { return _have_captured; }
+
+ void refill_all_diskstream_buffers ();
+ uint32_t diskstream_buffer_size() const { return dstream_buffer_size; }
+ uint32_t get_next_diskstream_id() const { return n_diskstreams(); }
+ uint32_t n_diskstreams() const;
+
+ typedef list<DiskStream *> DiskStreamList;
+
+ Session::DiskStreamList disk_streams() const {
+ LockMonitor lm (diskstream_lock, __LINE__, __FILE__);
+ return diskstreams; /* XXX yes, force a copy */
+ }
+
+ void foreach_diskstream (void (DiskStream::*func)(void));
+ template<class T> void foreach_diskstream (T *obj, void (T::*func)(DiskStream&));
+
+ typedef slist<Route *> RouteList;
+
+ RouteList get_routes() const {
+ LockMonitor rlock (route_lock, __LINE__, __FILE__);
+ return routes; /* XXX yes, force a copy */
+ }
+
+ uint32_t nroutes() const { return routes.size(); }
+ uint32_t ntracks () const;
+ uint32_t nbusses () const;
+
+ struct RoutePublicOrderSorter {
+ bool operator() (Route *, Route *b);
+ };
+
+ template<class T> void foreach_route (T *obj, void (T::*func)(Route&));
+ template<class T> void foreach_route (T *obj, void (T::*func)(Route*));
+ template<class T, class A> void foreach_route (T *obj, void (T::*func)(Route&, A), A arg);
+
+ Route *route_by_name (string);
+
+ bool route_name_unique (string) const;
+
+ bool get_record_enabled() const {
+ return (record_status () >= Enabled);
+ }
+
+ RecordState record_status() const {
+ return (RecordState) atomic_read (&_record_status);
+ }
+
+ bool actively_recording () {
+ return record_status() == Recording;
+ }
+
+ bool record_enabling_legal () const;
+ void maybe_enable_record ();
+ void disable_record ();
+ void step_back_from_record ();
+
+ sigc::signal<void> going_away;
+
+ /* Proxy signal for region hidden changes */
+
+ sigc::signal<void,Region*> RegionHiddenChange;
+
+ /* Emitted when all i/o connections are complete */
+
+ sigc::signal<void> IOConnectionsComplete;
+
+ /* Record status signals */
+
+ sigc::signal<void> RecordEnabled;
+ sigc::signal<void> RecordDisabled;
+
+ /* Transport mechanism signals */
+
+ sigc::signal<void> TransportStateChange; /* generic */
+ sigc::signal<void,jack_nframes_t> PositionChanged; /* sent after any non-sequential motion */
+ sigc::signal<void> DurationChanged;
+ sigc::signal<void> HaltOnXrun;
+
+ sigc::signal<void,Route*> RouteAdded;
+ sigc::signal<void,DiskStream*> DiskStreamAdded;
+
+ void request_roll ();
+ void request_bounded_roll (jack_nframes_t start, jack_nframes_t end);
+ void request_stop (bool abort = false);
+ void request_locate (jack_nframes_t frame, bool with_roll = false);
+ void request_auto_loop (bool yn);
+ jack_nframes_t last_transport_start() const { return _last_roll_location; }
+ void goto_end () { request_locate (end_location->start(), false);}
+ void goto_start () { request_locate (0, false); }
+ void use_rf_shuttle_speed ();
+ void request_transport_speed (float speed);
+ void request_overwrite_buffer (DiskStream*);
+ void request_diskstream_speed (DiskStream&, float speed);
+ void request_input_change_handling ();
+
+ int wipe ();
+ int wipe_diskstream (DiskStream *);
+
+ int remove_region_from_region_list (Region&);
+
+ jack_nframes_t current_end_frame() const { return end_location->start(); }
+ jack_nframes_t frame_rate() const { return _current_frame_rate; }
+ double frames_per_smpte_frame() const { return _frames_per_smpte_frame; }
+ jack_nframes_t frames_per_hour() const { return _frames_per_hour; }
+ jack_nframes_t smpte_frames_per_hour() const { return _smpte_frames_per_hour; }
+
+ /* Locations */
+
+ Locations *locations() { return &_locations; }
+
+ sigc::signal<void,Location*> auto_loop_location_changed;
+ sigc::signal<void,Location*> auto_punch_location_changed;
+ sigc::signal<void> locations_modified;
+
+ void set_auto_punch_location (Location *);
+ void set_auto_loop_location (Location *);
+
+
+ enum ControlType {
+ AutoPlay,
+ AutoLoop,
+ AutoReturn,
+ AutoInput,
+ PunchIn,
+ PunchOut,
+ SendMTC,
+ MMCControl,
+ Live,
+ RecordingPlugins,
+ CrossFadesActive,
+ SendMMC,
+ SlaveType,
+ Clicking,
+ EditingMode,
+ PlayRange,
+ AlignChoice,
+ SeamlessLoop,
+ MidiFeedback,
+ MidiControl
+ };
+
+ sigc::signal<void,ControlType> ControlChanged;
+
+ void set_auto_play (bool yn);
+ void set_auto_return (bool yn);
+ void set_auto_input (bool yn);
+ void set_input_auto_connect (bool yn);
+ void set_output_auto_connect (AutoConnectOption);
+ void set_punch_in (bool yn);
+ void set_punch_out (bool yn);
+ void set_send_mtc (bool yn);
+ void set_send_mmc (bool yn);
+ void set_mmc_control (bool yn);
+ void set_midi_feedback (bool yn);
+ void set_midi_control (bool yn);
+ void set_recording_plugins (bool yn);
+ void set_crossfades_active (bool yn);
+ void set_seamless_loop (bool yn);
+
+ bool get_auto_play () const { return auto_play; }
+ bool get_auto_input () const { return auto_input; }
+ bool get_auto_loop () const { return auto_loop; }
+ bool get_seamless_loop () const { return seamless_loop; }
+ bool get_punch_in () const { return punch_in; }
+ bool get_punch_out () const { return punch_out; }
+ bool get_all_safe () const { return all_safe; }
+ bool get_auto_return () const { return auto_return; }
+ bool get_send_mtc () const;
+ bool get_send_mmc () const;
+ bool get_mmc_control () const;
+ bool get_midi_feedback () const;
+ bool get_midi_control () const;
+ bool get_recording_plugins () const { return recording_plugins; }
+ bool get_crossfades_active () const { return crossfades_active; }
+
+ AutoConnectOption get_input_auto_connect () const { return input_auto_connect; }
+ AutoConnectOption get_output_auto_connect () const { return output_auto_connect; }
+
+ enum LayerModel {
+ LaterHigher,
+ MoveAddHigher,
+ AddHigher
+ };
+
+ void set_layer_model (LayerModel);
+ LayerModel get_layer_model () const { return layer_model; }
+
+ sigc::signal<void> LayerModelChanged;
+
+ void set_xfade_model (CrossfadeModel);
+ CrossfadeModel get_xfade_model () const { return xfade_model; }
+
+ void set_align_style (AlignStyle);
+ AlignStyle get_align_style () const { return align_style; }
+
+ void add_event (jack_nframes_t action_frame, Event::Type type, jack_nframes_t target_frame = 0);
+ void remove_event (jack_nframes_t frame, Event::Type type);
+ void clear_events (Event::Type type);
+
+ jack_nframes_t get_block_size() const { return current_block_size; }
+ jack_nframes_t worst_output_latency () const { return _worst_output_latency; }
+ jack_nframes_t worst_input_latency () const { return _worst_input_latency; }
+ jack_nframes_t worst_track_latency () const { return _worst_track_latency; }
+
+ int save_state (string snapshot_name, bool pending = false);
+ int restore_state (string snapshot_name);
+ int save_template (string template_name);
+
+ static int rename_template (string old_name, string new_name);
+
+ static int delete_template (string name);
+
+ sigc::signal<void,string> StateSaved;
+ sigc::signal<void> StateReady;
+
+ vector<string*>* possible_states() const;
+ static vector<string*>* possible_states(string path);
+
+ XMLNode& get_state();
+ int set_state(const XMLNode& node);
+ XMLNode& get_template();
+
+ void add_instant_xml (XMLNode&, const std::string& dir);
+
+ void swap_configuration(Configuration** new_config);
+ void copy_configuration(Configuration* new_config);
+
+ enum StateOfTheState {
+ Clean = 0x0,
+ Dirty = 0x1,
+ CannotSave = 0x2,
+ Deletion = 0x4,
+ InitialConnecting = 0x8,
+ Loading = 0x10,
+ InCleanup = 0x20
+ };
+
+ StateOfTheState state_of_the_state() const { return _state_of_the_state; }
+
+ RouteGroup* add_edit_group (string);
+ RouteGroup* add_mix_group (string);
+
+ RouteGroup *mix_group_by_name (string);
+ RouteGroup *edit_group_by_name (string);
+
+ sigc::signal<void,RouteGroup*> edit_group_added;
+ sigc::signal<void,RouteGroup*> mix_group_added;
+
+ template<class T> void foreach_edit_group (T *obj, void (T::*func)(RouteGroup *)) {
+ list<RouteGroup *>::iterator i;
+ for (i = edit_groups.begin(); i != edit_groups.end(); i++) {
+ (obj->*func)(*i);
+ }
+ }
+
+ template<class T> void foreach_mix_group (T *obj, void (T::*func)(RouteGroup *)) {
+ list<RouteGroup *>::iterator i;
+ for (i = mix_groups.begin(); i != mix_groups.end(); i++) {
+ (obj->*func)(*i);
+ }
+ }
+
+ /* fundamental operations. duh. */
+
+
+ AudioTrack *new_audio_track (int input_channels, int output_channels);
+
+ Route *new_audio_route (int input_channels, int output_channels);
+
+ void remove_route (Route&);
+ void resort_routes (void *src);
+
+ AudioEngine &engine() { return _engine; };
+
+ /* configuration. there should really be accessors/mutators
+ for these
+ */
+
+ float meter_hold () { return _meter_hold; }
+ void set_meter_hold (float);
+ sigc::signal<void> MeterHoldChanged;
+
+ float meter_falloff () { return _meter_falloff; }
+ void set_meter_falloff (float);
+ sigc::signal<void> MeterFalloffChanged;
+
+ int32_t max_level;
+ int32_t min_level;
+ string click_emphasis_sound;
+ string click_sound;
+ bool click_requested;
+ jack_nframes_t over_length_short;
+ jack_nframes_t over_length_long;
+ bool send_midi_timecode;
+ bool send_midi_machine_control;
+ float shuttle_speed_factor;
+ float shuttle_speed_threshold;
+ float rf_speed;
+ float smpte_frames_per_second;
+ bool smpte_drop_frames;
+ AnyTime preroll;
+ AnyTime postroll;
+
+ /* Time */
+
+ jack_nframes_t transport_frame () const {return _transport_frame; }
+ jack_nframes_t audible_frame () const;
+
+ int set_smpte_type (float fps, bool drop_frames);
+
+ void bbt_time (jack_nframes_t when, BBT_Time&);
+
+ ARDOUR::smpte_wrap_t smpte_increment( SMPTE_Time& smpte ) const;
+ ARDOUR::smpte_wrap_t smpte_decrement( SMPTE_Time& smpte ) const;
+ ARDOUR::smpte_wrap_t smpte_increment_subframes( SMPTE_Time& smpte ) const;
+ ARDOUR::smpte_wrap_t smpte_decrement_subframes( SMPTE_Time& smpte ) const;
+ ARDOUR::smpte_wrap_t smpte_increment_seconds( SMPTE_Time& smpte ) const;
+ ARDOUR::smpte_wrap_t smpte_increment_minutes( SMPTE_Time& smpte ) const;
+ ARDOUR::smpte_wrap_t smpte_increment_hours( SMPTE_Time& smpte ) const;
+ void smpte_frames_floor( SMPTE_Time& smpte ) const;
+ void smpte_seconds_floor( SMPTE_Time& smpte ) const;
+ void smpte_minutes_floor( SMPTE_Time& smpte ) const;
+ void smpte_hours_floor( SMPTE_Time& smpte ) const;
+ void smpte_to_sample( SMPTE_Time& smpte, jack_nframes_t& sample, bool use_offset, bool use_subframes ) const;
+ void sample_to_smpte( jack_nframes_t sample, SMPTE_Time& smpte, bool use_offset, bool use_subframes ) const;
+ void smpte_time (SMPTE_Time &);
+ void smpte_time (jack_nframes_t when, SMPTE_Time&);
+ void smpte_time_subframes (jack_nframes_t when, SMPTE_Time&);
+
+ void smpte_duration (jack_nframes_t, SMPTE_Time&) const;
+ void smpte_duration_string (char *, jack_nframes_t) const;
+
+ void set_smpte_offset (jack_nframes_t);
+ jack_nframes_t smpte_offset () const { return _smpte_offset; }
+ void set_smpte_offset_negative (bool);
+ bool smpte_offset_negative () const { return _smpte_offset_negative; }
+
+ jack_nframes_t convert_to_frames_at (jack_nframes_t position, AnyTime&);
+
+ sigc::signal<void> SMPTEOffsetChanged;
+ sigc::signal<void> SMPTETypeChanged;
+
+ void request_slave_source (SlaveSource, jack_nframes_t pos = 0);
+ SlaveSource slave_source() const { return _slave_type; }
+ bool synced_to_jack() const { return _slave_type == JACK; }
+ float transport_speed() const { return _transport_speed; }
+ bool transport_stopped() const { return _transport_speed == 0.0f; }
+ bool transport_rolling() const { return _transport_speed != 0.0f; }
+
+ int jack_slave_sync (jack_nframes_t);
+
+ TempoMap& tempo_map() { return *_tempo_map; }
+
+ /* region info */
+
+ sigc::signal<void,AudioRegion *> AudioRegionAdded;
+ sigc::signal<void,AudioRegion *> AudioRegionRemoved;
+
+ int region_name (string& result, string base = string(""), bool newlevel = false) const;
+ string new_region_name (string);
+ string path_from_region_name (string name, string identifier);
+
+ AudioRegion* find_whole_file_parent (AudioRegion&);
+ void find_equivalent_playlist_regions (AudioRegion&, std::vector<AudioRegion*>& result);
+
+ AudioRegion *XMLRegionFactory (const XMLNode&, bool full);
+
+ template<class T> void foreach_audio_region (T *obj, void (T::*func)(AudioRegion *));
+
+ /* source management */
+
+ struct import_status : public InterThreadInfo {
+ string doing_what;
+
+ /* control info */
+ bool multichan;
+ bool sample_convert;
+ volatile bool freeze;
+ string pathname;
+ };
+
+ int import_audiofile (import_status&);
+ bool sample_rate_convert (import_status&, string infile, string& outfile);
+ string build_tmp_convert_name (string file);
+
+ Session::SlaveSource post_export_slave;
+ jack_nframes_t post_export_position;
+
+ int start_audio_export (ARDOUR::AudioExportSpecification&);
+ int stop_audio_export (ARDOUR::AudioExportSpecification&);
+
+ void add_source (Source *);
+ int remove_file_source (FileSource&);
+
+ struct cleanup_report {
+ vector<string> paths;
+ int32_t space;
+ };
+
+ int cleanup_sources (cleanup_report&);
+ int cleanup_trash_sources (cleanup_report&);
+
+ int destroy_region (Region*);
+ int destroy_regions (list<Region*>);
+
+ int remove_last_capture ();
+
+ /* handlers should return -1 for "stop cleanup", 0 for
+ "yes, delete this playlist" and 1 for "no, don't delete
+ this playlist.
+ */
+
+ sigc::signal<int,ARDOUR::Playlist*> AskAboutPlaylistDeletion;
+
+
+ /* handlers should return !0 for use pending state, 0 for
+ ignore it.
+ */
+
+ static sigc::signal<int> AskAboutPendingState;
+
+ sigc::signal<void,Source *> SourceAdded;
+ sigc::signal<void,Source *> SourceRemoved;
+
+ FileSource *create_file_source (ARDOUR::DiskStream&, int32_t chan);
+ Source *get_source (ARDOUR::id_t);
+
+ /* playlist management */
+
+ Playlist* playlist_by_name (string name);
+ void add_playlist (Playlist *);
+ sigc::signal<void,Playlist*> PlaylistAdded;
+ sigc::signal<void,Playlist*> PlaylistRemoved;
+
+ Playlist *get_playlist (string name);
+
+ uint32_t n_playlists() const;
+
+ template<class T> void foreach_playlist (T *obj, void (T::*func)(Playlist *));
+
+ /* named selections */
+
+ NamedSelection* named_selection_by_name (string name);
+ void add_named_selection (NamedSelection *);
+ void remove_named_selection (NamedSelection *);
+
+ template<class T> void foreach_named_selection (T& obj, void (T::*func)(NamedSelection&));
+ sigc::signal<void> NamedSelectionAdded;
+ sigc::signal<void> NamedSelectionRemoved;
+
+ /* fade curves */
+
+ float get_default_fade_length () const { return default_fade_msecs; }
+ float get_default_fade_steepness () const { return default_fade_steepness; }
+ void set_default_fade (float steepness, float msecs);
+
+ /* auditioning */
+
+ Auditioner& the_auditioner() { return *auditioner; }
+ void audition_playlist ();
+ void audition_region (AudioRegion&);
+ void cancel_audition ();
+ bool is_auditioning () const;
+
+ sigc::signal<void,bool> AuditionActive;
+
+ /* flattening stuff */
+
+ int write_one_track (AudioTrack&, jack_nframes_t start, jack_nframes_t cnt, bool overwrite, vector<Source*>&,
+ InterThreadInfo& wot);
+ int freeze (InterThreadInfo&);
+
+ /* session-wide solo/mute/rec-enable */
+
+ enum SoloModel {
+ InverseMute,
+ SoloBus
+ };
+
+ bool soloing() const { return currently_soloing; }
+
+ SoloModel solo_model() const { return _solo_model; }
+ void set_solo_model (SoloModel);
+
+ bool solo_latched() const { return _solo_latched; }
+ void set_solo_latched (bool yn);
+
+ void set_all_solo (bool);
+ void set_all_mute (bool);
+
+ sigc::signal<void,bool> SoloActive;
+
+ void record_disenable_all ();
+ void record_enable_all ();
+
+ /* control/master out */
+
+ IO* control_out() const { return _control_out; }
+ IO* master_out() const { return _master_out; }
+
+ /* insert/send management */
+
+ uint32_t n_port_inserts() const { return _port_inserts.size(); }
+ uint32_t n_plugin_inserts() const { return _plugin_inserts.size(); }
+ uint32_t n_sends() const { return _sends.size(); }
+
+ string next_send_name();
+ string next_insert_name();
+
+ /* s/w "RAID" management */
+
+ jack_nframes_t available_capture_duration();
+
+ /* I/O Connections */
+
+ template<class T> void foreach_connection (T *obj, void (T::*func)(Connection *));
+ void add_connection (Connection *);
+ void remove_connection (Connection *);
+ Connection *connection_by_name (string) const;
+
+ sigc::signal<void,Connection *> ConnectionAdded;
+ sigc::signal<void,Connection *> ConnectionRemoved;
+
+ /* MIDI */
+
+ int set_mtc_port (string port_tag);
+ int set_mmc_port (string port_tag);
+ int set_midi_port (string port_tag);
+ MIDI::Port *mtc_port() const { return _mtc_port; }
+ MIDI::Port *mmc_port() const { return _mmc_port; }
+ MIDI::Port *midi_port() const { return _midi_port; }
+
+ sigc::signal<void> MTC_PortChanged;
+ sigc::signal<void> MMC_PortChanged;
+ sigc::signal<void> MIDI_PortChanged;
+
+ void set_trace_midi_input (bool, MIDI::Port* port = 0);
+ void set_trace_midi_output (bool, MIDI::Port* port = 0);
+
+ bool get_trace_midi_input(MIDI::Port *port = 0);
+ bool get_trace_midi_output(MIDI::Port *port = 0);
+
+ void send_midi_message (MIDI::Port * port, MIDI::eventType ev, MIDI::channel_t, MIDI::EventTwoBytes);
+ void send_all_midi_feedback ();
+
+ void deliver_midi (MIDI::Port*, MIDI::byte*, int32_t size);
+
+ /* Scrubbing */
+
+ void start_scrub (jack_nframes_t where);
+ void stop_scrub ();
+ void set_scrub_speed (float);
+ jack_nframes_t scrub_buffer_size() const;
+ sigc::signal<void> ScrubReady;
+
+ /* History (for editors, mixers, UIs etc.) */
+
+ void undo (uint32_t n) {
+ history.undo (n);
+ }
+ void redo (uint32_t n) {
+ history.redo (n);
+ }
+
+ uint32_t undo_depth() const { return history.undo_depth(); }
+ uint32_t redo_depth() const { return history.redo_depth(); }
+ string next_undo() const { return history.next_undo(); }
+ string next_redo() const { return history.next_redo(); }
+
+ void begin_reversible_command (string cmd_name, UndoAction *private_undo = 0);
+ void commit_reversible_command (UndoAction* private_redo = 0);
+
+ void add_undo (const UndoAction& ua) {
+ current_cmd.add_undo (ua);
+ }
+ void add_redo (const UndoAction& ua) {
+ current_cmd.add_redo (ua);
+ }
+ void add_redo_no_execute (const UndoAction& ua) {
+ current_cmd.add_redo_no_execute (ua);
+ }
+
+ UndoAction global_solo_memento (void *src);
+ UndoAction global_mute_memento (void *src);
+ UndoAction global_record_enable_memento (void *src);
+ UndoAction global_metering_memento (void *src);
+
+ /* edit mode */
+
+ void set_edit_mode (EditMode);
+ EditMode get_edit_mode () const { return _edit_mode; }
+
+ /* clicking */
+
+ IO& click_io() { return *_click_io; }
+ void set_clicking (bool yn);
+ bool get_clicking() const;
+
+ void set_click_sound (string path);
+ void set_click_emphasis_sound (string path);
+
+ /* tempo FX */
+
+ struct TimeStretchRequest {
+ ARDOUR::AudioRegion* region;
+ float fraction; /* session: read ; GUI: write */
+ float progress; /* session: write ; GUI: read */
+ bool running; /* read/write */
+ bool quick_seek; /* GUI: write */
+ bool antialias; /* GUI: write */
+
+ TimeStretchRequest () : region (0) {}
+ };
+
+ AudioRegion* tempoize_region (TimeStretchRequest&);
+
+ string raid_path() const;
+ void set_raid_path(string);
+
+ /* need to call this whenever we change native file formats */
+
+ void reset_native_file_format();
+
+ /* disk, buffer loads */
+
+ uint32_t playback_load ();
+ uint32_t capture_load ();
+ uint32_t playback_load_min ();
+ uint32_t capture_load_min ();
+
+ void reset_playback_load_min ();
+ void reset_capture_load_min ();
+
+ float read_data_rate () const;
+ float write_data_rate () const;
+
+ /* ranges */
+
+ void set_audio_range (list<AudioRange>&);
+ void set_music_range (list<MusicRange>&);
+
+ void request_play_range (bool yn);
+ bool get_play_range () const { return _play_range; }
+
+ /* favorite dirs */
+ typedef vector<string> FavoriteDirs;
+
+ static int read_favorite_dirs (FavoriteDirs&);
+
+ static int write_favorite_dirs (FavoriteDirs&);
+
+ /* file suffixes */
+
+ static const char* template_suffix() { return _template_suffix; }
+ static const char* statefile_suffix() { return _statefile_suffix; }
+ static const char* pending_suffix() { return _pending_suffix; }
+
+ /* buffers for gain and pan */
+
+ gain_t* gain_automation_buffer () const { return _gain_automation_buffer; }
+ pan_t** pan_automation_buffer() const { return _pan_automation_buffer; }
+
+ /* VST support */
+
+ static long vst_callback (AEffect* effect,
+ long opcode,
+ long index,
+ long value,
+ void* ptr,
+ float opt);
+
+ typedef float (*compute_peak_t) (Sample *, jack_nframes_t, float);
+ typedef void (*apply_gain_to_buffer_t) (Sample *, jack_nframes_t, float);
+ typedef void (*mix_buffers_with_gain_t) (Sample *, Sample *, jack_nframes_t, float);
+ typedef void (*mix_buffers_no_gain_t) (Sample *, Sample *, jack_nframes_t);
+
+ static compute_peak_t compute_peak;
+ static apply_gain_to_buffer_t apply_gain_to_buffer;
+ static mix_buffers_with_gain_t mix_buffers_with_gain;
+ static mix_buffers_no_gain_t mix_buffers_no_gain;
+
+ protected:
+ friend class AudioEngine;
+ void set_block_size (jack_nframes_t nframes);
+ void set_frame_rate (jack_nframes_t nframes);
+
+ protected:
+ friend class DiskStream;
+ void stop_butler ();
+ void wait_till_butler_finished();
+
+ protected:
+ friend class Route;
+ void schedule_curve_reallocation ();
+ void update_latency_compensation (bool, bool);
+
+ private:
+ int create (bool& new_session, string* mix_template, jack_nframes_t initial_length);
+
+ static const char* _template_suffix;
+ static const char* _statefile_suffix;
+ static const char* _pending_suffix;
+
+ enum SubState {
+ PendingDeclickIn = 0x1,
+ PendingDeclickOut = 0x2,
+ StopPendingCapture = 0x4,
+ AutoReturning = 0x10,
+ PendingLocate = 0x20,
+ PendingSetLoop = 0x40
+ };
+
+ /* stuff used in process() should be close together to
+ maximise cache hits
+ */
+
+ typedef void (Session::*process_function_type)(jack_nframes_t);
+
+ AudioEngine &_engine;
+ atomic_t processing_prohibited;
+ process_function_type process_function;
+ process_function_type last_process_function;
+ jack_nframes_t _current_frame_rate;
+ int transport_sub_state;
+ atomic_t _record_status;
+ jack_nframes_t _transport_frame;
+ Location* end_location;
+ Slave *_slave;
+ SlaveSource _slave_type;
+ float _transport_speed;
+ volatile float _desired_transport_speed;
+ float _last_transport_speed;
+ jack_nframes_t _last_slave_transport_frame;
+ jack_nframes_t maximum_output_latency;
+ jack_nframes_t last_stop_frame;
+ vector<Sample *> _passthru_buffers;
+ vector<Sample *> _silent_buffers;
+ jack_nframes_t current_block_size;
+ jack_nframes_t _worst_output_latency;
+ jack_nframes_t _worst_input_latency;
+ jack_nframes_t _worst_track_latency;
+ bool _have_captured;
+ float _meter_hold;
+ float _meter_falloff;
+ bool _end_location_is_free;
+
+ void set_worst_io_latencies (bool take_lock);
+ void set_worst_io_latencies_x (IOChange asifwecare, void *ignored) {
+ set_worst_io_latencies (true);
+ }
+
+ void update_latency_compensation_proxy (void* ignored);
+
+ void ensure_passthru_buffers (uint32_t howmany);
+
+ void process_scrub (jack_nframes_t);
+ void process_without_events (jack_nframes_t);
+ void process_with_events (jack_nframes_t);
+ void process_audition (jack_nframes_t);
+ int process_export (jack_nframes_t, ARDOUR::AudioExportSpecification*);
+
+ /* slave tracking */
+
+ static const int delta_accumulator_size = 25;
+ int delta_accumulator_cnt;
+ long delta_accumulator[delta_accumulator_size];
+ long average_slave_delta;
+ int average_dir;
+ bool have_first_delta_accumulator;
+
+ enum SlaveState {
+ Stopped,
+ Waiting,
+ Running
+ };
+
+ SlaveState slave_state;
+ jack_nframes_t slave_wait_end;
+
+ void reset_slave_state ();
+ bool follow_slave (jack_nframes_t, jack_nframes_t);
+
+ bool _exporting;
+ int prepare_to_export (ARDOUR::AudioExportSpecification&);
+
+ void prepare_diskstreams ();
+ void commit_diskstreams (jack_nframes_t, bool& session_requires_butler);
+ int process_routes (jack_nframes_t, jack_nframes_t);
+ int silent_process_routes (jack_nframes_t, jack_nframes_t);
+
+ bool get_rec_monitors_input () {
+ if (actively_recording()) {
+ return true;
+ } else {
+ if (auto_input) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+ }
+
+ int get_transport_declick_required () {
+
+ if (transport_sub_state & PendingDeclickIn) {
+ transport_sub_state &= ~PendingDeclickIn;
+ return 1;
+ } else if (transport_sub_state & PendingDeclickOut) {
+ return -1;
+ } else {
+ return 0;
+ }
+ }
+
+ bool maybe_stop (jack_nframes_t limit) {
+ if ((_transport_speed > 0.0f && _transport_frame >= limit) || (_transport_speed < 0.0f && _transport_frame == 0)) {
+ stop_transport ();
+ return true;
+ }
+ return false;
+ }
+
+ void check_declick_out ();
+
+ MIDI::MachineControl* mmc;
+ MIDI::Port* _mmc_port;
+ MIDI::Port* _mtc_port;
+ MIDI::Port* _midi_port;
+ string _path;
+ string _name;
+ bool recording_plugins;
+
+ /* toggles */
+
+ bool auto_play;
+ bool punch_in;
+ bool punch_out;
+ bool auto_loop;
+ bool seamless_loop;
+ bool loop_changing;
+ jack_nframes_t last_loopend;
+ bool auto_input;
+ bool crossfades_active;
+ bool all_safe;
+ bool auto_return;
+ bool monitor_in;
+ bool send_mtc;
+ bool send_mmc;
+ bool mmc_control;
+ bool midi_feedback;
+ bool midi_control;
+
+ RingBuffer<Event*> pending_events;
+
+ void hookup_io ();
+ void when_engine_running ();
+ sigc::connection first_time_running;
+ void graph_reordered ();
+
+ string _current_snapshot_name;
+
+ XMLTree* state_tree;
+ bool state_was_pending;
+ StateOfTheState _state_of_the_state;
+
+ void auto_save();
+ int load_options (const XMLNode&);
+ XMLNode& get_options () const;
+ int load_state (string snapshot_name);
+
+ jack_nframes_t _last_roll_location;
+ jack_nframes_t _last_record_location;
+ bool pending_locate_roll;
+ jack_nframes_t pending_locate_frame;
+
+ bool pending_locate_flush;
+ bool pending_abort;
+ bool pending_auto_loop;
+
+ Sample* butler_mixdown_buffer;
+ float* butler_gain_buffer;
+ pthread_t butler_thread;
+ PBD::NonBlockingLock butler_request_lock;
+ pthread_cond_t butler_paused;
+ bool butler_should_run;
+ atomic_t butler_should_do_transport_work;
+ int butler_request_pipe[2];
+
+ struct ButlerRequest {
+ enum Type {
+ Wake,
+ Run,
+ Pause,
+ Quit
+ };
+ };
+
+ enum PostTransportWork {
+ PostTransportStop = 0x1,
+ PostTransportDisableRecord = 0x2,
+ PostTransportPosition = 0x8,
+ PostTransportDidRecord = 0x20,
+ PostTransportDuration = 0x40,
+ PostTransportLocate = 0x80,
+ PostTransportRoll = 0x200,
+ PostTransportAbort = 0x800,
+ PostTransportOverWrite = 0x1000,
+ PostTransportSpeed = 0x2000,
+ PostTransportAudition = 0x4000,
+ PostTransportScrub = 0x8000,
+ PostTransportReverse = 0x10000,
+ PostTransportInputChange = 0x20000,
+ PostTransportCurveRealloc = 0x40000
+ };
+
+ static const PostTransportWork ProcessCannotProceedMask =
+ PostTransportWork (PostTransportInputChange|
+ PostTransportSpeed|
+ PostTransportReverse|
+ PostTransportCurveRealloc|
+ PostTransportScrub|
+ PostTransportAudition|
+ PostTransportLocate|
+ PostTransportStop);
+
+ PostTransportWork post_transport_work;
+
+ void summon_butler ();
+ void schedule_butler_transport_work ();
+ int start_butler_thread ();
+ void terminate_butler_thread ();
+ static void *_butler_thread_work (void *arg);
+ void* butler_thread_work ();
+
+ uint32_t cumulative_rf_motion;
+ uint32_t rf_scale;
+
+ void set_rf_speed (float speed);
+ void reset_rf_scale (jack_nframes_t frames_moved);
+
+ Locations _locations;
+ void locations_changed ();
+ void locations_added (Location*);
+ void handle_locations_changed (Locations::LocationList&);
+
+ sigc::connection auto_punch_start_changed_connection;
+ sigc::connection auto_punch_end_changed_connection;
+ sigc::connection auto_punch_changed_connection;
+ void auto_punch_start_changed (Location *);
+ void auto_punch_end_changed (Location *);
+ void auto_punch_changed (Location *);
+
+ sigc::connection auto_loop_start_changed_connection;
+ sigc::connection auto_loop_end_changed_connection;
+ sigc::connection auto_loop_changed_connection;
+ void auto_loop_changed (Location *);
+
+ typedef list<Event *> Events;
+ Events events;
+ Events immediate_events;
+ Events::iterator next_event;
+
+ /* there can only ever be one of each of these */
+
+ Event *auto_loop_event;
+ Event *punch_out_event;
+ Event *punch_in_event;
+
+ /* events */
+
+ void dump_events () const;
+ void queue_event (Event *ev);
+ void merge_event (Event*);
+ void replace_event (Event::Type, jack_nframes_t action_frame, jack_nframes_t target = 0);
+ bool _replace_event (Event*);
+ bool _remove_event (Event *);
+ void _clear_event_type (Event::Type);
+
+ void first_stage_init (string path, string snapshot_name);
+ int second_stage_init (bool new_tracks);
+ void find_current_end ();
+ void remove_empty_sounds ();
+
+ void setup_midi_control ();
+ int midi_read (MIDI::Port *);
+
+ void enable_record ();
+
+ void increment_transport_position (uint32_t val) {
+ if (max_frames - val < _transport_frame) {
+ _transport_frame = max_frames;
+ } else {
+ _transport_frame += val;
+ }
+ }
+
+ void decrement_transport_position (uint32_t val) {
+ if (val < _transport_frame) {
+ _transport_frame -= val;
+ } else {
+ _transport_frame = 0;
+ }
+ }
+
+ void post_transport_motion ();
+ static void *session_loader_thread (void *arg);
+
+ void *do_work();
+
+ void set_next_event ();
+ void process_event (Event *);
+
+ /* MIDI Machine Control */
+
+ void deliver_mmc (MIDI::MachineControl::Command, jack_nframes_t);
+ void deliver_midi_message (MIDI::Port * port, MIDI::eventType ev, MIDI::channel_t, MIDI::EventTwoBytes);
+ void deliver_data (MIDI::Port* port, MIDI::byte*, int32_t size);
+
+ void spp_start (MIDI::Parser&);
+ void spp_continue (MIDI::Parser&);
+ void spp_stop (MIDI::Parser&);
+
+ void mmc_deferred_play (MIDI::MachineControl &);
+ void mmc_stop (MIDI::MachineControl &);
+ void mmc_step (MIDI::MachineControl &, int);
+ void mmc_pause (MIDI::MachineControl &);
+ void mmc_record_pause (MIDI::MachineControl &);
+ void mmc_record_strobe (MIDI::MachineControl &);
+ void mmc_record_exit (MIDI::MachineControl &);
+ void mmc_track_record_status (MIDI::MachineControl &,
+ uint32_t track, bool enabled);
+ void mmc_fast_forward (MIDI::MachineControl &);
+ void mmc_rewind (MIDI::MachineControl &);
+ void mmc_locate (MIDI::MachineControl &, const MIDI::byte *);
+ void mmc_shuttle (MIDI::MachineControl &mmc, float speed, bool forw);
+ void mmc_record_enable (MIDI::MachineControl &mmc, size_t track, bool enabled);
+
+ struct timeval last_mmc_step;
+ double step_speed;
+
+ typedef sigc::slot<bool> MidiTimeoutCallback;
+ typedef list<MidiTimeoutCallback> MidiTimeoutList;
+
+ MidiTimeoutList midi_timeouts;
+ bool mmc_step_timeout ();
+
+ MIDI::byte mmc_buffer[32];
+ MIDI::byte mtc_msg[16];
+ MIDI::byte mtc_smpte_bits; /* encoding of SMTPE type for MTC */
+ MIDI::byte midi_msg[16];
+ jack_nframes_t outbound_mtc_smpte_frame;
+ SMPTE_Time transmitting_smpte_time;
+ int next_quarter_frame_to_send;
+
+ double _frames_per_smpte_frame; /* has to be floating point because of drop frame */
+ jack_nframes_t _frames_per_hour;
+ jack_nframes_t _smpte_frames_per_hour;
+ jack_nframes_t _smpte_offset;
+ bool _smpte_offset_negative;
+
+ /* cache the most-recently requested time conversions.
+ this helps when we have multiple clocks showing the
+ same time (e.g. the transport frame)
+ */
+
+ bool last_smpte_valid;
+ jack_nframes_t last_smpte_when;
+ SMPTE_Time last_smpte;
+
+ int send_full_time_code ();
+ int send_midi_time_code ();
+
+ void send_full_time_code_in_another_thread ();
+ void send_midi_time_code_in_another_thread ();
+ void send_time_code_in_another_thread (bool full);
+ void send_mmc_in_another_thread (MIDI::MachineControl::Command, jack_nframes_t frame = 0);
+
+ /* Feedback */
+
+ typedef sigc::slot<int> FeedbackFunctionPtr;
+ static void* _feedback_thread_work (void *);
+ void* feedback_thread_work ();
+ int feedback_generic_midi_function ();
+ std::list<FeedbackFunctionPtr> feedback_functions;
+ int active_feedback;
+ int feedback_request_pipe[2];
+ pthread_t feedback_thread;
+
+ struct FeedbackRequest {
+ enum Type {
+ Start,
+ Stop,
+ Quit
+ };
+ };
+
+ int init_feedback();
+ int start_feedback ();
+ int stop_feedback ();
+ void terminate_feedback ();
+ int poke_feedback (FeedbackRequest::Type);
+
+ jack_nframes_t adjust_apparent_position (jack_nframes_t frames);
+
+ void reset_record_status ();
+
+ int no_roll (jack_nframes_t nframes, jack_nframes_t offset);
+
+ bool non_realtime_work_pending() const { return static_cast<bool>(post_transport_work); }
+ bool process_can_proceed() const { return !(post_transport_work & ProcessCannotProceedMask); }
+
+ struct MIDIRequest {
+
+ enum Type {
+ SendFullMTC,
+ SendMTC,
+ SendMMC,
+ PortChange,
+ SendMessage,
+ Deliver,
+ Quit
+ };
+
+ Type type;
+ MIDI::MachineControl::Command mmc_cmd;
+ jack_nframes_t locate_frame;
+
+ // for SendMessage type
+
+ MIDI::Port * port;
+ MIDI::channel_t chan;
+ union {
+ MIDI::EventTwoBytes data;
+ MIDI::byte* buf;
+ };
+
+ union {
+ MIDI::eventType ev;
+ int32_t size;
+ };
+
+ MIDIRequest () {}
+
+ void *operator new(size_t ignored) {
+ return pool.alloc ();
+ };
+
+ void operator delete(void *ptr, size_t size) {
+ pool.release (ptr);
+ }
+
+ private:
+ static MultiAllocSingleReleasePool pool;
+ };
+
+ PBD::Lock midi_lock;
+ pthread_t midi_thread;
+ int midi_request_pipe[2];
+ atomic_t butler_active;
+ RingBuffer<MIDIRequest*> midi_requests;
+
+ int start_midi_thread ();
+ void terminate_midi_thread ();
+ void poke_midi_thread ();
+ static void *_midi_thread_work (void *arg);
+ void midi_thread_work ();
+ void change_midi_ports ();
+ int use_config_midi_ports ();
+
+ bool waiting_to_start;
+
+ void set_auto_loop (bool yn);
+ void overwrite_some_buffers (DiskStream*);
+ void flush_all_redirects ();
+ void locate (jack_nframes_t, bool with_roll, bool with_flush, bool with_loop=false);
+ void start_locate (jack_nframes_t, bool with_roll, bool with_flush, bool with_loop=false);
+ void force_locate (jack_nframes_t frame, bool with_roll = false);
+ void set_diskstream_speed (DiskStream*, float speed);
+ void set_transport_speed (float speed, bool abort = false);
+ void stop_transport (bool abort = false);
+ void start_transport ();
+ void actually_start_transport ();
+ void realtime_stop (bool abort);
+ void non_realtime_start_scrub ();
+ void non_realtime_set_speed ();
+ void non_realtime_stop (bool abort);
+ void non_realtime_overwrite ();
+ void non_realtime_buffer_fill ();
+ void butler_transport_work ();
+ void post_transport ();
+ void engine_halted ();
+ void xrun_recovery ();
+
+ TempoMap *_tempo_map;
+ void tempo_map_changed (Change);
+
+ /* edit/mix groups */
+
+ int load_route_groups (const XMLNode&, bool is_edit);
+ int load_edit_groups (const XMLNode&);
+ int load_mix_groups (const XMLNode&);
+
+
+ list<RouteGroup *> edit_groups;
+ list<RouteGroup *> mix_groups;
+
+ /* disk-streams */
+
+ DiskStreamList diskstreams;
+ mutable PBD::Lock diskstream_lock;
+ uint32_t dstream_buffer_size;
+ void add_diskstream (DiskStream*);
+ int load_diskstreams (const XMLNode&);
+
+ /* routes stuff */
+
+ RouteList routes;
+ mutable PBD::NonBlockingLock route_lock;
+ void add_route (Route*);
+
+ int load_routes (const XMLNode&);
+ Route* XMLRouteFactory (const XMLNode&);
+
+ /* mixer stuff */
+
+ bool _solo_latched;
+ SoloModel _solo_model;
+ bool solo_update_disabled;
+ bool currently_soloing;
+
+ void route_mute_changed (void *src);
+ void route_solo_changed (void *src, Route *);
+ void catch_up_on_solo ();
+ void update_route_solo_state ();
+ void modify_solo_mute (bool, bool);
+ void strip_portname_for_solo (string& portname);
+
+ /* REGION MANAGEMENT */
+
+ mutable PBD::Lock region_lock;
+ typedef map<ARDOUR::id_t,AudioRegion *> AudioRegionList;
+ AudioRegionList audio_regions;
+
+ void region_renamed (Region *);
+ void region_changed (Change, Region *);
+ void add_region (Region *);
+ void remove_region (Region *);
+
+ int load_regions (const XMLNode& node);
+
+ /* SOURCES */
+
+ mutable PBD::Lock source_lock;
+ typedef std::map<id_t, Source *> SourceList;
+
+ SourceList sources;
+
+ int load_sources (const XMLNode& node);
+ XMLNode& get_sources_as_xml ();
+
+ void remove_source (Source *);
+
+ Source *XMLSourceFactory (const XMLNode&);
+
+ /* PLAYLISTS */
+
+ mutable PBD::Lock playlist_lock;
+ typedef set<Playlist *> PlaylistList;
+ PlaylistList playlists;
+ PlaylistList unused_playlists;
+
+ int load_playlists (const XMLNode&);
+ int load_unused_playlists (const XMLNode&);
+ void remove_playlist (Playlist *);
+ void track_playlist (Playlist *, bool);
+
+ Playlist *playlist_factory (string name);
+ Playlist *XMLPlaylistFactory (const XMLNode&);
+
+ void playlist_length_changed (Playlist *);
+ void diskstream_playlist_changed (DiskStream *);
+
+ /* NAMED SELECTIONS */
+
+ mutable PBD::Lock named_selection_lock;
+ typedef set<NamedSelection *> NamedSelectionList;
+ NamedSelectionList named_selections;
+
+ int load_named_selections (const XMLNode&);
+
+ NamedSelection *named_selection_factory (string name);
+ NamedSelection *XMLNamedSelectionFactory (const XMLNode&);
+
+ /* DEFAULT FADE CURVES */
+
+ float default_fade_steepness;
+ float default_fade_msecs;
+
+ /* AUDITIONING */
+
+ Auditioner *auditioner;
+ void set_audition (AudioRegion*);
+ void non_realtime_set_audition ();
+ AudioRegion *pending_audition_region;
+
+ /* EXPORT */
+
+ /* FLATTEN */
+
+ int flatten_one_track (AudioTrack&, jack_nframes_t start, jack_nframes_t cnt);
+
+ /* INSERT AND SEND MANAGEMENT */
+
+ slist<PortInsert *> _port_inserts;
+ slist<PluginInsert *> _plugin_inserts;
+ slist<Send *> _sends;
+ uint32_t send_cnt;
+ uint32_t insert_cnt;
+
+ void add_redirect (Redirect *);
+ void remove_redirect (Redirect *);
+
+ /* S/W RAID */
+
+ struct space_and_path {
+ uint32_t blocks; /* 4kB blocks */
+ string path;
+
+ space_and_path() {
+ blocks = 0;
+ }
+ };
+
+ struct space_and_path_ascending_cmp {
+ bool operator() (space_and_path a, space_and_path b) {
+ return a.blocks > b.blocks;
+ }
+ };
+
+ void setup_raid_path (string path);
+
+ vector<space_and_path> session_dirs;
+ vector<space_and_path>::iterator last_rr_session_dir;
+ uint32_t _total_free_4k_blocks;
+ PBD::Lock space_lock;
+
+ static const char* sound_dir_name;
+ static const char* dead_sound_dir_name;
+ static const char* peak_dir_name;
+
+ string discover_best_sound_dir ();
+ int ensure_sound_dir (string, string&);
+ void refresh_disk_space ();
+
+ atomic_t _playback_load;
+ atomic_t _capture_load;
+ atomic_t _playback_load_min;
+ atomic_t _capture_load_min;
+
+ /* I/O Connections */
+
+ typedef list<Connection *> ConnectionList;
+ mutable PBD::Lock connection_lock;
+ ConnectionList _connections;
+ int load_connections (const XMLNode&);
+
+ int set_slave_source (SlaveSource, jack_nframes_t);
+
+ void reverse_diskstream_buffers ();
+
+ UndoHistory history;
+ UndoCommand current_cmd;
+
+ GlobalRouteBooleanState get_global_route_boolean (bool (Route::*method)(void) const);
+ GlobalRouteMeterState get_global_route_metering ();
+
+ void set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void *arg);
+ void set_global_route_metering (GlobalRouteMeterState s, void *arg);
+
+ void set_global_mute (GlobalRouteBooleanState s, void *src);
+ void set_global_solo (GlobalRouteBooleanState s, void *src);
+ void set_global_record_enable (GlobalRouteBooleanState s, void *src);
+
+ void jack_timebase_callback (jack_transport_state_t, jack_nframes_t, jack_position_t*, int);
+ int jack_sync_callback (jack_transport_state_t, jack_position_t*);
+ void record_enable_change_all (bool yn);
+
+ XMLNode& state(bool);
+
+ /* click track */
+
+ struct Click {
+ jack_nframes_t start;
+ jack_nframes_t duration;
+ jack_nframes_t offset;
+ const Sample *data;
+
+ Click (jack_nframes_t s, jack_nframes_t d, const Sample *b)
+ : start (s), duration (d), data (b) { offset = 0; }
+
+ void *operator new(size_t ignored) {
+ return pool.alloc ();
+ };
+
+ void operator delete(void *ptr, size_t size) {
+ pool.release (ptr);
+ }
+
+ private:
+ static Pool pool;
+ };
+
+ typedef list<Click*> Clicks;
+
+ Clicks clicks;
+ bool _clicking;
+ IO* _click_io;
+ Sample* click_data;
+ Sample* click_emphasis_data;
+ jack_nframes_t click_length;
+ jack_nframes_t click_emphasis_length;
+
+ static const Sample default_click[];
+ static const jack_nframes_t default_click_length;
+ static const Sample default_click_emphasis[];
+ static const jack_nframes_t default_click_emphasis_length;
+
+ Click *get_click();
+ void setup_click_sounds (int which);
+ void clear_clicks ();
+ void click (jack_nframes_t start, jack_nframes_t nframes, jack_nframes_t offset);
+
+ vector<Route*> master_outs;
+
+ EditMode _edit_mode;
+ EditMode pending_edit_mode;
+
+ /* range playback */
+
+ list<AudioRange> current_audio_range;
+ bool _play_range;
+ void set_play_range (bool yn);
+ void setup_auto_play ();
+
+ /* main outs */
+ uint32_t main_outs;
+
+ IO* _master_out;
+ IO* _control_out;
+
+ AutoConnectOption input_auto_connect;
+ AutoConnectOption output_auto_connect;
+
+ AlignStyle align_style;
+
+ gain_t* _gain_automation_buffer;
+ pan_t** _pan_automation_buffer;
+ void allocate_pan_automation_buffers (jack_nframes_t nframes, uint32_t howmany, bool force);
+ uint32_t _npan_buffers;
+
+ /* VST support */
+
+ long _vst_callback (VSTPlugin*,
+ long opcode,
+ long index,
+ long value,
+ void* ptr,
+ float opt);
+
+ /* number of hardware audio ports we're using,
+ based on max (requested,available)
+ */
+
+ uint32_t n_physical_outputs;
+ uint32_t n_physical_inputs;
+
+ void remove_pending_capture_state ();
+
+ int find_all_sources (std::string path, std::set<std::string>& result);
+ int find_all_sources_across_snapshots (std::set<std::string>& result, bool exclude_this_snapshot);
+
+ LayerModel layer_model;
+ CrossfadeModel xfade_model;
+};
+
+}; /* namespace ARDOUR */
+
+#endif /* __ardour_session_h__ */
diff --git a/libs/ardour/ardour/session_connection.h b/libs/ardour/ardour/session_connection.h
new file mode 100644
index 0000000000..caa20ed387
--- /dev/null
+++ b/libs/ardour/ardour/session_connection.h
@@ -0,0 +1,40 @@
+/*
+ Copyright (C) 2002 Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __ardour_session_connection_h__
+#define __ardour_session_connection_h__
+
+#include <ardour/session.h>
+#include <ardour/connection.h>
+
+namespace ARDOUR {
+
+template<class T> void
+Session::foreach_connection (T *obj, void (T::*func)(Connection *))
+{
+ LockMonitor lm (connection_lock, __LINE__, __FILE__);
+ for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); i++) {
+ (obj->*func) (*i);
+ }
+}
+
+} /* namespace */
+
+#endif /* __ardour_session_connection_h__ */
diff --git a/libs/ardour/ardour/session_diskstream.h b/libs/ardour/ardour/session_diskstream.h
new file mode 100644
index 0000000000..55c79f549f
--- /dev/null
+++ b/libs/ardour/ardour/session_diskstream.h
@@ -0,0 +1,42 @@
+/*
+ Copyright (C) 2002 Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __ardour_session_diskstream_h__
+#define __ardour_session_diskstream_h__
+
+#include <ardour/session.h>
+#include <ardour/diskstream.h>
+
+namespace ARDOUR {
+
+template<class T> void
+Session::foreach_diskstream (T *obj, void (T::*func)(DiskStream&))
+{
+ LockMonitor lm (diskstream_lock, __LINE__, __FILE__);
+ for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); i++) {
+ if (!(*i)->hidden()) {
+ (obj->*func) (**i);
+ }
+ }
+}
+
+} /* namespace */
+
+#endif /* __ardour_session_diskstream_h__ */
diff --git a/libs/ardour/ardour/session_playlist.h b/libs/ardour/ardour/session_playlist.h
new file mode 100644
index 0000000000..925a60182a
--- /dev/null
+++ b/libs/ardour/ardour/session_playlist.h
@@ -0,0 +1,47 @@
+/*
+ Copyright (C) 2002 Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __ardour_session_playlist_h__
+#define __ardour_session_playlist_h__
+
+#include <ardour/session.h>
+#include <ardour/playlist.h>
+
+namespace ARDOUR {
+
+template<class T> void
+Session::foreach_playlist (T *obj, void (T::*func)(Playlist *))
+{
+ LockMonitor lm (playlist_lock, __LINE__, __FILE__);
+ for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); i++) {
+ if (!(*i)->hidden()) {
+ (obj->*func) (*i);
+ }
+ }
+ for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); i++) {
+ if (!(*i)->hidden()) {
+ (obj->*func) (*i);
+ }
+ }
+}
+
+} /* namespace */
+
+#endif /* __ardour_session_playlist_h__ */
diff --git a/libs/ardour/ardour/session_region.h b/libs/ardour/ardour/session_region.h
new file mode 100644
index 0000000000..16580d8e73
--- /dev/null
+++ b/libs/ardour/ardour/session_region.h
@@ -0,0 +1,19 @@
+#ifndef __ardour_session_region_h__
+#define __ardour_session_region_h__
+
+#include <ardour/session.h>
+#include <ardour/audioregion.h>
+
+namespace ARDOUR {
+
+template<class T> void Session::foreach_audio_region (T *obj, void (T::*func)(AudioRegion *))
+{
+ LockMonitor lm (region_lock, __LINE__, __FILE__);
+ for (AudioRegionList::iterator i = audio_regions.begin(); i != audio_regions.end(); i++) {
+ (obj->*func) ((*i).second);
+ }
+}
+
+}
+
+#endif /* __ardour_session_region_h__ */
diff --git a/libs/ardour/ardour/session_route.h b/libs/ardour/ardour/session_route.h
new file mode 100644
index 0000000000..0b126531dc
--- /dev/null
+++ b/libs/ardour/ardour/session_route.h
@@ -0,0 +1,89 @@
+/*
+ Copyright (C) 2000 Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __ardour_session_route_h__
+#define __ardour_session_route_h__
+
+#include <iostream>
+
+#include <pbd/lockmonitor.h>
+#include <ardour/session.h>
+#include <ardour/route.h>
+
+namespace ARDOUR {
+
+template<class T> void
+Session::foreach_route (T *obj, void (T::*func)(Route&))
+{
+ RouteList public_order;
+
+ {
+ LockMonitor lm (route_lock, __LINE__, __FILE__);
+ public_order = routes;
+ }
+
+ RoutePublicOrderSorter cmp;
+ public_order.sort (cmp);
+
+ for (RouteList::iterator i = public_order.begin(); i != public_order.end(); i++) {
+ (obj->*func) (**i);
+ }
+}
+
+template<class T> void
+Session::foreach_route (T *obj, void (T::*func)(Route*))
+{
+ RouteList public_order;
+
+ {
+ LockMonitor lm (route_lock, __LINE__, __FILE__);
+ public_order = routes;
+ }
+
+ RoutePublicOrderSorter cmp;
+ public_order.sort (cmp);
+
+ for (RouteList::iterator i = public_order.begin(); i != public_order.end(); i++) {
+ (obj->*func) (*i);
+ }
+}
+
+
+template<class T, class A> void
+Session::foreach_route (T *obj, void (T::*func)(Route&, A), A arg1)
+{
+ RouteList public_order;
+
+ {
+ LockMonitor lm (route_lock, __LINE__, __FILE__);
+ public_order = routes;
+ }
+
+ RoutePublicOrderSorter cmp;
+ public_order.sort (cmp);
+
+ for (RouteList::iterator i = public_order.begin(); i != public_order.end(); i++) {
+ (obj->*func) (**i, arg1);
+ }
+}
+
+} /* namespace */
+
+#endif /* __ardour_session_route_h__ */
diff --git a/libs/ardour/ardour/session_selection.h b/libs/ardour/ardour/session_selection.h
new file mode 100644
index 0000000000..a1dd31d7ff
--- /dev/null
+++ b/libs/ardour/ardour/session_selection.h
@@ -0,0 +1,40 @@
+/*
+ Copyright (C) 2002 Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __ardour_session_named_selection_h__
+#define __ardour_session_named_selection_h__
+
+#include <ardour/session.h>
+#include <ardour/named_selection.h>
+
+namespace ARDOUR {
+
+template<class T> void
+Session::foreach_named_selection (T& obj, void (T::*func)(NamedSelection&))
+{
+ LockMonitor lm (named_selection_lock, __LINE__, __FILE__);
+ for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); i++) {
+ (obj.*func) (**i);
+ }
+}
+
+} /* namespace */
+
+#endif /* __ardour_session_named_selection_h__ */
diff --git a/libs/ardour/ardour/silentsource.h b/libs/ardour/ardour/silentsource.h
new file mode 100644
index 0000000000..0079e5f103
--- /dev/null
+++ b/libs/ardour/ardour/silentsource.h
@@ -0,0 +1,56 @@
+/*
+ Copyright (C) 2000 Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __playlist_const_buffer_h__
+#define __playlist_const_buffer_h__
+
+#include <string>
+#include <cstdlib>
+
+#include "source.h"
+
+namespace ARDOUR {
+
+class SilentSource : public Source {
+ public:
+ SilentSource () {
+ _name = "Silent Source";
+ }
+
+ static bool is_silent_source (const string& name) {
+ return name == "Silent Source";
+ }
+
+ jack_nframes_t length() { return ~0U; }
+
+ jack_nframes_t read (Source::Data *dst, jack_nframes_t start, jack_nframes_t cnt) {
+ jack_nframes_t n = cnt;
+ while (n--) *dst++ = 0;
+ return cnt;
+ }
+
+ void peak (guint8 *max, guint8 *min, jack_nframes_t start, jack_nframes_t cnt) {
+ *max = *min = 0;
+ }
+};
+
+}
+
+#endif /* __playlist_const_buffer_h__ */
diff --git a/libs/ardour/ardour/slave.h b/libs/ardour/ardour/slave.h
new file mode 100644
index 0000000000..90e63aed83
--- /dev/null
+++ b/libs/ardour/ardour/slave.h
@@ -0,0 +1,151 @@
+/*
+ Copyright (C) 2002 Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __ardour_slave_h__
+#define __ardour_slave_h__
+
+#include <vector>
+
+#include <jack/jack.h>
+
+#include <pthread.h>
+#include <sigc++/signal.h>
+#include <ardour/ardour.h>
+#include <midi++/parser.h>
+#include <midi++/types.h>
+
+namespace MIDI {
+ class Port;
+}
+
+namespace ARDOUR {
+class Session;
+
+class Slave {
+ public:
+ Slave() { }
+ virtual ~Slave() {}
+
+ virtual bool speed_and_position (float&, jack_nframes_t&) = 0;
+ virtual bool locked() const = 0;
+ virtual bool ok() const = 0;
+ virtual bool starting() const { return false; }
+ virtual jack_nframes_t resolution() const = 0;
+ virtual bool requires_seekahead () const = 0;
+};
+
+
+class MTC_Slave : public Slave, public sigc::trackable {
+ public:
+ MTC_Slave (Session&, MIDI::Port&);
+ ~MTC_Slave ();
+
+ void rebind (MIDI::Port&);
+ bool speed_and_position (float&, jack_nframes_t&);
+
+ bool locked() const;
+ bool ok() const;
+ void handle_locate (const MIDI::byte*);
+
+ jack_nframes_t resolution() const;
+ bool requires_seekahead () const { return true; }
+
+ private:
+ Session& session;
+ MIDI::Port* port;
+ std::vector<sigc::connection> connections;
+
+ struct SafeTime {
+
+
+ int guard1;
+ //SMPTE_Time mtc;
+ jack_nframes_t position;
+ jack_nframes_t timestamp;
+ int guard2;
+
+ SafeTime() {
+ guard1 = 0;
+ guard2 = 0;
+ timestamp = 0;
+ }
+ };
+
+ SafeTime current;
+ jack_nframes_t mtc_frame; /* current time */
+ jack_nframes_t last_inbound_frame; /* when we got it; audio clocked */
+
+ float mtc_speed;
+ jack_nframes_t first_mtc_frame;
+ jack_nframes_t first_mtc_time;
+
+ static const int32_t accumulator_size = 128;
+ float accumulator[accumulator_size];
+ int32_t accumulator_index;
+ bool have_first_accumulated_speed;
+
+ void reset ();
+ void update_mtc_qtr (MIDI::Parser&);
+ void update_mtc_time (const MIDI::byte *, bool);
+ void update_mtc_status (MIDI::Parser::MTC_Status);
+ void read_current (SafeTime *) const;
+};
+
+class ADAT_Slave : public Slave
+{
+ public:
+ ADAT_Slave () {}
+ ~ADAT_Slave () {}
+
+ bool speed_and_position (float& speed, jack_nframes_t& pos) {
+ speed = 0;
+ pos = 0;
+ return false;
+ }
+
+ bool locked() const { return false; }
+ bool ok() const { return false; }
+ jack_nframes_t resolution() const { return 1; }
+ bool requires_seekahead () const { return true; }
+};
+
+class JACK_Slave : public Slave
+{
+ public:
+ JACK_Slave (jack_client_t*);
+ ~JACK_Slave ();
+
+ bool speed_and_position (float& speed, jack_nframes_t& pos);
+
+ bool starting() const { return _starting; }
+ bool locked() const;
+ bool ok() const;
+ jack_nframes_t resolution() const { return 1; }
+ bool requires_seekahead () const { return false; }
+
+ private:
+ jack_client_t* jack;
+ float speed;
+ bool _starting;
+};
+
+} /* namespace */
+
+#endif /* __ardour_slave_h__ */
diff --git a/libs/ardour/ardour/sndfile_helpers.h b/libs/ardour/ardour/sndfile_helpers.h
new file mode 100644
index 0000000000..5bb4937410
--- /dev/null
+++ b/libs/ardour/ardour/sndfile_helpers.h
@@ -0,0 +1,37 @@
+#ifndef __sndfile_helpers_h__
+#define __sndfile_helpers_h__
+
+#include <string>
+#include <sndfile.h>
+
+using std::string;
+
+// Use this define when initializing arrarys for use in sndfile_*_format()
+#define SNDFILE_STR_LENGTH 32
+
+#define SNDFILE_HEADER_FORMATS 7
+extern const char * const sndfile_header_formats_strings[SNDFILE_HEADER_FORMATS+1];
+
+extern int sndfile_header_formats[SNDFILE_HEADER_FORMATS];
+
+#define SNDFILE_BITDEPTH_FORMATS 5
+extern const char * const sndfile_bitdepth_formats_strings[SNDFILE_BITDEPTH_FORMATS+1];
+
+extern int sndfile_bitdepth_formats[SNDFILE_BITDEPTH_FORMATS];
+
+#define SNDFILE_ENDIAN_FORMATS 2
+extern const char * const sndfile_endian_formats_strings[SNDFILE_ENDIAN_FORMATS+1];
+
+extern int sndfile_endian_formats[SNDFILE_ENDIAN_FORMATS];
+
+int sndfile_bitdepth_format_from_string(string);
+int sndfile_header_format_from_string(string);
+int sndfile_endian_format_from_string(string);
+
+int sndfile_data_width (int format);
+
+// It'd be nice if libsndfile did this for us
+string sndfile_major_format(int);
+string sndfile_minor_format(int);
+
+#endif /* __sndfile_helpers_h__ */
diff --git a/libs/ardour/ardour/sndfilesource.h b/libs/ardour/ardour/sndfilesource.h
new file mode 100644
index 0000000000..7f9712b7ec
--- /dev/null
+++ b/libs/ardour/ardour/sndfilesource.h
@@ -0,0 +1,63 @@
+/*
+ Copyright (C) 2000 Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __playlist_snd_file_buffer_h__
+#define __playlist_snd_file_buffer_h__
+
+#include <sndfile.h>
+
+#include <ardour/source.h>
+
+namespace ARDOUR {
+
+class SndFileSource : public Source {
+ public:
+ SndFileSource (const string& path_plus_channel, bool build_peak = true);
+ SndFileSource (const XMLNode&);
+ ~SndFileSource ();
+
+ jack_nframes_t length() const { return _info.frames; }
+ jack_nframes_t read (Sample *dst, jack_nframes_t start, jack_nframes_t cnt) const;
+ void mark_for_remove() {} // we never remove external sndfiles
+ string peak_path(string audio_path);
+ string old_peak_path(string audio_path);
+ string path() const { return _path; }
+
+ static void set_peak_dir (string dir) { peak_dir = dir; }
+
+ private:
+ static string peak_dir;
+
+ SNDFILE *sf;
+ SF_INFO _info;
+ uint16_t channel;
+ mutable float *tmpbuf;
+ mutable jack_nframes_t tmpbufsize;
+ mutable PBD::Lock _tmpbuf_lock;
+ string _path;
+
+ void init (const string &str, bool build_peak);
+ jack_nframes_t read_unlocked (Sample *dst, jack_nframes_t start, jack_nframes_t cnt) const;
+};
+
+}; /* namespace EDL */
+
+#endif /* __playlist_snd_file_buffer_h__ */
+
diff --git a/libs/ardour/ardour/soundseq.h b/libs/ardour/ardour/soundseq.h
new file mode 100644
index 0000000000..4a318e9750
--- /dev/null
+++ b/libs/ardour/ardour/soundseq.h
@@ -0,0 +1,54 @@
+/*
+ Copyright (C) 2001 Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __soundseq_h__
+#define __soundseq_h__
+
+#include "edl.h"
+
+namespace ARDOUR {
+
+typedef gint16 peak_datum;
+
+struct peak_data_t {
+ peak_datum min;
+ peak_datum max;
+};
+
+const uint32_t frames_per_peak = 2048;
+
+class Sound : public EDL::Piece {
+ public:
+ int peak (peak_data_t& pk, uint32_t start, uint32_t cnt);
+ int read_peaks (peak_data_t *, uint32_t npeaks, uint32_t start, uint32_t cnt);
+ int build_peak (uint32_t first_frame, uint32_t cnt);
+};
+
+class SoundPlaylist : public EDL::Playlist {
+ public:
+ int read_peaks (peak_data_t *, uint32_t npeaks, uint32_t start, uint32_t cnt);
+};
+
+} /* namespace ARDOUR */
+
+#endif /* __soundseq_h__ */
+
+
+
diff --git a/libs/ardour/ardour/source.h b/libs/ardour/ardour/source.h
new file mode 100644
index 0000000000..a6138f8239
--- /dev/null
+++ b/libs/ardour/ardour/source.h
@@ -0,0 +1,182 @@
+/*
+ Copyright (C) 2000 Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __ardour_source_h__
+#define __ardour_source_h__
+
+#include <list>
+#include <vector>
+#include <string>
+
+#include <time.h>
+
+#include <sigc++/signal.h>
+
+#include <ardour/ardour.h>
+#include <ardour/stateful.h>
+#include <pbd/xml++.h>
+
+using std::list;
+using std::vector;
+using std::string;
+
+namespace ARDOUR {
+
+struct PeakData {
+ typedef Sample PeakDatum;
+
+ PeakDatum min;
+ PeakDatum max;
+};
+
+const jack_nframes_t frames_per_peak = 256;
+
+class Source : public Stateful, public sigc::trackable
+{
+ public:
+ Source (bool announce=true);
+ Source (const XMLNode&);
+ virtual ~Source ();
+
+ const string& name() const { return _name; }
+ ARDOUR::id_t id() const { return _id; }
+
+ /* returns the number of items in this `source' */
+
+ virtual jack_nframes_t length() const {
+ return _length;
+ }
+
+ virtual jack_nframes_t read (Sample *dst, jack_nframes_t start, jack_nframes_t cnt) const {
+ return 0;
+ }
+
+ virtual jack_nframes_t write (Sample *src, jack_nframes_t cnt) {
+ return 0;
+ }
+
+ uint32_t use_cnt() const { return _use_cnt; }
+ void use ();
+ void release ();
+
+ virtual void mark_for_remove() = 0;
+ virtual void mark_streaming_write_completed () {}
+
+ time_t timestamp() const { return _timestamp; }
+ void stamp (time_t when) { _timestamp = when; }
+
+ void set_captured_for (string str) { _captured_for = str; }
+ string captured_for() const { return _captured_for; }
+
+ uint32_t read_data_count() const { return _read_data_count; }
+ uint32_t write_data_count() const { return _write_data_count; }
+
+ int read_peaks (PeakData *peaks, jack_nframes_t npeaks, jack_nframes_t start, jack_nframes_t cnt, double samples_per_unit) const;
+ int build_peaks ();
+ bool peaks_ready (sigc::slot<void>) const;
+
+ static sigc::signal<void,Source*> SourceCreated;
+
+ sigc::signal<void,Source *> GoingAway;
+ mutable sigc::signal<void> PeaksReady;
+ mutable sigc::signal<void,jack_nframes_t,jack_nframes_t> PeakRangeReady;
+
+ XMLNode& get_state ();
+ int set_state (const XMLNode&);
+
+
+ static int start_peak_thread ();
+ static void stop_peak_thread ();
+
+ static void set_build_missing_peakfiles (bool yn) {
+ _build_missing_peakfiles = yn;
+ }
+ static void set_build_peakfiles (bool yn) {
+ _build_peakfiles = yn;
+ }
+
+ protected:
+ static bool _build_missing_peakfiles;
+ static bool _build_peakfiles;
+
+ string _name;
+ uint32_t _use_cnt;
+ bool _peaks_built;
+ mutable PBD::Lock _lock;
+ jack_nframes_t _length;
+ bool next_peak_clear_should_notify;
+ string peakpath;
+ int peakfile; /* fd */
+ time_t _timestamp;
+ string _captured_for;
+
+ mutable uint32_t _read_data_count; // modified in read()
+ mutable uint32_t _write_data_count; // modified in write()
+
+ int initialize_peakfile (bool newfile, string path);
+ void build_peaks_from_scratch ();
+
+ int do_build_peak (jack_nframes_t, jack_nframes_t);
+ virtual jack_nframes_t read_unlocked (Sample *dst, jack_nframes_t start, jack_nframes_t cnt) const = 0;
+ virtual string peak_path(string audio_path) = 0;
+ virtual string old_peak_path(string audio_path) = 0;
+
+ static pthread_t peak_thread;
+ static bool have_peak_thread;
+ static void* peak_thread_work(void*);
+
+ static int peak_request_pipe[2];
+
+ struct PeakRequest {
+ enum Type {
+ Build,
+ Quit
+ };
+ };
+
+ static vector<Source*> pending_peak_sources;
+ static PBD::Lock pending_peak_sources_lock;
+
+ static void queue_for_peaks (Source&);
+ static void clear_queue_for_peaks ();
+
+ struct PeakBuildRecord {
+ jack_nframes_t frame;
+ jack_nframes_t cnt;
+
+ PeakBuildRecord (jack_nframes_t f, jack_nframes_t c)
+ : frame (f), cnt (c) {}
+ PeakBuildRecord (const PeakBuildRecord& other) {
+ frame = other.frame;
+ cnt = other.cnt;
+ }
+ };
+
+ list<Source::PeakBuildRecord *> pending_peak_builds;
+
+ private:
+ ARDOUR::id_t _id;
+
+ bool Source::file_changed (string path);
+};
+
+}
+
+#endif /* __ardour_source_h__ */
diff --git a/libs/ardour/ardour/spline.h b/libs/ardour/ardour/spline.h
new file mode 100644
index 0000000000..de1ece6edb
--- /dev/null
+++ b/libs/ardour/ardour/spline.h
@@ -0,0 +1,90 @@
+/* This code is based upon work that bore the legend:
+ *
+ * Copyright (C) 1997 David Mosberger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __ardour_spline_h__
+#define __ardour_spline_h__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct _spline Spline;
+typedef struct _spline_point SplinePoint;
+
+struct _spline_point
+{
+ float x;
+ float y;
+};
+
+Spline *spline_new (void);
+void spline_free (Spline *);
+
+void spline_set (Spline *, uint32_t n, SplinePoint *);
+void spline_add (Spline *, uint32_t n, SplinePoint *);
+void spline_solve (Spline *);
+float spline_eval (Spline *, float val);
+void spline_fill (Spline *, float x0, float x1, float *vec, uint32_t veclen);
+float spline_get_max_x (Spline *);
+float spline_get_min_x (Spline *);
+
+struct _spline
+{
+ float *deriv2;
+ float *x;
+ float *y;
+ float max_x;
+ float min_x;
+ SplinePoint *points;
+ uint32_t npoints;
+ uint32_t space;
+
+#ifdef __cplusplus
+
+ void set (uint32_t n, SplinePoint *points) {
+ spline_set (this, n, points);
+ }
+
+ void add (uint32_t n, SplinePoint *points) {
+ spline_add (this, n, points);
+ }
+
+ void solve () {
+ spline_solve (this);
+ }
+
+ float eval (float val) {
+ return spline_eval (this, val);
+ }
+
+ void fill (float x0, float x1, float *vec, uint32_t veclen) {
+ spline_fill (this, x0, x1, vec, veclen);
+ }
+
+#endif /* __cplusplus */
+
+};
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ardour_spline_h__ */
diff --git a/libs/ardour/ardour/state_manager.h b/libs/ardour/ardour/state_manager.h
new file mode 100644
index 0000000000..9dc2ea66ad
--- /dev/null
+++ b/libs/ardour/ardour/state_manager.h
@@ -0,0 +1,48 @@
+#ifndef __ardour_state_manager_h__
+#define __ardour_state_manager_h__
+
+#include <list>
+#include <string>
+
+#include <sigc++/signal.h>
+
+#include <ardour/ardour.h>
+
+namespace ARDOUR {
+
+typedef uint32_t state_id_t;
+
+
+ class StateManager : virtual public sigc::trackable
+{
+ public:
+ struct State {
+ std::string operation;
+ State (std::string why) : operation (why) {}
+ virtual ~State() {}
+ };
+
+ typedef std::list<State*> StateMap;
+
+ StateManager ();
+ virtual ~StateManager ();
+
+ virtual void drop_all_states ();
+ virtual void use_state (state_id_t);
+ virtual void save_state (std::string why);
+
+ sigc::signal<void,Change> StateChanged;
+
+ state_id_t _current_state_id;
+
+ protected:
+ StateMap states;
+
+ virtual Change restore_state (State&) = 0;
+ virtual State* state_factory (std::string why) const = 0;
+ virtual void send_state_changed (Change);
+};
+
+} // namespace ARDOUR
+
+#endif /* __ardour_state_manager_h__ */
diff --git a/libs/ardour/ardour/stateful.h b/libs/ardour/ardour/stateful.h
new file mode 100644
index 0000000000..4f4cb20b39
--- /dev/null
+++ b/libs/ardour/ardour/stateful.h
@@ -0,0 +1,51 @@
+/*
+ Copyright (C) 2000 Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __ardour_stateful_h__
+#define __ardour_stateful_h__
+
+#include <string>
+
+class XMLNode;
+
+class Stateful {
+ public:
+ Stateful();
+ virtual ~Stateful();
+
+ virtual XMLNode& get_state (void) = 0;
+
+ virtual int set_state (const XMLNode&) = 0;
+
+ /* Extra XML nodes */
+
+ void add_extra_xml (XMLNode&);
+ XMLNode *extra_xml (const std::string& str);
+
+ virtual void add_instant_xml (XMLNode&, const std::string& dir);
+ XMLNode *instant_xml (const std::string& str, const std::string& dir);
+
+ protected:
+ XMLNode *_extra_xml;
+ XMLNode *_instant_xml;
+};
+
+#endif /* __ardour_stateful_h__ */
+
diff --git a/libs/ardour/ardour/tempo.h b/libs/ardour/ardour/tempo.h
new file mode 100644
index 0000000000..2f04f603e7
--- /dev/null
+++ b/libs/ardour/ardour/tempo.h
@@ -0,0 +1,323 @@
+/*
+ Copyright (C) 2000 Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __ardour_tempo_h__
+#define __ardour_tempo_h__
+
+#include <list>
+#include <string>
+#include <vector>
+#include <cmath>
+#include <pthread.h>
+#include <pbd/lockmonitor.h>
+#include <pbd/undo.h>
+#include <sigc++/signal.h>
+
+#include <ardour/ardour.h>
+#include <ardour/stateful.h>
+#include <ardour/state_manager.h>
+
+class XMLNode;
+
+using std::list;
+using std::vector;
+
+namespace ARDOUR {
+
+class Tempo {
+ public:
+ Tempo (double bpm)
+ : _beats_per_minute (bpm) {}
+ Tempo (const Tempo& other) {
+ _beats_per_minute = other._beats_per_minute;
+ }
+ void operator= (const Tempo& other) {
+ if (&other != this) {
+ _beats_per_minute = other._beats_per_minute;
+ }
+ }
+
+ double beats_per_minute () const { return _beats_per_minute; }
+ double frames_per_beat (jack_nframes_t sr) const {
+ return ((60.0 * sr) / _beats_per_minute);
+ }
+
+ protected:
+ double _beats_per_minute;
+};
+
+class Meter {
+ public:
+ static const double ticks_per_beat;
+
+ Meter (double bpb, double bt)
+ : _beats_per_bar (bpb), _note_type (bt) {}
+ Meter (const Meter& other) {
+ _beats_per_bar = other._beats_per_bar;
+ _note_type = other._note_type;
+ }
+ void operator= (const Meter& other) {
+ if (&other != this) {
+ _beats_per_bar = other._beats_per_bar;
+ _note_type = other._note_type;
+ }
+ }
+
+ double beats_per_bar () const { return _beats_per_bar; }
+ double note_divisor() const { return _note_type; }
+
+ double frames_per_bar (const Tempo&, jack_nframes_t sr) const;
+
+ protected:
+
+ /* this is the number of beats in a bar. it is a real value
+ because there are musical traditions on our planet
+ that do not limit themselves to integral numbers of beats
+ per bar.
+ */
+
+ double _beats_per_bar;
+
+ /* this is the type of "note" that a beat represents. for example,
+ 4.0 would be a quarter (crotchet) note, 8.0 would be an eighth
+ (quaver) note, etc.
+ */
+
+ double _note_type;
+};
+
+class MetricSection {
+ public:
+ MetricSection (const BBT_Time& start)
+ : _start (start), _frame (0), _movable (true) {}
+ virtual ~MetricSection() {}
+
+ const BBT_Time& start() const { return _start; }
+ const jack_nframes_t frame() const { return _frame; }
+
+ void set_movable (bool yn) { _movable = yn; }
+ bool movable() const { return _movable; }
+
+ virtual void set_frame (jack_nframes_t f) {
+ _frame = f;
+ };
+
+ virtual void set_start (const BBT_Time& w) {
+ _start = w;
+ }
+
+ /* MeterSections are not stateful in the full sense,
+ but we do want them to control their own
+ XML state information.
+ */
+
+ virtual XMLNode& get_state() const = 0;
+
+ private:
+ BBT_Time _start;
+ jack_nframes_t _frame;
+ bool _movable;
+};
+
+class MeterSection : public MetricSection, public Meter {
+ public:
+ MeterSection (const BBT_Time& start, double bpb, double note_type)
+ : MetricSection (start), Meter (bpb, note_type) {}
+ MeterSection (const XMLNode&);
+
+ static const string xml_state_node_name;
+
+ XMLNode& get_state() const;
+};
+
+class TempoSection : public MetricSection, public Tempo {
+ public:
+ TempoSection (const BBT_Time& start, double qpm)
+ : MetricSection (start), Tempo (qpm) {}
+ TempoSection (const XMLNode&);
+
+ static const string xml_state_node_name;
+
+ XMLNode& get_state() const;
+};
+
+typedef list<MetricSection*> Metrics;
+
+class TempoMapState : public StateManager::State {
+ public:
+ TempoMapState (std::string why)
+ : StateManager::State (why) {
+ metrics = new Metrics;
+ }
+
+ Metrics *metrics;
+};
+
+class TempoMap : public Stateful, public StateManager {
+ public:
+
+ TempoMap (jack_nframes_t frame_rate);
+ ~TempoMap();
+
+ /* measure-based stuff */
+
+ enum BBTPointType {
+ Bar,
+ Beat,
+ };
+
+ struct BBTPoint {
+ BBTPointType type;
+ jack_nframes_t frame;
+ const Meter* meter;
+ const Tempo* tempo;
+ uint32_t bar;
+ uint32_t beat;
+
+ BBTPoint (const Meter& m, const Tempo& t, jack_nframes_t f, BBTPointType ty, uint32_t b, uint32_t e)
+ : type (ty), frame (f), meter (&m), tempo (&t), bar (b), beat (e) {}
+ };
+
+ typedef vector<BBTPoint> BBTPointList;
+
+ template<class T> void apply_with_metrics (T& obj, void (T::*method)(const Metrics&)) {
+ LockMonitor lm (lock, __LINE__, __FILE__);
+ (obj.*method)(*metrics);
+ }
+
+ BBTPointList *get_points (jack_nframes_t start, jack_nframes_t end) const;
+
+ void bbt_time (jack_nframes_t when, BBT_Time&) const;
+ jack_nframes_t frame_time (const BBT_Time&) const;
+ jack_nframes_t bbt_duration_at (jack_nframes_t, const BBT_Time&, int dir) const;
+
+ static const Tempo& default_tempo() { return _default_tempo; }
+ static const Meter& default_meter() { return _default_meter; }
+
+ const Tempo& tempo_at (jack_nframes_t);
+ const Meter& meter_at (jack_nframes_t);
+
+ void add_tempo(const Tempo&, BBT_Time where);
+ void add_meter(const Meter&, BBT_Time where);
+
+ void move_tempo (TempoSection&, const BBT_Time& to);
+ void move_meter (MeterSection&, const BBT_Time& to);
+
+ void remove_tempo(const TempoSection&);
+ void remove_meter(const MeterSection&);
+
+ void replace_tempo (TempoSection& existing, const Tempo& replacement);
+ void replace_meter (MeterSection& existing, const Meter& replacement);
+
+
+ jack_nframes_t round_to_bar (jack_nframes_t frame, int dir);
+
+ jack_nframes_t round_to_beat (jack_nframes_t frame, int dir);
+
+ jack_nframes_t round_to_beat_subdivision (jack_nframes_t fr, int sub_num);
+
+ jack_nframes_t round_to_tick (jack_nframes_t frame, int dir);
+
+ void set_length (jack_nframes_t frames);
+
+ XMLNode& get_state (void);
+ int set_state (const XMLNode&);
+
+ void dump (std::ostream&) const;
+ void clear ();
+
+ UndoAction get_memento() const;
+
+ /* this is a helper class that we use to be able to keep
+ track of which meter *AND* tempo are in effect at
+ a given point in time.
+ */
+
+ class Metric {
+ public:
+ Metric (const Meter& m, const Tempo& t) : _meter (&m), _tempo (&t), _frame (0) {}
+
+ void set_tempo (const Tempo& t) { _tempo = &t; }
+ void set_meter (const Meter& m) { _meter = &m; }
+ void set_frame (jack_nframes_t f) { _frame = f; }
+ void set_start (const BBT_Time& t) { _start = t; }
+
+ const Meter& meter() const { return *_meter; }
+ const Tempo& tempo() const { return *_tempo; }
+ jack_nframes_t frame() const { return _frame; }
+ const BBT_Time& start() const { return _start; }
+
+ private:
+ const Meter* _meter;
+ const Tempo* _tempo;
+ jack_nframes_t _frame;
+ BBT_Time _start;
+
+ };
+
+ Metric metric_at (BBT_Time bbt) const;
+ Metric metric_at (jack_nframes_t) const;
+ void bbt_time_with_metric (jack_nframes_t, BBT_Time&, const Metric&) const;
+
+ private:
+ static Tempo _default_tempo;
+ static Meter _default_meter;
+
+ Metrics *metrics;
+ jack_nframes_t _frame_rate;
+ jack_nframes_t last_bbt_when;
+ bool last_bbt_valid;
+ BBT_Time last_bbt;
+ mutable PBD::Lock lock;
+
+ void timestamp_metrics ();
+
+
+ jack_nframes_t round_to_type (jack_nframes_t fr, int dir, BBTPointType);
+
+ jack_nframes_t frame_time_unlocked (const BBT_Time&) const;
+
+ void bbt_time_unlocked (jack_nframes_t, BBT_Time&) const;
+
+ jack_nframes_t bbt_duration_at_unlocked (const BBT_Time& when, const BBT_Time& bbt, int dir) const;
+
+ const MeterSection& first_meter() const;
+ const TempoSection& first_tempo() const;
+
+ jack_nframes_t count_frames_between (const BBT_Time&, const BBT_Time&) const;
+ jack_nframes_t count_frames_between_metrics (const Meter&, const Tempo&, const BBT_Time&, const BBT_Time&) const;
+
+ int move_metric_section (MetricSection&, const BBT_Time& to);
+ void do_insert (MetricSection* section);
+
+ Change restore_state (StateManager::State&);
+ StateManager::State* state_factory (std::string why) const;
+
+ bool in_set_state;
+
+ /* override state_manager::save_state so we can check in_set_state */
+
+ void save_state (std::string why);
+
+};
+
+}; /* namespace ARDOUR */
+
+#endif /* __ardour_tempo_h__ */
diff --git a/libs/ardour/ardour/timestamps.h b/libs/ardour/ardour/timestamps.h
new file mode 100644
index 0000000000..4ebc28b2f9
--- /dev/null
+++ b/libs/ardour/ardour/timestamps.h
@@ -0,0 +1,13 @@
+#ifndef __ardour_timestamps_h__
+#define __ardour_timestamps_h__
+
+#ifdef WITH_JACK_TIMESTAMPS
+#include <jack/timestamps.h>
+#else
+#define jack_timestamp(s)
+#define jack_init_timestamps(n)
+#define jack_dump_timestamps(o)
+#define jack_reset_timestamps()
+#endif
+
+#endif /* __ardour_timestamps_h__ */
diff --git a/libs/ardour/ardour/types.h b/libs/ardour/ardour/types.h
new file mode 100644
index 0000000000..95f3c471f2
--- /dev/null
+++ b/libs/ardour/ardour/types.h
@@ -0,0 +1,243 @@
+/*
+ Copyright (C) 2002 Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __ardour_types_h__
+#define __ardour_types_h__
+
+#ifndef __STDC_FORMAT_MACROS
+#define __STDC_FORMAT_MACROS /* PRI<foo>; C++ requires explicit requesting of these */
+#endif
+
+#include <inttypes.h>
+#include <jack/types.h>
+#include <map>
+
+#if __GNUC__ < 3
+
+typedef int intptr_t;
+#endif
+
+namespace ARDOUR {
+
+ class Source;
+
+ typedef jack_default_audio_sample_t Sample;
+ typedef float pan_t;
+ typedef float gain_t;
+ typedef uint32_t layer_t;
+ typedef uint64_t id_t;
+
+ enum IOChange {
+ NoChange = 0,
+ ConfigurationChanged = 0x1,
+ ConnectionsChanged = 0x2
+ };
+
+ enum OverlapType {
+ OverlapNone, // no overlap
+ OverlapInternal, // the overlap is 100% with the object
+ OverlapStart, // overlap covers start, but ends within
+ OverlapEnd, // overlap begins within and covers end
+ OverlapExternal // overlap extends to (at least) begin+end
+ };
+
+ OverlapType coverage (jack_nframes_t start_a, jack_nframes_t end_a,
+ jack_nframes_t start_b, jack_nframes_t end_b);
+
+ enum AutomationType {
+ GainAutomation = 0x1,
+ PanAutomation = 0x2,
+ PluginAutomation = 0x4,
+ SoloAutomation = 0x8,
+ MuteAutomation = 0x10,
+ };
+
+ enum AutoState {
+ Off = 0x0,
+ Write = 0x1,
+ Touch = 0x2,
+ Play = 0x4
+ };
+
+ enum AutoStyle {
+ Absolute = 0x1,
+ Trim = 0x2
+ };
+
+ enum AlignStyle {
+ CaptureTime,
+ ExistingMaterial
+ };
+
+ enum MeterPoint {
+ MeterInput,
+ MeterPreFader,
+ MeterPostFader
+ };
+
+ enum smpte_wrap_t {
+ smpte_wrap_none = 0,
+ smpte_wrap_frames,
+ smpte_wrap_seconds,
+ smpte_wrap_minutes,
+ smpte_wrap_hours
+ };
+
+ struct SMPTE_Time {
+ bool negative;
+ long hours;
+ long minutes;
+ long seconds;
+ long frames;
+ long subframes; // mostly not used
+
+ SMPTE_Time() {
+ negative = false;
+ hours = 0;
+ minutes = 0;
+ seconds = 0;
+ frames = 0;
+ subframes = 0;
+ }
+
+ };
+
+ struct BBT_Time {
+ uint32_t bars;
+ uint32_t beats;
+ uint32_t ticks;
+
+ BBT_Time() {
+ bars = 1;
+ beats = 1;
+ ticks = 0;
+ }
+
+ /* we can't define arithmetic operators for BBT_Time, because
+ the results depend on a TempoMap, but we can define
+ a useful check on the less-than condition.
+ */
+
+ bool operator< (const BBT_Time& other) const {
+ return bars < other.bars ||
+ (bars == other.bars && beats < other.beats) ||
+ (bars == other.bars && beats == other.beats && ticks < other.ticks);
+ }
+
+ bool operator== (const BBT_Time& other) const {
+ return bars == other.bars && beats == other.beats && ticks == other.ticks;
+ }
+
+ };
+
+ struct AnyTime {
+ enum Type {
+ SMPTE,
+ BBT,
+ Frames,
+ Seconds
+ };
+
+ Type type;
+
+ SMPTE_Time smpte;
+ BBT_Time bbt;
+
+ union {
+ jack_nframes_t frames;
+ double seconds;
+ };
+ };
+
+ struct AudioRange {
+ jack_nframes_t start;
+ jack_nframes_t end;
+ uint32_t id;
+
+ AudioRange (jack_nframes_t s, jack_nframes_t e, uint32_t i) : start (s), end (e) , id (i) {}
+
+ jack_nframes_t length() { return end - start + 1; }
+
+ bool operator== (const AudioRange& other) const {
+ return start == other.start && end == other.end && id == other.id;
+ }
+
+ bool equal (const AudioRange& other) const {
+ return start == other.start && end == other.end;
+ }
+
+ OverlapType coverage (jack_nframes_t s, jack_nframes_t e) const {
+ return ARDOUR::coverage (start, end, s, e);
+ }
+ };
+
+ struct MusicRange {
+ BBT_Time start;
+ BBT_Time end;
+ uint32_t id;
+
+ MusicRange (BBT_Time& s, BBT_Time& e, uint32_t i)
+ : start (s), end (e), id (i) {}
+
+ bool operator== (const MusicRange& other) const {
+ return start == other.start && end == other.end && id == other.id;
+ }
+
+ bool equal (const MusicRange& other) const {
+ return start == other.start && end == other.end;
+ }
+ };
+
+ enum EditMode {
+ Slide,
+ Splice,
+ };
+
+ enum RegionPoint {
+ Start,
+ End,
+ SyncPoint
+ };
+
+ enum Change {
+ range_guarantee = ~0
+ };
+
+
+ enum Placement {
+ PreFader,
+ PostFader
+ };
+
+ enum CrossfadeModel {
+ FullCrossfade,
+ ShortCrossfade
+ };
+
+ struct InterThreadInfo {
+ volatile bool done;
+ volatile bool cancel;
+ volatile float progress;
+ pthread_t thread;
+ };
+};
+
+#endif /* __ardour_types_h__ */
+
diff --git a/libs/ardour/ardour/utils.h b/libs/ardour/ardour/utils.h
new file mode 100644
index 0000000000..36ee6f105f
--- /dev/null
+++ b/libs/ardour/ardour/utils.h
@@ -0,0 +1,59 @@
+/*
+ Copyright (C) 1999 Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __ardour_utils_h__
+#define __ardour_utils_h__
+
+#include <iostream>
+#include <string>
+#include <cmath>
+
+#include "ardour.h"
+
+class XMLNode;
+
+using std::ostream;
+
+void elapsed_time_to_str (char *buf, uint32_t seconds);
+string legalize_for_path (std::string str);
+ostream& operator<< (ostream& o, const ARDOUR::BBT_Time& bbt);
+XMLNode* find_named_node (const XMLNode& node, std::string name);
+string placement_as_string (ARDOUR::Placement);
+
+static inline float f_max(float x, float a) {
+ x -= a;
+ x += fabsf (x);
+ x *= 0.5f;
+ x += a;
+
+ return (x);
+}
+
+int cmp_nocase (const std::string& s, const std::string& s2);
+
+int tokenize_fullpath (string fullpath, string& path, string& name);
+
+int touch_file(string path);
+
+uint32_t long get_uid();
+
+string region_name_from_path (string path);
+
+#endif /* __ardour_utils_h__ */
diff --git a/libs/ardour/ardour/vst_plugin.h b/libs/ardour/ardour/vst_plugin.h
new file mode 100644
index 0000000000..6ae64ab50c
--- /dev/null
+++ b/libs/ardour/ardour/vst_plugin.h
@@ -0,0 +1,112 @@
+/*
+ Copyright (C) 2004 Paul Davis
+
+ 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; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __ardour_vst_plugin_h__
+#define __ardour_vst_plugin_h__
+
+#include <list>
+#include <map>
+#include <set>
+#include <vector>
+#include <string>
+#include <dlfcn.h>
+
+#include <midi++/controllable.h>
+#include <sigc++/signal.h>
+
+#include <jack/types.h>
+#include <ardour/stateful.h>
+#include <ardour/plugin_state.h>
+#include <ardour/plugin.h>
+#include <ardour/vst_plugin.h>
+
+using std::string;
+using std::vector;
+using std::list;
+using std::map;
+
+struct _FSTHandle;
+struct _FST;
+typedef struct _FSTHandle FSTHandle;
+typedef struct _FST FST;
+class AEffect;
+
+namespace ARDOUR {
+class AudioEngine;
+class Session;
+
+class VSTPlugin : public ARDOUR::Plugin
+{
+ public:
+ VSTPlugin (ARDOUR::AudioEngine&, ARDOUR::Session&, FSTHandle* handle);
+ VSTPlugin (const VSTPlugin &);
+ ~VSTPlugin ();
+
+ /* Plugin interface */
+
+ uint32_t unique_id() const;
+ const char * label() const;
+ const char * name() const;
+ const char * maker() const;
+ uint32_t parameter_count() const;
+ float default_value (uint32_t port);
+ jack_nframes_t latency() const;
+ void set_parameter (uint32_t port, float val);
+ float get_parameter (uint32_t port) const;
+ int get_parameter_descriptor (uint32_t which, ParameterDescriptor&) const;
+ std::set<uint32_t> automatable() const;
+ uint32_t nth_parameter (uint32_t port, bool& ok) const;
+ void activate ();
+ void deactivate ();
+ void set_block_size (jack_nframes_t nframes);
+ int connect_and_run (vector<Sample*>& bufs, uint32_t maxbuf, int32_t& in, int32_t& out, jack_nframes_t nframes, jack_nframes_t offset);
+ void store_state (ARDOUR::PluginState&);
+ void restore_state (ARDOUR::PluginState&);
+ string describe_parameter (uint32_t);
+ string state_node_name() const { return "vst"; }
+ void print_parameter (uint32_t, char*, uint32_t len) const;
+
+ bool parameter_is_audio(uint32_t i) const { return false; }
+ bool parameter_is_control(uint32_t i) const { return true; }
+ bool parameter_is_input(uint32_t i) const { return true; }
+ bool parameter_is_output(uint32_t i) const { return false; }
+
+ bool load_preset (const string preset_label );
+ bool save_preset(string name);
+
+ bool has_editor () const;
+
+ XMLNode& get_state();
+ int set_state(const XMLNode& node);
+
+ AEffect* plugin() const { return _plugin; }
+ FST* fst() const { return _fst; }
+
+
+ private:
+ FSTHandle* handle;
+ FST* _fst;
+ AEffect* _plugin;
+ bool been_resumed;
+};
+
+}
+
+#endif /* __ardour_vst_plugin_h__ */