summaryrefslogtreecommitdiff
path: root/libs/ardour/ardour
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2008-06-02 21:41:35 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2008-06-02 21:41:35 +0000
commit449aab3c465bbbf66d221fac3d7ea559f1720357 (patch)
tree6843cc40c88250a132acac701271f1504cd2df04 /libs/ardour/ardour
parent9c0d7d72d70082a54f823cd44c0ccda5da64bb6f (diff)
rollback to 3428, before the mysterious removal of libs/* at 3431/3432
git-svn-id: svn://localhost/ardour2/branches/3.0@3435 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/ardour/ardour')
-rw-r--r--libs/ardour/ardour/.cvsignore1
-rw-r--r--libs/ardour/ardour/amp.h44
-rw-r--r--libs/ardour/ardour/analyser.h35
-rw-r--r--libs/ardour/ardour/ardour.h87
-rw-r--r--libs/ardour/ardour/audio_buffer.h121
-rw-r--r--libs/ardour/ardour/audio_diskstream.h277
-rw-r--r--libs/ardour/ardour/audio_library.h54
-rw-r--r--libs/ardour/ardour/audio_port.h46
-rw-r--r--libs/ardour/ardour/audio_track.h80
-rw-r--r--libs/ardour/ardour/audio_unit.h172
-rw-r--r--libs/ardour/ardour/audioanalyser.h74
-rw-r--r--libs/ardour/ardour/audioengine.h276
-rw-r--r--libs/ardour/ardour/audiofilesource.h183
-rw-r--r--libs/ardour/ardour/audioplaylist.h93
-rw-r--r--libs/ardour/ardour/audioregion.h204
-rw-r--r--libs/ardour/ardour/audiosource.h159
-rw-r--r--libs/ardour/ardour/auditioner.h70
-rw-r--r--libs/ardour/ardour/auto_bundle.h50
-rw-r--r--libs/ardour/ardour/automatable.h121
-rw-r--r--libs/ardour/ardour/automation_control.h64
-rw-r--r--libs/ardour/ardour/automation_event.h309
-rw-r--r--libs/ardour/ardour/base_audio_port.h106
-rw-r--r--libs/ardour/ardour/base_midi_port.h67
-rw-r--r--libs/ardour/ardour/buffer.h92
-rw-r--r--libs/ardour/ardour/buffer_set.h159
-rw-r--r--libs/ardour/ardour/bundle.h73
-rw-r--r--libs/ardour/ardour/caimportable.h48
-rw-r--r--libs/ardour/ardour/chan_count.h126
-rw-r--r--libs/ardour/ardour/click.h45
-rw-r--r--libs/ardour/ardour/configuration.h106
-rw-r--r--libs/ardour/ardour/configuration_variable.h184
-rw-r--r--libs/ardour/ardour/configuration_vars.h176
-rw-r--r--libs/ardour/ardour/control_protocol_manager.h93
-rw-r--r--libs/ardour/ardour/control_protocol_search_path.h42
-rw-r--r--libs/ardour/ardour/coreaudiosource.h57
-rw-r--r--libs/ardour/ardour/crossfade.h179
-rw-r--r--libs/ardour/ardour/crossfade_compare.h42
-rw-r--r--libs/ardour/ardour/curve.h62
-rw-r--r--libs/ardour/ardour/cycle_timer.h50
-rw-r--r--libs/ardour/ardour/cycles.h221
-rw-r--r--libs/ardour/ardour/dB.h33
-rw-r--r--libs/ardour/ardour/data_type.h130
-rw-r--r--libs/ardour/ardour/directory_names.h23
-rw-r--r--libs/ardour/ardour/diskstream.h308
-rw-r--r--libs/ardour/ardour/export.h107
-rw-r--r--libs/ardour/ardour/filename_extensions.h17
-rw-r--r--libs/ardour/ardour/filesystem_paths.h50
-rw-r--r--libs/ardour/ardour/filter.h51
-rw-r--r--libs/ardour/ardour/gain.h43
-rw-r--r--libs/ardour/ardour/gdither.h92
-rw-r--r--libs/ardour/ardour/gdither_types.h48
-rw-r--r--libs/ardour/ardour/gdither_types_internal.h74
-rw-r--r--libs/ardour/ardour/importable_source.h43
-rw-r--r--libs/ardour/ardour/internal_audio_port.h55
-rw-r--r--libs/ardour/ardour/internal_port.h82
-rw-r--r--libs/ardour/ardour/io.h391
-rw-r--r--libs/ardour/ardour/io_processor.h86
-rw-r--r--libs/ardour/ardour/jack_audio_port.h51
-rw-r--r--libs/ardour/ardour/jack_midi_port.h52
-rw-r--r--libs/ardour/ardour/jack_port.h112
-rw-r--r--libs/ardour/ardour/ladspa.h606
-rw-r--r--libs/ardour/ardour/ladspa_plugin.h147
-rw-r--r--libs/ardour/ardour/latent.h26
-rw-r--r--libs/ardour/ardour/location.h206
-rw-r--r--libs/ardour/ardour/logcurve.h132
-rw-r--r--libs/ardour/ardour/lv2_plugin.h171
-rw-r--r--libs/ardour/ardour/meter.h77
-rw-r--r--libs/ardour/ardour/midi_buffer.h102
-rw-r--r--libs/ardour/ardour/midi_diskstream.h184
-rw-r--r--libs/ardour/ardour/midi_model.h252
-rw-r--r--libs/ardour/ardour/midi_playlist.h84
-rw-r--r--libs/ardour/ardour/midi_port.h47
-rw-r--r--libs/ardour/ardour/midi_region.h121
-rw-r--r--libs/ardour/ardour/midi_ring_buffer.h466
-rw-r--r--libs/ardour/ardour/midi_source.h119
-rw-r--r--libs/ardour/ardour/midi_stretch.h40
-rw-r--r--libs/ardour/ardour/midi_track.h111
-rw-r--r--libs/ardour/ardour/midi_util.h73
-rw-r--r--libs/ardour/ardour/mix.h65
-rw-r--r--libs/ardour/ardour/named_selection.h55
-rw-r--r--libs/ardour/ardour/noise.h38
-rw-r--r--libs/ardour/ardour/note.h82
-rw-r--r--libs/ardour/ardour/osc.h120
-rw-r--r--libs/ardour/ardour/panner.h299
-rw-r--r--libs/ardour/ardour/parameter.h168
-rw-r--r--libs/ardour/ardour/pcm_utils.h41
-rw-r--r--libs/ardour/ardour/peak.h36
-rw-r--r--libs/ardour/ardour/pitch.h62
-rw-r--r--libs/ardour/ardour/playlist.h287
-rw-r--r--libs/ardour/ardour/playlist_factory.h44
-rw-r--r--libs/ardour/ardour/playlist_templates.h48
-rw-r--r--libs/ardour/ardour/plugin.h174
-rw-r--r--libs/ardour/ardour/plugin_insert.h131
-rw-r--r--libs/ardour/ardour/plugin_manager.h101
-rw-r--r--libs/ardour/ardour/port.h180
-rw-r--r--libs/ardour/ardour/port_insert.h73
-rw-r--r--libs/ardour/ardour/port_set.h161
-rw-r--r--libs/ardour/ardour/processor.h123
-rw-r--r--libs/ardour/ardour/profile.h58
-rw-r--r--libs/ardour/ardour/quantize.h41
-rw-r--r--libs/ardour/ardour/rb_effect.h42
-rw-r--r--libs/ardour/ardour/readable.h20
-rw-r--r--libs/ardour/ardour/recent_sessions.h39
-rw-r--r--libs/ardour/ardour/region.h313
-rw-r--r--libs/ardour/ardour/region_factory.h64
-rw-r--r--libs/ardour/ardour/resampled_source.h55
-rw-r--r--libs/ardour/ardour/reverse.h37
-rw-r--r--libs/ardour/ardour/route.h384
-rw-r--r--libs/ardour/ardour/route_group.h124
-rw-r--r--libs/ardour/ardour/route_group_specialized.h41
-rw-r--r--libs/ardour/ardour/runtime_functions.h40
-rw-r--r--libs/ardour/ardour/send.h74
-rw-r--r--libs/ardour/ardour/session.h1714
-rw-r--r--libs/ardour/ardour/session_directory.h136
-rw-r--r--libs/ardour/ardour/session_object.h65
-rw-r--r--libs/ardour/ardour/session_playlist.h46
-rw-r--r--libs/ardour/ardour/session_region.h38
-rw-r--r--libs/ardour/ardour/session_route.h76
-rw-r--r--libs/ardour/ardour/session_selection.h39
-rw-r--r--libs/ardour/ardour/session_state_utils.h65
-rw-r--r--libs/ardour/ardour/session_utils.h26
-rw-r--r--libs/ardour/ardour/silentfilesource.h68
-rw-r--r--libs/ardour/ardour/slave.h153
-rw-r--r--libs/ardour/ardour/smf_reader.h87
-rw-r--r--libs/ardour/ardour/smf_source.h151
-rw-r--r--libs/ardour/ardour/smpte.h79
-rw-r--r--libs/ardour/ardour/sndfile_helpers.h58
-rw-r--r--libs/ardour/ardour/sndfileimportable.h50
-rw-r--r--libs/ardour/ardour/sndfilesource.h109
-rw-r--r--libs/ardour/ardour/soundseq.h53
-rw-r--r--libs/ardour/ardour/source.h112
-rw-r--r--libs/ardour/ardour/source_factory.h60
-rw-r--r--libs/ardour/ardour/spline.h90
-rw-r--r--libs/ardour/ardour/stretch.h62
-rw-r--r--libs/ardour/ardour/tape_file_matcher.h45
-rw-r--r--libs/ardour/ardour/template_utils.h20
-rw-r--r--libs/ardour/ardour/tempo.h322
-rw-r--r--libs/ardour/ardour/timestamps.h32
-rw-r--r--libs/ardour/ardour/track.h151
-rw-r--r--libs/ardour/ardour/transient_detector.h58
-rw-r--r--libs/ardour/ardour/types.h443
-rw-r--r--libs/ardour/ardour/user_bundle.h72
-rw-r--r--libs/ardour/ardour/utils.h76
-rw-r--r--libs/ardour/ardour/vst_plugin.h116
144 files changed, 17552 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/amp.h b/libs/ardour/ardour/amp.h
new file mode 100644
index 0000000000..cdbcacbd91
--- /dev/null
+++ b/libs/ardour/ardour/amp.h
@@ -0,0 +1,44 @@
+/*
+ Copyright (C) 2006 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_amp_h__
+#define __ardour_amp_h__
+
+#include <ardour/types.h>
+
+namespace ARDOUR {
+
+class BufferSet;
+
+
+/** Applies a declick operation to all audio inputs, passing the same number of
+ * audio outputs, and passing through any other types unchanged.
+ *
+ * FIXME: make this a Processor.
+ */
+class Amp {
+public:
+ static void run_in_place (BufferSet& bufs, nframes_t nframes, gain_t initial, gain_t target, bool invert_polarity);
+
+ static void apply_simple_gain(BufferSet& bufs, nframes_t nframes, gain_t target);
+};
+
+
+} // namespace ARDOUR
+
+#endif // __ardour_amp_h__
diff --git a/libs/ardour/ardour/analyser.h b/libs/ardour/ardour/analyser.h
new file mode 100644
index 0000000000..8771cab6b0
--- /dev/null
+++ b/libs/ardour/ardour/analyser.h
@@ -0,0 +1,35 @@
+#ifndef __ardour_analyser_h__
+#define __ardour_analyser_h__
+
+#include <glibmm/thread.h>
+#include <boost/shared_ptr.hpp>
+
+namespace ARDOUR {
+
+class AudioFileSource;
+class Source;
+class TransientDetector;
+
+class Analyser {
+
+ public:
+ Analyser();
+ ~Analyser ();
+
+ static void init ();
+ static void queue_source_for_analysis (boost::shared_ptr<Source>, bool force);
+ static void work ();
+
+ private:
+ static Analyser* the_analyser;
+ static Glib::StaticMutex analysis_queue_lock;
+ static Glib::Cond* SourcesToAnalyse;
+ static std::list<boost::weak_ptr<Source> > analysis_queue;
+
+ static void analyse_audio_file_source (boost::shared_ptr<AudioFileSource>);
+};
+
+
+}
+
+#endif /* __ardour_analyser_h__ */
diff --git a/libs/ardour/ardour/ardour.h b/libs/ardour/ardour/ardour.h
new file mode 100644
index 0000000000..6f653f10bf
--- /dev/null
+++ b/libs/ardour/ardour/ardour.h
@@ -0,0 +1,87 @@
+/*
+ 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.
+
+*/
+
+#ifndef __ardour_ardour_h__
+#define __ardour_ardour_h__
+
+#include <map>
+#include <string>
+
+#include <limits.h>
+#include <signal.h>
+
+#include <pbd/error.h>
+#include <pbd/failed_constructor.h>
+
+#include <ardour/configuration.h>
+#include <ardour/types.h>
+
+namespace MIDI {
+ class MachineControl;
+ class Port;
+}
+
+namespace ARDOUR {
+
+ class AudioEngine;
+ class OSC;
+
+ extern OSC* osc;
+
+ static const nframes_t max_frames = JACK_MAX_FRAMES;
+ extern sigc::signal<void,std::string> BootMessage;
+
+ int init (bool with_vst, bool try_optimization);
+ int cleanup ();
+
+ std::string get_ardour_revision ();
+
+ void find_bindings_files (std::map<std::string,std::string>&);
+
+ const layer_t max_layer = UCHAR_MAX;
+
+ microseconds_t get_microseconds ();
+
+ 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;
+ };
+
+ static const double SHUTTLE_FRACT_SPEED1=0.48412291827; /* derived from A1,A2 */
+
+ void setup_fpu ();
+}
+
+/* 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_buffer.h b/libs/ardour/ardour/audio_buffer.h
new file mode 100644
index 0000000000..71eaf60ade
--- /dev/null
+++ b/libs/ardour/ardour/audio_buffer.h
@@ -0,0 +1,121 @@
+/*
+ Copyright (C) 2006 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_audio_buffer_h__
+#define __ardour_audio_buffer_h__
+
+#include <cstring>
+#include <ardour/buffer.h>
+
+namespace ARDOUR {
+
+class AudioBuffer : public Buffer
+{
+public:
+ AudioBuffer(size_t capacity);
+
+ ~AudioBuffer();
+
+ void silence(nframes_t len, nframes_t offset = 0) {
+ if (!_silent) {
+ assert(_capacity > 0);
+ assert(offset + len <= _capacity);
+ memset(_data + offset, 0, sizeof (Sample) * len);
+ if (offset == 0 && len == _capacity) {
+ _silent = true;
+ }
+ }
+ }
+
+ /** Read @a len frames FROM THE START OF @a src into self at @a offset */
+ void read_from(const Buffer& src, nframes_t len, nframes_t offset) {
+ assert(&src != this);
+ assert(_capacity > 0);
+ assert(src.type() == DataType::AUDIO);
+ assert(offset + len <= _capacity);
+ memcpy(_data + offset, ((AudioBuffer&)src).data(), sizeof(Sample) * len);
+ _silent = src.silent();
+ }
+
+ /** Accumulate (add)@a len frames FROM THE START OF @a src into self at @a offset */
+ void accumulate_from(const AudioBuffer& src, nframes_t len, nframes_t offset) {
+ assert(_capacity > 0);
+ assert(offset + len <= _capacity);
+
+ Sample* const dst_raw = _data + offset;
+ const Sample* const src_raw = src.data();
+
+ mix_buffers_no_gain(dst_raw, src_raw, len);
+
+ _silent = (src.silent() && _silent);
+ }
+
+ /** Accumulate (add) @a len frames FROM THE START OF @a src into self at @a offset
+ * scaling by @a gain_coeff */
+ void accumulate_with_gain_from(const AudioBuffer& src, nframes_t len, nframes_t offset, gain_t gain_coeff) {
+ assert(_capacity > 0);
+ assert(offset + len <= _capacity);
+
+ Sample* const dst_raw = _data + offset;
+ const Sample* const src_raw = src.data();
+
+ mix_buffers_with_gain (dst_raw, src_raw, len, gain_coeff);
+
+ _silent = ( (src.silent() && _silent) || (_silent && gain_coeff == 0) );
+ }
+
+ void apply_gain(gain_t gain, nframes_t len, nframes_t offset=0) {
+ apply_gain_to_buffer (_data + offset, len, gain);
+ }
+
+ /** Set the data contained by this buffer manually (for setting directly to jack buffer).
+ *
+ * Constructor MUST have been passed capacity=0 or this will die (to prevent mem leaks).
+ */
+ void set_data (Sample* data, size_t size) {
+ assert(!_owns_data); // prevent leaks
+ _capacity = size;
+ _size = size;
+ _data = data;
+ _silent = false;
+ }
+
+ /** Reallocate the buffer used internally to handle at least @nframes of data
+ *
+ * Constructor MUST have been passed capacity!=0 or this will die (to prevent mem leaks).
+ */
+ void resize (size_t nframes);
+
+ const Sample* data () const { return _data; }
+ Sample* data () { return _data; }
+
+ const Sample* data(nframes_t nframes, nframes_t offset) const
+ { assert(offset + nframes <= _capacity); return _data + offset; }
+
+ Sample* data (nframes_t nframes, nframes_t offset)
+ { assert(offset + nframes <= _capacity); return _data + offset; }
+
+private:
+ bool _owns_data;
+ Sample* _data; ///< Actual buffer contents
+};
+
+
+} // namespace ARDOUR
+
+#endif // __ardour_audio_audio_buffer_h__
diff --git a/libs/ardour/ardour/audio_diskstream.h b/libs/ardour/ardour/audio_diskstream.h
new file mode 100644
index 0000000000..aaf5461361
--- /dev/null
+++ b/libs/ardour/ardour/audio_diskstream.h
@@ -0,0 +1,277 @@
+/*
+ Copyright (C) 2000-2006 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_audio_diskstream_h__
+#define __ardour_audio_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/stateful.h>
+#include <pbd/rcu.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/diskstream.h>
+#include <ardour/audioplaylist.h>
+
+struct tm;
+
+namespace ARDOUR {
+
+class AudioEngine;
+class Send;
+class Session;
+class AudioPlaylist;
+class AudioFileSource;
+class IO;
+
+class AudioDiskstream : public Diskstream
+{
+ public:
+ AudioDiskstream (Session &, const string& name, Diskstream::Flag f = Recordable);
+ AudioDiskstream (Session &, const XMLNode&);
+ ~AudioDiskstream();
+
+ float playback_buffer_load() const;
+ float capture_buffer_load() const;
+
+ string input_source (uint32_t n=0) const {
+ boost::shared_ptr<ChannelList> c = channels.reader();
+ if (n < c->size()) {
+ return (*c)[n]->source ? (*c)[n]->source->name() : "";
+ } else {
+ return "";
+ }
+ }
+
+ Port *input_source_port (uint32_t n=0) const {
+ boost::shared_ptr<ChannelList> c = channels.reader();
+ if (n < c->size()) return (*c)[n]->source; return 0;
+ }
+
+ void set_record_enabled (bool yn);
+ int set_destructive (bool yn);
+ bool can_become_destructive (bool& requires_bounce) const;
+
+ float peak_power(uint32_t n = 0) {
+ boost::shared_ptr<ChannelList> c = channels.reader();
+ ChannelInfo* chaninfo = (*c)[n];
+ float x = chaninfo->peak_power;
+ chaninfo->peak_power = 0.0f;
+ if (x > 0.0f) {
+ return 20.0f * fast_log10(x);
+ } else {
+ return minus_infinity();
+ }
+ }
+
+ boost::shared_ptr<AudioPlaylist> audio_playlist () { return boost::dynamic_pointer_cast<AudioPlaylist>(_playlist); }
+
+ int use_playlist (boost::shared_ptr<Playlist>);
+ int use_new_playlist ();
+ int use_copy_playlist ();
+
+ Sample *playback_buffer (uint32_t n = 0) {
+ boost::shared_ptr<ChannelList> c = channels.reader();
+ if (n < c->size())
+ return (*c)[n]->current_playback_buffer;
+ return 0;
+ }
+
+ Sample *capture_buffer (uint32_t n = 0) {
+ boost::shared_ptr<ChannelList> c = channels.reader();
+ if (n < c->size())
+ return (*c)[n]->current_capture_buffer;
+ return 0;
+ }
+
+ boost::shared_ptr<AudioFileSource> write_source (uint32_t n=0) {
+ boost::shared_ptr<ChannelList> c = channels.reader();
+ if (n < c->size())
+ return (*c)[n]->write_source;
+ return boost::shared_ptr<AudioFileSource>();
+ }
+
+ int add_channel (uint32_t how_many);
+ int remove_channel (uint32_t how_many);
+
+ /* stateful */
+
+ XMLNode& get_state(void);
+ int set_state(const XMLNode& node);
+
+ void monitor_input (bool);
+
+ 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, nframes_t n) {
+ while (n--) {
+ Sample tmp = *first;
+ *first++ = *last;
+ *last-- = tmp;
+ }
+ }
+
+ 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 set_block_size (nframes_t);
+ int internal_playback_seek (nframes_t distance);
+ int can_internal_playback_seek (nframes_t distance);
+ int rename_write_sources ();
+ void reset_write_sources (bool, bool force = false);
+ void non_realtime_input_change ();
+
+ protected:
+ friend class Auditioner;
+ int seek (nframes_t which_sample, bool complete_refill = false);
+
+ protected:
+ friend class AudioTrack;
+
+ int process (nframes_t transport_frame, nframes_t nframes, nframes_t offset, bool can_record, bool rec_monitors_input);
+ bool commit (nframes_t nframes);
+
+ private:
+
+ struct ChannelInfo {
+
+ ChannelInfo (nframes_t buffer_size, nframes_t speed_buffer_size, nframes_t wrap_buffer_size);
+ ~ChannelInfo ();
+
+ Sample *playback_wrap_buffer;
+ Sample *capture_wrap_buffer;
+ Sample *speed_buffer;
+
+ float peak_power;
+
+ boost::shared_ptr<AudioFileSource> fades_source;
+ boost::shared_ptr<AudioFileSource> write_source;
+
+ /// the Port that our audio data comes from
+ 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;
+
+ RingBufferNPT<CaptureTransition> * capture_transition_buf;
+ // the following are used in the butler thread only
+ nframes_t curr_capture_cnt;
+ };
+
+ typedef std::vector<ChannelInfo*> ChannelList;
+
+ /* The two central butler operations */
+ int do_flush (Session::RunContext context, bool force = false);
+ int do_refill () { return _do_refill(_mixdown_buffer, _gain_buffer); }
+
+ int do_refill_with_alloc ();
+
+ int read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer,
+ nframes_t& start, nframes_t cnt,
+ ChannelInfo* channel_info, int channel, bool reversed);
+
+ void finish_capture (bool rec_monitors_input, boost::shared_ptr<ChannelList>);
+ void transport_stopped (struct tm&, time_t, bool abort);
+ void transport_looped (nframes_t transport_frame);
+
+ void init (Diskstream::Flag);
+
+ void init_channel (ChannelInfo &chan);
+ void destroy_channel (ChannelInfo &chan);
+
+ int use_new_write_source (uint32_t n=0);
+
+ int find_and_use_playlist (const string&);
+
+ void allocate_temporary_buffers ();
+
+ int use_pending_capture_data (XMLNode& node);
+
+ void get_input_sources ();
+ void check_record_status (nframes_t transport_frame, nframes_t nframes, bool can_record);
+ void set_align_style_from_io();
+ void setup_destructive_playlist ();
+ void use_destructive_playlist ();
+
+ void engage_record_enable ();
+ void disengage_record_enable ();
+
+ // Working buffers for do_refill (butler thread)
+ static void allocate_working_buffers();
+ static void free_working_buffers();
+
+ static size_t _working_buffers_size;
+ static Sample* _mixdown_buffer;
+ static gain_t* _gain_buffer;
+
+ std::vector<boost::shared_ptr<AudioFileSource> > capturing_sources;
+
+ SerializedRCUManager<ChannelList> channels;
+
+ /* really */
+ private:
+ int _do_refill (Sample *mixdown_buffer, float *gain_buffer);
+
+ int add_channel_to (boost::shared_ptr<ChannelList>, uint32_t how_many);
+ int remove_channel_from (boost::shared_ptr<ChannelList>, uint32_t how_many);
+
+};
+
+} // namespace ARDOUR
+
+#endif /* __ardour_audio_diskstream_h__ */
diff --git a/libs/ardour/ardour/audio_library.h b/libs/ardour/ardour/audio_library.h
new file mode 100644
index 0000000000..86b5fb3aa2
--- /dev/null
+++ b/libs/ardour/ardour/audio_library.h
@@ -0,0 +1,54 @@
+/*
+ Copyright (C) 2003-2006 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_audio_library_h__
+#define __ardour_audio_library_h__
+
+#include <string>
+#include <map>
+#include <vector>
+
+using std::vector;
+using std::string;
+using std::map;
+
+namespace ARDOUR {
+
+class AudioLibrary
+{
+ public:
+ AudioLibrary ();
+ ~AudioLibrary ();
+
+ void set_tags (string member, vector<string> tags);
+ vector<string> get_tags (string member);
+
+ void search_members_and (vector<string>& results, const vector<string> tags);
+
+ void save_changes();
+
+ private:
+ string src;
+};
+
+extern AudioLibrary* Library;
+
+} // ARDOUR namespace
+
+#endif // __ardour_audio_library_h__
diff --git a/libs/ardour/ardour/audio_port.h b/libs/ardour/ardour/audio_port.h
new file mode 100644
index 0000000000..874f842d83
--- /dev/null
+++ b/libs/ardour/ardour/audio_port.h
@@ -0,0 +1,46 @@
+/*
+ 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: port.h 712 2006-07-28 01:08:57Z drobilla $
+*/
+
+#ifndef __ardour_audio_port_h__
+#define __ardour_audio_port_h__
+
+#include <ardour/base_audio_port.h>
+
+namespace ARDOUR {
+
+class AudioPort : public BaseAudioPort, public PortFacade {
+
+ public:
+ ~AudioPort();
+
+ void reset ();
+
+ void cycle_start (nframes_t nframes, nframes_t offset);
+ void cycle_end (nframes_t nframes, nframes_t offset);
+
+ protected:
+ friend class AudioEngine;
+
+ AudioPort (const std::string&, Flags, bool external, nframes_t);
+};
+
+} // namespace ARDOUR
+
+#endif /* __ardour_audio_port_h__ */
diff --git a/libs/ardour/ardour/audio_track.h b/libs/ardour/ardour/audio_track.h
new file mode 100644
index 0000000000..3546545329
--- /dev/null
+++ b/libs/ardour/ardour/audio_track.h
@@ -0,0 +1,80 @@
+/*
+ Copyright (C) 2002-2006 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_audio_track_h__
+#define __ardour_audio_track_h__
+
+#include <ardour/track.h>
+
+namespace ARDOUR {
+
+class Session;
+class AudioDiskstream;
+class AudioPlaylist;
+class RouteGroup;
+
+class AudioTrack : public Track
+{
+ public:
+ AudioTrack (Session&, string name, Route::Flag f = Route::Flag (0), TrackMode m = Normal);
+ AudioTrack (Session&, const XMLNode&);
+ ~AudioTrack ();
+
+ int set_mode (TrackMode m);
+ bool can_use_mode (TrackMode m, bool& bounce_required);
+
+ int roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
+ nframes_t offset, int declick, bool can_record, bool rec_monitors_input);
+
+ int no_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
+ nframes_t offset, bool state_changing, bool can_record, bool rec_monitors_input);
+
+ int silent_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
+ nframes_t offset, bool can_record, bool rec_monitors_input);
+
+ boost::shared_ptr<AudioDiskstream> audio_diskstream() const;
+
+ int use_diskstream (string name);
+ int use_diskstream (const PBD::ID& id);
+
+ int export_stuff (BufferSet& bufs, nframes_t nframes, nframes_t end_frame);
+
+ void freeze (InterThreadInfo&);
+ void unfreeze ();
+
+ void bounce (InterThreadInfo&);
+ void bounce_range (nframes_t start, nframes_t end, InterThreadInfo&);
+
+ int set_state(const XMLNode& node);
+
+ protected:
+ XMLNode& state (bool full);
+
+ int _set_state (const XMLNode&, bool call_base);
+
+ private:
+ int set_diskstream (boost::shared_ptr<AudioDiskstream>, void *);
+ int deprecated_use_diskstream_connections ();
+ void set_state_part_two ();
+ void set_state_part_three ();
+};
+
+} // namespace ARDOUR
+
+#endif /* __ardour_audio_track_h__ */
diff --git a/libs/ardour/ardour/audio_unit.h b/libs/ardour/ardour/audio_unit.h
new file mode 100644
index 0000000000..dc9a52d5d3
--- /dev/null
+++ b/libs/ardour/ardour/audio_unit.h
@@ -0,0 +1,172 @@
+/*
+ Copyright (C) 2006 Paul Davis
+ Written by 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.
+
+*/
+
+#ifndef __ardour_audio_unit_h__
+#define __ardour_audio_unit_h__
+
+#include <stdint.h>
+#include <boost/shared_ptr.hpp>
+
+#include <list>
+#include <set>
+#include <string>
+#include <vector>
+
+#include <ardour/plugin.h>
+
+#include <AudioUnit/AudioUnit.h>
+#include <appleutility/AUParamInfo.h>
+
+#include <boost/shared_ptr.hpp>
+
+class CAComponent;
+class CAAudioUnit;
+class CAComponentDescription;
+struct AudioBufferList;
+
+namespace ARDOUR {
+
+class AudioEngine;
+class Session;
+
+struct AUParameterDescriptor : public Plugin::ParameterDescriptor {
+ // additional fields to make operations more efficient
+ AudioUnitParameterID id;
+ AudioUnitScope scope;
+ AudioUnitElement element;
+ float default_value;
+ bool automatable;
+ AudioUnitParameterUnit unit;
+};
+
+class AUPlugin : public ARDOUR::Plugin
+{
+ public:
+ AUPlugin (AudioEngine& engine, Session& session, boost::shared_ptr<CAComponent> comp);
+ AUPlugin (const AUPlugin& other);
+ virtual ~AUPlugin ();
+
+ std::string unique_id () const;
+ const char * label () const;
+ const char * name () const { return _info->name.c_str(); }
+ const char * maker () const { return _info->creator.c_str(); }
+ uint32_t parameter_count () const;
+ float default_value (uint32_t port);
+ nframes_t signal_latency () const;
+ void set_parameter (uint32_t which, float val);
+ float get_parameter (uint32_t which) const;
+
+ int get_parameter_descriptor (uint32_t which, ParameterDescriptor&) const;
+ uint32_t nth_parameter (uint32_t which, bool& ok) const;
+ void activate ();
+ void deactivate ();
+ void set_block_size (nframes_t nframes);
+
+ int connect_and_run (BufferSet& bufs, uint32_t& in, uint32_t& out, nframes_t nframes, nframes_t offset);
+
+ std::set<uint32_t> automatable() const;
+ string describe_parameter (uint32_t);
+ string state_node_name () const { return "audiounit"; }
+ 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;
+
+ XMLNode& get_state();
+ int set_state(const XMLNode& node);
+
+ bool save_preset (string name);
+ bool load_preset (const string preset_label);
+ std::vector<std::string> get_presets ();
+
+ bool has_editor () const;
+
+ bool fixed_io() const { return false; }
+ int32_t can_support_input_configuration (int32_t in);
+ int32_t compute_output_streams (int32_t nplugins);
+ uint32_t output_streams() const;
+ uint32_t input_streams() const;
+
+ boost::shared_ptr<CAAudioUnit> get_au () { return unit; }
+ boost::shared_ptr<CAComponent> get_comp () const { return comp; }
+
+ OSStatus render_callback(AudioUnitRenderActionFlags *ioActionFlags,
+ const AudioTimeStamp *inTimeStamp,
+ UInt32 inBusNumber,
+ UInt32 inNumberFrames,
+ AudioBufferList* ioData);
+ private:
+ boost::shared_ptr<CAComponent> comp;
+ boost::shared_ptr<CAAudioUnit> unit;
+
+ AudioStreamBasicDescription streamFormat;
+ bool initialized;
+ int format_set;
+ AudioBufferList* buffers;
+
+ UInt32 global_elements;
+ UInt32 output_elements;
+ UInt32 input_elements;
+
+ int set_output_format ();
+ int set_input_format ();
+ int set_stream_format (int scope, uint32_t cnt);
+ int _set_block_size (nframes_t nframes);
+ void discover_parameters ();
+
+ std::vector<std::pair<uint32_t, uint32_t> > parameter_map;
+ uint32_t current_maxbuf;
+ nframes_t current_offset;
+ nframes_t cb_offset;
+ vector<Sample*>* current_buffers;
+ nframes_t frames_processed;
+
+ std::vector<AUParameterDescriptor> descriptors;
+ void init ();
+};
+
+typedef boost::shared_ptr<AUPlugin> AUPluginPtr;
+
+class AUPluginInfo : public PluginInfo {
+ public:
+ AUPluginInfo (boost::shared_ptr<CAComponentDescription>);
+ ~AUPluginInfo ();
+
+ PluginPtr load (Session& session);
+
+ static PluginInfoList discover ();
+ static void get_names (CAComponentDescription&, std::string& name, Glib::ustring& maker);
+ static std::string stringify_descriptor (const CAComponentDescription&);
+
+ private:
+ boost::shared_ptr<CAComponentDescription> descriptor;
+
+ static void discover_music (PluginInfoList&);
+ static void discover_fx (PluginInfoList&);
+ static void discover_by_description (PluginInfoList&, CAComponentDescription&);
+};
+
+typedef boost::shared_ptr<AUPluginInfo> AUPluginInfoPtr;
+
+} // namespace ARDOUR
+
+#endif // __ardour_audio_unit_h__
diff --git a/libs/ardour/ardour/audioanalyser.h b/libs/ardour/ardour/audioanalyser.h
new file mode 100644
index 0000000000..06b841990a
--- /dev/null
+++ b/libs/ardour/ardour/audioanalyser.h
@@ -0,0 +1,74 @@
+/*
+ Copyright (C) 2008 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_audioanalyser_h__
+#define __ardour_audioanalyser_h__
+
+#include <vector>
+#include <string>
+#include <ostream>
+#include <fstream>
+#include <vamp-sdk/Plugin.h>
+#include <ardour/audioregion.h>
+
+namespace ARDOUR {
+
+class Readable;
+class Session;
+
+class AudioAnalyser {
+
+ public:
+ typedef Vamp::Plugin AnalysisPlugin;
+ typedef std::string AnalysisPluginKey;
+
+ AudioAnalyser (float sample_rate, AnalysisPluginKey key);
+ virtual ~AudioAnalyser();
+
+ /* analysis object should provide a run method
+ that accepts a path to write the results to (optionally empty)
+ a Readable* to read data from
+ and a reference to a type-specific container to return the
+ results.
+ */
+
+ void reset ();
+
+ protected:
+ float sample_rate;
+ AnalysisPlugin* plugin;
+ AnalysisPluginKey plugin_key;
+
+ nframes64_t bufsize;
+ nframes64_t stepsize;
+
+ int initialize_plugin (AnalysisPluginKey name, float sample_rate);
+ int analyse (const std::string& path, Readable*, uint32_t channel);
+
+ /* instances of an analysis object will have this method called
+ whenever there are results to process. if out is non-null,
+ the data should be written to the stream it points to.
+ */
+
+ virtual int use_features (Vamp::Plugin::FeatureSet&, std::ostream*) = 0;
+};
+
+} /* namespace */
+
+#endif /* __ardour_audioanalyser_h__ */
diff --git a/libs/ardour/ardour/audioengine.h b/libs/ardour/ardour/audioengine.h
new file mode 100644
index 0000000000..e1d5e50cc2
--- /dev/null
+++ b/libs/ardour/ardour/audioengine.h
@@ -0,0 +1,276 @@
+/*
+ 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.
+
+*/
+
+#ifndef __ardour_audioengine_h__
+#define __ardour_audioengine_h__
+
+#include <list>
+#include <set>
+#include <cmath>
+#include <exception>
+#include <string>
+
+#include <sigc++/signal.h>
+
+#include <glibmm/thread.h>
+
+#include <pbd/rcu.h>
+
+#include <ardour/ardour.h>
+#include <jack/jack.h>
+#include <jack/transport.h>
+#include <ardour/types.h>
+#include <ardour/data_type.h>
+
+namespace ARDOUR {
+
+class Session;
+class Port;
+class InternalPort;
+
+class AudioEngine : public sigc::trackable
+{
+ public:
+ typedef std::set<Port*> Ports;
+
+ AudioEngine (std::string client_name);
+ virtual ~AudioEngine ();
+
+ jack_client_t* jack() const;
+ bool connected() const { return _jack != 0; }
+
+ bool is_realtime () const;
+
+ 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 (bool forever = false);
+ int start ();
+ bool running() const { return _running; }
+
+ Glib::Mutex& process_lock() { return _process_lock; }
+
+ nframes_t frame_rate();
+ nframes_t frames_per_cycle();
+
+ int usecs_per_cycle () const { return _usecs_per_cycle; }
+
+ bool get_sync_offset (nframes_t& offset) const;
+
+ nframes_t frames_since_cycle_start () {
+ if (!_running || !_jack) return 0;
+ return jack_frames_since_cycle_start (_jack);
+ }
+ nframes_t frame_time () {
+ if (!_running || !_jack) return 0;
+ return jack_frame_time (_jack);
+ }
+
+ nframes_t transport_frame () const {
+ if (!_running || !_jack) return 0;
+ return jack_get_current_transport_frame (_jack);
+ }
+
+ int request_buffer_size (nframes_t);
+
+ nframes_t set_monitor_check_interval (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:
+ PortRegistrationFailure (const char* why = "") {
+ reason = why;
+ }
+ virtual const char *what() const throw() { return reason; }
+
+ private:
+ const char* reason;
+ };
+
+ class NoBackendAvailable : public std::exception {
+ public:
+ virtual const char *what() const throw() { return "could not connect to engine backend"; }
+ };
+
+ Port *register_input_port (DataType, const std::string& portname, bool publish);
+ Port *register_output_port (DataType, const std::string& portname, bool publish);
+ int unregister_port (Port &);
+
+ int connect (const std::string& source, const std::string& destination);
+ int disconnect (const std::string& source, const std::string& destination);
+ int disconnect (Port &);
+
+ const char ** get_ports (const std::string& port_name_pattern, const std::string& type_name_pattern, uint32_t flags);
+
+ uint32_t n_physical_outputs () const;
+ uint32_t n_physical_inputs () const;
+
+ bool can_request_hardware_monitoring ();
+
+ void get_physical_outputs (std::vector<std::string>&);
+ void get_physical_inputs (std::vector<std::string>&);
+
+ std::string get_nth_physical_output (DataType type, uint32_t n) {
+ return get_nth_physical (type, n, JackPortIsInput);
+ }
+
+ std::string get_nth_physical_input (DataType type, uint32_t n) {
+ return get_nth_physical (type, n, JackPortIsOutput);
+ }
+
+ nframes_t get_port_total_latency (const Port&);
+ void update_total_latencies ();
+ void update_total_latency (const Port&);
+
+ /** Caller may not delete the object pointed to by the return value
+ */
+ Port *get_port_by_name (const std::string& name, bool keep = true) const;
+
+ enum TransportState {
+ TransportStopped = JackTransportStopped,
+ TransportRolling = JackTransportRolling,
+ TransportLooping = JackTransportLooping,
+ TransportStarting = JackTransportStarting
+ };
+
+ void transport_start ();
+ void transport_stop ();
+ void transport_locate (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,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,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;
+ mutable Glib::Mutex _process_lock;
+ Glib::Cond session_removed;
+ bool session_remove_pending;
+ bool _running;
+ bool _has_run;
+ nframes_t _buffer_size;
+ nframes_t _frame_rate;
+ /// number of frames between each check for changes in monitor input
+ nframes_t monitor_check_interval;
+ /// time of the last monitor check in frames
+ nframes_t last_monitor_check;
+ /// the number of frames processed since start() was called
+ nframes_t _processed_frames;
+ bool _freewheeling;
+ bool _freewheel_thread_registered;
+ sigc::slot<int,nframes_t> freewheel_action;
+ bool reconnect_on_halt;
+ int _usecs_per_cycle;
+
+ SerializedRCUManager<Ports> ports;
+
+ Port *register_port (DataType type, const std::string& portname, bool input, bool publish);
+
+ int process_callback (nframes_t nframes);
+ void remove_all_ports ();
+
+ Port* get_port (const std::string& short_name);
+
+ typedef std::pair<std::string,std::string> PortConnection;
+ typedef std::list<PortConnection> PortConnections;
+
+ PortConnections port_connections;
+ void remove_connections_for (Port&);
+
+ std::string get_nth_physical (DataType type, uint32_t n, int flags);
+
+ void port_registration_failure (const std::string& portname);
+
+ static int _xrun_callback (void *arg);
+ static int _graph_order_callback (void *arg);
+ static int _process_callback (nframes_t nframes, void *arg);
+ static int _sample_rate_callback (nframes_t nframes, void *arg);
+ static int _bufsize_callback (nframes_t nframes, void *arg);
+ static void _jack_timebase_callback (jack_transport_state_t, 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, nframes_t, jack_position_t*, int);
+ int jack_sync_callback (jack_transport_state_t, jack_position_t*);
+ int jack_bufsize_callback (nframes_t);
+ int jack_sample_rate_callback (nframes_t);
+
+ static void halted (void *);
+
+ int connect_to_jack (std::string client_name);
+
+ void meter_thread ();
+ void start_metering_thread ();
+ void stop_metering_thread ();
+
+ Glib::Thread* m_meter_thread;
+ static gint m_meter_exit;
+};
+
+} // namespace ARDOUR
+
+#endif /* __ardour_audioengine_h__ */
diff --git a/libs/ardour/ardour/audiofilesource.h b/libs/ardour/ardour/audiofilesource.h
new file mode 100644
index 0000000000..de388a06fc
--- /dev/null
+++ b/libs/ardour/ardour/audiofilesource.h
@@ -0,0 +1,183 @@
+/*
+ Copyright (C) 2006 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_audiofilesource_h__
+#define __ardour_audiofilesource_h__
+
+#include <exception>
+
+#include <time.h>
+
+#include <ardour/audiosource.h>
+
+namespace ARDOUR {
+
+class non_existent_source : public std::exception {
+ public:
+ virtual const char *what() const throw() { return "audio file does not exist"; }
+};
+
+struct SoundFileInfo {
+ float samplerate;
+ uint16_t channels;
+ int64_t length;
+ std::string format_name;
+ int64_t timecode;
+};
+
+class AudioFileSource : public AudioSource {
+ public:
+ enum Flag {
+ Writable = 0x1,
+ CanRename = 0x2,
+ Broadcast = 0x4,
+ Removable = 0x8,
+ RemovableIfEmpty = 0x10,
+ RemoveAtDestroy = 0x20,
+ NoPeakFile = 0x40,
+ Destructive = 0x80
+ };
+
+ virtual ~AudioFileSource ();
+
+ bool set_name (const std::string& newname) { return (set_source_name(newname, destructive()) == 0); }
+ int set_source_name (Glib::ustring newname, bool destructive);
+
+ Glib::ustring path() const { return _path; }
+ Glib::ustring peak_path (Glib::ustring audio_path);
+ Glib::ustring find_broken_peakfile (Glib::ustring missing_peak_path,
+ Glib::ustring audio_path);
+
+ uint16_t channel() const { return _channel; }
+
+ static void set_peak_dir (Glib::ustring dir) { peak_dir = dir; }
+
+ static bool get_soundfile_info (Glib::ustring path, SoundFileInfo& _info, std::string& error);
+
+ static bool safe_file_extension (Glib::ustring path);
+
+ void set_allow_remove_if_empty (bool yn);
+ void mark_for_remove();
+
+ /* this block of methods do nothing for regular file sources, but are significant
+ for files used in destructive recording.
+ */
+
+ virtual nframes_t last_capture_start_frame() const { return 0; }
+ virtual void mark_capture_start (nframes_t) {}
+ virtual void mark_capture_end () {}
+ virtual void clear_capture_marks() {}
+ virtual bool one_of_several_channels () const { return false; }
+
+ virtual int update_header (nframes_t when, struct tm&, time_t) = 0;
+ virtual int flush_header () = 0;
+
+ int move_to_trash (const Glib::ustring& trash_dir_name);
+
+ static bool is_empty (Session&, Glib::ustring path);
+ void mark_streaming_write_completed ();
+
+ void mark_take (Glib::ustring);
+ Glib::ustring take_id() const { return _take_id; }
+
+ bool is_embedded() const { return _is_embedded; }
+
+ static void set_bwf_serial_number (int);
+
+ static void set_search_path (Glib::ustring string);
+ static void set_header_position_offset (nframes_t offset );
+
+ int setup_peakfile ();
+
+ static sigc::signal<void> HeaderPositionOffsetChanged;
+
+ XMLNode& get_state ();
+ int set_state (const XMLNode&);
+
+ bool destructive() const { return (_flags & Destructive); }
+ virtual bool set_destructive (bool yn) { return false; }
+ bool can_truncate_peaks() const { return !destructive(); }
+
+ Flag flags() const { return _flags; }
+
+ void mark_immutable ();
+
+ /* this should really be protected, but C++ is getting stricter
+ and creating slots from protected member functions is starting
+ to cause issues.
+ */
+
+ virtual void handle_header_position_change () {}
+
+ bool can_be_analysed() const { return _length > 0; }
+
+ protected:
+
+ /* constructor to be called for existing external-to-session files */
+
+ AudioFileSource (Session&, Glib::ustring path, Flag flags);
+
+ /* constructor to be called for new in-session files */
+
+ AudioFileSource (Session&, Glib::ustring path, Flag flags,
+ SampleFormat samp_format, HeaderFormat hdr_format);
+
+ /* constructor to be called for existing in-session files */
+
+ AudioFileSource (Session&, const XMLNode&, bool must_exit = true);
+
+ int init (Glib::ustring idstr, bool must_exist);
+
+ Glib::ustring _path;
+ Flag _flags;
+ Glib::ustring _take_id;
+ int64_t timeline_position;
+ bool file_is_new;
+ uint16_t _channel;
+
+ bool _is_embedded;
+ static bool determine_embeddedness(Glib::ustring path);
+
+ static Glib::ustring peak_dir;
+ static Glib::ustring search_path;
+
+ static char bwf_country_code[3];
+ static char bwf_organization_code[4];
+ static char bwf_serial_number[13];
+
+ static uint64_t header_position_offset;
+
+ virtual void set_timeline_position (int64_t pos);
+ virtual void set_header_timeline_position () = 0;
+
+ bool find (Glib::ustring& path, bool must_exist, bool& is_new, uint16_t& chan);
+ bool removable() const;
+ bool writable() const { return _flags & Writable; }
+
+ static Sample* get_interleave_buffer (nframes_t size);
+
+ private:
+ Glib::ustring old_peak_path (Glib::ustring audio_path);
+ Glib::ustring broken_peak_path (Glib::ustring audio_path);
+};
+
+} // namespace ARDOUR
+
+#endif /* __ardour_audiofilesource_h__ */
+
diff --git a/libs/ardour/ardour/audioplaylist.h b/libs/ardour/ardour/audioplaylist.h
new file mode 100644
index 0000000000..4acbc9ad51
--- /dev/null
+++ b/libs/ardour/ardour/audioplaylist.h
@@ -0,0 +1,93 @@
+/*
+ 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.
+
+*/
+
+#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<boost::shared_ptr<Crossfade> > Crossfades;
+
+ public:
+ AudioPlaylist (Session&, const XMLNode&, bool hidden = false);
+ AudioPlaylist (Session&, string name, bool hidden = false);
+ AudioPlaylist (boost::shared_ptr<const AudioPlaylist>, string name, bool hidden = false);
+ AudioPlaylist (boost::shared_ptr<const AudioPlaylist>, nframes_t start, nframes_t cnt, string name, bool hidden = false);
+
+ ~AudioPlaylist ();
+
+ void clear (bool with_signals=true);
+
+ nframes_t read (Sample *dst, Sample *mixdown, float *gain_buffer, nframes_t start, nframes_t cnt, uint32_t chan_n=0);
+
+ int set_state (const XMLNode&);
+
+ sigc::signal<void,boost::shared_ptr<Crossfade> > NewCrossfade;
+
+ template<class T> void foreach_crossfade (T *t, void (T::*func)(boost::shared_ptr<Crossfade>));
+ void crossfades_at (nframes_t frame, Crossfades&);
+
+ bool destroy_region (boost::shared_ptr<Region>);
+
+ protected:
+
+ /* playlist "callbacks" */
+ void notify_crossfade_added (boost::shared_ptr<Crossfade>);
+ void flush_notifications ();
+
+ void finalize_split_region (boost::shared_ptr<Region> orig, boost::shared_ptr<Region> left, boost::shared_ptr<Region> right);
+
+ void refresh_dependents (boost::shared_ptr<Region> region);
+ void check_dependents (boost::shared_ptr<Region> region, bool norefresh);
+ void remove_dependents (boost::shared_ptr<Region> region);
+
+ private:
+ Crossfades _crossfades;
+ Crossfades _pending_xfade_adds;
+
+ void crossfade_invalidated (boost::shared_ptr<Region>);
+ XMLNode& state (bool full_state);
+ void dump () const;
+
+ bool region_changed (Change, boost::shared_ptr<Region>);
+ void crossfade_changed (Change);
+ void add_crossfade (boost::shared_ptr<Crossfade>);
+
+ void source_offset_changed (boost::shared_ptr<AudioRegion> region);
+};
+
+} /* 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..81b7ef7c57
--- /dev/null
+++ b/libs/ardour/ardour/audioregion.h
@@ -0,0 +1,204 @@
+/*
+ Copyright (C) 2000-2006 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_audio_region_h__
+#define __ardour_audio_region_h__
+
+#include <vector>
+#include <list>
+
+#include <pbd/fastlog.h>
+#include <pbd/undo.h>
+
+#include <ardour/ardour.h>
+#include <ardour/region.h>
+#include <ardour/gain.h>
+#include <ardour/logcurve.h>
+#include <ardour/export.h>
+
+class XMLNode;
+
+namespace ARDOUR {
+
+class Route;
+class Playlist;
+class Session;
+class Filter;
+class AudioSource;
+
+class AudioRegion : public Region
+{
+ public:
+ static Change FadeInChanged;
+ static Change FadeOutChanged;
+ static Change FadeInActiveChanged;
+ static Change FadeOutActiveChanged;
+ static Change EnvelopeActiveChanged;
+ static Change ScaleAmplitudeChanged;
+ static Change EnvelopeChanged;
+
+ ~AudioRegion();
+
+ bool speed_mismatch (float) const;
+
+ boost::shared_ptr<AudioSource> audio_source (uint32_t n=0) const;
+
+ void set_scale_amplitude (gain_t);
+ gain_t scale_amplitude() const { return _scale_amplitude; }
+
+ void normalize_to (float target_in_dB = 0.0f);
+
+ 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; }
+
+ boost::shared_ptr<AutomationList> fade_in() { return _fade_in; }
+ boost::shared_ptr<AutomationList> fade_out() { return _fade_out; }
+ boost::shared_ptr<AutomationList> envelope() { return _envelope; }
+
+ virtual nframes_t read_peaks (PeakData *buf, nframes_t npeaks,
+ nframes_t offset, nframes_t cnt,
+ uint32_t chan_n=0, double samples_per_unit= 1.0) const;
+
+ /* Readable interface */
+
+ virtual nframes64_t read (Sample*, nframes64_t pos, nframes64_t cnt, int channel) const;
+ virtual nframes64_t readable_length() const { return length(); }
+
+ virtual nframes_t read_at (Sample *buf, Sample *mixdown_buf,
+ float *gain_buf, nframes_t position, nframes_t cnt,
+ uint32_t chan_n = 0,
+ nframes_t read_frames = 0,
+ nframes_t skip_frames = 0) const;
+
+ virtual nframes_t master_read_at (Sample *buf, Sample *mixdown_buf,
+ float *gain_buf,
+ nframes_t position, nframes_t cnt, uint32_t chan_n=0) const;
+
+ virtual nframes_t read_raw_internal (Sample*, nframes_t, nframes_t) const;
+
+ XMLNode& state (bool);
+ int set_state (const XMLNode&);
+
+ static void set_default_fade (float steepness, nframes_t len);
+ bool fade_in_is_default () const;
+ bool fade_out_is_default () const;
+
+ 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 (nframes_t);
+ void set_fade_in (FadeShape, nframes_t);
+
+ void set_fade_out_active (bool yn);
+ void set_fade_out_shape (FadeShape);
+ void set_fade_out_length (nframes_t);
+ void set_fade_out (FadeShape, nframes_t);
+
+ void set_envelope_active (bool yn);
+ void set_default_envelope ();
+
+ int separate_by_channel (ARDOUR::Session&, vector<boost::shared_ptr<AudioRegion> >&) const;
+
+ /* export */
+
+ int exportme (ARDOUR::Session&, ARDOUR::ExportSpecification&);
+
+ /* xfade/fade interactions */
+
+ void suspend_fade_in ();
+ void suspend_fade_out ();
+ void resume_fade_in ();
+ void resume_fade_out ();
+
+ int get_transients (AnalysisFeatureList&, bool force_new = false);
+
+ private:
+ friend class RegionFactory;
+
+ AudioRegion (boost::shared_ptr<AudioSource>, nframes_t start, nframes_t length);
+ AudioRegion (boost::shared_ptr<AudioSource>, nframes_t start, nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags);
+ AudioRegion (const SourceList &, nframes_t start, nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags);
+ AudioRegion (boost::shared_ptr<const AudioRegion>, nframes_t start, nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags);
+ AudioRegion (boost::shared_ptr<AudioSource>, const XMLNode&);
+ AudioRegion (SourceList &, const XMLNode&);
+
+ private:
+ void init ();
+ void set_default_fades ();
+ void set_default_fade_in ();
+ void set_default_fade_out ();
+
+ void recompute_gain_at_end ();
+ void recompute_gain_at_start ();
+
+ nframes_t _read_at (const SourceList&, nframes_t limit,
+ Sample *buf, Sample *mixdown_buffer,
+ float *gain_buffer, nframes_t position, nframes_t cnt,
+ uint32_t chan_n = 0,
+ nframes_t read_frames = 0,
+ nframes_t skip_frames = 0,
+ bool raw = false) const;
+
+ void recompute_at_start ();
+ void recompute_at_end ();
+
+ void envelope_changed ();
+ void fade_in_changed ();
+ void fade_out_changed ();
+ void source_offset_changed ();
+ void listen_to_my_curves ();
+ void listen_to_my_sources ();
+
+ boost::shared_ptr<AutomationList> _fade_in;
+ FadeShape _fade_in_shape;
+ boost::shared_ptr<AutomationList> _fade_out;
+ FadeShape _fade_out_shape;
+ boost::shared_ptr<AutomationList> _envelope;
+ gain_t _scale_amplitude;
+ uint32_t _fade_in_disabled;
+ uint32_t _fade_out_disabled;
+
+ protected:
+ /* default constructor for derived (compound) types */
+
+ AudioRegion (Session& s, nframes_t, nframes_t, std::string name);
+ AudioRegion (boost::shared_ptr<const AudioRegion>);
+
+ int set_live_state (const XMLNode&, Change&, bool send);
+};
+
+} /* 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, double);
+}
+
+#endif /* __ardour_audio_region_h__ */
diff --git a/libs/ardour/ardour/audiosource.h b/libs/ardour/ardour/audiosource.h
new file mode 100644
index 0000000000..d11b829694
--- /dev/null
+++ b/libs/ardour/ardour/audiosource.h
@@ -0,0 +1,159 @@
+/*
+ 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.
+
+*/
+
+#ifndef __ardour_audio_source_h__
+#define __ardour_audio_source_h__
+
+#include <list>
+#include <vector>
+
+#include <boost/shared_ptr.hpp>
+#include <boost/enable_shared_from_this.hpp>
+
+#include <time.h>
+
+#include <glibmm/thread.h>
+#include <glibmm/ustring.h>
+
+#include <sigc++/signal.h>
+
+#include <ardour/source.h>
+#include <ardour/ardour.h>
+#include <pbd/stateful.h>
+#include <pbd/xml++.h>
+
+using std::list;
+using std::vector;
+
+namespace ARDOUR {
+
+class AudioSource : public Source, public boost::enable_shared_from_this<ARDOUR::AudioSource>
+{
+ public:
+ AudioSource (Session&, Glib::ustring name);
+ AudioSource (Session&, const XMLNode&);
+ virtual ~AudioSource ();
+
+ nframes64_t readable_length() const { return _length; }
+ uint32_t n_channels() const { return 1; }
+
+ virtual nframes_t available_peaks (double zoom) const;
+
+ /* stopgap until nframes_t becomes nframes64_t. this function is needed by the Readable interface */
+
+ virtual nframes64_t read (Sample *dst, nframes64_t start, nframes64_t cnt, int channel) const {
+ /* XXX currently ignores channel, assuming that source is always mono, which
+ historically has been true.
+ */
+ return read (dst, (nframes_t) start, (nframes_t) cnt);
+ }
+
+ virtual nframes_t read (Sample *dst, nframes_t start, nframes_t cnt) const;
+ virtual nframes_t write (Sample *src, nframes_t cnt);
+
+ virtual float sample_rate () const = 0;
+
+ virtual void mark_for_remove() = 0;
+ virtual void mark_streaming_write_completed () {}
+
+ virtual bool can_truncate_peaks() const { return true; }
+
+ void set_captured_for (Glib::ustring str) { _captured_for = str; }
+ Glib::ustring 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, nframes_t npeaks, nframes_t start, nframes_t cnt, double samples_per_visual_peak) const;
+
+ int build_peaks ();
+ bool peaks_ready (sigc::slot<void>, sigc::connection&) const;
+
+ mutable sigc::signal<void> PeaksReady;
+ mutable sigc::signal<void,nframes_t,nframes_t> PeakRangeReady;
+
+ XMLNode& get_state ();
+ int set_state (const XMLNode&);
+
+ int rename_peakfile (Glib::ustring newpath);
+ void touch_peakfile ();
+
+ static void set_build_missing_peakfiles (bool yn) {
+ _build_missing_peakfiles = yn;
+ }
+
+ static void set_build_peakfiles (bool yn) {
+ _build_peakfiles = yn;
+ }
+
+ static bool get_build_peakfiles () {
+ return _build_peakfiles;
+ }
+
+ virtual int setup_peakfile () { return 0; }
+
+ int prepare_for_peakfile_writes ();
+ void done_with_peakfile_writes (bool done = true);
+
+ protected:
+ static bool _build_missing_peakfiles;
+ static bool _build_peakfiles;
+
+ bool _peaks_built;
+ mutable Glib::Mutex _lock;
+ mutable Glib::Mutex _peaks_ready_lock;
+ Glib::ustring peakpath;
+ Glib::ustring _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, Glib::ustring path);
+ int build_peaks_from_scratch ();
+ int compute_and_write_peaks (Sample* buf, nframes_t first_frame, nframes_t cnt, bool force, bool intermediate_peaks_ready_signal);
+ void truncate_peakfile();
+
+ mutable off_t _peak_byte_max; // modified in compute_and_write_peak()
+
+ virtual nframes_t read_unlocked (Sample *dst, nframes_t start, nframes_t cnt) const = 0;
+ virtual nframes_t write_unlocked (Sample *dst, nframes_t cnt) = 0;
+ virtual Glib::ustring peak_path(Glib::ustring audio_path) = 0;
+ virtual Glib::ustring find_broken_peakfile (Glib::ustring missing_peak_path, Glib::ustring audio_path) = 0;
+
+ void update_length (nframes_t pos, nframes_t cnt);
+
+ virtual int read_peaks_with_fpp (PeakData *peaks, nframes_t npeaks, nframes_t start, nframes_t cnt,
+ double samples_per_visual_peak, nframes_t fpp) const;
+
+ int compute_and_write_peaks (Sample* buf, nframes_t first_frame, nframes_t cnt, bool force,
+ bool intermediate_peaks_ready_signal, nframes_t frames_per_peak);
+
+ private:
+ int peakfile;
+ nframes_t peak_leftover_cnt;
+ nframes_t peak_leftover_size;
+ Sample* peak_leftovers;
+ nframes_t peak_leftover_frame;
+
+ bool file_changed (Glib::ustring path);
+};
+
+}
+
+#endif /* __ardour_audio_source_h__ */
diff --git a/libs/ardour/ardour/auditioner.h b/libs/ardour/ardour/auditioner.h
new file mode 100644
index 0000000000..06d521ea21
--- /dev/null
+++ b/libs/ardour/ardour/auditioner.h
@@ -0,0 +1,70 @@
+/*
+ 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.
+
+*/
+
+#ifndef __ardour_auditioner_h__
+#define __ardour_auditioner_h__
+
+#include <string>
+
+#include <glibmm/thread.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 (boost::shared_ptr<Region>);
+
+ ARDOUR::AudioPlaylist& prepare_playlist ();
+ void audition_current_playlist ();
+
+ int play_audition (nframes_t nframes);
+
+ void cancel_audition () {
+ g_atomic_int_set (&_active, 0);
+ }
+
+ bool active() const { return g_atomic_int_get (&_active); }
+
+ private:
+ boost::shared_ptr<AudioRegion> the_region;
+ nframes_t current_frame;
+ mutable gint _active;
+ Glib::Mutex lock;
+ 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/auto_bundle.h b/libs/ardour/ardour/auto_bundle.h
new file mode 100644
index 0000000000..685a083e8d
--- /dev/null
+++ b/libs/ardour/ardour/auto_bundle.h
@@ -0,0 +1,50 @@
+/*
+ Copyright (C) 2007 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_auto_bundle_h__
+#define __ardour_auto_bundle_h__
+
+#include <vector>
+#include <glibmm/thread.h>
+#include "ardour/bundle.h"
+
+namespace ARDOUR {
+
+class AutoBundle : public Bundle {
+
+ public:
+ AutoBundle (bool i = true);
+ AutoBundle (std::string const &, bool i = true);
+
+ uint32_t nchannels () const;
+ const PortList& channel_ports (uint32_t) const;
+
+ void set_channels (uint32_t);
+ void set_port (uint32_t, std::string const &);
+
+ private:
+ /// mutex for _ports;
+ /// XXX: is this necessary?
+ mutable Glib::Mutex _ports_mutex;
+ std::vector<PortList> _ports;
+};
+
+}
+
+#endif /* __ardour_auto_bundle_h__ */
diff --git a/libs/ardour/ardour/automatable.h b/libs/ardour/ardour/automatable.h
new file mode 100644
index 0000000000..a2c1d98ae7
--- /dev/null
+++ b/libs/ardour/ardour/automatable.h
@@ -0,0 +1,121 @@
+/*
+ Copyright (C) 2000-2007 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_automatable_h__
+#define __ardour_automatable_h__
+
+#include <set>
+#include <map>
+#include <boost/shared_ptr.hpp>
+#include <ardour/session_object.h>
+#include <ardour/automation_event.h>
+#include <ardour/automation_control.h>
+#include <ardour/parameter.h>
+
+namespace ARDOUR {
+
+class Session;
+class AutomationControl;
+
+class Automatable : public SessionObject
+{
+public:
+ Automatable(Session&, const std::string& name);
+
+ virtual ~Automatable() {}
+
+ // shorthand for gain, pan, etc
+ inline boost::shared_ptr<AutomationControl>
+ control(AutomationType type, bool create_if_missing=false) {
+ return control(Parameter(type), create_if_missing);
+ }
+
+ virtual boost::shared_ptr<AutomationControl> control(Parameter id, bool create_if_missing=false);
+ virtual boost::shared_ptr<const AutomationControl> control(Parameter id) const;
+
+ boost::shared_ptr<AutomationControl> control_factory(boost::shared_ptr<AutomationList> list);
+
+ typedef std::map<Parameter,boost::shared_ptr<AutomationControl> > Controls;
+ Controls& controls() { return _controls; }
+ const Controls& controls() const { return _controls; }
+
+ virtual void add_control(boost::shared_ptr<AutomationControl>);
+
+ virtual void automation_snapshot(nframes_t now, bool force);
+ bool should_snapshot (nframes_t now) {
+ return (_last_automation_snapshot > now || (now - _last_automation_snapshot) > _automation_interval);
+ }
+ virtual void transport_stopped(nframes_t now);
+
+ virtual bool find_next_event(nframes_t start, nframes_t end, ControlEvent& ev) const;
+
+ virtual string describe_parameter(Parameter param);
+ virtual float default_parameter_value(Parameter param) { return 1.0f; }
+
+ virtual void clear_automation();
+
+ AutoState get_parameter_automation_state (Parameter param, bool lock = true);
+ virtual void set_parameter_automation_state (Parameter param, AutoState);
+
+ AutoStyle get_parameter_automation_style (Parameter param);
+ void set_parameter_automation_style (Parameter param, AutoStyle);
+
+ void protect_automation ();
+
+ void what_has_automation(std::set<Parameter>&) const;
+ void what_has_visible_automation(std::set<Parameter>&) const;
+ const std::set<Parameter>& what_can_be_automated() const { return _can_automate_list; }
+
+ void mark_automation_visible(Parameter, bool);
+
+ Glib::Mutex& automation_lock() const { return _automation_lock; }
+
+ static void set_automation_interval (jack_nframes_t frames) {
+ _automation_interval = frames;
+ }
+
+ static jack_nframes_t automation_interval() {
+ return _automation_interval;
+ }
+
+protected:
+
+ void can_automate(Parameter);
+
+ virtual void auto_state_changed (Parameter which) {}
+
+ int set_automation_state(const XMLNode&, Parameter default_param);
+ XMLNode& get_automation_state();
+
+ int load_automation (const std::string& path);
+ int old_set_automation_state(const XMLNode&);
+
+ mutable Glib::Mutex _automation_lock;
+
+ Controls _controls;
+ std::set<Parameter> _visible_controls;
+ std::set<Parameter> _can_automate_list;
+
+ nframes_t _last_automation_snapshot;
+ static nframes_t _automation_interval;
+};
+
+} // namespace ARDOUR
+
+#endif /* __ardour_automatable_h__ */
diff --git a/libs/ardour/ardour/automation_control.h b/libs/ardour/ardour/automation_control.h
new file mode 100644
index 0000000000..68ac5797dc
--- /dev/null
+++ b/libs/ardour/ardour/automation_control.h
@@ -0,0 +1,64 @@
+/*
+ Copyright (C) 2007 Paul Davis
+ Author: Dave Robillard
+
+ 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_automation_control_h__
+#define __ardour_automation_control_h__
+
+#include <boost/shared_ptr.hpp>
+#include <pbd/controllable.h>
+#include <ardour/parameter.h>
+
+namespace ARDOUR {
+
+class AutomationList;
+class Session;
+class Automatable;
+
+
+/** A PBD:Controllable with associated automation data (AutomationList)
+ */
+class AutomationControl : public PBD::Controllable
+{
+public:
+ AutomationControl(ARDOUR::Session&,
+ boost::shared_ptr<ARDOUR::AutomationList>,
+ std::string name="unnamed controllable");
+
+ void set_value(float val);
+ float get_value() const;
+ float user_value() const;
+
+ void set_list(boost::shared_ptr<ARDOUR::AutomationList>);
+
+ boost::shared_ptr<ARDOUR::AutomationList> list() { return _list; }
+ boost::shared_ptr<const ARDOUR::AutomationList> list() const { return _list; }
+
+ Parameter parameter() const;
+
+protected:
+ ARDOUR::Session& _session;
+ boost::shared_ptr<ARDOUR::AutomationList> _list;
+ float _user_value;
+};
+
+
+} // namespace ARDOUR
+
+#endif /* __ardour_automation_control_h__ */
diff --git a/libs/ardour/ardour/automation_event.h b/libs/ardour/ardour/automation_event.h
new file mode 100644
index 0000000000..18190aa9b6
--- /dev/null
+++ b/libs/ardour/ardour/automation_event.h
@@ -0,0 +1,309 @@
+/*
+ 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.
+
+*/
+
+#ifndef __ardour_automation_event_h__
+#define __ardour_automation_event_h__
+
+#include <stdint.h>
+#include <list>
+#include <cmath>
+
+#include <sigc++/signal.h>
+#include <glibmm/thread.h>
+
+#include <boost/pool/pool.hpp>
+#include <boost/pool/pool_alloc.hpp>
+
+#include <pbd/undo.h>
+#include <pbd/xml++.h>
+#include <pbd/statefuldestructible.h>
+
+#include <ardour/ardour.h>
+#include <ardour/parameter.h>
+
+namespace ARDOUR {
+
+class Curve;
+
+struct ControlEvent {
+
+ ControlEvent (double w, double v)
+ : when (w), value (v), coeff (0) {
+ }
+
+ ControlEvent (const ControlEvent& other)
+ : when (other.when), value (other.value), coeff (0) {
+ if (other.coeff) {
+ create_coeffs();
+ for (size_t i=0; i < 4; ++i)
+ coeff[i] = other.coeff[i];
+ }
+ }
+
+ ~ControlEvent() { if (coeff) delete[] coeff; }
+
+ void create_coeffs() {
+ if (!coeff)
+ coeff = new double[4];
+
+ coeff[0] = coeff[1] = coeff[2] = coeff[3] = 0.0;
+ }
+
+ double when;
+ double value;
+ double* coeff; ///< double[4] allocated by Curve as needed
+};
+
+/* automation lists use a pool allocator that does not use a lock and
+ allocates 8k of new pointers at a time
+*/
+
+typedef boost::fast_pool_allocator<ControlEvent*,
+ boost::default_user_allocator_new_delete,
+ boost::details::pool::null_mutex,
+ 8192> ControlEventAllocator;
+
+class AutomationList : public PBD::StatefulDestructible
+{
+ public:
+ typedef std::list<ControlEvent*,ControlEventAllocator> EventList;
+ typedef EventList::iterator iterator;
+ typedef EventList::reverse_iterator reverse_iterator;
+ typedef EventList::const_iterator const_iterator;
+
+ AutomationList (Parameter id, double min_val, double max_val, double default_val);
+ AutomationList (const XMLNode&, Parameter id);
+ ~AutomationList();
+
+ AutomationList (const AutomationList&);
+ AutomationList (const AutomationList&, double start, double end);
+ AutomationList& operator= (const AutomationList&);
+ bool operator== (const AutomationList&);
+
+ const Parameter& parameter() const { return _parameter; }
+ void set_parameter(Parameter p) { _parameter = p; }
+
+ void freeze();
+ void thaw ();
+
+ EventList::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 slide (iterator before, double distance);
+
+ void reposition_for_rt_add (double when);
+ void rt_add (double when, double value);
+ void add (double when, double value);
+ /* this should be private but old-school automation loading needs it in IO/IOProcessor */
+ void fast_simple_add (double when, double value);
+
+ void reset_range (double start, double end);
+ 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() const {
+ return (_state & Play) || ((_state & Touch) && !_touching);
+ }
+ bool automation_write () const {
+ 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&)) {
+ Glib::Mutex::Lock lm (_lock);
+ (obj.*method)(*this);
+ }
+
+ sigc::signal<void> StateChanged;
+
+ XMLNode& get_state(void);
+ int set_state (const XMLNode &s);
+ XMLNode& state (bool full);
+ XMLNode& serialize_events ();
+
+ void set_max_xval (double);
+ double get_max_xval() const { return _max_xval; }
+
+ double eval (double where) {
+ Glib::Mutex::Lock lm (_lock);
+ return unlocked_eval (where);
+ }
+
+ double rt_safe_eval (double where, bool& ok) {
+
+ Glib::Mutex::Lock lm (_lock, Glib::TRY_LOCK);
+
+ if ((ok = lm.locked())) {
+ return unlocked_eval (where);
+ } else {
+ return 0.0;
+ }
+ }
+
+ static inline bool time_comparator (const ControlEvent* a, const ControlEvent* b) {
+ return a->when < b->when;
+ }
+
+ /** Lookup cache for eval functions, range contains equivalent values */
+ struct LookupCache {
+ LookupCache() : left(-1) {}
+ double left; /* leftmost x coordinate used when finding "range" */
+ std::pair<AutomationList::const_iterator,AutomationList::const_iterator> range;
+ };
+
+ /** Lookup cache for point finding, range contains points between left and right */
+ struct SearchCache {
+ SearchCache() : left(-1), right(-1) {}
+ double left; /* leftmost x coordinate used when finding "range" */
+ double right; /* rightmost x coordinate used when finding "range" */
+ std::pair<AutomationList::const_iterator,AutomationList::const_iterator> range;
+ };
+
+ static sigc::signal<void, AutomationList*> AutomationListCreated;
+
+ const EventList& events() const { return _events; }
+ double default_value() const { return _default_value; }
+
+ // teeny const violations for Curve
+ mutable sigc::signal<void> Dirty;
+ Glib::Mutex& lock() const { return _lock; }
+ LookupCache& lookup_cache() const { return _lookup_cache; }
+ SearchCache& search_cache() const { return _search_cache; }
+
+ /** Called by locked entry point and various private
+ * locations where we already hold the lock.
+ *
+ * FIXME: Should this be private? Curve needs it..
+ */
+ double unlocked_eval (double x) const;
+
+ bool rt_safe_earliest_event (double start, double end, double& x, double& y, bool start_inclusive=false) const;
+ bool rt_safe_earliest_event_unlocked (double start, double end, double& x, double& y, bool start_inclusive=false) const;
+
+ Curve& curve() { return *_curve; }
+ const Curve& curve() const { return *_curve; }
+
+ enum InterpolationStyle {
+ Discrete,
+ Linear,
+ Curved
+ };
+
+ InterpolationStyle interpolation() const { return _interpolation; }
+ void set_interpolation(InterpolationStyle style) { _interpolation = style; }
+
+ private:
+
+ /** Called by unlocked_eval() to handle cases of 3 or more control points.
+ */
+ double multipoint_eval (double x) const;
+
+ void build_search_cache_if_necessary(double start, double end) const;
+
+ bool rt_safe_earliest_event_discrete_unlocked (double start, double end, double& x, double& y, bool inclusive) const;
+ bool rt_safe_earliest_event_linear_unlocked (double start, double end, double& x, double& y, bool inclusive) const;
+
+ AutomationList* cut_copy_clear (double, double, int op);
+
+ int deserialize_events (const XMLNode&);
+
+ void maybe_signal_changed ();
+ void mark_dirty ();
+ void _x_scale (double factor);
+
+ mutable LookupCache _lookup_cache;
+ mutable SearchCache _search_cache;
+
+ Parameter _parameter;
+ InterpolationStyle _interpolation;
+ EventList _events;
+ mutable Glib::Mutex _lock;
+ int8_t _frozen;
+ bool _changed_when_thawed;
+ AutoState _state;
+ AutoStyle _style;
+ bool _touching;
+ bool _new_touch;
+ double _max_xval;
+ double _min_yval;
+ double _max_yval;
+ double _default_value;
+ bool _sort_pending;
+ iterator _rt_insertion_point;
+ double _rt_pos;
+
+ Curve* _curve;
+};
+
+} // namespace
+
+#endif /* __ardour_automation_event_h__ */
diff --git a/libs/ardour/ardour/base_audio_port.h b/libs/ardour/ardour/base_audio_port.h
new file mode 100644
index 0000000000..791928fa03
--- /dev/null
+++ b/libs/ardour/ardour/base_audio_port.h
@@ -0,0 +1,106 @@
+/*
+ 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: port.h 712 2006-07-28 01:08:57Z drobilla $
+*/
+
+#ifndef __ardour_base_audio_port_h__
+#define __ardour_base_audio_port_h__
+
+#include <string>
+
+#include <sigc++/signal.h>
+
+#include <pbd/failed_constructor.h>
+
+#include <ardour/ardour.h>
+#include <ardour/port.h>
+#include <ardour/audio_buffer.h>
+
+namespace ARDOUR {
+
+class AudioEngine;
+
+class BaseAudioPort : public virtual Port {
+ public:
+ virtual ~BaseAudioPort();
+
+ DataType type() const { return DataType::AUDIO; }
+
+ virtual Buffer& get_buffer () {
+ assert (_buffer);
+ return *_buffer;
+ }
+
+ virtual AudioBuffer& get_audio_buffer() {
+ assert (_buffer);
+ return *_buffer;
+ }
+
+ void reset ();
+
+ void reset_overs () {
+ /* XXX NOT THREAD SAFE */
+ _short_overs = 0;
+ _long_overs = 0;
+ _overlen = 0;
+ }
+
+ void reset_peak_meter () {
+ /* XXX NOT THREAD SAFE */
+ _peak = 0;
+ }
+
+ void reset_meters () {
+ /* XXX NOT THREAD SAFE */
+ reset_peak_meter ();
+ reset_overs ();
+ }
+
+ float peak_db() const { return _peak_db; }
+ Sample 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 (nframes_t);
+ static void set_long_over_length (nframes_t);
+
+ void set_mixdown_function (void (*func)(const std::set<Port*>&, AudioBuffer*, nframes_t, nframes_t, bool));
+
+ protected:
+ BaseAudioPort (const std::string& name, Flags flags);
+
+ AudioBuffer* _buffer;
+ nframes_t _overlen;
+ Sample _peak;
+ float _peak_db;
+ uint32_t _short_overs;
+ uint32_t _long_overs;
+ bool _own_buffer;
+
+ void (*_mixdown)(const std::set<Port*>&, AudioBuffer*, nframes_t, nframes_t, bool);
+
+ static void default_mixdown (const std::set<Port*>&, AudioBuffer*, nframes_t, nframes_t, bool);
+
+ static nframes_t _long_over_length;
+ static nframes_t _short_over_length;
+};
+
+} // namespace ARDOUR
+
+#endif /* __ardour_base_audio_port_h__ */
diff --git a/libs/ardour/ardour/base_midi_port.h b/libs/ardour/ardour/base_midi_port.h
new file mode 100644
index 0000000000..1c9a69d48d
--- /dev/null
+++ b/libs/ardour/ardour/base_midi_port.h
@@ -0,0 +1,67 @@
+/*
+ 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: port.h 712 2006-07-28 01:08:57Z drobilla $
+*/
+
+#ifndef __ardour_base_midi_port_h__
+#define __ardour_base_midi_port_h__
+
+#include <sigc++/signal.h>
+#include <pbd/failed_constructor.h>
+#include <ardour/ardour.h>
+#include <ardour/port.h>
+#include <ardour/midi_buffer.h>
+
+namespace ARDOUR {
+
+class MidiEngine;
+
+class BaseMidiPort : public virtual Port {
+ public:
+ virtual ~BaseMidiPort();
+
+ DataType type() const { return DataType::MIDI; }
+
+ Buffer& get_buffer() {
+ assert (_buffer);
+ return *_buffer;
+ }
+
+ MidiBuffer& get_midi_buffer() {
+ assert (_buffer);
+ return *_buffer;
+ }
+
+ size_t capacity() { return _buffer->capacity(); }
+ size_t size() { return _buffer->size(); }
+
+ void set_mixdown_function (void (*func)(const std::set<Port*>&, MidiBuffer*, nframes_t, nframes_t, bool));
+
+ protected:
+ BaseMidiPort (const std::string& name, Flags);
+
+ MidiBuffer* _buffer;
+ bool _own_buffer;
+
+ void (*_mixdown)(const std::set<Port*>&, MidiBuffer*, nframes_t, nframes_t, bool);
+ static void default_mixdown (const std::set<Port*>&, MidiBuffer*, nframes_t, nframes_t, bool);
+};
+
+} // namespace ARDOUR
+
+#endif /* __ardour_base_midi_port_h__ */
diff --git a/libs/ardour/ardour/buffer.h b/libs/ardour/ardour/buffer.h
new file mode 100644
index 0000000000..fd94360226
--- /dev/null
+++ b/libs/ardour/ardour/buffer.h
@@ -0,0 +1,92 @@
+/*
+ Copyright (C) 2006 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_buffer_h__
+#define __ardour_buffer_h__
+
+#include <cstdlib>
+#include <cassert>
+#include <iostream>
+#include <boost/utility.hpp>
+#include <ardour/types.h>
+#include <ardour/data_type.h>
+#include <ardour/runtime_functions.h>
+
+namespace ARDOUR {
+
+
+/** A buffer of recordable/playable data.
+ *
+ * This is a datatype-agnostic base class for all buffers (there are no
+ * methods to actually access the data). This provides a way for code that
+ * doesn't care about the data type to still deal with buffers (which is
+ * why the base class can't be a template).
+ *
+ * To actually read/write buffer contents, use the appropriate derived class.
+ */
+class Buffer : public boost::noncopyable
+{
+public:
+ virtual ~Buffer() {}
+
+ /** Factory function */
+ static Buffer* create(DataType type, size_t capacity);
+
+ /** Maximum capacity of buffer.
+ * Note in some cases the entire buffer may not contain valid data, use size. */
+ size_t capacity() const { return _capacity; }
+
+ /** Amount of valid data in buffer. Use this over capacity almost always. */
+ size_t size() const { return _size; }
+
+ /** Type of this buffer.
+ * Based on this you can static cast a Buffer* to the desired type. */
+ DataType type() const { return _type; }
+
+ bool silent() const { return _silent; }
+
+ /** Reallocate the buffer used internally to handle at least @a size_t units of data.
+ *
+ * The buffer is not silent after this operation. the @a capacity argument
+ * passed to the constructor must have been non-zero.
+ */
+ virtual void resize(size_t) = 0;
+
+ /** Clear (eg zero, or empty) buffer starting at TIME @a offset */
+ virtual void silence(nframes_t len, nframes_t offset=0) = 0;
+
+ /** Clear the entire buffer */
+ virtual void clear() { silence(_capacity, 0); }
+
+ virtual void read_from(const Buffer& src, nframes_t offset, nframes_t len) = 0;
+
+protected:
+ Buffer(DataType type, size_t capacity)
+ : _type(type), _capacity(capacity), _size(0), _silent(true)
+ {}
+
+ DataType _type;
+ size_t _capacity;
+ size_t _size;
+ bool _silent;
+};
+
+
+} // namespace ARDOUR
+
+#endif // __ardour_buffer_h__
diff --git a/libs/ardour/ardour/buffer_set.h b/libs/ardour/ardour/buffer_set.h
new file mode 100644
index 0000000000..c750615798
--- /dev/null
+++ b/libs/ardour/ardour/buffer_set.h
@@ -0,0 +1,159 @@
+/*
+ Copyright (C) 2006 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_buffer_set_h__
+#define __ardour_buffer_set_h__
+
+#include <cassert>
+#include <vector>
+#include <ardour/chan_count.h>
+#include <ardour/data_type.h>
+
+namespace ARDOUR {
+
+class Buffer;
+class AudioBuffer;
+class MidiBuffer;
+class PortSet;
+
+
+/** A set of buffers of various types.
+ *
+ * These are mainly accessed from Session and passed around as scratch buffers
+ * (eg as parameters to run() methods) to do in-place signal processing.
+ *
+ * There are two types of counts associated with a BufferSet - available,
+ * and the 'use count'. Available is the actual number of allocated buffers
+ * (and so is the maximum acceptable value for the use counts).
+ *
+ * The use counts are how things determine the form of their input and inform
+ * others the form of their output (eg what they did to the BufferSet).
+ * Setting the use counts is realtime safe.
+ */
+class BufferSet
+{
+public:
+ BufferSet();
+ ~BufferSet();
+
+ void clear();
+
+ void attach_buffers(PortSet& ports);
+
+ void ensure_buffers(const ChanCount& count, size_t buffer_capacity);
+ void ensure_buffers(DataType type, size_t num_buffers, size_t buffer_capacity);
+
+ const ChanCount& available() const { return _available; }
+ ChanCount& available() { return _available; }
+
+ const ChanCount& count() const { return _count; }
+ ChanCount& count() { return _count; }
+
+ void set_count(const ChanCount& count) { _count = count; }
+
+ size_t buffer_capacity(DataType type) const;
+
+ Buffer& get(DataType type, size_t i)
+ {
+ assert(i <= _count.get(type));
+ return *_buffers[type][i];
+ }
+
+ AudioBuffer& get_audio(size_t i)
+ {
+ return (AudioBuffer&)get(DataType::AUDIO, i);
+ }
+
+ MidiBuffer& get_midi(size_t i)
+ {
+ return (MidiBuffer&)get(DataType::MIDI, i);
+ }
+
+ void read_from(BufferSet& in, jack_nframes_t nframes, jack_nframes_t offset=0);
+
+ // ITERATORS
+
+ // FIXME: this is a filthy copy-and-paste mess
+ // FIXME: litter these with assertions
+
+ class audio_iterator {
+ public:
+
+ AudioBuffer& operator*() { return _set.get_audio(_index); }
+ AudioBuffer* operator->() { return &_set.get_audio(_index); }
+ audio_iterator& operator++() { ++_index; return *this; } // yes, prefix only
+ bool operator==(const audio_iterator& other) { return (_index == other._index); }
+ bool operator!=(const audio_iterator& other) { return (_index != other._index); }
+
+ private:
+ friend class BufferSet;
+
+ audio_iterator(BufferSet& list, size_t index) : _set(list), _index(index) {}
+
+ BufferSet& _set;
+ size_t _index;
+ };
+
+ audio_iterator audio_begin() { return audio_iterator(*this, 0); }
+ audio_iterator audio_end() { return audio_iterator(*this, _count.n_audio()); }
+
+ class iterator {
+ public:
+
+ Buffer& operator*() { return _set.get(_type, _index); }
+ Buffer* operator->() { return &_set.get(_type, _index); }
+ iterator& operator++() { ++_index; return *this; } // yes, prefix only
+ bool operator==(const iterator& other) { return (_index == other._index); }
+ bool operator!=(const iterator& other) { return (_index != other._index); }
+ iterator operator=(const iterator& other) { _set = other._set; _type = other._type; _index = other._index; return *this; }
+
+ private:
+ friend class BufferSet;
+
+ iterator(BufferSet& list, DataType type, size_t index)
+ : _set(list), _type(type), _index(index) {}
+
+ BufferSet& _set;
+ DataType _type;
+ size_t _index;
+ };
+
+ iterator begin(DataType type) { return iterator(*this, type, 0); }
+ iterator end(DataType type) { return iterator(*this, type, _count.get(type)); }
+
+
+private:
+ typedef std::vector<Buffer*> BufferVec;
+
+ /// Vector of vectors, indexed by DataType
+ std::vector<BufferVec> _buffers;
+
+ /// Use counts (there may be more actual buffers than this)
+ ChanCount _count;
+
+ /// Available counts (number of buffers actually allocated)
+ ChanCount _available;
+
+ /// Whether we (don't) 'own' the contained buffers (otherwise we mirror a PortSet)
+ bool _is_mirror;
+};
+
+
+} // namespace ARDOUR
+
+#endif // __ardour_buffer_set_h__
diff --git a/libs/ardour/ardour/bundle.h b/libs/ardour/ardour/bundle.h
new file mode 100644
index 0000000000..ba92063b30
--- /dev/null
+++ b/libs/ardour/ardour/bundle.h
@@ -0,0 +1,73 @@
+/*
+ Copyright (C) 2002-2007 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_bundle_h__
+#define __ardour_bundle_h__
+
+#include <string>
+#include <sigc++/signal.h>
+#include "ardour/data_type.h"
+
+namespace ARDOUR {
+
+typedef std::vector<std::string> PortList;
+
+/**
+ * A set of `channels', each of which is associated with 0 or more JACK ports.
+ */
+
+class Bundle {
+ public:
+ Bundle () : _type (DataType::AUDIO) {}
+ Bundle (bool i) : _type (DataType::AUDIO), _ports_are_inputs (i) {}
+ Bundle (std::string const & n, bool i = true) : _name (n), _type (DataType::AUDIO), _ports_are_inputs (i) {}
+ virtual ~Bundle() {}
+
+ /**
+ * @return Number of channels that this Bundle has.
+ */
+ virtual uint32_t nchannels () const = 0;
+ virtual const PortList& channel_ports (uint32_t) const = 0;
+
+ void set_name (std::string const & n) {
+ _name = n;
+ NameChanged ();
+ }
+
+ std::string name () const { return _name; }
+
+ sigc::signal<void> NameChanged;
+
+ void set_type (DataType t) { _type = t; }
+ DataType type () const { return _type; }
+
+ void set_ports_are_inputs () { _ports_are_inputs = true; }
+ void set_ports_are_outputs () { _ports_are_inputs = false; }
+ bool ports_are_inputs () const { return _ports_are_inputs; }
+ bool ports_are_outputs () const { return !_ports_are_inputs; }
+
+ private:
+ std::string _name;
+ ARDOUR::DataType _type;
+ bool _ports_are_inputs;
+};
+
+}
+
+#endif /* __ardour_bundle_h__ */
diff --git a/libs/ardour/ardour/caimportable.h b/libs/ardour/ardour/caimportable.h
new file mode 100644
index 0000000000..dc7f5769ae
--- /dev/null
+++ b/libs/ardour/ardour/caimportable.h
@@ -0,0 +1,48 @@
+/*
+ Copyright (C) 2007 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_ca_importable_source_h__
+#define __ardour_ca_importable_source_h__
+
+#include <pbd/failed_constructor.h>
+#include <ardour/types.h>
+#include <ardour/importable_source.h>
+
+#include <appleutility/CAAudioFile.h>
+
+namespace ARDOUR {
+
+class CAImportableSource : public ImportableSource {
+ public:
+ CAImportableSource (const std::string& path);
+ virtual ~CAImportableSource();
+
+ nframes_t read (Sample* buffer, nframes_t nframes);
+ uint32_t channels() const;
+ nframes_t length() const;
+ nframes_t samplerate() const;
+ void seek (nframes_t pos);
+
+ protected:
+ mutable CAAudioFile af;
+};
+
+}
+
+#endif /* __ardour_ca_importable_source_h__ */
diff --git a/libs/ardour/ardour/chan_count.h b/libs/ardour/ardour/chan_count.h
new file mode 100644
index 0000000000..986ef76e25
--- /dev/null
+++ b/libs/ardour/ardour/chan_count.h
@@ -0,0 +1,126 @@
+/*
+ Copyright (C) 2006 Paul Davis
+ Author: Dave Robillard
+
+ 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_chan_count_h__
+#define __ardour_chan_count_h__
+
+#include <ardour/data_type.h>
+#include <cassert>
+
+namespace ARDOUR {
+
+
+/** A count of channels, possibly with many types.
+ *
+ * Operators are defined so this may safely be used as if it were a simple
+ * (single-typed) integer count of channels.
+ */
+class ChanCount {
+public:
+ ChanCount() { reset(); }
+
+ // Convenience constructor for making single-typed streams (stereo, mono, etc)
+ ChanCount(DataType type, uint32_t channels)
+ {
+ reset();
+ set(type, channels);
+ }
+
+ void reset()
+ {
+ for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
+ _counts[*t] = 0;
+ }
+ }
+
+ void set(DataType t, uint32_t count) { assert(t != DataType::NIL); _counts[t] = count; }
+ uint32_t get(DataType t) const { assert(t != DataType::NIL); return _counts[t]; }
+
+ inline uint32_t n_audio() const { return _counts[DataType::AUDIO]; }
+ inline void set_audio(uint32_t a) { _counts[DataType::AUDIO] = a; }
+
+ inline uint32_t n_midi() const { return _counts[DataType::MIDI]; }
+ inline void set_midi(uint32_t m) { _counts[DataType::MIDI] = m; }
+
+ uint32_t n_total() const
+ {
+ uint32_t ret = 0;
+ for (uint32_t i=0; i < DataType::num_types; ++i)
+ ret += _counts[i];
+
+ return ret;
+ }
+
+ bool operator==(const ChanCount& other) const
+ {
+ for (uint32_t i=0; i < DataType::num_types; ++i)
+ if (_counts[i] != other._counts[i])
+ return false;
+
+ return true;
+ }
+
+ bool operator!=(const ChanCount& other) const
+ {
+ return ! (*this == other);
+ }
+
+ bool operator<(const ChanCount& other) const
+ {
+ for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
+ if (_counts[*t] > other._counts[*t]) {
+ return false;
+ }
+ }
+ return (*this != other);
+ }
+
+ bool operator<=(const ChanCount& other) const
+ {
+ return ( (*this < other) || (*this == other) );
+ }
+
+ bool operator>(const ChanCount& other) const
+ {
+ for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
+ if (_counts[*t] < other._counts[*t]) {
+ return false;
+ }
+ }
+ return (*this != other);
+ }
+
+ bool operator>=(const ChanCount& other) const
+ {
+ return ( (*this > other) || (*this == other) );
+ }
+
+ static const ChanCount INFINITE;
+ static const ChanCount ZERO;
+
+private:
+
+ uint32_t _counts[DataType::num_types];
+};
+
+
+} // namespace ARDOUR
+
+#endif // __ardour_chan_count_h__
+
diff --git a/libs/ardour/ardour/click.h b/libs/ardour/ardour/click.h
new file mode 100644
index 0000000000..60499b98da
--- /dev/null
+++ b/libs/ardour/ardour/click.h
@@ -0,0 +1,45 @@
+/*
+ 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_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/configuration.h b/libs/ardour/ardour/configuration.h
new file mode 100644
index 0000000000..7b890500d8
--- /dev/null
+++ b/libs/ardour/ardour/configuration.h
@@ -0,0 +1,106 @@
+/*
+ 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.
+
+*/
+
+#ifndef __ardour_configuration_h__
+#define __ardour_configuration_h__
+
+#include <map>
+#include <vector>
+
+#include <sys/types.h>
+#include <string>
+
+#include <pbd/stateful.h>
+
+#include <ardour/types.h>
+#include <ardour/utils.h>
+#include <ardour/configuration_variable.h>
+
+class XMLNode;
+
+namespace ARDOUR {
+
+class Configuration : public PBD::Stateful
+{
+ public:
+ Configuration();
+ virtual ~Configuration();
+
+ std::map<std::string,XMLNode> midi_ports;
+
+ void map_parameters (sigc::slot<void,const char*> theSlot);
+
+ int load_state ();
+ int save_state ();
+
+ /// calls Stateful::*instant_xml methods using
+ /// ARDOUR::user_config_directory for the directory argument
+ void add_instant_xml (XMLNode&);
+ XMLNode * instant_xml (const std::string& str);
+
+ int set_state (const XMLNode&);
+ XMLNode& get_state (void);
+ XMLNode& get_variables (sigc::slot<bool,ConfigVariableBase::Owner>, std::string which_node = "Config");
+ void set_variables (const XMLNode&, ConfigVariableBase::Owner owner);
+
+ void set_current_owner (ConfigVariableBase::Owner);
+
+ XMLNode* control_protocol_state () { return _control_protocol_state; }
+
+ sigc::signal<void,const char*> ParameterChanged;
+
+ /* define accessor methods */
+
+#undef CONFIG_VARIABLE
+#undef CONFIG_VARIABLE_SPECIAL
+#define CONFIG_VARIABLE(Type,var,name,value) \
+ Type get_##var () const { return var.get(); } \
+ bool set_##var (Type val) { bool ret = var.set (val, current_owner); if (ret) { ParameterChanged (name); } return ret; }
+#define CONFIG_VARIABLE_SPECIAL(Type,var,name,value,mutator) \
+ Type get_##var () const { return var.get(); } \
+ bool set_##var (Type val) { bool ret = var.set (val, current_owner); if (ret) { ParameterChanged (name); } return ret; }
+#include "ardour/configuration_vars.h"
+#undef CONFIG_VARIABLE
+#undef CONFIG_VARIABLE_SPECIAL
+
+ private:
+
+ /* declare variables */
+
+#undef CONFIG_VARIABLE
+#undef CONFIG_VARIABLE_SPECIAL
+#define CONFIG_VARIABLE(Type,var,name,value) ConfigVariable<Type> var;
+#define CONFIG_VARIABLE_SPECIAL(Type,var,name,value,mutator) ConfigVariableWithMutation<Type> var;
+#include "ardour/configuration_vars.h"
+#undef CONFIG_VARIABLE
+#undef CONFIG_VARIABLE_SPECIAL
+
+ ConfigVariableBase::Owner current_owner;
+ XMLNode* _control_protocol_state;
+
+ XMLNode& state (sigc::slot<bool,ConfigVariableBase::Owner>);
+ bool save_config_options_predicate (ConfigVariableBase::Owner owner);
+};
+
+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/configuration_variable.h b/libs/ardour/ardour/configuration_variable.h
new file mode 100644
index 0000000000..a61283ecd0
--- /dev/null
+++ b/libs/ardour/ardour/configuration_variable.h
@@ -0,0 +1,184 @@
+/*
+ Copyright (C) 2000-2007 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_configuration_variable_h__
+#define __ardour_configuration_variable_h__
+
+#include <sstream>
+#include <ostream>
+#include <iostream>
+
+#include <pbd/xml++.h>
+
+namespace ARDOUR {
+
+class ConfigVariableBase {
+ public:
+ enum Owner {
+ Default = 0x1,
+ System = 0x2,
+ Config = 0x4,
+ Session = 0x8,
+ Interface = 0x10
+ };
+
+ ConfigVariableBase (std::string str) : _name (str), _owner (Default) {}
+ virtual ~ConfigVariableBase() {}
+
+ std::string name() const { return _name; }
+ Owner owner() const { return _owner; }
+
+ virtual void add_to_node (XMLNode& node) = 0;
+ virtual bool set_from_node (const XMLNode& node, Owner owner) = 0;
+
+ void show_stored_value (const std::string&);
+ static void set_show_stored_values (bool yn);
+
+ protected:
+ std::string _name;
+ Owner _owner;
+ static bool show_stores;
+
+ void notify ();
+ void miss ();
+};
+
+template<class T>
+class ConfigVariable : public ConfigVariableBase
+{
+ public:
+ ConfigVariable (std::string str) : ConfigVariableBase (str) {}
+ ConfigVariable (std::string str, T val) : ConfigVariableBase (str), value (val) {}
+
+ virtual bool set (T val, Owner owner = ARDOUR::ConfigVariableBase::Config) {
+ if (val == value) {
+ miss ();
+ return false;
+ }
+ value = val;
+ _owner = (ConfigVariableBase::Owner)(_owner |owner);
+ notify ();
+ return true;
+ }
+
+ T get() const {
+ return value;
+ }
+
+ void add_to_node (XMLNode& node) {
+ std::stringstream ss;
+ ss << value;
+ show_stored_value (ss.str());
+ XMLNode* child = new XMLNode ("Option");
+ child->add_property ("name", _name);
+ child->add_property ("value", ss.str());
+ node.add_child_nocopy (*child);
+ }
+
+ bool set_from_node (const XMLNode& node, Owner owner) {
+
+ if (node.name() == "Config") {
+
+ /* ardour.rc */
+
+ const XMLProperty* prop;
+ XMLNodeList nlist;
+ XMLNodeConstIterator niter;
+ XMLNode* child;
+
+ nlist = node.children();
+
+ for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
+
+ child = *niter;
+
+ if (child->name() == "Option") {
+ if ((prop = child->property ("name")) != 0) {
+ if (prop->value() == _name) {
+ if ((prop = child->property ("value")) != 0) {
+ std::stringstream ss;
+ ss << prop->value();
+ ss >> value;
+ _owner = (ConfigVariableBase::Owner)(_owner |owner);
+ return true;
+ }
+ }
+ }
+ }
+ }
+
+ } else if (node.name() == "Options") {
+
+ /* session file */
+
+ XMLNodeList olist;
+ XMLNodeConstIterator oiter;
+ XMLNode* option;
+ const XMLProperty* opt_prop;
+
+ olist = node.children();
+
+ for (oiter = olist.begin(); oiter != olist.end(); ++oiter) {
+
+ option = *oiter;
+
+ if (option->name() == _name) {
+ if ((opt_prop = option->property ("val")) != 0) {
+ std::stringstream ss;
+ ss << opt_prop->value();
+ ss >> value;
+ _owner = (ConfigVariableBase::Owner)(_owner |owner);
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+ }
+
+ protected:
+ virtual T get_for_save() { return value; }
+ T value;
+};
+
+template<class T>
+class ConfigVariableWithMutation : public ConfigVariable<T>
+{
+ public:
+ ConfigVariableWithMutation (std::string name, T val, T (*m)(T))
+ : ConfigVariable<T> (name, val), mutator (m) {}
+
+ bool set (T val, ConfigVariableBase::Owner owner) {
+ if (unmutated_value != val) {
+ unmutated_value = val;
+ return ConfigVariable<T>::set (mutator (val), owner);
+ }
+ return false;
+ }
+
+ protected:
+ virtual T get_for_save() { return unmutated_value; }
+ T unmutated_value;
+ T (*mutator)(T);
+};
+
+}
+
+#endif /* __ardour_configuration_variable_h__ */
diff --git a/libs/ardour/ardour/configuration_vars.h b/libs/ardour/ardour/configuration_vars.h
new file mode 100644
index 0000000000..4e2a14c07b
--- /dev/null
+++ b/libs/ardour/ardour/configuration_vars.h
@@ -0,0 +1,176 @@
+/*
+ Copyright (C) 2000-2007 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.
+
+*/
+
+/* IO connection */
+
+CONFIG_VARIABLE (AutoConnectOption, output_auto_connect, "output-auto-connect", AutoConnectOption (0))
+CONFIG_VARIABLE (AutoConnectOption, input_auto_connect, "input-auto-connect", AutoConnectOption (0))
+
+CONFIG_VARIABLE (std::string, auditioner_output_left, "auditioner-output-left", "default")
+CONFIG_VARIABLE (std::string, auditioner_output_right, "auditioner-output-right", "default")
+
+/* MIDI and MIDI related */
+
+CONFIG_VARIABLE (std::string, mtc_port_name, "mtc-port-name", "default")
+CONFIG_VARIABLE (std::string, mmc_port_name, "mmc-port-name", "default")
+CONFIG_VARIABLE (std::string, midi_port_name, "midi-port-name", "default")
+CONFIG_VARIABLE (bool, trace_midi_input, "trace-midi-input", false)
+CONFIG_VARIABLE (bool, trace_midi_output, "trace-midi-output", false)
+CONFIG_VARIABLE (bool, send_mtc, "send-mtc", false)
+CONFIG_VARIABLE (bool, send_mmc, "send-mmc", true)
+CONFIG_VARIABLE (bool, mmc_control, "mmc-control", true)
+CONFIG_VARIABLE (bool, midi_feedback, "midi-feedback", false)
+CONFIG_VARIABLE (uint8_t, mmc_receive_device_id, "mmc-receive-device-id", 0)
+CONFIG_VARIABLE (uint8_t, mmc_send_device_id, "mmc-send-device-id", 0)
+
+/* control surfaces */
+
+CONFIG_VARIABLE (uint32_t, feedback_interval_ms, "feedback-interval-ms", 100)
+CONFIG_VARIABLE (bool, use_tranzport, "use-tranzport", false)
+CONFIG_VARIABLE (std::string, mackie_emulation, "mackie-emulation", "mcu")
+CONFIG_VARIABLE (RemoteModel, remote_model, "remote-model", MixerOrdered)
+
+/* disk operations */
+
+CONFIG_VARIABLE (uint32_t, minimum_disk_io_bytes, "minimum-disk-io-bytes", 1024 * 256)
+CONFIG_VARIABLE (float, audio_track_buffer_seconds, "track-buffer-seconds", 5.0)
+CONFIG_VARIABLE (float, midi_track_buffer_seconds, "midi-track-buffer-seconds", 1.0)
+CONFIG_VARIABLE (uint32_t, disk_choice_space_threshold, "disk-choice-space-threshold", 57600000)
+CONFIG_VARIABLE (SampleFormat, native_file_data_format, "native-file-data-format", ARDOUR::FormatFloat)
+CONFIG_VARIABLE (HeaderFormat, native_file_header_format, "native-file-header-format", ARDOUR::WAVE)
+CONFIG_VARIABLE (bool, auto_analyse_audio, "auto-analyse-audio", false)
+
+/* OSC */
+
+CONFIG_VARIABLE (uint32_t, osc_port, "osc-port", 3819)
+CONFIG_VARIABLE (bool, use_osc, "use-osc", false)
+
+/* crossfades */
+
+CONFIG_VARIABLE (CrossfadeModel, xfade_model, "xfade-model", FullCrossfade)
+CONFIG_VARIABLE (bool, auto_xfade, "auto-xfade", true)
+CONFIG_VARIABLE (float, short_xfade_seconds, "short-xfade-seconds", 0.015)
+CONFIG_VARIABLE (bool, xfades_active, "xfades-active", true)
+CONFIG_VARIABLE (bool, xfades_visible, "xfades-visible", true)
+CONFIG_VARIABLE (uint32_t, destructive_xfade_msecs, "destructive-xfade-msecs", 2)
+
+/* editing related */
+
+CONFIG_VARIABLE (EditMode, edit_mode, "edit-mode", Slide)
+CONFIG_VARIABLE (LayerModel, layer_model, "layer-model", MoveAddHigher)
+CONFIG_VARIABLE (bool, link_region_and_track_selection, "link-region-and-track-selection", false)
+CONFIG_VARIABLE (std::string, keyboard_layout_name, "keyboard-layout-name", "ansi")
+
+/* monitoring, mute, solo etc */
+
+CONFIG_VARIABLE (bool, mute_affects_pre_fader, "mute-affects-pre-fader", true)
+CONFIG_VARIABLE (bool, mute_affects_post_fader, "mute-affects-post-fader", true)
+CONFIG_VARIABLE (bool, mute_affects_control_outs, "mute-affects-control-outs", true)
+CONFIG_VARIABLE (bool, mute_affects_main_outs, "mute-affects-main-outs", true)
+CONFIG_VARIABLE (MonitorModel, monitoring_model, "monitoring-model", ExternalMonitoring)
+CONFIG_VARIABLE (SoloModel, solo_model, "solo-model", InverseMute)
+CONFIG_VARIABLE (bool, solo_latched, "solo-latched", true)
+CONFIG_VARIABLE (bool, latched_record_enable, "latched-record-enable", false)
+CONFIG_VARIABLE (bool, all_safe, "all-safe", false)
+CONFIG_VARIABLE (bool, show_solo_mutes, "show-solo-mutes", false)
+CONFIG_VARIABLE (bool, tape_machine_mode, "tape-machine-mode", false)
+
+/* click */
+
+CONFIG_VARIABLE (bool, clicking, "clicking", false)
+CONFIG_VARIABLE (std::string, click_sound, "click-sound", "")
+CONFIG_VARIABLE (std::string, click_emphasis_sound, "click-emphasis-sound", "")
+
+/* transport control and related */
+
+CONFIG_VARIABLE (bool, auto_play, "auto-play", false)
+CONFIG_VARIABLE (bool, auto_return, "auto-return", false)
+CONFIG_VARIABLE (bool, auto_input, "auto-input", true)
+CONFIG_VARIABLE (bool, punch_in, "punch-in", false)
+CONFIG_VARIABLE (bool, punch_out, "punch-out", false)
+CONFIG_VARIABLE (bool, plugins_stop_with_transport, "plugins-stop-with-transport", false)
+CONFIG_VARIABLE (bool, do_not_record_plugins, "do-not-record-plugins", false)
+CONFIG_VARIABLE (bool, stop_recording_on_xrun, "stop-recording-on-xrun", false)
+CONFIG_VARIABLE (bool, create_xrun_marker, "create-xrun-marker", true)
+CONFIG_VARIABLE (bool, stop_at_session_end, "stop-at-session-end", true)
+CONFIG_VARIABLE (bool, seamless_loop, "seamless-loop", false)
+CONFIG_VARIABLE (nframes_t, preroll, "preroll", 0)
+CONFIG_VARIABLE (nframes_t, postroll, "postroll", 0)
+CONFIG_VARIABLE (float, rf_speed, "rf-speed", 2.0f)
+CONFIG_VARIABLE (float, shuttle_speed_factor, "shuttle-speed-factor", 1.0f)
+CONFIG_VARIABLE (float, shuttle_speed_threshold, "shuttle-speed-threshold", 5.0f)
+CONFIG_VARIABLE (SlaveSource, slave_source, "slave-source", None)
+CONFIG_VARIABLE (ShuttleBehaviour, shuttle_behaviour, "shuttle-behaviour", Sprung)
+CONFIG_VARIABLE (ShuttleUnits, shuttle_units, "shuttle-units", Percentage)
+CONFIG_VARIABLE (bool, quieten_at_speed, "quieten-at-speed", true)
+CONFIG_VARIABLE (bool, primary_clock_delta_edit_cursor, "primary-clock-delta-edit-cursor", false)
+CONFIG_VARIABLE (bool, secondary_clock_delta_edit_cursor, "secondary-clock-delta-edit-cursor", false)
+CONFIG_VARIABLE (bool, show_track_meters, "show-track-meters", true)
+
+/* timecode and sync */
+
+CONFIG_VARIABLE (bool, jack_time_master, "jack-time-master", true)
+CONFIG_VARIABLE (SmpteFormat, smpte_format, "smpte-format", smpte_30)
+CONFIG_VARIABLE (bool, use_video_sync, "use-video-sync", false)
+CONFIG_VARIABLE (bool, timecode_source_is_synced, "timecode-source-is-synced", true)
+CONFIG_VARIABLE (float, video_pullup, "video-pullup", 0.0f)
+
+/* metering */
+
+CONFIG_VARIABLE (float, meter_hold, "meter-hold", 100.0f)
+CONFIG_VARIABLE (float, meter_falloff, "meter-falloff", 27.0f)
+CONFIG_VARIABLE (nframes_t, over_length_short, "over-length-short", 2)
+CONFIG_VARIABLE (nframes_t, over_length_long, "over-length-long", 10)
+
+/* miscellany */
+
+CONFIG_VARIABLE (bool, hiding_groups_deactivates_groups, "hiding-groups-deactivates-groups", true)
+CONFIG_VARIABLE (bool, verify_remove_last_capture, "verify-remove-last-capture", true)
+CONFIG_VARIABLE (bool, no_new_session_dialog, "no-new-session-dialog", false)
+CONFIG_VARIABLE (bool, use_vst, "use-vst", true)
+CONFIG_VARIABLE (uint32_t, subframes_per_frame, "subframes-per-frame", 100)
+CONFIG_VARIABLE (bool, save_history, "save-history", true)
+CONFIG_VARIABLE (int32_t, saved_history_depth, "save-history-depth", 20)
+CONFIG_VARIABLE (int32_t, history_depth, "history-depth", 20)
+CONFIG_VARIABLE (bool, use_overlap_equivalency, "use-overlap-equivalency", false)
+CONFIG_VARIABLE (bool, periodic_safety_backups, "periodic-safety-backups", true)
+CONFIG_VARIABLE (uint32_t, periodic_safety_backup_interval, "periodic-safety-backup-interval", 120)
+CONFIG_VARIABLE (float, automation_interval, "automation-interval", 50)
+CONFIG_VARIABLE (bool, sync_all_route_ordering, "sync-all-route-ordering", true)
+CONFIG_VARIABLE (bool, only_copy_imported_files, "only-copy-imported-files", true)
+CONFIG_VARIABLE (std::string, keyboard_layout, "keyboard-layout", "ansi")
+CONFIG_VARIABLE (std::string, default_bindings, "default-bindings", "ardour")
+CONFIG_VARIABLE (bool, default_narrow_ms, "default-narrow_ms", false)
+CONFIG_VARIABLE (bool, rubberbanding_snaps_to_grid, "rubberbanding-snaps-to-grid", false)
+CONFIG_VARIABLE (long, font_scale, "font-scale", 102400)
+
+/* denormal management */
+
+CONFIG_VARIABLE (bool, denormal_protection, "denormal-protection", false)
+CONFIG_VARIABLE (DenormalModel, denormal_model, "denormal-model", DenormalNone)
+
+/* BWAV */
+
+CONFIG_VARIABLE (string, bwf_country_code, "bwf-country-code", "US")
+CONFIG_VARIABLE (string, bwf_organization_code, "bwf-organization-code", "US")
+
+/* these variables have custom set() methods (e.g. path globbing) */
+
+CONFIG_VARIABLE_SPECIAL(Glib::ustring, raid_path, "raid-path", "", path_expand)
+
diff --git a/libs/ardour/ardour/control_protocol_manager.h b/libs/ardour/ardour/control_protocol_manager.h
new file mode 100644
index 0000000000..c61513e117
--- /dev/null
+++ b/libs/ardour/ardour/control_protocol_manager.h
@@ -0,0 +1,93 @@
+/*
+ Copyright (C) 2000-2007 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_control_protocol_manager_h
+#define ardour_control_protocol_manager_h
+
+#include <string>
+#include <list>
+
+#include <sigc++/sigc++.h>
+
+#include <glibmm/thread.h>
+
+#include <pbd/stateful.h>
+
+namespace ARDOUR {
+
+class ControlProtocol;
+class ControlProtocolDescriptor;
+class Session;
+
+struct ControlProtocolInfo {
+ ControlProtocolDescriptor* descriptor;
+ ControlProtocol* protocol;
+ std::string name;
+ std::string path;
+ bool requested;
+ bool mandatory;
+ bool supports_feedback;
+ XMLNode* state;
+
+ ControlProtocolInfo() : descriptor (0), protocol (0), state (0) {}
+ ~ControlProtocolInfo() { if (state) { delete state; } }
+};
+
+ class ControlProtocolManager : public sigc::trackable, public PBD::Stateful
+{
+ public:
+ ControlProtocolManager ();
+ ~ControlProtocolManager ();
+
+ static ControlProtocolManager& instance() { return *_instance; }
+
+ void set_session (Session&);
+ void discover_control_protocols ();
+ void foreach_known_protocol (sigc::slot<void,const ControlProtocolInfo*>);
+ void load_mandatory_protocols ();
+
+ ControlProtocol* instantiate (ControlProtocolInfo&);
+ int teardown (ControlProtocolInfo&);
+
+ std::list<ControlProtocolInfo*> control_protocol_info;
+
+ static const std::string state_node_name;
+
+ void set_protocol_states (const XMLNode&);
+
+ int set_state (const XMLNode&);
+ XMLNode& get_state (void);
+
+ private:
+ static ControlProtocolManager* _instance;
+
+ Session* _session;
+ Glib::Mutex protocols_lock;
+ std::list<ControlProtocol*> control_protocols;
+
+ void drop_session ();
+
+ int control_protocol_discover (std::string path);
+ ControlProtocolDescriptor* get_descriptor (std::string path);
+ ControlProtocolInfo* cpi_by_name (std::string);
+};
+
+} // namespace
+
+#endif // ardour_control_protocol_manager_h
diff --git a/libs/ardour/ardour/control_protocol_search_path.h b/libs/ardour/ardour/control_protocol_search_path.h
new file mode 100644
index 0000000000..f9a8103c0c
--- /dev/null
+++ b/libs/ardour/ardour/control_protocol_search_path.h
@@ -0,0 +1,42 @@
+/*
+ Copyright (C) 2007 Tim Mayberry
+
+ 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_CONTROL_PROTOCOL_SEARCH_PATH_INCLUDED
+#define ARDOUR_CONTROL_PROTOCOL_SEARCH_PATH_INCLUDED
+
+#include <pbd/search_path.h>
+
+namespace ARDOUR {
+
+ using PBD::SearchPath;
+
+ /**
+ * return a SearchPath containing directories in which to look for
+ * control surface plugins.
+ *
+ * If ARDOUR_SURFACES_PATH is defined then the SearchPath returned
+ * will contain only those directories specified in it, otherwise it will
+ * contain the user and system directories which may contain control
+ * surface plugins.
+ */
+ SearchPath control_protocol_search_path ();
+
+} // namespace ARDOUR
+
+#endif
diff --git a/libs/ardour/ardour/coreaudiosource.h b/libs/ardour/ardour/coreaudiosource.h
new file mode 100644
index 0000000000..d7282b35bd
--- /dev/null
+++ b/libs/ardour/ardour/coreaudiosource.h
@@ -0,0 +1,57 @@
+/*
+ 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.
+
+*/
+
+#ifndef __coreaudio_source_h__
+#define __coreaudio_source_h__
+
+#include <appleutility/CAAudioFile.h>
+#include <ardour/audiofilesource.h>
+
+namespace ARDOUR {
+
+class CoreAudioSource : public AudioFileSource {
+ public:
+ CoreAudioSource (ARDOUR::Session&, const XMLNode&);
+ CoreAudioSource (ARDOUR::Session&, const string& path, int chn, Flag);
+ ~CoreAudioSource ();
+
+ float sample_rate() const;
+ int update_header (nframes_t when, struct tm&, time_t);
+
+ int flush_header () {return 0;};
+ void set_header_timeline_position () {};
+
+ static int get_soundfile_info (string path, SoundFileInfo& _info, string& error_msg);
+
+ protected:
+ nframes_t read_unlocked (Sample *dst, nframes_t start, nframes_t cnt) const;
+ nframes_t write_unlocked (Sample *dst, nframes_t cnt) { return 0; }
+
+ private:
+ mutable CAAudioFile af;
+ uint16_t n_channels;
+
+ void init ();
+ int safe_read (Sample*, nframes_t start, nframes_t cnt, AudioBufferList&) const;
+};
+
+}; /* namespace ARDOUR */
+
+#endif /* __coreaudio_source_h__ */
+
diff --git a/libs/ardour/ardour/crossfade.h b/libs/ardour/ardour/crossfade.h
new file mode 100644
index 0000000000..9ba3689e82
--- /dev/null
+++ b/libs/ardour/ardour/crossfade.h
@@ -0,0 +1,179 @@
+/*
+ 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.
+
+*/
+
+#ifndef __ardour_overlap_h__
+#define __ardour_overlap_h__
+
+#include <vector>
+#include <algorithm>
+#include <boost/shared_ptr.hpp>
+
+#include <sigc++/signal.h>
+
+#include <pbd/undo.h>
+#include <pbd/statefuldestructible.h>
+
+#include <ardour/ardour.h>
+#include <ardour/curve.h>
+#include <ardour/audioregion.h>
+#include <ardour/crossfade_compare.h>
+
+namespace ARDOUR {
+
+class AudioRegion;
+class Playlist;
+
+class Crossfade : public ARDOUR::AudioRegion
+{
+ 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 (boost::shared_ptr<ARDOUR::AudioRegion> in, boost::shared_ptr<ARDOUR::AudioRegion> out,
+ nframes_t position,
+ nframes_t initial_length,
+ AnchorPoint);
+
+ /* constructor for xfade between two regions that are overlapped in any way
+ except the "internal" case.
+ */
+
+ Crossfade (boost::shared_ptr<ARDOUR::AudioRegion> in, boost::shared_ptr<ARDOUR::AudioRegion> out, CrossfadeModel, bool active);
+
+
+ /* copy constructor to copy a crossfade with new regions. used (for example)
+ when a playlist copy is made
+ */
+ Crossfade (boost::shared_ptr<Crossfade>, boost::shared_ptr<ARDOUR::AudioRegion>, boost::shared_ptr<ARDOUR::AudioRegion>);
+
+ /* the usual XML constructor */
+
+ Crossfade (const Playlist&, XMLNode&);
+ virtual ~Crossfade();
+
+ bool operator== (const ARDOUR::Crossfade&);
+
+ XMLNode& get_state (void);
+ int set_state (const XMLNode&);
+
+ boost::shared_ptr<ARDOUR::AudioRegion> in() const { return _in; }
+ boost::shared_ptr<ARDOUR::AudioRegion> out() const { return _out; }
+
+ nframes_t read_at (Sample *buf, Sample *mixdown_buffer,
+ float *gain_buffer, nframes_t position, nframes_t cnt,
+ uint32_t chan_n,
+ nframes_t read_frames = 0,
+ nframes_t skip_frames = 0) const;
+
+ 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 (boost::shared_ptr<ARDOUR::AudioRegion> region) const {
+ return _in == region || _out == region;
+ }
+
+ bool involves (boost::shared_ptr<ARDOUR::AudioRegion> a, boost::shared_ptr<ARDOUR::AudioRegion> b) const {
+ return (_in == a && _out == b) || (_in == b && _out == a);
+ }
+
+ nframes_t overlap_length() const;
+
+ void invalidate();
+
+ sigc::signal<void,boost::shared_ptr<Region> > Invalidated;
+ sigc::signal<void,Change> StateChanged;
+
+ bool covers (nframes_t frame) const {
+ return _position <= frame && frame < _position + _length;
+ }
+
+ OverlapType coverage (nframes_t start, nframes_t end) const;
+
+ static void set_buffer_size (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);
+
+ AutomationList& fade_in() { return _fade_in; }
+ AutomationList& fade_out() { return _fade_out; }
+
+ nframes_t set_length (nframes_t);
+
+ bool is_dependent() const { return true; }
+ bool depends_on (boost::shared_ptr<Region> other) const {
+ return other == _in || other == _out;
+ }
+
+ static nframes_t short_xfade_length() { return _short_xfade_length; }
+ static void set_short_xfade_length (nframes_t n);
+
+ static Change ActiveChanged;
+ static Change FollowOverlapChanged;
+
+ private:
+ friend struct CrossfadeComparePtr;
+ friend class AudioPlaylist;
+
+ static nframes_t _short_xfade_length;
+
+ boost::shared_ptr<ARDOUR::AudioRegion> _in;
+ boost::shared_ptr<ARDOUR::AudioRegion> _out;
+ bool _active;
+ bool _in_update;
+ OverlapType overlap_type;
+ AnchorPoint _anchor_point;
+ bool _follow_overlap;
+ bool _fixed;
+ int32_t layer_relation;
+
+
+ mutable AutomationList _fade_in;
+ mutable AutomationList _fade_out;
+
+ static Sample* crossfade_buffer_out;
+ static Sample* crossfade_buffer_in;
+
+ void initialize ();
+ int compute (boost::shared_ptr<ARDOUR::AudioRegion>, boost::shared_ptr<ARDOUR::AudioRegion>, CrossfadeModel);
+ bool update ();
+
+ protected:
+ nframes_t read_raw_internal (Sample*, nframes_t, nframes_t) const;
+};
+
+
+} // 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..b92806a6bb
--- /dev/null
+++ b/libs/ardour/ardour/crossfade_compare.h
@@ -0,0 +1,42 @@
+/*
+ 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.
+
+*/
+
+#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..433b00a270
--- /dev/null
+++ b/libs/ardour/ardour/curve.h
@@ -0,0 +1,62 @@
+/*
+ Copyright (C) 2001-2007 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_curve_h__
+#define __ardour_curve_h__
+
+#include <sys/types.h>
+#include <boost/utility.hpp>
+#include <sigc++/signal.h>
+#include <glibmm/thread.h>
+#include <pbd/undo.h>
+#include <list>
+#include <algorithm>
+#include <ardour/automation_event.h>
+
+namespace ARDOUR {
+
+class Curve : public boost::noncopyable
+{
+ public:
+ Curve (const AutomationList& al);
+
+ 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);
+
+ void solve ();
+
+ private:
+ double unlocked_eval (double where);
+ double multipoint_eval (double x);
+
+ void _get_vector (double x0, double x1, float *arg, int32_t veclen);
+
+ void on_list_dirty() { _dirty = true; }
+
+ bool _dirty;
+ const AutomationList& _list;
+};
+
+} // 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..4e1a50e602
--- /dev/null
+++ b/libs/ardour/ardour/cycle_timer.h
@@ -0,0 +1,50 @@
+/*
+ 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.
+
+*/
+
+#ifndef __ardour_cycle_timer_h__
+#define __ardour_cycle_timer_h__
+
+#include <string>
+#include <iostream>
+
+#include <ardour/cycles.h>
+
+class CycleTimer {
+ private:
+ static float cycles_per_usec;
+ cycles_t _entry;
+ cycles_t _exit;
+ std::string _name;
+
+ public:
+ CycleTimer(std::string name) : _name (name){
+ if (cycles_per_usec == 0) {
+ cycles_per_usec = get_mhz ();
+ }
+ _entry = get_cycles();
+ }
+ ~CycleTimer() {
+ _exit = get_cycles();
+ std::cerr << _name << ": " << (float) (_exit - _entry) / cycles_per_usec << " (" << _entry << ", " << _exit << ')' << endl;
+ }
+
+ 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..0d1ac154dd
--- /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.
+
+*/
+
+#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/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..b67e581067
--- /dev/null
+++ b/libs/ardour/ardour/dB.h
@@ -0,0 +1,33 @@
+/*
+ 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.
+
+*/
+
+#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/data_type.h b/libs/ardour/ardour/data_type.h
new file mode 100644
index 0000000000..854f52acba
--- /dev/null
+++ b/libs/ardour/ardour/data_type.h
@@ -0,0 +1,130 @@
+/*
+ Copyright (C) 2006 Paul Davis
+ Author: Dave Robillard
+
+ 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_data_type_h__
+#define __ardour_data_type_h__
+
+#include <string>
+#include <jack/jack.h>
+
+namespace ARDOUR {
+
+
+/** A type of Data Ardour is capable of processing.
+ *
+ * The majority of this class is dedicated to conversion to and from various
+ * other type representations, simple comparison between then, etc. This code
+ * is deliberately 'ugly' so other code doesn't have to be.
+ */
+class DataType
+{
+public:
+ /** Numeric symbol for this DataType.
+ *
+ * Castable to int for use as an array index (e.g. by ChanCount).
+ * Note this means NIL is (ntypes-1) and guaranteed to change when
+ * types are added, so this number is NOT suitable for serialization,
+ * network, or binary anything.
+ *
+ * WARNING: The number of non-NIL entries here must match num_types.
+ */
+ enum Symbol {
+ AUDIO = 0,
+ MIDI = 1,
+ NIL = 2,
+ };
+
+ /** Number of types (not including NIL).
+ * WARNING: make sure this matches Symbol!
+ */
+ static const uint32_t num_types = 2;
+
+ DataType(const Symbol& symbol)
+ : _symbol(symbol)
+ {}
+
+ /** Construct from a string (Used for loading from XML and Ports)
+ * The string can be as in an XML file (eg "audio" or "midi"), or a
+ * Jack type string (from jack_port_type) */
+ DataType(const std::string& str)
+ : _symbol(NIL) {
+ if (str == "audio" || str == JACK_DEFAULT_AUDIO_TYPE)
+ _symbol = AUDIO;
+ else if (str == "midi" || str == JACK_DEFAULT_MIDI_TYPE)
+ _symbol = MIDI;
+ }
+
+ /** Get the Jack type this DataType corresponds to */
+ const char* to_jack_type() const {
+ switch (_symbol) {
+ case AUDIO: return JACK_DEFAULT_AUDIO_TYPE;
+ case MIDI: return JACK_DEFAULT_MIDI_TYPE;
+ default: return "";
+ }
+ }
+
+ /** Inverse of the from-string constructor */
+ const char* to_string() const {
+ switch (_symbol) {
+ case AUDIO: return "audio";
+ case MIDI: return "midi";
+ default: return "unknown"; // reeeally shouldn't ever happen
+ }
+ }
+
+ inline operator uint32_t() const { return (uint32_t)_symbol; }
+
+ /** DataType iterator, for writing generic loops that iterate over all
+ * available types.
+ */
+ class iterator {
+ public:
+
+ iterator(uint32_t index) : _index(index) {}
+
+ DataType operator*() { return DataType((Symbol)_index); }
+ iterator& operator++() { ++_index; return *this; } // yes, prefix only
+ bool operator==(const iterator& other) { return (_index == other._index); }
+ bool operator!=(const iterator& other) { return (_index != other._index); }
+
+ private:
+ friend class DataType;
+
+ uint32_t _index;
+ };
+
+ static iterator begin() { return iterator(0); }
+ static iterator end() { return iterator(num_types); }
+
+ bool operator==(const Symbol symbol) { return (_symbol == symbol); }
+ bool operator!=(const Symbol symbol) { return (_symbol != symbol); }
+
+ bool operator==(const DataType other) { return (_symbol == other._symbol); }
+ bool operator!=(const DataType other) { return (_symbol != other._symbol); }
+
+private:
+ Symbol _symbol; // could be const if not for the string constructor
+};
+
+
+
+} // namespace ARDOUR
+
+#endif // __ardour_data_type_h__
+
diff --git a/libs/ardour/ardour/directory_names.h b/libs/ardour/ardour/directory_names.h
new file mode 100644
index 0000000000..8fabe025d1
--- /dev/null
+++ b/libs/ardour/ardour/directory_names.h
@@ -0,0 +1,23 @@
+
+#ifndef __ardour_directory_names_h__
+#define __ardour_directory_names_h__
+
+#include <string>
+
+namespace ARDOUR {
+
+extern const char* const old_sound_dir_name;
+extern const char* const sound_dir_name;
+extern const char* const midi_dir_name;
+extern const char* const dead_sound_dir_name;
+extern const char* const dead_midi_dir_name;
+extern const char* const interchange_dir_name;
+extern const char* const peak_dir_name;
+extern const char* const export_dir_name;
+extern const char* const templates_dir_name;
+extern const char* const surfaces_dir_name;
+extern const char* const user_config_dir_name;
+
+};
+
+#endif
diff --git a/libs/ardour/ardour/diskstream.h b/libs/ardour/ardour/diskstream.h
new file mode 100644
index 0000000000..824d864663
--- /dev/null
+++ b/libs/ardour/ardour/diskstream.h
@@ -0,0 +1,308 @@
+/*
+ Copyright (C) 2000-2006 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_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/stateful.h>
+#include <pbd/statefuldestructible.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>
+
+struct tm;
+
+namespace ARDOUR {
+
+class AudioEngine;
+class Send;
+class Session;
+class Playlist;
+class IO;
+
+class Diskstream : public SessionObject
+{
+ public:
+ enum Flag {
+ Recordable = 0x1,
+ Hidden = 0x2,
+ Destructive = 0x4
+ };
+
+ Diskstream (Session &, const string& name, Flag f = Recordable);
+ Diskstream (Session &, const XMLNode&);
+ virtual ~Diskstream();
+
+ bool set_name (const string& str);
+
+ ARDOUR::IO* io() const { return _io; }
+ void set_io (ARDOUR::IO& io);
+
+ virtual float playback_buffer_load() const = 0;
+ virtual float capture_buffer_load() const = 0;
+
+ void set_flag (Flag f) { _flags = Flag (_flags | f); }
+ void unset_flag (Flag f) { _flags = Flag (_flags & ~f); }
+
+ AlignStyle alignment_style() const { return _alignment_style; }
+ void set_align_style (AlignStyle);
+ void set_persistent_align_style (AlignStyle a) { _persistent_alignment_style = a; }
+
+ nframes_t roll_delay() const { return _roll_delay; }
+ void set_roll_delay (nframes_t);
+
+ bool record_enabled() const { return g_atomic_int_get (&_record_enabled); }
+ virtual void set_record_enabled (bool yn) = 0;
+
+ bool destructive() const { return _flags & Destructive; }
+ virtual int set_destructive (bool yn) { return -1; }
+ virtual bool can_become_destructive (bool& requires_bounce) const { return false; }
+
+ bool hidden() const { return _flags & Hidden; }
+ bool recordable() const { return _flags & Recordable; }
+ bool reversed() const { return _actual_speed < 0.0f; }
+ double speed() const { return _visible_speed; }
+
+ virtual void punch_in() {}
+ virtual void punch_out() {}
+
+ void set_speed (double);
+ void non_realtime_set_speed ();
+ virtual void non_realtime_locate (nframes_t location) {};
+ virtual void playlist_modified ();
+
+ boost::shared_ptr<Playlist> playlist () { return _playlist; }
+
+ virtual int use_playlist (boost::shared_ptr<Playlist>);
+ virtual int use_new_playlist () = 0;
+ virtual int use_copy_playlist () = 0;
+
+ nframes_t current_capture_start() const { return capture_start_frame; }
+ nframes_t current_capture_end() const { return capture_start_frame + capture_captured; }
+ nframes_t get_capture_start_frame (uint32_t n=0);
+ nframes_t get_captured_frames (uint32_t n=0);
+
+ ChanCount n_channels() { return _n_channels; }
+
+ static nframes_t disk_io_frames() { return disk_io_chunk_frames; }
+ static void set_disk_io_chunk_frames (uint32_t n) { disk_io_chunk_frames = n; }
+
+ /* Stateful */
+ virtual XMLNode& get_state(void) = 0;
+ virtual int set_state(const XMLNode& node) = 0;
+
+ virtual void monitor_input (bool) {}
+
+ nframes_t capture_offset() const { return _capture_offset; }
+ virtual void set_capture_offset ();
+
+ bool slaved() const { return _slaved; }
+ void set_slaved(bool yn) { _slaved = yn; }
+
+ int set_loop (Location *loc);
+
+ std::list<boost::shared_ptr<Region> >& last_capture_regions () { return _last_capture_regions; }
+
+ void handle_input_change (IOChange, void *src);
+
+ void remove_region_from_last_capture (boost::weak_ptr<Region> wregion);
+
+ sigc::signal<void> RecordEnableChanged;
+ sigc::signal<void> SpeedChanged;
+ sigc::signal<void> ReverseChanged;
+ sigc::signal<void> PlaylistChanged;
+ sigc::signal<void> AlignmentStyleChanged;
+ sigc::signal<void,Location *> LoopSet;
+
+ static sigc::signal<void> DiskOverrun;
+ static sigc::signal<void> DiskUnderrun;
+
+ 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.
+ */
+
+ virtual void set_pending_overwrite (bool) = 0;
+ virtual int overwrite_existing_buffers () = 0;
+ virtual void set_block_size (nframes_t) = 0;
+ virtual int internal_playback_seek (nframes_t distance) = 0;
+ virtual int can_internal_playback_seek (nframes_t distance) = 0;
+ virtual int rename_write_sources () = 0;
+ virtual void reset_write_sources (bool, bool force = false) = 0;
+ virtual void non_realtime_input_change () = 0;
+
+ uint32_t read_data_count() const { return _read_data_count; }
+ uint32_t write_data_count() const { return _write_data_count; }
+
+ protected:
+ friend class Auditioner;
+ virtual int seek (nframes_t which_sample, bool complete_refill = false) = 0;
+
+ protected:
+ friend class Track;
+
+ virtual void prepare ();
+ virtual int process (nframes_t transport_frame, nframes_t nframes, nframes_t offset, bool can_record, bool rec_monitors_input) = 0;
+ virtual bool commit (nframes_t nframes) = 0;
+ virtual void recover (); /* called if commit will not be called, but process was */
+
+ //private:
+
+ enum TransitionType {
+ CaptureStart = 0,
+ CaptureEnd
+ };
+
+ struct CaptureTransition {
+ TransitionType type;
+ nframes_t capture_val; ///< The start or end file frame position
+ };
+
+ /* The two central butler operations */
+ virtual int do_flush (Session::RunContext context, bool force = false) = 0;
+ virtual int do_refill () = 0;
+
+ /** For non-butler contexts (allocates temporary working buffers) */
+ virtual int do_refill_with_alloc() = 0;
+
+ /* XXX fix this redundancy ... */
+
+ virtual void playlist_changed (Change);
+ virtual void playlist_deleted (boost::weak_ptr<Playlist>);
+
+ virtual void transport_stopped (struct tm&, time_t, bool abort) = 0;
+ virtual void transport_looped (nframes_t transport_frame) = 0;
+
+ struct CaptureInfo {
+ uint32_t start;
+ uint32_t frames;
+ };
+
+ virtual void init (Flag);
+
+ virtual int use_new_write_source (uint32_t n=0) = 0;
+
+ virtual int find_and_use_playlist (const string&) = 0;
+
+ virtual void allocate_temporary_buffers () = 0;
+
+ virtual bool realtime_set_speed (double, bool global_change);
+
+ std::list<boost::shared_ptr<Region> > _last_capture_regions;
+
+ virtual int use_pending_capture_data (XMLNode& node) = 0;
+
+ virtual void get_input_sources () = 0;
+ virtual void check_record_status (nframes_t transport_frame, nframes_t nframes, bool can_record) = 0;
+ virtual void set_align_style_from_io() {}
+ virtual void setup_destructive_playlist () {}
+ virtual void use_destructive_playlist () {}
+
+ static nframes_t disk_io_chunk_frames;
+ std::vector<CaptureInfo*> capture_info;
+ Glib::Mutex capture_info_lock;
+
+ uint32_t i_am_the_modifier;
+
+ ARDOUR::IO* _io;
+ ChanCount _n_channels;
+
+ boost::shared_ptr<Playlist> _playlist;
+
+ mutable gint _record_enabled;
+ double _visible_speed;
+ double _actual_speed;
+ /* items needed for speed change logic */
+ bool _buffer_reallocation_required;
+ bool _seek_required;
+
+ bool force_refill;
+ nframes_t capture_start_frame;
+ nframes_t capture_captured;
+ bool was_recording;
+ nframes_t adjust_capture_position;
+ nframes_t _capture_offset;
+ nframes_t _roll_delay;
+ nframes_t first_recordable_frame;
+ nframes_t last_recordable_frame;
+ int last_possibly_recording;
+ AlignStyle _alignment_style;
+ bool _scrubbing;
+ bool _slaved;
+ bool _processed;
+ Location* loop_location;
+ nframes_t overwrite_frame;
+ off_t overwrite_offset;
+ bool pending_overwrite;
+ bool overwrite_queued;
+ IOChange input_change_pending;
+ nframes_t wrap_buffer_size;
+ nframes_t speed_buffer_size;
+
+ uint64_t last_phase;
+ uint64_t phi;
+ uint64_t target_phi;
+
+ nframes_t file_frame;
+ nframes_t playback_sample;
+ nframes_t playback_distance;
+ bool commit_should_unlock;
+
+ uint32_t _read_data_count;
+ uint32_t _write_data_count;
+
+ bool in_set_state;
+ AlignStyle _persistent_alignment_style;
+ bool first_input_change;
+
+ Glib::Mutex state_lock;
+
+ nframes_t scrub_start;
+ nframes_t scrub_buffer_size;
+ nframes_t scrub_offset;
+
+ sigc::connection ports_created_c;
+ sigc::connection plmod_connection;
+ sigc::connection plgone_connection;
+
+ Flag _flags;
+};
+
+}; /* 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..141786873d
--- /dev/null
+++ b/libs/ardour/ardour/export.h
@@ -0,0 +1,107 @@
+/*
+ Copyright (C) 2000-2007 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_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> > ExportPortMap;
+
+ struct ExportSpecification : public SF_INFO, public sigc::trackable {
+
+ ExportSpecification();
+ ~ExportSpecification ();
+
+ void init ();
+ void clear ();
+
+
+ int prepare (nframes_t blocksize, nframes_t frame_rate);
+
+ int process (nframes_t nframes);
+
+ /* set by the user */
+
+ string path;
+ nframes_t sample_rate;
+
+ int src_quality;
+ SNDFILE* out;
+ uint32_t channels;
+ ExportPortMap port_map;
+ nframes_t start_frame;
+ nframes_t end_frame;
+ GDitherType dither_type;
+ bool do_freewheel;
+
+ /* used exclusively during export */
+
+ nframes_t frame_rate;
+ GDither dither;
+ float* dataF;
+ float* dataF2;
+ float* leftoverF;
+ nframes_t leftover_frames;
+ nframes_t max_leftover_frames;
+ void* output_data;
+ nframes_t out_samples_max;
+ uint32_t sample_bytes;
+ uint32_t data_width;
+
+ nframes_t total_frames;
+ SF_INFO sfinfo;
+ SRC_DATA src_data;
+ SRC_STATE* src_state;
+ nframes_t pos;
+
+ sigc::connection freewheel_connection;
+
+ /* shared between UI thread and audio thread */
+
+ volatile float progress; /* audio thread sets this */
+ volatile bool stop; /* UI sets this */
+ volatile bool running; /* audio thread sets to false when export is done */
+
+ int status;
+ };
+
+} // namespace ARDOUR
+
+#endif /* __ardour_export_h__ */
diff --git a/libs/ardour/ardour/filename_extensions.h b/libs/ardour/ardour/filename_extensions.h
new file mode 100644
index 0000000000..3e280d6326
--- /dev/null
+++ b/libs/ardour/ardour/filename_extensions.h
@@ -0,0 +1,17 @@
+
+#ifndef __ardour_filename_extensions_h__
+#define __ardour_filename_extensions_h__
+
+namespace ARDOUR {
+
+extern const char* const template_suffix;
+extern const char* const statefile_suffix;
+extern const char* const pending_suffix;
+extern const char* const peakfile_suffix;
+extern const char* const backup_suffix;
+extern const char* const temp_suffix;
+extern const char* const history_suffix;
+
+}
+
+#endif
diff --git a/libs/ardour/ardour/filesystem_paths.h b/libs/ardour/ardour/filesystem_paths.h
new file mode 100644
index 0000000000..12995bd818
--- /dev/null
+++ b/libs/ardour/ardour/filesystem_paths.h
@@ -0,0 +1,50 @@
+/*
+ Copyright (C) 2007 Tim Mayberry
+
+ 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_FILESYSTEM_PATHS_INCLUDED
+#define ARDOUR_FILESYSTEM_PATHS_INCLUDED
+
+#include <pbd/filesystem.h>
+#include <pbd/search_path.h>
+
+namespace ARDOUR {
+
+ using namespace PBD;
+
+ /**
+ * @return the path to the directory used to store user specific ardour
+ * configuration files.
+ */
+ sys::path user_config_directory ();
+
+ /**
+ * @return the path to the directory that contains the system wide ardour
+ * modules.
+ */
+ sys::path ardour_module_directory ();
+
+ SearchPath ardour_search_path ();
+
+ SearchPath system_config_search_path ();
+
+ SearchPath system_data_search_path ();
+
+} // namespace ARDOUR
+
+#endif
diff --git a/libs/ardour/ardour/filter.h b/libs/ardour/ardour/filter.h
new file mode 100644
index 0000000000..b659873bdb
--- /dev/null
+++ b/libs/ardour/ardour/filter.h
@@ -0,0 +1,51 @@
+/*
+ Copyright (C) 2007 Paul Davis
+ Author: Dave Robillard
+
+ 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_filter_h__
+#define __ardour_filter_h__
+
+#include <vector>
+#include <ardour/region.h>
+
+namespace ARDOUR {
+
+class Region;
+class Session;
+
+class Filter {
+
+ public:
+ virtual ~Filter() {}
+
+ virtual int run (boost::shared_ptr<ARDOUR::Region>) = 0;
+ std::vector<boost::shared_ptr<ARDOUR::Region> > results;
+
+ protected:
+ Filter (ARDOUR::Session& s) : session(s) {}
+
+ int make_new_sources (boost::shared_ptr<ARDOUR::Region>, ARDOUR::SourceList&, std::string suffix = "");
+ int finish (boost::shared_ptr<ARDOUR::Region>, ARDOUR::SourceList&, std::string region_name = "");
+
+ ARDOUR::Session& session;
+};
+
+} /* namespace */
+
+#endif /* __ardour_filter_h__ */
diff --git a/libs/ardour/ardour/gain.h b/libs/ardour/ardour/gain.h
new file mode 100644
index 0000000000..e57cfdc0d7
--- /dev/null
+++ b/libs/ardour/ardour/gain.h
@@ -0,0 +1,43 @@
+/*
+ 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.
+
+*/
+
+#ifndef __ardour_gain_h__
+#define __ardour_gain_h__
+
+#include "ardour.h"
+#include "curve.h"
+
+namespace ARDOUR {
+
+struct Gain : public AutomationList {
+
+ Gain();
+ Gain (const Gain&);
+ Gain& operator= (const Gain&);
+
+ static void fill_linear_fade_in (Gain& curve, nframes_t frames);
+ static void fill_linear_volume_fade_in (Gain& curve, nframes_t frames);
+ static void fill_linear_fade_out (Gain& curve, nframes_t frames);
+ static void fill_linear_volume_fade_out (Gain& curve, 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..67efcc3583
--- /dev/null
+++ b/libs/ardour/ardour/gdither.h
@@ -0,0 +1,92 @@
+/*
+ * 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.
+ *
+ */
+
+#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..bcc0097d7f
--- /dev/null
+++ b/libs/ardour/ardour/gdither_types.h
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ *
+ */
+
+#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..e73a256310
--- /dev/null
+++ b/libs/ardour/ardour/gdither_types_internal.h
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ *
+ */
+
+#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/importable_source.h b/libs/ardour/ardour/importable_source.h
new file mode 100644
index 0000000000..a33cf567e7
--- /dev/null
+++ b/libs/ardour/ardour/importable_source.h
@@ -0,0 +1,43 @@
+/*
+ Copyright (C) 2007 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_importable_source_h__
+#define __ardour_importable_source_h__
+
+#include <pbd/failed_constructor.h>
+#include <ardour/types.h>
+
+namespace ARDOUR {
+
+class ImportableSource {
+public:
+ ImportableSource () {}
+ virtual ~ImportableSource() {}
+
+ virtual nframes_t read (Sample* buffer, nframes_t nframes) = 0;
+ virtual float ratio() const { return 1.0f; }
+ virtual uint32_t channels() const = 0;
+ virtual nframes_t length() const = 0;
+ virtual nframes_t samplerate() const = 0;
+ virtual void seek (nframes_t pos) = 0;
+};
+
+}
+
+#endif /* __ardour_importable_source_h__ */
diff --git a/libs/ardour/ardour/internal_audio_port.h b/libs/ardour/ardour/internal_audio_port.h
new file mode 100644
index 0000000000..7b70989d4b
--- /dev/null
+++ b/libs/ardour/ardour/internal_audio_port.h
@@ -0,0 +1,55 @@
+/*
+ Copyright (C) 2007 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: port.h 712 2006-07-28 01:08:57Z drobilla $
+*/
+
+#ifndef __ardour_internal_audio_port_h__
+#define __ardour_internal_audio_port_h__
+
+#include <sigc++/signal.h>
+#include <pbd/failed_constructor.h>
+#include <ardour/ardour.h>
+#include <ardour/internal_port.h>
+#include <ardour/audio_port.h>
+
+namespace ARDOUR {
+
+class AudioEngine;
+class InternalAudioPort : public AudioPort, public InternalPort {
+ public:
+ void cycle_start(nframes_t nframes) {
+ _buffer.silence (nframes);
+ }
+
+ AudioBuffer& get_audio_buffer();
+
+ void set_mixdown_function (void (*func)(const std::list<InternalPort*>&, AudioBuffer&, nframes_t, nframes_t));
+ void reset ();
+
+ protected:
+ friend class AudioEngine;
+
+ InternalAudioPort (const std::string& name, Flags flags);
+ void (*_mixdown)(const std::list<InternalPort*>&, AudioBuffer&, nframes_t, nframes_t);
+
+ static void default_mixdown (const std::list<InternalPort*>&, AudioBuffer&, nframes_t, nframes_t);
+};
+
+} // namespace ARDOUR
+
+#endif /* __ardour_internal_audio_port_h__ */
diff --git a/libs/ardour/ardour/internal_port.h b/libs/ardour/ardour/internal_port.h
new file mode 100644
index 0000000000..e6053c0e58
--- /dev/null
+++ b/libs/ardour/ardour/internal_port.h
@@ -0,0 +1,82 @@
+/*
+ Copyright (C) 2007 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_internal_port_h__
+#define __ardour_internal_port_h__
+
+#include <list>
+
+#include <sigc++/signal.h>
+#include <pbd/failed_constructor.h>
+#include <ardour/port.h>
+
+namespace ARDOUR {
+
+class AudioEngine;
+class Buffer;
+
+/** Abstract class representing internal (ardour<->ardour only) ports
+ */
+class InternalPort : public virtual Port {
+ public:
+
+ ~InternalPort();
+
+ std::string short_name();
+
+ int set_name (std::string str);
+
+ int connected () const;
+
+ int reestablish ();
+
+ bool connected_to (const std::string& portname) const;
+
+ const char ** get_connections () const;
+ bool monitoring_input () const { return false; }
+
+ void ensure_monitor_input (bool yn) {}
+ void request_monitor_input (bool yn) {}
+
+ nframes_t latency () const { return _latency; }
+ nframes_t total_latency() const { return _latency; }
+
+ void set_latency (nframes_t nframes);
+
+ static void connect (InternalPort& src, InternalPort& dst);
+ static void disconnect (InternalPort& a, InternalPort& b);
+
+ protected:
+ friend class AudioEngine;
+
+ InternalPort (const std::string&, DataType type, Flags flags);
+
+ int disconnect ();
+ void recompute_total_latency() const;
+
+ std::list<InternalPort*> _connections;
+ nframes_t _latency;
+
+ static AudioEngine* engine;
+ static void set_engine (AudioEngine* e);
+};
+
+} // namespace ARDOUR
+
+#endif /* __ardour_internal_port_h__ */
diff --git a/libs/ardour/ardour/io.h b/libs/ardour/ardour/io.h
new file mode 100644
index 0000000000..83b6378dae
--- /dev/null
+++ b/libs/ardour/ardour/io.h
@@ -0,0 +1,391 @@
+/*
+ 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.
+
+*/
+
+#ifndef __ardour_io_h__
+#define __ardour_io_h__
+
+#include <string>
+#include <vector>
+#include <cmath>
+#include <sigc++/signal.h>
+#include <jack/jack.h>
+
+#include <glibmm/thread.h>
+
+#include <pbd/fastlog.h>
+#include <pbd/undo.h>
+#include <pbd/statefuldestructible.h>
+#include <pbd/controllable.h>
+
+#include <ardour/ardour.h>
+#include <ardour/automatable.h>
+#include <ardour/utils.h>
+#include <ardour/curve.h>
+#include <ardour/types.h>
+#include <ardour/data_type.h>
+#include <ardour/port_set.h>
+#include <ardour/chan_count.h>
+#include <ardour/latent.h>
+#include <ardour/automation_control.h>
+#include <ardour/user_bundle.h>
+
+using std::string;
+using std::vector;
+
+class XMLNode;
+
+namespace ARDOUR {
+
+class Session;
+class AudioEngine;
+class Bundle;
+class AutoBundle;
+class Panner;
+class PeakMeter;
+class Port;
+class AudioPort;
+class MidiPort;
+class BufferSet;
+
+
+/** A collection of input and output ports with connections.
+ *
+ * An IO can contain ports of varying types, making routes/inserts/etc with
+ * varied combinations of types (eg MIDI and audio) possible.
+ */
+
+class IO : public Automatable, public Latent
+{
+ public:
+ static const string state_node_name;
+
+ IO (Session&, const string& name,
+ int input_min = -1, int input_max = -1,
+ int output_min = -1, int output_max = -1,
+ DataType default_type = DataType::AUDIO,
+ bool public_ports = true);
+
+ IO (Session&, const XMLNode&, DataType default_type = DataType::AUDIO);
+
+ virtual ~IO();
+
+ ChanCount input_minimum() const { return _input_minimum; }
+ ChanCount input_maximum() const { return _input_maximum; }
+ ChanCount output_minimum() const { return _output_minimum; }
+ ChanCount output_maximum() const { return _output_maximum; }
+
+ void set_input_minimum (ChanCount n);
+ void set_input_maximum (ChanCount n);
+ void set_output_minimum (ChanCount n);
+ void set_output_maximum (ChanCount n);
+
+ bool active() const { return _active; }
+ void set_active (bool yn);
+
+ DataType default_type() const { return _default_type; }
+ void set_default_type(DataType t) { _default_type = t; }
+
+ bool set_name (const string& str);
+
+ virtual void silence (nframes_t, nframes_t offset);
+
+ void collect_input (BufferSet& bufs, nframes_t nframes, nframes_t offset);
+ void deliver_output (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame,
+ nframes_t nframes, nframes_t offset);
+ void just_meter_input (nframes_t start_frame, nframes_t end_frame,
+ nframes_t nframes, nframes_t offset);
+
+ gain_t gain () const { return _desired_gain; }
+ virtual gain_t effective_gain () const;
+
+ void set_denormal_protection (bool yn, void *src);
+ bool denormal_protection() const { return _denormal_protection; }
+
+ void set_phase_invert (bool yn, void *src);
+ bool phase_invert() const { return _phase_invert; }
+
+ Panner& panner() { return *_panner; }
+ PeakMeter& peak_meter() { return *_meter; }
+ const Panner& panner() const { return *_panner; }
+
+ int ensure_io (ChanCount in, ChanCount out, bool clear, void *src);
+
+ int connect_input_ports_to_bundle (boost::shared_ptr<Bundle>, void *src);
+ int connect_output_ports_to_bundle (boost::shared_ptr<Bundle>, void *src);
+
+ std::vector<boost::shared_ptr<Bundle> > bundles_connected_to_inputs ();
+ std::vector<boost::shared_ptr<Bundle> > bundles_connected_to_outputs ();
+
+ boost::shared_ptr<AutoBundle> bundle_for_inputs () { return _bundle_for_inputs; }
+ boost::shared_ptr<AutoBundle> bundle_for_outputs () { return _bundle_for_outputs; }
+
+ int add_input_port (string source, void *src, DataType type = DataType::NIL);
+ int add_output_port (string destination, void *src, DataType type = DataType::NIL);
+
+ 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);
+
+ nframes_t signal_latency() const { return _own_latency; }
+ nframes_t output_latency() const;
+ nframes_t input_latency() const;
+ void set_port_latency (nframes_t);
+
+ void update_port_total_latencies ();
+
+ const PortSet& inputs() const { return _inputs; }
+ const PortSet& outputs() const { return _outputs; }
+
+ Port *output (uint32_t n) const {
+ if (n < _outputs.num_ports()) {
+ return _outputs.port(n);
+ } else {
+ return 0;
+ }
+ }
+
+ Port *input (uint32_t n) const {
+ if (n < _inputs.num_ports()) {
+ return _inputs.port(n);
+ } else {
+ return 0;
+ }
+ }
+
+ AudioPort* audio_input(uint32_t n) const;
+ AudioPort* audio_output(uint32_t n) const;
+ MidiPort* midi_input(uint32_t n) const;
+ MidiPort* midi_output(uint32_t n) const;
+
+ const ChanCount& n_inputs () const { return _inputs.count(); }
+ const ChanCount& n_outputs () const { return _outputs.count(); }
+
+ void attach_buffers(ChanCount ignored);
+
+ sigc::signal<void> active_changed;
+
+ sigc::signal<void,IOChange,void*> input_changed;
+ sigc::signal<void,IOChange,void*> output_changed;
+
+ virtual XMLNode& state (bool full);
+ XMLNode& get_state (void);
+ int set_state (const XMLNode&);
+
+ 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;
+ /// raised when the number of input or output ports changes
+ static sigc::signal<void,ChanCount> PortCountChanged;
+ static sigc::signal<int> PortsCreated;
+
+ static void update_meters();
+
+ private:
+
+ static sigc::signal<void> Meter;
+ static Glib::StaticMutex m_meter_signal_lock;
+ sigc::connection m_meter_connection;
+
+ public:
+
+ /* automation */
+
+ struct GainControl : public AutomationControl {
+ GainControl (std::string name, IO& i, boost::shared_ptr<AutomationList> al)
+ : AutomationControl (i._session, al, name)
+ , _io (i)
+ {}
+
+ void set_value (float val);
+ float get_value (void) const;
+
+ IO& _io;
+ };
+
+ boost::shared_ptr<GainControl> gain_control() {
+ return _gain_control;
+ }
+ boost::shared_ptr<const GainControl> gain_control() const {
+ return _gain_control;
+ }
+
+ void clear_automation ();
+
+ void set_parameter_automation_state (Parameter, AutoState);
+
+ virtual void transport_stopped (nframes_t now);
+ virtual void automation_snapshot (nframes_t now, bool force);
+
+ void start_pan_touch (uint32_t which);
+ void end_pan_touch (uint32_t which);
+
+ 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 Glib::Mutex io_lock;
+
+ protected:
+ Panner* _panner;
+ BufferSet* _output_buffers; //< Set directly to output port buffers
+ bool _active;
+ gain_t _gain;
+ gain_t _effective_gain;
+ gain_t _desired_gain;
+ Glib::Mutex declick_lock;
+ PortSet _outputs;
+ PortSet _inputs;
+ PeakMeter* _meter;
+ bool no_panner_reset;
+ bool _phase_invert;
+ bool _denormal_protection;
+ XMLNode* deferred_state;
+ DataType _default_type;
+ bool _public_ports;
+
+ virtual void set_deferred_state() {}
+
+ void reset_panner ();
+
+ virtual uint32_t pans_required() const
+ { return _inputs.count().n_audio(); }
+
+ boost::shared_ptr<GainControl> _gain_control;
+
+ virtual void set_gain (gain_t g, void *src);
+ void inc_gain (gain_t delta, void *src);
+
+ bool apply_gain_automation;
+
+ virtual int load_automation (std::string path);
+
+ /* 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;
+
+ BufferSet& output_buffers() { return *_output_buffers; }
+
+ private:
+
+ friend class Send;
+
+ 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;
+
+ ChanCount _input_minimum; ///< minimum number of input channels (0 for no minimum)
+ ChanCount _input_maximum; ///< maximum number of input channels (ChanCount::INFINITE for no maximum)
+ ChanCount _output_minimum; ///< minimum number of output channels (0 for no minimum)
+ ChanCount _output_maximum; ///< maximum number of output channels (ChanCount::INFINITE for no maximum)
+
+ boost::shared_ptr<AutoBundle> _bundle_for_inputs; ///< a bundle representing our inputs
+ boost::shared_ptr<AutoBundle> _bundle_for_outputs; ///< a bundle representing our outputs
+
+ struct UserBundleInfo {
+ UserBundleInfo (IO*, boost::shared_ptr<UserBundle> b);
+
+ boost::shared_ptr<UserBundle> bundle;
+ sigc::connection configuration_will_change;
+ sigc::connection configuration_has_changed;
+ sigc::connection ports_will_change;
+ sigc::connection ports_have_changed;
+ };
+
+ std::vector<UserBundleInfo> _bundles_connected_to_outputs; ///< user bundles connected to our outputs
+ std::vector<UserBundleInfo> _bundles_connected_to_inputs; ///< user bundles connected to our inputs
+
+ 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 (ChanCount, bool clear, bool lockit, void *src);
+ int ensure_outputs (ChanCount, bool clear, bool lockit, void *src);
+
+ void check_bundles_connected_to_inputs ();
+ void check_bundles_connected_to_outputs ();
+ void check_bundles (std::vector<UserBundleInfo>&, const PortSet&);
+
+ void bundle_configuration_will_change ();
+ void bundle_configuration_has_changed ();
+ void bundle_ports_will_change (int);
+ void bundle_ports_have_changed (int);
+
+ int create_ports (const XMLNode&);
+ int make_connections (const XMLNode&);
+
+ void setup_peak_meters ();
+ void meter ();
+
+ bool ensure_inputs_locked (ChanCount, bool clear, void *src);
+ bool ensure_outputs_locked (ChanCount, bool clear, void *src);
+
+ std::string build_legal_port_name (DataType type, bool for_input);
+ int32_t find_input_port_hole (const char* base);
+ int32_t find_output_port_hole (const char* base);
+
+ void create_bundles_for_inputs_and_outputs ();
+ void setup_bundles_for_inputs_and_outputs ();
+
+ void maybe_add_input_bundle_to_list (boost::shared_ptr<Bundle>, std::vector<boost::shared_ptr<Bundle> >*);
+ void maybe_add_output_bundle_to_list (boost::shared_ptr<Bundle>, std::vector<boost::shared_ptr<Bundle> >*);
+};
+
+} // namespace ARDOUR
+
+#endif /*__ardour_io_h__ */
diff --git a/libs/ardour/ardour/io_processor.h b/libs/ardour/ardour/io_processor.h
new file mode 100644
index 0000000000..a535ce3bb4
--- /dev/null
+++ b/libs/ardour/ardour/io_processor.h
@@ -0,0 +1,86 @@
+/*
+ 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.
+
+*/
+
+#ifndef __ardour_redirect_h__
+#define __ardour_redirect_h__
+
+#include <string>
+#include <vector>
+#include <set>
+#include <map>
+#include <boost/shared_ptr.hpp>
+#include <sigc++/signal.h>
+
+#include <glibmm/thread.h>
+
+#include <pbd/undo.h>
+
+#include <ardour/ardour.h>
+#include <ardour/processor.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;
+
+/** A mixer strip element (Processor) with Jack ports (IO).
+ */
+class IOProcessor : public Processor
+{
+ public:
+ IOProcessor (Session&, const string& name, Placement,
+ int input_min = -1, int input_max = -1, int output_min = -1, int output_max = -1);
+ IOProcessor (const IOProcessor&);
+ virtual ~IOProcessor ();
+
+ virtual ChanCount output_streams() const { return _io->n_outputs(); }
+ virtual ChanCount input_streams () const { return _io->n_inputs(); }
+ virtual ChanCount natural_output_streams() const { return _io->n_outputs(); }
+ virtual ChanCount natural_input_streams () const { return _io->n_inputs(); }
+
+ boost::shared_ptr<IO> io() { return _io; }
+ boost::shared_ptr<const IO> io() const { return _io; }
+
+ virtual void automation_snapshot (nframes_t now, bool force) { _io->automation_snapshot(now, force); }
+
+ virtual void run_in_place (BufferSet& in, nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset) = 0;
+
+ void silence (nframes_t nframes, nframes_t offset);
+
+ sigc::signal<void,IOProcessor*,bool> AutomationPlaybackChanged;
+ sigc::signal<void,IOProcessor*,uint32_t> AutomationChanged;
+
+ XMLNode& state (bool full_state);
+ int set_state (const XMLNode&);
+
+ protected:
+ boost::shared_ptr<IO> _io;
+};
+
+} // namespace ARDOUR
+
+#endif /* __ardour_redirect_h__ */
diff --git a/libs/ardour/ardour/jack_audio_port.h b/libs/ardour/ardour/jack_audio_port.h
new file mode 100644
index 0000000000..703fb81fa3
--- /dev/null
+++ b/libs/ardour/ardour/jack_audio_port.h
@@ -0,0 +1,51 @@
+/*
+ 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: port.h 712 2006-07-28 01:08:57Z drobilla $
+*/
+
+#ifndef __ardour_jack_audio_port_h__
+#define __ardour_jack_audio_port_h__
+
+#include <sigc++/signal.h>
+#include <pbd/failed_constructor.h>
+#include <ardour/ardour.h>
+#include <ardour/jack_port.h>
+#include <ardour/audio_port.h>
+
+namespace ARDOUR {
+
+class AudioEngine;
+class JackAudioPort : public JackPort, public BaseAudioPort {
+ public:
+ void cycle_start (nframes_t nframes, nframes_t offset) {
+ _buffer->set_data ((Sample*) jack_port_get_buffer (_port, nframes) + offset, nframes);
+ }
+
+ int reestablish ();
+
+ protected:
+ friend class AudioPort;
+
+ JackAudioPort (const std::string& name, Flags flags, AudioBuffer* buf);
+
+ AudioBuffer* _source_buffer;
+};
+
+} // namespace ARDOUR
+
+#endif /* __ardour_jack_audio_port_h__ */
diff --git a/libs/ardour/ardour/jack_midi_port.h b/libs/ardour/ardour/jack_midi_port.h
new file mode 100644
index 0000000000..d1fb5cc4fb
--- /dev/null
+++ b/libs/ardour/ardour/jack_midi_port.h
@@ -0,0 +1,52 @@
+/*
+ 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: port.h 712 2006-07-28 01:08:57Z drobilla $
+*/
+
+#ifndef __ardour_jack_midi_port_h__
+#define __ardour_jack_midi_port_h__
+
+#include <sigc++/signal.h>
+#include <pbd/failed_constructor.h>
+#include <ardour/ardour.h>
+#include <jack/jack.h>
+#include <jack/midiport.h>
+#include <ardour/port.h>
+#include <ardour/jack_port.h>
+#include <ardour/base_midi_port.h>
+#include <ardour/midi_buffer.h>
+
+namespace ARDOUR {
+
+class MidiEngine;
+
+class JackMidiPort : public JackPort, public BaseMidiPort {
+ public:
+ void cycle_start (nframes_t nframes, nframes_t offset);
+ void cycle_end (nframes_t nframes, nframes_t offset);
+ void set_buffer (MidiBuffer& buf);
+
+ protected:
+ friend class MidiPort;
+
+ JackMidiPort (const std::string&, Flags, MidiBuffer*);
+};
+
+} // namespace ARDOUR
+
+#endif /* __ardour_jack_midi_port_h__ */
diff --git a/libs/ardour/ardour/jack_port.h b/libs/ardour/ardour/jack_port.h
new file mode 100644
index 0000000000..3fa0008e17
--- /dev/null
+++ b/libs/ardour/ardour/jack_port.h
@@ -0,0 +1,112 @@
+/*
+ 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.
+
+*/
+
+#ifndef __ardour_jack_port_h__
+#define __ardour_jack_port_h__
+
+#include <sigc++/signal.h>
+#include <pbd/failed_constructor.h>
+#include <ardour/port.h>
+#include <jack/jack.h>
+
+namespace ARDOUR {
+
+class AudioEngine;
+class Buffer;
+
+/** Abstract class representing JACK ports
+ */
+class JackPort : public virtual Port, public PortConnectableByName {
+ public:
+
+ ~JackPort();
+
+ std::string short_name() const {
+ return jack_port_short_name (_port);
+ }
+
+ int set_name (const std::string& str);
+
+ bool connected () const {
+ return jack_port_connected (_port);
+ }
+
+ int reestablish ();
+ int reconnect ();
+
+ int connect (Port& other) {
+ return connect (other.name());
+ }
+
+ int disconnect (Port& other) {
+ return disconnect (other.name());
+ }
+
+ int disconnect_all ();
+
+ // connect-by-name API
+
+ int connect (const std::string& other_name);
+ int disconnect (const std::string& other_name);
+
+ bool connected_to (const std::string& portname) const {
+ return jack_port_connected_to (_port, portname.c_str());
+ }
+
+ int get_connections (std::vector<std::string>& names) const;
+
+ bool monitoring_input () const {
+ return jack_port_monitoring_input (_port);
+ }
+
+ void ensure_monitor_input (bool yn) {
+ jack_port_ensure_monitor (_port, yn);
+ }
+
+ /*XXX completely bloody useless imho*/
+ void request_monitor_input (bool yn) {
+ jack_port_request_monitor (_port, yn);
+ }
+
+ nframes_t latency () const {
+ return jack_port_get_latency (_port);
+ }
+
+ nframes_t total_latency() const;
+
+ void set_latency (nframes_t nframes) {
+ jack_port_set_latency (_port, nframes);
+ }
+
+
+ protected:
+ friend class AudioEngine;
+
+ JackPort (const std::string&, DataType type, Flags flags);
+ jack_port_t* _port;
+
+ int disconnect ();
+ void recompute_total_latency() const;
+
+ std::set<std::string> _named_connections;
+};
+
+} // namespace ARDOUR
+
+#endif /* __ardour_jack_port_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..b26e4120b1
--- /dev/null
+++ b/libs/ardour/ardour/ladspa_plugin.h
@@ -0,0 +1,147 @@
+/*
+ Copyright (C) 2000-2006 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_ladspa_plugin_h__
+#define __ardour_ladspa_plugin_h__
+
+#include <set>
+#include <vector>
+#include <string>
+#include <dlfcn.h>
+
+#include <sigc++/signal.h>
+
+#include <pbd/stateful.h>
+
+#include <jack/types.h>
+#include <ardour/ladspa.h>
+#include <ardour/plugin.h>
+
+namespace ARDOUR {
+class AudioEngine;
+class Session;
+
+class LadspaPlugin : public ARDOUR::Plugin
+{
+ public:
+ LadspaPlugin (void *module, ARDOUR::AudioEngine&, ARDOUR::Session&, uint32_t index, nframes_t sample_rate);
+ LadspaPlugin (const LadspaPlugin &);
+ ~LadspaPlugin ();
+
+ /* Plugin interface */
+
+ std::string unique_id() const;
+ 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);
+ nframes_t signal_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;
+ uint32_t nth_parameter (uint32_t port, bool& ok) const;
+
+ std::set<Parameter> automatable() const;
+
+ void activate () {
+ if (!_was_activated && _descriptor->activate)
+ _descriptor->activate (_handle);
+
+ _was_activated = true;
+ }
+
+ void deactivate () {
+ if (_was_activated && _descriptor->deactivate)
+ _descriptor->deactivate (_handle);
+
+ _was_activated = false;
+ }
+
+ void cleanup () {
+ activate();
+ deactivate();
+
+ if (_descriptor->cleanup)
+ _descriptor->cleanup (_handle);
+ }
+
+ void set_block_size (nframes_t nframes) {}
+
+ int connect_and_run (BufferSet& bufs, uint32_t& in, uint32_t& out, nframes_t nframes, nframes_t offset);
+ std::string describe_parameter (Parameter);
+ std::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(std::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;
+ 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, nframes_t rate);
+ void run_in_place (nframes_t nsamples);
+ void latency_compute_run ();
+};
+
+class LadspaPluginInfo : public PluginInfo {
+ public:
+ LadspaPluginInfo () { };
+ ~LadspaPluginInfo () { };
+
+ PluginPtr load (Session& session);
+};
+
+typedef boost::shared_ptr<LadspaPluginInfo> LadspaPluginInfoPtr;
+
+} // namespace ARDOUR
+
+#endif /* __ardour_ladspa_plugin_h__ */
diff --git a/libs/ardour/ardour/latent.h b/libs/ardour/ardour/latent.h
new file mode 100644
index 0000000000..11bdf11370
--- /dev/null
+++ b/libs/ardour/ardour/latent.h
@@ -0,0 +1,26 @@
+#ifndef __ardour_latent_h__
+#define __ardour_latent_h__
+
+#include <ardour/types.h>
+
+namespace ARDOUR {
+
+class Latent {
+ public:
+ Latent() : _own_latency (0), _user_latency (0) {}
+ virtual ~Latent() {}
+
+ virtual nframes_t signal_latency() const = 0;
+ nframes_t user_latency () const { return _user_latency; }
+
+ virtual void set_latency_delay (nframes_t val) { _own_latency = val; }
+ virtual void set_user_latency (nframes_t val) { _user_latency = val; }
+
+ protected:
+ nframes_t _own_latency;
+ nframes_t _user_latency;
+};
+
+}
+
+#endif /* __ardour_latent_h__*/
diff --git a/libs/ardour/ardour/location.h b/libs/ardour/ardour/location.h
new file mode 100644
index 0000000000..53d9489823
--- /dev/null
+++ b/libs/ardour/ardour/location.h
@@ -0,0 +1,206 @@
+/*
+ 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.
+
+*/
+
+#ifndef __ardour_location_h__
+#define __ardour_location_h__
+
+#include <string>
+#include <list>
+#include <iostream>
+#include <map>
+
+#include <sys/types.h>
+#include <sigc++/signal.h>
+
+#include <glibmm/thread.h>
+
+#include <pbd/undo.h>
+#include <pbd/stateful.h>
+#include <pbd/statefuldestructible.h>
+
+#include <ardour/ardour.h>
+
+using std::string;
+
+namespace ARDOUR {
+
+class Location : public PBD::StatefulDestructible
+{
+ public:
+ enum Flags {
+ IsMark = 0x1,
+ IsAutoPunch = 0x2,
+ IsAutoLoop = 0x4,
+ IsHidden = 0x8,
+ IsCDMarker = 0x10,
+ IsEnd = 0x20,
+ IsRangeMarker = 0x40,
+ IsStart = 0x80
+ };
+
+ Location (nframes_t sample_start,
+ nframes_t sample_end,
+ const string &name,
+ Flags bits = Flags(0))
+
+ : _name (name),
+ _start (sample_start),
+ _end (sample_end),
+ _flags (bits),
+ _locked (false) { }
+
+ Location () {
+ _start = 0;
+ _end = 0;
+ _flags = Flags (0);
+ _locked = false;
+ }
+
+ Location (const Location& other);
+ Location (const XMLNode&);
+ Location* operator= (const Location& other);
+
+ bool locked() const { return _locked; }
+ void lock() { _locked = true; changed (this); }
+ void unlock() { _locked = false; changed (this); }
+
+ nframes_t start() const { return _start; }
+ nframes_t end() const { return _end; }
+ nframes_t length() const { return _end - _start; }
+
+ int set_start (nframes_t s);
+ int set_end (nframes_t e);
+ int set (nframes_t start, nframes_t end);
+
+ int move_to (nframes_t pos);
+
+ 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);
+ void set_is_start (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; }
+ bool is_start() { return _flags & IsStart; }
+ bool is_range_marker() { return _flags & IsRangeMarker; }
+
+ 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;
+ nframes_t _start;
+ nframes_t _end;
+ Flags _flags;
+ bool _locked;
+
+ void set_mark (bool yn);
+ bool set_flag_internal (bool yn, Flags flag);
+};
+
+class Locations : public PBD::StatefulDestructible
+{
+ public:
+ typedef std::list<Location *> LocationList;
+
+ Locations ();
+ ~Locations ();
+
+ const LocationList& list() { return 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 *get_location_by_id(PBD::ID);
+
+ Location* auto_loop_location () const;
+ Location* auto_punch_location () const;
+ Location* end_location() const;
+ Location* start_location() const;
+
+ int next_available_name(string& result,string base);
+ uint32_t num_range_markers() const;
+
+ int set_current (Location *, bool want_lock = true);
+ Location *current () const { return current_location; }
+
+ Location *first_location_before (nframes_t, bool include_special_ranges = false);
+ Location *first_location_after (nframes_t, bool include_special_ranges = false);
+
+ nframes_t first_mark_before (nframes_t, bool include_special_ranges = false);
+ nframes_t first_mark_after (nframes_t, bool include_special_ranges = false);
+
+ sigc::signal<void,Location*> current_changed;
+ sigc::signal<void> changed;
+ sigc::signal<void,Location*> added;
+ sigc::signal<void,Location*> removed;
+ sigc::signal<void,Change> StateChanged;
+
+ template<class T> void apply (T& obj, void (T::*method)(LocationList&)) {
+ Glib::Mutex::Lock lm (lock);
+ (obj.*method)(locations);
+ }
+
+ template<class T1, class T2> void apply (T1& obj, void (T1::*method)(LocationList&, T2& arg), T2& arg) {
+ Glib::Mutex::Lock lm (lock);
+ (obj.*method)(locations, arg);
+ }
+
+ private:
+
+ LocationList locations;
+ Location *current_location;
+ mutable Glib::Mutex lock;
+
+ int set_current_unlocked (Location *);
+ void location_changed (Location*);
+};
+
+} // 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..dd58263313
--- /dev/null
+++ b/libs/ardour/ardour/logcurve.h
@@ -0,0 +1,132 @@
+/*
+ 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.
+
+*/
+
+#ifndef __ardour_logcurve_h__
+#define __ardour_logcurve_h__
+
+#include <pbd/fastlog.h>
+#include <glibmm/thread.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 Glib::Mutex 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/lv2_plugin.h b/libs/ardour/ardour/lv2_plugin.h
new file mode 100644
index 0000000000..d20ece65bd
--- /dev/null
+++ b/libs/ardour/ardour/lv2_plugin.h
@@ -0,0 +1,171 @@
+/*
+ Copyright (C) 2008 Paul Davis
+ Author: Dave Robillard
+
+ 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_lv2_plugin_h__
+#define __ardour_lv2_plugin_h__
+
+#include <set>
+#include <vector>
+#include <string>
+#include <dlfcn.h>
+
+#include <sigc++/signal.h>
+
+#include <pbd/stateful.h>
+
+#include <jack/types.h>
+#include <slv2/slv2.h>
+#include <ardour/plugin.h>
+
+namespace ARDOUR {
+class AudioEngine;
+class Session;
+struct LV2World;
+
+class LV2Plugin : public ARDOUR::Plugin
+{
+ public:
+ LV2Plugin (ARDOUR::AudioEngine&, ARDOUR::Session&, ARDOUR::LV2World&, SLV2Plugin plugin, nframes_t sample_rate);
+ LV2Plugin (const LV2Plugin &);
+ ~LV2Plugin ();
+
+ /* Plugin interface */
+
+ std::string unique_id() const;
+ const char* label() const { return slv2_value_as_string(_name); }
+ const char* name() const { return slv2_value_as_string(_name); }
+ const char* maker() const { return _author ? slv2_value_as_string(_author) : "Unknown"; }
+ uint32_t parameter_count() const { return slv2_plugin_get_num_ports(_plugin); }
+ float default_value (uint32_t port);
+ nframes_t signal_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;
+ uint32_t nth_parameter (uint32_t port, bool& ok) const;
+
+ SLV2Plugin slv2_plugin() { return _plugin; }
+ SLV2Port slv2_port(uint32_t i) { return slv2_plugin_get_port_by_index(_plugin, i); }
+
+ std::set<Parameter> automatable() const;
+
+ void activate () {
+ if (!_was_activated) {
+ slv2_instance_activate(_instance);
+ _was_activated = true;
+ }
+ }
+
+ void deactivate () {
+ if (_was_activated) {
+ slv2_instance_deactivate(_instance);
+ _was_activated = false;
+ }
+ }
+
+ void cleanup () {
+ activate();
+ deactivate();
+ slv2_instance_free(_instance);
+ _instance = NULL;
+ }
+
+ void set_block_size (nframes_t nframes) {}
+
+ int connect_and_run (BufferSet& bufs, uint32_t& in, uint32_t& out, nframes_t nframes, nframes_t offset);
+ std::string describe_parameter (Parameter);
+ std::string state_node_name() const { return "lv2"; }
+ 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_midi(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(std::string name);
+
+ bool has_editor() const { return false; }
+
+ int require_output_streams (uint32_t);
+
+ private:
+ void* _module;
+ LV2World& _world;
+ SLV2Plugin _plugin;
+ SLV2Value _name;
+ SLV2Value _author;
+ SLV2Instance _instance;
+ nframes_t _sample_rate;
+ float* _control_data;
+ float* _shadow_data;
+ float* _defaults;
+ float* _latency_control_port;
+ bool _was_activated;
+ vector<bool> _port_is_input;
+
+ void init (LV2World& world, SLV2Plugin plugin, nframes_t rate);
+ void run (nframes_t nsamples);
+ void latency_compute_run ();
+};
+
+
+/** The SLV2World, and various cached (as symbols, fast) URIs.
+ *
+ * This object represents everything ardour 'knows' about LV2
+ * (ie understood extensions/features/etc)
+ */
+struct LV2World {
+ LV2World();
+ ~LV2World();
+
+ SLV2World world;
+ SLV2Value input_class; ///< Input port
+ SLV2Value output_class; ///< Output port
+ SLV2Value audio_class; ///< Audio port
+ SLV2Value control_class; ///< Control port
+ SLV2Value event_class; ///< Event port
+ SLV2Value midi_class; ///< MIDI event
+ SLV2Value in_place_broken;
+ SLV2Value integer;
+ SLV2Value toggled;
+ SLV2Value srate;
+};
+
+
+class LV2PluginInfo : public PluginInfo {
+public:
+ LV2PluginInfo (void* slv2_world, void* slv2_plugin);;
+ ~LV2PluginInfo ();;
+ static PluginInfoList discover (void* slv2_world);
+
+ PluginPtr load (Session& session);
+
+ void* _lv2_world;
+ void* _slv2_plugin;
+};
+
+typedef boost::shared_ptr<LV2PluginInfo> LV2PluginInfoPtr;
+
+} // namespace ARDOUR
+
+#endif /* __ardour_lv2_plugin_h__ */
diff --git a/libs/ardour/ardour/meter.h b/libs/ardour/ardour/meter.h
new file mode 100644
index 0000000000..e19c0a51ca
--- /dev/null
+++ b/libs/ardour/ardour/meter.h
@@ -0,0 +1,77 @@
+/*
+ Copyright (C) 2006 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_meter_h__
+#define __ardour_meter_h__
+
+#include <vector>
+#include <ardour/types.h>
+#include <ardour/processor.h>
+#include <pbd/fastlog.h>
+
+namespace ARDOUR {
+
+class BufferSet;
+class ChanCount;
+class Session;
+
+
+/** Meters peaks on the input and stores them for access.
+ */
+class PeakMeter : public Processor {
+public:
+ PeakMeter(Session& s) : Processor(s, "meter", PreFader) {}
+
+ void reset ();
+ void reset_max ();
+
+ bool configure_io (ChanCount in, ChanCount out);
+
+ /** Compute peaks */
+ void run_in_place (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset);
+
+ float peak_power (uint32_t n) {
+ if (n < _visible_peak_power.size()) {
+ return _visible_peak_power[n];
+ } else {
+ return minus_infinity();
+ }
+ }
+
+ float max_peak_power (uint32_t n) {
+ if (n < _max_peak_power.size()) {
+ return _max_peak_power[n];
+ } else {
+ return minus_infinity();
+ }
+ }
+
+private:
+
+ friend class IO;
+ void meter();
+
+ std::vector<float> _peak_power;
+ std::vector<float> _visible_peak_power;
+ std::vector<float> _max_peak_power;
+};
+
+
+} // namespace ARDOUR
+
+#endif // __ardour_meter_h__
diff --git a/libs/ardour/ardour/midi_buffer.h b/libs/ardour/ardour/midi_buffer.h
new file mode 100644
index 0000000000..699f461b17
--- /dev/null
+++ b/libs/ardour/ardour/midi_buffer.h
@@ -0,0 +1,102 @@
+/*
+ Copyright (C) 2006 Paul Davis
+ Author: Dave Robillard
+
+ 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_midi_buffer_h__
+#define __ardour_midi_buffer_h__
+
+#include <midi++/event.h>
+#include <ardour/buffer.h>
+
+namespace ARDOUR {
+
+
+/** Buffer containing 8-bit unsigned char (MIDI) data. */
+class MidiBuffer : public Buffer
+{
+public:
+ MidiBuffer(size_t capacity);
+ ~MidiBuffer();
+
+ void silence(nframes_t dur, nframes_t offset=0);
+
+ void read_from(const Buffer& src, nframes_t nframes, nframes_t offset);
+
+ void copy(const MidiBuffer& copy);
+
+ bool push_back(const MIDI::Event& event);
+ bool push_back(const jack_midi_event_t& event);
+ uint8_t* reserve(double time, size_t size);
+
+ void resize(size_t);
+
+ bool merge(const MidiBuffer& a, const MidiBuffer& b);
+
+ struct iterator {
+ iterator(MidiBuffer& b, size_t i) : buffer(b), index(i) {}
+
+ inline MIDI::Event& operator*() const { return buffer[index]; }
+ inline iterator& operator++() { ++index; return *this; } // prefix
+ inline bool operator!=(const iterator& other) const { return index != other.index; }
+
+ MidiBuffer& buffer;
+ size_t index;
+ };
+
+ struct const_iterator {
+ const_iterator(const MidiBuffer& b, size_t i) : buffer(b), index(i) {}
+
+ inline const MIDI::Event& operator*() const { return buffer[index]; }
+ inline const_iterator& operator++() { ++index; return *this; } // prefix
+ inline bool operator!=(const const_iterator& other) const { return index != other.index; }
+
+ const MidiBuffer& buffer;
+ size_t index;
+ };
+
+ iterator begin() { return iterator(*this, 0); }
+ iterator end() { return iterator(*this, _size); }
+
+ const_iterator begin() const { return const_iterator(*this, 0); }
+ const_iterator end() const { return const_iterator(*this, _size); }
+
+private:
+
+ friend class iterator;
+ friend class const_iterator;
+
+ const MIDI::Event& operator[](size_t i) const { assert(i < _size); return _events[i]; }
+ MIDI::Event& operator[](size_t i) { assert(i < _size); return _events[i]; }
+
+ // FIXME: Eliminate this
+ static const size_t MAX_EVENT_SIZE = 4; // bytes
+
+ /* We use _size as "number of events", so the size of _data is
+ * (_size * MAX_EVENT_SIZE)
+ */
+
+ /* FIXME: this is utter crap. rewrite as a flat/packed buffer like MidiRingBuffer */
+
+ MIDI::Event* _events; ///< Event structs that point to offsets in _data
+ uint8_t* _data; ///< MIDI, straight up. No time stamps.
+};
+
+
+} // namespace ARDOUR
+
+#endif // __ardour_midi_buffer_h__
diff --git a/libs/ardour/ardour/midi_diskstream.h b/libs/ardour/ardour/midi_diskstream.h
new file mode 100644
index 0000000000..28e80816a8
--- /dev/null
+++ b/libs/ardour/ardour/midi_diskstream.h
@@ -0,0 +1,184 @@
+/*
+ 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: diskstream.h 579 2006-06-12 19:56:37Z essej $
+*/
+
+#ifndef __ardour_midi_diskstream_h__
+#define __ardour_midi_diskstream_h__
+
+#include <sigc++/signal.h>
+
+#include <cmath>
+#include <cassert>
+#include <string>
+#include <queue>
+#include <map>
+#include <vector>
+
+#include <time.h>
+
+#include <pbd/fastlog.h>
+#include <pbd/ringbufferNPT.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/diskstream.h>
+#include <ardour/midi_playlist.h>
+#include <ardour/midi_ring_buffer.h>
+
+struct tm;
+
+namespace ARDOUR {
+
+class MidiEngine;
+class Send;
+class Session;
+class MidiPlaylist;
+class SMFSource;
+class IO;
+
+class MidiDiskstream : public Diskstream
+{
+ public:
+ MidiDiskstream (Session &, const string& name, Diskstream::Flag f = Recordable);
+ MidiDiskstream (Session &, const XMLNode&);
+ ~MidiDiskstream();
+
+ float playback_buffer_load() const;
+ float capture_buffer_load() const;
+
+ void get_playback(MidiBuffer& dst, nframes_t start, nframes_t end);
+
+ void set_record_enabled (bool yn);
+
+ boost::shared_ptr<MidiPlaylist> midi_playlist () { return boost::dynamic_pointer_cast<MidiPlaylist>(_playlist); }
+
+ int use_playlist (boost::shared_ptr<Playlist>);
+ int use_new_playlist ();
+ int use_copy_playlist ();
+
+ /* stateful */
+ XMLNode& get_state(void);
+ int set_state(const XMLNode& node);
+
+ void monitor_input (bool);
+
+ boost::shared_ptr<SMFSource> write_source () { return _write_source; }
+
+ int set_destructive (bool yn); // doom!
+
+ void set_note_mode (NoteMode m);
+
+ uint16_t get_channel_mask() {
+ uint16_t playback_mask = _playback_buf->get_channel_mask();
+#ifndef NDEBUG
+ uint16_t capture_mask = _capture_buf->get_channel_mask();
+ assert(playback_mask == capture_mask);
+#endif
+ return playback_mask;
+ }
+
+ void set_channel_mode(ChannelMode mode, uint16_t mask) {
+ _playback_buf->set_channel_mode(mode, mask);
+ _capture_buf->set_channel_mode(mode, mask);
+ }
+
+ ChannelMode get_channel_mode() {
+ ChannelMode playback_mode = _playback_buf->get_channel_mode();
+#ifndef NDEBUG
+ ChannelMode capture_mode = _capture_buf->get_channel_mode();
+ assert(playback_mode == capture_mode);
+#endif
+ return playback_mode;
+ }
+
+ 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 set_block_size (nframes_t);
+ int internal_playback_seek (nframes_t distance);
+ int can_internal_playback_seek (nframes_t distance);
+ int rename_write_sources ();
+ void reset_write_sources (bool, bool force = false);
+ void non_realtime_input_change ();
+ void non_realtime_locate (nframes_t location);
+
+ protected:
+ int seek (nframes_t which_sample, bool complete_refill = false);
+
+ protected:
+ friend class MidiTrack;
+
+ int process (nframes_t transport_frame, nframes_t nframes, nframes_t offset, bool can_record, bool rec_monitors_input);
+ bool commit (nframes_t nframes);
+
+ private:
+
+ /* The two central butler operations */
+ int do_flush (Session::RunContext context, bool force = false);
+ int do_refill ();
+
+ int do_refill_with_alloc();
+
+ int read (nframes_t& start, nframes_t cnt, bool reversed);
+
+ void finish_capture (bool rec_monitors_input);
+ void transport_stopped (struct tm&, time_t, bool abort);
+ void transport_looped (nframes_t transport_frame);
+
+ void init (Diskstream::Flag);
+
+ int use_new_write_source (uint32_t n=0);
+
+ int find_and_use_playlist (const string&);
+
+ void allocate_temporary_buffers ();
+
+ int use_pending_capture_data (XMLNode& node);
+
+ void get_input_sources ();
+ void check_record_status (nframes_t transport_frame, nframes_t nframes, bool can_record);
+ void set_align_style_from_io();
+
+ void engage_record_enable ();
+ void disengage_record_enable ();
+
+ MidiRingBuffer* _playback_buf;
+ MidiRingBuffer* _capture_buf;
+ MidiPort* _source_port;
+ boost::shared_ptr<SMFSource> _write_source;
+ nframes_t _last_flush_frame;
+ NoteMode _note_mode;
+};
+
+}; /* namespace ARDOUR */
+
+#endif /* __ardour_midi_diskstream_h__ */
diff --git a/libs/ardour/ardour/midi_model.h b/libs/ardour/ardour/midi_model.h
new file mode 100644
index 0000000000..2481aa8d34
--- /dev/null
+++ b/libs/ardour/ardour/midi_model.h
@@ -0,0 +1,252 @@
+/*
+ Copyright (C) 2007 Paul Davis
+ Author: Dave Robillard
+
+ 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_midi_model_h__
+#define __ardour_midi_model_h__
+
+#include <queue>
+#include <deque>
+#include <utility>
+#include <boost/utility.hpp>
+#include <glibmm/thread.h>
+#include <pbd/command.h>
+#include <ardour/types.h>
+#include <ardour/midi_buffer.h>
+#include <ardour/midi_ring_buffer.h>
+#include <ardour/automatable.h>
+#include <ardour/note.h>
+#include <ardour/types.h>
+
+namespace ARDOUR {
+
+class Session;
+class MidiSource;
+
+/**
+ * This class keeps track of the current x and y for a control
+ */
+class MidiControlIterator {
+public:
+ boost::shared_ptr<const AutomationList> automation_list;
+ double x;
+ double y;
+
+ MidiControlIterator(boost::shared_ptr<const AutomationList> a_list,
+ double a_x,
+ double a_y)
+ : automation_list(a_list)
+ , x(a_x)
+ , y(a_y)
+ {}
+};
+
+
+/** This is a higher level (than MidiBuffer) model of MIDI data, with separate
+ * representations for notes (instead of just unassociated note on/off events)
+ * and controller data. Controller data is represented as part of the
+ * Automatable base (i.e. in a map of AutomationList, keyed by Parameter).
+ */
+class MidiModel : public boost::noncopyable, public Automatable {
+public:
+ MidiModel(MidiSource* s, size_t size=0);
+
+ void write_lock();
+ void write_unlock();
+
+ void read_lock() const;
+ void read_unlock() const;
+
+ void clear();
+
+ NoteMode note_mode() const { return _note_mode; }
+ void set_note_mode(NoteMode mode) { _note_mode = mode; }
+
+ void start_write();
+ bool writing() const { return _writing; }
+ void end_write(bool delete_stuck=false);
+
+ size_t read (MidiRingBuffer& dst, nframes_t start, nframes_t nframes, nframes_t stamp_offset, nframes_t negative_stamp_offset) const;
+
+ /** Resizes vector if necessary (NOT realtime safe) */
+ void append(const MIDI::Event& ev);
+
+ inline const boost::shared_ptr<const Note> note_at(unsigned i) const { return _notes[i]; }
+ inline const boost::shared_ptr<Note> note_at(unsigned i) { return _notes[i]; }
+
+ inline size_t n_notes() const { return _notes.size(); }
+ inline bool empty() const { return _notes.size() == 0 && _controls.size() == 0; }
+
+ inline static bool note_time_comparator (const boost::shared_ptr<const Note> a,
+ const boost::shared_ptr<const Note> b) {
+ return a->time() < b->time();
+ }
+
+ struct LaterNoteEndComparator {
+ typedef const Note* value_type;
+ inline bool operator()(const boost::shared_ptr<const Note> a,
+ const boost::shared_ptr<const Note> b) const {
+ return a->end_time() > b->end_time();
+ }
+ };
+
+ typedef std::vector< boost::shared_ptr<Note> > Notes;
+ inline Notes& notes() { return _notes; }
+ inline const Notes& notes() const { return _notes; }
+
+ /** Add/Remove notes.
+ * Technically all operations can be implemented as one of these.
+ */
+ class DeltaCommand : public Command
+ {
+ public:
+ DeltaCommand (boost::shared_ptr<MidiModel> m, const std::string& name);
+ DeltaCommand (boost::shared_ptr<MidiModel>, const XMLNode& node);
+
+ const std::string& name() const { return _name; }
+
+ void operator()();
+ void undo();
+
+ int set_state (const XMLNode&);
+ XMLNode& get_state ();
+
+ void add(const boost::shared_ptr<Note> note);
+ void remove(const boost::shared_ptr<Note> note);
+
+ private:
+ XMLNode &marshal_note(const boost::shared_ptr<Note> note);
+ boost::shared_ptr<Note> unmarshal_note(XMLNode *xml_note);
+
+ boost::shared_ptr<MidiModel> _model;
+ const std::string _name;
+
+ typedef std::list< boost::shared_ptr<Note> > NoteList;
+
+ NoteList _added_notes;
+ NoteList _removed_notes;
+ };
+
+ MidiModel::DeltaCommand* new_delta_command(const std::string name="midi edit");
+ void apply_command(Command* cmd);
+
+ bool edited() const { return _edited; }
+ void set_edited(bool yn) { _edited = yn; }
+ bool write_to(boost::shared_ptr<MidiSource> source);
+
+ // MidiModel doesn't use the normal AutomationList serialisation code
+ // since controller data is stored in the .mid
+ XMLNode& get_state();
+ int set_state(const XMLNode&) { return 0; }
+
+ sigc::signal<void> ContentsChanged;
+
+ /** Read iterator */
+ class const_iterator {
+ public:
+ const_iterator(const MidiModel& model, double t);
+ ~const_iterator();
+
+ inline bool locked() const { return _locked; }
+
+ const MIDI::Event& operator*() const { return *_event; }
+ const boost::shared_ptr<MIDI::Event> operator->() const { return _event; }
+ const boost::shared_ptr<MIDI::Event> get_event_pointer() { return _event; }
+
+ const const_iterator& operator++(); // prefix only
+ bool operator==(const const_iterator& other) const;
+ bool operator!=(const const_iterator& other) const { return ! operator==(other); }
+
+ const_iterator& operator=(const const_iterator& other);
+
+ private:
+ friend class MidiModel;
+
+ const MidiModel* _model;
+ boost::shared_ptr<MIDI::Event> _event;
+
+ typedef std::priority_queue<
+ boost::shared_ptr<Note>, std::deque< boost::shared_ptr<Note> >,
+ LaterNoteEndComparator>
+ ActiveNotes;
+
+ mutable ActiveNotes _active_notes;
+
+ bool _is_end;
+ bool _locked;
+ Notes::const_iterator _note_iter;
+ std::vector<MidiControlIterator> _control_iters;
+ std::vector<MidiControlIterator>::iterator _control_iter;
+ };
+
+ const_iterator begin() const { return const_iterator(*this, 0); }
+ const const_iterator& end() const { return _end_iter; }
+
+ const MidiSource* midi_source() const { return _midi_source; }
+ void set_midi_source(MidiSource* source) { _midi_source = source; }
+ bool control_to_midi_event(boost::shared_ptr<MIDI::Event>& ev, const MidiControlIterator& iter) const;
+
+private:
+ friend class DeltaCommand;
+ void add_note_unlocked(const boost::shared_ptr<Note> note);
+ void remove_note_unlocked(const boost::shared_ptr<const Note> note);
+
+ friend class const_iterator;
+
+#ifndef NDEBUG
+ bool is_sorted() const;
+#endif
+
+ void append_note_on_unlocked(uint8_t chan, double time, uint8_t note, uint8_t velocity);
+ void append_note_off_unlocked(uint8_t chan, double time, uint8_t note);
+ void append_automation_event_unlocked(AutomationType type, uint8_t chan, double time, uint8_t first_byte, uint8_t second_byte);
+ void append_pgm_change_unlocked(uint8_t chan, double time, uint8_t number);
+
+ mutable Glib::RWLock _lock;
+
+ Notes _notes;
+
+ NoteMode _note_mode;
+
+ typedef std::vector<size_t> WriteNotes;
+ WriteNotes _write_notes[16];
+ bool _writing;
+ bool _edited;
+
+ typedef std::vector< boost::shared_ptr<const ARDOUR::AutomationList> > AutomationLists;
+ AutomationLists _dirty_automations;
+
+ const const_iterator _end_iter;
+
+ mutable nframes_t _next_read;
+ mutable const_iterator _read_iter;
+
+ typedef std::priority_queue<
+ boost::shared_ptr<Note>, std::deque< boost::shared_ptr<Note> >,
+ LaterNoteEndComparator>
+ ActiveNotes;
+
+ // We cannot use a boost::shared_ptr here to avoid a retain cycle
+ MidiSource* _midi_source;
+};
+
+} /* namespace ARDOUR */
+
+#endif /* __ardour_midi_model_h__ */
+
diff --git a/libs/ardour/ardour/midi_playlist.h b/libs/ardour/ardour/midi_playlist.h
new file mode 100644
index 0000000000..dcc202bbf4
--- /dev/null
+++ b/libs/ardour/ardour/midi_playlist.h
@@ -0,0 +1,84 @@
+/*
+ Copyright (C) 2006 Paul Davis
+ Written by Dave Robillard, 2006
+
+ 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_midi_playlist_h__
+#define __ardour_midi_playlist_h__
+
+#include <vector>
+#include <list>
+
+#include <ardour/ardour.h>
+#include <ardour/playlist.h>
+#include <ardour/parameter.h>
+
+namespace ARDOUR
+{
+
+class Session;
+class Region;
+class MidiRegion;
+class Source;
+class MidiRingBuffer;
+
+class MidiPlaylist : public ARDOUR::Playlist
+{
+public:
+ MidiPlaylist (Session&, const XMLNode&, bool hidden = false);
+ MidiPlaylist (Session&, string name, bool hidden = false);
+ MidiPlaylist (boost::shared_ptr<const MidiPlaylist> other, string name, bool hidden = false);
+ MidiPlaylist (boost::shared_ptr<const MidiPlaylist> other, nframes_t start, nframes_t cnt,
+ string name, bool hidden = false);
+
+ ~MidiPlaylist ();
+
+ nframes_t read (MidiRingBuffer& buf,
+ nframes_t start, nframes_t cnt, uint32_t chan_n=0);
+
+ int set_state (const XMLNode&);
+ UndoAction get_memento() const;
+
+ bool destroy_region (boost::shared_ptr<Region>);
+
+ void set_note_mode (NoteMode m) { _note_mode = m; }
+
+ std::set<Parameter> contained_automation();
+
+protected:
+
+ /* playlist "callbacks" */
+
+ void finalize_split_region (boost::shared_ptr<Region> original, boost::shared_ptr<Region> left, boost::shared_ptr<Region> right);
+
+ void check_dependents (boost::shared_ptr<Region> region, bool norefresh);
+ void refresh_dependents (boost::shared_ptr<Region> region);
+ void remove_dependents (boost::shared_ptr<Region> region);
+
+private:
+ void dump () const;
+
+ bool region_changed (Change, boost::shared_ptr<Region>);
+
+ NoteMode _note_mode;
+};
+
+} /* namespace ARDOUR */
+
+#endif /* __ardour_midi_playlist_h__ */
+
+
diff --git a/libs/ardour/ardour/midi_port.h b/libs/ardour/ardour/midi_port.h
new file mode 100644
index 0000000000..485834aaff
--- /dev/null
+++ b/libs/ardour/ardour/midi_port.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: port.h 712 2006-07-28 01:08:57Z drobilla $
+*/
+
+#ifndef __ardour_midi_port_h__
+#define __ardour_midi_port_h__
+
+#include <ardour/base_midi_port.h>
+
+namespace ARDOUR {
+
+class MidiEngine;
+
+class MidiPort : public BaseMidiPort, public PortFacade {
+ public:
+ ~MidiPort();
+
+ void reset ();
+
+ void cycle_start (nframes_t nframes, nframes_t offset);
+ void cycle_end (nframes_t nframes, nframes_t offset);
+
+ protected:
+ friend class AudioEngine;
+
+ MidiPort (const std::string& name, Flags, bool external, nframes_t bufsize);
+};
+
+} // namespace ARDOUR
+
+#endif /* __ardour_midi_port_h__ */
diff --git a/libs/ardour/ardour/midi_region.h b/libs/ardour/ardour/midi_region.h
new file mode 100644
index 0000000000..cd2b0d6132
--- /dev/null
+++ b/libs/ardour/ardour/midi_region.h
@@ -0,0 +1,121 @@
+/*
+ Copyright (C) 2000-2006 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: midiregion.h 733 2006-08-01 17:19:38Z drobilla $
+*/
+
+#ifndef __ardour_midi_region_h__
+#define __ardour_midi_region_h__
+
+#include <vector>
+
+#include <pbd/fastlog.h>
+#include <pbd/undo.h>
+
+#include <ardour/ardour.h>
+#include <ardour/region.h>
+#include <ardour/gain.h>
+#include <ardour/logcurve.h>
+#include <ardour/export.h>
+#include <ardour/midi_source.h>
+
+class XMLNode;
+
+namespace ARDOUR {
+
+class Route;
+class Playlist;
+class Session;
+class MidiFilter;
+class MidiSource;
+class MidiRingBuffer;
+
+class MidiRegion : public Region
+{
+ public:
+ ~MidiRegion();
+
+ boost::shared_ptr<MidiSource> midi_source (uint32_t n=0) const;
+
+ /* Stub Readable interface */
+ virtual nframes64_t read (Sample*, nframes64_t pos, nframes64_t cnt, int channel) const { return 0; }
+ virtual nframes64_t readable_length() const { return length(); }
+
+ nframes_t read_at (MidiRingBuffer& dst,
+ nframes_t position,
+ nframes_t dur,
+ uint32_t chan_n = 0,
+ NoteMode mode = Sustained) const;
+
+ nframes_t master_read_at (MidiRingBuffer& dst,
+ nframes_t position,
+ nframes_t dur,
+ uint32_t chan_n = 0,
+ NoteMode mode = Sustained) const;
+
+ XMLNode& state (bool);
+ int set_state (const XMLNode&);
+
+ int separate_by_channel (ARDOUR::Session&, vector<MidiRegion*>&) const;
+
+ UndoAction get_memento() const;
+
+ // Act as a proxy for MidiModel automation stuff (for CC)
+ // Yep, this is pretty ugly...
+ Controls& controls() { return midi_source()->model()->controls(); }
+ const Controls& controls() const { return midi_source()->model()->controls(); }
+
+ boost::shared_ptr<AutomationControl> control(Parameter id, bool create_if_missing=false)
+ { return midi_source()->model()->control(id, create_if_missing); }
+
+ boost::shared_ptr<const AutomationControl> control(Parameter id) const
+ { return midi_source()->model()->control(id); }
+
+ int exportme (ARDOUR::Session&, ARDOUR::ExportSpecification&);
+
+ private:
+ friend class RegionFactory;
+
+ MidiRegion (boost::shared_ptr<MidiSource>, nframes_t start, nframes_t length);
+ MidiRegion (boost::shared_ptr<MidiSource>, nframes_t start, nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags);
+ MidiRegion (const SourceList &, nframes_t start, nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags);
+ MidiRegion (boost::shared_ptr<const MidiRegion>, nframes_t start, nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags);
+ MidiRegion (boost::shared_ptr<const MidiRegion>);
+ MidiRegion (boost::shared_ptr<MidiSource>, const XMLNode&);
+ MidiRegion (const SourceList &, const XMLNode&);
+
+ private:
+ nframes_t _read_at (const SourceList&, MidiRingBuffer& dst,
+ nframes_t position,
+ nframes_t dur,
+ uint32_t chan_n = 0,
+ NoteMode mode = Sustained) const;
+
+ void recompute_at_start ();
+ void recompute_at_end ();
+
+ void switch_source(boost::shared_ptr<Source> source);
+
+ protected:
+
+ int set_live_state (const XMLNode&, Change&, bool send);
+};
+
+} /* namespace ARDOUR */
+
+
+#endif /* __ardour_midi_region_h__ */
diff --git a/libs/ardour/ardour/midi_ring_buffer.h b/libs/ardour/ardour/midi_ring_buffer.h
new file mode 100644
index 0000000000..ff0be5c997
--- /dev/null
+++ b/libs/ardour/ardour/midi_ring_buffer.h
@@ -0,0 +1,466 @@
+/*
+ Copyright (C) 2006 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_midi_ring_buffer_h__
+#define __ardour_midi_ring_buffer_h__
+
+#include <iostream>
+#include <algorithm>
+#include <ardour/types.h>
+#include <ardour/buffer.h>
+
+namespace ARDOUR {
+
+
+/* FIXME: this is probably too much inlined code */
+
+
+/** A RingBuffer.
+ * Read/Write realtime safe.
+ * Single-reader Single-writer thread safe.
+ *
+ * This is Raul::RingBuffer, lifted for MIDIRingBuffer to inherit from as it works
+ * a bit differently than PBD::Ringbuffer. This could/should be replaced with
+ * the PBD ringbuffer to decrease code size, but this code is tested and known to
+ * work, so here it sits for now...
+ *
+ * Ignore this class, use MidiRingBuffer.
+ */
+template <typename T>
+class MidiRingBufferBase {
+public:
+
+ /** @param size Size in bytes.
+ */
+ MidiRingBufferBase(size_t size)
+ : _size(size)
+ , _buf(new T[size])
+ {
+ reset();
+ assert(read_space() == 0);
+ assert(write_space() == size - 1);
+ }
+
+ virtual ~MidiRingBufferBase() {
+ delete[] _buf;
+ }
+
+ /** Reset(empty) the ringbuffer.
+ * NOT thread safe.
+ */
+ void reset() {
+ g_atomic_int_set(&_write_ptr, 0);
+ g_atomic_int_set(&_read_ptr, 0);
+ }
+
+ size_t write_space() const {
+
+ const size_t w = g_atomic_int_get(&_write_ptr);
+ const size_t r = g_atomic_int_get(&_read_ptr);
+
+ if (w > r) {
+ return ((r - w + _size) % _size) - 1;
+ } else if (w < r) {
+ return (r - w) - 1;
+ } else {
+ return _size - 1;
+ }
+ }
+
+ size_t read_space() const {
+
+ const size_t w = g_atomic_int_get(&_write_ptr);
+ const size_t r = g_atomic_int_get(&_read_ptr);
+
+ if (w > r) {
+ return w - r;
+ } else {
+ return (w - r + _size) % _size;
+ }
+ }
+
+ size_t capacity() const { return _size; }
+
+ size_t peek(size_t size, T* dst);
+ bool full_peek(size_t size, T* dst);
+
+ size_t read(size_t size, T* dst);
+ bool full_read(size_t size, T* dst);
+
+ bool skip(size_t size);
+
+ void write(size_t size, const T* src);
+
+protected:
+ mutable int _write_ptr;
+ mutable int _read_ptr;
+
+ size_t _size; ///< Size (capacity) in bytes
+ T* _buf; ///< size, event, size, event...
+};
+
+
+/** Peek at the ringbuffer (read w/o advancing read pointer).
+ *
+ * Note that a full read may not be done if the data wraps around.
+ * Caller must check return value and call again if necessary, or use the
+ * full_peek method which does this automatically.
+ */
+template<typename T>
+size_t
+MidiRingBufferBase<T>::peek(size_t size, T* dst)
+{
+ const size_t priv_read_ptr = g_atomic_int_get(&_read_ptr);
+
+ const size_t read_size = (priv_read_ptr + size < _size)
+ ? size
+ : _size - priv_read_ptr;
+
+ memcpy(dst, &_buf[priv_read_ptr], read_size);
+
+ return read_size;
+}
+
+
+template<typename T>
+bool
+MidiRingBufferBase<T>::full_peek(size_t size, T* dst)
+{
+ if (read_space() < size) {
+ return false;
+ }
+
+ const size_t read_size = peek(size, dst);
+
+ if (read_size < size) {
+ peek(size - read_size, dst + read_size);
+ }
+
+ return true;
+}
+
+
+/** Read from the ringbuffer.
+ *
+ * Note that a full read may not be done if the data wraps around.
+ * Caller must check return value and call again if necessary, or use the
+ * full_read method which does this automatically.
+ */
+template<typename T>
+size_t
+MidiRingBufferBase<T>::read(size_t size, T* dst)
+{
+ const size_t priv_read_ptr = g_atomic_int_get(&_read_ptr);
+
+ const size_t read_size = (priv_read_ptr + size < _size)
+ ? size
+ : _size - priv_read_ptr;
+
+ memcpy(dst, &_buf[priv_read_ptr], read_size);
+
+ g_atomic_int_set(&_read_ptr, (priv_read_ptr + read_size) % _size);
+
+ return read_size;
+}
+
+
+template<typename T>
+bool
+MidiRingBufferBase<T>::full_read(size_t size, T* dst)
+{
+ if (read_space() < size) {
+ return false;
+ }
+
+ const size_t read_size = read(size, dst);
+
+ if (read_size < size) {
+ read(size - read_size, dst + read_size);
+ }
+
+ return true;
+}
+
+
+template<typename T>
+bool
+MidiRingBufferBase<T>::skip(size_t size)
+{
+ if (read_space() < size) {
+ std::cerr << "WARNING: Attempt to skip past end of MIDI ring buffer" << std::endl;
+ return false;
+ }
+
+ const size_t priv_read_ptr = g_atomic_int_get(&_read_ptr);
+ g_atomic_int_set(&_read_ptr, (priv_read_ptr + size) % _size);
+
+ return true;
+}
+
+
+template<typename T>
+inline void
+MidiRingBufferBase<T>::write(size_t size, const T* src)
+{
+ const size_t priv_write_ptr = g_atomic_int_get(&_write_ptr);
+
+ if (priv_write_ptr + size <= _size) {
+ memcpy(&_buf[priv_write_ptr], src, size);
+ g_atomic_int_set(&_write_ptr, (priv_write_ptr + size) % _size);
+ } else {
+ const size_t this_size = _size - priv_write_ptr;
+ assert(this_size < size);
+ assert(priv_write_ptr + this_size <= _size);
+ memcpy(&_buf[priv_write_ptr], src, this_size);
+ memcpy(&_buf[0], src+this_size, size - this_size);
+ g_atomic_int_set(&_write_ptr, size - this_size);
+ }
+}
+
+
+/* ******************************************************************** */
+
+
+/** A MIDI RingBuffer.
+ *
+ * This is timestamps and MIDI packed sequentially into a single buffer, similarly
+ * to LV2 MIDI. The buffer looks like this:
+ *
+ * [timestamp][size][size bytes of raw MIDI][timestamp][size][etc..]
+ */
+class MidiRingBuffer : public MidiRingBufferBase<uint8_t> {
+public:
+ /** @param size Size in bytes.
+ */
+ MidiRingBuffer(size_t size)
+ : MidiRingBufferBase<uint8_t>(size), _channel_mask(0x0000FFFF)
+ {}
+
+ size_t write(double time, size_t size, const uint8_t* buf);
+ bool read(double* time, size_t* size, uint8_t* buf);
+
+ bool read_prefix(double* time, size_t* size);
+ bool read_contents(size_t size, uint8_t* buf);
+
+ size_t read(MidiBuffer& dst, nframes_t start, nframes_t end, nframes_t offset=0);
+
+ /** Set the channel filtering mode.
+ * @param mask If mode is FilterChannels, each bit represents a midi channel:
+ * bit 0 = channel 0, bit 1 = channel 1 etc. the read and write methods will only
+ * process events whose channel bit is 1.
+ * If mode is ForceChannel, mask is simply a channel number which all events will
+ * be forced to while reading.
+ */
+ void set_channel_mode(ChannelMode mode, uint16_t mask) {
+ g_atomic_int_set(&_channel_mask, ((uint16_t)mode << 16) | mask);
+ }
+
+ ChannelMode get_channel_mode() const {
+ return static_cast<ChannelMode>((g_atomic_int_get(&_channel_mask) & 0xFFFF0000) >> 16);
+ }
+
+ uint16_t get_channel_mask() const {
+ return static_cast<ChannelMode>((g_atomic_int_get(&_channel_mask) & 0x0000FFFF));
+ }
+
+protected:
+ inline bool is_channel_event(uint8_t event_type_byte) {
+ // mask out channel information
+ event_type_byte &= 0xF0;
+ // midi channel events range from 0x80 to 0xE0
+ return (0x80 <= event_type_byte) && (event_type_byte <= 0xE0);
+ }
+
+private:
+ volatile uint32_t _channel_mask; // 16 bits mode, 16 bits mask
+};
+
+
+inline bool
+MidiRingBuffer::read(double* time, size_t* size, uint8_t* buf)
+{
+ bool success = MidiRingBufferBase<uint8_t>::full_read(sizeof(double), (uint8_t*)time);
+
+ if (success) {
+ success = MidiRingBufferBase<uint8_t>::full_read(sizeof(size_t), (uint8_t*)size);
+ }
+ if (success) {
+ success = MidiRingBufferBase<uint8_t>::full_read(*size, buf);
+ }
+
+ return success;
+}
+
+
+/** Read the time and size of an event. This call MUST be immediately proceeded
+ * by a call to read_contents (or the read pointer will be garabage).
+ */
+inline bool
+MidiRingBuffer::read_prefix(double* time, size_t* size)
+{
+ bool success = MidiRingBufferBase<uint8_t>::full_read(sizeof(double), (uint8_t*)time);
+ if (success) {
+ success = MidiRingBufferBase<uint8_t>::full_read(sizeof(size_t), (uint8_t*)size);
+ }
+
+ return success;
+}
+
+
+/** Read the contenst of an event. This call MUST be immediately preceeded
+ * by a call to read_prefix (or the returned even will be garabage).
+ */
+inline bool
+MidiRingBuffer::read_contents(size_t size, uint8_t* buf)
+{
+ return MidiRingBufferBase<uint8_t>::full_read(size, buf);
+}
+
+
+inline size_t
+MidiRingBuffer::write(double time, size_t size, const uint8_t* buf)
+{
+ /*fprintf(stderr, "MRB %p write (t = %f) ", this, time);
+ for (size_t i = 0; i < size; ++i)
+ fprintf(stderr, "%X", (char)buf[i]);
+ fprintf(stderr, "\n");*/
+
+ assert(size > 0);
+
+ // Don't write event if it doesn't match channel filter
+ if (is_channel_event(buf[0]) && get_channel_mode() == FilterChannels) {
+ uint8_t channel = buf[0] & 0x0F;
+ if ( !(get_channel_mask() & (1L << channel)) ) {
+ return 0;
+ }
+ }
+
+ if (write_space() < (sizeof(double) + sizeof(size_t) + size)) {
+ return 0;
+ } else {
+ MidiRingBufferBase<uint8_t>::write(sizeof(double), (uint8_t*)&time);
+ MidiRingBufferBase<uint8_t>::write(sizeof(size_t), (uint8_t*)&size);
+ if (is_channel_event(buf[0]) && get_channel_mode() == ForceChannel) {
+ assert(size == 2 || size == 3);
+ uint8_t tmp_buf[3];
+ // Force event to channel
+ tmp_buf[0] = (buf[0] & 0xF0) | (get_channel_mask() & 0x0F);
+ tmp_buf[1] = buf[1];
+ if (size == 3) {
+ tmp_buf[2] = buf[2];
+ }
+ MidiRingBufferBase<uint8_t>::write(size, tmp_buf);
+ } else {
+ MidiRingBufferBase<uint8_t>::write(size, buf);
+ }
+ return size;
+ }
+
+}
+
+
+/** Read a block of MIDI events from buffer.
+ *
+ * Timestamps of events returned are relative to start (ie event with stamp 0
+ * occurred at start), with offset added.
+ */
+inline size_t
+MidiRingBuffer::read(MidiBuffer& dst, nframes_t start, nframes_t end, nframes_t offset)
+{
+ if (read_space() == 0)
+ return 0;
+
+ double ev_time;
+ uint32_t ev_size;
+
+ size_t count = 0;
+
+ //printf("---- MRB read %u .. %u + %u\n", start, end, offset);
+
+ while (read_space() > sizeof(double) + sizeof(size_t)) {
+
+ full_peek(sizeof(double), (uint8_t*)&ev_time);
+
+ if (ev_time > end) {
+ break;
+ }
+
+ bool success = MidiRingBufferBase<uint8_t>::full_read(sizeof(double), (uint8_t*)&ev_time);
+ if (success) {
+ success = MidiRingBufferBase<uint8_t>::full_read(sizeof(size_t), (uint8_t*)&ev_size);
+ }
+
+ if (!success) {
+ std::cerr << "MRB: READ ERROR (time/size)" << std::endl;
+ continue;
+ }
+
+ uint8_t status;
+ success = full_peek(sizeof(uint8_t), &status);
+ assert(success); // If this failed, buffer is corrupt, all hope is lost
+
+ // Ignore event if it doesn't match channel filter
+ if (is_channel_event(status) && get_channel_mode() == FilterChannels) {
+ const uint8_t channel = status & 0x0F;
+ if ( !(get_channel_mask() & (1L << channel)) ) {
+ skip(ev_size); // Advance read pointer to next event
+ continue;
+ }
+ }
+
+ if (ev_time >= start) {
+
+ /*std::cerr << "MRB " << this << " - Reading event, time = "
+ << ev_time << " - " << start << " => " << ev_time - start
+ << ", size = " << ev_size << std::endl;*/
+
+ ev_time -= start;
+
+ uint8_t* write_loc = dst.reserve(ev_time, ev_size);
+ if (write_loc == NULL) {
+ std::cerr << "MRB: Unable to reserve space in buffer, event skipped";
+ continue;
+ }
+
+ success = MidiRingBufferBase<uint8_t>::full_read(ev_size, write_loc);
+
+ if (success) {
+ if (is_channel_event(status) && get_channel_mode() == ForceChannel) {
+ write_loc[0] = (write_loc[0] & 0xF0) | (get_channel_mask() & 0x0F);
+ }
+ ++count;
+ //printf("MRB - read event at time %lf\n", ev_time);
+ } else {
+ std::cerr << "MRB: READ ERROR (data)" << std::endl;
+ }
+
+ } else {
+ printf("MRB (start %u) - Skipping event at (too early) time %f\n", start, ev_time);
+ }
+ }
+
+ //printf("(R) read space: %zu\n", read_space());
+
+ return count;
+}
+
+
+} // namespace ARDOUR
+
+#endif // __ardour_midi_ring_buffer_h__
+
diff --git a/libs/ardour/ardour/midi_source.h b/libs/ardour/ardour/midi_source.h
new file mode 100644
index 0000000000..997f3f9d69
--- /dev/null
+++ b/libs/ardour/ardour/midi_source.h
@@ -0,0 +1,119 @@
+/*
+ Copyright (C) 2006 Paul Davis
+ Written by Dave Robillard, 2006
+
+ 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_midi_source_h__
+#define __ardour_midi_source_h__
+
+#include <string>
+
+#include <time.h>
+
+#include <glibmm/thread.h>
+
+#include <sigc++/signal.h>
+
+#include <ardour/source.h>
+#include <ardour/ardour.h>
+#include <ardour/buffer.h>
+#include <ardour/midi_model.h>
+#include <pbd/stateful.h>
+#include <pbd/xml++.h>
+
+using std::string;
+
+namespace ARDOUR {
+
+class MidiRingBuffer;
+
+/** Source for MIDI data */
+class MidiSource : public Source
+{
+ public:
+ MidiSource (Session& session, string name);
+ MidiSource (Session& session, const XMLNode&);
+ virtual ~MidiSource ();
+
+ /* Stub Readable interface */
+ virtual nframes64_t read (Sample*, nframes64_t pos, nframes64_t cnt, int channel) const { return 0; }
+ virtual nframes64_t readable_length() const { return length(); }
+ virtual uint32_t n_channels () const { return 1; }
+
+ // FIXME: integrate this with the Readable::read interface somehow
+ virtual nframes_t midi_read (MidiRingBuffer& dst, nframes_t start, nframes_t cnt, nframes_t stamp_offset, nframes_t negative_stamp_offset) const;
+ virtual nframes_t midi_write (MidiRingBuffer& src, nframes_t cnt);
+
+ virtual void append_event_unlocked(EventTimeUnit unit, const MIDI::Event& ev) = 0;
+
+ virtual void mark_for_remove() = 0;
+ virtual void mark_streaming_midi_write_started (NoteMode mode, nframes_t start_time);
+ virtual void mark_streaming_write_started ();
+ virtual void mark_streaming_write_completed ();
+
+ uint64_t timeline_position () { return _timeline_position; }
+ void set_timeline_position (nframes_t when) { _timeline_position = when; }
+
+ virtual void session_saved();
+
+ string captured_for() const { return _captured_for; }
+ void set_captured_for (string str) { _captured_for = str; }
+
+ uint32_t read_data_count() const { return _read_data_count; }
+ uint32_t write_data_count() const { return _write_data_count; }
+
+ static sigc::signal<void,MidiSource*> MidiSourceCreated;
+
+ // Signal a range of recorded data is available for reading from model()
+ mutable sigc::signal<void,nframes_t,nframes_t> ViewDataRangeReady;
+
+ XMLNode& get_state ();
+ int set_state (const XMLNode&);
+
+ bool length_mutable() const { return true; }
+
+ virtual void load_model(bool lock=true, bool force_reload=false) = 0;
+ virtual void destroy_model() = 0;
+
+ void set_note_mode(NoteMode mode) { if (_model) _model->set_note_mode(mode); }
+
+ boost::shared_ptr<MidiModel> model() { return _model; }
+ void set_model(boost::shared_ptr<MidiModel> m) { _model = m; }
+
+ protected:
+ virtual int flush_header() = 0;
+ virtual int flush_footer() = 0;
+
+ virtual nframes_t read_unlocked (MidiRingBuffer& dst, nframes_t start, nframes_t cnt, nframes_t stamp_offset, nframes_t negative_stamp_offset) const = 0;
+ virtual nframes_t write_unlocked (MidiRingBuffer& dst, nframes_t cnt) = 0;
+
+ mutable Glib::Mutex _lock;
+ string _captured_for;
+ uint64_t _timeline_position;
+ mutable uint32_t _read_data_count; ///< modified in read()
+ mutable uint32_t _write_data_count; ///< modified in write()
+
+ boost::shared_ptr<MidiModel> _model;
+ bool _writing;
+
+ private:
+ bool file_changed (string path);
+};
+
+}
+
+#endif /* __ardour_midi_source_h__ */
diff --git a/libs/ardour/ardour/midi_stretch.h b/libs/ardour/ardour/midi_stretch.h
new file mode 100644
index 0000000000..f4b8f1c618
--- /dev/null
+++ b/libs/ardour/ardour/midi_stretch.h
@@ -0,0 +1,40 @@
+/*
+ Copyright (C) 2007 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_midi_stretch_h__
+#define __ardour_midi_stretch_h__
+
+#include <ardour/filter.h>
+
+namespace ARDOUR {
+
+class MidiStretch : public Filter {
+ public:
+ MidiStretch (ARDOUR::Session&, TimeFXRequest&);
+ ~MidiStretch ();
+
+ int run (boost::shared_ptr<ARDOUR::Region>);
+
+ private:
+ TimeFXRequest& _request;
+};
+
+} /* namespace ARDOUR */
+
+#endif /* __ardour_midi_stretch_h__ */
diff --git a/libs/ardour/ardour/midi_track.h b/libs/ardour/ardour/midi_track.h
new file mode 100644
index 0000000000..500502ac4b
--- /dev/null
+++ b/libs/ardour/ardour/midi_track.h
@@ -0,0 +1,111 @@
+/*
+ Copyright (C) 2006 Paul Davis
+ Written by Dave Robillard
+
+ 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_midi_track_h__
+#define __ardour_midi_track_h__
+
+#include <ardour/track.h>
+#include <ardour/midi_ring_buffer.h>
+
+namespace ARDOUR
+{
+
+class Session;
+class MidiDiskstream;
+class MidiPlaylist;
+class RouteGroup;
+
+class MidiTrack : public Track
+{
+public:
+ MidiTrack (Session&, string name, Route::Flag f = Route::Flag (0), TrackMode m = Normal);
+ MidiTrack (Session&, const XMLNode&);
+ ~MidiTrack ();
+
+ int roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
+ nframes_t offset, int declick, bool can_record, bool rec_monitors_input);
+
+ int no_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
+ nframes_t offset, bool state_changing, bool can_record, bool rec_monitors_input);
+
+ int silent_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
+ nframes_t offset, bool can_record, bool rec_monitors_input);
+
+ void process_output_buffers (BufferSet& bufs,
+ nframes_t start_frame, nframes_t end_frame,
+ nframes_t nframes, nframes_t offset, bool with_redirects, int declick,
+ bool meter);
+
+ boost::shared_ptr<MidiDiskstream> midi_diskstream() const;
+
+ int use_diskstream (string name);
+ int use_diskstream (const PBD::ID& id);
+
+ void set_latency_delay (nframes_t);
+
+ int export_stuff (BufferSet& bufs,
+ nframes_t nframes, nframes_t end_frame);
+
+ void freeze (InterThreadInfo&);
+ void unfreeze ();
+
+ void bounce (InterThreadInfo&);
+ void bounce_range (nframes_t start, nframes_t end, InterThreadInfo&);
+
+ int set_state(const XMLNode& node);
+
+ void midi_panic(void);
+ bool write_immediate_event(size_t size, const uint8_t* buf);
+
+ struct MidiControl : public AutomationControl {
+ MidiControl(MidiTrack* route, boost::shared_ptr<AutomationList> al)
+ : AutomationControl (route->session(), al, al->parameter().to_string())
+ , _route (route)
+ {}
+
+ void set_value (float val);
+
+ MidiTrack* _route;
+ };
+
+ NoteMode note_mode() const { return _note_mode; }
+ void set_note_mode (NoteMode m);
+
+protected:
+
+ XMLNode& state (bool full);
+
+ int _set_state (const XMLNode&, bool call_base);
+
+private:
+
+ void write_controller_messages(MidiBuffer& buf,
+ nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset);
+
+ int set_diskstream (boost::shared_ptr<MidiDiskstream> ds);
+ void set_state_part_two ();
+ void set_state_part_three ();
+
+ MidiRingBuffer _immediate_events;
+ NoteMode _note_mode;
+};
+
+} /* namespace ARDOUR*/
+
+#endif /* __ardour_midi_track_h__ */
diff --git a/libs/ardour/ardour/midi_util.h b/libs/ardour/ardour/midi_util.h
new file mode 100644
index 0000000000..6bcc6278e1
--- /dev/null
+++ b/libs/ardour/ardour/midi_util.h
@@ -0,0 +1,73 @@
+/*
+ Copyright (C) 2006 Paul Davis
+ Written by Dave Robillard, 2006
+
+ 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_midi_util_h__
+#define __ardour_midi_util_h__
+
+#include <midi++/events.h>
+
+namespace ARDOUR {
+
+/** Return the size of the given event NOT including the status byte,
+ * or -1 if unknown (eg sysex)
+ */
+static inline int
+midi_event_size(unsigned char status)
+{
+ // if we have a channel event
+ if (status >= 0x80 && status < 0xF0) {
+ status &= 0xF0; // mask off the channel
+ }
+
+ switch (status) {
+ case MIDI_CMD_NOTE_OFF:
+ case MIDI_CMD_NOTE_ON:
+ case MIDI_CMD_NOTE_PRESSURE:
+ case MIDI_CMD_CONTROL:
+ case MIDI_CMD_BENDER:
+ case MIDI_CMD_COMMON_SONG_POS:
+ return 2;
+
+ case MIDI_CMD_PGM_CHANGE:
+ case MIDI_CMD_CHANNEL_PRESSURE:
+ case MIDI_CMD_COMMON_MTC_QUARTER:
+ case MIDI_CMD_COMMON_SONG_SELECT:
+ return 1;
+
+ case MIDI_CMD_COMMON_TUNE_REQUEST:
+ case MIDI_CMD_COMMON_SYSEX_END:
+ case MIDI_CMD_COMMON_CLOCK:
+ case MIDI_CMD_COMMON_START:
+ case MIDI_CMD_COMMON_CONTINUE:
+ case MIDI_CMD_COMMON_STOP:
+ case MIDI_CMD_COMMON_SENSING:
+ case MIDI_CMD_COMMON_RESET:
+ return 0;
+
+ case MIDI_CMD_COMMON_SYSEX:
+ return -1;
+ }
+
+ return -1;
+}
+
+} // namespace ARDOUR
+
+#endif /* __ardour_midi_util_h__ */
diff --git a/libs/ardour/ardour/mix.h b/libs/ardour/ardour/mix.h
new file mode 100644
index 0000000000..67779f0e07
--- /dev/null
+++ b/libs/ardour/ardour/mix.h
@@ -0,0 +1,65 @@
+/*
+ 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.
+
+*/
+#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 (const ARDOUR::Sample * buf, nframes_t nsamples, float current);
+ void x86_sse_apply_gain_to_buffer (ARDOUR::Sample * buf, nframes_t nframes, float gain);
+ void x86_sse_mix_buffers_with_gain (ARDOUR::Sample * dst, const ARDOUR::Sample * src, nframes_t nframes, float gain);
+ void x86_sse_mix_buffers_no_gain (ARDOUR::Sample * dst, const ARDOUR::Sample * src, nframes_t nframes);
+}
+
+void x86_sse_find_peaks (const ARDOUR::Sample * buf, nframes_t nsamples, float *min, float *max);
+
+/* debug wrappers for SSE functions */
+
+float debug_compute_peak (const ARDOUR::Sample * buf, nframes_t nsamples, float current);
+void debug_apply_gain_to_buffer (ARDOUR::Sample * buf, nframes_t nframes, float gain);
+void debug_mix_buffers_with_gain (ARDOUR::Sample * dst, const ARDOUR::Sample * src, nframes_t nframes, float gain);
+void debug_mix_buffers_no_gain (ARDOUR::Sample * dst, const ARDOUR::Sample * src, nframes_t nframes);
+
+#endif
+
+#if defined (__APPLE__)
+
+float veclib_compute_peak (const ARDOUR::Sample * buf, nframes_t nsamples, float current);
+void veclib_find_peaks (const ARDOUR::Sample * buf, nframes_t nsamples, float *min, float *max);
+void veclib_apply_gain_to_buffer (ARDOUR::Sample * buf, nframes_t nframes, float gain);
+void veclib_mix_buffers_with_gain (ARDOUR::Sample * dst, const ARDOUR::Sample * src, nframes_t nframes, float gain);
+void veclib_mix_buffers_no_gain (ARDOUR::Sample * dst, const ARDOUR::Sample * src, nframes_t nframes);
+
+#endif
+
+/* non-optimized functions */
+
+float default_compute_peak (const ARDOUR::Sample * buf, nframes_t nsamples, float current);
+void default_find_peaks (const ARDOUR::Sample * buf, nframes_t nsamples, float *min, float *max);
+void default_apply_gain_to_buffer (ARDOUR::Sample * buf, nframes_t nframes, float gain);
+void default_mix_buffers_with_gain (ARDOUR::Sample * dst, const ARDOUR::Sample * src, nframes_t nframes, float gain);
+void default_mix_buffers_no_gain (ARDOUR::Sample * dst, const ARDOUR::Sample * src, 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..39ab524d4f
--- /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.
+
+*/
+
+#ifndef __ardour_named_selection_h__
+#define __ardour_named_selection_h__
+
+#include <string>
+#include <list>
+#include <boost/shared_ptr.hpp>
+
+#include <pbd/stateful.h>
+
+class XMLNode;
+
+namespace ARDOUR
+{
+class Session;
+class Playlist;
+
+struct NamedSelection : public PBD::Stateful
+{
+ NamedSelection (std::string, std::list<boost::shared_ptr<Playlist> >&);
+ NamedSelection (Session&, const XMLNode&);
+ virtual ~NamedSelection ();
+
+ std::string name;
+ std::list<boost::shared_ptr<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..f775fcce36
--- /dev/null
+++ b/libs/ardour/ardour/noise.h
@@ -0,0 +1,38 @@
+/*
+ Copyright (C) 2000-2007 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 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/note.h b/libs/ardour/ardour/note.h
new file mode 100644
index 0000000000..0f649b3370
--- /dev/null
+++ b/libs/ardour/ardour/note.h
@@ -0,0 +1,82 @@
+/*
+ Copyright (C) 2007 Paul Davis
+ Author: Dave Robillard
+
+ 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_note_h__
+#define __ardour_note_h__
+
+#include <stdint.h>
+#include <midi++/event.h>
+
+namespace ARDOUR {
+
+
+/** A MIDI Note.
+ *
+ * A note is (unfortunately) special and not just another MIDI::Event as it
+ * has a duration and two separate MIDI events (on and off).
+ */
+class Note {
+public:
+ Note(uint8_t chan=0, double time=0, double dur=0, uint8_t note=0, uint8_t vel=0x40);
+ Note(const Note& copy);
+ ~Note();
+
+ const Note& operator=(const Note& copy);
+
+ inline bool operator==(const Note& other)
+ { return time() == other.time() &&
+ note() == other.note() &&
+ duration() == other.duration() &&
+ velocity() == other.velocity() &&
+ channel() == other.channel();
+ }
+
+ inline double time() const { return _on_event.time(); }
+ inline double end_time() const { return _off_event.time(); }
+ inline uint8_t note() const { return _on_event.note(); }
+ inline uint8_t velocity() const { return _on_event.velocity(); }
+ inline double duration() const { return _off_event.time() - _on_event.time(); }
+ inline uint8_t channel() const {
+ assert(_on_event.channel() == _off_event.channel());
+ return _on_event.channel();
+ }
+
+ inline void set_time(double t) { _off_event.time() = t + duration(); _on_event.time() = t; }
+ inline void set_note(uint8_t n) { _on_event.buffer()[1] = n; _off_event.buffer()[1] = n; }
+ inline void set_velocity(uint8_t n) { _on_event.buffer()[2] = n; }
+ inline void set_duration(double d) { _off_event.time() = _on_event.time() + d; }
+ inline void set_channel(uint8_t c) { _on_event.set_channel(c); _off_event.set_channel(c); }
+
+ inline MIDI::Event& on_event() { return _on_event; }
+ inline MIDI::Event& off_event() { return _off_event; }
+
+ inline const MIDI::Event& on_event() const { return _on_event; }
+ inline const MIDI::Event& off_event() const { return _off_event; }
+
+private:
+ // Event buffers are self-contained
+ MIDI::Event _on_event;
+ MIDI::Event _off_event;
+};
+
+
+} // namespace ARDOUR
+
+#endif /* __ardour_note_h__ */
diff --git a/libs/ardour/ardour/osc.h b/libs/ardour/ardour/osc.h
new file mode 100644
index 0000000000..3f1ce03445
--- /dev/null
+++ b/libs/ardour/ardour/osc.h
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2006 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef ardour_osc_h
+#define ardour_osc_h
+
+#include <string>
+
+#include <sys/time.h>
+#include <pthread.h>
+
+#include <lo/lo.h>
+
+#include <sigc++/sigc++.h>
+
+#include <ardour/types.h>
+
+#include <control_protocol/basic_ui.h>
+
+namespace ARDOUR {
+ class Session;
+ class Route;
+
+class OSC : public BasicUI, public sigc::trackable
+{
+ public:
+ OSC (uint32_t port);
+ virtual ~OSC();
+
+ void set_session (ARDOUR::Session&);
+ int start ();
+ int stop ();
+
+ private:
+ uint32_t _port;
+ volatile bool _ok;
+ volatile bool _shutdown;
+ lo_server _osc_server;
+ lo_server _osc_unix_server;
+ std::string _osc_unix_socket_path;
+ std::string _osc_url_file;
+ pthread_t _osc_thread;
+ int _request_pipe[2];
+
+ static void * _osc_receiver(void * arg);
+ void osc_receiver();
+
+ bool init_osc_thread ();
+ void terminate_osc_thread ();
+ void poke_osc_thread ();
+
+ void register_callbacks ();
+
+ void session_going_away ();
+
+ std::string get_server_url ();
+ std::string get_unix_server_url ();
+
+ int current_value (const char *path, const char *types, lo_arg **argv, int argc, void *data, void *user_data);
+
+#define PATH_CALLBACK(name) \
+ static int _ ## name (const char *path, const char *types, lo_arg **argv, int argc, void *data, void *user_data) { \
+ return static_cast<OSC*>(user_data)->cb_ ## name (path, types, argv, argc, data); \
+ } \
+ int cb_ ## name (const char *path, const char *types, lo_arg **argv, int argc, void *data) { \
+ name (); \
+ return 0; \
+ }
+
+ PATH_CALLBACK(add_marker);
+ PATH_CALLBACK(loop_toggle);
+ PATH_CALLBACK(goto_start);
+ PATH_CALLBACK(goto_end);
+ PATH_CALLBACK(rewind);
+ PATH_CALLBACK(ffwd);
+ PATH_CALLBACK(transport_stop);
+ PATH_CALLBACK(transport_play);
+ PATH_CALLBACK(save_state);
+ PATH_CALLBACK(prev_marker);
+ PATH_CALLBACK(next_marker);
+ PATH_CALLBACK(undo);
+ PATH_CALLBACK(redo);
+ PATH_CALLBACK(toggle_punch_in);
+ PATH_CALLBACK(toggle_punch_out);
+ PATH_CALLBACK(rec_enable_toggle);
+ PATH_CALLBACK(toggle_all_rec_enables);
+
+#define PATH_CALLBACK1(name,type) \
+ static int _ ## name (const char *path, const char *types, lo_arg **argv, int argc, void *data, void *user_data) { \
+ return static_cast<OSC*>(user_data)->cb_ ## name (path, types, argv, argc, data); \
+ } \
+ int cb_ ## name (const char *path, const char *types, lo_arg **argv, int argc, void *data) { \
+ if (argc > 0) { \
+ name (argv[0]->type); \
+ }\
+ return 0; \
+ }
+
+ PATH_CALLBACK1(set_transport_speed,f);
+};
+
+}
+
+#endif // ardour_osc_h
diff --git a/libs/ardour/ardour/panner.h b/libs/ardour/ardour/panner.h
new file mode 100644
index 0000000000..2559eed003
--- /dev/null
+++ b/libs/ardour/ardour/panner.h
@@ -0,0 +1,299 @@
+/*
+ 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_panner_h__
+#define __ardour_panner_h__
+
+#include <cmath>
+#include <cassert>
+#include <vector>
+#include <string>
+#include <iostream>
+#include <sigc++/signal.h>
+
+#include <pbd/stateful.h>
+#include <pbd/controllable.h>
+
+#include <ardour/types.h>
+#include <ardour/curve.h>
+#include <ardour/automation_control.h>
+
+using std::istream;
+using std::ostream;
+
+namespace ARDOUR {
+
+class Session;
+class Panner;
+class BufferSet;
+class AudioBuffer;
+
+class StreamPanner : public sigc::trackable, public PBD::Stateful
+{
+ public:
+ StreamPanner (Panner& p, Parameter param);
+ ~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 StreamPanner API */
+
+ virtual void distribute (AudioBuffer& src, BufferSet& obufs, gain_t gain_coeff, nframes_t nframes) = 0;
+ virtual void distribute_automated (AudioBuffer& src, BufferSet& obufs,
+ nframes_t start, nframes_t end, nframes_t nframes, pan_t** buffers) = 0;
+
+ boost::shared_ptr<AutomationControl> pan_control() { return _control; }
+
+ 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; }
+
+ /* old school automation loading */
+
+ virtual int load (istream&, string path, uint32_t&) = 0;
+
+ 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;
+
+ struct PanControllable : public AutomationControl {
+ PanControllable (Session& s, std::string name, StreamPanner& p, Parameter param)
+ : AutomationControl (s, boost::shared_ptr<AutomationList>(new AutomationList(
+ param, 0.0, 1.0, 0.5)), name)
+ , panner (p) { assert(param.type() != NullAutomation); }
+
+ StreamPanner& panner;
+
+ void set_value (float);
+ float get_value (void) const;
+ bool can_send_feedback() const;
+ };
+
+ boost::shared_ptr<PanControllable> _control;
+
+ void add_state (XMLNode&);
+ virtual void update () = 0;
+};
+
+class BaseStereoPanner : public StreamPanner
+{
+ public:
+ BaseStereoPanner (Panner&, Parameter param);
+ ~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 (AudioBuffer& src, BufferSet& obufs, gain_t gain_coeff, nframes_t nframes);
+
+ /* old school automation loading */
+
+ int load (istream&, string path, uint32_t&);
+
+ protected:
+ float left;
+ float right;
+ float desired_left;
+ float desired_right;
+ float left_interp;
+ float right_interp;
+};
+
+class EqualPowerStereoPanner : public BaseStereoPanner
+{
+ public:
+ EqualPowerStereoPanner (Panner&, Parameter param);
+ ~EqualPowerStereoPanner ();
+
+ void distribute_automated (AudioBuffer& src, BufferSet& obufs,
+ nframes_t start, nframes_t end, nframes_t nframes, pan_t** buffers);
+
+ void get_current_coefficients (pan_t*) const;
+ void get_desired_coefficients (pan_t*) const;
+
+ static StreamPanner* factory (Panner&, Parameter param);
+ 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, Parameter);
+ ~Multi2dPanner ();
+
+ void distribute (AudioBuffer& src, BufferSet& obufs, gain_t gain_coeff, nframes_t nframes);
+ void distribute_automated (AudioBuffer& src, BufferSet& obufs,
+ nframes_t start, nframes_t end, nframes_t nframes, pan_t** buffers);
+
+ static StreamPanner* factory (Panner&, Parameter);
+ static string name;
+
+ XMLNode& state (bool full_state);
+ XMLNode& get_state (void);
+ int set_state (const XMLNode&);
+
+ /* old school automation loading */
+
+ int load (istream&, string path, uint32_t&);
+
+ private:
+ void update ();
+};
+
+class Panner : public std::vector<StreamPanner*>, public PBD::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 ();
+
+ /// The fundamental Panner function
+ void distribute(BufferSet& src, BufferSet& dest, nframes_t start_frame, nframes_t end_frames, nframes_t nframes, nframes_t offset);
+
+ 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 (nframes_t now);
+ void transport_stopped (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;
+
+ 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; }
+
+ 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);
+
+ /* old school automation */
+
+ int load ();
+
+ private:
+ void distribute_no_automation(BufferSet& src, BufferSet& dest, nframes_t nframes, nframes_t offset, gain_t gain_coeff);
+
+ Session& _session;
+ uint32_t current_outs;
+ bool _linked;
+ bool _bypassed;
+ LinkDirection _link_direction;
+
+ static float current_automation_version_number;
+
+ /* old school automation handling */
+
+ std::string automation_path;
+ void set_name (std::string);
+};
+
+} // namespace ARDOUR
+
+#endif /*__ardour_panner_h__ */
diff --git a/libs/ardour/ardour/parameter.h b/libs/ardour/ardour/parameter.h
new file mode 100644
index 0000000000..b86174aa0a
--- /dev/null
+++ b/libs/ardour/ardour/parameter.h
@@ -0,0 +1,168 @@
+/*
+ Copyright (C) 2007 Paul Davis
+ Author: Dave Robillard
+
+ 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_parameter_h__
+#define __ardour_parameter_h__
+
+#include <string>
+#include <pbd/compose.h>
+#include <pbd/error.h>
+#include <ardour/types.h>
+
+namespace ARDOUR {
+
+
+/** ID of an automatable parameter.
+ *
+ * A given automatable object has a number of automatable parameters. This is
+ * the unique ID for those parameters. Anything automatable (AutomationList,
+ * Curve) must have an ID unique with respect to it's Automatable parent.
+ *
+ * A parameter ID has two parts, a type and an int (only used by some types).
+ *
+ * This is a bit more ugly than it could be, due to using the existing/legacy
+ * ARDOUR::AutomationType: GainAutomation, PanAutomation, SoloAutomation,
+ * and MuteAutomation use only the type(), but PluginAutomation and
+ * MidiCCAutomation use the id() as port number and CC number, respectively.
+ *
+ * Future types may use a string or URI or whatever, as long as these are
+ * comparable anything may be added. ints are best as these should be fast to
+ * copy and compare with one another.
+ */
+class Parameter
+{
+public:
+ Parameter(AutomationType type = NullAutomation, uint32_t id=0, uint8_t channel=0)
+ : _type(type), _id(id), _channel(channel)
+ {}
+
+ Parameter(const std::string& str);
+
+ inline AutomationType type() const { return _type; }
+ inline uint32_t id() const { return _id; }
+ inline uint8_t channel() const { return _channel; }
+
+ /**
+ * Equivalence operator
+ * It is obvious from the definition that this operator
+ * is transitive, as required by stict weak ordering
+ * (see: http://www.sgi.com/tech/stl/StrictWeakOrdering.html)
+ */
+ inline bool operator==(const Parameter& id) const {
+ return (_type == id._type && _id == id._id && _channel == id._channel);
+ }
+
+ /** Strict weak ordering
+ * (see: http://www.sgi.com/tech/stl/StrictWeakOrdering.html)
+ * This is necessary so that std::set works):
+ * Sort Parameters first according to type then to id and lastly to channel.
+ *
+ * Proof:
+ * <ol>
+ * <li>Irreflexivity: f(x, x) is false because of the irreflexivity of \c < in each branch.</li>
+ *
+ * <li>Antisymmetry: given x != y, f(x, y) implies !f(y, x) because of the same
+ * property of \c < in each branch and the symmetry of operator==. </li>
+ *
+ * <li>Transitivity: let f(x, y) and f(y, z) be true. We prove by assuming the contrary,
+ * that f(x, z) does not hold.
+ * That would imply exactly one of the following:
+ * <ol>
+ * <li> x == z which contradicts the assumption f(x, y) and f(y, x)
+ * because of antisymmetry.
+ * </li>
+ * <li> f(z, x) is true. That would imply that one of the ivars (we call it i)
+ * of x is greater than the same ivar in z while all "previous" ivars
+ * are equal. That would imply that also in y all those "previous"
+ * ivars are equal and because if x.i > z.i it is impossible
+ * that there is an y that satisfies x.i < y.i < z.i at the same
+ * time which contradicts the assumption.
+ * </li>
+ * </ol>
+ * </li>
+ * </ol>
+ */
+
+ inline bool operator<(const Parameter& id) const {
+#ifndef NDEBUG
+ if (_type == NullAutomation)
+ PBD::warning << "Uninitialized Parameter compared." << endmsg;
+#endif
+ if (_type < id._type) {
+ return true;
+ } else if (_type == id._type && _id < id._id) {
+ return true;
+ } else if (_id == id._id && _channel < id._channel) {
+ return true;
+ }
+
+ return false;
+ }
+
+ inline operator bool() const { return (_type != 0); }
+
+ std::string to_string() const;
+
+ /* The below properties are only used for CC right now, but unchanging properties
+ * of parameters (rather than changing parameters of automation lists themselves)
+ * should be moved here */
+
+ inline double min() const {
+ switch(_type) {
+ case MidiCCAutomation:
+ case MidiPgmChangeAutomation:
+ case MidiPitchBenderAutomation:
+ case MidiChannelAftertouchAutomation:
+ return 0.0;
+
+ default:
+ return DBL_MIN;
+ }
+ }
+
+ inline double max() const {
+ switch(_type) {
+ case MidiCCAutomation:
+ case MidiPgmChangeAutomation:
+ case MidiChannelAftertouchAutomation:
+ return 127.0;
+ case MidiPitchBenderAutomation:
+ return 16383.0;
+
+ default:
+ return DBL_MAX;
+ }
+ }
+
+ inline bool is_integer() const {
+ return (_type >= MidiCCAutomation && _type <= MidiChannelAftertouchAutomation);
+ }
+
+private:
+ // default copy constructor is ok
+ AutomationType _type;
+ uint32_t _id;
+ uint8_t _channel;
+};
+
+
+} // namespace ARDOUR
+
+#endif // __ardour_parameter_h__
+
diff --git a/libs/ardour/ardour/pcm_utils.h b/libs/ardour/ardour/pcm_utils.h
new file mode 100644
index 0000000000..5e6436cc94
--- /dev/null
+++ b/libs/ardour/ardour/pcm_utils.h
@@ -0,0 +1,41 @@
+/*
+ Copyright (C) 2006 Paul Davis , portions Erik de Castro Lopo
+
+ 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_pcm_utils_h__
+#define __ardour_pcm_utils_h__
+
+typedef void tribyte ;
+
+#define SIZEOF_TRIBYTE 3
+
+#define BET2H_INT_PTR(x) (((x) [0] << 24) + ((x) [1] << 16) + ((x) [2] << 8))
+#define LET2H_INT_PTR(x) (((x) [0] << 8) + ((x) [1] << 16) + ((x) [2] << 24))
+
+
+
+void pcm_let2f_array (tribyte *src, int count, float *dest);
+void pcm_bet2f_array (tribyte *src, int count, float *dest);
+void pcm_f2let_array (float *src, tribyte *dest, int count);
+void pcm_f2let_clip_array (float *src, tribyte *dest, int count);
+void pcm_f2bet_array (const float *src, tribyte *dest, int count);
+void pcm_f2bet_clip_array (const float *src, tribyte *dest, int count);
+
+
+
+#endif
diff --git a/libs/ardour/ardour/peak.h b/libs/ardour/ardour/peak.h
new file mode 100644
index 0000000000..bbec40eea7
--- /dev/null
+++ b/libs/ardour/ardour/peak.h
@@ -0,0 +1,36 @@
+/*
+ Copyright (C) 2000-2007 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_peak_h__
+#define __ardour_peak_h__
+
+#include <cmath>
+#include <ardour/types.h>
+#include <ardour/utils.h>
+
+static inline float
+default_compute_peak (const ARDOUR::Sample * const buf, nframes_t nsamples, float current)
+{
+ for (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/pitch.h b/libs/ardour/ardour/pitch.h
new file mode 100644
index 0000000000..38d8380f5d
--- /dev/null
+++ b/libs/ardour/ardour/pitch.h
@@ -0,0 +1,62 @@
+/*
+ Copyright (C) 2007 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_pitch_h__
+#define __ardour_pitch_h__
+
+#include <ardour/filter.h>
+
+namespace ARDOUR {
+ class AudioRegion;
+}
+
+#ifdef USE_RUBBERBAND
+
+#include <ardour/rb_effect.h>
+
+namespace ARDOUR {
+
+class Pitch : public RBEffect {
+ public:
+ Pitch (ARDOUR::Session&, TimeFXRequest&);
+ ~Pitch () {}
+};
+
+} /* namespace */
+
+# else
+
+namespace ARDOUR {
+
+class Pitch : public Filter {
+ public:
+ Pitch (ARDOUR::Session&, TimeFXRequest&);
+ ~Pitch () {}
+
+ int run (boost::shared_ptr<ARDOUR::Region>);
+
+ private:
+ TimeFXRequest& tsr;
+};
+
+} /* namespace */
+
+#endif
+
+#endif /* __ardour_pitch_h__ */
diff --git a/libs/ardour/ardour/playlist.h b/libs/ardour/ardour/playlist.h
new file mode 100644
index 0000000000..ad7210f48f
--- /dev/null
+++ b/libs/ardour/ardour/playlist.h
@@ -0,0 +1,287 @@
+/*
+ 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.
+
+*/
+
+#ifndef __ardour_playlist_h__
+#define __ardour_playlist_h__
+
+#include <string>
+#include <set>
+#include <map>
+#include <list>
+#include <boost/shared_ptr.hpp>
+#include <boost/enable_shared_from_this.hpp>
+
+#include <sys/stat.h>
+
+#include <glib.h>
+
+#include <sigc++/signal.h>
+
+#include <pbd/undo.h>
+#include <pbd/stateful.h>
+#include <pbd/statefuldestructible.h>
+
+#include <ardour/ardour.h>
+#include <ardour/session_object.h>
+#include <ardour/crossfade_compare.h>
+#include <ardour/location.h>
+#include <ardour/data_type.h>
+
+namespace ARDOUR {
+
+class Session;
+class Region;
+
+class Playlist : public SessionObject, public boost::enable_shared_from_this<Playlist> {
+ public:
+ typedef list<boost::shared_ptr<Region> > RegionList;
+
+ Playlist (Session&, const XMLNode&, DataType type, bool hidden = false);
+ Playlist (Session&, string name, DataType type, bool hidden = false);
+ Playlist (boost::shared_ptr<const Playlist>, string name, bool hidden = false);
+ Playlist (boost::shared_ptr<const Playlist>, nframes_t start, nframes_t cnt, string name, bool hidden = false);
+
+ virtual ~Playlist ();
+
+ void set_region_ownership ();
+
+ virtual void clear (bool with_signals=true);
+ virtual void dump () const;
+
+ void use();
+ void release();
+ bool used () const { return _refcnt != 0; }
+
+ bool set_name (const string& str);
+
+ const DataType& data_type() const { return _type; }
+
+ bool frozen() const { return _frozen; }
+ void set_frozen (bool yn);
+
+ bool hidden() const { return _hidden; }
+ bool empty() const;
+ uint32_t n_regions() const;
+ 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 (boost::shared_ptr<Region>, nframes_t position, float times = 1);
+ void remove_region (boost::shared_ptr<Region>);
+ void get_equivalent_regions (boost::shared_ptr<Region>, std::vector<boost::shared_ptr<Region> >&);
+ void get_region_list_equivalent_regions (boost::shared_ptr<Region>, std::vector<boost::shared_ptr<Region> >&);
+ void replace_region (boost::shared_ptr<Region> old, boost::shared_ptr<Region> newr, nframes_t pos);
+ void split_region (boost::shared_ptr<Region>, nframes_t position);
+ void split (nframes64_t at);
+ void shift (nframes64_t at, nframes64_t distance, bool move_intersected, bool ignore_music_glue);
+ void partition (nframes_t start, nframes_t end, bool just_top_level);
+ void duplicate (boost::shared_ptr<Region>, nframes_t position, float times);
+ void nudge_after (nframes_t start, nframes_t distance, bool forwards);
+ void shuffle (boost::shared_ptr<Region>, int dir);
+ void update_after_tempo_map_change ();
+
+ boost::shared_ptr<Playlist> cut (list<AudioRange>&, bool result_is_hidden = true);
+ boost::shared_ptr<Playlist> copy (list<AudioRange>&, bool result_is_hidden = true);
+ int paste (boost::shared_ptr<Playlist>, nframes_t position, float times);
+
+ RegionList* regions_at (nframes_t frame);
+ RegionList* regions_touched (nframes_t start, nframes_t end);
+ RegionList* regions_to_read (nframes_t start, nframes_t end);
+ boost::shared_ptr<Region> find_region (const PBD::ID&) const;
+ boost::shared_ptr<Region> top_region_at (nframes_t frame);
+ boost::shared_ptr<Region> find_next_region (nframes_t frame, RegionPoint point, int dir);
+ nframes64_t find_next_region_boundary (nframes64_t frame, int dir);
+ bool region_is_shuffle_constrained (boost::shared_ptr<Region>);
+
+ nframes64_t find_next_transient (nframes64_t position, int dir);
+
+ template<class T> void foreach_region (T *t, void (T::*func)(boost::shared_ptr<Region>, void *), void *arg);
+ template<class T> void foreach_region (T *t, void (T::*func)(boost::shared_ptr<Region>));
+
+ XMLNode& get_state ();
+ int set_state (const XMLNode&);
+ XMLNode& get_template ();
+
+ sigc::signal<void,bool> InUse;
+ sigc::signal<void> Modified;
+ sigc::signal<void> NameChanged;
+ sigc::signal<void> LengthChanged;
+
+ static string bump_name (string old_name, Session&);
+
+ void freeze ();
+ void thaw ();
+
+ void raise_region (boost::shared_ptr<Region>);
+ void lower_region (boost::shared_ptr<Region>);
+ void raise_region_to_top (boost::shared_ptr<Region>);
+ void lower_region_to_bottom (boost::shared_ptr<Region>);
+
+ uint32_t read_data_count() const { return _read_data_count; }
+
+ const PBD::ID& get_orig_diskstream_id () const { return _orig_diskstream_id; }
+ void set_orig_diskstream_id (const PBD::ID& did) { _orig_diskstream_id = did; }
+
+ /* destructive editing */
+
+ virtual bool destroy_region (boost::shared_ptr<Region>) = 0;
+
+ /* special case function used by UI selection objects, which have playlists that actually own the regions
+ within them.
+ */
+
+ void drop_regions ();
+
+ protected:
+ friend class Session;
+
+ 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; /* the current list of regions in the playlist */
+ std::set<boost::shared_ptr<Region> > all_regions; /* all regions ever added to this playlist */
+ DataType _type;
+ mutable gint block_notifications;
+ mutable gint ignore_state_changes;
+ mutable Glib::Mutex region_lock;
+ std::set<boost::shared_ptr<Region> > pending_adds;
+ std::set<boost::shared_ptr<Region> > pending_removes;
+ RegionList pending_bounds;
+ bool pending_modified;
+ bool pending_length;
+ bool save_on_thaw;
+ string last_save_reason;
+ uint32_t in_set_state;
+ bool first_set_state;
+ bool _hidden;
+ bool _splicing;
+ bool _shuffling;
+ bool _nudging;
+ uint32_t _refcnt;
+ EditMode _edit_mode;
+ bool in_flush;
+ bool in_partition;
+ bool _frozen;
+ uint32_t subcnt;
+ uint32_t _read_data_count;
+ PBD::ID _orig_diskstream_id;
+ uint64_t layer_op_counter;
+ nframes_t freeze_length;
+
+ void init (bool hide);
+
+ bool holding_state () const {
+ return g_atomic_int_get (&block_notifications) != 0 ||
+ g_atomic_int_get (&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 (boost::shared_ptr<Region>);
+ void notify_region_added (boost::shared_ptr<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, boost::weak_ptr<Region>);
+ virtual bool region_changed (Change, boost::shared_ptr<Region>);
+
+ void region_bounds_changed (Change, boost::shared_ptr<Region>);
+ void region_deleted (boost::shared_ptr<Region>);
+
+ void sort_regions ();
+
+ void possibly_splice (nframes_t at, nframes64_t distance, boost::shared_ptr<Region> exclude = boost::shared_ptr<Region>());
+ void possibly_splice_unlocked(nframes_t at, nframes64_t distance, boost::shared_ptr<Region> exclude = boost::shared_ptr<Region>());
+
+ void core_splice (nframes_t at, nframes64_t distance, boost::shared_ptr<Region> exclude);
+ void splice_locked (nframes_t at, nframes64_t distance, boost::shared_ptr<Region> exclude);
+ void splice_unlocked (nframes_t at, nframes64_t distance, boost::shared_ptr<Region> exclude);
+
+ virtual void finalize_split_region (boost::shared_ptr<Region> original, boost::shared_ptr<Region> left, boost::shared_ptr<Region> right) {}
+
+ virtual void check_dependents (boost::shared_ptr<Region> region, bool norefresh) {}
+ virtual void refresh_dependents (boost::shared_ptr<Region> region) {}
+ virtual void remove_dependents (boost::shared_ptr<Region> region) {}
+
+ virtual XMLNode& state (bool);
+
+ boost::shared_ptr<Region> region_by_id (PBD::ID);
+
+ void add_region_internal (boost::shared_ptr<Region>, nframes_t position);
+
+ int remove_region_internal (boost::shared_ptr<Region>);
+ RegionList *find_regions_at (nframes_t frame);
+ void copy_regions (RegionList&) const;
+ void partition_internal (nframes_t start, nframes_t end, bool cutting, RegionList& thawlist);
+
+ nframes_t _get_maximum_extent() const;
+
+ boost::shared_ptr<Playlist> cut_copy (boost::shared_ptr<Playlist> (Playlist::*pmf)(nframes_t, nframes_t, bool),
+ list<AudioRange>& ranges, bool result_is_hidden);
+ boost::shared_ptr<Playlist> cut (nframes_t start, nframes_t cnt, bool result_is_hidden);
+ boost::shared_ptr<Playlist> copy (nframes_t start, nframes_t cnt, bool result_is_hidden);
+
+ int move_region_to_layer (layer_t, boost::shared_ptr<Region> r, int dir);
+ void relayer ();
+
+ void unset_freeze_parent (Playlist*);
+ void unset_freeze_child (Playlist*);
+
+ void timestamp_layer_op (boost::shared_ptr<Region>);
+
+ void _split_region (boost::shared_ptr<Region>, nframes_t position);
+};
+
+} /* namespace ARDOUR */
+
+#endif /* __ardour_playlist_h__ */
+
+
diff --git a/libs/ardour/ardour/playlist_factory.h b/libs/ardour/ardour/playlist_factory.h
new file mode 100644
index 0000000000..a28e2611d9
--- /dev/null
+++ b/libs/ardour/ardour/playlist_factory.h
@@ -0,0 +1,44 @@
+/*
+ Copyright (C) 2000-2007 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_playlist_factory_h__
+#define __ardour_playlist_factory_h__
+
+#include <ardour/playlist.h>
+
+class XMLNode;
+
+namespace ARDOUR {
+
+class Session;
+
+class PlaylistFactory {
+
+ public:
+ static sigc::signal<void,boost::shared_ptr<Playlist> > PlaylistCreated;
+
+ static boost::shared_ptr<Playlist> create (Session&, const XMLNode&, bool hidden = false);
+ static boost::shared_ptr<Playlist> create (DataType type, Session&, string name, bool hidden = false);
+ static boost::shared_ptr<Playlist> create (boost::shared_ptr<const Playlist>, string name, bool hidden = false);
+ static boost::shared_ptr<Playlist> create (boost::shared_ptr<const Playlist>, nframes_t start, nframes_t cnt, string name, bool hidden = false);
+};
+
+}
+
+#endif /* __ardour_playlist_factory_h__ */
diff --git a/libs/ardour/ardour/playlist_templates.h b/libs/ardour/ardour/playlist_templates.h
new file mode 100644
index 0000000000..bf072a71c1
--- /dev/null
+++ b/libs/ardour/ardour/playlist_templates.h
@@ -0,0 +1,48 @@
+/*
+ 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.
+
+*/
+
+#ifndef __ardour_playlist_templates_h__
+#define __ardour_playlist_templates_h__
+
+namespace ARDOUR {
+
+template<class T> void AudioPlaylist::foreach_crossfade (T *t, void (T::*func)(boost::shared_ptr<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)(boost::shared_ptr<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)(boost::shared_ptr<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..73f89f1a91
--- /dev/null
+++ b/libs/ardour/ardour/plugin.h
@@ -0,0 +1,174 @@
+/*
+ Copyright (C) 2000-2006 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_plugin_h__
+#define __ardour_plugin_h__
+
+#include <boost/shared_ptr.hpp>
+#include <sigc++/signal.h>
+#include <glibmm/ustring.h>
+
+#include <pbd/statefuldestructible.h>
+#include <pbd/controllable.h>
+
+#include <jack/types.h>
+#include <ardour/types.h>
+#include <ardour/chan_count.h>
+#include <ardour/cycles.h>
+#include <ardour/latent.h>
+#include <ardour/parameter.h>
+#include <ardour/plugin_insert.h>
+
+#include <vector>
+#include <set>
+#include <map>
+
+using std::string;
+using std::vector;
+using std::set;
+using std::map;
+
+namespace ARDOUR {
+
+class AudioEngine;
+class Session;
+class BufferSet;
+
+class Plugin;
+
+typedef boost::shared_ptr<Plugin> PluginPtr;
+
+class PluginInfo {
+ public:
+ PluginInfo () { }
+ PluginInfo (const PluginInfo &o)
+ : name(o.name),
+ category (o.category),
+ creator (o.creator),
+ path (o.path),
+ n_inputs(o.n_inputs),
+ n_outputs(o.n_outputs),
+ unique_id(o.unique_id),
+ index(o.index) {}
+ virtual ~PluginInfo () { }
+
+ string name;
+ string category;
+ Glib::ustring creator;
+ Glib::ustring path;
+ ChanCount n_inputs;
+ ChanCount n_outputs;
+ ARDOUR::PluginType type;
+
+ std::string unique_id;
+
+ virtual PluginPtr load (Session& session) = 0;
+
+ protected:
+ friend class PluginManager;
+ uint32_t index;
+};
+
+typedef boost::shared_ptr<PluginInfo> PluginInfoPtr;
+typedef std::list<PluginInfoPtr> PluginInfoList;
+
+class Plugin : public PBD::StatefulDestructible, public Latent
+{
+ public:
+ Plugin (ARDOUR::AudioEngine&, ARDOUR::Session&);
+ Plugin (const Plugin&);
+ virtual ~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 std::string 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 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 (nframes_t nframes) = 0;
+
+ virtual int connect_and_run (BufferSet& bufs, uint32_t& in, uint32_t& out, nframes_t nframes, nframes_t offset) = 0;
+
+ virtual std::set<Parameter> automatable() const = 0;
+ virtual string describe_parameter (Parameter) = 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 std::vector<std::string> get_presets();
+
+ virtual bool has_editor() const = 0;
+
+ PluginInfoPtr get_info() { return _info; }
+ void set_info (const PluginInfoPtr 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:
+ friend class PluginInsert;
+ friend struct PluginInsert::PluginControl;
+ virtual void set_parameter (uint32_t which, float val) = 0;
+
+ ARDOUR::AudioEngine& _engine;
+ ARDOUR::Session& _session;
+ PluginInfoPtr _info;
+ uint32_t _cycles;
+ map<string,string> presets;
+ bool save_preset(string name, string domain /* vst, ladspa etc. */);
+};
+
+PluginPtr find_plugin(ARDOUR::Session&, string unique_id, ARDOUR::PluginType);
+
+} // namespace ARDOUR
+
+#endif /* __ardour_plugin_h__ */
diff --git a/libs/ardour/ardour/plugin_insert.h b/libs/ardour/ardour/plugin_insert.h
new file mode 100644
index 0000000000..42c53c487c
--- /dev/null
+++ b/libs/ardour/ardour/plugin_insert.h
@@ -0,0 +1,131 @@
+/*
+ Copyright (C) 2000,2007 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_plugin_insert_h__
+#define __ardour_plugin_insert_h__
+
+#include <vector>
+#include <string>
+
+#include <sigc++/signal.h>
+#include <ardour/ardour.h>
+#include <ardour/types.h>
+#include <ardour/processor.h>
+#include <ardour/automation_event.h>
+
+class XMLNode;
+
+namespace ARDOUR {
+
+class Session;
+class Route;
+class Plugin;
+
+/** Plugin inserts: send data through a plugin
+ */
+class PluginInsert : public Processor
+{
+ public:
+ PluginInsert (Session&, boost::shared_ptr<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&);
+
+ void run_in_place (BufferSet& in, nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset);
+ void silence (nframes_t nframes, nframes_t offset);
+
+ void activate ();
+ void deactivate ();
+
+ void set_block_size (nframes_t nframes);
+
+ ChanCount output_streams() const;
+ ChanCount input_streams() const;
+ ChanCount natural_output_streams() const;
+ ChanCount natural_input_streams() const;
+
+ bool set_count (uint32_t num);
+ uint32_t get_count () const { return _plugins.size(); }
+
+ virtual bool can_support_input_configuration (ChanCount in) const;
+ virtual ChanCount output_for_input_configuration (ChanCount in) const;
+ virtual bool configure_io (ChanCount in, ChanCount out);
+
+ bool is_generator() const;
+
+ void set_parameter (Parameter param, float val);
+ float get_parameter (Parameter param);
+
+ float default_parameter_value (Parameter param);
+
+ struct PluginControl : public AutomationControl
+ {
+ PluginControl (PluginInsert& p, boost::shared_ptr<AutomationList> list);
+
+ void set_value (float val);
+ float get_value (void) const;
+
+ private:
+ PluginInsert& _plugin;
+ boost::shared_ptr<AutomationList> _list;
+ bool _logarithmic;
+ bool _toggled;
+ };
+
+ boost::shared_ptr<Plugin> plugin(uint32_t num=0) const {
+ if (num < _plugins.size()) {
+ return _plugins[num];
+ } else {
+ return _plugins[0]; // we always have one
+ }
+ }
+
+ PluginType type ();
+
+ string describe_parameter (Parameter param);
+
+ nframes_t signal_latency() const;
+
+ private:
+
+ void parameter_changed (Parameter, float);
+
+ std::vector<boost::shared_ptr<Plugin> > _plugins;
+
+ void automation_run (BufferSet& bufs, nframes_t nframes, nframes_t offset);
+ void connect_and_run (BufferSet& bufs, nframes_t nframes, nframes_t offset, bool with_auto, nframes_t now = 0);
+
+ void init ();
+ void set_automatable ();
+ void auto_state_changed (Parameter which);
+
+ int32_t count_for_configuration (ChanCount in, ChanCount out) const;
+
+ boost::shared_ptr<Plugin> plugin_factory (boost::shared_ptr<Plugin>);
+};
+
+} // namespace ARDOUR
+
+#endif /* __ardour_plugin_insert_h__ */
diff --git a/libs/ardour/ardour/plugin_manager.h b/libs/ardour/ardour/plugin_manager.h
new file mode 100644
index 0000000000..892c8bd75a
--- /dev/null
+++ b/libs/ardour/ardour/plugin_manager.h
@@ -0,0 +1,101 @@
+/*
+ Copyright (C) 2000-2007 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_plugin_manager_h__
+#define __ardour_plugin_manager_h__
+
+#include <list>
+#include <map>
+#include <string>
+
+#include <ardour/types.h>
+#include <ardour/plugin.h>
+
+#ifdef HAVE_SLV2
+#include <ardour/lv2_plugin.h>
+#endif
+
+namespace ARDOUR {
+
+class Plugin;
+
+class PluginManager {
+ public:
+ PluginManager ();
+ ~PluginManager ();
+
+ /* realtime plugin APIs */
+
+ ARDOUR::PluginInfoList &vst_plugin_info () { return _vst_plugin_info; }
+ ARDOUR::PluginInfoList &ladspa_plugin_info () { return _ladspa_plugin_info; }
+ ARDOUR::PluginInfoList &lv2_plugin_info () { return _lv2_plugin_info; }
+ ARDOUR::PluginInfoList &au_plugin_info () { return _au_plugin_info; }
+
+ void refresh ();
+
+ int add_ladspa_directory (std::string dirpath);
+ int add_vst_directory (std::string dirpath);
+
+ static PluginManager* the_manager() { return _manager; }
+
+ private:
+ ARDOUR::PluginInfoList _vst_plugin_info;
+ ARDOUR::PluginInfoList _ladspa_plugin_info;
+ ARDOUR::PluginInfoList _lv2_plugin_info;
+ ARDOUR::PluginInfoList _au_plugin_info;
+
+#ifdef HAVE_SLV2
+ LV2World* _lv2_world;
+#endif
+
+ 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 au_discover ();
+ void au_refresh ();
+
+ int lv2_discover ();
+ void lv2_refresh ();
+
+ 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);
+ std::vector<uint32_t> ladspa_plugin_whitelist;
+
+ static PluginManager* _manager; // singleton
+};
+
+} /* namespace ARDOUR */
+
+#endif /* __ardour_plugin_manager_h__ */
+
diff --git a/libs/ardour/ardour/port.h b/libs/ardour/ardour/port.h
new file mode 100644
index 0000000000..93c34da16d
--- /dev/null
+++ b/libs/ardour/ardour/port.h
@@ -0,0 +1,180 @@
+/*
+ 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.
+
+*/
+
+#ifndef __ardour_port_h__
+#define __ardour_port_h__
+
+#include <set>
+#include <vector>
+#include <string>
+
+#include <sigc++/signal.h>
+#include <pbd/failed_constructor.h>
+#include <ardour/ardour.h>
+#include <ardour/data_type.h>
+#include <jack/jack.h>
+
+namespace ARDOUR {
+
+class AudioEngine;
+class Buffer;
+
+/** Abstract base for ports
+ */
+class Port : public virtual sigc::trackable {
+ public:
+ enum Flags {
+ IsInput = JackPortIsInput,
+ IsOutput = JackPortIsOutput,
+ IsPhysical = JackPortIsPhysical,
+ IsTerminal = JackPortIsTerminal,
+ CanMonitor = JackPortCanMonitor
+ };
+
+ virtual ~Port();
+
+ std::string name() const {
+ return _name;
+ }
+
+ Flags flags() const {
+ return _flags;
+ }
+
+ bool receives_input() const {
+ return _flags & IsInput;
+ }
+
+ bool sends_output () const {
+ return _flags & IsOutput;
+ }
+
+ bool can_monitor () const {
+ return _flags & CanMonitor;
+ }
+
+ void enable_metering() {
+ _metering++;
+ }
+
+ void disable_metering () {
+ if (_metering) { _metering--; }
+ }
+
+ virtual void cycle_start (nframes_t nframes, nframes_t offset) {}
+ virtual void cycle_end (nframes_t nframes, nframes_t offset) {}
+ virtual DataType type() const = 0;
+ virtual Buffer& get_buffer() = 0;
+
+ virtual bool connected () const;
+ virtual bool connected_to (const std::string& portname) const;
+ virtual int get_connections (std::vector<std::string>&) const;
+
+ virtual int connect (Port& other);
+ virtual int disconnect (Port& other);
+ virtual int disconnect_all ();
+
+ virtual void reset ();
+ virtual int reestablish () {return 0; }
+ virtual int reconnect () { return 0; }
+
+ virtual int set_name (const std::string& str) {
+ _name = str;
+ return 0;
+ }
+
+ virtual std::string short_name() const = 0;
+ virtual bool monitoring_input () const = 0;
+ virtual void ensure_monitor_input (bool yn) = 0;
+ virtual void request_monitor_input (bool yn) = 0;
+ virtual nframes_t latency () const = 0;
+ virtual nframes_t total_latency () const = 0;
+ virtual void set_latency (nframes_t nframes) = 0;
+
+ sigc::signal<void,bool> MonitorInputChanged;
+ sigc::signal<void,bool> ClockSyncChanged;
+
+ static void set_engine (AudioEngine*);
+
+ protected:
+ friend class AudioEngine;
+
+ Port (const std::string& name, Flags flgs);
+
+ virtual void recompute_total_latency() const {}
+
+ /* engine isn't supposed to access below here */
+
+ Flags _flags;
+ std::string _type;
+ std::string _name;
+ unsigned short _metering;
+ bool _last_monitor;
+ nframes_t _latency;
+
+ std::set<Port*> _connections;
+
+ static AudioEngine* engine;
+};
+
+class PortConnectableByName {
+ public:
+ PortConnectableByName() {}
+ virtual ~PortConnectableByName() {}
+
+ virtual int connect (const std::string& other_name) = 0;
+ virtual int disconnect (const std::string& other_name) = 0;
+};
+
+class PortFacade : public virtual Port, public PortConnectableByName {
+ public:
+ PortFacade (const std::string& name, Flags flgs) : Port (name, flgs), _ext_port (0) {}
+ ~PortFacade() {}
+
+ void reset ();
+ int reestablish ();
+ int reconnect ();
+
+ int connect (Port& other);
+ int disconnect (Port& other);
+ int disconnect_all ();
+
+ int connect (const std::string& other_name);
+ int disconnect (const std::string& other_name);
+
+ bool connected () const;
+ bool connected_to (const std::string& portname) const;
+ int get_connections (std::vector<std::string>&) const;
+
+ std::string short_name() const;
+ int set_name (const std::string& str);
+ bool monitoring_input () const;
+ void ensure_monitor_input (bool yn);
+ void request_monitor_input (bool yn);
+ nframes_t latency () const;
+ nframes_t total_latency () const;
+ void set_latency (nframes_t nframes);
+
+ protected:
+ Port* _ext_port;
+};
+
+} // namespace ARDOUR
+
+#endif /* __ardour_port_h__ */
diff --git a/libs/ardour/ardour/port_insert.h b/libs/ardour/ardour/port_insert.h
new file mode 100644
index 0000000000..1743040bf5
--- /dev/null
+++ b/libs/ardour/ardour/port_insert.h
@@ -0,0 +1,73 @@
+/*
+ Copyright (C) 2000,2007 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_port_insert_h__
+#define __ardour_port_insert_h__
+
+#include <vector>
+#include <string>
+#include <exception>
+
+#include <sigc++/signal.h>
+#include <ardour/ardour.h>
+#include <ardour/io_processor.h>
+#include <ardour/types.h>
+
+class XMLNode;
+
+namespace ARDOUR {
+
+class Session;
+
+/** Port inserts: send output to a Jack port, pick up input at a Jack port
+ */
+class PortInsert : public IOProcessor
+{
+ 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_in_place (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset);
+
+ nframes_t signal_latency() const;
+
+ ChanCount output_streams() const;
+ ChanCount input_streams() const;
+
+ virtual bool can_support_input_configuration (ChanCount in) const;
+ virtual ChanCount output_for_input_configuration (ChanCount in) const;
+ virtual bool configure_io (ChanCount in, ChanCount out);
+
+ uint32_t bit_slot() const { return bitslot; }
+
+ private:
+ uint32_t bitslot;
+};
+
+} // namespace ARDOUR
+
+#endif /* __ardour_port_insert_h__ */
diff --git a/libs/ardour/ardour/port_set.h b/libs/ardour/ardour/port_set.h
new file mode 100644
index 0000000000..51673472c3
--- /dev/null
+++ b/libs/ardour/ardour/port_set.h
@@ -0,0 +1,161 @@
+/*
+ Copyright (C) 2006 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_port_set_h__
+#define __ardour_port_set_h__
+
+#include <vector>
+#include <ardour/port.h>
+#include <ardour/audio_port.h>
+#include <ardour/midi_port.h>
+#include <ardour/chan_count.h>
+
+namespace ARDOUR {
+
+
+/** An ordered list of Ports, possibly of various types.
+ *
+ * This allows access to all the ports as a list, ignoring type, or accessing
+ * the nth port of a given type. Note that port(n) and nth_audio_port(n) may
+ * NOT return the same port.
+ */
+class PortSet {
+public:
+ PortSet();
+
+ size_t num_ports() const;
+ size_t num_ports(DataType type) const { return _ports[type].size(); }
+
+ void add(Port* port);
+ bool remove(Port* port);
+
+ /** nth port */
+ Port* port(size_t index) const;
+
+ /** nth port of type @a t, or nth port if t = NIL */
+ Port* port(DataType t, size_t index) const;
+
+ AudioPort* nth_audio_port(size_t n) const;
+
+ MidiPort* nth_midi_port(size_t n) const;
+
+ bool contains(const Port* port) const;
+
+ /** Remove all ports from the PortSet. Ports are not deregistered with
+ * the engine, it's the caller's responsibility to not leak here!
+ */
+ void clear() { _ports.clear(); }
+
+ const ChanCount& count() const { return _count; }
+
+ bool empty() const { return (_count.n_total() == 0); }
+
+ // ITERATORS
+
+ // FIXME: this is a filthy copy-and-paste mess
+
+ class iterator {
+ public:
+
+ Port& operator*() { return *_set.port(_type, _index); }
+ Port* operator->() { return _set.port(_type, _index); }
+ iterator& operator++() { ++_index; return *this; } // yes, prefix only
+ bool operator==(const iterator& other) { return (_index == other._index); }
+ bool operator!=(const iterator& other) { return (_index != other._index); }
+
+ private:
+ friend class PortSet;
+
+ iterator(PortSet& list, DataType type, size_t index)
+ : _set(list), _type(type), _index(index) {}
+
+ PortSet& _set;
+ DataType _type; ///< Ignored if NIL (to iterator over entire set)
+ size_t _index;
+ };
+
+ iterator begin(DataType type = DataType::NIL)
+ { return iterator(*this, type, 0); }
+
+ iterator end(DataType type = DataType::NIL)
+ {
+ return iterator(*this, type,
+ (type == DataType::NIL) ? _count.n_total() : _count.get(type));
+ }
+
+ // FIXME: typeify
+ class const_iterator {
+ public:
+
+ const Port& operator*() { return *_set.port(_index); }
+ const Port* operator->() { return _set.port(_index); }
+ const_iterator& operator++() { ++_index; return *this; } // yes, prefix only
+ bool operator==(const const_iterator& other) { return (_index == other._index); }
+ bool operator!=(const const_iterator& other) { return (_index != other._index); }
+
+ private:
+ friend class PortSet;
+
+ const_iterator(const PortSet& list, size_t index) : _set(list), _index(index) {}
+
+ const PortSet& _set;
+ size_t _index;
+ };
+
+ const_iterator begin() const { return const_iterator(*this, 0); }
+ const_iterator end() const { return const_iterator(*this, _count.n_total()); }
+
+
+ class audio_iterator {
+ public:
+
+ AudioPort& operator*() { return *_set.nth_audio_port(_index); }
+ AudioPort* operator->() { return _set.nth_audio_port(_index); }
+ audio_iterator& operator++() { ++_index; return *this; } // yes, prefix only
+ bool operator==(const audio_iterator& other) { return (_index == other._index); }
+ bool operator!=(const audio_iterator& other) { return (_index != other._index); }
+
+ private:
+ friend class PortSet;
+
+ audio_iterator(PortSet& list, size_t index) : _set(list), _index(index) {}
+
+ PortSet& _set;
+ size_t _index;
+ };
+
+ audio_iterator audio_begin() { return audio_iterator(*this, 0); }
+ audio_iterator audio_end() { return audio_iterator(*this, _count.n_audio()); }
+
+private:
+ // Prevent copies (undefined)
+ PortSet(const PortSet& copy);
+ void operator=(const PortSet& other);
+
+ typedef std::vector<Port*> PortVec;
+
+ // Vector of vectors, indexed by DataType::to_index()
+ std::vector<PortVec> _ports;
+
+ ChanCount _count;
+};
+
+
+} // namespace ARDOUR
+
+#endif // __ardour_port_set_h__
diff --git a/libs/ardour/ardour/processor.h b/libs/ardour/ardour/processor.h
new file mode 100644
index 0000000000..d3e95e8ebf
--- /dev/null
+++ b/libs/ardour/ardour/processor.h
@@ -0,0 +1,123 @@
+/*
+ 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.
+
+*/
+
+#ifndef __ardour_processor_h__
+#define __ardour_processor_h__
+
+#include <vector>
+#include <string>
+#include <exception>
+
+#include <pbd/statefuldestructible.h>
+
+#include <sigc++/signal.h>
+
+#include <ardour/types.h>
+#include <ardour/ardour.h>
+#include <ardour/buffer_set.h>
+#include <ardour/automatable.h>
+#include <ardour/latent.h>
+
+class XMLNode;
+
+namespace ARDOUR {
+
+class Session;
+
+/* A mixer strip element - plugin, send, meter, etc.
+ */
+class Processor : public Automatable, public Latent
+{
+ public:
+ static const string state_node_name;
+
+ Processor(Session&, const string& name, Placement p); // TODO: remove placement in favour of sort key
+
+ virtual ~Processor() { }
+
+ static boost::shared_ptr<Processor> clone (boost::shared_ptr<const Processor>);
+
+ uint32_t sort_key() const { return _sort_key; }
+ void set_sort_key (uint32_t key);
+
+ Placement placement() const { return _placement; }
+ void set_placement (Placement);
+
+ bool active () const { return _active; }
+ void set_active (bool yn);
+
+ bool get_next_ab_is_active () const { return _next_ab_is_active; }
+ void set_next_ab_is_active (bool yn) { _next_ab_is_active = yn; }
+
+ virtual nframes_t signal_latency() const { return 0; }
+
+ virtual void transport_stopped (nframes_t frame) {}
+
+ virtual void set_block_size (nframes_t nframes) {}
+
+ virtual void run_in_place (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset) { assert(is_in_place()); }
+
+ virtual void run_out_of_place (BufferSet& input, BufferSet& output, nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset) { assert(is_out_of_place()); }
+
+ virtual void silence (nframes_t nframes, nframes_t offset) {}
+
+ virtual void activate () { _active = true; ActiveChanged.emit(); }
+ virtual void deactivate () { _active = false; ActiveChanged.emit(); }
+
+ virtual bool configure_io (ChanCount in, ChanCount out) { _configured_input = in; return (_configured = true); }
+
+ /* Derived classes should override these, or processor appears as an in-place pass-through */
+
+ /** In-place processors implement run_in_place and modify thee input buffer parameter */
+ virtual bool is_in_place () const { return true; }
+
+ /* Out-Of-Place processors implement run_out_of_place, don't modify the input parameter
+ * and write to their output parameter */
+ virtual bool is_out_of_place () const { return false; }
+
+ virtual bool can_support_input_configuration (ChanCount in) const { return true; }
+ virtual ChanCount output_for_input_configuration (ChanCount in) const { return in; }
+ virtual ChanCount output_streams() const { return _configured_input; }
+ virtual ChanCount input_streams () const { return _configured_input; }
+
+ virtual XMLNode& state (bool full);
+ virtual XMLNode& get_state (void);
+ virtual int set_state (const XMLNode&);
+
+ void *get_gui () const { return _gui; }
+ void set_gui (void *p) { _gui = p; }
+
+ static sigc::signal<void,Processor*> ProcessorCreated;
+
+ sigc::signal<void> ActiveChanged;
+ sigc::signal<void> PlacementChanged;
+
+protected:
+ bool _active;
+ bool _next_ab_is_active;
+ bool _configured;
+ ChanCount _configured_input;
+ Placement _placement;
+ uint32_t _sort_key;
+ void* _gui; /* generic, we don't know or care what this is */
+};
+
+} // namespace ARDOUR
+
+#endif /* __ardour_processor_h__ */
diff --git a/libs/ardour/ardour/profile.h b/libs/ardour/ardour/profile.h
new file mode 100644
index 0000000000..b016063c4d
--- /dev/null
+++ b/libs/ardour/ardour/profile.h
@@ -0,0 +1,58 @@
+/*
+ Copyright (C) 2000-2007 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_profile_h__
+#define __ardour_profile_h__
+
+#include <boost/dynamic_bitset.hpp>
+#include <stdint.h>
+
+namespace ARDOUR {
+
+class RuntimeProfile {
+ public:
+ enum Element {
+ SmallScreen,
+ SAE,
+ SinglePackage,
+ LastElement
+ };
+
+ RuntimeProfile() { bits.resize (LastElement); }
+ ~RuntimeProfile() {}
+
+ void set_small_screen() { bits[SmallScreen] = true; }
+ bool get_small_screen() const { return bits[SmallScreen]; }
+
+ void set_sae () { bits[SAE] = true; }
+ bool get_sae () const { return bits[SAE]; }
+
+ void set_single_package () { bits[SinglePackage] = true; }
+ bool get_single_package () const { return bits[SinglePackage]; }
+
+ private:
+ boost::dynamic_bitset<uint64_t> bits;
+
+};
+
+extern RuntimeProfile* Profile;
+
+}; // namespace ARDOUR
+
+#endif /* __ardour_profile_h__ */
diff --git a/libs/ardour/ardour/quantize.h b/libs/ardour/ardour/quantize.h
new file mode 100644
index 0000000000..143652dc63
--- /dev/null
+++ b/libs/ardour/ardour/quantize.h
@@ -0,0 +1,41 @@
+/*
+ Copyright (C) 2007 Paul Davis
+ Author: Dave Robillard
+
+ 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_quantize_h__
+#define __ardour_quantize_h__
+
+#include <ardour/filter.h>
+
+namespace ARDOUR {
+
+class Quantize : public Filter {
+public:
+ Quantize (ARDOUR::Session&, double q);
+ ~Quantize ();
+
+ int run (boost::shared_ptr<ARDOUR::Region>);
+
+private:
+ double _q;
+};
+
+} /* namespace */
+
+#endif /* __ardour_quantize_h__ */
diff --git a/libs/ardour/ardour/rb_effect.h b/libs/ardour/ardour/rb_effect.h
new file mode 100644
index 0000000000..a536a309b3
--- /dev/null
+++ b/libs/ardour/ardour/rb_effect.h
@@ -0,0 +1,42 @@
+/*
+ Copyright (C) 2007 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_rbeffect_h__
+#define __ardour_rbeffect_h__
+
+#include <ardour/filter.h>
+
+namespace ARDOUR {
+
+class AudioRegion;
+
+class RBEffect : public Filter {
+ public:
+ RBEffect (ARDOUR::Session&, TimeFXRequest&);
+ ~RBEffect ();
+
+ int run (boost::shared_ptr<ARDOUR::Region>);
+
+ private:
+ TimeFXRequest& tsr;
+};
+
+} /* namespace */
+
+#endif /* __ardour_rbeffect_h__ */
diff --git a/libs/ardour/ardour/readable.h b/libs/ardour/ardour/readable.h
new file mode 100644
index 0000000000..e072a1c95e
--- /dev/null
+++ b/libs/ardour/ardour/readable.h
@@ -0,0 +1,20 @@
+#ifndef __ardour_readable_h__
+#define __ardour_readable_h__
+
+#include <ardour/types.h>
+
+namespace ARDOUR {
+
+class Readable {
+ public:
+ Readable () {}
+ virtual ~Readable() {}
+
+ virtual nframes64_t read (Sample*, nframes64_t pos, nframes64_t cnt, int channel) const = 0;
+ virtual nframes64_t readable_length() const = 0;
+ virtual uint32_t n_channels () const = 0;
+};
+
+}
+
+#endif /* __ardour_readable_h__ */
diff --git a/libs/ardour/ardour/recent_sessions.h b/libs/ardour/ardour/recent_sessions.h
new file mode 100644
index 0000000000..e32b67bcd8
--- /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/region.h b/libs/ardour/ardour/region.h
new file mode 100644
index 0000000000..00315846b2
--- /dev/null
+++ b/libs/ardour/ardour/region.h
@@ -0,0 +1,313 @@
+/*
+ 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.
+
+*/
+
+#ifndef __ardour_region_h__
+#define __ardour_region_h__
+
+#include <vector>
+#include <boost/shared_ptr.hpp>
+#include <boost/enable_shared_from_this.hpp>
+
+#include <pbd/undo.h>
+
+#include <ardour/ardour.h>
+#include <ardour/data_type.h>
+#include <ardour/automatable.h>
+#include <ardour/readable.h>
+
+class XMLNode;
+
+namespace ARDOUR {
+
+class Playlist;
+class Filter;
+class ExportSpecification;
+
+enum RegionEditState {
+ EditChangesNothing = 0,
+ EditChangesName = 1,
+ EditChangesID = 2
+};
+
+class Region : public Automatable, public boost::enable_shared_from_this<Region>, public Readable
+{
+ public:
+ typedef std::vector<boost::shared_ptr<Source> > SourceList;
+
+ 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,
+ PositionLocked = 0x40000,
+ //
+ range_guarantoor = USHRT_MAX
+ };
+
+ enum PositionLockStyle {
+ AudioTime,
+ MusicTime
+ };
+
+ 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;
+
+ sigc::signal<void,Change> StateChanged;
+
+ virtual ~Region();
+
+ /** Note: changing the name of a Region does not constitute an edit */
+ bool set_name (const std::string& str);
+
+ const DataType& data_type() const { return _type; }
+
+ /**
+ * Thats how the region parameters play together:
+ * <PRE>
+ * |------------------------------------------------------------------- track
+ * |..........[------------------].....| region
+ * |-----------------------------| _position
+ * |------------------| _length
+ * |----------| _start
+ * </PRE>
+ */
+ nframes_t position () const { return _position; }
+ nframes_t start () const { return _start; }
+ nframes_t length() const { return _length; }
+ layer_t layer () const { return _layer; }
+
+ /* these two are valid ONLY during a StateChanged signal handler */
+
+ nframes_t last_position() const { return _last_position; }
+ nframes_t last_length() const { return _last_length; }
+
+ nframes64_t ancestral_start () const { return _ancestral_start; }
+ nframes64_t ancestral_length () const { return _ancestral_length; }
+ float stretch() const { return _stretch; }
+ float shift() const { return _shift; }
+
+ void set_ancestral_data (nframes64_t start, nframes64_t length, float stretch, float shift);
+
+ nframes_t sync_offset(int& dir) const;
+ nframes_t sync_position() const;
+
+ nframes_t adjust_to_sync (nframes_t);
+
+ /* first_frame() is an alias; last_frame() just hides some math */
+
+ nframes_t first_frame() const { return _position; }
+ nframes_t last_frame() const { return _position + _length - 1; }
+
+ Flag flags() const { return _flags; }
+ bool hidden() const { return _flags & Hidden; }
+ bool muted() const { return _flags & Muted; }
+ bool opaque () const { return _flags & Opaque; }
+ bool locked() const { return _flags & Locked; }
+ bool position_locked() const { return _flags & PositionLocked; }
+ bool automatic() const { return _flags & Automatic; }
+ bool whole_file() const { return _flags & WholeFile ; }
+ bool captured() const { return !(_flags & (Region::Flag (Region::Import|Region::External))); }
+ bool can_move() const { return !(_flags & (Locked|PositionLocked)); }
+
+ PositionLockStyle positional_lock_style() const { return _positional_lock_style; }
+ void set_position_lock_style (PositionLockStyle ps);
+ void recompute_position_from_lock_style ();
+
+ virtual bool should_save_state () const { return !(_flags & DoNotSaveState); };
+
+ void freeze ();
+ void thaw (const string& why);
+
+ bool covers (nframes_t frame) const {
+ return first_frame() <= frame && frame <= last_frame();
+ }
+
+ OverlapType coverage (nframes_t start, nframes_t end) const {
+ return ARDOUR::coverage (first_frame(), last_frame(), start, end);
+ }
+
+ bool equivalent (boost::shared_ptr<const Region>) const;
+ bool size_equivalent (boost::shared_ptr<const Region>) const;
+ bool overlap_equivalent (boost::shared_ptr<const Region>) const;
+ bool region_list_equivalent (boost::shared_ptr<const Region>) const;
+ bool source_equivalent (boost::shared_ptr<const Region>) const;
+
+ /* EDITING OPERATIONS */
+
+ void set_length (nframes_t, void *src);
+ void set_start (nframes_t, void *src);
+ void set_position (nframes_t, void *src);
+ void set_position_on_top (nframes_t, void *src);
+ void special_set_position (nframes_t);
+ void update_position_after_tempo_map_change ();
+ void nudge_position (nframes64_t, void *src);
+
+ bool at_natural_position () const;
+ void move_to_natural_position (void *src);
+
+ void trim_start (nframes_t new_position, void *src);
+ void trim_front (nframes_t new_position, void *src);
+ void trim_end (nframes_t new_position, void *src);
+ void trim_to (nframes_t position, 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 (nframes_t n);
+ void clear_sync_position ();
+ void set_hidden (bool yn);
+ void set_muted (bool yn);
+ void set_opaque (bool yn);
+ void set_locked (bool yn);
+ void set_position_locked (bool yn);
+
+ int apply (Filter&);
+
+ virtual uint32_t read_data_count() const { return _read_data_count; }
+
+ boost::shared_ptr<ARDOUR::Playlist> playlist() const { return _playlist.lock(); }
+ virtual void set_playlist (boost::weak_ptr<ARDOUR::Playlist>);
+
+ void source_deleted (boost::shared_ptr<Source>);
+
+ boost::shared_ptr<Source> source (uint32_t n=0) const { return _sources[ (n < _sources.size()) ? n : 0 ]; }
+ uint32_t n_channels() const { return _sources.size(); }
+
+ const SourceList& sources() const { return _sources; }
+ const SourceList& master_sources() const { return _master_sources; }
+
+ std::vector<string> master_source_names();
+ void set_master_sources (SourceList&);
+
+ /* serialization */
+
+ XMLNode& get_state ();
+ virtual XMLNode& state (bool);
+ virtual int set_state (const XMLNode&);
+ virtual int set_live_state (const XMLNode&, Change&, bool send);
+
+ virtual boost::shared_ptr<Region> get_parent() const;
+
+ uint64_t last_layer_op() const { return _last_layer_op; }
+ void set_last_layer_op (uint64_t when);
+
+ virtual bool is_dependent() const { return false; }
+ virtual bool depends_on (boost::shared_ptr<Region> other) const { return false; }
+
+ virtual int exportme (ARDOUR::Session&, ARDOUR::ExportSpecification&) = 0;
+
+ virtual int get_transients (AnalysisFeatureList&, bool force_new = false) {
+ // no transients, but its OK
+ return 0;
+ }
+
+ void invalidate_transients ();
+
+ protected:
+ friend class RegionFactory;
+
+ Region (boost::shared_ptr<Source> src, nframes_t start, nframes_t length,
+ const string& name, DataType type, layer_t = 0, Flag flags = DefaultFlags);
+ Region (const SourceList& srcs, nframes_t start, nframes_t length,
+ const string& name, DataType type, layer_t = 0, Flag flags = DefaultFlags);
+
+ Region (boost::shared_ptr<const Region>, nframes_t start, nframes_t length, const string& name, layer_t = 0, Flag flags = DefaultFlags);
+ Region (boost::shared_ptr<const Region>);
+ Region (boost::shared_ptr<Source> src, const XMLNode&);
+ Region (const SourceList& srcs, const XMLNode&);
+
+ Region (Session& s, nframes_t start, nframes_t length, const string& name, DataType, layer_t = 0, Flag flags = DefaultFlags);
+
+ protected:
+ XMLNode& get_short_state (); /* used only by Session */
+
+ void send_change (Change);
+
+ void trim_to_internal (nframes_t position, nframes_t length, void *src);
+ void set_position_internal (nframes_t pos, bool allow_bbt_recompute);
+
+ bool copied() const { return _flags & Copied; }
+ void maybe_uncopy ();
+ void first_edit ();
+
+ bool verify_start (nframes_t);
+ bool verify_start_and_length (nframes_t, nframes_t&);
+ bool verify_start_mutable (nframes_t&_start);
+ bool verify_length (nframes_t);
+
+ virtual void recompute_at_start () = 0;
+ virtual void recompute_at_end () = 0;
+
+ DataType _type;
+ Flag _flags;
+ nframes_t _start;
+ nframes_t _length;
+ nframes_t _last_length;
+ nframes_t _position;
+ nframes_t _last_position;
+ PositionLockStyle _positional_lock_style;
+ nframes_t _sync_position;
+ layer_t _layer;
+ mutable RegionEditState _first_edit;
+ int _frozen;
+ nframes64_t _ancestral_start;
+ nframes64_t _ancestral_length;
+ float _stretch;
+ float _shift;
+ BBT_Time _bbt_time;
+ AnalysisFeatureList _transients;
+ bool _valid_transients;
+ mutable uint32_t _read_data_count; ///< modified in read()
+ Change _pending_changed;
+ uint64_t _last_layer_op; ///< timestamp
+ Glib::Mutex _lock;
+ SourceList _sources;
+ /** Used when timefx are applied, so we can always use the original source */
+ SourceList _master_sources;
+
+ boost::weak_ptr<ARDOUR::Playlist> _playlist;
+};
+
+} /* 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..12437ba998
--- /dev/null
+++ b/libs/ardour/ardour/region_factory.h
@@ -0,0 +1,64 @@
+/*
+ Copyright (C) 2000-2007 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_region_factory_h__
+#define __ardour_region_factory_h__
+
+#include <ardour/types.h>
+#include <ardour/region.h>
+
+class XMLNode;
+
+namespace ARDOUR {
+
+class Session;
+
+class RegionFactory {
+
+ public:
+ /** 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,boost::shared_ptr<Region> > CheckNewRegion;
+
+ static boost::shared_ptr<Region> create (boost::shared_ptr<const Region>);
+
+ /* note: both of the first two should use const shared_ptr as well, but
+ gcc 4.1 doesn't seem to be able to disambiguate them if they do.
+ */
+
+ static boost::shared_ptr<Region> create (boost::shared_ptr<Region>, nframes_t start,
+ nframes_t length, std::string name,
+ layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true);
+ static boost::shared_ptr<Region> create (boost::shared_ptr<AudioRegion>, nframes_t start,
+ nframes_t length, std::string name,
+ layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true);
+ static boost::shared_ptr<Region> create (boost::shared_ptr<Source>, nframes_t start, nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true);
+ static boost::shared_ptr<Region> create (const SourceList &, nframes_t start, nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true);
+ static boost::shared_ptr<Region> create (Session&, XMLNode&, bool);
+ static boost::shared_ptr<Region> create (SourceList &, const XMLNode&);
+};
+
+}
+
+#endif /* __ardour_region_factory_h__ */
diff --git a/libs/ardour/ardour/resampled_source.h b/libs/ardour/ardour/resampled_source.h
new file mode 100644
index 0000000000..6eca4cda98
--- /dev/null
+++ b/libs/ardour/ardour/resampled_source.h
@@ -0,0 +1,55 @@
+/*
+ Copyright (C) 2007 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_resampled_source_h__
+#define __ardour_resampled_source_h__
+
+#include <samplerate.h>
+
+#include <ardour/types.h>
+#include <ardour/importable_source.h>
+
+namespace ARDOUR {
+
+class ResampledImportableSource : public ImportableSource
+{
+ public:
+ ResampledImportableSource (boost::shared_ptr<ImportableSource>, nframes_t rate, SrcQuality);
+
+ ~ResampledImportableSource ();
+
+ nframes_t read (Sample* buffer, nframes_t nframes);
+ float ratio() const { return src_data.src_ratio; }
+ uint32_t channels() const { return source->channels(); }
+ nframes_t length() const { return source->length(); }
+ nframes_t samplerate() const { return source->samplerate(); }
+ void seek (nframes_t pos) { source->seek (pos); }
+
+ static const uint32_t blocksize;
+
+ private:
+ boost::shared_ptr<ImportableSource> source;
+ float* input;
+ SRC_STATE* src_state;
+ SRC_DATA src_data;
+};
+
+}
+
+#endif /* __ardour_resampled_source_h__ */
diff --git a/libs/ardour/ardour/reverse.h b/libs/ardour/ardour/reverse.h
new file mode 100644
index 0000000000..7870b5aa2e
--- /dev/null
+++ b/libs/ardour/ardour/reverse.h
@@ -0,0 +1,37 @@
+/*
+ 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_reverse_h__
+#define __ardour_reverse_h__
+
+#include <ardour/filter.h>
+
+namespace ARDOUR {
+
+class Reverse : public Filter {
+ public:
+ Reverse (ARDOUR::Session&);
+ ~Reverse ();
+
+ int run (boost::shared_ptr<ARDOUR::Region>);
+};
+
+} /* 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..c7c0b77102
--- /dev/null
+++ b/libs/ardour/ardour/route.h
@@ -0,0 +1,384 @@
+/*
+ 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.
+
+*/
+
+#ifndef __ardour_route_h__
+#define __ardour_route_h__
+
+#include <cmath>
+#include <list>
+#include <set>
+#include <map>
+#include <string>
+
+#include <boost/shared_ptr.hpp>
+
+#include <pbd/fastlog.h>
+#include <glibmm/thread.h>
+#include <pbd/xml++.h>
+#include <pbd/undo.h>
+#include <pbd/stateful.h>
+#include <pbd/controllable.h>
+#include <pbd/destructible.h>
+
+#include <ardour/ardour.h>
+#include <ardour/io.h>
+#include <ardour/session.h>
+#include <ardour/io_processor.h>
+#include <ardour/types.h>
+
+namespace ARDOUR {
+
+class Processor;
+class Send;
+class RouteGroup;
+
+enum mute_type {
+ PRE_FADER = 0x1,
+ POST_FADER = 0x2,
+ CONTROL_OUTS = 0x4,
+ MAIN_OUTS = 0x8
+};
+
+class Route : public IO
+{
+ protected:
+
+ typedef list<boost::shared_ptr<Processor> > ProcessorList;
+
+ 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), DataType default_type = DataType::AUDIO);
+ Route (Session&, const XMLNode&, DataType default_type = DataType::AUDIO);
+ virtual ~Route();
+
+ static std::string ensure_track_or_route_name(std::string, Session &);
+
+ std::string comment() { return _comment; }
+ void set_comment (std::string str, void *src);
+
+ long order_key (const char* name) const;
+ void set_order_key (const char* name, long n);
+
+ bool is_hidden() const { return _flags & Hidden; }
+ bool is_master() const { return _flags & MasterOut; }
+ bool is_control() const { return _flags & ControlOut; }
+
+ /* these are the core of the API of a Route. see the protected sections as well */
+
+
+ virtual int roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
+ nframes_t offset, int declick, bool can_record, bool rec_monitors_input);
+
+ virtual int no_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
+ nframes_t offset, bool state_changing, bool can_record, bool rec_monitors_input);
+
+ virtual int silent_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
+ nframes_t offset, bool can_record, bool rec_monitors_input);
+ virtual void toggle_monitor_input ();
+ virtual bool can_record() { return false; }
+ virtual void set_record_enable (bool yn, void *src) {}
+ virtual bool record_enabled() const { return false; }
+ virtual void handle_transport_stopped (bool abort, bool did_locate, bool flush_processors);
+ 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);
+
+ 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; }
+ bool solo_muted() const { return desired_solo_gain == 0.0; }
+
+ void set_mute_config (mute_type, bool, void *src);
+ bool get_mute_config (mute_type);
+
+ void set_edit_group (RouteGroup *, void *);
+ void drop_edit_group (void *);
+ RouteGroup *edit_group () { return _edit_group; }
+
+ void set_mix_group (RouteGroup *, void *);
+ void drop_mix_group (void *);
+ RouteGroup *mix_group () { return _mix_group; }
+
+ virtual void set_meter_point (MeterPoint, void *src);
+ MeterPoint meter_point() const { return _meter_point; }
+
+ /* Processors */
+
+ void flush_processors ();
+
+ template<class T> void foreach_processor (T *obj, void (T::*func)(boost::shared_ptr<Processor>)) {
+ Glib::RWLock::ReaderLock lm (_processor_lock);
+ for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
+ (obj->*func) (*i);
+ }
+ }
+
+ boost::shared_ptr<Processor> nth_processor (uint32_t n) {
+ Glib::RWLock::ReaderLock lm (_processor_lock);
+ ProcessorList::iterator i;
+ for (i = _processors.begin(); i != _processors.end() && n; ++i, --n);
+ if (i == _processors.end()) {
+ return boost::shared_ptr<IOProcessor> ();
+ } else {
+ return *i;
+ }
+ }
+
+ ChanCount max_processor_outs () const { return processor_max_outs; }
+ ChanCount pre_fader_streams() const;
+
+ /** A record of the stream configuration at some point in the processor list.
+ * Used to return where and why an processor list configuration request failed.
+ */
+ struct ProcessorStreams {
+ ProcessorStreams(size_t i=0, ChanCount c=ChanCount()) : index(i), count(c) {}
+
+ size_t index; ///< Index of processor where configuration failed
+ ChanCount count; ///< Input requested of processor
+ };
+
+ int add_processor (boost::shared_ptr<Processor>, ProcessorStreams* err = 0);
+ int add_processors (const ProcessorList&, ProcessorStreams* err = 0);
+ int remove_processor (boost::shared_ptr<Processor>, ProcessorStreams* err = 0);
+ int copy_processors (const Route&, Placement, ProcessorStreams* err = 0);
+ int sort_processors (ProcessorStreams* err = 0);
+ void disable_processors (Placement);
+ void disable_processors ();
+ void disable_plugins (Placement);
+ void disable_plugins ();
+ void ab_plugins (bool forward);
+ void clear_processors (Placement);
+ void all_processors_flip();
+ void all_processors_active (Placement, bool state);
+
+ virtual nframes_t update_total_latency();
+ void set_latency_delay (nframes_t);
+ void set_user_latency (nframes_t);
+ nframes_t initial_delay() const { return _initial_delay; }
+
+ 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> processors_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,void*> meter_change;
+ sigc::signal<void> signal_latency_changed;
+ sigc::signal<void> initial_delay_changed;
+
+ /* 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);
+ virtual XMLNode& get_template();
+
+ XMLNode& get_processor_state ();
+ int set_processor_state (const XMLNode&);
+
+ sigc::signal<void,void*> SelectedChanged;
+
+ int set_control_outs (const vector<std::string>& ports);
+ IO* control_outs() { return _control_outs; }
+
+ bool feeds (boost::shared_ptr<Route>);
+ set<boost::shared_ptr<Route> > fed_by;
+
+ struct ToggleControllable : public PBD::Controllable {
+ enum ToggleType {
+ MuteControl = 0,
+ SoloControl
+ };
+
+ ToggleControllable (std::string name, Route&, ToggleType);
+ void set_value (float);
+ float get_value (void) const;
+
+ Route& route;
+ ToggleType type;
+ };
+
+ boost::shared_ptr<PBD::Controllable> solo_control() {
+ return _solo_control;
+ }
+
+ boost::shared_ptr<PBD::Controllable> mute_control() {
+ return _mute_control;
+ }
+
+ void automation_snapshot (nframes_t now, bool force=false);
+ void protect_automation ();
+
+ void set_remote_control_id (uint32_t id);
+ uint32_t remote_control_id () const;
+ sigc::signal<void> RemoteControlIDChanged;
+
+ void sync_order_keys ();
+ static sigc::signal<void> SyncOrderKeys;
+
+ protected:
+ friend class Session;
+
+ void set_solo_mute (bool yn);
+ void set_block_size (nframes_t nframes);
+ bool has_external_redirects() const;
+ void curve_reallocate ();
+
+ protected:
+ Flag _flags;
+
+ /* tight cache-line access here is more important than sheer speed of
+ access.
+ */
+
+ bool _muted : 1;
+ bool _soloed : 1;
+ bool _solo_safe : 1;
+ bool _recordable : 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;
+
+
+
+ nframes_t _initial_delay;
+ nframes_t _roll_delay;
+ ProcessorList _processors;
+ Glib::RWLock _processor_lock;
+ IO *_control_outs;
+ Glib::Mutex _control_outs_lock;
+ RouteGroup *_edit_group;
+ RouteGroup *_mix_group;
+ std::string _comment;
+ bool _have_internal_generator;
+
+ boost::shared_ptr<ToggleControllable> _solo_control;
+ boost::shared_ptr<ToggleControllable> _mute_control;
+
+ nframes_t check_initial_delay (nframes_t, nframes_t&, nframes_t&);
+
+ void passthru (nframes_t start_frame, nframes_t end_frame,
+ nframes_t nframes, nframes_t offset, int declick, bool meter_inputs);
+
+ virtual void process_output_buffers (BufferSet& bufs,
+ nframes_t start_frame, nframes_t end_frame,
+ nframes_t nframes, nframes_t offset, bool with_processors, int declick,
+ bool meter);
+
+ protected:
+
+ virtual XMLNode& state(bool);
+
+ void passthru_silence (nframes_t start_frame, nframes_t end_frame,
+ nframes_t nframes, nframes_t offset, int declick,
+ bool meter);
+
+ void silence (nframes_t nframes, nframes_t offset);
+
+ sigc::connection input_signal_connection;
+
+ ChanCount processor_max_outs;
+ uint32_t _remote_control_id;
+
+ uint32_t pans_required() const;
+ ChanCount n_process_buffers ();
+
+ virtual int _set_state (const XMLNode&, bool call_base);
+ virtual void _set_processor_states (const XMLNodeList&);
+
+ private:
+ void init ();
+
+ static uint32_t order_key_cnt;
+
+ struct ltstr
+ {
+ bool operator()(const char* s1, const char* s2) const
+ {
+ return strcmp(s1, s2) < 0;
+ }
+ };
+
+ typedef std::map<const char*,long,ltstr> OrderKeys;
+ OrderKeys order_keys;
+
+ void input_change_handler (IOChange, void *src);
+ void output_change_handler (IOChange, void *src);
+
+ int reset_plugin_counts (ProcessorStreams*); /* locked */
+ int _reset_plugin_counts (ProcessorStreams*); /* unlocked */
+
+ /* processor I/O channels and plugin count handling */
+
+ struct ProcessorCount {
+ boost::shared_ptr<ARDOUR::Processor> processor;
+ ChanCount in;
+ ChanCount out;
+
+ ProcessorCount (boost::shared_ptr<ARDOUR::Processor> ins) : processor(ins) {}
+ };
+
+ int32_t apply_some_plugin_counts (std::list<ProcessorCount>& iclist);
+ bool check_some_plugin_counts (std::list<ProcessorCount>& iclist, ChanCount required_inputs, ProcessorStreams* err_streams);
+
+ void set_deferred_state ();
+ void add_processor_from_xml (const XMLNode&);
+};
+
+} // 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..ae16394289
--- /dev/null
+++ b/libs/ardour/ardour/route_group.h
@@ -0,0 +1,124 @@
+/*
+ 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.
+
+*/
+
+#ifndef __ardour_route_group_h__
+#define __ardour_route_group_h__
+
+#include <list>
+#include <set>
+#include <string>
+#include <stdint.h>
+#include <sigc++/signal.h>
+#include <pbd/stateful.h>
+#include <ardour/types.h>
+
+using std::string;
+using std::list;
+
+namespace ARDOUR {
+
+class Route;
+class Track;
+class AudioTrack;
+class Session;
+
+class RouteGroup : public PBD::Stateful, public sigc::trackable {
+ public:
+ enum Flag {
+ Relative = 0x1,
+ Active = 0x2,
+ Hidden = 0x4
+ };
+
+ RouteGroup (Session& s, const string &n, Flag f = Flag(0));
+
+ const string& name() { return _name; }
+ void set_name (std::string str);
+
+ 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 *);
+
+ void apply (void (Route::*func)(void *), void *src) {
+ for (list<Route *>::iterator i = routes.begin(); i != routes.end(); i++) {
+ ((*i)->*func)(src);
+ }
+ }
+
+ 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, src);
+ }
+ }
+
+ 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 (Track::*func)(T, void *), T val, void *src);
+
+ /* fills at_set with all members of the group that are AudioTracks */
+
+ void audio_track_group (std::set<AudioTrack*>& at_set);
+
+ 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:
+ Session& _session;
+ list<Route *> routes;
+ string _name;
+ Flag _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..9e04c46d0e
--- /dev/null
+++ b/libs/ardour/ardour/route_group_specialized.h
@@ -0,0 +1,41 @@
+/*
+ Copyright (C) 2000-2007 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_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 (Track::*func)(T, void *), T val, void *src)
+{
+ for (list<Route *>::iterator i = routes.begin(); i != routes.end(); i++) {
+ Track *at;
+ if ((at = dynamic_cast<Track*>(*i)) != 0) {
+ (at->*func)(val, this);
+ }
+ }
+}
+
+} /* namespace ARDOUR */
+
+#endif /* __ardour_route_group_specialized_h__ */
diff --git a/libs/ardour/ardour/runtime_functions.h b/libs/ardour/ardour/runtime_functions.h
new file mode 100644
index 0000000000..c1dab4ebc7
--- /dev/null
+++ b/libs/ardour/ardour/runtime_functions.h
@@ -0,0 +1,40 @@
+/*
+ Copyright (C) 2007 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_runtime_functions_h__
+#define __ardour_runtime_functions_h__
+
+#include <ardour/types.h>
+
+namespace ARDOUR {
+
+ typedef float (*compute_peak_t) (const ARDOUR::Sample *, nframes_t, float);
+ typedef void (*find_peaks_t) (const ARDOUR::Sample *, nframes_t, float *, float*);
+ typedef void (*apply_gain_to_buffer_t) (ARDOUR::Sample *, nframes_t, float);
+ typedef void (*mix_buffers_with_gain_t) (ARDOUR::Sample *, const ARDOUR::Sample *, nframes_t, float);
+ typedef void (*mix_buffers_no_gain_t) (ARDOUR::Sample *, const ARDOUR::Sample *, nframes_t);
+
+ extern compute_peak_t compute_peak;
+ extern find_peaks_t find_peaks;
+ extern apply_gain_to_buffer_t apply_gain_to_buffer;
+ extern mix_buffers_with_gain_t mix_buffers_with_gain;
+ extern mix_buffers_no_gain_t mix_buffers_no_gain;
+}
+
+#endif /* __ardour_runtime_functions_h__ */
diff --git a/libs/ardour/ardour/send.h b/libs/ardour/ardour/send.h
new file mode 100644
index 0000000000..1ee8bbceca
--- /dev/null
+++ b/libs/ardour/ardour/send.h
@@ -0,0 +1,74 @@
+/*
+ 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.
+
+*/
+
+#ifndef __ardour_send_h__
+#define __ardour_send_h__
+
+#include <sigc++/signal.h>
+#include <string>
+
+
+#include <pbd/stateful.h>
+#include <ardour/ardour.h>
+#include <ardour/audioengine.h>
+#include <ardour/io.h>
+#include <ardour/io_processor.h>
+
+namespace ARDOUR {
+
+class Send : public IOProcessor
+{
+ public:
+ Send (Session&, Placement);
+ Send (Session&, const XMLNode&);
+ Send (const Send&);
+ virtual ~Send ();
+
+ uint32_t bit_slot() const { return bitslot; }
+
+ ChanCount output_streams() const;
+ ChanCount input_streams () const;
+
+ void run_in_place (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame, nframes_t nframes, 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 _configured_input.n_audio(); }
+
+ virtual bool can_support_input_configuration (ChanCount in) const;
+ virtual ChanCount output_for_input_configuration (ChanCount in) const;
+ virtual bool configure_io (ChanCount in, ChanCount out);
+
+ static uint32_t how_many_sends();
+
+ private:
+ bool _metering;
+ uint32_t bitslot;
+};
+
+} // namespace ARDOUR
+
+#endif /* __ardour_send_h__ */
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
new file mode 100644
index 0000000000..b718d751b4
--- /dev/null
+++ b/libs/ardour/ardour/session.h
@@ -0,0 +1,1714 @@
+/*
+ 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.
+
+*/
+
+#ifndef __ardour_session_h__
+#define __ardour_session_h__
+
+#include <string>
+#include <list>
+#include <map>
+#include <vector>
+#include <set>
+#include <stack>
+
+#include <boost/scoped_ptr.hpp>
+#include <boost/weak_ptr.hpp>
+#include <boost/dynamic_bitset.hpp>
+
+#include <stdint.h>
+
+#include <sndfile.h>
+
+#include <glibmm/thread.h>
+
+#include <pbd/error.h>
+#include <pbd/undo.h>
+#include <pbd/pool.h>
+#include <pbd/rcu.h>
+#include <pbd/statefuldestructible.h>
+
+#include <midi++/types.h>
+#include <midi++/mmc.h>
+
+#include <pbd/stateful.h>
+#include <pbd/destructible.h>
+
+#include <ardour/ardour.h>
+#include <ardour/configuration.h>
+#include <ardour/location.h>
+#include <ardour/gain.h>
+#include <ardour/io.h>
+
+#include <ardour/smpte.h>
+
+class XMLTree;
+class XMLNode;
+class AEffect;
+
+namespace MIDI {
+ class Port;
+}
+
+namespace PBD {
+ class Controllable;
+}
+
+namespace ARDOUR {
+
+class Port;
+class AudioEngine;
+class Slave;
+class Diskstream;
+class Route;
+class AuxInput;
+class Source;
+class AudioSource;
+class BufferSet;
+
+class Diskstream;
+class AudioDiskstream;
+class MidiDiskstream;
+class AudioFileSource;
+class MidiSource;
+class Auditioner;
+class Processor;
+class Send;
+class IOProcessor;
+class PortInsert;
+class PluginInsert;
+class Bundle;
+class TempoMap;
+class AudioTrack;
+class NamedSelection;
+class AudioRegion;
+
+class Region;
+class Playlist;
+class VSTPlugin;
+class ControlProtocolInfo;
+
+class MidiTrack;
+class MidiRegion;
+class SMFSource;
+
+class SessionDirectory;
+
+struct ExportSpecification;
+struct RouteGroup;
+
+using std::vector;
+using std::string;
+using std::map;
+using std::set;
+
+class Session : public PBD::StatefulDestructible
+{
+ private:
+ typedef std::pair<boost::weak_ptr<Route>,bool> RouteBooleanState;
+ typedef vector<RouteBooleanState> GlobalRouteBooleanState;
+ typedef std::pair<boost::weak_ptr<Route>,MeterPoint> RouteMeterState;
+ typedef vector<RouteMeterState> GlobalRouteMeterState;
+
+ public:
+ enum RecordState {
+ Disabled = 0,
+ Enabled = 1,
+ Recording = 2
+ };
+
+ struct Event {
+ enum Type {
+ SetTransportSpeed,
+ SetDiskstreamSpeed,
+ Locate,
+ LocateRoll,
+ LocateRollLocate,
+ 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;
+ nframes_t action_frame;
+ nframes_t target_frame;
+ float speed;
+
+ union {
+ void* ptr;
+ bool yes_or_no;
+ nframes_t target2_frame;
+ SlaveSource slave;
+ Route* route;
+ };
+
+ boost::shared_ptr<Region> region;
+
+ list<AudioRange> audio_range;
+ list<MusicRange> music_range;
+
+ Event(Type t, Action a, nframes_t when, 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 nframes_t Immediate = 0;
+
+ private:
+ static MultiAllocSingleReleasePool pool;
+ };
+
+ /* creating from an XML file */
+
+ Session (AudioEngine&,
+ const string& fullpath,
+ const string& snapshot_name,
+ string mix_template = "");
+
+ /* 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,
+ nframes_t initial_length);
+
+ virtual ~Session ();
+
+ string path() const { return _path; }
+ string name() const { return _name; }
+ string snap_name() const { return _current_snapshot_name; }
+ string raid_path () const;
+
+ void set_snap_name ();
+
+ void set_dirty ();
+ void set_clean ();
+ bool dirty() const { return _state_of_the_state & Dirty; }
+ void set_deletion_in_progress ();
+ bool deletion_in_progress() const { return _state_of_the_state & Deletion; }
+ sigc::signal<void> DirtyChanged;
+
+ const SessionDirectory& session_directory () const { return *(_session_dir.get()); }
+
+ static sigc::signal<void> AutoBindingOn;
+ static sigc::signal<void> AutoBindingOff;
+
+ static sigc::signal<void,std::string> Dialog;
+
+ std::string sound_dir (bool with_path = true) const;
+ std::string peak_dir () const;
+ std::string dead_sound_dir () const;
+ std::string automation_dir () const;
+ std::string analysis_dir() const;
+
+ int ensure_subdirs ();
+
+ Glib::ustring peak_path (Glib::ustring) const;
+
+ static string change_audio_path_by_name (string oldpath, string oldname, string newname, bool destructive);
+ static string change_midi_path_by_name (string oldpath, string oldname, string newname, bool destructive);
+
+ string peak_path_from_audio_path (string) const;
+ string audio_path_from_name (string, uint32_t nchans, uint32_t chan, bool destructive);
+ string midi_path_from_name (string);
+
+ void process (nframes_t nframes);
+
+ BufferSet& get_silent_buffers (ChanCount count = ChanCount::ZERO);
+ BufferSet& get_scratch_buffers (ChanCount count = ChanCount::ZERO);
+ BufferSet& get_mix_buffers (ChanCount count = ChanCount::ZERO);
+
+ void add_diskstream (boost::shared_ptr<Diskstream>);
+ boost::shared_ptr<Diskstream> diskstream_by_id (const PBD::ID& id);
+ boost::shared_ptr<Diskstream> diskstream_by_name (string name);
+
+ bool have_captured() const { return _have_captured; }
+
+ void refill_all_diskstream_buffers ();
+ uint32_t audio_diskstream_buffer_size() const { return audio_dstream_buffer_size; }
+ uint32_t midi_diskstream_buffer_size() const { return midi_dstream_buffer_size; }
+
+ uint32_t get_next_diskstream_id() const { return n_diskstreams(); }
+ uint32_t n_diskstreams() const;
+
+ typedef std::list<boost::shared_ptr<Diskstream> > DiskstreamList;
+ typedef std::list<boost::shared_ptr<Route> > RouteList;
+
+ boost::shared_ptr<RouteList> get_routes() const {
+ return routes.reader ();
+ }
+
+ uint32_t nroutes() const { return routes.reader()->size(); }
+ uint32_t ntracks () const;
+ uint32_t nbusses () const;
+
+ struct RoutePublicOrderSorter {
+ bool operator() (boost::shared_ptr<Route>, boost::shared_ptr<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)(boost::shared_ptr<Route>));
+ template<class T, class A> void foreach_route (T *obj, void (T::*func)(Route&, A), A arg);
+
+ boost::shared_ptr<Route> route_by_name (string);
+ boost::shared_ptr<Route> route_by_id (PBD::ID);
+ boost::shared_ptr<Route> route_by_remote_id (uint32_t id);
+
+ bool route_name_unique (string) const;
+
+ bool get_record_enabled() const {
+ return (record_status () >= Enabled);
+ }
+
+ RecordState record_status() const {
+ return (RecordState) g_atomic_int_get (&_record_status);
+ }
+
+ bool actively_recording () {
+ return record_status() == Recording;
+ }
+
+ bool record_enabling_legal () const;
+ void maybe_enable_record ();
+ void disable_record (bool rt_context, bool force = false);
+ void step_back_from_record ();
+
+ void maybe_write_autosave ();
+
+ /* Proxy signal for region hidden changes */
+
+ sigc::signal<void,boost::shared_ptr<Region> > RegionHiddenChange;
+
+ /* Emitted when all i/o connections are complete */
+
+ sigc::signal<void> IOConnectionsComplete;
+
+ /* Record status signals */
+
+ sigc::signal<void> RecordStateChanged;
+
+ /* Transport mechanism signals */
+
+ sigc::signal<void> TransportStateChange; /* generic */
+ sigc::signal<void,nframes_t> PositionChanged; /* sent after any non-sequential motion */
+ sigc::signal<void> DurationChanged;
+ sigc::signal<void,nframes_t> Xrun;
+ sigc::signal<void> TransportLooped;
+
+ sigc::signal<void,RouteList&> RouteAdded;
+
+ void request_roll_at_and_return (nframes_t start, nframes_t return_to);
+ void request_bounded_roll (nframes_t start, nframes_t end);
+ void request_stop (bool abort = false);
+ void request_locate (nframes_t frame, bool with_roll = false);
+
+ void request_play_loop (bool yn);
+ bool get_play_loop () const { return play_loop; }
+
+ nframes_t last_transport_start() const { return _last_roll_location; }
+ void goto_end () { request_locate (end_location->start(), false);}
+ void goto_start () { request_locate (start_location->start(), false); }
+ void set_session_start (nframes_t start) { start_location->set_start(start); }
+ void set_session_end (nframes_t end) { end_location->set_start(end); _end_location_is_free = false; }
+ void use_rf_shuttle_speed ();
+ void allow_auto_play (bool yn);
+ void request_transport_speed (float speed);
+ void request_overwrite_buffer (Diskstream*);
+ void request_diskstream_speed (Diskstream&, float speed);
+ void request_input_change_handling ();
+
+ bool locate_pending() const { return static_cast<bool>(post_transport_work&PostTransportLocate); }
+ bool transport_locked () const;
+
+ int wipe ();
+ //int wipe_diskstream (AudioDiskstream *);
+
+ int remove_region_from_region_list (boost::shared_ptr<Region>);
+
+ nframes_t get_maximum_extent () const;
+ nframes_t current_end_frame() const { return end_location->start(); }
+ nframes_t current_start_frame() const { return start_location->start(); }
+ // "actual" sample rate of session, set by current audioengine rate, pullup/down etc.
+ nframes_t frame_rate() const { return _current_frame_rate; }
+ // "native" sample rate of session, regardless of current audioengine rate, pullup/down etc
+ nframes_t nominal_frame_rate() const { return _nominal_frame_rate; }
+ nframes_t frames_per_hour() const { return _frames_per_hour; }
+
+ double frames_per_smpte_frame() const { return _frames_per_smpte_frame; }
+ nframes_t smpte_frames_per_hour() const { return _smpte_frames_per_hour; }
+
+ float smpte_frames_per_second() const;
+ bool smpte_drop_frames() const;
+
+ /* 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 *);
+ int location_name(string& result, string base = string(""));
+
+ void reset_input_monitor_state ();
+
+ void add_event (nframes_t action_frame, Event::Type type, nframes_t target_frame = 0);
+ void remove_event (nframes_t frame, Event::Type type);
+ void clear_events (Event::Type type);
+
+ nframes_t get_block_size() const { return current_block_size; }
+ nframes_t worst_output_latency () const { return _worst_output_latency; }
+ nframes_t worst_input_latency () const { return _worst_input_latency; }
+ 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);
+ int save_history (string snapshot_name = "");
+ int restore_history (string snapshot_name);
+ void remove_state (string snapshot_name);
+ void rename_state (string old_name, string new_name);
+ void remove_pending_capture_state ();
+
+ 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); // not idempotent
+ XMLNode& get_template();
+
+ /// The instant xml file is written to the session directory
+ void add_instant_xml (XMLNode&);
+ XMLNode * instant_xml (const std::string& str);
+
+ 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);
+
+ void remove_edit_group (RouteGroup&);
+ void remove_mix_group (RouteGroup&);
+
+ 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;
+ sigc::signal<void> edit_group_removed;
+ sigc::signal<void> mix_group_removed;
+
+ void foreach_edit_group (sigc::slot<void,RouteGroup*> sl) {
+ for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); i++) {
+ sl (*i);
+ }
+ }
+
+ void foreach_mix_group (sigc::slot<void,RouteGroup*> sl) {
+ for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); i++) {
+ sl (*i);
+ }
+ }
+
+ /* fundamental operations. duh. */
+
+ std::list<boost::shared_ptr<AudioTrack> > new_audio_track (int input_channels, int output_channels, TrackMode mode = Normal, uint32_t how_many = 1);
+ RouteList new_audio_route (int input_channels, int output_channels, uint32_t how_many);
+
+ std::list<boost::shared_ptr<MidiTrack> > new_midi_track (TrackMode mode = Normal, uint32_t how_many = 1);
+ //boost::shared_ptr<Route> new_midi_route (uint32_t how_many = 1);
+
+ void remove_route (boost::shared_ptr<Route>);
+ void resort_routes ();
+ void resort_routes_using (boost::shared_ptr<RouteList>);
+
+ void set_remote_control_ids();
+
+ AudioEngine & engine() { return _engine; }
+ AudioEngine const & engine () const { return _engine; }
+
+ int32_t max_level;
+ int32_t min_level;
+
+ /* Time */
+
+ nframes_t transport_frame () const {return _transport_frame; }
+ nframes_t audible_frame () const;
+ nframes64_t requested_return_frame() const { return _requested_return_frame; }
+
+ enum PullupFormat {
+ pullup_Plus4Plus1,
+ pullup_Plus4,
+ pullup_Plus4Minus1,
+ pullup_Plus1,
+ pullup_None,
+ pullup_Minus1,
+ pullup_Minus4Plus1,
+ pullup_Minus4,
+ pullup_Minus4Minus1
+ };
+
+ int set_smpte_format (SmpteFormat);
+ void sync_time_vars();
+
+ void bbt_time (nframes_t when, BBT_Time&);
+ void smpte_to_sample( SMPTE::Time& smpte, nframes_t& sample, bool use_offset, bool use_subframes ) const;
+ void sample_to_smpte( nframes_t sample, SMPTE::Time& smpte, bool use_offset, bool use_subframes ) const;
+ void smpte_time (SMPTE::Time &);
+ void smpte_time (nframes_t when, SMPTE::Time&);
+ void smpte_time_subframes (nframes_t when, SMPTE::Time&);
+
+ void smpte_duration (nframes_t, SMPTE::Time&) const;
+ void smpte_duration_string (char *, nframes_t) const;
+
+ void set_smpte_offset (nframes_t);
+ nframes_t smpte_offset () const { return _smpte_offset; }
+ void set_smpte_offset_negative (bool);
+ bool smpte_offset_negative () const { return _smpte_offset_negative; }
+
+ nframes_t convert_to_frames_at (nframes_t position, AnyTime&);
+
+ static sigc::signal<void> StartTimeChanged;
+ static sigc::signal<void> EndTimeChanged;
+ static sigc::signal<void> SMPTEOffsetChanged;
+
+ void request_slave_source (SlaveSource);
+ bool synced_to_jack() const { return Config->get_slave_source() == 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; }
+
+ void set_silent (bool yn);
+ bool silent () { return _silent; }
+
+ int jack_slave_sync (nframes_t);
+
+ TempoMap& tempo_map() { return *_tempo_map; }
+
+ /* region info */
+
+ void add_regions (std::vector<boost::shared_ptr<Region> >&);
+
+ sigc::signal<void,boost::weak_ptr<Region> > RegionAdded;
+ sigc::signal<void,std::vector<boost::weak_ptr<Region> >& > RegionsAdded;
+ sigc::signal<void,boost::weak_ptr<Region> > RegionRemoved;
+
+ int region_name (string& result, string base = string(""), bool newlevel = false) const;
+ string new_region_name (string);
+ string path_from_region_name (DataType type, string name, string identifier);
+
+ boost::shared_ptr<Region> find_whole_file_parent (boost::shared_ptr<Region const>);
+
+ void find_equivalent_playlist_regions (boost::shared_ptr<Region>, std::vector<boost::shared_ptr<Region> >& result);
+
+ boost::shared_ptr<Region> XMLRegionFactory (const XMLNode&, bool full);
+ boost::shared_ptr<AudioRegion> XMLAudioRegionFactory (const XMLNode&, bool full);
+ boost::shared_ptr<MidiRegion> XMLMidiRegionFactory (const XMLNode&, bool full);
+
+ template<class T> void foreach_region (T *obj, void (T::*func)(boost::shared_ptr<Region>));
+
+ /* source management */
+
+ struct import_status : public InterThreadInfo {
+ string doing_what;
+
+ /* control info */
+ SrcQuality quality;
+ volatile bool freeze;
+ std::vector<Glib::ustring> paths;
+ bool replace_existing_source;
+
+ /* result */
+ SourceList sources;
+
+ };
+
+ void import_audiofiles (import_status&);
+ bool sample_rate_convert (import_status&, string infile, string& outfile);
+ string build_tmp_convert_name (string file);
+
+ SlaveSource post_export_slave;
+ nframes_t post_export_position;
+
+ int start_export (ARDOUR::ExportSpecification&);
+ int stop_export (ARDOUR::ExportSpecification&);
+ void finalize_audio_export ();
+
+ void add_source (boost::shared_ptr<Source>);
+ void remove_source (boost::weak_ptr<Source>);
+
+ struct cleanup_report {
+ vector<string> paths;
+ int64_t space;
+ };
+
+ int cleanup_sources (cleanup_report&);
+ int cleanup_trash_sources (cleanup_report&);
+
+ int destroy_region (boost::shared_ptr<Region>);
+ int destroy_regions (std::list<boost::shared_ptr<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,boost::shared_ptr<ARDOUR::Playlist> > AskAboutPlaylistDeletion;
+
+ /* handlers should return 0 for "ignore the rate mismatch"
+ and !0 for "do not use this session"
+ */
+
+ static sigc::signal<int,nframes_t, nframes_t> AskAboutSampleRateMismatch;
+
+ /* handlers should return !0 for use pending state, 0 for
+ ignore it.
+ */
+
+ static sigc::signal<int> AskAboutPendingState;
+
+ boost::shared_ptr<AudioFileSource> create_audio_source_for_session (ARDOUR::AudioDiskstream&, uint32_t which_channel, bool destructive);
+
+ boost::shared_ptr<MidiSource> create_midi_source_for_session (ARDOUR::MidiDiskstream&);
+
+ boost::shared_ptr<Source> source_by_id (const PBD::ID&);
+ boost::shared_ptr<Source> source_by_path_and_channel (const Glib::ustring&, uint16_t);
+
+ /* playlist management */
+
+ boost::shared_ptr<Playlist> playlist_by_name (string name);
+ void add_playlist (boost::shared_ptr<Playlist>);
+ sigc::signal<void,boost::shared_ptr<Playlist> > PlaylistAdded;
+ sigc::signal<void,boost::shared_ptr<Playlist> > PlaylistRemoved;
+
+ uint32_t n_playlists() const;
+
+ template<class T> void foreach_playlist (T *obj, void (T::*func)(boost::shared_ptr<Playlist>));
+ void get_playlists (std::vector<boost::shared_ptr<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;
+
+ /* Curves and AutomationLists (TODO when they go away) */
+ void add_curve(Curve*);
+ void add_automation_list(AutomationList*);
+
+ /* 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 */
+
+ boost::shared_ptr<Auditioner> the_auditioner() { return auditioner; }
+ void audition_playlist ();
+ void audition_region (boost::shared_ptr<Region>);
+ void cancel_audition ();
+ bool is_auditioning () const;
+
+ sigc::signal<void,bool> AuditionActive;
+
+ /* flattening stuff */
+
+ int write_one_audio_track (AudioTrack&, nframes_t start, nframes_t cnt, bool overwrite,
+ vector<boost::shared_ptr<Source> >&, InterThreadInfo& wot);
+
+ int freeze (InterThreadInfo&);
+
+ /* session-wide solo/mute/rec-enable */
+
+ bool soloing() const { return currently_soloing; }
+
+ void set_all_solo (bool);
+ void set_all_mute (bool);
+
+ sigc::signal<void,bool> SoloActive;
+ sigc::signal<void> SoloChanged;
+
+ void record_disenable_all ();
+ void record_enable_all ();
+
+ /* control/master out */
+
+ boost::shared_ptr<IO> control_out() const { return _control_out; }
+ boost::shared_ptr<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(); }
+
+ static void set_disable_all_loaded_plugins (bool yn) {
+ _disable_all_loaded_plugins = yn;
+ }
+ static bool get_disable_all_loaded_plugins() {
+ return _disable_all_loaded_plugins;
+ }
+
+ uint32_t next_send_id();
+ uint32_t next_insert_id();
+ void mark_send_id (uint32_t);
+ void mark_insert_id (uint32_t);
+
+ /* s/w "RAID" management */
+
+ nframes_t available_capture_duration();
+
+ /* I/O bundles */
+
+ void foreach_bundle (sigc::slot<void, boost::shared_ptr<Bundle> >);
+ void add_bundle (boost::shared_ptr<Bundle>);
+ void remove_bundle (boost::shared_ptr<Bundle>);
+ boost::shared_ptr<Bundle> bundle_by_name (string) const;
+
+ sigc::signal<void,boost::shared_ptr<Bundle> > BundleAdded;
+ sigc::signal<void,boost::shared_ptr<Bundle> > BundleRemoved;
+
+ /* MIDI */
+
+ void midi_panic(void);
+ 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 set_mmc_receive_device_id (uint32_t id);
+ void set_mmc_send_device_id (uint32_t id);
+
+ /* Scrubbing */
+
+ void start_scrub (nframes_t where);
+ void stop_scrub ();
+ void set_scrub_speed (float);
+ nframes_t scrub_buffer_size() const;
+ sigc::signal<void> ScrubReady;
+
+ /* History (for editors, mixers, UIs etc.) */
+
+ /** Undo some transactions.
+ * @param n Number of transactions to undo.
+ */
+ void undo (uint32_t n) {
+ _history.undo (n);
+ }
+
+ void redo (uint32_t n) {
+ _history.redo (n);
+ }
+
+ UndoHistory& history() { return _history; }
+
+ 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 (const string& cmd_name);
+ void commit_reversible_command (Command* cmd = 0);
+
+ void add_command (Command *const cmd) {
+ current_trans->add_command (cmd);
+ }
+
+ std::map<PBD::ID, PBD::StatefulThingWithGoingAway*> registry;
+
+ // these commands are implemented in libs/ardour/session_command.cc
+ Command* memento_command_factory(XMLNode* n);
+ void register_with_memento_command_factory(PBD::ID, PBD::StatefulThingWithGoingAway*);
+
+ Command* global_state_command_factory (const XMLNode& n);
+
+ class GlobalRouteStateCommand : public Command
+ {
+ public:
+ GlobalRouteStateCommand (Session&, void*);
+ GlobalRouteStateCommand (Session&, const XMLNode& node);
+ int set_state (const XMLNode&);
+ XMLNode& get_state ();
+
+ protected:
+ GlobalRouteBooleanState before, after;
+ Session& sess;
+ void* src;
+
+ };
+
+ class GlobalSoloStateCommand : public GlobalRouteStateCommand
+ {
+ public:
+ GlobalSoloStateCommand (Session &, void *src);
+ GlobalSoloStateCommand (Session&, const XMLNode&);
+ void operator()(); //redo
+ void undo();
+ XMLNode &get_state();
+ void mark();
+ };
+
+ class GlobalMuteStateCommand : public GlobalRouteStateCommand
+ {
+ public:
+ GlobalMuteStateCommand(Session &, void *src);
+ GlobalMuteStateCommand (Session&, const XMLNode&);
+ void operator()(); // redo
+ void undo();
+ XMLNode &get_state();
+ void mark();
+ };
+
+ class GlobalRecordEnableStateCommand : public GlobalRouteStateCommand
+ {
+ public:
+ GlobalRecordEnableStateCommand(Session &, void *src);
+ GlobalRecordEnableStateCommand (Session&, const XMLNode&);
+ void operator()(); // redo
+ void undo();
+ XMLNode &get_state();
+ void mark();
+ };
+
+ class GlobalMeteringStateCommand : public Command
+ {
+ public:
+ GlobalMeteringStateCommand(Session &, void *src);
+ GlobalMeteringStateCommand (Session&, const XMLNode&);
+ void operator()();
+ void undo();
+ XMLNode &get_state();
+ int set_state (const XMLNode&);
+ void mark();
+
+ protected:
+ Session& sess;
+ void* src;
+ GlobalRouteMeterState before;
+ GlobalRouteMeterState after;
+ };
+
+ /* clicking */
+
+ boost::shared_ptr<IO> click_io() { return _click_io; }
+
+ /* 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; }
+
+ /* 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; }
+
+ /* buffers for conversion */
+ enum RunContext {
+ ButlerContext = 0,
+ TransportContext,
+ ExportContext
+ };
+
+ /* VST support */
+
+ static long vst_callback (AEffect* effect,
+ long opcode,
+ long index,
+ long value,
+ void* ptr,
+ float opt);
+
+ typedef float (*compute_peak_t) (Sample *, nframes_t, float);
+ typedef void (*find_peaks_t) (Sample *, nframes_t, float *, float*);
+ typedef void (*apply_gain_to_buffer_t) (Sample *, nframes_t, float);
+ typedef void (*mix_buffers_with_gain_t) (Sample *, Sample *, nframes_t, float);
+ typedef void (*mix_buffers_no_gain_t) (Sample *, Sample *, nframes_t);
+
+ static compute_peak_t compute_peak;
+ static find_peaks_t find_peaks;
+ 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;
+
+ static sigc::signal<void> SendFeedback;
+
+ /* Controllables */
+
+ boost::shared_ptr<PBD::Controllable> controllable_by_id (const PBD::ID&);
+
+ void add_controllable (boost::shared_ptr<PBD::Controllable>);
+ void remove_controllable (PBD::Controllable*);
+
+ protected:
+ friend class AudioEngine;
+ void set_block_size (nframes_t nframes);
+ void set_frame_rate (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, const string& mix_template, nframes_t initial_length);
+ void destroy ();
+
+ nframes_t compute_initial_length ();
+
+ 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)(nframes_t);
+
+ AudioEngine& _engine;
+ mutable gint processing_prohibited;
+ process_function_type process_function;
+ process_function_type last_process_function;
+ bool waiting_for_sync_offset;
+ nframes_t _base_frame_rate;
+ nframes_t _current_frame_rate; //this includes video pullup offset
+ nframes_t _nominal_frame_rate; //ignores audioengine setting, "native" SR
+ int transport_sub_state;
+ mutable gint _record_status;
+ volatile nframes_t _transport_frame;
+ Location* end_location;
+ Location* start_location;
+ Slave* _slave;
+ bool _silent;
+ volatile float _transport_speed;
+ volatile float _desired_transport_speed;
+ float _last_transport_speed;
+ bool auto_play_legal;
+ nframes_t _last_slave_transport_frame;
+ nframes_t maximum_output_latency;
+ nframes_t last_stop_frame;
+ volatile nframes64_t _requested_return_frame;
+ BufferSet* _scratch_buffers;
+ BufferSet* _silent_buffers;
+ BufferSet* _mix_buffers;
+ nframes_t current_block_size;
+ nframes_t _worst_output_latency;
+ nframes_t _worst_input_latency;
+ nframes_t _worst_track_latency;
+ bool _have_captured;
+ float _meter_hold;
+ float _meter_falloff;
+ bool _end_location_is_free;
+
+ void set_worst_io_latencies ();
+ void set_worst_io_latencies_x (IOChange asifwecare, void *ignored) {
+ set_worst_io_latencies ();
+ }
+
+ void update_latency_compensation_proxy (void* ignored);
+
+ void ensure_buffers (ChanCount howmany);
+
+ void process_scrub (nframes_t);
+ void process_without_events (nframes_t);
+ void process_with_events (nframes_t);
+ void process_audition (nframes_t);
+ int process_export (nframes_t, ARDOUR::ExportSpecification*);
+
+ /* 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;
+ nframes_t slave_wait_end;
+
+ void reset_slave_state ();
+ bool follow_slave (nframes_t, nframes_t);
+ void set_slave_source (SlaveSource);
+
+ bool _exporting;
+ int prepare_to_export (ARDOUR::ExportSpecification&);
+
+ void prepare_diskstreams ();
+ void commit_diskstreams (nframes_t, bool& session_requires_butler);
+ int process_routes (nframes_t, nframes_t);
+ int silent_process_routes (nframes_t, nframes_t);
+
+ bool get_rec_monitors_input () {
+ if (actively_recording()) {
+ return true;
+ } else {
+ if (Config->get_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 (nframes_t limit) {
+ if ((_transport_speed > 0.0f && _transport_frame >= limit) || (_transport_speed < 0.0f && _transport_frame == 0)) {
+ stop_transport ();
+ return true;
+ }
+ return false;
+ }
+
+ bool maybe_sync_start (nframes_t&, nframes_t&);
+
+ void check_declick_out ();
+
+ MIDI::MachineControl* mmc;
+ MIDI::Port* _mmc_port;
+ MIDI::Port* _mtc_port;
+ MIDI::Port* _midi_port;
+ string _path;
+ string _name;
+ bool session_send_mmc;
+ bool session_send_mtc;
+ bool session_midi_feedback;
+ bool play_loop;
+ bool loop_changing;
+ nframes_t last_loopend;
+
+ boost::scoped_ptr<SessionDirectory> _session_dir;
+
+ RingBuffer<Event*> pending_events;
+
+ void hookup_io ();
+ void when_engine_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);
+ bool save_config_options_predicate (ConfigVariableBase::Owner owner) const;
+
+ nframes_t _last_roll_location;
+ nframes_t _last_record_location;
+
+ bool pending_locate_roll;
+ 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;
+ Glib::Mutex butler_request_lock;
+ Glib::Cond butler_paused;
+ bool butler_should_run;
+ mutable gint butler_should_do_transport_work;
+ int butler_request_pipe[2];
+
+ inline bool transport_work_requested() const { return g_atomic_int_get(&butler_should_do_transport_work); }
+
+ 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 (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, nframes_t action_frame, 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 *ev);
+
+ /* MIDI Machine Control */
+
+ void deliver_mmc (MIDI::MachineControl::Command, nframes_t);
+
+ 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];
+ 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 */
+ nframes_t _frames_per_hour;
+ nframes_t _smpte_frames_per_hour;
+ 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;
+ nframes_t last_smpte_when;
+ SMPTE::Time last_smpte;
+
+ bool _send_smpte_update; ///< Flag to send a full frame (SMPTE) MTC message this cycle
+
+ int send_full_time_code(nframes_t nframes);
+ int send_midi_time_code_for_cycle(nframes_t nframes);
+
+ nframes_t adjust_apparent_position (nframes_t frames);
+
+ void reset_record_status ();
+
+ int no_roll (nframes_t nframes, 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 {
+ PortChange,
+ Quit
+ };
+
+ Type type;
+
+ MIDIRequest () {}
+ };
+
+ Glib::Mutex midi_lock;
+ pthread_t midi_thread;
+ int midi_request_pipe[2];
+ 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 ();
+
+ mutable gint butler_active;
+ bool waiting_to_start;
+
+ void set_play_loop (bool yn);
+ void overwrite_some_buffers (Diskstream*);
+ void flush_all_inserts ();
+ void locate (nframes_t, bool with_roll, bool with_flush, bool with_loop=false);
+ void start_locate (nframes_t, bool with_roll, bool with_flush, bool with_loop=false);
+ void force_locate (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_locate ();
+ void non_realtime_stop (bool abort, int entry_request_count, bool& finished);
+ void non_realtime_overwrite (int entry_request_count, bool& finished);
+ 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 */
+
+ SerializedRCUManager<DiskstreamList> diskstreams;
+
+ uint32_t audio_dstream_buffer_size;
+ uint32_t midi_dstream_buffer_size;
+ int load_diskstreams (const XMLNode&);
+
+ /* routes stuff */
+
+ SerializedRCUManager<RouteList> routes;
+
+ void add_routes (RouteList&, bool save);
+ uint32_t destructive_index;
+
+ int load_routes (const XMLNode&);
+ boost::shared_ptr<Route> XMLRouteFactory (const XMLNode&);
+
+ /* mixer stuff */
+
+ bool solo_update_disabled;
+ bool currently_soloing;
+
+ void route_mute_changed (void *src);
+ void route_solo_changed (void *src, boost::weak_ptr<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 Glib::Mutex region_lock;
+ typedef map<PBD::ID,boost::shared_ptr<Region> > RegionList;
+ RegionList regions;
+
+ void add_region (boost::shared_ptr<Region>);
+ void region_changed (Change, boost::weak_ptr<Region>);
+ void remove_region (boost::weak_ptr<Region>);
+
+ int load_regions (const XMLNode& node);
+
+ /* SOURCES */
+
+ mutable Glib::Mutex source_lock;
+ typedef std::map<PBD::ID,boost::shared_ptr<Source> > SourceMap;
+
+ SourceMap sources;
+
+ public:
+ SourceMap get_sources() { return sources; }
+
+ private:
+
+
+ int load_sources (const XMLNode& node);
+ XMLNode& get_sources_as_xml ();
+
+ boost::shared_ptr<Source> XMLSourceFactory (const XMLNode&);
+
+ /* PLAYLISTS */
+
+ mutable Glib::Mutex playlist_lock;
+ typedef set<boost::shared_ptr<Playlist> > PlaylistList;
+ PlaylistList playlists;
+ PlaylistList unused_playlists;
+
+ int load_playlists (const XMLNode&);
+ int load_unused_playlists (const XMLNode&);
+ void remove_playlist (boost::weak_ptr<Playlist>);
+ void track_playlist (bool, boost::weak_ptr<Playlist>);
+
+ boost::shared_ptr<Playlist> playlist_factory (string name);
+ boost::shared_ptr<Playlist> XMLPlaylistFactory (const XMLNode&);
+
+ void playlist_length_changed ();
+ void diskstream_playlist_changed (boost::shared_ptr<Diskstream>);
+
+ /* NAMED SELECTIONS */
+
+ mutable Glib::Mutex 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&);
+
+ /* CURVES and AUTOMATION LISTS */
+ std::map<PBD::ID, Curve*> curves;
+ std::map<PBD::ID, AutomationList*> automation_lists;
+
+ /* DEFAULT FADE CURVES */
+
+ float default_fade_steepness;
+ float default_fade_msecs;
+
+ /* AUDITIONING */
+
+ boost::shared_ptr<Auditioner> auditioner;
+ void set_audition (boost::shared_ptr<Region>);
+ void non_realtime_set_audition ();
+ boost::shared_ptr<Region> pending_audition_region;
+
+ /* EXPORT */
+
+ /* FLATTEN */
+
+ int flatten_one_track (AudioTrack&, nframes_t start, nframes_t cnt);
+
+ /* INSERT AND SEND MANAGEMENT */
+
+ list<PortInsert *> _port_inserts;
+ list<PluginInsert *> _plugin_inserts;
+ list<Send *> _sends;
+ boost::dynamic_bitset<uint32_t> send_bitset;
+ boost::dynamic_bitset<uint32_t> insert_bitset;
+ uint32_t send_cnt;
+ uint32_t insert_cnt;
+
+
+ void add_processor (Processor *);
+ void remove_processor (Processor *);
+
+ /* 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;
+ Glib::Mutex space_lock;
+
+ string get_best_session_directory_for_new_source ();
+ void refresh_disk_space ();
+
+ mutable gint _playback_load;
+ mutable gint _capture_load;
+ mutable gint _playback_load_min;
+ mutable gint _capture_load_min;
+
+ /* I/O bundles */
+
+ typedef list<boost::shared_ptr<Bundle> > BundleList;
+ mutable Glib::Mutex bundle_lock;
+ BundleList _bundles;
+ XMLNode* _bundle_xml_node;
+ int load_bundles (XMLNode const &);
+
+ void reverse_diskstream_buffers ();
+
+ UndoHistory _history;
+ UndoTransaction* current_trans;
+
+ 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, nframes_t, jack_position_t*, int);
+ int jack_sync_callback (jack_transport_state_t, jack_position_t*);
+ void reset_jack_connection (jack_client_t* jack);
+ void record_enable_change_all (bool yn);
+
+ XMLNode& state(bool);
+
+ /* click track */
+
+ struct Click {
+ nframes_t start;
+ nframes_t duration;
+ nframes_t offset;
+ const Sample *data;
+
+ Click (nframes_t s, 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;
+ boost::shared_ptr<IO> _click_io;
+ Sample* click_data;
+ Sample* click_emphasis_data;
+ nframes_t click_length;
+ nframes_t click_emphasis_length;
+ mutable Glib::RWLock click_lock;
+
+ static const Sample default_click[];
+ static const nframes_t default_click_length;
+ static const Sample default_click_emphasis[];
+ static const nframes_t default_click_emphasis_length;
+
+ Click *get_click();
+ void setup_click_sounds (int which);
+ void clear_clicks ();
+ void click (nframes_t start, nframes_t nframes, nframes_t offset);
+
+ vector<Route*> master_outs;
+
+ /* 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;
+
+ boost::shared_ptr<IO> _master_out;
+ boost::shared_ptr<IO> _control_out;
+
+ gain_t* _gain_automation_buffer;
+ pan_t** _pan_automation_buffer;
+ void allocate_pan_automation_buffers (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 ports we're using,
+ based on max (requested,available)
+ */
+
+ uint32_t n_physical_outputs;
+ uint32_t n_physical_inputs;
+
+
+ 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;
+
+ typedef std::set<boost::shared_ptr<PBD::Controllable> > Controllables;
+ Glib::Mutex controllables_lock;
+ Controllables controllables;
+
+ void reset_native_file_format();
+ bool first_file_data_format_reset;
+ bool first_file_header_format_reset;
+
+ void config_changed (const char*);
+
+ XMLNode& get_control_protocol_state ();
+
+ void set_history_depth (uint32_t depth);
+ void sync_order_keys ();
+
+ static bool _disable_all_loaded_plugins;
+};
+
+} // namespace ARDOUR
+
+#endif /* __ardour_session_h__ */
diff --git a/libs/ardour/ardour/session_directory.h b/libs/ardour/ardour/session_directory.h
new file mode 100644
index 0000000000..a4fb7d07c5
--- /dev/null
+++ b/libs/ardour/ardour/session_directory.h
@@ -0,0 +1,136 @@
+/*
+ Copyright (C) 2007 Tim Mayberry
+
+ 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_session_directory_h__
+#define __ardour_session_directory_h__
+
+#include <string>
+#include <vector>
+
+#include <pbd/filesystem.h>
+
+namespace ARDOUR {
+
+using std::string;
+using std::vector;
+using PBD::sys::path;
+
+class SessionDirectory
+{
+public:
+
+ /**
+ * @param session_path An absolute path to a session directory.
+ */
+ SessionDirectory (const path& session_path);
+
+ /**
+ * @return the absolute path to the root directory of the session
+ */
+ const path root_path() const { return m_root_path; }
+
+ /**
+ * @return the absolute path to the directory in which
+ * the session stores audio files.
+ *
+ * If the session is an older session with an existing
+ * "sounds" directory then it will return a path to that
+ * directory otherwise it will return the new location
+ * of root_path()/interchange/session_name/audiofiles
+ */
+ const path sound_path () const;
+
+ /**
+ * @return the absolute path to the directory in which
+ * the session stores MIDI files, ie
+ * root_path()/interchange/session_name/midifiles
+ */
+ const path midi_path () const;
+
+ /**
+ * @return The absolute path to the directory in which all
+ * peak files are stored for a session.
+ */
+ const path peak_path () const;
+
+ /**
+ * @return The absolute path to the directory that audio
+ * files are moved to when they are no longer part of the
+ * session.
+ */
+ const path dead_sound_path () const;
+
+ /**
+ * @return The absolute path to the directory that midi
+ * files are moved to when they are no longer part of the
+ * session.
+ */
+ const path dead_midi_path () const;
+
+ /**
+ * @return The absolute path to the directory that audio
+ * files are created in by default when exporting.
+ */
+ const path export_path () const;
+
+ /**
+ * @return true if session directory and all the required
+ * subdirectories exist.
+ */
+ bool is_valid () const;
+
+ /**
+ * Create the session directory and all the subdirectories.
+ *
+ * @throw PBD::sys::filesystem_error if the directories were
+ * not able to be created.
+ *
+ * @return true If a new session directory was created, otherwise
+ * (if it already existed) false.
+ *
+ * @post is_valid ()
+ */
+ bool create ();
+
+protected:
+
+ /**
+ * @return The path to the old style sound directory.
+ * It isn't created by create().
+ */
+ const path old_sound_path () const;
+
+ /**
+ * @return The path to the directory under which source directories
+ * are created for different source types.
+ * i.e root_path()/interchange/session_name
+ */
+ const path sources_root() const;
+
+ /**
+ * @return a vector containing the fullpath of all subdirectories.
+ */
+ const vector<PBD::sys::path> sub_directories () const;
+
+ /// The path to the root of the session directory.
+ const path m_root_path;
+};
+
+} // namespace ARDOUR
+
+#endif
diff --git a/libs/ardour/ardour/session_object.h b/libs/ardour/ardour/session_object.h
new file mode 100644
index 0000000000..bb726cb0d0
--- /dev/null
+++ b/libs/ardour/ardour/session_object.h
@@ -0,0 +1,65 @@
+/*
+ Copyright (C) 2000-2007 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_session_object_h__
+#define __ardour_session_object_h__
+
+#include <string>
+#include <pbd/statefuldestructible.h>
+
+namespace ARDOUR {
+
+class Session;
+
+
+/** An object associated with a Session.
+ *
+ * This is a few common things factored out of IO which weren't IO specific
+ * (to fix the problem with e.g. PluginInsert being an IO which it shouldn't be).
+ * collection of input and output ports with connections.
+ */
+class SessionObject : public PBD::StatefulDestructible
+{
+public:
+ SessionObject(Session& session, const std::string& name)
+ : _session(session)
+ , _name(name)
+ {}
+
+ Session& session() const { return _session; }
+ const std::string& name() const { return _name; }
+
+ virtual bool set_name (const std::string& str) {
+ if (_name != str) {
+ _name = str;
+ NameChanged();
+ }
+ return true;
+ }
+
+ sigc::signal<void> NameChanged;
+
+protected:
+ Session& _session;
+ std::string _name;
+};
+
+} // namespace ARDOUR
+
+#endif /*__ardour_io_h__ */
diff --git a/libs/ardour/ardour/session_playlist.h b/libs/ardour/ardour/session_playlist.h
new file mode 100644
index 0000000000..baeb74916d
--- /dev/null
+++ b/libs/ardour/ardour/session_playlist.h
@@ -0,0 +1,46 @@
+/*
+ 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.
+
+*/
+
+#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)(boost::shared_ptr<Playlist>))
+{
+ Glib::Mutex::Lock lm (playlist_lock);
+ 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..254bbfe1a3
--- /dev/null
+++ b/libs/ardour/ardour/session_region.h
@@ -0,0 +1,38 @@
+/*
+ Copyright (C) 2000-2007 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_session_region_h__
+#define __ardour_session_region_h__
+
+#include <ardour/session.h>
+#include <ardour/audioregion.h>
+
+namespace ARDOUR {
+
+template<class T> void Session::foreach_region (T *obj, void (T::*func)(boost::shared_ptr<Region>))
+{
+ Glib::Mutex::Lock lm (region_lock);
+ for (RegionList::iterator i = regions.begin(); i != regions.end(); i++) {
+ (obj->*func) (i->second);
+ }
+}
+
+} // namespace ARDOUR
+
+#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..0c70bf407d
--- /dev/null
+++ b/libs/ardour/ardour/session_route.h
@@ -0,0 +1,76 @@
+/*
+ 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.
+
+*/
+
+#ifndef __ardour_session_route_h__
+#define __ardour_session_route_h__
+
+#include <iostream>
+
+#include <glibmm/thread.h>
+
+#include <ardour/session.h>
+#include <ardour/route.h>
+
+namespace ARDOUR {
+
+template<class T> void
+Session::foreach_route (T *obj, void (T::*func)(Route&))
+{
+ boost::shared_ptr<RouteList> r = routes.reader();
+ RouteList public_order (*r);
+ 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)(boost::shared_ptr<Route>))
+{
+ boost::shared_ptr<RouteList> r = routes.reader();
+ RouteList public_order (*r);
+ 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)
+{
+ boost::shared_ptr<RouteList> r = routes.reader();
+ RouteList public_order (*r);
+ 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..4169a3a511
--- /dev/null
+++ b/libs/ardour/ardour/session_selection.h
@@ -0,0 +1,39 @@
+/*
+ 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.
+
+*/
+
+#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&))
+{
+ Glib::Mutex::Lock lm (named_selection_lock);
+ 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/session_state_utils.h b/libs/ardour/ardour/session_state_utils.h
new file mode 100644
index 0000000000..8825b041f3
--- /dev/null
+++ b/libs/ardour/ardour/session_state_utils.h
@@ -0,0 +1,65 @@
+/*
+ Copyright (C) 2007 Tim Mayberry
+
+ 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_SESSION_STATE_UTILS_INCLUDED
+#define ARDOUR_SESSION_STATE_UTILS_INCLUDED
+
+#include <vector>
+#include <string>
+
+#include <pbd/filesystem.h>
+
+namespace ARDOUR {
+
+using std::string;
+using std::vector;
+using namespace PBD;
+
+/**
+ * Attempt to create a backup copy of a file.
+ *
+ * A copy of the file is created in the same directory using
+ * the same filename with the backup suffix appended.
+ *
+ * @return true if successful, false otherwise.
+ */
+bool create_backup_file (const sys::path & file_path);
+
+/**
+ * Get the absolute paths to all state files in the directory
+ * at path directory_path.
+ *
+ * @param directory_path The absolute path to a directory.
+ * @param result vector to contain resulting state files.
+ */
+void get_state_files_in_directory (const sys::path & directory_path,
+ vector<sys::path>& result);
+
+/**
+ * Given a vector of paths to files, return a vector containing
+ * the filenames without any extension.
+ *
+ * @param file_paths a vector containing the file paths
+ * @return a vector containing a list of file names without any
+ * filename extension.
+ */
+vector<string> get_file_names_no_extension (const vector<sys::path> & file_paths);
+
+} // namespace ARDOUR
+
+#endif
diff --git a/libs/ardour/ardour/session_utils.h b/libs/ardour/ardour/session_utils.h
new file mode 100644
index 0000000000..8a9f6f584c
--- /dev/null
+++ b/libs/ardour/ardour/session_utils.h
@@ -0,0 +1,26 @@
+
+#ifndef __ardour_session_utils_h__
+#define __ardour_session_utils_h__
+
+#include <string>
+
+namespace ARDOUR {
+
+using std::string;
+
+int find_session (string str, string& path, string& snapshot, bool& isnew);
+
+/**
+ * Create a SessionDirectory at the path specified by
+ * session_directory_path, this includes all subdirectories.
+ *
+ * @return true if the session directory was able to be created
+ * or if it already existed, false otherwise.
+ *
+ * @see SessionDirectory
+ */
+bool create_session_directory (const string& session_directory_path);
+
+};
+
+#endif
diff --git a/libs/ardour/ardour/silentfilesource.h b/libs/ardour/ardour/silentfilesource.h
new file mode 100644
index 0000000000..cbb123139a
--- /dev/null
+++ b/libs/ardour/ardour/silentfilesource.h
@@ -0,0 +1,68 @@
+/*
+ Copyright (C) 2007 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_silentfilesource_h__
+#define __ardour_silentfilesource_h__
+
+#include <cstring>
+#include <ardour/audiofilesource.h>
+
+namespace ARDOUR {
+
+class SilentFileSource : public AudioFileSource {
+ public:
+ virtual ~SilentFileSource ();
+
+ int update_header (nframes_t when, struct tm&, time_t) { return 0; }
+ int flush_header () { return 0; }
+ float sample_rate () const { return _sample_rate; }
+
+ void set_length (nframes_t len);
+
+ bool destructive() const { return false; }
+ bool can_be_analysed() const { return false; }
+
+ protected:
+
+ float _sample_rate;
+
+ SilentFileSource (Session&, const XMLNode&, nframes_t nframes, float sample_rate);
+
+ friend class SourceFactory;
+
+ nframes_t read_unlocked (Sample *dst, nframes_t start, nframes_t cnt) const {
+ memset (dst, 0, sizeof (Sample) * cnt);
+ return cnt;
+ }
+
+ nframes_t write_unlocked (Sample *dst, nframes_t cnt) { return 0; }
+
+ void set_header_timeline_position () {}
+
+ int read_peaks_with_fpp (PeakData *peaks, nframes_t npeaks, nframes_t start, nframes_t cnt, double samples_per_unit, nframes_t fpp) const {
+ memset (peaks, 0, sizeof (PeakData) * npeaks);
+ return 0;
+ }
+
+};
+
+} // namespace ARDOUR
+
+#endif /* __ardour_audiofilesource_h__ */
+
diff --git a/libs/ardour/ardour/slave.h b/libs/ardour/ardour/slave.h
new file mode 100644
index 0000000000..509f8fa9d2
--- /dev/null
+++ b/libs/ardour/ardour/slave.h
@@ -0,0 +1,153 @@
+/*
+ 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.
+
+*/
+
+#ifndef __ardour_slave_h__
+#define __ardour_slave_h__
+
+#include <vector>
+
+#include <jack/jack.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&, nframes_t&) = 0;
+ virtual bool locked() const = 0;
+ virtual bool ok() const = 0;
+ virtual bool starting() const { return false; }
+ virtual nframes_t resolution() const = 0;
+ virtual bool requires_seekahead () const = 0;
+ virtual bool is_always_synced() const { return false; }
+};
+
+
+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&, nframes_t&);
+
+ bool locked() const;
+ bool ok() const;
+ void handle_locate (const MIDI::byte*);
+
+ nframes_t resolution() const;
+ bool requires_seekahead () const { return true; }
+
+ private:
+ Session& session;
+ MIDI::Port* port;
+ std::vector<sigc::connection> connections;
+ bool can_notify_on_unknown_rate;
+
+ struct SafeTime {
+
+
+ int guard1;
+ //SMPTE_Time mtc;
+ nframes_t position;
+ nframes_t timestamp;
+ int guard2;
+
+ SafeTime() {
+ guard1 = 0;
+ guard2 = 0;
+ timestamp = 0;
+ }
+ };
+
+ SafeTime current;
+ nframes_t mtc_frame; /* current time */
+ nframes_t last_inbound_frame; /* when we got it; audio clocked */
+
+ float mtc_speed;
+ nframes_t first_mtc_frame;
+ 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, nframes_t& pos) {
+ speed = 0;
+ pos = 0;
+ return false;
+ }
+
+ bool locked() const { return false; }
+ bool ok() const { return false; }
+ 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, nframes_t& pos);
+
+ bool starting() const { return _starting; }
+ bool locked() const;
+ bool ok() const;
+ nframes_t resolution() const { return 1; }
+ bool requires_seekahead () const { return false; }
+ void reset_client (jack_client_t* jack);
+ bool is_always_synced() const { return true; }
+
+ private:
+ jack_client_t* jack;
+ float speed;
+ bool _starting;
+};
+
+} /* namespace */
+
+#endif /* __ardour_slave_h__ */
diff --git a/libs/ardour/ardour/smf_reader.h b/libs/ardour/ardour/smf_reader.h
new file mode 100644
index 0000000000..e41dcc3bc4
--- /dev/null
+++ b/libs/ardour/ardour/smf_reader.h
@@ -0,0 +1,87 @@
+/*
+ Copyright (C) 2008 Paul Davis
+ Written by Dave Robillard
+
+ 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_smf_reader_h__
+#define __ardour_smf_reader_h__
+
+#include <exception>
+#include <stdexcept>
+#include <string>
+#include <inttypes.h>
+
+namespace ARDOUR {
+
+
+/** Standard MIDI File (Type 0) Reader
+ *
+ * Currently this only reads SMF files with tempo-based timing.
+ */
+class SMFReader {
+public:
+ class PrematureEOF : public std::exception {
+ const char* what() const throw() { return "Unexpected end of file"; }
+ };
+ class CorruptFile : public std::exception {
+ const char* what() const throw() { return "Corrupted file"; }
+ };
+ class UnsupportedTime : public std::exception {
+ const char* what() const throw() { return "Unsupported time stamp type (SMPTE)"; }
+ };
+
+ SMFReader(const std::string filename="");
+ ~SMFReader();
+
+ bool open(const std::string& filename) throw (std::logic_error, UnsupportedTime);
+
+ bool seek_to_track(unsigned track) throw (std::logic_error);
+
+ const std::string& filename() const { return _filename; };
+
+ uint16_t type() const { return _type; }
+ uint16_t ppqn() const { return _ppqn; }
+ uint16_t num_tracks() const { return _num_tracks; }
+
+ int read_event(size_t buf_len,
+ uint8_t* buf,
+ uint32_t* ev_size,
+ uint32_t* ev_delta_time)
+ throw (std::logic_error, PrematureEOF, CorruptFile);
+
+ void close();
+
+ static uint32_t read_var_len(FILE* fd) throw (PrematureEOF);
+
+protected:
+ /** size of SMF header, including MTrk chunk header */
+ static const uint32_t HEADER_SIZE = 22;
+
+ std::string _filename;
+ FILE* _fd;
+ uint16_t _type;
+ uint16_t _ppqn;
+ uint16_t _num_tracks;
+ uint32_t _track;
+ uint32_t _track_size;
+};
+
+
+} // namespace ARDOUR
+
+#endif /* __ardour_smf_reader_h__ */
+
diff --git a/libs/ardour/ardour/smf_source.h b/libs/ardour/ardour/smf_source.h
new file mode 100644
index 0000000000..88bf1e5d13
--- /dev/null
+++ b/libs/ardour/ardour/smf_source.h
@@ -0,0 +1,151 @@
+/*
+ Copyright (C) 2006 Paul Davis
+ Written by Dave Robillard, 2006
+
+ 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_smf_filesource_h__
+#define __ardour_smf_filesource_h__
+
+#include <cstdio>
+#include <time.h>
+
+#include <ardour/midi_source.h>
+
+namespace ARDOUR {
+
+class MidiRingBuffer;
+
+/** Standard Midi File (Type 0) Source */
+class SMFSource : public MidiSource {
+ public:
+ enum Flag {
+ Writable = 0x1,
+ CanRename = 0x2,
+ Broadcast = 0x4,
+ Removable = 0x8,
+ RemovableIfEmpty = 0x10,
+ RemoveAtDestroy = 0x20,
+ BuildPeaks = 0x40
+ };
+
+ /** Constructor for existing external-to-session files */
+ SMFSource (Session& session, std::string path, Flag flags = Flag(0));
+
+ /* Constructor for existing in-session files */
+ SMFSource (Session& session, const XMLNode&);
+
+ virtual ~SMFSource ();
+
+ /* this block of methods do nothing for regular file sources, but are significant
+ for files used in destructive recording.
+ */
+ // FIXME and thus are useless for MIDI.. but make MidiDiskstream compile easier! :)
+
+ virtual nframes_t last_capture_start_frame() const { return 0; }
+ virtual void mark_capture_start (nframes_t) {}
+ virtual void mark_capture_end () {}
+ virtual void clear_capture_marks() {}
+
+ bool set_name (const std::string& newname) { return (set_source_name(newname, false) == 0); }
+ int set_source_name (string newname, bool destructive);
+
+ static bool safe_file_extension (const Glib::ustring& path);
+
+ Glib::ustring path() const { return _path; }
+
+ void set_allow_remove_if_empty (bool yn);
+ void mark_for_remove();
+
+ void append_event_unlocked(EventTimeUnit unit, const MIDI::Event& ev);
+
+ int flush_header ();
+ int flush_footer ();
+
+ int move_to_trash (const string trash_dir_name);
+
+ bool is_empty () const;
+ void mark_streaming_midi_write_started (NoteMode mode, nframes_t start_time);
+ void mark_streaming_write_completed ();
+
+ void mark_take (string);
+ string take_id() const { return _take_id; }
+
+ static void set_search_path (string);
+ static void set_header_position_offset (nframes_t offset, bool negative);
+
+ XMLNode& get_state ();
+ int set_state (const XMLNode&);
+
+ void seek_to(nframes_t time);
+
+ void load_model(bool lock=true, bool force_reload=false);
+ void destroy_model();
+
+ uint16_t ppqn() const { return _ppqn; }
+
+ private:
+
+ int init (string idstr, bool must_exist);
+
+ nframes_t read_unlocked (MidiRingBuffer& dst, nframes_t start, nframes_t cn, nframes_t stamp_offset, nframes_t negative_stamp_offset) const;
+ nframes_t write_unlocked (MidiRingBuffer& dst, nframes_t cnt);
+
+ bool find (std::string path, bool must_exist, bool& is_new);
+ bool removable() const;
+ bool writable() const { return _flags & Writable; }
+
+ int open();
+ void close();
+
+ /**
+ * This method is only used by flush_footer() to find the right seek position
+ * for the footer (at the end after recording or -4 offset ro SEEK_END
+ * if a footer is already present)
+ */
+ void seek_to_footer_position();
+
+ /**
+ * write the track footer at the current seek position
+ */
+ void write_footer();
+
+ void write_chunk_header(const char id[4], uint32_t length);
+ void write_chunk(const char id[4], uint32_t length, void* data);
+ size_t write_var_len(uint32_t val);
+ uint32_t read_var_len() const;
+ int read_event(uint32_t* delta_t, uint32_t* size, uint8_t** buf) const;
+
+ static const uint16_t _ppqn = 19200;
+
+ Glib::ustring _path;
+ Flag _flags;
+ string _take_id;
+ bool _allow_remove_if_empty;
+ FILE* _fd;
+ double _last_ev_time; ///< last frame time written, relative to source start
+ uint32_t _track_size;
+ uint32_t _header_size; ///< size of SMF header, including MTrk chunk header
+ bool _empty; ///< true iff file contains (non-empty) events
+
+ static string _search_path;
+};
+
+}; /* namespace ARDOUR */
+
+#endif /* __ardour_smf_filesource_h__ */
+
diff --git a/libs/ardour/ardour/smpte.h b/libs/ardour/ardour/smpte.h
new file mode 100644
index 0000000000..d0901c372e
--- /dev/null
+++ b/libs/ardour/ardour/smpte.h
@@ -0,0 +1,79 @@
+/* Copyright (C) 2006 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.,
+ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#ifndef __ardour_smpte_h__
+#define __ardour_smpte_h__
+
+#include <inttypes.h>
+
+namespace SMPTE {
+
+enum Wrap {
+ NONE = 0,
+ FRAMES,
+ SECONDS,
+ MINUTES,
+ HOURS
+};
+
+/** SMPTE frame rate (in frames per second).
+ *
+ * This should be eliminated in favour of a float to support arbitrary rates.
+ */
+enum FPS {
+ MTC_24_FPS = 0,
+ MTC_25_FPS = 1,
+ MTC_30_FPS_DROP = 2,
+ MTC_30_FPS = 3
+};
+
+struct Time {
+ bool negative;
+ uint32_t hours;
+ uint32_t minutes;
+ uint32_t seconds;
+ uint32_t frames; ///< SMPTE frames (not audio samples)
+ uint32_t subframes; ///< Typically unused
+ FPS rate; ///< Frame rate of this Time
+ static FPS default_rate; ///< Rate to use for default constructor
+
+ Time(FPS a_rate = default_rate) {
+ negative = false;
+ hours = 0;
+ minutes = 0;
+ seconds = 0;
+ frames = 0;
+ subframes = 0;
+ rate = a_rate;
+ }
+};
+
+Wrap increment( Time& smpte );
+Wrap decrement( Time& smpte );
+Wrap increment_subframes( Time& smpte );
+Wrap decrement_subframes( Time& smpte );
+Wrap increment_seconds( Time& smpte );
+Wrap increment_minutes( Time& smpte );
+Wrap increment_hours( Time& smpte );
+void frames_floor( Time& smpte );
+void seconds_floor( Time& smpte );
+void minutes_floor( Time& smpte );
+void hours_floor( Time& smpte );
+
+} // namespace SMPTE
+
+#endif // __ardour_smpte_h__
diff --git a/libs/ardour/ardour/sndfile_helpers.h b/libs/ardour/ardour/sndfile_helpers.h
new file mode 100644
index 0000000000..cf6b15f3a4
--- /dev/null
+++ b/libs/ardour/ardour/sndfile_helpers.h
@@ -0,0 +1,58 @@
+/*
+ Copyright (C) 2000-2007 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 __sndfile_helpers_h__
+#define __sndfile_helpers_h__
+
+#include <string>
+#include <stdint.h>
+
+using std::string;
+
+// Use this define when initializing arrarys for use in sndfile_*_format()
+#define SNDFILE_STR_LENGTH 32
+
+#define SNDFILE_HEADER_FORMATS 5
+extern const char * const sndfile_header_formats_strings[SNDFILE_HEADER_FORMATS+1];
+extern const char * const sndfile_file_endings_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);
+string sndfile_file_ending_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/sndfileimportable.h b/libs/ardour/ardour/sndfileimportable.h
new file mode 100644
index 0000000000..5cd84f4f5f
--- /dev/null
+++ b/libs/ardour/ardour/sndfileimportable.h
@@ -0,0 +1,50 @@
+/*
+ Copyright (C) 2007 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_sndfile_importable_source_h__
+#define __ardour_sndfile_importable_source_h__
+
+#include <boost/shared_ptr.hpp>
+#include <sndfile.h>
+#include <pbd/failed_constructor.h>
+#include <ardour/types.h>
+#include <ardour/importable_source.h>
+
+namespace ARDOUR {
+
+class SndFileImportableSource : public ImportableSource {
+ public:
+ SndFileImportableSource (const std::string& path);
+ virtual ~SndFileImportableSource();
+
+ nframes_t read (Sample* buffer, nframes_t nframes);
+ uint32_t channels() const;
+ nframes_t length() const;
+ nframes_t samplerate() const;
+ void seek (nframes_t pos);
+
+ protected:
+ SF_INFO sf_info;
+ boost::shared_ptr<SNDFILE> in;
+
+};
+
+}
+
+#endif /* __ardour_sndfile_importable_source_h__ */
diff --git a/libs/ardour/ardour/sndfilesource.h b/libs/ardour/ardour/sndfilesource.h
new file mode 100644
index 0000000000..4ad967c132
--- /dev/null
+++ b/libs/ardour/ardour/sndfilesource.h
@@ -0,0 +1,109 @@
+/*
+ Copyright (C) 2006 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 __sndfile_source_h__
+#define __sndfile_source_h__
+
+#include <sndfile.h>
+
+#include <ardour/audiofilesource.h>
+
+namespace ARDOUR {
+
+class SndFileSource : public AudioFileSource {
+ public:
+ /* constructor to be called for existing external-to-session files */
+
+ SndFileSource (Session&, Glib::ustring path, int chn, Flag flags);
+
+ /* constructor to be called for new in-session files */
+
+ SndFileSource (Session&, Glib::ustring path, SampleFormat samp_format, HeaderFormat hdr_format, nframes_t rate,
+ Flag flags = SndFileSource::default_writable_flags);
+
+ /* constructor to be called for existing in-session files */
+
+ SndFileSource (Session&, const XMLNode&);
+
+ ~SndFileSource ();
+
+ float sample_rate () const;
+ int update_header (nframes_t when, struct tm&, time_t);
+ int flush_header ();
+
+ nframes_t natural_position () const;
+
+ nframes_t last_capture_start_frame() const;
+ void mark_capture_start (nframes_t);
+ void mark_capture_end ();
+ void clear_capture_marks();
+
+ bool set_destructive (bool yn);
+
+ bool one_of_several_channels () const;
+
+ static void setup_standard_crossfades (nframes_t sample_rate);
+ static const AudioFileSource::Flag default_writable_flags;
+
+ static int get_soundfile_info (const Glib::ustring& path, SoundFileInfo& _info, string& error_msg);
+
+ protected:
+ void set_header_timeline_position ();
+
+ nframes_t read_unlocked (Sample *dst, nframes_t start, nframes_t cnt) const;
+ nframes_t write_unlocked (Sample *dst, nframes_t cnt);
+
+ nframes_t write_float (Sample* data, nframes_t pos, nframes_t cnt);
+
+ private:
+ SNDFILE *sf;
+ SF_INFO _info;
+ SF_BROADCAST_INFO *_broadcast_info;
+
+ void init ();
+ int open();
+ int setup_broadcast_info (nframes_t when, struct tm&, time_t);
+
+ /* destructive */
+
+ static nframes_t xfade_frames;
+ static gain_t* out_coefficient;
+ static gain_t* in_coefficient;
+
+ bool _capture_start;
+ bool _capture_end;
+ nframes_t capture_start_frame;
+ nframes_t file_pos; // unit is frames
+ nframes_t xfade_out_count;
+ nframes_t xfade_in_count;
+ Sample* xfade_buf;
+
+ nframes_t crossfade (Sample* data, nframes_t cnt, int dir);
+ void set_timeline_position (int64_t);
+ nframes_t destructive_write_unlocked (Sample *dst, nframes_t cnt);
+ nframes_t nondestructive_write_unlocked (Sample *dst, nframes_t cnt);
+ void handle_header_position_change ();
+
+ static int64_t get_timecode_info (SNDFILE* sf, SF_BROADCAST_INFO* binfo, bool& exists);
+};
+
+} // namespace ARDOUR
+
+#endif /* __sndfile_source_h__ */
+
diff --git a/libs/ardour/ardour/soundseq.h b/libs/ardour/ardour/soundseq.h
new file mode 100644
index 0000000000..c7157428ee
--- /dev/null
+++ b/libs/ardour/ardour/soundseq.h
@@ -0,0 +1,53 @@
+/*
+ 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.
+
+*/
+
+#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..a2ee96bf63
--- /dev/null
+++ b/libs/ardour/ardour/source.h
@@ -0,0 +1,112 @@
+/*
+ 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.
+
+*/
+
+#ifndef __ardour_source_h__
+#define __ardour_source_h__
+
+#include <string>
+#include <set>
+
+#include <sigc++/signal.h>
+
+#include <pbd/statefuldestructible.h>
+
+#include <ardour/ardour.h>
+#include <ardour/session_object.h>
+#include <ardour/data_type.h>
+#include <ardour/readable.h>
+
+namespace ARDOUR {
+
+class Session;
+class Playlist;
+
+class Source : public SessionObject, public ARDOUR::Readable
+{
+ public:
+ Source (Session&, const std::string& name, DataType type);
+ Source (Session&, const XMLNode&);
+
+ virtual ~Source ();
+
+ DataType type() { return _type; }
+
+ time_t timestamp() const { return _timestamp; }
+ void stamp (time_t when) { _timestamp = when; }
+
+ nframes_t length() const { return _length; }
+
+ virtual Glib::ustring path() const = 0;
+
+ virtual nframes_t natural_position() const { return 0; }
+
+ virtual void mark_for_remove() = 0;
+ virtual void mark_streaming_write_started () {}
+ virtual void mark_streaming_write_completed () = 0;
+
+ virtual void session_saved() {}
+
+ XMLNode& get_state ();
+ int set_state (const XMLNode&);
+
+ virtual bool destructive() const { return false; }
+ virtual bool length_mutable() const { return false; }
+
+ void use () { _in_use++; }
+ void disuse () { if (_in_use) { _in_use--; } }
+
+ void add_playlist (boost::shared_ptr<ARDOUR::Playlist>);
+ void remove_playlist (boost::weak_ptr<ARDOUR::Playlist>);
+
+ uint32_t used() const;
+
+ static sigc::signal<void,Source*> SourceCreated;
+ sigc::signal<void,boost::shared_ptr<Source> > Switched;
+
+ bool has_been_analysed() const;
+ virtual bool can_be_analysed() const { return false; }
+ virtual void set_been_analysed (bool yn);
+ virtual bool check_for_analysis_data_on_disk();
+
+ sigc::signal<void> AnalysisChanged;
+
+ AnalysisFeatureList transients;
+ std::string get_transients_path() const;
+ int load_transients (const std::string&);
+
+ void update_length (nframes_t pos, nframes_t cnt);
+
+ protected:
+ DataType _type;
+ time_t _timestamp;
+ nframes_t _length;
+ bool _analysed;
+ mutable Glib::Mutex _analysis_lock;
+ Glib::Mutex _playlist_lock;
+
+ typedef std::map<boost::shared_ptr<ARDOUR::Playlist>, uint32_t > PlaylistMap;
+ PlaylistMap _playlists;
+
+ private:
+ uint32_t _in_use;
+};
+
+}
+
+#endif /* __ardour_source_h__ */
diff --git a/libs/ardour/ardour/source_factory.h b/libs/ardour/ardour/source_factory.h
new file mode 100644
index 0000000000..7e9be451e8
--- /dev/null
+++ b/libs/ardour/ardour/source_factory.h
@@ -0,0 +1,60 @@
+/*
+ Copyright (C) 2000-2007 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_source_factory_h__
+#define __ardour_source_factory_h__
+
+#include <string>
+#include <stdint.h>
+#include <sigc++/sigc++.h>
+#include <boost/shared_ptr.hpp>
+
+#include <ardour/source.h>
+#include <ardour/audiofilesource.h>
+
+class XMLNode;
+
+namespace ARDOUR {
+
+class Session;
+
+class SourceFactory {
+ public:
+ static void init ();
+
+ static sigc::signal<void,boost::shared_ptr<Source> > SourceCreated;
+
+ static boost::shared_ptr<Source> create (Session&, const XMLNode& node, bool async = false);
+ static boost::shared_ptr<Source> createSilent (Session&, const XMLNode& node, nframes_t nframes, float sample_rate);
+
+ static boost::shared_ptr<Source> createReadable (DataType type, Session&, std::string path, int chn, AudioFileSource::Flag flags,
+ bool announce = true, bool async = false);
+ static boost::shared_ptr<Source> createWritable (DataType type, Session&, std::string name, bool destructive, nframes_t rate,
+ bool announce = true, bool async = false);
+
+ static Glib::Cond* PeaksToBuild;
+ static Glib::StaticMutex peak_building_lock;
+ static std::list<boost::weak_ptr<AudioSource> > files_with_peaks;
+
+ static int setup_peakfile (boost::shared_ptr<Source>, bool async);
+};
+
+}
+
+#endif /* __ardour_source_factory_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/stretch.h b/libs/ardour/ardour/stretch.h
new file mode 100644
index 0000000000..b01a9ae208
--- /dev/null
+++ b/libs/ardour/ardour/stretch.h
@@ -0,0 +1,62 @@
+/*
+ Copyright (C) 2007 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_stretch_h__
+#define __ardour_stretch_h__
+
+#include <ardour/filter.h>
+
+#ifdef USE_RUBBERBAND
+
+#include <ardour/rb_effect.h>
+
+namespace ARDOUR {
+
+class Stretch : public RBEffect {
+ public:
+ Stretch (ARDOUR::Session&, TimeFXRequest&);
+ ~Stretch() {}
+};
+
+} /* namespace */
+
+#else
+
+#include <soundtouch/SoundTouch.h>
+
+namespace ARDOUR {
+
+class Stretch : public Filter {
+ public:
+ Stretch (ARDOUR::Session&, TimeFXRequest&);
+ ~Stretch ();
+
+ int run (boost::shared_ptr<ARDOUR::Region>);
+
+ private:
+ TimeFXRequest& tsr;
+
+ soundtouch::SoundTouch st;
+};
+
+} /* namespace */
+
+#endif
+
+#endif /* __ardour_stretch_h__ */
diff --git a/libs/ardour/ardour/tape_file_matcher.h b/libs/ardour/ardour/tape_file_matcher.h
new file mode 100644
index 0000000000..59ec18e818
--- /dev/null
+++ b/libs/ardour/ardour/tape_file_matcher.h
@@ -0,0 +1,45 @@
+/*
+ Copyright (C) 2007 Tim Mayberry
+
+ 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_TAPE_FILE_MATCHER_INCLUDED
+#define ARDOUR_TAPE_FILE_MATCHER_INCLUDED
+
+#include <string>
+
+#include <regex.h>
+
+namespace ARDOUR {
+
+using std::string;
+
+class TapeFileMatcher
+{
+public:
+
+ TapeFileMatcher();
+
+ bool matches (const string& filename) const;
+
+private:
+
+ regex_t m_compiled_pattern;
+};
+
+} // namespace ARDOUR
+
+#endif
diff --git a/libs/ardour/ardour/template_utils.h b/libs/ardour/ardour/template_utils.h
new file mode 100644
index 0000000000..0676d5b245
--- /dev/null
+++ b/libs/ardour/ardour/template_utils.h
@@ -0,0 +1,20 @@
+
+#ifndef TEMPLATE_UTILS_INCLUDED
+#define TEMPLATE_UTILS_INCLUDED
+
+#include <vector>
+
+#include <pbd/filesystem.h>
+
+namespace ARDOUR {
+
+ using std::vector;
+ using namespace PBD;
+
+ sys::path system_template_directory ();
+
+ sys::path user_template_directory ();
+
+} // namespace ARDOUR
+
+#endif
diff --git a/libs/ardour/ardour/tempo.h b/libs/ardour/ardour/tempo.h
new file mode 100644
index 0000000000..c4915072c5
--- /dev/null
+++ b/libs/ardour/ardour/tempo.h
@@ -0,0 +1,322 @@
+/*
+ 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.
+
+*/
+
+#ifndef __ardour_tempo_h__
+#define __ardour_tempo_h__
+
+#include <list>
+#include <string>
+#include <vector>
+#include <cmath>
+#include <glibmm/thread.h>
+
+#include <pbd/undo.h>
+#include <pbd/stateful.h>
+#include <pbd/statefuldestructible.h>
+
+#include <sigc++/signal.h>
+
+#include <ardour/ardour.h>
+
+class XMLNode;
+
+using std::list;
+using std::vector;
+
+namespace ARDOUR {
+class Meter;
+class Tempo {
+ public:
+ Tempo (double bpm, double type=4.0) // defaulting to quarter note
+ : _beats_per_minute (bpm), _note_type(type) {}
+ Tempo (const Tempo& other) {
+ _beats_per_minute = other._beats_per_minute;
+ _note_type = other._note_type;
+ }
+ void operator= (const Tempo& other) {
+ if (&other != this) {
+ _beats_per_minute = other._beats_per_minute;
+ _note_type = other._note_type;
+ }
+ }
+
+ double beats_per_minute () const { return _beats_per_minute;}
+ double note_type () const { return _note_type;}
+ double frames_per_beat (nframes_t sr, const Meter& meter) const;
+
+ protected:
+ double _beats_per_minute;
+ double _note_type;
+};
+
+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&, 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) {}
+ MetricSection (nframes_t start)
+ : _frame (start), _movable (true) {}
+
+ virtual ~MetricSection() {}
+
+ const BBT_Time& start() const { return _start; }
+ const nframes_t frame() const { return _frame; }
+
+ void set_movable (bool yn) { _movable = yn; }
+ bool movable() const { return _movable; }
+
+ virtual void set_frame (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;
+ 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 (nframes_t 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, double note_type)
+ : MetricSection (start), Tempo (qpm, note_type) {}
+ TempoSection (nframes_t start, double qpm, double note_type)
+ : MetricSection (start), Tempo (qpm, note_type) {}
+ TempoSection (const XMLNode&);
+
+ static const string xml_state_node_name;
+
+ XMLNode& get_state() const;
+};
+
+typedef list<MetricSection*> Metrics;
+
+class TempoMap : public PBD::StatefulDestructible
+{
+ public:
+ TempoMap (nframes_t frame_rate);
+ ~TempoMap();
+
+ /* measure-based stuff */
+
+ enum BBTPointType {
+ Bar,
+ Beat,
+ };
+
+ struct BBTPoint {
+ BBTPointType type;
+ nframes_t frame;
+ const Meter* meter;
+ const Tempo* tempo;
+ uint32_t bar;
+ uint32_t beat;
+
+ BBTPoint (const Meter& m, const Tempo& t, 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&)) {
+ Glib::RWLock::ReaderLock lm (lock);
+ (obj.*method)(*metrics);
+ }
+
+ BBTPointList *get_points (nframes_t start, nframes_t end) const;
+
+ void bbt_time (nframes_t when, BBT_Time&) const;
+ nframes_t frame_time (const BBT_Time&) const;
+ nframes_t bbt_duration_at (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 (nframes_t);
+ const Meter& meter_at (nframes_t);
+
+ const TempoSection& tempo_section_at (nframes_t);
+
+ void add_tempo(const Tempo&, BBT_Time where);
+ void add_meter(const Meter&, BBT_Time where);
+
+ void add_tempo(const Tempo&, nframes_t where);
+ void add_meter(const Meter&, nframes_t 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);
+
+
+ nframes_t round_to_bar (nframes_t frame, int dir);
+
+ nframes_t round_to_beat (nframes_t frame, int dir);
+
+ nframes_t round_to_beat_subdivision (nframes_t fr, int sub_num);
+
+ nframes_t round_to_tick (nframes_t frame, int dir);
+
+ void set_length (nframes_t frames);
+
+ XMLNode& get_state (void);
+ int set_state (const XMLNode&);
+
+ void dump (std::ostream&) const;
+ void clear ();
+
+ /* 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 (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; }
+ nframes_t frame() const { return _frame; }
+ const BBT_Time& start() const { return _start; }
+
+ private:
+ const Meter* _meter;
+ const Tempo* _tempo;
+ nframes_t _frame;
+ BBT_Time _start;
+
+ };
+
+ Metric metric_at (BBT_Time bbt) const;
+ Metric metric_at (nframes_t) const;
+ void bbt_time_with_metric (nframes_t, BBT_Time&, const Metric&) const;
+
+ void change_existing_tempo_at (nframes_t, double bpm, double note_type);
+ void change_initial_tempo (double bpm, double note_type);
+
+ int n_tempos () const;
+ int n_meters () const;
+
+ sigc::signal<void,ARDOUR::Change> StateChanged;
+
+ private:
+ static Tempo _default_tempo;
+ static Meter _default_meter;
+
+ Metrics* metrics;
+ nframes_t _frame_rate;
+ nframes_t last_bbt_when;
+ bool last_bbt_valid;
+ BBT_Time last_bbt;
+ mutable Glib::RWLock lock;
+
+ void timestamp_metrics (bool use_bbt);
+
+ nframes_t round_to_type (nframes_t fr, int dir, BBTPointType);
+
+ nframes_t frame_time_unlocked (const BBT_Time&) const;
+
+ void bbt_time_unlocked (nframes_t, BBT_Time&) const;
+
+ 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;
+
+ nframes_t count_frames_between (const BBT_Time&, const BBT_Time&) const;
+ 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, bool with_bbt);
+};
+
+}; /* 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..a0aeeae13d
--- /dev/null
+++ b/libs/ardour/ardour/timestamps.h
@@ -0,0 +1,32 @@
+/*
+ Copyright (C) 2000-2007 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_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/track.h b/libs/ardour/ardour/track.h
new file mode 100644
index 0000000000..4d5545c0dc
--- /dev/null
+++ b/libs/ardour/ardour/track.h
@@ -0,0 +1,151 @@
+/*
+ Copyright (C) 2006 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_track_h__
+#define __ardour_track_h__
+
+#include <boost/shared_ptr.hpp>
+
+#include <ardour/route.h>
+
+namespace ARDOUR {
+
+class Session;
+class Diskstream;
+class Playlist;
+class RouteGroup;
+
+class Track : public Route
+{
+ public:
+ Track (Session&, string name, Route::Flag f = Route::Flag (0), TrackMode m = Normal, DataType default_type = DataType::AUDIO);
+
+ virtual ~Track ();
+
+ bool set_name (const std::string& str);
+
+ TrackMode mode () const { return _mode; }
+ virtual int set_mode (TrackMode m) { return false; }
+ virtual bool can_use_mode (TrackMode m, bool& bounce_required) { return false; }
+ sigc::signal<void> TrackModeChanged;
+
+ virtual int roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
+ nframes_t offset, int declick, bool can_record, bool rec_monitors_input) = 0;
+
+ virtual int no_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
+ nframes_t offset, bool state_changing, bool can_record, bool rec_monitors_input) = 0;
+
+ virtual int silent_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
+ nframes_t offset, bool can_record, bool rec_monitors_input) = 0;
+
+ void toggle_monitor_input ();
+
+ bool can_record();
+
+ boost::shared_ptr<Diskstream> diskstream() const { return _diskstream; }
+
+ virtual int use_diskstream (string name) = 0;
+ virtual int use_diskstream (const PBD::ID& id) = 0;
+
+ nframes_t update_total_latency();
+ void set_latency_delay (nframes_t);
+
+ enum FreezeState {
+ NoFreeze,
+ Frozen,
+ UnFrozen
+ };
+
+ FreezeState freeze_state() const;
+
+ virtual void freeze (InterThreadInfo&) = 0;
+ virtual void unfreeze () = 0;
+
+ virtual void bounce (InterThreadInfo&) = 0;
+ virtual void bounce_range (nframes_t start, nframes_t end, InterThreadInfo&) = 0;
+
+ XMLNode& get_state();
+ XMLNode& get_template();
+ virtual int set_state(const XMLNode& node) = 0;
+
+ boost::shared_ptr<PBD::Controllable> rec_enable_control() { return _rec_enable_control; }
+
+ bool record_enabled() const;
+ void set_record_enable (bool yn, void *src);
+
+ void set_meter_point (MeterPoint, void* src);
+
+ sigc::signal<void> DiskstreamChanged;
+ sigc::signal<void> FreezeChange;
+
+ protected:
+ Track (Session& sess, const XMLNode& node, DataType default_type = DataType::AUDIO);
+
+ virtual XMLNode& state (bool full) = 0;
+
+ boost::shared_ptr<Diskstream> _diskstream;
+ MeterPoint _saved_meter_point;
+ TrackMode _mode;
+
+ //private: (FIXME)
+ struct FreezeRecordProcessorInfo {
+ FreezeRecordProcessorInfo(XMLNode& st, boost::shared_ptr<Processor> proc)
+ : state (st), processor (proc) {}
+
+ XMLNode state;
+ boost::shared_ptr<Processor> processor;
+ PBD::ID id;
+ UndoAction memento;
+ };
+
+ struct FreezeRecord {
+ FreezeRecord()
+ : have_mementos(false)
+ {}
+
+ ~FreezeRecord();
+
+ boost::shared_ptr<Playlist> playlist;
+ vector<FreezeRecordProcessorInfo*> processor_info;
+ bool have_mementos;
+ FreezeState state;
+ };
+
+ struct RecEnableControllable : public PBD::Controllable {
+ RecEnableControllable (Track&);
+
+ void set_value (float);
+ float get_value (void) const;
+
+ Track& track;
+ };
+
+ virtual void set_state_part_two () = 0;
+
+ FreezeRecord _freeze_record;
+ XMLNode* pending_state;
+ sigc::connection recenable_connection;
+ sigc::connection ic_connection;
+ bool _destructive;
+
+ boost::shared_ptr<RecEnableControllable> _rec_enable_control;
+};
+
+}; /* namespace ARDOUR*/
+
+#endif /* __ardour_track_h__ */
diff --git a/libs/ardour/ardour/transient_detector.h b/libs/ardour/ardour/transient_detector.h
new file mode 100644
index 0000000000..259b79176f
--- /dev/null
+++ b/libs/ardour/ardour/transient_detector.h
@@ -0,0 +1,58 @@
+/*
+ Copyright (C) 2008 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_transient_detector_h__
+#define __ardour_transient_detector_h__
+
+#include <ardour/audioanalyser.h>
+
+namespace ARDOUR {
+
+class AudioSource;
+class Session;
+
+class TransientDetector : public AudioAnalyser
+{
+
+ public:
+ TransientDetector (float sample_rate);
+ ~TransientDetector();
+
+ static std::string operational_identifier();
+
+ void set_threshold (float);
+ void set_sensitivity (float);
+
+ float get_threshold () const;
+ float get_sensitivity () const;
+
+ int run (const std::string& path, Readable*, uint32_t channel, AnalysisFeatureList& results);
+
+ static void cleanup_transients (AnalysisFeatureList&, float sr, float gap_msecs);
+
+ protected:
+ AnalysisFeatureList* current_results;
+ int use_features (Vamp::Plugin::FeatureSet&, std::ostream*);
+
+ static std::string _op_id;
+};
+
+} /* namespace */
+
+#endif /* __ardour_audioanalyser_h__ */
diff --git a/libs/ardour/ardour/types.h b/libs/ardour/ardour/types.h
new file mode 100644
index 0000000000..9bfd93cdbf
--- /dev/null
+++ b/libs/ardour/ardour/types.h
@@ -0,0 +1,443 @@
+/*
+ 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.
+
+*/
+
+#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 <istream>
+#include <vector>
+#include <boost/shared_ptr.hpp>
+
+#include <inttypes.h>
+#include <jack/types.h>
+#include <jack/midiport.h>
+#include <control_protocol/smpte.h>
+#include <pbd/id.h>
+
+#include <map>
+
+#if __GNUC__ < 3
+
+typedef int intptr_t;
+#endif
+
+/* eventually, we'd like everything (including JACK) to
+ move to this. for now, its a dedicated type.
+*/
+
+typedef int64_t nframes64_t;
+
+namespace ARDOUR {
+
+ class Source;
+ class AudioSource;
+
+ typedef jack_default_audio_sample_t Sample;
+ typedef float pan_t;
+ typedef float gain_t;
+ typedef uint32_t layer_t;
+ typedef uint64_t microseconds_t;
+ typedef uint32_t nframes_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 (nframes_t start_a, nframes_t end_a,
+ nframes_t start_b, nframes_t end_b);
+
+ /** See parameter.h
+ * XXX: I don't think/hope these hex values matter anymore.
+ */
+ enum AutomationType {
+ NullAutomation = 0x0,
+ GainAutomation = 0x1,
+ PanAutomation = 0x2,
+ PluginAutomation = 0x4,
+ SoloAutomation = 0x8,
+ MuteAutomation = 0x10,
+ MidiCCAutomation = 0x20,
+ MidiPgmChangeAutomation = 0x21,
+ MidiPitchBenderAutomation = 0x22,
+ MidiChannelAftertouchAutomation = 0x23,
+ FadeInAutomation = 0x40,
+ FadeOutAutomation = 0x80,
+ EnvelopeAutomation = 0x100
+ };
+
+ enum AutoState {
+ Off = 0x0,
+ Write = 0x1,
+ Touch = 0x2,
+ Play = 0x4
+ };
+
+ std::string auto_state_to_string (AutoState);
+ AutoState string_to_auto_state (std::string);
+
+ enum AutoStyle {
+ Absolute = 0x1,
+ Trim = 0x2
+ };
+
+ std::string auto_style_to_string (AutoStyle);
+ AutoStyle string_to_auto_style (std::string);
+
+ enum AlignStyle {
+ CaptureTime,
+ ExistingMaterial
+ };
+
+ enum MeterPoint {
+ MeterInput,
+ MeterPreFader,
+ MeterPostFader
+ };
+
+ enum TrackMode {
+ Normal,
+ Destructive
+ };
+
+ enum NoteMode {
+ Sustained,
+ Percussive
+ };
+
+ enum ChannelMode {
+ AllChannels = 0, ///< Pass through all channel information unmodified
+ FilterChannels, ///< Ignore events on certain channels
+ ForceChannel ///< Force all events to a certain channel
+ };
+
+ enum EventTimeUnit {
+ Frames,
+ Beats
+ };
+
+ 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;
+ }
+
+ };
+ enum SmpteFormat {
+ smpte_23976,
+ smpte_24,
+ smpte_24976,
+ smpte_25,
+ smpte_2997,
+ smpte_2997drop,
+ smpte_30,
+ smpte_30drop,
+ smpte_5994,
+ smpte_60
+ };
+
+ struct AnyTime {
+ enum Type {
+ SMPTE,
+ BBT,
+ Frames,
+ Seconds
+ };
+
+ Type type;
+
+ SMPTE::Time smpte;
+ BBT_Time bbt;
+
+ union {
+ nframes_t frames;
+ double seconds;
+ };
+
+ AnyTime() { type = Frames; frames = 0; }
+ };
+
+ struct AudioRange {
+ nframes_t start;
+ nframes_t end;
+ uint32_t id;
+
+ AudioRange (nframes_t s, nframes_t e, uint32_t i) : start (s), end (e) , id (i) {}
+
+ 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 (nframes_t s, 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;
+ }
+ };
+
+ /*
+ Slowest = 6.6dB/sec falloff at update rate of 40ms
+ Slow = 6.8dB/sec falloff at update rate of 40ms
+ */
+
+ enum MeterFalloff {
+ MeterFalloffOff = 0,
+ MeterFalloffSlowest = 1,
+ MeterFalloffSlow = 2,
+ MeterFalloffMedium = 3,
+ MeterFalloffFast = 4,
+ MeterFalloffFaster = 5,
+ MeterFalloffFastest = 6
+ };
+
+ enum MeterHold {
+ MeterHoldOff = 0,
+ MeterHoldShort = 40,
+ MeterHoldMedium = 100,
+ MeterHoldLong = 200
+ };
+
+ enum EditMode {
+ Slide,
+ Splice,
+ Lock
+ };
+
+ enum RegionPoint {
+ Start,
+ End,
+ SyncPoint
+ };
+
+ enum Change {
+ range_guarantee = ~0
+ };
+
+
+ enum Placement {
+ PreFader,
+ PostFader
+ };
+
+ enum MonitorModel {
+ HardwareMonitoring,
+ SoftwareMonitoring,
+ ExternalMonitoring
+ };
+
+ enum DenormalModel {
+ DenormalNone,
+ DenormalFTZ,
+ DenormalDAZ,
+ DenormalFTZDAZ
+ };
+
+ enum RemoteModel {
+ UserOrdered,
+ MixerOrdered,
+ EditorOrdered
+ };
+
+ enum CrossfadeModel {
+ FullCrossfade,
+ ShortCrossfade
+ };
+
+ enum LayerModel {
+ LaterHigher,
+ MoveAddHigher,
+ AddHigher
+ };
+
+ enum SoloModel {
+ InverseMute,
+ SoloBus
+ };
+
+ enum AutoConnectOption {
+ AutoConnectPhysical = 0x1,
+ AutoConnectMaster = 0x2
+ };
+
+ struct InterThreadInfo {
+ volatile bool done;
+ volatile bool cancel;
+ volatile float progress;
+ pthread_t thread;
+ };
+
+ enum SampleFormat {
+ FormatFloat = 0,
+ FormatInt24,
+ FormatInt16
+ };
+
+
+ enum HeaderFormat {
+ BWF,
+ WAVE,
+ WAVE64,
+ CAF,
+ AIFF,
+ iXML,
+ RF64
+ };
+
+ struct PeakData {
+ typedef Sample PeakDatum;
+
+ PeakDatum min;
+ PeakDatum max;
+ };
+
+ enum PluginType {
+ AudioUnit,
+ LADSPA,
+ LV2,
+ VST
+ };
+
+ enum SlaveSource {
+ None = 0,
+ MTC,
+ JACK
+ };
+
+ enum ShuttleBehaviour {
+ Sprung,
+ Wheel
+ };
+
+ enum ShuttleUnits {
+ Percentage,
+ Semitones
+ };
+
+ typedef std::vector<boost::shared_ptr<Source> > SourceList;
+
+ enum SrcQuality {
+ SrcBest,
+ SrcGood,
+ SrcQuick,
+ SrcFast,
+ SrcFastest
+ };
+
+ struct TimeFXRequest : public InterThreadInfo {
+ TimeFXRequest() : time_fraction(0), pitch_fraction(0),
+ quick_seek(false), antialias(false), opts(0) {}
+ float time_fraction;
+ float pitch_fraction;
+ /* SoundTouch */
+ bool quick_seek;
+ bool antialias;
+ /* RubberBand */
+ int opts; // really RubberBandStretcher::Options
+ };
+
+ typedef std::list<nframes64_t> AnalysisFeatureList;
+
+} // namespace ARDOUR
+
+std::istream& operator>>(std::istream& o, ARDOUR::SampleFormat& sf);
+std::istream& operator>>(std::istream& o, ARDOUR::HeaderFormat& sf);
+std::istream& operator>>(std::istream& o, ARDOUR::AutoConnectOption& sf);
+std::istream& operator>>(std::istream& o, ARDOUR::EditMode& sf);
+std::istream& operator>>(std::istream& o, ARDOUR::MonitorModel& sf);
+std::istream& operator>>(std::istream& o, ARDOUR::RemoteModel& sf);
+std::istream& operator>>(std::istream& o, ARDOUR::SoloModel& sf);
+std::istream& operator>>(std::istream& o, ARDOUR::LayerModel& sf);
+std::istream& operator>>(std::istream& o, ARDOUR::CrossfadeModel& sf);
+std::istream& operator>>(std::istream& o, ARDOUR::SlaveSource& sf);
+std::istream& operator>>(std::istream& o, ARDOUR::ShuttleBehaviour& sf);
+std::istream& operator>>(std::istream& o, ARDOUR::ShuttleUnits& sf);
+std::istream& operator>>(std::istream& o, ARDOUR::SmpteFormat& sf);
+std::istream& operator>>(std::istream& o, ARDOUR::DenormalModel& sf);
+
+using ARDOUR::nframes_t;
+
+static inline nframes_t
+session_frame_to_track_frame (nframes_t session_frame, double speed)
+{
+ return (nframes_t)( (double)session_frame * speed );
+}
+
+static inline nframes_t
+track_frame_to_session_frame (nframes_t track_frame, double speed)
+{
+ return (nframes_t)( (double)track_frame / speed );
+}
+
+
+#endif /* __ardour_types_h__ */
+
diff --git a/libs/ardour/ardour/user_bundle.h b/libs/ardour/ardour/user_bundle.h
new file mode 100644
index 0000000000..954e93d5d1
--- /dev/null
+++ b/libs/ardour/ardour/user_bundle.h
@@ -0,0 +1,72 @@
+/*
+ Copyright (C) 2007 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_user_bundle_h__
+#define __ardour_user_bundle_h__
+
+#include <vector>
+#include <glibmm/thread.h>
+#include "pbd/stateful.h"
+#include "ardour/bundle.h"
+
+namespace ARDOUR {
+
+class Session;
+
+class UserBundle : public Bundle, public PBD::Stateful {
+
+ public:
+ UserBundle (std::string const &);
+ UserBundle (XMLNode const &, bool);
+
+ uint32_t nchannels () const;
+ const ARDOUR::PortList& channel_ports (uint32_t) const;
+
+ void add_channel ();
+ void set_channels (uint32_t);
+ void remove_channel (uint32_t);
+ void add_port_to_channel (uint32_t, std::string const &);
+ void remove_port_from_channel (uint32_t, std::string const &);
+ bool port_attached_to_channel (uint32_t, std::string const &) const;
+ XMLNode& get_state ();
+
+ /// The number of channels is about to change
+ sigc::signal<void> ConfigurationWillChange;
+ /// The number of channels has changed
+ sigc::signal<void> ConfigurationHasChanged;
+ /// The port set associated with one of our channels is about to change
+ /// Parameter is the channel number
+ sigc::signal<void, int> PortsWillChange;
+ /// The port set associated with one of our channels has changed
+ /// Parameter is the channel number
+ sigc::signal<void, int> PortsHaveChanged;
+
+ private:
+
+ int set_state (const XMLNode &);
+
+ /// mutex for _ports;
+ /// XXX: is this necessary?
+ mutable Glib::Mutex _ports_mutex;
+ std::vector<PortList> _ports;
+};
+
+}
+
+#endif
diff --git a/libs/ardour/ardour/utils.h b/libs/ardour/ardour/utils.h
new file mode 100644
index 0000000000..eecde2e85f
--- /dev/null
+++ b/libs/ardour/ardour/utils.h
@@ -0,0 +1,76 @@
+/*
+ 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.
+
+*/
+
+#ifndef __ardour_utils_h__
+#define __ardour_utils_h__
+
+#include <iostream>
+#include <string>
+#include <cmath>
+
+#if defined(HAVE_COREAUDIO) || defined(HAVE_AUDIOUNITS)
+#include <CoreFoundation/CoreFoundation.h>
+#endif
+
+#include "ardour.h"
+
+class XMLNode;
+
+Glib::ustring legalize_for_path (Glib::ustring str);
+std::ostream& operator<< (std::ostream& o, const ARDOUR::BBT_Time& bbt);
+XMLNode* find_named_node (const XMLNode& node, std::string name);
+
+static inline float f_max(float x, float a) {
+ x -= a;
+ x += fabsf (x);
+ x *= 0.5f;
+ x += a;
+
+ return (x);
+}
+
+std::string bump_name_once(std::string s);
+
+int cmp_nocase (const std::string& s, const std::string& s2);
+
+int touch_file(Glib::ustring path);
+
+Glib::ustring path_expand (Glib::ustring);
+Glib::ustring region_name_from_path (Glib::ustring path, bool strip_channels, bool add_channel_suffix = false, uint32_t total = 0, uint32_t this_one = 0);
+bool path_is_paired (Glib::ustring path, Glib::ustring& pair_base);
+
+void compute_equal_power_fades (nframes_t nframes, float* in, float* out);
+
+const char* slave_source_to_string (ARDOUR::SlaveSource src);
+ARDOUR::SlaveSource string_to_slave_source (std::string str);
+
+const char* edit_mode_to_string (ARDOUR::EditMode);
+ARDOUR::EditMode string_to_edit_mode (std::string);
+
+float meter_falloff_to_float (ARDOUR::MeterFalloff);
+ARDOUR::MeterFalloff meter_falloff_from_float (float);
+float meter_falloff_to_db_per_sec (float);
+float meter_hold_to_float (ARDOUR::MeterHold);
+
+#if defined(HAVE_COREAUDIO) || defined(HAVE_AUDIOUNITS)
+std::string CFStringRefToStdString(CFStringRef stringRef);
+#endif // HAVE_COREAUDIO
+
+#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..e41d000f9c
--- /dev/null
+++ b/libs/ardour/ardour/vst_plugin.h
@@ -0,0 +1,116 @@
+/*
+ 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_vst_plugin_h__
+#define __ardour_vst_plugin_h__
+
+#include <list>
+#include <map>
+#include <set>
+#include <vector>
+#include <string>
+#include <dlfcn.h>
+
+#include <sigc++/signal.h>
+#include <pbd/stateful.h>
+#include <jack/types.h>
+#include <ardour/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 */
+
+ std::string 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);
+ nframes_t signal_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 (nframes_t nframes);
+ int connect_and_run (BufferSet&, uint32_t& in, uint32_t& out, nframes_t nframes, nframes_t offset);
+ 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;
+};
+
+class VSTPluginInfo : public PluginInfo
+{
+ public:
+ VSTPluginInfo () {}
+ ~VSTPluginInfo () {}
+
+ PluginPtr load (Session& session);
+};
+
+typedef boost::shared_ptr<VSTPluginInfo> VSTPluginInfoPtr;
+
+} // namespace ARDOUR
+
+#endif /* __ardour_vst_plugin_h__ */