From 449aab3c465bbbf66d221fac3d7ea559f1720357 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Mon, 2 Jun 2008 21:41:35 +0000 Subject: 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 --- libs/ardour/ardour/.cvsignore | 1 + libs/ardour/ardour/amp.h | 44 + libs/ardour/ardour/analyser.h | 35 + libs/ardour/ardour/ardour.h | 87 ++ libs/ardour/ardour/audio_buffer.h | 121 ++ libs/ardour/ardour/audio_diskstream.h | 277 ++++ libs/ardour/ardour/audio_library.h | 54 + libs/ardour/ardour/audio_port.h | 46 + libs/ardour/ardour/audio_track.h | 80 + libs/ardour/ardour/audio_unit.h | 172 +++ libs/ardour/ardour/audioanalyser.h | 74 + libs/ardour/ardour/audioengine.h | 276 ++++ libs/ardour/ardour/audiofilesource.h | 183 +++ libs/ardour/ardour/audioplaylist.h | 93 ++ libs/ardour/ardour/audioregion.h | 204 +++ libs/ardour/ardour/audiosource.h | 159 ++ libs/ardour/ardour/auditioner.h | 70 + libs/ardour/ardour/auto_bundle.h | 50 + libs/ardour/ardour/automatable.h | 121 ++ libs/ardour/ardour/automation_control.h | 64 + libs/ardour/ardour/automation_event.h | 309 ++++ libs/ardour/ardour/base_audio_port.h | 106 ++ libs/ardour/ardour/base_midi_port.h | 67 + libs/ardour/ardour/buffer.h | 92 ++ libs/ardour/ardour/buffer_set.h | 159 ++ libs/ardour/ardour/bundle.h | 73 + libs/ardour/ardour/caimportable.h | 48 + libs/ardour/ardour/chan_count.h | 126 ++ libs/ardour/ardour/click.h | 45 + libs/ardour/ardour/configuration.h | 106 ++ libs/ardour/ardour/configuration_variable.h | 184 +++ libs/ardour/ardour/configuration_vars.h | 176 +++ libs/ardour/ardour/control_protocol_manager.h | 93 ++ libs/ardour/ardour/control_protocol_search_path.h | 42 + libs/ardour/ardour/coreaudiosource.h | 57 + libs/ardour/ardour/crossfade.h | 179 +++ libs/ardour/ardour/crossfade_compare.h | 42 + libs/ardour/ardour/curve.h | 62 + libs/ardour/ardour/cycle_timer.h | 50 + libs/ardour/ardour/cycles.h | 221 +++ libs/ardour/ardour/dB.h | 33 + libs/ardour/ardour/data_type.h | 130 ++ libs/ardour/ardour/directory_names.h | 23 + libs/ardour/ardour/diskstream.h | 308 ++++ libs/ardour/ardour/export.h | 107 ++ libs/ardour/ardour/filename_extensions.h | 17 + libs/ardour/ardour/filesystem_paths.h | 50 + libs/ardour/ardour/filter.h | 51 + libs/ardour/ardour/gain.h | 43 + libs/ardour/ardour/gdither.h | 92 ++ libs/ardour/ardour/gdither_types.h | 48 + libs/ardour/ardour/gdither_types_internal.h | 74 + libs/ardour/ardour/importable_source.h | 43 + libs/ardour/ardour/internal_audio_port.h | 55 + libs/ardour/ardour/internal_port.h | 82 + libs/ardour/ardour/io.h | 391 +++++ libs/ardour/ardour/io_processor.h | 86 ++ libs/ardour/ardour/jack_audio_port.h | 51 + libs/ardour/ardour/jack_midi_port.h | 52 + libs/ardour/ardour/jack_port.h | 112 ++ libs/ardour/ardour/ladspa.h | 606 ++++++++ libs/ardour/ardour/ladspa_plugin.h | 147 ++ libs/ardour/ardour/latent.h | 26 + libs/ardour/ardour/location.h | 206 +++ libs/ardour/ardour/logcurve.h | 132 ++ libs/ardour/ardour/lv2_plugin.h | 171 ++ libs/ardour/ardour/meter.h | 77 + libs/ardour/ardour/midi_buffer.h | 102 ++ libs/ardour/ardour/midi_diskstream.h | 184 +++ libs/ardour/ardour/midi_model.h | 252 +++ libs/ardour/ardour/midi_playlist.h | 84 + libs/ardour/ardour/midi_port.h | 47 + libs/ardour/ardour/midi_region.h | 121 ++ libs/ardour/ardour/midi_ring_buffer.h | 466 ++++++ libs/ardour/ardour/midi_source.h | 119 ++ libs/ardour/ardour/midi_stretch.h | 40 + libs/ardour/ardour/midi_track.h | 111 ++ libs/ardour/ardour/midi_util.h | 73 + libs/ardour/ardour/mix.h | 65 + libs/ardour/ardour/named_selection.h | 55 + libs/ardour/ardour/noise.h | 38 + libs/ardour/ardour/note.h | 82 + libs/ardour/ardour/osc.h | 120 ++ libs/ardour/ardour/panner.h | 299 ++++ libs/ardour/ardour/parameter.h | 168 ++ libs/ardour/ardour/pcm_utils.h | 41 + libs/ardour/ardour/peak.h | 36 + libs/ardour/ardour/pitch.h | 62 + libs/ardour/ardour/playlist.h | 287 ++++ libs/ardour/ardour/playlist_factory.h | 44 + libs/ardour/ardour/playlist_templates.h | 48 + libs/ardour/ardour/plugin.h | 174 +++ libs/ardour/ardour/plugin_insert.h | 131 ++ libs/ardour/ardour/plugin_manager.h | 101 ++ libs/ardour/ardour/port.h | 180 +++ libs/ardour/ardour/port_insert.h | 73 + libs/ardour/ardour/port_set.h | 161 ++ libs/ardour/ardour/processor.h | 123 ++ libs/ardour/ardour/profile.h | 58 + libs/ardour/ardour/quantize.h | 41 + libs/ardour/ardour/rb_effect.h | 42 + libs/ardour/ardour/readable.h | 20 + libs/ardour/ardour/recent_sessions.h | 39 + libs/ardour/ardour/region.h | 313 ++++ libs/ardour/ardour/region_factory.h | 64 + libs/ardour/ardour/resampled_source.h | 55 + libs/ardour/ardour/reverse.h | 37 + libs/ardour/ardour/route.h | 384 +++++ libs/ardour/ardour/route_group.h | 124 ++ libs/ardour/ardour/route_group_specialized.h | 41 + libs/ardour/ardour/runtime_functions.h | 40 + libs/ardour/ardour/send.h | 74 + libs/ardour/ardour/session.h | 1714 +++++++++++++++++++++ libs/ardour/ardour/session_directory.h | 136 ++ libs/ardour/ardour/session_object.h | 65 + libs/ardour/ardour/session_playlist.h | 46 + libs/ardour/ardour/session_region.h | 38 + libs/ardour/ardour/session_route.h | 76 + libs/ardour/ardour/session_selection.h | 39 + libs/ardour/ardour/session_state_utils.h | 65 + libs/ardour/ardour/session_utils.h | 26 + libs/ardour/ardour/silentfilesource.h | 68 + libs/ardour/ardour/slave.h | 153 ++ libs/ardour/ardour/smf_reader.h | 87 ++ libs/ardour/ardour/smf_source.h | 151 ++ libs/ardour/ardour/smpte.h | 79 + libs/ardour/ardour/sndfile_helpers.h | 58 + libs/ardour/ardour/sndfileimportable.h | 50 + libs/ardour/ardour/sndfilesource.h | 109 ++ libs/ardour/ardour/soundseq.h | 53 + libs/ardour/ardour/source.h | 112 ++ libs/ardour/ardour/source_factory.h | 60 + libs/ardour/ardour/spline.h | 90 ++ libs/ardour/ardour/stretch.h | 62 + libs/ardour/ardour/tape_file_matcher.h | 45 + libs/ardour/ardour/template_utils.h | 20 + libs/ardour/ardour/tempo.h | 322 ++++ libs/ardour/ardour/timestamps.h | 32 + libs/ardour/ardour/track.h | 151 ++ libs/ardour/ardour/transient_detector.h | 58 + libs/ardour/ardour/types.h | 443 ++++++ libs/ardour/ardour/user_bundle.h | 72 + libs/ardour/ardour/utils.h | 76 + libs/ardour/ardour/vst_plugin.h | 116 ++ 144 files changed, 17552 insertions(+) create mode 100644 libs/ardour/ardour/.cvsignore create mode 100644 libs/ardour/ardour/amp.h create mode 100644 libs/ardour/ardour/analyser.h create mode 100644 libs/ardour/ardour/ardour.h create mode 100644 libs/ardour/ardour/audio_buffer.h create mode 100644 libs/ardour/ardour/audio_diskstream.h create mode 100644 libs/ardour/ardour/audio_library.h create mode 100644 libs/ardour/ardour/audio_port.h create mode 100644 libs/ardour/ardour/audio_track.h create mode 100644 libs/ardour/ardour/audio_unit.h create mode 100644 libs/ardour/ardour/audioanalyser.h create mode 100644 libs/ardour/ardour/audioengine.h create mode 100644 libs/ardour/ardour/audiofilesource.h create mode 100644 libs/ardour/ardour/audioplaylist.h create mode 100644 libs/ardour/ardour/audioregion.h create mode 100644 libs/ardour/ardour/audiosource.h create mode 100644 libs/ardour/ardour/auditioner.h create mode 100644 libs/ardour/ardour/auto_bundle.h create mode 100644 libs/ardour/ardour/automatable.h create mode 100644 libs/ardour/ardour/automation_control.h create mode 100644 libs/ardour/ardour/automation_event.h create mode 100644 libs/ardour/ardour/base_audio_port.h create mode 100644 libs/ardour/ardour/base_midi_port.h create mode 100644 libs/ardour/ardour/buffer.h create mode 100644 libs/ardour/ardour/buffer_set.h create mode 100644 libs/ardour/ardour/bundle.h create mode 100644 libs/ardour/ardour/caimportable.h create mode 100644 libs/ardour/ardour/chan_count.h create mode 100644 libs/ardour/ardour/click.h create mode 100644 libs/ardour/ardour/configuration.h create mode 100644 libs/ardour/ardour/configuration_variable.h create mode 100644 libs/ardour/ardour/configuration_vars.h create mode 100644 libs/ardour/ardour/control_protocol_manager.h create mode 100644 libs/ardour/ardour/control_protocol_search_path.h create mode 100644 libs/ardour/ardour/coreaudiosource.h create mode 100644 libs/ardour/ardour/crossfade.h create mode 100644 libs/ardour/ardour/crossfade_compare.h create mode 100644 libs/ardour/ardour/curve.h create mode 100644 libs/ardour/ardour/cycle_timer.h create mode 100644 libs/ardour/ardour/cycles.h create mode 100644 libs/ardour/ardour/dB.h create mode 100644 libs/ardour/ardour/data_type.h create mode 100644 libs/ardour/ardour/directory_names.h create mode 100644 libs/ardour/ardour/diskstream.h create mode 100644 libs/ardour/ardour/export.h create mode 100644 libs/ardour/ardour/filename_extensions.h create mode 100644 libs/ardour/ardour/filesystem_paths.h create mode 100644 libs/ardour/ardour/filter.h create mode 100644 libs/ardour/ardour/gain.h create mode 100644 libs/ardour/ardour/gdither.h create mode 100644 libs/ardour/ardour/gdither_types.h create mode 100644 libs/ardour/ardour/gdither_types_internal.h create mode 100644 libs/ardour/ardour/importable_source.h create mode 100644 libs/ardour/ardour/internal_audio_port.h create mode 100644 libs/ardour/ardour/internal_port.h create mode 100644 libs/ardour/ardour/io.h create mode 100644 libs/ardour/ardour/io_processor.h create mode 100644 libs/ardour/ardour/jack_audio_port.h create mode 100644 libs/ardour/ardour/jack_midi_port.h create mode 100644 libs/ardour/ardour/jack_port.h create mode 100644 libs/ardour/ardour/ladspa.h create mode 100644 libs/ardour/ardour/ladspa_plugin.h create mode 100644 libs/ardour/ardour/latent.h create mode 100644 libs/ardour/ardour/location.h create mode 100644 libs/ardour/ardour/logcurve.h create mode 100644 libs/ardour/ardour/lv2_plugin.h create mode 100644 libs/ardour/ardour/meter.h create mode 100644 libs/ardour/ardour/midi_buffer.h create mode 100644 libs/ardour/ardour/midi_diskstream.h create mode 100644 libs/ardour/ardour/midi_model.h create mode 100644 libs/ardour/ardour/midi_playlist.h create mode 100644 libs/ardour/ardour/midi_port.h create mode 100644 libs/ardour/ardour/midi_region.h create mode 100644 libs/ardour/ardour/midi_ring_buffer.h create mode 100644 libs/ardour/ardour/midi_source.h create mode 100644 libs/ardour/ardour/midi_stretch.h create mode 100644 libs/ardour/ardour/midi_track.h create mode 100644 libs/ardour/ardour/midi_util.h create mode 100644 libs/ardour/ardour/mix.h create mode 100644 libs/ardour/ardour/named_selection.h create mode 100644 libs/ardour/ardour/noise.h create mode 100644 libs/ardour/ardour/note.h create mode 100644 libs/ardour/ardour/osc.h create mode 100644 libs/ardour/ardour/panner.h create mode 100644 libs/ardour/ardour/parameter.h create mode 100644 libs/ardour/ardour/pcm_utils.h create mode 100644 libs/ardour/ardour/peak.h create mode 100644 libs/ardour/ardour/pitch.h create mode 100644 libs/ardour/ardour/playlist.h create mode 100644 libs/ardour/ardour/playlist_factory.h create mode 100644 libs/ardour/ardour/playlist_templates.h create mode 100644 libs/ardour/ardour/plugin.h create mode 100644 libs/ardour/ardour/plugin_insert.h create mode 100644 libs/ardour/ardour/plugin_manager.h create mode 100644 libs/ardour/ardour/port.h create mode 100644 libs/ardour/ardour/port_insert.h create mode 100644 libs/ardour/ardour/port_set.h create mode 100644 libs/ardour/ardour/processor.h create mode 100644 libs/ardour/ardour/profile.h create mode 100644 libs/ardour/ardour/quantize.h create mode 100644 libs/ardour/ardour/rb_effect.h create mode 100644 libs/ardour/ardour/readable.h create mode 100644 libs/ardour/ardour/recent_sessions.h create mode 100644 libs/ardour/ardour/region.h create mode 100644 libs/ardour/ardour/region_factory.h create mode 100644 libs/ardour/ardour/resampled_source.h create mode 100644 libs/ardour/ardour/reverse.h create mode 100644 libs/ardour/ardour/route.h create mode 100644 libs/ardour/ardour/route_group.h create mode 100644 libs/ardour/ardour/route_group_specialized.h create mode 100644 libs/ardour/ardour/runtime_functions.h create mode 100644 libs/ardour/ardour/send.h create mode 100644 libs/ardour/ardour/session.h create mode 100644 libs/ardour/ardour/session_directory.h create mode 100644 libs/ardour/ardour/session_object.h create mode 100644 libs/ardour/ardour/session_playlist.h create mode 100644 libs/ardour/ardour/session_region.h create mode 100644 libs/ardour/ardour/session_route.h create mode 100644 libs/ardour/ardour/session_selection.h create mode 100644 libs/ardour/ardour/session_state_utils.h create mode 100644 libs/ardour/ardour/session_utils.h create mode 100644 libs/ardour/ardour/silentfilesource.h create mode 100644 libs/ardour/ardour/slave.h create mode 100644 libs/ardour/ardour/smf_reader.h create mode 100644 libs/ardour/ardour/smf_source.h create mode 100644 libs/ardour/ardour/smpte.h create mode 100644 libs/ardour/ardour/sndfile_helpers.h create mode 100644 libs/ardour/ardour/sndfileimportable.h create mode 100644 libs/ardour/ardour/sndfilesource.h create mode 100644 libs/ardour/ardour/soundseq.h create mode 100644 libs/ardour/ardour/source.h create mode 100644 libs/ardour/ardour/source_factory.h create mode 100644 libs/ardour/ardour/spline.h create mode 100644 libs/ardour/ardour/stretch.h create mode 100644 libs/ardour/ardour/tape_file_matcher.h create mode 100644 libs/ardour/ardour/template_utils.h create mode 100644 libs/ardour/ardour/tempo.h create mode 100644 libs/ardour/ardour/timestamps.h create mode 100644 libs/ardour/ardour/track.h create mode 100644 libs/ardour/ardour/transient_detector.h create mode 100644 libs/ardour/ardour/types.h create mode 100644 libs/ardour/ardour/user_bundle.h create mode 100644 libs/ardour/ardour/utils.h create mode 100644 libs/ardour/ardour/vst_plugin.h (limited to 'libs/ardour/ardour') 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 + +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 +#include + +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, bool force); + static void work (); + + private: + static Analyser* the_analyser; + static Glib::StaticMutex analysis_queue_lock; + static Glib::Cond* SourcesToAnalyse; + static std::list > analysis_queue; + + static void analyse_audio_file_source (boost::shared_ptr); +}; + + +} + +#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 +#include + +#include +#include + +#include +#include + +#include +#include + +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 BootMessage; + + int init (bool with_vst, bool try_optimization); + int cleanup (); + + std::string get_ardour_revision (); + + void find_bindings_files (std::map&); + + 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 +#include + +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 + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 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 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 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 audio_playlist () { return boost::dynamic_pointer_cast(_playlist); } + + int use_playlist (boost::shared_ptr); + int use_new_playlist (); + int use_copy_playlist (); + + Sample *playback_buffer (uint32_t n = 0) { + boost::shared_ptr 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 c = channels.reader(); + if (n < c->size()) + return (*c)[n]->current_capture_buffer; + return 0; + } + + boost::shared_ptr write_source (uint32_t n=0) { + boost::shared_ptr c = channels.reader(); + if (n < c->size()) + return (*c)[n]->write_source; + return boost::shared_ptr(); + } + + 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 fades_source; + boost::shared_ptr write_source; + + /// the Port that our audio data comes from + Port *source; + Sample *current_capture_buffer; + Sample *current_playback_buffer; + + RingBufferNPT *playback_buf; + RingBufferNPT *capture_buf; + + Sample* scrub_buffer; + Sample* scrub_forward_buffer; + Sample* scrub_reverse_buffer; + + RingBufferNPT::rw_vector playback_vector; + RingBufferNPT::rw_vector capture_vector; + + RingBufferNPT * capture_transition_buf; + // the following are used in the butler thread only + nframes_t curr_capture_cnt; + }; + + typedef std::vector 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); + 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 > capturing_sources; + + SerializedRCUManager channels; + + /* really */ + private: + int _do_refill (Sample *mixdown_buffer, float *gain_buffer); + + int add_channel_to (boost::shared_ptr, uint32_t how_many); + int remove_channel_from (boost::shared_ptr, 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 +#include +#include + +using std::vector; +using std::string; +using std::map; + +namespace ARDOUR { + +class AudioLibrary +{ + public: + AudioLibrary (); + ~AudioLibrary (); + + void set_tags (string member, vector tags); + vector get_tags (string member); + + void search_members_and (vector& results, const vector 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 + +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 + +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 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, 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 +#include + +#include +#include +#include +#include + +#include + +#include +#include + +#include + +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 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 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 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 get_au () { return unit; } + boost::shared_ptr get_comp () const { return comp; } + + OSStatus render_callback(AudioUnitRenderActionFlags *ioActionFlags, + const AudioTimeStamp *inTimeStamp, + UInt32 inBusNumber, + UInt32 inNumberFrames, + AudioBufferList* ioData); + private: + boost::shared_ptr comp; + boost::shared_ptr 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 > parameter_map; + uint32_t current_maxbuf; + nframes_t current_offset; + nframes_t cb_offset; + vector* current_buffers; + nframes_t frames_processed; + + std::vector descriptors; + void init (); +}; + +typedef boost::shared_ptr AUPluginPtr; + +class AUPluginInfo : public PluginInfo { + public: + AUPluginInfo (boost::shared_ptr); + ~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 descriptor; + + static void discover_music (PluginInfoList&); + static void discover_fx (PluginInfoList&); + static void discover_by_description (PluginInfoList&, CAComponentDescription&); +}; + +typedef boost::shared_ptr 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 +#include +#include +#include +#include +#include + +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 +#include +#include +#include +#include + +#include + +#include + +#include + +#include +#include +#include +#include +#include + +namespace ARDOUR { + +class Session; +class Port; +class InternalPort; + +class AudioEngine : public sigc::trackable +{ + public: + typedef std::set 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&); + void get_physical_inputs (std::vector&); + + 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 Freewheel; + + sigc::signal Xrun; + + /* this signal is if JACK notifies us of a graph order event */ + + sigc::signal GraphReordered; + + /* this signal is emitted if the sample rate changes */ + + sigc::signal SampleRateChanged; + + /* this signal is sent if JACK ever disconnects us */ + + sigc::signal Halted; + + /* these two are emitted when the engine itself is + started and stopped + */ + + sigc::signal Running; + sigc::signal 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 freewheel_action; + bool reconnect_on_halt; + int _usecs_per_cycle; + + SerializedRCUManager 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 PortConnection; + typedef std::list 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 + +#include + +#include + +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 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 +#include + +#include +#include + +namespace ARDOUR { + +class Session; +class Region; +class AudioRegion; +class Source; + +class AudioPlaylist : public ARDOUR::Playlist +{ + public: + typedef std::list > Crossfades; + + public: + AudioPlaylist (Session&, const XMLNode&, bool hidden = false); + AudioPlaylist (Session&, string name, bool hidden = false); + AudioPlaylist (boost::shared_ptr, string name, bool hidden = false); + AudioPlaylist (boost::shared_ptr, 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 > NewCrossfade; + + template void foreach_crossfade (T *t, void (T::*func)(boost::shared_ptr)); + void crossfades_at (nframes_t frame, Crossfades&); + + bool destroy_region (boost::shared_ptr); + + protected: + + /* playlist "callbacks" */ + void notify_crossfade_added (boost::shared_ptr); + void flush_notifications (); + + void finalize_split_region (boost::shared_ptr orig, boost::shared_ptr left, boost::shared_ptr right); + + void refresh_dependents (boost::shared_ptr region); + void check_dependents (boost::shared_ptr region, bool norefresh); + void remove_dependents (boost::shared_ptr region); + + private: + Crossfades _crossfades; + Crossfades _pending_xfade_adds; + + void crossfade_invalidated (boost::shared_ptr); + XMLNode& state (bool full_state); + void dump () const; + + bool region_changed (Change, boost::shared_ptr); + void crossfade_changed (Change); + void add_crossfade (boost::shared_ptr); + + void source_offset_changed (boost::shared_ptr 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 +#include + +#include +#include + +#include +#include +#include +#include +#include + +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 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 fade_in() { return _fade_in; } + boost::shared_ptr fade_out() { return _fade_out; } + boost::shared_ptr 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 >&) 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, nframes_t start, nframes_t length); + AudioRegion (boost::shared_ptr, 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, nframes_t start, nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags); + AudioRegion (boost::shared_ptr, 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 _fade_in; + FadeShape _fade_in_shape; + boost::shared_ptr _fade_out; + FadeShape _fade_out_shape; + boost::shared_ptr _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); + + 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 +#include + +#include +#include + +#include + +#include +#include + +#include + +#include +#include +#include +#include + +using std::list; +using std::vector; + +namespace ARDOUR { + +class AudioSource : public Source, public boost::enable_shared_from_this +{ + 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, sigc::connection&) const; + + mutable sigc::signal PeaksReady; + mutable sigc::signal 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 + +#include + +#include +#include + +namespace ARDOUR { + +class Session; +class AudioRegion; +class AudioPlaylist; + +class Auditioner : public AudioTrack +{ + public: + Auditioner (Session&); + ~Auditioner (); + + void audition_region (boost::shared_ptr); + + 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 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 +#include +#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 _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 +#include +#include +#include +#include +#include +#include + +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 + control(AutomationType type, bool create_if_missing=false) { + return control(Parameter(type), create_if_missing); + } + + virtual boost::shared_ptr control(Parameter id, bool create_if_missing=false); + virtual boost::shared_ptr control(Parameter id) const; + + boost::shared_ptr control_factory(boost::shared_ptr list); + + typedef std::map > Controls; + Controls& controls() { return _controls; } + const Controls& controls() const { return _controls; } + + virtual void add_control(boost::shared_ptr); + + 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&) const; + void what_has_visible_automation(std::set&) const; + const std::set& 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 _visible_controls; + std::set _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 +#include +#include + +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, + std::string name="unnamed controllable"); + + void set_value(float val); + float get_value() const; + float user_value() const; + + void set_list(boost::shared_ptr); + + boost::shared_ptr list() { return _list; } + boost::shared_ptr list() const { return _list; } + + Parameter parameter() const; + +protected: + ARDOUR::Session& _session; + boost::shared_ptr _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 +#include +#include + +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include + +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 ControlEventAllocator; + +class AutomationList : public PBD::StatefulDestructible +{ + public: + typedef std::list 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 automation_style_changed; + + void set_automation_style (AutoStyle m); + AutoStyle automation_style() const { return _style; } + sigc::signal 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 control_points_adjacent (double when); + + template void apply_to_points (T& obj, void (T::*method)(const AutomationList&)) { + Glib::Mutex::Lock lm (_lock); + (obj.*method)(*this); + } + + sigc::signal 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 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 range; + }; + + static sigc::signal AutomationListCreated; + + const EventList& events() const { return _events; } + double default_value() const { return _default_value; } + + // teeny const violations for Curve + mutable sigc::signal 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 + +#include + +#include + +#include +#include +#include + +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&, 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&, AudioBuffer*, nframes_t, nframes_t, bool); + + static void default_mixdown (const std::set&, 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 +#include +#include +#include +#include + +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&, MidiBuffer*, nframes_t, nframes_t, bool)); + + protected: + BaseMidiPort (const std::string& name, Flags); + + MidiBuffer* _buffer; + bool _own_buffer; + + void (*_mixdown)(const std::set&, MidiBuffer*, nframes_t, nframes_t, bool); + static void default_mixdown (const std::set&, 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 +#include +#include +#include +#include +#include +#include + +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 +#include +#include +#include + +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 BufferVec; + + /// Vector of vectors, indexed by DataType + std::vector _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 +#include +#include "ardour/data_type.h" + +namespace ARDOUR { + +typedef std::vector 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 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 +#include +#include + +#include + +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 +#include + +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 + +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 +#include + +#include +#include + +#include + +#include +#include +#include + +class XMLNode; + +namespace ARDOUR { + +class Configuration : public PBD::Stateful +{ + public: + Configuration(); + virtual ~Configuration(); + + std::map midi_ports; + + void map_parameters (sigc::slot 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, 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 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 var; +#define CONFIG_VARIABLE_SPECIAL(Type,var,name,value,mutator) ConfigVariableWithMutation 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 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 +#include +#include + +#include + +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 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 ConfigVariableWithMutation : public ConfigVariable +{ + public: + ConfigVariableWithMutation (std::string name, T val, T (*m)(T)) + : ConfigVariable (name, val), mutator (m) {} + + bool set (T val, ConfigVariableBase::Owner owner) { + if (unmutated_value != val) { + unmutated_value = val; + return ConfigVariable::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 +#include + +#include + +#include + +#include + +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 load_mandatory_protocols (); + + ControlProtocol* instantiate (ControlProtocolInfo&); + int teardown (ControlProtocolInfo&); + + std::list 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 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 + +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 +#include + +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 +#include +#include + +#include + +#include +#include + +#include +#include +#include +#include + +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 in, boost::shared_ptr 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 in, boost::shared_ptr 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, boost::shared_ptr, boost::shared_ptr); + + /* 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 in() const { return _in; } + boost::shared_ptr 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 region) const { + return _in == region || _out == region; + } + + bool involves (boost::shared_ptr a, boost::shared_ptr b) const { + return (_in == a && _out == b) || (_in == b && _out == a); + } + + nframes_t overlap_length() const; + + void invalidate(); + + sigc::signal > Invalidated; + sigc::signal 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 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 _in; + boost::shared_ptr _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, boost::shared_ptr, 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 +#include +#include +#include +#include +#include +#include +#include + +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 +#include + +#include + +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 + +#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 + +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 + +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 + +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 +#include + +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 + +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 + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +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 () { return _playlist; } + + virtual int use_playlist (boost::shared_ptr); + 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 >& last_capture_regions () { return _last_capture_regions; } + + void handle_input_change (IOChange, void *src); + + void remove_region_from_last_capture (boost::weak_ptr wregion); + + sigc::signal RecordEnableChanged; + sigc::signal SpeedChanged; + sigc::signal ReverseChanged; + sigc::signal PlaylistChanged; + sigc::signal AlignmentStyleChanged; + sigc::signal LoopSet; + + static sigc::signal DiskOverrun; + static sigc::signal 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); + + 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 > _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 capture_info; + Glib::Mutex capture_info_lock; + + uint32_t i_am_the_modifier; + + ARDOUR::IO* _io; + ChanCount _n_channels; + + boost::shared_ptr _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 +#include +#include + +#include + +#include +#include + +#include +#include + +using std::map; +using std::vector; +using std::string; +using std::pair; + +namespace ARDOUR +{ + class Port; + + typedef pair PortChannelPair; + typedef map > 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 +#include + +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 +#include + +namespace ARDOUR { + +class Region; +class Session; + +class Filter { + + public: + virtual ~Filter() {} + + virtual int run (boost::shared_ptr) = 0; + std::vector > results; + + protected: + Filter (ARDOUR::Session& s) : session(s) {} + + int make_new_sources (boost::shared_ptr, ARDOUR::SourceList&, std::string suffix = ""); + int finish (boost::shared_ptr, 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 + * + * 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 + * + * 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 + * + * 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 + +#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 +#include + +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 +#include +#include +#include +#include + +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&, AudioBuffer&, nframes_t, nframes_t)); + void reset (); + + protected: + friend class AudioEngine; + + InternalAudioPort (const std::string& name, Flags flags); + void (*_mixdown)(const std::list&, AudioBuffer&, nframes_t, nframes_t); + + static void default_mixdown (const std::list&, 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 + +#include +#include +#include + +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 _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 +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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, void *src); + int connect_output_ports_to_bundle (boost::shared_ptr, void *src); + + std::vector > bundles_connected_to_inputs (); + std::vector > bundles_connected_to_outputs (); + + boost::shared_ptr bundle_for_inputs () { return _bundle_for_inputs; } + boost::shared_ptr 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 active_changed; + + sigc::signal input_changed; + sigc::signal 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 PortsLegal; + static sigc::signal PannersLegal; + static sigc::signal ConnectingLegal; + /// raised when the number of input or output ports changes + static sigc::signal PortCountChanged; + static sigc::signal PortsCreated; + + static void update_meters(); + + private: + + static sigc::signal 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 al) + : AutomationControl (i._session, al, name) + , _io (i) + {} + + void set_value (float val); + float get_value (void) const; + + IO& _io; + }; + + boost::shared_ptr gain_control() { + return _gain_control; + } + boost::shared_ptr 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 _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 _bundle_for_inputs; ///< a bundle representing our inputs + boost::shared_ptr _bundle_for_outputs; ///< a bundle representing our outputs + + struct UserBundleInfo { + UserBundleInfo (IO*, boost::shared_ptr b); + + boost::shared_ptr bundle; + sigc::connection configuration_will_change; + sigc::connection configuration_has_changed; + sigc::connection ports_will_change; + sigc::connection ports_have_changed; + }; + + std::vector _bundles_connected_to_outputs; ///< user bundles connected to our outputs + std::vector _bundles_connected_to_inputs; ///< user bundles connected to our inputs + + static int parse_io_string (const string&, vector& chns); + + static int parse_gain_string (const string&, vector& chns); + + int set_sources (vector&, void *src, bool add); + int set_destinations (vector&, 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&, 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, std::vector >*); + void maybe_add_output_bundle_to_list (boost::shared_ptr, std::vector >*); +}; + +} // 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 +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include + +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() { return _io; } + boost::shared_ptr 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 AutomationPlaybackChanged; + sigc::signal AutomationChanged; + + XMLNode& state (bool full_state); + int set_state (const XMLNode&); + + protected: + boost::shared_ptr _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 +#include +#include +#include +#include + +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 +#include +#include +#include +#include +#include +#include +#include +#include + +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 +#include +#include +#include + +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& 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 _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 +#include +#include +#include + +#include + +#include + +#include +#include +#include + +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 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 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 + +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 +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include + +#include + +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 name_changed; + sigc::signal end_changed; + sigc::signal start_changed; + + sigc::signal FlagsChanged; + + /* this is sent only when both start&end change at the same time */ + + sigc::signal changed; + + /* CD Track / CD-Text info */ + + std::map 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 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 current_changed; + sigc::signal changed; + sigc::signal added; + sigc::signal removed; + sigc::signal StateChanged; + + template void apply (T& obj, void (T::*method)(LocationList&)) { + Glib::Mutex::Lock lm (lock); + (obj.*method)(locations); + } + + template 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 +#include + +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 +#include +#include +#include + +#include + +#include + +#include +#include +#include + +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 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 _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 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 +#include +#include +#include + +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 _peak_power; + std::vector _visible_peak_power; + std::vector _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 +#include + +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 + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 midi_playlist () { return boost::dynamic_pointer_cast(_playlist); } + + int use_playlist (boost::shared_ptr); + 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 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 _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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 automation_list; + double x; + double y; + + MidiControlIterator(boost::shared_ptr 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 note_at(unsigned i) const { return _notes[i]; } + inline const boost::shared_ptr 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 a, + const boost::shared_ptr b) { + return a->time() < b->time(); + } + + struct LaterNoteEndComparator { + typedef const Note* value_type; + inline bool operator()(const boost::shared_ptr a, + const boost::shared_ptr b) const { + return a->end_time() > b->end_time(); + } + }; + + typedef std::vector< boost::shared_ptr > 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 m, const std::string& name); + DeltaCommand (boost::shared_ptr, 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); + void remove(const boost::shared_ptr note); + + private: + XMLNode &marshal_note(const boost::shared_ptr note); + boost::shared_ptr unmarshal_note(XMLNode *xml_note); + + boost::shared_ptr _model; + const std::string _name; + + typedef std::list< boost::shared_ptr > 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 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 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 operator->() const { return _event; } + const boost::shared_ptr 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 _event; + + typedef std::priority_queue< + boost::shared_ptr, std::deque< boost::shared_ptr >, + LaterNoteEndComparator> + ActiveNotes; + + mutable ActiveNotes _active_notes; + + bool _is_end; + bool _locked; + Notes::const_iterator _note_iter; + std::vector _control_iters; + std::vector::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& ev, const MidiControlIterator& iter) const; + +private: + friend class DeltaCommand; + void add_note_unlocked(const boost::shared_ptr note); + void remove_note_unlocked(const boost::shared_ptr 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 WriteNotes; + WriteNotes _write_notes[16]; + bool _writing; + bool _edited; + + typedef std::vector< boost::shared_ptr > 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, std::deque< boost::shared_ptr >, + 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 +#include + +#include +#include +#include + +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 other, string name, bool hidden = false); + MidiPlaylist (boost::shared_ptr 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); + + void set_note_mode (NoteMode m) { _note_mode = m; } + + std::set contained_automation(); + +protected: + + /* playlist "callbacks" */ + + void finalize_split_region (boost::shared_ptr original, boost::shared_ptr left, boost::shared_ptr right); + + void check_dependents (boost::shared_ptr region, bool norefresh); + void refresh_dependents (boost::shared_ptr region); + void remove_dependents (boost::shared_ptr region); + +private: + void dump () const; + + bool region_changed (Change, boost::shared_ptr); + + 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 + +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 + +#include +#include + +#include +#include +#include +#include +#include +#include + +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 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&) 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 control(Parameter id, bool create_if_missing=false) + { return midi_source()->model()->control(id, create_if_missing); } + + boost::shared_ptr control(Parameter id) const + { return midi_source()->model()->control(id); } + + int exportme (ARDOUR::Session&, ARDOUR::ExportSpecification&); + + private: + friend class RegionFactory; + + MidiRegion (boost::shared_ptr, nframes_t start, nframes_t length); + MidiRegion (boost::shared_ptr, 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, nframes_t start, nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags); + MidiRegion (boost::shared_ptr); + MidiRegion (boost::shared_ptr, 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); + + 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 +#include +#include +#include + +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 +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 +size_t +MidiRingBufferBase::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 +bool +MidiRingBufferBase::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 +size_t +MidiRingBufferBase::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 +bool +MidiRingBufferBase::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 +bool +MidiRingBufferBase::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 +inline void +MidiRingBufferBase::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 { +public: + /** @param size Size in bytes. + */ + MidiRingBuffer(size_t size) + : MidiRingBufferBase(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((g_atomic_int_get(&_channel_mask) & 0xFFFF0000) >> 16); + } + + uint16_t get_channel_mask() const { + return static_cast((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::full_read(sizeof(double), (uint8_t*)time); + + if (success) { + success = MidiRingBufferBase::full_read(sizeof(size_t), (uint8_t*)size); + } + if (success) { + success = MidiRingBufferBase::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::full_read(sizeof(double), (uint8_t*)time); + if (success) { + success = MidiRingBufferBase::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::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::write(sizeof(double), (uint8_t*)&time); + MidiRingBufferBase::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::write(size, tmp_buf); + } else { + MidiRingBufferBase::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::full_read(sizeof(double), (uint8_t*)&ev_time); + if (success) { + success = MidiRingBufferBase::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::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 + +#include + +#include + +#include + +#include +#include +#include +#include +#include +#include + +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 MidiSourceCreated; + + // Signal a range of recorded data is available for reading from model() + mutable sigc::signal 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 model() { return _model; } + void set_model(boost::shared_ptr 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 _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 + +namespace ARDOUR { + +class MidiStretch : public Filter { + public: + MidiStretch (ARDOUR::Session&, TimeFXRequest&); + ~MidiStretch (); + + int run (boost::shared_ptr); + + 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 +#include + +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 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 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 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 + +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 +#include +#include + +#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 +#include +#include + +#include + +class XMLNode; + +namespace ARDOUR +{ +class Session; +class Playlist; + +struct NamedSelection : public PBD::Stateful +{ + NamedSelection (std::string, std::list >&); + NamedSelection (Session&, const XMLNode&); + virtual ~NamedSelection (); + + std::string name; + std::list > playlists; + + XMLNode& get_state (void); + + int set_state (const XMLNode&); + + static sigc::signal 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 +#include + +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 + +#include +#include + +#include + +#include + +#include + +#include + +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(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(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 +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +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 pan_control() { return _control; } + + sigc::signal Changed; /* for position */ + sigc::signal 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(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 _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, 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 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 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 LinkStateChanged; + sigc::signal 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 +#include +#include +#include + +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: + *
    + *
  1. Irreflexivity: f(x, x) is false because of the irreflexivity of \c < in each branch.
  2. + * + *
  3. 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==.
  4. + * + *
  5. 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: + *
      + *
    1. x == z which contradicts the assumption f(x, y) and f(y, x) + * because of antisymmetry. + *
    2. + *
    3. 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. + *
    4. + *
    + *
  6. + *
+ */ + + 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 +#include +#include + +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 + +namespace ARDOUR { + class AudioRegion; +} + +#ifdef USE_RUBBERBAND + +#include + +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); + + 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 +#include +#include +#include +#include +#include + +#include + +#include + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace ARDOUR { + +class Session; +class Region; + +class Playlist : public SessionObject, public boost::enable_shared_from_this { + public: + typedef list > RegionList; + + Playlist (Session&, const XMLNode&, DataType type, bool hidden = false); + Playlist (Session&, string name, DataType type, bool hidden = false); + Playlist (boost::shared_ptr, string name, bool hidden = false); + Playlist (boost::shared_ptr, 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, nframes_t position, float times = 1); + void remove_region (boost::shared_ptr); + void get_equivalent_regions (boost::shared_ptr, std::vector >&); + void get_region_list_equivalent_regions (boost::shared_ptr, std::vector >&); + void replace_region (boost::shared_ptr old, boost::shared_ptr newr, nframes_t pos); + void split_region (boost::shared_ptr, 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, nframes_t position, float times); + void nudge_after (nframes_t start, nframes_t distance, bool forwards); + void shuffle (boost::shared_ptr, int dir); + void update_after_tempo_map_change (); + + boost::shared_ptr cut (list&, bool result_is_hidden = true); + boost::shared_ptr copy (list&, bool result_is_hidden = true); + int paste (boost::shared_ptr, 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 find_region (const PBD::ID&) const; + boost::shared_ptr top_region_at (nframes_t frame); + boost::shared_ptr 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); + + nframes64_t find_next_transient (nframes64_t position, int dir); + + template void foreach_region (T *t, void (T::*func)(boost::shared_ptr, void *), void *arg); + template void foreach_region (T *t, void (T::*func)(boost::shared_ptr)); + + XMLNode& get_state (); + int set_state (const XMLNode&); + XMLNode& get_template (); + + sigc::signal InUse; + sigc::signal Modified; + sigc::signal NameChanged; + sigc::signal LengthChanged; + + static string bump_name (string old_name, Session&); + + void freeze (); + void thaw (); + + void raise_region (boost::shared_ptr); + void lower_region (boost::shared_ptr); + void raise_region_to_top (boost::shared_ptr); + void lower_region_to_bottom (boost::shared_ptr); + + 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) = 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 > 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 > pending_adds; + std::set > 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); + void notify_region_added (boost::shared_ptr); + 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); + virtual bool region_changed (Change, boost::shared_ptr); + + void region_bounds_changed (Change, boost::shared_ptr); + void region_deleted (boost::shared_ptr); + + void sort_regions (); + + void possibly_splice (nframes_t at, nframes64_t distance, boost::shared_ptr exclude = boost::shared_ptr()); + void possibly_splice_unlocked(nframes_t at, nframes64_t distance, boost::shared_ptr exclude = boost::shared_ptr()); + + void core_splice (nframes_t at, nframes64_t distance, boost::shared_ptr exclude); + void splice_locked (nframes_t at, nframes64_t distance, boost::shared_ptr exclude); + void splice_unlocked (nframes_t at, nframes64_t distance, boost::shared_ptr exclude); + + virtual void finalize_split_region (boost::shared_ptr original, boost::shared_ptr left, boost::shared_ptr right) {} + + virtual void check_dependents (boost::shared_ptr region, bool norefresh) {} + virtual void refresh_dependents (boost::shared_ptr region) {} + virtual void remove_dependents (boost::shared_ptr region) {} + + virtual XMLNode& state (bool); + + boost::shared_ptr region_by_id (PBD::ID); + + void add_region_internal (boost::shared_ptr, nframes_t position); + + int remove_region_internal (boost::shared_ptr); + 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 cut_copy (boost::shared_ptr (Playlist::*pmf)(nframes_t, nframes_t, bool), + list& ranges, bool result_is_hidden); + boost::shared_ptr cut (nframes_t start, nframes_t cnt, bool result_is_hidden); + boost::shared_ptr copy (nframes_t start, nframes_t cnt, bool result_is_hidden); + + int move_region_to_layer (layer_t, boost::shared_ptr r, int dir); + void relayer (); + + void unset_freeze_parent (Playlist*); + void unset_freeze_child (Playlist*); + + void timestamp_layer_op (boost::shared_ptr); + + void _split_region (boost::shared_ptr, 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 + +class XMLNode; + +namespace ARDOUR { + +class Session; + +class PlaylistFactory { + + public: + static sigc::signal > PlaylistCreated; + + static boost::shared_ptr create (Session&, const XMLNode&, bool hidden = false); + static boost::shared_ptr create (DataType type, Session&, string name, bool hidden = false); + static boost::shared_ptr create (boost::shared_ptr, string name, bool hidden = false); + static boost::shared_ptr create (boost::shared_ptr, 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 void AudioPlaylist::foreach_crossfade (T *t, void (T::*func)(boost::shared_ptr)) { + RegionLock rlock (this, false); + for (Crossfades::iterator i = _crossfades.begin(); i != _crossfades.end(); i++) { + (t->*func) (*i); + } +} + +template void Playlist::foreach_region (T *t, void (T::*func)(boost::shared_ptr, void *), void *arg) { + RegionLock rlock (this, false); + for (RegionList::iterator i = regions.begin(); i != regions.end(); i++) { + (t->*func) ((*i), arg); + } + } + +template void Playlist::foreach_region (T *t, void (T::*func)(boost::shared_ptr)) { + 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 +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +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 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 PluginInfoPtr; +typedef std::list 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 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 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 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 +#include + +#include +#include +#include +#include +#include + +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, 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 list); + + void set_value (float val); + float get_value (void) const; + + private: + PluginInsert& _plugin; + boost::shared_ptr _list; + bool _logarithmic; + bool _toggled; + }; + + boost::shared_ptr 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 > _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_factory (boost::shared_ptr); +}; + +} // 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 +#include +#include + +#include +#include + +#ifdef HAVE_SLV2 +#include +#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 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 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 +#include +#include + +#include +#include +#include +#include +#include + +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&) 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 MonitorInputChanged; + sigc::signal 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 _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&) 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 +#include +#include + +#include +#include +#include +#include + +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 +#include +#include +#include +#include + +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 PortVec; + + // Vector of vectors, indexed by DataType::to_index() + std::vector _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 +#include +#include + +#include + +#include + +#include +#include +#include +#include +#include + +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 clone (boost::shared_ptr); + + 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 ProcessorCreated; + + sigc::signal ActiveChanged; + sigc::signal 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 +#include + +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 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 + +namespace ARDOUR { + +class Quantize : public Filter { +public: + Quantize (ARDOUR::Session&, double q); + ~Quantize (); + + int run (boost::shared_ptr); + +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 + +namespace ARDOUR { + +class AudioRegion; + +class RBEffect : public Filter { + public: + RBEffect (ARDOUR::Session&, TimeFXRequest&); + ~RBEffect (); + + int run (boost::shared_ptr); + + 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 + +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 +#include +#include + +using std::deque; +using std::pair; +using std::string; + +namespace ARDOUR { + typedef deque > 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 +#include +#include + +#include + +#include +#include +#include +#include + +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, public Readable +{ + public: + typedef std::vector > 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 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: + *
+	 * |------------------------------------------------------------------- track
+	 *                    |..........[------------------].....| region
+	 * |-----------------------------| _position
+	 *                               |------------------| _length
+	 *                    |----------| _start
+	 * 
+ */ + 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; + bool size_equivalent (boost::shared_ptr) const; + bool overlap_equivalent (boost::shared_ptr) const; + bool region_list_equivalent (boost::shared_ptr) const; + bool source_equivalent (boost::shared_ptr) 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 playlist() const { return _playlist.lock(); } + virtual void set_playlist (boost::weak_ptr); + + void source_deleted (boost::shared_ptr); + + boost::shared_ptr 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 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 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 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 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, nframes_t start, nframes_t length, const string& name, layer_t = 0, Flag flags = DefaultFlags); + Region (boost::shared_ptr); + Region (boost::shared_ptr 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 _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 +#include + +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 > CheckNewRegion; + + static boost::shared_ptr create (boost::shared_ptr); + + /* 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 create (boost::shared_ptr, nframes_t start, + nframes_t length, std::string name, + layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true); + static boost::shared_ptr create (boost::shared_ptr, nframes_t start, + nframes_t length, std::string name, + layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true); + static boost::shared_ptr create (boost::shared_ptr, nframes_t start, nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true); + static boost::shared_ptr 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 create (Session&, XMLNode&, bool); + static boost::shared_ptr 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 + +#include +#include + +namespace ARDOUR { + +class ResampledImportableSource : public ImportableSource +{ + public: + ResampledImportableSource (boost::shared_ptr, 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 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 + +namespace ARDOUR { + +class Reverse : public Filter { + public: + Reverse (ARDOUR::Session&); + ~Reverse (); + + int run (boost::shared_ptr); +}; + +} /* 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 +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +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 > 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 void foreach_processor (T *obj, void (T::*func)(boost::shared_ptr)) { + Glib::RWLock::ReaderLock lm (_processor_lock); + for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { + (obj->*func) (*i); + } + } + + boost::shared_ptr 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 (); + } 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, ProcessorStreams* err = 0); + int add_processors (const ProcessorList&, ProcessorStreams* err = 0); + int remove_processor (boost::shared_ptr, 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 solo_changed; + sigc::signal solo_safe_changed; + sigc::signal comment_changed; + sigc::signal mute_changed; + sigc::signal pre_fader_changed; + sigc::signal post_fader_changed; + sigc::signal control_outs_changed; + sigc::signal main_outs_changed; + sigc::signal processors_changed; + sigc::signal record_enable_changed; + sigc::signal edit_group_changed; + sigc::signal mix_group_changed; + sigc::signal meter_change; + sigc::signal signal_latency_changed; + sigc::signal initial_delay_changed; + + /* gui's call this for their own purposes. */ + + sigc::signal 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 SelectedChanged; + + int set_control_outs (const vector& ports); + IO* control_outs() { return _control_outs; } + + bool feeds (boost::shared_ptr); + set > 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 solo_control() { + return _solo_control; + } + + boost::shared_ptr 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 RemoteControlIDChanged; + + void sync_order_keys (); + static sigc::signal 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 _solo_control; + boost::shared_ptr _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 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 processor; + ChanCount in; + ChanCount out; + + ProcessorCount (boost::shared_ptr ins) : processor(ins) {} + }; + + int32_t apply_some_plugin_counts (std::list& iclist); + bool check_some_plugin_counts (std::list& 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 +#include +#include +#include +#include +#include +#include + +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::iterator i = routes.begin(); i != routes.end(); i++) { + ((*i)->*func)(src); + } + } + + template void apply (void (Route::*func)(T, void *), T val, void *src) { + for (list::iterator i = routes.begin(); i != routes.end(); i++) { + ((*i)->*func)(val, src); + } + } + + template void foreach_route (T *obj, void (T::*func)(Route&)) { + for (list::iterator i = routes.begin(); i != routes.end(); i++) { + (obj->*func)(**i); + } + } + + /* to use these, #include */ + + template 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& at_set); + + void clear () { + routes.clear (); + changed(); + } + + const list& route_list() { return routes; } + + sigc::signal changed; + sigc::signal FlagsChanged; + + XMLNode& get_state (void); + + int set_state (const XMLNode&); + + private: + Session& _session; + list 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 +#include + +namespace ARDOUR { + +template void +RouteGroup::apply (void (Track::*func)(T, void *), T val, void *src) +{ + for (list::iterator i = routes.begin(); i != routes.end(); i++) { + Track *at; + if ((at = dynamic_cast(*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 + +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 +#include + + +#include +#include +#include +#include +#include + +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 +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include + +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,bool> RouteBooleanState; + typedef vector GlobalRouteBooleanState; + typedef std::pair,MeterPoint> RouteMeterState; + typedef vector 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; + + list audio_range; + list 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 DirtyChanged; + + const SessionDirectory& session_directory () const { return *(_session_dir.get()); } + + static sigc::signal AutoBindingOn; + static sigc::signal AutoBindingOff; + + static sigc::signal 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); + boost::shared_ptr diskstream_by_id (const PBD::ID& id); + boost::shared_ptr 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 > DiskstreamList; + typedef std::list > RouteList; + + boost::shared_ptr 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, boost::shared_ptr b); + }; + + template void foreach_route (T *obj, void (T::*func)(Route&)); + template void foreach_route (T *obj, void (T::*func)(boost::shared_ptr)); + template void foreach_route (T *obj, void (T::*func)(Route&, A), A arg); + + boost::shared_ptr route_by_name (string); + boost::shared_ptr route_by_id (PBD::ID); + boost::shared_ptr 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 > RegionHiddenChange; + + /* Emitted when all i/o connections are complete */ + + sigc::signal IOConnectionsComplete; + + /* Record status signals */ + + sigc::signal RecordStateChanged; + + /* Transport mechanism signals */ + + sigc::signal TransportStateChange; /* generic */ + sigc::signal PositionChanged; /* sent after any non-sequential motion */ + sigc::signal DurationChanged; + sigc::signal Xrun; + sigc::signal TransportLooped; + + sigc::signal 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(post_transport_work&PostTransportLocate); } + bool transport_locked () const; + + int wipe (); + //int wipe_diskstream (AudioDiskstream *); + + int remove_region_from_region_list (boost::shared_ptr); + + 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 auto_loop_location_changed; + sigc::signal auto_punch_location_changed; + sigc::signal 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 StateSaved; + sigc::signal StateReady; + + vector* possible_states() const; + static vector* 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 edit_group_added; + sigc::signal mix_group_added; + sigc::signal edit_group_removed; + sigc::signal mix_group_removed; + + void foreach_edit_group (sigc::slot sl) { + for (list::iterator i = edit_groups.begin(); i != edit_groups.end(); i++) { + sl (*i); + } + } + + void foreach_mix_group (sigc::slot sl) { + for (list::iterator i = mix_groups.begin(); i != mix_groups.end(); i++) { + sl (*i); + } + } + + /* fundamental operations. duh. */ + + std::list > 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 > new_midi_track (TrackMode mode = Normal, uint32_t how_many = 1); + //boost::shared_ptr new_midi_route (uint32_t how_many = 1); + + void remove_route (boost::shared_ptr); + void resort_routes (); + void resort_routes_using (boost::shared_ptr); + + 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 StartTimeChanged; + static sigc::signal EndTimeChanged; + static sigc::signal 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 >&); + + sigc::signal > RegionAdded; + sigc::signal >& > RegionsAdded; + sigc::signal > 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 find_whole_file_parent (boost::shared_ptr); + + void find_equivalent_playlist_regions (boost::shared_ptr, std::vector >& result); + + boost::shared_ptr XMLRegionFactory (const XMLNode&, bool full); + boost::shared_ptr XMLAudioRegionFactory (const XMLNode&, bool full); + boost::shared_ptr XMLMidiRegionFactory (const XMLNode&, bool full); + + template void foreach_region (T *obj, void (T::*func)(boost::shared_ptr)); + + /* source management */ + + struct import_status : public InterThreadInfo { + string doing_what; + + /* control info */ + SrcQuality quality; + volatile bool freeze; + std::vector 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); + void remove_source (boost::weak_ptr); + + struct cleanup_report { + vector paths; + int64_t space; + }; + + int cleanup_sources (cleanup_report&); + int cleanup_trash_sources (cleanup_report&); + + int destroy_region (boost::shared_ptr); + int destroy_regions (std::list >); + + 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 > AskAboutPlaylistDeletion; + + /* handlers should return 0 for "ignore the rate mismatch" + and !0 for "do not use this session" + */ + + static sigc::signal AskAboutSampleRateMismatch; + + /* handlers should return !0 for use pending state, 0 for + ignore it. + */ + + static sigc::signal AskAboutPendingState; + + boost::shared_ptr create_audio_source_for_session (ARDOUR::AudioDiskstream&, uint32_t which_channel, bool destructive); + + boost::shared_ptr create_midi_source_for_session (ARDOUR::MidiDiskstream&); + + boost::shared_ptr source_by_id (const PBD::ID&); + boost::shared_ptr source_by_path_and_channel (const Glib::ustring&, uint16_t); + + /* playlist management */ + + boost::shared_ptr playlist_by_name (string name); + void add_playlist (boost::shared_ptr); + sigc::signal > PlaylistAdded; + sigc::signal > PlaylistRemoved; + + uint32_t n_playlists() const; + + template void foreach_playlist (T *obj, void (T::*func)(boost::shared_ptr)); + void get_playlists (std::vector >&); + + /* named selections */ + + NamedSelection* named_selection_by_name (string name); + void add_named_selection (NamedSelection *); + void remove_named_selection (NamedSelection *); + + template void foreach_named_selection (T& obj, void (T::*func)(NamedSelection&)); + sigc::signal NamedSelectionAdded; + sigc::signal 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 the_auditioner() { return auditioner; } + void audition_playlist (); + void audition_region (boost::shared_ptr); + void cancel_audition (); + bool is_auditioning () const; + + sigc::signal AuditionActive; + + /* flattening stuff */ + + int write_one_audio_track (AudioTrack&, nframes_t start, nframes_t cnt, bool overwrite, + vector >&, 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 SoloActive; + sigc::signal SoloChanged; + + void record_disenable_all (); + void record_enable_all (); + + /* control/master out */ + + boost::shared_ptr control_out() const { return _control_out; } + boost::shared_ptr 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 add_bundle (boost::shared_ptr); + void remove_bundle (boost::shared_ptr); + boost::shared_ptr bundle_by_name (string) const; + + sigc::signal > BundleAdded; + sigc::signal > 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 MTC_PortChanged; + sigc::signal MMC_PortChanged; + sigc::signal 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 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 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 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&); + void set_music_range (list&); + + 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 SendFeedback; + + /* Controllables */ + + boost::shared_ptr controllable_by_id (const PBD::ID&); + + void add_controllable (boost::shared_ptr); + 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 _session_dir; + + RingBuffer 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 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 MidiTimeoutCallback; + typedef list 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(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 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 edit_groups; + list mix_groups; + + /* disk-streams */ + + SerializedRCUManager diskstreams; + + uint32_t audio_dstream_buffer_size; + uint32_t midi_dstream_buffer_size; + int load_diskstreams (const XMLNode&); + + /* routes stuff */ + + SerializedRCUManager routes; + + void add_routes (RouteList&, bool save); + uint32_t destructive_index; + + int load_routes (const XMLNode&); + boost::shared_ptr 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); + 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 > RegionList; + RegionList regions; + + void add_region (boost::shared_ptr); + void region_changed (Change, boost::weak_ptr); + void remove_region (boost::weak_ptr); + + int load_regions (const XMLNode& node); + + /* SOURCES */ + + mutable Glib::Mutex source_lock; + typedef std::map > SourceMap; + + SourceMap sources; + + public: + SourceMap get_sources() { return sources; } + + private: + + + int load_sources (const XMLNode& node); + XMLNode& get_sources_as_xml (); + + boost::shared_ptr XMLSourceFactory (const XMLNode&); + + /* PLAYLISTS */ + + mutable Glib::Mutex playlist_lock; + typedef set > PlaylistList; + PlaylistList playlists; + PlaylistList unused_playlists; + + int load_playlists (const XMLNode&); + int load_unused_playlists (const XMLNode&); + void remove_playlist (boost::weak_ptr); + void track_playlist (bool, boost::weak_ptr); + + boost::shared_ptr playlist_factory (string name); + boost::shared_ptr XMLPlaylistFactory (const XMLNode&); + + void playlist_length_changed (); + void diskstream_playlist_changed (boost::shared_ptr); + + /* NAMED SELECTIONS */ + + mutable Glib::Mutex named_selection_lock; + typedef set 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 curves; + std::map automation_lists; + + /* DEFAULT FADE CURVES */ + + float default_fade_steepness; + float default_fade_msecs; + + /* AUDITIONING */ + + boost::shared_ptr auditioner; + void set_audition (boost::shared_ptr); + void non_realtime_set_audition (); + boost::shared_ptr pending_audition_region; + + /* EXPORT */ + + /* FLATTEN */ + + int flatten_one_track (AudioTrack&, nframes_t start, nframes_t cnt); + + /* INSERT AND SEND MANAGEMENT */ + + list _port_inserts; + list _plugin_inserts; + list _sends; + boost::dynamic_bitset send_bitset; + boost::dynamic_bitset 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 session_dirs; + vector::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 > 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 Clicks; + + Clicks clicks; + bool _clicking; + boost::shared_ptr _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 master_outs; + + /* range playback */ + + list 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 _master_out; + boost::shared_ptr _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& result); + int find_all_sources_across_snapshots (std::set& result, bool exclude_this_snapshot); + + LayerModel layer_model; + CrossfadeModel xfade_model; + + typedef std::set > 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 +#include + +#include + +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 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 +#include + +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 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 +#include + +namespace ARDOUR { + +template void +Session::foreach_playlist (T *obj, void (T::*func)(boost::shared_ptr)) +{ + 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 +#include + +namespace ARDOUR { + +template void Session::foreach_region (T *obj, void (T::*func)(boost::shared_ptr)) +{ + 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 + +#include + +#include +#include + +namespace ARDOUR { + +template void +Session::foreach_route (T *obj, void (T::*func)(Route&)) +{ + boost::shared_ptr 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 void +Session::foreach_route (T *obj, void (T::*func)(boost::shared_ptr)) +{ + boost::shared_ptr 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 void +Session::foreach_route (T *obj, void (T::*func)(Route&, A), A arg1) +{ + boost::shared_ptr 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 +#include + +namespace ARDOUR { + +template 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 +#include + +#include + +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& 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 get_file_names_no_extension (const vector & 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 + +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 +#include + +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 + +#include + +#include +#include +#include +#include + +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 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 +#include +#include +#include + +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 +#include + +#include + +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 + +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 +#include + +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 +#include +#include +#include +#include + +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 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 + +#include + +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 +#include + +#include + +#include + +#include +#include +#include +#include + +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); + void remove_playlist (boost::weak_ptr); + + uint32_t used() const; + + static sigc::signal SourceCreated; + sigc::signal > 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 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, 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 +#include +#include +#include + +#include +#include + +class XMLNode; + +namespace ARDOUR { + +class Session; + +class SourceFactory { + public: + static void init (); + + static sigc::signal > SourceCreated; + + static boost::shared_ptr create (Session&, const XMLNode& node, bool async = false); + static boost::shared_ptr createSilent (Session&, const XMLNode& node, nframes_t nframes, float sample_rate); + + static boost::shared_ptr createReadable (DataType type, Session&, std::string path, int chn, AudioFileSource::Flag flags, + bool announce = true, bool async = false); + static boost::shared_ptr 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 > files_with_peaks; + + static int setup_peakfile (boost::shared_ptr, 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 + +#ifdef USE_RUBBERBAND + +#include + +namespace ARDOUR { + +class Stretch : public RBEffect { + public: + Stretch (ARDOUR::Session&, TimeFXRequest&); + ~Stretch() {} +}; + +} /* namespace */ + +#else + +#include + +namespace ARDOUR { + +class Stretch : public Filter { + public: + Stretch (ARDOUR::Session&, TimeFXRequest&); + ~Stretch (); + + int run (boost::shared_ptr); + + 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 + +#include + +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 + +#include + +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 +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include + +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 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 BBTPointList; + + template 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 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 +#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 + +#include + +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 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() 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 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 DiskstreamChanged; + sigc::signal FreezeChange; + + protected: + Track (Session& sess, const XMLNode& node, DataType default_type = DataType::AUDIO); + + virtual XMLNode& state (bool full) = 0; + + boost::shared_ptr _diskstream; + MeterPoint _saved_meter_point; + TrackMode _mode; + + //private: (FIXME) + struct FreezeRecordProcessorInfo { + FreezeRecordProcessorInfo(XMLNode& st, boost::shared_ptr proc) + : state (st), processor (proc) {} + + XMLNode state; + boost::shared_ptr processor; + PBD::ID id; + UndoAction memento; + }; + + struct FreezeRecord { + FreezeRecord() + : have_mementos(false) + {} + + ~FreezeRecord(); + + boost::shared_ptr playlist; + vector 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 _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 + +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; C++ requires explicit requesting of these */ +#endif + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#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 > 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 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 +#include +#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 ConfigurationWillChange; + /// The number of channels has changed + sigc::signal ConfigurationHasChanged; + /// The port set associated with one of our channels is about to change + /// Parameter is the channel number + sigc::signal PortsWillChange; + /// The port set associated with one of our channels has changed + /// Parameter is the channel number + sigc::signal PortsHaveChanged; + + private: + + int set_state (const XMLNode &); + + /// mutex for _ports; + /// XXX: is this necessary? + mutable Glib::Mutex _ports_mutex; + std::vector _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 +#include +#include + +#if defined(HAVE_COREAUDIO) || defined(HAVE_AUDIOUNITS) +#include +#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 +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +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 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 VSTPluginInfoPtr; + +} // namespace ARDOUR + +#endif /* __ardour_vst_plugin_h__ */ -- cgit v1.2.3