diff options
Diffstat (limited to 'libs/ardour')
291 files changed, 0 insertions, 96490 deletions
diff --git a/libs/ardour/.cvsignore b/libs/ardour/.cvsignore deleted file mode 100644 index 15d7926473..0000000000 --- a/libs/ardour/.cvsignore +++ /dev/null @@ -1,8 +0,0 @@ -libardour.la -libardour.pc -version.cc -*.lo -*.os -*.mo -*.pot -*.dylib diff --git a/libs/ardour/ChangeLog b/libs/ardour/ChangeLog deleted file mode 100644 index a0d3b193b6..0000000000 --- a/libs/ardour/ChangeLog +++ /dev/null @@ -1,118 +0,0 @@ -2002-11-24 gettextize <bug-gnu-gettext@gnu.org> - - * configure.ac (AC_OUTPUT): Add intl/Makefile, - -2002-11-24 gettextize <bug-gnu-gettext@gnu.org> - - * Makefile.am (ACLOCAL_AMFLAGS): New variable. - -2001-10-26 Paul Davis <pbd> - - * playlist.cc (recover_backup): restored the backup recovery code - for playlists. - - * diskstream.cc (do_refill): added state_lock to diskstream, just - to be safe. - - * session.cc (butler_thread_work): changed Session ISA thread to - HASA thread. - -2001-10-23 Paul Davis <pbd> - - merged in marcus' patch for edit/mix group save/restore, and - rationalized both it and the existing code for Route::set_state() - -2001-10-20 Paul Davis <pbd> - - * session.cc (get_state): in get_state, use the public order for routes. - -2001-10-18 Paul Davis <pbd> - - * playlist.cc (read): stop a muted region from causing a playlist - read error. - -2001-10-17 Paul Davis <pbd> - - * region.cc (read_at): remove staccato noise caused by not - shifting target buffer when !opaque. - -2001-10-15 Paul Davis <pbd> - - * region.cc (set_fade_out_active): made region fade in/out optional. - - * configure.in: patches from Ben related to libxml++ - -2001-10-12 Paul Davis <pbd> - - * session.cc (XMLRegionFactory): move most XML-based Region - constructor into region. - - -2001-10-10 Paul Davis <pbd> - - * session.cc (load_sources): add whole-file regions when loading - sources. - -2001-10-09 Paul Davis <pbd> - - * ardour/session.h: fix an ugly bug with a non-reference return type. - -2001-10-04 Paul Davis <pbd> - - * playlist.cc (split_region): ensure that left region after split - is in the right place. - - * auditioner.cc (play_audition): stop existing audition before - starting a new one. - -2001-10-03 Paul Davis <pbd> - - * session.cc (process): stop regular process() call from operating - on hidden diskstreams and routes. the butler thread still works on - all diskstreams, every time, which might be a mistake. - -2001-10-02 Paul Davis <pbd> - - * session.cc (set_auto_play_range): added provisional support - for play ranges using session events. added code to use - auditioner. - - * auditioner.cc: new file/object to support auditioning. - - * route.cc: remove seek() function (didn't exist). - - * session.cc (process): use list<DiskStream *> instead of GList - for diskstreams. add auditioner object. - -2001-09-30 Paul Davis <pbd> - - * playlist.cc (split_region): fix problem with region splitting - not defining two *smaller* regions of the original. - - * region.cc (set_position): remove RegionTemplate object. - - * playlist.cc (struct RegionSorter ): fix sorting to use position, - not start - whatever was i thinking ? - -2001-09-28 Paul Davis <pbd> - - * source.cc: emit source creation signal. - - * session.cc (first_stage_init): catch all source creation events. - - * sndfilesource.cc (init): fix up an off-by-one substr-length - error when creating a sndfilesource. - -2001-09-27 Paul Davis <pbd> - - * route.cc (operator): correct loop increment bug that caused a - hang when an Insert is added to a Route as a Redirect. - -2001-09-25 Paul Davis <pbd> - - * session.cc: make new file sources be partially named for their - initial host diskstream. - - peak file construction now carried out en-masse at the - end of capture run. - diff --git a/libs/ardour/SConscript b/libs/ardour/SConscript deleted file mode 100644 index b50aecbcb3..0000000000 --- a/libs/ardour/SConscript +++ /dev/null @@ -1,395 +0,0 @@ -# -*- python -*- - -import os -import os.path -import glob - -Import('env final_prefix install_prefix final_config_prefix libraries i18n') - -ardour = env.Copy() - -# -# this defines the version number of libardour -# - -domain = 'libardour3' - -ardour.Append(DOMAIN = domain, MAJOR = 2, MINOR = 0, MICRO = 0) -ardour.Append(CXXFLAGS = "-DPACKAGE=\\\"" + domain + "\\\"") -ardour.Append(CXXFLAGS=["-DLIBSIGC_DISABLE_DEPRECATED", "-DGLIBMM_EXCEPTIONS_ENABLED"]) -ardour.Append(PACKAGE = domain) -ardour.Append(POTFILE = domain + '.pot') - -if ardour['IS_OSX']: - ardour.Append (LINKFLAGS="-Xlinker -headerpad -Xlinker 2048") - -# -# explicitly reference the control protocol LGPL library for includes -# - -ardour.Append(CPPPATH = '#libs/surfaces/control_protocol') - -ardour_files=Split(""" -amp.cc -analyser.cc -audioanalyser.cc -audio_buffer.cc -audio_diskstream.cc -audioengine.cc -audiofilesource.cc -audio_library.cc -audio_playlist.cc -audio_port.cc -audioregion.cc -audiosource.cc -audio_track.cc -auditioner.cc -auto_bundle.cc -automatable.cc -automation.cc -automation_control.cc -automation_event.cc -base_audio_port.cc -base_midi_port.cc -buffer.cc -buffer_set.cc -chan_count.cc -configuration.cc -control_protocol_manager.cc -control_protocol_search_path.cc -crossfade.cc -curve.cc -cycle_timer.cc -default_click.cc -directory_names.cc -diskstream.cc -enums.cc -filename_extensions.cc -filesystem_paths.cc -filter.cc -find_session.cc -gain.cc -gdither.cc -globals.cc -import.cc -io.cc -io_processor.cc -jack_audio_port.cc -jack_midi_port.cc -jack_port.cc -jack_slave.cc -ladspa_plugin.cc -location.cc -meter.cc -midi_buffer.cc -midi_diskstream.cc -midi_model.cc -midi_playlist.cc -midi_port.cc -midi_region.cc -midi_source.cc -midi_stretch.cc -midi_track.cc -mix.cc -mtc_slave.cc -named_selection.cc -note.cc -panner.cc -parameter.cc -pcm_utils.cc -playlist.cc -playlist_factory.cc -plugin.cc -plugin_insert.cc -plugin_manager.cc -port.cc -port_insert.cc -port_set.cc -processor.cc -quantize.cc -recent_sessions.cc -region.cc -region_factory.cc -resampled_source.cc -reverse.cc -route.cc -route_group.cc -send.cc -session_butler.cc -session.cc -session_click.cc -session_command.cc -session_directory.cc -session_events.cc -session_export.cc -session_midi.cc -session_process.cc -session_state.cc -session_state_utils.cc -session_time.cc -session_transport.cc -session_utils.cc -silentfilesource.cc -smf_reader.cc -smf_source.cc -sndfile_helpers.cc -sndfilesource.cc -sndfileimportable.cc -source.cc -source_factory.cc -tape_file_matcher.cc -template_utils.cc -tempo.cc -track.cc -transient_detector.cc -user_bundle.cc -utils.cc -version.cc -""") - -arch_specific_objects = [ ] - -osc_files = [ 'osc.cc' ] -vst_files = [ 'vst_plugin.cc', 'session_vst.cc' ] -lv2_files = [ 'lv2_plugin.cc' ] -audiounit_files = [ 'audio_unit.cc' ] -coreaudio_files = [ 'coreaudiosource.cc', 'caimportable.cc' ] -extra_sources = [ ] -timefx_sources = [ ] - -if ardour['VST']: - extra_sources += vst_files - ardour.Append(CCFLAGS="-DVST_SUPPORT", CPPPATH="#libs/fst") - -if ardour['LV2']: - extra_sources += lv2_files - ardour.Append(CCFLAGS="-DHAVE_SLV2") - -if ardour['LIBLO']: - extra_sources += osc_files - -ardour.Append(CCFLAGS="-D_REENTRANT -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE") -ardour.Append(CXXFLAGS="-DDATA_DIR=\\\"" + os.path.join (final_prefix, 'share') + "\\\"") -ardour.Append(CXXFLAGS="-DMODULE_DIR=\\\"" + os.path.join (final_prefix, env['LIBDIR']) + "\\\"") -ardour.Append(CXXFLAGS="-DVAMP_DIR=\\\"" + os.path.join (final_prefix, env['LIBDIR'], 'ardour3', 'vamp') + "\\\"") -ardour.Append(CXXFLAGS="-DCONFIG_DIR=\\\"" + final_config_prefix + "\\\"") -ardour.Append(CXXFLAGS="-DLOCALEDIR=\\\"" + os.path.join (final_prefix, 'share', 'locale') + "\\\"") - -ardour.Merge ([ libraries['jack'] ]) - -# -# See if JACK supports jack_client_open() -# - -jack_test_source_file = """ -#include <jack/jack.h> -int main(int argc, char **argv) -{ - jack_client_open ("foo", 0, 0); - return 0; -} -""" -def CheckJackClientOpen(context): - context.Message('Checking for jack_client_open()...') - result = context.TryLink(jack_test_source_file, '.c') - context.Result(result) - return result - -# -# See if JACK supports jack_recompute_total_latencies() -# - -jack_test_source_file = """ -#include <jack/jack.h> -int main(int argc, char **argv) -{ - jack_recompute_total_latencies ((jack_client_t*) 0); - return 0; -} -""" -def CheckJackRecomputeLatencies(context): - context.Message('Checking for jack_recompute_total_latencies()...') - result = context.TryLink(jack_test_source_file, '.c') - context.Result(result) - return result - -jack_video_frame_offset_test = """ -#include <jack/transport.h> -int main(int argc, char** argv) -{ - jack_position_t pos; - - pos.valid & JackVideoFrameOffset; - return 0; -} -""" -def CheckJackVideoFrameOffset(context): - context.Message('Checking for JackVideoFrameOffset in jack_position_bits_t enum...') - result = context.TryLink(jack_video_frame_offset_test, '.c') - context.Result(result) - return result - - -# -# See if JACK supports jack_recompute_total_latency() (single port version) -# - -jack_port_latency_test = """ -#include <jack/jack.h> -int main(int argc, char **argv) -{ - jack_recompute_total_latency ((jack_client_t*) 0, (jack_port_t*) 0); - return 0; -} -""" -def CheckJackRecomputeLatency(context): - context.Message('Checking for jack_recompute_total_latency()...') - result = context.TryLink(jack_port_latency_test, '.c') - context.Result(result) - return result - -conf = Configure(ardour, custom_tests = { - 'CheckJackClientOpen' : CheckJackClientOpen, - 'CheckJackRecomputeLatencies' : CheckJackRecomputeLatencies, - 'CheckJackRecomputeLatency' : CheckJackRecomputeLatency, - 'CheckJackVideoFrameOffset' : CheckJackVideoFrameOffset -}) - -if conf.CheckJackClientOpen(): - ardour.Append(CXXFLAGS="-DHAVE_JACK_CLIENT_OPEN") - -if conf.CheckJackRecomputeLatencies(): - ardour.Append(CXXFLAGS="-DHAVE_JACK_RECOMPUTE_LATENCIES") - -if conf.CheckJackRecomputeLatency(): - ardour.Append(CXXFLAGS="-DHAVE_JACK_RECOMPUTE_LATENCY") - -if conf.CheckJackVideoFrameOffset(): - ardour.Append(CXXFLAGS="-DHAVE_JACK_VIDEO_SUPPORT") - -# -# Optional header files -# - -if conf.CheckCHeader('wordexp.h'): - ardour.Append(CXXFLAGS="-DHAVE_WORDEXP") - -if conf.CheckCHeader('sys/vfs.h'): - ardour.Append(CXXFLAGS="-DHAVE_SYS_VFS_H") - -if conf.CheckCHeader('/System/Library/Frameworks/CoreMIDI.framework/Headers/CoreMIDI.h'): - ardour.Append(LINKFLAGS="-framework CoreMIDI") - -if conf.CheckCHeader('/System/Library/Frameworks/AudioToolbox.framework/Headers/ExtendedAudioFile.h'): - ardour.Append(LINKFLAGS="-framework AudioToolbox") - -if conf.CheckCHeader('/System/Library/Frameworks/CoreAudio.framework/Headers/CoreAudio.h'): - ardour.Append(CXXFLAGS="-DHAVE_WEAK_COREAUDIO") - -if conf.CheckCHeader('/System/Library/Frameworks/AudioUnit.framework/Headers/AudioUnit.h') and ardour['AUDIOUNITS']: - ardour.Append(CXXFLAGS="-DHAVE_AUDIOUNITS") - ardour.Append(LINKFLAGS="-framework AudioUnit") - extra_sources += audiounit_files - -if ardour['COREAUDIO']: - ardour.Append(CXXFLAGS="-DHAVE_COREAUDIO") - extra_sources += coreaudio_files - -if env['CONFIG_ARCH'] == 'apple': - # this next line avoids issues with circular dependencies between libardour and libardour_cp. - # it is based on the (entirely reasonable) assumption that a system with CoreAudio is OS X - # - ardour.Append(LINKFLAGS='-undefined suppress -flat_namespace') - -ardour = conf.Finish () - -ardour.Merge ([ - libraries['core'], - libraries['fftw3'], - libraries['fftw3f'], - libraries['glib2'], - libraries['glibmm2'], - libraries['lrdf'], - libraries['midi++2'], - libraries['pbd'], - libraries['raptor'], - libraries['samplerate'], - libraries['sigc2'], - libraries['sndfile-ardour'], - libraries['vamp'], - libraries['vamphost'], - libraries['xml'] - ]) - -if ardour['RUBBERBAND']: - ardour.Merge ([ libraries['rubberband']]) - timefx_sources += [ 'rb_effect.cc' ] -else: - ardour.Merge ([ libraries['soundtouch'] ]) - timefx_sources += [ 'st_stretch.cc', 'st_pitch.cc' ] - -if ardour['LV2']: - ardour.Merge ([ libraries['slv2'] ]) - -if ardour['LIBLO']: - ardour.Merge ([ libraries['lo'] ]) - -if ardour['COREAUDIO'] or ardour['AUDIOUNITS']: - ardour.Merge ([ libraries['appleutility'] ]) - -def SharedAsmObjectEmitter(target, source, env): - for tgt in target: - tgt.attributes.shared = 1 - return (target, source) - - -env['BUILDERS']['SharedAsmObject'] = Builder (action = '$CXX -c -fPIC $SOURCE -o $TARGET', - emitter = SharedAsmObjectEmitter, - suffix = '$SHOBJSUFFIX', - src_suffix = '.s', - single_source = 1) -# -# handle objects that should always be compiled with -msse in their own -# special environment, which is exactly like "ardour" but unconditionally -# includes -msse -# - - -always_sse_objects = [] -sse_env = ardour.Copy() -sse_env.Append (CXXFLAGS="-msse") - -if env['FPU_OPTIMIZATION']: - if env['DIST_TARGET'] == "i386": - arch_specific_objects = env.SharedAsmObject('sse_functions.os', 'sse_functions.s') - always_sse_objects += [ sse_env.SharedObject (source = 'sse_functions_xmm.cc') ] - if env['DIST_TARGET'] == "i686": - arch_specific_objects = env.SharedAsmObject('sse_functions.os', 'sse_functions.s') - always_sse_objects += [ sse_env.SharedObject (source = 'sse_functions_xmm.cc') ] - if env['DIST_TARGET'] == "x86_64": - arch_specific_objects = env.SharedAsmObject('sse_functions_64bit.os', 'sse_functions_64bit.s') - always_sse_objects += [ sse_env.SharedObject (source = 'sse_functions_xmm.cc') ] - -libardour = ardour.SharedLibrary('ardour', ardour_files + always_sse_objects + timefx_sources + extra_sources + arch_specific_objects) - -Default(libardour) - -if env['NLS']: - i18n (ardour, ardour_files + vst_files + coreaudio_files + timefx_sources + audiounit_files, env) - - -env.Alias('install', env.Install(os.path.join(install_prefix, env['LIBDIR'], 'ardour3'), libardour)) - -env.Alias('version', ardour.VersionBuild(['version.cc', 'ardour/version.h'], [])) - -env.Alias('tarball', env.Distribute (env['DISTTREE'], - [ 'SConscript', 'i18n.h', 'gettext.h' ] + - [ 'sse_functions_xmm.cc', 'sse_functions.s', 'sse_functions_64bit.s' ] + - [ 'rb_effect.cc', 'st_stretch.cc', 'st_pitch.cc' ] + - ardour_files + - osc_files + - vst_files + - coreaudio_files + - audiounit_files + - lv2_files + - glob.glob('po/*.po') + glob.glob('ardour/*.h'))) diff --git a/libs/ardour/amp.cc b/libs/ardour/amp.cc deleted file mode 100644 index a2ad70e8b1..0000000000 --- a/libs/ardour/amp.cc +++ /dev/null @@ -1,102 +0,0 @@ -/* - 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. -*/ - -#include <cstring> -#include <cmath> -#include <algorithm> -#include <ardour/amp.h> -#include <ardour/buffer_set.h> -#include <ardour/audio_buffer.h> - -namespace ARDOUR { - - -/** Apply a declicked gain to the audio buffers of @a bufs */ -void -Amp::run_in_place (BufferSet& bufs, nframes_t nframes, gain_t initial, gain_t target, bool invert_polarity) -{ - if (nframes == 0) - return; - - if (bufs.count().n_audio() == 0) - return; - - // assert(bufs.buffer_capacity(DataType::AUDIO) >= nframes); - - // if we don't need to declick, defer to apply_simple_gain - if (initial == target) { - if (target == 0.0) { - for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) { - memset (i->data(), 0, sizeof (Sample) * nframes); - } - } else if (target != 1.0) { - for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) { - apply_gain_to_buffer (i->data(), nframes, target); - } - } - return; - } - - const nframes_t declick = std::min ((nframes_t)128, nframes); - gain_t delta; - double fractional_shift = -1.0/declick; - double fractional_pos; - gain_t polscale = invert_polarity ? -1.0f : 1.0f; - - if (target < initial) { - /* fade out: remove more and more of delta from initial */ - delta = -(initial - target); - } else { - /* fade in: add more and more of delta from initial */ - delta = target - initial; - } - - for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) { - Sample* const buffer = i->data(); - - fractional_pos = 1.0; - - for (nframes_t nx = 0; nx < declick; ++nx) { - buffer[nx] *= polscale * (initial + (delta * (0.5 + 0.5 * cos (M_PI * fractional_pos)))); - fractional_pos += fractional_shift; - } - - /* now ensure the rest of the buffer has the target value applied, if necessary. */ - - if (declick != nframes) { - - if (invert_polarity) { - target = -target; - } - - if (target == 0.0) { - memset (&buffer[declick], 0, sizeof (Sample) * (nframes - declick)); - } else if (target != 1.0) { - apply_gain_to_buffer (&buffer[declick], nframes - declick, target); - } - } - } -} - -void -Amp::apply_simple_gain (BufferSet& bufs, nframes_t nframes, gain_t target) -{ -} - - -} // namespace ARDOUR diff --git a/libs/ardour/analyser.cc b/libs/ardour/analyser.cc deleted file mode 100644 index 2e14c74b86..0000000000 --- a/libs/ardour/analyser.cc +++ /dev/null @@ -1,119 +0,0 @@ -/* - 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. - -*/ - -#include <ardour/analyser.h> -#include <ardour/audiofilesource.h> -#include <ardour/transient_detector.h> - -#include <pbd/pthread_utils.h> -#include <pbd/convert.h> - -using namespace std; -using namespace sigc; -using namespace ARDOUR; -using namespace PBD; - -Analyser* Analyser::the_analyser = 0; -Glib::StaticMutex Analyser::analysis_queue_lock = GLIBMM_STATIC_MUTEX_INIT; -Glib::Cond* Analyser::SourcesToAnalyse = 0; -list<boost::weak_ptr<Source> > Analyser::analysis_queue; - -Analyser::Analyser () -{ - -} - -Analyser::~Analyser () -{ -} - -static void -analyser_work () -{ - Analyser::work (); -} - -void -Analyser::init () -{ - SourcesToAnalyse = new Glib::Cond(); - Glib::Thread::create (sigc::ptr_fun (analyser_work), false); -} - -void -Analyser::queue_source_for_analysis (boost::shared_ptr<Source> src, bool force) -{ - if (!src->can_be_analysed()) { - return; - } - - if (!force && src->has_been_analysed()) { - return; - } - - Glib::Mutex::Lock lm (analysis_queue_lock); - analysis_queue.push_back (boost::weak_ptr<Source>(src)); - SourcesToAnalyse->broadcast (); -} - -void -Analyser::work () -{ - PBD::ThreadCreated (pthread_self(), string ("analyser-") + to_string (pthread_self(), std::dec)); - - while (true) { - analysis_queue_lock.lock (); - - wait: - if (analysis_queue.empty()) { - SourcesToAnalyse->wait (analysis_queue_lock); - } - - if (analysis_queue.empty()) { - goto wait; - } - - boost::shared_ptr<Source> src (analysis_queue.front().lock()); - analysis_queue.pop_front(); - analysis_queue_lock.unlock (); - - boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (src); - - if (afs && afs->length()) { - analyse_audio_file_source (afs); - } - } -} - -void -Analyser::analyse_audio_file_source (boost::shared_ptr<AudioFileSource> src) -{ - AnalysisFeatureList results; - - TransientDetector td (src->sample_rate()); - - if (td.run (src->get_transients_path(), src.get(), 0, results) == 0) { - src->set_been_analysed (true); - } else { - src->set_been_analysed (false); - } - -} - - diff --git a/libs/ardour/ardour/.cvsignore b/libs/ardour/ardour/.cvsignore deleted file mode 100644 index 67020331ba..0000000000 --- a/libs/ardour/ardour/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -version.h diff --git a/libs/ardour/ardour/amp.h b/libs/ardour/ardour/amp.h deleted file mode 100644 index cdbcacbd91..0000000000 --- a/libs/ardour/ardour/amp.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - Copyright (C) 2006 Paul Davis - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the Free - Software Foundation; either version 2 of the License, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifndef __ardour_amp_h__ -#define __ardour_amp_h__ - -#include <ardour/types.h> - -namespace ARDOUR { - -class BufferSet; - - -/** Applies a declick operation to all audio inputs, passing the same number of - * audio outputs, and passing through any other types unchanged. - * - * FIXME: make this a Processor. - */ -class Amp { -public: - static void run_in_place (BufferSet& bufs, nframes_t nframes, gain_t initial, gain_t target, bool invert_polarity); - - static void apply_simple_gain(BufferSet& bufs, nframes_t nframes, gain_t target); -}; - - -} // namespace ARDOUR - -#endif // __ardour_amp_h__ diff --git a/libs/ardour/ardour/analyser.h b/libs/ardour/ardour/analyser.h deleted file mode 100644 index 8771cab6b0..0000000000 --- a/libs/ardour/ardour/analyser.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef __ardour_analyser_h__ -#define __ardour_analyser_h__ - -#include <glibmm/thread.h> -#include <boost/shared_ptr.hpp> - -namespace ARDOUR { - -class AudioFileSource; -class Source; -class TransientDetector; - -class Analyser { - - public: - Analyser(); - ~Analyser (); - - static void init (); - static void queue_source_for_analysis (boost::shared_ptr<Source>, bool force); - static void work (); - - private: - static Analyser* the_analyser; - static Glib::StaticMutex analysis_queue_lock; - static Glib::Cond* SourcesToAnalyse; - static std::list<boost::weak_ptr<Source> > analysis_queue; - - static void analyse_audio_file_source (boost::shared_ptr<AudioFileSource>); -}; - - -} - -#endif /* __ardour_analyser_h__ */ diff --git a/libs/ardour/ardour/ardour.h b/libs/ardour/ardour/ardour.h deleted file mode 100644 index 6f653f10bf..0000000000 --- a/libs/ardour/ardour/ardour.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - Copyright (C) 1999 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_ardour_h__ -#define __ardour_ardour_h__ - -#include <map> -#include <string> - -#include <limits.h> -#include <signal.h> - -#include <pbd/error.h> -#include <pbd/failed_constructor.h> - -#include <ardour/configuration.h> -#include <ardour/types.h> - -namespace MIDI { - class MachineControl; - class Port; -} - -namespace ARDOUR { - - class AudioEngine; - class OSC; - - extern OSC* osc; - - static const nframes_t max_frames = JACK_MAX_FRAMES; - extern sigc::signal<void,std::string> BootMessage; - - int init (bool with_vst, bool try_optimization); - int cleanup (); - - std::string get_ardour_revision (); - - void find_bindings_files (std::map<std::string,std::string>&); - - const layer_t max_layer = UCHAR_MAX; - - microseconds_t get_microseconds (); - - Change new_change (); - - extern Change StartChanged; - extern Change LengthChanged; - extern Change PositionChanged; - extern Change NameChanged; - extern Change BoundsChanged; - - struct LocaleGuard { - LocaleGuard (const char*); - ~LocaleGuard (); - const char* old; - }; - - static const double SHUTTLE_FRACT_SPEED1=0.48412291827; /* derived from A1,A2 */ - - void setup_fpu (); -} - -/* how do we make these be within the Ardour namespace? */ - -extern MIDI::Port* default_mmc_port; -extern MIDI::Port* default_mtc_port; -extern MIDI::Port* default_midi_port; - -#endif /* __ardour_ardour_h__ */ - diff --git a/libs/ardour/ardour/audio_buffer.h b/libs/ardour/ardour/audio_buffer.h deleted file mode 100644 index 71eaf60ade..0000000000 --- a/libs/ardour/ardour/audio_buffer.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - Copyright (C) 2006 Paul Davis - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the Free - Software Foundation; either version 2 of the License, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifndef __ardour_audio_buffer_h__ -#define __ardour_audio_buffer_h__ - -#include <cstring> -#include <ardour/buffer.h> - -namespace ARDOUR { - -class AudioBuffer : public Buffer -{ -public: - AudioBuffer(size_t capacity); - - ~AudioBuffer(); - - void silence(nframes_t len, nframes_t offset = 0) { - if (!_silent) { - assert(_capacity > 0); - assert(offset + len <= _capacity); - memset(_data + offset, 0, sizeof (Sample) * len); - if (offset == 0 && len == _capacity) { - _silent = true; - } - } - } - - /** Read @a len frames FROM THE START OF @a src into self at @a offset */ - void read_from(const Buffer& src, nframes_t len, nframes_t offset) { - assert(&src != this); - assert(_capacity > 0); - assert(src.type() == DataType::AUDIO); - assert(offset + len <= _capacity); - memcpy(_data + offset, ((AudioBuffer&)src).data(), sizeof(Sample) * len); - _silent = src.silent(); - } - - /** Accumulate (add)@a len frames FROM THE START OF @a src into self at @a offset */ - void accumulate_from(const AudioBuffer& src, nframes_t len, nframes_t offset) { - assert(_capacity > 0); - assert(offset + len <= _capacity); - - Sample* const dst_raw = _data + offset; - const Sample* const src_raw = src.data(); - - mix_buffers_no_gain(dst_raw, src_raw, len); - - _silent = (src.silent() && _silent); - } - - /** Accumulate (add) @a len frames FROM THE START OF @a src into self at @a offset - * scaling by @a gain_coeff */ - void accumulate_with_gain_from(const AudioBuffer& src, nframes_t len, nframes_t offset, gain_t gain_coeff) { - assert(_capacity > 0); - assert(offset + len <= _capacity); - - Sample* const dst_raw = _data + offset; - const Sample* const src_raw = src.data(); - - mix_buffers_with_gain (dst_raw, src_raw, len, gain_coeff); - - _silent = ( (src.silent() && _silent) || (_silent && gain_coeff == 0) ); - } - - void apply_gain(gain_t gain, nframes_t len, nframes_t offset=0) { - apply_gain_to_buffer (_data + offset, len, gain); - } - - /** Set the data contained by this buffer manually (for setting directly to jack buffer). - * - * Constructor MUST have been passed capacity=0 or this will die (to prevent mem leaks). - */ - void set_data (Sample* data, size_t size) { - assert(!_owns_data); // prevent leaks - _capacity = size; - _size = size; - _data = data; - _silent = false; - } - - /** Reallocate the buffer used internally to handle at least @nframes of data - * - * Constructor MUST have been passed capacity!=0 or this will die (to prevent mem leaks). - */ - void resize (size_t nframes); - - const Sample* data () const { return _data; } - Sample* data () { return _data; } - - const Sample* data(nframes_t nframes, nframes_t offset) const - { assert(offset + nframes <= _capacity); return _data + offset; } - - Sample* data (nframes_t nframes, nframes_t offset) - { assert(offset + nframes <= _capacity); return _data + offset; } - -private: - bool _owns_data; - Sample* _data; ///< Actual buffer contents -}; - - -} // namespace ARDOUR - -#endif // __ardour_audio_audio_buffer_h__ diff --git a/libs/ardour/ardour/audio_diskstream.h b/libs/ardour/ardour/audio_diskstream.h deleted file mode 100644 index aaf5461361..0000000000 --- a/libs/ardour/ardour/audio_diskstream.h +++ /dev/null @@ -1,277 +0,0 @@ -/* - Copyright (C) 2000-2006 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifndef __ardour_audio_diskstream_h__ -#define __ardour_audio_diskstream_h__ - -#include <sigc++/signal.h> - -#include <cmath> -#include <string> -#include <queue> -#include <map> -#include <vector> - -#include <time.h> - -#include <pbd/fastlog.h> -#include <pbd/ringbufferNPT.h> -#include <pbd/stateful.h> -#include <pbd/rcu.h> - -#include <ardour/ardour.h> -#include <ardour/configuration.h> -#include <ardour/session.h> -#include <ardour/route_group.h> -#include <ardour/route.h> -#include <ardour/port.h> -#include <ardour/utils.h> -#include <ardour/diskstream.h> -#include <ardour/audioplaylist.h> - -struct tm; - -namespace ARDOUR { - -class AudioEngine; -class Send; -class Session; -class AudioPlaylist; -class AudioFileSource; -class IO; - -class AudioDiskstream : public Diskstream -{ - public: - AudioDiskstream (Session &, const string& name, Diskstream::Flag f = Recordable); - AudioDiskstream (Session &, const XMLNode&); - ~AudioDiskstream(); - - float playback_buffer_load() const; - float capture_buffer_load() const; - - string input_source (uint32_t n=0) const { - boost::shared_ptr<ChannelList> c = channels.reader(); - if (n < c->size()) { - return (*c)[n]->source ? (*c)[n]->source->name() : ""; - } else { - return ""; - } - } - - Port *input_source_port (uint32_t n=0) const { - boost::shared_ptr<ChannelList> c = channels.reader(); - if (n < c->size()) return (*c)[n]->source; return 0; - } - - void set_record_enabled (bool yn); - int set_destructive (bool yn); - bool can_become_destructive (bool& requires_bounce) const; - - float peak_power(uint32_t n = 0) { - boost::shared_ptr<ChannelList> c = channels.reader(); - ChannelInfo* chaninfo = (*c)[n]; - float x = chaninfo->peak_power; - chaninfo->peak_power = 0.0f; - if (x > 0.0f) { - return 20.0f * fast_log10(x); - } else { - return minus_infinity(); - } - } - - boost::shared_ptr<AudioPlaylist> audio_playlist () { return boost::dynamic_pointer_cast<AudioPlaylist>(_playlist); } - - int use_playlist (boost::shared_ptr<Playlist>); - int use_new_playlist (); - int use_copy_playlist (); - - Sample *playback_buffer (uint32_t n = 0) { - boost::shared_ptr<ChannelList> c = channels.reader(); - if (n < c->size()) - return (*c)[n]->current_playback_buffer; - return 0; - } - - Sample *capture_buffer (uint32_t n = 0) { - boost::shared_ptr<ChannelList> c = channels.reader(); - if (n < c->size()) - return (*c)[n]->current_capture_buffer; - return 0; - } - - boost::shared_ptr<AudioFileSource> write_source (uint32_t n=0) { - boost::shared_ptr<ChannelList> c = channels.reader(); - if (n < c->size()) - return (*c)[n]->write_source; - return boost::shared_ptr<AudioFileSource>(); - } - - int add_channel (uint32_t how_many); - int remove_channel (uint32_t how_many); - - /* stateful */ - - XMLNode& get_state(void); - int set_state(const XMLNode& node); - - void monitor_input (bool); - - static void swap_by_ptr (Sample *first, Sample *last) { - while (first < last) { - Sample tmp = *first; - *first++ = *last; - *last-- = tmp; - } - } - - static void swap_by_ptr (Sample *first, Sample *last, nframes_t n) { - while (n--) { - Sample tmp = *first; - *first++ = *last; - *last-- = tmp; - } - } - - XMLNode* deprecated_io_node; - - protected: - friend class Session; - - /* the Session is the only point of access for these - because they require that the Session is "inactive" - while they are called. - */ - - void set_pending_overwrite(bool); - int overwrite_existing_buffers (); - void set_block_size (nframes_t); - int internal_playback_seek (nframes_t distance); - int can_internal_playback_seek (nframes_t distance); - int rename_write_sources (); - void reset_write_sources (bool, bool force = false); - void non_realtime_input_change (); - - protected: - friend class Auditioner; - int seek (nframes_t which_sample, bool complete_refill = false); - - protected: - friend class AudioTrack; - - int process (nframes_t transport_frame, nframes_t nframes, nframes_t offset, bool can_record, bool rec_monitors_input); - bool commit (nframes_t nframes); - - private: - - struct ChannelInfo { - - ChannelInfo (nframes_t buffer_size, nframes_t speed_buffer_size, nframes_t wrap_buffer_size); - ~ChannelInfo (); - - Sample *playback_wrap_buffer; - Sample *capture_wrap_buffer; - Sample *speed_buffer; - - float peak_power; - - boost::shared_ptr<AudioFileSource> fades_source; - boost::shared_ptr<AudioFileSource> write_source; - - /// the Port that our audio data comes from - Port *source; - Sample *current_capture_buffer; - Sample *current_playback_buffer; - - RingBufferNPT<Sample> *playback_buf; - RingBufferNPT<Sample> *capture_buf; - - Sample* scrub_buffer; - Sample* scrub_forward_buffer; - Sample* scrub_reverse_buffer; - - RingBufferNPT<Sample>::rw_vector playback_vector; - RingBufferNPT<Sample>::rw_vector capture_vector; - - RingBufferNPT<CaptureTransition> * capture_transition_buf; - // the following are used in the butler thread only - nframes_t curr_capture_cnt; - }; - - typedef std::vector<ChannelInfo*> ChannelList; - - /* The two central butler operations */ - int do_flush (Session::RunContext context, bool force = false); - int do_refill () { return _do_refill(_mixdown_buffer, _gain_buffer); } - - int do_refill_with_alloc (); - - int read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer, - nframes_t& start, nframes_t cnt, - ChannelInfo* channel_info, int channel, bool reversed); - - void finish_capture (bool rec_monitors_input, boost::shared_ptr<ChannelList>); - void transport_stopped (struct tm&, time_t, bool abort); - void transport_looped (nframes_t transport_frame); - - void init (Diskstream::Flag); - - void init_channel (ChannelInfo &chan); - void destroy_channel (ChannelInfo &chan); - - int use_new_write_source (uint32_t n=0); - - int find_and_use_playlist (const string&); - - void allocate_temporary_buffers (); - - int use_pending_capture_data (XMLNode& node); - - void get_input_sources (); - void check_record_status (nframes_t transport_frame, nframes_t nframes, bool can_record); - void set_align_style_from_io(); - void setup_destructive_playlist (); - void use_destructive_playlist (); - - void engage_record_enable (); - void disengage_record_enable (); - - // Working buffers for do_refill (butler thread) - static void allocate_working_buffers(); - static void free_working_buffers(); - - static size_t _working_buffers_size; - static Sample* _mixdown_buffer; - static gain_t* _gain_buffer; - - std::vector<boost::shared_ptr<AudioFileSource> > capturing_sources; - - SerializedRCUManager<ChannelList> channels; - - /* really */ - private: - int _do_refill (Sample *mixdown_buffer, float *gain_buffer); - - int add_channel_to (boost::shared_ptr<ChannelList>, uint32_t how_many); - int remove_channel_from (boost::shared_ptr<ChannelList>, uint32_t how_many); - -}; - -} // namespace ARDOUR - -#endif /* __ardour_audio_diskstream_h__ */ diff --git a/libs/ardour/ardour/audio_library.h b/libs/ardour/ardour/audio_library.h deleted file mode 100644 index 86b5fb3aa2..0000000000 --- a/libs/ardour/ardour/audio_library.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - Copyright (C) 2003-2006 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_audio_library_h__ -#define __ardour_audio_library_h__ - -#include <string> -#include <map> -#include <vector> - -using std::vector; -using std::string; -using std::map; - -namespace ARDOUR { - -class AudioLibrary -{ - public: - AudioLibrary (); - ~AudioLibrary (); - - void set_tags (string member, vector<string> tags); - vector<string> get_tags (string member); - - void search_members_and (vector<string>& results, const vector<string> tags); - - void save_changes(); - - private: - string src; -}; - -extern AudioLibrary* Library; - -} // ARDOUR namespace - -#endif // __ardour_audio_library_h__ diff --git a/libs/ardour/ardour/audio_port.h b/libs/ardour/ardour/audio_port.h deleted file mode 100644 index 874f842d83..0000000000 --- a/libs/ardour/ardour/audio_port.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - Copyright (C) 2002 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - $Id: port.h 712 2006-07-28 01:08:57Z drobilla $ -*/ - -#ifndef __ardour_audio_port_h__ -#define __ardour_audio_port_h__ - -#include <ardour/base_audio_port.h> - -namespace ARDOUR { - -class AudioPort : public BaseAudioPort, public PortFacade { - - public: - ~AudioPort(); - - void reset (); - - void cycle_start (nframes_t nframes, nframes_t offset); - void cycle_end (nframes_t nframes, nframes_t offset); - - protected: - friend class AudioEngine; - - AudioPort (const std::string&, Flags, bool external, nframes_t); -}; - -} // namespace ARDOUR - -#endif /* __ardour_audio_port_h__ */ diff --git a/libs/ardour/ardour/audio_track.h b/libs/ardour/ardour/audio_track.h deleted file mode 100644 index 3546545329..0000000000 --- a/libs/ardour/ardour/audio_track.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - Copyright (C) 2002-2006 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_audio_track_h__ -#define __ardour_audio_track_h__ - -#include <ardour/track.h> - -namespace ARDOUR { - -class Session; -class AudioDiskstream; -class AudioPlaylist; -class RouteGroup; - -class AudioTrack : public Track -{ - public: - AudioTrack (Session&, string name, Route::Flag f = Route::Flag (0), TrackMode m = Normal); - AudioTrack (Session&, const XMLNode&); - ~AudioTrack (); - - int set_mode (TrackMode m); - bool can_use_mode (TrackMode m, bool& bounce_required); - - int roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, - nframes_t offset, int declick, bool can_record, bool rec_monitors_input); - - int no_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, - nframes_t offset, bool state_changing, bool can_record, bool rec_monitors_input); - - int silent_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, - nframes_t offset, bool can_record, bool rec_monitors_input); - - boost::shared_ptr<AudioDiskstream> audio_diskstream() const; - - int use_diskstream (string name); - int use_diskstream (const PBD::ID& id); - - int export_stuff (BufferSet& bufs, nframes_t nframes, nframes_t end_frame); - - void freeze (InterThreadInfo&); - void unfreeze (); - - void bounce (InterThreadInfo&); - void bounce_range (nframes_t start, nframes_t end, InterThreadInfo&); - - int set_state(const XMLNode& node); - - protected: - XMLNode& state (bool full); - - int _set_state (const XMLNode&, bool call_base); - - private: - int set_diskstream (boost::shared_ptr<AudioDiskstream>, void *); - int deprecated_use_diskstream_connections (); - void set_state_part_two (); - void set_state_part_three (); -}; - -} // namespace ARDOUR - -#endif /* __ardour_audio_track_h__ */ diff --git a/libs/ardour/ardour/audio_unit.h b/libs/ardour/ardour/audio_unit.h deleted file mode 100644 index dc9a52d5d3..0000000000 --- a/libs/ardour/ardour/audio_unit.h +++ /dev/null @@ -1,172 +0,0 @@ -/* - Copyright (C) 2006 Paul Davis - Written by Taybin Rutkin - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_audio_unit_h__ -#define __ardour_audio_unit_h__ - -#include <stdint.h> -#include <boost/shared_ptr.hpp> - -#include <list> -#include <set> -#include <string> -#include <vector> - -#include <ardour/plugin.h> - -#include <AudioUnit/AudioUnit.h> -#include <appleutility/AUParamInfo.h> - -#include <boost/shared_ptr.hpp> - -class CAComponent; -class CAAudioUnit; -class CAComponentDescription; -struct AudioBufferList; - -namespace ARDOUR { - -class AudioEngine; -class Session; - -struct AUParameterDescriptor : public Plugin::ParameterDescriptor { - // additional fields to make operations more efficient - AudioUnitParameterID id; - AudioUnitScope scope; - AudioUnitElement element; - float default_value; - bool automatable; - AudioUnitParameterUnit unit; -}; - -class AUPlugin : public ARDOUR::Plugin -{ - public: - AUPlugin (AudioEngine& engine, Session& session, boost::shared_ptr<CAComponent> comp); - AUPlugin (const AUPlugin& other); - virtual ~AUPlugin (); - - std::string unique_id () const; - const char * label () const; - const char * name () const { return _info->name.c_str(); } - const char * maker () const { return _info->creator.c_str(); } - uint32_t parameter_count () const; - float default_value (uint32_t port); - nframes_t signal_latency () const; - void set_parameter (uint32_t which, float val); - float get_parameter (uint32_t which) const; - - int get_parameter_descriptor (uint32_t which, ParameterDescriptor&) const; - uint32_t nth_parameter (uint32_t which, bool& ok) const; - void activate (); - void deactivate (); - void set_block_size (nframes_t nframes); - - int connect_and_run (BufferSet& bufs, uint32_t& in, uint32_t& out, nframes_t nframes, nframes_t offset); - - std::set<uint32_t> automatable() const; - string describe_parameter (uint32_t); - string state_node_name () const { return "audiounit"; } - void print_parameter (uint32_t, char*, uint32_t len) const; - - bool parameter_is_audio (uint32_t) const; - bool parameter_is_control (uint32_t) const; - bool parameter_is_input (uint32_t) const; - bool parameter_is_output (uint32_t) const; - - XMLNode& get_state(); - int set_state(const XMLNode& node); - - bool save_preset (string name); - bool load_preset (const string preset_label); - std::vector<std::string> get_presets (); - - bool has_editor () const; - - bool fixed_io() const { return false; } - int32_t can_support_input_configuration (int32_t in); - int32_t compute_output_streams (int32_t nplugins); - uint32_t output_streams() const; - uint32_t input_streams() const; - - boost::shared_ptr<CAAudioUnit> get_au () { return unit; } - boost::shared_ptr<CAComponent> get_comp () const { return comp; } - - OSStatus render_callback(AudioUnitRenderActionFlags *ioActionFlags, - const AudioTimeStamp *inTimeStamp, - UInt32 inBusNumber, - UInt32 inNumberFrames, - AudioBufferList* ioData); - private: - boost::shared_ptr<CAComponent> comp; - boost::shared_ptr<CAAudioUnit> unit; - - AudioStreamBasicDescription streamFormat; - bool initialized; - int format_set; - AudioBufferList* buffers; - - UInt32 global_elements; - UInt32 output_elements; - UInt32 input_elements; - - int set_output_format (); - int set_input_format (); - int set_stream_format (int scope, uint32_t cnt); - int _set_block_size (nframes_t nframes); - void discover_parameters (); - - std::vector<std::pair<uint32_t, uint32_t> > parameter_map; - uint32_t current_maxbuf; - nframes_t current_offset; - nframes_t cb_offset; - vector<Sample*>* current_buffers; - nframes_t frames_processed; - - std::vector<AUParameterDescriptor> descriptors; - void init (); -}; - -typedef boost::shared_ptr<AUPlugin> AUPluginPtr; - -class AUPluginInfo : public PluginInfo { - public: - AUPluginInfo (boost::shared_ptr<CAComponentDescription>); - ~AUPluginInfo (); - - PluginPtr load (Session& session); - - static PluginInfoList discover (); - static void get_names (CAComponentDescription&, std::string& name, Glib::ustring& maker); - static std::string stringify_descriptor (const CAComponentDescription&); - - private: - boost::shared_ptr<CAComponentDescription> descriptor; - - static void discover_music (PluginInfoList&); - static void discover_fx (PluginInfoList&); - static void discover_by_description (PluginInfoList&, CAComponentDescription&); -}; - -typedef boost::shared_ptr<AUPluginInfo> AUPluginInfoPtr; - -} // namespace ARDOUR - -#endif // __ardour_audio_unit_h__ diff --git a/libs/ardour/ardour/audioanalyser.h b/libs/ardour/ardour/audioanalyser.h deleted file mode 100644 index 06b841990a..0000000000 --- a/libs/ardour/ardour/audioanalyser.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - Copyright (C) 2008 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_audioanalyser_h__ -#define __ardour_audioanalyser_h__ - -#include <vector> -#include <string> -#include <ostream> -#include <fstream> -#include <vamp-sdk/Plugin.h> -#include <ardour/audioregion.h> - -namespace ARDOUR { - -class Readable; -class Session; - -class AudioAnalyser { - - public: - typedef Vamp::Plugin AnalysisPlugin; - typedef std::string AnalysisPluginKey; - - AudioAnalyser (float sample_rate, AnalysisPluginKey key); - virtual ~AudioAnalyser(); - - /* analysis object should provide a run method - that accepts a path to write the results to (optionally empty) - a Readable* to read data from - and a reference to a type-specific container to return the - results. - */ - - void reset (); - - protected: - float sample_rate; - AnalysisPlugin* plugin; - AnalysisPluginKey plugin_key; - - nframes64_t bufsize; - nframes64_t stepsize; - - int initialize_plugin (AnalysisPluginKey name, float sample_rate); - int analyse (const std::string& path, Readable*, uint32_t channel); - - /* instances of an analysis object will have this method called - whenever there are results to process. if out is non-null, - the data should be written to the stream it points to. - */ - - virtual int use_features (Vamp::Plugin::FeatureSet&, std::ostream*) = 0; -}; - -} /* namespace */ - -#endif /* __ardour_audioanalyser_h__ */ diff --git a/libs/ardour/ardour/audioengine.h b/libs/ardour/ardour/audioengine.h deleted file mode 100644 index e1d5e50cc2..0000000000 --- a/libs/ardour/ardour/audioengine.h +++ /dev/null @@ -1,276 +0,0 @@ -/* - Copyright (C) 2002-2004 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_audioengine_h__ -#define __ardour_audioengine_h__ - -#include <list> -#include <set> -#include <cmath> -#include <exception> -#include <string> - -#include <sigc++/signal.h> - -#include <glibmm/thread.h> - -#include <pbd/rcu.h> - -#include <ardour/ardour.h> -#include <jack/jack.h> -#include <jack/transport.h> -#include <ardour/types.h> -#include <ardour/data_type.h> - -namespace ARDOUR { - -class Session; -class Port; -class InternalPort; - -class AudioEngine : public sigc::trackable -{ - public: - typedef std::set<Port*> Ports; - - AudioEngine (std::string client_name); - virtual ~AudioEngine (); - - jack_client_t* jack() const; - bool connected() const { return _jack != 0; } - - bool is_realtime () const; - - std::string client_name() const { return jack_client_name; } - - int reconnect_to_jack (); - int disconnect_from_jack(); - - bool will_reconnect_at_halt (); - void set_reconnect_at_halt (bool); - - int stop (bool forever = false); - int start (); - bool running() const { return _running; } - - Glib::Mutex& process_lock() { return _process_lock; } - - nframes_t frame_rate(); - nframes_t frames_per_cycle(); - - int usecs_per_cycle () const { return _usecs_per_cycle; } - - bool get_sync_offset (nframes_t& offset) const; - - nframes_t frames_since_cycle_start () { - if (!_running || !_jack) return 0; - return jack_frames_since_cycle_start (_jack); - } - nframes_t frame_time () { - if (!_running || !_jack) return 0; - return jack_frame_time (_jack); - } - - nframes_t transport_frame () const { - if (!_running || !_jack) return 0; - return jack_get_current_transport_frame (_jack); - } - - int request_buffer_size (nframes_t); - - nframes_t set_monitor_check_interval (nframes_t); - - float get_cpu_load() { - if (!_running || !_jack) return 0; - return jack_cpu_load (_jack); - } - - void set_session (Session *); - void remove_session (); - - class PortRegistrationFailure : public std::exception { - public: - PortRegistrationFailure (const char* why = "") { - reason = why; - } - virtual const char *what() const throw() { return reason; } - - private: - const char* reason; - }; - - class NoBackendAvailable : public std::exception { - public: - virtual const char *what() const throw() { return "could not connect to engine backend"; } - }; - - Port *register_input_port (DataType, const std::string& portname, bool publish); - Port *register_output_port (DataType, const std::string& portname, bool publish); - int unregister_port (Port &); - - int connect (const std::string& source, const std::string& destination); - int disconnect (const std::string& source, const std::string& destination); - int disconnect (Port &); - - const char ** get_ports (const std::string& port_name_pattern, const std::string& type_name_pattern, uint32_t flags); - - uint32_t n_physical_outputs () const; - uint32_t n_physical_inputs () const; - - bool can_request_hardware_monitoring (); - - void get_physical_outputs (std::vector<std::string>&); - void get_physical_inputs (std::vector<std::string>&); - - std::string get_nth_physical_output (DataType type, uint32_t n) { - return get_nth_physical (type, n, JackPortIsInput); - } - - std::string get_nth_physical_input (DataType type, uint32_t n) { - return get_nth_physical (type, n, JackPortIsOutput); - } - - nframes_t get_port_total_latency (const Port&); - void update_total_latencies (); - void update_total_latency (const Port&); - - /** Caller may not delete the object pointed to by the return value - */ - Port *get_port_by_name (const std::string& name, bool keep = true) const; - - enum TransportState { - TransportStopped = JackTransportStopped, - TransportRolling = JackTransportRolling, - TransportLooping = JackTransportLooping, - TransportStarting = JackTransportStarting - }; - - void transport_start (); - void transport_stop (); - void transport_locate (nframes_t); - TransportState transport_state (); - - int reset_timebase (); - - /* start/stop freewheeling */ - - int freewheel (bool onoff); - bool freewheeling() const { return _freewheeling; } - - /* this signal is sent for every process() cycle while freewheeling. - the regular process() call to session->process() is not made. - */ - - sigc::signal<int,nframes_t> Freewheel; - - sigc::signal<void> Xrun; - - /* this signal is if JACK notifies us of a graph order event */ - - sigc::signal<void> GraphReordered; - - /* this signal is emitted if the sample rate changes */ - - sigc::signal<void,nframes_t> SampleRateChanged; - - /* this signal is sent if JACK ever disconnects us */ - - sigc::signal<void> Halted; - - /* these two are emitted when the engine itself is - started and stopped - */ - - sigc::signal<void> Running; - sigc::signal<void> Stopped; - - std::string make_port_name_relative (std::string); - std::string make_port_name_non_relative (std::string); - - private: - ARDOUR::Session *session; - jack_client_t *_jack; - std::string jack_client_name; - mutable Glib::Mutex _process_lock; - Glib::Cond session_removed; - bool session_remove_pending; - bool _running; - bool _has_run; - nframes_t _buffer_size; - nframes_t _frame_rate; - /// number of frames between each check for changes in monitor input - nframes_t monitor_check_interval; - /// time of the last monitor check in frames - nframes_t last_monitor_check; - /// the number of frames processed since start() was called - nframes_t _processed_frames; - bool _freewheeling; - bool _freewheel_thread_registered; - sigc::slot<int,nframes_t> freewheel_action; - bool reconnect_on_halt; - int _usecs_per_cycle; - - SerializedRCUManager<Ports> ports; - - Port *register_port (DataType type, const std::string& portname, bool input, bool publish); - - int process_callback (nframes_t nframes); - void remove_all_ports (); - - Port* get_port (const std::string& short_name); - - typedef std::pair<std::string,std::string> PortConnection; - typedef std::list<PortConnection> PortConnections; - - PortConnections port_connections; - void remove_connections_for (Port&); - - std::string get_nth_physical (DataType type, uint32_t n, int flags); - - void port_registration_failure (const std::string& portname); - - static int _xrun_callback (void *arg); - static int _graph_order_callback (void *arg); - static int _process_callback (nframes_t nframes, void *arg); - static int _sample_rate_callback (nframes_t nframes, void *arg); - static int _bufsize_callback (nframes_t nframes, void *arg); - static void _jack_timebase_callback (jack_transport_state_t, nframes_t, jack_position_t*, int, void*); - static int _jack_sync_callback (jack_transport_state_t, jack_position_t*, void *arg); - static void _freewheel_callback (int , void *arg); - - void jack_timebase_callback (jack_transport_state_t, nframes_t, jack_position_t*, int); - int jack_sync_callback (jack_transport_state_t, jack_position_t*); - int jack_bufsize_callback (nframes_t); - int jack_sample_rate_callback (nframes_t); - - static void halted (void *); - - int connect_to_jack (std::string client_name); - - void meter_thread (); - void start_metering_thread (); - void stop_metering_thread (); - - Glib::Thread* m_meter_thread; - static gint m_meter_exit; -}; - -} // namespace ARDOUR - -#endif /* __ardour_audioengine_h__ */ diff --git a/libs/ardour/ardour/audiofilesource.h b/libs/ardour/ardour/audiofilesource.h deleted file mode 100644 index de388a06fc..0000000000 --- a/libs/ardour/ardour/audiofilesource.h +++ /dev/null @@ -1,183 +0,0 @@ -/* - Copyright (C) 2006 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_audiofilesource_h__ -#define __ardour_audiofilesource_h__ - -#include <exception> - -#include <time.h> - -#include <ardour/audiosource.h> - -namespace ARDOUR { - -class non_existent_source : public std::exception { - public: - virtual const char *what() const throw() { return "audio file does not exist"; } -}; - -struct SoundFileInfo { - float samplerate; - uint16_t channels; - int64_t length; - std::string format_name; - int64_t timecode; -}; - -class AudioFileSource : public AudioSource { - public: - enum Flag { - Writable = 0x1, - CanRename = 0x2, - Broadcast = 0x4, - Removable = 0x8, - RemovableIfEmpty = 0x10, - RemoveAtDestroy = 0x20, - NoPeakFile = 0x40, - Destructive = 0x80 - }; - - virtual ~AudioFileSource (); - - bool set_name (const std::string& newname) { return (set_source_name(newname, destructive()) == 0); } - int set_source_name (Glib::ustring newname, bool destructive); - - Glib::ustring path() const { return _path; } - Glib::ustring peak_path (Glib::ustring audio_path); - Glib::ustring find_broken_peakfile (Glib::ustring missing_peak_path, - Glib::ustring audio_path); - - uint16_t channel() const { return _channel; } - - static void set_peak_dir (Glib::ustring dir) { peak_dir = dir; } - - static bool get_soundfile_info (Glib::ustring path, SoundFileInfo& _info, std::string& error); - - static bool safe_file_extension (Glib::ustring path); - - void set_allow_remove_if_empty (bool yn); - void mark_for_remove(); - - /* this block of methods do nothing for regular file sources, but are significant - for files used in destructive recording. - */ - - virtual nframes_t last_capture_start_frame() const { return 0; } - virtual void mark_capture_start (nframes_t) {} - virtual void mark_capture_end () {} - virtual void clear_capture_marks() {} - virtual bool one_of_several_channels () const { return false; } - - virtual int update_header (nframes_t when, struct tm&, time_t) = 0; - virtual int flush_header () = 0; - - int move_to_trash (const Glib::ustring& trash_dir_name); - - static bool is_empty (Session&, Glib::ustring path); - void mark_streaming_write_completed (); - - void mark_take (Glib::ustring); - Glib::ustring take_id() const { return _take_id; } - - bool is_embedded() const { return _is_embedded; } - - static void set_bwf_serial_number (int); - - static void set_search_path (Glib::ustring string); - static void set_header_position_offset (nframes_t offset ); - - int setup_peakfile (); - - static sigc::signal<void> HeaderPositionOffsetChanged; - - XMLNode& get_state (); - int set_state (const XMLNode&); - - bool destructive() const { return (_flags & Destructive); } - virtual bool set_destructive (bool yn) { return false; } - bool can_truncate_peaks() const { return !destructive(); } - - Flag flags() const { return _flags; } - - void mark_immutable (); - - /* this should really be protected, but C++ is getting stricter - and creating slots from protected member functions is starting - to cause issues. - */ - - virtual void handle_header_position_change () {} - - bool can_be_analysed() const { return _length > 0; } - - protected: - - /* constructor to be called for existing external-to-session files */ - - AudioFileSource (Session&, Glib::ustring path, Flag flags); - - /* constructor to be called for new in-session files */ - - AudioFileSource (Session&, Glib::ustring path, Flag flags, - SampleFormat samp_format, HeaderFormat hdr_format); - - /* constructor to be called for existing in-session files */ - - AudioFileSource (Session&, const XMLNode&, bool must_exit = true); - - int init (Glib::ustring idstr, bool must_exist); - - Glib::ustring _path; - Flag _flags; - Glib::ustring _take_id; - int64_t timeline_position; - bool file_is_new; - uint16_t _channel; - - bool _is_embedded; - static bool determine_embeddedness(Glib::ustring path); - - static Glib::ustring peak_dir; - static Glib::ustring search_path; - - static char bwf_country_code[3]; - static char bwf_organization_code[4]; - static char bwf_serial_number[13]; - - static uint64_t header_position_offset; - - virtual void set_timeline_position (int64_t pos); - virtual void set_header_timeline_position () = 0; - - bool find (Glib::ustring& path, bool must_exist, bool& is_new, uint16_t& chan); - bool removable() const; - bool writable() const { return _flags & Writable; } - - static Sample* get_interleave_buffer (nframes_t size); - - private: - Glib::ustring old_peak_path (Glib::ustring audio_path); - Glib::ustring broken_peak_path (Glib::ustring audio_path); -}; - -} // namespace ARDOUR - -#endif /* __ardour_audiofilesource_h__ */ - diff --git a/libs/ardour/ardour/audioplaylist.h b/libs/ardour/ardour/audioplaylist.h deleted file mode 100644 index 4acbc9ad51..0000000000 --- a/libs/ardour/ardour/audioplaylist.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - Copyright (C) 2003 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_audio_playlist_h__ -#define __ardour_audio_playlist_h__ - -#include <vector> -#include <list> - -#include <ardour/ardour.h> -#include <ardour/playlist.h> - -namespace ARDOUR { - -class Session; -class Region; -class AudioRegion; -class Source; - -class AudioPlaylist : public ARDOUR::Playlist -{ - public: - typedef std::list<boost::shared_ptr<Crossfade> > Crossfades; - - public: - AudioPlaylist (Session&, const XMLNode&, bool hidden = false); - AudioPlaylist (Session&, string name, bool hidden = false); - AudioPlaylist (boost::shared_ptr<const AudioPlaylist>, string name, bool hidden = false); - AudioPlaylist (boost::shared_ptr<const AudioPlaylist>, nframes_t start, nframes_t cnt, string name, bool hidden = false); - - ~AudioPlaylist (); - - void clear (bool with_signals=true); - - nframes_t read (Sample *dst, Sample *mixdown, float *gain_buffer, nframes_t start, nframes_t cnt, uint32_t chan_n=0); - - int set_state (const XMLNode&); - - sigc::signal<void,boost::shared_ptr<Crossfade> > NewCrossfade; - - template<class T> void foreach_crossfade (T *t, void (T::*func)(boost::shared_ptr<Crossfade>)); - void crossfades_at (nframes_t frame, Crossfades&); - - bool destroy_region (boost::shared_ptr<Region>); - - protected: - - /* playlist "callbacks" */ - void notify_crossfade_added (boost::shared_ptr<Crossfade>); - void flush_notifications (); - - void finalize_split_region (boost::shared_ptr<Region> orig, boost::shared_ptr<Region> left, boost::shared_ptr<Region> right); - - void refresh_dependents (boost::shared_ptr<Region> region); - void check_dependents (boost::shared_ptr<Region> region, bool norefresh); - void remove_dependents (boost::shared_ptr<Region> region); - - private: - Crossfades _crossfades; - Crossfades _pending_xfade_adds; - - void crossfade_invalidated (boost::shared_ptr<Region>); - XMLNode& state (bool full_state); - void dump () const; - - bool region_changed (Change, boost::shared_ptr<Region>); - void crossfade_changed (Change); - void add_crossfade (boost::shared_ptr<Crossfade>); - - void source_offset_changed (boost::shared_ptr<AudioRegion> region); -}; - -} /* namespace ARDOUR */ - -#endif /* __ardour_audio_playlist_h__ */ - - diff --git a/libs/ardour/ardour/audioregion.h b/libs/ardour/ardour/audioregion.h deleted file mode 100644 index 81b7ef7c57..0000000000 --- a/libs/ardour/ardour/audioregion.h +++ /dev/null @@ -1,204 +0,0 @@ -/* - Copyright (C) 2000-2006 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_audio_region_h__ -#define __ardour_audio_region_h__ - -#include <vector> -#include <list> - -#include <pbd/fastlog.h> -#include <pbd/undo.h> - -#include <ardour/ardour.h> -#include <ardour/region.h> -#include <ardour/gain.h> -#include <ardour/logcurve.h> -#include <ardour/export.h> - -class XMLNode; - -namespace ARDOUR { - -class Route; -class Playlist; -class Session; -class Filter; -class AudioSource; - -class AudioRegion : public Region -{ - public: - static Change FadeInChanged; - static Change FadeOutChanged; - static Change FadeInActiveChanged; - static Change FadeOutActiveChanged; - static Change EnvelopeActiveChanged; - static Change ScaleAmplitudeChanged; - static Change EnvelopeChanged; - - ~AudioRegion(); - - bool speed_mismatch (float) const; - - boost::shared_ptr<AudioSource> audio_source (uint32_t n=0) const; - - void set_scale_amplitude (gain_t); - gain_t scale_amplitude() const { return _scale_amplitude; } - - void normalize_to (float target_in_dB = 0.0f); - - bool envelope_active () const { return _flags & Region::EnvelopeActive; } - bool fade_in_active () const { return _flags & Region::FadeIn; } - bool fade_out_active () const { return _flags & Region::FadeOut; } - - boost::shared_ptr<AutomationList> fade_in() { return _fade_in; } - boost::shared_ptr<AutomationList> fade_out() { return _fade_out; } - boost::shared_ptr<AutomationList> envelope() { return _envelope; } - - virtual nframes_t read_peaks (PeakData *buf, nframes_t npeaks, - nframes_t offset, nframes_t cnt, - uint32_t chan_n=0, double samples_per_unit= 1.0) const; - - /* Readable interface */ - - virtual nframes64_t read (Sample*, nframes64_t pos, nframes64_t cnt, int channel) const; - virtual nframes64_t readable_length() const { return length(); } - - virtual nframes_t read_at (Sample *buf, Sample *mixdown_buf, - float *gain_buf, nframes_t position, nframes_t cnt, - uint32_t chan_n = 0, - nframes_t read_frames = 0, - nframes_t skip_frames = 0) const; - - virtual nframes_t master_read_at (Sample *buf, Sample *mixdown_buf, - float *gain_buf, - nframes_t position, nframes_t cnt, uint32_t chan_n=0) const; - - virtual nframes_t read_raw_internal (Sample*, nframes_t, nframes_t) const; - - XMLNode& state (bool); - int set_state (const XMLNode&); - - static void set_default_fade (float steepness, nframes_t len); - bool fade_in_is_default () const; - bool fade_out_is_default () const; - - enum FadeShape { - Linear, - Fast, - Slow, - LogA, - LogB - }; - - void set_fade_in_active (bool yn); - void set_fade_in_shape (FadeShape); - void set_fade_in_length (nframes_t); - void set_fade_in (FadeShape, nframes_t); - - void set_fade_out_active (bool yn); - void set_fade_out_shape (FadeShape); - void set_fade_out_length (nframes_t); - void set_fade_out (FadeShape, nframes_t); - - void set_envelope_active (bool yn); - void set_default_envelope (); - - int separate_by_channel (ARDOUR::Session&, vector<boost::shared_ptr<AudioRegion> >&) const; - - /* export */ - - int exportme (ARDOUR::Session&, ARDOUR::ExportSpecification&); - - /* xfade/fade interactions */ - - void suspend_fade_in (); - void suspend_fade_out (); - void resume_fade_in (); - void resume_fade_out (); - - int get_transients (AnalysisFeatureList&, bool force_new = false); - - private: - friend class RegionFactory; - - AudioRegion (boost::shared_ptr<AudioSource>, nframes_t start, nframes_t length); - AudioRegion (boost::shared_ptr<AudioSource>, nframes_t start, nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags); - AudioRegion (const SourceList &, nframes_t start, nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags); - AudioRegion (boost::shared_ptr<const AudioRegion>, nframes_t start, nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags); - AudioRegion (boost::shared_ptr<AudioSource>, const XMLNode&); - AudioRegion (SourceList &, const XMLNode&); - - private: - void init (); - void set_default_fades (); - void set_default_fade_in (); - void set_default_fade_out (); - - void recompute_gain_at_end (); - void recompute_gain_at_start (); - - nframes_t _read_at (const SourceList&, nframes_t limit, - Sample *buf, Sample *mixdown_buffer, - float *gain_buffer, nframes_t position, nframes_t cnt, - uint32_t chan_n = 0, - nframes_t read_frames = 0, - nframes_t skip_frames = 0, - bool raw = false) const; - - void recompute_at_start (); - void recompute_at_end (); - - void envelope_changed (); - void fade_in_changed (); - void fade_out_changed (); - void source_offset_changed (); - void listen_to_my_curves (); - void listen_to_my_sources (); - - boost::shared_ptr<AutomationList> _fade_in; - FadeShape _fade_in_shape; - boost::shared_ptr<AutomationList> _fade_out; - FadeShape _fade_out_shape; - boost::shared_ptr<AutomationList> _envelope; - gain_t _scale_amplitude; - uint32_t _fade_in_disabled; - uint32_t _fade_out_disabled; - - protected: - /* default constructor for derived (compound) types */ - - AudioRegion (Session& s, nframes_t, nframes_t, std::string name); - AudioRegion (boost::shared_ptr<const AudioRegion>); - - int set_live_state (const XMLNode&, Change&, bool send); -}; - -} /* namespace ARDOUR */ - -/* access from C objects */ - -extern "C" { - int region_read_peaks_from_c (void *arg, uint32_t npeaks, uint32_t start, uint32_t length, intptr_t data, uint32_t n_chan, double samples_per_unit); - uint32_t region_length_from_c (void *arg); - uint32_t sourcefile_length_from_c (void *arg, double); -} - -#endif /* __ardour_audio_region_h__ */ diff --git a/libs/ardour/ardour/audiosource.h b/libs/ardour/ardour/audiosource.h deleted file mode 100644 index d11b829694..0000000000 --- a/libs/ardour/ardour/audiosource.h +++ /dev/null @@ -1,159 +0,0 @@ -/* - Copyright (C) 2000 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_audio_source_h__ -#define __ardour_audio_source_h__ - -#include <list> -#include <vector> - -#include <boost/shared_ptr.hpp> -#include <boost/enable_shared_from_this.hpp> - -#include <time.h> - -#include <glibmm/thread.h> -#include <glibmm/ustring.h> - -#include <sigc++/signal.h> - -#include <ardour/source.h> -#include <ardour/ardour.h> -#include <pbd/stateful.h> -#include <pbd/xml++.h> - -using std::list; -using std::vector; - -namespace ARDOUR { - -class AudioSource : public Source, public boost::enable_shared_from_this<ARDOUR::AudioSource> -{ - public: - AudioSource (Session&, Glib::ustring name); - AudioSource (Session&, const XMLNode&); - virtual ~AudioSource (); - - nframes64_t readable_length() const { return _length; } - uint32_t n_channels() const { return 1; } - - virtual nframes_t available_peaks (double zoom) const; - - /* stopgap until nframes_t becomes nframes64_t. this function is needed by the Readable interface */ - - virtual nframes64_t read (Sample *dst, nframes64_t start, nframes64_t cnt, int channel) const { - /* XXX currently ignores channel, assuming that source is always mono, which - historically has been true. - */ - return read (dst, (nframes_t) start, (nframes_t) cnt); - } - - virtual nframes_t read (Sample *dst, nframes_t start, nframes_t cnt) const; - virtual nframes_t write (Sample *src, nframes_t cnt); - - virtual float sample_rate () const = 0; - - virtual void mark_for_remove() = 0; - virtual void mark_streaming_write_completed () {} - - virtual bool can_truncate_peaks() const { return true; } - - void set_captured_for (Glib::ustring str) { _captured_for = str; } - Glib::ustring captured_for() const { return _captured_for; } - - uint32_t read_data_count() const { return _read_data_count; } - uint32_t write_data_count() const { return _write_data_count; } - - int read_peaks (PeakData *peaks, nframes_t npeaks, nframes_t start, nframes_t cnt, double samples_per_visual_peak) const; - - int build_peaks (); - bool peaks_ready (sigc::slot<void>, sigc::connection&) const; - - mutable sigc::signal<void> PeaksReady; - mutable sigc::signal<void,nframes_t,nframes_t> PeakRangeReady; - - XMLNode& get_state (); - int set_state (const XMLNode&); - - int rename_peakfile (Glib::ustring newpath); - void touch_peakfile (); - - static void set_build_missing_peakfiles (bool yn) { - _build_missing_peakfiles = yn; - } - - static void set_build_peakfiles (bool yn) { - _build_peakfiles = yn; - } - - static bool get_build_peakfiles () { - return _build_peakfiles; - } - - virtual int setup_peakfile () { return 0; } - - int prepare_for_peakfile_writes (); - void done_with_peakfile_writes (bool done = true); - - protected: - static bool _build_missing_peakfiles; - static bool _build_peakfiles; - - bool _peaks_built; - mutable Glib::Mutex _lock; - mutable Glib::Mutex _peaks_ready_lock; - Glib::ustring peakpath; - Glib::ustring _captured_for; - - mutable uint32_t _read_data_count; // modified in read() - mutable uint32_t _write_data_count; // modified in write() - - int initialize_peakfile (bool newfile, Glib::ustring path); - int build_peaks_from_scratch (); - int compute_and_write_peaks (Sample* buf, nframes_t first_frame, nframes_t cnt, bool force, bool intermediate_peaks_ready_signal); - void truncate_peakfile(); - - mutable off_t _peak_byte_max; // modified in compute_and_write_peak() - - virtual nframes_t read_unlocked (Sample *dst, nframes_t start, nframes_t cnt) const = 0; - virtual nframes_t write_unlocked (Sample *dst, nframes_t cnt) = 0; - virtual Glib::ustring peak_path(Glib::ustring audio_path) = 0; - virtual Glib::ustring find_broken_peakfile (Glib::ustring missing_peak_path, Glib::ustring audio_path) = 0; - - void update_length (nframes_t pos, nframes_t cnt); - - virtual int read_peaks_with_fpp (PeakData *peaks, nframes_t npeaks, nframes_t start, nframes_t cnt, - double samples_per_visual_peak, nframes_t fpp) const; - - int compute_and_write_peaks (Sample* buf, nframes_t first_frame, nframes_t cnt, bool force, - bool intermediate_peaks_ready_signal, nframes_t frames_per_peak); - - private: - int peakfile; - nframes_t peak_leftover_cnt; - nframes_t peak_leftover_size; - Sample* peak_leftovers; - nframes_t peak_leftover_frame; - - bool file_changed (Glib::ustring path); -}; - -} - -#endif /* __ardour_audio_source_h__ */ diff --git a/libs/ardour/ardour/auditioner.h b/libs/ardour/ardour/auditioner.h deleted file mode 100644 index 06d521ea21..0000000000 --- a/libs/ardour/ardour/auditioner.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - Copyright (C) 2001 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_auditioner_h__ -#define __ardour_auditioner_h__ - -#include <string> - -#include <glibmm/thread.h> - -#include <ardour/ardour.h> -#include <ardour/audio_track.h> - -namespace ARDOUR { - -class Session; -class AudioRegion; -class AudioPlaylist; - -class Auditioner : public AudioTrack -{ - public: - Auditioner (Session&); - ~Auditioner (); - - void audition_region (boost::shared_ptr<Region>); - - ARDOUR::AudioPlaylist& prepare_playlist (); - void audition_current_playlist (); - - int play_audition (nframes_t nframes); - - void cancel_audition () { - g_atomic_int_set (&_active, 0); - } - - bool active() const { return g_atomic_int_get (&_active); } - - private: - boost::shared_ptr<AudioRegion> the_region; - nframes_t current_frame; - mutable gint _active; - Glib::Mutex lock; - nframes_t length; - - void drop_ports (); - static void *_drop_ports (void *); - void actually_drop_ports (); - void output_changed (IOChange, void*); -}; - -}; /* namespace ARDOUR */ - -#endif /* __ardour_auditioner_h__ */ diff --git a/libs/ardour/ardour/auto_bundle.h b/libs/ardour/ardour/auto_bundle.h deleted file mode 100644 index 685a083e8d..0000000000 --- a/libs/ardour/ardour/auto_bundle.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - Copyright (C) 2007 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_auto_bundle_h__ -#define __ardour_auto_bundle_h__ - -#include <vector> -#include <glibmm/thread.h> -#include "ardour/bundle.h" - -namespace ARDOUR { - -class AutoBundle : public Bundle { - - public: - AutoBundle (bool i = true); - AutoBundle (std::string const &, bool i = true); - - uint32_t nchannels () const; - const PortList& channel_ports (uint32_t) const; - - void set_channels (uint32_t); - void set_port (uint32_t, std::string const &); - - private: - /// mutex for _ports; - /// XXX: is this necessary? - mutable Glib::Mutex _ports_mutex; - std::vector<PortList> _ports; -}; - -} - -#endif /* __ardour_auto_bundle_h__ */ diff --git a/libs/ardour/ardour/automatable.h b/libs/ardour/ardour/automatable.h deleted file mode 100644 index a2c1d98ae7..0000000000 --- a/libs/ardour/ardour/automatable.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - Copyright (C) 2000-2007 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_automatable_h__ -#define __ardour_automatable_h__ - -#include <set> -#include <map> -#include <boost/shared_ptr.hpp> -#include <ardour/session_object.h> -#include <ardour/automation_event.h> -#include <ardour/automation_control.h> -#include <ardour/parameter.h> - -namespace ARDOUR { - -class Session; -class AutomationControl; - -class Automatable : public SessionObject -{ -public: - Automatable(Session&, const std::string& name); - - virtual ~Automatable() {} - - // shorthand for gain, pan, etc - inline boost::shared_ptr<AutomationControl> - control(AutomationType type, bool create_if_missing=false) { - return control(Parameter(type), create_if_missing); - } - - virtual boost::shared_ptr<AutomationControl> control(Parameter id, bool create_if_missing=false); - virtual boost::shared_ptr<const AutomationControl> control(Parameter id) const; - - boost::shared_ptr<AutomationControl> control_factory(boost::shared_ptr<AutomationList> list); - - typedef std::map<Parameter,boost::shared_ptr<AutomationControl> > Controls; - Controls& controls() { return _controls; } - const Controls& controls() const { return _controls; } - - virtual void add_control(boost::shared_ptr<AutomationControl>); - - virtual void automation_snapshot(nframes_t now, bool force); - bool should_snapshot (nframes_t now) { - return (_last_automation_snapshot > now || (now - _last_automation_snapshot) > _automation_interval); - } - virtual void transport_stopped(nframes_t now); - - virtual bool find_next_event(nframes_t start, nframes_t end, ControlEvent& ev) const; - - virtual string describe_parameter(Parameter param); - virtual float default_parameter_value(Parameter param) { return 1.0f; } - - virtual void clear_automation(); - - AutoState get_parameter_automation_state (Parameter param, bool lock = true); - virtual void set_parameter_automation_state (Parameter param, AutoState); - - AutoStyle get_parameter_automation_style (Parameter param); - void set_parameter_automation_style (Parameter param, AutoStyle); - - void protect_automation (); - - void what_has_automation(std::set<Parameter>&) const; - void what_has_visible_automation(std::set<Parameter>&) const; - const std::set<Parameter>& what_can_be_automated() const { return _can_automate_list; } - - void mark_automation_visible(Parameter, bool); - - Glib::Mutex& automation_lock() const { return _automation_lock; } - - static void set_automation_interval (jack_nframes_t frames) { - _automation_interval = frames; - } - - static jack_nframes_t automation_interval() { - return _automation_interval; - } - -protected: - - void can_automate(Parameter); - - virtual void auto_state_changed (Parameter which) {} - - int set_automation_state(const XMLNode&, Parameter default_param); - XMLNode& get_automation_state(); - - int load_automation (const std::string& path); - int old_set_automation_state(const XMLNode&); - - mutable Glib::Mutex _automation_lock; - - Controls _controls; - std::set<Parameter> _visible_controls; - std::set<Parameter> _can_automate_list; - - nframes_t _last_automation_snapshot; - static nframes_t _automation_interval; -}; - -} // namespace ARDOUR - -#endif /* __ardour_automatable_h__ */ diff --git a/libs/ardour/ardour/automation_control.h b/libs/ardour/ardour/automation_control.h deleted file mode 100644 index 68ac5797dc..0000000000 --- a/libs/ardour/ardour/automation_control.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - Copyright (C) 2007 Paul Davis - Author: Dave Robillard - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_automation_control_h__ -#define __ardour_automation_control_h__ - -#include <boost/shared_ptr.hpp> -#include <pbd/controllable.h> -#include <ardour/parameter.h> - -namespace ARDOUR { - -class AutomationList; -class Session; -class Automatable; - - -/** A PBD:Controllable with associated automation data (AutomationList) - */ -class AutomationControl : public PBD::Controllable -{ -public: - AutomationControl(ARDOUR::Session&, - boost::shared_ptr<ARDOUR::AutomationList>, - std::string name="unnamed controllable"); - - void set_value(float val); - float get_value() const; - float user_value() const; - - void set_list(boost::shared_ptr<ARDOUR::AutomationList>); - - boost::shared_ptr<ARDOUR::AutomationList> list() { return _list; } - boost::shared_ptr<const ARDOUR::AutomationList> list() const { return _list; } - - Parameter parameter() const; - -protected: - ARDOUR::Session& _session; - boost::shared_ptr<ARDOUR::AutomationList> _list; - float _user_value; -}; - - -} // namespace ARDOUR - -#endif /* __ardour_automation_control_h__ */ diff --git a/libs/ardour/ardour/automation_event.h b/libs/ardour/ardour/automation_event.h deleted file mode 100644 index 18190aa9b6..0000000000 --- a/libs/ardour/ardour/automation_event.h +++ /dev/null @@ -1,309 +0,0 @@ -/* - Copyright (C) 2002 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_automation_event_h__ -#define __ardour_automation_event_h__ - -#include <stdint.h> -#include <list> -#include <cmath> - -#include <sigc++/signal.h> -#include <glibmm/thread.h> - -#include <boost/pool/pool.hpp> -#include <boost/pool/pool_alloc.hpp> - -#include <pbd/undo.h> -#include <pbd/xml++.h> -#include <pbd/statefuldestructible.h> - -#include <ardour/ardour.h> -#include <ardour/parameter.h> - -namespace ARDOUR { - -class Curve; - -struct ControlEvent { - - ControlEvent (double w, double v) - : when (w), value (v), coeff (0) { - } - - ControlEvent (const ControlEvent& other) - : when (other.when), value (other.value), coeff (0) { - if (other.coeff) { - create_coeffs(); - for (size_t i=0; i < 4; ++i) - coeff[i] = other.coeff[i]; - } - } - - ~ControlEvent() { if (coeff) delete[] coeff; } - - void create_coeffs() { - if (!coeff) - coeff = new double[4]; - - coeff[0] = coeff[1] = coeff[2] = coeff[3] = 0.0; - } - - double when; - double value; - double* coeff; ///< double[4] allocated by Curve as needed -}; - -/* automation lists use a pool allocator that does not use a lock and - allocates 8k of new pointers at a time -*/ - -typedef boost::fast_pool_allocator<ControlEvent*, - boost::default_user_allocator_new_delete, - boost::details::pool::null_mutex, - 8192> ControlEventAllocator; - -class AutomationList : public PBD::StatefulDestructible -{ - public: - typedef std::list<ControlEvent*,ControlEventAllocator> EventList; - typedef EventList::iterator iterator; - typedef EventList::reverse_iterator reverse_iterator; - typedef EventList::const_iterator const_iterator; - - AutomationList (Parameter id, double min_val, double max_val, double default_val); - AutomationList (const XMLNode&, Parameter id); - ~AutomationList(); - - AutomationList (const AutomationList&); - AutomationList (const AutomationList&, double start, double end); - AutomationList& operator= (const AutomationList&); - bool operator== (const AutomationList&); - - const Parameter& parameter() const { return _parameter; } - void set_parameter(Parameter p) { _parameter = p; } - - void freeze(); - void thaw (); - - EventList::size_type size() const { return _events.size(); } - bool empty() const { return _events.empty(); } - - void reset_default (double val) { - _default_value = val; - } - - void clear (); - void x_scale (double factor); - bool extend_to (double); - void slide (iterator before, double distance); - - void reposition_for_rt_add (double when); - void rt_add (double when, double value); - void add (double when, double value); - /* this should be private but old-school automation loading needs it in IO/IOProcessor */ - void fast_simple_add (double when, double value); - - void reset_range (double start, double end); - void erase_range (double start, double end); - void erase (iterator); - void erase (iterator, iterator); - void move_range (iterator start, iterator end, double, double); - void modify (iterator, double, double); - - AutomationList* cut (double, double); - AutomationList* copy (double, double); - void clear (double, double); - - AutomationList* cut (iterator, iterator); - AutomationList* copy (iterator, iterator); - void clear (iterator, iterator); - - bool paste (AutomationList&, double position, float times); - - void set_automation_state (AutoState); - AutoState automation_state() const { return _state; } - sigc::signal<void> automation_style_changed; - - void set_automation_style (AutoStyle m); - AutoStyle automation_style() const { return _style; } - sigc::signal<void> automation_state_changed; - - bool automation_playback() const { - return (_state & Play) || ((_state & Touch) && !_touching); - } - bool automation_write () const { - return (_state & Write) || ((_state & Touch) && _touching); - } - - void start_touch (); - void stop_touch (); - bool touching() const { return _touching; } - - void set_yrange (double min, double max) { - _min_yval = min; - _max_yval = max; - } - - double get_max_y() const { return _max_yval; } - double get_min_y() const { return _min_yval; } - - void truncate_end (double length); - void truncate_start (double length); - - iterator begin() { return _events.begin(); } - iterator end() { return _events.end(); } - - ControlEvent* back() { return _events.back(); } - ControlEvent* front() { return _events.front(); } - - const_iterator const_begin() const { return _events.begin(); } - const_iterator const_end() const { return _events.end(); } - - std::pair<AutomationList::iterator,AutomationList::iterator> control_points_adjacent (double when); - - template<class T> void apply_to_points (T& obj, void (T::*method)(const AutomationList&)) { - Glib::Mutex::Lock lm (_lock); - (obj.*method)(*this); - } - - sigc::signal<void> StateChanged; - - XMLNode& get_state(void); - int set_state (const XMLNode &s); - XMLNode& state (bool full); - XMLNode& serialize_events (); - - void set_max_xval (double); - double get_max_xval() const { return _max_xval; } - - double eval (double where) { - Glib::Mutex::Lock lm (_lock); - return unlocked_eval (where); - } - - double rt_safe_eval (double where, bool& ok) { - - Glib::Mutex::Lock lm (_lock, Glib::TRY_LOCK); - - if ((ok = lm.locked())) { - return unlocked_eval (where); - } else { - return 0.0; - } - } - - static inline bool time_comparator (const ControlEvent* a, const ControlEvent* b) { - return a->when < b->when; - } - - /** Lookup cache for eval functions, range contains equivalent values */ - struct LookupCache { - LookupCache() : left(-1) {} - double left; /* leftmost x coordinate used when finding "range" */ - std::pair<AutomationList::const_iterator,AutomationList::const_iterator> range; - }; - - /** Lookup cache for point finding, range contains points between left and right */ - struct SearchCache { - SearchCache() : left(-1), right(-1) {} - double left; /* leftmost x coordinate used when finding "range" */ - double right; /* rightmost x coordinate used when finding "range" */ - std::pair<AutomationList::const_iterator,AutomationList::const_iterator> range; - }; - - static sigc::signal<void, AutomationList*> AutomationListCreated; - - const EventList& events() const { return _events; } - double default_value() const { return _default_value; } - - // teeny const violations for Curve - mutable sigc::signal<void> Dirty; - Glib::Mutex& lock() const { return _lock; } - LookupCache& lookup_cache() const { return _lookup_cache; } - SearchCache& search_cache() const { return _search_cache; } - - /** Called by locked entry point and various private - * locations where we already hold the lock. - * - * FIXME: Should this be private? Curve needs it.. - */ - double unlocked_eval (double x) const; - - bool rt_safe_earliest_event (double start, double end, double& x, double& y, bool start_inclusive=false) const; - bool rt_safe_earliest_event_unlocked (double start, double end, double& x, double& y, bool start_inclusive=false) const; - - Curve& curve() { return *_curve; } - const Curve& curve() const { return *_curve; } - - enum InterpolationStyle { - Discrete, - Linear, - Curved - }; - - InterpolationStyle interpolation() const { return _interpolation; } - void set_interpolation(InterpolationStyle style) { _interpolation = style; } - - private: - - /** Called by unlocked_eval() to handle cases of 3 or more control points. - */ - double multipoint_eval (double x) const; - - void build_search_cache_if_necessary(double start, double end) const; - - bool rt_safe_earliest_event_discrete_unlocked (double start, double end, double& x, double& y, bool inclusive) const; - bool rt_safe_earliest_event_linear_unlocked (double start, double end, double& x, double& y, bool inclusive) const; - - AutomationList* cut_copy_clear (double, double, int op); - - int deserialize_events (const XMLNode&); - - void maybe_signal_changed (); - void mark_dirty (); - void _x_scale (double factor); - - mutable LookupCache _lookup_cache; - mutable SearchCache _search_cache; - - Parameter _parameter; - InterpolationStyle _interpolation; - EventList _events; - mutable Glib::Mutex _lock; - int8_t _frozen; - bool _changed_when_thawed; - AutoState _state; - AutoStyle _style; - bool _touching; - bool _new_touch; - double _max_xval; - double _min_yval; - double _max_yval; - double _default_value; - bool _sort_pending; - iterator _rt_insertion_point; - double _rt_pos; - - Curve* _curve; -}; - -} // namespace - -#endif /* __ardour_automation_event_h__ */ diff --git a/libs/ardour/ardour/base_audio_port.h b/libs/ardour/ardour/base_audio_port.h deleted file mode 100644 index 791928fa03..0000000000 --- a/libs/ardour/ardour/base_audio_port.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - Copyright (C) 2002 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - $Id: port.h 712 2006-07-28 01:08:57Z drobilla $ -*/ - -#ifndef __ardour_base_audio_port_h__ -#define __ardour_base_audio_port_h__ - -#include <string> - -#include <sigc++/signal.h> - -#include <pbd/failed_constructor.h> - -#include <ardour/ardour.h> -#include <ardour/port.h> -#include <ardour/audio_buffer.h> - -namespace ARDOUR { - -class AudioEngine; - -class BaseAudioPort : public virtual Port { - public: - virtual ~BaseAudioPort(); - - DataType type() const { return DataType::AUDIO; } - - virtual Buffer& get_buffer () { - assert (_buffer); - return *_buffer; - } - - virtual AudioBuffer& get_audio_buffer() { - assert (_buffer); - return *_buffer; - } - - void reset (); - - void reset_overs () { - /* XXX NOT THREAD SAFE */ - _short_overs = 0; - _long_overs = 0; - _overlen = 0; - } - - void reset_peak_meter () { - /* XXX NOT THREAD SAFE */ - _peak = 0; - } - - void reset_meters () { - /* XXX NOT THREAD SAFE */ - reset_peak_meter (); - reset_overs (); - } - - float peak_db() const { return _peak_db; } - Sample peak() const { return _peak; } - - uint32_t short_overs () const { return _short_overs; } - uint32_t long_overs () const { return _long_overs; } - - static void set_short_over_length (nframes_t); - static void set_long_over_length (nframes_t); - - void set_mixdown_function (void (*func)(const std::set<Port*>&, AudioBuffer*, nframes_t, nframes_t, bool)); - - protected: - BaseAudioPort (const std::string& name, Flags flags); - - AudioBuffer* _buffer; - nframes_t _overlen; - Sample _peak; - float _peak_db; - uint32_t _short_overs; - uint32_t _long_overs; - bool _own_buffer; - - void (*_mixdown)(const std::set<Port*>&, AudioBuffer*, nframes_t, nframes_t, bool); - - static void default_mixdown (const std::set<Port*>&, AudioBuffer*, nframes_t, nframes_t, bool); - - static nframes_t _long_over_length; - static nframes_t _short_over_length; -}; - -} // namespace ARDOUR - -#endif /* __ardour_base_audio_port_h__ */ diff --git a/libs/ardour/ardour/base_midi_port.h b/libs/ardour/ardour/base_midi_port.h deleted file mode 100644 index 1c9a69d48d..0000000000 --- a/libs/ardour/ardour/base_midi_port.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - Copyright (C) 2002 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - $Id: port.h 712 2006-07-28 01:08:57Z drobilla $ -*/ - -#ifndef __ardour_base_midi_port_h__ -#define __ardour_base_midi_port_h__ - -#include <sigc++/signal.h> -#include <pbd/failed_constructor.h> -#include <ardour/ardour.h> -#include <ardour/port.h> -#include <ardour/midi_buffer.h> - -namespace ARDOUR { - -class MidiEngine; - -class BaseMidiPort : public virtual Port { - public: - virtual ~BaseMidiPort(); - - DataType type() const { return DataType::MIDI; } - - Buffer& get_buffer() { - assert (_buffer); - return *_buffer; - } - - MidiBuffer& get_midi_buffer() { - assert (_buffer); - return *_buffer; - } - - size_t capacity() { return _buffer->capacity(); } - size_t size() { return _buffer->size(); } - - void set_mixdown_function (void (*func)(const std::set<Port*>&, MidiBuffer*, nframes_t, nframes_t, bool)); - - protected: - BaseMidiPort (const std::string& name, Flags); - - MidiBuffer* _buffer; - bool _own_buffer; - - void (*_mixdown)(const std::set<Port*>&, MidiBuffer*, nframes_t, nframes_t, bool); - static void default_mixdown (const std::set<Port*>&, MidiBuffer*, nframes_t, nframes_t, bool); -}; - -} // namespace ARDOUR - -#endif /* __ardour_base_midi_port_h__ */ diff --git a/libs/ardour/ardour/buffer.h b/libs/ardour/ardour/buffer.h deleted file mode 100644 index fd94360226..0000000000 --- a/libs/ardour/ardour/buffer.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - Copyright (C) 2006 Paul Davis - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the Free - Software Foundation; either version 2 of the License, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifndef __ardour_buffer_h__ -#define __ardour_buffer_h__ - -#include <cstdlib> -#include <cassert> -#include <iostream> -#include <boost/utility.hpp> -#include <ardour/types.h> -#include <ardour/data_type.h> -#include <ardour/runtime_functions.h> - -namespace ARDOUR { - - -/** A buffer of recordable/playable data. - * - * This is a datatype-agnostic base class for all buffers (there are no - * methods to actually access the data). This provides a way for code that - * doesn't care about the data type to still deal with buffers (which is - * why the base class can't be a template). - * - * To actually read/write buffer contents, use the appropriate derived class. - */ -class Buffer : public boost::noncopyable -{ -public: - virtual ~Buffer() {} - - /** Factory function */ - static Buffer* create(DataType type, size_t capacity); - - /** Maximum capacity of buffer. - * Note in some cases the entire buffer may not contain valid data, use size. */ - size_t capacity() const { return _capacity; } - - /** Amount of valid data in buffer. Use this over capacity almost always. */ - size_t size() const { return _size; } - - /** Type of this buffer. - * Based on this you can static cast a Buffer* to the desired type. */ - DataType type() const { return _type; } - - bool silent() const { return _silent; } - - /** Reallocate the buffer used internally to handle at least @a size_t units of data. - * - * The buffer is not silent after this operation. the @a capacity argument - * passed to the constructor must have been non-zero. - */ - virtual void resize(size_t) = 0; - - /** Clear (eg zero, or empty) buffer starting at TIME @a offset */ - virtual void silence(nframes_t len, nframes_t offset=0) = 0; - - /** Clear the entire buffer */ - virtual void clear() { silence(_capacity, 0); } - - virtual void read_from(const Buffer& src, nframes_t offset, nframes_t len) = 0; - -protected: - Buffer(DataType type, size_t capacity) - : _type(type), _capacity(capacity), _size(0), _silent(true) - {} - - DataType _type; - size_t _capacity; - size_t _size; - bool _silent; -}; - - -} // namespace ARDOUR - -#endif // __ardour_buffer_h__ diff --git a/libs/ardour/ardour/buffer_set.h b/libs/ardour/ardour/buffer_set.h deleted file mode 100644 index c750615798..0000000000 --- a/libs/ardour/ardour/buffer_set.h +++ /dev/null @@ -1,159 +0,0 @@ -/* - Copyright (C) 2006 Paul Davis - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the Free - Software Foundation; either version 2 of the License, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifndef __ardour_buffer_set_h__ -#define __ardour_buffer_set_h__ - -#include <cassert> -#include <vector> -#include <ardour/chan_count.h> -#include <ardour/data_type.h> - -namespace ARDOUR { - -class Buffer; -class AudioBuffer; -class MidiBuffer; -class PortSet; - - -/** A set of buffers of various types. - * - * These are mainly accessed from Session and passed around as scratch buffers - * (eg as parameters to run() methods) to do in-place signal processing. - * - * There are two types of counts associated with a BufferSet - available, - * and the 'use count'. Available is the actual number of allocated buffers - * (and so is the maximum acceptable value for the use counts). - * - * The use counts are how things determine the form of their input and inform - * others the form of their output (eg what they did to the BufferSet). - * Setting the use counts is realtime safe. - */ -class BufferSet -{ -public: - BufferSet(); - ~BufferSet(); - - void clear(); - - void attach_buffers(PortSet& ports); - - void ensure_buffers(const ChanCount& count, size_t buffer_capacity); - void ensure_buffers(DataType type, size_t num_buffers, size_t buffer_capacity); - - const ChanCount& available() const { return _available; } - ChanCount& available() { return _available; } - - const ChanCount& count() const { return _count; } - ChanCount& count() { return _count; } - - void set_count(const ChanCount& count) { _count = count; } - - size_t buffer_capacity(DataType type) const; - - Buffer& get(DataType type, size_t i) - { - assert(i <= _count.get(type)); - return *_buffers[type][i]; - } - - AudioBuffer& get_audio(size_t i) - { - return (AudioBuffer&)get(DataType::AUDIO, i); - } - - MidiBuffer& get_midi(size_t i) - { - return (MidiBuffer&)get(DataType::MIDI, i); - } - - void read_from(BufferSet& in, jack_nframes_t nframes, jack_nframes_t offset=0); - - // ITERATORS - - // FIXME: this is a filthy copy-and-paste mess - // FIXME: litter these with assertions - - class audio_iterator { - public: - - AudioBuffer& operator*() { return _set.get_audio(_index); } - AudioBuffer* operator->() { return &_set.get_audio(_index); } - audio_iterator& operator++() { ++_index; return *this; } // yes, prefix only - bool operator==(const audio_iterator& other) { return (_index == other._index); } - bool operator!=(const audio_iterator& other) { return (_index != other._index); } - - private: - friend class BufferSet; - - audio_iterator(BufferSet& list, size_t index) : _set(list), _index(index) {} - - BufferSet& _set; - size_t _index; - }; - - audio_iterator audio_begin() { return audio_iterator(*this, 0); } - audio_iterator audio_end() { return audio_iterator(*this, _count.n_audio()); } - - class iterator { - public: - - Buffer& operator*() { return _set.get(_type, _index); } - Buffer* operator->() { return &_set.get(_type, _index); } - iterator& operator++() { ++_index; return *this; } // yes, prefix only - bool operator==(const iterator& other) { return (_index == other._index); } - bool operator!=(const iterator& other) { return (_index != other._index); } - iterator operator=(const iterator& other) { _set = other._set; _type = other._type; _index = other._index; return *this; } - - private: - friend class BufferSet; - - iterator(BufferSet& list, DataType type, size_t index) - : _set(list), _type(type), _index(index) {} - - BufferSet& _set; - DataType _type; - size_t _index; - }; - - iterator begin(DataType type) { return iterator(*this, type, 0); } - iterator end(DataType type) { return iterator(*this, type, _count.get(type)); } - - -private: - typedef std::vector<Buffer*> BufferVec; - - /// Vector of vectors, indexed by DataType - std::vector<BufferVec> _buffers; - - /// Use counts (there may be more actual buffers than this) - ChanCount _count; - - /// Available counts (number of buffers actually allocated) - ChanCount _available; - - /// Whether we (don't) 'own' the contained buffers (otherwise we mirror a PortSet) - bool _is_mirror; -}; - - -} // namespace ARDOUR - -#endif // __ardour_buffer_set_h__ diff --git a/libs/ardour/ardour/bundle.h b/libs/ardour/ardour/bundle.h deleted file mode 100644 index ba92063b30..0000000000 --- a/libs/ardour/ardour/bundle.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - Copyright (C) 2002-2007 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_bundle_h__ -#define __ardour_bundle_h__ - -#include <string> -#include <sigc++/signal.h> -#include "ardour/data_type.h" - -namespace ARDOUR { - -typedef std::vector<std::string> PortList; - -/** - * A set of `channels', each of which is associated with 0 or more JACK ports. - */ - -class Bundle { - public: - Bundle () : _type (DataType::AUDIO) {} - Bundle (bool i) : _type (DataType::AUDIO), _ports_are_inputs (i) {} - Bundle (std::string const & n, bool i = true) : _name (n), _type (DataType::AUDIO), _ports_are_inputs (i) {} - virtual ~Bundle() {} - - /** - * @return Number of channels that this Bundle has. - */ - virtual uint32_t nchannels () const = 0; - virtual const PortList& channel_ports (uint32_t) const = 0; - - void set_name (std::string const & n) { - _name = n; - NameChanged (); - } - - std::string name () const { return _name; } - - sigc::signal<void> NameChanged; - - void set_type (DataType t) { _type = t; } - DataType type () const { return _type; } - - void set_ports_are_inputs () { _ports_are_inputs = true; } - void set_ports_are_outputs () { _ports_are_inputs = false; } - bool ports_are_inputs () const { return _ports_are_inputs; } - bool ports_are_outputs () const { return !_ports_are_inputs; } - - private: - std::string _name; - ARDOUR::DataType _type; - bool _ports_are_inputs; -}; - -} - -#endif /* __ardour_bundle_h__ */ diff --git a/libs/ardour/ardour/caimportable.h b/libs/ardour/ardour/caimportable.h deleted file mode 100644 index dc7f5769ae..0000000000 --- a/libs/ardour/ardour/caimportable.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - Copyright (C) 2007 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_ca_importable_source_h__ -#define __ardour_ca_importable_source_h__ - -#include <pbd/failed_constructor.h> -#include <ardour/types.h> -#include <ardour/importable_source.h> - -#include <appleutility/CAAudioFile.h> - -namespace ARDOUR { - -class CAImportableSource : public ImportableSource { - public: - CAImportableSource (const std::string& path); - virtual ~CAImportableSource(); - - nframes_t read (Sample* buffer, nframes_t nframes); - uint32_t channels() const; - nframes_t length() const; - nframes_t samplerate() const; - void seek (nframes_t pos); - - protected: - mutable CAAudioFile af; -}; - -} - -#endif /* __ardour_ca_importable_source_h__ */ diff --git a/libs/ardour/ardour/chan_count.h b/libs/ardour/ardour/chan_count.h deleted file mode 100644 index 986ef76e25..0000000000 --- a/libs/ardour/ardour/chan_count.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - Copyright (C) 2006 Paul Davis - Author: Dave Robillard - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifndef __ardour_chan_count_h__ -#define __ardour_chan_count_h__ - -#include <ardour/data_type.h> -#include <cassert> - -namespace ARDOUR { - - -/** A count of channels, possibly with many types. - * - * Operators are defined so this may safely be used as if it were a simple - * (single-typed) integer count of channels. - */ -class ChanCount { -public: - ChanCount() { reset(); } - - // Convenience constructor for making single-typed streams (stereo, mono, etc) - ChanCount(DataType type, uint32_t channels) - { - reset(); - set(type, channels); - } - - void reset() - { - for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) { - _counts[*t] = 0; - } - } - - void set(DataType t, uint32_t count) { assert(t != DataType::NIL); _counts[t] = count; } - uint32_t get(DataType t) const { assert(t != DataType::NIL); return _counts[t]; } - - inline uint32_t n_audio() const { return _counts[DataType::AUDIO]; } - inline void set_audio(uint32_t a) { _counts[DataType::AUDIO] = a; } - - inline uint32_t n_midi() const { return _counts[DataType::MIDI]; } - inline void set_midi(uint32_t m) { _counts[DataType::MIDI] = m; } - - uint32_t n_total() const - { - uint32_t ret = 0; - for (uint32_t i=0; i < DataType::num_types; ++i) - ret += _counts[i]; - - return ret; - } - - bool operator==(const ChanCount& other) const - { - for (uint32_t i=0; i < DataType::num_types; ++i) - if (_counts[i] != other._counts[i]) - return false; - - return true; - } - - bool operator!=(const ChanCount& other) const - { - return ! (*this == other); - } - - bool operator<(const ChanCount& other) const - { - for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) { - if (_counts[*t] > other._counts[*t]) { - return false; - } - } - return (*this != other); - } - - bool operator<=(const ChanCount& other) const - { - return ( (*this < other) || (*this == other) ); - } - - bool operator>(const ChanCount& other) const - { - for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) { - if (_counts[*t] < other._counts[*t]) { - return false; - } - } - return (*this != other); - } - - bool operator>=(const ChanCount& other) const - { - return ( (*this > other) || (*this == other) ); - } - - static const ChanCount INFINITE; - static const ChanCount ZERO; - -private: - - uint32_t _counts[DataType::num_types]; -}; - - -} // namespace ARDOUR - -#endif // __ardour_chan_count_h__ - diff --git a/libs/ardour/ardour/click.h b/libs/ardour/ardour/click.h deleted file mode 100644 index 60499b98da..0000000000 --- a/libs/ardour/ardour/click.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - Copyright (C) 2004 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_click_h__ -#define __ardour_click_h__ - -#include <ardour/io.h> - -namespace ARDOUR { - -class ClickIO : public IO -{ - public: - ClickIO (Session& s, const string& name, - - int input_min = -1, int input_max = -1, - - int output_min = -1, int output_max = -1) - : IO (s, name, input_min, input_max, output_min, output_max) {} - - ~ClickIO() {} - - protected: - uint32_t pans_required () const { return 1; } -}; - -}; /* namespace ARDOUR */ - -#endif /*__ardour_click_h__ */ diff --git a/libs/ardour/ardour/configuration.h b/libs/ardour/ardour/configuration.h deleted file mode 100644 index 7b890500d8..0000000000 --- a/libs/ardour/ardour/configuration.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - Copyright (C) 1999 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_configuration_h__ -#define __ardour_configuration_h__ - -#include <map> -#include <vector> - -#include <sys/types.h> -#include <string> - -#include <pbd/stateful.h> - -#include <ardour/types.h> -#include <ardour/utils.h> -#include <ardour/configuration_variable.h> - -class XMLNode; - -namespace ARDOUR { - -class Configuration : public PBD::Stateful -{ - public: - Configuration(); - virtual ~Configuration(); - - std::map<std::string,XMLNode> midi_ports; - - void map_parameters (sigc::slot<void,const char*> theSlot); - - int load_state (); - int save_state (); - - /// calls Stateful::*instant_xml methods using - /// ARDOUR::user_config_directory for the directory argument - void add_instant_xml (XMLNode&); - XMLNode * instant_xml (const std::string& str); - - int set_state (const XMLNode&); - XMLNode& get_state (void); - XMLNode& get_variables (sigc::slot<bool,ConfigVariableBase::Owner>, std::string which_node = "Config"); - void set_variables (const XMLNode&, ConfigVariableBase::Owner owner); - - void set_current_owner (ConfigVariableBase::Owner); - - XMLNode* control_protocol_state () { return _control_protocol_state; } - - sigc::signal<void,const char*> ParameterChanged; - - /* define accessor methods */ - -#undef CONFIG_VARIABLE -#undef CONFIG_VARIABLE_SPECIAL -#define CONFIG_VARIABLE(Type,var,name,value) \ - Type get_##var () const { return var.get(); } \ - bool set_##var (Type val) { bool ret = var.set (val, current_owner); if (ret) { ParameterChanged (name); } return ret; } -#define CONFIG_VARIABLE_SPECIAL(Type,var,name,value,mutator) \ - Type get_##var () const { return var.get(); } \ - bool set_##var (Type val) { bool ret = var.set (val, current_owner); if (ret) { ParameterChanged (name); } return ret; } -#include "ardour/configuration_vars.h" -#undef CONFIG_VARIABLE -#undef CONFIG_VARIABLE_SPECIAL - - private: - - /* declare variables */ - -#undef CONFIG_VARIABLE -#undef CONFIG_VARIABLE_SPECIAL -#define CONFIG_VARIABLE(Type,var,name,value) ConfigVariable<Type> var; -#define CONFIG_VARIABLE_SPECIAL(Type,var,name,value,mutator) ConfigVariableWithMutation<Type> var; -#include "ardour/configuration_vars.h" -#undef CONFIG_VARIABLE -#undef CONFIG_VARIABLE_SPECIAL - - ConfigVariableBase::Owner current_owner; - XMLNode* _control_protocol_state; - - XMLNode& state (sigc::slot<bool,ConfigVariableBase::Owner>); - bool save_config_options_predicate (ConfigVariableBase::Owner owner); -}; - -extern Configuration *Config; -extern gain_t speed_quietning; /* see comment in configuration.cc */ - -} // namespace ARDOUR - -#endif /* __ardour_configuration_h__ */ diff --git a/libs/ardour/ardour/configuration_variable.h b/libs/ardour/ardour/configuration_variable.h deleted file mode 100644 index a61283ecd0..0000000000 --- a/libs/ardour/ardour/configuration_variable.h +++ /dev/null @@ -1,184 +0,0 @@ -/* - Copyright (C) 2000-2007 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_configuration_variable_h__ -#define __ardour_configuration_variable_h__ - -#include <sstream> -#include <ostream> -#include <iostream> - -#include <pbd/xml++.h> - -namespace ARDOUR { - -class ConfigVariableBase { - public: - enum Owner { - Default = 0x1, - System = 0x2, - Config = 0x4, - Session = 0x8, - Interface = 0x10 - }; - - ConfigVariableBase (std::string str) : _name (str), _owner (Default) {} - virtual ~ConfigVariableBase() {} - - std::string name() const { return _name; } - Owner owner() const { return _owner; } - - virtual void add_to_node (XMLNode& node) = 0; - virtual bool set_from_node (const XMLNode& node, Owner owner) = 0; - - void show_stored_value (const std::string&); - static void set_show_stored_values (bool yn); - - protected: - std::string _name; - Owner _owner; - static bool show_stores; - - void notify (); - void miss (); -}; - -template<class T> -class ConfigVariable : public ConfigVariableBase -{ - public: - ConfigVariable (std::string str) : ConfigVariableBase (str) {} - ConfigVariable (std::string str, T val) : ConfigVariableBase (str), value (val) {} - - virtual bool set (T val, Owner owner = ARDOUR::ConfigVariableBase::Config) { - if (val == value) { - miss (); - return false; - } - value = val; - _owner = (ConfigVariableBase::Owner)(_owner |owner); - notify (); - return true; - } - - T get() const { - return value; - } - - void add_to_node (XMLNode& node) { - std::stringstream ss; - ss << value; - show_stored_value (ss.str()); - XMLNode* child = new XMLNode ("Option"); - child->add_property ("name", _name); - child->add_property ("value", ss.str()); - node.add_child_nocopy (*child); - } - - bool set_from_node (const XMLNode& node, Owner owner) { - - if (node.name() == "Config") { - - /* ardour.rc */ - - const XMLProperty* prop; - XMLNodeList nlist; - XMLNodeConstIterator niter; - XMLNode* child; - - nlist = node.children(); - - for (niter = nlist.begin(); niter != nlist.end(); ++niter) { - - child = *niter; - - if (child->name() == "Option") { - if ((prop = child->property ("name")) != 0) { - if (prop->value() == _name) { - if ((prop = child->property ("value")) != 0) { - std::stringstream ss; - ss << prop->value(); - ss >> value; - _owner = (ConfigVariableBase::Owner)(_owner |owner); - return true; - } - } - } - } - } - - } else if (node.name() == "Options") { - - /* session file */ - - XMLNodeList olist; - XMLNodeConstIterator oiter; - XMLNode* option; - const XMLProperty* opt_prop; - - olist = node.children(); - - for (oiter = olist.begin(); oiter != olist.end(); ++oiter) { - - option = *oiter; - - if (option->name() == _name) { - if ((opt_prop = option->property ("val")) != 0) { - std::stringstream ss; - ss << opt_prop->value(); - ss >> value; - _owner = (ConfigVariableBase::Owner)(_owner |owner); - return true; - } - } - } - } - - return false; - } - - protected: - virtual T get_for_save() { return value; } - T value; -}; - -template<class T> -class ConfigVariableWithMutation : public ConfigVariable<T> -{ - public: - ConfigVariableWithMutation (std::string name, T val, T (*m)(T)) - : ConfigVariable<T> (name, val), mutator (m) {} - - bool set (T val, ConfigVariableBase::Owner owner) { - if (unmutated_value != val) { - unmutated_value = val; - return ConfigVariable<T>::set (mutator (val), owner); - } - return false; - } - - protected: - virtual T get_for_save() { return unmutated_value; } - T unmutated_value; - T (*mutator)(T); -}; - -} - -#endif /* __ardour_configuration_variable_h__ */ diff --git a/libs/ardour/ardour/configuration_vars.h b/libs/ardour/ardour/configuration_vars.h deleted file mode 100644 index 4e2a14c07b..0000000000 --- a/libs/ardour/ardour/configuration_vars.h +++ /dev/null @@ -1,176 +0,0 @@ -/* - 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 deleted file mode 100644 index c61513e117..0000000000 --- a/libs/ardour/ardour/control_protocol_manager.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - Copyright (C) 2000-2007 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef ardour_control_protocol_manager_h -#define ardour_control_protocol_manager_h - -#include <string> -#include <list> - -#include <sigc++/sigc++.h> - -#include <glibmm/thread.h> - -#include <pbd/stateful.h> - -namespace ARDOUR { - -class ControlProtocol; -class ControlProtocolDescriptor; -class Session; - -struct ControlProtocolInfo { - ControlProtocolDescriptor* descriptor; - ControlProtocol* protocol; - std::string name; - std::string path; - bool requested; - bool mandatory; - bool supports_feedback; - XMLNode* state; - - ControlProtocolInfo() : descriptor (0), protocol (0), state (0) {} - ~ControlProtocolInfo() { if (state) { delete state; } } -}; - - class ControlProtocolManager : public sigc::trackable, public PBD::Stateful -{ - public: - ControlProtocolManager (); - ~ControlProtocolManager (); - - static ControlProtocolManager& instance() { return *_instance; } - - void set_session (Session&); - void discover_control_protocols (); - void foreach_known_protocol (sigc::slot<void,const ControlProtocolInfo*>); - void load_mandatory_protocols (); - - ControlProtocol* instantiate (ControlProtocolInfo&); - int teardown (ControlProtocolInfo&); - - std::list<ControlProtocolInfo*> control_protocol_info; - - static const std::string state_node_name; - - void set_protocol_states (const XMLNode&); - - int set_state (const XMLNode&); - XMLNode& get_state (void); - - private: - static ControlProtocolManager* _instance; - - Session* _session; - Glib::Mutex protocols_lock; - std::list<ControlProtocol*> control_protocols; - - void drop_session (); - - int control_protocol_discover (std::string path); - ControlProtocolDescriptor* get_descriptor (std::string path); - ControlProtocolInfo* cpi_by_name (std::string); -}; - -} // namespace - -#endif // ardour_control_protocol_manager_h diff --git a/libs/ardour/ardour/control_protocol_search_path.h b/libs/ardour/ardour/control_protocol_search_path.h deleted file mode 100644 index f9a8103c0c..0000000000 --- a/libs/ardour/ardour/control_protocol_search_path.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - Copyright (C) 2007 Tim Mayberry - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef ARDOUR_CONTROL_PROTOCOL_SEARCH_PATH_INCLUDED -#define ARDOUR_CONTROL_PROTOCOL_SEARCH_PATH_INCLUDED - -#include <pbd/search_path.h> - -namespace ARDOUR { - - using PBD::SearchPath; - - /** - * return a SearchPath containing directories in which to look for - * control surface plugins. - * - * If ARDOUR_SURFACES_PATH is defined then the SearchPath returned - * will contain only those directories specified in it, otherwise it will - * contain the user and system directories which may contain control - * surface plugins. - */ - SearchPath control_protocol_search_path (); - -} // namespace ARDOUR - -#endif diff --git a/libs/ardour/ardour/coreaudiosource.h b/libs/ardour/ardour/coreaudiosource.h deleted file mode 100644 index d7282b35bd..0000000000 --- a/libs/ardour/ardour/coreaudiosource.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - Copyright (C) 2000 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __coreaudio_source_h__ -#define __coreaudio_source_h__ - -#include <appleutility/CAAudioFile.h> -#include <ardour/audiofilesource.h> - -namespace ARDOUR { - -class CoreAudioSource : public AudioFileSource { - public: - CoreAudioSource (ARDOUR::Session&, const XMLNode&); - CoreAudioSource (ARDOUR::Session&, const string& path, int chn, Flag); - ~CoreAudioSource (); - - float sample_rate() const; - int update_header (nframes_t when, struct tm&, time_t); - - int flush_header () {return 0;}; - void set_header_timeline_position () {}; - - static int get_soundfile_info (string path, SoundFileInfo& _info, string& error_msg); - - protected: - nframes_t read_unlocked (Sample *dst, nframes_t start, nframes_t cnt) const; - nframes_t write_unlocked (Sample *dst, nframes_t cnt) { return 0; } - - private: - mutable CAAudioFile af; - uint16_t n_channels; - - void init (); - int safe_read (Sample*, nframes_t start, nframes_t cnt, AudioBufferList&) const; -}; - -}; /* namespace ARDOUR */ - -#endif /* __coreaudio_source_h__ */ - diff --git a/libs/ardour/ardour/crossfade.h b/libs/ardour/ardour/crossfade.h deleted file mode 100644 index 9ba3689e82..0000000000 --- a/libs/ardour/ardour/crossfade.h +++ /dev/null @@ -1,179 +0,0 @@ -/* - Copyright (C) 2000 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_overlap_h__ -#define __ardour_overlap_h__ - -#include <vector> -#include <algorithm> -#include <boost/shared_ptr.hpp> - -#include <sigc++/signal.h> - -#include <pbd/undo.h> -#include <pbd/statefuldestructible.h> - -#include <ardour/ardour.h> -#include <ardour/curve.h> -#include <ardour/audioregion.h> -#include <ardour/crossfade_compare.h> - -namespace ARDOUR { - -class AudioRegion; -class Playlist; - -class Crossfade : public ARDOUR::AudioRegion -{ - public: - - class NoCrossfadeHere: std::exception { - public: - virtual const char *what() const throw() { return "no crossfade should be constructed here"; } - }; - - /* constructor for "fixed" xfades at each end of an internal overlap */ - - Crossfade (boost::shared_ptr<ARDOUR::AudioRegion> in, boost::shared_ptr<ARDOUR::AudioRegion> out, - nframes_t position, - nframes_t initial_length, - AnchorPoint); - - /* constructor for xfade between two regions that are overlapped in any way - except the "internal" case. - */ - - Crossfade (boost::shared_ptr<ARDOUR::AudioRegion> in, boost::shared_ptr<ARDOUR::AudioRegion> out, CrossfadeModel, bool active); - - - /* copy constructor to copy a crossfade with new regions. used (for example) - when a playlist copy is made - */ - Crossfade (boost::shared_ptr<Crossfade>, boost::shared_ptr<ARDOUR::AudioRegion>, boost::shared_ptr<ARDOUR::AudioRegion>); - - /* the usual XML constructor */ - - Crossfade (const Playlist&, XMLNode&); - virtual ~Crossfade(); - - bool operator== (const ARDOUR::Crossfade&); - - XMLNode& get_state (void); - int set_state (const XMLNode&); - - boost::shared_ptr<ARDOUR::AudioRegion> in() const { return _in; } - boost::shared_ptr<ARDOUR::AudioRegion> out() const { return _out; } - - nframes_t read_at (Sample *buf, Sample *mixdown_buffer, - float *gain_buffer, nframes_t position, nframes_t cnt, - uint32_t chan_n, - nframes_t read_frames = 0, - nframes_t skip_frames = 0) const; - - bool refresh (); - - uint32_t upper_layer () const { - return std::max (_in->layer(), _out->layer()); - } - - uint32_t lower_layer () const { - return std::min (_in->layer(), _out->layer()); - } - - bool involves (boost::shared_ptr<ARDOUR::AudioRegion> region) const { - return _in == region || _out == region; - } - - bool involves (boost::shared_ptr<ARDOUR::AudioRegion> a, boost::shared_ptr<ARDOUR::AudioRegion> b) const { - return (_in == a && _out == b) || (_in == b && _out == a); - } - - nframes_t overlap_length() const; - - void invalidate(); - - sigc::signal<void,boost::shared_ptr<Region> > Invalidated; - sigc::signal<void,Change> StateChanged; - - bool covers (nframes_t frame) const { - return _position <= frame && frame < _position + _length; - } - - OverlapType coverage (nframes_t start, nframes_t end) const; - - static void set_buffer_size (nframes_t); - - bool active () const { return _active; } - void set_active (bool yn); - - bool following_overlap() const { return _follow_overlap; } - bool can_follow_overlap() const; - void set_follow_overlap (bool yn); - - AutomationList& fade_in() { return _fade_in; } - AutomationList& fade_out() { return _fade_out; } - - nframes_t set_length (nframes_t); - - bool is_dependent() const { return true; } - bool depends_on (boost::shared_ptr<Region> other) const { - return other == _in || other == _out; - } - - static nframes_t short_xfade_length() { return _short_xfade_length; } - static void set_short_xfade_length (nframes_t n); - - static Change ActiveChanged; - static Change FollowOverlapChanged; - - private: - friend struct CrossfadeComparePtr; - friend class AudioPlaylist; - - static nframes_t _short_xfade_length; - - boost::shared_ptr<ARDOUR::AudioRegion> _in; - boost::shared_ptr<ARDOUR::AudioRegion> _out; - bool _active; - bool _in_update; - OverlapType overlap_type; - AnchorPoint _anchor_point; - bool _follow_overlap; - bool _fixed; - int32_t layer_relation; - - - mutable AutomationList _fade_in; - mutable AutomationList _fade_out; - - static Sample* crossfade_buffer_out; - static Sample* crossfade_buffer_in; - - void initialize (); - int compute (boost::shared_ptr<ARDOUR::AudioRegion>, boost::shared_ptr<ARDOUR::AudioRegion>, CrossfadeModel); - bool update (); - - protected: - nframes_t read_raw_internal (Sample*, nframes_t, nframes_t) const; -}; - - -} // namespace ARDOUR - -#endif /* __ardour_overlap_h__ */ diff --git a/libs/ardour/ardour/crossfade_compare.h b/libs/ardour/ardour/crossfade_compare.h deleted file mode 100644 index b92806a6bb..0000000000 --- a/libs/ardour/ardour/crossfade_compare.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - 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 deleted file mode 100644 index 433b00a270..0000000000 --- a/libs/ardour/ardour/curve.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - Copyright (C) 2001-2007 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_curve_h__ -#define __ardour_curve_h__ - -#include <sys/types.h> -#include <boost/utility.hpp> -#include <sigc++/signal.h> -#include <glibmm/thread.h> -#include <pbd/undo.h> -#include <list> -#include <algorithm> -#include <ardour/automation_event.h> - -namespace ARDOUR { - -class Curve : public boost::noncopyable -{ - public: - Curve (const AutomationList& al); - - bool rt_safe_get_vector (double x0, double x1, float *arg, int32_t veclen); - void get_vector (double x0, double x1, float *arg, int32_t veclen); - - void solve (); - - private: - double unlocked_eval (double where); - double multipoint_eval (double x); - - void _get_vector (double x0, double x1, float *arg, int32_t veclen); - - void on_list_dirty() { _dirty = true; } - - bool _dirty; - const AutomationList& _list; -}; - -} // namespace ARDOUR - -extern "C" { - void curve_get_vector_from_c (void *arg, double, double, float*, int32_t); -} - -#endif /* __ardour_curve_h__ */ diff --git a/libs/ardour/ardour/cycle_timer.h b/libs/ardour/ardour/cycle_timer.h deleted file mode 100644 index 4e1a50e602..0000000000 --- a/libs/ardour/ardour/cycle_timer.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - Copyright (C) 2002 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_cycle_timer_h__ -#define __ardour_cycle_timer_h__ - -#include <string> -#include <iostream> - -#include <ardour/cycles.h> - -class CycleTimer { - private: - static float cycles_per_usec; - cycles_t _entry; - cycles_t _exit; - std::string _name; - - public: - CycleTimer(std::string name) : _name (name){ - if (cycles_per_usec == 0) { - cycles_per_usec = get_mhz (); - } - _entry = get_cycles(); - } - ~CycleTimer() { - _exit = get_cycles(); - std::cerr << _name << ": " << (float) (_exit - _entry) / cycles_per_usec << " (" << _entry << ", " << _exit << ')' << endl; - } - - static float get_mhz (); -}; - -#endif /* __ardour_cycle_timer_h__ */ diff --git a/libs/ardour/ardour/cycles.h b/libs/ardour/ardour/cycles.h deleted file mode 100644 index 0d1ac154dd..0000000000 --- a/libs/ardour/ardour/cycles.h +++ /dev/null @@ -1,221 +0,0 @@ -/* - Copyright (C) 2001 Paul Davis - Code derived from various headers from the Linux kernel - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_cycles_h__ -#define __ardour_cycles_h__ - -#include <stdint.h> - -#if defined(__i386__) || defined(__x86_64__) - -/* - * Standard way to access the cycle counter on i586+ CPUs. - * Currently only used on SMP. - * - * If you really have a SMP machine with i486 chips or older, - * compile for that, and this will just always return zero. - * That's ok, it just means that the nicer scheduling heuristics - * won't work for you. - * - * We only use the low 32 bits, and we'd simply better make sure - * that we reschedule before that wraps. Scheduling at least every - * four billion cycles just basically sounds like a good idea, - * regardless of how fast the machine is. - */ -typedef uint64_t cycles_t; - -extern cycles_t cacheflush_time; - -#define rdtscll(val) \ - __asm__ __volatile__("rdtsc" : "=A" (val)) - -static inline cycles_t get_cycles (void) -{ - uint32_t long ret; - - rdtscll(ret); - return ret; -} - -#elif defined(__powerpc__) - -#define CPU_FTR_601 0x00000100 - -typedef uint32_t cycles_t; - -/* - * For the "cycle" counter we use the timebase lower half. - * Currently only used on SMP. - */ - -extern cycles_t cacheflush_time; - -static inline cycles_t get_cycles(void) -{ - cycles_t ret = 0; - - __asm__ __volatile__( - "98: mftb %0\n" - "99:\n" - ".section __ftr_fixup,\"a\"\n" - " .long %1\n" - " .long 0\n" - " .long 98b\n" - " .long 99b\n" - ".previous" - : "=r" (ret) : "i" (CPU_FTR_601)); - return ret; -} - -#elif defined(__ia64__) -/* ia64 */ - -typedef uint32_t cycles_t; -static inline cycles_t -get_cycles (void) -{ - cycles_t ret; - __asm__ __volatile__ ("mov %0=ar.itc" : "=r"(ret)); - return ret; -} - -#elif defined(__alpha__) -/* alpha */ - -/* - * Standard way to access the cycle counter. - * Currently only used on SMP for scheduling. - * - * Only the low 32 bits are available as a continuously counting entity. - * But this only means we'll force a reschedule every 8 seconds or so, - * which isn't an evil thing. - */ - -typedef uint32_t cycles_t; -static inline cycles_t get_cycles (void) -{ - cycles_t ret; - __asm__ __volatile__ ("rpcc %0" : "=r"(ret)); - return ret; -} - -#elif defined(__s390__) -/* s390 */ - -typedef uint32_t long cycles_t; -static inline cycles_t get_cycles(void) -{ - cycles_t cycles; - __asm__("stck 0(%0)" : : "a" (&(cycles)) : "memory", "cc"); - return cycles >> 2; -} - -#elif defined(__hppa__) -/* hppa/parisc */ - -#define mfctl(reg) ({ \ - uint32_t cr; \ - __asm__ __volatile__( \ - "mfctl " #reg ",%0" : \ - "=r" (cr) \ - ); \ - cr; \ -}) - -typedef uint32_t cycles_t; -static inline cycles_t get_cycles (void) -{ - return mfctl(16); -} - -#elif defined(__mips__) -/* mips/mipsel */ - -/* - * Standard way to access the cycle counter. - * Currently only used on SMP for scheduling. - * - * Only the low 32 bits are available as a continuously counting entity. - * But this only means we'll force a reschedule every 8 seconds or so, - * which isn't an evil thing. - * - * We know that all SMP capable CPUs have cycle counters. - */ - -#define __read_32bit_c0_register(source, sel) \ -({ int __res; \ - if (sel == 0) \ - __asm__ __volatile__( \ - "mfc0\t%0, " #source "\n\t" \ - : "=r" (__res)); \ - else \ - __asm__ __volatile__( \ - ".set\tmips32\n\t" \ - "mfc0\t%0, " #source ", " #sel "\n\t" \ - ".set\tmips0\n\t" \ - : "=r" (__res)); \ - __res; \ -}) - -/* #define CP0_COUNT $9 */ -#define read_c0_count() __read_32bit_c0_register($9, 0) - -typedef uint32_t cycles_t; -static inline cycles_t get_cycles (void) -{ - return read_c0_count(); -} - -/* begin mach */ -#elif defined(__APPLE__) - -#include <CoreAudio/HostTime.h> - -typedef UInt64 cycles_t; -static inline cycles_t get_cycles (void) -{ - UInt64 time = AudioGetCurrentHostTime(); - return AudioConvertHostTimeToNanos(time); -} -/* end mach */ - -#else - -/* debian: sparc, arm, m68k */ - -#warning You are compiling libardour on a platform for which ardour/cycles.h needs work - -#include <sys/time.h> - -typedef long cycles_t; - -extern cycles_t cacheflush_time; - -static inline cycles_t get_cycles(void) -{ - struct timeval tv; - gettimeofday (&tv, NULL); - - return tv.tv_usec; -} - -#endif - -#endif /* __ardour_cycles_h__ */ diff --git a/libs/ardour/ardour/dB.h b/libs/ardour/ardour/dB.h deleted file mode 100644 index b67e581067..0000000000 --- a/libs/ardour/ardour/dB.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - Copyright (C) 2001 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_dB_h__ -#define __ardour_dB_h__ - -#include <pbd/fastlog.h> - -static inline float dB_to_coefficient (float dB) { - return dB > -318.8f ? pow (10.0f, dB * 0.05f) : 0.0f; -} - -static inline float coefficient_to_dB (float coeff) { - return 20.0f * fast_log10 (coeff); -} - -#endif /* __ardour_dB_h__ */ diff --git a/libs/ardour/ardour/data_type.h b/libs/ardour/ardour/data_type.h deleted file mode 100644 index 854f52acba..0000000000 --- a/libs/ardour/ardour/data_type.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - Copyright (C) 2006 Paul Davis - Author: Dave Robillard - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the Free - Software Foundation; either version 2 of the License, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifndef __ardour_data_type_h__ -#define __ardour_data_type_h__ - -#include <string> -#include <jack/jack.h> - -namespace ARDOUR { - - -/** A type of Data Ardour is capable of processing. - * - * The majority of this class is dedicated to conversion to and from various - * other type representations, simple comparison between then, etc. This code - * is deliberately 'ugly' so other code doesn't have to be. - */ -class DataType -{ -public: - /** Numeric symbol for this DataType. - * - * Castable to int for use as an array index (e.g. by ChanCount). - * Note this means NIL is (ntypes-1) and guaranteed to change when - * types are added, so this number is NOT suitable for serialization, - * network, or binary anything. - * - * WARNING: The number of non-NIL entries here must match num_types. - */ - enum Symbol { - AUDIO = 0, - MIDI = 1, - NIL = 2, - }; - - /** Number of types (not including NIL). - * WARNING: make sure this matches Symbol! - */ - static const uint32_t num_types = 2; - - DataType(const Symbol& symbol) - : _symbol(symbol) - {} - - /** Construct from a string (Used for loading from XML and Ports) - * The string can be as in an XML file (eg "audio" or "midi"), or a - * Jack type string (from jack_port_type) */ - DataType(const std::string& str) - : _symbol(NIL) { - if (str == "audio" || str == JACK_DEFAULT_AUDIO_TYPE) - _symbol = AUDIO; - else if (str == "midi" || str == JACK_DEFAULT_MIDI_TYPE) - _symbol = MIDI; - } - - /** Get the Jack type this DataType corresponds to */ - const char* to_jack_type() const { - switch (_symbol) { - case AUDIO: return JACK_DEFAULT_AUDIO_TYPE; - case MIDI: return JACK_DEFAULT_MIDI_TYPE; - default: return ""; - } - } - - /** Inverse of the from-string constructor */ - const char* to_string() const { - switch (_symbol) { - case AUDIO: return "audio"; - case MIDI: return "midi"; - default: return "unknown"; // reeeally shouldn't ever happen - } - } - - inline operator uint32_t() const { return (uint32_t)_symbol; } - - /** DataType iterator, for writing generic loops that iterate over all - * available types. - */ - class iterator { - public: - - iterator(uint32_t index) : _index(index) {} - - DataType operator*() { return DataType((Symbol)_index); } - iterator& operator++() { ++_index; return *this; } // yes, prefix only - bool operator==(const iterator& other) { return (_index == other._index); } - bool operator!=(const iterator& other) { return (_index != other._index); } - - private: - friend class DataType; - - uint32_t _index; - }; - - static iterator begin() { return iterator(0); } - static iterator end() { return iterator(num_types); } - - bool operator==(const Symbol symbol) { return (_symbol == symbol); } - bool operator!=(const Symbol symbol) { return (_symbol != symbol); } - - bool operator==(const DataType other) { return (_symbol == other._symbol); } - bool operator!=(const DataType other) { return (_symbol != other._symbol); } - -private: - Symbol _symbol; // could be const if not for the string constructor -}; - - - -} // namespace ARDOUR - -#endif // __ardour_data_type_h__ - diff --git a/libs/ardour/ardour/directory_names.h b/libs/ardour/ardour/directory_names.h deleted file mode 100644 index 8fabe025d1..0000000000 --- a/libs/ardour/ardour/directory_names.h +++ /dev/null @@ -1,23 +0,0 @@ - -#ifndef __ardour_directory_names_h__ -#define __ardour_directory_names_h__ - -#include <string> - -namespace ARDOUR { - -extern const char* const old_sound_dir_name; -extern const char* const sound_dir_name; -extern const char* const midi_dir_name; -extern const char* const dead_sound_dir_name; -extern const char* const dead_midi_dir_name; -extern const char* const interchange_dir_name; -extern const char* const peak_dir_name; -extern const char* const export_dir_name; -extern const char* const templates_dir_name; -extern const char* const surfaces_dir_name; -extern const char* const user_config_dir_name; - -}; - -#endif diff --git a/libs/ardour/ardour/diskstream.h b/libs/ardour/ardour/diskstream.h deleted file mode 100644 index 824d864663..0000000000 --- a/libs/ardour/ardour/diskstream.h +++ /dev/null @@ -1,308 +0,0 @@ -/* - Copyright (C) 2000-2006 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_diskstream_h__ -#define __ardour_diskstream_h__ - -#include <sigc++/signal.h> - -#include <cmath> -#include <string> -#include <queue> -#include <map> -#include <vector> - -#include <time.h> - -#include <pbd/fastlog.h> -#include <pbd/ringbufferNPT.h> -#include <pbd/stateful.h> -#include <pbd/statefuldestructible.h> - -#include <ardour/ardour.h> -#include <ardour/configuration.h> -#include <ardour/session.h> -#include <ardour/route_group.h> -#include <ardour/route.h> -#include <ardour/port.h> -#include <ardour/utils.h> - -struct tm; - -namespace ARDOUR { - -class AudioEngine; -class Send; -class Session; -class Playlist; -class IO; - -class Diskstream : public SessionObject -{ - public: - enum Flag { - Recordable = 0x1, - Hidden = 0x2, - Destructive = 0x4 - }; - - Diskstream (Session &, const string& name, Flag f = Recordable); - Diskstream (Session &, const XMLNode&); - virtual ~Diskstream(); - - bool set_name (const string& str); - - ARDOUR::IO* io() const { return _io; } - void set_io (ARDOUR::IO& io); - - virtual float playback_buffer_load() const = 0; - virtual float capture_buffer_load() const = 0; - - void set_flag (Flag f) { _flags = Flag (_flags | f); } - void unset_flag (Flag f) { _flags = Flag (_flags & ~f); } - - AlignStyle alignment_style() const { return _alignment_style; } - void set_align_style (AlignStyle); - void set_persistent_align_style (AlignStyle a) { _persistent_alignment_style = a; } - - nframes_t roll_delay() const { return _roll_delay; } - void set_roll_delay (nframes_t); - - bool record_enabled() const { return g_atomic_int_get (&_record_enabled); } - virtual void set_record_enabled (bool yn) = 0; - - bool destructive() const { return _flags & Destructive; } - virtual int set_destructive (bool yn) { return -1; } - virtual bool can_become_destructive (bool& requires_bounce) const { return false; } - - bool hidden() const { return _flags & Hidden; } - bool recordable() const { return _flags & Recordable; } - bool reversed() const { return _actual_speed < 0.0f; } - double speed() const { return _visible_speed; } - - virtual void punch_in() {} - virtual void punch_out() {} - - void set_speed (double); - void non_realtime_set_speed (); - virtual void non_realtime_locate (nframes_t location) {}; - virtual void playlist_modified (); - - boost::shared_ptr<Playlist> playlist () { return _playlist; } - - virtual int use_playlist (boost::shared_ptr<Playlist>); - virtual int use_new_playlist () = 0; - virtual int use_copy_playlist () = 0; - - nframes_t current_capture_start() const { return capture_start_frame; } - nframes_t current_capture_end() const { return capture_start_frame + capture_captured; } - nframes_t get_capture_start_frame (uint32_t n=0); - nframes_t get_captured_frames (uint32_t n=0); - - ChanCount n_channels() { return _n_channels; } - - static nframes_t disk_io_frames() { return disk_io_chunk_frames; } - static void set_disk_io_chunk_frames (uint32_t n) { disk_io_chunk_frames = n; } - - /* Stateful */ - virtual XMLNode& get_state(void) = 0; - virtual int set_state(const XMLNode& node) = 0; - - virtual void monitor_input (bool) {} - - nframes_t capture_offset() const { return _capture_offset; } - virtual void set_capture_offset (); - - bool slaved() const { return _slaved; } - void set_slaved(bool yn) { _slaved = yn; } - - int set_loop (Location *loc); - - std::list<boost::shared_ptr<Region> >& last_capture_regions () { return _last_capture_regions; } - - void handle_input_change (IOChange, void *src); - - void remove_region_from_last_capture (boost::weak_ptr<Region> wregion); - - sigc::signal<void> RecordEnableChanged; - sigc::signal<void> SpeedChanged; - sigc::signal<void> ReverseChanged; - sigc::signal<void> PlaylistChanged; - sigc::signal<void> AlignmentStyleChanged; - sigc::signal<void,Location *> LoopSet; - - static sigc::signal<void> DiskOverrun; - static sigc::signal<void> DiskUnderrun; - - protected: - friend class Session; - - /* the Session is the only point of access for these because they require - * that the Session is "inactive" while they are called. - */ - - virtual void set_pending_overwrite (bool) = 0; - virtual int overwrite_existing_buffers () = 0; - virtual void set_block_size (nframes_t) = 0; - virtual int internal_playback_seek (nframes_t distance) = 0; - virtual int can_internal_playback_seek (nframes_t distance) = 0; - virtual int rename_write_sources () = 0; - virtual void reset_write_sources (bool, bool force = false) = 0; - virtual void non_realtime_input_change () = 0; - - uint32_t read_data_count() const { return _read_data_count; } - uint32_t write_data_count() const { return _write_data_count; } - - protected: - friend class Auditioner; - virtual int seek (nframes_t which_sample, bool complete_refill = false) = 0; - - protected: - friend class Track; - - virtual void prepare (); - virtual int process (nframes_t transport_frame, nframes_t nframes, nframes_t offset, bool can_record, bool rec_monitors_input) = 0; - virtual bool commit (nframes_t nframes) = 0; - virtual void recover (); /* called if commit will not be called, but process was */ - - //private: - - enum TransitionType { - CaptureStart = 0, - CaptureEnd - }; - - struct CaptureTransition { - TransitionType type; - nframes_t capture_val; ///< The start or end file frame position - }; - - /* The two central butler operations */ - virtual int do_flush (Session::RunContext context, bool force = false) = 0; - virtual int do_refill () = 0; - - /** For non-butler contexts (allocates temporary working buffers) */ - virtual int do_refill_with_alloc() = 0; - - /* XXX fix this redundancy ... */ - - virtual void playlist_changed (Change); - virtual void playlist_deleted (boost::weak_ptr<Playlist>); - - virtual void transport_stopped (struct tm&, time_t, bool abort) = 0; - virtual void transport_looped (nframes_t transport_frame) = 0; - - struct CaptureInfo { - uint32_t start; - uint32_t frames; - }; - - virtual void init (Flag); - - virtual int use_new_write_source (uint32_t n=0) = 0; - - virtual int find_and_use_playlist (const string&) = 0; - - virtual void allocate_temporary_buffers () = 0; - - virtual bool realtime_set_speed (double, bool global_change); - - std::list<boost::shared_ptr<Region> > _last_capture_regions; - - virtual int use_pending_capture_data (XMLNode& node) = 0; - - virtual void get_input_sources () = 0; - virtual void check_record_status (nframes_t transport_frame, nframes_t nframes, bool can_record) = 0; - virtual void set_align_style_from_io() {} - virtual void setup_destructive_playlist () {} - virtual void use_destructive_playlist () {} - - static nframes_t disk_io_chunk_frames; - std::vector<CaptureInfo*> capture_info; - Glib::Mutex capture_info_lock; - - uint32_t i_am_the_modifier; - - ARDOUR::IO* _io; - ChanCount _n_channels; - - boost::shared_ptr<Playlist> _playlist; - - mutable gint _record_enabled; - double _visible_speed; - double _actual_speed; - /* items needed for speed change logic */ - bool _buffer_reallocation_required; - bool _seek_required; - - bool force_refill; - nframes_t capture_start_frame; - nframes_t capture_captured; - bool was_recording; - nframes_t adjust_capture_position; - nframes_t _capture_offset; - nframes_t _roll_delay; - nframes_t first_recordable_frame; - nframes_t last_recordable_frame; - int last_possibly_recording; - AlignStyle _alignment_style; - bool _scrubbing; - bool _slaved; - bool _processed; - Location* loop_location; - nframes_t overwrite_frame; - off_t overwrite_offset; - bool pending_overwrite; - bool overwrite_queued; - IOChange input_change_pending; - nframes_t wrap_buffer_size; - nframes_t speed_buffer_size; - - uint64_t last_phase; - uint64_t phi; - uint64_t target_phi; - - nframes_t file_frame; - nframes_t playback_sample; - nframes_t playback_distance; - bool commit_should_unlock; - - uint32_t _read_data_count; - uint32_t _write_data_count; - - bool in_set_state; - AlignStyle _persistent_alignment_style; - bool first_input_change; - - Glib::Mutex state_lock; - - nframes_t scrub_start; - nframes_t scrub_buffer_size; - nframes_t scrub_offset; - - sigc::connection ports_created_c; - sigc::connection plmod_connection; - sigc::connection plgone_connection; - - Flag _flags; -}; - -}; /* namespace ARDOUR */ - -#endif /* __ardour_diskstream_h__ */ diff --git a/libs/ardour/ardour/export.h b/libs/ardour/ardour/export.h deleted file mode 100644 index 141786873d..0000000000 --- a/libs/ardour/ardour/export.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - Copyright (C) 2000-2007 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_export_h__ -#define __ardour_export_h__ - -#include <map> -#include <vector> -#include <string> - -#include <sigc++/signal.h> - -#include <sndfile.h> -#include <samplerate.h> - -#include <ardour/ardour.h> -#include <ardour/gdither.h> - -using std::map; -using std::vector; -using std::string; -using std::pair; - -namespace ARDOUR -{ - class Port; - - typedef pair<Port *, uint32_t> PortChannelPair; - typedef map<uint32_t, vector<PortChannelPair> > ExportPortMap; - - struct ExportSpecification : public SF_INFO, public sigc::trackable { - - ExportSpecification(); - ~ExportSpecification (); - - void init (); - void clear (); - - - int prepare (nframes_t blocksize, nframes_t frame_rate); - - int process (nframes_t nframes); - - /* set by the user */ - - string path; - nframes_t sample_rate; - - int src_quality; - SNDFILE* out; - uint32_t channels; - ExportPortMap port_map; - nframes_t start_frame; - nframes_t end_frame; - GDitherType dither_type; - bool do_freewheel; - - /* used exclusively during export */ - - nframes_t frame_rate; - GDither dither; - float* dataF; - float* dataF2; - float* leftoverF; - nframes_t leftover_frames; - nframes_t max_leftover_frames; - void* output_data; - nframes_t out_samples_max; - uint32_t sample_bytes; - uint32_t data_width; - - nframes_t total_frames; - SF_INFO sfinfo; - SRC_DATA src_data; - SRC_STATE* src_state; - nframes_t pos; - - sigc::connection freewheel_connection; - - /* shared between UI thread and audio thread */ - - volatile float progress; /* audio thread sets this */ - volatile bool stop; /* UI sets this */ - volatile bool running; /* audio thread sets to false when export is done */ - - int status; - }; - -} // namespace ARDOUR - -#endif /* __ardour_export_h__ */ diff --git a/libs/ardour/ardour/filename_extensions.h b/libs/ardour/ardour/filename_extensions.h deleted file mode 100644 index 3e280d6326..0000000000 --- a/libs/ardour/ardour/filename_extensions.h +++ /dev/null @@ -1,17 +0,0 @@ - -#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 deleted file mode 100644 index 12995bd818..0000000000 --- a/libs/ardour/ardour/filesystem_paths.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - Copyright (C) 2007 Tim Mayberry - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef ARDOUR_FILESYSTEM_PATHS_INCLUDED -#define ARDOUR_FILESYSTEM_PATHS_INCLUDED - -#include <pbd/filesystem.h> -#include <pbd/search_path.h> - -namespace ARDOUR { - - using namespace PBD; - - /** - * @return the path to the directory used to store user specific ardour - * configuration files. - */ - sys::path user_config_directory (); - - /** - * @return the path to the directory that contains the system wide ardour - * modules. - */ - sys::path ardour_module_directory (); - - SearchPath ardour_search_path (); - - SearchPath system_config_search_path (); - - SearchPath system_data_search_path (); - -} // namespace ARDOUR - -#endif diff --git a/libs/ardour/ardour/filter.h b/libs/ardour/ardour/filter.h deleted file mode 100644 index b659873bdb..0000000000 --- a/libs/ardour/ardour/filter.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - Copyright (C) 2007 Paul Davis - Author: Dave Robillard - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_filter_h__ -#define __ardour_filter_h__ - -#include <vector> -#include <ardour/region.h> - -namespace ARDOUR { - -class Region; -class Session; - -class Filter { - - public: - virtual ~Filter() {} - - virtual int run (boost::shared_ptr<ARDOUR::Region>) = 0; - std::vector<boost::shared_ptr<ARDOUR::Region> > results; - - protected: - Filter (ARDOUR::Session& s) : session(s) {} - - int make_new_sources (boost::shared_ptr<ARDOUR::Region>, ARDOUR::SourceList&, std::string suffix = ""); - int finish (boost::shared_ptr<ARDOUR::Region>, ARDOUR::SourceList&, std::string region_name = ""); - - ARDOUR::Session& session; -}; - -} /* namespace */ - -#endif /* __ardour_filter_h__ */ diff --git a/libs/ardour/ardour/gain.h b/libs/ardour/ardour/gain.h deleted file mode 100644 index e57cfdc0d7..0000000000 --- a/libs/ardour/ardour/gain.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - 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 deleted file mode 100644 index 67efcc3583..0000000000 --- a/libs/ardour/ardour/gdither.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) 2002 Steve Harris <steve@plugin.org.uk> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#ifndef GDITHER_H -#define GDITHER_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include "gdither_types.h" - -/* Create and initialise a state structure, takes a dither type, a number of - * channels and a bit depth as input - * - * The Dither type is one of - * - * GDitherNone - straight nearest neighbour rounding. Theres no pressing - * reason to do this at 8 or 16 bit, but you might want to at 24, for some - * reason. At the lest it will save you writing int->float conversion code, - * which is arder than it sounds. - * - * GDitherRect - mathematically most accurate, lowest noise floor, but not - * that good for audio. It is the fastest though. - * - * GDitherTri - a happy medium between Rectangular and Shaped, reasonable - * noise floor, not too obvious, quite fast. - * - * GDitherShaped - should have the least audible impact, but has the highest - * noise floor, fairly CPU intensive. Not advisible if your going to apply - * any frequency manipulation afterwards. - * - * channels, sets the number of channels in the output data, output data will - * be written interleaved into the area given to gdither_run(). Set to 1 - * if you are not working with interleaved buffers. - * - * bit depth, sets the bit width of the output sample data, it can be one of: - * - * GDither8bit - 8 bit unsiged - * GDither16bit - 16 bit signed - * GDither32bit - 24+bits in upper bits of a 32 bit word - * GDitherFloat - IEEE floating point (32bits) - * GDitherDouble - Double precision IEEE floating point (64bits) - * - * dither_depth, set the number of bits before the signal will be truncated to, - * eg. 16 will produce an output stream with 16bits-worth of signal. Setting to - * zero or greater than the width of the output format will dither to the - * maximum precision allowed by the output format. - */ -GDither gdither_new(GDitherType type, uint32_t channels, - - GDitherSize bit_depth, int dither_depth); - -/* Frees memory used by gdither_new. - */ -void gdither_free(GDither s); - -/* Applies dithering to the supplied signal. - * - * channel is the channel number you are processing (0 - channles-1), length is - * the length of the input, in samples, x is the input samples (float), y is - * where the output samples will be written, it should have the approaprate - * type for the chosen bit depth - */ -void gdither_runf(GDither s, uint32_t channel, uint32_t length, - float *x, void *y); - -/* see gdither_runf, vut input argument is double format */ -void gdither_run(GDither s, uint32_t channel, uint32_t length, - double *x, void *y); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/libs/ardour/ardour/gdither_types.h b/libs/ardour/ardour/gdither_types.h deleted file mode 100644 index bcc0097d7f..0000000000 --- a/libs/ardour/ardour/gdither_types.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2002 Steve Harris <steve@plugin.org.uk> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#ifndef GDITHER_TYPES_H -#define GDITHER_TYPES_H - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum { - GDitherNone = 0, - GDitherRect, - GDitherTri, - GDitherShaped -} GDitherType; - -typedef enum { - GDither8bit = 8, - GDither16bit = 16, - GDither32bit = 32, - GDitherFloat = 25, - GDitherDouble = 54 -} GDitherSize; - -typedef void *GDither; - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/libs/ardour/ardour/gdither_types_internal.h b/libs/ardour/ardour/gdither_types_internal.h deleted file mode 100644 index e73a256310..0000000000 --- a/libs/ardour/ardour/gdither_types_internal.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2002 Steve Harris <steve@plugin.org.uk> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#ifndef GDITHER_TYPES_H -#define GDITHER_TYPES_H - -#include <stdint.h> - -#ifdef __cplusplus -extern "C" { -#endif - -#define GDITHER_SH_BUF_SIZE 8 -#define GDITHER_SH_BUF_MASK 7 - -/* this must agree with whats in gdither_types.h */ -typedef enum { - GDitherNone = 0, - GDitherRect, - GDitherTri, - GDitherShaped -} GDitherType; - -typedef enum { - GDither8bit = 8, - GDither16bit = 16, - GDither32bit = 32, - GDitherFloat = 25, - GDitherDouble = 54 -} GDitherSize; - -typedef struct { - uint32_t phase; - float buffer[GDITHER_SH_BUF_SIZE]; -} GDitherShapedState; - -typedef struct GDither_s { - GDitherType type; - uint32_t channels; - uint32_t bit_depth; - uint32_t dither_depth; - float scale; - uint32_t post_scale; - float post_scale_fp; - float bias; - - int clamp_u; - - int clamp_l; - float *tri_state; - GDitherShapedState *shaped_state; -} *GDither; - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/libs/ardour/ardour/importable_source.h b/libs/ardour/ardour/importable_source.h deleted file mode 100644 index a33cf567e7..0000000000 --- a/libs/ardour/ardour/importable_source.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - Copyright (C) 2007 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_importable_source_h__ -#define __ardour_importable_source_h__ - -#include <pbd/failed_constructor.h> -#include <ardour/types.h> - -namespace ARDOUR { - -class ImportableSource { -public: - ImportableSource () {} - virtual ~ImportableSource() {} - - virtual nframes_t read (Sample* buffer, nframes_t nframes) = 0; - virtual float ratio() const { return 1.0f; } - virtual uint32_t channels() const = 0; - virtual nframes_t length() const = 0; - virtual nframes_t samplerate() const = 0; - virtual void seek (nframes_t pos) = 0; -}; - -} - -#endif /* __ardour_importable_source_h__ */ diff --git a/libs/ardour/ardour/internal_audio_port.h b/libs/ardour/ardour/internal_audio_port.h deleted file mode 100644 index 7b70989d4b..0000000000 --- a/libs/ardour/ardour/internal_audio_port.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - Copyright (C) 2007 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - $Id: port.h 712 2006-07-28 01:08:57Z drobilla $ -*/ - -#ifndef __ardour_internal_audio_port_h__ -#define __ardour_internal_audio_port_h__ - -#include <sigc++/signal.h> -#include <pbd/failed_constructor.h> -#include <ardour/ardour.h> -#include <ardour/internal_port.h> -#include <ardour/audio_port.h> - -namespace ARDOUR { - -class AudioEngine; -class InternalAudioPort : public AudioPort, public InternalPort { - public: - void cycle_start(nframes_t nframes) { - _buffer.silence (nframes); - } - - AudioBuffer& get_audio_buffer(); - - void set_mixdown_function (void (*func)(const std::list<InternalPort*>&, AudioBuffer&, nframes_t, nframes_t)); - void reset (); - - protected: - friend class AudioEngine; - - InternalAudioPort (const std::string& name, Flags flags); - void (*_mixdown)(const std::list<InternalPort*>&, AudioBuffer&, nframes_t, nframes_t); - - static void default_mixdown (const std::list<InternalPort*>&, AudioBuffer&, nframes_t, nframes_t); -}; - -} // namespace ARDOUR - -#endif /* __ardour_internal_audio_port_h__ */ diff --git a/libs/ardour/ardour/internal_port.h b/libs/ardour/ardour/internal_port.h deleted file mode 100644 index e6053c0e58..0000000000 --- a/libs/ardour/ardour/internal_port.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - Copyright (C) 2007 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_internal_port_h__ -#define __ardour_internal_port_h__ - -#include <list> - -#include <sigc++/signal.h> -#include <pbd/failed_constructor.h> -#include <ardour/port.h> - -namespace ARDOUR { - -class AudioEngine; -class Buffer; - -/** Abstract class representing internal (ardour<->ardour only) ports - */ -class InternalPort : public virtual Port { - public: - - ~InternalPort(); - - std::string short_name(); - - int set_name (std::string str); - - int connected () const; - - int reestablish (); - - bool connected_to (const std::string& portname) const; - - const char ** get_connections () const; - bool monitoring_input () const { return false; } - - void ensure_monitor_input (bool yn) {} - void request_monitor_input (bool yn) {} - - nframes_t latency () const { return _latency; } - nframes_t total_latency() const { return _latency; } - - void set_latency (nframes_t nframes); - - static void connect (InternalPort& src, InternalPort& dst); - static void disconnect (InternalPort& a, InternalPort& b); - - protected: - friend class AudioEngine; - - InternalPort (const std::string&, DataType type, Flags flags); - - int disconnect (); - void recompute_total_latency() const; - - std::list<InternalPort*> _connections; - nframes_t _latency; - - static AudioEngine* engine; - static void set_engine (AudioEngine* e); -}; - -} // namespace ARDOUR - -#endif /* __ardour_internal_port_h__ */ diff --git a/libs/ardour/ardour/io.h b/libs/ardour/ardour/io.h deleted file mode 100644 index 83b6378dae..0000000000 --- a/libs/ardour/ardour/io.h +++ /dev/null @@ -1,391 +0,0 @@ -/* - Copyright (C) 2000 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_io_h__ -#define __ardour_io_h__ - -#include <string> -#include <vector> -#include <cmath> -#include <sigc++/signal.h> -#include <jack/jack.h> - -#include <glibmm/thread.h> - -#include <pbd/fastlog.h> -#include <pbd/undo.h> -#include <pbd/statefuldestructible.h> -#include <pbd/controllable.h> - -#include <ardour/ardour.h> -#include <ardour/automatable.h> -#include <ardour/utils.h> -#include <ardour/curve.h> -#include <ardour/types.h> -#include <ardour/data_type.h> -#include <ardour/port_set.h> -#include <ardour/chan_count.h> -#include <ardour/latent.h> -#include <ardour/automation_control.h> -#include <ardour/user_bundle.h> - -using std::string; -using std::vector; - -class XMLNode; - -namespace ARDOUR { - -class Session; -class AudioEngine; -class Bundle; -class AutoBundle; -class Panner; -class PeakMeter; -class Port; -class AudioPort; -class MidiPort; -class BufferSet; - - -/** A collection of input and output ports with connections. - * - * An IO can contain ports of varying types, making routes/inserts/etc with - * varied combinations of types (eg MIDI and audio) possible. - */ - -class IO : public Automatable, public Latent -{ - public: - static const string state_node_name; - - IO (Session&, const string& name, - int input_min = -1, int input_max = -1, - int output_min = -1, int output_max = -1, - DataType default_type = DataType::AUDIO, - bool public_ports = true); - - IO (Session&, const XMLNode&, DataType default_type = DataType::AUDIO); - - virtual ~IO(); - - ChanCount input_minimum() const { return _input_minimum; } - ChanCount input_maximum() const { return _input_maximum; } - ChanCount output_minimum() const { return _output_minimum; } - ChanCount output_maximum() const { return _output_maximum; } - - void set_input_minimum (ChanCount n); - void set_input_maximum (ChanCount n); - void set_output_minimum (ChanCount n); - void set_output_maximum (ChanCount n); - - bool active() const { return _active; } - void set_active (bool yn); - - DataType default_type() const { return _default_type; } - void set_default_type(DataType t) { _default_type = t; } - - bool set_name (const string& str); - - virtual void silence (nframes_t, nframes_t offset); - - void collect_input (BufferSet& bufs, nframes_t nframes, nframes_t offset); - void deliver_output (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame, - nframes_t nframes, nframes_t offset); - void just_meter_input (nframes_t start_frame, nframes_t end_frame, - nframes_t nframes, nframes_t offset); - - gain_t gain () const { return _desired_gain; } - virtual gain_t effective_gain () const; - - void set_denormal_protection (bool yn, void *src); - bool denormal_protection() const { return _denormal_protection; } - - void set_phase_invert (bool yn, void *src); - bool phase_invert() const { return _phase_invert; } - - Panner& panner() { return *_panner; } - PeakMeter& peak_meter() { return *_meter; } - const Panner& panner() const { return *_panner; } - - int ensure_io (ChanCount in, ChanCount out, bool clear, void *src); - - int connect_input_ports_to_bundle (boost::shared_ptr<Bundle>, void *src); - int connect_output_ports_to_bundle (boost::shared_ptr<Bundle>, void *src); - - std::vector<boost::shared_ptr<Bundle> > bundles_connected_to_inputs (); - std::vector<boost::shared_ptr<Bundle> > bundles_connected_to_outputs (); - - boost::shared_ptr<AutoBundle> bundle_for_inputs () { return _bundle_for_inputs; } - boost::shared_ptr<AutoBundle> bundle_for_outputs () { return _bundle_for_outputs; } - - int add_input_port (string source, void *src, DataType type = DataType::NIL); - int add_output_port (string destination, void *src, DataType type = DataType::NIL); - - int remove_input_port (Port *, void *src); - int remove_output_port (Port *, void *src); - - int set_input (Port *, void *src); - - int connect_input (Port *our_port, string other_port, void *src); - int connect_output (Port *our_port, string other_port, void *src); - - int disconnect_input (Port *our_port, string other_port, void *src); - int disconnect_output (Port *our_port, string other_port, void *src); - - int disconnect_inputs (void *src); - int disconnect_outputs (void *src); - - nframes_t signal_latency() const { return _own_latency; } - nframes_t output_latency() const; - nframes_t input_latency() const; - void set_port_latency (nframes_t); - - void update_port_total_latencies (); - - const PortSet& inputs() const { return _inputs; } - const PortSet& outputs() const { return _outputs; } - - Port *output (uint32_t n) const { - if (n < _outputs.num_ports()) { - return _outputs.port(n); - } else { - return 0; - } - } - - Port *input (uint32_t n) const { - if (n < _inputs.num_ports()) { - return _inputs.port(n); - } else { - return 0; - } - } - - AudioPort* audio_input(uint32_t n) const; - AudioPort* audio_output(uint32_t n) const; - MidiPort* midi_input(uint32_t n) const; - MidiPort* midi_output(uint32_t n) const; - - const ChanCount& n_inputs () const { return _inputs.count(); } - const ChanCount& n_outputs () const { return _outputs.count(); } - - void attach_buffers(ChanCount ignored); - - sigc::signal<void> active_changed; - - sigc::signal<void,IOChange,void*> input_changed; - sigc::signal<void,IOChange,void*> output_changed; - - virtual XMLNode& state (bool full); - XMLNode& get_state (void); - int set_state (const XMLNode&); - - static int disable_connecting (void); - - static int enable_connecting (void); - - static int disable_ports (void); - - static int enable_ports (void); - - static int disable_panners (void); - - static int reset_panners (void); - - static sigc::signal<int> PortsLegal; - static sigc::signal<int> PannersLegal; - static sigc::signal<int> ConnectingLegal; - /// raised when the number of input or output ports changes - static sigc::signal<void,ChanCount> PortCountChanged; - static sigc::signal<int> PortsCreated; - - static void update_meters(); - - private: - - static sigc::signal<void> Meter; - static Glib::StaticMutex m_meter_signal_lock; - sigc::connection m_meter_connection; - - public: - - /* automation */ - - struct GainControl : public AutomationControl { - GainControl (std::string name, IO& i, boost::shared_ptr<AutomationList> al) - : AutomationControl (i._session, al, name) - , _io (i) - {} - - void set_value (float val); - float get_value (void) const; - - IO& _io; - }; - - boost::shared_ptr<GainControl> gain_control() { - return _gain_control; - } - boost::shared_ptr<const GainControl> gain_control() const { - return _gain_control; - } - - void clear_automation (); - - void set_parameter_automation_state (Parameter, AutoState); - - virtual void transport_stopped (nframes_t now); - virtual void automation_snapshot (nframes_t now, bool force); - - void start_pan_touch (uint32_t which); - void end_pan_touch (uint32_t which); - - void defer_pan_reset (); - void allow_pan_reset (); - - /* the session calls this for master outs before - anyone else. controls outs too, at some point. - */ - - XMLNode *pending_state_node; - int ports_became_legal (); - - private: - mutable Glib::Mutex io_lock; - - protected: - Panner* _panner; - BufferSet* _output_buffers; //< Set directly to output port buffers - bool _active; - gain_t _gain; - gain_t _effective_gain; - gain_t _desired_gain; - Glib::Mutex declick_lock; - PortSet _outputs; - PortSet _inputs; - PeakMeter* _meter; - bool no_panner_reset; - bool _phase_invert; - bool _denormal_protection; - XMLNode* deferred_state; - DataType _default_type; - bool _public_ports; - - virtual void set_deferred_state() {} - - void reset_panner (); - - virtual uint32_t pans_required() const - { return _inputs.count().n_audio(); } - - boost::shared_ptr<GainControl> _gain_control; - - virtual void set_gain (gain_t g, void *src); - void inc_gain (gain_t delta, void *src); - - bool apply_gain_automation; - - virtual int load_automation (std::string path); - - /* AudioTrack::deprecated_use_diskstream_connections() needs these */ - - int set_inputs (const string& str); - int set_outputs (const string& str); - - static bool connecting_legal; - static bool ports_legal; - - BufferSet& output_buffers() { return *_output_buffers; } - - private: - - friend class Send; - - static bool panners_legal; - - int connecting_became_legal (); - int panners_became_legal (); - sigc::connection connection_legal_c; - sigc::connection port_legal_c; - sigc::connection panner_legal_c; - - ChanCount _input_minimum; ///< minimum number of input channels (0 for no minimum) - ChanCount _input_maximum; ///< maximum number of input channels (ChanCount::INFINITE for no maximum) - ChanCount _output_minimum; ///< minimum number of output channels (0 for no minimum) - ChanCount _output_maximum; ///< maximum number of output channels (ChanCount::INFINITE for no maximum) - - boost::shared_ptr<AutoBundle> _bundle_for_inputs; ///< a bundle representing our inputs - boost::shared_ptr<AutoBundle> _bundle_for_outputs; ///< a bundle representing our outputs - - struct UserBundleInfo { - UserBundleInfo (IO*, boost::shared_ptr<UserBundle> b); - - boost::shared_ptr<UserBundle> bundle; - sigc::connection configuration_will_change; - sigc::connection configuration_has_changed; - sigc::connection ports_will_change; - sigc::connection ports_have_changed; - }; - - std::vector<UserBundleInfo> _bundles_connected_to_outputs; ///< user bundles connected to our outputs - std::vector<UserBundleInfo> _bundles_connected_to_inputs; ///< user bundles connected to our inputs - - static int parse_io_string (const string&, vector<string>& chns); - - static int parse_gain_string (const string&, vector<string>& chns); - - int set_sources (vector<string>&, void *src, bool add); - int set_destinations (vector<string>&, void *src, bool add); - - int ensure_inputs (ChanCount, bool clear, bool lockit, void *src); - int ensure_outputs (ChanCount, bool clear, bool lockit, void *src); - - void check_bundles_connected_to_inputs (); - void check_bundles_connected_to_outputs (); - void check_bundles (std::vector<UserBundleInfo>&, const PortSet&); - - void bundle_configuration_will_change (); - void bundle_configuration_has_changed (); - void bundle_ports_will_change (int); - void bundle_ports_have_changed (int); - - int create_ports (const XMLNode&); - int make_connections (const XMLNode&); - - void setup_peak_meters (); - void meter (); - - bool ensure_inputs_locked (ChanCount, bool clear, void *src); - bool ensure_outputs_locked (ChanCount, bool clear, void *src); - - std::string build_legal_port_name (DataType type, bool for_input); - int32_t find_input_port_hole (const char* base); - int32_t find_output_port_hole (const char* base); - - void create_bundles_for_inputs_and_outputs (); - void setup_bundles_for_inputs_and_outputs (); - - void maybe_add_input_bundle_to_list (boost::shared_ptr<Bundle>, std::vector<boost::shared_ptr<Bundle> >*); - void maybe_add_output_bundle_to_list (boost::shared_ptr<Bundle>, std::vector<boost::shared_ptr<Bundle> >*); -}; - -} // namespace ARDOUR - -#endif /*__ardour_io_h__ */ diff --git a/libs/ardour/ardour/io_processor.h b/libs/ardour/ardour/io_processor.h deleted file mode 100644 index a535ce3bb4..0000000000 --- a/libs/ardour/ardour/io_processor.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - Copyright (C) 2001 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_redirect_h__ -#define __ardour_redirect_h__ - -#include <string> -#include <vector> -#include <set> -#include <map> -#include <boost/shared_ptr.hpp> -#include <sigc++/signal.h> - -#include <glibmm/thread.h> - -#include <pbd/undo.h> - -#include <ardour/ardour.h> -#include <ardour/processor.h> -#include <ardour/io.h> -#include <ardour/automation_event.h> - -using std::map; -using std::set; -using std::string; -using std::vector; - -class XMLNode; - -namespace ARDOUR { - -class Session; - -/** A mixer strip element (Processor) with Jack ports (IO). - */ -class IOProcessor : public Processor -{ - public: - IOProcessor (Session&, const string& name, Placement, - int input_min = -1, int input_max = -1, int output_min = -1, int output_max = -1); - IOProcessor (const IOProcessor&); - virtual ~IOProcessor (); - - virtual ChanCount output_streams() const { return _io->n_outputs(); } - virtual ChanCount input_streams () const { return _io->n_inputs(); } - virtual ChanCount natural_output_streams() const { return _io->n_outputs(); } - virtual ChanCount natural_input_streams () const { return _io->n_inputs(); } - - boost::shared_ptr<IO> io() { return _io; } - boost::shared_ptr<const IO> io() const { return _io; } - - virtual void automation_snapshot (nframes_t now, bool force) { _io->automation_snapshot(now, force); } - - virtual void run_in_place (BufferSet& in, nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset) = 0; - - void silence (nframes_t nframes, nframes_t offset); - - sigc::signal<void,IOProcessor*,bool> AutomationPlaybackChanged; - sigc::signal<void,IOProcessor*,uint32_t> AutomationChanged; - - XMLNode& state (bool full_state); - int set_state (const XMLNode&); - - protected: - boost::shared_ptr<IO> _io; -}; - -} // namespace ARDOUR - -#endif /* __ardour_redirect_h__ */ diff --git a/libs/ardour/ardour/jack_audio_port.h b/libs/ardour/ardour/jack_audio_port.h deleted file mode 100644 index 703fb81fa3..0000000000 --- a/libs/ardour/ardour/jack_audio_port.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - Copyright (C) 2002 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - $Id: port.h 712 2006-07-28 01:08:57Z drobilla $ -*/ - -#ifndef __ardour_jack_audio_port_h__ -#define __ardour_jack_audio_port_h__ - -#include <sigc++/signal.h> -#include <pbd/failed_constructor.h> -#include <ardour/ardour.h> -#include <ardour/jack_port.h> -#include <ardour/audio_port.h> - -namespace ARDOUR { - -class AudioEngine; -class JackAudioPort : public JackPort, public BaseAudioPort { - public: - void cycle_start (nframes_t nframes, nframes_t offset) { - _buffer->set_data ((Sample*) jack_port_get_buffer (_port, nframes) + offset, nframes); - } - - int reestablish (); - - protected: - friend class AudioPort; - - JackAudioPort (const std::string& name, Flags flags, AudioBuffer* buf); - - AudioBuffer* _source_buffer; -}; - -} // namespace ARDOUR - -#endif /* __ardour_jack_audio_port_h__ */ diff --git a/libs/ardour/ardour/jack_midi_port.h b/libs/ardour/ardour/jack_midi_port.h deleted file mode 100644 index d1fb5cc4fb..0000000000 --- a/libs/ardour/ardour/jack_midi_port.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - Copyright (C) 2002 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - $Id: port.h 712 2006-07-28 01:08:57Z drobilla $ -*/ - -#ifndef __ardour_jack_midi_port_h__ -#define __ardour_jack_midi_port_h__ - -#include <sigc++/signal.h> -#include <pbd/failed_constructor.h> -#include <ardour/ardour.h> -#include <jack/jack.h> -#include <jack/midiport.h> -#include <ardour/port.h> -#include <ardour/jack_port.h> -#include <ardour/base_midi_port.h> -#include <ardour/midi_buffer.h> - -namespace ARDOUR { - -class MidiEngine; - -class JackMidiPort : public JackPort, public BaseMidiPort { - public: - void cycle_start (nframes_t nframes, nframes_t offset); - void cycle_end (nframes_t nframes, nframes_t offset); - void set_buffer (MidiBuffer& buf); - - protected: - friend class MidiPort; - - JackMidiPort (const std::string&, Flags, MidiBuffer*); -}; - -} // namespace ARDOUR - -#endif /* __ardour_jack_midi_port_h__ */ diff --git a/libs/ardour/ardour/jack_port.h b/libs/ardour/ardour/jack_port.h deleted file mode 100644 index 3fa0008e17..0000000000 --- a/libs/ardour/ardour/jack_port.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - Copyright (C) 2002 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_jack_port_h__ -#define __ardour_jack_port_h__ - -#include <sigc++/signal.h> -#include <pbd/failed_constructor.h> -#include <ardour/port.h> -#include <jack/jack.h> - -namespace ARDOUR { - -class AudioEngine; -class Buffer; - -/** Abstract class representing JACK ports - */ -class JackPort : public virtual Port, public PortConnectableByName { - public: - - ~JackPort(); - - std::string short_name() const { - return jack_port_short_name (_port); - } - - int set_name (const std::string& str); - - bool connected () const { - return jack_port_connected (_port); - } - - int reestablish (); - int reconnect (); - - int connect (Port& other) { - return connect (other.name()); - } - - int disconnect (Port& other) { - return disconnect (other.name()); - } - - int disconnect_all (); - - // connect-by-name API - - int connect (const std::string& other_name); - int disconnect (const std::string& other_name); - - bool connected_to (const std::string& portname) const { - return jack_port_connected_to (_port, portname.c_str()); - } - - int get_connections (std::vector<std::string>& names) const; - - bool monitoring_input () const { - return jack_port_monitoring_input (_port); - } - - void ensure_monitor_input (bool yn) { - jack_port_ensure_monitor (_port, yn); - } - - /*XXX completely bloody useless imho*/ - void request_monitor_input (bool yn) { - jack_port_request_monitor (_port, yn); - } - - nframes_t latency () const { - return jack_port_get_latency (_port); - } - - nframes_t total_latency() const; - - void set_latency (nframes_t nframes) { - jack_port_set_latency (_port, nframes); - } - - - protected: - friend class AudioEngine; - - JackPort (const std::string&, DataType type, Flags flags); - jack_port_t* _port; - - int disconnect (); - void recompute_total_latency() const; - - std::set<std::string> _named_connections; -}; - -} // namespace ARDOUR - -#endif /* __ardour_jack_port_h__ */ diff --git a/libs/ardour/ardour/ladspa.h b/libs/ardour/ardour/ladspa.h deleted file mode 100644 index e552f35bb5..0000000000 --- a/libs/ardour/ardour/ladspa.h +++ /dev/null @@ -1,606 +0,0 @@ -/* 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 deleted file mode 100644 index b26e4120b1..0000000000 --- a/libs/ardour/ardour/ladspa_plugin.h +++ /dev/null @@ -1,147 +0,0 @@ -/* - Copyright (C) 2000-2006 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_ladspa_plugin_h__ -#define __ardour_ladspa_plugin_h__ - -#include <set> -#include <vector> -#include <string> -#include <dlfcn.h> - -#include <sigc++/signal.h> - -#include <pbd/stateful.h> - -#include <jack/types.h> -#include <ardour/ladspa.h> -#include <ardour/plugin.h> - -namespace ARDOUR { -class AudioEngine; -class Session; - -class LadspaPlugin : public ARDOUR::Plugin -{ - public: - LadspaPlugin (void *module, ARDOUR::AudioEngine&, ARDOUR::Session&, uint32_t index, nframes_t sample_rate); - LadspaPlugin (const LadspaPlugin &); - ~LadspaPlugin (); - - /* Plugin interface */ - - std::string unique_id() const; - const char* label() const { return _descriptor->Label; } - const char* name() const { return _descriptor->Name; } - const char* maker() const { return _descriptor->Maker; } - uint32_t parameter_count() const { return _descriptor->PortCount; } - float default_value (uint32_t port); - nframes_t signal_latency() const; - void set_parameter (uint32_t port, float val); - float get_parameter (uint32_t port) const; - int get_parameter_descriptor (uint32_t which, ParameterDescriptor&) const; - uint32_t nth_parameter (uint32_t port, bool& ok) const; - - std::set<Parameter> automatable() const; - - void activate () { - if (!_was_activated && _descriptor->activate) - _descriptor->activate (_handle); - - _was_activated = true; - } - - void deactivate () { - if (_was_activated && _descriptor->deactivate) - _descriptor->deactivate (_handle); - - _was_activated = false; - } - - void cleanup () { - activate(); - deactivate(); - - if (_descriptor->cleanup) - _descriptor->cleanup (_handle); - } - - void set_block_size (nframes_t nframes) {} - - int connect_and_run (BufferSet& bufs, uint32_t& in, uint32_t& out, nframes_t nframes, nframes_t offset); - std::string describe_parameter (Parameter); - std::string state_node_name() const { return "ladspa"; } - void print_parameter (uint32_t, char*, uint32_t len) const; - - bool parameter_is_audio(uint32_t) const; - bool parameter_is_control(uint32_t) const; - bool parameter_is_input(uint32_t) const; - bool parameter_is_output(uint32_t) const; - bool parameter_is_toggled(uint32_t) const; - - XMLNode& get_state(); - int set_state(const XMLNode& node); - bool save_preset(std::string name); - - bool has_editor() const { return false; } - - int require_output_streams (uint32_t); - - /* LADSPA extras */ - - LADSPA_Properties properties() const { return _descriptor->Properties; } - uint32_t index() const { return _index; } - const char * copyright() const { return _descriptor->Copyright; } - LADSPA_PortDescriptor port_descriptor(uint32_t i) const { return _descriptor->PortDescriptors[i]; } - const LADSPA_PortRangeHint* port_range_hints() const { return _descriptor->PortRangeHints; } - const char * const * port_names() const { return _descriptor->PortNames; } - - void set_gain (float gain) { _descriptor->set_run_adding_gain (_handle, gain); } - void run_adding (uint32_t nsamples) { _descriptor->run_adding (_handle, nsamples); } - void connect_port (uint32_t port, float *ptr) { _descriptor->connect_port (_handle, port, ptr); } - - private: - void* _module; - const LADSPA_Descriptor* _descriptor; - LADSPA_Handle _handle; - nframes_t _sample_rate; - LADSPA_Data* _control_data; - LADSPA_Data* _shadow_data; - LADSPA_Data* _latency_control_port; - uint32_t _index; - bool _was_activated; - - void init (void *mod, uint32_t index, nframes_t rate); - void run_in_place (nframes_t nsamples); - void latency_compute_run (); -}; - -class LadspaPluginInfo : public PluginInfo { - public: - LadspaPluginInfo () { }; - ~LadspaPluginInfo () { }; - - PluginPtr load (Session& session); -}; - -typedef boost::shared_ptr<LadspaPluginInfo> LadspaPluginInfoPtr; - -} // namespace ARDOUR - -#endif /* __ardour_ladspa_plugin_h__ */ diff --git a/libs/ardour/ardour/latent.h b/libs/ardour/ardour/latent.h deleted file mode 100644 index 11bdf11370..0000000000 --- a/libs/ardour/ardour/latent.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef __ardour_latent_h__ -#define __ardour_latent_h__ - -#include <ardour/types.h> - -namespace ARDOUR { - -class Latent { - public: - Latent() : _own_latency (0), _user_latency (0) {} - virtual ~Latent() {} - - virtual nframes_t signal_latency() const = 0; - nframes_t user_latency () const { return _user_latency; } - - virtual void set_latency_delay (nframes_t val) { _own_latency = val; } - virtual void set_user_latency (nframes_t val) { _user_latency = val; } - - protected: - nframes_t _own_latency; - nframes_t _user_latency; -}; - -} - -#endif /* __ardour_latent_h__*/ diff --git a/libs/ardour/ardour/location.h b/libs/ardour/ardour/location.h deleted file mode 100644 index 53d9489823..0000000000 --- a/libs/ardour/ardour/location.h +++ /dev/null @@ -1,206 +0,0 @@ -/* - Copyright (C) 2000 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_location_h__ -#define __ardour_location_h__ - -#include <string> -#include <list> -#include <iostream> -#include <map> - -#include <sys/types.h> -#include <sigc++/signal.h> - -#include <glibmm/thread.h> - -#include <pbd/undo.h> -#include <pbd/stateful.h> -#include <pbd/statefuldestructible.h> - -#include <ardour/ardour.h> - -using std::string; - -namespace ARDOUR { - -class Location : public PBD::StatefulDestructible -{ - public: - enum Flags { - IsMark = 0x1, - IsAutoPunch = 0x2, - IsAutoLoop = 0x4, - IsHidden = 0x8, - IsCDMarker = 0x10, - IsEnd = 0x20, - IsRangeMarker = 0x40, - IsStart = 0x80 - }; - - Location (nframes_t sample_start, - nframes_t sample_end, - const string &name, - Flags bits = Flags(0)) - - : _name (name), - _start (sample_start), - _end (sample_end), - _flags (bits), - _locked (false) { } - - Location () { - _start = 0; - _end = 0; - _flags = Flags (0); - _locked = false; - } - - Location (const Location& other); - Location (const XMLNode&); - Location* operator= (const Location& other); - - bool locked() const { return _locked; } - void lock() { _locked = true; changed (this); } - void unlock() { _locked = false; changed (this); } - - nframes_t start() const { return _start; } - nframes_t end() const { return _end; } - nframes_t length() const { return _end - _start; } - - int set_start (nframes_t s); - int set_end (nframes_t e); - int set (nframes_t start, nframes_t end); - - int move_to (nframes_t pos); - - const string& name() { return _name; } - void set_name (const string &str) { _name = str; name_changed(this); } - - void set_auto_punch (bool yn, void *src); - void set_auto_loop (bool yn, void *src); - void set_hidden (bool yn, void *src); - void set_cd (bool yn, void *src); - void set_is_end (bool yn, void* src); - void set_is_start (bool yn, void* src); - - bool is_auto_punch () { return _flags & IsAutoPunch; } - bool is_auto_loop () { return _flags & IsAutoLoop; } - bool is_mark () { return _flags & IsMark; } - bool is_hidden () { return _flags & IsHidden; } - bool is_cd_marker () { return _flags & IsCDMarker; } - bool is_end() { return _flags & IsEnd; } - bool is_start() { return _flags & IsStart; } - bool is_range_marker() { return _flags & IsRangeMarker; } - - sigc::signal<void,Location*> name_changed; - sigc::signal<void,Location*> end_changed; - sigc::signal<void,Location*> start_changed; - - sigc::signal<void,Location*,void*> FlagsChanged; - - /* this is sent only when both start&end change at the same time */ - - sigc::signal<void,Location*> changed; - - /* CD Track / CD-Text info */ - - std::map<string, string> cd_info; - XMLNode& cd_info_node (const string &, const string &); - - XMLNode& get_state (void); - int set_state (const XMLNode&); - - private: - string _name; - nframes_t _start; - nframes_t _end; - Flags _flags; - bool _locked; - - void set_mark (bool yn); - bool set_flag_internal (bool yn, Flags flag); -}; - -class Locations : public PBD::StatefulDestructible -{ - public: - typedef std::list<Location *> LocationList; - - Locations (); - ~Locations (); - - const LocationList& list() { return locations; } - - void add (Location *, bool make_current = false); - void remove (Location *); - void clear (); - void clear_markers (); - void clear_ranges (); - - XMLNode& get_state (void); - int set_state (const XMLNode&); - Location *get_location_by_id(PBD::ID); - - Location* auto_loop_location () const; - Location* auto_punch_location () const; - Location* end_location() const; - Location* start_location() const; - - int next_available_name(string& result,string base); - uint32_t num_range_markers() const; - - int set_current (Location *, bool want_lock = true); - Location *current () const { return current_location; } - - Location *first_location_before (nframes_t, bool include_special_ranges = false); - Location *first_location_after (nframes_t, bool include_special_ranges = false); - - nframes_t first_mark_before (nframes_t, bool include_special_ranges = false); - nframes_t first_mark_after (nframes_t, bool include_special_ranges = false); - - sigc::signal<void,Location*> current_changed; - sigc::signal<void> changed; - sigc::signal<void,Location*> added; - sigc::signal<void,Location*> removed; - sigc::signal<void,Change> StateChanged; - - template<class T> void apply (T& obj, void (T::*method)(LocationList&)) { - Glib::Mutex::Lock lm (lock); - (obj.*method)(locations); - } - - template<class T1, class T2> void apply (T1& obj, void (T1::*method)(LocationList&, T2& arg), T2& arg) { - Glib::Mutex::Lock lm (lock); - (obj.*method)(locations, arg); - } - - private: - - LocationList locations; - Location *current_location; - mutable Glib::Mutex lock; - - int set_current_unlocked (Location *); - void location_changed (Location*); -}; - -} // namespace ARDOUR - -#endif /* __ardour_location_h__ */ diff --git a/libs/ardour/ardour/logcurve.h b/libs/ardour/ardour/logcurve.h deleted file mode 100644 index dd58263313..0000000000 --- a/libs/ardour/ardour/logcurve.h +++ /dev/null @@ -1,132 +0,0 @@ -/* - Copyright (C) 2001 Steve Harris & Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_logcurve_h__ -#define __ardour_logcurve_h__ - -#include <pbd/fastlog.h> -#include <glibmm/thread.h> - -namespace ARDOUR { - -class LogCurve { - public: - LogCurve (float steepness = 0.2, uint32_t len = 0) { - l = len; - S = steepness; - a = log(S); - b = 1.0f / log(1.0f + (1.0f / S)); - } - - bool operator== (const LogCurve& other) const { - return S == other.S && l == other.l; - } - - bool operator!= (const LogCurve& other) const { - return S != other.S || l != other.l; - } - - float value (float frac) const { - return (fast_log(frac + S) - a) * b; - } - - float value (uint32_t pos) const { - return (fast_log(((float) pos/l) + S) - a) * b; - } - - float invert_value (float frac) const { - return (a - fast_log(frac + S)) * b; - } - - float invert_value (uint32_t pos) const { - return (a - fast_log(((float) pos/l) + S)) * b; - } - - void fill (float *vec, uint32_t veclen, bool invert) const { - float dx = 1.0f/veclen; - float x; - uint32_t i; - - if (!invert) { - - vec[0] = 0.0; - vec[veclen-1] = 1.0; - - for (i = 1, x = 0; i < veclen - 1; x += dx, i++) { - vec[i] = value (x); - } - - } else { - - vec[0] = 1.0; - vec[veclen-1] = 0.0; - - for (i = veclen-2, x = 0.0f; i > 0; x += dx, i--) { - vec[i] = value (x); - } - } - } - - float steepness() const { return S; } - uint32_t length() const { return l; } - - void set_steepness (float steepness) { - S = steepness; - a = log(S); - b = 1.0f / log(1.0f + (1.0f / S)); - } - void set_length (uint32_t len) { l = len; } - - mutable Glib::Mutex lock; - - protected: - float a; - float b; - float S; - uint32_t l; -}; - -class LogCurveIn : public LogCurve -{ - public: - LogCurveIn (float steepness = 0.2, uint32_t len = 0) - : LogCurve (steepness, len) {} - - float value (float frac) const { - return (fast_log(frac + S) - a) * b; - } - - float value (uint32_t pos) const { - return (fast_log(((float) pos/l) + S) - a) * b; - } -}; - -class LogCurveOut : public LogCurve -{ - public: - LogCurveOut (float steepness = 0.2, uint32_t len = 0) - : LogCurve (steepness, len) {} - -}; - -} // namespace ARDOUR - -#endif /* __ardour_logcurve_h__ */ - - diff --git a/libs/ardour/ardour/lv2_plugin.h b/libs/ardour/ardour/lv2_plugin.h deleted file mode 100644 index d20ece65bd..0000000000 --- a/libs/ardour/ardour/lv2_plugin.h +++ /dev/null @@ -1,171 +0,0 @@ -/* - Copyright (C) 2008 Paul Davis - Author: Dave Robillard - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_lv2_plugin_h__ -#define __ardour_lv2_plugin_h__ - -#include <set> -#include <vector> -#include <string> -#include <dlfcn.h> - -#include <sigc++/signal.h> - -#include <pbd/stateful.h> - -#include <jack/types.h> -#include <slv2/slv2.h> -#include <ardour/plugin.h> - -namespace ARDOUR { -class AudioEngine; -class Session; -struct LV2World; - -class LV2Plugin : public ARDOUR::Plugin -{ - public: - LV2Plugin (ARDOUR::AudioEngine&, ARDOUR::Session&, ARDOUR::LV2World&, SLV2Plugin plugin, nframes_t sample_rate); - LV2Plugin (const LV2Plugin &); - ~LV2Plugin (); - - /* Plugin interface */ - - std::string unique_id() const; - const char* label() const { return slv2_value_as_string(_name); } - const char* name() const { return slv2_value_as_string(_name); } - const char* maker() const { return _author ? slv2_value_as_string(_author) : "Unknown"; } - uint32_t parameter_count() const { return slv2_plugin_get_num_ports(_plugin); } - float default_value (uint32_t port); - nframes_t signal_latency() const; - void set_parameter (uint32_t port, float val); - float get_parameter (uint32_t port) const; - int get_parameter_descriptor (uint32_t which, ParameterDescriptor&) const; - uint32_t nth_parameter (uint32_t port, bool& ok) const; - - SLV2Plugin slv2_plugin() { return _plugin; } - SLV2Port slv2_port(uint32_t i) { return slv2_plugin_get_port_by_index(_plugin, i); } - - std::set<Parameter> automatable() const; - - void activate () { - if (!_was_activated) { - slv2_instance_activate(_instance); - _was_activated = true; - } - } - - void deactivate () { - if (_was_activated) { - slv2_instance_deactivate(_instance); - _was_activated = false; - } - } - - void cleanup () { - activate(); - deactivate(); - slv2_instance_free(_instance); - _instance = NULL; - } - - void set_block_size (nframes_t nframes) {} - - int connect_and_run (BufferSet& bufs, uint32_t& in, uint32_t& out, nframes_t nframes, nframes_t offset); - std::string describe_parameter (Parameter); - std::string state_node_name() const { return "lv2"; } - void print_parameter (uint32_t, char*, uint32_t len) const; - - bool parameter_is_audio(uint32_t) const; - bool parameter_is_control(uint32_t) const; - bool parameter_is_midi(uint32_t) const; - bool parameter_is_input(uint32_t) const; - bool parameter_is_output(uint32_t) const; - bool parameter_is_toggled(uint32_t) const; - - XMLNode& get_state(); - int set_state(const XMLNode& node); - bool save_preset(std::string name); - - bool has_editor() const { return false; } - - int require_output_streams (uint32_t); - - private: - void* _module; - LV2World& _world; - SLV2Plugin _plugin; - SLV2Value _name; - SLV2Value _author; - SLV2Instance _instance; - nframes_t _sample_rate; - float* _control_data; - float* _shadow_data; - float* _defaults; - float* _latency_control_port; - bool _was_activated; - vector<bool> _port_is_input; - - void init (LV2World& world, SLV2Plugin plugin, nframes_t rate); - void run (nframes_t nsamples); - void latency_compute_run (); -}; - - -/** The SLV2World, and various cached (as symbols, fast) URIs. - * - * This object represents everything ardour 'knows' about LV2 - * (ie understood extensions/features/etc) - */ -struct LV2World { - LV2World(); - ~LV2World(); - - SLV2World world; - SLV2Value input_class; ///< Input port - SLV2Value output_class; ///< Output port - SLV2Value audio_class; ///< Audio port - SLV2Value control_class; ///< Control port - SLV2Value event_class; ///< Event port - SLV2Value midi_class; ///< MIDI event - SLV2Value in_place_broken; - SLV2Value integer; - SLV2Value toggled; - SLV2Value srate; -}; - - -class LV2PluginInfo : public PluginInfo { -public: - LV2PluginInfo (void* slv2_world, void* slv2_plugin);; - ~LV2PluginInfo ();; - static PluginInfoList discover (void* slv2_world); - - PluginPtr load (Session& session); - - void* _lv2_world; - void* _slv2_plugin; -}; - -typedef boost::shared_ptr<LV2PluginInfo> LV2PluginInfoPtr; - -} // namespace ARDOUR - -#endif /* __ardour_lv2_plugin_h__ */ diff --git a/libs/ardour/ardour/meter.h b/libs/ardour/ardour/meter.h deleted file mode 100644 index e19c0a51ca..0000000000 --- a/libs/ardour/ardour/meter.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - Copyright (C) 2006 Paul Davis - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the Free - Software Foundation; either version 2 of the License, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifndef __ardour_meter_h__ -#define __ardour_meter_h__ - -#include <vector> -#include <ardour/types.h> -#include <ardour/processor.h> -#include <pbd/fastlog.h> - -namespace ARDOUR { - -class BufferSet; -class ChanCount; -class Session; - - -/** Meters peaks on the input and stores them for access. - */ -class PeakMeter : public Processor { -public: - PeakMeter(Session& s) : Processor(s, "meter", PreFader) {} - - void reset (); - void reset_max (); - - bool configure_io (ChanCount in, ChanCount out); - - /** Compute peaks */ - void run_in_place (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset); - - float peak_power (uint32_t n) { - if (n < _visible_peak_power.size()) { - return _visible_peak_power[n]; - } else { - return minus_infinity(); - } - } - - float max_peak_power (uint32_t n) { - if (n < _max_peak_power.size()) { - return _max_peak_power[n]; - } else { - return minus_infinity(); - } - } - -private: - - friend class IO; - void meter(); - - std::vector<float> _peak_power; - std::vector<float> _visible_peak_power; - std::vector<float> _max_peak_power; -}; - - -} // namespace ARDOUR - -#endif // __ardour_meter_h__ diff --git a/libs/ardour/ardour/midi_buffer.h b/libs/ardour/ardour/midi_buffer.h deleted file mode 100644 index 699f461b17..0000000000 --- a/libs/ardour/ardour/midi_buffer.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - Copyright (C) 2006 Paul Davis - Author: Dave Robillard - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the Free - Software Foundation; either version 2 of the License, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifndef __ardour_midi_buffer_h__ -#define __ardour_midi_buffer_h__ - -#include <midi++/event.h> -#include <ardour/buffer.h> - -namespace ARDOUR { - - -/** Buffer containing 8-bit unsigned char (MIDI) data. */ -class MidiBuffer : public Buffer -{ -public: - MidiBuffer(size_t capacity); - ~MidiBuffer(); - - void silence(nframes_t dur, nframes_t offset=0); - - void read_from(const Buffer& src, nframes_t nframes, nframes_t offset); - - void copy(const MidiBuffer& copy); - - bool push_back(const MIDI::Event& event); - bool push_back(const jack_midi_event_t& event); - uint8_t* reserve(double time, size_t size); - - void resize(size_t); - - bool merge(const MidiBuffer& a, const MidiBuffer& b); - - struct iterator { - iterator(MidiBuffer& b, size_t i) : buffer(b), index(i) {} - - inline MIDI::Event& operator*() const { return buffer[index]; } - inline iterator& operator++() { ++index; return *this; } // prefix - inline bool operator!=(const iterator& other) const { return index != other.index; } - - MidiBuffer& buffer; - size_t index; - }; - - struct const_iterator { - const_iterator(const MidiBuffer& b, size_t i) : buffer(b), index(i) {} - - inline const MIDI::Event& operator*() const { return buffer[index]; } - inline const_iterator& operator++() { ++index; return *this; } // prefix - inline bool operator!=(const const_iterator& other) const { return index != other.index; } - - const MidiBuffer& buffer; - size_t index; - }; - - iterator begin() { return iterator(*this, 0); } - iterator end() { return iterator(*this, _size); } - - const_iterator begin() const { return const_iterator(*this, 0); } - const_iterator end() const { return const_iterator(*this, _size); } - -private: - - friend class iterator; - friend class const_iterator; - - const MIDI::Event& operator[](size_t i) const { assert(i < _size); return _events[i]; } - MIDI::Event& operator[](size_t i) { assert(i < _size); return _events[i]; } - - // FIXME: Eliminate this - static const size_t MAX_EVENT_SIZE = 4; // bytes - - /* We use _size as "number of events", so the size of _data is - * (_size * MAX_EVENT_SIZE) - */ - - /* FIXME: this is utter crap. rewrite as a flat/packed buffer like MidiRingBuffer */ - - MIDI::Event* _events; ///< Event structs that point to offsets in _data - uint8_t* _data; ///< MIDI, straight up. No time stamps. -}; - - -} // namespace ARDOUR - -#endif // __ardour_midi_buffer_h__ diff --git a/libs/ardour/ardour/midi_diskstream.h b/libs/ardour/ardour/midi_diskstream.h deleted file mode 100644 index 28e80816a8..0000000000 --- a/libs/ardour/ardour/midi_diskstream.h +++ /dev/null @@ -1,184 +0,0 @@ -/* - Copyright (C) 2000 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - $Id: diskstream.h 579 2006-06-12 19:56:37Z essej $ -*/ - -#ifndef __ardour_midi_diskstream_h__ -#define __ardour_midi_diskstream_h__ - -#include <sigc++/signal.h> - -#include <cmath> -#include <cassert> -#include <string> -#include <queue> -#include <map> -#include <vector> - -#include <time.h> - -#include <pbd/fastlog.h> -#include <pbd/ringbufferNPT.h> - - -#include <ardour/ardour.h> -#include <ardour/configuration.h> -#include <ardour/session.h> -#include <ardour/route_group.h> -#include <ardour/route.h> -#include <ardour/port.h> -#include <ardour/utils.h> -#include <ardour/diskstream.h> -#include <ardour/midi_playlist.h> -#include <ardour/midi_ring_buffer.h> - -struct tm; - -namespace ARDOUR { - -class MidiEngine; -class Send; -class Session; -class MidiPlaylist; -class SMFSource; -class IO; - -class MidiDiskstream : public Diskstream -{ - public: - MidiDiskstream (Session &, const string& name, Diskstream::Flag f = Recordable); - MidiDiskstream (Session &, const XMLNode&); - ~MidiDiskstream(); - - float playback_buffer_load() const; - float capture_buffer_load() const; - - void get_playback(MidiBuffer& dst, nframes_t start, nframes_t end); - - void set_record_enabled (bool yn); - - boost::shared_ptr<MidiPlaylist> midi_playlist () { return boost::dynamic_pointer_cast<MidiPlaylist>(_playlist); } - - int use_playlist (boost::shared_ptr<Playlist>); - int use_new_playlist (); - int use_copy_playlist (); - - /* stateful */ - XMLNode& get_state(void); - int set_state(const XMLNode& node); - - void monitor_input (bool); - - boost::shared_ptr<SMFSource> write_source () { return _write_source; } - - int set_destructive (bool yn); // doom! - - void set_note_mode (NoteMode m); - - uint16_t get_channel_mask() { - uint16_t playback_mask = _playback_buf->get_channel_mask(); -#ifndef NDEBUG - uint16_t capture_mask = _capture_buf->get_channel_mask(); - assert(playback_mask == capture_mask); -#endif - return playback_mask; - } - - void set_channel_mode(ChannelMode mode, uint16_t mask) { - _playback_buf->set_channel_mode(mode, mask); - _capture_buf->set_channel_mode(mode, mask); - } - - ChannelMode get_channel_mode() { - ChannelMode playback_mode = _playback_buf->get_channel_mode(); -#ifndef NDEBUG - ChannelMode capture_mode = _capture_buf->get_channel_mode(); - assert(playback_mode == capture_mode); -#endif - return playback_mode; - } - - protected: - friend class Session; - - /* the Session is the only point of access for these - because they require that the Session is "inactive" - while they are called. - */ - - void set_pending_overwrite(bool); - int overwrite_existing_buffers (); - void set_block_size (nframes_t); - int internal_playback_seek (nframes_t distance); - int can_internal_playback_seek (nframes_t distance); - int rename_write_sources (); - void reset_write_sources (bool, bool force = false); - void non_realtime_input_change (); - void non_realtime_locate (nframes_t location); - - protected: - int seek (nframes_t which_sample, bool complete_refill = false); - - protected: - friend class MidiTrack; - - int process (nframes_t transport_frame, nframes_t nframes, nframes_t offset, bool can_record, bool rec_monitors_input); - bool commit (nframes_t nframes); - - private: - - /* The two central butler operations */ - int do_flush (Session::RunContext context, bool force = false); - int do_refill (); - - int do_refill_with_alloc(); - - int read (nframes_t& start, nframes_t cnt, bool reversed); - - void finish_capture (bool rec_monitors_input); - void transport_stopped (struct tm&, time_t, bool abort); - void transport_looped (nframes_t transport_frame); - - void init (Diskstream::Flag); - - int use_new_write_source (uint32_t n=0); - - int find_and_use_playlist (const string&); - - void allocate_temporary_buffers (); - - int use_pending_capture_data (XMLNode& node); - - void get_input_sources (); - void check_record_status (nframes_t transport_frame, nframes_t nframes, bool can_record); - void set_align_style_from_io(); - - void engage_record_enable (); - void disengage_record_enable (); - - MidiRingBuffer* _playback_buf; - MidiRingBuffer* _capture_buf; - MidiPort* _source_port; - boost::shared_ptr<SMFSource> _write_source; - nframes_t _last_flush_frame; - NoteMode _note_mode; -}; - -}; /* namespace ARDOUR */ - -#endif /* __ardour_midi_diskstream_h__ */ diff --git a/libs/ardour/ardour/midi_model.h b/libs/ardour/ardour/midi_model.h deleted file mode 100644 index 2481aa8d34..0000000000 --- a/libs/ardour/ardour/midi_model.h +++ /dev/null @@ -1,252 +0,0 @@ -/* - Copyright (C) 2007 Paul Davis - Author: Dave Robillard - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_midi_model_h__ -#define __ardour_midi_model_h__ - -#include <queue> -#include <deque> -#include <utility> -#include <boost/utility.hpp> -#include <glibmm/thread.h> -#include <pbd/command.h> -#include <ardour/types.h> -#include <ardour/midi_buffer.h> -#include <ardour/midi_ring_buffer.h> -#include <ardour/automatable.h> -#include <ardour/note.h> -#include <ardour/types.h> - -namespace ARDOUR { - -class Session; -class MidiSource; - -/** - * This class keeps track of the current x and y for a control - */ -class MidiControlIterator { -public: - boost::shared_ptr<const AutomationList> automation_list; - double x; - double y; - - MidiControlIterator(boost::shared_ptr<const AutomationList> a_list, - double a_x, - double a_y) - : automation_list(a_list) - , x(a_x) - , y(a_y) - {} -}; - - -/** This is a higher level (than MidiBuffer) model of MIDI data, with separate - * representations for notes (instead of just unassociated note on/off events) - * and controller data. Controller data is represented as part of the - * Automatable base (i.e. in a map of AutomationList, keyed by Parameter). - */ -class MidiModel : public boost::noncopyable, public Automatable { -public: - MidiModel(MidiSource* s, size_t size=0); - - void write_lock(); - void write_unlock(); - - void read_lock() const; - void read_unlock() const; - - void clear(); - - NoteMode note_mode() const { return _note_mode; } - void set_note_mode(NoteMode mode) { _note_mode = mode; } - - void start_write(); - bool writing() const { return _writing; } - void end_write(bool delete_stuck=false); - - size_t read (MidiRingBuffer& dst, nframes_t start, nframes_t nframes, nframes_t stamp_offset, nframes_t negative_stamp_offset) const; - - /** Resizes vector if necessary (NOT realtime safe) */ - void append(const MIDI::Event& ev); - - inline const boost::shared_ptr<const Note> note_at(unsigned i) const { return _notes[i]; } - inline const boost::shared_ptr<Note> note_at(unsigned i) { return _notes[i]; } - - inline size_t n_notes() const { return _notes.size(); } - inline bool empty() const { return _notes.size() == 0 && _controls.size() == 0; } - - inline static bool note_time_comparator (const boost::shared_ptr<const Note> a, - const boost::shared_ptr<const Note> b) { - return a->time() < b->time(); - } - - struct LaterNoteEndComparator { - typedef const Note* value_type; - inline bool operator()(const boost::shared_ptr<const Note> a, - const boost::shared_ptr<const Note> b) const { - return a->end_time() > b->end_time(); - } - }; - - typedef std::vector< boost::shared_ptr<Note> > Notes; - inline Notes& notes() { return _notes; } - inline const Notes& notes() const { return _notes; } - - /** Add/Remove notes. - * Technically all operations can be implemented as one of these. - */ - class DeltaCommand : public Command - { - public: - DeltaCommand (boost::shared_ptr<MidiModel> m, const std::string& name); - DeltaCommand (boost::shared_ptr<MidiModel>, const XMLNode& node); - - const std::string& name() const { return _name; } - - void operator()(); - void undo(); - - int set_state (const XMLNode&); - XMLNode& get_state (); - - void add(const boost::shared_ptr<Note> note); - void remove(const boost::shared_ptr<Note> note); - - private: - XMLNode &marshal_note(const boost::shared_ptr<Note> note); - boost::shared_ptr<Note> unmarshal_note(XMLNode *xml_note); - - boost::shared_ptr<MidiModel> _model; - const std::string _name; - - typedef std::list< boost::shared_ptr<Note> > NoteList; - - NoteList _added_notes; - NoteList _removed_notes; - }; - - MidiModel::DeltaCommand* new_delta_command(const std::string name="midi edit"); - void apply_command(Command* cmd); - - bool edited() const { return _edited; } - void set_edited(bool yn) { _edited = yn; } - bool write_to(boost::shared_ptr<MidiSource> source); - - // MidiModel doesn't use the normal AutomationList serialisation code - // since controller data is stored in the .mid - XMLNode& get_state(); - int set_state(const XMLNode&) { return 0; } - - sigc::signal<void> ContentsChanged; - - /** Read iterator */ - class const_iterator { - public: - const_iterator(const MidiModel& model, double t); - ~const_iterator(); - - inline bool locked() const { return _locked; } - - const MIDI::Event& operator*() const { return *_event; } - const boost::shared_ptr<MIDI::Event> operator->() const { return _event; } - const boost::shared_ptr<MIDI::Event> get_event_pointer() { return _event; } - - const const_iterator& operator++(); // prefix only - bool operator==(const const_iterator& other) const; - bool operator!=(const const_iterator& other) const { return ! operator==(other); } - - const_iterator& operator=(const const_iterator& other); - - private: - friend class MidiModel; - - const MidiModel* _model; - boost::shared_ptr<MIDI::Event> _event; - - typedef std::priority_queue< - boost::shared_ptr<Note>, std::deque< boost::shared_ptr<Note> >, - LaterNoteEndComparator> - ActiveNotes; - - mutable ActiveNotes _active_notes; - - bool _is_end; - bool _locked; - Notes::const_iterator _note_iter; - std::vector<MidiControlIterator> _control_iters; - std::vector<MidiControlIterator>::iterator _control_iter; - }; - - const_iterator begin() const { return const_iterator(*this, 0); } - const const_iterator& end() const { return _end_iter; } - - const MidiSource* midi_source() const { return _midi_source; } - void set_midi_source(MidiSource* source) { _midi_source = source; } - bool control_to_midi_event(boost::shared_ptr<MIDI::Event>& ev, const MidiControlIterator& iter) const; - -private: - friend class DeltaCommand; - void add_note_unlocked(const boost::shared_ptr<Note> note); - void remove_note_unlocked(const boost::shared_ptr<const Note> note); - - friend class const_iterator; - -#ifndef NDEBUG - bool is_sorted() const; -#endif - - void append_note_on_unlocked(uint8_t chan, double time, uint8_t note, uint8_t velocity); - void append_note_off_unlocked(uint8_t chan, double time, uint8_t note); - void append_automation_event_unlocked(AutomationType type, uint8_t chan, double time, uint8_t first_byte, uint8_t second_byte); - void append_pgm_change_unlocked(uint8_t chan, double time, uint8_t number); - - mutable Glib::RWLock _lock; - - Notes _notes; - - NoteMode _note_mode; - - typedef std::vector<size_t> WriteNotes; - WriteNotes _write_notes[16]; - bool _writing; - bool _edited; - - typedef std::vector< boost::shared_ptr<const ARDOUR::AutomationList> > AutomationLists; - AutomationLists _dirty_automations; - - const const_iterator _end_iter; - - mutable nframes_t _next_read; - mutable const_iterator _read_iter; - - typedef std::priority_queue< - boost::shared_ptr<Note>, std::deque< boost::shared_ptr<Note> >, - LaterNoteEndComparator> - ActiveNotes; - - // We cannot use a boost::shared_ptr here to avoid a retain cycle - MidiSource* _midi_source; -}; - -} /* namespace ARDOUR */ - -#endif /* __ardour_midi_model_h__ */ - diff --git a/libs/ardour/ardour/midi_playlist.h b/libs/ardour/ardour/midi_playlist.h deleted file mode 100644 index dcc202bbf4..0000000000 --- a/libs/ardour/ardour/midi_playlist.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - Copyright (C) 2006 Paul Davis - Written by Dave Robillard, 2006 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifndef __ardour_midi_playlist_h__ -#define __ardour_midi_playlist_h__ - -#include <vector> -#include <list> - -#include <ardour/ardour.h> -#include <ardour/playlist.h> -#include <ardour/parameter.h> - -namespace ARDOUR -{ - -class Session; -class Region; -class MidiRegion; -class Source; -class MidiRingBuffer; - -class MidiPlaylist : public ARDOUR::Playlist -{ -public: - MidiPlaylist (Session&, const XMLNode&, bool hidden = false); - MidiPlaylist (Session&, string name, bool hidden = false); - MidiPlaylist (boost::shared_ptr<const MidiPlaylist> other, string name, bool hidden = false); - MidiPlaylist (boost::shared_ptr<const MidiPlaylist> other, nframes_t start, nframes_t cnt, - string name, bool hidden = false); - - ~MidiPlaylist (); - - nframes_t read (MidiRingBuffer& buf, - nframes_t start, nframes_t cnt, uint32_t chan_n=0); - - int set_state (const XMLNode&); - UndoAction get_memento() const; - - bool destroy_region (boost::shared_ptr<Region>); - - void set_note_mode (NoteMode m) { _note_mode = m; } - - std::set<Parameter> contained_automation(); - -protected: - - /* playlist "callbacks" */ - - void finalize_split_region (boost::shared_ptr<Region> original, boost::shared_ptr<Region> left, boost::shared_ptr<Region> right); - - void check_dependents (boost::shared_ptr<Region> region, bool norefresh); - void refresh_dependents (boost::shared_ptr<Region> region); - void remove_dependents (boost::shared_ptr<Region> region); - -private: - void dump () const; - - bool region_changed (Change, boost::shared_ptr<Region>); - - NoteMode _note_mode; -}; - -} /* namespace ARDOUR */ - -#endif /* __ardour_midi_playlist_h__ */ - - diff --git a/libs/ardour/ardour/midi_port.h b/libs/ardour/ardour/midi_port.h deleted file mode 100644 index 485834aaff..0000000000 --- a/libs/ardour/ardour/midi_port.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - Copyright (C) 2002 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - $Id: port.h 712 2006-07-28 01:08:57Z drobilla $ -*/ - -#ifndef __ardour_midi_port_h__ -#define __ardour_midi_port_h__ - -#include <ardour/base_midi_port.h> - -namespace ARDOUR { - -class MidiEngine; - -class MidiPort : public BaseMidiPort, public PortFacade { - public: - ~MidiPort(); - - void reset (); - - void cycle_start (nframes_t nframes, nframes_t offset); - void cycle_end (nframes_t nframes, nframes_t offset); - - protected: - friend class AudioEngine; - - MidiPort (const std::string& name, Flags, bool external, nframes_t bufsize); -}; - -} // namespace ARDOUR - -#endif /* __ardour_midi_port_h__ */ diff --git a/libs/ardour/ardour/midi_region.h b/libs/ardour/ardour/midi_region.h deleted file mode 100644 index cd2b0d6132..0000000000 --- a/libs/ardour/ardour/midi_region.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - Copyright (C) 2000-2006 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - $Id: midiregion.h 733 2006-08-01 17:19:38Z drobilla $ -*/ - -#ifndef __ardour_midi_region_h__ -#define __ardour_midi_region_h__ - -#include <vector> - -#include <pbd/fastlog.h> -#include <pbd/undo.h> - -#include <ardour/ardour.h> -#include <ardour/region.h> -#include <ardour/gain.h> -#include <ardour/logcurve.h> -#include <ardour/export.h> -#include <ardour/midi_source.h> - -class XMLNode; - -namespace ARDOUR { - -class Route; -class Playlist; -class Session; -class MidiFilter; -class MidiSource; -class MidiRingBuffer; - -class MidiRegion : public Region -{ - public: - ~MidiRegion(); - - boost::shared_ptr<MidiSource> midi_source (uint32_t n=0) const; - - /* Stub Readable interface */ - virtual nframes64_t read (Sample*, nframes64_t pos, nframes64_t cnt, int channel) const { return 0; } - virtual nframes64_t readable_length() const { return length(); } - - nframes_t read_at (MidiRingBuffer& dst, - nframes_t position, - nframes_t dur, - uint32_t chan_n = 0, - NoteMode mode = Sustained) const; - - nframes_t master_read_at (MidiRingBuffer& dst, - nframes_t position, - nframes_t dur, - uint32_t chan_n = 0, - NoteMode mode = Sustained) const; - - XMLNode& state (bool); - int set_state (const XMLNode&); - - int separate_by_channel (ARDOUR::Session&, vector<MidiRegion*>&) const; - - UndoAction get_memento() const; - - // Act as a proxy for MidiModel automation stuff (for CC) - // Yep, this is pretty ugly... - Controls& controls() { return midi_source()->model()->controls(); } - const Controls& controls() const { return midi_source()->model()->controls(); } - - boost::shared_ptr<AutomationControl> control(Parameter id, bool create_if_missing=false) - { return midi_source()->model()->control(id, create_if_missing); } - - boost::shared_ptr<const AutomationControl> control(Parameter id) const - { return midi_source()->model()->control(id); } - - int exportme (ARDOUR::Session&, ARDOUR::ExportSpecification&); - - private: - friend class RegionFactory; - - MidiRegion (boost::shared_ptr<MidiSource>, nframes_t start, nframes_t length); - MidiRegion (boost::shared_ptr<MidiSource>, nframes_t start, nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags); - MidiRegion (const SourceList &, nframes_t start, nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags); - MidiRegion (boost::shared_ptr<const MidiRegion>, nframes_t start, nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags); - MidiRegion (boost::shared_ptr<const MidiRegion>); - MidiRegion (boost::shared_ptr<MidiSource>, const XMLNode&); - MidiRegion (const SourceList &, const XMLNode&); - - private: - nframes_t _read_at (const SourceList&, MidiRingBuffer& dst, - nframes_t position, - nframes_t dur, - uint32_t chan_n = 0, - NoteMode mode = Sustained) const; - - void recompute_at_start (); - void recompute_at_end (); - - void switch_source(boost::shared_ptr<Source> source); - - protected: - - int set_live_state (const XMLNode&, Change&, bool send); -}; - -} /* namespace ARDOUR */ - - -#endif /* __ardour_midi_region_h__ */ diff --git a/libs/ardour/ardour/midi_ring_buffer.h b/libs/ardour/ardour/midi_ring_buffer.h deleted file mode 100644 index ff0be5c997..0000000000 --- a/libs/ardour/ardour/midi_ring_buffer.h +++ /dev/null @@ -1,466 +0,0 @@ -/* - Copyright (C) 2006 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifndef __ardour_midi_ring_buffer_h__ -#define __ardour_midi_ring_buffer_h__ - -#include <iostream> -#include <algorithm> -#include <ardour/types.h> -#include <ardour/buffer.h> - -namespace ARDOUR { - - -/* FIXME: this is probably too much inlined code */ - - -/** A RingBuffer. - * Read/Write realtime safe. - * Single-reader Single-writer thread safe. - * - * This is Raul::RingBuffer, lifted for MIDIRingBuffer to inherit from as it works - * a bit differently than PBD::Ringbuffer. This could/should be replaced with - * the PBD ringbuffer to decrease code size, but this code is tested and known to - * work, so here it sits for now... - * - * Ignore this class, use MidiRingBuffer. - */ -template <typename T> -class MidiRingBufferBase { -public: - - /** @param size Size in bytes. - */ - MidiRingBufferBase(size_t size) - : _size(size) - , _buf(new T[size]) - { - reset(); - assert(read_space() == 0); - assert(write_space() == size - 1); - } - - virtual ~MidiRingBufferBase() { - delete[] _buf; - } - - /** Reset(empty) the ringbuffer. - * NOT thread safe. - */ - void reset() { - g_atomic_int_set(&_write_ptr, 0); - g_atomic_int_set(&_read_ptr, 0); - } - - size_t write_space() const { - - const size_t w = g_atomic_int_get(&_write_ptr); - const size_t r = g_atomic_int_get(&_read_ptr); - - if (w > r) { - return ((r - w + _size) % _size) - 1; - } else if (w < r) { - return (r - w) - 1; - } else { - return _size - 1; - } - } - - size_t read_space() const { - - const size_t w = g_atomic_int_get(&_write_ptr); - const size_t r = g_atomic_int_get(&_read_ptr); - - if (w > r) { - return w - r; - } else { - return (w - r + _size) % _size; - } - } - - size_t capacity() const { return _size; } - - size_t peek(size_t size, T* dst); - bool full_peek(size_t size, T* dst); - - size_t read(size_t size, T* dst); - bool full_read(size_t size, T* dst); - - bool skip(size_t size); - - void write(size_t size, const T* src); - -protected: - mutable int _write_ptr; - mutable int _read_ptr; - - size_t _size; ///< Size (capacity) in bytes - T* _buf; ///< size, event, size, event... -}; - - -/** Peek at the ringbuffer (read w/o advancing read pointer). - * - * Note that a full read may not be done if the data wraps around. - * Caller must check return value and call again if necessary, or use the - * full_peek method which does this automatically. - */ -template<typename T> -size_t -MidiRingBufferBase<T>::peek(size_t size, T* dst) -{ - const size_t priv_read_ptr = g_atomic_int_get(&_read_ptr); - - const size_t read_size = (priv_read_ptr + size < _size) - ? size - : _size - priv_read_ptr; - - memcpy(dst, &_buf[priv_read_ptr], read_size); - - return read_size; -} - - -template<typename T> -bool -MidiRingBufferBase<T>::full_peek(size_t size, T* dst) -{ - if (read_space() < size) { - return false; - } - - const size_t read_size = peek(size, dst); - - if (read_size < size) { - peek(size - read_size, dst + read_size); - } - - return true; -} - - -/** Read from the ringbuffer. - * - * Note that a full read may not be done if the data wraps around. - * Caller must check return value and call again if necessary, or use the - * full_read method which does this automatically. - */ -template<typename T> -size_t -MidiRingBufferBase<T>::read(size_t size, T* dst) -{ - const size_t priv_read_ptr = g_atomic_int_get(&_read_ptr); - - const size_t read_size = (priv_read_ptr + size < _size) - ? size - : _size - priv_read_ptr; - - memcpy(dst, &_buf[priv_read_ptr], read_size); - - g_atomic_int_set(&_read_ptr, (priv_read_ptr + read_size) % _size); - - return read_size; -} - - -template<typename T> -bool -MidiRingBufferBase<T>::full_read(size_t size, T* dst) -{ - if (read_space() < size) { - return false; - } - - const size_t read_size = read(size, dst); - - if (read_size < size) { - read(size - read_size, dst + read_size); - } - - return true; -} - - -template<typename T> -bool -MidiRingBufferBase<T>::skip(size_t size) -{ - if (read_space() < size) { - std::cerr << "WARNING: Attempt to skip past end of MIDI ring buffer" << std::endl; - return false; - } - - const size_t priv_read_ptr = g_atomic_int_get(&_read_ptr); - g_atomic_int_set(&_read_ptr, (priv_read_ptr + size) % _size); - - return true; -} - - -template<typename T> -inline void -MidiRingBufferBase<T>::write(size_t size, const T* src) -{ - const size_t priv_write_ptr = g_atomic_int_get(&_write_ptr); - - if (priv_write_ptr + size <= _size) { - memcpy(&_buf[priv_write_ptr], src, size); - g_atomic_int_set(&_write_ptr, (priv_write_ptr + size) % _size); - } else { - const size_t this_size = _size - priv_write_ptr; - assert(this_size < size); - assert(priv_write_ptr + this_size <= _size); - memcpy(&_buf[priv_write_ptr], src, this_size); - memcpy(&_buf[0], src+this_size, size - this_size); - g_atomic_int_set(&_write_ptr, size - this_size); - } -} - - -/* ******************************************************************** */ - - -/** A MIDI RingBuffer. - * - * This is timestamps and MIDI packed sequentially into a single buffer, similarly - * to LV2 MIDI. The buffer looks like this: - * - * [timestamp][size][size bytes of raw MIDI][timestamp][size][etc..] - */ -class MidiRingBuffer : public MidiRingBufferBase<uint8_t> { -public: - /** @param size Size in bytes. - */ - MidiRingBuffer(size_t size) - : MidiRingBufferBase<uint8_t>(size), _channel_mask(0x0000FFFF) - {} - - size_t write(double time, size_t size, const uint8_t* buf); - bool read(double* time, size_t* size, uint8_t* buf); - - bool read_prefix(double* time, size_t* size); - bool read_contents(size_t size, uint8_t* buf); - - size_t read(MidiBuffer& dst, nframes_t start, nframes_t end, nframes_t offset=0); - - /** Set the channel filtering mode. - * @param mask If mode is FilterChannels, each bit represents a midi channel: - * bit 0 = channel 0, bit 1 = channel 1 etc. the read and write methods will only - * process events whose channel bit is 1. - * If mode is ForceChannel, mask is simply a channel number which all events will - * be forced to while reading. - */ - void set_channel_mode(ChannelMode mode, uint16_t mask) { - g_atomic_int_set(&_channel_mask, ((uint16_t)mode << 16) | mask); - } - - ChannelMode get_channel_mode() const { - return static_cast<ChannelMode>((g_atomic_int_get(&_channel_mask) & 0xFFFF0000) >> 16); - } - - uint16_t get_channel_mask() const { - return static_cast<ChannelMode>((g_atomic_int_get(&_channel_mask) & 0x0000FFFF)); - } - -protected: - inline bool is_channel_event(uint8_t event_type_byte) { - // mask out channel information - event_type_byte &= 0xF0; - // midi channel events range from 0x80 to 0xE0 - return (0x80 <= event_type_byte) && (event_type_byte <= 0xE0); - } - -private: - volatile uint32_t _channel_mask; // 16 bits mode, 16 bits mask -}; - - -inline bool -MidiRingBuffer::read(double* time, size_t* size, uint8_t* buf) -{ - bool success = MidiRingBufferBase<uint8_t>::full_read(sizeof(double), (uint8_t*)time); - - if (success) { - success = MidiRingBufferBase<uint8_t>::full_read(sizeof(size_t), (uint8_t*)size); - } - if (success) { - success = MidiRingBufferBase<uint8_t>::full_read(*size, buf); - } - - return success; -} - - -/** Read the time and size of an event. This call MUST be immediately proceeded - * by a call to read_contents (or the read pointer will be garabage). - */ -inline bool -MidiRingBuffer::read_prefix(double* time, size_t* size) -{ - bool success = MidiRingBufferBase<uint8_t>::full_read(sizeof(double), (uint8_t*)time); - if (success) { - success = MidiRingBufferBase<uint8_t>::full_read(sizeof(size_t), (uint8_t*)size); - } - - return success; -} - - -/** Read the contenst of an event. This call MUST be immediately preceeded - * by a call to read_prefix (or the returned even will be garabage). - */ -inline bool -MidiRingBuffer::read_contents(size_t size, uint8_t* buf) -{ - return MidiRingBufferBase<uint8_t>::full_read(size, buf); -} - - -inline size_t -MidiRingBuffer::write(double time, size_t size, const uint8_t* buf) -{ - /*fprintf(stderr, "MRB %p write (t = %f) ", this, time); - for (size_t i = 0; i < size; ++i) - fprintf(stderr, "%X", (char)buf[i]); - fprintf(stderr, "\n");*/ - - assert(size > 0); - - // Don't write event if it doesn't match channel filter - if (is_channel_event(buf[0]) && get_channel_mode() == FilterChannels) { - uint8_t channel = buf[0] & 0x0F; - if ( !(get_channel_mask() & (1L << channel)) ) { - return 0; - } - } - - if (write_space() < (sizeof(double) + sizeof(size_t) + size)) { - return 0; - } else { - MidiRingBufferBase<uint8_t>::write(sizeof(double), (uint8_t*)&time); - MidiRingBufferBase<uint8_t>::write(sizeof(size_t), (uint8_t*)&size); - if (is_channel_event(buf[0]) && get_channel_mode() == ForceChannel) { - assert(size == 2 || size == 3); - uint8_t tmp_buf[3]; - // Force event to channel - tmp_buf[0] = (buf[0] & 0xF0) | (get_channel_mask() & 0x0F); - tmp_buf[1] = buf[1]; - if (size == 3) { - tmp_buf[2] = buf[2]; - } - MidiRingBufferBase<uint8_t>::write(size, tmp_buf); - } else { - MidiRingBufferBase<uint8_t>::write(size, buf); - } - return size; - } - -} - - -/** Read a block of MIDI events from buffer. - * - * Timestamps of events returned are relative to start (ie event with stamp 0 - * occurred at start), with offset added. - */ -inline size_t -MidiRingBuffer::read(MidiBuffer& dst, nframes_t start, nframes_t end, nframes_t offset) -{ - if (read_space() == 0) - return 0; - - double ev_time; - uint32_t ev_size; - - size_t count = 0; - - //printf("---- MRB read %u .. %u + %u\n", start, end, offset); - - while (read_space() > sizeof(double) + sizeof(size_t)) { - - full_peek(sizeof(double), (uint8_t*)&ev_time); - - if (ev_time > end) { - break; - } - - bool success = MidiRingBufferBase<uint8_t>::full_read(sizeof(double), (uint8_t*)&ev_time); - if (success) { - success = MidiRingBufferBase<uint8_t>::full_read(sizeof(size_t), (uint8_t*)&ev_size); - } - - if (!success) { - std::cerr << "MRB: READ ERROR (time/size)" << std::endl; - continue; - } - - uint8_t status; - success = full_peek(sizeof(uint8_t), &status); - assert(success); // If this failed, buffer is corrupt, all hope is lost - - // Ignore event if it doesn't match channel filter - if (is_channel_event(status) && get_channel_mode() == FilterChannels) { - const uint8_t channel = status & 0x0F; - if ( !(get_channel_mask() & (1L << channel)) ) { - skip(ev_size); // Advance read pointer to next event - continue; - } - } - - if (ev_time >= start) { - - /*std::cerr << "MRB " << this << " - Reading event, time = " - << ev_time << " - " << start << " => " << ev_time - start - << ", size = " << ev_size << std::endl;*/ - - ev_time -= start; - - uint8_t* write_loc = dst.reserve(ev_time, ev_size); - if (write_loc == NULL) { - std::cerr << "MRB: Unable to reserve space in buffer, event skipped"; - continue; - } - - success = MidiRingBufferBase<uint8_t>::full_read(ev_size, write_loc); - - if (success) { - if (is_channel_event(status) && get_channel_mode() == ForceChannel) { - write_loc[0] = (write_loc[0] & 0xF0) | (get_channel_mask() & 0x0F); - } - ++count; - //printf("MRB - read event at time %lf\n", ev_time); - } else { - std::cerr << "MRB: READ ERROR (data)" << std::endl; - } - - } else { - printf("MRB (start %u) - Skipping event at (too early) time %f\n", start, ev_time); - } - } - - //printf("(R) read space: %zu\n", read_space()); - - return count; -} - - -} // namespace ARDOUR - -#endif // __ardour_midi_ring_buffer_h__ - diff --git a/libs/ardour/ardour/midi_source.h b/libs/ardour/ardour/midi_source.h deleted file mode 100644 index 997f3f9d69..0000000000 --- a/libs/ardour/ardour/midi_source.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - Copyright (C) 2006 Paul Davis - Written by Dave Robillard, 2006 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifndef __ardour_midi_source_h__ -#define __ardour_midi_source_h__ - -#include <string> - -#include <time.h> - -#include <glibmm/thread.h> - -#include <sigc++/signal.h> - -#include <ardour/source.h> -#include <ardour/ardour.h> -#include <ardour/buffer.h> -#include <ardour/midi_model.h> -#include <pbd/stateful.h> -#include <pbd/xml++.h> - -using std::string; - -namespace ARDOUR { - -class MidiRingBuffer; - -/** Source for MIDI data */ -class MidiSource : public Source -{ - public: - MidiSource (Session& session, string name); - MidiSource (Session& session, const XMLNode&); - virtual ~MidiSource (); - - /* Stub Readable interface */ - virtual nframes64_t read (Sample*, nframes64_t pos, nframes64_t cnt, int channel) const { return 0; } - virtual nframes64_t readable_length() const { return length(); } - virtual uint32_t n_channels () const { return 1; } - - // FIXME: integrate this with the Readable::read interface somehow - virtual nframes_t midi_read (MidiRingBuffer& dst, nframes_t start, nframes_t cnt, nframes_t stamp_offset, nframes_t negative_stamp_offset) const; - virtual nframes_t midi_write (MidiRingBuffer& src, nframes_t cnt); - - virtual void append_event_unlocked(EventTimeUnit unit, const MIDI::Event& ev) = 0; - - virtual void mark_for_remove() = 0; - virtual void mark_streaming_midi_write_started (NoteMode mode, nframes_t start_time); - virtual void mark_streaming_write_started (); - virtual void mark_streaming_write_completed (); - - uint64_t timeline_position () { return _timeline_position; } - void set_timeline_position (nframes_t when) { _timeline_position = when; } - - virtual void session_saved(); - - string captured_for() const { return _captured_for; } - void set_captured_for (string str) { _captured_for = str; } - - uint32_t read_data_count() const { return _read_data_count; } - uint32_t write_data_count() const { return _write_data_count; } - - static sigc::signal<void,MidiSource*> MidiSourceCreated; - - // Signal a range of recorded data is available for reading from model() - mutable sigc::signal<void,nframes_t,nframes_t> ViewDataRangeReady; - - XMLNode& get_state (); - int set_state (const XMLNode&); - - bool length_mutable() const { return true; } - - virtual void load_model(bool lock=true, bool force_reload=false) = 0; - virtual void destroy_model() = 0; - - void set_note_mode(NoteMode mode) { if (_model) _model->set_note_mode(mode); } - - boost::shared_ptr<MidiModel> model() { return _model; } - void set_model(boost::shared_ptr<MidiModel> m) { _model = m; } - - protected: - virtual int flush_header() = 0; - virtual int flush_footer() = 0; - - virtual nframes_t read_unlocked (MidiRingBuffer& dst, nframes_t start, nframes_t cnt, nframes_t stamp_offset, nframes_t negative_stamp_offset) const = 0; - virtual nframes_t write_unlocked (MidiRingBuffer& dst, nframes_t cnt) = 0; - - mutable Glib::Mutex _lock; - string _captured_for; - uint64_t _timeline_position; - mutable uint32_t _read_data_count; ///< modified in read() - mutable uint32_t _write_data_count; ///< modified in write() - - boost::shared_ptr<MidiModel> _model; - bool _writing; - - private: - bool file_changed (string path); -}; - -} - -#endif /* __ardour_midi_source_h__ */ diff --git a/libs/ardour/ardour/midi_stretch.h b/libs/ardour/ardour/midi_stretch.h deleted file mode 100644 index f4b8f1c618..0000000000 --- a/libs/ardour/ardour/midi_stretch.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - Copyright (C) 2007 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_midi_stretch_h__ -#define __ardour_midi_stretch_h__ - -#include <ardour/filter.h> - -namespace ARDOUR { - -class MidiStretch : public Filter { - public: - MidiStretch (ARDOUR::Session&, TimeFXRequest&); - ~MidiStretch (); - - int run (boost::shared_ptr<ARDOUR::Region>); - - private: - TimeFXRequest& _request; -}; - -} /* namespace ARDOUR */ - -#endif /* __ardour_midi_stretch_h__ */ diff --git a/libs/ardour/ardour/midi_track.h b/libs/ardour/ardour/midi_track.h deleted file mode 100644 index 500502ac4b..0000000000 --- a/libs/ardour/ardour/midi_track.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - Copyright (C) 2006 Paul Davis - Written by Dave Robillard - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifndef __ardour_midi_track_h__ -#define __ardour_midi_track_h__ - -#include <ardour/track.h> -#include <ardour/midi_ring_buffer.h> - -namespace ARDOUR -{ - -class Session; -class MidiDiskstream; -class MidiPlaylist; -class RouteGroup; - -class MidiTrack : public Track -{ -public: - MidiTrack (Session&, string name, Route::Flag f = Route::Flag (0), TrackMode m = Normal); - MidiTrack (Session&, const XMLNode&); - ~MidiTrack (); - - int roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, - nframes_t offset, int declick, bool can_record, bool rec_monitors_input); - - int no_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, - nframes_t offset, bool state_changing, bool can_record, bool rec_monitors_input); - - int silent_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, - nframes_t offset, bool can_record, bool rec_monitors_input); - - void process_output_buffers (BufferSet& bufs, - nframes_t start_frame, nframes_t end_frame, - nframes_t nframes, nframes_t offset, bool with_redirects, int declick, - bool meter); - - boost::shared_ptr<MidiDiskstream> midi_diskstream() const; - - int use_diskstream (string name); - int use_diskstream (const PBD::ID& id); - - void set_latency_delay (nframes_t); - - int export_stuff (BufferSet& bufs, - nframes_t nframes, nframes_t end_frame); - - void freeze (InterThreadInfo&); - void unfreeze (); - - void bounce (InterThreadInfo&); - void bounce_range (nframes_t start, nframes_t end, InterThreadInfo&); - - int set_state(const XMLNode& node); - - void midi_panic(void); - bool write_immediate_event(size_t size, const uint8_t* buf); - - struct MidiControl : public AutomationControl { - MidiControl(MidiTrack* route, boost::shared_ptr<AutomationList> al) - : AutomationControl (route->session(), al, al->parameter().to_string()) - , _route (route) - {} - - void set_value (float val); - - MidiTrack* _route; - }; - - NoteMode note_mode() const { return _note_mode; } - void set_note_mode (NoteMode m); - -protected: - - XMLNode& state (bool full); - - int _set_state (const XMLNode&, bool call_base); - -private: - - void write_controller_messages(MidiBuffer& buf, - nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset); - - int set_diskstream (boost::shared_ptr<MidiDiskstream> ds); - void set_state_part_two (); - void set_state_part_three (); - - MidiRingBuffer _immediate_events; - NoteMode _note_mode; -}; - -} /* namespace ARDOUR*/ - -#endif /* __ardour_midi_track_h__ */ diff --git a/libs/ardour/ardour/midi_util.h b/libs/ardour/ardour/midi_util.h deleted file mode 100644 index 6bcc6278e1..0000000000 --- a/libs/ardour/ardour/midi_util.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - Copyright (C) 2006 Paul Davis - Written by Dave Robillard, 2006 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_midi_util_h__ -#define __ardour_midi_util_h__ - -#include <midi++/events.h> - -namespace ARDOUR { - -/** Return the size of the given event NOT including the status byte, - * or -1 if unknown (eg sysex) - */ -static inline int -midi_event_size(unsigned char status) -{ - // if we have a channel event - if (status >= 0x80 && status < 0xF0) { - status &= 0xF0; // mask off the channel - } - - switch (status) { - case MIDI_CMD_NOTE_OFF: - case MIDI_CMD_NOTE_ON: - case MIDI_CMD_NOTE_PRESSURE: - case MIDI_CMD_CONTROL: - case MIDI_CMD_BENDER: - case MIDI_CMD_COMMON_SONG_POS: - return 2; - - case MIDI_CMD_PGM_CHANGE: - case MIDI_CMD_CHANNEL_PRESSURE: - case MIDI_CMD_COMMON_MTC_QUARTER: - case MIDI_CMD_COMMON_SONG_SELECT: - return 1; - - case MIDI_CMD_COMMON_TUNE_REQUEST: - case MIDI_CMD_COMMON_SYSEX_END: - case MIDI_CMD_COMMON_CLOCK: - case MIDI_CMD_COMMON_START: - case MIDI_CMD_COMMON_CONTINUE: - case MIDI_CMD_COMMON_STOP: - case MIDI_CMD_COMMON_SENSING: - case MIDI_CMD_COMMON_RESET: - return 0; - - case MIDI_CMD_COMMON_SYSEX: - return -1; - } - - return -1; -} - -} // namespace ARDOUR - -#endif /* __ardour_midi_util_h__ */ diff --git a/libs/ardour/ardour/mix.h b/libs/ardour/ardour/mix.h deleted file mode 100644 index 67779f0e07..0000000000 --- a/libs/ardour/ardour/mix.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - Copyright (C) 2005 Sampo Savolainen - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ -#ifndef __ardour_mix_h__ -#define __ardour_mix_h__ - -#include <ardour/types.h> -#include <ardour/utils.h> -#include <ardour/io.h> - -#if defined (ARCH_X86) && defined (BUILD_SSE_OPTIMIZATIONS) - -extern "C" { -/* SSE functions */ - float x86_sse_compute_peak (const ARDOUR::Sample * buf, nframes_t nsamples, float current); - void x86_sse_apply_gain_to_buffer (ARDOUR::Sample * buf, nframes_t nframes, float gain); - void x86_sse_mix_buffers_with_gain (ARDOUR::Sample * dst, const ARDOUR::Sample * src, nframes_t nframes, float gain); - void x86_sse_mix_buffers_no_gain (ARDOUR::Sample * dst, const ARDOUR::Sample * src, nframes_t nframes); -} - -void x86_sse_find_peaks (const ARDOUR::Sample * buf, nframes_t nsamples, float *min, float *max); - -/* debug wrappers for SSE functions */ - -float debug_compute_peak (const ARDOUR::Sample * buf, nframes_t nsamples, float current); -void debug_apply_gain_to_buffer (ARDOUR::Sample * buf, nframes_t nframes, float gain); -void debug_mix_buffers_with_gain (ARDOUR::Sample * dst, const ARDOUR::Sample * src, nframes_t nframes, float gain); -void debug_mix_buffers_no_gain (ARDOUR::Sample * dst, const ARDOUR::Sample * src, nframes_t nframes); - -#endif - -#if defined (__APPLE__) - -float veclib_compute_peak (const ARDOUR::Sample * buf, nframes_t nsamples, float current); -void veclib_find_peaks (const ARDOUR::Sample * buf, nframes_t nsamples, float *min, float *max); -void veclib_apply_gain_to_buffer (ARDOUR::Sample * buf, nframes_t nframes, float gain); -void veclib_mix_buffers_with_gain (ARDOUR::Sample * dst, const ARDOUR::Sample * src, nframes_t nframes, float gain); -void veclib_mix_buffers_no_gain (ARDOUR::Sample * dst, const ARDOUR::Sample * src, nframes_t nframes); - -#endif - -/* non-optimized functions */ - -float default_compute_peak (const ARDOUR::Sample * buf, nframes_t nsamples, float current); -void default_find_peaks (const ARDOUR::Sample * buf, nframes_t nsamples, float *min, float *max); -void default_apply_gain_to_buffer (ARDOUR::Sample * buf, nframes_t nframes, float gain); -void default_mix_buffers_with_gain (ARDOUR::Sample * dst, const ARDOUR::Sample * src, nframes_t nframes, float gain); -void default_mix_buffers_no_gain (ARDOUR::Sample * dst, const ARDOUR::Sample * src, nframes_t nframes); - -#endif /* __ardour_mix_h__ */ diff --git a/libs/ardour/ardour/named_selection.h b/libs/ardour/ardour/named_selection.h deleted file mode 100644 index 39ab524d4f..0000000000 --- a/libs/ardour/ardour/named_selection.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - Copyright (C) 2003 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_named_selection_h__ -#define __ardour_named_selection_h__ - -#include <string> -#include <list> -#include <boost/shared_ptr.hpp> - -#include <pbd/stateful.h> - -class XMLNode; - -namespace ARDOUR -{ -class Session; -class Playlist; - -struct NamedSelection : public PBD::Stateful -{ - NamedSelection (std::string, std::list<boost::shared_ptr<Playlist> >&); - NamedSelection (Session&, const XMLNode&); - virtual ~NamedSelection (); - - std::string name; - std::list<boost::shared_ptr<Playlist> > playlists; - - XMLNode& get_state (void); - - int set_state (const XMLNode&); - - static sigc::signal<void,NamedSelection*> NamedSelectionCreated; -}; - -}/* namespace ARDOUR */ - -#endif /* __ardour_named_selection_h__ */ - diff --git a/libs/ardour/ardour/noise.h b/libs/ardour/ardour/noise.h deleted file mode 100644 index f775fcce36..0000000000 --- a/libs/ardour/ardour/noise.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - 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 deleted file mode 100644 index 0f649b3370..0000000000 --- a/libs/ardour/ardour/note.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - Copyright (C) 2007 Paul Davis - Author: Dave Robillard - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_note_h__ -#define __ardour_note_h__ - -#include <stdint.h> -#include <midi++/event.h> - -namespace ARDOUR { - - -/** A MIDI Note. - * - * A note is (unfortunately) special and not just another MIDI::Event as it - * has a duration and two separate MIDI events (on and off). - */ -class Note { -public: - Note(uint8_t chan=0, double time=0, double dur=0, uint8_t note=0, uint8_t vel=0x40); - Note(const Note& copy); - ~Note(); - - const Note& operator=(const Note& copy); - - inline bool operator==(const Note& other) - { return time() == other.time() && - note() == other.note() && - duration() == other.duration() && - velocity() == other.velocity() && - channel() == other.channel(); - } - - inline double time() const { return _on_event.time(); } - inline double end_time() const { return _off_event.time(); } - inline uint8_t note() const { return _on_event.note(); } - inline uint8_t velocity() const { return _on_event.velocity(); } - inline double duration() const { return _off_event.time() - _on_event.time(); } - inline uint8_t channel() const { - assert(_on_event.channel() == _off_event.channel()); - return _on_event.channel(); - } - - inline void set_time(double t) { _off_event.time() = t + duration(); _on_event.time() = t; } - inline void set_note(uint8_t n) { _on_event.buffer()[1] = n; _off_event.buffer()[1] = n; } - inline void set_velocity(uint8_t n) { _on_event.buffer()[2] = n; } - inline void set_duration(double d) { _off_event.time() = _on_event.time() + d; } - inline void set_channel(uint8_t c) { _on_event.set_channel(c); _off_event.set_channel(c); } - - inline MIDI::Event& on_event() { return _on_event; } - inline MIDI::Event& off_event() { return _off_event; } - - inline const MIDI::Event& on_event() const { return _on_event; } - inline const MIDI::Event& off_event() const { return _off_event; } - -private: - // Event buffers are self-contained - MIDI::Event _on_event; - MIDI::Event _off_event; -}; - - -} // namespace ARDOUR - -#endif /* __ardour_note_h__ */ diff --git a/libs/ardour/ardour/osc.h b/libs/ardour/ardour/osc.h deleted file mode 100644 index 3f1ce03445..0000000000 --- a/libs/ardour/ardour/osc.h +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (C) 2006 Paul Davis - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - */ - -#ifndef ardour_osc_h -#define ardour_osc_h - -#include <string> - -#include <sys/time.h> -#include <pthread.h> - -#include <lo/lo.h> - -#include <sigc++/sigc++.h> - -#include <ardour/types.h> - -#include <control_protocol/basic_ui.h> - -namespace ARDOUR { - class Session; - class Route; - -class OSC : public BasicUI, public sigc::trackable -{ - public: - OSC (uint32_t port); - virtual ~OSC(); - - void set_session (ARDOUR::Session&); - int start (); - int stop (); - - private: - uint32_t _port; - volatile bool _ok; - volatile bool _shutdown; - lo_server _osc_server; - lo_server _osc_unix_server; - std::string _osc_unix_socket_path; - std::string _osc_url_file; - pthread_t _osc_thread; - int _request_pipe[2]; - - static void * _osc_receiver(void * arg); - void osc_receiver(); - - bool init_osc_thread (); - void terminate_osc_thread (); - void poke_osc_thread (); - - void register_callbacks (); - - void session_going_away (); - - std::string get_server_url (); - std::string get_unix_server_url (); - - int current_value (const char *path, const char *types, lo_arg **argv, int argc, void *data, void *user_data); - -#define PATH_CALLBACK(name) \ - static int _ ## name (const char *path, const char *types, lo_arg **argv, int argc, void *data, void *user_data) { \ - return static_cast<OSC*>(user_data)->cb_ ## name (path, types, argv, argc, data); \ - } \ - int cb_ ## name (const char *path, const char *types, lo_arg **argv, int argc, void *data) { \ - name (); \ - return 0; \ - } - - PATH_CALLBACK(add_marker); - PATH_CALLBACK(loop_toggle); - PATH_CALLBACK(goto_start); - PATH_CALLBACK(goto_end); - PATH_CALLBACK(rewind); - PATH_CALLBACK(ffwd); - PATH_CALLBACK(transport_stop); - PATH_CALLBACK(transport_play); - PATH_CALLBACK(save_state); - PATH_CALLBACK(prev_marker); - PATH_CALLBACK(next_marker); - PATH_CALLBACK(undo); - PATH_CALLBACK(redo); - PATH_CALLBACK(toggle_punch_in); - PATH_CALLBACK(toggle_punch_out); - PATH_CALLBACK(rec_enable_toggle); - PATH_CALLBACK(toggle_all_rec_enables); - -#define PATH_CALLBACK1(name,type) \ - static int _ ## name (const char *path, const char *types, lo_arg **argv, int argc, void *data, void *user_data) { \ - return static_cast<OSC*>(user_data)->cb_ ## name (path, types, argv, argc, data); \ - } \ - int cb_ ## name (const char *path, const char *types, lo_arg **argv, int argc, void *data) { \ - if (argc > 0) { \ - name (argv[0]->type); \ - }\ - return 0; \ - } - - PATH_CALLBACK1(set_transport_speed,f); -}; - -} - -#endif // ardour_osc_h diff --git a/libs/ardour/ardour/panner.h b/libs/ardour/ardour/panner.h deleted file mode 100644 index 2559eed003..0000000000 --- a/libs/ardour/ardour/panner.h +++ /dev/null @@ -1,299 +0,0 @@ -/* - Copyright (C) 2004 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_panner_h__ -#define __ardour_panner_h__ - -#include <cmath> -#include <cassert> -#include <vector> -#include <string> -#include <iostream> -#include <sigc++/signal.h> - -#include <pbd/stateful.h> -#include <pbd/controllable.h> - -#include <ardour/types.h> -#include <ardour/curve.h> -#include <ardour/automation_control.h> - -using std::istream; -using std::ostream; - -namespace ARDOUR { - -class Session; -class Panner; -class BufferSet; -class AudioBuffer; - -class StreamPanner : public sigc::trackable, public PBD::Stateful -{ - public: - StreamPanner (Panner& p, Parameter param); - ~StreamPanner (); - - void set_muted (bool yn); - bool muted() const { return _muted; } - - void set_position (float x, bool link_call = false); - void set_position (float x, float y, bool link_call = false); - void set_position (float x, float y, float z, bool link_call = false); - - void get_position (float& xpos) const { xpos = x; } - void get_position (float& xpos, float& ypos) const { xpos = x; ypos = y; } - void get_position (float& xpos, float& ypos, float& zpos) const { xpos = x; ypos = y; zpos = z; } - - void get_effective_position (float& xpos) const { xpos = effective_x; } - void get_effective_position (float& xpos, float& ypos) const { xpos = effective_x; ypos = effective_y; } - void get_effective_position (float& xpos, float& ypos, float& zpos) const { xpos = effective_x; ypos = effective_y; zpos = effective_z; } - - /* the basic StreamPanner API */ - - virtual void distribute (AudioBuffer& src, BufferSet& obufs, gain_t gain_coeff, nframes_t nframes) = 0; - virtual void distribute_automated (AudioBuffer& src, BufferSet& obufs, - nframes_t start, nframes_t end, nframes_t nframes, pan_t** buffers) = 0; - - boost::shared_ptr<AutomationControl> pan_control() { return _control; } - - sigc::signal<void> Changed; /* for position */ - sigc::signal<void> StateChanged; /* for mute */ - - int set_state (const XMLNode&); - virtual XMLNode& state (bool full_state) = 0; - - Panner & get_parent() { return parent; } - - /* old school automation loading */ - - virtual int load (istream&, string path, uint32_t&) = 0; - - protected: - friend class Panner; - Panner& parent; - - float x; - float y; - float z; - - /* these are for automation. they store the last value - used by the most recent process() cycle. - */ - - float effective_x; - float effective_y; - float effective_z; - - bool _muted; - - struct PanControllable : public AutomationControl { - PanControllable (Session& s, std::string name, StreamPanner& p, Parameter param) - : AutomationControl (s, boost::shared_ptr<AutomationList>(new AutomationList( - param, 0.0, 1.0, 0.5)), name) - , panner (p) { assert(param.type() != NullAutomation); } - - StreamPanner& panner; - - void set_value (float); - float get_value (void) const; - bool can_send_feedback() const; - }; - - boost::shared_ptr<PanControllable> _control; - - void add_state (XMLNode&); - virtual void update () = 0; -}; - -class BaseStereoPanner : public StreamPanner -{ - public: - BaseStereoPanner (Panner&, Parameter param); - ~BaseStereoPanner (); - - /* this class just leaves the pan law itself to be defined - by the update(), distribute_automated() - methods. derived classes also need a factory method - and a type name. See EqualPowerStereoPanner as an example. - */ - - void distribute (AudioBuffer& src, BufferSet& obufs, gain_t gain_coeff, nframes_t nframes); - - /* old school automation loading */ - - int load (istream&, string path, uint32_t&); - - protected: - float left; - float right; - float desired_left; - float desired_right; - float left_interp; - float right_interp; -}; - -class EqualPowerStereoPanner : public BaseStereoPanner -{ - public: - EqualPowerStereoPanner (Panner&, Parameter param); - ~EqualPowerStereoPanner (); - - void distribute_automated (AudioBuffer& src, BufferSet& obufs, - nframes_t start, nframes_t end, nframes_t nframes, pan_t** buffers); - - void get_current_coefficients (pan_t*) const; - void get_desired_coefficients (pan_t*) const; - - static StreamPanner* factory (Panner&, Parameter param); - static string name; - - XMLNode& state (bool full_state); - XMLNode& get_state (void); - int set_state (const XMLNode&); - - private: - void update (); -}; - -class Multi2dPanner : public StreamPanner -{ - public: - Multi2dPanner (Panner& parent, Parameter); - ~Multi2dPanner (); - - void distribute (AudioBuffer& src, BufferSet& obufs, gain_t gain_coeff, nframes_t nframes); - void distribute_automated (AudioBuffer& src, BufferSet& obufs, - nframes_t start, nframes_t end, nframes_t nframes, pan_t** buffers); - - static StreamPanner* factory (Panner&, Parameter); - static string name; - - XMLNode& state (bool full_state); - XMLNode& get_state (void); - int set_state (const XMLNode&); - - /* old school automation loading */ - - int load (istream&, string path, uint32_t&); - - private: - void update (); -}; - -class Panner : public std::vector<StreamPanner*>, public PBD::Stateful, public sigc::trackable -{ - public: - struct Output { - float x; - float y; - pan_t current_pan; - pan_t desired_pan; - - Output (float xp, float yp) - : x (xp), y (yp), current_pan (0.0f), desired_pan (0.f) {} - - }; - - Panner (string name, Session&); - virtual ~Panner (); - - /// The fundamental Panner function - void distribute(BufferSet& src, BufferSet& dest, nframes_t start_frame, nframes_t end_frames, nframes_t nframes, nframes_t offset); - - bool bypassed() const { return _bypassed; } - void set_bypassed (bool yn); - - StreamPanner* add (); - void remove (uint32_t which); - void clear (); - void reset (uint32_t noutputs, uint32_t npans); - - void snapshot (nframes_t now); - void transport_stopped (nframes_t frame); - - void clear_automation (); - - void set_automation_state (AutoState); - AutoState automation_state() const; - void set_automation_style (AutoStyle); - AutoStyle automation_style() const; - bool touching() const; - - XMLNode& get_state (void); - XMLNode& state (bool full); - int set_state (const XMLNode&); - - sigc::signal<void> Changed; - - static bool equivalent (pan_t a, pan_t b) { - return fabsf (a - b) < 0.002; // about 1 degree of arc for a stereo panner - } - - void move_output (uint32_t, float x, float y); - uint32_t nouts() const { return outputs.size(); } - Output& output (uint32_t n) { return outputs[n]; } - - std::vector<Output> outputs; - Session& session() const { return _session; } - - enum LinkDirection { - SameDirection, - OppositeDirection - }; - - LinkDirection link_direction() const { return _link_direction; } - void set_link_direction (LinkDirection); - - bool linked() const { return _linked; } - void set_linked (bool yn); - - sigc::signal<void> LinkStateChanged; - sigc::signal<void> StateChanged; /* for bypass */ - - /* only StreamPanner should call these */ - - void set_position (float x, StreamPanner& orig); - void set_position (float x, float y, StreamPanner& orig); - void set_position (float x, float y, float z, StreamPanner& orig); - - /* old school automation */ - - int load (); - - private: - void distribute_no_automation(BufferSet& src, BufferSet& dest, nframes_t nframes, nframes_t offset, gain_t gain_coeff); - - Session& _session; - uint32_t current_outs; - bool _linked; - bool _bypassed; - LinkDirection _link_direction; - - static float current_automation_version_number; - - /* old school automation handling */ - - std::string automation_path; - void set_name (std::string); -}; - -} // namespace ARDOUR - -#endif /*__ardour_panner_h__ */ diff --git a/libs/ardour/ardour/parameter.h b/libs/ardour/ardour/parameter.h deleted file mode 100644 index b86174aa0a..0000000000 --- a/libs/ardour/ardour/parameter.h +++ /dev/null @@ -1,168 +0,0 @@ -/* - Copyright (C) 2007 Paul Davis - Author: Dave Robillard - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the Free - Software Foundation; either version 2 of the License, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifndef __ardour_parameter_h__ -#define __ardour_parameter_h__ - -#include <string> -#include <pbd/compose.h> -#include <pbd/error.h> -#include <ardour/types.h> - -namespace ARDOUR { - - -/** ID of an automatable parameter. - * - * A given automatable object has a number of automatable parameters. This is - * the unique ID for those parameters. Anything automatable (AutomationList, - * Curve) must have an ID unique with respect to it's Automatable parent. - * - * A parameter ID has two parts, a type and an int (only used by some types). - * - * This is a bit more ugly than it could be, due to using the existing/legacy - * ARDOUR::AutomationType: GainAutomation, PanAutomation, SoloAutomation, - * and MuteAutomation use only the type(), but PluginAutomation and - * MidiCCAutomation use the id() as port number and CC number, respectively. - * - * Future types may use a string or URI or whatever, as long as these are - * comparable anything may be added. ints are best as these should be fast to - * copy and compare with one another. - */ -class Parameter -{ -public: - Parameter(AutomationType type = NullAutomation, uint32_t id=0, uint8_t channel=0) - : _type(type), _id(id), _channel(channel) - {} - - Parameter(const std::string& str); - - inline AutomationType type() const { return _type; } - inline uint32_t id() const { return _id; } - inline uint8_t channel() const { return _channel; } - - /** - * Equivalence operator - * It is obvious from the definition that this operator - * is transitive, as required by stict weak ordering - * (see: http://www.sgi.com/tech/stl/StrictWeakOrdering.html) - */ - inline bool operator==(const Parameter& id) const { - return (_type == id._type && _id == id._id && _channel == id._channel); - } - - /** Strict weak ordering - * (see: http://www.sgi.com/tech/stl/StrictWeakOrdering.html) - * This is necessary so that std::set works): - * Sort Parameters first according to type then to id and lastly to channel. - * - * Proof: - * <ol> - * <li>Irreflexivity: f(x, x) is false because of the irreflexivity of \c < in each branch.</li> - * - * <li>Antisymmetry: given x != y, f(x, y) implies !f(y, x) because of the same - * property of \c < in each branch and the symmetry of operator==. </li> - * - * <li>Transitivity: let f(x, y) and f(y, z) be true. We prove by assuming the contrary, - * that f(x, z) does not hold. - * That would imply exactly one of the following: - * <ol> - * <li> x == z which contradicts the assumption f(x, y) and f(y, x) - * because of antisymmetry. - * </li> - * <li> f(z, x) is true. That would imply that one of the ivars (we call it i) - * of x is greater than the same ivar in z while all "previous" ivars - * are equal. That would imply that also in y all those "previous" - * ivars are equal and because if x.i > z.i it is impossible - * that there is an y that satisfies x.i < y.i < z.i at the same - * time which contradicts the assumption. - * </li> - * </ol> - * </li> - * </ol> - */ - - inline bool operator<(const Parameter& id) const { -#ifndef NDEBUG - if (_type == NullAutomation) - PBD::warning << "Uninitialized Parameter compared." << endmsg; -#endif - if (_type < id._type) { - return true; - } else if (_type == id._type && _id < id._id) { - return true; - } else if (_id == id._id && _channel < id._channel) { - return true; - } - - return false; - } - - inline operator bool() const { return (_type != 0); } - - std::string to_string() const; - - /* The below properties are only used for CC right now, but unchanging properties - * of parameters (rather than changing parameters of automation lists themselves) - * should be moved here */ - - inline double min() const { - switch(_type) { - case MidiCCAutomation: - case MidiPgmChangeAutomation: - case MidiPitchBenderAutomation: - case MidiChannelAftertouchAutomation: - return 0.0; - - default: - return DBL_MIN; - } - } - - inline double max() const { - switch(_type) { - case MidiCCAutomation: - case MidiPgmChangeAutomation: - case MidiChannelAftertouchAutomation: - return 127.0; - case MidiPitchBenderAutomation: - return 16383.0; - - default: - return DBL_MAX; - } - } - - inline bool is_integer() const { - return (_type >= MidiCCAutomation && _type <= MidiChannelAftertouchAutomation); - } - -private: - // default copy constructor is ok - AutomationType _type; - uint32_t _id; - uint8_t _channel; -}; - - -} // namespace ARDOUR - -#endif // __ardour_parameter_h__ - diff --git a/libs/ardour/ardour/pcm_utils.h b/libs/ardour/ardour/pcm_utils.h deleted file mode 100644 index 5e6436cc94..0000000000 --- a/libs/ardour/ardour/pcm_utils.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - 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 deleted file mode 100644 index bbec40eea7..0000000000 --- a/libs/ardour/ardour/peak.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - Copyright (C) 2000-2007 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_peak_h__ -#define __ardour_peak_h__ - -#include <cmath> -#include <ardour/types.h> -#include <ardour/utils.h> - -static inline float -default_compute_peak (const ARDOUR::Sample * const buf, nframes_t nsamples, float current) -{ - for (nframes_t i = 0; i < nsamples; ++i) { - current = f_max (current, fabsf (buf[i])); - } - return current; -} - -#endif /* __ardour_peak_h__ */ diff --git a/libs/ardour/ardour/pitch.h b/libs/ardour/ardour/pitch.h deleted file mode 100644 index 38d8380f5d..0000000000 --- a/libs/ardour/ardour/pitch.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - Copyright (C) 2007 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_pitch_h__ -#define __ardour_pitch_h__ - -#include <ardour/filter.h> - -namespace ARDOUR { - class AudioRegion; -} - -#ifdef USE_RUBBERBAND - -#include <ardour/rb_effect.h> - -namespace ARDOUR { - -class Pitch : public RBEffect { - public: - Pitch (ARDOUR::Session&, TimeFXRequest&); - ~Pitch () {} -}; - -} /* namespace */ - -# else - -namespace ARDOUR { - -class Pitch : public Filter { - public: - Pitch (ARDOUR::Session&, TimeFXRequest&); - ~Pitch () {} - - int run (boost::shared_ptr<ARDOUR::Region>); - - private: - TimeFXRequest& tsr; -}; - -} /* namespace */ - -#endif - -#endif /* __ardour_pitch_h__ */ diff --git a/libs/ardour/ardour/playlist.h b/libs/ardour/ardour/playlist.h deleted file mode 100644 index ad7210f48f..0000000000 --- a/libs/ardour/ardour/playlist.h +++ /dev/null @@ -1,287 +0,0 @@ -/* - Copyright (C) 2000 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_playlist_h__ -#define __ardour_playlist_h__ - -#include <string> -#include <set> -#include <map> -#include <list> -#include <boost/shared_ptr.hpp> -#include <boost/enable_shared_from_this.hpp> - -#include <sys/stat.h> - -#include <glib.h> - -#include <sigc++/signal.h> - -#include <pbd/undo.h> -#include <pbd/stateful.h> -#include <pbd/statefuldestructible.h> - -#include <ardour/ardour.h> -#include <ardour/session_object.h> -#include <ardour/crossfade_compare.h> -#include <ardour/location.h> -#include <ardour/data_type.h> - -namespace ARDOUR { - -class Session; -class Region; - -class Playlist : public SessionObject, public boost::enable_shared_from_this<Playlist> { - public: - typedef list<boost::shared_ptr<Region> > RegionList; - - Playlist (Session&, const XMLNode&, DataType type, bool hidden = false); - Playlist (Session&, string name, DataType type, bool hidden = false); - Playlist (boost::shared_ptr<const Playlist>, string name, bool hidden = false); - Playlist (boost::shared_ptr<const Playlist>, nframes_t start, nframes_t cnt, string name, bool hidden = false); - - virtual ~Playlist (); - - void set_region_ownership (); - - virtual void clear (bool with_signals=true); - virtual void dump () const; - - void use(); - void release(); - bool used () const { return _refcnt != 0; } - - bool set_name (const string& str); - - const DataType& data_type() const { return _type; } - - bool frozen() const { return _frozen; } - void set_frozen (bool yn); - - bool hidden() const { return _hidden; } - bool empty() const; - uint32_t n_regions() const; - nframes_t get_maximum_extent () const; - layer_t top_layer() const; - - EditMode get_edit_mode() const { return _edit_mode; } - void set_edit_mode (EditMode); - - /* Editing operations */ - - void add_region (boost::shared_ptr<Region>, nframes_t position, float times = 1); - void remove_region (boost::shared_ptr<Region>); - void get_equivalent_regions (boost::shared_ptr<Region>, std::vector<boost::shared_ptr<Region> >&); - void get_region_list_equivalent_regions (boost::shared_ptr<Region>, std::vector<boost::shared_ptr<Region> >&); - void replace_region (boost::shared_ptr<Region> old, boost::shared_ptr<Region> newr, nframes_t pos); - void split_region (boost::shared_ptr<Region>, nframes_t position); - void split (nframes64_t at); - void shift (nframes64_t at, nframes64_t distance, bool move_intersected, bool ignore_music_glue); - void partition (nframes_t start, nframes_t end, bool just_top_level); - void duplicate (boost::shared_ptr<Region>, nframes_t position, float times); - void nudge_after (nframes_t start, nframes_t distance, bool forwards); - void shuffle (boost::shared_ptr<Region>, int dir); - void update_after_tempo_map_change (); - - boost::shared_ptr<Playlist> cut (list<AudioRange>&, bool result_is_hidden = true); - boost::shared_ptr<Playlist> copy (list<AudioRange>&, bool result_is_hidden = true); - int paste (boost::shared_ptr<Playlist>, nframes_t position, float times); - - RegionList* regions_at (nframes_t frame); - RegionList* regions_touched (nframes_t start, nframes_t end); - RegionList* regions_to_read (nframes_t start, nframes_t end); - boost::shared_ptr<Region> find_region (const PBD::ID&) const; - boost::shared_ptr<Region> top_region_at (nframes_t frame); - boost::shared_ptr<Region> find_next_region (nframes_t frame, RegionPoint point, int dir); - nframes64_t find_next_region_boundary (nframes64_t frame, int dir); - bool region_is_shuffle_constrained (boost::shared_ptr<Region>); - - nframes64_t find_next_transient (nframes64_t position, int dir); - - template<class T> void foreach_region (T *t, void (T::*func)(boost::shared_ptr<Region>, void *), void *arg); - template<class T> void foreach_region (T *t, void (T::*func)(boost::shared_ptr<Region>)); - - XMLNode& get_state (); - int set_state (const XMLNode&); - XMLNode& get_template (); - - sigc::signal<void,bool> InUse; - sigc::signal<void> Modified; - sigc::signal<void> NameChanged; - sigc::signal<void> LengthChanged; - - static string bump_name (string old_name, Session&); - - void freeze (); - void thaw (); - - void raise_region (boost::shared_ptr<Region>); - void lower_region (boost::shared_ptr<Region>); - void raise_region_to_top (boost::shared_ptr<Region>); - void lower_region_to_bottom (boost::shared_ptr<Region>); - - uint32_t read_data_count() const { return _read_data_count; } - - const PBD::ID& get_orig_diskstream_id () const { return _orig_diskstream_id; } - void set_orig_diskstream_id (const PBD::ID& did) { _orig_diskstream_id = did; } - - /* destructive editing */ - - virtual bool destroy_region (boost::shared_ptr<Region>) = 0; - - /* special case function used by UI selection objects, which have playlists that actually own the regions - within them. - */ - - void drop_regions (); - - protected: - friend class Session; - - protected: - struct RegionLock { - RegionLock (Playlist *pl, bool do_block_notify = true) : playlist (pl), block_notify (do_block_notify) { - playlist->region_lock.lock(); - if (block_notify) { - playlist->delay_notifications(); - } - } - ~RegionLock() { - playlist->region_lock.unlock(); - if (block_notify) { - playlist->release_notifications (); - } - } - Playlist *playlist; - bool block_notify; - }; - - friend class RegionLock; - - RegionList regions; /* the current list of regions in the playlist */ - std::set<boost::shared_ptr<Region> > all_regions; /* all regions ever added to this playlist */ - DataType _type; - mutable gint block_notifications; - mutable gint ignore_state_changes; - mutable Glib::Mutex region_lock; - std::set<boost::shared_ptr<Region> > pending_adds; - std::set<boost::shared_ptr<Region> > pending_removes; - RegionList pending_bounds; - bool pending_modified; - bool pending_length; - bool save_on_thaw; - string last_save_reason; - uint32_t in_set_state; - bool first_set_state; - bool _hidden; - bool _splicing; - bool _shuffling; - bool _nudging; - uint32_t _refcnt; - EditMode _edit_mode; - bool in_flush; - bool in_partition; - bool _frozen; - uint32_t subcnt; - uint32_t _read_data_count; - PBD::ID _orig_diskstream_id; - uint64_t layer_op_counter; - nframes_t freeze_length; - - void init (bool hide); - - bool holding_state () const { - return g_atomic_int_get (&block_notifications) != 0 || - g_atomic_int_get (&ignore_state_changes) != 0; - } - - /* prevent the compiler from ever generating these */ - - Playlist (const Playlist&); - Playlist (Playlist&); - - void delay_notifications (); - void release_notifications (); - virtual void flush_notifications (); - - void notify_region_removed (boost::shared_ptr<Region>); - void notify_region_added (boost::shared_ptr<Region>); - void notify_length_changed (); - void notify_layering_changed (); - void notify_modified (); - void notify_state_changed (Change); - - void mark_session_dirty(); - - void region_changed_proxy (Change, boost::weak_ptr<Region>); - virtual bool region_changed (Change, boost::shared_ptr<Region>); - - void region_bounds_changed (Change, boost::shared_ptr<Region>); - void region_deleted (boost::shared_ptr<Region>); - - void sort_regions (); - - void possibly_splice (nframes_t at, nframes64_t distance, boost::shared_ptr<Region> exclude = boost::shared_ptr<Region>()); - void possibly_splice_unlocked(nframes_t at, nframes64_t distance, boost::shared_ptr<Region> exclude = boost::shared_ptr<Region>()); - - void core_splice (nframes_t at, nframes64_t distance, boost::shared_ptr<Region> exclude); - void splice_locked (nframes_t at, nframes64_t distance, boost::shared_ptr<Region> exclude); - void splice_unlocked (nframes_t at, nframes64_t distance, boost::shared_ptr<Region> exclude); - - virtual void finalize_split_region (boost::shared_ptr<Region> original, boost::shared_ptr<Region> left, boost::shared_ptr<Region> right) {} - - virtual void check_dependents (boost::shared_ptr<Region> region, bool norefresh) {} - virtual void refresh_dependents (boost::shared_ptr<Region> region) {} - virtual void remove_dependents (boost::shared_ptr<Region> region) {} - - virtual XMLNode& state (bool); - - boost::shared_ptr<Region> region_by_id (PBD::ID); - - void add_region_internal (boost::shared_ptr<Region>, nframes_t position); - - int remove_region_internal (boost::shared_ptr<Region>); - RegionList *find_regions_at (nframes_t frame); - void copy_regions (RegionList&) const; - void partition_internal (nframes_t start, nframes_t end, bool cutting, RegionList& thawlist); - - nframes_t _get_maximum_extent() const; - - boost::shared_ptr<Playlist> cut_copy (boost::shared_ptr<Playlist> (Playlist::*pmf)(nframes_t, nframes_t, bool), - list<AudioRange>& ranges, bool result_is_hidden); - boost::shared_ptr<Playlist> cut (nframes_t start, nframes_t cnt, bool result_is_hidden); - boost::shared_ptr<Playlist> copy (nframes_t start, nframes_t cnt, bool result_is_hidden); - - int move_region_to_layer (layer_t, boost::shared_ptr<Region> r, int dir); - void relayer (); - - void unset_freeze_parent (Playlist*); - void unset_freeze_child (Playlist*); - - void timestamp_layer_op (boost::shared_ptr<Region>); - - void _split_region (boost::shared_ptr<Region>, nframes_t position); -}; - -} /* namespace ARDOUR */ - -#endif /* __ardour_playlist_h__ */ - - diff --git a/libs/ardour/ardour/playlist_factory.h b/libs/ardour/ardour/playlist_factory.h deleted file mode 100644 index a28e2611d9..0000000000 --- a/libs/ardour/ardour/playlist_factory.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - Copyright (C) 2000-2007 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_playlist_factory_h__ -#define __ardour_playlist_factory_h__ - -#include <ardour/playlist.h> - -class XMLNode; - -namespace ARDOUR { - -class Session; - -class PlaylistFactory { - - public: - static sigc::signal<void,boost::shared_ptr<Playlist> > PlaylistCreated; - - static boost::shared_ptr<Playlist> create (Session&, const XMLNode&, bool hidden = false); - static boost::shared_ptr<Playlist> create (DataType type, Session&, string name, bool hidden = false); - static boost::shared_ptr<Playlist> create (boost::shared_ptr<const Playlist>, string name, bool hidden = false); - static boost::shared_ptr<Playlist> create (boost::shared_ptr<const Playlist>, nframes_t start, nframes_t cnt, string name, bool hidden = false); -}; - -} - -#endif /* __ardour_playlist_factory_h__ */ diff --git a/libs/ardour/ardour/playlist_templates.h b/libs/ardour/ardour/playlist_templates.h deleted file mode 100644 index bf072a71c1..0000000000 --- a/libs/ardour/ardour/playlist_templates.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - Copyright (C) 2003 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_playlist_templates_h__ -#define __ardour_playlist_templates_h__ - -namespace ARDOUR { - -template<class T> void AudioPlaylist::foreach_crossfade (T *t, void (T::*func)(boost::shared_ptr<Crossfade>)) { - RegionLock rlock (this, false); - for (Crossfades::iterator i = _crossfades.begin(); i != _crossfades.end(); i++) { - (t->*func) (*i); - } -} - -template<class T> void Playlist::foreach_region (T *t, void (T::*func)(boost::shared_ptr<Region>, void *), void *arg) { - RegionLock rlock (this, false); - for (RegionList::iterator i = regions.begin(); i != regions.end(); i++) { - (t->*func) ((*i), arg); - } - } - -template<class T> void Playlist::foreach_region (T *t, void (T::*func)(boost::shared_ptr<Region>)) { - RegionLock rlock (this, false); - for (RegionList::const_iterator i = regions.begin(); i != regions.end(); i++) { - (t->*func) (*i); - } -} - -} - -#endif /* __ardour_playlist_templates_h__ */ diff --git a/libs/ardour/ardour/plugin.h b/libs/ardour/ardour/plugin.h deleted file mode 100644 index 73f89f1a91..0000000000 --- a/libs/ardour/ardour/plugin.h +++ /dev/null @@ -1,174 +0,0 @@ -/* - Copyright (C) 2000-2006 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_plugin_h__ -#define __ardour_plugin_h__ - -#include <boost/shared_ptr.hpp> -#include <sigc++/signal.h> -#include <glibmm/ustring.h> - -#include <pbd/statefuldestructible.h> -#include <pbd/controllable.h> - -#include <jack/types.h> -#include <ardour/types.h> -#include <ardour/chan_count.h> -#include <ardour/cycles.h> -#include <ardour/latent.h> -#include <ardour/parameter.h> -#include <ardour/plugin_insert.h> - -#include <vector> -#include <set> -#include <map> - -using std::string; -using std::vector; -using std::set; -using std::map; - -namespace ARDOUR { - -class AudioEngine; -class Session; -class BufferSet; - -class Plugin; - -typedef boost::shared_ptr<Plugin> PluginPtr; - -class PluginInfo { - public: - PluginInfo () { } - PluginInfo (const PluginInfo &o) - : name(o.name), - category (o.category), - creator (o.creator), - path (o.path), - n_inputs(o.n_inputs), - n_outputs(o.n_outputs), - unique_id(o.unique_id), - index(o.index) {} - virtual ~PluginInfo () { } - - string name; - string category; - Glib::ustring creator; - Glib::ustring path; - ChanCount n_inputs; - ChanCount n_outputs; - ARDOUR::PluginType type; - - std::string unique_id; - - virtual PluginPtr load (Session& session) = 0; - - protected: - friend class PluginManager; - uint32_t index; -}; - -typedef boost::shared_ptr<PluginInfo> PluginInfoPtr; -typedef std::list<PluginInfoPtr> PluginInfoList; - -class Plugin : public PBD::StatefulDestructible, public Latent -{ - public: - Plugin (ARDOUR::AudioEngine&, ARDOUR::Session&); - Plugin (const Plugin&); - virtual ~Plugin (); - - struct ParameterDescriptor { - - /* essentially a union of LADSPA and VST info */ - - bool integer_step; - bool toggled; - bool logarithmic; - bool sr_dependent; - string label; - float lower; - float upper; - float step; - float smallstep; - float largestep; - bool min_unbound; - bool max_unbound; - }; - - virtual std::string unique_id() const = 0; - virtual const char * label() const = 0; - virtual const char * name() const = 0; - virtual const char * maker() const = 0; - virtual uint32_t parameter_count () const = 0; - virtual float default_value (uint32_t port) = 0; - virtual float get_parameter(uint32_t which) const = 0; - - virtual int get_parameter_descriptor (uint32_t which, ParameterDescriptor&) const = 0; - virtual uint32_t nth_parameter (uint32_t which, bool& ok) const = 0; - virtual void activate () = 0; - virtual void deactivate () = 0; - virtual void set_block_size (nframes_t nframes) = 0; - - virtual int connect_and_run (BufferSet& bufs, uint32_t& in, uint32_t& out, nframes_t nframes, nframes_t offset) = 0; - - virtual std::set<Parameter> automatable() const = 0; - virtual string describe_parameter (Parameter) = 0; - virtual string state_node_name() const = 0; - virtual void print_parameter (uint32_t, char*, uint32_t len) const = 0; - - virtual bool parameter_is_audio(uint32_t) const = 0; - virtual bool parameter_is_control(uint32_t) const = 0; - virtual bool parameter_is_input(uint32_t) const = 0; - virtual bool parameter_is_output(uint32_t) const = 0; - - virtual bool save_preset(string name) = 0; - virtual bool load_preset (const string preset_label); - virtual std::vector<std::string> get_presets(); - - virtual bool has_editor() const = 0; - - PluginInfoPtr get_info() { return _info; } - void set_info (const PluginInfoPtr inf) { _info = inf; } - - ARDOUR::AudioEngine& engine() const { return _engine; } - ARDOUR::Session& session() const { return _session; } - - void set_cycles (uint32_t c) { _cycles = c; } - cycles_t cycles() const { return _cycles; } - - protected: - friend class PluginInsert; - friend struct PluginInsert::PluginControl; - virtual void set_parameter (uint32_t which, float val) = 0; - - ARDOUR::AudioEngine& _engine; - ARDOUR::Session& _session; - PluginInfoPtr _info; - uint32_t _cycles; - map<string,string> presets; - bool save_preset(string name, string domain /* vst, ladspa etc. */); -}; - -PluginPtr find_plugin(ARDOUR::Session&, string unique_id, ARDOUR::PluginType); - -} // namespace ARDOUR - -#endif /* __ardour_plugin_h__ */ diff --git a/libs/ardour/ardour/plugin_insert.h b/libs/ardour/ardour/plugin_insert.h deleted file mode 100644 index 42c53c487c..0000000000 --- a/libs/ardour/ardour/plugin_insert.h +++ /dev/null @@ -1,131 +0,0 @@ -/* - Copyright (C) 2000,2007 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_plugin_insert_h__ -#define __ardour_plugin_insert_h__ - -#include <vector> -#include <string> - -#include <sigc++/signal.h> -#include <ardour/ardour.h> -#include <ardour/types.h> -#include <ardour/processor.h> -#include <ardour/automation_event.h> - -class XMLNode; - -namespace ARDOUR { - -class Session; -class Route; -class Plugin; - -/** Plugin inserts: send data through a plugin - */ -class PluginInsert : public Processor -{ - public: - PluginInsert (Session&, boost::shared_ptr<Plugin>, Placement); - PluginInsert (Session&, const XMLNode&); - PluginInsert (const PluginInsert&); - ~PluginInsert (); - - static const string port_automation_node_name; - - XMLNode& state(bool); - XMLNode& get_state(void); - int set_state(const XMLNode&); - - void run_in_place (BufferSet& in, nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset); - void silence (nframes_t nframes, nframes_t offset); - - void activate (); - void deactivate (); - - void set_block_size (nframes_t nframes); - - ChanCount output_streams() const; - ChanCount input_streams() const; - ChanCount natural_output_streams() const; - ChanCount natural_input_streams() const; - - bool set_count (uint32_t num); - uint32_t get_count () const { return _plugins.size(); } - - virtual bool can_support_input_configuration (ChanCount in) const; - virtual ChanCount output_for_input_configuration (ChanCount in) const; - virtual bool configure_io (ChanCount in, ChanCount out); - - bool is_generator() const; - - void set_parameter (Parameter param, float val); - float get_parameter (Parameter param); - - float default_parameter_value (Parameter param); - - struct PluginControl : public AutomationControl - { - PluginControl (PluginInsert& p, boost::shared_ptr<AutomationList> list); - - void set_value (float val); - float get_value (void) const; - - private: - PluginInsert& _plugin; - boost::shared_ptr<AutomationList> _list; - bool _logarithmic; - bool _toggled; - }; - - boost::shared_ptr<Plugin> plugin(uint32_t num=0) const { - if (num < _plugins.size()) { - return _plugins[num]; - } else { - return _plugins[0]; // we always have one - } - } - - PluginType type (); - - string describe_parameter (Parameter param); - - nframes_t signal_latency() const; - - private: - - void parameter_changed (Parameter, float); - - std::vector<boost::shared_ptr<Plugin> > _plugins; - - void automation_run (BufferSet& bufs, nframes_t nframes, nframes_t offset); - void connect_and_run (BufferSet& bufs, nframes_t nframes, nframes_t offset, bool with_auto, nframes_t now = 0); - - void init (); - void set_automatable (); - void auto_state_changed (Parameter which); - - int32_t count_for_configuration (ChanCount in, ChanCount out) const; - - boost::shared_ptr<Plugin> plugin_factory (boost::shared_ptr<Plugin>); -}; - -} // namespace ARDOUR - -#endif /* __ardour_plugin_insert_h__ */ diff --git a/libs/ardour/ardour/plugin_manager.h b/libs/ardour/ardour/plugin_manager.h deleted file mode 100644 index 892c8bd75a..0000000000 --- a/libs/ardour/ardour/plugin_manager.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - Copyright (C) 2000-2007 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_plugin_manager_h__ -#define __ardour_plugin_manager_h__ - -#include <list> -#include <map> -#include <string> - -#include <ardour/types.h> -#include <ardour/plugin.h> - -#ifdef HAVE_SLV2 -#include <ardour/lv2_plugin.h> -#endif - -namespace ARDOUR { - -class Plugin; - -class PluginManager { - public: - PluginManager (); - ~PluginManager (); - - /* realtime plugin APIs */ - - ARDOUR::PluginInfoList &vst_plugin_info () { return _vst_plugin_info; } - ARDOUR::PluginInfoList &ladspa_plugin_info () { return _ladspa_plugin_info; } - ARDOUR::PluginInfoList &lv2_plugin_info () { return _lv2_plugin_info; } - ARDOUR::PluginInfoList &au_plugin_info () { return _au_plugin_info; } - - void refresh (); - - int add_ladspa_directory (std::string dirpath); - int add_vst_directory (std::string dirpath); - - static PluginManager* the_manager() { return _manager; } - - private: - ARDOUR::PluginInfoList _vst_plugin_info; - ARDOUR::PluginInfoList _ladspa_plugin_info; - ARDOUR::PluginInfoList _lv2_plugin_info; - ARDOUR::PluginInfoList _au_plugin_info; - -#ifdef HAVE_SLV2 - LV2World* _lv2_world; -#endif - - std::map<uint32_t, std::string> rdf_type; - - std::string ladspa_path; - std::string vst_path; - - void ladspa_refresh (); - void vst_refresh (); - - void add_lrdf_data (const std::string &path); - void add_ladspa_presets (); - void add_vst_presets (); - void add_presets (std::string domain); - - int au_discover (); - void au_refresh (); - - int lv2_discover (); - void lv2_refresh (); - - int vst_discover_from_path (std::string path); - int vst_discover (std::string path); - - int ladspa_discover_from_path (std::string path); - int ladspa_discover (std::string path); - - std::string get_ladspa_category (uint32_t id); - std::vector<uint32_t> ladspa_plugin_whitelist; - - static PluginManager* _manager; // singleton -}; - -} /* namespace ARDOUR */ - -#endif /* __ardour_plugin_manager_h__ */ - diff --git a/libs/ardour/ardour/port.h b/libs/ardour/ardour/port.h deleted file mode 100644 index 93c34da16d..0000000000 --- a/libs/ardour/ardour/port.h +++ /dev/null @@ -1,180 +0,0 @@ -/* - Copyright (C) 2002 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_port_h__ -#define __ardour_port_h__ - -#include <set> -#include <vector> -#include <string> - -#include <sigc++/signal.h> -#include <pbd/failed_constructor.h> -#include <ardour/ardour.h> -#include <ardour/data_type.h> -#include <jack/jack.h> - -namespace ARDOUR { - -class AudioEngine; -class Buffer; - -/** Abstract base for ports - */ -class Port : public virtual sigc::trackable { - public: - enum Flags { - IsInput = JackPortIsInput, - IsOutput = JackPortIsOutput, - IsPhysical = JackPortIsPhysical, - IsTerminal = JackPortIsTerminal, - CanMonitor = JackPortCanMonitor - }; - - virtual ~Port(); - - std::string name() const { - return _name; - } - - Flags flags() const { - return _flags; - } - - bool receives_input() const { - return _flags & IsInput; - } - - bool sends_output () const { - return _flags & IsOutput; - } - - bool can_monitor () const { - return _flags & CanMonitor; - } - - void enable_metering() { - _metering++; - } - - void disable_metering () { - if (_metering) { _metering--; } - } - - virtual void cycle_start (nframes_t nframes, nframes_t offset) {} - virtual void cycle_end (nframes_t nframes, nframes_t offset) {} - virtual DataType type() const = 0; - virtual Buffer& get_buffer() = 0; - - virtual bool connected () const; - virtual bool connected_to (const std::string& portname) const; - virtual int get_connections (std::vector<std::string>&) const; - - virtual int connect (Port& other); - virtual int disconnect (Port& other); - virtual int disconnect_all (); - - virtual void reset (); - virtual int reestablish () {return 0; } - virtual int reconnect () { return 0; } - - virtual int set_name (const std::string& str) { - _name = str; - return 0; - } - - virtual std::string short_name() const = 0; - virtual bool monitoring_input () const = 0; - virtual void ensure_monitor_input (bool yn) = 0; - virtual void request_monitor_input (bool yn) = 0; - virtual nframes_t latency () const = 0; - virtual nframes_t total_latency () const = 0; - virtual void set_latency (nframes_t nframes) = 0; - - sigc::signal<void,bool> MonitorInputChanged; - sigc::signal<void,bool> ClockSyncChanged; - - static void set_engine (AudioEngine*); - - protected: - friend class AudioEngine; - - Port (const std::string& name, Flags flgs); - - virtual void recompute_total_latency() const {} - - /* engine isn't supposed to access below here */ - - Flags _flags; - std::string _type; - std::string _name; - unsigned short _metering; - bool _last_monitor; - nframes_t _latency; - - std::set<Port*> _connections; - - static AudioEngine* engine; -}; - -class PortConnectableByName { - public: - PortConnectableByName() {} - virtual ~PortConnectableByName() {} - - virtual int connect (const std::string& other_name) = 0; - virtual int disconnect (const std::string& other_name) = 0; -}; - -class PortFacade : public virtual Port, public PortConnectableByName { - public: - PortFacade (const std::string& name, Flags flgs) : Port (name, flgs), _ext_port (0) {} - ~PortFacade() {} - - void reset (); - int reestablish (); - int reconnect (); - - int connect (Port& other); - int disconnect (Port& other); - int disconnect_all (); - - int connect (const std::string& other_name); - int disconnect (const std::string& other_name); - - bool connected () const; - bool connected_to (const std::string& portname) const; - int get_connections (std::vector<std::string>&) const; - - std::string short_name() const; - int set_name (const std::string& str); - bool monitoring_input () const; - void ensure_monitor_input (bool yn); - void request_monitor_input (bool yn); - nframes_t latency () const; - nframes_t total_latency () const; - void set_latency (nframes_t nframes); - - protected: - Port* _ext_port; -}; - -} // namespace ARDOUR - -#endif /* __ardour_port_h__ */ diff --git a/libs/ardour/ardour/port_insert.h b/libs/ardour/ardour/port_insert.h deleted file mode 100644 index 1743040bf5..0000000000 --- a/libs/ardour/ardour/port_insert.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - Copyright (C) 2000,2007 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_port_insert_h__ -#define __ardour_port_insert_h__ - -#include <vector> -#include <string> -#include <exception> - -#include <sigc++/signal.h> -#include <ardour/ardour.h> -#include <ardour/io_processor.h> -#include <ardour/types.h> - -class XMLNode; - -namespace ARDOUR { - -class Session; - -/** Port inserts: send output to a Jack port, pick up input at a Jack port - */ -class PortInsert : public IOProcessor -{ - public: - PortInsert (Session&, Placement); - PortInsert (Session&, const XMLNode&); - PortInsert (const PortInsert&); - ~PortInsert (); - - XMLNode& state(bool full); - XMLNode& get_state(void); - int set_state(const XMLNode&); - - void init (); - - void run_in_place (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset); - - nframes_t signal_latency() const; - - ChanCount output_streams() const; - ChanCount input_streams() const; - - virtual bool can_support_input_configuration (ChanCount in) const; - virtual ChanCount output_for_input_configuration (ChanCount in) const; - virtual bool configure_io (ChanCount in, ChanCount out); - - uint32_t bit_slot() const { return bitslot; } - - private: - uint32_t bitslot; -}; - -} // namespace ARDOUR - -#endif /* __ardour_port_insert_h__ */ diff --git a/libs/ardour/ardour/port_set.h b/libs/ardour/ardour/port_set.h deleted file mode 100644 index 51673472c3..0000000000 --- a/libs/ardour/ardour/port_set.h +++ /dev/null @@ -1,161 +0,0 @@ -/* - Copyright (C) 2006 Paul Davis - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the Free - Software Foundation; either version 2 of the License, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifndef __ardour_port_set_h__ -#define __ardour_port_set_h__ - -#include <vector> -#include <ardour/port.h> -#include <ardour/audio_port.h> -#include <ardour/midi_port.h> -#include <ardour/chan_count.h> - -namespace ARDOUR { - - -/** An ordered list of Ports, possibly of various types. - * - * This allows access to all the ports as a list, ignoring type, or accessing - * the nth port of a given type. Note that port(n) and nth_audio_port(n) may - * NOT return the same port. - */ -class PortSet { -public: - PortSet(); - - size_t num_ports() const; - size_t num_ports(DataType type) const { return _ports[type].size(); } - - void add(Port* port); - bool remove(Port* port); - - /** nth port */ - Port* port(size_t index) const; - - /** nth port of type @a t, or nth port if t = NIL */ - Port* port(DataType t, size_t index) const; - - AudioPort* nth_audio_port(size_t n) const; - - MidiPort* nth_midi_port(size_t n) const; - - bool contains(const Port* port) const; - - /** Remove all ports from the PortSet. Ports are not deregistered with - * the engine, it's the caller's responsibility to not leak here! - */ - void clear() { _ports.clear(); } - - const ChanCount& count() const { return _count; } - - bool empty() const { return (_count.n_total() == 0); } - - // ITERATORS - - // FIXME: this is a filthy copy-and-paste mess - - class iterator { - public: - - Port& operator*() { return *_set.port(_type, _index); } - Port* operator->() { return _set.port(_type, _index); } - iterator& operator++() { ++_index; return *this; } // yes, prefix only - bool operator==(const iterator& other) { return (_index == other._index); } - bool operator!=(const iterator& other) { return (_index != other._index); } - - private: - friend class PortSet; - - iterator(PortSet& list, DataType type, size_t index) - : _set(list), _type(type), _index(index) {} - - PortSet& _set; - DataType _type; ///< Ignored if NIL (to iterator over entire set) - size_t _index; - }; - - iterator begin(DataType type = DataType::NIL) - { return iterator(*this, type, 0); } - - iterator end(DataType type = DataType::NIL) - { - return iterator(*this, type, - (type == DataType::NIL) ? _count.n_total() : _count.get(type)); - } - - // FIXME: typeify - class const_iterator { - public: - - const Port& operator*() { return *_set.port(_index); } - const Port* operator->() { return _set.port(_index); } - const_iterator& operator++() { ++_index; return *this; } // yes, prefix only - bool operator==(const const_iterator& other) { return (_index == other._index); } - bool operator!=(const const_iterator& other) { return (_index != other._index); } - - private: - friend class PortSet; - - const_iterator(const PortSet& list, size_t index) : _set(list), _index(index) {} - - const PortSet& _set; - size_t _index; - }; - - const_iterator begin() const { return const_iterator(*this, 0); } - const_iterator end() const { return const_iterator(*this, _count.n_total()); } - - - class audio_iterator { - public: - - AudioPort& operator*() { return *_set.nth_audio_port(_index); } - AudioPort* operator->() { return _set.nth_audio_port(_index); } - audio_iterator& operator++() { ++_index; return *this; } // yes, prefix only - bool operator==(const audio_iterator& other) { return (_index == other._index); } - bool operator!=(const audio_iterator& other) { return (_index != other._index); } - - private: - friend class PortSet; - - audio_iterator(PortSet& list, size_t index) : _set(list), _index(index) {} - - PortSet& _set; - size_t _index; - }; - - audio_iterator audio_begin() { return audio_iterator(*this, 0); } - audio_iterator audio_end() { return audio_iterator(*this, _count.n_audio()); } - -private: - // Prevent copies (undefined) - PortSet(const PortSet& copy); - void operator=(const PortSet& other); - - typedef std::vector<Port*> PortVec; - - // Vector of vectors, indexed by DataType::to_index() - std::vector<PortVec> _ports; - - ChanCount _count; -}; - - -} // namespace ARDOUR - -#endif // __ardour_port_set_h__ diff --git a/libs/ardour/ardour/processor.h b/libs/ardour/ardour/processor.h deleted file mode 100644 index d3e95e8ebf..0000000000 --- a/libs/ardour/ardour/processor.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - Copyright (C) 2000 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_processor_h__ -#define __ardour_processor_h__ - -#include <vector> -#include <string> -#include <exception> - -#include <pbd/statefuldestructible.h> - -#include <sigc++/signal.h> - -#include <ardour/types.h> -#include <ardour/ardour.h> -#include <ardour/buffer_set.h> -#include <ardour/automatable.h> -#include <ardour/latent.h> - -class XMLNode; - -namespace ARDOUR { - -class Session; - -/* A mixer strip element - plugin, send, meter, etc. - */ -class Processor : public Automatable, public Latent -{ - public: - static const string state_node_name; - - Processor(Session&, const string& name, Placement p); // TODO: remove placement in favour of sort key - - virtual ~Processor() { } - - static boost::shared_ptr<Processor> clone (boost::shared_ptr<const Processor>); - - uint32_t sort_key() const { return _sort_key; } - void set_sort_key (uint32_t key); - - Placement placement() const { return _placement; } - void set_placement (Placement); - - bool active () const { return _active; } - void set_active (bool yn); - - bool get_next_ab_is_active () const { return _next_ab_is_active; } - void set_next_ab_is_active (bool yn) { _next_ab_is_active = yn; } - - virtual nframes_t signal_latency() const { return 0; } - - virtual void transport_stopped (nframes_t frame) {} - - virtual void set_block_size (nframes_t nframes) {} - - virtual void run_in_place (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset) { assert(is_in_place()); } - - virtual void run_out_of_place (BufferSet& input, BufferSet& output, nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset) { assert(is_out_of_place()); } - - virtual void silence (nframes_t nframes, nframes_t offset) {} - - virtual void activate () { _active = true; ActiveChanged.emit(); } - virtual void deactivate () { _active = false; ActiveChanged.emit(); } - - virtual bool configure_io (ChanCount in, ChanCount out) { _configured_input = in; return (_configured = true); } - - /* Derived classes should override these, or processor appears as an in-place pass-through */ - - /** In-place processors implement run_in_place and modify thee input buffer parameter */ - virtual bool is_in_place () const { return true; } - - /* Out-Of-Place processors implement run_out_of_place, don't modify the input parameter - * and write to their output parameter */ - virtual bool is_out_of_place () const { return false; } - - virtual bool can_support_input_configuration (ChanCount in) const { return true; } - virtual ChanCount output_for_input_configuration (ChanCount in) const { return in; } - virtual ChanCount output_streams() const { return _configured_input; } - virtual ChanCount input_streams () const { return _configured_input; } - - virtual XMLNode& state (bool full); - virtual XMLNode& get_state (void); - virtual int set_state (const XMLNode&); - - void *get_gui () const { return _gui; } - void set_gui (void *p) { _gui = p; } - - static sigc::signal<void,Processor*> ProcessorCreated; - - sigc::signal<void> ActiveChanged; - sigc::signal<void> PlacementChanged; - -protected: - bool _active; - bool _next_ab_is_active; - bool _configured; - ChanCount _configured_input; - Placement _placement; - uint32_t _sort_key; - void* _gui; /* generic, we don't know or care what this is */ -}; - -} // namespace ARDOUR - -#endif /* __ardour_processor_h__ */ diff --git a/libs/ardour/ardour/profile.h b/libs/ardour/ardour/profile.h deleted file mode 100644 index b016063c4d..0000000000 --- a/libs/ardour/ardour/profile.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - Copyright (C) 2000-2007 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_profile_h__ -#define __ardour_profile_h__ - -#include <boost/dynamic_bitset.hpp> -#include <stdint.h> - -namespace ARDOUR { - -class RuntimeProfile { - public: - enum Element { - SmallScreen, - SAE, - SinglePackage, - LastElement - }; - - RuntimeProfile() { bits.resize (LastElement); } - ~RuntimeProfile() {} - - void set_small_screen() { bits[SmallScreen] = true; } - bool get_small_screen() const { return bits[SmallScreen]; } - - void set_sae () { bits[SAE] = true; } - bool get_sae () const { return bits[SAE]; } - - void set_single_package () { bits[SinglePackage] = true; } - bool get_single_package () const { return bits[SinglePackage]; } - - private: - boost::dynamic_bitset<uint64_t> bits; - -}; - -extern RuntimeProfile* Profile; - -}; // namespace ARDOUR - -#endif /* __ardour_profile_h__ */ diff --git a/libs/ardour/ardour/quantize.h b/libs/ardour/ardour/quantize.h deleted file mode 100644 index 143652dc63..0000000000 --- a/libs/ardour/ardour/quantize.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - Copyright (C) 2007 Paul Davis - Author: Dave Robillard - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_quantize_h__ -#define __ardour_quantize_h__ - -#include <ardour/filter.h> - -namespace ARDOUR { - -class Quantize : public Filter { -public: - Quantize (ARDOUR::Session&, double q); - ~Quantize (); - - int run (boost::shared_ptr<ARDOUR::Region>); - -private: - double _q; -}; - -} /* namespace */ - -#endif /* __ardour_quantize_h__ */ diff --git a/libs/ardour/ardour/rb_effect.h b/libs/ardour/ardour/rb_effect.h deleted file mode 100644 index a536a309b3..0000000000 --- a/libs/ardour/ardour/rb_effect.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - Copyright (C) 2007 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_rbeffect_h__ -#define __ardour_rbeffect_h__ - -#include <ardour/filter.h> - -namespace ARDOUR { - -class AudioRegion; - -class RBEffect : public Filter { - public: - RBEffect (ARDOUR::Session&, TimeFXRequest&); - ~RBEffect (); - - int run (boost::shared_ptr<ARDOUR::Region>); - - private: - TimeFXRequest& tsr; -}; - -} /* namespace */ - -#endif /* __ardour_rbeffect_h__ */ diff --git a/libs/ardour/ardour/readable.h b/libs/ardour/ardour/readable.h deleted file mode 100644 index e072a1c95e..0000000000 --- a/libs/ardour/ardour/readable.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef __ardour_readable_h__ -#define __ardour_readable_h__ - -#include <ardour/types.h> - -namespace ARDOUR { - -class Readable { - public: - Readable () {} - virtual ~Readable() {} - - virtual nframes64_t read (Sample*, nframes64_t pos, nframes64_t cnt, int channel) const = 0; - virtual nframes64_t readable_length() const = 0; - virtual uint32_t n_channels () const = 0; -}; - -} - -#endif /* __ardour_readable_h__ */ diff --git a/libs/ardour/ardour/recent_sessions.h b/libs/ardour/ardour/recent_sessions.h deleted file mode 100644 index e32b67bcd8..0000000000 --- a/libs/ardour/ardour/recent_sessions.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - Copyright (C) 2004 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_recent_sessions_h__ -#define __ardour_recent_sessions_h__ - -#include <deque> -#include <utility> -#include <string> - -using std::deque; -using std::pair; -using std::string; - -namespace ARDOUR { - typedef deque<pair<string,string> > RecentSessions; - - int read_recent_sessions (RecentSessions& rs); - int store_recent_sessions (string name, string path); - int write_recent_sessions (RecentSessions& rs); -}; // namespace ARDOUR - -#endif // __ardour_recent_sessions_h__ diff --git a/libs/ardour/ardour/region.h b/libs/ardour/ardour/region.h deleted file mode 100644 index 00315846b2..0000000000 --- a/libs/ardour/ardour/region.h +++ /dev/null @@ -1,313 +0,0 @@ -/* - Copyright (C) 2000-2001 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_region_h__ -#define __ardour_region_h__ - -#include <vector> -#include <boost/shared_ptr.hpp> -#include <boost/enable_shared_from_this.hpp> - -#include <pbd/undo.h> - -#include <ardour/ardour.h> -#include <ardour/data_type.h> -#include <ardour/automatable.h> -#include <ardour/readable.h> - -class XMLNode; - -namespace ARDOUR { - -class Playlist; -class Filter; -class ExportSpecification; - -enum RegionEditState { - EditChangesNothing = 0, - EditChangesName = 1, - EditChangesID = 2 -}; - -class Region : public Automatable, public boost::enable_shared_from_this<Region>, public Readable -{ - public: - typedef std::vector<boost::shared_ptr<Source> > SourceList; - - enum Flag { - Muted = 0x1, - Opaque = 0x2, - EnvelopeActive = 0x4, - DefaultFadeIn = 0x8, - DefaultFadeOut = 0x10, - Locked = 0x20, - Automatic = 0x40, - WholeFile = 0x80, - FadeIn = 0x100, - FadeOut = 0x200, - Copied = 0x400, - Import = 0x800, - External = 0x1000, - SyncMarked = 0x2000, - LeftOfSplit = 0x4000, - RightOfSplit = 0x8000, - Hidden = 0x10000, - DoNotSaveState = 0x20000, - PositionLocked = 0x40000, - // - range_guarantoor = USHRT_MAX - }; - - enum PositionLockStyle { - AudioTime, - MusicTime - }; - - static const Flag DefaultFlags = Flag (Opaque|DefaultFadeIn|DefaultFadeOut|FadeIn|FadeOut); - - static Change FadeChanged; - static Change SyncOffsetChanged; - static Change MuteChanged; - static Change OpacityChanged; - static Change LockChanged; - static Change LayerChanged; - static Change HiddenChanged; - - sigc::signal<void,Change> StateChanged; - - virtual ~Region(); - - /** Note: changing the name of a Region does not constitute an edit */ - bool set_name (const std::string& str); - - const DataType& data_type() const { return _type; } - - /** - * Thats how the region parameters play together: - * <PRE> - * |------------------------------------------------------------------- track - * |..........[------------------].....| region - * |-----------------------------| _position - * |------------------| _length - * |----------| _start - * </PRE> - */ - nframes_t position () const { return _position; } - nframes_t start () const { return _start; } - nframes_t length() const { return _length; } - layer_t layer () const { return _layer; } - - /* these two are valid ONLY during a StateChanged signal handler */ - - nframes_t last_position() const { return _last_position; } - nframes_t last_length() const { return _last_length; } - - nframes64_t ancestral_start () const { return _ancestral_start; } - nframes64_t ancestral_length () const { return _ancestral_length; } - float stretch() const { return _stretch; } - float shift() const { return _shift; } - - void set_ancestral_data (nframes64_t start, nframes64_t length, float stretch, float shift); - - nframes_t sync_offset(int& dir) const; - nframes_t sync_position() const; - - nframes_t adjust_to_sync (nframes_t); - - /* first_frame() is an alias; last_frame() just hides some math */ - - nframes_t first_frame() const { return _position; } - nframes_t last_frame() const { return _position + _length - 1; } - - Flag flags() const { return _flags; } - bool hidden() const { return _flags & Hidden; } - bool muted() const { return _flags & Muted; } - bool opaque () const { return _flags & Opaque; } - bool locked() const { return _flags & Locked; } - bool position_locked() const { return _flags & PositionLocked; } - bool automatic() const { return _flags & Automatic; } - bool whole_file() const { return _flags & WholeFile ; } - bool captured() const { return !(_flags & (Region::Flag (Region::Import|Region::External))); } - bool can_move() const { return !(_flags & (Locked|PositionLocked)); } - - PositionLockStyle positional_lock_style() const { return _positional_lock_style; } - void set_position_lock_style (PositionLockStyle ps); - void recompute_position_from_lock_style (); - - virtual bool should_save_state () const { return !(_flags & DoNotSaveState); }; - - void freeze (); - void thaw (const string& why); - - bool covers (nframes_t frame) const { - return first_frame() <= frame && frame <= last_frame(); - } - - OverlapType coverage (nframes_t start, nframes_t end) const { - return ARDOUR::coverage (first_frame(), last_frame(), start, end); - } - - bool equivalent (boost::shared_ptr<const Region>) const; - bool size_equivalent (boost::shared_ptr<const Region>) const; - bool overlap_equivalent (boost::shared_ptr<const Region>) const; - bool region_list_equivalent (boost::shared_ptr<const Region>) const; - bool source_equivalent (boost::shared_ptr<const Region>) const; - - /* EDITING OPERATIONS */ - - void set_length (nframes_t, void *src); - void set_start (nframes_t, void *src); - void set_position (nframes_t, void *src); - void set_position_on_top (nframes_t, void *src); - void special_set_position (nframes_t); - void update_position_after_tempo_map_change (); - void nudge_position (nframes64_t, void *src); - - bool at_natural_position () const; - void move_to_natural_position (void *src); - - void trim_start (nframes_t new_position, void *src); - void trim_front (nframes_t new_position, void *src); - void trim_end (nframes_t new_position, void *src); - void trim_to (nframes_t position, nframes_t length, void *src); - - void set_layer (layer_t l); /* ONLY Playlist can call this */ - void raise (); - void lower (); - void raise_to_top (); - void lower_to_bottom (); - - void set_sync_position (nframes_t n); - void clear_sync_position (); - void set_hidden (bool yn); - void set_muted (bool yn); - void set_opaque (bool yn); - void set_locked (bool yn); - void set_position_locked (bool yn); - - int apply (Filter&); - - virtual uint32_t read_data_count() const { return _read_data_count; } - - boost::shared_ptr<ARDOUR::Playlist> playlist() const { return _playlist.lock(); } - virtual void set_playlist (boost::weak_ptr<ARDOUR::Playlist>); - - void source_deleted (boost::shared_ptr<Source>); - - boost::shared_ptr<Source> source (uint32_t n=0) const { return _sources[ (n < _sources.size()) ? n : 0 ]; } - uint32_t n_channels() const { return _sources.size(); } - - const SourceList& sources() const { return _sources; } - const SourceList& master_sources() const { return _master_sources; } - - std::vector<string> master_source_names(); - void set_master_sources (SourceList&); - - /* serialization */ - - XMLNode& get_state (); - virtual XMLNode& state (bool); - virtual int set_state (const XMLNode&); - virtual int set_live_state (const XMLNode&, Change&, bool send); - - virtual boost::shared_ptr<Region> get_parent() const; - - uint64_t last_layer_op() const { return _last_layer_op; } - void set_last_layer_op (uint64_t when); - - virtual bool is_dependent() const { return false; } - virtual bool depends_on (boost::shared_ptr<Region> other) const { return false; } - - virtual int exportme (ARDOUR::Session&, ARDOUR::ExportSpecification&) = 0; - - virtual int get_transients (AnalysisFeatureList&, bool force_new = false) { - // no transients, but its OK - return 0; - } - - void invalidate_transients (); - - protected: - friend class RegionFactory; - - Region (boost::shared_ptr<Source> src, nframes_t start, nframes_t length, - const string& name, DataType type, layer_t = 0, Flag flags = DefaultFlags); - Region (const SourceList& srcs, nframes_t start, nframes_t length, - const string& name, DataType type, layer_t = 0, Flag flags = DefaultFlags); - - Region (boost::shared_ptr<const Region>, nframes_t start, nframes_t length, const string& name, layer_t = 0, Flag flags = DefaultFlags); - Region (boost::shared_ptr<const Region>); - Region (boost::shared_ptr<Source> src, const XMLNode&); - Region (const SourceList& srcs, const XMLNode&); - - Region (Session& s, nframes_t start, nframes_t length, const string& name, DataType, layer_t = 0, Flag flags = DefaultFlags); - - protected: - XMLNode& get_short_state (); /* used only by Session */ - - void send_change (Change); - - void trim_to_internal (nframes_t position, nframes_t length, void *src); - void set_position_internal (nframes_t pos, bool allow_bbt_recompute); - - bool copied() const { return _flags & Copied; } - void maybe_uncopy (); - void first_edit (); - - bool verify_start (nframes_t); - bool verify_start_and_length (nframes_t, nframes_t&); - bool verify_start_mutable (nframes_t&_start); - bool verify_length (nframes_t); - - virtual void recompute_at_start () = 0; - virtual void recompute_at_end () = 0; - - DataType _type; - Flag _flags; - nframes_t _start; - nframes_t _length; - nframes_t _last_length; - nframes_t _position; - nframes_t _last_position; - PositionLockStyle _positional_lock_style; - nframes_t _sync_position; - layer_t _layer; - mutable RegionEditState _first_edit; - int _frozen; - nframes64_t _ancestral_start; - nframes64_t _ancestral_length; - float _stretch; - float _shift; - BBT_Time _bbt_time; - AnalysisFeatureList _transients; - bool _valid_transients; - mutable uint32_t _read_data_count; ///< modified in read() - Change _pending_changed; - uint64_t _last_layer_op; ///< timestamp - Glib::Mutex _lock; - SourceList _sources; - /** Used when timefx are applied, so we can always use the original source */ - SourceList _master_sources; - - boost::weak_ptr<ARDOUR::Playlist> _playlist; -}; - -} /* namespace ARDOUR */ - -#endif /* __ardour_region_h__ */ diff --git a/libs/ardour/ardour/region_factory.h b/libs/ardour/ardour/region_factory.h deleted file mode 100644 index 12437ba998..0000000000 --- a/libs/ardour/ardour/region_factory.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - Copyright (C) 2000-2007 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_region_factory_h__ -#define __ardour_region_factory_h__ - -#include <ardour/types.h> -#include <ardour/region.h> - -class XMLNode; - -namespace ARDOUR { - -class Session; - -class RegionFactory { - - public: - /** This is emitted only when a new id is assigned. Therefore, - in a pure Region copy, it will not be emitted. - - It must be emitted by derived classes, not Region - itself, to permit dynamic_cast<> to be used to - infer the type of Region. - */ - static sigc::signal<void,boost::shared_ptr<Region> > CheckNewRegion; - - static boost::shared_ptr<Region> create (boost::shared_ptr<const Region>); - - /* note: both of the first two should use const shared_ptr as well, but - gcc 4.1 doesn't seem to be able to disambiguate them if they do. - */ - - static boost::shared_ptr<Region> create (boost::shared_ptr<Region>, nframes_t start, - nframes_t length, std::string name, - layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true); - static boost::shared_ptr<Region> create (boost::shared_ptr<AudioRegion>, nframes_t start, - nframes_t length, std::string name, - layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true); - static boost::shared_ptr<Region> create (boost::shared_ptr<Source>, nframes_t start, nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true); - static boost::shared_ptr<Region> create (const SourceList &, nframes_t start, nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true); - static boost::shared_ptr<Region> create (Session&, XMLNode&, bool); - static boost::shared_ptr<Region> create (SourceList &, const XMLNode&); -}; - -} - -#endif /* __ardour_region_factory_h__ */ diff --git a/libs/ardour/ardour/resampled_source.h b/libs/ardour/ardour/resampled_source.h deleted file mode 100644 index 6eca4cda98..0000000000 --- a/libs/ardour/ardour/resampled_source.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - Copyright (C) 2007 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_resampled_source_h__ -#define __ardour_resampled_source_h__ - -#include <samplerate.h> - -#include <ardour/types.h> -#include <ardour/importable_source.h> - -namespace ARDOUR { - -class ResampledImportableSource : public ImportableSource -{ - public: - ResampledImportableSource (boost::shared_ptr<ImportableSource>, nframes_t rate, SrcQuality); - - ~ResampledImportableSource (); - - nframes_t read (Sample* buffer, nframes_t nframes); - float ratio() const { return src_data.src_ratio; } - uint32_t channels() const { return source->channels(); } - nframes_t length() const { return source->length(); } - nframes_t samplerate() const { return source->samplerate(); } - void seek (nframes_t pos) { source->seek (pos); } - - static const uint32_t blocksize; - - private: - boost::shared_ptr<ImportableSource> source; - float* input; - SRC_STATE* src_state; - SRC_DATA src_data; -}; - -} - -#endif /* __ardour_resampled_source_h__ */ diff --git a/libs/ardour/ardour/reverse.h b/libs/ardour/ardour/reverse.h deleted file mode 100644 index 7870b5aa2e..0000000000 --- a/libs/ardour/ardour/reverse.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - Copyright (C) 2004 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_reverse_h__ -#define __ardour_reverse_h__ - -#include <ardour/filter.h> - -namespace ARDOUR { - -class Reverse : public Filter { - public: - Reverse (ARDOUR::Session&); - ~Reverse (); - - int run (boost::shared_ptr<ARDOUR::Region>); -}; - -} /* namespace */ - -#endif /* __ardour_reverse_h__ */ diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h deleted file mode 100644 index c7c0b77102..0000000000 --- a/libs/ardour/ardour/route.h +++ /dev/null @@ -1,384 +0,0 @@ -/* - Copyright (C) 2000-2002 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_route_h__ -#define __ardour_route_h__ - -#include <cmath> -#include <list> -#include <set> -#include <map> -#include <string> - -#include <boost/shared_ptr.hpp> - -#include <pbd/fastlog.h> -#include <glibmm/thread.h> -#include <pbd/xml++.h> -#include <pbd/undo.h> -#include <pbd/stateful.h> -#include <pbd/controllable.h> -#include <pbd/destructible.h> - -#include <ardour/ardour.h> -#include <ardour/io.h> -#include <ardour/session.h> -#include <ardour/io_processor.h> -#include <ardour/types.h> - -namespace ARDOUR { - -class Processor; -class Send; -class RouteGroup; - -enum mute_type { - PRE_FADER = 0x1, - POST_FADER = 0x2, - CONTROL_OUTS = 0x4, - MAIN_OUTS = 0x8 -}; - -class Route : public IO -{ - protected: - - typedef list<boost::shared_ptr<Processor> > ProcessorList; - - public: - - enum Flag { - Hidden = 0x1, - MasterOut = 0x2, - ControlOut = 0x4 - }; - - - Route (Session&, std::string name, int input_min, int input_max, int output_min, int output_max, - Flag flags = Flag(0), DataType default_type = DataType::AUDIO); - Route (Session&, const XMLNode&, DataType default_type = DataType::AUDIO); - virtual ~Route(); - - static std::string ensure_track_or_route_name(std::string, Session &); - - std::string comment() { return _comment; } - void set_comment (std::string str, void *src); - - long order_key (const char* name) const; - void set_order_key (const char* name, long n); - - bool is_hidden() const { return _flags & Hidden; } - bool is_master() const { return _flags & MasterOut; } - bool is_control() const { return _flags & ControlOut; } - - /* these are the core of the API of a Route. see the protected sections as well */ - - - virtual int roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, - nframes_t offset, int declick, bool can_record, bool rec_monitors_input); - - virtual int no_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, - nframes_t offset, bool state_changing, bool can_record, bool rec_monitors_input); - - virtual int silent_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, - nframes_t offset, bool can_record, bool rec_monitors_input); - virtual void toggle_monitor_input (); - virtual bool can_record() { return false; } - virtual void set_record_enable (bool yn, void *src) {} - virtual bool record_enabled() const { return false; } - virtual void handle_transport_stopped (bool abort, bool did_locate, bool flush_processors); - virtual void set_pending_declick (int); - - /* end of vfunc-based API */ - - /* override IO::set_gain() to provide group control */ - - void set_gain (gain_t val, void *src); - void inc_gain (gain_t delta, void *src); - - void set_solo (bool yn, void *src); - bool soloed() const { return _soloed; } - - void set_solo_safe (bool yn, void *src); - bool solo_safe() const { return _solo_safe; } - - void set_mute (bool yn, void *src); - bool muted() const { return _muted; } - bool solo_muted() const { return desired_solo_gain == 0.0; } - - void set_mute_config (mute_type, bool, void *src); - bool get_mute_config (mute_type); - - void set_edit_group (RouteGroup *, void *); - void drop_edit_group (void *); - RouteGroup *edit_group () { return _edit_group; } - - void set_mix_group (RouteGroup *, void *); - void drop_mix_group (void *); - RouteGroup *mix_group () { return _mix_group; } - - virtual void set_meter_point (MeterPoint, void *src); - MeterPoint meter_point() const { return _meter_point; } - - /* Processors */ - - void flush_processors (); - - template<class T> void foreach_processor (T *obj, void (T::*func)(boost::shared_ptr<Processor>)) { - Glib::RWLock::ReaderLock lm (_processor_lock); - for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { - (obj->*func) (*i); - } - } - - boost::shared_ptr<Processor> nth_processor (uint32_t n) { - Glib::RWLock::ReaderLock lm (_processor_lock); - ProcessorList::iterator i; - for (i = _processors.begin(); i != _processors.end() && n; ++i, --n); - if (i == _processors.end()) { - return boost::shared_ptr<IOProcessor> (); - } else { - return *i; - } - } - - ChanCount max_processor_outs () const { return processor_max_outs; } - ChanCount pre_fader_streams() const; - - /** A record of the stream configuration at some point in the processor list. - * Used to return where and why an processor list configuration request failed. - */ - struct ProcessorStreams { - ProcessorStreams(size_t i=0, ChanCount c=ChanCount()) : index(i), count(c) {} - - size_t index; ///< Index of processor where configuration failed - ChanCount count; ///< Input requested of processor - }; - - int add_processor (boost::shared_ptr<Processor>, ProcessorStreams* err = 0); - int add_processors (const ProcessorList&, ProcessorStreams* err = 0); - int remove_processor (boost::shared_ptr<Processor>, ProcessorStreams* err = 0); - int copy_processors (const Route&, Placement, ProcessorStreams* err = 0); - int sort_processors (ProcessorStreams* err = 0); - void disable_processors (Placement); - void disable_processors (); - void disable_plugins (Placement); - void disable_plugins (); - void ab_plugins (bool forward); - void clear_processors (Placement); - void all_processors_flip(); - void all_processors_active (Placement, bool state); - - virtual nframes_t update_total_latency(); - void set_latency_delay (nframes_t); - void set_user_latency (nframes_t); - nframes_t initial_delay() const { return _initial_delay; } - - sigc::signal<void,void*> solo_changed; - sigc::signal<void,void*> solo_safe_changed; - sigc::signal<void,void*> comment_changed; - sigc::signal<void,void*> mute_changed; - sigc::signal<void,void*> pre_fader_changed; - sigc::signal<void,void*> post_fader_changed; - sigc::signal<void,void*> control_outs_changed; - sigc::signal<void,void*> main_outs_changed; - sigc::signal<void> processors_changed; - sigc::signal<void,void*> record_enable_changed; - sigc::signal<void,void*> edit_group_changed; - sigc::signal<void,void*> mix_group_changed; - sigc::signal<void,void*> meter_change; - sigc::signal<void> signal_latency_changed; - sigc::signal<void> initial_delay_changed; - - /* gui's call this for their own purposes. */ - - sigc::signal<void,std::string,void*> gui_changed; - - /* stateful */ - - XMLNode& get_state(); - int set_state(const XMLNode& node); - virtual XMLNode& get_template(); - - XMLNode& get_processor_state (); - int set_processor_state (const XMLNode&); - - sigc::signal<void,void*> SelectedChanged; - - int set_control_outs (const vector<std::string>& ports); - IO* control_outs() { return _control_outs; } - - bool feeds (boost::shared_ptr<Route>); - set<boost::shared_ptr<Route> > fed_by; - - struct ToggleControllable : public PBD::Controllable { - enum ToggleType { - MuteControl = 0, - SoloControl - }; - - ToggleControllable (std::string name, Route&, ToggleType); - void set_value (float); - float get_value (void) const; - - Route& route; - ToggleType type; - }; - - boost::shared_ptr<PBD::Controllable> solo_control() { - return _solo_control; - } - - boost::shared_ptr<PBD::Controllable> mute_control() { - return _mute_control; - } - - void automation_snapshot (nframes_t now, bool force=false); - void protect_automation (); - - void set_remote_control_id (uint32_t id); - uint32_t remote_control_id () const; - sigc::signal<void> RemoteControlIDChanged; - - void sync_order_keys (); - static sigc::signal<void> SyncOrderKeys; - - protected: - friend class Session; - - void set_solo_mute (bool yn); - void set_block_size (nframes_t nframes); - bool has_external_redirects() const; - void curve_reallocate (); - - protected: - Flag _flags; - - /* tight cache-line access here is more important than sheer speed of - access. - */ - - bool _muted : 1; - bool _soloed : 1; - bool _solo_safe : 1; - bool _recordable : 1; - bool _mute_affects_pre_fader : 1; - bool _mute_affects_post_fader : 1; - bool _mute_affects_control_outs : 1; - bool _mute_affects_main_outs : 1; - bool _silent : 1; - bool _declickable : 1; - int _pending_declick; - - MeterPoint _meter_point; - - gain_t solo_gain; - gain_t mute_gain; - gain_t desired_solo_gain; - gain_t desired_mute_gain; - - - - nframes_t _initial_delay; - nframes_t _roll_delay; - ProcessorList _processors; - Glib::RWLock _processor_lock; - IO *_control_outs; - Glib::Mutex _control_outs_lock; - RouteGroup *_edit_group; - RouteGroup *_mix_group; - std::string _comment; - bool _have_internal_generator; - - boost::shared_ptr<ToggleControllable> _solo_control; - boost::shared_ptr<ToggleControllable> _mute_control; - - nframes_t check_initial_delay (nframes_t, nframes_t&, nframes_t&); - - void passthru (nframes_t start_frame, nframes_t end_frame, - nframes_t nframes, nframes_t offset, int declick, bool meter_inputs); - - virtual void process_output_buffers (BufferSet& bufs, - nframes_t start_frame, nframes_t end_frame, - nframes_t nframes, nframes_t offset, bool with_processors, int declick, - bool meter); - - protected: - - virtual XMLNode& state(bool); - - void passthru_silence (nframes_t start_frame, nframes_t end_frame, - nframes_t nframes, nframes_t offset, int declick, - bool meter); - - void silence (nframes_t nframes, nframes_t offset); - - sigc::connection input_signal_connection; - - ChanCount processor_max_outs; - uint32_t _remote_control_id; - - uint32_t pans_required() const; - ChanCount n_process_buffers (); - - virtual int _set_state (const XMLNode&, bool call_base); - virtual void _set_processor_states (const XMLNodeList&); - - private: - void init (); - - static uint32_t order_key_cnt; - - struct ltstr - { - bool operator()(const char* s1, const char* s2) const - { - return strcmp(s1, s2) < 0; - } - }; - - typedef std::map<const char*,long,ltstr> OrderKeys; - OrderKeys order_keys; - - void input_change_handler (IOChange, void *src); - void output_change_handler (IOChange, void *src); - - int reset_plugin_counts (ProcessorStreams*); /* locked */ - int _reset_plugin_counts (ProcessorStreams*); /* unlocked */ - - /* processor I/O channels and plugin count handling */ - - struct ProcessorCount { - boost::shared_ptr<ARDOUR::Processor> processor; - ChanCount in; - ChanCount out; - - ProcessorCount (boost::shared_ptr<ARDOUR::Processor> ins) : processor(ins) {} - }; - - int32_t apply_some_plugin_counts (std::list<ProcessorCount>& iclist); - bool check_some_plugin_counts (std::list<ProcessorCount>& iclist, ChanCount required_inputs, ProcessorStreams* err_streams); - - void set_deferred_state (); - void add_processor_from_xml (const XMLNode&); -}; - -} // namespace ARDOUR - -#endif /* __ardour_route_h__ */ diff --git a/libs/ardour/ardour/route_group.h b/libs/ardour/ardour/route_group.h deleted file mode 100644 index ae16394289..0000000000 --- a/libs/ardour/ardour/route_group.h +++ /dev/null @@ -1,124 +0,0 @@ -/* - Copyright (C) 2000 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_route_group_h__ -#define __ardour_route_group_h__ - -#include <list> -#include <set> -#include <string> -#include <stdint.h> -#include <sigc++/signal.h> -#include <pbd/stateful.h> -#include <ardour/types.h> - -using std::string; -using std::list; - -namespace ARDOUR { - -class Route; -class Track; -class AudioTrack; -class Session; - -class RouteGroup : public PBD::Stateful, public sigc::trackable { - public: - enum Flag { - Relative = 0x1, - Active = 0x2, - Hidden = 0x4 - }; - - RouteGroup (Session& s, const string &n, Flag f = Flag(0)); - - const string& name() { return _name; } - void set_name (std::string str); - - bool is_active () const { return _flags & Active; } - bool is_relative () const { return _flags & Relative; } - bool is_hidden () const { return _flags & Hidden; } - bool empty() const {return routes.empty();} - - gain_t get_max_factor(gain_t factor); - gain_t get_min_factor(gain_t factor); - - int size() { return routes.size();} - ARDOUR::Route * first () const { return *routes.begin();} - - void set_active (bool yn, void *src); - void set_relative (bool yn, void *src); - void set_hidden (bool yn, void *src); - - int add (Route *); - - int remove (Route *); - - void apply (void (Route::*func)(void *), void *src) { - for (list<Route *>::iterator i = routes.begin(); i != routes.end(); i++) { - ((*i)->*func)(src); - } - } - - template<class T> void apply (void (Route::*func)(T, void *), T val, void *src) { - for (list<Route *>::iterator i = routes.begin(); i != routes.end(); i++) { - ((*i)->*func)(val, src); - } - } - - template<class T> void foreach_route (T *obj, void (T::*func)(Route&)) { - for (list<Route *>::iterator i = routes.begin(); i != routes.end(); i++) { - (obj->*func)(**i); - } - } - - /* to use these, #include <ardour/route_group_specialized.h> */ - - template<class T> void apply (void (Track::*func)(T, void *), T val, void *src); - - /* fills at_set with all members of the group that are AudioTracks */ - - void audio_track_group (std::set<AudioTrack*>& at_set); - - void clear () { - routes.clear (); - changed(); - } - - const list<Route*>& route_list() { return routes; } - - sigc::signal<void> changed; - sigc::signal<void,void*> FlagsChanged; - - XMLNode& get_state (void); - - int set_state (const XMLNode&); - - private: - Session& _session; - list<Route *> routes; - string _name; - Flag _flags; - - void remove_when_going_away (Route*); -}; - -} /* namespace */ - -#endif /* __ardour_route_group_h__ */ diff --git a/libs/ardour/ardour/route_group_specialized.h b/libs/ardour/ardour/route_group_specialized.h deleted file mode 100644 index 9e04c46d0e..0000000000 --- a/libs/ardour/ardour/route_group_specialized.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - Copyright (C) 2000-2007 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_route_group_specialized_h__ -#define __ardour_route_group_specialized_h__ - -#include <ardour/route_group.h> -#include <ardour/audio_track.h> - -namespace ARDOUR { - -template<class T> void -RouteGroup::apply (void (Track::*func)(T, void *), T val, void *src) -{ - for (list<Route *>::iterator i = routes.begin(); i != routes.end(); i++) { - Track *at; - if ((at = dynamic_cast<Track*>(*i)) != 0) { - (at->*func)(val, this); - } - } -} - -} /* namespace ARDOUR */ - -#endif /* __ardour_route_group_specialized_h__ */ diff --git a/libs/ardour/ardour/runtime_functions.h b/libs/ardour/ardour/runtime_functions.h deleted file mode 100644 index c1dab4ebc7..0000000000 --- a/libs/ardour/ardour/runtime_functions.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - Copyright (C) 2007 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_runtime_functions_h__ -#define __ardour_runtime_functions_h__ - -#include <ardour/types.h> - -namespace ARDOUR { - - typedef float (*compute_peak_t) (const ARDOUR::Sample *, nframes_t, float); - typedef void (*find_peaks_t) (const ARDOUR::Sample *, nframes_t, float *, float*); - typedef void (*apply_gain_to_buffer_t) (ARDOUR::Sample *, nframes_t, float); - typedef void (*mix_buffers_with_gain_t) (ARDOUR::Sample *, const ARDOUR::Sample *, nframes_t, float); - typedef void (*mix_buffers_no_gain_t) (ARDOUR::Sample *, const ARDOUR::Sample *, nframes_t); - - extern compute_peak_t compute_peak; - extern find_peaks_t find_peaks; - extern apply_gain_to_buffer_t apply_gain_to_buffer; - extern mix_buffers_with_gain_t mix_buffers_with_gain; - extern mix_buffers_no_gain_t mix_buffers_no_gain; -} - -#endif /* __ardour_runtime_functions_h__ */ diff --git a/libs/ardour/ardour/send.h b/libs/ardour/ardour/send.h deleted file mode 100644 index 1ee8bbceca..0000000000 --- a/libs/ardour/ardour/send.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - Copyright (C) 2000 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_send_h__ -#define __ardour_send_h__ - -#include <sigc++/signal.h> -#include <string> - - -#include <pbd/stateful.h> -#include <ardour/ardour.h> -#include <ardour/audioengine.h> -#include <ardour/io.h> -#include <ardour/io_processor.h> - -namespace ARDOUR { - -class Send : public IOProcessor -{ - public: - Send (Session&, Placement); - Send (Session&, const XMLNode&); - Send (const Send&); - virtual ~Send (); - - uint32_t bit_slot() const { return bitslot; } - - ChanCount output_streams() const; - ChanCount input_streams () const; - - void run_in_place (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset); - - void activate() {} - void deactivate () {} - - void set_metering (bool yn); - - XMLNode& state(bool full); - XMLNode& get_state(void); - int set_state(const XMLNode& node); - - uint32_t pans_required() const { return _configured_input.n_audio(); } - - virtual bool can_support_input_configuration (ChanCount in) const; - virtual ChanCount output_for_input_configuration (ChanCount in) const; - virtual bool configure_io (ChanCount in, ChanCount out); - - static uint32_t how_many_sends(); - - private: - bool _metering; - uint32_t bitslot; -}; - -} // namespace ARDOUR - -#endif /* __ardour_send_h__ */ diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h deleted file mode 100644 index b718d751b4..0000000000 --- a/libs/ardour/ardour/session.h +++ /dev/null @@ -1,1714 +0,0 @@ -/* - Copyright (C) 2000 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_session_h__ -#define __ardour_session_h__ - -#include <string> -#include <list> -#include <map> -#include <vector> -#include <set> -#include <stack> - -#include <boost/scoped_ptr.hpp> -#include <boost/weak_ptr.hpp> -#include <boost/dynamic_bitset.hpp> - -#include <stdint.h> - -#include <sndfile.h> - -#include <glibmm/thread.h> - -#include <pbd/error.h> -#include <pbd/undo.h> -#include <pbd/pool.h> -#include <pbd/rcu.h> -#include <pbd/statefuldestructible.h> - -#include <midi++/types.h> -#include <midi++/mmc.h> - -#include <pbd/stateful.h> -#include <pbd/destructible.h> - -#include <ardour/ardour.h> -#include <ardour/configuration.h> -#include <ardour/location.h> -#include <ardour/gain.h> -#include <ardour/io.h> - -#include <ardour/smpte.h> - -class XMLTree; -class XMLNode; -class AEffect; - -namespace MIDI { - class Port; -} - -namespace PBD { - class Controllable; -} - -namespace ARDOUR { - -class Port; -class AudioEngine; -class Slave; -class Diskstream; -class Route; -class AuxInput; -class Source; -class AudioSource; -class BufferSet; - -class Diskstream; -class AudioDiskstream; -class MidiDiskstream; -class AudioFileSource; -class MidiSource; -class Auditioner; -class Processor; -class Send; -class IOProcessor; -class PortInsert; -class PluginInsert; -class Bundle; -class TempoMap; -class AudioTrack; -class NamedSelection; -class AudioRegion; - -class Region; -class Playlist; -class VSTPlugin; -class ControlProtocolInfo; - -class MidiTrack; -class MidiRegion; -class SMFSource; - -class SessionDirectory; - -struct ExportSpecification; -struct RouteGroup; - -using std::vector; -using std::string; -using std::map; -using std::set; - -class Session : public PBD::StatefulDestructible -{ - private: - typedef std::pair<boost::weak_ptr<Route>,bool> RouteBooleanState; - typedef vector<RouteBooleanState> GlobalRouteBooleanState; - typedef std::pair<boost::weak_ptr<Route>,MeterPoint> RouteMeterState; - typedef vector<RouteMeterState> GlobalRouteMeterState; - - public: - enum RecordState { - Disabled = 0, - Enabled = 1, - Recording = 2 - }; - - struct Event { - enum Type { - SetTransportSpeed, - SetDiskstreamSpeed, - Locate, - LocateRoll, - LocateRollLocate, - SetLoop, - PunchIn, - PunchOut, - RangeStop, - RangeLocate, - Overwrite, - SetSlaveSource, - Audition, - InputConfigurationChange, - SetAudioRange, - SetPlayRange, - - /* only one of each of these events - can be queued at any one time - */ - - StopOnce, - AutoLoop - }; - - enum Action { - Add, - Remove, - Replace, - Clear - }; - - Type type; - Action action; - nframes_t action_frame; - nframes_t target_frame; - float speed; - - union { - void* ptr; - bool yes_or_no; - nframes_t target2_frame; - SlaveSource slave; - Route* route; - }; - - boost::shared_ptr<Region> region; - - list<AudioRange> audio_range; - list<MusicRange> music_range; - - Event(Type t, Action a, nframes_t when, nframes_t where, float spd, bool yn = false) - : type (t), - action (a), - action_frame (when), - target_frame (where), - speed (spd), - yes_or_no (yn) {} - - void set_ptr (void* p) { - ptr = p; - } - - bool before (const Event& other) const { - return action_frame < other.action_frame; - } - - bool after (const Event& other) const { - return action_frame > other.action_frame; - } - - static bool compare (const Event *e1, const Event *e2) { - return e1->before (*e2); - } - - void *operator new (size_t ignored) { - return pool.alloc (); - } - - void operator delete(void *ptr, size_t size) { - pool.release (ptr); - } - - static const nframes_t Immediate = 0; - - private: - static MultiAllocSingleReleasePool pool; - }; - - /* creating from an XML file */ - - Session (AudioEngine&, - const string& fullpath, - const string& snapshot_name, - string mix_template = ""); - - /* creating a new Session */ - - Session (AudioEngine&, - string fullpath, - string snapshot_name, - AutoConnectOption input_auto_connect, - AutoConnectOption output_auto_connect, - uint32_t control_out_channels, - uint32_t master_out_channels, - uint32_t n_physical_in, - uint32_t n_physical_out, - nframes_t initial_length); - - virtual ~Session (); - - string path() const { return _path; } - string name() const { return _name; } - string snap_name() const { return _current_snapshot_name; } - string raid_path () const; - - void set_snap_name (); - - void set_dirty (); - void set_clean (); - bool dirty() const { return _state_of_the_state & Dirty; } - void set_deletion_in_progress (); - bool deletion_in_progress() const { return _state_of_the_state & Deletion; } - sigc::signal<void> DirtyChanged; - - const SessionDirectory& session_directory () const { return *(_session_dir.get()); } - - static sigc::signal<void> AutoBindingOn; - static sigc::signal<void> AutoBindingOff; - - static sigc::signal<void,std::string> Dialog; - - std::string sound_dir (bool with_path = true) const; - std::string peak_dir () const; - std::string dead_sound_dir () const; - std::string automation_dir () const; - std::string analysis_dir() const; - - int ensure_subdirs (); - - Glib::ustring peak_path (Glib::ustring) const; - - static string change_audio_path_by_name (string oldpath, string oldname, string newname, bool destructive); - static string change_midi_path_by_name (string oldpath, string oldname, string newname, bool destructive); - - string peak_path_from_audio_path (string) const; - string audio_path_from_name (string, uint32_t nchans, uint32_t chan, bool destructive); - string midi_path_from_name (string); - - void process (nframes_t nframes); - - BufferSet& get_silent_buffers (ChanCount count = ChanCount::ZERO); - BufferSet& get_scratch_buffers (ChanCount count = ChanCount::ZERO); - BufferSet& get_mix_buffers (ChanCount count = ChanCount::ZERO); - - void add_diskstream (boost::shared_ptr<Diskstream>); - boost::shared_ptr<Diskstream> diskstream_by_id (const PBD::ID& id); - boost::shared_ptr<Diskstream> diskstream_by_name (string name); - - bool have_captured() const { return _have_captured; } - - void refill_all_diskstream_buffers (); - uint32_t audio_diskstream_buffer_size() const { return audio_dstream_buffer_size; } - uint32_t midi_diskstream_buffer_size() const { return midi_dstream_buffer_size; } - - uint32_t get_next_diskstream_id() const { return n_diskstreams(); } - uint32_t n_diskstreams() const; - - typedef std::list<boost::shared_ptr<Diskstream> > DiskstreamList; - typedef std::list<boost::shared_ptr<Route> > RouteList; - - boost::shared_ptr<RouteList> get_routes() const { - return routes.reader (); - } - - uint32_t nroutes() const { return routes.reader()->size(); } - uint32_t ntracks () const; - uint32_t nbusses () const; - - struct RoutePublicOrderSorter { - bool operator() (boost::shared_ptr<Route>, boost::shared_ptr<Route> b); - }; - - template<class T> void foreach_route (T *obj, void (T::*func)(Route&)); - template<class T> void foreach_route (T *obj, void (T::*func)(boost::shared_ptr<Route>)); - template<class T, class A> void foreach_route (T *obj, void (T::*func)(Route&, A), A arg); - - boost::shared_ptr<Route> route_by_name (string); - boost::shared_ptr<Route> route_by_id (PBD::ID); - boost::shared_ptr<Route> route_by_remote_id (uint32_t id); - - bool route_name_unique (string) const; - - bool get_record_enabled() const { - return (record_status () >= Enabled); - } - - RecordState record_status() const { - return (RecordState) g_atomic_int_get (&_record_status); - } - - bool actively_recording () { - return record_status() == Recording; - } - - bool record_enabling_legal () const; - void maybe_enable_record (); - void disable_record (bool rt_context, bool force = false); - void step_back_from_record (); - - void maybe_write_autosave (); - - /* Proxy signal for region hidden changes */ - - sigc::signal<void,boost::shared_ptr<Region> > RegionHiddenChange; - - /* Emitted when all i/o connections are complete */ - - sigc::signal<void> IOConnectionsComplete; - - /* Record status signals */ - - sigc::signal<void> RecordStateChanged; - - /* Transport mechanism signals */ - - sigc::signal<void> TransportStateChange; /* generic */ - sigc::signal<void,nframes_t> PositionChanged; /* sent after any non-sequential motion */ - sigc::signal<void> DurationChanged; - sigc::signal<void,nframes_t> Xrun; - sigc::signal<void> TransportLooped; - - sigc::signal<void,RouteList&> RouteAdded; - - void request_roll_at_and_return (nframes_t start, nframes_t return_to); - void request_bounded_roll (nframes_t start, nframes_t end); - void request_stop (bool abort = false); - void request_locate (nframes_t frame, bool with_roll = false); - - void request_play_loop (bool yn); - bool get_play_loop () const { return play_loop; } - - nframes_t last_transport_start() const { return _last_roll_location; } - void goto_end () { request_locate (end_location->start(), false);} - void goto_start () { request_locate (start_location->start(), false); } - void set_session_start (nframes_t start) { start_location->set_start(start); } - void set_session_end (nframes_t end) { end_location->set_start(end); _end_location_is_free = false; } - void use_rf_shuttle_speed (); - void allow_auto_play (bool yn); - void request_transport_speed (float speed); - void request_overwrite_buffer (Diskstream*); - void request_diskstream_speed (Diskstream&, float speed); - void request_input_change_handling (); - - bool locate_pending() const { return static_cast<bool>(post_transport_work&PostTransportLocate); } - bool transport_locked () const; - - int wipe (); - //int wipe_diskstream (AudioDiskstream *); - - int remove_region_from_region_list (boost::shared_ptr<Region>); - - nframes_t get_maximum_extent () const; - nframes_t current_end_frame() const { return end_location->start(); } - nframes_t current_start_frame() const { return start_location->start(); } - // "actual" sample rate of session, set by current audioengine rate, pullup/down etc. - nframes_t frame_rate() const { return _current_frame_rate; } - // "native" sample rate of session, regardless of current audioengine rate, pullup/down etc - nframes_t nominal_frame_rate() const { return _nominal_frame_rate; } - nframes_t frames_per_hour() const { return _frames_per_hour; } - - double frames_per_smpte_frame() const { return _frames_per_smpte_frame; } - nframes_t smpte_frames_per_hour() const { return _smpte_frames_per_hour; } - - float smpte_frames_per_second() const; - bool smpte_drop_frames() const; - - /* Locations */ - - Locations *locations() { return &_locations; } - - sigc::signal<void,Location*> auto_loop_location_changed; - sigc::signal<void,Location*> auto_punch_location_changed; - sigc::signal<void> locations_modified; - - void set_auto_punch_location (Location *); - void set_auto_loop_location (Location *); - int location_name(string& result, string base = string("")); - - void reset_input_monitor_state (); - - void add_event (nframes_t action_frame, Event::Type type, nframes_t target_frame = 0); - void remove_event (nframes_t frame, Event::Type type); - void clear_events (Event::Type type); - - nframes_t get_block_size() const { return current_block_size; } - nframes_t worst_output_latency () const { return _worst_output_latency; } - nframes_t worst_input_latency () const { return _worst_input_latency; } - nframes_t worst_track_latency () const { return _worst_track_latency; } - - int save_state (string snapshot_name, bool pending = false); - int restore_state (string snapshot_name); - int save_template (string template_name); - int save_history (string snapshot_name = ""); - int restore_history (string snapshot_name); - void remove_state (string snapshot_name); - void rename_state (string old_name, string new_name); - void remove_pending_capture_state (); - - sigc::signal<void,string> StateSaved; - sigc::signal<void> StateReady; - - vector<string*>* possible_states() const; - static vector<string*>* possible_states(string path); - - XMLNode& get_state(); - int set_state(const XMLNode& node); // not idempotent - XMLNode& get_template(); - - /// The instant xml file is written to the session directory - void add_instant_xml (XMLNode&); - XMLNode * instant_xml (const std::string& str); - - enum StateOfTheState { - Clean = 0x0, - Dirty = 0x1, - CannotSave = 0x2, - Deletion = 0x4, - InitialConnecting = 0x8, - Loading = 0x10, - InCleanup = 0x20 - }; - - StateOfTheState state_of_the_state() const { return _state_of_the_state; } - - RouteGroup* add_edit_group (string); - RouteGroup* add_mix_group (string); - - void remove_edit_group (RouteGroup&); - void remove_mix_group (RouteGroup&); - - RouteGroup *mix_group_by_name (string); - RouteGroup *edit_group_by_name (string); - - sigc::signal<void,RouteGroup*> edit_group_added; - sigc::signal<void,RouteGroup*> mix_group_added; - sigc::signal<void> edit_group_removed; - sigc::signal<void> mix_group_removed; - - void foreach_edit_group (sigc::slot<void,RouteGroup*> sl) { - for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); i++) { - sl (*i); - } - } - - void foreach_mix_group (sigc::slot<void,RouteGroup*> sl) { - for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); i++) { - sl (*i); - } - } - - /* fundamental operations. duh. */ - - std::list<boost::shared_ptr<AudioTrack> > new_audio_track (int input_channels, int output_channels, TrackMode mode = Normal, uint32_t how_many = 1); - RouteList new_audio_route (int input_channels, int output_channels, uint32_t how_many); - - std::list<boost::shared_ptr<MidiTrack> > new_midi_track (TrackMode mode = Normal, uint32_t how_many = 1); - //boost::shared_ptr<Route> new_midi_route (uint32_t how_many = 1); - - void remove_route (boost::shared_ptr<Route>); - void resort_routes (); - void resort_routes_using (boost::shared_ptr<RouteList>); - - void set_remote_control_ids(); - - AudioEngine & engine() { return _engine; } - AudioEngine const & engine () const { return _engine; } - - int32_t max_level; - int32_t min_level; - - /* Time */ - - nframes_t transport_frame () const {return _transport_frame; } - nframes_t audible_frame () const; - nframes64_t requested_return_frame() const { return _requested_return_frame; } - - enum PullupFormat { - pullup_Plus4Plus1, - pullup_Plus4, - pullup_Plus4Minus1, - pullup_Plus1, - pullup_None, - pullup_Minus1, - pullup_Minus4Plus1, - pullup_Minus4, - pullup_Minus4Minus1 - }; - - int set_smpte_format (SmpteFormat); - void sync_time_vars(); - - void bbt_time (nframes_t when, BBT_Time&); - void smpte_to_sample( SMPTE::Time& smpte, nframes_t& sample, bool use_offset, bool use_subframes ) const; - void sample_to_smpte( nframes_t sample, SMPTE::Time& smpte, bool use_offset, bool use_subframes ) const; - void smpte_time (SMPTE::Time &); - void smpte_time (nframes_t when, SMPTE::Time&); - void smpte_time_subframes (nframes_t when, SMPTE::Time&); - - void smpte_duration (nframes_t, SMPTE::Time&) const; - void smpte_duration_string (char *, nframes_t) const; - - void set_smpte_offset (nframes_t); - nframes_t smpte_offset () const { return _smpte_offset; } - void set_smpte_offset_negative (bool); - bool smpte_offset_negative () const { return _smpte_offset_negative; } - - nframes_t convert_to_frames_at (nframes_t position, AnyTime&); - - static sigc::signal<void> StartTimeChanged; - static sigc::signal<void> EndTimeChanged; - static sigc::signal<void> SMPTEOffsetChanged; - - void request_slave_source (SlaveSource); - bool synced_to_jack() const { return Config->get_slave_source() == JACK; } - - float transport_speed() const { return _transport_speed; } - bool transport_stopped() const { return _transport_speed == 0.0f; } - bool transport_rolling() const { return _transport_speed != 0.0f; } - - void set_silent (bool yn); - bool silent () { return _silent; } - - int jack_slave_sync (nframes_t); - - TempoMap& tempo_map() { return *_tempo_map; } - - /* region info */ - - void add_regions (std::vector<boost::shared_ptr<Region> >&); - - sigc::signal<void,boost::weak_ptr<Region> > RegionAdded; - sigc::signal<void,std::vector<boost::weak_ptr<Region> >& > RegionsAdded; - sigc::signal<void,boost::weak_ptr<Region> > RegionRemoved; - - int region_name (string& result, string base = string(""), bool newlevel = false) const; - string new_region_name (string); - string path_from_region_name (DataType type, string name, string identifier); - - boost::shared_ptr<Region> find_whole_file_parent (boost::shared_ptr<Region const>); - - void find_equivalent_playlist_regions (boost::shared_ptr<Region>, std::vector<boost::shared_ptr<Region> >& result); - - boost::shared_ptr<Region> XMLRegionFactory (const XMLNode&, bool full); - boost::shared_ptr<AudioRegion> XMLAudioRegionFactory (const XMLNode&, bool full); - boost::shared_ptr<MidiRegion> XMLMidiRegionFactory (const XMLNode&, bool full); - - template<class T> void foreach_region (T *obj, void (T::*func)(boost::shared_ptr<Region>)); - - /* source management */ - - struct import_status : public InterThreadInfo { - string doing_what; - - /* control info */ - SrcQuality quality; - volatile bool freeze; - std::vector<Glib::ustring> paths; - bool replace_existing_source; - - /* result */ - SourceList sources; - - }; - - void import_audiofiles (import_status&); - bool sample_rate_convert (import_status&, string infile, string& outfile); - string build_tmp_convert_name (string file); - - SlaveSource post_export_slave; - nframes_t post_export_position; - - int start_export (ARDOUR::ExportSpecification&); - int stop_export (ARDOUR::ExportSpecification&); - void finalize_audio_export (); - - void add_source (boost::shared_ptr<Source>); - void remove_source (boost::weak_ptr<Source>); - - struct cleanup_report { - vector<string> paths; - int64_t space; - }; - - int cleanup_sources (cleanup_report&); - int cleanup_trash_sources (cleanup_report&); - - int destroy_region (boost::shared_ptr<Region>); - int destroy_regions (std::list<boost::shared_ptr<Region> >); - - int remove_last_capture (); - - /* handlers should return -1 for "stop cleanup", 0 for - "yes, delete this playlist" and 1 for "no, don't delete - this playlist. - */ - - sigc::signal<int,boost::shared_ptr<ARDOUR::Playlist> > AskAboutPlaylistDeletion; - - /* handlers should return 0 for "ignore the rate mismatch" - and !0 for "do not use this session" - */ - - static sigc::signal<int,nframes_t, nframes_t> AskAboutSampleRateMismatch; - - /* handlers should return !0 for use pending state, 0 for - ignore it. - */ - - static sigc::signal<int> AskAboutPendingState; - - boost::shared_ptr<AudioFileSource> create_audio_source_for_session (ARDOUR::AudioDiskstream&, uint32_t which_channel, bool destructive); - - boost::shared_ptr<MidiSource> create_midi_source_for_session (ARDOUR::MidiDiskstream&); - - boost::shared_ptr<Source> source_by_id (const PBD::ID&); - boost::shared_ptr<Source> source_by_path_and_channel (const Glib::ustring&, uint16_t); - - /* playlist management */ - - boost::shared_ptr<Playlist> playlist_by_name (string name); - void add_playlist (boost::shared_ptr<Playlist>); - sigc::signal<void,boost::shared_ptr<Playlist> > PlaylistAdded; - sigc::signal<void,boost::shared_ptr<Playlist> > PlaylistRemoved; - - uint32_t n_playlists() const; - - template<class T> void foreach_playlist (T *obj, void (T::*func)(boost::shared_ptr<Playlist>)); - void get_playlists (std::vector<boost::shared_ptr<Playlist> >&); - - /* named selections */ - - NamedSelection* named_selection_by_name (string name); - void add_named_selection (NamedSelection *); - void remove_named_selection (NamedSelection *); - - template<class T> void foreach_named_selection (T& obj, void (T::*func)(NamedSelection&)); - sigc::signal<void> NamedSelectionAdded; - sigc::signal<void> NamedSelectionRemoved; - - /* Curves and AutomationLists (TODO when they go away) */ - void add_curve(Curve*); - void add_automation_list(AutomationList*); - - /* fade curves */ - - float get_default_fade_length () const { return default_fade_msecs; } - float get_default_fade_steepness () const { return default_fade_steepness; } - void set_default_fade (float steepness, float msecs); - - /* auditioning */ - - boost::shared_ptr<Auditioner> the_auditioner() { return auditioner; } - void audition_playlist (); - void audition_region (boost::shared_ptr<Region>); - void cancel_audition (); - bool is_auditioning () const; - - sigc::signal<void,bool> AuditionActive; - - /* flattening stuff */ - - int write_one_audio_track (AudioTrack&, nframes_t start, nframes_t cnt, bool overwrite, - vector<boost::shared_ptr<Source> >&, InterThreadInfo& wot); - - int freeze (InterThreadInfo&); - - /* session-wide solo/mute/rec-enable */ - - bool soloing() const { return currently_soloing; } - - void set_all_solo (bool); - void set_all_mute (bool); - - sigc::signal<void,bool> SoloActive; - sigc::signal<void> SoloChanged; - - void record_disenable_all (); - void record_enable_all (); - - /* control/master out */ - - boost::shared_ptr<IO> control_out() const { return _control_out; } - boost::shared_ptr<IO> master_out() const { return _master_out; } - - /* insert/send management */ - - uint32_t n_port_inserts() const { return _port_inserts.size(); } - uint32_t n_plugin_inserts() const { return _plugin_inserts.size(); } - uint32_t n_sends() const { return _sends.size(); } - - static void set_disable_all_loaded_plugins (bool yn) { - _disable_all_loaded_plugins = yn; - } - static bool get_disable_all_loaded_plugins() { - return _disable_all_loaded_plugins; - } - - uint32_t next_send_id(); - uint32_t next_insert_id(); - void mark_send_id (uint32_t); - void mark_insert_id (uint32_t); - - /* s/w "RAID" management */ - - nframes_t available_capture_duration(); - - /* I/O bundles */ - - void foreach_bundle (sigc::slot<void, boost::shared_ptr<Bundle> >); - void add_bundle (boost::shared_ptr<Bundle>); - void remove_bundle (boost::shared_ptr<Bundle>); - boost::shared_ptr<Bundle> bundle_by_name (string) const; - - sigc::signal<void,boost::shared_ptr<Bundle> > BundleAdded; - sigc::signal<void,boost::shared_ptr<Bundle> > BundleRemoved; - - /* MIDI */ - - void midi_panic(void); - int set_mtc_port (string port_tag); - int set_mmc_port (string port_tag); - int set_midi_port (string port_tag); - MIDI::Port *mtc_port() const { return _mtc_port; } - MIDI::Port *mmc_port() const { return _mmc_port; } - MIDI::Port *midi_port() const { return _midi_port; } - - sigc::signal<void> MTC_PortChanged; - sigc::signal<void> MMC_PortChanged; - sigc::signal<void> MIDI_PortChanged; - - void set_trace_midi_input (bool, MIDI::Port* port = 0); - void set_trace_midi_output (bool, MIDI::Port* port = 0); - - bool get_trace_midi_input(MIDI::Port *port = 0); - bool get_trace_midi_output(MIDI::Port *port = 0); - - void set_mmc_receive_device_id (uint32_t id); - void set_mmc_send_device_id (uint32_t id); - - /* Scrubbing */ - - void start_scrub (nframes_t where); - void stop_scrub (); - void set_scrub_speed (float); - nframes_t scrub_buffer_size() const; - sigc::signal<void> ScrubReady; - - /* History (for editors, mixers, UIs etc.) */ - - /** Undo some transactions. - * @param n Number of transactions to undo. - */ - void undo (uint32_t n) { - _history.undo (n); - } - - void redo (uint32_t n) { - _history.redo (n); - } - - UndoHistory& history() { return _history; } - - uint32_t undo_depth() const { return _history.undo_depth(); } - uint32_t redo_depth() const { return _history.redo_depth(); } - string next_undo() const { return _history.next_undo(); } - string next_redo() const { return _history.next_redo(); } - - void begin_reversible_command (const string& cmd_name); - void commit_reversible_command (Command* cmd = 0); - - void add_command (Command *const cmd) { - current_trans->add_command (cmd); - } - - std::map<PBD::ID, PBD::StatefulThingWithGoingAway*> registry; - - // these commands are implemented in libs/ardour/session_command.cc - Command* memento_command_factory(XMLNode* n); - void register_with_memento_command_factory(PBD::ID, PBD::StatefulThingWithGoingAway*); - - Command* global_state_command_factory (const XMLNode& n); - - class GlobalRouteStateCommand : public Command - { - public: - GlobalRouteStateCommand (Session&, void*); - GlobalRouteStateCommand (Session&, const XMLNode& node); - int set_state (const XMLNode&); - XMLNode& get_state (); - - protected: - GlobalRouteBooleanState before, after; - Session& sess; - void* src; - - }; - - class GlobalSoloStateCommand : public GlobalRouteStateCommand - { - public: - GlobalSoloStateCommand (Session &, void *src); - GlobalSoloStateCommand (Session&, const XMLNode&); - void operator()(); //redo - void undo(); - XMLNode &get_state(); - void mark(); - }; - - class GlobalMuteStateCommand : public GlobalRouteStateCommand - { - public: - GlobalMuteStateCommand(Session &, void *src); - GlobalMuteStateCommand (Session&, const XMLNode&); - void operator()(); // redo - void undo(); - XMLNode &get_state(); - void mark(); - }; - - class GlobalRecordEnableStateCommand : public GlobalRouteStateCommand - { - public: - GlobalRecordEnableStateCommand(Session &, void *src); - GlobalRecordEnableStateCommand (Session&, const XMLNode&); - void operator()(); // redo - void undo(); - XMLNode &get_state(); - void mark(); - }; - - class GlobalMeteringStateCommand : public Command - { - public: - GlobalMeteringStateCommand(Session &, void *src); - GlobalMeteringStateCommand (Session&, const XMLNode&); - void operator()(); - void undo(); - XMLNode &get_state(); - int set_state (const XMLNode&); - void mark(); - - protected: - Session& sess; - void* src; - GlobalRouteMeterState before; - GlobalRouteMeterState after; - }; - - /* clicking */ - - boost::shared_ptr<IO> click_io() { return _click_io; } - - /* disk, buffer loads */ - - uint32_t playback_load (); - uint32_t capture_load (); - uint32_t playback_load_min (); - uint32_t capture_load_min (); - - void reset_playback_load_min (); - void reset_capture_load_min (); - - float read_data_rate () const; - float write_data_rate () const; - - /* ranges */ - - void set_audio_range (list<AudioRange>&); - void set_music_range (list<MusicRange>&); - - void request_play_range (bool yn); - bool get_play_range () const { return _play_range; } - - /* buffers for gain and pan */ - - gain_t* gain_automation_buffer () const { return _gain_automation_buffer; } - pan_t** pan_automation_buffer () const { return _pan_automation_buffer; } - - /* buffers for conversion */ - enum RunContext { - ButlerContext = 0, - TransportContext, - ExportContext - }; - - /* VST support */ - - static long vst_callback (AEffect* effect, - long opcode, - long index, - long value, - void* ptr, - float opt); - - typedef float (*compute_peak_t) (Sample *, nframes_t, float); - typedef void (*find_peaks_t) (Sample *, nframes_t, float *, float*); - typedef void (*apply_gain_to_buffer_t) (Sample *, nframes_t, float); - typedef void (*mix_buffers_with_gain_t) (Sample *, Sample *, nframes_t, float); - typedef void (*mix_buffers_no_gain_t) (Sample *, Sample *, nframes_t); - - static compute_peak_t compute_peak; - static find_peaks_t find_peaks; - static apply_gain_to_buffer_t apply_gain_to_buffer; - static mix_buffers_with_gain_t mix_buffers_with_gain; - static mix_buffers_no_gain_t mix_buffers_no_gain; - - static sigc::signal<void> SendFeedback; - - /* Controllables */ - - boost::shared_ptr<PBD::Controllable> controllable_by_id (const PBD::ID&); - - void add_controllable (boost::shared_ptr<PBD::Controllable>); - void remove_controllable (PBD::Controllable*); - - protected: - friend class AudioEngine; - void set_block_size (nframes_t nframes); - void set_frame_rate (nframes_t nframes); - - protected: - friend class Diskstream; - void stop_butler (); - void wait_till_butler_finished(); - - protected: - friend class Route; - void schedule_curve_reallocation (); - void update_latency_compensation (bool, bool); - - private: - int create (bool& new_session, const string& mix_template, nframes_t initial_length); - void destroy (); - - nframes_t compute_initial_length (); - - enum SubState { - PendingDeclickIn = 0x1, - PendingDeclickOut = 0x2, - StopPendingCapture = 0x4, - AutoReturning = 0x10, - PendingLocate = 0x20, - PendingSetLoop = 0x40 - }; - - /* stuff used in process() should be close together to - maximise cache hits - */ - - typedef void (Session::*process_function_type)(nframes_t); - - AudioEngine& _engine; - mutable gint processing_prohibited; - process_function_type process_function; - process_function_type last_process_function; - bool waiting_for_sync_offset; - nframes_t _base_frame_rate; - nframes_t _current_frame_rate; //this includes video pullup offset - nframes_t _nominal_frame_rate; //ignores audioengine setting, "native" SR - int transport_sub_state; - mutable gint _record_status; - volatile nframes_t _transport_frame; - Location* end_location; - Location* start_location; - Slave* _slave; - bool _silent; - volatile float _transport_speed; - volatile float _desired_transport_speed; - float _last_transport_speed; - bool auto_play_legal; - nframes_t _last_slave_transport_frame; - nframes_t maximum_output_latency; - nframes_t last_stop_frame; - volatile nframes64_t _requested_return_frame; - BufferSet* _scratch_buffers; - BufferSet* _silent_buffers; - BufferSet* _mix_buffers; - nframes_t current_block_size; - nframes_t _worst_output_latency; - nframes_t _worst_input_latency; - nframes_t _worst_track_latency; - bool _have_captured; - float _meter_hold; - float _meter_falloff; - bool _end_location_is_free; - - void set_worst_io_latencies (); - void set_worst_io_latencies_x (IOChange asifwecare, void *ignored) { - set_worst_io_latencies (); - } - - void update_latency_compensation_proxy (void* ignored); - - void ensure_buffers (ChanCount howmany); - - void process_scrub (nframes_t); - void process_without_events (nframes_t); - void process_with_events (nframes_t); - void process_audition (nframes_t); - int process_export (nframes_t, ARDOUR::ExportSpecification*); - - /* slave tracking */ - - static const int delta_accumulator_size = 25; - int delta_accumulator_cnt; - long delta_accumulator[delta_accumulator_size]; - long average_slave_delta; - int average_dir; - bool have_first_delta_accumulator; - - enum SlaveState { - Stopped, - Waiting, - Running - }; - - SlaveState slave_state; - nframes_t slave_wait_end; - - void reset_slave_state (); - bool follow_slave (nframes_t, nframes_t); - void set_slave_source (SlaveSource); - - bool _exporting; - int prepare_to_export (ARDOUR::ExportSpecification&); - - void prepare_diskstreams (); - void commit_diskstreams (nframes_t, bool& session_requires_butler); - int process_routes (nframes_t, nframes_t); - int silent_process_routes (nframes_t, nframes_t); - - bool get_rec_monitors_input () { - if (actively_recording()) { - return true; - } else { - if (Config->get_auto_input()) { - return false; - } else { - return true; - } - } - } - - int get_transport_declick_required () { - - if (transport_sub_state & PendingDeclickIn) { - transport_sub_state &= ~PendingDeclickIn; - return 1; - } else if (transport_sub_state & PendingDeclickOut) { - return -1; - } else { - return 0; - } - } - - bool maybe_stop (nframes_t limit) { - if ((_transport_speed > 0.0f && _transport_frame >= limit) || (_transport_speed < 0.0f && _transport_frame == 0)) { - stop_transport (); - return true; - } - return false; - } - - bool maybe_sync_start (nframes_t&, nframes_t&); - - void check_declick_out (); - - MIDI::MachineControl* mmc; - MIDI::Port* _mmc_port; - MIDI::Port* _mtc_port; - MIDI::Port* _midi_port; - string _path; - string _name; - bool session_send_mmc; - bool session_send_mtc; - bool session_midi_feedback; - bool play_loop; - bool loop_changing; - nframes_t last_loopend; - - boost::scoped_ptr<SessionDirectory> _session_dir; - - RingBuffer<Event*> pending_events; - - void hookup_io (); - void when_engine_running (); - void graph_reordered (); - - string _current_snapshot_name; - - XMLTree* state_tree; - bool state_was_pending; - StateOfTheState _state_of_the_state; - - void auto_save(); - int load_options (const XMLNode&); - XMLNode& get_options () const; - int load_state (string snapshot_name); - bool save_config_options_predicate (ConfigVariableBase::Owner owner) const; - - nframes_t _last_roll_location; - nframes_t _last_record_location; - - bool pending_locate_roll; - nframes_t pending_locate_frame; - bool pending_locate_flush; - bool pending_abort; - bool pending_auto_loop; - - Sample* butler_mixdown_buffer; - float* butler_gain_buffer; - pthread_t butler_thread; - Glib::Mutex butler_request_lock; - Glib::Cond butler_paused; - bool butler_should_run; - mutable gint butler_should_do_transport_work; - int butler_request_pipe[2]; - - inline bool transport_work_requested() const { return g_atomic_int_get(&butler_should_do_transport_work); } - - struct ButlerRequest { - enum Type { - Wake, - Run, - Pause, - Quit - }; - }; - - enum PostTransportWork { - PostTransportStop = 0x1, - PostTransportDisableRecord = 0x2, - PostTransportPosition = 0x8, - PostTransportDidRecord = 0x20, - PostTransportDuration = 0x40, - PostTransportLocate = 0x80, - PostTransportRoll = 0x200, - PostTransportAbort = 0x800, - PostTransportOverWrite = 0x1000, - PostTransportSpeed = 0x2000, - PostTransportAudition = 0x4000, - PostTransportScrub = 0x8000, - PostTransportReverse = 0x10000, - PostTransportInputChange = 0x20000, - PostTransportCurveRealloc = 0x40000 - }; - - static const PostTransportWork ProcessCannotProceedMask = - PostTransportWork (PostTransportInputChange| - PostTransportSpeed| - PostTransportReverse| - PostTransportCurveRealloc| - PostTransportScrub| - PostTransportAudition| - PostTransportLocate| - PostTransportStop); - - PostTransportWork post_transport_work; - - void summon_butler (); - void schedule_butler_transport_work (); - int start_butler_thread (); - void terminate_butler_thread (); - static void *_butler_thread_work (void *arg); - void* butler_thread_work (); - - uint32_t cumulative_rf_motion; - uint32_t rf_scale; - - void set_rf_speed (float speed); - void reset_rf_scale (nframes_t frames_moved); - - Locations _locations; - void locations_changed (); - void locations_added (Location*); - void handle_locations_changed (Locations::LocationList&); - - sigc::connection auto_punch_start_changed_connection; - sigc::connection auto_punch_end_changed_connection; - sigc::connection auto_punch_changed_connection; - void auto_punch_start_changed (Location *); - void auto_punch_end_changed (Location *); - void auto_punch_changed (Location *); - - sigc::connection auto_loop_start_changed_connection; - sigc::connection auto_loop_end_changed_connection; - sigc::connection auto_loop_changed_connection; - void auto_loop_changed (Location *); - - typedef list<Event *> Events; - Events events; - Events immediate_events; - Events::iterator next_event; - - /* there can only ever be one of each of these */ - - Event *auto_loop_event; - Event *punch_out_event; - Event *punch_in_event; - - /* events */ - - void dump_events () const; - void queue_event (Event *ev); - void merge_event (Event*); - void replace_event (Event::Type, nframes_t action_frame, nframes_t target = 0); - bool _replace_event (Event*); - bool _remove_event (Event *); - void _clear_event_type (Event::Type); - - void first_stage_init (string path, string snapshot_name); - int second_stage_init (bool new_tracks); - void find_current_end (); - void remove_empty_sounds (); - - void setup_midi_control (); - int midi_read (MIDI::Port *); - - void enable_record (); - - void increment_transport_position (uint32_t val) { - if (max_frames - val < _transport_frame) { - _transport_frame = max_frames; - } else { - _transport_frame += val; - } - } - - void decrement_transport_position (uint32_t val) { - if (val < _transport_frame) { - _transport_frame -= val; - } else { - _transport_frame = 0; - } - } - - void post_transport_motion (); - static void *session_loader_thread (void *arg); - - void *do_work(); - - void set_next_event (); - void process_event (Event *ev); - - /* MIDI Machine Control */ - - void deliver_mmc (MIDI::MachineControl::Command, nframes_t); - - void spp_start (MIDI::Parser&); - void spp_continue (MIDI::Parser&); - void spp_stop (MIDI::Parser&); - - void mmc_deferred_play (MIDI::MachineControl &); - void mmc_stop (MIDI::MachineControl &); - void mmc_step (MIDI::MachineControl &, int); - void mmc_pause (MIDI::MachineControl &); - void mmc_record_pause (MIDI::MachineControl &); - void mmc_record_strobe (MIDI::MachineControl &); - void mmc_record_exit (MIDI::MachineControl &); - void mmc_track_record_status (MIDI::MachineControl &, uint32_t track, bool enabled); - void mmc_fast_forward (MIDI::MachineControl &); - void mmc_rewind (MIDI::MachineControl &); - void mmc_locate (MIDI::MachineControl &, const MIDI::byte *); - void mmc_shuttle (MIDI::MachineControl &mmc, float speed, bool forw); - void mmc_record_enable (MIDI::MachineControl &mmc, size_t track, bool enabled); - - struct timeval last_mmc_step; - double step_speed; - - typedef sigc::slot<bool> MidiTimeoutCallback; - typedef list<MidiTimeoutCallback> MidiTimeoutList; - - MidiTimeoutList midi_timeouts; - bool mmc_step_timeout (); - - MIDI::byte mmc_buffer[32]; - MIDI::byte mtc_msg[16]; - MIDI::byte mtc_smpte_bits; /* encoding of SMTPE type for MTC */ - MIDI::byte midi_msg[16]; - nframes_t outbound_mtc_smpte_frame; - SMPTE::Time transmitting_smpte_time; - int next_quarter_frame_to_send; - - double _frames_per_smpte_frame; /* has to be floating point because of drop frame */ - nframes_t _frames_per_hour; - nframes_t _smpte_frames_per_hour; - nframes_t _smpte_offset; - bool _smpte_offset_negative; - - /* cache the most-recently requested time conversions. This helps when we - * have multiple clocks showing the same time (e.g. the transport frame) */ - bool last_smpte_valid; - nframes_t last_smpte_when; - SMPTE::Time last_smpte; - - bool _send_smpte_update; ///< Flag to send a full frame (SMPTE) MTC message this cycle - - int send_full_time_code(nframes_t nframes); - int send_midi_time_code_for_cycle(nframes_t nframes); - - nframes_t adjust_apparent_position (nframes_t frames); - - void reset_record_status (); - - int no_roll (nframes_t nframes, nframes_t offset); - - bool non_realtime_work_pending() const { return static_cast<bool>(post_transport_work); } - bool process_can_proceed() const { return !(post_transport_work & ProcessCannotProceedMask); } - - struct MIDIRequest { - - enum Type { - PortChange, - Quit - }; - - Type type; - - MIDIRequest () {} - }; - - Glib::Mutex midi_lock; - pthread_t midi_thread; - int midi_request_pipe[2]; - RingBuffer<MIDIRequest*> midi_requests; - - int start_midi_thread (); - void terminate_midi_thread (); - void poke_midi_thread (); - static void *_midi_thread_work (void *arg); - void midi_thread_work (); - void change_midi_ports (); - int use_config_midi_ports (); - - mutable gint butler_active; - bool waiting_to_start; - - void set_play_loop (bool yn); - void overwrite_some_buffers (Diskstream*); - void flush_all_inserts (); - void locate (nframes_t, bool with_roll, bool with_flush, bool with_loop=false); - void start_locate (nframes_t, bool with_roll, bool with_flush, bool with_loop=false); - void force_locate (nframes_t frame, bool with_roll = false); - void set_diskstream_speed (Diskstream*, float speed); - void set_transport_speed (float speed, bool abort = false); - void stop_transport (bool abort = false); - void start_transport (); - void actually_start_transport (); - void realtime_stop (bool abort); - void non_realtime_start_scrub (); - void non_realtime_set_speed (); - void non_realtime_locate (); - void non_realtime_stop (bool abort, int entry_request_count, bool& finished); - void non_realtime_overwrite (int entry_request_count, bool& finished); - void butler_transport_work (); - void post_transport (); - void engine_halted (); - void xrun_recovery (); - - TempoMap *_tempo_map; - void tempo_map_changed (Change); - - /* edit/mix groups */ - - int load_route_groups (const XMLNode&, bool is_edit); - int load_edit_groups (const XMLNode&); - int load_mix_groups (const XMLNode&); - - - list<RouteGroup *> edit_groups; - list<RouteGroup *> mix_groups; - - /* disk-streams */ - - SerializedRCUManager<DiskstreamList> diskstreams; - - uint32_t audio_dstream_buffer_size; - uint32_t midi_dstream_buffer_size; - int load_diskstreams (const XMLNode&); - - /* routes stuff */ - - SerializedRCUManager<RouteList> routes; - - void add_routes (RouteList&, bool save); - uint32_t destructive_index; - - int load_routes (const XMLNode&); - boost::shared_ptr<Route> XMLRouteFactory (const XMLNode&); - - /* mixer stuff */ - - bool solo_update_disabled; - bool currently_soloing; - - void route_mute_changed (void *src); - void route_solo_changed (void *src, boost::weak_ptr<Route>); - void catch_up_on_solo (); - void update_route_solo_state (); - void modify_solo_mute (bool, bool); - void strip_portname_for_solo (string& portname); - - /* REGION MANAGEMENT */ - - mutable Glib::Mutex region_lock; - typedef map<PBD::ID,boost::shared_ptr<Region> > RegionList; - RegionList regions; - - void add_region (boost::shared_ptr<Region>); - void region_changed (Change, boost::weak_ptr<Region>); - void remove_region (boost::weak_ptr<Region>); - - int load_regions (const XMLNode& node); - - /* SOURCES */ - - mutable Glib::Mutex source_lock; - typedef std::map<PBD::ID,boost::shared_ptr<Source> > SourceMap; - - SourceMap sources; - - public: - SourceMap get_sources() { return sources; } - - private: - - - int load_sources (const XMLNode& node); - XMLNode& get_sources_as_xml (); - - boost::shared_ptr<Source> XMLSourceFactory (const XMLNode&); - - /* PLAYLISTS */ - - mutable Glib::Mutex playlist_lock; - typedef set<boost::shared_ptr<Playlist> > PlaylistList; - PlaylistList playlists; - PlaylistList unused_playlists; - - int load_playlists (const XMLNode&); - int load_unused_playlists (const XMLNode&); - void remove_playlist (boost::weak_ptr<Playlist>); - void track_playlist (bool, boost::weak_ptr<Playlist>); - - boost::shared_ptr<Playlist> playlist_factory (string name); - boost::shared_ptr<Playlist> XMLPlaylistFactory (const XMLNode&); - - void playlist_length_changed (); - void diskstream_playlist_changed (boost::shared_ptr<Diskstream>); - - /* NAMED SELECTIONS */ - - mutable Glib::Mutex named_selection_lock; - typedef set<NamedSelection *> NamedSelectionList; - NamedSelectionList named_selections; - - int load_named_selections (const XMLNode&); - - NamedSelection *named_selection_factory (string name); - NamedSelection *XMLNamedSelectionFactory (const XMLNode&); - - /* CURVES and AUTOMATION LISTS */ - std::map<PBD::ID, Curve*> curves; - std::map<PBD::ID, AutomationList*> automation_lists; - - /* DEFAULT FADE CURVES */ - - float default_fade_steepness; - float default_fade_msecs; - - /* AUDITIONING */ - - boost::shared_ptr<Auditioner> auditioner; - void set_audition (boost::shared_ptr<Region>); - void non_realtime_set_audition (); - boost::shared_ptr<Region> pending_audition_region; - - /* EXPORT */ - - /* FLATTEN */ - - int flatten_one_track (AudioTrack&, nframes_t start, nframes_t cnt); - - /* INSERT AND SEND MANAGEMENT */ - - list<PortInsert *> _port_inserts; - list<PluginInsert *> _plugin_inserts; - list<Send *> _sends; - boost::dynamic_bitset<uint32_t> send_bitset; - boost::dynamic_bitset<uint32_t> insert_bitset; - uint32_t send_cnt; - uint32_t insert_cnt; - - - void add_processor (Processor *); - void remove_processor (Processor *); - - /* S/W RAID */ - - struct space_and_path { - uint32_t blocks; /* 4kB blocks */ - string path; - - space_and_path() { - blocks = 0; - } - }; - - struct space_and_path_ascending_cmp { - bool operator() (space_and_path a, space_and_path b) { - return a.blocks > b.blocks; - } - }; - - void setup_raid_path (string path); - - vector<space_and_path> session_dirs; - vector<space_and_path>::iterator last_rr_session_dir; - uint32_t _total_free_4k_blocks; - Glib::Mutex space_lock; - - string get_best_session_directory_for_new_source (); - void refresh_disk_space (); - - mutable gint _playback_load; - mutable gint _capture_load; - mutable gint _playback_load_min; - mutable gint _capture_load_min; - - /* I/O bundles */ - - typedef list<boost::shared_ptr<Bundle> > BundleList; - mutable Glib::Mutex bundle_lock; - BundleList _bundles; - XMLNode* _bundle_xml_node; - int load_bundles (XMLNode const &); - - void reverse_diskstream_buffers (); - - UndoHistory _history; - UndoTransaction* current_trans; - - GlobalRouteBooleanState get_global_route_boolean (bool (Route::*method)(void) const); - GlobalRouteMeterState get_global_route_metering (); - - void set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void *arg); - void set_global_route_metering (GlobalRouteMeterState s, void *arg); - - void set_global_mute (GlobalRouteBooleanState s, void *src); - void set_global_solo (GlobalRouteBooleanState s, void *src); - void set_global_record_enable (GlobalRouteBooleanState s, void *src); - - void jack_timebase_callback (jack_transport_state_t, nframes_t, jack_position_t*, int); - int jack_sync_callback (jack_transport_state_t, jack_position_t*); - void reset_jack_connection (jack_client_t* jack); - void record_enable_change_all (bool yn); - - XMLNode& state(bool); - - /* click track */ - - struct Click { - nframes_t start; - nframes_t duration; - nframes_t offset; - const Sample *data; - - Click (nframes_t s, nframes_t d, const Sample *b) - : start (s), duration (d), data (b) { offset = 0; } - - void *operator new(size_t ignored) { - return pool.alloc (); - }; - - void operator delete(void *ptr, size_t size) { - pool.release (ptr); - } - - private: - static Pool pool; - }; - - typedef list<Click*> Clicks; - - Clicks clicks; - bool _clicking; - boost::shared_ptr<IO> _click_io; - Sample* click_data; - Sample* click_emphasis_data; - nframes_t click_length; - nframes_t click_emphasis_length; - mutable Glib::RWLock click_lock; - - static const Sample default_click[]; - static const nframes_t default_click_length; - static const Sample default_click_emphasis[]; - static const nframes_t default_click_emphasis_length; - - Click *get_click(); - void setup_click_sounds (int which); - void clear_clicks (); - void click (nframes_t start, nframes_t nframes, nframes_t offset); - - vector<Route*> master_outs; - - /* range playback */ - - list<AudioRange> current_audio_range; - bool _play_range; - void set_play_range (bool yn); - void setup_auto_play (); - - /* main outs */ - uint32_t main_outs; - - boost::shared_ptr<IO> _master_out; - boost::shared_ptr<IO> _control_out; - - gain_t* _gain_automation_buffer; - pan_t** _pan_automation_buffer; - void allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force); - uint32_t _npan_buffers; - - /* VST support */ - - long _vst_callback (VSTPlugin*, - long opcode, - long index, - long value, - void* ptr, - float opt); - - /* number of hardware ports we're using, - based on max (requested,available) - */ - - uint32_t n_physical_outputs; - uint32_t n_physical_inputs; - - - int find_all_sources (std::string path, std::set<std::string>& result); - int find_all_sources_across_snapshots (std::set<std::string>& result, bool exclude_this_snapshot); - - LayerModel layer_model; - CrossfadeModel xfade_model; - - typedef std::set<boost::shared_ptr<PBD::Controllable> > Controllables; - Glib::Mutex controllables_lock; - Controllables controllables; - - void reset_native_file_format(); - bool first_file_data_format_reset; - bool first_file_header_format_reset; - - void config_changed (const char*); - - XMLNode& get_control_protocol_state (); - - void set_history_depth (uint32_t depth); - void sync_order_keys (); - - static bool _disable_all_loaded_plugins; -}; - -} // namespace ARDOUR - -#endif /* __ardour_session_h__ */ diff --git a/libs/ardour/ardour/session_directory.h b/libs/ardour/ardour/session_directory.h deleted file mode 100644 index a4fb7d07c5..0000000000 --- a/libs/ardour/ardour/session_directory.h +++ /dev/null @@ -1,136 +0,0 @@ -/* - Copyright (C) 2007 Tim Mayberry - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifndef __ardour_session_directory_h__ -#define __ardour_session_directory_h__ - -#include <string> -#include <vector> - -#include <pbd/filesystem.h> - -namespace ARDOUR { - -using std::string; -using std::vector; -using PBD::sys::path; - -class SessionDirectory -{ -public: - - /** - * @param session_path An absolute path to a session directory. - */ - SessionDirectory (const path& session_path); - - /** - * @return the absolute path to the root directory of the session - */ - const path root_path() const { return m_root_path; } - - /** - * @return the absolute path to the directory in which - * the session stores audio files. - * - * If the session is an older session with an existing - * "sounds" directory then it will return a path to that - * directory otherwise it will return the new location - * of root_path()/interchange/session_name/audiofiles - */ - const path sound_path () const; - - /** - * @return the absolute path to the directory in which - * the session stores MIDI files, ie - * root_path()/interchange/session_name/midifiles - */ - const path midi_path () const; - - /** - * @return The absolute path to the directory in which all - * peak files are stored for a session. - */ - const path peak_path () const; - - /** - * @return The absolute path to the directory that audio - * files are moved to when they are no longer part of the - * session. - */ - const path dead_sound_path () const; - - /** - * @return The absolute path to the directory that midi - * files are moved to when they are no longer part of the - * session. - */ - const path dead_midi_path () const; - - /** - * @return The absolute path to the directory that audio - * files are created in by default when exporting. - */ - const path export_path () const; - - /** - * @return true if session directory and all the required - * subdirectories exist. - */ - bool is_valid () const; - - /** - * Create the session directory and all the subdirectories. - * - * @throw PBD::sys::filesystem_error if the directories were - * not able to be created. - * - * @return true If a new session directory was created, otherwise - * (if it already existed) false. - * - * @post is_valid () - */ - bool create (); - -protected: - - /** - * @return The path to the old style sound directory. - * It isn't created by create(). - */ - const path old_sound_path () const; - - /** - * @return The path to the directory under which source directories - * are created for different source types. - * i.e root_path()/interchange/session_name - */ - const path sources_root() const; - - /** - * @return a vector containing the fullpath of all subdirectories. - */ - const vector<PBD::sys::path> sub_directories () const; - - /// The path to the root of the session directory. - const path m_root_path; -}; - -} // namespace ARDOUR - -#endif diff --git a/libs/ardour/ardour/session_object.h b/libs/ardour/ardour/session_object.h deleted file mode 100644 index bb726cb0d0..0000000000 --- a/libs/ardour/ardour/session_object.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - Copyright (C) 2000-2007 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_session_object_h__ -#define __ardour_session_object_h__ - -#include <string> -#include <pbd/statefuldestructible.h> - -namespace ARDOUR { - -class Session; - - -/** An object associated with a Session. - * - * This is a few common things factored out of IO which weren't IO specific - * (to fix the problem with e.g. PluginInsert being an IO which it shouldn't be). - * collection of input and output ports with connections. - */ -class SessionObject : public PBD::StatefulDestructible -{ -public: - SessionObject(Session& session, const std::string& name) - : _session(session) - , _name(name) - {} - - Session& session() const { return _session; } - const std::string& name() const { return _name; } - - virtual bool set_name (const std::string& str) { - if (_name != str) { - _name = str; - NameChanged(); - } - return true; - } - - sigc::signal<void> NameChanged; - -protected: - Session& _session; - std::string _name; -}; - -} // namespace ARDOUR - -#endif /*__ardour_io_h__ */ diff --git a/libs/ardour/ardour/session_playlist.h b/libs/ardour/ardour/session_playlist.h deleted file mode 100644 index baeb74916d..0000000000 --- a/libs/ardour/ardour/session_playlist.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - Copyright (C) 2002 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_session_playlist_h__ -#define __ardour_session_playlist_h__ - -#include <ardour/session.h> -#include <ardour/playlist.h> - -namespace ARDOUR { - -template<class T> void -Session::foreach_playlist (T *obj, void (T::*func)(boost::shared_ptr<Playlist>)) -{ - Glib::Mutex::Lock lm (playlist_lock); - for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); i++) { - if (!(*i)->hidden()) { - (obj->*func) (*i); - } - } - for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); i++) { - if (!(*i)->hidden()) { - (obj->*func) (*i); - } - } -} - -} /* namespace */ - -#endif /* __ardour_session_playlist_h__ */ diff --git a/libs/ardour/ardour/session_region.h b/libs/ardour/ardour/session_region.h deleted file mode 100644 index 254bbfe1a3..0000000000 --- a/libs/ardour/ardour/session_region.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - Copyright (C) 2000-2007 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_session_region_h__ -#define __ardour_session_region_h__ - -#include <ardour/session.h> -#include <ardour/audioregion.h> - -namespace ARDOUR { - -template<class T> void Session::foreach_region (T *obj, void (T::*func)(boost::shared_ptr<Region>)) -{ - Glib::Mutex::Lock lm (region_lock); - for (RegionList::iterator i = regions.begin(); i != regions.end(); i++) { - (obj->*func) (i->second); - } -} - -} // namespace ARDOUR - -#endif /* __ardour_session_region_h__ */ diff --git a/libs/ardour/ardour/session_route.h b/libs/ardour/ardour/session_route.h deleted file mode 100644 index 0c70bf407d..0000000000 --- a/libs/ardour/ardour/session_route.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - Copyright (C) 2000 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_session_route_h__ -#define __ardour_session_route_h__ - -#include <iostream> - -#include <glibmm/thread.h> - -#include <ardour/session.h> -#include <ardour/route.h> - -namespace ARDOUR { - -template<class T> void -Session::foreach_route (T *obj, void (T::*func)(Route&)) -{ - boost::shared_ptr<RouteList> r = routes.reader(); - RouteList public_order (*r); - RoutePublicOrderSorter cmp; - - public_order.sort (cmp); - - for (RouteList::iterator i = public_order.begin(); i != public_order.end(); i++) { - (obj->*func) (**i); - } -} - -template<class T> void -Session::foreach_route (T *obj, void (T::*func)(boost::shared_ptr<Route>)) -{ - boost::shared_ptr<RouteList> r = routes.reader(); - RouteList public_order (*r); - RoutePublicOrderSorter cmp; - - public_order.sort (cmp); - - for (RouteList::iterator i = public_order.begin(); i != public_order.end(); i++) { - (obj->*func) (*i); - } -} - -template<class T, class A> void -Session::foreach_route (T *obj, void (T::*func)(Route&, A), A arg1) -{ - boost::shared_ptr<RouteList> r = routes.reader(); - RouteList public_order (*r); - RoutePublicOrderSorter cmp; - - public_order.sort (cmp); - - for (RouteList::iterator i = public_order.begin(); i != public_order.end(); i++) { - (obj->*func) (**i, arg1); - } -} - -} /* namespace */ - -#endif /* __ardour_session_route_h__ */ diff --git a/libs/ardour/ardour/session_selection.h b/libs/ardour/ardour/session_selection.h deleted file mode 100644 index 4169a3a511..0000000000 --- a/libs/ardour/ardour/session_selection.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - Copyright (C) 2002 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_session_named_selection_h__ -#define __ardour_session_named_selection_h__ - -#include <ardour/session.h> -#include <ardour/named_selection.h> - -namespace ARDOUR { - -template<class T> void -Session::foreach_named_selection (T& obj, void (T::*func)(NamedSelection&)) -{ - Glib::Mutex::Lock lm (named_selection_lock); - for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); i++) { - (obj.*func) (**i); - } -} - -} /* namespace */ - -#endif /* __ardour_session_named_selection_h__ */ diff --git a/libs/ardour/ardour/session_state_utils.h b/libs/ardour/ardour/session_state_utils.h deleted file mode 100644 index 8825b041f3..0000000000 --- a/libs/ardour/ardour/session_state_utils.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - Copyright (C) 2007 Tim Mayberry - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifndef ARDOUR_SESSION_STATE_UTILS_INCLUDED -#define ARDOUR_SESSION_STATE_UTILS_INCLUDED - -#include <vector> -#include <string> - -#include <pbd/filesystem.h> - -namespace ARDOUR { - -using std::string; -using std::vector; -using namespace PBD; - -/** - * Attempt to create a backup copy of a file. - * - * A copy of the file is created in the same directory using - * the same filename with the backup suffix appended. - * - * @return true if successful, false otherwise. - */ -bool create_backup_file (const sys::path & file_path); - -/** - * Get the absolute paths to all state files in the directory - * at path directory_path. - * - * @param directory_path The absolute path to a directory. - * @param result vector to contain resulting state files. - */ -void get_state_files_in_directory (const sys::path & directory_path, - vector<sys::path>& result); - -/** - * Given a vector of paths to files, return a vector containing - * the filenames without any extension. - * - * @param file_paths a vector containing the file paths - * @return a vector containing a list of file names without any - * filename extension. - */ -vector<string> get_file_names_no_extension (const vector<sys::path> & file_paths); - -} // namespace ARDOUR - -#endif diff --git a/libs/ardour/ardour/session_utils.h b/libs/ardour/ardour/session_utils.h deleted file mode 100644 index 8a9f6f584c..0000000000 --- a/libs/ardour/ardour/session_utils.h +++ /dev/null @@ -1,26 +0,0 @@ - -#ifndef __ardour_session_utils_h__ -#define __ardour_session_utils_h__ - -#include <string> - -namespace ARDOUR { - -using std::string; - -int find_session (string str, string& path, string& snapshot, bool& isnew); - -/** - * Create a SessionDirectory at the path specified by - * session_directory_path, this includes all subdirectories. - * - * @return true if the session directory was able to be created - * or if it already existed, false otherwise. - * - * @see SessionDirectory - */ -bool create_session_directory (const string& session_directory_path); - -}; - -#endif diff --git a/libs/ardour/ardour/silentfilesource.h b/libs/ardour/ardour/silentfilesource.h deleted file mode 100644 index cbb123139a..0000000000 --- a/libs/ardour/ardour/silentfilesource.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - Copyright (C) 2007 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_silentfilesource_h__ -#define __ardour_silentfilesource_h__ - -#include <cstring> -#include <ardour/audiofilesource.h> - -namespace ARDOUR { - -class SilentFileSource : public AudioFileSource { - public: - virtual ~SilentFileSource (); - - int update_header (nframes_t when, struct tm&, time_t) { return 0; } - int flush_header () { return 0; } - float sample_rate () const { return _sample_rate; } - - void set_length (nframes_t len); - - bool destructive() const { return false; } - bool can_be_analysed() const { return false; } - - protected: - - float _sample_rate; - - SilentFileSource (Session&, const XMLNode&, nframes_t nframes, float sample_rate); - - friend class SourceFactory; - - nframes_t read_unlocked (Sample *dst, nframes_t start, nframes_t cnt) const { - memset (dst, 0, sizeof (Sample) * cnt); - return cnt; - } - - nframes_t write_unlocked (Sample *dst, nframes_t cnt) { return 0; } - - void set_header_timeline_position () {} - - int read_peaks_with_fpp (PeakData *peaks, nframes_t npeaks, nframes_t start, nframes_t cnt, double samples_per_unit, nframes_t fpp) const { - memset (peaks, 0, sizeof (PeakData) * npeaks); - return 0; - } - -}; - -} // namespace ARDOUR - -#endif /* __ardour_audiofilesource_h__ */ - diff --git a/libs/ardour/ardour/slave.h b/libs/ardour/ardour/slave.h deleted file mode 100644 index 509f8fa9d2..0000000000 --- a/libs/ardour/ardour/slave.h +++ /dev/null @@ -1,153 +0,0 @@ -/* - Copyright (C) 2002 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_slave_h__ -#define __ardour_slave_h__ - -#include <vector> - -#include <jack/jack.h> - -#include <sigc++/signal.h> -#include <ardour/ardour.h> -#include <midi++/parser.h> -#include <midi++/types.h> - -namespace MIDI { - class Port; -} - -namespace ARDOUR { -class Session; - -class Slave { - public: - Slave() { } - virtual ~Slave() {} - - virtual bool speed_and_position (float&, nframes_t&) = 0; - virtual bool locked() const = 0; - virtual bool ok() const = 0; - virtual bool starting() const { return false; } - virtual nframes_t resolution() const = 0; - virtual bool requires_seekahead () const = 0; - virtual bool is_always_synced() const { return false; } -}; - - -class MTC_Slave : public Slave, public sigc::trackable { - public: - MTC_Slave (Session&, MIDI::Port&); - ~MTC_Slave (); - - void rebind (MIDI::Port&); - bool speed_and_position (float&, nframes_t&); - - bool locked() const; - bool ok() const; - void handle_locate (const MIDI::byte*); - - nframes_t resolution() const; - bool requires_seekahead () const { return true; } - - private: - Session& session; - MIDI::Port* port; - std::vector<sigc::connection> connections; - bool can_notify_on_unknown_rate; - - struct SafeTime { - - - int guard1; - //SMPTE_Time mtc; - nframes_t position; - nframes_t timestamp; - int guard2; - - SafeTime() { - guard1 = 0; - guard2 = 0; - timestamp = 0; - } - }; - - SafeTime current; - nframes_t mtc_frame; /* current time */ - nframes_t last_inbound_frame; /* when we got it; audio clocked */ - - float mtc_speed; - nframes_t first_mtc_frame; - nframes_t first_mtc_time; - - static const int32_t accumulator_size = 128; - float accumulator[accumulator_size]; - int32_t accumulator_index; - bool have_first_accumulated_speed; - - void reset (); - void update_mtc_qtr (MIDI::Parser&); - void update_mtc_time (const MIDI::byte *, bool); - void update_mtc_status (MIDI::Parser::MTC_Status); - void read_current (SafeTime *) const; -}; - -class ADAT_Slave : public Slave -{ - public: - ADAT_Slave () {} - ~ADAT_Slave () {} - - bool speed_and_position (float& speed, nframes_t& pos) { - speed = 0; - pos = 0; - return false; - } - - bool locked() const { return false; } - bool ok() const { return false; } - nframes_t resolution() const { return 1; } - bool requires_seekahead () const { return true; } -}; - -class JACK_Slave : public Slave -{ - public: - JACK_Slave (jack_client_t*); - ~JACK_Slave (); - - bool speed_and_position (float& speed, nframes_t& pos); - - bool starting() const { return _starting; } - bool locked() const; - bool ok() const; - nframes_t resolution() const { return 1; } - bool requires_seekahead () const { return false; } - void reset_client (jack_client_t* jack); - bool is_always_synced() const { return true; } - - private: - jack_client_t* jack; - float speed; - bool _starting; -}; - -} /* namespace */ - -#endif /* __ardour_slave_h__ */ diff --git a/libs/ardour/ardour/smf_reader.h b/libs/ardour/ardour/smf_reader.h deleted file mode 100644 index e41dcc3bc4..0000000000 --- a/libs/ardour/ardour/smf_reader.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - Copyright (C) 2008 Paul Davis - Written by Dave Robillard - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifndef __ardour_smf_reader_h__ -#define __ardour_smf_reader_h__ - -#include <exception> -#include <stdexcept> -#include <string> -#include <inttypes.h> - -namespace ARDOUR { - - -/** Standard MIDI File (Type 0) Reader - * - * Currently this only reads SMF files with tempo-based timing. - */ -class SMFReader { -public: - class PrematureEOF : public std::exception { - const char* what() const throw() { return "Unexpected end of file"; } - }; - class CorruptFile : public std::exception { - const char* what() const throw() { return "Corrupted file"; } - }; - class UnsupportedTime : public std::exception { - const char* what() const throw() { return "Unsupported time stamp type (SMPTE)"; } - }; - - SMFReader(const std::string filename=""); - ~SMFReader(); - - bool open(const std::string& filename) throw (std::logic_error, UnsupportedTime); - - bool seek_to_track(unsigned track) throw (std::logic_error); - - const std::string& filename() const { return _filename; }; - - uint16_t type() const { return _type; } - uint16_t ppqn() const { return _ppqn; } - uint16_t num_tracks() const { return _num_tracks; } - - int read_event(size_t buf_len, - uint8_t* buf, - uint32_t* ev_size, - uint32_t* ev_delta_time) - throw (std::logic_error, PrematureEOF, CorruptFile); - - void close(); - - static uint32_t read_var_len(FILE* fd) throw (PrematureEOF); - -protected: - /** size of SMF header, including MTrk chunk header */ - static const uint32_t HEADER_SIZE = 22; - - std::string _filename; - FILE* _fd; - uint16_t _type; - uint16_t _ppqn; - uint16_t _num_tracks; - uint32_t _track; - uint32_t _track_size; -}; - - -} // namespace ARDOUR - -#endif /* __ardour_smf_reader_h__ */ - diff --git a/libs/ardour/ardour/smf_source.h b/libs/ardour/ardour/smf_source.h deleted file mode 100644 index 88bf1e5d13..0000000000 --- a/libs/ardour/ardour/smf_source.h +++ /dev/null @@ -1,151 +0,0 @@ -/* - Copyright (C) 2006 Paul Davis - Written by Dave Robillard, 2006 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_smf_filesource_h__ -#define __ardour_smf_filesource_h__ - -#include <cstdio> -#include <time.h> - -#include <ardour/midi_source.h> - -namespace ARDOUR { - -class MidiRingBuffer; - -/** Standard Midi File (Type 0) Source */ -class SMFSource : public MidiSource { - public: - enum Flag { - Writable = 0x1, - CanRename = 0x2, - Broadcast = 0x4, - Removable = 0x8, - RemovableIfEmpty = 0x10, - RemoveAtDestroy = 0x20, - BuildPeaks = 0x40 - }; - - /** Constructor for existing external-to-session files */ - SMFSource (Session& session, std::string path, Flag flags = Flag(0)); - - /* Constructor for existing in-session files */ - SMFSource (Session& session, const XMLNode&); - - virtual ~SMFSource (); - - /* this block of methods do nothing for regular file sources, but are significant - for files used in destructive recording. - */ - // FIXME and thus are useless for MIDI.. but make MidiDiskstream compile easier! :) - - virtual nframes_t last_capture_start_frame() const { return 0; } - virtual void mark_capture_start (nframes_t) {} - virtual void mark_capture_end () {} - virtual void clear_capture_marks() {} - - bool set_name (const std::string& newname) { return (set_source_name(newname, false) == 0); } - int set_source_name (string newname, bool destructive); - - static bool safe_file_extension (const Glib::ustring& path); - - Glib::ustring path() const { return _path; } - - void set_allow_remove_if_empty (bool yn); - void mark_for_remove(); - - void append_event_unlocked(EventTimeUnit unit, const MIDI::Event& ev); - - int flush_header (); - int flush_footer (); - - int move_to_trash (const string trash_dir_name); - - bool is_empty () const; - void mark_streaming_midi_write_started (NoteMode mode, nframes_t start_time); - void mark_streaming_write_completed (); - - void mark_take (string); - string take_id() const { return _take_id; } - - static void set_search_path (string); - static void set_header_position_offset (nframes_t offset, bool negative); - - XMLNode& get_state (); - int set_state (const XMLNode&); - - void seek_to(nframes_t time); - - void load_model(bool lock=true, bool force_reload=false); - void destroy_model(); - - uint16_t ppqn() const { return _ppqn; } - - private: - - int init (string idstr, bool must_exist); - - nframes_t read_unlocked (MidiRingBuffer& dst, nframes_t start, nframes_t cn, nframes_t stamp_offset, nframes_t negative_stamp_offset) const; - nframes_t write_unlocked (MidiRingBuffer& dst, nframes_t cnt); - - bool find (std::string path, bool must_exist, bool& is_new); - bool removable() const; - bool writable() const { return _flags & Writable; } - - int open(); - void close(); - - /** - * This method is only used by flush_footer() to find the right seek position - * for the footer (at the end after recording or -4 offset ro SEEK_END - * if a footer is already present) - */ - void seek_to_footer_position(); - - /** - * write the track footer at the current seek position - */ - void write_footer(); - - void write_chunk_header(const char id[4], uint32_t length); - void write_chunk(const char id[4], uint32_t length, void* data); - size_t write_var_len(uint32_t val); - uint32_t read_var_len() const; - int read_event(uint32_t* delta_t, uint32_t* size, uint8_t** buf) const; - - static const uint16_t _ppqn = 19200; - - Glib::ustring _path; - Flag _flags; - string _take_id; - bool _allow_remove_if_empty; - FILE* _fd; - double _last_ev_time; ///< last frame time written, relative to source start - uint32_t _track_size; - uint32_t _header_size; ///< size of SMF header, including MTrk chunk header - bool _empty; ///< true iff file contains (non-empty) events - - static string _search_path; -}; - -}; /* namespace ARDOUR */ - -#endif /* __ardour_smf_filesource_h__ */ - diff --git a/libs/ardour/ardour/smpte.h b/libs/ardour/ardour/smpte.h deleted file mode 100644 index d0901c372e..0000000000 --- a/libs/ardour/ardour/smpte.h +++ /dev/null @@ -1,79 +0,0 @@ -/* Copyright (C) 2006 Paul Davis - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#ifndef __ardour_smpte_h__ -#define __ardour_smpte_h__ - -#include <inttypes.h> - -namespace SMPTE { - -enum Wrap { - NONE = 0, - FRAMES, - SECONDS, - MINUTES, - HOURS -}; - -/** SMPTE frame rate (in frames per second). - * - * This should be eliminated in favour of a float to support arbitrary rates. - */ -enum FPS { - MTC_24_FPS = 0, - MTC_25_FPS = 1, - MTC_30_FPS_DROP = 2, - MTC_30_FPS = 3 -}; - -struct Time { - bool negative; - uint32_t hours; - uint32_t minutes; - uint32_t seconds; - uint32_t frames; ///< SMPTE frames (not audio samples) - uint32_t subframes; ///< Typically unused - FPS rate; ///< Frame rate of this Time - static FPS default_rate; ///< Rate to use for default constructor - - Time(FPS a_rate = default_rate) { - negative = false; - hours = 0; - minutes = 0; - seconds = 0; - frames = 0; - subframes = 0; - rate = a_rate; - } -}; - -Wrap increment( Time& smpte ); -Wrap decrement( Time& smpte ); -Wrap increment_subframes( Time& smpte ); -Wrap decrement_subframes( Time& smpte ); -Wrap increment_seconds( Time& smpte ); -Wrap increment_minutes( Time& smpte ); -Wrap increment_hours( Time& smpte ); -void frames_floor( Time& smpte ); -void seconds_floor( Time& smpte ); -void minutes_floor( Time& smpte ); -void hours_floor( Time& smpte ); - -} // namespace SMPTE - -#endif // __ardour_smpte_h__ diff --git a/libs/ardour/ardour/sndfile_helpers.h b/libs/ardour/ardour/sndfile_helpers.h deleted file mode 100644 index cf6b15f3a4..0000000000 --- a/libs/ardour/ardour/sndfile_helpers.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - Copyright (C) 2000-2007 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __sndfile_helpers_h__ -#define __sndfile_helpers_h__ - -#include <string> -#include <stdint.h> - -using std::string; - -// Use this define when initializing arrarys for use in sndfile_*_format() -#define SNDFILE_STR_LENGTH 32 - -#define SNDFILE_HEADER_FORMATS 5 -extern const char * const sndfile_header_formats_strings[SNDFILE_HEADER_FORMATS+1]; -extern const char * const sndfile_file_endings_strings[SNDFILE_HEADER_FORMATS+1]; - -extern int sndfile_header_formats[SNDFILE_HEADER_FORMATS]; - -#define SNDFILE_BITDEPTH_FORMATS 5 -extern const char * const sndfile_bitdepth_formats_strings[SNDFILE_BITDEPTH_FORMATS+1]; - -extern int sndfile_bitdepth_formats[SNDFILE_BITDEPTH_FORMATS]; - -#define SNDFILE_ENDIAN_FORMATS 2 -extern const char * const sndfile_endian_formats_strings[SNDFILE_ENDIAN_FORMATS+1]; - -extern int sndfile_endian_formats[SNDFILE_ENDIAN_FORMATS]; - -int sndfile_bitdepth_format_from_string(string); -int sndfile_header_format_from_string(string); -int sndfile_endian_format_from_string(string); -string sndfile_file_ending_from_string(string); - -int sndfile_data_width (int format); - -// It'd be nice if libsndfile did this for us -string sndfile_major_format(int); -string sndfile_minor_format(int); - -#endif /* __sndfile_helpers_h__ */ diff --git a/libs/ardour/ardour/sndfileimportable.h b/libs/ardour/ardour/sndfileimportable.h deleted file mode 100644 index 5cd84f4f5f..0000000000 --- a/libs/ardour/ardour/sndfileimportable.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - Copyright (C) 2007 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_sndfile_importable_source_h__ -#define __ardour_sndfile_importable_source_h__ - -#include <boost/shared_ptr.hpp> -#include <sndfile.h> -#include <pbd/failed_constructor.h> -#include <ardour/types.h> -#include <ardour/importable_source.h> - -namespace ARDOUR { - -class SndFileImportableSource : public ImportableSource { - public: - SndFileImportableSource (const std::string& path); - virtual ~SndFileImportableSource(); - - nframes_t read (Sample* buffer, nframes_t nframes); - uint32_t channels() const; - nframes_t length() const; - nframes_t samplerate() const; - void seek (nframes_t pos); - - protected: - SF_INFO sf_info; - boost::shared_ptr<SNDFILE> in; - -}; - -} - -#endif /* __ardour_sndfile_importable_source_h__ */ diff --git a/libs/ardour/ardour/sndfilesource.h b/libs/ardour/ardour/sndfilesource.h deleted file mode 100644 index 4ad967c132..0000000000 --- a/libs/ardour/ardour/sndfilesource.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - Copyright (C) 2006 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __sndfile_source_h__ -#define __sndfile_source_h__ - -#include <sndfile.h> - -#include <ardour/audiofilesource.h> - -namespace ARDOUR { - -class SndFileSource : public AudioFileSource { - public: - /* constructor to be called for existing external-to-session files */ - - SndFileSource (Session&, Glib::ustring path, int chn, Flag flags); - - /* constructor to be called for new in-session files */ - - SndFileSource (Session&, Glib::ustring path, SampleFormat samp_format, HeaderFormat hdr_format, nframes_t rate, - Flag flags = SndFileSource::default_writable_flags); - - /* constructor to be called for existing in-session files */ - - SndFileSource (Session&, const XMLNode&); - - ~SndFileSource (); - - float sample_rate () const; - int update_header (nframes_t when, struct tm&, time_t); - int flush_header (); - - nframes_t natural_position () const; - - nframes_t last_capture_start_frame() const; - void mark_capture_start (nframes_t); - void mark_capture_end (); - void clear_capture_marks(); - - bool set_destructive (bool yn); - - bool one_of_several_channels () const; - - static void setup_standard_crossfades (nframes_t sample_rate); - static const AudioFileSource::Flag default_writable_flags; - - static int get_soundfile_info (const Glib::ustring& path, SoundFileInfo& _info, string& error_msg); - - protected: - void set_header_timeline_position (); - - nframes_t read_unlocked (Sample *dst, nframes_t start, nframes_t cnt) const; - nframes_t write_unlocked (Sample *dst, nframes_t cnt); - - nframes_t write_float (Sample* data, nframes_t pos, nframes_t cnt); - - private: - SNDFILE *sf; - SF_INFO _info; - SF_BROADCAST_INFO *_broadcast_info; - - void init (); - int open(); - int setup_broadcast_info (nframes_t when, struct tm&, time_t); - - /* destructive */ - - static nframes_t xfade_frames; - static gain_t* out_coefficient; - static gain_t* in_coefficient; - - bool _capture_start; - bool _capture_end; - nframes_t capture_start_frame; - nframes_t file_pos; // unit is frames - nframes_t xfade_out_count; - nframes_t xfade_in_count; - Sample* xfade_buf; - - nframes_t crossfade (Sample* data, nframes_t cnt, int dir); - void set_timeline_position (int64_t); - nframes_t destructive_write_unlocked (Sample *dst, nframes_t cnt); - nframes_t nondestructive_write_unlocked (Sample *dst, nframes_t cnt); - void handle_header_position_change (); - - static int64_t get_timecode_info (SNDFILE* sf, SF_BROADCAST_INFO* binfo, bool& exists); -}; - -} // namespace ARDOUR - -#endif /* __sndfile_source_h__ */ - diff --git a/libs/ardour/ardour/soundseq.h b/libs/ardour/ardour/soundseq.h deleted file mode 100644 index c7157428ee..0000000000 --- a/libs/ardour/ardour/soundseq.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - 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 deleted file mode 100644 index a2ee96bf63..0000000000 --- a/libs/ardour/ardour/source.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - Copyright (C) 2000 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_source_h__ -#define __ardour_source_h__ - -#include <string> -#include <set> - -#include <sigc++/signal.h> - -#include <pbd/statefuldestructible.h> - -#include <ardour/ardour.h> -#include <ardour/session_object.h> -#include <ardour/data_type.h> -#include <ardour/readable.h> - -namespace ARDOUR { - -class Session; -class Playlist; - -class Source : public SessionObject, public ARDOUR::Readable -{ - public: - Source (Session&, const std::string& name, DataType type); - Source (Session&, const XMLNode&); - - virtual ~Source (); - - DataType type() { return _type; } - - time_t timestamp() const { return _timestamp; } - void stamp (time_t when) { _timestamp = when; } - - nframes_t length() const { return _length; } - - virtual Glib::ustring path() const = 0; - - virtual nframes_t natural_position() const { return 0; } - - virtual void mark_for_remove() = 0; - virtual void mark_streaming_write_started () {} - virtual void mark_streaming_write_completed () = 0; - - virtual void session_saved() {} - - XMLNode& get_state (); - int set_state (const XMLNode&); - - virtual bool destructive() const { return false; } - virtual bool length_mutable() const { return false; } - - void use () { _in_use++; } - void disuse () { if (_in_use) { _in_use--; } } - - void add_playlist (boost::shared_ptr<ARDOUR::Playlist>); - void remove_playlist (boost::weak_ptr<ARDOUR::Playlist>); - - uint32_t used() const; - - static sigc::signal<void,Source*> SourceCreated; - sigc::signal<void,boost::shared_ptr<Source> > Switched; - - bool has_been_analysed() const; - virtual bool can_be_analysed() const { return false; } - virtual void set_been_analysed (bool yn); - virtual bool check_for_analysis_data_on_disk(); - - sigc::signal<void> AnalysisChanged; - - AnalysisFeatureList transients; - std::string get_transients_path() const; - int load_transients (const std::string&); - - void update_length (nframes_t pos, nframes_t cnt); - - protected: - DataType _type; - time_t _timestamp; - nframes_t _length; - bool _analysed; - mutable Glib::Mutex _analysis_lock; - Glib::Mutex _playlist_lock; - - typedef std::map<boost::shared_ptr<ARDOUR::Playlist>, uint32_t > PlaylistMap; - PlaylistMap _playlists; - - private: - uint32_t _in_use; -}; - -} - -#endif /* __ardour_source_h__ */ diff --git a/libs/ardour/ardour/source_factory.h b/libs/ardour/ardour/source_factory.h deleted file mode 100644 index 7e9be451e8..0000000000 --- a/libs/ardour/ardour/source_factory.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - Copyright (C) 2000-2007 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_source_factory_h__ -#define __ardour_source_factory_h__ - -#include <string> -#include <stdint.h> -#include <sigc++/sigc++.h> -#include <boost/shared_ptr.hpp> - -#include <ardour/source.h> -#include <ardour/audiofilesource.h> - -class XMLNode; - -namespace ARDOUR { - -class Session; - -class SourceFactory { - public: - static void init (); - - static sigc::signal<void,boost::shared_ptr<Source> > SourceCreated; - - static boost::shared_ptr<Source> create (Session&, const XMLNode& node, bool async = false); - static boost::shared_ptr<Source> createSilent (Session&, const XMLNode& node, nframes_t nframes, float sample_rate); - - static boost::shared_ptr<Source> createReadable (DataType type, Session&, std::string path, int chn, AudioFileSource::Flag flags, - bool announce = true, bool async = false); - static boost::shared_ptr<Source> createWritable (DataType type, Session&, std::string name, bool destructive, nframes_t rate, - bool announce = true, bool async = false); - - static Glib::Cond* PeaksToBuild; - static Glib::StaticMutex peak_building_lock; - static std::list<boost::weak_ptr<AudioSource> > files_with_peaks; - - static int setup_peakfile (boost::shared_ptr<Source>, bool async); -}; - -} - -#endif /* __ardour_source_factory_h__ */ diff --git a/libs/ardour/ardour/spline.h b/libs/ardour/ardour/spline.h deleted file mode 100644 index de1ece6edb..0000000000 --- a/libs/ardour/ardour/spline.h +++ /dev/null @@ -1,90 +0,0 @@ -/* 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 deleted file mode 100644 index b01a9ae208..0000000000 --- a/libs/ardour/ardour/stretch.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - Copyright (C) 2007 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_stretch_h__ -#define __ardour_stretch_h__ - -#include <ardour/filter.h> - -#ifdef USE_RUBBERBAND - -#include <ardour/rb_effect.h> - -namespace ARDOUR { - -class Stretch : public RBEffect { - public: - Stretch (ARDOUR::Session&, TimeFXRequest&); - ~Stretch() {} -}; - -} /* namespace */ - -#else - -#include <soundtouch/SoundTouch.h> - -namespace ARDOUR { - -class Stretch : public Filter { - public: - Stretch (ARDOUR::Session&, TimeFXRequest&); - ~Stretch (); - - int run (boost::shared_ptr<ARDOUR::Region>); - - private: - TimeFXRequest& tsr; - - soundtouch::SoundTouch st; -}; - -} /* namespace */ - -#endif - -#endif /* __ardour_stretch_h__ */ diff --git a/libs/ardour/ardour/tape_file_matcher.h b/libs/ardour/ardour/tape_file_matcher.h deleted file mode 100644 index 59ec18e818..0000000000 --- a/libs/ardour/ardour/tape_file_matcher.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - Copyright (C) 2007 Tim Mayberry - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifndef ARDOUR_TAPE_FILE_MATCHER_INCLUDED -#define ARDOUR_TAPE_FILE_MATCHER_INCLUDED - -#include <string> - -#include <regex.h> - -namespace ARDOUR { - -using std::string; - -class TapeFileMatcher -{ -public: - - TapeFileMatcher(); - - bool matches (const string& filename) const; - -private: - - regex_t m_compiled_pattern; -}; - -} // namespace ARDOUR - -#endif diff --git a/libs/ardour/ardour/template_utils.h b/libs/ardour/ardour/template_utils.h deleted file mode 100644 index 0676d5b245..0000000000 --- a/libs/ardour/ardour/template_utils.h +++ /dev/null @@ -1,20 +0,0 @@ - -#ifndef TEMPLATE_UTILS_INCLUDED -#define TEMPLATE_UTILS_INCLUDED - -#include <vector> - -#include <pbd/filesystem.h> - -namespace ARDOUR { - - using std::vector; - using namespace PBD; - - sys::path system_template_directory (); - - sys::path user_template_directory (); - -} // namespace ARDOUR - -#endif diff --git a/libs/ardour/ardour/tempo.h b/libs/ardour/ardour/tempo.h deleted file mode 100644 index c4915072c5..0000000000 --- a/libs/ardour/ardour/tempo.h +++ /dev/null @@ -1,322 +0,0 @@ -/* - Copyright (C) 2000 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_tempo_h__ -#define __ardour_tempo_h__ - -#include <list> -#include <string> -#include <vector> -#include <cmath> -#include <glibmm/thread.h> - -#include <pbd/undo.h> -#include <pbd/stateful.h> -#include <pbd/statefuldestructible.h> - -#include <sigc++/signal.h> - -#include <ardour/ardour.h> - -class XMLNode; - -using std::list; -using std::vector; - -namespace ARDOUR { -class Meter; -class Tempo { - public: - Tempo (double bpm, double type=4.0) // defaulting to quarter note - : _beats_per_minute (bpm), _note_type(type) {} - Tempo (const Tempo& other) { - _beats_per_minute = other._beats_per_minute; - _note_type = other._note_type; - } - void operator= (const Tempo& other) { - if (&other != this) { - _beats_per_minute = other._beats_per_minute; - _note_type = other._note_type; - } - } - - double beats_per_minute () const { return _beats_per_minute;} - double note_type () const { return _note_type;} - double frames_per_beat (nframes_t sr, const Meter& meter) const; - - protected: - double _beats_per_minute; - double _note_type; -}; - -class Meter { - public: - static const double ticks_per_beat; - - Meter (double bpb, double bt) - : _beats_per_bar (bpb), _note_type (bt) {} - Meter (const Meter& other) { - _beats_per_bar = other._beats_per_bar; - _note_type = other._note_type; - } - void operator= (const Meter& other) { - if (&other != this) { - _beats_per_bar = other._beats_per_bar; - _note_type = other._note_type; - } - } - - double beats_per_bar () const { return _beats_per_bar; } - double note_divisor() const { return _note_type; } - - double frames_per_bar (const Tempo&, nframes_t sr) const; - - protected: - - /* this is the number of beats in a bar. it is a real value - because there are musical traditions on our planet - that do not limit themselves to integral numbers of beats - per bar. - */ - - double _beats_per_bar; - - /* this is the type of "note" that a beat represents. for example, - 4.0 would be a quarter (crotchet) note, 8.0 would be an eighth - (quaver) note, etc. - */ - - double _note_type; -}; - -class MetricSection { - public: - MetricSection (const BBT_Time& start) - : _start (start), _frame (0), _movable (true) {} - MetricSection (nframes_t start) - : _frame (start), _movable (true) {} - - virtual ~MetricSection() {} - - const BBT_Time& start() const { return _start; } - const nframes_t frame() const { return _frame; } - - void set_movable (bool yn) { _movable = yn; } - bool movable() const { return _movable; } - - virtual void set_frame (nframes_t f) { - _frame = f; - }; - - virtual void set_start (const BBT_Time& w) { - _start = w; - } - - /* MeterSections are not stateful in the full sense, - but we do want them to control their own - XML state information. - */ - - virtual XMLNode& get_state() const = 0; - - private: - BBT_Time _start; - nframes_t _frame; - bool _movable; -}; - -class MeterSection : public MetricSection, public Meter { - public: - MeterSection (const BBT_Time& start, double bpb, double note_type) - : MetricSection (start), Meter (bpb, note_type) {} - MeterSection (nframes_t start, double bpb, double note_type) - : MetricSection (start), Meter (bpb, note_type) {} - MeterSection (const XMLNode&); - - static const string xml_state_node_name; - - XMLNode& get_state() const; -}; - -class TempoSection : public MetricSection, public Tempo { - public: - TempoSection (const BBT_Time& start, double qpm, double note_type) - : MetricSection (start), Tempo (qpm, note_type) {} - TempoSection (nframes_t start, double qpm, double note_type) - : MetricSection (start), Tempo (qpm, note_type) {} - TempoSection (const XMLNode&); - - static const string xml_state_node_name; - - XMLNode& get_state() const; -}; - -typedef list<MetricSection*> Metrics; - -class TempoMap : public PBD::StatefulDestructible -{ - public: - TempoMap (nframes_t frame_rate); - ~TempoMap(); - - /* measure-based stuff */ - - enum BBTPointType { - Bar, - Beat, - }; - - struct BBTPoint { - BBTPointType type; - nframes_t frame; - const Meter* meter; - const Tempo* tempo; - uint32_t bar; - uint32_t beat; - - BBTPoint (const Meter& m, const Tempo& t, nframes_t f, BBTPointType ty, uint32_t b, uint32_t e) - : type (ty), frame (f), meter (&m), tempo (&t), bar (b), beat (e) {} - }; - - typedef vector<BBTPoint> BBTPointList; - - template<class T> void apply_with_metrics (T& obj, void (T::*method)(const Metrics&)) { - Glib::RWLock::ReaderLock lm (lock); - (obj.*method)(*metrics); - } - - BBTPointList *get_points (nframes_t start, nframes_t end) const; - - void bbt_time (nframes_t when, BBT_Time&) const; - nframes_t frame_time (const BBT_Time&) const; - nframes_t bbt_duration_at (nframes_t, const BBT_Time&, int dir) const; - - static const Tempo& default_tempo() { return _default_tempo; } - static const Meter& default_meter() { return _default_meter; } - - const Tempo& tempo_at (nframes_t); - const Meter& meter_at (nframes_t); - - const TempoSection& tempo_section_at (nframes_t); - - void add_tempo(const Tempo&, BBT_Time where); - void add_meter(const Meter&, BBT_Time where); - - void add_tempo(const Tempo&, nframes_t where); - void add_meter(const Meter&, nframes_t where); - - void move_tempo (TempoSection&, const BBT_Time& to); - void move_meter (MeterSection&, const BBT_Time& to); - - void remove_tempo(const TempoSection&); - void remove_meter(const MeterSection&); - - void replace_tempo (TempoSection& existing, const Tempo& replacement); - void replace_meter (MeterSection& existing, const Meter& replacement); - - - nframes_t round_to_bar (nframes_t frame, int dir); - - nframes_t round_to_beat (nframes_t frame, int dir); - - nframes_t round_to_beat_subdivision (nframes_t fr, int sub_num); - - nframes_t round_to_tick (nframes_t frame, int dir); - - void set_length (nframes_t frames); - - XMLNode& get_state (void); - int set_state (const XMLNode&); - - void dump (std::ostream&) const; - void clear (); - - /* this is a helper class that we use to be able to keep - track of which meter *AND* tempo are in effect at - a given point in time. - */ - - class Metric { - public: - Metric (const Meter& m, const Tempo& t) : _meter (&m), _tempo (&t), _frame (0) {} - - void set_tempo (const Tempo& t) { _tempo = &t; } - void set_meter (const Meter& m) { _meter = &m; } - void set_frame (nframes_t f) { _frame = f; } - void set_start (const BBT_Time& t) { _start = t; } - - const Meter& meter() const { return *_meter; } - const Tempo& tempo() const { return *_tempo; } - nframes_t frame() const { return _frame; } - const BBT_Time& start() const { return _start; } - - private: - const Meter* _meter; - const Tempo* _tempo; - nframes_t _frame; - BBT_Time _start; - - }; - - Metric metric_at (BBT_Time bbt) const; - Metric metric_at (nframes_t) const; - void bbt_time_with_metric (nframes_t, BBT_Time&, const Metric&) const; - - void change_existing_tempo_at (nframes_t, double bpm, double note_type); - void change_initial_tempo (double bpm, double note_type); - - int n_tempos () const; - int n_meters () const; - - sigc::signal<void,ARDOUR::Change> StateChanged; - - private: - static Tempo _default_tempo; - static Meter _default_meter; - - Metrics* metrics; - nframes_t _frame_rate; - nframes_t last_bbt_when; - bool last_bbt_valid; - BBT_Time last_bbt; - mutable Glib::RWLock lock; - - void timestamp_metrics (bool use_bbt); - - nframes_t round_to_type (nframes_t fr, int dir, BBTPointType); - - nframes_t frame_time_unlocked (const BBT_Time&) const; - - void bbt_time_unlocked (nframes_t, BBT_Time&) const; - - nframes_t bbt_duration_at_unlocked (const BBT_Time& when, const BBT_Time& bbt, int dir) const; - - const MeterSection& first_meter() const; - const TempoSection& first_tempo() const; - - nframes_t count_frames_between (const BBT_Time&, const BBT_Time&) const; - nframes_t count_frames_between_metrics (const Meter&, const Tempo&, const BBT_Time&, const BBT_Time&) const; - - int move_metric_section (MetricSection&, const BBT_Time& to); - void do_insert (MetricSection* section, bool with_bbt); -}; - -}; /* namespace ARDOUR */ - -#endif /* __ardour_tempo_h__ */ diff --git a/libs/ardour/ardour/timestamps.h b/libs/ardour/ardour/timestamps.h deleted file mode 100644 index a0aeeae13d..0000000000 --- a/libs/ardour/ardour/timestamps.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - Copyright (C) 2000-2007 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_timestamps_h__ -#define __ardour_timestamps_h__ - -#ifdef WITH_JACK_TIMESTAMPS -#include <jack/timestamps.h> -#else -#define jack_timestamp(s) -#define jack_init_timestamps(n) -#define jack_dump_timestamps(o) -#define jack_reset_timestamps() -#endif - -#endif /* __ardour_timestamps_h__ */ diff --git a/libs/ardour/ardour/track.h b/libs/ardour/ardour/track.h deleted file mode 100644 index 4d5545c0dc..0000000000 --- a/libs/ardour/ardour/track.h +++ /dev/null @@ -1,151 +0,0 @@ -/* - Copyright (C) 2006 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifndef __ardour_track_h__ -#define __ardour_track_h__ - -#include <boost/shared_ptr.hpp> - -#include <ardour/route.h> - -namespace ARDOUR { - -class Session; -class Diskstream; -class Playlist; -class RouteGroup; - -class Track : public Route -{ - public: - Track (Session&, string name, Route::Flag f = Route::Flag (0), TrackMode m = Normal, DataType default_type = DataType::AUDIO); - - virtual ~Track (); - - bool set_name (const std::string& str); - - TrackMode mode () const { return _mode; } - virtual int set_mode (TrackMode m) { return false; } - virtual bool can_use_mode (TrackMode m, bool& bounce_required) { return false; } - sigc::signal<void> TrackModeChanged; - - virtual int roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, - nframes_t offset, int declick, bool can_record, bool rec_monitors_input) = 0; - - virtual int no_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, - nframes_t offset, bool state_changing, bool can_record, bool rec_monitors_input) = 0; - - virtual int silent_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, - nframes_t offset, bool can_record, bool rec_monitors_input) = 0; - - void toggle_monitor_input (); - - bool can_record(); - - boost::shared_ptr<Diskstream> diskstream() const { return _diskstream; } - - virtual int use_diskstream (string name) = 0; - virtual int use_diskstream (const PBD::ID& id) = 0; - - nframes_t update_total_latency(); - void set_latency_delay (nframes_t); - - enum FreezeState { - NoFreeze, - Frozen, - UnFrozen - }; - - FreezeState freeze_state() const; - - virtual void freeze (InterThreadInfo&) = 0; - virtual void unfreeze () = 0; - - virtual void bounce (InterThreadInfo&) = 0; - virtual void bounce_range (nframes_t start, nframes_t end, InterThreadInfo&) = 0; - - XMLNode& get_state(); - XMLNode& get_template(); - virtual int set_state(const XMLNode& node) = 0; - - boost::shared_ptr<PBD::Controllable> rec_enable_control() { return _rec_enable_control; } - - bool record_enabled() const; - void set_record_enable (bool yn, void *src); - - void set_meter_point (MeterPoint, void* src); - - sigc::signal<void> DiskstreamChanged; - sigc::signal<void> FreezeChange; - - protected: - Track (Session& sess, const XMLNode& node, DataType default_type = DataType::AUDIO); - - virtual XMLNode& state (bool full) = 0; - - boost::shared_ptr<Diskstream> _diskstream; - MeterPoint _saved_meter_point; - TrackMode _mode; - - //private: (FIXME) - struct FreezeRecordProcessorInfo { - FreezeRecordProcessorInfo(XMLNode& st, boost::shared_ptr<Processor> proc) - : state (st), processor (proc) {} - - XMLNode state; - boost::shared_ptr<Processor> processor; - PBD::ID id; - UndoAction memento; - }; - - struct FreezeRecord { - FreezeRecord() - : have_mementos(false) - {} - - ~FreezeRecord(); - - boost::shared_ptr<Playlist> playlist; - vector<FreezeRecordProcessorInfo*> processor_info; - bool have_mementos; - FreezeState state; - }; - - struct RecEnableControllable : public PBD::Controllable { - RecEnableControllable (Track&); - - void set_value (float); - float get_value (void) const; - - Track& track; - }; - - virtual void set_state_part_two () = 0; - - FreezeRecord _freeze_record; - XMLNode* pending_state; - sigc::connection recenable_connection; - sigc::connection ic_connection; - bool _destructive; - - boost::shared_ptr<RecEnableControllable> _rec_enable_control; -}; - -}; /* namespace ARDOUR*/ - -#endif /* __ardour_track_h__ */ diff --git a/libs/ardour/ardour/transient_detector.h b/libs/ardour/ardour/transient_detector.h deleted file mode 100644 index 259b79176f..0000000000 --- a/libs/ardour/ardour/transient_detector.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - Copyright (C) 2008 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_transient_detector_h__ -#define __ardour_transient_detector_h__ - -#include <ardour/audioanalyser.h> - -namespace ARDOUR { - -class AudioSource; -class Session; - -class TransientDetector : public AudioAnalyser -{ - - public: - TransientDetector (float sample_rate); - ~TransientDetector(); - - static std::string operational_identifier(); - - void set_threshold (float); - void set_sensitivity (float); - - float get_threshold () const; - float get_sensitivity () const; - - int run (const std::string& path, Readable*, uint32_t channel, AnalysisFeatureList& results); - - static void cleanup_transients (AnalysisFeatureList&, float sr, float gap_msecs); - - protected: - AnalysisFeatureList* current_results; - int use_features (Vamp::Plugin::FeatureSet&, std::ostream*); - - static std::string _op_id; -}; - -} /* namespace */ - -#endif /* __ardour_audioanalyser_h__ */ diff --git a/libs/ardour/ardour/types.h b/libs/ardour/ardour/types.h deleted file mode 100644 index 9bfd93cdbf..0000000000 --- a/libs/ardour/ardour/types.h +++ /dev/null @@ -1,443 +0,0 @@ -/* - Copyright (C) 2002 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_types_h__ -#define __ardour_types_h__ - -#ifndef __STDC_FORMAT_MACROS -#define __STDC_FORMAT_MACROS /* PRI<foo>; C++ requires explicit requesting of these */ -#endif - -#include <istream> -#include <vector> -#include <boost/shared_ptr.hpp> - -#include <inttypes.h> -#include <jack/types.h> -#include <jack/midiport.h> -#include <control_protocol/smpte.h> -#include <pbd/id.h> - -#include <map> - -#if __GNUC__ < 3 - -typedef int intptr_t; -#endif - -/* eventually, we'd like everything (including JACK) to - move to this. for now, its a dedicated type. -*/ - -typedef int64_t nframes64_t; - -namespace ARDOUR { - - class Source; - class AudioSource; - - typedef jack_default_audio_sample_t Sample; - typedef float pan_t; - typedef float gain_t; - typedef uint32_t layer_t; - typedef uint64_t microseconds_t; - typedef uint32_t nframes_t; - - enum IOChange { - NoChange = 0, - ConfigurationChanged = 0x1, - ConnectionsChanged = 0x2 - }; - - enum OverlapType { - OverlapNone, // no overlap - OverlapInternal, // the overlap is 100% with the object - OverlapStart, // overlap covers start, but ends within - OverlapEnd, // overlap begins within and covers end - OverlapExternal // overlap extends to (at least) begin+end - }; - - OverlapType coverage (nframes_t start_a, nframes_t end_a, - nframes_t start_b, nframes_t end_b); - - /** See parameter.h - * XXX: I don't think/hope these hex values matter anymore. - */ - enum AutomationType { - NullAutomation = 0x0, - GainAutomation = 0x1, - PanAutomation = 0x2, - PluginAutomation = 0x4, - SoloAutomation = 0x8, - MuteAutomation = 0x10, - MidiCCAutomation = 0x20, - MidiPgmChangeAutomation = 0x21, - MidiPitchBenderAutomation = 0x22, - MidiChannelAftertouchAutomation = 0x23, - FadeInAutomation = 0x40, - FadeOutAutomation = 0x80, - EnvelopeAutomation = 0x100 - }; - - enum AutoState { - Off = 0x0, - Write = 0x1, - Touch = 0x2, - Play = 0x4 - }; - - std::string auto_state_to_string (AutoState); - AutoState string_to_auto_state (std::string); - - enum AutoStyle { - Absolute = 0x1, - Trim = 0x2 - }; - - std::string auto_style_to_string (AutoStyle); - AutoStyle string_to_auto_style (std::string); - - enum AlignStyle { - CaptureTime, - ExistingMaterial - }; - - enum MeterPoint { - MeterInput, - MeterPreFader, - MeterPostFader - }; - - enum TrackMode { - Normal, - Destructive - }; - - enum NoteMode { - Sustained, - Percussive - }; - - enum ChannelMode { - AllChannels = 0, ///< Pass through all channel information unmodified - FilterChannels, ///< Ignore events on certain channels - ForceChannel ///< Force all events to a certain channel - }; - - enum EventTimeUnit { - Frames, - Beats - }; - - struct BBT_Time { - uint32_t bars; - uint32_t beats; - uint32_t ticks; - - BBT_Time() { - bars = 1; - beats = 1; - ticks = 0; - } - - /* we can't define arithmetic operators for BBT_Time, because - the results depend on a TempoMap, but we can define - a useful check on the less-than condition. - */ - - bool operator< (const BBT_Time& other) const { - return bars < other.bars || - (bars == other.bars && beats < other.beats) || - (bars == other.bars && beats == other.beats && ticks < other.ticks); - } - - bool operator== (const BBT_Time& other) const { - return bars == other.bars && beats == other.beats && ticks == other.ticks; - } - - }; - enum SmpteFormat { - smpte_23976, - smpte_24, - smpte_24976, - smpte_25, - smpte_2997, - smpte_2997drop, - smpte_30, - smpte_30drop, - smpte_5994, - smpte_60 - }; - - struct AnyTime { - enum Type { - SMPTE, - BBT, - Frames, - Seconds - }; - - Type type; - - SMPTE::Time smpte; - BBT_Time bbt; - - union { - nframes_t frames; - double seconds; - }; - - AnyTime() { type = Frames; frames = 0; } - }; - - struct AudioRange { - nframes_t start; - nframes_t end; - uint32_t id; - - AudioRange (nframes_t s, nframes_t e, uint32_t i) : start (s), end (e) , id (i) {} - - nframes_t length() { return end - start + 1; } - - bool operator== (const AudioRange& other) const { - return start == other.start && end == other.end && id == other.id; - } - - bool equal (const AudioRange& other) const { - return start == other.start && end == other.end; - } - - OverlapType coverage (nframes_t s, nframes_t e) const { - return ARDOUR::coverage (start, end, s, e); - } - }; - - struct MusicRange { - BBT_Time start; - BBT_Time end; - uint32_t id; - - MusicRange (BBT_Time& s, BBT_Time& e, uint32_t i) - : start (s), end (e), id (i) {} - - bool operator== (const MusicRange& other) const { - return start == other.start && end == other.end && id == other.id; - } - - bool equal (const MusicRange& other) const { - return start == other.start && end == other.end; - } - }; - - /* - Slowest = 6.6dB/sec falloff at update rate of 40ms - Slow = 6.8dB/sec falloff at update rate of 40ms - */ - - enum MeterFalloff { - MeterFalloffOff = 0, - MeterFalloffSlowest = 1, - MeterFalloffSlow = 2, - MeterFalloffMedium = 3, - MeterFalloffFast = 4, - MeterFalloffFaster = 5, - MeterFalloffFastest = 6 - }; - - enum MeterHold { - MeterHoldOff = 0, - MeterHoldShort = 40, - MeterHoldMedium = 100, - MeterHoldLong = 200 - }; - - enum EditMode { - Slide, - Splice, - Lock - }; - - enum RegionPoint { - Start, - End, - SyncPoint - }; - - enum Change { - range_guarantee = ~0 - }; - - - enum Placement { - PreFader, - PostFader - }; - - enum MonitorModel { - HardwareMonitoring, - SoftwareMonitoring, - ExternalMonitoring - }; - - enum DenormalModel { - DenormalNone, - DenormalFTZ, - DenormalDAZ, - DenormalFTZDAZ - }; - - enum RemoteModel { - UserOrdered, - MixerOrdered, - EditorOrdered - }; - - enum CrossfadeModel { - FullCrossfade, - ShortCrossfade - }; - - enum LayerModel { - LaterHigher, - MoveAddHigher, - AddHigher - }; - - enum SoloModel { - InverseMute, - SoloBus - }; - - enum AutoConnectOption { - AutoConnectPhysical = 0x1, - AutoConnectMaster = 0x2 - }; - - struct InterThreadInfo { - volatile bool done; - volatile bool cancel; - volatile float progress; - pthread_t thread; - }; - - enum SampleFormat { - FormatFloat = 0, - FormatInt24, - FormatInt16 - }; - - - enum HeaderFormat { - BWF, - WAVE, - WAVE64, - CAF, - AIFF, - iXML, - RF64 - }; - - struct PeakData { - typedef Sample PeakDatum; - - PeakDatum min; - PeakDatum max; - }; - - enum PluginType { - AudioUnit, - LADSPA, - LV2, - VST - }; - - enum SlaveSource { - None = 0, - MTC, - JACK - }; - - enum ShuttleBehaviour { - Sprung, - Wheel - }; - - enum ShuttleUnits { - Percentage, - Semitones - }; - - typedef std::vector<boost::shared_ptr<Source> > SourceList; - - enum SrcQuality { - SrcBest, - SrcGood, - SrcQuick, - SrcFast, - SrcFastest - }; - - struct TimeFXRequest : public InterThreadInfo { - TimeFXRequest() : time_fraction(0), pitch_fraction(0), - quick_seek(false), antialias(false), opts(0) {} - float time_fraction; - float pitch_fraction; - /* SoundTouch */ - bool quick_seek; - bool antialias; - /* RubberBand */ - int opts; // really RubberBandStretcher::Options - }; - - typedef std::list<nframes64_t> AnalysisFeatureList; - -} // namespace ARDOUR - -std::istream& operator>>(std::istream& o, ARDOUR::SampleFormat& sf); -std::istream& operator>>(std::istream& o, ARDOUR::HeaderFormat& sf); -std::istream& operator>>(std::istream& o, ARDOUR::AutoConnectOption& sf); -std::istream& operator>>(std::istream& o, ARDOUR::EditMode& sf); -std::istream& operator>>(std::istream& o, ARDOUR::MonitorModel& sf); -std::istream& operator>>(std::istream& o, ARDOUR::RemoteModel& sf); -std::istream& operator>>(std::istream& o, ARDOUR::SoloModel& sf); -std::istream& operator>>(std::istream& o, ARDOUR::LayerModel& sf); -std::istream& operator>>(std::istream& o, ARDOUR::CrossfadeModel& sf); -std::istream& operator>>(std::istream& o, ARDOUR::SlaveSource& sf); -std::istream& operator>>(std::istream& o, ARDOUR::ShuttleBehaviour& sf); -std::istream& operator>>(std::istream& o, ARDOUR::ShuttleUnits& sf); -std::istream& operator>>(std::istream& o, ARDOUR::SmpteFormat& sf); -std::istream& operator>>(std::istream& o, ARDOUR::DenormalModel& sf); - -using ARDOUR::nframes_t; - -static inline nframes_t -session_frame_to_track_frame (nframes_t session_frame, double speed) -{ - return (nframes_t)( (double)session_frame * speed ); -} - -static inline nframes_t -track_frame_to_session_frame (nframes_t track_frame, double speed) -{ - return (nframes_t)( (double)track_frame / speed ); -} - - -#endif /* __ardour_types_h__ */ - diff --git a/libs/ardour/ardour/user_bundle.h b/libs/ardour/ardour/user_bundle.h deleted file mode 100644 index 954e93d5d1..0000000000 --- a/libs/ardour/ardour/user_bundle.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - Copyright (C) 2007 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_user_bundle_h__ -#define __ardour_user_bundle_h__ - -#include <vector> -#include <glibmm/thread.h> -#include "pbd/stateful.h" -#include "ardour/bundle.h" - -namespace ARDOUR { - -class Session; - -class UserBundle : public Bundle, public PBD::Stateful { - - public: - UserBundle (std::string const &); - UserBundle (XMLNode const &, bool); - - uint32_t nchannels () const; - const ARDOUR::PortList& channel_ports (uint32_t) const; - - void add_channel (); - void set_channels (uint32_t); - void remove_channel (uint32_t); - void add_port_to_channel (uint32_t, std::string const &); - void remove_port_from_channel (uint32_t, std::string const &); - bool port_attached_to_channel (uint32_t, std::string const &) const; - XMLNode& get_state (); - - /// The number of channels is about to change - sigc::signal<void> ConfigurationWillChange; - /// The number of channels has changed - sigc::signal<void> ConfigurationHasChanged; - /// The port set associated with one of our channels is about to change - /// Parameter is the channel number - sigc::signal<void, int> PortsWillChange; - /// The port set associated with one of our channels has changed - /// Parameter is the channel number - sigc::signal<void, int> PortsHaveChanged; - - private: - - int set_state (const XMLNode &); - - /// mutex for _ports; - /// XXX: is this necessary? - mutable Glib::Mutex _ports_mutex; - std::vector<PortList> _ports; -}; - -} - -#endif diff --git a/libs/ardour/ardour/utils.h b/libs/ardour/ardour/utils.h deleted file mode 100644 index eecde2e85f..0000000000 --- a/libs/ardour/ardour/utils.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - Copyright (C) 1999 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_utils_h__ -#define __ardour_utils_h__ - -#include <iostream> -#include <string> -#include <cmath> - -#if defined(HAVE_COREAUDIO) || defined(HAVE_AUDIOUNITS) -#include <CoreFoundation/CoreFoundation.h> -#endif - -#include "ardour.h" - -class XMLNode; - -Glib::ustring legalize_for_path (Glib::ustring str); -std::ostream& operator<< (std::ostream& o, const ARDOUR::BBT_Time& bbt); -XMLNode* find_named_node (const XMLNode& node, std::string name); - -static inline float f_max(float x, float a) { - x -= a; - x += fabsf (x); - x *= 0.5f; - x += a; - - return (x); -} - -std::string bump_name_once(std::string s); - -int cmp_nocase (const std::string& s, const std::string& s2); - -int touch_file(Glib::ustring path); - -Glib::ustring path_expand (Glib::ustring); -Glib::ustring region_name_from_path (Glib::ustring path, bool strip_channels, bool add_channel_suffix = false, uint32_t total = 0, uint32_t this_one = 0); -bool path_is_paired (Glib::ustring path, Glib::ustring& pair_base); - -void compute_equal_power_fades (nframes_t nframes, float* in, float* out); - -const char* slave_source_to_string (ARDOUR::SlaveSource src); -ARDOUR::SlaveSource string_to_slave_source (std::string str); - -const char* edit_mode_to_string (ARDOUR::EditMode); -ARDOUR::EditMode string_to_edit_mode (std::string); - -float meter_falloff_to_float (ARDOUR::MeterFalloff); -ARDOUR::MeterFalloff meter_falloff_from_float (float); -float meter_falloff_to_db_per_sec (float); -float meter_hold_to_float (ARDOUR::MeterHold); - -#if defined(HAVE_COREAUDIO) || defined(HAVE_AUDIOUNITS) -std::string CFStringRefToStdString(CFStringRef stringRef); -#endif // HAVE_COREAUDIO - -#endif /* __ardour_utils_h__ */ - diff --git a/libs/ardour/ardour/vst_plugin.h b/libs/ardour/ardour/vst_plugin.h deleted file mode 100644 index e41d000f9c..0000000000 --- a/libs/ardour/ardour/vst_plugin.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - Copyright (C) 2004 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_vst_plugin_h__ -#define __ardour_vst_plugin_h__ - -#include <list> -#include <map> -#include <set> -#include <vector> -#include <string> -#include <dlfcn.h> - -#include <sigc++/signal.h> -#include <pbd/stateful.h> -#include <jack/types.h> -#include <ardour/plugin.h> - -using std::string; -using std::vector; -using std::list; -using std::map; - -struct _FSTHandle; -struct _FST; -typedef struct _FSTHandle FSTHandle; -typedef struct _FST FST; -class AEffect; - -namespace ARDOUR { -class AudioEngine; -class Session; - -class VSTPlugin : public ARDOUR::Plugin -{ - public: - VSTPlugin (ARDOUR::AudioEngine&, ARDOUR::Session&, FSTHandle* handle); - VSTPlugin (const VSTPlugin &); - ~VSTPlugin (); - - /* Plugin interface */ - - std::string unique_id() const; - const char * label() const; - const char * name() const; - const char * maker() const; - uint32_t parameter_count() const; - float default_value (uint32_t port); - nframes_t signal_latency() const; - void set_parameter (uint32_t port, float val); - float get_parameter (uint32_t port) const; - int get_parameter_descriptor (uint32_t which, ParameterDescriptor&) const; - std::set<uint32_t> automatable() const; - uint32_t nth_parameter (uint32_t port, bool& ok) const; - void activate (); - void deactivate (); - void set_block_size (nframes_t nframes); - int connect_and_run (BufferSet&, uint32_t& in, uint32_t& out, nframes_t nframes, nframes_t offset); - string describe_parameter (uint32_t); - string state_node_name() const { return "vst"; } - void print_parameter (uint32_t, char*, uint32_t len) const; - - bool parameter_is_audio(uint32_t i) const { return false; } - bool parameter_is_control(uint32_t i) const { return true; } - bool parameter_is_input(uint32_t i) const { return true; } - bool parameter_is_output(uint32_t i) const { return false; } - - bool load_preset (const string preset_label ); - bool save_preset(string name); - - bool has_editor () const; - - XMLNode& get_state(); - int set_state(const XMLNode& node); - - AEffect* plugin() const { return _plugin; } - FST* fst() const { return _fst; } - - - private: - FSTHandle* handle; - FST* _fst; - AEffect* _plugin; - bool been_resumed; -}; - -class VSTPluginInfo : public PluginInfo -{ - public: - VSTPluginInfo () {} - ~VSTPluginInfo () {} - - PluginPtr load (Session& session); -}; - -typedef boost::shared_ptr<VSTPluginInfo> VSTPluginInfoPtr; - -} // namespace ARDOUR - -#endif /* __ardour_vst_plugin_h__ */ diff --git a/libs/ardour/audio_buffer.cc b/libs/ardour/audio_buffer.cc deleted file mode 100644 index 915fdeb948..0000000000 --- a/libs/ardour/audio_buffer.cc +++ /dev/null @@ -1,82 +0,0 @@ -/* - Copyright (C) 2006-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. -*/ - -#include <ardour/audio_buffer.h> -#include <pbd/error.h> -#include <errno.h> - -#include "i18n.h" - -#ifdef __x86_64__ -static const int CPU_CACHE_ALIGN = 64; -#else -static const int CPU_CACHE_ALIGN = 16; /* arguably 32 on most arches, but it matters less */ -#endif - -using namespace PBD; - -namespace ARDOUR { - - -AudioBuffer::AudioBuffer(size_t capacity) - : Buffer(DataType::AUDIO, capacity) - , _owns_data (false) - , _data (0) -{ - if (_capacity > 0) { - _owns_data = true; // prevent resize() from gagging - resize (_capacity); - silence (_capacity); - } -} - -AudioBuffer::~AudioBuffer() -{ - if (_owns_data) - free(_data); -} - -void -AudioBuffer::resize (size_t size) -{ - if (!_owns_data || (size < _capacity)) { - return; - } - - if (_data) { - free (_data); - } - - _capacity = size; - _size = size; - _silent = false; - -#ifdef NO_POSIX_MEMALIGN - _data = (Sample *) malloc(sizeof(Sample) * _capacity); -#else - if (posix_memalign((void**)&_data, CPU_CACHE_ALIGN, sizeof(Sample) * _capacity)) { - fatal << string_compose (_("Memory allocation error: posix_memalign (%1 * %2) failed (%3)"), - CPU_CACHE_ALIGN, sizeof (Sample) * _capacity, strerror (errno)) << endmsg; - } -#endif - - _owns_data = true; -} - -} // namespace ARDOUR - diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc deleted file mode 100644 index 091e1df30f..0000000000 --- a/libs/ardour/audio_diskstream.cc +++ /dev/null @@ -1,2490 +0,0 @@ -/* - 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. -*/ - -#include <fstream> -#include <cstdio> -#include <unistd.h> -#include <cmath> -#include <cerrno> -#include <cassert> -#include <string> -#include <climits> -#include <fcntl.h> -#include <cstdlib> -#include <ctime> -#include <sys/stat.h> -#include <sys/mman.h> - -#include <pbd/error.h> -#include <glibmm/thread.h> -#include <pbd/xml++.h> -#include <pbd/memento_command.h> -#include <pbd/enumwriter.h> -#include <pbd/stacktrace.h> - -#include <ardour/ardour.h> -#include <ardour/audioengine.h> -#include <ardour/analyser.h> -#include <ardour/audio_diskstream.h> -#include <ardour/utils.h> -#include <ardour/configuration.h> -#include <ardour/audiofilesource.h> -#include <ardour/send.h> -#include <ardour/region_factory.h> -#include <ardour/audioplaylist.h> -#include <ardour/playlist_factory.h> -#include <ardour/cycle_timer.h> -#include <ardour/audioregion.h> -#include <ardour/audio_port.h> -#include <ardour/source_factory.h> - -#include "i18n.h" -#include <locale.h> - -using namespace std; -using namespace ARDOUR; -using namespace PBD; - -size_t AudioDiskstream::_working_buffers_size = 0; -Sample* AudioDiskstream::_mixdown_buffer = 0; -gain_t* AudioDiskstream::_gain_buffer = 0; - -AudioDiskstream::AudioDiskstream (Session &sess, const string &name, Diskstream::Flag flag) - : Diskstream(sess, name, flag) - , deprecated_io_node(NULL) - , channels (new ChannelList) -{ - /* prevent any write sources from being created */ - - in_set_state = true; - - init(flag); - use_new_playlist (); - - in_set_state = false; -} - -AudioDiskstream::AudioDiskstream (Session& sess, const XMLNode& node) - : Diskstream(sess, node) - , deprecated_io_node(NULL) - , channels (new ChannelList) -{ - in_set_state = true; - init (Recordable); - - if (set_state (node)) { - in_set_state = false; - throw failed_constructor(); - } - - in_set_state = false; - - if (destructive()) { - use_destructive_playlist (); - } -} - -void -AudioDiskstream::init (Diskstream::Flag f) -{ - Diskstream::init(f); - - /* there are no channels at this point, so these - two calls just get speed_buffer_size and wrap_buffer - size setup without duplicating their code. - */ - - set_block_size (_session.get_block_size()); - allocate_temporary_buffers (); - - add_channel (1); - assert(_n_channels == ChanCount(DataType::AUDIO, 1)); -} - -AudioDiskstream::~AudioDiskstream () -{ - notify_callbacks (); - - { - RCUWriter<ChannelList> writer (channels); - boost::shared_ptr<ChannelList> c = writer.get_copy(); - - for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) { - delete *chan; - } - - c->clear(); - } - - channels.flush (); -} - -void -AudioDiskstream::allocate_working_buffers() -{ - assert(disk_io_frames() > 0); - - _working_buffers_size = disk_io_frames(); - _mixdown_buffer = new Sample[_working_buffers_size]; - _gain_buffer = new gain_t[_working_buffers_size]; -} - -void -AudioDiskstream::free_working_buffers() -{ - delete [] _mixdown_buffer; - delete [] _gain_buffer; - _working_buffers_size = 0; - _mixdown_buffer = 0; - _gain_buffer = 0; -} - -void -AudioDiskstream::non_realtime_input_change () -{ - { - Glib::Mutex::Lock lm (state_lock); - - if (input_change_pending == NoChange) { - return; - } - - { - RCUWriter<ChannelList> writer (channels); - boost::shared_ptr<ChannelList> c = writer.get_copy(); - - _n_channels.set(DataType::AUDIO, c->size()); - - if (_io->n_inputs().n_audio() > _n_channels.n_audio()) { - add_channel_to (c, _io->n_inputs().n_audio() - _n_channels.n_audio()); - } else if (_io->n_inputs().n_audio() < _n_channels.n_audio()) { - remove_channel_from (c, _n_channels.n_audio() - _io->n_inputs().n_audio()); - } - } - - get_input_sources (); - set_capture_offset (); - - if (first_input_change) { - set_align_style (_persistent_alignment_style); - first_input_change = false; - } else { - set_align_style_from_io (); - } - - input_change_pending = NoChange; - - /* implicit unlock */ - } - - /* reset capture files */ - - reset_write_sources (false); - - /* now refill channel buffers */ - - if (speed() != 1.0f || speed() != -1.0f) { - seek ((nframes_t) (_session.transport_frame() * (double) speed())); - } else { - seek (_session.transport_frame()); - } -} - -void -AudioDiskstream::get_input_sources () -{ - boost::shared_ptr<ChannelList> c = channels.reader(); - - uint32_t n; - ChannelList::iterator chan; - uint32_t ni = _io->n_inputs().n_audio(); - vector<string> connections; - - for (n = 0, chan = c->begin(); chan != c->end() && n < ni; ++chan, ++n) { - - connections.clear (); - - if (_io->input(n)->get_connections (connections) == 0) { - - if ((*chan)->source) { - // _source->disable_metering (); - } - - (*chan)->source = 0; - - } else { - (*chan)->source = dynamic_cast<AudioPort*>(_session.engine().get_port_by_name (connections[0]) ); - } - } -} - -int -AudioDiskstream::find_and_use_playlist (const string& name) -{ - boost::shared_ptr<AudioPlaylist> playlist; - - if ((playlist = boost::dynamic_pointer_cast<AudioPlaylist> (_session.playlist_by_name (name))) == 0) { - playlist = boost::dynamic_pointer_cast<AudioPlaylist> (PlaylistFactory::create (DataType::AUDIO, _session, name)); - } - - if (!playlist) { - error << string_compose(_("AudioDiskstream: Playlist \"%1\" isn't an audio playlist"), name) << endmsg; - return -1; - } - - return use_playlist (playlist); -} - -int -AudioDiskstream::use_playlist (boost::shared_ptr<Playlist> playlist) -{ - assert(boost::dynamic_pointer_cast<AudioPlaylist>(playlist)); - - Diskstream::use_playlist(playlist); - - return 0; -} - -int -AudioDiskstream::use_new_playlist () -{ - string newname; - boost::shared_ptr<AudioPlaylist> playlist; - - if (!in_set_state && destructive()) { - return 0; - } - - if (_playlist) { - newname = Playlist::bump_name (_playlist->name(), _session); - } else { - newname = Playlist::bump_name (_name, _session); - } - - if ((playlist = boost::dynamic_pointer_cast<AudioPlaylist> (PlaylistFactory::create (DataType::AUDIO, _session, newname, hidden()))) != 0) { - - playlist->set_orig_diskstream_id (id()); - return use_playlist (playlist); - - } else { - return -1; - } -} - -int -AudioDiskstream::use_copy_playlist () -{ - assert(audio_playlist()); - - if (destructive()) { - return 0; - } - - if (_playlist == 0) { - error << string_compose(_("AudioDiskstream %1: there is no existing playlist to make a copy of!"), _name) << endmsg; - return -1; - } - - string newname; - boost::shared_ptr<AudioPlaylist> playlist; - - newname = Playlist::bump_name (_playlist->name(), _session); - - if ((playlist = boost::dynamic_pointer_cast<AudioPlaylist>(PlaylistFactory::create (audio_playlist(), newname))) != 0) { - playlist->set_orig_diskstream_id (id()); - return use_playlist (playlist); - } else { - return -1; - } -} - -void -AudioDiskstream::setup_destructive_playlist () -{ - SourceList srcs; - boost::shared_ptr<ChannelList> c = channels.reader(); - - for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) { - srcs.push_back ((*chan)->write_source); - } - - /* a single full-sized region */ - - boost::shared_ptr<Region> region (RegionFactory::create (srcs, 0, max_frames - srcs.front()->natural_position(), _name)); - _playlist->add_region (region, srcs.front()->natural_position()); -} - -void -AudioDiskstream::use_destructive_playlist () -{ - /* this is called from the XML-based constructor or ::set_destructive. when called, - we already have a playlist and a region, but we need to - set up our sources for write. we use the sources associated - with the (presumed single, full-extent) region. - */ - - boost::shared_ptr<Region> rp = _playlist->find_next_region (_session.current_start_frame(), Start, 1); - - if (!rp) { - reset_write_sources (false, true); - return; - } - - boost::shared_ptr<AudioRegion> region = boost::dynamic_pointer_cast<AudioRegion> (rp); - - if (region == 0) { - throw failed_constructor(); - } - - /* be sure to stretch the region out to the maximum length */ - - region->set_length (max_frames - region->position(), this); - - uint32_t n; - ChannelList::iterator chan; - boost::shared_ptr<ChannelList> c = channels.reader(); - - for (n = 0, chan = c->begin(); chan != c->end(); ++chan, ++n) { - (*chan)->write_source = boost::dynamic_pointer_cast<AudioFileSource>(region->source (n)); - assert((*chan)->write_source); - (*chan)->write_source->set_allow_remove_if_empty (false); - - /* this might be false if we switched modes, so force it */ - - (*chan)->write_source->set_destructive (true); - } - - /* the source list will never be reset for a destructive track */ -} - -void -AudioDiskstream::check_record_status (nframes_t transport_frame, nframes_t nframes, bool can_record) -{ - int possibly_recording; - int rolling; - int change; - const int transport_rolling = 0x4; - const int track_rec_enabled = 0x2; - const int global_rec_enabled = 0x1; - - /* merge together the 3 factors that affect record status, and compute - what has changed. - */ - - rolling = _session.transport_speed() != 0.0f; - possibly_recording = (rolling << 2) | (record_enabled() << 1) | can_record; - change = possibly_recording ^ last_possibly_recording; - - if (possibly_recording == last_possibly_recording) { - return; - } - - /* change state */ - - /* if per-track or global rec-enable turned on while the other was already on, we've started recording */ - - if (((change & track_rec_enabled) && record_enabled() && (!(change & global_rec_enabled) && can_record)) || - (((change & global_rec_enabled) && can_record && (!(change & track_rec_enabled) && record_enabled())))) { - - /* starting to record: compute first+last frames */ - - first_recordable_frame = transport_frame + _capture_offset; - last_recordable_frame = max_frames; - capture_start_frame = transport_frame; - - if (!(last_possibly_recording & transport_rolling) && (possibly_recording & transport_rolling)) { - - /* was stopped, now rolling (and recording) */ - - if (_alignment_style == ExistingMaterial) { - first_recordable_frame += _session.worst_output_latency(); - } else { - first_recordable_frame += _roll_delay; - } - - } else { - - /* was rolling, but record state changed */ - - if (_alignment_style == ExistingMaterial) { - - if (!Config->get_punch_in()) { - - /* manual punch in happens at the correct transport frame - because the user hit a button. but to get alignment correct - we have to back up the position of the new region to the - appropriate spot given the roll delay. - */ - - capture_start_frame -= _roll_delay; - - /* XXX paul notes (august 2005): i don't know why - this is needed. - */ - - first_recordable_frame += _capture_offset; - - } else { - - /* autopunch toggles recording at the precise - transport frame, and then the DS waits - to start recording for a time that depends - on the output latency. - */ - - first_recordable_frame += _session.worst_output_latency(); - } - - } else { - - if (Config->get_punch_in()) { - first_recordable_frame += _roll_delay; - } else { - capture_start_frame -= _roll_delay; - } - } - - } - - if (recordable() && destructive()) { - boost::shared_ptr<ChannelList> c = channels.reader(); - for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) { - - RingBufferNPT<CaptureTransition>::rw_vector transvec; - (*chan)->capture_transition_buf->get_write_vector(&transvec); - - if (transvec.len[0] > 0) { - transvec.buf[0]->type = CaptureStart; - transvec.buf[0]->capture_val = capture_start_frame; - (*chan)->capture_transition_buf->increment_write_ptr(1); - } - else { - // bad! - fatal << X_("programming error: capture_transition_buf is full on rec start! inconceivable!") - << endmsg; - } - } - } - - } else if (!record_enabled() || !can_record) { - - /* stop recording */ - - last_recordable_frame = transport_frame + _capture_offset; - - if (_alignment_style == ExistingMaterial) { - last_recordable_frame += _session.worst_output_latency(); - } else { - last_recordable_frame += _roll_delay; - } - } - - last_possibly_recording = possibly_recording; -} - -int -AudioDiskstream::process (nframes_t transport_frame, nframes_t nframes, nframes_t offset, bool can_record, bool rec_monitors_input) -{ - uint32_t n; - boost::shared_ptr<ChannelList> c = channels.reader(); - ChannelList::iterator chan; - int ret = -1; - nframes_t rec_offset = 0; - nframes_t rec_nframes = 0; - bool nominally_recording; - bool re = record_enabled (); - bool collect_playback = false; - - /* if we've already processed the frames corresponding to this call, - just return. this allows multiple routes that are taking input - from this diskstream to call our ::process() method, but have - this stuff only happen once. more commonly, it allows both - the AudioTrack that is using this AudioDiskstream *and* the Session - to call process() without problems. - */ - - if (_processed) { - return 0; - } - - commit_should_unlock = false; - - if (!_io->active()) { - _processed = true; - return 0; - } - - check_record_status (transport_frame, nframes, can_record); - - nominally_recording = (can_record && re); - - if (nframes == 0) { - _processed = true; - return 0; - } - - /* This lock is held until the end of AudioDiskstream::commit, so these two functions - must always be called as a pair. The only exception is if this function - returns a non-zero value, in which case, ::commit should not be called. - */ - - // If we can't take the state lock return. - if (!state_lock.trylock()) { - return 1; - } - commit_should_unlock = true; - adjust_capture_position = 0; - - for (chan = c->begin(); chan != c->end(); ++chan) { - (*chan)->current_capture_buffer = 0; - (*chan)->current_playback_buffer = 0; - } - - if (nominally_recording || (_session.get_record_enabled() && Config->get_punch_in())) { - OverlapType ot; - - // Safeguard against situations where process() goes haywire when autopunching and last_recordable_frame < first_recordable_frame - if (last_recordable_frame < first_recordable_frame) { - last_recordable_frame = max_frames; - } - - ot = coverage (first_recordable_frame, last_recordable_frame, transport_frame, transport_frame + nframes); - - switch (ot) { - case OverlapNone: - rec_nframes = 0; - break; - - case OverlapInternal: - /* ---------- recrange - |---| transrange - */ - rec_nframes = nframes; - rec_offset = 0; - break; - - case OverlapStart: - /* |--------| recrange - -----| transrange - */ - rec_nframes = transport_frame + nframes - first_recordable_frame; - if (rec_nframes) { - rec_offset = first_recordable_frame - transport_frame; - } - break; - - case OverlapEnd: - /* |--------| recrange - |-------- transrange - */ - rec_nframes = last_recordable_frame - transport_frame; - rec_offset = 0; - break; - - case OverlapExternal: - /* |--------| recrange - -------------- transrange - */ - rec_nframes = last_recordable_frame - first_recordable_frame; - rec_offset = first_recordable_frame - transport_frame; - break; - } - - if (rec_nframes && !was_recording) { - capture_captured = 0; - was_recording = true; - } - } - - - if (can_record && !_last_capture_regions.empty()) { - _last_capture_regions.clear (); - } - - if (nominally_recording || rec_nframes) { - - uint32_t limit = _io->n_inputs ().n_audio(); - - /* one or more ports could already have been removed from _io, but our - channel setup hasn't yet been updated. prevent us from trying to - use channels that correspond to missing ports. note that the - process callback (from which this is called) is always atomic - with respect to port removal/addition. - */ - - for (n = 0, chan = c->begin(); chan != c->end() && n < limit; ++chan, ++n) { - - ChannelInfo* chaninfo (*chan); - - chaninfo->capture_buf->get_write_vector (&chaninfo->capture_vector); - - if (rec_nframes <= chaninfo->capture_vector.len[0]) { - - chaninfo->current_capture_buffer = chaninfo->capture_vector.buf[0]; - - /* note: grab the entire port buffer, but only copy what we were supposed to for recording, and use - rec_offset - */ - - AudioPort* const ap = _io->audio_input(n); - assert(ap); - assert(rec_nframes <= ap->get_audio_buffer().capacity()); - memcpy (chaninfo->current_capture_buffer, ap->get_audio_buffer().data(rec_nframes, offset + rec_offset), sizeof (Sample) * rec_nframes); - - } else { - - nframes_t total = chaninfo->capture_vector.len[0] + chaninfo->capture_vector.len[1]; - - if (rec_nframes > total) { - DiskOverrun (); - goto out; - } - - AudioPort* const ap = _io->audio_input(n); - assert(ap); - - Sample* buf = ap->get_audio_buffer().data(nframes, offset); - nframes_t first = chaninfo->capture_vector.len[0]; - - memcpy (chaninfo->capture_wrap_buffer, buf, sizeof (Sample) * first); - memcpy (chaninfo->capture_vector.buf[0], buf, sizeof (Sample) * first); - memcpy (chaninfo->capture_wrap_buffer+first, buf + first, sizeof (Sample) * (rec_nframes - first)); - memcpy (chaninfo->capture_vector.buf[1], buf + first, sizeof (Sample) * (rec_nframes - first)); - - chaninfo->current_capture_buffer = chaninfo->capture_wrap_buffer; - } - } - - } else { - - if (was_recording) { - finish_capture (rec_monitors_input, c); - } - - } - - if (rec_nframes) { - - /* data will be written to disk */ - - if (rec_nframes == nframes && rec_offset == 0) { - - for (chan = c->begin(); chan != c->end(); ++chan) { - (*chan)->current_playback_buffer = (*chan)->current_capture_buffer; - } - - playback_distance = nframes; - - } else { - - - /* we can't use the capture buffer as the playback buffer, because - we recorded only a part of the current process' cycle data - for capture. - */ - - collect_playback = true; - } - - adjust_capture_position = rec_nframes; - - } else if (nominally_recording) { - - /* can't do actual capture yet - waiting for latency effects to finish before we start*/ - - for (chan = c->begin(); chan != c->end(); ++chan) { - (*chan)->current_playback_buffer = (*chan)->current_capture_buffer; - } - - playback_distance = nframes; - - } else { - - collect_playback = true; - } - - if (collect_playback) { - - /* we're doing playback */ - - nframes_t necessary_samples; - - /* no varispeed playback if we're recording, because the output .... TBD */ - - if (rec_nframes == 0 && _actual_speed != 1.0f) { - necessary_samples = (nframes_t) floor ((nframes * fabs (_actual_speed))) + 1; - } else { - necessary_samples = nframes; - } - - for (chan = c->begin(); chan != c->end(); ++chan) { - (*chan)->playback_buf->get_read_vector (&(*chan)->playback_vector); - } - - n = 0; - - for (chan = c->begin(); chan != c->end(); ++chan, ++n) { - - ChannelInfo* chaninfo (*chan); - - if (necessary_samples <= chaninfo->playback_vector.len[0]) { - - chaninfo->current_playback_buffer = chaninfo->playback_vector.buf[0]; - - } else { - nframes_t total = chaninfo->playback_vector.len[0] + chaninfo->playback_vector.len[1]; - - if (necessary_samples > total) { - cerr << "underrun for " << _name << endl; - DiskUnderrun (); - goto out; - - } else { - - memcpy ((char *) chaninfo->playback_wrap_buffer, chaninfo->playback_vector.buf[0], - chaninfo->playback_vector.len[0] * sizeof (Sample)); - memcpy (chaninfo->playback_wrap_buffer + chaninfo->playback_vector.len[0], chaninfo->playback_vector.buf[1], - (necessary_samples - chaninfo->playback_vector.len[0]) * sizeof (Sample)); - - chaninfo->current_playback_buffer = chaninfo->playback_wrap_buffer; - } - } - } - - if (rec_nframes == 0 && _actual_speed != 1.0f && _actual_speed != -1.0f) { - - uint64_t phase = last_phase; - int64_t phi_delta; - nframes_t i = 0; - - // Linearly interpolate into the alt buffer - // using 40.24 fixp maths (swh) - - if (phi != target_phi) { - phi_delta = ((int64_t)(target_phi - phi)) / nframes; - } else { - phi_delta = 0; - } - - for (chan = c->begin(); chan != c->end(); ++chan) { - - float fr; - ChannelInfo* chaninfo (*chan); - - i = 0; - phase = last_phase; - - for (nframes_t outsample = 0; outsample < nframes; ++outsample) { - i = phase >> 24; - fr = (phase & 0xFFFFFF) / 16777216.0f; - chaninfo->speed_buffer[outsample] = - chaninfo->current_playback_buffer[i] * (1.0f - fr) + - chaninfo->current_playback_buffer[i+1] * fr; - phase += phi + phi_delta; - } - - chaninfo->current_playback_buffer = chaninfo->speed_buffer; - } - - playback_distance = i; // + 1; - last_phase = (phase & 0xFFFFFF); - - } else { - playback_distance = nframes; - } - - phi = target_phi; - - } - - ret = 0; - - out: - _processed = true; - - if (ret) { - - /* we're exiting with failure, so ::commit will not - be called. unlock the state lock. - */ - - commit_should_unlock = false; - state_lock.unlock(); - } - - return ret; -} - -bool -AudioDiskstream::commit (nframes_t nframes) -{ - bool need_butler = false; - - if (!_io->active()) { - return false; - } - - if (_actual_speed < 0.0) { - playback_sample -= playback_distance; - } else { - playback_sample += playback_distance; - } - - boost::shared_ptr<ChannelList> c = channels.reader(); - for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) { - - (*chan)->playback_buf->increment_read_ptr (playback_distance); - - if (adjust_capture_position) { - (*chan)->capture_buf->increment_write_ptr (adjust_capture_position); - } - } - - if (adjust_capture_position != 0) { - capture_captured += adjust_capture_position; - adjust_capture_position = 0; - } - - if (_slaved) { - if (_io && _io->active()) { - need_butler = c->front()->playback_buf->write_space() >= c->front()->playback_buf->bufsize() / 2; - } else { - need_butler = false; - } - } else { - if (_io && _io->active()) { - need_butler = c->front()->playback_buf->write_space() >= disk_io_chunk_frames - || c->front()->capture_buf->read_space() >= disk_io_chunk_frames; - } else { - need_butler = c->front()->capture_buf->read_space() >= disk_io_chunk_frames; - } - } - - if (commit_should_unlock) { - state_lock.unlock(); - } - - _processed = false; - - return need_butler; -} - -void -AudioDiskstream::set_pending_overwrite (bool yn) -{ - /* called from audio thread, so we can use the read ptr and playback sample as we wish */ - - pending_overwrite = yn; - - overwrite_frame = playback_sample; - overwrite_offset = channels.reader()->front()->playback_buf->get_read_ptr(); -} - -int -AudioDiskstream::overwrite_existing_buffers () -{ - boost::shared_ptr<ChannelList> c = channels.reader(); - Sample* mixdown_buffer; - float* gain_buffer; - int ret = -1; - bool reversed = (_visible_speed * _session.transport_speed()) < 0.0f; - - overwrite_queued = false; - - /* assume all are the same size */ - nframes_t size = c->front()->playback_buf->bufsize(); - - mixdown_buffer = new Sample[size]; - gain_buffer = new float[size]; - - /* reduce size so that we can fill the buffer correctly. */ - size--; - - uint32_t n=0; - nframes_t start; - - for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan, ++n) { - - start = overwrite_frame; - nframes_t cnt = size; - - /* to fill the buffer without resetting the playback sample, we need to - do it one or two chunks (normally two). - - |----------------------------------------------------------------------| - - ^ - overwrite_offset - |<- second chunk->||<----------------- first chunk ------------------>| - - */ - - nframes_t to_read = size - overwrite_offset; - - if (read ((*chan)->playback_buf->buffer() + overwrite_offset, mixdown_buffer, gain_buffer, start, to_read, *chan, n, reversed)) { - error << string_compose(_("AudioDiskstream %1: when refilling, cannot read %2 from playlist at frame %3"), - _id, size, playback_sample) << endmsg; - goto out; - } - - if (cnt > to_read) { - - cnt -= to_read; - - if (read ((*chan)->playback_buf->buffer(), mixdown_buffer, gain_buffer, - start, cnt, *chan, n, reversed)) { - error << string_compose(_("AudioDiskstream %1: when refilling, cannot read %2 from playlist at frame %3"), - _id, size, playback_sample) << endmsg; - goto out; - } - } - } - - ret = 0; - - out: - pending_overwrite = false; - delete [] gain_buffer; - delete [] mixdown_buffer; - return ret; -} - -int -AudioDiskstream::seek (nframes_t frame, bool complete_refill) -{ - uint32_t n; - int ret = -1; - ChannelList::iterator chan; - boost::shared_ptr<ChannelList> c = channels.reader(); - - Glib::Mutex::Lock lm (state_lock); - - for (n = 0, chan = c->begin(); chan != c->end(); ++chan, ++n) { - (*chan)->playback_buf->reset (); - (*chan)->capture_buf->reset (); - } - - /* can't rec-enable in destructive mode if transport is before start */ - - if (destructive() && record_enabled() && frame < _session.current_start_frame()) { - disengage_record_enable (); - } - - playback_sample = frame; - file_frame = frame; - - if (complete_refill) { - while ((ret = do_refill_with_alloc ()) > 0) ; - } else { - ret = do_refill_with_alloc (); - } - - return ret; -} - -int -AudioDiskstream::can_internal_playback_seek (nframes_t distance) -{ - ChannelList::iterator chan; - boost::shared_ptr<ChannelList> c = channels.reader(); - - for (chan = c->begin(); chan != c->end(); ++chan) { - if ((*chan)->playback_buf->read_space() < distance) { - return false; - } - } - return true; -} - -int -AudioDiskstream::internal_playback_seek (nframes_t distance) -{ - ChannelList::iterator chan; - boost::shared_ptr<ChannelList> c = channels.reader(); - - for (chan = c->begin(); chan != c->end(); ++chan) { - (*chan)->playback_buf->increment_read_ptr (distance); - } - - first_recordable_frame += distance; - playback_sample += distance; - - return 0; -} - -int -AudioDiskstream::read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer, nframes_t& start, nframes_t cnt, - ChannelInfo* channel_info, int channel, bool reversed) -{ - nframes_t this_read = 0; - bool reloop = false; - nframes_t loop_end = 0; - nframes_t loop_start = 0; - nframes_t loop_length = 0; - nframes_t offset = 0; - Location *loc = 0; - - /* XXX we don't currently play loops in reverse. not sure why */ - - if (!reversed) { - - /* Make the use of a Location atomic for this read operation. - - Note: Locations don't get deleted, so all we care about - when I say "atomic" is that we are always pointing to - the same one and using a start/length values obtained - just once. - */ - - if ((loc = loop_location) != 0) { - loop_start = loc->start(); - loop_end = loc->end(); - loop_length = loop_end - loop_start; - } - - /* if we are looping, ensure that the first frame we read is at the correct - position within the loop. - */ - - if (loc && start >= loop_end) { - //cerr << "start adjusted from " << start; - start = loop_start + ((start - loop_start) % loop_length); - //cerr << "to " << start << endl; - } - - //cerr << "start is " << start << " loopstart: " << loop_start << " loopend: " << loop_end << endl; - } - - while (cnt) { - - if (reversed) { - start -= cnt; - } - - /* take any loop into account. we can't read past the end of the loop. */ - - if (loc && (loop_end - start < cnt)) { - this_read = loop_end - start; - //cerr << "reloop true: thisread: " << this_read << " cnt: " << cnt << endl; - reloop = true; - } else { - reloop = false; - this_read = cnt; - } - - if (this_read == 0) { - break; - } - - this_read = min(cnt,this_read); - - if (audio_playlist()->read (buf+offset, mixdown_buffer, gain_buffer, start, this_read, channel) != this_read) { - error << string_compose(_("AudioDiskstream %1: cannot read %2 from playlist at frame %3"), _id, this_read, - start) << endmsg; - return -1; - } - - _read_data_count = _playlist->read_data_count(); - - if (reversed) { - - swap_by_ptr (buf, buf + this_read - 1); - - } else { - - /* if we read to the end of the loop, go back to the beginning */ - - if (reloop) { - start = loop_start; - } else { - start += this_read; - } - } - - cnt -= this_read; - offset += this_read; - } - - return 0; -} - -int -AudioDiskstream::do_refill_with_alloc () -{ - Sample* mix_buf = new Sample[disk_io_chunk_frames]; - float* gain_buf = new float[disk_io_chunk_frames]; - - int ret = _do_refill(mix_buf, gain_buf); - - delete [] mix_buf; - delete [] gain_buf; - - return ret; -} - -int -AudioDiskstream::_do_refill (Sample* mixdown_buffer, float* gain_buffer) -{ - int32_t ret = 0; - nframes_t to_read; - RingBufferNPT<Sample>::rw_vector vector; - bool reversed = (_visible_speed * _session.transport_speed()) < 0.0f; - nframes_t total_space; - nframes_t zero_fill; - uint32_t chan_n; - ChannelList::iterator i; - boost::shared_ptr<ChannelList> c = channels.reader(); - nframes_t ts; - - if (c->empty()) { - return 0; - } - - assert(mixdown_buffer); - assert(gain_buffer); - - vector.buf[0] = 0; - vector.len[0] = 0; - vector.buf[1] = 0; - vector.len[1] = 0; - - c->front()->playback_buf->get_write_vector (&vector); - - if ((total_space = vector.len[0] + vector.len[1]) == 0) { - return 0; - } - - /* if there are 2+ chunks of disk i/o possible for - this track, let the caller know so that it can arrange - for us to be called again, ASAP. - */ - - if (total_space >= (_slaved?3:2) * disk_io_chunk_frames) { - ret = 1; - } - - /* if we're running close to normal speed and there isn't enough - space to do disk_io_chunk_frames of I/O, then don't bother. - - at higher speeds, just do it because the sync between butler - and audio thread may not be good enough. - */ - - if ((total_space < disk_io_chunk_frames) && fabs (_actual_speed) < 2.0f) { - return 0; - } - - /* when slaved, don't try to get too close to the read pointer. this - leaves space for the buffer reversal to have something useful to - work with. - */ - - if (_slaved && total_space < (c->front()->playback_buf->bufsize() / 2)) { - return 0; - } - - /* never do more than disk_io_chunk_frames worth of disk input per call (limit doesn't apply for memset) */ - - total_space = min (disk_io_chunk_frames, total_space); - - if (reversed) { - - if (file_frame == 0) { - - /* at start: nothing to do but fill with silence */ - - for (chan_n = 0, i = c->begin(); i != c->end(); ++i, ++chan_n) { - - ChannelInfo* chan (*i); - chan->playback_buf->get_write_vector (&vector); - memset (vector.buf[0], 0, sizeof(Sample) * vector.len[0]); - if (vector.len[1]) { - memset (vector.buf[1], 0, sizeof(Sample) * vector.len[1]); - } - chan->playback_buf->increment_write_ptr (vector.len[0] + vector.len[1]); - } - return 0; - } - - if (file_frame < total_space) { - - /* too close to the start: read what we can, - and then zero fill the rest - */ - - zero_fill = total_space - file_frame; - total_space = file_frame; - file_frame = 0; - - } else { - - zero_fill = 0; - } - - } else { - - if (file_frame == max_frames) { - - /* at end: nothing to do but fill with silence */ - - for (chan_n = 0, i = c->begin(); i != c->end(); ++i, ++chan_n) { - - ChannelInfo* chan (*i); - chan->playback_buf->get_write_vector (&vector); - memset (vector.buf[0], 0, sizeof(Sample) * vector.len[0]); - if (vector.len[1]) { - memset (vector.buf[1], 0, sizeof(Sample) * vector.len[1]); - } - chan->playback_buf->increment_write_ptr (vector.len[0] + vector.len[1]); - } - return 0; - } - - if (file_frame > max_frames - total_space) { - - /* to close to the end: read what we can, and zero fill the rest */ - - zero_fill = total_space - (max_frames - file_frame); - total_space = max_frames - file_frame; - - } else { - zero_fill = 0; - } - } - - nframes_t file_frame_tmp = 0; - - for (chan_n = 0, i = c->begin(); i != c->end(); ++i, ++chan_n) { - - ChannelInfo* chan (*i); - Sample* buf1; - Sample* buf2; - nframes_t len1, len2; - - chan->playback_buf->get_write_vector (&vector); - - if (vector.len[0] > disk_io_chunk_frames) { - - /* we're not going to fill the first chunk, so certainly do not bother with the - other part. it won't be connected with the part we do fill, as in: - - .... => writable space - ++++ => readable space - ^^^^ => 1 x disk_io_chunk_frames that would be filled - - |......|+++++++++++++|...............................| - buf1 buf0 - ^^^^^^^^^^^^^^^ - - - So, just pretend that the buf1 part isn't there. - - */ - - vector.buf[1] = 0; - vector.len[1] = 0; - - } - - ts = total_space; - file_frame_tmp = file_frame; - - buf1 = vector.buf[0]; - len1 = vector.len[0]; - buf2 = vector.buf[1]; - len2 = vector.len[1]; - - to_read = min (ts, len1); - to_read = min (to_read, disk_io_chunk_frames); - - if (to_read) { - - if (read (buf1, mixdown_buffer, gain_buffer, file_frame_tmp, to_read, chan, chan_n, reversed)) { - ret = -1; - goto out; - } - - chan->playback_buf->increment_write_ptr (to_read); - ts -= to_read; - } - - to_read = min (ts, len2); - - if (to_read) { - - /* we read all of vector.len[0], but it wasn't an entire disk_io_chunk_frames of data, - so read some or all of vector.len[1] as well. - */ - - if (read (buf2, mixdown_buffer, gain_buffer, file_frame_tmp, to_read, chan, chan_n, reversed)) { - ret = -1; - goto out; - } - - chan->playback_buf->increment_write_ptr (to_read); - } - - if (zero_fill) { - /* do something */ - } - - } - - file_frame = file_frame_tmp; - - out: - - return ret; -} - -/** Flush pending data to disk. - * - * Important note: this function will write *AT MOST* disk_io_chunk_frames - * of data to disk. it will never write more than that. If it writes that - * much and there is more than that waiting to be written, it will return 1, - * otherwise 0 on success or -1 on failure. - * - * If there is less than disk_io_chunk_frames to be written, no data will be - * written at all unless @a force_flush is true. - */ -int -AudioDiskstream::do_flush (Session::RunContext context, bool force_flush) -{ - uint32_t to_write; - int32_t ret = 0; - RingBufferNPT<Sample>::rw_vector vector; - RingBufferNPT<CaptureTransition>::rw_vector transvec; - nframes_t total; - - _write_data_count = 0; - - transvec.buf[0] = 0; - transvec.buf[1] = 0; - vector.buf[0] = 0; - vector.buf[1] = 0; - - boost::shared_ptr<ChannelList> c = channels.reader(); - for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) { - - (*chan)->capture_buf->get_read_vector (&vector); - - total = vector.len[0] + vector.len[1]; - - if (total == 0 || (total < disk_io_chunk_frames && !force_flush && was_recording)) { - goto out; - } - - /* if there are 2+ chunks of disk i/o possible for - this track, let the caller know so that it can arrange - for us to be called again, ASAP. - - if we are forcing a flush, then if there is* any* extra - work, let the caller know. - - if we are no longer recording and there is any extra work, - let the caller know too. - */ - - if (total >= 2 * disk_io_chunk_frames || ((force_flush || !was_recording) && total > disk_io_chunk_frames)) { - ret = 1; - } - - to_write = min (disk_io_chunk_frames, (nframes_t) vector.len[0]); - - // check the transition buffer when recording destructive - // important that we get this after the capture buf - - if (destructive()) { - (*chan)->capture_transition_buf->get_read_vector(&transvec); - size_t transcount = transvec.len[0] + transvec.len[1]; - bool have_start = false; - size_t ti; - - for (ti=0; ti < transcount; ++ti) { - CaptureTransition & captrans = (ti < transvec.len[0]) ? transvec.buf[0][ti] : transvec.buf[1][ti-transvec.len[0]]; - - if (captrans.type == CaptureStart) { - // by definition, the first data we got above represents the given capture pos - - (*chan)->write_source->mark_capture_start (captrans.capture_val); - (*chan)->curr_capture_cnt = 0; - - have_start = true; - } - else if (captrans.type == CaptureEnd) { - - // capture end, the capture_val represents total frames in capture - - if (captrans.capture_val <= (*chan)->curr_capture_cnt + to_write) { - - // shorten to make the write a perfect fit - uint32_t nto_write = (captrans.capture_val - (*chan)->curr_capture_cnt); - - if (nto_write < to_write) { - ret = 1; // should we? - } - to_write = nto_write; - - (*chan)->write_source->mark_capture_end (); - - // increment past this transition, but go no further - ++ti; - break; - } - else { - // actually ends just beyond this chunk, so force more work - ret = 1; - break; - } - } - } - - if (ti > 0) { - (*chan)->capture_transition_buf->increment_read_ptr(ti); - } - } - - if ((!(*chan)->write_source) || (*chan)->write_source->write (vector.buf[0], to_write) != to_write) { - error << string_compose(_("AudioDiskstream %1: cannot write to disk"), _id) << endmsg; - return -1; - } - - (*chan)->capture_buf->increment_read_ptr (to_write); - (*chan)->curr_capture_cnt += to_write; - - if ((to_write == vector.len[0]) && (total > to_write) && (to_write < disk_io_chunk_frames) && !destructive()) { - - /* we wrote all of vector.len[0] but it wasn't an entire - disk_io_chunk_frames of data, so arrange for some part - of vector.len[1] to be flushed to disk as well. - */ - - to_write = min ((nframes_t)(disk_io_chunk_frames - to_write), (nframes_t) vector.len[1]); - - if ((*chan)->write_source->write (vector.buf[1], to_write) != to_write) { - error << string_compose(_("AudioDiskstream %1: cannot write to disk"), _id) << endmsg; - return -1; - } - - _write_data_count += (*chan)->write_source->write_data_count(); - - (*chan)->capture_buf->increment_read_ptr (to_write); - (*chan)->curr_capture_cnt += to_write; - } - } - - out: - return ret; -} - -void -AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_capture) -{ - uint32_t buffer_position; - bool more_work = true; - int err = 0; - boost::shared_ptr<AudioRegion> region; - nframes_t total_capture; - SourceList srcs; - SourceList::iterator src; - ChannelList::iterator chan; - vector<CaptureInfo*>::iterator ci; - boost::shared_ptr<ChannelList> c = channels.reader(); - uint32_t n = 0; - bool mark_write_completed = false; - - finish_capture (true, c); - - /* butler is already stopped, but there may be work to do - to flush remaining data to disk. - */ - - while (more_work && !err) { - switch (do_flush (Session::TransportContext, true)) { - case 0: - more_work = false; - break; - case 1: - break; - case -1: - error << string_compose(_("AudioDiskstream \"%1\": cannot flush captured data to disk!"), _name) << endmsg; - err++; - } - } - - /* XXX is there anything we can do if err != 0 ? */ - Glib::Mutex::Lock lm (capture_info_lock); - - if (capture_info.empty()) { - return; - } - - if (abort_capture) { - - if (destructive()) { - goto outout; - } - - for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) { - - if ((*chan)->write_source) { - - (*chan)->write_source->mark_for_remove (); - (*chan)->write_source->drop_references (); - (*chan)->write_source.reset (); - } - - /* new source set up in "out" below */ - } - - goto out; - } - - for (total_capture = 0, ci = capture_info.begin(); ci != capture_info.end(); ++ci) { - total_capture += (*ci)->frames; - } - - /* figure out the name for this take */ - - for (n = 0, chan = c->begin(); chan != c->end(); ++chan, ++n) { - - boost::shared_ptr<AudioFileSource> s = (*chan)->write_source; - - if (s) { - srcs.push_back (s); - s->update_header (capture_info.front()->start, when, twhen); - s->set_captured_for (_name); - s->mark_immutable (); - if (Config->get_auto_analyse_audio()) { - Analyser::queue_source_for_analysis (s, true); - } - } - } - - /* destructive tracks have a single, never changing region */ - - if (destructive()) { - - /* send a signal that any UI can pick up to do the right thing. there is - a small problem here in that a UI may need the peak data to be ready - for the data that was recorded and this isn't interlocked with that - process. this problem is deferred to the UI. - */ - - _playlist->Modified(); - - } else { - - string whole_file_region_name; - whole_file_region_name = region_name_from_path (c->front()->write_source->name(), true); - - /* Register a new region with the Session that - describes the entire source. Do this first - so that any sub-regions will obviously be - children of this one (later!) - */ - - try { - boost::shared_ptr<Region> rx (RegionFactory::create (srcs, c->front()->write_source->last_capture_start_frame(), total_capture, - whole_file_region_name, - 0, AudioRegion::Flag (AudioRegion::DefaultFlags|AudioRegion::Automatic|AudioRegion::WholeFile))); - - region = boost::dynamic_pointer_cast<AudioRegion> (rx); - region->special_set_position (capture_info.front()->start); - } - - - catch (failed_constructor& err) { - error << string_compose(_("%1: could not create region for complete audio file"), _name) << endmsg; - /* XXX what now? */ - } - - _last_capture_regions.push_back (region); - - // cerr << _name << ": there are " << capture_info.size() << " capture_info records\n"; - - XMLNode &before = _playlist->get_state(); - _playlist->freeze (); - - for (buffer_position = c->front()->write_source->last_capture_start_frame(), ci = capture_info.begin(); ci != capture_info.end(); ++ci) { - - string region_name; - - _session.region_name (region_name, whole_file_region_name, false); - - // cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->frames << " add region " << region_name << endl; - - try { - boost::shared_ptr<Region> rx (RegionFactory::create (srcs, buffer_position, (*ci)->frames, region_name)); - region = boost::dynamic_pointer_cast<AudioRegion> (rx); - } - - catch (failed_constructor& err) { - error << _("AudioDiskstream: could not create region for captured audio!") << endmsg; - continue; /* XXX is this OK? */ - } - - region->GoingAway.connect (bind (mem_fun (*this, &Diskstream::remove_region_from_last_capture), boost::weak_ptr<Region>(region))); - - _last_capture_regions.push_back (region); - - i_am_the_modifier++; - _playlist->add_region (region, (*ci)->start); - i_am_the_modifier--; - - buffer_position += (*ci)->frames; - } - - _playlist->thaw (); - XMLNode &after = _playlist->get_state(); - _session.add_command (new MementoCommand<Playlist>(*_playlist, &before, &after)); - } - - mark_write_completed = true; - - out: - reset_write_sources (mark_write_completed); - - outout: - - for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) { - delete *ci; - } - - capture_info.clear (); - capture_start_frame = 0; -} - -void -AudioDiskstream::transport_looped (nframes_t transport_frame) -{ - if (was_recording) { - // all we need to do is finish this capture, with modified capture length - boost::shared_ptr<ChannelList> c = channels.reader(); - - // adjust the capture length knowing that the data will be recorded to disk - // only necessary after the first loop where we're recording - if (capture_info.size() == 0) { - capture_captured += _capture_offset; - - if (_alignment_style == ExistingMaterial) { - capture_captured += _session.worst_output_latency(); - } else { - capture_captured += _roll_delay; - } - } - - finish_capture (true, c); - - // the next region will start recording via the normal mechanism - // we'll set the start position to the current transport pos - // no latency adjustment or capture offset needs to be made, as that already happened the first time - capture_start_frame = transport_frame; - first_recordable_frame = transport_frame; // mild lie - last_recordable_frame = max_frames; - was_recording = true; - - if (recordable() && destructive()) { - for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) { - - RingBufferNPT<CaptureTransition>::rw_vector transvec; - (*chan)->capture_transition_buf->get_write_vector(&transvec); - - if (transvec.len[0] > 0) { - transvec.buf[0]->type = CaptureStart; - transvec.buf[0]->capture_val = capture_start_frame; - (*chan)->capture_transition_buf->increment_write_ptr(1); - } - else { - // bad! - fatal << X_("programming error: capture_transition_buf is full on rec loop! inconceivable!") - << endmsg; - } - } - } - - } -} - -void -AudioDiskstream::finish_capture (bool rec_monitors_input, boost::shared_ptr<ChannelList> c) -{ - was_recording = false; - - if (capture_captured == 0) { - return; - } - - if (recordable() && destructive()) { - for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) { - - RingBufferNPT<CaptureTransition>::rw_vector transvec; - (*chan)->capture_transition_buf->get_write_vector(&transvec); - - if (transvec.len[0] > 0) { - transvec.buf[0]->type = CaptureEnd; - transvec.buf[0]->capture_val = capture_captured; - (*chan)->capture_transition_buf->increment_write_ptr(1); - } - else { - // bad! - fatal << string_compose (_("programmer error: %1"), X_("capture_transition_buf is full when stopping record! inconceivable!")) << endmsg; - } - } - } - - - CaptureInfo* ci = new CaptureInfo; - - ci->start = capture_start_frame; - ci->frames = capture_captured; - - /* XXX theoretical race condition here. Need atomic exchange ? - However, the circumstances when this is called right - now (either on record-disable or transport_stopped) - mean that no actual race exists. I think ... - We now have a capture_info_lock, but it is only to be used - to synchronize in the transport_stop and the capture info - accessors, so that invalidation will not occur (both non-realtime). - */ - - // cerr << "Finish capture, add new CI, " << ci->start << '+' << ci->frames << endl; - - capture_info.push_back (ci); - capture_captured = 0; - - /* now we've finished a capture, reset first_recordable_frame for next time */ - first_recordable_frame = max_frames; -} - -void -AudioDiskstream::set_record_enabled (bool yn) -{ - if (!recordable() || !_session.record_enabling_legal() || _io->n_inputs().n_audio() == 0) { - return; - } - - /* can't rec-enable in destructive mode if transport is before start */ - - if (destructive() && yn && _session.transport_frame() < _session.current_start_frame()) { - return; - } - - if (yn && channels.reader()->front()->source == 0) { - - /* pick up connections not initiated *from* the IO object - we're associated with. - */ - - get_input_sources (); - } - - /* yes, i know that this not proof against race conditions, but its - good enough. i think. - */ - - if (record_enabled() != yn) { - if (yn) { - engage_record_enable (); - } else { - disengage_record_enable (); - } - } -} - -void -AudioDiskstream::engage_record_enable () -{ - bool rolling = _session.transport_speed() != 0.0f; - boost::shared_ptr<ChannelList> c = channels.reader(); - - g_atomic_int_set (&_record_enabled, 1); - capturing_sources.clear (); - - if (Config->get_monitoring_model() == HardwareMonitoring) { - - for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) { - if ((*chan)->source) { - (*chan)->source->ensure_monitor_input (!(Config->get_auto_input() && rolling)); - } - capturing_sources.push_back ((*chan)->write_source); - (*chan)->write_source->mark_streaming_write_started (); - } - - } else { - for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) { - capturing_sources.push_back ((*chan)->write_source); - (*chan)->write_source->mark_streaming_write_started (); - } - } - - RecordEnableChanged (); /* EMIT SIGNAL */ -} - -void -AudioDiskstream::disengage_record_enable () -{ - g_atomic_int_set (&_record_enabled, 0); - boost::shared_ptr<ChannelList> c = channels.reader(); - if (Config->get_monitoring_model() == HardwareMonitoring) { - for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) { - if ((*chan)->source) { - (*chan)->source->ensure_monitor_input (false); - } - } - } - capturing_sources.clear (); - RecordEnableChanged (); /* EMIT SIGNAL */ -} - -XMLNode& -AudioDiskstream::get_state () -{ - XMLNode* node = new XMLNode ("AudioDiskstream"); - char buf[64] = ""; - LocaleGuard lg (X_("POSIX")); - boost::shared_ptr<ChannelList> c = channels.reader(); - - node->add_property ("flags", enum_2_string (_flags)); - - snprintf (buf, sizeof(buf), "%zd", c->size()); - node->add_property ("channels", buf); - - node->add_property ("playlist", _playlist->name()); - - snprintf (buf, sizeof(buf), "%.12g", _visible_speed); - node->add_property ("speed", buf); - - node->add_property("name", _name); - id().print (buf, sizeof (buf)); - node->add_property("id", buf); - - if (!capturing_sources.empty() && _session.get_record_enabled()) { - - XMLNode* cs_child = new XMLNode (X_("CapturingSources")); - XMLNode* cs_grandchild; - - for (vector<boost::shared_ptr<AudioFileSource> >::iterator i = capturing_sources.begin(); i != capturing_sources.end(); ++i) { - cs_grandchild = new XMLNode (X_("file")); - cs_grandchild->add_property (X_("path"), (*i)->path()); - cs_child->add_child_nocopy (*cs_grandchild); - } - - /* store the location where capture will start */ - - Location* pi; - - if (Config->get_punch_in() && ((pi = _session.locations()->auto_punch_location()) != 0)) { - snprintf (buf, sizeof (buf), "%" PRIu32, pi->start()); - } else { - snprintf (buf, sizeof (buf), "%" PRIu32, _session.transport_frame()); - } - - cs_child->add_property (X_("at"), buf); - node->add_child_nocopy (*cs_child); - } - - if (_extra_xml) { - node->add_child_copy (*_extra_xml); - } - - return* node; -} - -int -AudioDiskstream::set_state (const XMLNode& node) -{ - const XMLProperty* prop; - XMLNodeList nlist = node.children(); - XMLNodeIterator niter; - uint32_t nchans = 1; - XMLNode* capture_pending_node = 0; - LocaleGuard lg (X_("POSIX")); - - in_set_state = true; - - for (niter = nlist.begin(); niter != nlist.end(); ++niter) { - if ((*niter)->name() == IO::state_node_name) { - deprecated_io_node = new XMLNode (**niter); - } - - if ((*niter)->name() == X_("CapturingSources")) { - capture_pending_node = *niter; - } - } - - /* prevent write sources from being created */ - - in_set_state = true; - - if ((prop = node.property ("name")) != 0) { - _name = prop->value(); - } - - if (deprecated_io_node) { - if ((prop = deprecated_io_node->property ("id")) != 0) { - _id = prop->value (); - } - } else { - if ((prop = node.property ("id")) != 0) { - _id = prop->value (); - } - } - - if ((prop = node.property ("flags")) != 0) { - _flags = Flag (string_2_enum (prop->value(), _flags)); - } - - if ((prop = node.property ("channels")) != 0) { - nchans = atoi (prop->value().c_str()); - } - - // create necessary extra channels - // we are always constructed with one and we always need one - - _n_channels.set(DataType::AUDIO, channels.reader()->size()); - - if (nchans > _n_channels.n_audio()) { - - add_channel (nchans - _n_channels.n_audio()); - IO::PortCountChanged(_n_channels); - - } else if (nchans < _n_channels.n_audio()) { - - remove_channel (_n_channels.n_audio() - nchans); - } - - if ((prop = node.property ("playlist")) == 0) { - return -1; - } - - { - bool had_playlist = (_playlist != 0); - - if (find_and_use_playlist (prop->value())) { - return -1; - } - - if (!had_playlist) { - _playlist->set_orig_diskstream_id (_id); - } - - if (!destructive() && capture_pending_node) { - /* destructive streams have one and only one source per channel, - and so they never end up in pending capture in any useful - sense. - */ - use_pending_capture_data (*capture_pending_node); - } - - } - - if ((prop = node.property ("speed")) != 0) { - double sp = atof (prop->value().c_str()); - - if (realtime_set_speed (sp, false)) { - non_realtime_set_speed (); - } - } - - in_set_state = false; - - /* make sure this is clear before we do anything else */ - - capturing_sources.clear (); - - /* write sources are handled when we handle the input set - up of the IO that owns this DS (::non_realtime_input_change()) - */ - - return 0; -} - -int -AudioDiskstream::use_new_write_source (uint32_t n) -{ - boost::shared_ptr<ChannelList> c = channels.reader(); - - if (!recordable()) { - return 1; - } - - if (n >= c->size()) { - error << string_compose (_("AudioDiskstream: channel %1 out of range"), n) << endmsg; - return -1; - } - - ChannelInfo* chan = (*c)[n]; - - if (chan->write_source) { - chan->write_source->done_with_peakfile_writes (); - chan->write_source->set_allow_remove_if_empty (true); - chan->write_source.reset (); - } - - try { - if ((chan->write_source = _session.create_audio_source_for_session (*this, n, destructive())) == 0) { - throw failed_constructor(); - } - } - - catch (failed_constructor &err) { - error << string_compose (_("%1:%2 new capture file not initialized correctly"), _name, n) << endmsg; - chan->write_source.reset (); - return -1; - } - - /* do not remove destructive files even if they are empty */ - - chan->write_source->set_allow_remove_if_empty (!destructive()); - - return 0; -} - -void -AudioDiskstream::reset_write_sources (bool mark_write_complete, bool force) -{ - ChannelList::iterator chan; - boost::shared_ptr<ChannelList> c = channels.reader(); - uint32_t n; - - if (!recordable()) { - return; - } - - capturing_sources.clear (); - - for (chan = c->begin(), n = 0; chan != c->end(); ++chan, ++n) { - if (!destructive()) { - - if ((*chan)->write_source && mark_write_complete) { - (*chan)->write_source->mark_streaming_write_completed (); - } - use_new_write_source (n); - - if (record_enabled()) { - capturing_sources.push_back ((*chan)->write_source); - } - - } else { - if ((*chan)->write_source == 0) { - use_new_write_source (n); - } - } - } - - if (destructive()) { - - /* we now have all our write sources set up, so create the - playlist's single region. - */ - - if (_playlist->empty()) { - setup_destructive_playlist (); - } - } -} - -int -AudioDiskstream::rename_write_sources () -{ - ChannelList::iterator chan; - boost::shared_ptr<ChannelList> c = channels.reader(); - uint32_t n; - - for (chan = c->begin(), n = 0; chan != c->end(); ++chan, ++n) { - if ((*chan)->write_source != 0) { - (*chan)->write_source->set_source_name (_name, destructive()); - /* XXX what to do if one of them fails ? */ - } - } - - return 0; -} - -void -AudioDiskstream::set_block_size (nframes_t nframes) -{ - if (_session.get_block_size() > speed_buffer_size) { - speed_buffer_size = _session.get_block_size(); - boost::shared_ptr<ChannelList> c = channels.reader(); - - for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) { - if ((*chan)->speed_buffer) delete [] (*chan)->speed_buffer; - (*chan)->speed_buffer = new Sample[speed_buffer_size]; - } - } - allocate_temporary_buffers (); -} - -void -AudioDiskstream::allocate_temporary_buffers () -{ - /* make sure the wrap buffer is at least large enough to deal - with the speeds up to 1.2, to allow for micro-variation - when slaving to MTC, SMPTE etc. - */ - - double sp = max (fabsf (_actual_speed), 1.2f); - nframes_t required_wrap_size = (nframes_t) floor (_session.get_block_size() * sp) + 1; - - if (required_wrap_size > wrap_buffer_size) { - - boost::shared_ptr<ChannelList> c = channels.reader(); - - for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) { - if ((*chan)->playback_wrap_buffer) delete [] (*chan)->playback_wrap_buffer; - (*chan)->playback_wrap_buffer = new Sample[required_wrap_size]; - if ((*chan)->capture_wrap_buffer) delete [] (*chan)->capture_wrap_buffer; - (*chan)->capture_wrap_buffer = new Sample[required_wrap_size]; - } - - wrap_buffer_size = required_wrap_size; - } -} - -void -AudioDiskstream::monitor_input (bool yn) -{ - boost::shared_ptr<ChannelList> c = channels.reader(); - - for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) { - - if ((*chan)->source) { - (*chan)->source->ensure_monitor_input (yn); - } - } -} - -void -AudioDiskstream::set_align_style_from_io () -{ - bool have_physical = false; - - if (_io == 0) { - return; - } - - get_input_sources (); - - boost::shared_ptr<ChannelList> c = channels.reader(); - - for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) { - if ((*chan)->source && (*chan)->source->flags() & JackPortIsPhysical) { - have_physical = true; - break; - } - } - - if (have_physical) { - set_align_style (ExistingMaterial); - } else { - set_align_style (CaptureTime); - } -} - -int -AudioDiskstream::add_channel_to (boost::shared_ptr<ChannelList> c, uint32_t how_many) -{ - while (how_many--) { - c->push_back (new ChannelInfo(_session.audio_diskstream_buffer_size(), speed_buffer_size, wrap_buffer_size)); - } - - _n_channels.set(DataType::AUDIO, c->size()); - - return 0; -} - -int -AudioDiskstream::add_channel (uint32_t how_many) -{ - RCUWriter<ChannelList> writer (channels); - boost::shared_ptr<ChannelList> c = writer.get_copy(); - - return add_channel_to (c, how_many); -} - -int -AudioDiskstream::remove_channel_from (boost::shared_ptr<ChannelList> c, uint32_t how_many) -{ - while (how_many-- && !c->empty()) { - delete c->back(); - c->pop_back(); - } - - _n_channels.set(DataType::AUDIO, c->size()); - - return 0; -} - -int -AudioDiskstream::remove_channel (uint32_t how_many) -{ - RCUWriter<ChannelList> writer (channels); - boost::shared_ptr<ChannelList> c = writer.get_copy(); - - return remove_channel_from (c, how_many); -} - -float -AudioDiskstream::playback_buffer_load () const -{ - boost::shared_ptr<ChannelList> c = channels.reader(); - - return (float) ((double) c->front()->playback_buf->read_space()/ - (double) c->front()->playback_buf->bufsize()); -} - -float -AudioDiskstream::capture_buffer_load () const -{ - boost::shared_ptr<ChannelList> c = channels.reader(); - - return (float) ((double) c->front()->capture_buf->write_space()/ - (double) c->front()->capture_buf->bufsize()); -} - -int -AudioDiskstream::use_pending_capture_data (XMLNode& node) -{ - const XMLProperty* prop; - XMLNodeList nlist = node.children(); - XMLNodeIterator niter; - boost::shared_ptr<AudioFileSource> fs; - boost::shared_ptr<AudioFileSource> first_fs; - SourceList pending_sources; - nframes_t position; - - if ((prop = node.property (X_("at"))) == 0) { - return -1; - } - - if (sscanf (prop->value().c_str(), "%" PRIu32, &position) != 1) { - return -1; - } - - for (niter = nlist.begin(); niter != nlist.end(); ++niter) { - if ((*niter)->name() == X_("file")) { - - if ((prop = (*niter)->property (X_("path"))) == 0) { - continue; - } - - // This protects sessions from errant CapturingSources in stored sessions - struct stat sbuf; - if (stat (prop->value().c_str(), &sbuf)) { - continue; - } - - try { - fs = boost::dynamic_pointer_cast<AudioFileSource> ( - SourceFactory::createWritable (DataType::AUDIO, _session, prop->value(), false, _session.frame_rate())); - } - - catch (failed_constructor& err) { - error << string_compose (_("%1: cannot restore pending capture source file %2"), - _name, prop->value()) - << endmsg; - return -1; - } - - pending_sources.push_back (fs); - - if (first_fs == 0) { - first_fs = fs; - } - - fs->set_captured_for (_name); - } - } - - if (pending_sources.size() == 0) { - /* nothing can be done */ - return 1; - } - - if (pending_sources.size() != _n_channels.n_audio()) { - error << string_compose (_("%1: incorrect number of pending sources listed - ignoring them all"), _name) - << endmsg; - return -1; - } - - boost::shared_ptr<AudioRegion> region; - - try { - region = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (pending_sources, 0, first_fs->length(), - region_name_from_path (first_fs->name(), true), - 0, AudioRegion::Flag (AudioRegion::DefaultFlags|AudioRegion::Automatic|AudioRegion::WholeFile))); - region->special_set_position (0); - } - - catch (failed_constructor& err) { - error << string_compose (_("%1: cannot create whole-file region from pending capture sources"), - _name) - << endmsg; - - return -1; - } - - try { - region = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (pending_sources, 0, first_fs->length(), region_name_from_path (first_fs->name(), true))); - } - - catch (failed_constructor& err) { - error << string_compose (_("%1: cannot create region from pending capture sources"), - _name) - << endmsg; - - return -1; - } - - _playlist->add_region (region, position); - - return 0; -} - -int -AudioDiskstream::set_destructive (bool yn) -{ - bool bounce_ignored; - - if (yn != destructive()) { - - if (yn) { - /* requestor should already have checked this and - bounced if necessary and desired - */ - if (!can_become_destructive (bounce_ignored)) { - return -1; - } - _flags = Flag (_flags | Destructive); - use_destructive_playlist (); - } else { - _flags = Flag (_flags & ~Destructive); - reset_write_sources (true, true); - } - } - - return 0; -} - -bool -AudioDiskstream::can_become_destructive (bool& requires_bounce) const -{ - if (!_playlist) { - requires_bounce = false; - return false; - } - - /* is there only one region ? */ - - if (_playlist->n_regions() != 1) { - requires_bounce = true; - return false; - } - - boost::shared_ptr<Region> first = _playlist->find_next_region (_session.current_start_frame(), Start, 1); - assert (first); - - /* do the source(s) for the region cover the session start position ? */ - - if (first->position() != _session.current_start_frame()) { - if (first->start() > _session.current_start_frame()) { - requires_bounce = true; - return false; - } - } - - /* is the source used by only 1 playlist ? */ - - boost::shared_ptr<AudioRegion> afirst = boost::dynamic_pointer_cast<AudioRegion> (first); - - assert (afirst); - - if (afirst->source()->used() > 1) { - requires_bounce = true; - return false; - } - - requires_bounce = false; - return true; -} - -AudioDiskstream::ChannelInfo::ChannelInfo (nframes_t bufsize, nframes_t speed_size, nframes_t wrap_size) -{ - peak_power = 0.0f; - source = 0; - current_capture_buffer = 0; - current_playback_buffer = 0; - curr_capture_cnt = 0; - - speed_buffer = new Sample[speed_size]; - playback_wrap_buffer = new Sample[wrap_size]; - capture_wrap_buffer = new Sample[wrap_size]; - - playback_buf = new RingBufferNPT<Sample> (bufsize); - capture_buf = new RingBufferNPT<Sample> (bufsize); - capture_transition_buf = new RingBufferNPT<CaptureTransition> (256); - - /* touch the ringbuffer buffers, which will cause - them to be mapped into locked physical RAM if - we're running with mlockall(). this doesn't do - much if we're not. - */ - - memset (playback_buf->buffer(), 0, sizeof (Sample) * playback_buf->bufsize()); - memset (capture_buf->buffer(), 0, sizeof (Sample) * capture_buf->bufsize()); - memset (capture_transition_buf->buffer(), 0, sizeof (CaptureTransition) * capture_transition_buf->bufsize()); -} - -AudioDiskstream::ChannelInfo::~ChannelInfo () -{ - if (write_source) { - write_source.reset (); - } - - if (speed_buffer) { - delete [] speed_buffer; - speed_buffer = 0; - } - - if (playback_wrap_buffer) { - delete [] playback_wrap_buffer; - playback_wrap_buffer = 0; - } - - if (capture_wrap_buffer) { - delete [] capture_wrap_buffer; - capture_wrap_buffer = 0; - } - - if (playback_buf) { - delete playback_buf; - playback_buf = 0; - } - - if (capture_buf) { - delete capture_buf; - capture_buf = 0; - } - - if (capture_transition_buf) { - delete capture_transition_buf; - capture_transition_buf = 0; - } -} diff --git a/libs/ardour/audio_library.cc b/libs/ardour/audio_library.cc deleted file mode 100644 index a35846ab29..0000000000 --- a/libs/ardour/audio_library.cc +++ /dev/null @@ -1,154 +0,0 @@ -/* - 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. - -*/ - -#include <sstream> - -#include <libxml/uri.h> - -#include <lrdf.h> - -#include <glibmm/convert.h> - -#include <pbd/compose.h> - -#include <ardour/audio_library.h> -#include <ardour/utils.h> -#include <ardour/filesystem_paths.h> - -#include "i18n.h" - -using namespace std; -using namespace ARDOUR; - -namespace { - const char* const sfdb_file_name = "sfdb"; -} // anonymous namespace - -static const char* TAG = "http://ardour.org/ontology/Tag"; - -AudioLibrary::AudioLibrary () -{ - sys::path sfdb_file_path(user_config_directory ()); - - sfdb_file_path /= sfdb_file_name; - - src = Glib::filename_to_uri (sfdb_file_path.to_string ()); - - // workaround for possible bug in raptor that crashes when saving to a - // non-existant file. - touch_file(sfdb_file_path.to_string()); - - lrdf_read_file(src.c_str()); -} - -AudioLibrary::~AudioLibrary () -{ -} - -void -AudioLibrary::save_changes () -{ - if (lrdf_export_by_source(src.c_str(), src.substr(5).c_str())) { - PBD::warning << string_compose(_("Could not open %1. Audio Library not saved"), src) << endmsg; - } -} - -void -AudioLibrary::set_tags (string member, vector<string> tags) -{ - sort (tags.begin(), tags.end()); - tags.erase (unique(tags.begin(), tags.end()), tags.end()); - - const string file_uri(Glib::filename_to_uri (member)); - - lrdf_remove_uri_matches (file_uri.c_str()); - - for (vector<string>::iterator i = tags.begin(); i != tags.end(); ++i) { - lrdf_add_triple (src.c_str(), file_uri.c_str(), TAG, (*i).c_str(), lrdf_literal); - } -} - -vector<string> -AudioLibrary::get_tags (string member) -{ - vector<string> tags; - - lrdf_statement pattern; - pattern.subject = strdup(Glib::filename_to_uri(member).c_str()); - pattern.predicate = (char*)TAG; - pattern.object = 0; - pattern.object_type = lrdf_literal; - - lrdf_statement* matches = lrdf_matches (&pattern); - free (pattern.subject); - - lrdf_statement* current = matches; - while (current != 0) { - tags.push_back (current->object); - - current = current->next; - } - - lrdf_free_statements (matches); - - sort (tags.begin(), tags.end()); - - return tags; -} - -void -AudioLibrary::search_members_and (vector<string>& members, const vector<string> tags) -{ - lrdf_statement **head; - lrdf_statement* pattern = 0; - lrdf_statement* old = 0; - head = &pattern; - - vector<string>::const_iterator i; - for (i = tags.begin(); i != tags.end(); ++i){ - pattern = new lrdf_statement; - pattern->subject = (char*)"?"; - pattern->predicate = (char*)TAG; - pattern->object = strdup((*i).c_str()); - pattern->next = old; - - old = pattern; - } - - if (*head != 0) { - lrdf_uris* ulist = lrdf_match_multi(*head); - for (uint32_t j = 0; ulist && j < ulist->count; ++j) { -// cerr << "AND: " << Glib::filename_from_uri(ulist->items[j]) << endl; - members.push_back(Glib::filename_from_uri(ulist->items[j])); - } - lrdf_free_uris(ulist); - - sort(members.begin(), members.end()); - unique(members.begin(), members.end()); - } - - // memory clean up - pattern = *head; - while(pattern){ - free(pattern->object); - old = pattern; - pattern = pattern->next; - delete old; - } -} diff --git a/libs/ardour/audio_playlist.cc b/libs/ardour/audio_playlist.cc deleted file mode 100644 index 1506d204f1..0000000000 --- a/libs/ardour/audio_playlist.cc +++ /dev/null @@ -1,788 +0,0 @@ -/* - 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. - -*/ - -#include <algorithm> - -#include <cstdlib> - -#include <sigc++/bind.h> - -#include <ardour/types.h> -#include <ardour/configuration.h> -#include <ardour/audioplaylist.h> -#include <ardour/audioregion.h> -#include <ardour/crossfade.h> -#include <ardour/crossfade_compare.h> -#include <ardour/session.h> -#include <pbd/enumwriter.h> - -#include "i18n.h" - -using namespace ARDOUR; -using namespace sigc; -using namespace std; -using namespace PBD; - -AudioPlaylist::AudioPlaylist (Session& session, const XMLNode& node, bool hidden) - : Playlist (session, node, DataType::AUDIO, hidden) -{ - const XMLProperty* prop = node.property("type"); - assert(!prop || DataType(prop->value()) == DataType::AUDIO); - - in_set_state++; - set_state (node); - in_set_state--; -} - -AudioPlaylist::AudioPlaylist (Session& session, string name, bool hidden) - : Playlist (session, name, DataType::AUDIO, hidden) -{ -} - -AudioPlaylist::AudioPlaylist (boost::shared_ptr<const AudioPlaylist> other, string name, bool hidden) - : Playlist (other, name, hidden) -{ - RegionList::const_iterator in_o = other->regions.begin(); - RegionList::iterator in_n = regions.begin(); - - while (in_o != other->regions.end()) { - boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion>(*in_o); - - // We look only for crossfades which begin with the current region, so we don't get doubles - for (Crossfades::const_iterator xfades = other->_crossfades.begin(); xfades != other->_crossfades.end(); ++xfades) { - if ((*xfades)->in() == ar) { - // We found one! Now copy it! - - RegionList::const_iterator out_o = other->regions.begin(); - RegionList::const_iterator out_n = regions.begin(); - - while (out_o != other->regions.end()) { - - boost::shared_ptr<AudioRegion>ar2 = boost::dynamic_pointer_cast<AudioRegion>(*out_o); - - if ((*xfades)->out() == ar2) { - boost::shared_ptr<AudioRegion>in = boost::dynamic_pointer_cast<AudioRegion>(*in_n); - boost::shared_ptr<AudioRegion>out = boost::dynamic_pointer_cast<AudioRegion>(*out_n); - boost::shared_ptr<Crossfade> new_fade = boost::shared_ptr<Crossfade> (new Crossfade (*xfades, in, out)); - add_crossfade(new_fade); - break; - } - - out_o++; - out_n++; - } -// cerr << "HUH!? second region in the crossfade not found!" << endl; - } - } - - in_o++; - in_n++; - } -} - -AudioPlaylist::AudioPlaylist (boost::shared_ptr<const AudioPlaylist> other, nframes_t start, nframes_t cnt, string name, bool hidden) - : Playlist (other, start, cnt, name, hidden) -{ - /* this constructor does NOT notify others (session) */ -} - -AudioPlaylist::~AudioPlaylist () -{ - GoingAway (); /* EMIT SIGNAL */ - - /* drop connections to signals */ - - notify_callbacks (); - - _crossfades.clear (); -} - -struct RegionSortByLayer { - bool operator() (boost::shared_ptr<Region> a, boost::shared_ptr<Region> b) { - return a->layer() < b->layer(); - } -}; - -ARDOUR::nframes_t -AudioPlaylist::read (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, nframes_t start, - nframes_t cnt, unsigned chan_n) -{ - nframes_t ret = cnt; - nframes_t end; - nframes_t read_frames; - nframes_t skip_frames; - - /* optimizing this memset() away involves a lot of conditionals - that may well cause more of a hit due to cache misses - and related stuff than just doing this here. - - it would be great if someone could measure this - at some point. - - one way or another, parts of the requested area - that are not written to by Region::region_at() - for all Regions that cover the area need to be - zeroed. - */ - - memset (buf, 0, sizeof (Sample) * cnt); - - /* this function is never called from a realtime thread, so - its OK to block (for short intervals). - */ - - Glib::Mutex::Lock rm (region_lock); - - end = start + cnt - 1; - read_frames = 0; - skip_frames = 0; - _read_data_count = 0; - - _read_data_count = 0; - - RegionList* rlist = regions_to_read (start, start+cnt); - - if (rlist->empty()) { - delete rlist; - return cnt; - } - - map<uint32_t,vector<boost::shared_ptr<Region> > > relevant_regions; - map<uint32_t,vector<boost::shared_ptr<Crossfade> > > relevant_xfades; - vector<uint32_t> relevant_layers; - - for (RegionList::iterator i = rlist->begin(); i != rlist->end(); ++i) { - if ((*i)->coverage (start, end) != OverlapNone) { - relevant_regions[(*i)->layer()].push_back (*i); - relevant_layers.push_back ((*i)->layer()); - } - } - - for (Crossfades::iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) { - if ((*i)->coverage (start, end) != OverlapNone) { - relevant_xfades[(*i)->upper_layer()].push_back (*i); - } - } - -// RegionSortByLayer layer_cmp; -// relevant_regions.sort (layer_cmp); - - /* XXX this whole per-layer approach is a hack that - should be removed once Crossfades become - CrossfadeRegions and we just grab a list of relevant - regions and call read_at() on all of them. - */ - - sort (relevant_layers.begin(), relevant_layers.end()); - - for (vector<uint32_t>::iterator l = relevant_layers.begin(); l != relevant_layers.end(); ++l) { - - vector<boost::shared_ptr<Region> > r (relevant_regions[*l]); - vector<boost::shared_ptr<Crossfade> >& x (relevant_xfades[*l]); - - for (vector<boost::shared_ptr<Region> >::iterator i = r.begin(); i != r.end(); ++i) { - boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion>(*i); - assert(ar); - ar->read_at (buf, mixdown_buffer, gain_buffer, start, cnt, chan_n, read_frames, skip_frames); - _read_data_count += ar->read_data_count(); - } - - for (vector<boost::shared_ptr<Crossfade> >::iterator i = x.begin(); i != x.end(); ++i) { - (*i)->read_at (buf, mixdown_buffer, gain_buffer, start, cnt, chan_n); - - /* don't JACK up _read_data_count, since its the same data as we just - read from the regions, and the OS should handle that for us. - */ - } - } - - delete rlist; - return ret; -} - - -void -AudioPlaylist::remove_dependents (boost::shared_ptr<Region> region) -{ - boost::shared_ptr<AudioRegion> r = boost::dynamic_pointer_cast<AudioRegion> (region); - - if (in_set_state) { - return; - } - - if (r == 0) { - fatal << _("programming error: non-audio Region passed to remove_overlap in audio playlist") - << endmsg; - return; - } - - for (Crossfades::iterator i = _crossfades.begin(); i != _crossfades.end(); ) { - - if ((*i)->involves (r)) { - i = _crossfades.erase (i); - } else { - ++i; - } - } -} - - -void -AudioPlaylist::flush_notifications () -{ - Playlist::flush_notifications(); - - if (in_flush) { - return; - } - - in_flush = true; - - Crossfades::iterator a; - for (a = _pending_xfade_adds.begin(); a != _pending_xfade_adds.end(); ++a) { - NewCrossfade (*a); /* EMIT SIGNAL */ - } - - _pending_xfade_adds.clear (); - - in_flush = false; -} - -void -AudioPlaylist::refresh_dependents (boost::shared_ptr<Region> r) -{ - boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion>(r); - set<boost::shared_ptr<Crossfade> > updated; - - if (ar == 0) { - return; - } - - for (Crossfades::iterator x = _crossfades.begin(); x != _crossfades.end();) { - - Crossfades::iterator tmp; - - tmp = x; - ++tmp; - - /* only update them once */ - - if ((*x)->involves (ar)) { - - pair<set<boost::shared_ptr<Crossfade> >::iterator, bool> const u = updated.insert (*x); - - if (u.second) { - /* x was successfully inserted into the set, so it has not already been updated */ - try { - (*x)->refresh (); - } - - catch (Crossfade::NoCrossfadeHere& err) { - // relax, Invalidated during refresh - } - } - } - - x = tmp; - } -} - -void -AudioPlaylist::finalize_split_region (boost::shared_ptr<Region> o, boost::shared_ptr<Region> l, boost::shared_ptr<Region> r) -{ - boost::shared_ptr<AudioRegion> orig = boost::dynamic_pointer_cast<AudioRegion>(o); - boost::shared_ptr<AudioRegion> left = boost::dynamic_pointer_cast<AudioRegion>(l); - boost::shared_ptr<AudioRegion> right = boost::dynamic_pointer_cast<AudioRegion>(r); - - for (Crossfades::iterator x = _crossfades.begin(); x != _crossfades.end();) { - Crossfades::iterator tmp; - tmp = x; - ++tmp; - - boost::shared_ptr<Crossfade> fade; - - if ((*x)->_in == orig) { - if (! (*x)->covers(right->position())) { - fade = boost::shared_ptr<Crossfade> (new Crossfade (*x, left, (*x)->_out)); - } else { - // Overlap, the crossfade is copied on the left side of the right region instead - fade = boost::shared_ptr<Crossfade> (new Crossfade (*x, right, (*x)->_out)); - } - } - - if ((*x)->_out == orig) { - if (! (*x)->covers(right->position())) { - fade = boost::shared_ptr<Crossfade> (new Crossfade (*x, (*x)->_in, right)); - } else { - // Overlap, the crossfade is copied on the right side of the left region instead - fade = boost::shared_ptr<Crossfade> (new Crossfade (*x, (*x)->_in, left)); - } - } - - if (fade) { - _crossfades.remove (*x); - add_crossfade (fade); - } - x = tmp; - } -} - -void -AudioPlaylist::check_dependents (boost::shared_ptr<Region> r, bool norefresh) -{ - boost::shared_ptr<AudioRegion> other; - boost::shared_ptr<AudioRegion> region; - boost::shared_ptr<AudioRegion> top; - boost::shared_ptr<AudioRegion> bottom; - boost::shared_ptr<Crossfade> xfade; - RegionList* touched_regions; - - if (in_set_state || in_partition) { - return; - } - - if ((region = boost::dynamic_pointer_cast<AudioRegion> (r)) == 0) { - fatal << _("programming error: non-audio Region tested for overlap in audio playlist") - << endmsg; - return; - } - - if (!norefresh) { - refresh_dependents (r); - } - - - if (!Config->get_auto_xfade()) { - return; - } - - for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { - - nframes_t xfade_length; - - other = boost::dynamic_pointer_cast<AudioRegion> (*i); - - if (other == region) { - continue; - } - - if (other->muted() || region->muted()) { - continue; - } - - - if (other->layer() < region->layer()) { - top = region; - bottom = other; - } else { - top = other; - bottom = region; - } - - if (!top->opaque()) { - continue; - } - - OverlapType c = top->coverage (bottom->position(), bottom->last_frame()); - - try { - switch (c) { - case OverlapNone: - break; - - case OverlapInternal: - /* {=============== top =============} - * [ ----- bottom ------- ] - */ - break; - - case OverlapExternal: - - /* [ -------- top ------- ] - * {=========== bottom =============} - */ - - /* to avoid discontinuities at the region boundaries of an internal - overlap (this region is completely within another), we create - two hidden crossfades at each boundary. this is not dependent - on the auto-xfade option, because we require it as basic - audio engineering. - */ - - xfade_length = min ((nframes_t) 720, top->length()); - - if (top_region_at (top->first_frame()) == top) { - - xfade = boost::shared_ptr<Crossfade> (new Crossfade (top, bottom, xfade_length, top->first_frame(), StartOfIn)); - add_crossfade (xfade); - } - - if (top_region_at (top->last_frame() - 1) == top) { - - /* - only add a fade out if there is no region on top of the end of 'top' (which - would cover it). - */ - - xfade = boost::shared_ptr<Crossfade> (new Crossfade (bottom, top, xfade_length, top->last_frame() - xfade_length, EndOfOut)); - add_crossfade (xfade); - } - break; - case OverlapStart: - - /* { ==== top ============ } - * [---- bottom -------------------] - */ - - if (Config->get_xfade_model() == FullCrossfade) { - touched_regions = regions_touched (top->first_frame(), bottom->last_frame()); - if (touched_regions->size() <= 2) { - xfade = boost::shared_ptr<Crossfade> (new Crossfade (region, other, Config->get_xfade_model(), Config->get_xfades_active())); - add_crossfade (xfade); - } - } else { - - touched_regions = regions_touched (top->first_frame(), - top->first_frame() + min ((nframes_t)Config->get_short_xfade_seconds() * _session.frame_rate(), - top->length())); - if (touched_regions->size() <= 2) { - xfade = boost::shared_ptr<Crossfade> (new Crossfade (region, other, Config->get_xfade_model(), Config->get_xfades_active())); - add_crossfade (xfade); - } - } - break; - case OverlapEnd: - - - /* [---- top ------------------------] - * { ==== bottom ============ } - */ - - if (Config->get_xfade_model() == FullCrossfade) { - - touched_regions = regions_touched (bottom->first_frame(), top->last_frame()); - if (touched_regions->size() <= 2) { - xfade = boost::shared_ptr<Crossfade> (new Crossfade (region, other, - Config->get_xfade_model(), Config->get_xfades_active())); - add_crossfade (xfade); - } - - } else { - touched_regions = regions_touched (bottom->first_frame(), - bottom->first_frame() + min ((nframes_t)Config->get_short_xfade_seconds() * _session.frame_rate(), - bottom->length())); - if (touched_regions->size() <= 2) { - xfade = boost::shared_ptr<Crossfade> (new Crossfade (region, other, Config->get_xfade_model(), Config->get_xfades_active())); - add_crossfade (xfade); - } - } - break; - default: - xfade = boost::shared_ptr<Crossfade> (new Crossfade (region, other, - Config->get_xfade_model(), Config->get_xfades_active())); - add_crossfade (xfade); - } - } - - catch (failed_constructor& err) { - continue; - } - - catch (Crossfade::NoCrossfadeHere& err) { - continue; - } - - } -} - -void -AudioPlaylist::add_crossfade (boost::shared_ptr<Crossfade> xfade) -{ - Crossfades::iterator ci; - - for (ci = _crossfades.begin(); ci != _crossfades.end(); ++ci) { - if (*(*ci) == *xfade) { // Crossfade::operator==() - break; - } - } - - if (ci != _crossfades.end()) { - // it will just go away - } else { - _crossfades.push_back (xfade); - - xfade->Invalidated.connect (mem_fun (*this, &AudioPlaylist::crossfade_invalidated)); - xfade->StateChanged.connect (mem_fun (*this, &AudioPlaylist::crossfade_changed)); - - notify_crossfade_added (xfade); - } -} - -void AudioPlaylist::notify_crossfade_added (boost::shared_ptr<Crossfade> x) -{ - if (g_atomic_int_get(&block_notifications)) { - _pending_xfade_adds.insert (_pending_xfade_adds.end(), x); - } else { - - NewCrossfade (x); /* EMIT SIGNAL */ - } -} - -void -AudioPlaylist::crossfade_invalidated (boost::shared_ptr<Region> r) -{ - Crossfades::iterator i; - boost::shared_ptr<Crossfade> xfade = boost::dynamic_pointer_cast<Crossfade> (r); - - xfade->in()->resume_fade_in (); - xfade->out()->resume_fade_out (); - - if ((i = find (_crossfades.begin(), _crossfades.end(), xfade)) != _crossfades.end()) { - _crossfades.erase (i); - } -} - -int -AudioPlaylist::set_state (const XMLNode& node) -{ - XMLNode *child; - XMLNodeList nlist; - XMLNodeConstIterator niter; - - in_set_state++; - freeze (); - - Playlist::set_state (node); - - nlist = node.children(); - - for (niter = nlist.begin(); niter != nlist.end(); ++niter) { - - child = *niter; - - if (child->name() != "Crossfade") { - continue; - } - - try { - boost::shared_ptr<Crossfade> xfade = boost::shared_ptr<Crossfade> (new Crossfade (*((const Playlist *)this), *child)); - _crossfades.push_back (xfade); - xfade->Invalidated.connect (mem_fun (*this, &AudioPlaylist::crossfade_invalidated)); - xfade->StateChanged.connect (mem_fun (*this, &AudioPlaylist::crossfade_changed)); - NewCrossfade(xfade); - } - - catch (failed_constructor& err) { - // cout << string_compose (_("could not create crossfade object in playlist %1"), - // _name) - // << endl; - continue; - } - } - - thaw (); - in_set_state--; - - return 0; -} - -void -AudioPlaylist::clear (bool with_signals) -{ - _crossfades.clear (); - Playlist::clear (with_signals); -} - -XMLNode& -AudioPlaylist::state (bool full_state) -{ - XMLNode& node = Playlist::state (full_state); - - if (full_state) { - for (Crossfades::iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) { - node.add_child_nocopy ((*i)->get_state()); - } - } - - return node; -} - -void -AudioPlaylist::dump () const -{ - boost::shared_ptr<Region>r; - boost::shared_ptr<Crossfade> x; - - cerr << "Playlist \"" << _name << "\" " << endl - << regions.size() << " regions " - << _crossfades.size() << " crossfades" - << endl; - - for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) { - r = *i; - cerr << " " << r->name() << " @ " << r << " [" - << r->start() << "+" << r->length() - << "] at " - << r->position() - << " on layer " - << r->layer () - << endl; - } - - for (Crossfades::const_iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) { - x = *i; - cerr << " xfade [" - << x->out()->name() - << ',' - << x->in()->name() - << " @ " - << x->position() - << " length = " - << x->length () - << " active ? " - << (x->active() ? "yes" : "no") - << endl; - } -} - -bool -AudioPlaylist::destroy_region (boost::shared_ptr<Region> region) -{ - boost::shared_ptr<AudioRegion> r = boost::dynamic_pointer_cast<AudioRegion> (region); - bool changed = false; - Crossfades::iterator c, ctmp; - set<boost::shared_ptr<Crossfade> > unique_xfades; - - if (r == 0) { - fatal << _("programming error: non-audio Region passed to remove_overlap in audio playlist") - << endmsg; - /*NOTREACHED*/ - return false; - } - - { - RegionLock rlock (this); - - for (RegionList::iterator i = regions.begin(); i != regions.end(); ) { - - RegionList::iterator tmp = i; - ++tmp; - - if ((*i) == region) { - regions.erase (i); - changed = true; - } - - i = tmp; - } - - for (set<boost::shared_ptr<Region> >::iterator x = all_regions.begin(); x != all_regions.end(); ) { - - set<boost::shared_ptr<Region> >::iterator xtmp = x; - ++xtmp; - - if ((*x) == region) { - all_regions.erase (x); - changed = true; - } - - x = xtmp; - } - - region->set_playlist (boost::shared_ptr<Playlist>()); - } - - for (c = _crossfades.begin(); c != _crossfades.end(); ) { - ctmp = c; - ++ctmp; - - if ((*c)->involves (r)) { - unique_xfades.insert (*c); - _crossfades.erase (c); - } - - c = ctmp; - } - - if (changed) { - /* overload this, it normally means "removed", not destroyed */ - notify_region_removed (region); - } - - return changed; -} - -void -AudioPlaylist::crossfade_changed (Change ignored) -{ - if (in_flush || in_set_state) { - return; - } - - /* XXX is there a loop here? can an xfade change not happen - due to a playlist change? well, sure activation would - be an example. maybe we should check the type of change - that occured. - */ - - notify_modified (); -} - -bool -AudioPlaylist::region_changed (Change what_changed, boost::shared_ptr<Region> region) -{ - if (in_flush || in_set_state) { - return false; - } - - Change our_interests = Change (AudioRegion::FadeInChanged| - AudioRegion::FadeOutChanged| - AudioRegion::FadeInActiveChanged| - AudioRegion::FadeOutActiveChanged| - AudioRegion::EnvelopeActiveChanged| - AudioRegion::ScaleAmplitudeChanged| - AudioRegion::EnvelopeChanged); - bool parent_wants_notify; - - parent_wants_notify = Playlist::region_changed (what_changed, region); - - if ((parent_wants_notify || (what_changed & our_interests))) { - notify_modified (); - } - - return true; -} - -void -AudioPlaylist::crossfades_at (nframes_t frame, Crossfades& clist) -{ - RegionLock rlock (this); - - for (Crossfades::iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) { - nframes_t start, end; - - start = (*i)->position(); - end = start + (*i)->overlap_length(); // not length(), important difference - - if (frame >= start && frame <= end) { - clist.push_back (*i); - } - } -} - diff --git a/libs/ardour/audio_port.cc b/libs/ardour/audio_port.cc deleted file mode 100644 index 714be28f34..0000000000 --- a/libs/ardour/audio_port.cc +++ /dev/null @@ -1,126 +0,0 @@ -/* - 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. -*/ - -#include <cassert> -#include <ardour/audio_port.h> -#include <ardour/jack_audio_port.h> -#include <ardour/audioengine.h> -#include <ardour/data_type.h> - -using namespace ARDOUR; -using namespace std; - -AudioPort::AudioPort (const std::string& name, Flags flags, bool external, nframes_t capacity) - : Port (name, flags) - , BaseAudioPort (name, flags) - , PortFacade (name, flags) -{ - if (!external || receives_input()) { - - /* internal-only and input ports need their own buffers. - external output ports use the external port buffer. - */ - - _buffer = new AudioBuffer (capacity); - _own_buffer = true; - } - - if (!external) { - - _ext_port = 0; - set_name (name); - - } else { - - /* make the JackAudioPort create its own buffer. For input, - we will copy from it during cycle_start(). For output, - we will set up our buffer to point to its buffer, which - will in turn be using the JACK port buffer for data. - */ - - _ext_port = new JackAudioPort (name, flags, 0); - - if (sends_output()) { - _buffer = &dynamic_cast<JackAudioPort*>(_ext_port)->get_audio_buffer(); - } - - Port::set_name (_ext_port->name()); - } - - reset (); -} - -AudioPort::~AudioPort() -{ - if (_ext_port) { - delete _ext_port; - _ext_port = 0; - } -} - -void -AudioPort::reset() -{ - BaseAudioPort::reset(); - - if (_ext_port) { - _ext_port->reset (); - } -} - - -void -AudioPort::cycle_start (nframes_t nframes, nframes_t offset) -{ - /* caller must hold process lock */ - - if (_ext_port) { - _ext_port->cycle_start (nframes, offset); - } - - if (_flags & IsInput) { - - if (_ext_port) { - _buffer->read_from (dynamic_cast<BaseAudioPort*>(_ext_port)->get_audio_buffer(), nframes, offset); - - if (!_connections.empty()) { - (*_mixdown) (_connections, _buffer, nframes, offset, false); - } - - } else { - - if (_connections.empty()) { - _buffer->silence (nframes, offset); - } else { - (*_mixdown) (_connections, _buffer, nframes, offset, true); - } - } - - } else { - - // XXX if we could get the output stage to not purely mix into, but also - // to initially overwrite the buffer, we could avoid this silence step. - - _buffer->silence (nframes, offset); - } -} - -void -AudioPort::cycle_end (nframes_t nframes, nframes_t offset) -{ -} diff --git a/libs/ardour/audio_track.cc b/libs/ardour/audio_track.cc deleted file mode 100644 index 53f918ec4e..0000000000 --- a/libs/ardour/audio_track.cc +++ /dev/null @@ -1,884 +0,0 @@ -/* - 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. - -*/ - -#include <sigc++/retype.h> -#include <sigc++/retype_return.h> -#include <sigc++/bind.h> - -#include <pbd/error.h> -#include <pbd/enumwriter.h> - -#include <ardour/audio_track.h> -#include <ardour/audio_diskstream.h> -#include <ardour/session.h> -#include <ardour/io_processor.h> -#include <ardour/audioregion.h> -#include <ardour/audiosource.h> -#include <ardour/region_factory.h> -#include <ardour/route_group_specialized.h> -#include <ardour/processor.h> -#include <ardour/plugin_insert.h> -#include <ardour/audioplaylist.h> -#include <ardour/playlist_factory.h> -#include <ardour/panner.h> -#include <ardour/utils.h> -#include <ardour/buffer_set.h> -#include "i18n.h" - -using namespace std; -using namespace ARDOUR; -using namespace PBD; - -AudioTrack::AudioTrack (Session& sess, string name, Route::Flag flag, TrackMode mode) - : Track (sess, name, flag, mode) -{ - AudioDiskstream::Flag dflags = AudioDiskstream::Flag (0); - - if (_flags & Hidden) { - dflags = AudioDiskstream::Flag (dflags | AudioDiskstream::Hidden); - } else { - dflags = AudioDiskstream::Flag (dflags | AudioDiskstream::Recordable); - } - - if (mode == Destructive) { - dflags = AudioDiskstream::Flag (dflags | AudioDiskstream::Destructive); - } - - boost::shared_ptr<AudioDiskstream> ds (new AudioDiskstream (_session, name, dflags)); - - _session.add_diskstream (ds); - - set_diskstream (boost::dynamic_pointer_cast<AudioDiskstream> (ds), this); -} - -AudioTrack::AudioTrack (Session& sess, const XMLNode& node) - : Track (sess, node) -{ - _set_state (node, false); -} - -AudioTrack::~AudioTrack () -{ -} - -int -AudioTrack::set_mode (TrackMode m) -{ - if (m != _mode) { - - if (_diskstream->set_destructive (m == Destructive)) { - return -1; - } - - _mode = m; - - TrackModeChanged (); /* EMIT SIGNAL */ - } - - return 0; -} - -bool -AudioTrack::can_use_mode (TrackMode m, bool& bounce_required) -{ - switch (m) { - case Normal: - bounce_required = false; - return true; - - case Destructive: - default: - return _diskstream->can_become_destructive (bounce_required); - } -} - -int -AudioTrack::deprecated_use_diskstream_connections () -{ - boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream(); - - if (diskstream->deprecated_io_node == 0) { - return 0; - } - - const XMLProperty* prop; - XMLNode& node (*diskstream->deprecated_io_node); - - /* don't do this more than once. */ - - diskstream->deprecated_io_node = 0; - - set_input_minimum (ChanCount::ZERO); - set_input_maximum (ChanCount::INFINITE); - set_output_minimum (ChanCount::ZERO); - set_output_maximum (ChanCount::INFINITE); - - if ((prop = node.property ("gain")) != 0) { - set_gain (atof (prop->value().c_str()), this); - _gain = _desired_gain; - } - - if ((prop = node.property ("input-connection")) != 0) { - boost::shared_ptr<Bundle> c = _session.bundle_by_name (prop->value()); - - if (c == 0) { - error << string_compose(_("Unknown bundle \"%1\" listed for input of %2"), prop->value(), _name) << endmsg; - - if ((c = _session.bundle_by_name (_("in 1"))) == 0) { - error << _("No input bundles available as a replacement") - << endmsg; - return -1; - } else { - info << string_compose (_("Bundle %1 was not available - \"in 1\" used instead"), prop->value()) - << endmsg; - } - } - - connect_input_ports_to_bundle (c, this); - - } else if ((prop = node.property ("inputs")) != 0) { - if (set_inputs (prop->value())) { - error << string_compose(_("improper input channel list in XML node (%1)"), prop->value()) << endmsg; - return -1; - } - } - - return 0; -} - -int -AudioTrack::set_diskstream (boost::shared_ptr<AudioDiskstream> ds, void *src) -{ - _diskstream = ds; - _diskstream->set_io (*this); - _diskstream->set_destructive (_mode == Destructive); - - if (audio_diskstream()->deprecated_io_node) { - - if (!connecting_legal) { - ConnectingLegal.connect (mem_fun (*this, &AudioTrack::deprecated_use_diskstream_connections)); - } else { - deprecated_use_diskstream_connections (); - } - } - - _diskstream->set_record_enabled (false); - _diskstream->monitor_input (false); - - ic_connection.disconnect(); - ic_connection = input_changed.connect (mem_fun (*_diskstream, &Diskstream::handle_input_change)); - - DiskstreamChanged (); /* EMIT SIGNAL */ - - return 0; -} - -int -AudioTrack::use_diskstream (string name) -{ - boost::shared_ptr<AudioDiskstream> dstream; - - if ((dstream = boost::dynamic_pointer_cast<AudioDiskstream>(_session.diskstream_by_name (name))) == 0) { - error << string_compose(_("AudioTrack: audio diskstream \"%1\" not known by session"), name) << endmsg; - return -1; - } - - return set_diskstream (dstream, this); -} - -int -AudioTrack::use_diskstream (const PBD::ID& id) -{ - boost::shared_ptr<AudioDiskstream> dstream; - - if ((dstream = boost::dynamic_pointer_cast<AudioDiskstream> (_session.diskstream_by_id (id))) == 0) { - error << string_compose(_("AudioTrack: audio diskstream \"%1\" not known by session"), id) << endmsg; - return -1; - } - - return set_diskstream (dstream, this); -} - -boost::shared_ptr<AudioDiskstream> -AudioTrack::audio_diskstream() const -{ - return boost::dynamic_pointer_cast<AudioDiskstream>(_diskstream); -} - -int -AudioTrack::set_state (const XMLNode& node) -{ - return _set_state (node, true); -} - -int -AudioTrack::_set_state (const XMLNode& node, bool call_base) -{ - const XMLProperty *prop; - XMLNodeConstIterator iter; - - if (call_base) { - if (Route::_set_state (node, call_base)) { - return -1; - } - } - - if ((prop = node.property (X_("mode"))) != 0) { - _mode = TrackMode (string_2_enum (prop->value(), _mode)); - } else { - _mode = Normal; - } - - if ((prop = node.property ("diskstream-id")) == 0) { - - /* some old sessions use the diskstream name rather than the ID */ - - if ((prop = node.property ("diskstream")) == 0) { - fatal << _("programming error: AudioTrack given state without diskstream!") << endmsg; - /*NOTREACHED*/ - return -1; - } - - if (use_diskstream (prop->value())) { - return -1; - } - - } else { - - PBD::ID id (prop->value()); - - if (use_diskstream (id)) { - return -1; - } - } - - - XMLNodeList nlist; - XMLNodeConstIterator niter; - XMLNode *child; - - nlist = node.children(); - for (niter = nlist.begin(); niter != nlist.end(); ++niter){ - child = *niter; - - if (child->name() == X_("recenable")) { - _rec_enable_control->set_state (*child); - _session.add_controllable (_rec_enable_control); - } - } - - pending_state = const_cast<XMLNode*> (&node); - - _session.StateReady.connect (mem_fun (*this, &AudioTrack::set_state_part_two)); - - return 0; -} - -XMLNode& -AudioTrack::state(bool full_state) -{ - XMLNode& root (Route::state(full_state)); - XMLNode* freeze_node; - char buf[64]; - - if (_freeze_record.playlist) { - XMLNode* inode; - - freeze_node = new XMLNode (X_("freeze-info")); - freeze_node->add_property ("playlist", _freeze_record.playlist->name()); - freeze_node->add_property ("state", enum_2_string (_freeze_record.state)); - - for (vector<FreezeRecordProcessorInfo*>::iterator i = _freeze_record.processor_info.begin(); i != _freeze_record.processor_info.end(); ++i) { - inode = new XMLNode (X_("processor")); - (*i)->id.print (buf, sizeof (buf)); - inode->add_property (X_("id"), buf); - inode->add_child_copy ((*i)->state); - - freeze_node->add_child_nocopy (*inode); - } - - root.add_child_nocopy (*freeze_node); - } - - /* Alignment: act as a proxy for the diskstream */ - - XMLNode* align_node = new XMLNode (X_("alignment")); - AlignStyle as = _diskstream->alignment_style (); - align_node->add_property (X_("style"), enum_2_string (as)); - root.add_child_nocopy (*align_node); - - root.add_property (X_("mode"), enum_2_string (_mode)); - - /* we don't return diskstream state because we don't - own the diskstream exclusively. control of the diskstream - state is ceded to the Session, even if we create the - diskstream. - */ - - _diskstream->id().print (buf, sizeof (buf)); - root.add_property ("diskstream-id", buf); - - root.add_child_nocopy (_rec_enable_control->get_state()); - - return root; -} - -void -AudioTrack::set_state_part_two () -{ - XMLNode* fnode; - XMLProperty* prop; - LocaleGuard lg (X_("POSIX")); - - /* This is called after all session state has been restored but before - have been made ports and connections are established. - */ - - if (pending_state == 0) { - return; - } - - if ((fnode = find_named_node (*pending_state, X_("freeze-info"))) != 0) { - - - _freeze_record.have_mementos = false; - _freeze_record.state = Frozen; - - for (vector<FreezeRecordProcessorInfo*>::iterator i = _freeze_record.processor_info.begin(); i != _freeze_record.processor_info.end(); ++i) { - delete *i; - } - _freeze_record.processor_info.clear (); - - if ((prop = fnode->property (X_("playlist"))) != 0) { - boost::shared_ptr<Playlist> pl = _session.playlist_by_name (prop->value()); - if (pl) { - _freeze_record.playlist = boost::dynamic_pointer_cast<AudioPlaylist> (pl); - } else { - _freeze_record.playlist.reset (); - _freeze_record.state = NoFreeze; - return; - } - } - - if ((prop = fnode->property (X_("state"))) != 0) { - _freeze_record.state = FreezeState (string_2_enum (prop->value(), _freeze_record.state)); - } - - XMLNodeConstIterator citer; - XMLNodeList clist = fnode->children(); - - for (citer = clist.begin(); citer != clist.end(); ++citer) { - if ((*citer)->name() != X_("processor")) { - continue; - } - - if ((prop = (*citer)->property (X_("id"))) == 0) { - continue; - } - - FreezeRecordProcessorInfo* frii = new FreezeRecordProcessorInfo (*((*citer)->children().front()), - boost::shared_ptr<Processor>()); - frii->id = prop->value (); - _freeze_record.processor_info.push_back (frii); - } - } - - /* Alignment: act as a proxy for the diskstream */ - - if ((fnode = find_named_node (*pending_state, X_("alignment"))) != 0) { - - if ((prop = fnode->property (X_("style"))) != 0) { - - /* fix for older sessions from before EnumWriter */ - - string pstr; - - if (prop->value() == "capture") { - pstr = "CaptureTime"; - } else if (prop->value() == "existing") { - pstr = "ExistingMaterial"; - } else { - pstr = prop->value(); - } - - AlignStyle as = AlignStyle (string_2_enum (pstr, as)); - _diskstream->set_persistent_align_style (as); - } - } - return; -} - -int -AudioTrack::no_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, nframes_t offset, - bool session_state_changing, bool can_record, bool rec_monitors_input) -{ - if (n_outputs().n_total() == 0) { - return 0; - } - - if (!_active) { - silence (nframes, offset); - return 0; - } - - if (session_state_changing) { - - /* XXX is this safe to do against transport state changes? */ - - passthru_silence (start_frame, end_frame, nframes, offset, 0, false); - return 0; - } - - audio_diskstream()->check_record_status (start_frame, nframes, can_record); - - bool send_silence; - - if (_have_internal_generator) { - /* since the instrument has no input streams, - there is no reason to send any signal - into the route. - */ - send_silence = true; - } else { - - if (!Config->get_tape_machine_mode()) { - /* - ADATs work in a strange way.. - they monitor input always when stopped.and auto-input is engaged. - */ - if ((Config->get_monitoring_model() == SoftwareMonitoring) && (Config->get_auto_input () || _diskstream->record_enabled())) { - send_silence = false; - } else { - send_silence = true; - } - } else { - /* - Other machines switch to input on stop if the track is record enabled, - regardless of the auto input setting (auto input only changes the - monitoring state when the transport is rolling) - */ - if ((Config->get_monitoring_model() == SoftwareMonitoring) && _diskstream->record_enabled()) { - send_silence = false; - } else { - send_silence = true; - } - } - } - - apply_gain_automation = false; - - if (send_silence) { - - /* if we're sending silence, but we want the meters to show levels for the signal, - meter right here. - */ - - if (_have_internal_generator) { - passthru_silence (start_frame, end_frame, nframes, offset, 0, true); - } else { - if (_meter_point == MeterInput) { - just_meter_input (start_frame, end_frame, nframes, offset); - } - passthru_silence (start_frame, end_frame, nframes, offset, 0, false); - } - - } else { - - /* we're sending signal, but we may still want to meter the input. - */ - - passthru (start_frame, end_frame, nframes, offset, 0, (_meter_point == MeterInput)); - } - - return 0; -} - -int -AudioTrack::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 dret; - Sample* b; - Sample* tmpb; - nframes_t transport_frame; - boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream(); - - { - Glib::RWLock::ReaderLock lm (_processor_lock, Glib::TRY_LOCK); - if (lm.locked()) { - // automation snapshot can also be called from the non-rt context - // and it uses the redirect list, so we take the lock out here - automation_snapshot (start_frame, false); - } - } - - - if (n_outputs().n_total() == 0 && _processors.empty()) { - return 0; - } - - if (!_active) { - silence (nframes, offset); - return 0; - } - - transport_frame = _session.transport_frame(); - - if ((nframes = check_initial_delay (nframes, offset, transport_frame)) == 0) { - /* need to do this so that the diskstream sets its - playback distance to zero, thus causing diskstream::commit - to do nothing. - */ - return diskstream->process (transport_frame, 0, 0, can_record, rec_monitors_input); - } - - _silent = false; - apply_gain_automation = false; - - if ((dret = diskstream->process (transport_frame, nframes, offset, can_record, rec_monitors_input)) != 0) { - - silence (nframes, offset); - - return dret; - } - - /* special condition applies */ - - if (_meter_point == MeterInput) { - just_meter_input (start_frame, end_frame, nframes, offset); - } - - if (diskstream->record_enabled() && !can_record && !Config->get_auto_input()) { - - /* not actually recording, but we want to hear the input material anyway, - at least potentially (depending on monitoring options) - */ - - passthru (start_frame, end_frame, nframes, offset, 0, true); - - } else if ((b = diskstream->playback_buffer(0)) != 0) { - - /* - XXX is it true that the earlier test on n_outputs() - means that we can avoid checking it again here? i think - so, because changing the i/o configuration of an IO - requires holding the AudioEngine lock, which we hold - while in the process() tree. - */ - - - /* copy the diskstream data to all output buffers */ - - const size_t limit = n_process_buffers().n_audio(); - BufferSet& bufs = _session.get_scratch_buffers (n_process_buffers()); - - uint32_t n; - uint32_t i; - - for (i = 0, n = 1; i < limit; ++i, ++n) { - memcpy (bufs.get_audio(i).data(), b, sizeof (Sample) * nframes); - if (n < diskstream->n_channels().n_audio()) { - tmpb = diskstream->playback_buffer(n); - if (tmpb!=0) { - b = tmpb; - } - } - } - - /* don't waste time with automation if we're recording or we've just stopped (yes it can happen) */ - - if (!diskstream->record_enabled() && _session.transport_rolling()) { - Glib::Mutex::Lock am (_automation_lock, Glib::TRY_LOCK); - - if (am.locked() && gain_control()->list()->automation_playback()) { - apply_gain_automation = gain_control()->list()->curve().rt_safe_get_vector (start_frame, end_frame, _session.gain_automation_buffer(), nframes); - } - } - - process_output_buffers (bufs, start_frame, end_frame, nframes, offset, (!_session.get_record_enabled() || !Config->get_do_not_record_plugins()), declick, (_meter_point != MeterInput)); - - } else { - /* problem with the diskstream; just be quiet for a bit */ - silence (nframes, offset); - } - - return 0; -} - -int -AudioTrack::silent_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, nframes_t offset, - bool can_record, bool rec_monitors_input) -{ - if (n_outputs().n_total() == 0 && _processors.empty()) { - return 0; - } - - if (!_active) { - silence (nframes, offset); - return 0; - } - - _silent = true; - apply_gain_automation = false; - - silence (nframes, offset); - - return audio_diskstream()->process (_session.transport_frame() + offset, nframes, offset, can_record, rec_monitors_input); -} - -int -AudioTrack::export_stuff (BufferSet& buffers, nframes_t start, nframes_t nframes) -{ - gain_t gain_automation[nframes]; - gain_t gain_buffer[nframes]; - float mix_buffer[nframes]; - ProcessorList::iterator i; - bool post_fader_work = false; - gain_t this_gain = _gain; - boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream(); - - Glib::RWLock::ReaderLock rlock (_processor_lock); - - boost::shared_ptr<AudioPlaylist> apl = boost::dynamic_pointer_cast<AudioPlaylist>(diskstream->playlist()); - assert(apl); - - assert(buffers.get_audio(0).capacity() >= nframes); - - if (apl->read (buffers.get_audio(0).data(), mix_buffer, gain_buffer, start, nframes) != nframes) { - return -1; - } - - assert(buffers.count().n_audio() >= 1); - uint32_t n=1; - Sample* b = buffers.get_audio(0).data(); - BufferSet::audio_iterator bi = buffers.audio_begin(); - ++bi; - for ( ; bi != buffers.audio_end(); ++bi, ++n) { - if (n < diskstream->n_channels().n_audio()) { - if (apl->read (bi->data(), mix_buffer, gain_buffer, start, nframes, n) != nframes) { - return -1; - } - b = bi->data(); - } - else { - /* duplicate last across remaining buffers */ - memcpy (bi->data(), b, sizeof (Sample) * nframes); - } - } - - - /* note: only run processors during export. other layers in the machinery - will already have checked that there are no external port processors. - */ - - for (i = _processors.begin(); i != _processors.end(); ++i) { - boost::shared_ptr<Processor> processor; - - if ((processor = boost::dynamic_pointer_cast<Processor>(*i)) != 0) { - switch (processor->placement()) { - case PreFader: - processor->run_in_place (buffers, start, start+nframes, nframes, 0); - break; - case PostFader: - post_fader_work = true; - break; - } - } - } - - if (gain_control()->list()->automation_state() == Play) { - - gain_control()->list()->curve().get_vector (start, start + nframes, gain_automation, nframes); - - for (BufferSet::audio_iterator bi = buffers.audio_begin(); bi != buffers.audio_end(); ++bi) { - Sample *b = bi->data(); - for (nframes_t n = 0; n < nframes; ++n) { - b[n] *= gain_automation[n]; - } - } - - } else { - - for (BufferSet::audio_iterator bi = buffers.audio_begin(); bi != buffers.audio_end(); ++bi) { - Sample *b = bi->data(); - for (nframes_t n = 0; n < nframes; ++n) { - b[n] *= this_gain; - } - } - } - - if (post_fader_work) { - - for (i = _processors.begin(); i != _processors.end(); ++i) { - boost::shared_ptr<PluginInsert> processor; - - if ((processor = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) { - switch ((*i)->placement()) { - case PreFader: - break; - case PostFader: - processor->run_in_place (buffers, start, start+nframes, nframes, 0); - break; - } - } - } - } - - return 0; -} - -void -AudioTrack::bounce (InterThreadInfo& itt) -{ - vector<boost::shared_ptr<Source> > srcs; - _session.write_one_audio_track (*this, 0, _session.current_end_frame(), false, srcs, itt); - itt.done = true; -} - - -void -AudioTrack::bounce_range (nframes_t start, nframes_t end, InterThreadInfo& itt) -{ - vector<boost::shared_ptr<Source> > srcs; - _session.write_one_audio_track (*this, start, end, false, srcs, itt); - itt.done = true; -} - -void -AudioTrack::freeze (InterThreadInfo& itt) -{ - vector<boost::shared_ptr<Source> > srcs; - string new_playlist_name; - boost::shared_ptr<Playlist> new_playlist; - string dir; - string region_name; - boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream(); - - if ((_freeze_record.playlist = boost::dynamic_pointer_cast<AudioPlaylist>(diskstream->playlist())) == 0) { - return; - } - - uint32_t n = 1; - - while (n < (UINT_MAX-1)) { - - string candidate; - - candidate = string_compose ("<F%2>%1", _freeze_record.playlist->name(), n); - - if (_session.playlist_by_name (candidate) == 0) { - new_playlist_name = candidate; - break; - } - - ++n; - - } - - if (n == (UINT_MAX-1)) { - error << string_compose (X_("There are too many frozen versions of playlist \"%1\"" - " to create another one"), _freeze_record.playlist->name()) - << endmsg; - return; - } - - if (_session.write_one_audio_track (*this, _session.current_start_frame(), _session.current_end_frame(), true, srcs, itt)) { - return; - } - - _freeze_record.processor_info.clear (); - _freeze_record.have_mementos = true; - - { - Glib::RWLock::ReaderLock lm (_processor_lock); - - for (ProcessorList::iterator r = _processors.begin(); r != _processors.end(); ++r) { - - boost::shared_ptr<Processor> processor; - - if ((processor = boost::dynamic_pointer_cast<Processor>(*r)) != 0) { - - FreezeRecordProcessorInfo* frii = new FreezeRecordProcessorInfo ((*r)->get_state(), processor); - - frii->id = processor->id(); - - _freeze_record.processor_info.push_back (frii); - - /* now deactivate the processor */ - - processor->set_active (false); - _session.set_dirty (); - } - } - } - - new_playlist = PlaylistFactory::create (DataType::AUDIO, _session, new_playlist_name, false); - region_name = new_playlist_name; - - /* create a new region from all filesources, keep it private */ - - boost::shared_ptr<Region> region (RegionFactory::create (srcs, 0, srcs[0]->length(), - region_name, 0, - (Region::Flag) (Region::WholeFile|Region::DefaultFlags), - false)); - - new_playlist->set_orig_diskstream_id (diskstream->id()); - new_playlist->add_region (region, _session.current_start_frame()); - new_playlist->set_frozen (true); - region->set_locked (true); - - diskstream->use_playlist (boost::dynamic_pointer_cast<AudioPlaylist>(new_playlist)); - diskstream->set_record_enabled (false); - - _freeze_record.state = Frozen; - FreezeChange(); /* EMIT SIGNAL */ -} - -void -AudioTrack::unfreeze () -{ - if (_freeze_record.playlist) { - audio_diskstream()->use_playlist (_freeze_record.playlist); - - if (_freeze_record.have_mementos) { - - for (vector<FreezeRecordProcessorInfo*>::iterator i = _freeze_record.processor_info.begin(); i != _freeze_record.processor_info.end(); ++i) { - (*i)->memento (); - } - - } else { - - Glib::RWLock::ReaderLock lm (_processor_lock); // should this be a write lock? jlc - for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { - for (vector<FreezeRecordProcessorInfo*>::iterator ii = _freeze_record.processor_info.begin(); ii != _freeze_record.processor_info.end(); ++ii) { - if ((*ii)->id == (*i)->id()) { - (*i)->set_state (((*ii)->state)); - break; - } - } - } - } - - _freeze_record.playlist.reset (); - } - - _freeze_record.state = UnFrozen; - FreezeChange (); /* EMIT SIGNAL */ -} - diff --git a/libs/ardour/audio_unit.cc b/libs/ardour/audio_unit.cc deleted file mode 100644 index b941bc10bb..0000000000 --- a/libs/ardour/audio_unit.cc +++ /dev/null @@ -1,924 +0,0 @@ -/* - 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. - -*/ - -#include <sstream> - -#include <pbd/transmitter.h> -#include <pbd/xml++.h> -#include <pbd/whitespace.h> - -#include <glibmm/thread.h> - -#include <ardour/audioengine.h> -#include <ardour/io.h> -#include <ardour/audio_unit.h> -#include <ardour/session.h> -#include <ardour/utils.h> - -#include <appleutility/CAAudioUnit.h> -#include <appleutility/CAAUParameter.h> - -#include <CoreServices/CoreServices.h> -#include <AudioUnit/AudioUnit.h> - -#include "i18n.h" - -using namespace std; -using namespace PBD; -using namespace ARDOUR; - -static OSStatus -_render_callback(void *userData, - AudioUnitRenderActionFlags *ioActionFlags, - const AudioTimeStamp *inTimeStamp, - UInt32 inBusNumber, - UInt32 inNumberFrames, - AudioBufferList* ioData) -{ - return ((AUPlugin*)userData)->render_callback (ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames, ioData); -} - -AUPlugin::AUPlugin (AudioEngine& engine, Session& session, boost::shared_ptr<CAComponent> _comp) - : Plugin (engine, session), - comp (_comp), - unit (new CAAudioUnit), - initialized (false), - buffers (0), - current_maxbuf (0), - current_offset (0), - current_buffers (0), - frames_processed (0) -{ - init (); -} - -AUPlugin::AUPlugin (const AUPlugin& other) - : Plugin (other) - , comp (other.get_comp()) - , unit (new CAAudioUnit) - , initialized (false) - , buffers (0) - , current_maxbuf (0) - , current_offset (0) - , current_buffers (0) - , frames_processed (0) - -{ - init (); -} - -AUPlugin::~AUPlugin () -{ - if (unit) { - unit->Uninitialize (); - } - - if (buffers) { - free (buffers); - } -} - - -void -AUPlugin::init () -{ - OSErr err = CAAudioUnit::Open (*(comp.get()), *unit); - - if (err != noErr) { - error << _("AudioUnit: Could not convert CAComponent to CAAudioUnit") << endmsg; - throw failed_constructor (); - } - - AURenderCallbackStruct renderCallbackInfo; - - renderCallbackInfo.inputProc = _render_callback; - renderCallbackInfo.inputProcRefCon = this; - - if ((err = unit->SetProperty (kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, - 0, (void*) &renderCallbackInfo, sizeof(renderCallbackInfo))) != 0) { - cerr << "cannot install render callback (err = " << err << ')' << endl; - throw failed_constructor(); - } - - unit->GetElementCount (kAudioUnitScope_Global, global_elements); - unit->GetElementCount (kAudioUnitScope_Input, input_elements); - unit->GetElementCount (kAudioUnitScope_Output, output_elements); - - // set up the basic stream format. these fields do not change - - streamFormat.mSampleRate = _session.frame_rate(); - streamFormat.mFormatID = kAudioFormatLinearPCM; - streamFormat.mFormatFlags = kAudioFormatFlagIsFloat|kAudioFormatFlagIsPacked|kAudioFormatFlagIsNonInterleaved; - -#ifdef __LITTLE_ENDIAN__ - /* relax */ -#else - streamFormat.mFormatFlags |= kAudioFormatFlagIsBigEndian; -#endif - - streamFormat.mBitsPerChannel = 32; - streamFormat.mFramesPerPacket = 1; - - // subject to later modification as we discover channel counts - - streamFormat.mBytesPerPacket = 4; - streamFormat.mBytesPerFrame = 4; - streamFormat.mChannelsPerFrame = 1; - - format_set = 0; - - if (_set_block_size (_session.get_block_size())) { - error << _("AUPlugin: cannot set processing block size") << endmsg; - throw failed_constructor(); - } - - discover_parameters (); - - Plugin::setup_controls (); -} - -void -AUPlugin::discover_parameters () -{ - /* discover writable parameters */ - - AudioUnitScope scopes[] = { - kAudioUnitScope_Global, - kAudioUnitScope_Output, - kAudioUnitScope_Input - }; - - descriptors.clear (); - - for (uint32_t i = 0; i < sizeof (scopes) / sizeof (scopes[0]); ++i) { - - AUParamInfo param_info (unit->AU(), false, false, scopes[i]); - - for (uint32_t i = 0; i < param_info.NumParams(); ++i) { - - AUParameterDescriptor d; - - d.id = param_info.ParamID (i); - - const CAAUParameter* param = param_info.GetParamInfo (d.id); - const AudioUnitParameterInfo& info (param->ParamInfo()); - - const int len = CFStringGetLength (param->GetName());; - char local_buffer[len*2]; - Boolean good = CFStringGetCString(param->GetName(),local_buffer,len*2,kCFStringEncodingMacRoman); - if (!good) { - d.label = "???"; - } else { - d.label = local_buffer; - } - - d.scope = param_info.GetScope (); - d.element = param_info.GetElement (); - - /* info.units to consider */ - /* - kAudioUnitParameterUnit_Generic = 0 - kAudioUnitParameterUnit_Indexed = 1 - kAudioUnitParameterUnit_Boolean = 2 - kAudioUnitParameterUnit_Percent = 3 - kAudioUnitParameterUnit_Seconds = 4 - kAudioUnitParameterUnit_SampleFrames = 5 - kAudioUnitParameterUnit_Phase = 6 - kAudioUnitParameterUnit_Rate = 7 - kAudioUnitParameterUnit_Hertz = 8 - kAudioUnitParameterUnit_Cents = 9 - kAudioUnitParameterUnit_RelativeSemiTones = 10 - kAudioUnitParameterUnit_MIDINoteNumber = 11 - kAudioUnitParameterUnit_MIDIController = 12 - kAudioUnitParameterUnit_Decibels = 13 - kAudioUnitParameterUnit_LinearGain = 14 - kAudioUnitParameterUnit_Degrees = 15 - kAudioUnitParameterUnit_EqualPowerCrossfade = 16 - kAudioUnitParameterUnit_MixerFaderCurve1 = 17 - kAudioUnitParameterUnit_Pan = 18 - kAudioUnitParameterUnit_Meters = 19 - kAudioUnitParameterUnit_AbsoluteCents = 20 - kAudioUnitParameterUnit_Octaves = 21 - kAudioUnitParameterUnit_BPM = 22 - kAudioUnitParameterUnit_Beats = 23 - kAudioUnitParameterUnit_Milliseconds = 24 - kAudioUnitParameterUnit_Ratio = 25 - */ - - /* info.flags to consider */ - - /* - - kAudioUnitParameterFlag_CFNameRelease = (1L << 4) - kAudioUnitParameterFlag_HasClump = (1L << 20) - kAudioUnitParameterFlag_HasName = (1L << 21) - kAudioUnitParameterFlag_DisplayLogarithmic = (1L << 22) - kAudioUnitParameterFlag_IsHighResolution = (1L << 23) - kAudioUnitParameterFlag_NonRealTime = (1L << 24) - kAudioUnitParameterFlag_CanRamp = (1L << 25) - kAudioUnitParameterFlag_ExpertMode = (1L << 26) - kAudioUnitParameterFlag_HasCFNameString = (1L << 27) - kAudioUnitParameterFlag_IsGlobalMeta = (1L << 28) - kAudioUnitParameterFlag_IsElementMeta = (1L << 29) - kAudioUnitParameterFlag_IsReadable = (1L << 30) - kAudioUnitParameterFlag_IsWritable = (1L << 31) - */ - - d.lower = info.minValue; - d.upper = info.maxValue; - d.default_value = info.defaultValue; - - d.integer_step = (info.unit & kAudioUnitParameterUnit_Indexed); - d.toggled = (info.unit & kAudioUnitParameterUnit_Boolean) || - (d.integer_step && ((d.upper - d.lower) == 1.0)); - d.sr_dependent = (info.unit & kAudioUnitParameterUnit_SampleFrames); - d.automatable = !d.toggled && - !(info.flags & kAudioUnitParameterFlag_NonRealTime) && - (info.flags & kAudioUnitParameterFlag_IsWritable); - - d.logarithmic = (info.flags & kAudioUnitParameterFlag_DisplayLogarithmic); - d.unit = info.unit; - - d.step = 1.0; - d.smallstep = 0.1; - d.largestep = 10.0; - d.min_unbound = 0; // lower is bound - d.max_unbound = 0; // upper is bound - - descriptors.push_back (d); - } - } -} - - -string -AUPlugin::unique_id () const -{ - return AUPluginInfo::stringify_descriptor (comp->Desc()); -} - -const char * -AUPlugin::label () const -{ - return _info->name.c_str(); -} - -uint32_t -AUPlugin::parameter_count () const -{ - return descriptors.size(); -} - -float -AUPlugin::default_value (uint32_t port) -{ - if (port < descriptors.size()) { - return descriptors[port].default_value; - } - - return 0; -} - -nframes_t -AUPlugin::signal_latency () const -{ - if (_user_latency) { - return _user_latency; - } - - return unit->Latency() * _session.frame_rate(); -} - -void -AUPlugin::set_parameter (uint32_t which, float val) -{ - if (which < descriptors.size()) { - const AUParameterDescriptor& d (descriptors[which]); - unit->SetParameter (d.id, d.scope, d.element, val); - } -} - -float -AUPlugin::get_parameter (uint32_t which) const -{ - float val = 0.0; - if (which < descriptors.size()) { - const AUParameterDescriptor& d (descriptors[which]); - unit->GetParameter(d.id, d.scope, d.element, val); - } - return val; -} - -int -AUPlugin::get_parameter_descriptor (uint32_t which, ParameterDescriptor& pd) const -{ - if (which < descriptors.size()) { - pd = descriptors[which]; - return 0; - } - return -1; -} - -uint32_t -AUPlugin::nth_parameter (uint32_t which, bool& ok) const -{ - if (which < descriptors.size()) { - ok = true; - return which; - } - ok = false; - return 0; -} - -void -AUPlugin::activate () -{ - if (!initialized) { - OSErr err; - if ((err = unit->Initialize()) != noErr) { - error << string_compose (_("AUPlugin: %1 cannot initialize plugin (err = %2)"), name(), err) << endmsg; - } else { - frames_processed = 0; - initialized = true; - } - } -} - -void -AUPlugin::deactivate () -{ - unit->GlobalReset (); -} - -void -AUPlugin::set_block_size (nframes_t nframes) -{ - _set_block_size (nframes); -} - -int -AUPlugin::_set_block_size (nframes_t nframes) -{ - bool was_initialized = initialized; - UInt32 numFrames = nframes; - OSErr err; - - if (initialized) { - unit->Uninitialize (); - } - - if ((err = unit->SetProperty (kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, - 0, &numFrames, sizeof (numFrames))) != noErr) { - cerr << "cannot set max frames (err = " << err << ')' << endl; - return -1; - } - - if (was_initialized) { - activate (); - } - - return 0; -} - -int32_t -AUPlugin::can_support_input_configuration (int32_t in) -{ - streamFormat.mChannelsPerFrame = in; - /* apple says that for non-interleaved data, these - values always refer to a single channel. - */ - streamFormat.mBytesPerPacket = 4; - streamFormat.mBytesPerFrame = 4; - - if (set_input_format () == 0) { - return 1; - } else { - return -1; - } -} - -int -AUPlugin::set_input_format () -{ - return set_stream_format (kAudioUnitScope_Input, input_elements); -} - -int -AUPlugin::set_output_format () -{ - return set_stream_format (kAudioUnitScope_Output, output_elements); -} - -int -AUPlugin::set_stream_format (int scope, uint32_t cnt) -{ - OSErr result; - - for (uint32_t i = 0; i < cnt; ++i) { - if ((result = unit->SetFormat (scope, i, streamFormat)) != 0) { - error << string_compose (_("AUPlugin: could not set stream format for %1/%2 (err = %3)"), - (scope == kAudioUnitScope_Input ? "input" : "output"), i, result) << endmsg; - return -1; - } - } - - if (scope == kAudioUnitScope_Input) { - format_set |= 0x1; - } else { - format_set |= 0x2; - } - - return 0; -} - -int32_t -AUPlugin::compute_output_streams (int32_t nplugins) -{ - /* we will never replicate AU plugins - either they can do the I/O we need - or not. thus, we can ignore nplugins entirely. - */ - - if (set_output_format() == 0) { - - if (buffers) { - free (buffers); - buffers = 0; - } - - buffers = (AudioBufferList *) malloc (offsetof(AudioBufferList, mBuffers) + - streamFormat.mChannelsPerFrame * sizeof(AudioBuffer)); - - Glib::Mutex::Lock em (_session.engine().process_lock()); - IO::MoreOutputs (streamFormat.mChannelsPerFrame); - - return streamFormat.mChannelsPerFrame; - } else { - return -1; - } -} - -uint32_t -AUPlugin::output_streams() const -{ - if (!(format_set & 0x2)) { - warning << string_compose (_("AUPlugin: %1 output_streams() called without any format set!"), name()) << endmsg; - return 1; - } - - return streamFormat.mChannelsPerFrame; -} - - -uint32_t -AUPlugin::input_streams() const -{ - if (!(format_set & 0x1)) { - warning << _("AUPlugin: input_streams() called without any format set!") << endmsg; - return 1; - } - return streamFormat.mChannelsPerFrame; -} - -OSStatus -AUPlugin::render_callback(AudioUnitRenderActionFlags *ioActionFlags, - const AudioTimeStamp *inTimeStamp, - UInt32 inBusNumber, - UInt32 inNumberFrames, - AudioBufferList* ioData) -{ - /* not much to do - the data is already in the buffers given to us in connect_and_run() */ - - if (current_maxbuf == 0) { - error << _("AUPlugin: render callback called illegally!") << endmsg; - return kAudioUnitErr_CannotDoInCurrentContext; - } - - for (uint32_t i = 0; i < current_maxbuf; ++i) { - ioData->mBuffers[i].mNumberChannels = 1; - ioData->mBuffers[i].mDataByteSize = sizeof (Sample) * inNumberFrames; - ioData->mBuffers[i].mData = (*current_buffers)[i] + cb_offset + current_offset; - } - - cb_offset += inNumberFrames; - - return noErr; -} - -int -AUPlugin::connect_and_run (vector<Sample*>& bufs, uint32_t maxbuf, int32_t& in, int32_t& out, nframes_t nframes, nframes_t offset) -{ - AudioUnitRenderActionFlags flags = 0; - AudioTimeStamp ts; - - current_buffers = &bufs; - current_maxbuf = maxbuf; - current_offset = offset; - cb_offset = 0; - - buffers->mNumberBuffers = maxbuf; - - for (uint32_t i = 0; i < maxbuf; ++i) { - buffers->mBuffers[i].mNumberChannels = 1; - buffers->mBuffers[i].mDataByteSize = nframes * sizeof (Sample); - buffers->mBuffers[i].mData = 0; - } - - ts.mSampleTime = frames_processed; - ts.mFlags = kAudioTimeStampSampleTimeValid; - - if (unit->Render (&flags, &ts, 0, nframes, buffers) == noErr) { - - current_maxbuf = 0; - frames_processed += nframes; - - for (uint32_t i = 0; i < maxbuf; ++i) { - if (bufs[i] + offset != buffers->mBuffers[i].mData) { - memcpy (bufs[i]+offset, buffers->mBuffers[i].mData, nframes * sizeof (Sample)); - } - } - return 0; - } - - return -1; -} - -set<uint32_t> -AUPlugin::automatable() const -{ - set<uint32_t> automates; - - for (uint32_t i = 0; i < descriptors.size(); ++i) { - if (descriptors[i].automatable) { - automates.insert (i); - } - } - - return automates; -} - -string -AUPlugin::describe_parameter (uint32_t param) -{ - return descriptors[param].label; -} - -void -AUPlugin::print_parameter (uint32_t param, char* buf, uint32_t len) const -{ - // NameValue stuff here -} - -bool -AUPlugin::parameter_is_audio (uint32_t) const -{ - return false; -} - -bool -AUPlugin::parameter_is_control (uint32_t) const -{ - return true; -} - -bool -AUPlugin::parameter_is_input (uint32_t) const -{ - return false; -} - -bool -AUPlugin::parameter_is_output (uint32_t) const -{ - return false; -} - -XMLNode& -AUPlugin::get_state() -{ - XMLNode *root = new XMLNode (state_node_name()); - LocaleGuard lg (X_("POSIX")); - return *root; -} - -int -AUPlugin::set_state(const XMLNode& node) -{ - return -1; -} - -bool -AUPlugin::save_preset (string name) -{ - return false; -} - -bool -AUPlugin::load_preset (const string preset_label) -{ - return false; -} - -vector<string> -AUPlugin::get_presets () -{ - vector<string> presets; - - return presets; -} - -bool -AUPlugin::has_editor () const -{ - // even if the plugin doesn't have its own editor, the AU API can be used - // to create one that looks native. - return true; -} - -AUPluginInfo::AUPluginInfo (boost::shared_ptr<CAComponentDescription> d) - : descriptor (d) -{ - -} - -AUPluginInfo::~AUPluginInfo () -{ -} - -PluginPtr -AUPluginInfo::load (Session& session) -{ - try { - PluginPtr plugin; - - boost::shared_ptr<CAComponent> comp (new CAComponent(*descriptor)); - - if (!comp->IsValid()) { - error << ("AudioUnit: not a valid Component") << endmsg; - } else { - plugin.reset (new AUPlugin (session.engine(), session, comp)); - } - - plugin->set_info (PluginInfoPtr (new AUPluginInfo (*this))); - return plugin; - } - - catch (failed_constructor &err) { - return PluginPtr ((Plugin*) 0); - } -} - -PluginInfoList -AUPluginInfo::discover () -{ - PluginInfoList plugs; - - discover_fx (plugs); - discover_music (plugs); - - return plugs; -} - -void -AUPluginInfo::discover_music (PluginInfoList& plugs) -{ - CAComponentDescription desc; - desc.componentFlags = 0; - desc.componentFlagsMask = 0; - desc.componentSubType = 0; - desc.componentManufacturer = 0; - desc.componentType = kAudioUnitType_MusicEffect; - - discover_by_description (plugs, desc); -} - -void -AUPluginInfo::discover_fx (PluginInfoList& plugs) -{ - CAComponentDescription desc; - desc.componentFlags = 0; - desc.componentFlagsMask = 0; - desc.componentSubType = 0; - desc.componentManufacturer = 0; - desc.componentType = kAudioUnitType_Effect; - - discover_by_description (plugs, desc); -} - -void -AUPluginInfo::discover_by_description (PluginInfoList& plugs, CAComponentDescription& desc) -{ - Component comp = 0; - - comp = FindNextComponent (NULL, &desc); - - while (comp != NULL) { - CAComponentDescription temp; - GetComponentInfo (comp, &temp, NULL, NULL, NULL); - - AUPluginInfoPtr info (new AUPluginInfo - (boost::shared_ptr<CAComponentDescription> (new CAComponentDescription(temp)))); - - /* no panners, format converters or i/o AU's for our purposes - */ - - switch (info->descriptor->Type()) { - case kAudioUnitType_Panner: - case kAudioUnitType_OfflineEffect: - case kAudioUnitType_FormatConverter: - continue; - default: - break; - } - - switch (info->descriptor->SubType()) { - case kAudioUnitSubType_DefaultOutput: - case kAudioUnitSubType_SystemOutput: - case kAudioUnitSubType_GenericOutput: - case kAudioUnitSubType_AUConverter: - continue; - break; - - case kAudioUnitSubType_DLSSynth: - info->category = "DLSSynth"; - break; - - case kAudioUnitType_MusicEffect: - info->category = "MusicEffect"; - break; - - case kAudioUnitSubType_Varispeed: - info->category = "Varispeed"; - break; - - case kAudioUnitSubType_Delay: - info->category = "Delay"; - break; - - case kAudioUnitSubType_LowPassFilter: - info->category = "LowPassFilter"; - break; - - case kAudioUnitSubType_HighPassFilter: - info->category = "HighPassFilter"; - break; - - case kAudioUnitSubType_BandPassFilter: - info->category = "BandPassFilter"; - break; - - case kAudioUnitSubType_HighShelfFilter: - info->category = "HighShelfFilter"; - break; - - case kAudioUnitSubType_LowShelfFilter: - info->category = "LowShelfFilter"; - break; - - case kAudioUnitSubType_ParametricEQ: - info->category = "ParametricEQ"; - break; - - case kAudioUnitSubType_GraphicEQ: - info->category = "GraphicEQ"; - break; - - case kAudioUnitSubType_PeakLimiter: - info->category = "PeakLimiter"; - break; - - case kAudioUnitSubType_DynamicsProcessor: - info->category = "DynamicsProcessor"; - break; - - case kAudioUnitSubType_MultiBandCompressor: - info->category = "MultiBandCompressor"; - break; - - case kAudioUnitSubType_MatrixReverb: - info->category = "MatrixReverb"; - break; - - case kAudioUnitType_Mixer: - info->category = "Mixer"; - break; - - case kAudioUnitSubType_StereoMixer: - info->category = "StereoMixer"; - break; - - case kAudioUnitSubType_3DMixer: - info->category = "3DMixer"; - break; - - case kAudioUnitSubType_MatrixMixer: - info->category = "MatrixMixer"; - break; - - default: - info->category = ""; - } - - AUPluginInfo::get_names (temp, info->name, info->creator); - - info->type = ARDOUR::AudioUnit; - info->unique_id = stringify_descriptor (*info->descriptor); - - /* mark the plugin as having flexible i/o */ - - info->n_inputs = -1; - info->n_outputs = -1; - - plugs.push_back (info); - - comp = FindNextComponent (comp, &desc); - } -} - -void -AUPluginInfo::get_names (CAComponentDescription& comp_desc, std::string& name, Glib::ustring& maker) -{ - CFStringRef itemName = NULL; - - // Marc Poirier-style item name - CAComponent auComponent (comp_desc); - if (auComponent.IsValid()) { - CAComponentDescription dummydesc; - Handle nameHandle = NewHandle(sizeof(void*)); - if (nameHandle != NULL) { - OSErr err = GetComponentInfo(auComponent.Comp(), &dummydesc, nameHandle, NULL, NULL); - if (err == noErr) { - ConstStr255Param nameString = (ConstStr255Param) (*nameHandle); - if (nameString != NULL) { - itemName = CFStringCreateWithPascalString(kCFAllocatorDefault, nameString, CFStringGetSystemEncoding()); - } - } - DisposeHandle(nameHandle); - } - } - - // if Marc-style fails, do the original way - if (itemName == NULL) { - CFStringRef compTypeString = UTCreateStringForOSType(comp_desc.componentType); - CFStringRef compSubTypeString = UTCreateStringForOSType(comp_desc.componentSubType); - CFStringRef compManufacturerString = UTCreateStringForOSType(comp_desc.componentManufacturer); - - itemName = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@ - %@ - %@"), - compTypeString, compManufacturerString, compSubTypeString); - - if (compTypeString != NULL) - CFRelease(compTypeString); - if (compSubTypeString != NULL) - CFRelease(compSubTypeString); - if (compManufacturerString != NULL) - CFRelease(compManufacturerString); - } - - string str = CFStringRefToStdString(itemName); - string::size_type colon = str.find (':'); - - if (colon) { - name = str.substr (colon+1); - maker = str.substr (0, colon); - // strip_whitespace_edges (maker); - // strip_whitespace_edges (name); - } else { - name = str; - maker = "unknown"; - } -} - -// from CAComponentDescription.cpp (in libs/appleutility in ardour source) -extern char *StringForOSType (OSType t, char *writeLocation); - -std::string -AUPluginInfo::stringify_descriptor (const CAComponentDescription& desc) -{ - char str[24]; - stringstream s; - - s << StringForOSType (desc.Type(), str); - s << " - "; - - s << StringForOSType (desc.SubType(), str); - s << " - "; - - s << StringForOSType (desc.Manu(), str); - - return s.str(); -} diff --git a/libs/ardour/audioanalyser.cc b/libs/ardour/audioanalyser.cc deleted file mode 100644 index 98c4206301..0000000000 --- a/libs/ardour/audioanalyser.cc +++ /dev/null @@ -1,166 +0,0 @@ -#include <cstring> -#include <vamp-sdk/hostext/PluginLoader.h> -#include <glibmm/miscutils.h> -#include <glibmm/fileutils.h> -#include <glib/gstdio.h> // for g_remove() - -#include <pbd/error.h> - -#include <ardour/audioanalyser.h> -#include <ardour/readable.h> -#include <ardour/readable.h> - -#include "i18n.h" - -using namespace std; -using namespace Vamp; -using namespace PBD; -using namespace ARDOUR; - -AudioAnalyser::AudioAnalyser (float sr, AnalysisPluginKey key) - : sample_rate (sr) - , plugin_key (key) -{ - /* create VAMP plugin and initialize */ - - if (initialize_plugin (plugin_key, sample_rate)) { - error << string_compose (_("cannot load VAMP plugin \"%1\""), key) << endmsg; - throw failed_constructor(); - } -} - -AudioAnalyser::~AudioAnalyser () -{ - delete plugin; -} - -int -AudioAnalyser::initialize_plugin (AnalysisPluginKey key, float sr) -{ - using namespace Vamp::HostExt; - - PluginLoader* loader (PluginLoader::getInstance()); - - plugin = loader->loadPlugin (key, sr, PluginLoader::ADAPT_ALL); - - if (!plugin) { - error << string_compose (_("VAMP Plugin \"%1\" could not be loaded"), key) << endmsg; - return -1; - } - - /* we asked for the buffering adapter, so set the blocksize to - something that makes for efficient disk i/o - */ - - bufsize = 65536; - stepsize = bufsize; - - if (plugin->getMinChannelCount() > 1) { - delete plugin; - return -1; - } - - if (!plugin->initialise (1, stepsize, bufsize)) { - delete plugin; - return -1; - } - - return 0; -} - -void -AudioAnalyser::reset () -{ - if (plugin) { - plugin->reset (); - } -} - -int -AudioAnalyser::analyse (const string& path, Readable* src, uint32_t channel) -{ - ofstream ofile; - Plugin::FeatureSet features; - int ret = -1; - bool done = false; - Sample* data = 0; - nframes64_t len = src->readable_length(); - nframes64_t pos = 0; - float* bufs[1] = { 0 }; - string tmp_path; - - if (!path.empty()) { - - /* store data in tmp file, not the real one */ - - tmp_path = path; - tmp_path += ".tmp"; - - ofile.open (tmp_path.c_str()); - if (!ofile) { - goto out; - } - } - - data = new Sample[bufsize]; - bufs[0] = data; - - while (!done) { - - nframes64_t to_read; - - /* read from source */ - - to_read = min ((len - pos), bufsize); - - if (src->read (data, pos, to_read, channel) != to_read) { - goto out; - } - - /* zero fill buffer if necessary */ - - if (to_read != bufsize) { - memset (data + to_read, 0, (bufsize - to_read) * sizeof (Sample)); - } - - features = plugin->process (bufs, RealTime::fromSeconds ((double) pos / sample_rate)); - - if (use_features (features, (path.empty() ? 0 : &ofile))) { - goto out; - } - - pos += min (stepsize, to_read); - - if (pos >= len) { - done = true; - } - } - - /* finish up VAMP plugin */ - - features = plugin->getRemainingFeatures (); - - if (use_features (features, (path.empty() ? &ofile : 0))) { - goto out; - } - - ret = 0; - - out: - /* works even if it has not been opened */ - ofile.close (); - - if (ret) { - g_remove (tmp_path.c_str()); - } else if (!path.empty()) { - /* move the data file to the requested path */ - g_rename (tmp_path.c_str(), path.c_str()); - } - - if (data) { - delete [] data; - } - - return ret; -} - diff --git a/libs/ardour/audioengine.cc b/libs/ardour/audioengine.cc deleted file mode 100644 index 8bbed46733..0000000000 --- a/libs/ardour/audioengine.cc +++ /dev/null @@ -1,1379 +0,0 @@ -/* - 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. - -*/ - -#include <unistd.h> -#include <cerrno> -#include <vector> -#include <exception> -#include <stdexcept> -#include <sstream> - -#include <glibmm/timer.h> -#include <pbd/pthread_utils.h> -#include <pbd/stacktrace.h> -#include <pbd/unknown_type.h> - -#include <midi++/jack.h> - -#include <ardour/audioengine.h> -#include <ardour/buffer.h> -#include <ardour/port.h> -#include <ardour/jack_audio_port.h> -#include <ardour/jack_midi_port.h> -#include <ardour/audio_port.h> -#include <ardour/session.h> -#include <ardour/cycle_timer.h> -#include <ardour/utils.h> -#ifdef VST_SUPPORT -#include <fst.h> -#endif - -#include <ardour/timestamps.h> - -#include "i18n.h" - -using namespace std; -using namespace ARDOUR; -using namespace PBD; - -gint AudioEngine::m_meter_exit; - -static void -ardour_jack_error (const char* msg) -{ - error << "JACK: " << msg << endmsg; -} - -AudioEngine::AudioEngine (string client_name) - : ports (new Ports) -{ - session = 0; - session_remove_pending = false; - _running = false; - _has_run = false; - last_monitor_check = 0; - monitor_check_interval = max_frames; - _processed_frames = 0; - _freewheeling = false; - _usecs_per_cycle = 0; - _jack = 0; - _frame_rate = 0; - _buffer_size = 0; - _freewheeling = false; - _freewheel_thread_registered = false; - - m_meter_thread = 0; - g_atomic_int_set (&m_meter_exit, 0); - - if (connect_to_jack (client_name)) { - throw NoBackendAvailable (); - } - Port::set_engine (this); -} - -AudioEngine::~AudioEngine () -{ - { - Glib::Mutex::Lock tm (_process_lock); - session_removed.signal (); - - if (_running) { - jack_client_close (_jack); - } - - stop_metering_thread (); - } -} - -jack_client_t* -AudioEngine::jack() const -{ - return _jack; -} - -void -_thread_init_callback (void *arg) -{ - /* make sure that anybody who needs to know about this thread - knows about it. - */ - - PBD::ThreadCreatedWithRequestSize (pthread_self(), X_("Audioengine"), 4096); - MIDI::JACK_MidiPort::set_process_thread (pthread_self()); -} - -int -AudioEngine::start () -{ - if (!_running) { - - if (session) { - nframes_t blocksize = jack_get_buffer_size (_jack); - - BootMessage (_("Connect session to engine")); - - session->set_block_size (blocksize); - session->set_frame_rate (jack_get_sample_rate (_jack)); - - /* page in as much of the session process code as we - can before we really start running. - */ - - session->process (blocksize); - session->process (blocksize); - session->process (blocksize); - session->process (blocksize); - session->process (blocksize); - session->process (blocksize); - session->process (blocksize); - session->process (blocksize); - } - - _processed_frames = 0; - last_monitor_check = 0; - - jack_on_shutdown (_jack, halted, this); - jack_set_graph_order_callback (_jack, _graph_order_callback, this); - jack_set_thread_init_callback (_jack, _thread_init_callback, this); - jack_set_process_callback (_jack, _process_callback, this); - jack_set_sample_rate_callback (_jack, _sample_rate_callback, this); - jack_set_buffer_size_callback (_jack, _bufsize_callback, this); - jack_set_xrun_callback (_jack, _xrun_callback, this); - jack_set_sync_callback (_jack, _jack_sync_callback, this); - jack_set_freewheel_callback (_jack, _freewheel_callback, this); - - if (Config->get_jack_time_master()) { - jack_set_timebase_callback (_jack, 0, _jack_timebase_callback, this); - } - - if (jack_activate (_jack) == 0) { - _running = true; - _has_run = true; - Running(); /* EMIT SIGNAL */ - } else { - // error << _("cannot activate JACK client") << endmsg; - } - - start_metering_thread(); - } - - return _running ? 0 : -1; -} - -int -AudioEngine::stop (bool forever) -{ - if (_running) { - _running = false; - stop_metering_thread (); - if (forever) { - jack_client_t* foo = _jack; - _jack = 0; - jack_client_close (foo); - } else { - jack_deactivate (_jack); - } - Stopped(); /* EMIT SIGNAL */ - } - - return _running ? -1 : 0; -} - - -bool -AudioEngine::get_sync_offset (nframes_t& offset) const -{ - -#ifdef HAVE_JACK_VIDEO_SUPPORT - - jack_position_t pos; - - (void) jack_transport_query (_jack, &pos); - - if (pos.valid & JackVideoFrameOffset) { - offset = pos.video_offset; - return true; - } - -#endif - - return false; -} - -void -AudioEngine::_jack_timebase_callback (jack_transport_state_t state, nframes_t nframes, - jack_position_t* pos, int new_position, void *arg) -{ - static_cast<AudioEngine*> (arg)->jack_timebase_callback (state, nframes, pos, new_position); -} - -void -AudioEngine::jack_timebase_callback (jack_transport_state_t state, nframes_t nframes, - jack_position_t* pos, int new_position) -{ - if (_jack && session && session->synced_to_jack()) { - session->jack_timebase_callback (state, nframes, pos, new_position); - } -} - -int -AudioEngine::_jack_sync_callback (jack_transport_state_t state, jack_position_t* pos, void* arg) -{ - return static_cast<AudioEngine*> (arg)->jack_sync_callback (state, pos); -} - -int -AudioEngine::jack_sync_callback (jack_transport_state_t state, jack_position_t* pos) -{ - if (_jack && session) { - return session->jack_sync_callback (state, pos); - } - - return true; -} - -int -AudioEngine::_xrun_callback (void *arg) -{ - AudioEngine* ae = static_cast<AudioEngine*> (arg); - if (ae->jack()) { - ae->Xrun (); /* EMIT SIGNAL */ - } - return 0; -} - -int -AudioEngine::_graph_order_callback (void *arg) -{ - AudioEngine* ae = static_cast<AudioEngine*> (arg); - if (ae->jack()) { - ae->GraphReordered (); /* EMIT SIGNAL */ - } - return 0; -} - -/** Wrapped which is called by JACK as its process callback. It is just - * here to get us back into C++ land by calling AudioEngine::process_callback() - * @param nframes Number of frames passed by JACK. - * @param arg User argument passed by JACK, which will be the AudioEngine*. - */ -int -AudioEngine::_process_callback (nframes_t nframes, void *arg) -{ - return static_cast<AudioEngine *> (arg)->process_callback (nframes); -} - -void -AudioEngine::_freewheel_callback (int onoff, void *arg) -{ - static_cast<AudioEngine*>(arg)->_freewheeling = onoff; -} - -/** Method called by JACK (via _process_callback) which says that there - * is work to be done. - * @param nframes Number of frames to process. - */ -int -AudioEngine::process_callback (nframes_t nframes) -{ - // CycleTimer ct ("AudioEngine::process"); - Glib::Mutex::Lock tm (_process_lock, Glib::TRY_LOCK); - - /// The number of frames that will have been processed when we've finished - nframes_t next_processed_frames; - - /* handle wrap around of total frames counter */ - - if (max_frames - _processed_frames < nframes) { - next_processed_frames = nframes - (max_frames - _processed_frames); - } else { - next_processed_frames = _processed_frames + nframes; - } - - if (!tm.locked() || session == 0) { - /* return having done nothing */ - _processed_frames = next_processed_frames; - return 0; - } - - if (session_remove_pending) { - /* perform the actual session removal */ - session = 0; - session_remove_pending = false; - session_removed.signal(); - _processed_frames = next_processed_frames; - return 0; - } - - if (_freewheeling) { - /* emit the Freewheel signal and stop freewheeling in the event of trouble */ - if (Freewheel (nframes)) { - cerr << "Freewheeling returned non-zero!\n"; - _freewheeling = false; - jack_set_freewheel (_jack, false); - } - return 0; - } - - boost::shared_ptr<Ports> p = ports.reader(); - - // Prepare ports (ie read data if necessary) - for (Ports::iterator i = p->begin(); i != p->end(); ++i) { - (*i)->cycle_start (nframes, 0); - } - - if (session) { - session->process (nframes); - } - - // Finalize ports (ie write data if necessary) - - for (Ports::iterator i = p->begin(); i != p->end(); ++i) { - (*i)->cycle_end (nframes, 0); - } - - if (!_running) { - _processed_frames = next_processed_frames; - return 0; - } - - if (last_monitor_check + monitor_check_interval < next_processed_frames) { - - boost::shared_ptr<Ports> p = ports.reader(); - - for (Ports::iterator i = p->begin(); i != p->end(); ++i) { - - Port *port = (*i); - bool x; - - if (port->_last_monitor != (x = port->monitoring_input ())) { - port->_last_monitor = x; - /* XXX I think this is dangerous, due to - a likely mutex in the signal handlers ... - */ - port->MonitorInputChanged (x); /* EMIT SIGNAL */ - } - } - last_monitor_check = next_processed_frames; - } - - if (session->silent()) { - - boost::shared_ptr<Ports> p = ports.reader(); - - for (Ports::iterator i = p->begin(); i != p->end(); ++i) { - - Port *port = (*i); - - if (port->sends_output()) { - port->get_buffer().silence(nframes); - } - } - } - - _processed_frames = next_processed_frames; - return 0; -} - -int -AudioEngine::_sample_rate_callback (nframes_t nframes, void *arg) -{ - return static_cast<AudioEngine *> (arg)->jack_sample_rate_callback (nframes); -} - -int -AudioEngine::jack_sample_rate_callback (nframes_t nframes) -{ - _frame_rate = nframes; - _usecs_per_cycle = (int) floor ((((double) frames_per_cycle() / nframes)) * 1000000.0); - - /* check for monitor input change every 1/10th of second */ - - monitor_check_interval = nframes / 10; - last_monitor_check = 0; - - if (session) { - session->set_frame_rate (nframes); - } - - SampleRateChanged (nframes); /* EMIT SIGNAL */ - - return 0; -} - -int -AudioEngine::_bufsize_callback (nframes_t nframes, void *arg) -{ - return static_cast<AudioEngine *> (arg)->jack_bufsize_callback (nframes); -} - -int -AudioEngine::jack_bufsize_callback (nframes_t nframes) -{ - _buffer_size = nframes; - _usecs_per_cycle = (int) floor ((((double) nframes / frame_rate())) * 1000000.0); - last_monitor_check = 0; - - boost::shared_ptr<Ports> p = ports.reader(); - - for (Ports::iterator i = p->begin(); i != p->end(); ++i) { - (*i)->reset(); - } - - if (session) { - session->set_block_size (_buffer_size); - } - - return 0; -} - -void -AudioEngine::stop_metering_thread () -{ - if (m_meter_thread) { - g_atomic_int_set (&m_meter_exit, 1); - m_meter_thread->join (); - m_meter_thread = 0; - } -} - -void -AudioEngine::start_metering_thread () -{ - if (m_meter_thread == 0) { - g_atomic_int_set (&m_meter_exit, 0); - m_meter_thread = Glib::Thread::create (sigc::mem_fun(this, &AudioEngine::meter_thread), - 500000, true, true, Glib::THREAD_PRIORITY_NORMAL); - } -} - -void -AudioEngine::meter_thread () -{ - while (true) { - Glib::usleep (10000); /* 1/100th sec interval */ - if (g_atomic_int_get(&m_meter_exit)) { - break; - } - IO::update_meters (); - } -} - -void -AudioEngine::set_session (Session *s) -{ - Glib::Mutex::Lock pl (_process_lock); - - if (!session) { - - session = s; - - nframes_t blocksize = jack_get_buffer_size (_jack); - - /* page in as much of the session process code as we - can before we really start running. - */ - - boost::shared_ptr<Ports> p = ports.reader(); - - for (Ports::iterator i = p->begin(); i != p->end(); ++i) { - (*i)->cycle_start (blocksize, 0); - } - - s->process (blocksize); - s->process (blocksize); - s->process (blocksize); - s->process (blocksize); - s->process (blocksize); - s->process (blocksize); - s->process (blocksize); - s->process (blocksize); - - for (Ports::iterator i = p->begin(); i != p->end(); ++i) { - (*i)->cycle_end (blocksize, 0); - } - } -} - -void -AudioEngine::remove_session () -{ - Glib::Mutex::Lock lm (_process_lock); - - if (_running) { - - if (session) { - session_remove_pending = true; - session_removed.wait(_process_lock); - } - - } else { - session = 0; - } - - //FIXME: Preliminary bugfix for http://tracker.ardour.org/view.php?id=1985 - //remove_all_ports (); -} - -void -AudioEngine::port_registration_failure (const std::string& portname) -{ - string full_portname = jack_client_name; - full_portname += ':'; - full_portname += portname; - - - jack_port_t* p = jack_port_by_name (_jack, full_portname.c_str()); - string reason; - - if (p) { - reason = _("a port with this name already exists: check for duplicated track/bus names"); - } else { - reason = _("unknown error"); - } - - throw PortRegistrationFailure (string_compose (_("AudioEngine: cannot register port \"%1\": %2"), portname, reason).c_str()); -} - -Port * -AudioEngine::register_port (DataType dtype, const string& portname, bool input, bool publish) -{ - Port* newport = 0; - - /*cerr << "trying to register port with name " << portname << endl;*/ - try { - if (dtype == DataType::AUDIO) { - newport = new AudioPort (portname, (input ? Port::IsInput : Port::IsOutput), publish, frames_per_cycle()); - } else if (dtype == DataType::MIDI) { - newport = new MidiPort (portname, (input ? Port::IsInput : Port::IsOutput), publish, frames_per_cycle()); - } else { - throw unknown_type(); - } - - /*cerr << "successfully got port " << portname << " with address " << newport << endl;*/ - - RCUWriter<Ports> writer (ports); - boost::shared_ptr<Ports> ps = writer.get_copy (); - /*cerr << "Address of ports list: " << ps << endl - << "Ports set size before insert: " << ps->size() << endl;*/ - ps->insert (ps->begin(), newport); - /*cerr << "Ports set size after insert: " << ps->size() << endl;*/ - - /* writer goes out of scope, forces update */ - - return newport; - } - - catch (...) { - throw PortRegistrationFailure("unable to create port (unknown type?)"); - } -} - -Port* -AudioEngine::get_port (const std::string& full_name) -{ - boost::shared_ptr<Ports> p = ports.reader(); - - for (Ports::iterator i = p->begin(); i != p->end(); ++i) { - //cerr << "comparing port name '" << (*i)->name() << "' with '" << full_name << "'" << endl; - if ((*i)->name() == full_name) { - return *i; - } - } - return 0; -} - - -Port * -AudioEngine::register_input_port (DataType type, const string& portname, bool publish) -{ - return register_port (type, portname, true, publish); -} - -Port * -AudioEngine::register_output_port (DataType type, const string& portname, bool publish) -{ - return register_port (type, portname, false, publish); -} - -int -AudioEngine::unregister_port (Port& port) -{ - /* caller must hold process lock */ - - cerr << "about to unregister Port xx x" << &port << "\n"; - - if (!_running) { - /* probably happening when the engine has been halted by JACK, - in which case, there is nothing we can do here. - */ - cerr << "not running\n"; - return 0; - } - - { - cerr << "before getcopy\n"; - - RCUWriter<Ports> writer (ports); - boost::shared_ptr<Ports> ps = writer.get_copy (); - - cerr << "Ports set size: " << ps.get()->size() << endl; - - for (Ports::iterator i = ps->begin(); i != ps->end(); ++i) { - cerr << "before delete" << endl; - if ((*i) == &port) { - cerr << "About to delete " << &port << endl; - delete *i; - ps->erase (i); - cerr << "After erasing ports size: " << ps->size(); - break; - } - } - - /* writer goes out of scope, forces update */ - } - - cerr << "before remove_connections\n"; - remove_connections_for (port); - - return 0; -} - -int -AudioEngine::connect (const string& source, const string& destination) -{ - int ret; - - if (!_running) { - if (!_has_run) { - fatal << _("connect called before engine was started") << endmsg; - /*NOTREACHED*/ - } else { - return -1; - } - } - - string s = make_port_name_non_relative (source); - string d = make_port_name_non_relative (destination); - - //cerr << "Trying to connect source: " << s << " with destination " << d << endl; - - Port* src = get_port (s); - Port* dst = get_port (d); - - if (src && dst) { - - /* both ports are known to us, so do the internal connect stuff */ - - if ((ret = src->connect (*dst)) == 0) { - ret = dst->connect (*src); - } - - } else if (src || dst) { - - /* one port is known to us, try to connect it to something external */ - - PortConnectableByName* pcn; - string other; - - if (src) { - pcn = dynamic_cast<PortConnectableByName*>(src); - other = d; - } else { - pcn = dynamic_cast<PortConnectableByName*>(dst); - other = s; - } - - if (pcn) { - ret = pcn->connect (other); - } else { - ret = -1; - } - - } else { - - /* neither port is known to us, and this API isn't intended for use as a general patch bay */ - - ret = -1; - - } - - if (ret > 0) { - error << string_compose(_("AudioEngine: connection already exists: %1 (%2) to %3 (%4)"), - source, s, destination, d) - << endmsg; - } else if (ret < 0) { - error << string_compose(_("AudioEngine: cannot connect %1 (%2) to %3 (%4)"), - source, s, destination, d) - << endmsg; - } - - return ret; -} - -int -AudioEngine::disconnect (const string& source, const string& destination) -{ - int ret; - - if (!_running) { - if (!_has_run) { - fatal << _("disconnect called before engine was started") << endmsg; - /*NOTREACHED*/ - } else { - return -1; - } - } - - string s = make_port_name_non_relative (source); - string d = make_port_name_non_relative (destination); - - //cerr << "trying to disconnect port '" << s << "' from port '" << d << endl; - - Port* src = get_port (s); - Port* dst = get_port (d); - - if (src && dst) { - - /* both ports are known to us, so do the internal connect stuff */ - - if ((ret = src->disconnect (*dst)) == 0) { - ret = dst->disconnect (*src); - } - - } else if (src || dst) { - - /* one port is known to us, try to connect it to something external */ - - - PortConnectableByName* pcn; - string other; - - if (src) { - pcn = dynamic_cast<PortConnectableByName*>(src); - other = d; - } else { - pcn = dynamic_cast<PortConnectableByName*>(dst); - other = s; - } - - if (pcn) { - ret = pcn->disconnect (other); - } else { - ret = -1; - } - - } else { - - /* neither port is known to us, and this API isn't intended for use as a general patch bay */ - - ret = -1; - - } - - return ret; -} - -int -AudioEngine::disconnect (Port& port) -{ - if (!_running) { - if (!_has_run) { - fatal << _("disconnect called before engine was started") << endmsg; - /*NOTREACHED*/ - } else { - return -1; - } - } - - return port.disconnect_all (); -} - -ARDOUR::nframes_t -AudioEngine::frame_rate () -{ - if (_jack) { - if (_frame_rate == 0) { - return (_frame_rate = jack_get_sample_rate (_jack)); - } else { - return _frame_rate; - } - } else { - fatal << X_("programming error: AudioEngine::frame_rate() called while disconnected from JACK") - << endmsg; - /*NOTREACHED*/ - return 0; - } -} - -ARDOUR::nframes_t -AudioEngine::frames_per_cycle () -{ - if (_jack) { - if (_buffer_size == 0) { - return (_buffer_size = jack_get_buffer_size (_jack)); - } else { - return _buffer_size; - } - } else { - fatal << X_("programming error: AudioEngine::frame_rate() called while disconnected from JACK") - << endmsg; - /*NOTREACHED*/ - return 0; - } -} - -/** Get a port by name. - * Note this can return NULL, it will NOT create a port if it is not found (any more). - */ -Port * -AudioEngine::get_port_by_name (const string& portname, bool keep) const -{ - Glib::Mutex::Lock lm (_process_lock); - - if (!_running) { - if (!_has_run) { - fatal << _("get_port_by_name() called before engine was started") << endmsg; - /*NOTREACHED*/ - } else { - return 0; - } - } - - boost::shared_ptr<Ports> pr = ports.reader(); - - for (Ports::iterator i = pr->begin(); i != pr->end(); ++i) { - if (portname == (*i)->name()) { - return (*i); - } - } - - return 0; -} - -const char ** -AudioEngine::get_ports (const string& port_name_pattern, const string& type_name_pattern, uint32_t flags) -{ - if (!_running) { - if (!_has_run) { - fatal << _("get_ports called before engine was started") << endmsg; - /*NOTREACHED*/ - } else { - return 0; - } - } - return jack_get_ports (_jack, port_name_pattern.c_str(), type_name_pattern.c_str(), flags); -} - -void -AudioEngine::halted (void *arg) -{ - AudioEngine* ae = static_cast<AudioEngine *> (arg); - bool was_running = ae->_running; - - ae->stop_metering_thread (); - - ae->_running = false; - ae->_buffer_size = 0; - ae->_frame_rate = 0; - ae->_jack = 0; - - if (was_running) { - ae->Halted(); /* EMIT SIGNAL */ - } -} - -bool -AudioEngine::can_request_hardware_monitoring () -{ - const char ** ports; - - if (!_jack) { - return 0; - } - - if ((ports = jack_get_ports (_jack, NULL, JACK_DEFAULT_AUDIO_TYPE, JackPortCanMonitor)) == 0) { - return false; - } - - free (ports); - - return true; -} - - -uint32_t -AudioEngine::n_physical_outputs () const -{ - const char ** ports; - uint32_t i = 0; - - if (!_jack) { - return 0; - } - - if ((ports = jack_get_ports (_jack, NULL, NULL, JackPortIsPhysical|JackPortIsInput)) == 0) { - return 0; - } - - for (i = 0; ports[i]; ++i); - free (ports); - - return i; -} - -uint32_t -AudioEngine::n_physical_inputs () const -{ - const char ** ports; - uint32_t i = 0; - - if (!_jack) { - return 0; - } - - if ((ports = jack_get_ports (_jack, NULL, NULL, JackPortIsPhysical|JackPortIsOutput)) == 0) { - return 0; - } - - if (ports) { - for (i = 0; ports[i]; ++i); - free (ports); - } - return i; -} - -void -AudioEngine::get_physical_inputs (vector<string>& ins) -{ - const char ** ports; - uint32_t i = 0; - - if (!_jack) { - return; - } - - if ((ports = jack_get_ports (_jack, NULL, NULL, JackPortIsPhysical|JackPortIsOutput)) == 0) { - return; - } - - if (ports) { - for (i = 0; ports[i]; ++i) { - ins.push_back (ports[i]); - } - free (ports); - } -} - -void -AudioEngine::get_physical_outputs (vector<string>& outs) -{ - const char ** ports; - uint32_t i = 0; - - if (!_jack) { - return; - } - - if ((ports = jack_get_ports (_jack, NULL, NULL, JackPortIsPhysical|JackPortIsInput)) == 0) { - return; - } - - if (ports) { - for (i = 0; ports[i]; ++i) { - outs.push_back (ports[i]); - } - free (ports); - } -} - -string -AudioEngine::get_nth_physical (DataType type, uint32_t n, int flag) -{ - const char ** ports; - uint32_t i; - string ret; - - assert(type != DataType::NIL); - - if (!_running || !_jack) { - if (!_has_run) { - fatal << _("get_nth_physical called before engine was started") << endmsg; - /*NOTREACHED*/ - } else { - return ""; - } - } - - ports = jack_get_ports (_jack, NULL, type.to_jack_type(), JackPortIsPhysical|flag); - - if (ports == 0) { - return ""; - } - - for (i = 0; i < n && ports[i]; ++i); - - if (ports[i]) { - ret = ports[i]; - } - - free ((char *) ports); - - return ret; -} - -ARDOUR::nframes_t -AudioEngine::get_port_total_latency (const Port& port) -{ - return port.total_latency (); -} - -void -AudioEngine::update_total_latency (const Port& port) -{ - if (!_jack) { - fatal << _("update_total_latency() called with no JACK client connection") << endmsg; - /*NOTREACHED*/ - } - - if (!_running) { - if (!_has_run) { - fatal << _("update_total_latency() called before engine was started") << endmsg; - /*NOTREACHED*/ - } - } - - port.recompute_total_latency (); -} - -void -AudioEngine::transport_stop () -{ - // cerr << "tell JACK to stop\n"; - if (_jack) { - jack_transport_stop (_jack); - } -} - -void -AudioEngine::transport_start () -{ - // cerr << "tell JACK to start\n"; - if (_jack) { - jack_transport_start (_jack); - } -} - -void -AudioEngine::transport_locate (nframes_t where) -{ - // cerr << "tell JACK to locate to " << where << endl; - if (_jack) { - jack_transport_locate (_jack, where); - } -} - -AudioEngine::TransportState -AudioEngine::transport_state () -{ - if (_jack) { - jack_position_t pos; - return (TransportState) jack_transport_query (_jack, &pos); - } else { - return (TransportState) JackTransportStopped; - } -} - -int -AudioEngine::reset_timebase () -{ - if (_jack) { - if (Config->get_jack_time_master()) { - return jack_set_timebase_callback (_jack, 0, _jack_timebase_callback, this); - } else { - return jack_release_timebase (_jack); - } - } else { - return -1; - } -} - -int -AudioEngine::freewheel (bool onoff) -{ - if (_jack) { - - if (onoff) { - _freewheel_thread_registered = false; - } - - return jack_set_freewheel (_jack, onoff); - - } else { - return -1; - } -} - -void -AudioEngine::remove_all_ports () -{ - /* process lock MUST be held */ - - { - RCUWriter<Ports> writer (ports); - boost::shared_ptr<Ports> ps = writer.get_copy (); - ps->clear (); - } -} - -void -AudioEngine::remove_connections_for (Port& port) -{ - for (PortConnections::iterator i = port_connections.begin(); i != port_connections.end(); ) { - PortConnections::iterator tmp; - - tmp = i; - ++tmp; - - if ((*i).first == port.name()) { - port_connections.erase (i); - } - - i = tmp; - } -} - - -#ifdef HAVE_JACK_CLIENT_OPEN - -int -AudioEngine::connect_to_jack (string client_name) -{ - jack_options_t options = JackNullOption; - jack_status_t status; - const char *server_name = NULL; - - jack_client_name = client_name; /* might be reset below */ - _jack = jack_client_open (jack_client_name.c_str(), options, &status, server_name); - - if (_jack == NULL) { - - if (status & JackServerFailed) { - error << _("Unable to connect to JACK server") << endmsg; - } - - // error message is not useful here - return -1; - } - - if (status & JackServerStarted) { - info << _("JACK server started") << endmsg; - } - - if (status & JackNameNotUnique) { - jack_client_name = jack_get_client_name (_jack); - } - - jack_set_error_function (ardour_jack_error); - - return 0; -} - -#else - -int -AudioEngine::connect_to_jack (string client_name) -{ - jack_client_name = client_name; - - if ((_jack = jack_client_new (client_name.c_str())) == NULL) { - return -1; - } - - return 0; -} - -#endif /* HAVE_JACK_CLIENT_OPEN */ - -int -AudioEngine::disconnect_from_jack () -{ - if (_jack == 0) { - return 0; - } - - jack_client_close (_jack); - - _buffer_size = 0; - _frame_rate = 0; - - if (_running) { - stop_metering_thread (); - _running = false; - Stopped(); /* EMIT SIGNAL */ - } - - _jack = 0; - return 0; -} - -int -AudioEngine::reconnect_to_jack () -{ - if (_jack) { - disconnect_from_jack (); - /* XXX give jackd a chance */ - Glib::usleep (250000); - } - - if (connect_to_jack (jack_client_name)) { - error << _("failed to connect to JACK") << endmsg; - return -1; - } - - Ports::iterator i; - - boost::shared_ptr<Ports> p = ports.reader (); - - for (i = p->begin(); i != p->end(); ++i) { - if ((*i)->reestablish ()) { - break; - } - } - - if (i != p->end()) { - /* failed */ - remove_all_ports (); - return -1; - } - - - if (session) { - session->reset_jack_connection (_jack); - nframes_t blocksize = jack_get_buffer_size (_jack); - session->set_block_size (blocksize); - session->set_frame_rate (jack_get_sample_rate (_jack)); - } - - last_monitor_check = 0; - - jack_on_shutdown (_jack, halted, this); - jack_set_graph_order_callback (_jack, _graph_order_callback, this); - jack_set_thread_init_callback (_jack, _thread_init_callback, this); - jack_set_process_callback (_jack, _process_callback, this); - jack_set_sample_rate_callback (_jack, _sample_rate_callback, this); - jack_set_buffer_size_callback (_jack, _bufsize_callback, this); - jack_set_xrun_callback (_jack, _xrun_callback, this); - jack_set_sync_callback (_jack, _jack_sync_callback, this); - jack_set_freewheel_callback (_jack, _freewheel_callback, this); - - if (Config->get_jack_time_master()) { - jack_set_timebase_callback (_jack, 0, _jack_timebase_callback, this); - } - - if (jack_activate (_jack) == 0) { - _running = true; - _has_run = true; - } else { - return -1; - } - - /* re-establish connections */ - - for (i = p->begin(); i != p->end(); ++i) { - (*i)->reconnect (); - } - - Running (); /* EMIT SIGNAL*/ - - start_metering_thread (); - - return 0; -} - -int -AudioEngine::request_buffer_size (nframes_t nframes) -{ - if (_jack) { - - if (nframes == jack_get_buffer_size (_jack)) { - return 0; - } - - return jack_set_buffer_size (_jack, nframes); - - } else { - return -1; - } -} - -void -AudioEngine::update_total_latencies () -{ -#ifdef HAVE_JACK_RECOMPUTE_LATENCIES - jack_recompute_total_latencies (_jack); -#endif -} - -string -AudioEngine::make_port_name_relative (string portname) -{ - string::size_type len; - string::size_type n; - - len = portname.length(); - - for (n = 0; n < len; ++n) { - if (portname[n] == ':') { - break; - } - } - - if ((n != len) && (portname.substr (0, n) == jack_client_name)) { - return portname.substr (n+1); - } - - return portname; -} - -string -AudioEngine::make_port_name_non_relative (string portname) -{ - string str; - - if (portname.find_first_of (':') != string::npos) { - return portname; - } - - str = jack_client_name; - str += ':'; - str += portname; - - return str; -} - -bool -AudioEngine::is_realtime () const -{ - if (_jack) { - return jack_is_realtime (_jack); - } else { - return false; - } -} diff --git a/libs/ardour/audiofilesource.cc b/libs/ardour/audiofilesource.cc deleted file mode 100644 index 026cb3e7c0..0000000000 --- a/libs/ardour/audiofilesource.cc +++ /dev/null @@ -1,759 +0,0 @@ -/* - 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. - -*/ - -#include <vector> - -#include <sys/time.h> -#include <sys/stat.h> -#include <stdio.h> // for rename(), sigh -#include <unistd.h> -#include <fcntl.h> -#include <errno.h> - -#include <pbd/convert.h> -#include <pbd/basename.h> -#include <pbd/mountpoint.h> -#include <pbd/stl_delete.h> -#include <pbd/strsplit.h> -#include <pbd/shortpath.h> -#include <pbd/enumwriter.h> - -#include <sndfile.h> - -#include <glibmm/miscutils.h> -#include <glibmm/fileutils.h> -#include <glibmm/thread.h> - -#include <ardour/audiofilesource.h> -#include <ardour/sndfile_helpers.h> -#include <ardour/sndfilesource.h> -#include <ardour/session.h> -#include <ardour/session_directory.h> -#include <ardour/source_factory.h> -#include <ardour/filename_extensions.h> - -// if these headers come before sigc++ is included -// the parser throws ObjC++ errors. (nil is a keyword) -#ifdef HAVE_COREAUDIO -#include <ardour/coreaudiosource.h> -#include <AudioToolbox/ExtendedAudioFile.h> -#include <AudioToolbox/AudioFormat.h> -#endif // HAVE_COREAUDIO - -#include "i18n.h" - -using namespace ARDOUR; -using namespace PBD; -using namespace Glib; - -ustring AudioFileSource::peak_dir = ""; -ustring AudioFileSource::search_path; - -sigc::signal<void> AudioFileSource::HeaderPositionOffsetChanged; -uint64_t AudioFileSource::header_position_offset = 0; - -/* XXX maybe this too */ -char AudioFileSource::bwf_serial_number[13] = "000000000000"; - -struct SizedSampleBuffer { - nframes_t size; - Sample* buf; - - SizedSampleBuffer (nframes_t sz) : size (sz) { - buf = new Sample[size]; - } - - ~SizedSampleBuffer() { - delete [] buf; - } -}; - -Glib::StaticPrivate<SizedSampleBuffer> thread_interleave_buffer = GLIBMM_STATIC_PRIVATE_INIT; - -AudioFileSource::AudioFileSource (Session& s, ustring path, Flag flags) - : AudioSource (s, path), _flags (flags), - _channel (0) -{ - /* constructor used for existing external to session files. file must exist already */ - _is_embedded = AudioFileSource::determine_embeddedness (path); - - if (init (path, true)) { - throw failed_constructor (); - } - -} - -AudioFileSource::AudioFileSource (Session& s, ustring path, Flag flags, SampleFormat samp_format, HeaderFormat hdr_format) - : AudioSource (s, path), _flags (flags), - _channel (0) -{ - /* constructor used for new internal-to-session files. file cannot exist */ - _is_embedded = false; - - if (init (path, false)) { - throw failed_constructor (); - } -} - -AudioFileSource::AudioFileSource (Session& s, const XMLNode& node, bool must_exist) - : AudioSource (s, node), _flags (Flag (Writable|CanRename)) - /* _channel is set in set_state() or init() */ -{ - /* constructor used for existing internal-to-session files. file must exist */ - - if (set_state (node)) { - throw failed_constructor (); - } - - string foo = _name; - - if (init (foo, must_exist)) { - throw failed_constructor (); - } -} - -AudioFileSource::~AudioFileSource () -{ - if (removable()) { - unlink (_path.c_str()); - unlink (peakpath.c_str()); - } -} - -bool -AudioFileSource::determine_embeddedness (ustring path) -{ - return (path.find("/") == 0); -} - -bool -AudioFileSource::removable () const -{ - return (_flags & Removable) && ((_flags & RemoveAtDestroy) || ((_flags & RemovableIfEmpty) && length() == 0)); -} - -int -AudioFileSource::init (ustring pathstr, bool must_exist) -{ - _length = 0; - timeline_position = 0; - _peaks_built = false; - - if (!find (pathstr, must_exist, file_is_new, _channel)) { - throw non_existent_source (); - } - - if (file_is_new && must_exist) { - return -1; - } - - return 0; -} - - -ustring -AudioFileSource::peak_path (ustring audio_path) -{ - ustring base; - - base = PBD::basename_nosuffix (audio_path); - base += '%'; - base += (char) ('A' + _channel); - - return _session.peak_path (base); -} - -ustring -AudioFileSource::find_broken_peakfile (ustring peak_path, ustring audio_path) -{ - ustring str; - - /* check for the broken location in use by 2.0 for several months */ - - str = broken_peak_path (audio_path); - - if (Glib::file_test (str, Glib::FILE_TEST_EXISTS)) { - - if (is_embedded()) { - - /* it would be nice to rename it but the nature of - the bug means that we can't reliably use it. - */ - - peak_path = str; - - } else { - /* all native files are mono, so we can just rename - it. - */ - ::rename (str.c_str(), peak_path.c_str()); - } - - } else { - /* Nasty band-aid for older sessions that were created before we - used libsndfile for all audio files. - */ - - - str = old_peak_path (audio_path); - if (Glib::file_test (str, Glib::FILE_TEST_EXISTS)) { - peak_path = str; - } - } - - return peak_path; -} - -ustring -AudioFileSource::broken_peak_path (ustring audio_path) -{ - return _session.peak_path (audio_path); -} - -ustring -AudioFileSource::old_peak_path (ustring audio_path) -{ - /* XXX hardly bombproof! fix me */ - - struct stat stat_file; - struct stat stat_mount; - - ustring mp = mountpoint (audio_path); - - stat (audio_path.c_str(), &stat_file); - stat (mp.c_str(), &stat_mount); - - char buf[32]; -#ifdef __APPLE__ - snprintf (buf, sizeof (buf), "%u-%u-%d.peak", stat_mount.st_ino, stat_file.st_ino, _channel); -#else - snprintf (buf, sizeof (buf), "%ld-%ld-%d.peak", stat_mount.st_ino, stat_file.st_ino, _channel); -#endif - - ustring res = peak_dir; - res += buf; - res += peakfile_suffix; - - return res; -} - -bool -AudioFileSource::get_soundfile_info (ustring path, SoundFileInfo& _info, string& error_msg) -{ -#ifdef HAVE_COREAUDIO - if (CoreAudioSource::get_soundfile_info (path, _info, error_msg) == 0) { - return true; - } -#endif // HAVE_COREAUDIO - - if (SndFileSource::get_soundfile_info (path, _info, error_msg) != 0) { - return true; - } - - return false; -} - -XMLNode& -AudioFileSource::get_state () -{ - XMLNode& root (AudioSource::get_state()); - char buf[32]; - root.add_property (X_("flags"), enum_2_string (_flags)); - snprintf (buf, sizeof (buf), "%u", _channel); - root.add_property (X_("channel"), buf); - return root; -} - -int -AudioFileSource::set_state (const XMLNode& node) -{ - const XMLProperty* prop; - - if (AudioSource::set_state (node)) { - return -1; - } - - if ((prop = node.property (X_("flags"))) != 0) { - _flags = Flag (string_2_enum (prop->value(), _flags)); - } else { - _flags = Flag (0); - - } - - if ((prop = node.property (X_("channel"))) != 0) { - _channel = atoi (prop->value()); - } else { - _channel = 0; - } - - if ((prop = node.property (X_("name"))) != 0) { - _is_embedded = AudioFileSource::determine_embeddedness (prop->value()); - } else { - _is_embedded = false; - } - - if ((prop = node.property (X_("destructive"))) != 0) { - /* old style, from the period when we had DestructiveFileSource */ - _flags = Flag (_flags | Destructive); - } - - return 0; -} - -void -AudioFileSource::mark_for_remove () -{ - // This operation is not allowed for sources for destructive tracks or embedded files. - // Fortunately mark_for_remove() is never called for embedded files. This function - // must be fixed if that ever happens. - if (_flags & Destructive) { - return; - } - - _flags = Flag (_flags | Removable | RemoveAtDestroy); -} - -void -AudioFileSource::mark_streaming_write_completed () -{ - if (!writable()) { - return; - } - - /* XXX notice that we're readers of _peaks_built - but we must hold a solid lock on PeaksReady. - */ - - Glib::Mutex::Lock lm (_lock); - - if (_peaks_built) { - PeaksReady (); /* EMIT SIGNAL */ - } -} - -void -AudioFileSource::mark_take (ustring id) -{ - if (writable()) { - _take_id = id; - } -} - -int -AudioFileSource::move_to_trash (const ustring& trash_dir_name) -{ - if (is_embedded()) { - cerr << "tried to move an embedded region to trash" << endl; - return -1; - } - - ustring newpath; - - if (!writable()) { - return -1; - } - - /* don't move the file across filesystems, just - stick it in the `trash_dir_name' directory - on whichever filesystem it was already on. - */ - - newpath = Glib::path_get_dirname (_path); - newpath = Glib::path_get_dirname (newpath); - - cerr << "from " << _path << " dead dir looks like " << newpath << endl; - - newpath += '/'; - newpath += trash_dir_name; - newpath += '/'; - newpath += Glib::path_get_basename (_path); - - if (access (newpath.c_str(), F_OK) == 0) { - - /* the new path already exists, try versioning */ - - char buf[PATH_MAX+1]; - int version = 1; - ustring newpath_v; - - snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version); - newpath_v = buf; - - while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) { - snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version); - newpath_v = buf; - } - - if (version == 999) { - error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"), - newpath) - << endmsg; - } else { - newpath = newpath_v; - } - - } else { - - /* it doesn't exist, or we can't read it or something */ - - } - - if (::rename (_path.c_str(), newpath.c_str()) != 0) { - error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"), - _path, newpath, strerror (errno)) - << endmsg; - return -1; - } - - if (::unlink (peakpath.c_str()) != 0) { - error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"), - peakpath, _path, strerror (errno)) - << endmsg; - /* try to back out */ - rename (newpath.c_str(), _path.c_str()); - return -1; - } - - _path = newpath; - peakpath = ""; - - /* file can not be removed twice, since the operation is not idempotent */ - - _flags = Flag (_flags & ~(RemoveAtDestroy|Removable|RemovableIfEmpty)); - - return 0; -} - -bool -AudioFileSource::find (ustring& pathstr, bool must_exist, bool& isnew, uint16_t& chan) -{ - ustring::size_type pos; - bool ret = false; - - isnew = false; - - if (pathstr[0] != '/') { - - /* non-absolute pathname: find pathstr in search path */ - - vector<ustring> dirs; - int cnt; - ustring fullpath; - ustring keeppath; - - if (search_path.length() == 0) { - error << _("FileSource: search path not set") << endmsg; - goto out; - } - - split (search_path, dirs, ':'); - - cnt = 0; - - for (vector<ustring>::iterator i = dirs.begin(); i != dirs.end(); ++i) { - - fullpath = *i; - if (fullpath[fullpath.length()-1] != '/') { - fullpath += '/'; - } - - fullpath += pathstr; - - /* i (paul) made a nasty design error by using ':' as a special character in - Ardour 0.99 .. this hack tries to make things sort of work. - */ - - if ((pos = pathstr.find_last_of (':')) != ustring::npos) { - - if (Glib::file_test (fullpath, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_REGULAR)) { - - /* its a real file, no problem */ - - keeppath = fullpath; - ++cnt; - - } else { - - if (must_exist) { - - /* might be an older session using file:channel syntax. see if the version - without the :suffix exists - */ - - ustring shorter = pathstr.substr (0, pos); - fullpath = *i; - - if (fullpath[fullpath.length()-1] != '/') { - fullpath += '/'; - } - - fullpath += shorter; - - if (Glib::file_test (pathstr, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_REGULAR)) { - chan = atoi (pathstr.substr (pos+1)); - pathstr = shorter; - keeppath = fullpath; - ++cnt; - } - - } else { - - /* new derived file (e.g. for timefx) being created in a newer session */ - - } - } - - } else { - - if (Glib::file_test (fullpath, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_REGULAR)) { - keeppath = fullpath; - ++cnt; - } - } - } - - if (cnt > 1) { - - error << string_compose (_("FileSource: \"%1\" is ambigous when searching %2\n\t"), pathstr, search_path) << endmsg; - goto out; - - } else if (cnt == 0) { - - if (must_exist) { - error << string_compose(_("Filesource: cannot find required file (%1): while searching %2"), pathstr, search_path) << endmsg; - goto out; - } else { - isnew = true; - } - } - - _name = pathstr; - _path = keeppath; - ret = true; - - } else { - - /* external files and/or very very old style sessions include full paths */ - - /* ugh, handle ':' situation */ - - if ((pos = pathstr.find_last_of (':')) != ustring::npos) { - - ustring shorter = pathstr.substr (0, pos); - - if (Glib::file_test (shorter, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_REGULAR)) { - chan = atoi (pathstr.substr (pos+1)); - pathstr = shorter; - } - } - - _path = pathstr; - - if (is_embedded()) { - _name = pathstr; - } else { - _name = pathstr.substr (pathstr.find_last_of ('/') + 1); - } - - if (!Glib::file_test (pathstr, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_REGULAR)) { - - /* file does not exist or we cannot read it */ - - if (must_exist) { - error << string_compose(_("Filesource: cannot find required file (%1): %2"), _path, strerror (errno)) << endmsg; - goto out; - } - - if (errno != ENOENT) { - error << string_compose(_("Filesource: cannot check for existing file (%1): %2"), _path, strerror (errno)) << endmsg; - goto out; - } - - /* a new file */ - - isnew = true; - ret = true; - - } else { - - /* already exists */ - - ret = true; - - } - } - - out: - return ret; -} - -void -AudioFileSource::set_search_path (ustring p) -{ - search_path = p; -} - -void -AudioFileSource::set_header_position_offset (nframes_t offset) -{ - header_position_offset = offset; - HeaderPositionOffsetChanged (); -} - -void -AudioFileSource::set_timeline_position (int64_t pos) -{ - timeline_position = pos; -} - -void -AudioFileSource::set_allow_remove_if_empty (bool yn) -{ - if (!writable()) { - return; - } - - if (yn) { - _flags = Flag (_flags | RemovableIfEmpty); - } else { - _flags = Flag (_flags & ~RemovableIfEmpty); - } -} - -int -AudioFileSource::set_source_name (ustring newname, bool destructive) -{ - Glib::Mutex::Lock lm (_lock); - ustring oldpath = _path; - ustring newpath = Session::change_audio_path_by_name (oldpath, _name, newname, destructive); - - if (newpath.empty()) { - error << string_compose (_("programming error: %1"), "cannot generate a changed audio path") << endmsg; - return -1; - } - - // Test whether newpath exists, if yes notify the user but continue. - if (access(newpath.c_str(),F_OK) == 0) { - error << _("Programming error! Ardour tried to rename a file over another file! It's safe to continue working, but please report this to the developers.") << endmsg; - return -1; - } - - if (rename (oldpath.c_str(), newpath.c_str()) != 0) { - error << string_compose (_("cannot rename audio file %1 to %2"), _name, newpath) << endmsg; - return -1; - } - - _name = Glib::path_get_basename (newpath); - _path = newpath; - - return rename_peakfile (peak_path (_path)); -} - -bool -AudioFileSource::is_empty (Session& s, ustring path) -{ - SoundFileInfo info; - string err; - - if (!get_soundfile_info (path, info, err)) { - /* dangerous: we can't get info, so assume that its not empty */ - return false; - } - - return info.length == 0; -} - -int -AudioFileSource::setup_peakfile () -{ - if (!(_flags & NoPeakFile)) { - return initialize_peakfile (file_is_new, _path); - } else { - return 0; - } -} - -bool -AudioFileSource::safe_file_extension(ustring file) -{ - const char* suffixes[] = { - ".wav", ".WAV", - ".aiff", ".AIFF", - ".caf", ".CAF", - ".aif", ".AIF", - ".amb", ".AMB", - ".snd", ".SND", - ".au", ".AU", - ".raw", ".RAW", - ".sf", ".SF", - ".cdr", ".CDR", - ".smp", ".SMP", - ".maud", ".MAUD", - ".vwe", ".VWE", - ".paf", ".PAF", - ".voc", ".VOC", -#ifdef HAVE_FLAC - ".flac", ".FLAC", -#endif // HAVE_FLAC -#ifdef HAVE_COREAUDIO - ".mp3", ".MP3", - ".aac", ".AAC", - ".mp4", ".MP4", -#endif // HAVE_COREAUDIO - }; - - for (size_t n = 0; n < sizeof(suffixes)/sizeof(suffixes[0]); ++n) { - if (file.rfind (suffixes[n]) == file.length() - strlen (suffixes[n])) { - return true; - } - } - - return false; -} - -void -AudioFileSource::mark_immutable () -{ - /* destructive sources stay writable, and their other flags don't - change. - */ - - if (!(_flags & Destructive)) { - _flags = Flag (_flags & ~(Writable|Removable|RemovableIfEmpty|RemoveAtDestroy|CanRename)); - } -} - - -Sample* -AudioFileSource::get_interleave_buffer (nframes_t size) -{ - SizedSampleBuffer* ssb; - - if ((ssb = thread_interleave_buffer.get()) == 0) { - ssb = new SizedSampleBuffer (size); - thread_interleave_buffer.set (ssb); - } - - if (ssb->size < size) { - ssb = new SizedSampleBuffer (size); - thread_interleave_buffer.set (ssb); - } - - return ssb->buf; -} diff --git a/libs/ardour/audioregion.cc b/libs/ardour/audioregion.cc deleted file mode 100644 index f5f04eac6d..0000000000 --- a/libs/ardour/audioregion.cc +++ /dev/null @@ -1,1402 +0,0 @@ -/* - 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. - -*/ - -#include <cmath> -#include <climits> -#include <cfloat> -#include <algorithm> - -#include <set> - -#include <sigc++/bind.h> -#include <sigc++/class_slot.h> - -#include <glibmm/thread.h> - -#include <pbd/basename.h> -#include <pbd/xml++.h> -#include <pbd/stacktrace.h> -#include <pbd/enumwriter.h> -#include <pbd/convert.h> - -#include <ardour/audioregion.h> -#include <ardour/session.h> -#include <ardour/gain.h> -#include <ardour/dB.h> -#include <ardour/playlist.h> -#include <ardour/audiofilesource.h> -#include <ardour/region_factory.h> -#include <ardour/runtime_functions.h> -#include <ardour/transient_detector.h> - -#include "i18n.h" -#include <locale.h> - -using namespace std; -using namespace ARDOUR; -using namespace PBD; - -/* a Session will reset these to its chosen defaults by calling AudioRegion::set_default_fade() */ - -Change AudioRegion::FadeInChanged = ARDOUR::new_change(); -Change AudioRegion::FadeOutChanged = ARDOUR::new_change(); -Change AudioRegion::FadeInActiveChanged = ARDOUR::new_change(); -Change AudioRegion::FadeOutActiveChanged = ARDOUR::new_change(); -Change AudioRegion::EnvelopeActiveChanged = ARDOUR::new_change(); -Change AudioRegion::ScaleAmplitudeChanged = ARDOUR::new_change(); -Change AudioRegion::EnvelopeChanged = ARDOUR::new_change(); - -void -AudioRegion::init () -{ - _scale_amplitude = 1.0; - - set_default_fades (); - set_default_envelope (); - - listen_to_my_curves (); - listen_to_my_sources (); -} - -/* constructor for use by derived types only */ -AudioRegion::AudioRegion (Session& s, nframes_t start, nframes_t length, string name) - : Region (s, start, length, name, DataType::AUDIO) - , _fade_in (new AutomationList(Parameter(FadeInAutomation), 0.0, 2.0, 1.0)) - , _fade_out (new AutomationList(Parameter(FadeOutAutomation), 0.0, 2.0, 1.0)) - , _envelope (new AutomationList(Parameter(EnvelopeAutomation), 0.0, 2.0, 1.0)) -{ - init (); -} - -/** Basic AudioRegion constructor (one channel) */ -AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, nframes_t start, nframes_t length) - : Region (src, start, length, PBD::basename_nosuffix(src->name()), DataType::AUDIO, 0, Region::Flag(Region::DefaultFlags|Region::External)) - , _fade_in (new AutomationList(Parameter(FadeInAutomation), 0.0, 2.0, 1.0)) - , _fade_out (new AutomationList(Parameter(FadeOutAutomation), 0.0, 2.0, 1.0)) - , _envelope (new AutomationList(Parameter(EnvelopeAutomation), 0.0, 2.0, 1.0)) -{ - boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (src); - if (afs) { - afs->HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioRegion::source_offset_changed)); - } - - init (); -} - -/* Basic AudioRegion constructor (one channel) */ -AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, nframes_t start, nframes_t length, const string& name, layer_t layer, Flag flags) - : Region (src, start, length, name, DataType::AUDIO, layer, flags) - , _fade_in (new AutomationList(Parameter(FadeInAutomation), 0.0, 2.0, 1.0)) - , _fade_out (new AutomationList(Parameter(FadeOutAutomation), 0.0, 2.0, 1.0)) - , _envelope (new AutomationList(Parameter(EnvelopeAutomation), 0.0, 2.0, 1.0)) -{ - boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (src); - if (afs) { - afs->HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioRegion::source_offset_changed)); - } - - init (); -} - -/* Basic AudioRegion constructor (many channels) */ -AudioRegion::AudioRegion (const SourceList& srcs, nframes_t start, nframes_t length, const string& name, layer_t layer, Flag flags) - : Region (srcs, start, length, name, DataType::AUDIO, layer, flags) - , _fade_in (new AutomationList(Parameter(FadeInAutomation), 0.0, 2.0, 1.0)) - , _fade_out (new AutomationList(Parameter(FadeOutAutomation), 0.0, 2.0, 1.0)) - , _envelope (new AutomationList(Parameter(EnvelopeAutomation), 0.0, 2.0, 1.0)) -{ - init (); - listen_to_my_sources (); -} - -/** Create a new AudioRegion, that is part of an existing one */ -AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, nframes_t offset, nframes_t length, const string& name, layer_t layer, Flag flags) - : Region (other, offset, length, name, layer, flags) - , _fade_in (new AutomationList(Parameter(FadeInAutomation), 0.0, 2.0, 1.0)) - , _fade_out (new AutomationList(Parameter(FadeOutAutomation), 0.0, 2.0, 1.0)) - , _envelope (new AutomationList(Parameter(EnvelopeAutomation), 0.0, 2.0, 1.0)) -{ - set<boost::shared_ptr<Source> > unique_srcs; - - for (SourceList::const_iterator i= other->_sources.begin(); i != other->_sources.end(); ++i) { - _sources.push_back (*i); - - pair<set<boost::shared_ptr<Source> >::iterator,bool> result; - - result = unique_srcs.insert (*i); - - if (result.second) { - boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (*i); - if (afs) { - afs->HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioRegion::source_offset_changed)); - } - } - } - - /* return to default fades if the existing ones are too long */ - init (); - - if (_flags & LeftOfSplit) { - if (_fade_in->back()->when >= _length) { - set_default_fade_in (); - } else { - _fade_in_disabled = other->_fade_in_disabled; - } - set_default_fade_out (); - _flags = Flag (_flags & ~Region::LeftOfSplit); - } - - if (_flags & RightOfSplit) { - if (_fade_out->back()->when >= _length) { - set_default_fade_out (); - } else { - _fade_out_disabled = other->_fade_out_disabled; - } - set_default_fade_in (); - _flags = Flag (_flags & ~Region::RightOfSplit); - } - - _scale_amplitude = other->_scale_amplitude; - - assert(_type == DataType::AUDIO); - listen_to_my_sources (); -} - -AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other) - : Region (other) - , _fade_in (new AutomationList(Parameter(FadeInAutomation), 0.0, 2.0, 1.0)) - , _fade_out (new AutomationList(Parameter(FadeOutAutomation), 0.0, 2.0, 1.0)) - , _envelope (new AutomationList(Parameter(EnvelopeAutomation), 0.0, 2.0, 1.0)) -{ - assert(_type == DataType::AUDIO); - _scale_amplitude = other->_scale_amplitude; - _envelope = other->_envelope; - - set_default_fades (); - - listen_to_my_curves (); - listen_to_my_sources (); -} - -AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, const XMLNode& node) - : Region (src, node) - , _fade_in (new AutomationList(Parameter(FadeInAutomation), 0.0, 2.0, 1.0)) - , _fade_out (new AutomationList(Parameter(FadeOutAutomation), 0.0, 2.0, 1.0)) - , _envelope (new AutomationList(Parameter(EnvelopeAutomation), 0.0, 2.0, 1.0)) -{ - boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (src); - if (afs) { - afs->HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioRegion::source_offset_changed)); - } - - init (); - - if (set_state (node)) { - throw failed_constructor(); - } - - assert(_type == DataType::AUDIO); - listen_to_my_sources (); -} - -AudioRegion::AudioRegion (SourceList& srcs, const XMLNode& node) - : Region (srcs, node) - , _fade_in (new AutomationList(Parameter(FadeInAutomation), 0.0, 2.0, 1.0)) - , _fade_out (new AutomationList(Parameter(FadeOutAutomation), 0.0, 2.0, 1.0)) - , _envelope (new AutomationList(Parameter(EnvelopeAutomation), 0.0, 2.0, 1.0)) -{ - init (); - - if (set_state (node)) { - throw failed_constructor(); - } - - assert(_type == DataType::AUDIO); - listen_to_my_sources (); -} - -AudioRegion::~AudioRegion () -{ -} - -void -AudioRegion::listen_to_my_sources () -{ - for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) { - (*i)->AnalysisChanged.connect (mem_fun (*this, &AudioRegion::invalidate_transients)); - } -} - -void -AudioRegion::listen_to_my_curves () -{ - _envelope->StateChanged.connect (mem_fun (*this, &AudioRegion::envelope_changed)); - _fade_in->StateChanged.connect (mem_fun (*this, &AudioRegion::fade_in_changed)); - _fade_out->StateChanged.connect (mem_fun (*this, &AudioRegion::fade_out_changed)); -} - -void -AudioRegion::set_envelope_active (bool yn) -{ - if (envelope_active() != yn) { - char buf[64]; - if (yn) { - snprintf (buf, sizeof (buf), "envelope active"); - _flags = Flag (_flags|EnvelopeActive); - } else { - snprintf (buf, sizeof (buf), "envelope off"); - _flags = Flag (_flags & ~EnvelopeActive); - } - send_change (EnvelopeActiveChanged); - } -} - -ARDOUR::nframes_t -AudioRegion::read_peaks (PeakData *buf, nframes_t npeaks, nframes_t offset, nframes_t cnt, uint32_t chan_n, double samples_per_unit) const -{ - if (chan_n >= _sources.size()) { - return 0; - } - - if (audio_source(chan_n)->read_peaks (buf, npeaks, offset, cnt, samples_per_unit)) { - return 0; - } else { - if (_scale_amplitude != 1.0) { - for (nframes_t n = 0; n < npeaks; ++n) { - buf[n].max *= _scale_amplitude; - buf[n].min *= _scale_amplitude; - } - } - return cnt; - } -} - -nframes64_t -AudioRegion::read (Sample* buf, nframes64_t position, nframes64_t cnt, int channel) const -{ - /* raw read, no fades, no gain, nada */ - return _read_at (_sources, _length, buf, 0, 0, _position + position, cnt, channel, 0, 0, true); -} - -nframes_t -AudioRegion::read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, nframes_t position, - nframes_t cnt, - uint32_t chan_n, nframes_t read_frames, nframes_t skip_frames) const -{ - /* regular diskstream/butler read complete with fades etc */ - return _read_at (_sources, _length, buf, mixdown_buffer, gain_buffer, position, cnt, chan_n, read_frames, skip_frames, false); -} - -nframes_t -AudioRegion::master_read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, nframes_t position, - nframes_t cnt, uint32_t chan_n) const -{ - return _read_at (_master_sources, _master_sources.front()->length(), buf, mixdown_buffer, gain_buffer, position, cnt, chan_n, 0, 0); -} - -nframes_t -AudioRegion::_read_at (const SourceList& srcs, nframes_t limit, - Sample *buf, Sample *mixdown_buffer, float *gain_buffer, - nframes_t position, nframes_t cnt, - uint32_t chan_n, - nframes_t read_frames, - nframes_t skip_frames, - bool raw) const -{ - nframes_t internal_offset; - nframes_t buf_offset; - nframes_t to_read; - - if (muted() && !raw) { - return 0; /* read nothing */ - } - - /* precondition: caller has verified that we cover the desired section */ - - if (position < _position) { - internal_offset = 0; - buf_offset = _position - position; - cnt -= buf_offset; - } else { - internal_offset = position - _position; - buf_offset = 0; - } - - if (internal_offset >= limit) { - return 0; /* read nothing */ - } - - if ((to_read = min (cnt, limit - internal_offset)) == 0) { - return 0; /* read nothing */ - } - - if (opaque() || raw) { - /* overwrite whatever is there */ - mixdown_buffer = buf + buf_offset; - } else { - mixdown_buffer += buf_offset; - } - - if (!raw) { - _read_data_count = 0; - } - - if (chan_n < n_channels()) { - - boost::shared_ptr<AudioSource> src = audio_source(chan_n); - if (src->read (mixdown_buffer, _start + internal_offset, to_read) != to_read) { - return 0; /* "read nothing" */ - } - - if (!raw) { - _read_data_count += src->read_data_count(); - } - - } else { - - /* track is N-channel, this region has less channels; silence the ones - we don't have. - */ - - memset (mixdown_buffer, 0, sizeof (Sample) * cnt); - - /* no fades required */ - - if (!raw) { - goto merge; - } - } - - /* fade in */ - - if (!raw) { - - if (_flags & FadeIn) { - - nframes_t fade_in_length = (nframes_t) _fade_in->back()->when; - - /* see if this read is within the fade in */ - - if (internal_offset < fade_in_length) { - - nframes_t fi_limit; - - fi_limit = min (to_read, fade_in_length - internal_offset); - - _fade_in->curve().get_vector (internal_offset, internal_offset+fi_limit, gain_buffer, fi_limit); - - for (nframes_t n = 0; n < fi_limit; ++n) { - mixdown_buffer[n] *= gain_buffer[n]; - } - } - } - - /* fade out */ - - if (_flags & FadeOut) { - - /* see if some part of this read is within the fade out */ - - /* ................. >| REGION - limit - - { } FADE - fade_out_length - ^ - limit - fade_out_length - |--------------| - ^internal_offset - ^internal_offset + to_read - - we need the intersection of [internal_offset,internal_offset+to_read] with - [limit - fade_out_length, limit] - - */ - - - nframes_t fade_out_length = (nframes_t) _fade_out->back()->when; - nframes_t fade_interval_start = max(internal_offset, limit-fade_out_length); - nframes_t fade_interval_end = min(internal_offset + to_read, limit); - - if (fade_interval_end > fade_interval_start) { - /* (part of the) the fade out is in this buffer */ - - nframes_t fo_limit = fade_interval_end - fade_interval_start; - nframes_t curve_offset = fade_interval_start - (limit-fade_out_length); - nframes_t fade_offset = fade_interval_start - internal_offset; - - _fade_out->curve().get_vector (curve_offset, curve_offset+fo_limit, gain_buffer, fo_limit); - - for (nframes_t n = 0, m = fade_offset; n < fo_limit; ++n, ++m) { - mixdown_buffer[m] *= gain_buffer[n]; - } - } - - } - - /* Regular gain curves */ - - if (envelope_active()) { - _envelope->curve().get_vector (internal_offset, internal_offset + to_read, gain_buffer, to_read); - - if (_scale_amplitude != 1.0f) { - for (nframes_t n = 0; n < to_read; ++n) { - mixdown_buffer[n] *= gain_buffer[n] * _scale_amplitude; - } - } else { - for (nframes_t n = 0; n < to_read; ++n) { - mixdown_buffer[n] *= gain_buffer[n]; - } - } - } else if (_scale_amplitude != 1.0f) { - Session::apply_gain_to_buffer (mixdown_buffer, to_read, _scale_amplitude); - } - - merge: - - if (!opaque()) { - - /* gack. the things we do for users. - */ - - buf += buf_offset; - - for (nframes_t n = 0; n < to_read; ++n) { - buf[n] += mixdown_buffer[n]; - } - } - } - - return to_read; -} - -XMLNode& -AudioRegion::state (bool full) -{ - XMLNode& node (Region::state (full)); - XMLNode *child; - char buf[64]; - char buf2[64]; - LocaleGuard lg (X_("POSIX")); - - node.add_property ("flags", enum_2_string (_flags)); - - snprintf (buf, sizeof(buf), "%.12g", _scale_amplitude); - node.add_property ("scale-gain", buf); - - // XXX these should move into Region - - for (uint32_t n=0; n < _sources.size(); ++n) { - snprintf (buf2, sizeof(buf2), "source-%d", n); - _sources[n]->id().print (buf, sizeof (buf)); - node.add_property (buf2, buf); - } - - for (uint32_t n=0; n < _master_sources.size(); ++n) { - snprintf (buf2, sizeof(buf2), "master-source-%d", n); - _master_sources[n]->id().print (buf, sizeof (buf)); - node.add_property (buf2, buf); - } - - snprintf (buf, sizeof (buf), "%u", (uint32_t) _sources.size()); - node.add_property ("channels", buf); - - if (full) { - - child = node.add_child (X_("FadeIn")); - - if ((_flags & DefaultFadeIn)) { - child->add_property (X_("default"), X_("yes")); - } else { - child->add_child_nocopy (_fade_in->get_state ()); - } - - child->add_property (X_("active"), _fade_in_disabled ? X_("no") : X_("yes")); - - child = node.add_child (X_("FadeOut")); - - if ((_flags & DefaultFadeOut)) { - child->add_property (X_("default"), X_("yes")); - } else { - child->add_child_nocopy (_fade_out->get_state ()); - } - - child->add_property (X_("active"), _fade_out_disabled ? X_("no") : X_("yes")); - } - - child = node.add_child ("Envelope"); - - if (full) { - bool default_env = false; - - // If there are only two points, the points are in the start of the region and the end of the region - // so, if they are both at 1.0f, that means the default region. - - if (_envelope->size() == 2 && - _envelope->front()->value == 1.0f && - _envelope->back()->value==1.0f) { - if (_envelope->front()->when == 0 && _envelope->back()->when == _length) { - default_env = true; - } - } - - if (default_env) { - child->add_property ("default", "yes"); - } else { - child->add_child_nocopy (_envelope->get_state ()); - } - - } else { - child->add_property ("default", "yes"); - } - - if (full && _extra_xml) { - node.add_child_copy (*_extra_xml); - } - - return node; -} - -int -AudioRegion::set_live_state (const XMLNode& node, Change& what_changed, bool send) -{ - const XMLNodeList& nlist = node.children(); - const XMLProperty *prop; - LocaleGuard lg (X_("POSIX")); - - Region::set_live_state (node, what_changed, false); - - uint32_t old_flags = _flags; - - if ((prop = node.property ("flags")) != 0) { - _flags = Flag (string_2_enum (prop->value(), _flags)); - - //_flags = Flag (strtol (prop->value().c_str(), (char **) 0, 16)); - - _flags = Flag (_flags & ~Region::LeftOfSplit); - _flags = Flag (_flags & ~Region::RightOfSplit); - } - - if ((old_flags ^ _flags) & Muted) { - what_changed = Change (what_changed|MuteChanged); - } - if ((old_flags ^ _flags) & Opaque) { - what_changed = Change (what_changed|OpacityChanged); - } - if ((old_flags ^ _flags) & Locked) { - what_changed = Change (what_changed|LockChanged); - } - - if ((prop = node.property ("scale-gain")) != 0) { - _scale_amplitude = atof (prop->value().c_str()); - what_changed = Change (what_changed|ScaleAmplitudeChanged); - } else { - _scale_amplitude = 1.0; - } - - /* Now find envelope description and other misc child items */ - - for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) { - - XMLNode *child; - XMLProperty *prop; - - child = (*niter); - - if (child->name() == "Envelope") { - - _envelope->clear (); - - if ((prop = child->property ("default")) != 0 || _envelope->set_state (*child)) { - set_default_envelope (); - } - - _envelope->set_max_xval (_length); - _envelope->truncate_end (_length); - - } else if (child->name() == "FadeIn") { - - _fade_in->clear (); - - if ((prop = child->property ("default")) != 0 || (prop = child->property ("steepness")) != 0) { - set_default_fade_in (); - } else { - XMLNode* grandchild = child->child ("AutomationList"); - if (grandchild) { - _fade_in->set_state (*grandchild); - } - } - - if ((prop = child->property ("active")) != 0) { - if (prop->value() == "yes") { - set_fade_in_active (true); - } else { - set_fade_in_active (true); - } - } - - } else if (child->name() == "FadeOut") { - - _fade_out->clear (); - - if ((prop = child->property ("default")) != 0 || (prop = child->property ("steepness")) != 0) { - set_default_fade_out (); - } else { - XMLNode* grandchild = child->child ("AutomationList"); - if (grandchild) { - _fade_out->set_state (*grandchild); - } - } - - if ((prop = child->property ("active")) != 0) { - if (prop->value() == "yes") { - set_fade_out_active (true); - } else { - set_fade_out_active (false); - } - } - - } - } - - if (send) { - send_change (what_changed); - } - - return 0; -} - -int -AudioRegion::set_state (const XMLNode& node) -{ - /* Region::set_state() calls the virtual set_live_state(), - which will get us back to AudioRegion::set_live_state() - to handle the relevant stuff. - */ - - return Region::set_state (node); -} - -void -AudioRegion::set_fade_in_shape (FadeShape shape) -{ - set_fade_in (shape, (nframes_t) _fade_in->back()->when); -} - -void -AudioRegion::set_fade_out_shape (FadeShape shape) -{ - set_fade_out (shape, (nframes_t) _fade_out->back()->when); -} - -void -AudioRegion::set_fade_in (FadeShape shape, nframes_t len) -{ - _fade_in->freeze (); - _fade_in->clear (); - - switch (shape) { - case Linear: - _fade_in->fast_simple_add (0.0, 0.0); - _fade_in->fast_simple_add (len, 1.0); - break; - - case Fast: - _fade_in->fast_simple_add (0, 0); - _fade_in->fast_simple_add (len * 0.389401, 0.0333333); - _fade_in->fast_simple_add (len * 0.629032, 0.0861111); - _fade_in->fast_simple_add (len * 0.829493, 0.233333); - _fade_in->fast_simple_add (len * 0.9447, 0.483333); - _fade_in->fast_simple_add (len * 0.976959, 0.697222); - _fade_in->fast_simple_add (len, 1); - break; - - case Slow: - _fade_in->fast_simple_add (0, 0); - _fade_in->fast_simple_add (len * 0.0207373, 0.197222); - _fade_in->fast_simple_add (len * 0.0645161, 0.525); - _fade_in->fast_simple_add (len * 0.152074, 0.802778); - _fade_in->fast_simple_add (len * 0.276498, 0.919444); - _fade_in->fast_simple_add (len * 0.481567, 0.980556); - _fade_in->fast_simple_add (len * 0.767281, 1); - _fade_in->fast_simple_add (len, 1); - break; - - case LogA: - _fade_in->fast_simple_add (0, 0); - _fade_in->fast_simple_add (len * 0.0737327, 0.308333); - _fade_in->fast_simple_add (len * 0.246544, 0.658333); - _fade_in->fast_simple_add (len * 0.470046, 0.886111); - _fade_in->fast_simple_add (len * 0.652074, 0.972222); - _fade_in->fast_simple_add (len * 0.771889, 0.988889); - _fade_in->fast_simple_add (len, 1); - break; - - case LogB: - _fade_in->fast_simple_add (0, 0); - _fade_in->fast_simple_add (len * 0.304147, 0.0694444); - _fade_in->fast_simple_add (len * 0.529954, 0.152778); - _fade_in->fast_simple_add (len * 0.725806, 0.333333); - _fade_in->fast_simple_add (len * 0.847926, 0.558333); - _fade_in->fast_simple_add (len * 0.919355, 0.730556); - _fade_in->fast_simple_add (len, 1); - break; - } - - _fade_in->thaw (); - _fade_in_shape = shape; - - send_change (FadeInChanged); -} - -void -AudioRegion::set_fade_out (FadeShape shape, nframes_t len) -{ - _fade_out->freeze (); - _fade_out->clear (); - - switch (shape) { - case Fast: - _fade_out->fast_simple_add (len * 0, 1); - _fade_out->fast_simple_add (len * 0.023041, 0.697222); - _fade_out->fast_simple_add (len * 0.0553, 0.483333); - _fade_out->fast_simple_add (len * 0.170507, 0.233333); - _fade_out->fast_simple_add (len * 0.370968, 0.0861111); - _fade_out->fast_simple_add (len * 0.610599, 0.0333333); - _fade_out->fast_simple_add (len * 1, 0); - break; - - case LogA: - _fade_out->fast_simple_add (len * 0, 1); - _fade_out->fast_simple_add (len * 0.228111, 0.988889); - _fade_out->fast_simple_add (len * 0.347926, 0.972222); - _fade_out->fast_simple_add (len * 0.529954, 0.886111); - _fade_out->fast_simple_add (len * 0.753456, 0.658333); - _fade_out->fast_simple_add (len * 0.9262673, 0.308333); - _fade_out->fast_simple_add (len * 1, 0); - break; - - case Slow: - _fade_out->fast_simple_add (len * 0, 1); - _fade_out->fast_simple_add (len * 0.305556, 1); - _fade_out->fast_simple_add (len * 0.548611, 0.991736); - _fade_out->fast_simple_add (len * 0.759259, 0.931129); - _fade_out->fast_simple_add (len * 0.918981, 0.68595); - _fade_out->fast_simple_add (len * 0.976852, 0.22865); - _fade_out->fast_simple_add (len * 1, 0); - break; - - case LogB: - _fade_out->fast_simple_add (len * 0, 1); - _fade_out->fast_simple_add (len * 0.080645, 0.730556); - _fade_out->fast_simple_add (len * 0.277778, 0.289256); - _fade_out->fast_simple_add (len * 0.470046, 0.152778); - _fade_out->fast_simple_add (len * 0.695853, 0.0694444); - _fade_out->fast_simple_add (len * 1, 0); - break; - - case Linear: - _fade_out->fast_simple_add (len * 0, 1); - _fade_out->fast_simple_add (len * 1, 0); - break; - } - - _fade_out->thaw (); - _fade_out_shape = shape; - - send_change (FadeOutChanged); -} - -void -AudioRegion::set_fade_in_length (nframes_t len) -{ - if (len > _length) { - len = _length - 1; - } - - bool changed = _fade_in->extend_to (len); - - if (changed) { - _flags = Flag (_flags & ~DefaultFadeIn); - send_change (FadeInChanged); - } -} - -void -AudioRegion::set_fade_out_length (nframes_t len) -{ - if (len > _length) { - len = _length - 1; - } - - bool changed = _fade_out->extend_to (len); - - if (changed) { - _flags = Flag (_flags & ~DefaultFadeOut); - send_change (FadeOutChanged); - } -} - -void -AudioRegion::set_fade_in_active (bool yn) -{ - if (yn == (_flags & FadeIn)) { - return; - } - if (yn) { - _flags = Flag (_flags|FadeIn); - } else { - _flags = Flag (_flags & ~FadeIn); - } - - send_change (FadeInActiveChanged); -} - -void -AudioRegion::set_fade_out_active (bool yn) -{ - if (yn == (_flags & FadeOut)) { - return; - } - if (yn) { - _flags = Flag (_flags | FadeOut); - } else { - _flags = Flag (_flags & ~FadeOut); - } - - send_change (FadeOutActiveChanged); -} - -bool -AudioRegion::fade_in_is_default () const -{ - return _fade_in_shape == Linear && _fade_in->back()->when == 64; -} - -bool -AudioRegion::fade_out_is_default () const -{ - return _fade_out_shape == Linear && _fade_out->back()->when == 64; -} - -void -AudioRegion::set_default_fade_in () -{ - set_fade_in (Linear, 64); -} - -void -AudioRegion::set_default_fade_out () -{ - set_fade_out (Linear, 64); -} - -void -AudioRegion::set_default_fades () -{ - _fade_in_disabled = 0; - _fade_out_disabled = 0; - set_default_fade_in (); - set_default_fade_out (); -} - -void -AudioRegion::set_default_envelope () -{ - _envelope->freeze (); - _envelope->clear (); - _envelope->fast_simple_add (0, 1.0f); - _envelope->fast_simple_add (_length, 1.0f); - _envelope->thaw (); -} - -void -AudioRegion::recompute_at_end () -{ - /* our length has changed. recompute a new final point by interpolating - based on the the existing curve. - */ - - _envelope->freeze (); - _envelope->truncate_end (_length); - _envelope->set_max_xval (_length); - _envelope->thaw (); - - if (_fade_in->back()->when > _length) { - _fade_in->extend_to (_length); - send_change (FadeInChanged); - } - - if (_fade_out->back()->when > _length) { - _fade_out->extend_to (_length); - send_change (FadeOutChanged); - } -} - -void -AudioRegion::recompute_at_start () -{ - /* as above, but the shift was from the front */ - - _envelope->truncate_start (_length); - - if (_fade_in->back()->when > _length) { - _fade_in->extend_to (_length); - send_change (FadeInChanged); - } - - if (_fade_out->back()->when > _length) { - _fade_out->extend_to (_length); - send_change (FadeOutChanged); - } -} - -int -AudioRegion::separate_by_channel (Session& session, vector<boost::shared_ptr<AudioRegion> >& v) const -{ - SourceList srcs; - string new_name; - int n; - - if (_sources.size() < 2) { - return 0; - } - - n = 0; - - for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) { - - srcs.clear (); - srcs.push_back (*i); - - new_name = _name; - - if (_sources.size() == 2) { - if (n == 0) { - new_name += "-L"; - } else { - new_name += "-R"; - } - } else { - new_name += '-'; - new_name += ('0' + n + 1); - } - - /* create a copy with just one source. prevent if from being thought of as "whole file" even if - it covers the entire source file(s). - */ - - Flag f = Flag (_flags & ~WholeFile); - - boost::shared_ptr<Region> r = RegionFactory::create (srcs, _start, _length, new_name, _layer, f); - boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion> (r); - - v.push_back (ar); - - ++n; - } - - return 0; -} - -nframes_t -AudioRegion::read_raw_internal (Sample* buf, nframes_t pos, nframes_t cnt) const -{ - return audio_source()->read (buf, pos, cnt); -} - -int -AudioRegion::exportme (Session& session, ARDOUR::ExportSpecification& spec) -{ - const nframes_t blocksize = 4096; - nframes_t to_read; - int status = -1; - - spec.channels = _sources.size(); - - if (spec.prepare (blocksize, session.frame_rate())) { - goto out; - } - - spec.pos = 0; - spec.total_frames = _length; - - while (spec.pos < _length && !spec.stop) { - - - /* step 1: interleave */ - - to_read = min (_length - spec.pos, blocksize); - - if (spec.channels == 1) { - - if (read_raw_internal (spec.dataF, _start + spec.pos, to_read) != to_read) { - goto out; - } - - } else { - - Sample buf[blocksize]; - - for (uint32_t chan = 0; chan < spec.channels; ++chan) { - - if (audio_source(chan)->read (buf, _start + spec.pos, to_read) != to_read) { - goto out; - } - - for (nframes_t x = 0; x < to_read; ++x) { - spec.dataF[chan+(x*spec.channels)] = buf[x]; - } - } - } - - if (spec.process (to_read)) { - goto out; - } - - spec.pos += to_read; - spec.progress = (double) spec.pos /_length; - - } - - status = 0; - - out: - spec.running = false; - spec.status = status; - spec.clear(); - - return status; -} - -void -AudioRegion::set_scale_amplitude (gain_t g) -{ - boost::shared_ptr<Playlist> pl (playlist()); - - _scale_amplitude = g; - - /* tell the diskstream we're in */ - - if (pl) { - pl->Modified(); - } - - /* tell everybody else */ - - send_change (ScaleAmplitudeChanged); -} - -void -AudioRegion::normalize_to (float target_dB) -{ - const nframes_t blocksize = 64 * 1024; - Sample buf[blocksize]; - nframes_t fpos; - nframes_t fend; - nframes_t to_read; - double maxamp = 0; - gain_t target = dB_to_coefficient (target_dB); - - if (target == 1.0f) { - /* do not normalize to precisely 1.0 (0 dBFS), to avoid making it appear - that we may have clipped. - */ - target -= FLT_EPSILON; - } - - fpos = _start; - fend = _start + _length; - - /* first pass: find max amplitude */ - - while (fpos < fend) { - - uint32_t n; - - to_read = min (fend - fpos, blocksize); - - for (n = 0; n < n_channels(); ++n) { - - /* read it in */ - - if (read_raw_internal (buf, fpos, to_read) != to_read) { - return; - } - - maxamp = compute_peak (buf, to_read, maxamp); - } - - fpos += to_read; - }; - - if (maxamp == 0.0f) { - /* don't even try */ - return; - } - - if (maxamp == target) { - /* we can't do anything useful */ - return; - } - - /* compute scale factor */ - - _scale_amplitude = target/maxamp; - - /* tell the diskstream we're in */ - - boost::shared_ptr<Playlist> pl (playlist()); - - if (pl) { - pl->Modified(); - } - - /* tell everybody else */ - - send_change (ScaleAmplitudeChanged); -} - -void -AudioRegion::fade_in_changed () -{ - send_change (FadeInChanged); -} - -void -AudioRegion::fade_out_changed () -{ - send_change (FadeOutChanged); -} - -void -AudioRegion::envelope_changed () -{ - send_change (EnvelopeChanged); -} - -void -AudioRegion::suspend_fade_in () -{ - if (++_fade_in_disabled == 1) { - if (fade_in_is_default()) { - set_fade_in_active (false); - } - } -} - -void -AudioRegion::resume_fade_in () -{ - if (--_fade_in_disabled == 0 && _fade_in_disabled) { - set_fade_in_active (true); - } -} - -void -AudioRegion::suspend_fade_out () -{ - if (++_fade_out_disabled == 1) { - if (fade_out_is_default()) { - set_fade_out_active (false); - } - } -} - -void -AudioRegion::resume_fade_out () -{ - if (--_fade_out_disabled == 0 &&_fade_out_disabled) { - set_fade_out_active (true); - } -} - -bool -AudioRegion::speed_mismatch (float sr) const -{ - if (_sources.empty()) { - /* impossible, but ... */ - return false; - } - - float fsr = audio_source()->sample_rate(); - - return fsr != sr; -} - -void -AudioRegion::source_offset_changed () -{ - boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(_sources.front()); - - if (afs && afs->destructive()) { - // set_start (source()->natural_position(), this); - set_position (source()->natural_position(), this); - } -} - -boost::shared_ptr<AudioSource> -AudioRegion::audio_source (uint32_t n) const -{ - // Guaranteed to succeed (use a static cast for speed?) - return boost::dynamic_pointer_cast<AudioSource>(source(n)); -} - -int -AudioRegion::get_transients (AnalysisFeatureList& results, bool force_new) -{ - boost::shared_ptr<Playlist> pl = playlist(); - - if (!pl) { - return -1; - } - - if (_valid_transients && !force_new) { - results = _transients; - return 0; - } - - SourceList::iterator s; - - for (s = _sources.begin() ; s != _sources.end(); ++s) { - if (!(*s)->has_been_analysed()) { - cerr << "For " << name() << " source " << (*s)->name() << " has not been analyzed\n"; - break; - } - } - - if (s == _sources.end()) { - /* all sources are analyzed, merge data from each one */ - - for (s = _sources.begin() ; s != _sources.end(); ++s) { - - /* find the set of transients within the bounds of this region */ - - AnalysisFeatureList::iterator low = lower_bound ((*s)->transients.begin(), - (*s)->transients.end(), - _start); - - AnalysisFeatureList::iterator high = upper_bound ((*s)->transients.begin(), - (*s)->transients.end(), - _start + _length); - - /* and add them */ - - results.insert (results.end(), low, high); - } - - TransientDetector::cleanup_transients (results, pl->session().frame_rate(), 3.0); - - /* translate all transients to current position */ - - for (AnalysisFeatureList::iterator x = results.begin(); x != results.end(); ++x) { - (*x) -= _start; - (*x) += _position; - } - - _transients = results; - _valid_transients = true; - - return 0; - } - - /* no existing/complete transient info */ - - if (!Config->get_auto_analyse_audio()) { - pl->session().Dialog (_("\ -You have requested an operation that requires audio analysis.\n\n\ -You currently have \"auto-analyse-audio\" disabled, which means\n\ -that transient data must be generated every time it is required.\n\n\ -If you are doing work that will require transient data on a\n\ -regular basis, you should probably enable \"auto-analyse-audio\"\n\ -then quit ardour and restart.")); - } - - TransientDetector t (pl->session().frame_rate()); - bool existing_results = !results.empty(); - - _transients.clear (); - _valid_transients = false; - - for (uint32_t i = 0; i < n_channels(); ++i) { - - AnalysisFeatureList these_results; - - t.reset (); - - if (t.run ("", this, i, these_results)) { - return -1; - } - - /* translate all transients to give absolute position */ - - for (AnalysisFeatureList::iterator i = these_results.begin(); i != these_results.end(); ++i) { - (*i) += _position; - } - - /* merge */ - - _transients.insert (_transients.end(), these_results.begin(), these_results.end()); - } - - if (!results.empty()) { - if (existing_results) { - - /* merge our transients into the existing ones, then clean up - those. - */ - - results.insert (results.end(), _transients.begin(), _transients.end()); - TransientDetector::cleanup_transients (results, pl->session().frame_rate(), 3.0); - } - - /* make sure ours are clean too */ - - TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0); - - } else { - - TransientDetector::cleanup_transients (_transients, pl->session().frame_rate(), 3.0); - results = _transients; - } - - _valid_transients = true; - - return 0; -} - -extern "C" { - - int region_read_peaks_from_c (void *arg, uint32_t npeaks, uint32_t start, uint32_t cnt, intptr_t data, uint32_t n_chan, double samples_per_unit) -{ - return ((AudioRegion *) arg)->read_peaks ((PeakData *) data, (nframes_t) npeaks, (nframes_t) start, (nframes_t) cnt, n_chan,samples_per_unit); -} - -uint32_t region_length_from_c (void *arg) -{ - - return ((AudioRegion *) arg)->length(); -} - -uint32_t sourcefile_length_from_c (void *arg, double zoom_factor) -{ - return ( (AudioRegion *) arg)->audio_source()->available_peaks (zoom_factor) ; -} - -} /* extern "C" */ diff --git a/libs/ardour/audiosource.cc b/libs/ardour/audiosource.cc deleted file mode 100644 index 01dea08d3e..0000000000 --- a/libs/ardour/audiosource.cc +++ /dev/null @@ -1,932 +0,0 @@ -/* - 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. - -*/ - -#include <sys/stat.h> -#include <unistd.h> -#include <fcntl.h> -#include <poll.h> -#include <float.h> -#include <utime.h> -#include <cerrno> -#include <ctime> -#include <cmath> -#include <iomanip> -#include <fstream> -#include <algorithm> -#include <vector> - -#include <glibmm/fileutils.h> -#include <glibmm/miscutils.h> - -#include <pbd/xml++.h> -#include <pbd/pthread_utils.h> - -#include <ardour/audiosource.h> -#include <ardour/cycle_timer.h> -#include <ardour/session.h> -#include <ardour/transient_detector.h> - -#include "i18n.h" - -using namespace std; -using namespace ARDOUR; -using namespace PBD; -using Glib::ustring; - -bool AudioSource::_build_missing_peakfiles = false; -bool AudioSource::_build_peakfiles = false; - -#define _FPP 256 - -AudioSource::AudioSource (Session& s, ustring name) - : Source (s, name, DataType::AUDIO) -{ - _peaks_built = false; - _peak_byte_max = 0; - peakfile = -1; - _read_data_count = 0; - _write_data_count = 0; - peak_leftover_cnt = 0; - peak_leftover_size = 0; - peak_leftovers = 0; -} - -AudioSource::AudioSource (Session& s, const XMLNode& node) - : Source (s, node) -{ - - _peaks_built = false; - _peak_byte_max = 0; - peakfile = -1; - _read_data_count = 0; - _write_data_count = 0; - peak_leftover_cnt = 0; - peak_leftover_size = 0; - peak_leftovers = 0; - - if (set_state (node)) { - throw failed_constructor(); - } -} - -AudioSource::~AudioSource () -{ - /* shouldn't happen but make sure we don't leak file descriptors anyway */ - - if (peak_leftover_cnt) { - cerr << "AudioSource destroyed with leftover peak data pending" << endl; - } - - if (peakfile >= 0) { - ::close (peakfile); - } - - if (peak_leftovers) { - delete [] peak_leftovers; - } -} - -XMLNode& -AudioSource::get_state () -{ - XMLNode& node (Source::get_state()); - - if (_captured_for.length()) { - node.add_property ("captured-for", _captured_for); - } - - return node; -} - -int -AudioSource::set_state (const XMLNode& node) -{ - const XMLProperty* prop; - - Source::set_state (node); - - if ((prop = node.property ("captured-for")) != 0) { - _captured_for = prop->value(); - } - - return 0; -} - -/*********************************************************************** - PEAK FILE STUFF - ***********************************************************************/ - -bool -AudioSource::peaks_ready (sigc::slot<void> the_slot, sigc::connection& conn) const -{ - bool ret; - Glib::Mutex::Lock lm (_peaks_ready_lock); - - /* check to see if the peak data is ready. if not - connect the slot while still holding the lock. - */ - - if (!(ret = _peaks_built)) { - conn = PeaksReady.connect (the_slot); - } - - return ret; -} - -void -AudioSource::touch_peakfile () -{ - struct stat statbuf; - - if (stat (peakpath.c_str(), &statbuf) != 0 || statbuf.st_size == 0) { - return; - } - - struct utimbuf tbuf; - - tbuf.actime = statbuf.st_atime; - tbuf.modtime = time ((time_t) 0); - - utime (peakpath.c_str(), &tbuf); -} - -int -AudioSource::rename_peakfile (ustring newpath) -{ - /* caller must hold _lock */ - - ustring oldpath = peakpath; - - if (access (oldpath.c_str(), F_OK) == 0) { - if (rename (oldpath.c_str(), newpath.c_str()) != 0) { - error << string_compose (_("cannot rename peakfile for %1 from %2 to %3 (%4)"), _name, oldpath, newpath, strerror (errno)) << endmsg; - return -1; - } - } - - peakpath = newpath; - - return 0; -} - -int -AudioSource::initialize_peakfile (bool newfile, ustring audio_path) -{ - struct stat statbuf; - - peakpath = peak_path (audio_path); - - /* if the peak file should be there, but isn't .... */ - - if (!newfile && !Glib::file_test (peakpath.c_str(), Glib::FILE_TEST_EXISTS)) { - peakpath = find_broken_peakfile (peakpath, audio_path); - } - - if (stat (peakpath.c_str(), &statbuf)) { - if (errno != ENOENT) { - /* it exists in the peaks dir, but there is some kind of error */ - - error << string_compose(_("AudioSource: cannot stat peakfile \"%1\""), peakpath) << endmsg; - return -1; - } - - /* peakfile does not exist */ - - _peaks_built = false; - - } else { - - /* we found it in the peaks dir, so check it out */ - - if (statbuf.st_size == 0 || (statbuf.st_size < ((length() / _FPP) * sizeof (PeakData)))) { - // empty - _peaks_built = false; - } else { - // Check if the audio file has changed since the peakfile was built. - struct stat stat_file; - int err = stat (audio_path.c_str(), &stat_file); - - if (err) { - _peaks_built = false; - _peak_byte_max = 0; - } else { - - /* allow 6 seconds slop on checking peak vs. file times because of various - disk action "races" - */ - - if (stat_file.st_mtime > statbuf.st_mtime && (stat_file.st_mtime - statbuf.st_mtime > 6)) { - _peaks_built = false; - _peak_byte_max = 0; - } else { - _peaks_built = true; - _peak_byte_max = statbuf.st_size; - } - } - } - } - - if (!newfile && !_peaks_built && _build_missing_peakfiles && _build_peakfiles) { - build_peaks_from_scratch (); - } - - return 0; -} - -nframes_t -AudioSource::read (Sample *dst, nframes_t start, nframes_t cnt) const -{ - Glib::Mutex::Lock lm (_lock); - return read_unlocked (dst, start, cnt); -} - -nframes_t -AudioSource::write (Sample *dst, nframes_t cnt) -{ - Glib::Mutex::Lock lm (_lock); - return write_unlocked (dst, cnt); -} - -int -AudioSource::read_peaks (PeakData *peaks, nframes_t npeaks, nframes_t start, nframes_t cnt, double samples_per_visual_peak) const -{ - return read_peaks_with_fpp (peaks, npeaks, start, cnt, samples_per_visual_peak, _FPP); -} - -int -AudioSource::read_peaks_with_fpp (PeakData *peaks, nframes_t npeaks, nframes_t start, nframes_t cnt, - double samples_per_visual_peak, nframes_t samples_per_file_peak) const -{ - Glib::Mutex::Lock lm (_lock); - double scale; - double expected_peaks; - PeakData::PeakDatum xmax; - PeakData::PeakDatum xmin; - int32_t to_read; - uint32_t nread; - nframes_t zero_fill = 0; - int ret = -1; - PeakData* staging = 0; - Sample* raw_staging = 0; - int _peakfile = -1; - - expected_peaks = (cnt / (double) samples_per_file_peak); - scale = npeaks/expected_peaks; - -#undef DEBUG_READ_PEAKS -#ifdef DEBUG_READ_PEAKS - cerr << "======>RP: npeaks = " << npeaks - << " start = " << start - << " cnt = " << cnt - << " len = " << _length - << " samples_per_visual_peak =" << samples_per_visual_peak - << " expected was " << expected_peaks << " ... scale = " << scale - << " PD ptr = " << peaks - <<endl; - -#endif - - /* fix for near-end-of-file conditions */ - - if (cnt > _length - start) { - // cerr << "too close to end @ " << _length << " given " << start << " + " << cnt << endl; - cnt = _length - start; - nframes_t old = npeaks; - npeaks = min ((nframes_t) floor (cnt / samples_per_visual_peak), npeaks); - zero_fill = old - npeaks; - } - - // cerr << "actual npeaks = " << npeaks << " zf = " << zero_fill << endl; - - if (npeaks == cnt) { - -#ifdef DEBUG_READ_PEAKS - cerr << "RAW DATA\n"; -#endif - /* no scaling at all, just get the sample data and duplicate it for - both max and min peak values. - */ - - Sample* raw_staging = new Sample[cnt]; - - if (read_unlocked (raw_staging, start, cnt) != cnt) { - error << _("cannot read sample data for unscaled peak computation") << endmsg; - return -1; - } - - for (nframes_t i = 0; i < npeaks; ++i) { - peaks[i].max = raw_staging[i]; - peaks[i].min = raw_staging[i]; - } - - delete [] raw_staging; - return 0; - } - - if (scale == 1.0) { - - off_t first_peak_byte = (start / samples_per_file_peak) * sizeof (PeakData); - - /* open, read, close */ - - if ((_peakfile = ::open (peakpath.c_str(), O_RDONLY, 0664)) < 0) { - error << string_compose(_("AudioSource: cannot open peakpath (a) \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg; - return -1; - } - -#ifdef DEBUG_READ_PEAKS - cerr << "DIRECT PEAKS\n"; -#endif - - nread = ::pread (_peakfile, peaks, sizeof (PeakData)* npeaks, first_peak_byte); - close (_peakfile); - - if (nread != sizeof (PeakData) * npeaks) { - cerr << "AudioSource[" - << _name - << "]: cannot read peaks from peakfile! (read only " - << nread - << " not " - << npeaks - << "at sample " - << start - << " = byte " - << first_peak_byte - << ')' - << endl; - return -1; - } - - if (zero_fill) { - memset (&peaks[npeaks], 0, sizeof (PeakData) * zero_fill); - } - - return 0; - } - - - nframes_t tnp; - - if (scale < 1.0) { - -#ifdef DEBUG_READ_PEAKS - cerr << "DOWNSAMPLE\n"; -#endif - /* the caller wants: - - - more frames-per-peak (lower resolution) than the peakfile, or to put it another way, - - less peaks than the peakfile holds for the same range - - So, read a block into a staging area, and then downsample from there. - - to avoid confusion, I'll refer to the requested peaks as visual_peaks and the peakfile peaks as stored_peaks - */ - - const uint32_t chunksize = (uint32_t) min (expected_peaks, 65536.0); - - staging = new PeakData[chunksize]; - - /* compute the rounded up frame position */ - - nframes_t current_frame = start; - nframes_t current_stored_peak = (nframes_t) ceil (current_frame / (double) samples_per_file_peak); - uint32_t next_visual_peak = (uint32_t) ceil (current_frame / samples_per_visual_peak); - double next_visual_peak_frame = next_visual_peak * samples_per_visual_peak; - uint32_t stored_peak_before_next_visual_peak = (nframes_t) next_visual_peak_frame / samples_per_file_peak; - uint32_t nvisual_peaks = 0; - uint32_t stored_peaks_read = 0; - uint32_t i = 0; - - /* handle the case where the initial visual peak is on a pixel boundary */ - - current_stored_peak = min (current_stored_peak, stored_peak_before_next_visual_peak); - - /* open ... close during out: handling */ - - if ((_peakfile = ::open (peakpath.c_str(), O_RDONLY, 0664)) < 0) { - error << string_compose(_("AudioSource: cannot open peakpath (b) \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg; - return 0; - } - - while (nvisual_peaks < npeaks) { - - if (i == stored_peaks_read) { - - uint32_t start_byte = current_stored_peak * sizeof(PeakData); - tnp = min ((_length/samples_per_file_peak - current_stored_peak), (nframes_t) expected_peaks); - to_read = min (chunksize, tnp); - -#ifdef DEBUG_READ_PEAKS - cerr << "read " << sizeof (PeakData) * to_read << " from peakfile @ " << start_byte << endl; -#endif - - if ((nread = ::pread (_peakfile, staging, sizeof (PeakData) * to_read, start_byte)) - != sizeof (PeakData) * to_read) { - - off_t fend = lseek (_peakfile, 0, SEEK_END); - - cerr << "AudioSource[" - << _name - << "]: cannot read peak data from peakfile (" - << (nread / sizeof(PeakData)) - << " peaks instead of " - << to_read - << ") (" - << strerror (errno) - << ')' - << " at start_byte = " << start_byte - << " _length = " << _length << " versus len = " << fend - << " expected maxpeaks = " << (_length - current_frame)/samples_per_file_peak - << " npeaks was " << npeaks - << endl; - goto out; - } - - i = 0; - stored_peaks_read = nread / sizeof(PeakData); - } - - xmax = -1.0; - xmin = 1.0; - - while ((i < stored_peaks_read) && (current_stored_peak <= stored_peak_before_next_visual_peak)) { - - xmax = max (xmax, staging[i].max); - xmin = min (xmin, staging[i].min); - ++i; - ++current_stored_peak; - --expected_peaks; - } - - peaks[nvisual_peaks].max = xmax; - peaks[nvisual_peaks].min = xmin; - ++nvisual_peaks; - ++next_visual_peak; - - //next_visual_peak_frame = min ((next_visual_peak * samples_per_visual_peak), (next_visual_peak_frame+samples_per_visual_peak) ); - next_visual_peak_frame = min ((double) start+cnt, (next_visual_peak_frame+samples_per_visual_peak) ); - stored_peak_before_next_visual_peak = (uint32_t) next_visual_peak_frame / samples_per_file_peak; - } - - if (zero_fill) { - memset (&peaks[npeaks], 0, sizeof (PeakData) * zero_fill); - } - - ret = 0; - - } else { - -#ifdef DEBUG_READ_PEAKS - cerr << "UPSAMPLE\n"; -#endif - /* the caller wants - - - less frames-per-peak (more resolution) - - more peaks than stored in the Peakfile - - So, fetch data from the raw source, and generate peak - data on the fly. - */ - - nframes_t frames_read = 0; - nframes_t current_frame = start; - nframes_t i = 0; - nframes_t nvisual_peaks = 0; - nframes_t chunksize = (nframes_t) min (cnt, (nframes_t) 4096); - raw_staging = new Sample[chunksize]; - - nframes_t frame_pos = start; - double pixel_pos = floor (frame_pos / samples_per_visual_peak); - double next_pixel_pos = ceil (frame_pos / samples_per_visual_peak); - double pixels_per_frame = 1.0 / samples_per_visual_peak; - - xmin = 1.0; - xmax = -1.0; - - while (nvisual_peaks < npeaks) { - - if (i == frames_read) { - - to_read = min (chunksize, (_length - current_frame)); - - if (to_read == 0) { - /* XXX ARGH .. out by one error ... need to figure out why this happens - and fix it rather than do this band-aid move. - */ - zero_fill = npeaks - nvisual_peaks; - break; - } - - if ((frames_read = read_unlocked (raw_staging, current_frame, to_read)) == 0) { - error << string_compose(_("AudioSource[%1]: peak read - cannot read %2 samples at offset %3 of %4 (%5)"), - _name, to_read, current_frame, _length, strerror (errno)) - << endmsg; - goto out; - } - - i = 0; - } - - xmax = max (xmax, raw_staging[i]); - xmin = min (xmin, raw_staging[i]); - ++i; - ++current_frame; - pixel_pos += pixels_per_frame; - - if (pixel_pos >= next_pixel_pos) { - - peaks[nvisual_peaks].max = xmax; - peaks[nvisual_peaks].min = xmin; - ++nvisual_peaks; - xmin = 1.0; - xmax = -1.0; - - next_pixel_pos = ceil (pixel_pos + 0.5); - } - } - - if (zero_fill) { - memset (&peaks[npeaks], 0, sizeof (PeakData) * zero_fill); - } - - ret = 0; - } - - out: - if (_peakfile >= 0) { - close (_peakfile); - } - - if (staging) { - delete [] staging; - } - - if (raw_staging) { - delete [] raw_staging; - } - -#ifdef DEBUG_READ_PEAKS - cerr << "RP DONE\n"; -#endif - - return ret; -} - -#undef DEBUG_PEAK_BUILD - -int -AudioSource::build_peaks_from_scratch () -{ - nframes_t current_frame; - nframes_t cnt; - Sample* buf = 0; - nframes_t frames_read; - nframes_t frames_to_read; - const nframes_t bufsize = 65536; // 256kB per disk read for mono data is about ideal - - int ret = -1; - - { - /* hold lock while building peaks */ - - Glib::Mutex::Lock lp (_lock); - - if (prepare_for_peakfile_writes ()) { - goto out; - } - - current_frame = 0; - cnt = _length; - _peaks_built = false; - buf = new Sample[bufsize]; - - while (cnt) { - - frames_to_read = min (bufsize, cnt); - - if ((frames_read = read_unlocked (buf, current_frame, frames_to_read)) != frames_to_read) { - error << string_compose(_("%1: could not write read raw data for peak computation (%2)"), _name, strerror (errno)) << endmsg; - done_with_peakfile_writes (false); - goto out; - } - - if (compute_and_write_peaks (buf, current_frame, frames_read, true, false, _FPP)) { - break; - } - - current_frame += frames_read; - cnt -= frames_read; - } - - if (cnt == 0) { - /* success */ - truncate_peakfile(); - } - - done_with_peakfile_writes ((cnt == 0)); - } - - { - Glib::Mutex::Lock lm (_peaks_ready_lock); - - if (_peaks_built) { - PeaksReady (); /* EMIT SIGNAL */ - ret = 0; - } - } - - out: - if (ret) { - unlink (peakpath.c_str()); - } - - if (buf) { - delete [] buf; - } - - return ret; -} - -int -AudioSource::prepare_for_peakfile_writes () -{ - if ((peakfile = ::open (peakpath.c_str(), O_RDWR|O_CREAT, 0664)) < 0) { - error << string_compose(_("AudioSource: cannot open peakpath (c) \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg; - return -1; - } - return 0; -} - -void -AudioSource::done_with_peakfile_writes (bool done) -{ - if (peak_leftover_cnt) { - compute_and_write_peaks (0, 0, 0, true, false, _FPP); - } - - if (done) { - _peaks_built = true; - } - - if (peakfile >= 0) { - close (peakfile); - peakfile = -1; - } -} - -int -AudioSource::compute_and_write_peaks (Sample* buf, nframes_t first_frame, nframes_t cnt, bool force, bool intermediate_peaks_ready) -{ - return compute_and_write_peaks (buf, first_frame, cnt, force, intermediate_peaks_ready, _FPP); -} - -int -AudioSource::compute_and_write_peaks (Sample* buf, nframes_t first_frame, nframes_t cnt, bool force, - bool intermediate_peaks_ready, nframes_t fpp) -{ - Sample* buf2 = 0; - nframes_t to_do; - uint32_t peaks_computed; - PeakData* peakbuf = 0; - int ret = -1; - nframes_t current_frame; - nframes_t frames_done; - const size_t blocksize = (128 * 1024); - off_t first_peak_byte; - - if (peakfile < 0) { - prepare_for_peakfile_writes (); - } - - restart: - if (peak_leftover_cnt) { - - if (first_frame != peak_leftover_frame + peak_leftover_cnt) { - - /* uh-oh, ::seek() since the last ::compute_and_write_peaks(), - and we have leftovers. flush a single peak (since the leftovers - never represent more than that, and restart. - */ - - PeakData x; - - x.min = peak_leftovers[0]; - x.max = peak_leftovers[0]; - - off_t byte = (peak_leftover_frame / fpp) * sizeof (PeakData); - - if (::pwrite (peakfile, &x, sizeof (PeakData), byte) != sizeof (PeakData)) { - error << string_compose(_("%1: could not write peak file data (%2)"), _name, strerror (errno)) << endmsg; - goto out; - } - - _peak_byte_max = max (_peak_byte_max, (off_t) (byte + sizeof(PeakData))); - - { - Glib::Mutex::Lock lm (_peaks_ready_lock); - PeakRangeReady (peak_leftover_frame, peak_leftover_cnt); /* EMIT SIGNAL */ - if (intermediate_peaks_ready) { - PeaksReady (); /* EMIT SIGNAL */ - } - } - - /* left overs are done */ - - peak_leftover_cnt = 0; - goto restart; - } - - /* else ... had leftovers, but they immediately preceed the new data, so just - merge them and compute. - */ - - /* make a new contiguous buffer containing leftovers and the new stuff */ - - to_do = cnt + peak_leftover_cnt; - buf2 = new Sample[to_do]; - - /* the remnants */ - memcpy (buf2, peak_leftovers, peak_leftover_cnt * sizeof (Sample)); - - /* the new stuff */ - memcpy (buf2+peak_leftover_cnt, buf, cnt * sizeof (Sample)); - - /* no more leftovers */ - peak_leftover_cnt = 0; - - /* use the temporary buffer */ - buf = buf2; - - /* make sure that when we write into the peakfile, we startup where we left off */ - - first_frame = peak_leftover_frame; - - } else { - to_do = cnt; - } - - peakbuf = new PeakData[(to_do/fpp)+1]; - peaks_computed = 0; - current_frame = first_frame; - frames_done = 0; - - while (to_do) { - - /* if some frames were passed in (i.e. we're not flushing leftovers) - and there are less than fpp to do, save them till - next time - */ - - if (force && (to_do < fpp)) { - /* keep the left overs around for next time */ - - if (peak_leftover_size < to_do) { - delete [] peak_leftovers; - peak_leftovers = new Sample[to_do]; - peak_leftover_size = to_do; - } - memcpy (peak_leftovers, buf, to_do * sizeof (Sample)); - peak_leftover_cnt = to_do; - peak_leftover_frame = current_frame; - - /* done for now */ - - break; - } - - nframes_t this_time = min (fpp, to_do); - - peakbuf[peaks_computed].max = buf[0]; - peakbuf[peaks_computed].min = buf[0]; - - ARDOUR::find_peaks (buf+1, this_time-1, &peakbuf[peaks_computed].min, &peakbuf[peaks_computed].max); - - peaks_computed++; - buf += this_time; - to_do -= this_time; - frames_done += this_time; - current_frame += this_time; - } - - first_peak_byte = (first_frame / fpp) * sizeof (PeakData); - - if (can_truncate_peaks()) { - - /* on some filesystems (ext3, at least) this helps to reduce fragmentation of - the peakfiles. its not guaranteed to do so, and even on ext3 (as of december 2006) - it does not cause single-extent allocation even for peakfiles of - less than BLOCKSIZE bytes. only call ftruncate if we'll make the file larger. - */ - - off_t endpos = lseek (peakfile, 0, SEEK_END); - off_t target_length = blocksize * ((first_peak_byte + blocksize + 1) / blocksize); - - if (endpos < target_length) { - ftruncate (peakfile, target_length); - /* error doesn't actually matter though, so continue on without testing */ - } - } - - if (::pwrite (peakfile, peakbuf, sizeof (PeakData) * peaks_computed, first_peak_byte) != (ssize_t) (sizeof (PeakData) * peaks_computed)) { - error << string_compose(_("%1: could not write peak file data (%2)"), _name, strerror (errno)) << endmsg; - goto out; - } - - _peak_byte_max = max (_peak_byte_max, (off_t) (first_peak_byte + sizeof(PeakData)*peaks_computed)); - - if (frames_done) { - Glib::Mutex::Lock lm (_peaks_ready_lock); - PeakRangeReady (first_frame, frames_done); /* EMIT SIGNAL */ - if (intermediate_peaks_ready) { - PeaksReady (); /* EMIT SIGNAL */ - } - } - - ret = 0; - - out: - delete [] peakbuf; - if (buf2) { - delete [] buf2; - } - return ret; -} - -void -AudioSource::truncate_peakfile () -{ - if (peakfile < 0) { - error << string_compose (_("programming error: %1"), "AudioSource::truncate_peakfile() called without open peakfile descriptor") - << endmsg; - return; - } - - /* truncate the peakfile down to its natural length if necessary */ - - off_t end = lseek (peakfile, 0, SEEK_END); - - if (end > _peak_byte_max) { - ftruncate (peakfile, _peak_byte_max); - } -} - -bool -AudioSource::file_changed (ustring path) -{ - struct stat stat_file; - struct stat stat_peak; - - int e1 = stat (path.c_str(), &stat_file); - int e2 = stat (peak_path(path).c_str(), &stat_peak); - - if (!e1 && !e2 && stat_file.st_mtime > stat_peak.st_mtime){ - return true; - } else { - return false; - } -} - -nframes_t -AudioSource::available_peaks (double zoom_factor) const -{ - off_t end; - - if (zoom_factor < _FPP) { - return length(); // peak data will come from the audio file - } - - /* peak data comes from peakfile, but the filesize might not represent - the valid data due to ftruncate optimizations, so use _peak_byte_max state. - XXX - there might be some atomicity issues here, we should probably add a lock, - but _peak_byte_max only monotonically increases after initialization. - */ - - end = _peak_byte_max; - - return (end/sizeof(PeakData)) * _FPP; -} - -void -AudioSource::update_length (nframes_t pos, nframes_t cnt) -{ - if (pos + cnt > _length) { - _length = pos+cnt; - } -} - diff --git a/libs/ardour/auditioner.cc b/libs/ardour/auditioner.cc deleted file mode 100644 index d6f63c2f9d..0000000000 --- a/libs/ardour/auditioner.cc +++ /dev/null @@ -1,233 +0,0 @@ -/* - 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. - -*/ - -#include <glibmm/thread.h> - -#include <pbd/error.h> - -#include <ardour/audio_diskstream.h> -#include <ardour/audioregion.h> -#include <ardour/audioengine.h> -#include <ardour/route.h> -#include <ardour/session.h> -#include <ardour/auditioner.h> -#include <ardour/audioplaylist.h> -#include <ardour/panner.h> -#include <ardour/data_type.h> -#include <ardour/region_factory.h> - -using namespace std; -using namespace ARDOUR; -using namespace PBD; - -#include "i18n.h" - -Auditioner::Auditioner (Session& s) - : AudioTrack (s, "auditioner", Route::Hidden) -{ - string left = Config->get_auditioner_output_left(); - string right = Config->get_auditioner_output_right(); - - if (left == "default") { - left = _session.engine().get_nth_physical_output (DataType::AUDIO, 0); - } - - if (right == "default") { - right = _session.engine().get_nth_physical_output (DataType::AUDIO, 1); - } - - if ((left.length() == 0) && (right.length() == 0)) { - warning << _("no outputs available for auditioner - manual connection required") << endmsg; - return; - } - - defer_pan_reset (); - - if (left.length()) { - add_output_port (left, this, DataType::AUDIO); - } - - if (right.length()) { - audio_diskstream()->add_channel (1); - add_output_port (right, this, DataType::AUDIO); - } - - allow_pan_reset (); - - reset_panner (); - - IO::output_changed.connect (mem_fun (*this, &Auditioner::output_changed)); - - the_region.reset ((AudioRegion*) 0); - g_atomic_int_set (&_active, 0); -} - -Auditioner::~Auditioner () -{ -} - -AudioPlaylist& -Auditioner::prepare_playlist () -{ - // FIXME auditioner is still audio-only - boost::shared_ptr<AudioPlaylist> apl = boost::dynamic_pointer_cast<AudioPlaylist>(_diskstream->playlist()); - assert(apl); - - apl->clear (); - return *apl; -} - -void -Auditioner::audition_current_playlist () -{ - if (g_atomic_int_get (&_active)) { - /* don't go via session for this, because we are going - to remain active. - */ - cancel_audition (); - } - - Glib::Mutex::Lock lm (lock); - _diskstream->seek (0); - length = _diskstream->playlist()->get_maximum_extent(); - current_frame = 0; - - /* force a panner reset now that we have all channels */ - - _panner->reset (n_outputs().n_audio(), _diskstream->n_channels().n_audio()); - - g_atomic_int_set (&_active, 1); -} - -void -Auditioner::audition_region (boost::shared_ptr<Region> region) -{ - if (g_atomic_int_get (&_active)) { - /* don't go via session for this, because we are going - to remain active. - */ - cancel_audition (); - } - - if (boost::dynamic_pointer_cast<AudioRegion>(region) == 0) { - error << _("Auditioning of non-audio regions not yet supported") << endmsg; - return; - } - - Glib::Mutex::Lock lm (lock); - - /* copy it */ - - boost::shared_ptr<AudioRegion> the_region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (region))); - the_region->set_position (0, this); - - _diskstream->playlist()->drop_regions (); - _diskstream->playlist()->add_region (the_region, 0, 1); - - if (_diskstream->n_channels().n_audio() < the_region->n_channels()) { - audio_diskstream()->add_channel (the_region->n_channels() - _diskstream->n_channels().n_audio()); - } else if (_diskstream->n_channels().n_audio() > the_region->n_channels()) { - audio_diskstream()->remove_channel (_diskstream->n_channels().n_audio() - the_region->n_channels()); - } - - /* force a panner reset now that we have all channels */ - - reset_panner(); - - length = the_region->length(); - - int dir; - nframes_t offset = the_region->sync_offset (dir); - - /* can't audition from a negative sync point */ - - if (dir < 0) { - offset = 0; - } - - _diskstream->seek (offset); - current_frame = offset; - - g_atomic_int_set (&_active, 1); -} - -int -Auditioner::play_audition (nframes_t nframes) -{ - bool need_butler; - nframes_t this_nframes; - int ret; - - if (g_atomic_int_get (&_active) == 0) { - silence (nframes, 0); - return 0; - } - - this_nframes = min (nframes, length - current_frame); - - _diskstream->prepare (); - - if ((ret = roll (this_nframes, current_frame, current_frame + nframes, 0, false, false, false)) != 0) { - silence (nframes, 0); - return ret; - } - - need_butler = _diskstream->commit (this_nframes); - current_frame += this_nframes; - - if (current_frame >= length) { - _session.cancel_audition (); - return 0; - } else { - return need_butler ? 1 : 0; - } -} - -void -Auditioner::output_changed (IOChange change, void* src) -{ - string phys; - - if (change & ConnectionsChanged) { - vector<string> connections; - if (output (0)->get_connections (connections)) { - phys = _session.engine().get_nth_physical_output (DataType::AUDIO, 0); - if (phys != connections[0]) { - Config->set_auditioner_output_left (connections[0]); - } else { - Config->set_auditioner_output_left ("default"); - } - } else { - Config->set_auditioner_output_left (""); - } - - connections.clear (); - - if (output (1)->get_connections (connections)) { - phys = _session.engine().get_nth_physical_output (DataType::AUDIO, 1); - if (phys != connections[0]) { - Config->set_auditioner_output_right (connections[0]); - } else { - Config->set_auditioner_output_right ("default"); - } - } else { - Config->set_auditioner_output_right (""); - } - } -} diff --git a/libs/ardour/auto_bundle.cc b/libs/ardour/auto_bundle.cc deleted file mode 100644 index 9da32bbb7a..0000000000 --- a/libs/ardour/auto_bundle.cc +++ /dev/null @@ -1,47 +0,0 @@ -#include <cassert> -#include "ardour/auto_bundle.h" - -ARDOUR::AutoBundle::AutoBundle (bool i) - : Bundle (i) -{ - -} - -ARDOUR::AutoBundle::AutoBundle (std::string const & n, bool i) - : Bundle (n, i) -{ - -} - -uint32_t -ARDOUR::AutoBundle::nchannels () const -{ - Glib::Mutex::Lock lm (_ports_mutex); - return _ports.size (); -} - -const ARDOUR::PortList& -ARDOUR::AutoBundle::channel_ports (uint32_t c) const -{ - assert (c < nchannels()); - - Glib::Mutex::Lock lm (_ports_mutex); - return _ports[c]; -} - -void -ARDOUR::AutoBundle::set_channels (uint32_t n) -{ - Glib::Mutex::Lock lm (_ports_mutex); - _ports.resize (n); -} - -void -ARDOUR::AutoBundle::set_port (uint32_t c, std::string const & p) -{ - assert (c < nchannels ()); - - Glib::Mutex::Lock lm (_ports_mutex); - _ports[c].resize (1); - _ports[c][0] = p; -} diff --git a/libs/ardour/automatable.cc b/libs/ardour/automatable.cc deleted file mode 100644 index 3c076c371a..0000000000 --- a/libs/ardour/automatable.cc +++ /dev/null @@ -1,477 +0,0 @@ -/* - 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. - -*/ - -#include <ardour/ardour.h> -#include <fstream> -#include <inttypes.h> -#include <cstdio> -#include <errno.h> -#include <pbd/error.h> -#include <pbd/enumwriter.h> -#include <midi++/names.h> -#include <ardour/session.h> -#include <ardour/automatable.h> -#include <ardour/midi_track.h> - -#include "i18n.h" - -using namespace std; -using namespace ARDOUR; -using namespace PBD; - -nframes_t Automatable::_automation_interval = 0; - -Automatable::Automatable(Session& _session, const string& name) - : SessionObject(_session, name) - , _last_automation_snapshot(0) -{} - -int -Automatable::old_set_automation_state (const XMLNode& node) -{ - const XMLProperty *prop; - - if ((prop = node.property ("path")) != 0) { - load_automation (prop->value()); - } else { - warning << string_compose(_("%1: Automation node has no path property"), _name) << endmsg; - } - - if ((prop = node.property ("visible")) != 0) { - uint32_t what; - stringstream sstr; - - _visible_controls.clear (); - - sstr << prop->value(); - while (1) { - sstr >> what; - if (sstr.fail()) { - break; - } - mark_automation_visible (Parameter(PluginAutomation, what), true); - } - } - - _last_automation_snapshot = 0; - - return 0; -} - -int -Automatable::load_automation (const string& path) -{ - string fullpath; - - if (path[0] == '/') { // legacy - fullpath = path; - } else { - fullpath = _session.automation_dir(); - fullpath += path; - } - ifstream in (fullpath.c_str()); - - if (!in) { - warning << string_compose(_("%1: cannot open %2 to load automation data (%3)"), _name, fullpath, strerror (errno)) << endmsg; - return 1; - } - - Glib::Mutex::Lock lm (_automation_lock); - set<Parameter> tosave; - _controls.clear (); - - _last_automation_snapshot = 0; - - while (in) { - double when; - double value; - uint32_t port; - - in >> port; if (!in) break; - in >> when; if (!in) goto bad; - in >> value; if (!in) goto bad; - - /* FIXME: this is legacy and only used for plugin inserts? I think? */ - boost::shared_ptr<AutomationControl> c = control (Parameter(PluginAutomation, port), true); - c->list()->add (when, value); - tosave.insert (Parameter(PluginAutomation, port)); - } - - return 0; - - bad: - error << string_compose(_("%1: cannot load automation data from %2"), _name, fullpath) << endmsg; - _controls.clear (); - return -1; -} - -void -Automatable::add_control(boost::shared_ptr<AutomationControl> ac) -{ - Parameter param = ac->parameter(); - - _controls[param] = ac; - - _can_automate_list.insert(param); - - // Sync everything (derived classes) up to initial values - auto_state_changed(param); -} - -void -Automatable::what_has_automation (set<Parameter>& s) const -{ - Glib::Mutex::Lock lm (_automation_lock); - Controls::const_iterator li; - - // FIXME: correct semantics? - for (li = _controls.begin(); li != _controls.end(); ++li) { - s.insert ((*li).first); - } -} - -void -Automatable::what_has_visible_automation (set<Parameter>& s) const -{ - Glib::Mutex::Lock lm (_automation_lock); - set<Parameter>::const_iterator li; - - for (li = _visible_controls.begin(); li != _visible_controls.end(); ++li) { - s.insert (*li); - } -} - -/** Returns NULL if we don't have an AutomationList for \a parameter. - */ -boost::shared_ptr<AutomationControl> -Automatable::control (Parameter parameter, bool create_if_missing) -{ - Controls::iterator i = _controls.find(parameter); - - if (i != _controls.end()) { - return i->second; - - } else if (create_if_missing) { - boost::shared_ptr<AutomationList> al (new AutomationList ( - parameter, FLT_MIN, FLT_MAX, default_parameter_value (parameter))); - boost::shared_ptr<AutomationControl> ac(control_factory(al)); - add_control(ac); - return ac; - - } else { - //warning << "AutomationList " << parameter.to_string() << " not found for " << _name << endmsg; - return boost::shared_ptr<AutomationControl>(); - } -} - -boost::shared_ptr<const AutomationControl> -Automatable::control (Parameter parameter) const -{ - Controls::const_iterator i = _controls.find(parameter); - - if (i != _controls.end()) { - return i->second; - } else { - //warning << "AutomationList " << parameter.to_string() << " not found for " << _name << endmsg; - return boost::shared_ptr<AutomationControl>(); - } -} - -string -Automatable::describe_parameter (Parameter param) -{ - /* derived classes like PluginInsert should override this */ - - if (param == Parameter(GainAutomation)) { - return _("Fader"); - } else if (param.type() == PanAutomation) { - return (string_compose(_("Pan %1"), param.id())); - } else if (param.type() == MidiCCAutomation) { - return string_compose("CC %1 (%2) [%3]", - param.id(), midi_name(param.id()), int(param.channel()) + 1); - } else if (param.type() == MidiPgmChangeAutomation) { - return string_compose("Program [%1]", int(param.channel()) + 1); - } else if (param.type() == MidiPitchBenderAutomation) { - return string_compose("Bender [%1]", int(param.channel()) + 1); - } else if (param.type() == MidiChannelAftertouchAutomation) { - return string_compose("Aftertouch [%1]", int(param.channel()) + 1); - } else { - return param.to_string(); - } -} - -void -Automatable::can_automate (Parameter what) -{ - _can_automate_list.insert (what); -} - -void -Automatable::mark_automation_visible (Parameter what, bool yn) -{ - if (yn) { - _visible_controls.insert (what); - } else { - set<Parameter>::iterator i; - - if ((i = _visible_controls.find (what)) != _visible_controls.end()) { - _visible_controls.erase (i); - } - } -} - -bool -Automatable::find_next_event (nframes_t now, nframes_t end, ControlEvent& next_event) const -{ - Controls::const_iterator li; - - next_event.when = max_frames; - - for (li = _controls.begin(); li != _controls.end(); ++li) { - - AutomationList::const_iterator i; - boost::shared_ptr<const AutomationList> alist (li->second->list()); - ControlEvent cp (now, 0.0f); - - for (i = lower_bound (alist->const_begin(), alist->const_end(), &cp, AutomationList::time_comparator); - i != alist->const_end() && (*i)->when < end; ++i) { - if ((*i)->when > now) { - break; - } - } - - if (i != alist->const_end() && (*i)->when < end) { - - if ((*i)->when < next_event.when) { - next_event.when = (*i)->when; - } - } - } - - return next_event.when != max_frames; -} - -/** \a legacy_param is used for loading legacy sessions where an object (IO, Panner) - * had a single automation parameter, with it's type implicit. Derived objects should - * pass that type and it will be used for the untyped AutomationList found. - */ -int -Automatable::set_automation_state (const XMLNode& node, Parameter legacy_param) -{ - Glib::Mutex::Lock lm (_automation_lock); - - /* Don't clear controls, since some may be special derived Controllable classes */ - - _visible_controls.clear (); - - XMLNodeList nlist = node.children(); - XMLNodeIterator niter; - - for (niter = nlist.begin(); niter != nlist.end(); ++niter) { - - /*if (sscanf ((*niter)->name().c_str(), "parameter-%" PRIu32, ¶m) != 1) { - error << string_compose (_("%2: badly formatted node name in XML automation state, ignored"), _name) << endmsg; - continue; - }*/ - - if ((*niter)->name() == "AutomationList") { - - const XMLProperty* id_prop = (*niter)->property("automation-id"); - - Parameter param = (id_prop ? Parameter(id_prop->value()) : legacy_param); - - boost::shared_ptr<AutomationList> al (new AutomationList(**niter, param)); - - if (!id_prop) { - warning << "AutomationList node without automation-id property, " - << "using default: " << legacy_param.to_string() << endmsg; - al->set_parameter(legacy_param); - } - - boost::shared_ptr<AutomationControl> existing = control(param); - if (existing) - existing->set_list(al); - else - add_control(control_factory(al)); - - } else { - error << "Expected AutomationList node, got '" << (*niter)->name() << endmsg; - } - } - - _last_automation_snapshot = 0; - - return 0; -} - -XMLNode& -Automatable::get_automation_state () -{ - Glib::Mutex::Lock lm (_automation_lock); - XMLNode* node = new XMLNode (X_("Automation")); - - if (_controls.empty()) { - return *node; - } - - for (Controls::iterator li = _controls.begin(); li != _controls.end(); ++li) { - node->add_child_nocopy (li->second->list()->get_state ()); - } - - return *node; -} - -void -Automatable::clear_automation () -{ - Glib::Mutex::Lock lm (_automation_lock); - - for (Controls::iterator li = _controls.begin(); li != _controls.end(); ++li) - li->second->list()->clear(); -} - -void -Automatable::set_parameter_automation_state (Parameter param, AutoState s) -{ - Glib::Mutex::Lock lm (_automation_lock); - - boost::shared_ptr<AutomationControl> c = control (param, true); - - if (s != c->list()->automation_state()) { - c->list()->set_automation_state (s); - _session.set_dirty (); - } -} - -AutoState -Automatable::get_parameter_automation_state (Parameter param, bool lock) -{ - AutoState result = Off; - - if (lock) - _automation_lock.lock(); - - boost::shared_ptr<AutomationControl> c = control(param); - - if (c) - result = c->list()->automation_state(); - - if (lock) - _automation_lock.unlock(); - - return result; -} - -void -Automatable::set_parameter_automation_style (Parameter param, AutoStyle s) -{ - Glib::Mutex::Lock lm (_automation_lock); - - boost::shared_ptr<AutomationControl> c = control(param, true); - - if (s != c->list()->automation_style()) { - c->list()->set_automation_style (s); - _session.set_dirty (); - } -} - -AutoStyle -Automatable::get_parameter_automation_style (Parameter param) -{ - Glib::Mutex::Lock lm (_automation_lock); - - boost::shared_ptr<AutomationControl> c = control(param); - - if (c) { - return c->list()->automation_style(); - } else { - return Absolute; // whatever - } -} - -void -Automatable::protect_automation () -{ - set<Parameter> automated_params; - - what_has_automation (automated_params); - - for (set<Parameter>::iterator i = automated_params.begin(); i != automated_params.end(); ++i) { - - boost::shared_ptr<AutomationControl> c = control(*i); - - switch (c->list()->automation_state()) { - case Write: - c->list()->set_automation_state (Off); - break; - case Touch: - c->list()->set_automation_state (Play); - break; - default: - break; - } - } -} - -void -Automatable::automation_snapshot (nframes_t now, bool force) -{ - if (force || _last_automation_snapshot > now || (now - _last_automation_snapshot) > _automation_interval) { - - for (Controls::iterator i = _controls.begin(); i != _controls.end(); ++i) { - if (i->second->list()->automation_write()) { - i->second->list()->rt_add (now, i->second->user_value()); - } - } - - _last_automation_snapshot = now; - } -} - -void -Automatable::transport_stopped (nframes_t now) -{ - for (Controls::iterator li = _controls.begin(); li != _controls.end(); ++li) { - - boost::shared_ptr<AutomationControl> c = li->second; - - c->list()->reposition_for_rt_add (now); - - if (c->list()->automation_state() != Off) { - c->set_value(c->list()->eval(now)); - } - } -} - -/* FIXME: this probably doesn't belong here */ -boost::shared_ptr<AutomationControl> -Automatable::control_factory(boost::shared_ptr<AutomationList> list) -{ - if ( - list->parameter().type() == MidiCCAutomation || - list->parameter().type() == MidiPgmChangeAutomation || - list->parameter().type() == MidiChannelAftertouchAutomation - ) { - // FIXME: this will die horribly if this is not a MidiTrack - return boost::shared_ptr<AutomationControl>(new MidiTrack::MidiControl((MidiTrack*)this, list)); - } else { - return boost::shared_ptr<AutomationControl>(new AutomationControl(_session, list)); - } -} - diff --git a/libs/ardour/automation.cc b/libs/ardour/automation.cc deleted file mode 100644 index c6e96cfac8..0000000000 --- a/libs/ardour/automation.cc +++ /dev/null @@ -1,32 +0,0 @@ -/* - 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. - -*/ - -#include <stdint.h> - -template<class AutomatedObject> -struct AutomationEvent { - uint32_t frame; - AutomatedObject *object; - void (AutomatedObject::*function) (void *); - void *arg; - - void operator() (){ - object->function (arg); - } -}; diff --git a/libs/ardour/automation_control.cc b/libs/ardour/automation_control.cc deleted file mode 100644 index 4885a6fed9..0000000000 --- a/libs/ardour/automation_control.cc +++ /dev/null @@ -1,91 +0,0 @@ -/* - 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. - -*/ - -#include <iostream> -#include <ardour/automation_control.h> -#include <ardour/session.h> -#include <ardour/automatable.h> -#include <ardour/midi_track.h> - -using namespace std; -using namespace ARDOUR; -using namespace PBD; - - -AutomationControl::AutomationControl(Session& session, boost::shared_ptr<AutomationList> list, string name) - : Controllable((name == "unnamed controllable") ? list->parameter().to_string() : name) - , _session(session) - , _list(list) - , _user_value(list->default_value()) -{ -} - - -/** Get the currently effective value (ie the one that corresponds to current output) - */ -float -AutomationControl::get_value() const -{ - if (_list->automation_playback()) - return _list->eval(_session.transport_frame()); - else - return _user_value; -} - - -void -AutomationControl::set_value(float value) -{ - _user_value = value; - - if (_session.transport_stopped() && _list->automation_write()) - _list->add(_session.transport_frame(), value); - - Changed(); /* EMIT SIGNAL */ -} - - -/** Get the latest user-set value, which may not equal get_value() when automation - * is playing back, etc. - * - * Automation write/touch works by periodically sampling this value and adding it - * to the AutomationList. - */ -float -AutomationControl::user_value() const -{ - return _user_value; -} - - -void -AutomationControl::set_list(boost::shared_ptr<ARDOUR::AutomationList> list) -{ - _list = list; - _user_value = list->default_value(); - Changed(); /* EMIT SIGNAL */ -} - - -Parameter -AutomationControl::parameter() const -{ - return _list->parameter(); -} diff --git a/libs/ardour/automation_event.cc b/libs/ardour/automation_event.cc deleted file mode 100644 index af390953f4..0000000000 --- a/libs/ardour/automation_event.cc +++ /dev/null @@ -1,1666 +0,0 @@ -/* - 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. - -*/ - -#include <set> -#include <climits> -#include <float.h> -#include <cmath> -#include <sstream> -#include <algorithm> -#include <sigc++/bind.h> -#include <ardour/parameter.h> -#include <ardour/automation_event.h> -#include <ardour/curve.h> -#include <pbd/stacktrace.h> -#include <pbd/enumwriter.h> - -#include "i18n.h" - -using namespace std; -using namespace ARDOUR; -using namespace sigc; -using namespace PBD; - -sigc::signal<void,AutomationList *> AutomationList::AutomationListCreated; - -static bool sort_events_by_time (ControlEvent* a, ControlEvent* b) -{ - return a->when < b->when; -} - -#if 0 -static void dumpit (const AutomationList& al, string prefix = "") -{ - cerr << prefix << &al << endl; - for (AutomationList::const_iterator i = al.const_begin(); i != al.const_end(); ++i) { - cerr << prefix << '\t' << (*i)->when << ',' << (*i)->value << endl; - } - cerr << "\n"; -} -#endif - -/* XXX: min_val max_val redundant? (param.min() param.max()) */ -AutomationList::AutomationList (Parameter id, double min_val, double max_val, double default_val) - : _parameter(id) - , _interpolation(Linear) - , _curve(new Curve(*this)) -{ - _parameter = id; - _frozen = 0; - _changed_when_thawed = false; - _state = Off; - _style = Absolute; - _min_yval = min_val; - _max_yval = max_val; - _touching = false; - _max_xval = 0; // means "no limit" - _default_value = default_val; - _rt_insertion_point = _events.end(); - _lookup_cache.left = -1; - _lookup_cache.range.first = _events.end(); - _search_cache.left = -1; - _search_cache.range.first = _events.end(); - _sort_pending = false; - - assert(_parameter.type() != NullAutomation); - AutomationListCreated(this); -} - -AutomationList::AutomationList (const AutomationList& other) - : _parameter(other._parameter) - , _interpolation(Linear) - , _curve(new Curve(*this)) -{ - _frozen = 0; - _changed_when_thawed = false; - _style = other._style; - _min_yval = other._min_yval; - _max_yval = other._max_yval; - _max_xval = other._max_xval; - _default_value = other._default_value; - _state = other._state; - _touching = other._touching; - _rt_insertion_point = _events.end(); - _lookup_cache.range.first = _events.end(); - _search_cache.range.first = _events.end(); - _sort_pending = false; - - for (const_iterator i = other._events.begin(); i != other._events.end(); ++i) { - _events.push_back (new ControlEvent (**i)); - } - - mark_dirty (); - assert(_parameter.type() != NullAutomation); - AutomationListCreated(this); -} - -AutomationList::AutomationList (const AutomationList& other, double start, double end) - : _parameter(other._parameter) - , _interpolation(Linear) - , _curve(new Curve(*this)) -{ - _frozen = 0; - _changed_when_thawed = false; - _style = other._style; - _min_yval = other._min_yval; - _max_yval = other._max_yval; - _max_xval = other._max_xval; - _default_value = other._default_value; - _state = other._state; - _touching = other._touching; - _rt_insertion_point = _events.end(); - _lookup_cache.range.first = _events.end(); - _search_cache.range.first = _events.end(); - _sort_pending = false; - - /* now grab the relevant points, and shift them back if necessary */ - - AutomationList* section = const_cast<AutomationList*>(&other)->copy (start, end); - - if (!section->empty()) { - for (iterator i = section->begin(); i != section->end(); ++i) { - _events.push_back (new ControlEvent ((*i)->when, (*i)->value)); - } - } - - delete section; - - mark_dirty (); - - assert(_parameter.type() != NullAutomation); - AutomationListCreated(this); -} - -/** \a id is used for legacy sessions where the type is not present - * in or below the <AutomationList> node. It is used if \a id is non-null. - */ -AutomationList::AutomationList (const XMLNode& node, Parameter id) - : _interpolation(Linear) - , _curve(new Curve(*this)) -{ - _frozen = 0; - _changed_when_thawed = false; - _touching = false; - _min_yval = FLT_MIN; - _max_yval = FLT_MAX; - _max_xval = 0; // means "no limit" - _state = Off; - _style = Absolute; - _rt_insertion_point = _events.end(); - _lookup_cache.range.first = _events.end(); - _search_cache.range.first = _events.end(); - _sort_pending = false; - - set_state (node); - - if (id) - _parameter = id; - - assert(_parameter.type() != NullAutomation); - AutomationListCreated(this); -} - -AutomationList::~AutomationList() -{ - GoingAway (); - - for (EventList::iterator x = _events.begin(); x != _events.end(); ++x) { - delete (*x); - } -} - -bool -AutomationList::operator== (const AutomationList& other) -{ - return _events == other._events; -} - -AutomationList& -AutomationList::operator= (const AutomationList& other) -{ - if (this != &other) { - - _events.clear (); - - for (const_iterator i = other._events.begin(); i != other._events.end(); ++i) { - _events.push_back (new ControlEvent (**i)); - } - - _min_yval = other._min_yval; - _max_yval = other._max_yval; - _max_xval = other._max_xval; - _default_value = other._default_value; - - mark_dirty (); - maybe_signal_changed (); - } - - return *this; -} - -void -AutomationList::maybe_signal_changed () -{ - mark_dirty (); - - if (_frozen) { - _changed_when_thawed = true; - } else { - StateChanged (); - } -} - -void -AutomationList::set_automation_state (AutoState s) -{ - if (s != _state) { - _state = s; - automation_state_changed (); /* EMIT SIGNAL */ - } -} - -void -AutomationList::set_automation_style (AutoStyle s) -{ - if (s != _style) { - _style = s; - automation_style_changed (); /* EMIT SIGNAL */ - } -} - -void -AutomationList::start_touch () -{ - _touching = true; - _new_touch = true; -} - -void -AutomationList::stop_touch () -{ - _touching = false; - _new_touch = false; -} - -void -AutomationList::clear () -{ - { - Glib::Mutex::Lock lm (_lock); - _events.clear (); - mark_dirty (); - } - - maybe_signal_changed (); -} - -void -AutomationList::x_scale (double factor) -{ - Glib::Mutex::Lock lm (_lock); - _x_scale (factor); -} - -bool -AutomationList::extend_to (double when) -{ - Glib::Mutex::Lock lm (_lock); - if (_events.empty() || _events.back()->when == when) { - return false; - } - double factor = when / _events.back()->when; - _x_scale (factor); - return true; -} - -void AutomationList::_x_scale (double factor) -{ - for (iterator i = _events.begin(); i != _events.end(); ++i) { - (*i)->when = floor ((*i)->when * factor); - } - - mark_dirty (); -} - -void -AutomationList::reposition_for_rt_add (double when) -{ - _rt_insertion_point = _events.end(); -} - -void -AutomationList::rt_add (double when, double value) -{ - /* this is for automation recording */ - - if ((_state & Touch) && !_touching) { - return; - } - - // cerr << "RT: alist @ " << this << " add " << value << " @ " << when << endl; - - { - Glib::Mutex::Lock lm (_lock); - - iterator where; - ControlEvent cp (when, 0.0); - bool done = false; - - if ((_rt_insertion_point != _events.end()) && ((*_rt_insertion_point)->when < when) ) { - - /* we have a previous insertion point, so we should delete - everything between it and the position where we are going - to insert this point. - */ - - iterator after = _rt_insertion_point; - - if (++after != _events.end()) { - iterator far = after; - - while (far != _events.end()) { - if ((*far)->when > when) { - break; - } - ++far; - } - - if (_new_touch) { - where = far; - _rt_insertion_point = where; - - if ((*where)->when == when) { - (*where)->value = value; - done = true; - } - } else { - where = _events.erase (after, far); - } - - } else { - - where = after; - - } - - iterator previous = _rt_insertion_point; - --previous; - - if (_rt_insertion_point != _events.begin() && (*_rt_insertion_point)->value == value && (*previous)->value == value) { - (*_rt_insertion_point)->when = when; - done = true; - - } - - } else { - - where = lower_bound (_events.begin(), _events.end(), &cp, time_comparator); - - if (where != _events.end()) { - if ((*where)->when == when) { - (*where)->value = value; - done = true; - } - } - } - - if (!done) { - _rt_insertion_point = _events.insert (where, new ControlEvent (when, value)); - } - - _new_touch = false; - mark_dirty (); - } - - maybe_signal_changed (); -} - -void -AutomationList::fast_simple_add (double when, double value) -{ - /* to be used only for loading pre-sorted data from saved state */ - _events.insert (_events.end(), new ControlEvent (when, value)); - assert(_events.back()); -} - -void -AutomationList::add (double when, double value) -{ - /* this is for graphical editing */ - - { - Glib::Mutex::Lock lm (_lock); - ControlEvent cp (when, 0.0f); - bool insert = true; - iterator insertion_point; - - for (insertion_point = lower_bound (_events.begin(), _events.end(), &cp, time_comparator); insertion_point != _events.end(); ++insertion_point) { - - /* only one point allowed per time point */ - - if ((*insertion_point)->when == when) { - (*insertion_point)->value = value; - insert = false; - break; - } - - if ((*insertion_point)->when >= when) { - break; - } - } - - if (insert) { - - _events.insert (insertion_point, new ControlEvent (when, value)); - reposition_for_rt_add (0); - - } - - mark_dirty (); - } - - maybe_signal_changed (); -} - -void -AutomationList::erase (iterator i) -{ - { - Glib::Mutex::Lock lm (_lock); - _events.erase (i); - reposition_for_rt_add (0); - mark_dirty (); - } - maybe_signal_changed (); -} - -void -AutomationList::erase (iterator start, iterator end) -{ - { - Glib::Mutex::Lock lm (_lock); - _events.erase (start, end); - reposition_for_rt_add (0); - mark_dirty (); - } - maybe_signal_changed (); -} - -void -AutomationList::reset_range (double start, double endt) -{ - bool reset = false; - - { - Glib::Mutex::Lock lm (_lock); - ControlEvent cp (start, 0.0f); - iterator s; - iterator e; - - if ((s = lower_bound (_events.begin(), _events.end(), &cp, time_comparator)) != _events.end()) { - - cp.when = endt; - e = upper_bound (_events.begin(), _events.end(), &cp, time_comparator); - - for (iterator i = s; i != e; ++i) { - (*i)->value = _default_value; - } - - reset = true; - - mark_dirty (); - } - } - - if (reset) { - maybe_signal_changed (); - } -} - -void -AutomationList::erase_range (double start, double endt) -{ - bool erased = false; - - { - Glib::Mutex::Lock lm (_lock); - ControlEvent cp (start, 0.0f); - iterator s; - iterator e; - - if ((s = lower_bound (_events.begin(), _events.end(), &cp, time_comparator)) != _events.end()) { - cp.when = endt; - e = upper_bound (_events.begin(), _events.end(), &cp, time_comparator); - _events.erase (s, e); - reposition_for_rt_add (0); - erased = true; - mark_dirty (); - } - - } - - if (erased) { - maybe_signal_changed (); - } -} - -void -AutomationList::move_range (iterator start, iterator end, double xdelta, double ydelta) -{ - /* note: we assume higher level logic is in place to avoid this - reordering the time-order of control events in the list. ie. all - points after end are later than (end)->when. - */ - - { - Glib::Mutex::Lock lm (_lock); - - while (start != end) { - (*start)->when += xdelta; - (*start)->value += ydelta; - if (isnan ((*start)->value)) { - abort (); - } - ++start; - } - - if (!_frozen) { - _events.sort (sort_events_by_time); - } else { - _sort_pending = true; - } - - mark_dirty (); - } - - maybe_signal_changed (); -} - -void -AutomationList::slide (iterator before, double distance) -{ - { - Glib::Mutex::Lock lm (_lock); - - if (before == _events.end()) { - return; - } - - while (before != _events.end()) { - (*before)->when += distance; - ++before; - } - } - - maybe_signal_changed (); -} - -void -AutomationList::modify (iterator iter, double when, double val) -{ - /* note: we assume higher level logic is in place to avoid this - reordering the time-order of control events in the list. ie. all - points after *iter are later than when. - */ - - { - Glib::Mutex::Lock lm (_lock); - - (*iter)->when = when; - (*iter)->value = val; - - if (isnan (val)) { - abort (); - } - - if (!_frozen) { - _events.sort (sort_events_by_time); - } else { - _sort_pending = true; - } - - mark_dirty (); - } - - maybe_signal_changed (); -} - -std::pair<AutomationList::iterator,AutomationList::iterator> -AutomationList::control_points_adjacent (double xval) -{ - Glib::Mutex::Lock lm (_lock); - iterator i; - ControlEvent cp (xval, 0.0f); - std::pair<iterator,iterator> ret; - - ret.first = _events.end(); - ret.second = _events.end(); - - for (i = lower_bound (_events.begin(), _events.end(), &cp, time_comparator); i != _events.end(); ++i) { - - if (ret.first == _events.end()) { - if ((*i)->when >= xval) { - if (i != _events.begin()) { - ret.first = i; - --ret.first; - } else { - return ret; - } - } - } - - if ((*i)->when > xval) { - ret.second = i; - break; - } - } - - return ret; -} - -void -AutomationList::freeze () -{ - _frozen++; -} - -void -AutomationList::thaw () -{ - if (_frozen == 0) { - PBD::stacktrace (cerr); - fatal << string_compose (_("programming error: %1"), X_("AutomationList::thaw() called while not frozen")) << endmsg; - /*NOTREACHED*/ - } - - if (--_frozen > 0) { - return; - } - - { - Glib::Mutex::Lock lm (_lock); - - if (_sort_pending) { - _events.sort (sort_events_by_time); - _sort_pending = false; - } - } - - if (_changed_when_thawed) { - StateChanged(); /* EMIT SIGNAL */ - } -} - -void -AutomationList::set_max_xval (double x) -{ - _max_xval = x; -} - -void -AutomationList::mark_dirty () -{ - _lookup_cache.left = -1; - _search_cache.left = -1; - Dirty (); /* EMIT SIGNAL */ -} - -void -AutomationList::truncate_end (double last_coordinate) -{ - { - Glib::Mutex::Lock lm (_lock); - ControlEvent cp (last_coordinate, 0); - AutomationList::reverse_iterator i; - double last_val; - - if (_events.empty()) { - return; - } - - if (last_coordinate == _events.back()->when) { - return; - } - - if (last_coordinate > _events.back()->when) { - - /* extending end: - */ - - iterator foo = _events.begin(); - bool lessthantwo; - - if (foo == _events.end()) { - lessthantwo = true; - } else if (++foo == _events.end()) { - lessthantwo = true; - } else { - lessthantwo = false; - } - - if (lessthantwo) { - /* less than 2 points: add a new point */ - _events.push_back (new ControlEvent (last_coordinate, _events.back()->value)); - } else { - - /* more than 2 points: check to see if the last 2 values - are equal. if so, just move the position of the - last point. otherwise, add a new point. - */ - - iterator penultimate = _events.end(); - --penultimate; /* points at last point */ - --penultimate; /* points at the penultimate point */ - - if (_events.back()->value == (*penultimate)->value) { - _events.back()->when = last_coordinate; - } else { - _events.push_back (new ControlEvent (last_coordinate, _events.back()->value)); - } - } - - } else { - - /* shortening end */ - - last_val = unlocked_eval (last_coordinate); - last_val = max ((double) _min_yval, last_val); - last_val = min ((double) _max_yval, last_val); - - i = _events.rbegin(); - - /* make i point to the last control point */ - - ++i; - - /* now go backwards, removing control points that are - beyond the new last coordinate. - */ - - uint32_t sz = _events.size(); - - while (i != _events.rend() && sz > 2) { - AutomationList::reverse_iterator tmp; - - tmp = i; - ++tmp; - - if ((*i)->when < last_coordinate) { - break; - } - - _events.erase (i.base()); - --sz; - - i = tmp; - } - - _events.back()->when = last_coordinate; - _events.back()->value = last_val; - } - - reposition_for_rt_add (0); - mark_dirty(); - } - - maybe_signal_changed (); -} - -void -AutomationList::truncate_start (double overall_length) -{ - { - Glib::Mutex::Lock lm (_lock); - iterator i; - double first_legal_value; - double first_legal_coordinate; - - if (_events.empty()) { - fatal << _("programming error:") - << "AutomationList::truncate_start() called on an empty list" - << endmsg; - /*NOTREACHED*/ - return; - } - - if (overall_length == _events.back()->when) { - /* no change in overall length */ - return; - } - - if (overall_length > _events.back()->when) { - - /* growing at front: duplicate first point. shift all others */ - - double shift = overall_length - _events.back()->when; - uint32_t np; - - for (np = 0, i = _events.begin(); i != _events.end(); ++i, ++np) { - (*i)->when += shift; - } - - if (np < 2) { - - /* less than 2 points: add a new point */ - _events.push_front (new ControlEvent (0, _events.front()->value)); - - } else { - - /* more than 2 points: check to see if the first 2 values - are equal. if so, just move the position of the - first point. otherwise, add a new point. - */ - - iterator second = _events.begin(); - ++second; /* points at the second point */ - - if (_events.front()->value == (*second)->value) { - /* first segment is flat, just move start point back to zero */ - _events.front()->when = 0; - } else { - /* leave non-flat segment in place, add a new leading point. */ - _events.push_front (new ControlEvent (0, _events.front()->value)); - } - } - - } else { - - /* shrinking at front */ - - first_legal_coordinate = _events.back()->when - overall_length; - first_legal_value = unlocked_eval (first_legal_coordinate); - first_legal_value = max (_min_yval, first_legal_value); - first_legal_value = min (_max_yval, first_legal_value); - - /* remove all events earlier than the new "front" */ - - i = _events.begin(); - - while (i != _events.end() && !_events.empty()) { - AutomationList::iterator tmp; - - tmp = i; - ++tmp; - - if ((*i)->when > first_legal_coordinate) { - break; - } - - _events.erase (i); - - i = tmp; - } - - - /* shift all remaining points left to keep their same - relative position - */ - - for (i = _events.begin(); i != _events.end(); ++i) { - (*i)->when -= first_legal_coordinate; - } - - /* add a new point for the interpolated new value */ - - _events.push_front (new ControlEvent (0, first_legal_value)); - } - - reposition_for_rt_add (0); - - mark_dirty(); - } - - maybe_signal_changed (); -} - -double -AutomationList::unlocked_eval (double x) const -{ - pair<EventList::iterator,EventList::iterator> range; - int32_t npoints; - double lpos, upos; - double lval, uval; - double fraction; - - npoints = _events.size(); - - switch (npoints) { - case 0: - return _default_value; - - case 1: - if (x >= _events.front()->when) { - return _events.front()->value; - } else { - // return _default_value; - return _events.front()->value; - } - - case 2: - if (x >= _events.back()->when) { - return _events.back()->value; - } else if (x == _events.front()->when) { - return _events.front()->value; - } else if (x < _events.front()->when) { - // return _default_value; - return _events.front()->value; - } - - lpos = _events.front()->when; - lval = _events.front()->value; - upos = _events.back()->when; - uval = _events.back()->value; - - if (_interpolation == Discrete) - return lval; - - /* linear interpolation betweeen the two points - */ - - fraction = (double) (x - lpos) / (double) (upos - lpos); - return lval + (fraction * (uval - lval)); - - default: - - if (x >= _events.back()->when) { - return _events.back()->value; - } else if (x == _events.front()->when) { - return _events.front()->value; - } else if (x < _events.front()->when) { - // return _default_value; - return _events.front()->value; - } - - return multipoint_eval (x); - break; - } - - /*NOTREACHED*/ /* stupid gcc */ - return 0.0; -} - -double -AutomationList::multipoint_eval (double x) const -{ - double upos, lpos; - double uval, lval; - double fraction; - - /* "Stepped" lookup (no interpolation) */ - /* FIXME: no cache. significant? */ - if (_interpolation == Discrete) { - const ControlEvent cp (x, 0); - EventList::const_iterator i = lower_bound (_events.begin(), _events.end(), &cp, time_comparator); - - // shouldn't have made it to multipoint_eval - assert(i != _events.end()); - - if (i == _events.begin() || (*i)->when == x) - return (*i)->value; - else - return (*(--i))->value; - } - - /* Only do the range lookup if x is in a different range than last time - * this was called (or if the lookup cache has been marked "dirty" (left<0) */ - if ((_lookup_cache.left < 0) || - ((_lookup_cache.left > x) || - (_lookup_cache.range.first == _events.end()) || - ((*_lookup_cache.range.second)->when < x))) { - - const ControlEvent cp (x, 0); - - _lookup_cache.range = equal_range (_events.begin(), _events.end(), &cp, time_comparator); - } - - pair<const_iterator,const_iterator> range = _lookup_cache.range; - - if (range.first == range.second) { - - /* x does not exist within the list as a control point */ - - _lookup_cache.left = x; - - if (range.first != _events.begin()) { - --range.first; - lpos = (*range.first)->when; - lval = (*range.first)->value; - } else { - /* we're before the first point */ - // return _default_value; - return _events.front()->value; - } - - if (range.second == _events.end()) { - /* we're after the last point */ - return _events.back()->value; - } - - upos = (*range.second)->when; - uval = (*range.second)->value; - - /* linear interpolation betweeen the two points - on either side of x - */ - - fraction = (double) (x - lpos) / (double) (upos - lpos); - return lval + (fraction * (uval - lval)); - - } - - /* x is a control point in the data */ - _lookup_cache.left = -1; - return (*range.first)->value; -} - -void -AutomationList::build_search_cache_if_necessary(double start, double end) const -{ - /* Only do the range lookup if x is in a different range than last time - * this was called (or if the search cache has been marked "dirty" (left<0) */ - if (!_events.empty() && ((_search_cache.left < 0) || - ((_search_cache.left > start) || - (_search_cache.right < end)))) { - - const ControlEvent start_point (start, 0); - const ControlEvent end_point (end, 0); - - //cerr << "REBUILD: (" << _search_cache.left << ".." << _search_cache.right << ") := (" - // << start << ".." << end << ")" << endl; - - _search_cache.range.first = lower_bound (_events.begin(), _events.end(), &start_point, time_comparator); - _search_cache.range.second = upper_bound (_events.begin(), _events.end(), &end_point, time_comparator); - - _search_cache.left = start; - _search_cache.right = end; - } -} - -/** Get the earliest event between \a start and \a end, using the current interpolation style. - * - * If an event is found, \a x and \a y are set to its coordinates. - * - * \param inclusive Include events with timestamp exactly equal to \a start - * \return true if event is found (and \a x and \a y are valid). - */ -bool -AutomationList::rt_safe_earliest_event(double start, double end, double& x, double& y, bool inclusive) const -{ - // FIXME: It would be nice if this was unnecessary.. - Glib::Mutex::Lock lm(_lock, Glib::TRY_LOCK); - if (!lm.locked()) { - return false; - } - - return rt_safe_earliest_event_unlocked(start, end, x, y, inclusive); -} - - -/** Get the earliest event between \a start and \a end, using the current interpolation style. - * - * If an event is found, \a x and \a y are set to its coordinates. - * - * \param inclusive Include events with timestamp exactly equal to \a start - * \return true if event is found (and \a x and \a y are valid). - */ -bool -AutomationList::rt_safe_earliest_event_unlocked(double start, double end, double& x, double& y, bool inclusive) const -{ - if (_interpolation == Discrete) - return rt_safe_earliest_event_discrete_unlocked(start, end, x, y, inclusive); - else - return rt_safe_earliest_event_linear_unlocked(start, end, x, y, inclusive); -} - - -/** Get the earliest event between \a start and \a end (Discrete (lack of) interpolation) - * - * If an event is found, \a x and \a y are set to its coordinates. - * - * \param inclusive Include events with timestamp exactly equal to \a start - * \return true if event is found (and \a x and \a y are valid). - */ -bool -AutomationList::rt_safe_earliest_event_discrete_unlocked (double start, double end, double& x, double& y, bool inclusive) const -{ - build_search_cache_if_necessary(start, end); - - const pair<const_iterator,const_iterator>& range = _search_cache.range; - - if (range.first != _events.end()) { - const ControlEvent* const first = *range.first; - - const bool past_start = (inclusive ? first->when >= start : first->when > start); - - /* Earliest points is in range, return it */ - if (past_start >= start && first->when < end) { - - x = first->when; - y = first->value; - - /* Move left of cache to this point - * (Optimize for immediate call this cycle within range) */ - _search_cache.left = x; - ++_search_cache.range.first; - - assert(x >= start); - assert(x < end); - return true; - - } else { - return false; - } - - /* No points in range */ - } else { - return false; - } -} - -/** Get the earliest time the line crosses an integer (Linear interpolation). - * - * If an event is found, \a x and \a y are set to its coordinates. - * - * \param inclusive Include events with timestamp exactly equal to \a start - * \return true if event is found (and \a x and \a y are valid). - */ -bool -AutomationList::rt_safe_earliest_event_linear_unlocked (double start, double end, double& x, double& y, bool inclusive) const -{ - //cerr << "earliest_event(" << start << ", " << end << ", " << x << ", " << y << ", " << inclusive << endl; - - if (_events.size() == 0) - return false; - else if (_events.size() == 1) - return rt_safe_earliest_event_discrete_unlocked(start, end, x, y, inclusive); - - // Hack to avoid infinitely repeating the same event - build_search_cache_if_necessary(start, end); - - pair<const_iterator,const_iterator> range = _search_cache.range; - - if (range.first != _events.end()) { - - const ControlEvent* first = NULL; - const ControlEvent* next = NULL; - - /* Step is after first */ - if (range.first == _events.begin() || (*range.first)->when == start) { - first = *range.first; - next = *(++range.first); - ++_search_cache.range.first; - - /* Step is before first */ - } else { - const_iterator prev = range.first; - --prev; - first = *prev; - next = *range.first; - } - - if (inclusive && first->when == start) { - x = first->when; - y = first->value; - /* Move left of cache to this point - * (Optimize for immediate call this cycle within range) */ - _search_cache.left = x; - //++_search_cache.range.first; - return true; - } - - if (abs(first->value - next->value) <= 1) { - if (next->when <= end && (!inclusive || next->when > start)) { - x = next->when; - y = next->value; - /* Move left of cache to this point - * (Optimize for immediate call this cycle within range) */ - _search_cache.left = x; - //++_search_cache.range.first; - return true; - } else { - return false; - } - } - - const double slope = (next->value - first->value) / (double)(next->when - first->when); - //cerr << "start y: " << start_y << endl; - - //y = first->value + (slope * fabs(start - first->when)); - y = first->value; - - if (first->value < next->value) // ramping up - y = ceil(y); - else // ramping down - y = floor(y); - - x = first->when + (y - first->value) / (double)slope; - - while ((inclusive && x < start) || (x <= start && y != next->value)) { - - if (first->value < next->value) // ramping up - y += 1.0; - else // ramping down - y -= 1.0; - - x = first->when + (y - first->value) / (double)slope; - } - - /*cerr << first->value << " @ " << first->when << " ... " - << next->value << " @ " << next->when - << " = " << y << " @ " << x << endl;*/ - - assert( (y >= first->value && y <= next->value) - || (y <= first->value && y >= next->value) ); - - - const bool past_start = (inclusive ? x >= start : x > start); - if (past_start && x < end) { - /* Move left of cache to this point - * (Optimize for immediate call this cycle within range) */ - _search_cache.left = x; - - return true; - - } else { - return false; - } - - /* No points in the future, so no steps (towards them) in the future */ - } else { - return false; - } -} - -AutomationList* -AutomationList::cut (iterator start, iterator end) -{ - AutomationList* nal = new AutomationList (_parameter, _min_yval, _max_yval, _default_value); - - { - Glib::Mutex::Lock lm (_lock); - - for (iterator x = start; x != end; ) { - iterator tmp; - - tmp = x; - ++tmp; - - nal->_events.push_back (new ControlEvent (**x)); - _events.erase (x); - - reposition_for_rt_add (0); - - x = tmp; - } - - mark_dirty (); - } - - maybe_signal_changed (); - - return nal; -} - -AutomationList* -AutomationList::cut_copy_clear (double start, double end, int op) -{ - AutomationList* nal = new AutomationList (_parameter, _min_yval, _max_yval, _default_value); - iterator s, e; - ControlEvent cp (start, 0.0); - bool changed = false; - - { - Glib::Mutex::Lock lm (_lock); - - if ((s = lower_bound (_events.begin(), _events.end(), &cp, time_comparator)) == _events.end()) { - return nal; - } - - cp.when = end; - e = upper_bound (_events.begin(), _events.end(), &cp, time_comparator); - - if (op != 2 && (*s)->when != start) { - nal->_events.push_back (new ControlEvent (0, unlocked_eval (start))); - } - - for (iterator x = s; x != e; ) { - iterator tmp; - - tmp = x; - ++tmp; - - changed = true; - - /* adjust new points to be relative to start, which - has been set to zero. - */ - - if (op != 2) { - nal->_events.push_back (new ControlEvent ((*x)->when - start, (*x)->value)); - } - - if (op != 1) { - _events.erase (x); - } - - x = tmp; - } - - if (op != 2 && nal->_events.back()->when != end - start) { - nal->_events.push_back (new ControlEvent (end - start, unlocked_eval (end))); - } - - if (changed) { - reposition_for_rt_add (0); - } - - mark_dirty (); - } - - maybe_signal_changed (); - - return nal; - -} - -AutomationList* -AutomationList::copy (iterator start, iterator end) -{ - AutomationList* nal = new AutomationList (_parameter, _min_yval, _max_yval, _default_value); - - { - Glib::Mutex::Lock lm (_lock); - - for (iterator x = start; x != end; ) { - iterator tmp; - - tmp = x; - ++tmp; - - nal->_events.push_back (new ControlEvent (**x)); - - x = tmp; - } - } - - return nal; -} - -AutomationList* -AutomationList::cut (double start, double end) -{ - return cut_copy_clear (start, end, 0); -} - -AutomationList* -AutomationList::copy (double start, double end) -{ - return cut_copy_clear (start, end, 1); -} - -void -AutomationList::clear (double start, double end) -{ - (void) cut_copy_clear (start, end, 2); -} - -bool -AutomationList::paste (AutomationList& alist, double pos, float times) -{ - if (alist._events.empty()) { - return false; - } - - { - Glib::Mutex::Lock lm (_lock); - iterator where; - iterator prev; - double end = 0; - ControlEvent cp (pos, 0.0); - - where = upper_bound (_events.begin(), _events.end(), &cp, time_comparator); - - for (iterator i = alist.begin();i != alist.end(); ++i) { - _events.insert (where, new ControlEvent( (*i)->when+pos,( *i)->value)); - end = (*i)->when + pos; - } - - - /* move all points after the insertion along the timeline by - the correct amount. - */ - - while (where != _events.end()) { - iterator tmp; - if ((*where)->when <= end) { - tmp = where; - ++tmp; - _events.erase(where); - where = tmp; - - } else { - break; - } - } - - reposition_for_rt_add (0); - mark_dirty (); - } - - maybe_signal_changed (); - return true; -} - -XMLNode& -AutomationList::get_state () -{ - return state (true); -} - -XMLNode& -AutomationList::state (bool full) -{ - XMLNode* root = new XMLNode (X_("AutomationList")); - char buf[64]; - LocaleGuard lg (X_("POSIX")); - - root->add_property ("automation-id", _parameter.to_string()); - - root->add_property ("id", _id.to_s()); - - snprintf (buf, sizeof (buf), "%.12g", _default_value); - root->add_property ("default", buf); - snprintf (buf, sizeof (buf), "%.12g", _min_yval); - root->add_property ("min_yval", buf); - snprintf (buf, sizeof (buf), "%.12g", _max_yval); - root->add_property ("max_yval", buf); - snprintf (buf, sizeof (buf), "%.12g", _max_xval); - root->add_property ("max_xval", buf); - - root->add_property ("interpolation-style", enum_2_string (_interpolation)); - - if (full) { - root->add_property ("state", auto_state_to_string (_state)); - } else { - /* never save anything but Off for automation state to a template */ - root->add_property ("state", auto_state_to_string (Off)); - } - - root->add_property ("style", auto_style_to_string (_style)); - - if (!_events.empty()) { - root->add_child_nocopy (serialize_events()); - } - - return *root; -} - -XMLNode& -AutomationList::serialize_events () -{ - XMLNode* node = new XMLNode (X_("events")); - stringstream str; - - for (iterator xx = _events.begin(); xx != _events.end(); ++xx) { - str << (double) (*xx)->when; - str << ' '; - str <<(double) (*xx)->value; - str << '\n'; - } - - /* XML is a bit wierd */ - - XMLNode* content_node = new XMLNode (X_("foo")); /* it gets renamed by libxml when we set content */ - content_node->set_content (str.str()); - - node->add_child_nocopy (*content_node); - - return *node; -} - -int -AutomationList::deserialize_events (const XMLNode& node) -{ - if (node.children().empty()) { - return -1; - } - - XMLNode* content_node = node.children().front(); - - if (content_node->content().empty()) { - return -1; - } - - freeze (); - clear (); - - stringstream str (content_node->content()); - - double x; - double y; - bool ok = true; - - while (str) { - str >> x; - if (!str) { - break; - } - str >> y; - if (!str) { - ok = false; - break; - } - fast_simple_add (x, y); - } - - if (!ok) { - clear (); - error << _("automation list: cannot load coordinates from XML, all points ignored") << endmsg; - } else { - mark_dirty (); - reposition_for_rt_add (0); - maybe_signal_changed (); - } - - thaw (); - - return 0; -} - -int -AutomationList::set_state (const XMLNode& node) -{ - XMLNodeList nlist = node.children(); - XMLNode* nsos; - XMLNodeIterator niter; - const XMLProperty* prop; - - if (node.name() == X_("events")) { - /* partial state setting*/ - return deserialize_events (node); - } - - if (node.name() == X_("Envelope") || node.name() == X_("FadeOut") || node.name() == X_("FadeIn")) { - - if ((nsos = node.child (X_("AutomationList")))) { - /* new school in old school clothing */ - return set_state (*nsos); - } - - /* old school */ - - const XMLNodeList& elist = node.children(); - XMLNodeConstIterator i; - XMLProperty* prop; - nframes_t x; - double y; - - freeze (); - clear (); - - for (i = elist.begin(); i != elist.end(); ++i) { - - if ((prop = (*i)->property ("x")) == 0) { - error << _("automation list: no x-coordinate stored for control point (point ignored)") << endmsg; - continue; - } - x = atoi (prop->value().c_str()); - - if ((prop = (*i)->property ("y")) == 0) { - error << _("automation list: no y-coordinate stored for control point (point ignored)") << endmsg; - continue; - } - y = atof (prop->value().c_str()); - - fast_simple_add (x, y); - } - - thaw (); - - return 0; - } - - if (node.name() != X_("AutomationList") ) { - error << string_compose (_("AutomationList: passed XML node called %1, not \"AutomationList\" - ignored"), node.name()) << endmsg; - return -1; - } - - if ((prop = node.property ("id")) != 0) { - _id = prop->value (); - /* update session AL list */ - AutomationListCreated(this); - } - - if ((prop = node.property (X_("automation-id"))) != 0){ - _parameter = Parameter(prop->value()); - } else { - warning << "Legacy session: automation list has no automation-id property."; - } - - if ((prop = node.property (X_("interpolation-style"))) != 0) { - _interpolation = (InterpolationStyle)string_2_enum(prop->value(), _interpolation); - } else { - _interpolation = Linear; - } - - if ((prop = node.property (X_("default"))) != 0){ - _default_value = atof (prop->value().c_str()); - } else { - _default_value = 0.0; - } - - if ((prop = node.property (X_("style"))) != 0) { - _style = string_to_auto_style (prop->value()); - } else { - _style = Absolute; - } - - if ((prop = node.property (X_("state"))) != 0) { - _state = string_to_auto_state (prop->value()); - } else { - _state = Off; - } - - if ((prop = node.property (X_("min_yval"))) != 0) { - _min_yval = atof (prop->value ().c_str()); - } else { - _min_yval = FLT_MIN; - } - - if ((prop = node.property (X_("max_yval"))) != 0) { - _max_yval = atof (prop->value ().c_str()); - } else { - _max_yval = FLT_MAX; - } - - if ((prop = node.property (X_("max_xval"))) != 0) { - _max_xval = atof (prop->value ().c_str()); - } else { - _max_xval = 0; // means "no limit ; - } - - for (niter = nlist.begin(); niter != nlist.end(); ++niter) { - if ((*niter)->name() == X_("events")) { - deserialize_events (*(*niter)); - } - } - - return 0; -} - diff --git a/libs/ardour/base_audio_port.cc b/libs/ardour/base_audio_port.cc deleted file mode 100644 index ceec4c1d3a..0000000000 --- a/libs/ardour/base_audio_port.cc +++ /dev/null @@ -1,82 +0,0 @@ -/* - 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. -*/ - -#include <cassert> -#include <glib.h> -#include <ardour/base_audio_port.h> -#include <ardour/audioengine.h> -#include <ardour/data_type.h> - -using namespace ARDOUR; -using namespace std; - -nframes_t BaseAudioPort::_short_over_length = 2; -nframes_t BaseAudioPort::_long_over_length = 10; - -BaseAudioPort::BaseAudioPort (const std::string& name, Flags flgs) - : Port (name, flgs) - , _buffer (0) - , _own_buffer (false) -{ - _type = DataType::AUDIO; - _mixdown = default_mixdown; -} - -BaseAudioPort::~BaseAudioPort () -{ - if (_own_buffer && _buffer) { - delete _buffer; - } -} - -void -BaseAudioPort::reset() -{ - Port::reset(); - - if (_own_buffer && _buffer) { - _buffer->resize (engine->frames_per_cycle()); - _buffer->clear (); - } - - _metering = 0; - reset_meters (); -} - -void -BaseAudioPort::default_mixdown (const set<Port*>& ports, AudioBuffer* dest, nframes_t cnt, nframes_t offset, bool first_overwrite) -{ - set<Port*>::const_iterator p = ports.begin(); - - if (first_overwrite) { - dest->read_from ((dynamic_cast<BaseAudioPort*>(*p))->get_audio_buffer(), cnt, offset); - p++; - } - - for (; p != ports.end(); ++p) { - dest->accumulate_from ((dynamic_cast<BaseAudioPort*>(*p))->get_audio_buffer(), cnt, offset); - } -} - -void -BaseAudioPort::set_mixdown_function (void (*func)(const set<Port*>&, AudioBuffer*, nframes_t, nframes_t, bool)) -{ - g_atomic_pointer_set(&_mixdown, func); -} - - diff --git a/libs/ardour/base_midi_port.cc b/libs/ardour/base_midi_port.cc deleted file mode 100644 index 49d748dd20..0000000000 --- a/libs/ardour/base_midi_port.cc +++ /dev/null @@ -1,67 +0,0 @@ -/* - 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. -*/ - -#include <cassert> -#include <iostream> -#include <glib.h> -#include <ardour/base_midi_port.h> -#include <ardour/data_type.h> - -using namespace ARDOUR; -using namespace std; - -BaseMidiPort::BaseMidiPort (const std::string& name, Flags flags) - : Port (name, flags) - , _buffer (0) - , _own_buffer (false) -{ - _type = DataType::MIDI; - _mixdown = default_mixdown; -} - -BaseMidiPort::~BaseMidiPort() -{ - if (_own_buffer && _buffer) { - delete _buffer; - } -} - -void -BaseMidiPort::default_mixdown (const set<Port*>& ports, MidiBuffer* dest, nframes_t cnt, nframes_t offset, bool first_overwrite) -{ - set<Port*>::const_iterator p = ports.begin(); - - if (first_overwrite) { - cout << "first overwrite" << endl; - dest->read_from ((dynamic_cast<BaseMidiPort*>(*p))->get_midi_buffer(), cnt, offset); - p++; - } - - // XXX DAVE: this is just a guess - - for (; p != ports.end(); ++p) { - cout << "merge" << endl; - dest->merge (*dest, (dynamic_cast<BaseMidiPort*>(*p))->get_midi_buffer()); - } -} - -void -BaseMidiPort::set_mixdown_function (void (*func)(const set<Port*>&, MidiBuffer*, nframes_t, nframes_t, bool)) -{ - g_atomic_pointer_set(&_mixdown, func); -} diff --git a/libs/ardour/buffer.cc b/libs/ardour/buffer.cc deleted file mode 100644 index 8abe238a47..0000000000 --- a/libs/ardour/buffer.cc +++ /dev/null @@ -1,45 +0,0 @@ -/* - 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. -*/ - -#include <ardour/buffer.h> -#include <ardour/audio_buffer.h> -#include <ardour/midi_buffer.h> - -#ifdef __x86_64__ -static const int CPU_CACHE_ALIGN = 64; -#else -static const int CPU_CACHE_ALIGN = 16; /* arguably 32 on most arches, but it matters less */ -#endif - -namespace ARDOUR { - - -Buffer* -Buffer::create(DataType type, size_t capacity) -{ - if (type == DataType::AUDIO) - return new AudioBuffer(capacity); - else if (type == DataType::MIDI) - return new MidiBuffer(capacity); - else - return NULL; -} - - -} // namespace ARDOUR - diff --git a/libs/ardour/buffer_set.cc b/libs/ardour/buffer_set.cc deleted file mode 100644 index 65e9f8ac8f..0000000000 --- a/libs/ardour/buffer_set.cc +++ /dev/null @@ -1,177 +0,0 @@ -/* - 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. -*/ - -#include <algorithm> -#include <ardour/buffer_set.h> -#include <ardour/buffer.h> -#include <ardour/port.h> -#include <ardour/port_set.h> - -namespace ARDOUR { - -/** Create a new, empty BufferSet */ -BufferSet::BufferSet() - : _is_mirror(false) -{ - for (size_t i=0; i < DataType::num_types; ++i) - _buffers.push_back( BufferVec() ); - - _count.reset(); - _available.reset(); -} - -BufferSet::~BufferSet() -{ - clear(); -} - -/** Destroy all contained buffers. - */ -void -BufferSet::clear() -{ - if (!_is_mirror) { - for (std::vector<BufferVec>::iterator i = _buffers.begin(); i != _buffers.end(); ++i) { - for (BufferVec::iterator j = (*i).begin(); j != (*i).end(); ++j) { - delete *j; - } - (*i).clear(); - } - } - _buffers.clear(); - _count.reset(); - _available.reset(); -} - -/** Make this BufferSet a direct mirror of a PortSet's buffers. - */ -void -BufferSet::attach_buffers(PortSet& ports) -{ - clear(); - - for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) { - _buffers.push_back(BufferVec()); - BufferVec& v = _buffers[*t]; - - for (PortSet::iterator p = ports.begin(*t); p != ports.end(*t); ++p) { - assert(p->type() == *t); - v.push_back(&(p->get_buffer())); - } - - } - - _count = ports.count(); - - _is_mirror = true; -} - -void -BufferSet::ensure_buffers(const ChanCount& count, size_t buffer_capacity) -{ - for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) { - ensure_buffers(*t, count.get(*t), buffer_capacity); - } -} - - -/** Ensure that there are @a num_buffers buffers of type @a type available, - * each of size at least @a buffer_size - */ -void -BufferSet::ensure_buffers(DataType type, size_t num_buffers, size_t buffer_capacity) -{ - assert(type != DataType::NIL); - assert(type < _buffers.size()); - assert(buffer_capacity > 0); - - if (num_buffers == 0) - return; - - // FIXME: Kludge to make MIDI buffers larger (size is bytes, not frames) - // See MidiPort::MidiPort - // We probably need a map<DataType, size_t> parameter for capacity - if (type == DataType::MIDI) - buffer_capacity *= 8; - - // The vector of buffers of the type we care about - BufferVec& bufs = _buffers[type]; - - // If we're a mirror just make sure we're ok - if (_is_mirror) { - assert(_count.get(type) >= num_buffers); - assert(bufs[0]->type() == type); - return; - } - - // If there's not enough or they're too small, just nuke the whole thing and - // rebuild it (so I'm lazy..) - if (bufs.size() < num_buffers - || (bufs.size() > 0 && bufs[0]->capacity() < buffer_capacity)) { - - // Nuke it - for (BufferVec::iterator i = bufs.begin(); i != bufs.end(); ++i) { - delete (*i); - } - bufs.clear(); - - // Rebuild it - for (size_t i=0; i < num_buffers; ++i) { - bufs.push_back(Buffer::create(type, buffer_capacity)); - } - - _available.set(type, num_buffers); - } - - // Post-conditions - assert(bufs[0]->type() == type); - assert(bufs.size() >= num_buffers); - assert(bufs.size() == _available.get(type)); - assert(bufs[0]->capacity() >= buffer_capacity); -} - -/** Get the capacity (size) of the available buffers of the given type. - * - * All buffers of a certain type always have the same capacity. - */ -size_t -BufferSet::buffer_capacity(DataType type) const -{ - assert(_available.get(type) > 0); - return _buffers[type][0]->capacity(); -} - -// FIXME: make 'in' const -void -BufferSet::read_from(BufferSet& in, nframes_t nframes, nframes_t offset) -{ - assert(available() >= in.count()); - - // Copy all buffers 1:1 - for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) { - BufferSet::iterator o = begin(*t); - for (BufferSet::iterator i = in.begin(*t); i != in.end(*t); ++i, ++o) { - o->read_from(*i, nframes, offset); - } - } - - set_count(in.count()); -} - -} // namespace ARDOUR - diff --git a/libs/ardour/bundle.cc b/libs/ardour/bundle.cc deleted file mode 100644 index 0d8c36a84f..0000000000 --- a/libs/ardour/bundle.cc +++ /dev/null @@ -1,282 +0,0 @@ -/* - 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. - -*/ - -#include <algorithm> - -#include <pbd/failed_constructor.h> -#include <ardour/ardour.h> -#include <ardour/bundle.h> -#include <pbd/xml++.h> - -#include "i18n.h" - -using namespace ARDOUR; -using namespace PBD; - -/** Construct a Bundle from an XML node. - * @param node XML node. - */ -Bundle::Bundle (const XMLNode& node) -{ - if (set_state (node)) { - throw failed_constructor(); - } -} - -/** Construct an InputBundle from an XML node. - * @param node XML node. - */ -InputBundle::InputBundle (const XMLNode& node) - : Bundle (node) -{ - -} - -/** Construct an OutputBundle from an XML node. - * @param node XML node. - */ -OutputBundle::OutputBundle (const XMLNode& node) - : Bundle (node) -{ - -} - -/** Set the name. - * @param name New name. - */ -void -Bundle::set_name (string name, void *src) -{ - _name = name; - NameChanged (src); -} - -/** Add an association between one of our channels and a JACK port. - * @param ch Channel index. - * @param portname JACK port name to associate with. - */ -void -Bundle::add_port_to_channel (int ch, string portname) -{ - { - Glib::Mutex::Lock lm (channels_lock); - _channels[ch].push_back (portname); - } - - PortsChanged (ch); /* EMIT SIGNAL */ -} - -/** Disassociate a JACK port from one of our channels. - * @param ch Channel index. - * @param portname JACK port name to disassociate from. - */ - -void -Bundle::remove_port_from_channel (int ch, string portname) -{ - bool changed = false; - - { - Glib::Mutex::Lock lm (channels_lock); - PortList& pl = _channels[ch]; - PortList::iterator i = find (pl.begin(), pl.end(), portname); - - if (i != pl.end()) { - pl.erase (i); - changed = true; - } - } - - if (changed) { - PortsChanged (ch); /* EMIT SIGNAL */ - } -} - -/** - * @param ch Channel index. - * @return List of JACK ports that this channel is connected to. - */ -const Bundle::PortList& -Bundle::channel_ports (int ch) const -{ - Glib::Mutex::Lock lm (channels_lock); - return _channels[ch]; -} - -/** operator== for Bundles; they are equal if their channels are the same. - * @param other Bundle to compare with this one. - */ -bool -Bundle::operator== (const Bundle& other) const -{ - return other._channels == _channels; -} - - -/** Set the number of channels. - * @param n New number of channels. - */ - -void -Bundle::set_nchannels (int n) -{ - { - Glib::Mutex::Lock lm (channels_lock); - _channels.clear (); - for (int i = 0; i < n; ++i) { - _channels.push_back (PortList()); - } - } - - ConfigurationChanged (); /* EMIT SIGNAL */ -} - -XMLNode& -Bundle::get_state () -{ - XMLNode *node; - string str; - - if (dynamic_cast<InputBundle *> (this)) { - node = new XMLNode ("InputConnection"); - } else { - node = new XMLNode ("OutputConnection"); - } - - node->add_property ("name", _name); - - for (vector<PortList>::iterator i = _channels.begin(); i != _channels.end(); ++i) { - - str += '{'; - - for (vector<string>::iterator ii = (*i).begin(); ii != (*i).end(); ++ii) { - if (ii != (*i).begin()) { - str += ','; - } - str += *ii; - } - str += '}'; - } - - node->add_property ("connections", str); - - return *node; -} - -int -Bundle::set_state (const XMLNode& node) -{ - const XMLProperty *prop; - - if ((prop = node.property ("name")) == 0) { - error << _("Node for Connection has no \"name\" property") << endmsg; - return -1; - } - - _name = prop->value(); - _dynamic = false; - - if ((prop = node.property ("connections")) == 0) { - error << _("Node for Connection has no \"connections\" property") << endmsg; - return -1; - } - - set_channels (prop->value()); - - return 0; -} - -/** Set up channels from an XML property string. - * @param str String. - * @return 0 on success, -1 on error. - */ -int -Bundle::set_channels (const string& str) -{ - vector<string> ports; - int i; - int n; - int nchannels; - - if ((nchannels = count (str.begin(), str.end(), '{')) == 0) { - return 0; - } - - set_nchannels (nchannels); - - string::size_type start, end, ostart; - - ostart = 0; - start = 0; - end = 0; - i = 0; - - while ((start = str.find_first_of ('{', ostart)) != string::npos) { - start += 1; - - if ((end = str.find_first_of ('}', start)) == string::npos) { - error << string_compose(_("IO: badly formed string in XML node for inputs \"%1\""), str) << endmsg; - return -1; - } - - if ((n = parse_io_string (str.substr (start, end - start), ports)) < 0) { - error << string_compose(_("bad input string in XML node \"%1\""), str) << endmsg; - - return -1; - - } else if (n > 0) { - - for (int x = 0; x < n; ++x) { - add_port_to_channel (i, ports[x]); - } - } - - ostart = end+1; - i++; - } - - return 0; -} - -int -Bundle::parse_io_string (const string& str, vector<string>& ports) -{ - string::size_type pos, opos; - - if (str.length() == 0) { - return 0; - } - - pos = 0; - opos = 0; - - ports.clear (); - - while ((pos = str.find_first_of (',', opos)) != string::npos) { - ports.push_back (str.substr (opos, pos - opos)); - opos = pos + 1; - } - - if (opos < str.length()) { - ports.push_back (str.substr(opos)); - } - - return ports.size(); -} - diff --git a/libs/ardour/caimportable.cc b/libs/ardour/caimportable.cc deleted file mode 100644 index 229bfa8809..0000000000 --- a/libs/ardour/caimportable.cc +++ /dev/null @@ -1,118 +0,0 @@ -#include <ardour/caimportable.h> -#include <sndfile.h> -#include <pbd/error.h> - -#include "i18n.h" - -using namespace ARDOUR; -using namespace std; -using namespace PBD; - -CAImportableSource::CAImportableSource (const string& path) -{ - try { - af.Open (path.c_str()); - - CAStreamBasicDescription file_format (af.GetFileDataFormat()); - CAStreamBasicDescription client_format (file_format); - - /* set canonial form (PCM, native float packed, 32 bit, with the correct number of channels - and interleaved (since we plan to deinterleave ourselves) - */ - - client_format.SetCanonical(client_format.NumberChannels(), true); - af.SetClientFormat (client_format); - - } catch (CAXException& cax) { - error << string_compose ("CAImportable: %1", cax.mOperation) << endmsg; - throw failed_constructor (); - } - -} - -CAImportableSource::~CAImportableSource () -{ -} - -nframes_t -CAImportableSource::read (Sample* buffer, nframes_t nframes) -{ - nframes_t nread = 0; - AudioBufferList abl; - nframes_t per_channel; - bool at_end = false; - - abl.mNumberBuffers = 1; - abl.mBuffers[0].mNumberChannels = channels(); - - per_channel = nframes / abl.mBuffers[0].mNumberChannels; - - while (nread < per_channel) { - - UInt32 new_cnt = per_channel - nread; - - abl.mBuffers[0].mDataByteSize = new_cnt * abl.mBuffers[0].mNumberChannels * sizeof(Sample); - abl.mBuffers[0].mData = buffer + nread; - - try { - af.Read (new_cnt, &abl); - } catch (CAXException& cax) { - error << string_compose("CAImportable: %1", cax.mOperation); - return -1; - } - - if (new_cnt == 0) { - /* EOF */ - at_end = true; - break; - } - - nread += new_cnt; - } - - if (!at_end && nread < per_channel) { - return 0; - } else { - return nread * abl.mBuffers[0].mNumberChannels; - } -} - -uint -CAImportableSource::channels () const -{ - return af.GetFileDataFormat().NumberChannels(); -} - -nframes_t -CAImportableSource::length () const -{ - return af.GetNumberFrames(); -} - -nframes_t -CAImportableSource::samplerate() const -{ - CAStreamBasicDescription client_asbd; - - try { - client_asbd = af.GetClientDataFormat (); - } catch (CAXException& cax) { - error << string_compose ("CAImportable: %1", cax.mOperation) << endmsg; - return 0.0; - } - - return client_asbd.mSampleRate; -} - -void -CAImportableSource::seek (nframes_t pos) -{ - try { - af.Seek (pos); - } catch (CAXException& cax) { - error << string_compose ("CAImportable: %1 to %2", cax.mOperation, pos) << endmsg; - } -} - - - diff --git a/libs/ardour/chan_count.cc b/libs/ardour/chan_count.cc deleted file mode 100644 index b6f51a4d95..0000000000 --- a/libs/ardour/chan_count.cc +++ /dev/null @@ -1,48 +0,0 @@ -/* - 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. - - $Id: insert.cc 712 2006-07-28 01:08:57Z drobilla $ -*/ - -#define __STDC_LIMIT_MACROS 1 -#include <stdint.h> -#include <ardour/chan_count.h> - -namespace ARDOUR { - -// infinite/zero chan count stuff, for setting minimums and maximums, etc. -// FIXME: implement this in a less fugly way - -ChanCount -infinity_factory() -{ - ChanCount ret; - - for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) { - ret.set(*t, UINT32_MAX); - } - - return ret; -} - - -// Statics -const ChanCount ChanCount::INFINITE = infinity_factory(); -const ChanCount ChanCount::ZERO = ChanCount(); - - -} // namespace ARDOUR diff --git a/libs/ardour/configuration.cc b/libs/ardour/configuration.cc deleted file mode 100644 index b164d418ab..0000000000 --- a/libs/ardour/configuration.cc +++ /dev/null @@ -1,371 +0,0 @@ -/* - Copyright (C) 1999-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. - -*/ - -#include <unistd.h> -#include <cstdio> /* for snprintf, grrr */ - -#include <glib.h> -#include <glib/gstdio.h> /* for g_stat() */ - -#include <pbd/failed_constructor.h> -#include <pbd/xml++.h> -#include <pbd/filesystem.h> -#include <pbd/file_utils.h> - -#include <midi++/manager.h> - -#include <ardour/ardour.h> -#include <ardour/configuration.h> -#include <ardour/audio_diskstream.h> -#include <ardour/control_protocol_manager.h> -#include <ardour/filesystem_paths.h> - -#include "i18n.h" - -using namespace ARDOUR; -using namespace std; -using namespace PBD; - -/* this is global so that we do not have to indirect through an object pointer - to reference it. -*/ - -namespace ARDOUR { - float speed_quietning = 0.251189; // -12dB reduction for ffwd or rewind -} - -Configuration::Configuration () - : -/* construct variables */ -#undef CONFIG_VARIABLE -#undef CONFIG_VARIABLE_SPECIAL -#define CONFIG_VARIABLE(Type,var,name,value) var (name,value), -#define CONFIG_VARIABLE_SPECIAL(Type,var,name,value,mutator) var (name,value,mutator), -#include "ardour/configuration_vars.h" -#undef CONFIG_VARIABLE -#undef CONFIG_VARIABLE_SPECIAL - - - current_owner (ConfigVariableBase::Default) -{ - _control_protocol_state = 0; -} - -Configuration::~Configuration () -{ -} - -void -Configuration::set_current_owner (ConfigVariableBase::Owner owner) -{ - current_owner = owner; -} - -int -Configuration::load_state () -{ - bool found = false; - - sys::path system_rc_file; - struct stat statbuf; - - /* load system configuration first */ - - if ( find_file_in_search_path (ardour_search_path() + system_config_search_path(), - "ardour_system.rc", system_rc_file) ) - { - XMLTree tree; - found = true; - - string rcfile = system_rc_file.to_string(); - - /* stupid XML Parser hates empty files */ - - if (g_stat (rcfile.c_str(), &statbuf)) { - return -1; - } - - if (statbuf.st_size != 0) { - cerr << string_compose (_("loading system configuration file %1"), rcfile) << endl; - - if (!tree.read (rcfile.c_str())) { - error << string_compose(_("Ardour: cannot read system configuration file \"%1\""), rcfile) << endmsg; - return -1; - } - - current_owner = ConfigVariableBase::System; - - if (set_state (*tree.root())) { - error << string_compose(_("Ardour: system configuration file \"%1\" not loaded successfully."), rcfile) << endmsg; - return -1; - } - } else { - error << _("your system Ardour configuration file is empty. This probably means that there as an error installing Ardour") << endmsg; - } - } - - /* now load configuration file for user */ - - sys::path user_rc_file; - - if (find_file_in_search_path (ardour_search_path() + user_config_directory(), - "ardour.rc", user_rc_file)) - { - XMLTree tree; - - string rcfile = user_rc_file.to_string(); - - /* stupid XML parser hates empty files */ - - if (g_stat (rcfile.c_str(), &statbuf)) { - return -1; - } - - if (statbuf.st_size != 0) { - cerr << string_compose (_("loading user configuration file %1"), rcfile) << endl; - - if (!tree.read (rcfile)) { - error << string_compose(_("Ardour: cannot read configuration file \"%1\""), rcfile) << endmsg; - return -1; - } - - current_owner = ConfigVariableBase::Config; - - if (set_state (*tree.root())) { - error << string_compose(_("Ardour: user configuration file \"%1\" not loaded successfully."), rcfile) << endmsg; - return -1; - } - } else { - warning << _("your Ardour configuration file is empty. This is not normal.") << endmsg; - } - } - - if (!found) - error << "Ardour: could not find configuration file (ardour.rc), canvas will look broken." << endmsg; - - return 0; -} - -int -Configuration::save_state() -{ - XMLTree tree; - - try - { - sys::create_directories (user_config_directory ()); - } - catch (const sys::filesystem_error& ex) - { - error << "Could not create user configuration directory" << endmsg; - return -1; - } - - sys::path rcfile_path(user_config_directory()); - - rcfile_path /= "ardour.rc"; - const string rcfile = rcfile_path.to_string(); - - // this test seems bogus? - if (rcfile.length()) { - tree.set_root (&get_state()); - if (!tree.write (rcfile.c_str())){ - error << string_compose (_("Config file %1 not saved"), rcfile) << endmsg; - return -1; - } - } - - return 0; -} - -void -Configuration::add_instant_xml(XMLNode& node) -{ - Stateful::add_instant_xml (node, user_config_directory ()); -} - -XMLNode* -Configuration::instant_xml(const string& node_name) -{ - return Stateful::instant_xml (node_name, user_config_directory ()); -} - - -bool -Configuration::save_config_options_predicate (ConfigVariableBase::Owner owner) -{ - /* only save things that were in the config file to start with */ - return owner & ConfigVariableBase::Config; -} - -XMLNode& -Configuration::get_state () -{ - XMLNode* root; - LocaleGuard lg (X_("POSIX")); - - root = new XMLNode("Ardour"); - - MIDI::Manager::PortMap::const_iterator i; - const MIDI::Manager::PortMap& ports = MIDI::Manager::instance()->get_midi_ports(); - - for (i = ports.begin(); i != ports.end(); ++i) { - root->add_child_nocopy(i->second->get_state()); - } - - root->add_child_nocopy (get_variables (sigc::mem_fun (*this, &Configuration::save_config_options_predicate), "Config")); - - if (_extra_xml) { - root->add_child_copy (*_extra_xml); - } - - root->add_child_nocopy (ControlProtocolManager::instance().get_state()); - - return *root; -} - -XMLNode& -Configuration::get_variables (sigc::slot<bool,ConfigVariableBase::Owner> predicate, std::string which_node) -{ - XMLNode* node; - LocaleGuard lg (X_("POSIX")); - - node = new XMLNode(which_node); - -#undef CONFIG_VARIABLE -#undef CONFIG_VARIABLE_SPECIAL -#define CONFIG_VARIABLE(type,var,Name,value) \ - if (node->name() == "Config") { if (predicate (var.owner())) { var.add_to_node (*node); }} -#define CONFIG_VARIABLE_SPECIAL(type,var,Name,value,mutator) \ - if (node->name() == "Config") { if (predicate (var.owner())) { var.add_to_node (*node); }} -#include "ardour/configuration_vars.h" -#undef CONFIG_VARIABLE -#undef CONFIG_VARIABLE_SPECIAL - - return *node; -} - -int -Configuration::set_state (const XMLNode& root) -{ - if (root.name() != "Ardour") { - return -1; - } - - XMLNodeList nlist = root.children(); - XMLNodeConstIterator niter; - XMLNode *node; - - for (niter = nlist.begin(); niter != nlist.end(); ++niter) { - - node = *niter; - - if (node->name() == "MIDI-port") { - - try { - - MIDI::Port::Descriptor desc (*node); - map<string,XMLNode>::iterator x; - if ((x = midi_ports.find (desc.tag)) != midi_ports.end()) { - midi_ports.erase (x); - } - midi_ports.insert (pair<string,XMLNode>(desc.tag,*node)); - } - - catch (failed_constructor& err) { - warning << _("ill-formed MIDI port specification in ardour rcfile (ignored)") << endmsg; - } - - } else if (node->name() == "Config") { - - set_variables (*node, ConfigVariableBase::Config); - - } else if (node->name() == "extra") { - _extra_xml = new XMLNode (*node); - - } else if (node->name() == ControlProtocolManager::state_node_name) { - _control_protocol_state = new XMLNode (*node); - } - } - - Diskstream::set_disk_io_chunk_frames (minimum_disk_io_bytes.get() / sizeof (Sample)); - - return 0; -} - -void -Configuration::set_variables (const XMLNode& node, ConfigVariableBase::Owner owner) -{ -#undef CONFIG_VARIABLE -#undef CONFIG_VARIABLE_SPECIAL -#define CONFIG_VARIABLE(type,var,name,value) \ - if (var.set_from_node (node, owner)) { \ - ParameterChanged (name); \ - } -#define CONFIG_VARIABLE_SPECIAL(type,var,name,value,mutator) \ - if (var.set_from_node (node, owner)) { \ - ParameterChanged (name); \ - } - -#include "ardour/configuration_vars.h" -#undef CONFIG_VARIABLE -#undef CONFIG_VARIABLE_SPECIAL - -} -void -Configuration::map_parameters (sigc::slot<void,const char*> theSlot) -{ -#undef CONFIG_VARIABLE -#undef CONFIG_VARIABLE_SPECIAL -#define CONFIG_VARIABLE(type,var,name,value) theSlot (name); -#define CONFIG_VARIABLE_SPECIAL(type,var,name,value,mutator) theSlot (name); -#include "ardour/configuration_vars.h" -#undef CONFIG_VARIABLE -#undef CONFIG_VARIABLE_SPECIAL -} - -bool ConfigVariableBase::show_stores = false; - -void -ConfigVariableBase::set_show_stored_values (bool yn) -{ - show_stores = yn; -} - -void -ConfigVariableBase::show_stored_value (const string& str) -{ - if (show_stores) { - cerr << "Config variable " << _name << " stored as " << str << endl; - } -} - -void -ConfigVariableBase::notify () -{ - // placeholder for any debugging desired when a config variable is modified -} - -void -ConfigVariableBase::miss () -{ - // placeholder for any debugging desired when a config variable - // is set but to the same value as it already has -} - diff --git a/libs/ardour/control_protocol_manager.cc b/libs/ardour/control_protocol_manager.cc deleted file mode 100644 index 11c18175d1..0000000000 --- a/libs/ardour/control_protocol_manager.cc +++ /dev/null @@ -1,390 +0,0 @@ -/* - 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. - -*/ - -#include <dlfcn.h> - -#include <pbd/compose.h> -#include <pbd/file_utils.h> -#include <pbd/error.h> - -#include <control_protocol/control_protocol.h> - -#include <ardour/session.h> -#include <ardour/control_protocol_manager.h> -#include <ardour/control_protocol_search_path.h> - -using namespace ARDOUR; -using namespace std; -using namespace PBD; - -#include "i18n.h" - -ControlProtocolManager* ControlProtocolManager::_instance = 0; -const string ControlProtocolManager::state_node_name = X_("ControlProtocols"); - -ControlProtocolManager::ControlProtocolManager () -{ - if (_instance == 0) { - _instance = this; - } - - _session = 0; -} - -ControlProtocolManager::~ControlProtocolManager() -{ - Glib::Mutex::Lock lm (protocols_lock); - - for (list<ControlProtocol*>::iterator i = control_protocols.begin(); i != control_protocols.end(); ++i) { - delete (*i); - } - - control_protocols.clear (); - - - for (list<ControlProtocolInfo*>::iterator p = control_protocol_info.begin(); p != control_protocol_info.end(); ++p) { - delete (*p); - } - - control_protocol_info.clear(); -} - -void -ControlProtocolManager::set_session (Session& s) -{ - _session = &s; - _session->GoingAway.connect (mem_fun (*this, &ControlProtocolManager::drop_session)); - - for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) { - if ((*i)->requested || (*i)->mandatory) { - instantiate (**i); - (*i)->requested = false; - - if ((*i)->protocol && (*i)->state) { - (*i)->protocol->set_state (*(*i)->state); - } - } - } -} - -void -ControlProtocolManager::drop_session () -{ - _session = 0; - - { - Glib::Mutex::Lock lm (protocols_lock); - for (list<ControlProtocol*>::iterator p = control_protocols.begin(); p != control_protocols.end(); ++p) { - delete *p; - } - control_protocols.clear (); - - for (list<ControlProtocolInfo*>::iterator p = control_protocol_info.begin(); p != control_protocol_info.end(); ++p) { - // otherwise the ControlProtocol instances are not recreated in set_session - if ((*p)->protocol) { - (*p)->requested = true; - (*p)->protocol = 0; - } - } - } -} - -ControlProtocol* -ControlProtocolManager::instantiate (ControlProtocolInfo& cpi) -{ - if (_session == 0) { - return 0; - } - - cpi.descriptor = get_descriptor (cpi.path); - - if (cpi.descriptor == 0) { - error << string_compose (_("control protocol name \"%1\" has no descriptor"), cpi.name) << endmsg; - return 0; - } - - if ((cpi.protocol = cpi.descriptor->initialize (cpi.descriptor, _session)) == 0) { - error << string_compose (_("control protocol name \"%1\" could not be initialized"), cpi.name) << endmsg; - return 0; - } - - Glib::Mutex::Lock lm (protocols_lock); - control_protocols.push_back (cpi.protocol); - - return cpi.protocol; -} - -int -ControlProtocolManager::teardown (ControlProtocolInfo& cpi) -{ - if (!cpi.protocol) { - return 0; - } - - if (!cpi.descriptor) { - return 0; - } - - if (cpi.mandatory) { - return 0; - } - - cpi.descriptor->destroy (cpi.descriptor, cpi.protocol); - - { - Glib::Mutex::Lock lm (protocols_lock); - list<ControlProtocol*>::iterator p = find (control_protocols.begin(), control_protocols.end(), cpi.protocol); - if (p != control_protocols.end()) { - control_protocols.erase (p); - } else { - cerr << "Programming error: ControlProtocolManager::teardown() called for " << cpi.name << ", but it was not found in control_protocols" << endl; - } - - list<ControlProtocolInfo*>::iterator p2 = find (control_protocol_info.begin(), control_protocol_info.end(), &cpi); - if (p2 != control_protocol_info.end()) { - control_protocol_info.erase (p2); - } else { - cerr << "Programming error: ControlProtocolManager::teardown() called for " << cpi.name << ", but it was not found in control_protocol_info" << endl; - } - } - - cpi.protocol = 0; - dlclose (cpi.descriptor->module); - return 0; -} - -void -ControlProtocolManager::load_mandatory_protocols () -{ - if (_session == 0) { - return; - } - - for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) { - if ((*i)->mandatory && ((*i)->protocol == 0)) { - info << string_compose (_("Instantiating mandatory control protocol %1"), (*i)->name) << endmsg; - instantiate (**i); - } - } -} - -void -ControlProtocolManager::discover_control_protocols () -{ - vector<sys::path> cp_modules; - - Glib::PatternSpec so_extension_pattern("*.so"); - Glib::PatternSpec dylib_extension_pattern("*.dylib"); - - find_matching_files_in_search_path (control_protocol_search_path (), - so_extension_pattern, cp_modules); - - find_matching_files_in_search_path (control_protocol_search_path (), - dylib_extension_pattern, cp_modules); - - info << string_compose (_("looking for control protocols in %1"), control_protocol_search_path().to_string()) << endmsg; - - for (vector<sys::path>::iterator i = cp_modules.begin(); i != cp_modules.end(); ++i) { - control_protocol_discover ((*i).to_string()); - } -} - -int -ControlProtocolManager::control_protocol_discover (string path) -{ - ControlProtocolDescriptor* descriptor; - - if ((descriptor = get_descriptor (path)) != 0) { - - ControlProtocolInfo* cpi = new ControlProtocolInfo (); - - if (!descriptor->probe (descriptor)) { - info << string_compose (_("Control protocol %1 not usable"), descriptor->name) << endmsg; - } else { - - cpi->descriptor = descriptor; - cpi->name = descriptor->name; - cpi->path = path; - cpi->protocol = 0; - cpi->requested = false; - cpi->mandatory = descriptor->mandatory; - cpi->supports_feedback = descriptor->supports_feedback; - cpi->state = 0; - - control_protocol_info.push_back (cpi); - - info << string_compose(_("Control surface protocol discovered: \"%1\""), cpi->name) << endmsg; - } - - dlclose (descriptor->module); - } - - return 0; -} - -ControlProtocolDescriptor* -ControlProtocolManager::get_descriptor (string path) -{ - void *module; - ControlProtocolDescriptor *descriptor = 0; - ControlProtocolDescriptor* (*dfunc)(void); - const char *errstr; - - if ((module = dlopen (path.c_str(), RTLD_NOW)) == 0) { - error << string_compose(_("ControlProtocolManager: cannot load module \"%1\" (%2)"), path, dlerror()) << endmsg; - return 0; - } - - - dfunc = (ControlProtocolDescriptor* (*)(void)) dlsym (module, "protocol_descriptor"); - - if ((errstr = dlerror()) != 0) { - error << string_compose(_("ControlProtocolManager: module \"%1\" has no descriptor function."), path) << endmsg; - error << errstr << endmsg; - dlclose (module); - return 0; - } - - descriptor = dfunc(); - if (descriptor) { - descriptor->module = module; - } else { - dlclose (module); - } - - return descriptor; -} - -void -ControlProtocolManager::foreach_known_protocol (sigc::slot<void,const ControlProtocolInfo*> method) -{ - for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) { - method (*i); - } -} - -ControlProtocolInfo* -ControlProtocolManager::cpi_by_name (string name) -{ - for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) { - if (name == (*i)->name) { - return *i; - } - } - return 0; -} - -int -ControlProtocolManager::set_state (const XMLNode& node) -{ - XMLNodeList clist; - XMLNodeConstIterator citer; - XMLProperty* prop; - - clist = node.children(); - - for (citer = clist.begin(); citer != clist.end(); ++citer) { - if ((*citer)->name() == X_("Protocol")) { - - prop = (*citer)->property (X_("active")); - - if (prop && prop->value() == X_("yes")) { - if ((prop = (*citer)->property (X_("name"))) != 0) { - ControlProtocolInfo* cpi = cpi_by_name (prop->value()); - if (cpi) { - if (!(*citer)->children().empty()) { - cpi->state = (*citer)->children().front (); - } else { - cpi->state = 0; - } - - if (_session) { - instantiate (*cpi); - } else { - cpi->requested = true; - } - } - } - } - } - } - return 0; -} - -XMLNode& -ControlProtocolManager::get_state (void) -{ - XMLNode* root = new XMLNode (state_node_name); - Glib::Mutex::Lock lm (protocols_lock); - - for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) { - - XMLNode * child; - - if ((*i)->protocol) { - child = &((*i)->protocol->get_state()); - child->add_property (X_("active"), "yes"); - // should we update (*i)->state here? probably. - root->add_child_nocopy (*child); - } - else if ((*i)->state) { - // keep ownership clear - root->add_child_copy (*(*i)->state); - } - else { - child = new XMLNode (X_("Protocol")); - child->add_property (X_("name"), (*i)->name); - child->add_property (X_("active"), "no"); - root->add_child_nocopy (*child); - } - } - - return *root; -} - -void -ControlProtocolManager::set_protocol_states (const XMLNode& node) -{ - XMLNodeList nlist; - XMLNodeConstIterator niter; - XMLProperty* prop; - - nlist = node.children(); - - for (niter = nlist.begin(); niter != nlist.end(); ++niter) { - - XMLNode* child = (*niter); - - if ((prop = child->property ("name")) == 0) { - error << _("control protocol XML node has no name property. Ignored.") << endmsg; - continue; - } - - ControlProtocolInfo* cpi = cpi_by_name (prop->value()); - - if (!cpi) { - warning << string_compose (_("control protocol \"%1\" is not known. Ignored"), prop->value()) << endmsg; - continue; - } - - /* copy the node so that ownership is clear */ - - cpi->state = new XMLNode (*child); - } -} diff --git a/libs/ardour/control_protocol_search_path.cc b/libs/ardour/control_protocol_search_path.cc deleted file mode 100644 index 713ef30e65..0000000000 --- a/libs/ardour/control_protocol_search_path.cc +++ /dev/null @@ -1,52 +0,0 @@ -/* - 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. - -*/ - -#include <glibmm/miscutils.h> - -#include <ardour/control_protocol_search_path.h> -#include <ardour/directory_names.h> -#include <ardour/filesystem_paths.h> - -namespace { - const char * const surfaces_env_variable_name = "ARDOUR_SURFACES_PATH"; -} // anonymous - -namespace ARDOUR { - -SearchPath -control_protocol_search_path () -{ - bool surfaces_path_defined = false; - SearchPath spath_env(Glib::getenv(surfaces_env_variable_name, surfaces_path_defined)); - - if (surfaces_path_defined) - { - return spath_env; - } - - SearchPath spath(user_config_directory ()); - - spath += ardour_module_directory (); - - spath.add_subdirectory_to_paths(surfaces_dir_name); - - return spath; -} - -} // namespace ARDOUR diff --git a/libs/ardour/coreaudiosource.cc b/libs/ardour/coreaudiosource.cc deleted file mode 100644 index 4383f1a696..0000000000 --- a/libs/ardour/coreaudiosource.cc +++ /dev/null @@ -1,270 +0,0 @@ -/* - 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. - -*/ - -#include <algorithm> - -#include <pbd/error.h> -#include <ardour/coreaudiosource.h> -#include <ardour/utils.h> - -#include <appleutility/CAAudioFile.h> -#include <appleutility/CAStreamBasicDescription.h> - -#include "i18n.h" - -#include <AudioToolbox/AudioFormat.h> - -using namespace std; -using namespace ARDOUR; -using namespace PBD; - -CoreAudioSource::CoreAudioSource (Session& s, const XMLNode& node) - : AudioFileSource (s, node) -{ - init (); -} - -CoreAudioSource::CoreAudioSource (Session& s, const string& path, int chn, Flag flags) - /* files created this way are never writable or removable */ - : AudioFileSource (s, path, Flag (flags & ~(Writable|Removable|RemovableIfEmpty|RemoveAtDestroy))) -{ - _channel = chn; - init (); -} - -void -CoreAudioSource::init () -{ - /* note that we temporarily truncated _id at the colon */ - try { - af.Open(_path.c_str()); - - CAStreamBasicDescription file_format (af.GetFileDataFormat()); - n_channels = file_format.NumberChannels(); - - if (_channel >= n_channels) { - error << string_compose("CoreAudioSource: file only contains %1 channels; %2 is invalid as a channel number (%3)", n_channels, _channel, name()) << endmsg; - throw failed_constructor(); - } - - _length = af.GetNumberFrames(); - - CAStreamBasicDescription client_format (file_format); - - /* set canonial form (PCM, native float packed, 32 bit, with the correct number of channels - and interleaved (since we plan to deinterleave ourselves) - */ - - client_format.SetCanonical(client_format.NumberChannels(), true); - af.SetClientFormat (client_format); - - } catch (CAXException& cax) { - - error << string_compose(_("CoreAudioSource: cannot open file \"%1\" for %2"), - _path, (writable() ? "read+write" : "reading")) << endmsg; - throw failed_constructor (); - } -} - -CoreAudioSource::~CoreAudioSource () -{ - GoingAway (); /* EMIT SIGNAL */ -} - -int -CoreAudioSource::safe_read (Sample* dst, nframes_t start, nframes_t cnt, AudioBufferList& abl) const -{ - nframes_t nread = 0; - - while (nread < cnt) { - - try { - af.Seek (start+nread); - } catch (CAXException& cax) { - error << string_compose("CoreAudioSource: %1 to %2 (%3)", cax.mOperation, start+nread, _name.substr (1)) << endmsg; - return -1; - } - - UInt32 new_cnt = cnt - nread; - - abl.mBuffers[0].mDataByteSize = new_cnt * n_channels * sizeof(Sample); - abl.mBuffers[0].mData = dst + nread; - - try { - af.Read (new_cnt, &abl); - } catch (CAXException& cax) { - error << string_compose("CoreAudioSource: %1 (%2)", cax.mOperation, _name); - return -1; - } - - if (new_cnt == 0) { - /* EOF */ - if (start+cnt == _length) { - /* we really did hit the end */ - nread = cnt; - } - break; - } - - nread += new_cnt; - } - - if (nread < cnt) { - return -1; - } else { - return 0; - } -} - - -nframes_t -CoreAudioSource::read_unlocked (Sample *dst, nframes_t start, nframes_t cnt) const -{ - nframes_t file_cnt; - AudioBufferList abl; - - abl.mNumberBuffers = 1; - abl.mBuffers[0].mNumberChannels = n_channels; - - if (start > _length) { - - /* read starts beyond end of data, just memset to zero */ - - file_cnt = 0; - - } else if (start + cnt > _length) { - - /* read ends beyond end of data, read some, memset the rest */ - - file_cnt = _length - start; - - } else { - - /* read is entirely within data */ - - file_cnt = cnt; - } - - if (file_cnt != cnt) { - nframes_t delta = cnt - file_cnt; - memset (dst+file_cnt, 0, sizeof (Sample) * delta); - } - - if (file_cnt) { - - if (n_channels == 1) { - if (safe_read (dst, start, file_cnt, abl) == 0) { - _read_data_count = cnt * sizeof (Sample); - return cnt; - } - return 0; - } - } - - Sample* interleave_buf = get_interleave_buffer (file_cnt * n_channels); - - if (safe_read (interleave_buf, start, file_cnt, abl) != 0) { - return 0; - } - - _read_data_count = cnt * sizeof(float); - - Sample *ptr = interleave_buf + _channel; - - /* stride through the interleaved data */ - - for (uint32_t n = 0; n < file_cnt; ++n) { - dst[n] = *ptr; - ptr += n_channels; - } - - return cnt; -} - -float -CoreAudioSource::sample_rate() const -{ - CAStreamBasicDescription client_asbd; - - try { - client_asbd = af.GetClientDataFormat (); - } catch (CAXException& cax) { - error << string_compose("CoreAudioSource: %1 (%2)", cax.mOperation, _name); - return 0.0; - } - - return client_asbd.mSampleRate; -} - -int -CoreAudioSource::update_header (nframes_t when, struct tm&, time_t) -{ - return 0; -} - -int -CoreAudioSource::get_soundfile_info (string path, SoundFileInfo& _info, string& error_msg) -{ - FSRef ref; - ExtAudioFileRef af = 0; - size_t size; - CFStringRef name; - int ret = -1; - - if (FSPathMakeRef ((UInt8*)path.c_str(), &ref, 0) != noErr) { - goto out; - } - - if (ExtAudioFileOpen(&ref, &af) != noErr) { - goto out; - } - - AudioStreamBasicDescription absd; - memset(&absd, 0, sizeof(absd)); - size = sizeof(AudioStreamBasicDescription); - if (ExtAudioFileGetProperty (af, kExtAudioFileProperty_FileDataFormat, &size, &absd) != noErr) { - goto out; - } - - _info.samplerate = absd.mSampleRate; - _info.channels = absd.mChannelsPerFrame; - - size = sizeof(_info.length); - if (ExtAudioFileGetProperty(af, kExtAudioFileProperty_FileLengthFrames, &size, &_info.length) != noErr) { - goto out; - } - - size = sizeof(CFStringRef); - if (AudioFormatGetProperty(kAudioFormatProperty_FormatName, sizeof(absd), &absd, &size, &name) != noErr) { - goto out; - } - - _info.format_name = CFStringRefToStdString(name); - - // XXX it would be nice to find a way to get this information if it exists - - _info.timecode = 0; - ret = 0; - - out: - ExtAudioFileDispose (af); - return ret; - -} diff --git a/libs/ardour/crossfade.cc b/libs/ardour/crossfade.cc deleted file mode 100644 index f3dfa28165..0000000000 --- a/libs/ardour/crossfade.cc +++ /dev/null @@ -1,904 +0,0 @@ -/* - 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. - -*/ - -#include <sigc++/bind.h> - -#include <pbd/stacktrace.h> - -#include <ardour/types.h> -#include <ardour/crossfade.h> -#include <ardour/crossfade_compare.h> -#include <ardour/audioregion.h> -#include <ardour/playlist.h> -#include <ardour/utils.h> -#include <ardour/session.h> -#include <ardour/source.h> - -#include "i18n.h" -#include <locale.h> - -using namespace std; -using namespace ARDOUR; -using namespace PBD; - -nframes_t Crossfade::_short_xfade_length = 0; -Change Crossfade::ActiveChanged = new_change(); -Change Crossfade::FollowOverlapChanged = new_change(); - -/* XXX if and when we ever implement parallel processing of the process() - callback, these will need to be handled on a per-thread basis. -*/ - -Sample* Crossfade::crossfade_buffer_out = 0; -Sample* Crossfade::crossfade_buffer_in = 0; - -void -Crossfade::set_buffer_size (nframes_t sz) -{ - if (crossfade_buffer_out) { - delete [] crossfade_buffer_out; - crossfade_buffer_out = 0; - } - - if (crossfade_buffer_in) { - delete [] crossfade_buffer_in; - crossfade_buffer_in = 0; - } - - if (sz) { - crossfade_buffer_out = new Sample[sz]; - crossfade_buffer_in = new Sample[sz]; - } -} - -bool -Crossfade::operator== (const Crossfade& other) -{ - return (_in == other._in) && (_out == other._out); -} - -Crossfade::Crossfade (boost::shared_ptr<AudioRegion> in, boost::shared_ptr<AudioRegion> out, - nframes_t length, - nframes_t position, - AnchorPoint ap) - : AudioRegion (in->session(), position, length, "foobar"), - _fade_in (Parameter(FadeInAutomation), 0.0, 2.0, 1.0), // linear (gain coefficient) => -inf..+6dB - _fade_out (Parameter(FadeOutAutomation), 0.0, 2.0, 1.0) // linear (gain coefficient) => -inf..+6dB - -{ - _in = in; - _out = out; - - _anchor_point = ap; - _follow_overlap = false; - - _active = Config->get_xfades_active (); - _fixed = true; - - initialize (); -} - -Crossfade::Crossfade (boost::shared_ptr<AudioRegion> a, boost::shared_ptr<AudioRegion> b, CrossfadeModel model, bool act) - : AudioRegion (a->session(), 0, 0, "foobar"), - _fade_in (Parameter(FadeInAutomation), 0.0, 2.0, 1.0), // linear (gain coefficient) => -inf..+6dB - _fade_out (Parameter(FadeOutAutomation), 0.0, 2.0, 1.0) // linear (gain coefficient) => -inf..+6dB -{ - _in_update = false; - _fixed = false; - - if (compute (a, b, model)) { - throw failed_constructor(); - } - - _active = act; - - initialize (); - - -} - -Crossfade::Crossfade (const Playlist& playlist, XMLNode& node) - : AudioRegion (playlist.session(), 0, 0, "foobar"), - _fade_in (Parameter(FadeInAutomation), 0.0, 2.0, 1.0), // linear (gain coefficient) => -inf..+6dB - _fade_out (Parameter(FadeOutAutomation), 0.0, 2.0, 1.0) // linear (gain coefficient) => -inf..+6dB - -{ - boost::shared_ptr<Region> r; - XMLProperty* prop; - LocaleGuard lg (X_("POSIX")); - - /* we have to find the in/out regions before we can do anything else */ - - if ((prop = node.property ("in")) == 0) { - error << _("Crossfade: no \"in\" region in state") << endmsg; - throw failed_constructor(); - } - - PBD::ID id (prop->value()); - - if ((r = playlist.find_region (id)) == 0) { - error << string_compose (_("Crossfade: no \"in\" region %1 found in playlist %2"), id, playlist.name()) - << endmsg; - throw failed_constructor(); - } - - if ((_in = boost::dynamic_pointer_cast<AudioRegion> (r)) == 0) { - throw failed_constructor(); - } - - if ((prop = node.property ("out")) == 0) { - error << _("Crossfade: no \"out\" region in state") << endmsg; - throw failed_constructor(); - } - - PBD::ID id2 (prop->value()); - - if ((r = playlist.find_region (id2)) == 0) { - error << string_compose (_("Crossfade: no \"out\" region %1 found in playlist %2"), id2, playlist.name()) - << endmsg; - throw failed_constructor(); - } - - if ((_out = boost::dynamic_pointer_cast<AudioRegion> (r)) == 0) { - throw failed_constructor(); - } - - _length = 0; - initialize(); - _active = true; - - if (set_state (node)) { - throw failed_constructor(); - } -} - -Crossfade::Crossfade (boost::shared_ptr<Crossfade> orig, boost::shared_ptr<AudioRegion> newin, boost::shared_ptr<AudioRegion> newout) - : AudioRegion (boost::dynamic_pointer_cast<const AudioRegion> (orig)), - _fade_in (orig->_fade_in), - _fade_out (orig->_fade_out) -{ - _active = orig->_active; - _in_update = orig->_in_update; - _anchor_point = orig->_anchor_point; - _follow_overlap = orig->_follow_overlap; - _fixed = orig->_fixed; - - _in = newin; - _out = newout; - - // copied from Crossfade::initialize() - _in_update = false; - - _out->suspend_fade_out (); - _in->suspend_fade_in (); - - overlap_type = _in->coverage (_out->position(), _out->last_frame()); - layer_relation = (int32_t) (_in->layer() - _out->layer()); - - // Let's make sure the fade isn't too long - set_length(_length); -} - - -Crossfade::~Crossfade () -{ - notify_callbacks (); -} - -void -Crossfade::initialize () -{ - /* merge source lists from regions */ - - _sources = _in->sources(); - _sources.insert (_sources.end(), _out->sources().begin(), _out->sources().end()); - _master_sources = _in->master_sources(); - _master_sources.insert(_master_sources.end(), _out->master_sources().begin(), _out->master_sources().end()); - - _in_update = false; - - _out->suspend_fade_out (); - _in->suspend_fade_in (); - - _fade_out.freeze (); - _fade_out.clear (); - _fade_out.add (0.0, 1.0); - _fade_out.add ((_length * 0.1), 0.99); - _fade_out.add ((_length * 0.2), 0.97); - _fade_out.add ((_length * 0.8), 0.03); - _fade_out.add ((_length * 0.9), 0.01); - _fade_out.add (_length, 0.0); - _fade_out.thaw (); - - _fade_in.freeze (); - _fade_in.clear (); - _fade_in.add (0.0, 0.0); - _fade_in.add ((_length * 0.1), 0.01); - _fade_in.add ((_length * 0.2), 0.03); - _fade_in.add ((_length * 0.8), 0.97); - _fade_in.add ((_length * 0.9), 0.99); - _fade_in.add (_length, 1.0); - _fade_in.thaw (); - - overlap_type = _in->coverage (_out->position(), _out->last_frame()); - layer_relation = (int32_t) (_in->layer() - _out->layer()); -} - -nframes_t -Crossfade::read_raw_internal (Sample* buf, nframes_t start, nframes_t cnt) const -{ -#if 0 - Sample* mixdown = new Sample[cnt]; - float* gain = new float[cnt]; - nframes_t ret; - - ret = read_at (buf, mixdown, gain, start, cnt, chan_n, cnt); - - delete [] mixdown; - delete [] gain; - - return ret; -#endif - return cnt; -} - -nframes_t -Crossfade::read_at (Sample *buf, Sample *mixdown_buffer, - float *gain_buffer, nframes_t start, nframes_t cnt, uint32_t chan_n, - nframes_t read_frames, nframes_t skip_frames) const -{ - nframes_t offset; - nframes_t to_write; - - if (!_active) { - return 0; - } - - if (start < _position) { - - /* handle an initial section of the read area that we do not - cover. - */ - - offset = _position - start; - - if (offset < cnt) { - cnt -= offset; - } else { - return 0; - } - - start = _position; - buf += offset; - to_write = min (_length, cnt); - - } else { - - to_write = min (_length - (start - _position), cnt); - - } - - offset = start - _position; - - /* Prevent data from piling up inthe crossfade buffers when reading a transparent region */ - if (!(_out->opaque())) { - memset (crossfade_buffer_out, 0, sizeof (Sample) * to_write); - } else if (!(_in->opaque())) { - memset (crossfade_buffer_in, 0, sizeof (Sample) * to_write); - } - - _out->read_at (crossfade_buffer_out, mixdown_buffer, gain_buffer, start, to_write, chan_n, read_frames, skip_frames); - _in->read_at (crossfade_buffer_in, mixdown_buffer, gain_buffer, start, to_write, chan_n, read_frames, skip_frames); - - float* fiv = new float[to_write]; - float* fov = new float[to_write]; - - _fade_in.curve().get_vector (offset, offset+to_write, fiv, to_write); - _fade_out.curve().get_vector (offset, offset+to_write, fov, to_write); - - /* note: although we have not explicitly taken into account the return values - from _out->read_at() or _in->read_at(), the length() function does this - implicitly. why? because it computes a value based on the in+out regions' - position and length, and so we know precisely how much data they could return. - */ - - for (nframes_t n = 0; n < to_write; ++n) { - buf[n] = (crossfade_buffer_out[n] * fov[n]) + (crossfade_buffer_in[n] * fiv[n]); - } - - delete [] fov; - delete [] fiv; - - return to_write; -} - -OverlapType -Crossfade::coverage (nframes_t start, nframes_t end) const -{ - nframes_t my_end = _position + _length; - - if ((start >= _position) && (end <= my_end)) { - return OverlapInternal; - } - if ((end >= _position) && (end <= my_end)) { - return OverlapStart; - } - if ((start >= _position) && (start <= my_end)) { - return OverlapEnd; - } - if ((_position >= start) && (_position <= end) && (my_end <= end)) { - return OverlapExternal; - } - return OverlapNone; -} - -void -Crossfade::set_active (bool yn) -{ - if (_active != yn) { - _active = yn; - StateChanged (ActiveChanged); - } -} - -bool -Crossfade::refresh () -{ - /* crossfades must be between non-muted regions */ - - if (_out->muted() || _in->muted()) { - Invalidated (shared_from_this ()); - return false; - } - - /* Top layer shouldn't be transparent */ - - if (!((layer_relation > 0 ? _in : _out)->opaque())) { - Invalidated (shared_from_this()); - return false; - } - - /* layer ordering cannot change */ - - int32_t new_layer_relation = (int32_t) (_in->layer() - _out->layer()); - - if (new_layer_relation * layer_relation < 0) { // different sign, layers rotated - Invalidated (shared_from_this ()); - return false; - } - - OverlapType ot = _in->coverage (_out->first_frame(), _out->last_frame()); - - if (ot == OverlapNone) { - Invalidated (shared_from_this ()); - return false; - } - - bool send_signal; - - if (ot != overlap_type) { - - if (_follow_overlap) { - - try { - compute (_in, _out, Config->get_xfade_model()); - } - - catch (NoCrossfadeHere& err) { - Invalidated (shared_from_this ()); - return false; - } - - send_signal = true; - - } else { - - Invalidated (shared_from_this ()); - return false; - } - - } else { - - send_signal = update (); - } - - if (send_signal) { - StateChanged (BoundsChanged); /* EMIT SIGNAL */ - } - - _in_update = false; - - return true; -} - -bool -Crossfade::update () -{ - nframes_t newlen; - - if (_follow_overlap) { - newlen = _out->first_frame() + _out->length() - _in->first_frame(); - } else { - newlen = _length; - } - - if (newlen == 0) { - Invalidated (shared_from_this ()); - return false; - } - - _in_update = true; - - if ((_follow_overlap && newlen != _length) || (_length > newlen)) { - - double factor = newlen / (double) _length; - - _fade_out.x_scale (factor); - _fade_in.x_scale (factor); - - _length = newlen; - } - - switch (_anchor_point) { - case StartOfIn: - _position = _in->first_frame(); - break; - - case EndOfIn: - _position = _in->last_frame() - _length; - break; - - case EndOfOut: - _position = _out->last_frame() - _length; - } - - return true; -} - -int -Crossfade::compute (boost::shared_ptr<AudioRegion> a, boost::shared_ptr<AudioRegion> b, CrossfadeModel model) -{ - boost::shared_ptr<AudioRegion> top; - boost::shared_ptr<AudioRegion> bottom; - nframes_t short_xfade_length; - - short_xfade_length = _short_xfade_length; - - if (a->layer() < b->layer()) { - top = b; - bottom = a; - } else { - top = a; - bottom = b; - } - - /* first check for matching ends */ - - if (top->first_frame() == bottom->first_frame()) { - - /* Both regions start at the same point */ - - if (top->last_frame() < bottom->last_frame()) { - - /* top ends before bottom, so put an xfade - in at the end of top. - */ - - /* [-------- top ---------- ] - * {====== bottom =====================} - */ - - _in = bottom; - _out = top; - - if (top->last_frame() < short_xfade_length) { - _position = 0; - } else { - _position = top->last_frame() - short_xfade_length; - } - - _length = min (short_xfade_length, top->length()); - _follow_overlap = false; - _anchor_point = EndOfIn; - _active = true; - _fixed = true; - - } else { - /* top ends after (or same time) as bottom - no xfade - */ - - /* [-------- top ------------------------ ] - * {====== bottom =====================} - */ - - throw NoCrossfadeHere(); - } - - } else if (top->last_frame() == bottom->last_frame()) { - - /* Both regions end at the same point */ - - if (top->first_frame() > bottom->first_frame()) { - - /* top starts after bottom, put an xfade in at the - start of top - */ - - /* [-------- top ---------- ] - * {====== bottom =====================} - */ - - _in = top; - _out = bottom; - _position = top->first_frame(); - _length = min (short_xfade_length, top->length()); - _follow_overlap = false; - _anchor_point = StartOfIn; - _active = true; - _fixed = true; - - } else { - /* top starts before bottom - no xfade - */ - - /* [-------- top ------------------------ ] - * {====== bottom =====================} - */ - - throw NoCrossfadeHere(); - } - - } else { - - /* OK, time to do more regular overlapping */ - - OverlapType ot = top->coverage (bottom->first_frame(), bottom->last_frame()); - - switch (ot) { - case OverlapNone: - /* should be NOTREACHED as a precondition of creating - a new crossfade, but we need to handle it here. - */ - throw NoCrossfadeHere(); - break; - - case OverlapInternal: - case OverlapExternal: - /* should be NOTREACHED because of tests above */ - throw NoCrossfadeHere(); - break; - - case OverlapEnd: /* top covers start of bottom but ends within it */ - - /* [---- top ------------------------] - * { ==== bottom ============ } - */ - - _in = bottom; - _out = top; - _anchor_point = EndOfOut; - - if (model == FullCrossfade) { - _position = bottom->first_frame(); // "{" - _length = _out->first_frame() + _out->length() - _in->first_frame(); - /* leave active alone */ - _follow_overlap = true; - } else { - _length = min (short_xfade_length, top->length()); - _position = top->last_frame() - _length; // "]" - length - _active = true; - _follow_overlap = false; - - } - break; - - case OverlapStart: /* top starts within bottom but covers bottom's end */ - - /* { ==== top ============ } - * [---- bottom -------------------] - */ - - _in = top; - _out = bottom; - _position = top->first_frame(); - _anchor_point = StartOfIn; - - if (model == FullCrossfade) { - _length = _out->first_frame() + _out->length() - _in->first_frame(); - /* leave active alone */ - _follow_overlap = true; - } else { - _length = min (short_xfade_length, top->length()); - _active = true; - _follow_overlap = false; - - } - - break; - } - } - - return 0; -} - -XMLNode& -Crossfade::get_state () -{ - XMLNode* node = new XMLNode (X_("Crossfade")); - XMLNode* child; - char buf[64]; - LocaleGuard lg (X_("POSIX")); - - _out->id().print (buf, sizeof (buf)); - node->add_property ("out", buf); - _in->id().print (buf, sizeof (buf)); - node->add_property ("in", buf); - node->add_property ("active", (_active ? "yes" : "no")); - node->add_property ("follow-overlap", (_follow_overlap ? "yes" : "no")); - node->add_property ("fixed", (_fixed ? "yes" : "no")); - snprintf (buf, sizeof(buf), "%" PRIu32, _length); - node->add_property ("length", buf); - snprintf (buf, sizeof(buf), "%" PRIu32, (uint32_t) _anchor_point); - node->add_property ("anchor-point", buf); - snprintf (buf, sizeof(buf), "%" PRIu32, (uint32_t) _position); - node->add_property ("position", buf); - - child = node->add_child ("FadeIn"); - - for (AutomationList::iterator ii = _fade_in.begin(); ii != _fade_in.end(); ++ii) { - XMLNode* pnode; - - pnode = new XMLNode ("point"); - - snprintf (buf, sizeof (buf), "%" PRIu32, (nframes_t) floor ((*ii)->when)); - pnode->add_property ("x", buf); - snprintf (buf, sizeof (buf), "%.12g", (*ii)->value); - pnode->add_property ("y", buf); - child->add_child_nocopy (*pnode); - } - - child = node->add_child ("FadeOut"); - - for (AutomationList::iterator ii = _fade_out.begin(); ii != _fade_out.end(); ++ii) { - XMLNode* pnode; - - pnode = new XMLNode ("point"); - - snprintf (buf, sizeof (buf), "%" PRIu32, (nframes_t) floor ((*ii)->when)); - pnode->add_property ("x", buf); - snprintf (buf, sizeof (buf), "%.12g", (*ii)->value); - pnode->add_property ("y", buf); - child->add_child_nocopy (*pnode); - } - - return *node; -} - -int -Crossfade::set_state (const XMLNode& node) -{ - XMLNodeConstIterator i; - XMLNodeList children; - XMLNode* fi; - XMLNode* fo; - const XMLProperty* prop; - LocaleGuard lg (X_("POSIX")); - Change what_changed = Change (0); - nframes_t val; - - if ((prop = node.property ("position")) != 0) { - sscanf (prop->value().c_str(), "%" PRIu32, &val); - if (val != _position) { - _position = val; - what_changed = Change (what_changed | PositionChanged); - } - } else { - warning << _("old-style crossfade information - no position information") << endmsg; - _position = _in->first_frame(); - } - - if ((prop = node.property ("active")) != 0) { - bool x = (prop->value() == "yes"); - if (x != _active) { - _active = x; - what_changed = Change (what_changed | ActiveChanged); - } - } else { - _active = true; - } - - if ((prop = node.property ("follow-overlap")) != 0) { - _follow_overlap = (prop->value() == "yes"); - } else { - _follow_overlap = false; - } - - if ((prop = node.property ("fixed")) != 0) { - _fixed = (prop->value() == "yes"); - } else { - _fixed = false; - } - - if ((prop = node.property ("anchor-point")) != 0) { - _anchor_point = AnchorPoint (atoi ((prop->value().c_str()))); - } else { - _anchor_point = StartOfIn; - } - - if ((prop = node.property ("length")) != 0) { - - sscanf (prop->value().c_str(), "%" PRIu32, &val); - if (val != _length) { - _length = atol (prop->value().c_str()); - what_changed = Change (what_changed | LengthChanged); - } - - } else { - - /* XXX this branch is legacy code from before - the point where we stored xfade lengths. - */ - - if ((_length = overlap_length()) == 0) { - throw failed_constructor(); - } - } - - if ((fi = find_named_node (node, "FadeIn")) == 0) { - return -1; - } - - if ((fo = find_named_node (node, "FadeOut")) == 0) { - return -1; - } - - /* fade in */ - - _fade_in.freeze (); - _fade_in.clear (); - - children = fi->children(); - - for (i = children.begin(); i != children.end(); ++i) { - if ((*i)->name() == "point") { - nframes_t x; - float y; - - prop = (*i)->property ("x"); - sscanf (prop->value().c_str(), "%" PRIu32, &x); - - prop = (*i)->property ("y"); - sscanf (prop->value().c_str(), "%f", &y); - - _fade_in.add (x, y); - } - } - - _fade_in.thaw (); - - /* fade out */ - - _fade_out.freeze (); - _fade_out.clear (); - - children = fo->children(); - - for (i = children.begin(); i != children.end(); ++i) { - if ((*i)->name() == "point") { - nframes_t x; - float y; - XMLProperty* prop; - - prop = (*i)->property ("x"); - sscanf (prop->value().c_str(), "%" PRIu32, &x); - - prop = (*i)->property ("y"); - sscanf (prop->value().c_str(), "%f", &y); - - _fade_out.add (x, y); - } - } - - _fade_out.thaw (); - - StateChanged (what_changed); /* EMIT SIGNAL */ - - return 0; -} - -bool -Crossfade::can_follow_overlap () const -{ - return !_fixed; -} - -void -Crossfade::set_follow_overlap (bool yn) -{ - if (yn == _follow_overlap || _fixed) { - return; - } - - _follow_overlap = yn; - - if (!yn) { - set_length (_short_xfade_length); - } else { - set_length (_out->first_frame() + _out->length() - _in->first_frame()); - } - - StateChanged (FollowOverlapChanged); -} - -nframes_t -Crossfade::set_length (nframes_t len) -{ - nframes_t limit; - - switch (_anchor_point) { - case StartOfIn: - limit = _in->length(); - break; - - case EndOfIn: - limit = _in->length(); - break; - - case EndOfOut: - limit = _out->length(); - break; - - } - - len = min (limit, len); - - double factor = len / (double) _length; - - _in_update = true; - _fade_out.x_scale (factor); - _fade_in.x_scale (factor); - _in_update = false; - - _length = len; - - StateChanged (LengthChanged); - - return len; -} - -nframes_t -Crossfade::overlap_length () const -{ - if (_fixed) { - return _length; - } - return _out->first_frame() + _out->length() - _in->first_frame(); -} - -void -Crossfade::set_short_xfade_length (nframes_t n) -{ - _short_xfade_length = n; -} - -void -Crossfade::invalidate () -{ - Invalidated (shared_from_this ()); /* EMIT SIGNAL */ -} diff --git a/libs/ardour/curve.cc b/libs/ardour/curve.cc deleted file mode 100644 index dcce3c0c6c..0000000000 --- a/libs/ardour/curve.cc +++ /dev/null @@ -1,406 +0,0 @@ -/* - Copyright (C) 2001-2007 Paul Davis - - Contains ideas derived from "Constrained Cubic Spline Interpolation" - by CJC Kruger (www.korf.co.uk/spline.pdf). - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include <iostream> -#include <float.h> -#include <cmath> -#include <climits> -#include <cfloat> -#include <cmath> - -#include <glibmm/thread.h> -#include <sigc++/bind.h> - -#include "ardour/curve.h" -#include "ardour/automation_event.h" - -#include "i18n.h" - -using namespace std; -using namespace ARDOUR; -using namespace sigc; -using namespace PBD; - -Curve::Curve (const AutomationList& al) - : _dirty (true) - , _list (al) -{ - _list.Dirty.connect(mem_fun(*this, &Curve::on_list_dirty)); -} - -void -Curve::solve () -{ - uint32_t npoints; - - if (!_dirty) { - return; - } - - if ((npoints = _list.events().size()) > 2) { - - /* Compute coefficients needed to efficiently compute a constrained spline - curve. See "Constrained Cubic Spline Interpolation" by CJC Kruger - (www.korf.co.uk/spline.pdf) for more details. - */ - - double x[npoints]; - double y[npoints]; - uint32_t i; - AutomationList::EventList::const_iterator xx; - - for (i = 0, xx = _list.events().begin(); xx != _list.events().end(); ++xx, ++i) { - x[i] = (double) (*xx)->when; - y[i] = (double) (*xx)->value; - } - - double lp0, lp1, fpone; - - lp0 = (x[1] - x[0])/(y[1] - y[0]); - lp1 = (x[2] - x[1])/(y[2] - y[1]); - - if (lp0*lp1 < 0) { - fpone = 0; - } else { - fpone = 2 / (lp1 + lp0); - } - - double fplast = 0; - - for (i = 0, xx = _list.events().begin(); xx != _list.events().end(); ++xx, ++i) { - - double xdelta; /* gcc is wrong about possible uninitialized use */ - double xdelta2; /* ditto */ - double ydelta; /* ditto */ - double fppL, fppR; - double fpi; - - if (i > 0) { - xdelta = x[i] - x[i-1]; - xdelta2 = xdelta * xdelta; - ydelta = y[i] - y[i-1]; - } - - /* compute (constrained) first derivatives */ - - if (i == 0) { - - /* first segment */ - - fplast = ((3 * (y[1] - y[0]) / (2 * (x[1] - x[0]))) - (fpone * 0.5)); - - /* we don't store coefficients for i = 0 */ - - continue; - - } else if (i == npoints - 1) { - - /* last segment */ - - fpi = ((3 * ydelta) / (2 * xdelta)) - (fplast * 0.5); - - } else { - - /* all other segments */ - - double slope_before = ((x[i+1] - x[i]) / (y[i+1] - y[i])); - double slope_after = (xdelta / ydelta); - - if (slope_after * slope_before < 0.0) { - /* slope changed sign */ - fpi = 0.0; - } else { - fpi = 2 / (slope_before + slope_after); - } - - } - - /* compute second derivative for either side of control point `i' */ - - fppL = (((-2 * (fpi + (2 * fplast))) / (xdelta))) + - ((6 * ydelta) / xdelta2); - - fppR = (2 * ((2 * fpi) + fplast) / xdelta) - - ((6 * ydelta) / xdelta2); - - /* compute polynomial coefficients */ - - double b, c, d; - - d = (fppR - fppL) / (6 * xdelta); - c = ((x[i] * fppL) - (x[i-1] * fppR))/(2 * xdelta); - - double xim12, xim13; - double xi2, xi3; - - xim12 = x[i-1] * x[i-1]; /* "x[i-1] squared" */ - xim13 = xim12 * x[i-1]; /* "x[i-1] cubed" */ - xi2 = x[i] * x[i]; /* "x[i] squared" */ - xi3 = xi2 * x[i]; /* "x[i] cubed" */ - - b = (ydelta - (c * (xi2 - xim12)) - (d * (xi3 - xim13))) / xdelta; - - /* store */ - - (*xx)->create_coeffs(); - (*xx)->coeff[0] = y[i-1] - (b * x[i-1]) - (c * xim12) - (d * xim13); - (*xx)->coeff[1] = b; - (*xx)->coeff[2] = c; - (*xx)->coeff[3] = d; - - fplast = fpi; - } - - } - - _dirty = false; -} - -bool -Curve::rt_safe_get_vector (double x0, double x1, float *vec, int32_t veclen) -{ - Glib::Mutex::Lock lm(_list.lock(), Glib::TRY_LOCK); - - if (!lm.locked()) { - return false; - } else { - _get_vector (x0, x1, vec, veclen); - return true; - } -} - -void -Curve::get_vector (double x0, double x1, float *vec, int32_t veclen) -{ - Glib::Mutex::Lock lm(_list.lock()); - _get_vector (x0, x1, vec, veclen); -} - -void -Curve::_get_vector (double x0, double x1, float *vec, int32_t veclen) -{ - double rx, dx, lx, hx, max_x, min_x; - int32_t i; - int32_t original_veclen; - int32_t npoints; - - if ((npoints = _list.events().size()) == 0) { - for (i = 0; i < veclen; ++i) { - vec[i] = _list.default_value(); - } - return; - } - - /* events is now known not to be empty */ - - max_x = _list.events().back()->when; - min_x = _list.events().front()->when; - - lx = max (min_x, x0); - - if (x1 < 0) { - x1 = _list.events().back()->when; - } - - hx = min (max_x, x1); - - original_veclen = veclen; - - if (x0 < min_x) { - - /* fill some beginning section of the array with the - initial (used to be default) value - */ - - double frac = (min_x - x0) / (x1 - x0); - int32_t subveclen = (int32_t) floor (veclen * frac); - - subveclen = min (subveclen, veclen); - - for (i = 0; i < subveclen; ++i) { - vec[i] = _list.events().front()->value; - } - - veclen -= subveclen; - vec += subveclen; - } - - if (veclen && x1 > max_x) { - - /* fill some end section of the array with the default or final value */ - - double frac = (x1 - max_x) / (x1 - x0); - - int32_t subveclen = (int32_t) floor (original_veclen * frac); - - float val; - - subveclen = min (subveclen, veclen); - - val = _list.events().back()->value; - - i = veclen - subveclen; - - for (i = veclen - subveclen; i < veclen; ++i) { - vec[i] = val; - } - - veclen -= subveclen; - } - - if (veclen == 0) { - return; - } - - if (npoints == 1 ) { - - for (i = 0; i < veclen; ++i) { - vec[i] = _list.events().front()->value; - } - return; - } - - - if (npoints == 2) { - - /* linear interpolation between 2 points */ - - /* XXX I'm not sure that this is the right thing to - do here. but its not a common case for the envisaged - uses. - */ - - if (veclen > 1) { - dx = (hx - lx) / (veclen - 1) ; - } else { - dx = 0; // not used - } - - double slope = (_list.events().back()->value - _list.events().front()->value)/ - (_list.events().back()->when - _list.events().front()->when); - double yfrac = dx*slope; - - vec[0] = _list.events().front()->value + slope * (lx - _list.events().front()->when); - - for (i = 1; i < veclen; ++i) { - vec[i] = vec[i-1] + yfrac; - } - - return; - } - - if (_dirty) { - solve (); - } - - rx = lx; - - if (veclen > 1) { - - dx = (hx - lx) / veclen; - - for (i = 0; i < veclen; ++i, rx += dx) { - vec[i] = multipoint_eval (rx); - } - } -} - -double -Curve::unlocked_eval (double x) -{ - // I don't see the point of this... - - if (_dirty) { - solve (); - } - - return _list.unlocked_eval (x); -} - -double -Curve::multipoint_eval (double x) -{ - pair<AutomationList::EventList::const_iterator,AutomationList::EventList::const_iterator> range; - - AutomationList::LookupCache& lookup_cache = _list.lookup_cache(); - - if ((lookup_cache.left < 0) || - ((lookup_cache.left > x) || - (lookup_cache.range.first == _list.events().end()) || - ((*lookup_cache.range.second)->when < x))) { - - ControlEvent cp (x, 0.0); - - lookup_cache.range = equal_range (_list.events().begin(), _list.events().end(), &cp, AutomationList::time_comparator); - } - - range = lookup_cache.range; - - /* EITHER - - a) x is an existing control point, so first == existing point, second == next point - - OR - - b) x is between control points, so range is empty (first == second, points to where - to insert x) - - */ - - if (range.first == range.second) { - - /* x does not exist within the list as a control point */ - - lookup_cache.left = x; - - if (range.first == _list.events().begin()) { - /* we're before the first point */ - // return default_value; - _list.events().front()->value; - } - - if (range.second == _list.events().end()) { - /* we're after the last point */ - return _list.events().back()->value; - } - - double x2 = x * x; - ControlEvent* ev = *range.second; - - return ev->coeff[0] + (ev->coeff[1] * x) + (ev->coeff[2] * x2) + (ev->coeff[3] * x2 * x); - } - - /* x is a control point in the data */ - /* invalidate the cached range because its not usable */ - lookup_cache.left = -1; - return (*range.first)->value; -} - -extern "C" { - -void -curve_get_vector_from_c (void *arg, double x0, double x1, float* vec, int32_t vecsize) -{ - static_cast<Curve*>(arg)->get_vector (x0, x1, vec, vecsize); -} - -} diff --git a/libs/ardour/cycle_timer.cc b/libs/ardour/cycle_timer.cc deleted file mode 100644 index 143cb841ec..0000000000 --- a/libs/ardour/cycle_timer.cc +++ /dev/null @@ -1,74 +0,0 @@ -/* - Copyright (C) 2002 Andrew Morton - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include <cstdio> -#include <pbd/error.h> -#include <ardour/cycle_timer.h> - -#include "i18n.h" - -using namespace PBD; - -float CycleTimer::cycles_per_usec = 0; - -float -CycleTimer::get_mhz() -{ - FILE *f; - - if ((f = fopen("/proc/cpuinfo", "r")) == 0) { - fatal << _("CycleTimer::get_mhz(): can't open /proc/cpuinfo") << endmsg; - /*NOTREACHED*/ - return 0.0f; - } - - while (true) { - - float mhz; - int ret; - char buf[1000]; - - if (fgets (buf, sizeof(buf), f) == 0) { - fatal << _("CycleTimer::get_mhz(): cannot locate cpu MHz in /proc/cpuinfo") << endmsg; - /*NOTREACHED*/ - return 0.0f; - } - -#ifdef __powerpc__ - - int imhz; - - /* why can't the PPC crew standardize their /proc/cpuinfo format ? */ - ret = sscanf (buf, "clock\t: %dMHz", &imhz); - mhz = (float) imhz; - -#else /* XXX don't assume its x86 just because its not power pc */ - ret = sscanf (buf, "cpu MHz : %f", &mhz); - -#endif - if (ret == 1) { - fclose(f); - return mhz; - } - } - - fatal << _("cannot locate cpu MHz in /proc/cpuinfo") << endmsg; - /*NOTREACHED*/ - return 0.0f; -} diff --git a/libs/ardour/default_click.cc b/libs/ardour/default_click.cc deleted file mode 100644 index 5bdbeb2ac5..0000000000 --- a/libs/ardour/default_click.cc +++ /dev/null @@ -1,1174 +0,0 @@ -/* - Copyright (C) 20002 Paul Davis - Sounds by Nick Mainsbridge. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include <ardour/ardour.h> -#include <ardour/session.h> - -using namespace ARDOUR; - -const Sample Session::default_click_emphasis[] = { - - - 0.011260986, 0.055389404, 0.10488892, 0.14285278, 0.17984009, - 0.20492554, 0.2244873, 0.23187256, 0.23144531, 0.21932983, - 0.19973755, 0.17034912, 0.13473511, 0.09274292, 0.04699707, - -0.0009765625, -0.048919678, -0.095123291, -0.13772583, - -0.17495728, -0.20523071, -0.22750854, -0.24038696, -0.24423218, - -0.23831177, -0.22305298, -0.19918823, -0.16748047, -0.12948608, - -0.086730957, -0.041015625, 0.0060424805, 0.052276611, - 0.09588623, 0.13513184, 0.16827393, 0.19415283, 0.21182251, - 0.22024536, 0.2194519, 0.20932007, 0.19030762, 0.1633606, - 0.1295166, 0.090118408, 0.046844482, 0.0015563965, -0.0440979, - -0.088043213, -0.12854004, -0.16415405, -0.19317627, - -0.21456909, -0.22750854, -0.23141479, -0.22619629, -0.21224976, - -0.18994141, -0.1602478, -0.12457275, -0.084228516, - -0.040893555, 0.0035400391, 0.047485352, 0.08895874, 0.12628174, - 0.15808105, 0.1829834, 0.19998169, 0.20849609, 0.2081604, - 0.19891357, 0.18139648, 0.15621948, 0.12438965, 0.087371826, - 0.046569824, 0.0036621094, -0.039489746, -0.081207275, - -0.11987305, -0.15371704, -0.18154907, -0.20220947, -0.21481323, - -0.21896362, -0.21453857, -0.20159912, -0.18084717, -0.15319824, - -0.11959839, -0.081604004, -0.040771484, 0.001373291, - 0.04296875, 0.082275391, 0.11791992, 0.14828491, 0.17214966, - 0.18869019, 0.19711304, 0.19714355, 0.18896484, 0.17272949, - 0.14916992, 0.11941528, 0.084564209, 0.046081543, 0.005645752, - -0.03527832, -0.074890137, -0.11154175, -0.14389038, - -0.17053223, -0.19036865, -0.20272827, -0.20709229, -0.20321655, - -0.19143677, -0.17221069, -0.14624023, -0.11477661, - -0.079040527, -0.040435791, -0.00064086914, 0.038726807, - 0.076171875, 0.11004639, 0.13900757, 0.16201782, 0.177948, - 0.18634033, 0.18685913, 0.17938232, 0.16436768, 0.14254761, - 0.11459351, 0.081817627, 0.045623779, 0.0073242188, - -0.031402588, -0.068939209, -0.10388184, -0.13473511, - -0.16018677, -0.17938232, -0.19143677, -0.19589233, -0.19271851, - -0.1819458, -0.16400146, -0.13980103, -0.11026001, -0.076507568, - -0.040130615, -0.0024414062, 0.034973145, 0.070465088, - 0.10275269, 0.13052368, 0.15255737, 0.1680603, 0.17642212, - 0.17718506, 0.17056274, 0.15673828, 0.13626099, 0.1100769, - 0.079284668, 0.045013428, 0.0088195801, -0.027862549, - -0.06362915, -0.096862793, -0.12631226, -0.15081787, - -0.16931152, -0.18109131, -0.18579102, -0.18310547, -0.17321777, - -0.15661621, -0.13391113, -0.10604858, -0.074310303, - -0.039794922, -0.0040588379, 0.031433105, 0.065338135, - 0.096191406, 0.1227417, 0.14398193, 0.15905762, 0.16726685, - 0.16845703, 0.16247559, 0.14962769, 0.1305542, 0.10595703, - 0.076812744, 0.044494629, 0.010162354, -0.024719238, - -0.058685303, -0.090423584, -0.11865234, -0.14208984, - -0.15994263, -0.17150879, -0.1762085, -0.17401123, -0.16500854, - -0.1494751, -0.12820435, -0.10205078, -0.071990967, - -0.039398193, -0.0055847168, 0.028198242, 0.060424805, - 0.089782715, 0.11523438, 0.13565063, 0.15014648, 0.1583252, - 0.159729, 0.15438843, 0.14260864, 0.12475586, 0.10162354, - 0.074310303, 0.043762207, 0.011291504, -0.02166748, - -0.053924561, -0.084136963, -0.1109314, -0.13342285, - -0.15060425, -0.16177368, -0.16659546, -0.16485596, -0.15655518, - -0.14221191, -0.12234497, -0.097747803, -0.069519043, - -0.038818359, -0.0067749023, 0.025115967, 0.055633545, - 0.083618164, 0.1078186, 0.12731934, 0.14138794, 0.14935303, - 0.15097046, 0.14630127, 0.13537598, 0.11877441, 0.097259521, - 0.071563721, 0.04284668, 0.012329102, -0.018859863, - -0.049346924, -0.077880859, -0.10342407, -0.12484741, - -0.14126587, -0.15213013, -0.1569519, -0.1555481, -0.14807129, - -0.13479614, -0.11624146, -0.093322754, -0.066864014, - -0.03793335, -0.0078735352, 0.022247314, 0.051116943, - 0.077575684, 0.10055542, 0.11920166, 0.13265991, 0.14047241, - 0.14233398, 0.13812256, 0.12814331, 0.11282349, 0.092681885, - 0.068695068, 0.0418396, 0.013122559, -0.016174316, -0.044891357, - -0.071929932, -0.096038818, -0.11636353, -0.1321106, - -0.14254761, -0.14733887, -0.14633179, -0.13955688, -0.12728882, - -0.11016846, -0.088745117, -0.063995361, -0.036987305, - -0.0087280273, 0.019592285, 0.04675293, 0.071746826, - 0.093536377, 0.11120605, 0.12411499, 0.13171387, 0.13366699, - 0.1300354, 0.12094116, 0.10671997, 0.088104248, 0.065765381, - 0.040588379, 0.013763428, -0.013702393, -0.040740967, - -0.066101074, -0.088897705, -0.10818481, -0.12310791, - -0.13314819, -0.13793945, -0.13720703, -0.13113403, -0.11993408, - -0.10400391, -0.084136963, -0.061126709, -0.035858154, - -0.0094299316, 0.017059326, 0.042633057, 0.066131592, - 0.086669922, 0.10345459, 0.11572266, 0.12304688, 0.12521362, - 0.12203979, 0.11373901, 0.10070801, 0.083435059, 0.062652588, - 0.039276123, 0.014221191, -0.011505127, -0.036773682, - -0.060638428, -0.082092285, -0.10025024, -0.11444092, - -0.12408447, -0.12875366, -0.12835693, -0.1229248, -0.11260986, - -0.097991943, -0.079620361, -0.058166504, -0.034698486, - -0.010040283, 0.014770508, 0.038665771, 0.06072998, 0.080108643, - 0.095916748, 0.10760498, 0.11471558, 0.11691284, 0.11419678, - 0.10671997, 0.094726562, 0.078765869, 0.059570312, 0.037811279, - 0.014465332, -0.0094604492, -0.03314209, -0.055480957, - -0.075592041, -0.09274292, -0.10617065, -0.11532593, -0.1199646, - -0.11981201, -0.11489868, -0.1055603, -0.092102051, - -0.075073242, -0.055267334, -0.033447266, -0.010467529, - 0.012634277, 0.035003662, 0.05569458, 0.073822021, 0.088745117, - 0.099853516, 0.10665894, 0.10894775, 0.10665894, 0.099853516, - 0.088897705, 0.07421875, 0.056427002, 0.0362854, 0.01461792, - -0.0077209473, -0.029754639, -0.050628662, -0.069519043, - -0.085571289, -0.098236084, -0.10702515, -0.11151123, - -0.11157227, -0.1072998, -0.098754883, -0.086364746, - -0.070739746, -0.052368164, -0.032104492, -0.01083374, - 0.01071167, 0.031585693, 0.050872803, 0.067932129, 0.081970215, - 0.092437744, 0.098999023, 0.10134888, 0.099395752, 0.093292236, - 0.083282471, 0.069763184, 0.053375244, 0.034729004, 0.01461792, - -0.0061035156, -0.026641846, -0.046142578, -0.063751221, - -0.078857422, -0.090820312, -0.099121094, -0.10351562, - -0.1038208, -0.099975586, -0.092254639, -0.080932617, - -0.066497803, -0.049560547, -0.030822754, -0.011016846, - 0.0090026855, 0.028411865, 0.046478271, 0.062408447, - 0.075592041, 0.085571289, 0.091827393, 0.094177246, 0.092590332, - 0.087097168, 0.077941895, 0.065582275, 0.050445557, 0.033203125, - 0.014587402, -0.0046691895, -0.023803711, -0.04196167, - -0.05847168, -0.072662354, -0.083892822, -0.091827393, - -0.096099854, -0.0965271, -0.093170166, -0.086181641, - -0.075775146, -0.062530518, -0.046875, -0.029510498, - -0.011169434, 0.0074462891, 0.02557373, 0.042419434, - 0.057342529, 0.069793701, 0.079162598, 0.085174561, 0.087585449, - 0.086273193, 0.081329346, 0.073028564, 0.061645508, 0.047668457, - 0.031768799, 0.014465332, -0.0034484863, -0.021209717, - -0.038208008, -0.053649902, -0.066925049, -0.077575684, - -0.085113525, -0.089233398, -0.08984375, -0.086914062, - -0.080535889, -0.071075439, -0.058837891, -0.044342041, - -0.028289795, -0.011230469, 0.0061340332, 0.023010254, - 0.038787842, 0.05279541, 0.064483643, 0.073394775, 0.079162598, - 0.081542969, 0.080535889, 0.07611084, 0.068481445, 0.058044434, - 0.045166016, 0.03036499, 0.014343262, -0.0023193359, - -0.018951416, -0.034820557, -0.049285889, -0.061828613, - -0.071868896, -0.079040527, -0.083099365, -0.083831787, - -0.081237793, -0.075500488, -0.066772461, -0.055480957, - -0.042114258, -0.027130127, -0.011230469, 0.0049133301, - 0.020751953, 0.035552979, 0.048706055, 0.059783936, 0.068237305, - 0.073760986, 0.076202393, 0.075408936, 0.07144165, 0.064483643, - 0.054840088, 0.042877197, 0.029174805, 0.014190674, - -0.0014038086, -0.016937256, -0.031829834, -0.045501709, - -0.057312012, -0.066864014, -0.073760986, -0.077667236, - -0.078552246, -0.076293945, -0.071044922, -0.063018799, - -0.052581787, -0.040100098, -0.026153564, -0.011291504, - 0.00390625, 0.018768311, 0.032714844, 0.045196533, 0.05569458, - 0.063751221, 0.069152832, 0.071563721, 0.070983887, 0.067443848, - 0.061035156, 0.052093506, 0.040985107, 0.028137207, 0.014099121, - -0.00051879883, -0.015197754, -0.029296875, -0.042205811, - -0.053466797, -0.062591553, -0.069213867, -0.073120117, - -0.07409668, -0.072113037, -0.067321777, -0.059906006, - -0.050140381, -0.038482666, -0.025360107, -0.011322021, - 0.0029907227, 0.017089844, 0.03036499, 0.042236328, 0.052276611, - 0.060089111, 0.0652771, 0.067749023, 0.067382812, 0.064117432, - 0.058227539, 0.04989624, 0.039428711, 0.02734375, 0.014099121, - 0.00021362305, -0.013702393, -0.027099609, -0.039459229, - -0.050231934, -0.058990479, -0.065429688, -0.069244385, - -0.0703125, -0.068634033, -0.064208984, -0.057250977, - -0.048126221, -0.037109375, -0.024688721, -0.011413574, - 0.0021972656, 0.015625, 0.028259277, 0.039642334, 0.049285889, - 0.056793213, 0.061889648, 0.064361572, 0.064117432, 0.061187744, - 0.05569458, 0.047851562, 0.03805542, 0.026611328, 0.014038086, - 0.00088500977, -0.012329102, -0.025146484, -0.03692627, - -0.047241211, -0.055725098, -0.061920166, -0.065673828, - -0.066864014, -0.065338135, -0.061279297, -0.05480957, - -0.046203613, -0.035797119, -0.024078369, -0.011474609, - 0.0014648438, 0.014251709, 0.02633667, 0.037200928, 0.046447754, - 0.053741455, 0.05871582, 0.061157227, 0.061096191, 0.058441162, - 0.053314209, 0.04598999, 0.036712646, 0.025909424, 0.014007568, - 0.0014953613, -0.011138916, -0.02331543, -0.034576416, - -0.044494629, -0.052612305, -0.058654785, -0.06237793, - -0.063598633, -0.062316895, -0.058563232, -0.052490234, - -0.044403076, -0.034606934, -0.023468018, -0.011505127, - 0.00079345703, 0.013000488, 0.024505615, 0.034942627, - 0.04385376, 0.050872803, 0.05569458, 0.058197021, 0.058227539, - 0.055786133, 0.051055908, 0.044158936, 0.035430908, 0.02520752, - 0.013916016, 0.0020141602, -0.009979248, -0.021636963, - -0.032440186, -0.041931152, -0.04977417, -0.055664062, - -0.059265137, -0.060577393, -0.05947876, -0.055999756, - -0.050354004, -0.042724609, -0.033447266, -0.022918701, - -0.011566162, 0.00018310547, 0.011810303, 0.022827148, - 0.032836914, 0.041381836, 0.048187256, 0.05291748, 0.055389404, - 0.055541992, 0.053344727, 0.048919678, 0.042449951, 0.034210205, - 0.024536133, 0.013793945, 0.0025024414, -0.008972168, - -0.020080566, -0.030426025, -0.039581299, -0.047149658, - -0.05279541, -0.056396484, -0.057739258, -0.056793213, - -0.053619385, -0.048309326, -0.041137695, -0.03237915, - -0.022369385, -0.011566162, -0.00039672852, 0.01071167, - 0.02130127, 0.030883789, 0.039123535, 0.045684814, 0.050292969, - 0.052764893, 0.053039551, 0.051055908, 0.046936035, 0.040863037, - 0.033081055, 0.023895264, 0.01373291, 0.0029296875, - -0.0079956055, -0.01864624, -0.028564453, -0.037353516, - -0.044647217, -0.050170898, -0.05368042, -0.055084229, - -0.054290771, -0.051361084, -0.046386719, -0.039642334, - -0.031311035, -0.021820068, -0.011566162, -0.00088500977, - 0.0097351074, 0.019836426, 0.029083252, 0.037017822, - 0.043365479, 0.04788208, 0.050323486, 0.050689697, 0.048919678, - 0.045074463, 0.039367676, 0.032012939, 0.02331543, 0.01361084, - 0.0033569336, -0.0071105957, -0.017303467, -0.026794434, - -0.035247803, -0.042327881, -0.047668457, -0.051147461, - -0.052581787, -0.0519104, -0.049224854, -0.044586182, - -0.03817749, -0.030334473, -0.021331787, -0.011505127, - -0.0013427734, 0.0088195801, 0.01852417, 0.027374268, - 0.03503418, 0.04119873, 0.045593262, 0.048034668, 0.048492432, - 0.046905518, 0.043334961, 0.037963867, 0.031005859, 0.022735596, - 0.013519287, 0.003692627, -0.0062866211, -0.016021729, - -0.025177002, -0.033325195, -0.040130615, -0.045349121, - -0.04876709, -0.050231934, -0.049713135, -0.047210693, - -0.04284668, -0.036834717, -0.029388428, -0.020812988, - -0.011474609, -0.001739502, 0.0079650879, 0.017272949, - 0.025787354, 0.033203125, 0.039154053, 0.043457031, 0.045898438, - 0.046417236, 0.04498291, 0.041687012, 0.036621094, 0.030029297, - 0.022186279, 0.013397217, 0.0040588379, -0.0054931641, - -0.014862061, -0.023651123, -0.031494141, -0.038085938, - -0.043151855, -0.046508789, -0.048034668, -0.047607422, - -0.045318604, -0.041259766, -0.035552979, -0.0284729, - -0.020324707, -0.011413574, -0.0021057129, 0.0071716309, - 0.016113281, 0.02432251, 0.031463623, 0.037231445, 0.041442871, - 0.043884277, 0.044464111, 0.043212891, 0.040100098, 0.035339355, - 0.02911377, 0.021636963, 0.013275146, 0.0043640137, - -0.0048217773, -0.013763428, -0.022216797, -0.029785156, - -0.03616333, -0.041107178, -0.044403076, -0.045928955, - -0.045623779, -0.043548584, -0.039703369, -0.034332275, - -0.027648926, -0.019866943, -0.011352539, -0.0024719238, - 0.0064697266, 0.015045166, 0.022918701, 0.029815674, - 0.035430908, 0.039520264, 0.04196167, 0.042602539, 0.041473389, - 0.038604736, 0.034118652, 0.02822876, 0.021148682, 0.013153076, - 0.0046081543, -0.0041503906, -0.012756348, -0.020874023, - -0.028167725, -0.034332275, -0.039154053, -0.042388916, - -0.043945312, -0.043762207, -0.041809082, -0.038238525, - -0.033172607, -0.026794434, -0.01940918, -0.011291504, - -0.0027770996, 0.0057678223, 0.014007568, 0.021636963, - 0.028259277, 0.033691406, 0.037719727, 0.040100098, 0.04083252, - 0.039825439, 0.03717041, 0.032958984, 0.027374268, 0.020599365, - 0.013000488, 0.0048522949, -0.0035400391, -0.011810303, - -0.019592285, -0.026641846, -0.032623291, -0.03729248, - -0.040466309, -0.042053223, -0.041931152, -0.04019165, - -0.036834717, -0.032012939, -0.026000977, -0.018951416, - -0.011199951, -0.0030517578, 0.0051269531, 0.013061523, - 0.020385742, 0.026794434, 0.032073975, 0.035980225, 0.038360596, - 0.039123535, 0.038238525, 0.035766602, 0.031799316, 0.026489258, - 0.020080566, 0.0128479, 0.0050354004, -0.0029907227, - -0.010894775, -0.018432617, -0.02520752, -0.030975342, - -0.035522461, -0.038635254, -0.040222168, -0.04019165, - -0.038574219, -0.035430908, -0.030914307, -0.025177002, - -0.018493652, -0.011108398, -0.0032958984, 0.0045471191, - 0.012145996, 0.019195557, 0.025390625, 0.030487061, 0.034301758, - 0.036651611, 0.037475586, 0.036712646, 0.034423828, 0.030670166, - 0.025665283, 0.019592285, 0.012664795, 0.0052185059, - -0.0024719238, -0.010070801, -0.017272949, -0.023803711, - -0.029388428, -0.033813477, -0.036865234, -0.038452148, - -0.038513184, -0.03704834, -0.034118652, -0.029815674, - -0.024383545, -0.018035889, -0.010955811, -0.0035400391, - 0.0039978027, 0.011291504, 0.018066406, 0.024047852, - 0.028991699, 0.032684326, 0.035003662, 0.035858154, 0.035217285, - 0.033081055, 0.029571533, 0.024810791, 0.019042969, 0.012481689, - 0.0053405762, -0.0020141602, -0.0092773438, -0.016204834, - -0.022491455, -0.027862549, -0.032165527, -0.03515625, - -0.036743164, -0.036865234, -0.035552979, -0.032775879, - -0.028778076, -0.023620605, -0.017547607, -0.01083374, - -0.0037231445, 0.0034790039, 0.010467529, 0.016967773, - 0.022735596, 0.027526855, 0.03112793, 0.033416748, 0.034301758, - 0.033752441, 0.031768799, 0.0284729, 0.023986816, 0.01852417, - 0.012237549, 0.0054626465, -0.0015563965, -0.0085449219, - -0.015167236, -0.021209717, -0.026428223, -0.030578613, - -0.033508301, -0.035095215, -0.03527832, -0.034057617, - -0.031524658, -0.027709961, -0.022827148, -0.017089844, - -0.010681152, -0.00390625, 0.0029907227, 0.0096740723, - 0.015960693, 0.021484375, 0.026123047, 0.029632568, 0.031890869, - 0.032806396, 0.032348633, 0.030517578, 0.027435303, 0.023193359, - 0.017974854, 0.012023926, 0.0055847168, -0.001159668, - -0.0078125, -0.014190674, -0.020019531, -0.025024414, - -0.029052734, -0.031921387, -0.033477783, -0.033752441, - -0.032653809, -0.030273438, -0.026702881, -0.022094727, - -0.016601562, -0.010498047, -0.0040588379, 0.002532959, - 0.008972168, 0.014953613, 0.020324707, 0.024780273, 0.028198242, - 0.030426025, 0.031341553, 0.030975342, 0.029296875, 0.026397705, - 0.022399902, 0.017486572, 0.011810303, 0.005645752, - -0.00076293945, -0.0071411133, -0.013275146, -0.018859863, - -0.023681641, -0.027587891, -0.03036499, -0.031951904, - -0.03225708, -0.03125, -0.029052734, -0.025695801, -0.02130127, - -0.016113281, -0.010345459, -0.0041503906, 0.0021362305, - 0.0082702637, 0.014068604, 0.019195557, 0.023498535, - 0.026824951, 0.028991699, 0.029937744, 0.029663086, 0.028106689, - 0.025390625, 0.021636963, 0.016967773, 0.011566162, - 0.0057067871, -0.00039672852, -0.0065307617, -0.012359619, - -0.01776123, -0.022399902, -0.026184082, -0.028900146, - -0.030456543, -0.030792236, -0.029937744, -0.027862549, - -0.024688721, -0.020568848, -0.015655518, -0.010131836, - -0.0042419434, 0.001739502, 0.0076599121, 0.013183594, - 0.018127441, 0.022277832, 0.025512695, 0.027618408, 0.028625488, - 0.028381348, 0.026977539, 0.02444458, 0.020874023, 0.016448975, - 0.011352539, 0.0057373047, -9.1552734e-05, -0.0059204102, - -0.011535645, -0.016693115, -0.021179199, -0.024841309, - -0.02746582, -0.029022217, -0.029418945, -0.028625488, - -0.026702881, -0.023742676, -0.019866943, -0.015197754, - -0.0099487305, -0.0043334961, 0.0014038086, 0.007019043, - 0.012329102, 0.017089844, 0.021087646, 0.024230957, 0.026306152, - 0.027282715, 0.027130127, 0.025848389, 0.023468018, 0.020111084, - 0.015930176, 0.011077881, 0.0057678223, 0.00021362305, - -0.0053710938, -0.010742188, -0.015686035, -0.020019531, - -0.023529053, -0.026123047, -0.027648926, -0.028076172, - -0.027374268, -0.025604248, -0.022827148, -0.019134521, - -0.01473999, -0.0097351074, -0.0043945312, 0.0010681152, - 0.0064697266, 0.011535645, 0.016113281, 0.019989014, - 0.023010254, 0.025024414, 0.026031494, 0.025939941, 0.024749756, - 0.02255249, 0.019378662, 0.015411377, 0.01083374, 0.0057678223, - 0.00045776367, -0.0048522949, -0.010009766, -0.01473999, - -0.018890381, -0.02230835, -0.024810791, -0.02633667, - -0.026794434, -0.026184082, -0.024536133, -0.021911621, - -0.018463135, -0.014251709, -0.009552002, -0.0044555664, - 0.00076293945, 0.0059204102, 0.010772705, 0.015167236, - 0.018890381, 0.021820068, 0.023803711, 0.024810791, 0.024749756, - 0.023681641, 0.021606445, 0.01864624, 0.014923096, 0.010559082, - 0.0057373047, 0.0007019043, -0.0043945312, -0.0093078613, - -0.01385498, -0.017852783, -0.021118164, -0.02355957, - -0.025054932, -0.025543213, -0.024993896, -0.023498535, - -0.021057129, -0.01776123, -0.013824463, -0.0093383789, - -0.004486084, 0.00048828125, 0.0054016113, 0.010040283, - 0.014251709, 0.017852783, 0.020690918, 0.022613525, 0.023620605, - 0.023620605, 0.022644043, 0.020721436, 0.017944336, 0.014404297, - 0.010284424, 0.0057373047, 0.00091552734, -0.0039367676, - -0.0086364746, -0.013000488, -0.016815186, -0.019989014, - -0.022338867, -0.023803711, -0.02432251, -0.023864746, - -0.022460938, -0.020172119, -0.017089844, -0.013366699, - -0.0090942383, -0.0045166016, 0.00021362305, 0.0049133301, - 0.0093688965, 0.013397217, 0.016845703, 0.019592285, - 0.021484375, 0.022491455, 0.022521973, 0.021636963, 0.019866943, - 0.017242432, 0.013916016, 0.010009766, 0.0056762695, - 0.0010986328, -0.0035095215, -0.0079956055, -0.012176514, - -0.015838623, -0.018890381, -0.021179199, -0.022613525, - -0.023162842, -0.022766113, -0.021484375, -0.019348145, - -0.016418457, -0.012908936, -0.0088806152, -0.0045166016, 0, - 0.0044555664, 0.0087280273, 0.012573242, 0.015899658, - 0.01852417, 0.020385742, 0.021362305, 0.021484375, 0.0206604, - 0.019012451, 0.016571045, 0.013427734, 0.0097045898, - 0.0056152344, 0.0012817383, -0.003112793, -0.0073852539, - -0.011383057, -0.014923096, -0.017822266, -0.020050049, - -0.021453857, -0.022003174, -0.021697998, -0.020507812, - -0.018493652, -0.015777588, -0.012451172, -0.0086364746, - -0.004486084, -0.00021362305, 0.0040588379, 0.0080871582, - 0.011779785, 0.014984131, 0.01751709, 0.019317627, 0.020294189, - 0.020446777, 0.019714355, 0.018188477, 0.015869141, 0.012908936, - 0.0094299316, 0.0055541992, 0.0014343262, -0.002746582, - -0.0068359375, -0.010620117, -0.014007568, -0.016815186, - -0.018981934, -0.020355225, -0.020904541, -0.020629883, - -0.019561768, -0.017700195, -0.015136719, -0.011993408, - -0.008392334, -0.0044555664, -0.00039672852, 0.0036621094, - 0.0075073242, 0.011047363, 0.014099121, 0.016540527, - 0.018280029, 0.019256592, 0.01940918, 0.018768311, 0.017364502, - 0.015197754, 0.012420654, 0.0091247559, 0.0054626465, - 0.0015563965, -0.0024108887, -0.0062866211, -0.0099182129, - -0.013153076, -0.015838623, -0.017913818, -0.019256592, - -0.019836426, -0.019622803, -0.018615723, -0.016876221, - -0.01449585, -0.011535645, -0.0081176758, -0.0044250488, - -0.00057983398, 0.0032958984, 0.0069580078, 0.010314941, - 0.013244629, 0.015594482, 0.017272949, 0.018249512, 0.018432617, - 0.017852783, 0.016540527, 0.014556885, 0.011932373, - 0.0088195801, 0.0053710938, 0.0016784668, -0.0021057129, - -0.0057678223, -0.0092468262, -0.012329102, -0.014892578, - -0.016906738, -0.018188477, -0.018768311, -0.018615723, - -0.017700195, -0.016082764, -0.01385498, -0.011047363, - -0.0078430176, -0.0043640137, -0.0007019043, 0.0029296875, - 0.006439209, 0.0096435547, 0.012451172, 0.014678955, - 0.016326904, 0.017272949, 0.017486572, 0.016967773, 0.01574707, - 0.013885498, 0.011444092, 0.0085144043, 0.0052490234, - 0.0017700195, -0.0018005371, -0.0053100586, -0.0085754395, - -0.011535645, -0.014007568, -0.015899658, -0.017181396, - -0.01776123, -0.01763916, -0.016815186, -0.015319824, - -0.013214111, -0.0105896, -0.007598877, -0.0042724609, - -0.00082397461, 0.0026245117, 0.0059509277, 0.0090026855, - 0.011657715, 0.013824463, 0.015380859, 0.016296387, 0.016540527, - 0.016082764, 0.014984131, 0.013244629, 0.010955811, - 0.0082092285, 0.0051269531, 0.0018310547, -0.0015258789, - -0.0048522949, -0.0079650879, -0.010772705, -0.013122559, - -0.014953613, -0.016204834, -0.01675415, -0.016693115, - -0.015930176, -0.014556885, -0.01260376, -0.010131836, - -0.0072937012, -0.0042114258, -0.00094604492, 0.0023193359, - 0.0054626465, 0.0083618164, 0.010894775, 0.012939453, - 0.014465332, 0.015380859, 0.015625, 0.015228271, 0.014221191, - 0.012573242, 0.010467529, 0.0078735352, 0.0049743652, - 0.0018920898, -0.0012817383, -0.0044250488, -0.0073852539, - -0.010040283, -0.012298584, -0.014038086, -0.015228271, - -0.015808105, -0.01574707, -0.015075684, -0.013793945, - -0.011962891, -0.0096740723, -0.007019043, -0.004119873, - -0.0010375977, 0.0020446777, 0.0050048828, 0.0077514648, - 0.010162354, 0.012115479, 0.013580322, 0.014465332, 0.01473999, - 0.014373779, 0.013458252, 0.011962891, 0.0099487305, - 0.0075378418, 0.0048522949, 0.0019226074, -0.0010681152, - -0.0040283203, -0.0068054199, -0.0093383789, -0.011474609, - -0.013153076, -0.014312744, -0.014862061, -0.014862061, - -0.014251709, -0.013061523, -0.011352539, -0.0092468262, - -0.0067443848, -0.0039978027, -0.0011291504, 0.0017700195, - 0.0045776367, 0.0071716309, 0.0094604492, 0.011322021, - 0.012695312, 0.013580322, 0.01385498, 0.013549805, 0.012695312, - 0.011322021, 0.0094604492, 0.007232666, 0.0046691895, - 0.001953125, -0.00085449219, -0.0036621094, -0.0062866211, - -0.0086669922, -0.010681152, -0.012298584, -0.013397217, - -0.013946533, -0.013946533, -0.013397217, -0.012329102, - -0.010772705, -0.0087585449, -0.006439209, -0.00390625, - -0.0011901855, 0.0015258789, 0.0041809082, 0.0066223145, - 0.0087585449, 0.010559082, 0.011871338, 0.012695312, - 0.013000488, 0.012756348, 0.011962891, 0.010681152, 0.008972168, - 0.0068664551, 0.0045166016, 0.001953125, -0.00067138672, - -0.0032958984, -0.0057678223, -0.0079956055, -0.0099182129, - -0.011444092, -0.012512207, -0.013061523, -0.013092041, - -0.01260376, -0.01159668, -0.010162354, -0.0083007812, - -0.0061645508, -0.0037536621, -0.0012512207, 0.0013122559, - 0.0037841797, 0.0061035156, 0.0081176758, 0.0097961426, - 0.011077881, 0.011871338, 0.012145996, 0.011932373, 0.011230469, - 0.010070801, 0.0084838867, 0.0065307617, 0.0043334961, - 0.001953125, -0.00051879883, -0.0029602051, -0.005279541, - -0.0073852539, -0.009185791, -0.010620117, -0.011627197, - -0.012176514, -0.012237549, -0.011779785, -0.010894775, - -0.009552002, -0.0078430176, -0.0058288574, -0.0036315918, - -0.0012817383, 0.0011291504, 0.0034179688, 0.0055847168, - 0.0075073242, 0.0090637207, 0.010284424, 0.011047363, - 0.011322021, 0.011169434, 0.010528564, 0.0094604492, - 0.0079956055, 0.0061950684, 0.0041503906, 0.0019226074, - -0.00036621094, -0.0026550293, -0.0048217773, -0.0067749023, - -0.0084838867, -0.0098266602, -0.010803223, -0.011322021, - -0.011383057, -0.010986328, -0.010192871, -0.0089416504, - -0.0073852539, -0.0055236816, -0.0034790039, -0.0012817383, - 0.00094604492, 0.0030822754, 0.0050964355, 0.0068969727, - 0.008392334, 0.0095214844, 0.010223389, 0.010528564, - 0.010406494, 0.0098266602, 0.0088500977, 0.0075073242, - 0.0058288574, 0.0039672852, 0.0018920898, -0.00021362305, - -0.0023498535, -0.0043640137, -0.0061950684, -0.0077819824, - -0.0090637207, -0.009979248, -0.010467529, -0.010559082, - -0.010223389, -0.0094909668, -0.0083618164, -0.0069274902, - -0.0052185059, -0.0032958984, -0.0012817383, 0.00076293945, - 0.0027770996, 0.0046386719, 0.0063171387, 0.0076904297, - 0.0087585449, 0.0094604492, 0.0097351074, 0.0096435547, - 0.0091247559, 0.0082397461, 0.0069885254, 0.0054931641, - 0.0037536621, 0.0018615723, -0.00012207031, -0.0020751953, - -0.0039367676, -0.005645752, -0.0071411133, -0.0083312988, - -0.009185791, -0.0096740723, -0.009765625, -0.0094604492, - -0.0087890625, -0.0077819824, -0.006439209, -0.0048828125, - -0.0031433105, -0.0012817383, 0.00061035156, 0.0024719238, - 0.0042114258, 0.0057373047, 0.0070495605, 0.008026123, - 0.0086975098, 0.008972168, 0.0088806152, 0.0084228516, - 0.0076293945, 0.0065002441, 0.0051269531, 0.0035400391, - 0.0018005371, 0, -0.0018005371, -0.0035400391, -0.0051269531, - -0.0065002441, -0.007598877, -0.008392334, -0.0088500977, - -0.008972168, -0.0086975098, -0.0081176758, -0.0071716309, - -0.0059814453, -0.0045471191, -0.0029602051, -0.0012512207, - 0.00048828125, 0.0021972656, 0.0037841797, 0.0052185059, - 0.0064086914, 0.0073242188, 0.0079345703, 0.0082092285, - 0.0081481934, 0.0077514648, 0.007019043, 0.0060119629, - 0.0047607422, 0.0032958984, 0.0017089844, 6.1035156e-05, - -0.0015869141, -0.0031738281, -0.0046081543, -0.0058898926, - -0.0068969727, -0.0076293945, -0.0080566406, -0.0081787109, - -0.0079650879, -0.0074157715, -0.0065917969, -0.0055236816, - -0.0042114258, -0.0027770996, -0.0012207031, 0.00036621094, - 0.0019226074, 0.0033874512, 0.0046691895, 0.0057678223, - 0.0066223145, 0.0072021484, 0.0074768066, 0.0074157715, - 0.0070800781, 0.0064086914, 0.0055236816, 0.0043945312, - 0.0030822754, 0.0016479492, 0.00015258789, -0.001373291, - -0.0028076172, -0.004119873, -0.005279541, -0.0062255859, - -0.0068969727, -0.0072937012, -0.0074157715, -0.007232666, - -0.0067443848, -0.0060119629, -0.0050354004, -0.0038757324, - -0.0025634766, -0.001159668, 0.0002746582, 0.0016784668, - 0.0029907227, 0.0041809082, 0.0051879883, 0.0059509277, - 0.0064697266, 0.0067443848, 0.0067138672, 0.0064086914, - 0.0058288574, 0.0050048828, 0.0039978027, 0.0028381348, - 0.0015258789, 0.00018310547, -0.001159668, -0.0024719238, - -0.0036621094, -0.004699707, -0.0055541992, -0.0061645508, - -0.0065307617, -0.006652832, -0.0065002441, -0.006072998, - -0.0054321289, -0.0045776367, -0.0035400391, -0.0023498535, - -0.0010986328, 0.00018310547, 0.0014343262, 0.0026245117, - 0.003692627, 0.0046081543, 0.0053100586, 0.0057678223, - 0.0060119629, 0.0060119629, 0.0057373047, 0.0052185059, - 0.0045166016, 0.0036315918, 0.0025634766, 0.0014343262, - 0.00024414062, -0.0009765625, -0.0021362305, -0.0032043457, - -0.0041503906, -0.0049133301, -0.0054626465, -0.0057983398, - -0.0059204102, -0.0057678223, -0.0054321289, -0.0048522949, - -0.0040893555, -0.0031738281, -0.0021362305, -0.0010375977, - 9.1552734e-05, 0.0012207031, 0.0022583008, 0.0032348633, - 0.0040283203, 0.0046691895, 0.0050964355, 0.0053100586, - 0.0053100586, 0.005065918, 0.0046386719, 0.0039978027, - 0.0032348633, 0.0023193359, 0.0013122559, 0.00024414062, - -0.00079345703, -0.0018310547, -0.0027770996, -0.0036010742, - -0.0042724609, -0.0047607422, -0.005065918, -0.0051879883, - -0.005065918, -0.0047607422, -0.0042724609, -0.0036010742, - -0.0028076172, -0.0019226074, -0.00094604492, 3.0517578e-05, - 0.0010070801, 0.0019226074, 0.0027770996, 0.0034790039, - 0.0040283203, 0.0043945312, 0.0046081543, 0.0046081543, - 0.0044250488, 0.0040283203, 0.0035095215, 0.0028381348, - 0.0020446777, 0.001159668, 0.0002746582, -0.00064086914, - -0.0015258789, -0.0023498535, -0.0030517578, -0.0036621094, - -0.0040893555, -0.0043640137, -0.0044555664, -0.0043640137, - -0.0040893555, -0.003692627, -0.003112793, -0.0024414062, - -0.0016784668, -0.00085449219, 0, 0.00082397461, 0.0016174316, - 0.0023193359, 0.0029296875, 0.0034179688, 0.0037536621, - 0.00390625, 0.00390625, 0.0037536621, 0.0034484863, - 0.0029907227, 0.0024414062, 0.0017700195, 0.0010375977, - 0.0002746582, -0.00051879883, -0.0012512207, -0.001953125, - -0.0025634766, -0.0030517578, -0.0034179688, -0.0036621094, - -0.0037231445, -0.0036621094, -0.0034484863, -0.003112793, - -0.0026245117, -0.0020751953, -0.0014343262, -0.00073242188, - -3.0517578e-05, 0.00067138672, 0.0013122559, 0.0019226074, - 0.0024108887, 0.0028076172, 0.0030822754, 0.0032348633, - 0.0032348633, 0.003112793, 0.0028686523, 0.0025024414, - 0.0020141602, 0.0014648438, 0.00088500977, 0.00024414062, - -0.00039672852, -0.0010070801, -0.0015563965, -0.0020446777, - -0.0024719238, -0.0027770996, -0.0029602051, -0.0030212402, - -0.0029602051, -0.0028076172, -0.0025024414, -0.0021362305, - -0.0016784668, -0.001159668, -0.00061035156, -6.1035156e-05, - 0.00048828125, 0.0010375977, 0.0014953613, 0.0018920898, - 0.0022277832, 0.0024414062, 0.0025634766, 0.0025634766, - 0.0024719238, 0.0022583008, 0.0019836426, 0.0016174316, - 0.0011901855, 0.0007019043, 0.00021362305, -0.0002746582, - -0.00076293945, -0.0011901855, -0.0015563965, -0.0018920898, - -0.0021057129, -0.0022583008, -0.0023193359, -0.0022583008, - -0.0021362305, -0.0019226074, -0.0016479492, -0.0012817383, - -0.00091552734, -0.00048828125, -6.1035156e-05, 0.00036621094, - 0.00076293945, 0.0010986328, 0.0014038086, 0.0016479492, - 0.0018005371, 0.0018920898, 0.0018920898, 0.0018005371, - 0.0016479492, 0.0014343262, 0.0011901855, 0.00085449219, - 0.00051879883, 0.00018310547, -0.00018310547, -0.00051879883, - -0.00082397461, -0.0010986328, -0.0013122559, -0.0014953613, - -0.0015869141, -0.0016174316, -0.0015869141, -0.0014953613, - -0.0013427734, -0.0011291504, -0.00088500977, -0.00064086914, - -0.00033569336, -6.1035156e-05, 0.00021362305, 0.00048828125, - 0.00073242188, 0.00091552734, 0.0010681152, 0.001159668, - 0.0012207031, 0.0012207031, 0.001159668, 0.0010681152, - 0.00091552734, 0.00073242188, 0.00054931641, 0.00033569336, - 0.00012207031, -9.1552734e-05, -0.00030517578, -0.00048828125, - -0.00064086914, -0.00076293945, -0.00085449219, -0.00091552734, - -0.00091552734, -0.00088500977, -0.00082397461, -0.00073242188, - -0.00061035156, -0.00048828125, -0.00033569336, -0.00018310547, - -3.0517578e-05, 0.00012207031, 0.00024414062, 0.00033569336, - 0.00042724609, 0.00048828125, 0.00054931641, 0.00054931641, - 0.00054931641, 0.00051879883, 0.00045776367, 0.00039672852, - 0.00030517578, 0.00021362305, 0.00012207031, 6.1035156e-05, - -3.0517578e-05, -9.1552734e-05, -0.00015258789, -0.00018310547, - -0.00021362305, -0.00024414062, -0.00024414062, -0.00021362305, - -0.00021362305, -0.00018310547, -0.00012207031, -9.1552734e-05, - -6.1035156e-05, -3.0517578e-05, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, -}; - -const nframes_t Session::default_click_emphasis_length = sizeof (default_click_emphasis) / sizeof (default_click_emphasis[0]); - -const Sample Session::default_click[] = { - 0, -0.014312744, -0.03338623, 0.019165039, 0.042541504, - 0.08984375, 0.082611084, 0.13909912, 0.17236328, - 0.19238281, 0.21087646, 0.22238159, 0.23114014, - 0.23321533, 0.23080444, 0.222229, 0.20944214, - 0.19146729, 0.16964722, 0.14352417, 0.11450195, - 0.082489014, 0.049316406, 0.014068604, -0.020507812, - -0.055969238, -0.089233398, -0.1211853, -0.15036011, - -0.1763916, -0.19882202, -0.2170105, -0.23062134, - -0.23916626, -0.24279785, -0.24142456, -0.23483276, - -0.22357178, -0.2074585, -0.18701172, -0.16308594, - -0.1355896, -0.10562134, -0.073547363, -0.040100098, - -0.0061645508, 0.027618408, 0.060394287, 0.091796875, - 0.12072754, 0.14685059, 0.16949463, 0.18804932, - 0.20245361, 0.21212769, 0.21694946, 0.21691895, - 0.21191406, 0.20214844, 0.18786621, 0.16943359, - 0.14706421, 0.12145996, 0.093139648, 0.06262207, - 0.030822754, -0.0018310547, -0.034545898, -0.066467285, - -0.097076416, -0.12564087, -0.15155029, -0.17422485, - -0.19326782, -0.20812988, -0.21862793, -0.22457886, - -0.22567749, -0.22210693, -0.21392822, -0.20120239, - -0.18438721, -0.16381836, -0.13986206, -0.11315918, - -0.084289551, -0.053771973, -0.02243042, 0.0090942383, - 0.040252686, 0.07019043, 0.098297119, 0.12408447, - 0.14685059, 0.16616821, 0.18170166, 0.19302368, - 0.19985962, 0.20230103, 0.20007324, 0.19329834, - 0.18231201, 0.16711426, 0.14819336, 0.1260376, - 0.10095215, 0.073608398, 0.044647217, 0.01461792, - -0.015808105, -0.04586792, -0.075073242, -0.10272217, - -0.12811279, -0.15084839, -0.17041016, -0.1862793, - -0.19827271, -0.20602417, -0.20941162, -0.20846558, - -0.203125, -0.19348145, -0.17990112, -0.16259766, - -0.14190674, -0.11846924, -0.092651367, -0.065002441, - -0.0362854, -0.0069885254, 0.022247314, 0.05065918, - 0.077758789, 0.10296631, 0.12561035, 0.14532471, - 0.16171265, 0.17428589, 0.18289185, 0.18737793, - 0.18756104, 0.18353271, 0.17541504, 0.16329956, - 0.14755249, 0.12854004, 0.10656738, 0.082244873, - 0.056091309, 0.028594971, 0.00045776367, -0.027709961, - -0.055419922, -0.08190918, -0.10665894, -0.12924194, - -0.14901733, -0.1656189, -0.17877197, -0.18811035, - -0.19342041, -0.19473267, -0.19189453, -0.18505859, - -0.17440796, -0.16009521, -0.14245605, -0.12203979, - -0.099121094, -0.07421875, -0.048034668, -0.020935059, - 0.0063781738, 0.033233643, 0.059234619, 0.083709717, - 0.1060791, 0.12600708, 0.14294434, 0.15655518, - 0.16662598, 0.17288208, 0.1751709, 0.17355347, - 0.16802979, 0.15866089, 0.14581299, 0.12966919, - 0.1105957, 0.089080811, 0.065551758, 0.040466309, - 0.014556885, -0.011779785, -0.037963867, -0.063293457, - -0.087341309, -0.10958862, -0.12942505, -0.14654541, - -0.16061401, -0.1711731, -0.17816162, -0.18145752, - -0.18081665, -0.17642212, -0.16836548, -0.15673828, - -0.14193726, -0.12426758, -0.10400391, -0.081695557, - -0.057891846, -0.032928467, -0.0075073242, 0.017791748, - 0.042602539, 0.066192627, 0.088134766, 0.10803223, - 0.12530518, 0.13967896, 0.15087891, 0.15859985, - 0.16265869, 0.16311646, 0.15982056, 0.1529541, - 0.14273071, 0.12921143, 0.11282349, 0.093963623, - 0.072967529, 0.050323486, 0.026580811, 0.002166748, - -0.022369385, -0.046356201, -0.069458008, -0.091094971, - -0.11071777, -0.12808228, -0.1427002, -0.15420532, - -0.16253662, -0.16741943, -0.16867065, -0.16647339, - -0.1607666, -0.15164185, -0.13946533, -0.12438965, - -0.10675049, -0.087036133, -0.065582275, -0.042877197, - -0.019500732, 0.004119873, 0.027496338, 0.049957275, - 0.071228027, 0.090759277, 0.10803223, 0.12283325, - 0.13482666, 0.14364624, 0.14923096, 0.15145874, - 0.150177, 0.14556885, 0.13772583, 0.1267395, 0.11294556, - 0.096679688, 0.078155518, 0.057952881, 0.036499023, - 0.014099121, -0.0085449219, -0.031066895, -0.052978516, - -0.073730469, -0.092895508, -0.11013794, -0.125, - -0.13717651, -0.14648438, -0.15264893, -0.15557861, - -0.15527344, -0.15164185, -0.14486694, -0.13510132, - -0.12252808, -0.10742188, -0.090240479, -0.07119751, - -0.05078125, -0.029510498, -0.0077514648, 0.014007568, - 0.035186768, 0.055480957, 0.074401855, 0.091430664, - 0.10638428, 0.11880493, 0.128479, 0.13525391, - 0.13891602, 0.1394043, 0.1368103, 0.13113403, - 0.12246704, 0.11114502, 0.097320557, 0.081268311, - 0.06350708, 0.044281006, 0.024017334, 0.0032958984, - -0.017578125, -0.038116455, -0.057769775, -0.07623291, - -0.093109131, -0.10791016, -0.12045288, -0.13046265, - -0.13763428, -0.14190674, -0.14321899, -0.14141846, - -0.13674927, -0.12921143, -0.11895752, -0.10629272, - -0.091491699, -0.074798584, -0.05670166, -0.037536621, - -0.017700195, 0.0022888184, 0.022033691, 0.04119873, - 0.059234619, 0.075805664, 0.090606689, 0.10324097, - 0.11346436, 0.12112427, 0.12594604, 0.12796021, - 0.12710571, 0.12335205, 0.11682129, 0.10772705, - 0.096191406, 0.082519531, 0.067077637, 0.050079346, - 0.031982422, 0.013244629, -0.0058898926, -0.024902344, - -0.043334961, -0.060882568, -0.077148438, -0.091674805, - -0.10430908, -0.11471558, -0.12261963, -0.12799072, - -0.13061523, -0.13043213, -0.12759399, -0.12203979, - -0.11392212, -0.10351562, -0.0909729, -0.076568604, - -0.060699463, -0.043640137, -0.025787354, -0.0075683594, - 0.010650635, 0.028503418, 0.045532227, 0.061431885, - 0.075836182, 0.088409424, 0.098968506, 0.10720825, - 0.11297607, 0.11621094, 0.11682129, 0.11471558, - 0.11010742, 0.10305786, 0.093658447, 0.082214355, - 0.068969727, 0.054138184, 0.038146973, 0.021331787, - 0.0039978027, -0.013397217, -0.030517578, -0.047027588, - -0.062469482, -0.076568604, -0.089080811, -0.099609375, - -0.10803223, -0.11419678, -0.1178894, -0.11907959, - -0.11779785, -0.11398315, -0.1078186, -0.099456787, - -0.089019775, -0.076751709, -0.063018799, -0.047973633, - -0.032073975, -0.015655518, 0.0010070801, 0.017456055, - 0.033355713, 0.048431396, 0.062286377, 0.074615479, - 0.085235596, 0.09387207, 0.10031128, 0.10449219, - 0.10629272, 0.10565186, 0.10272217, 0.097442627, - 0.089996338, 0.080566406, 0.069366455, 0.05657959, - 0.042633057, 0.027679443, 0.012115479, -0.003692627, - -0.01940918, -0.034759521, -0.049316406, -0.062835693, - -0.075012207, -0.085510254, -0.094238281, -0.10095215, - -0.10543823, -0.10775757, -0.10778809, -0.10552979, - -0.10107422, -0.094512939, -0.085968018, -0.075714111, - -0.063934326, -0.050842285, -0.036834717, -0.022125244, - -0.0070800781, 0.0079650879, 0.022705078, 0.036865234, - 0.050018311, 0.061981201, 0.072479248, 0.081268311, - 0.088165283, 0.093109131, 0.095855713, 0.096466064, - 0.094940186, 0.091247559, 0.085510254, 0.077911377, - 0.06854248, 0.057678223, 0.045593262, 0.032440186, - 0.018585205, 0.0043640137, -0.010009766, -0.024169922, - -0.037750244, -0.050567627, -0.062286377, -0.072631836, - -0.081451416, -0.088500977, -0.093658447, -0.096862793, - -0.097961426, -0.097015381, -0.094024658, -0.089080811, - -0.082275391, -0.073791504, -0.063812256, -0.052520752, - -0.040252686, -0.027191162, -0.013641357, 0, - 0.013580322, 0.026733398, 0.039154053, 0.050628662, - 0.060913086, 0.069702148, 0.076934814, 0.082366943, - 0.085906982, 0.087524414, 0.087158203, 0.08480835, - 0.080627441, 0.074615479, 0.066925049, 0.057800293, - 0.047393799, 0.035888672, 0.023651123, 0.010894775, - -0.0021362305, -0.015106201, -0.027740479, -0.039825439, - -0.050994873, -0.061096191, -0.069885254, -0.077148438, - -0.082763672, -0.086669922, -0.088684082, -0.088806152, - -0.087097168, -0.083526611, -0.07824707, -0.071350098, - -0.062957764, -0.053314209, -0.042633057, -0.031066895, - -0.018981934, -0.0065917969, 0.0058288574, 0.018035889, - 0.029693604, 0.040649414, 0.050628662, 0.059356689, - 0.066741943, 0.072570801, 0.076721191, 0.079162598, - 0.079772949, 0.078613281, 0.075714111, 0.071105957, - 0.064880371, 0.057281494, 0.048400879, 0.038421631, - 0.027618408, 0.016204834, 0.0043945312, -0.0074768066, - -0.019195557, -0.030548096, -0.041168213, -0.050964355, - -0.059661865, -0.067047119, -0.072998047, -0.077453613, - -0.080169678, -0.081237793, -0.080596924, -0.078216553, - -0.074249268, -0.068725586, -0.061767578, -0.05355835, - -0.044281006, -0.034088135, -0.023284912, -0.012084961, - -0.00067138672, 0.010650635, 0.021606445, 0.032043457, - 0.041687012, 0.050292969, 0.057769775, 0.063903809, - 0.06854248, 0.071655273, 0.073120117, 0.072937012, - 0.071166992, 0.067749023, 0.062835693, 0.056549072, - 0.048980713, 0.040313721, 0.030792236, 0.020568848, - 0.0098571777, -0.0010375977, -0.011932373, -0.022613525, - -0.032745361, -0.042236328, -0.050811768, -0.058288574, - -0.064544678, -0.069396973, -0.072784424, -0.074645996, - -0.074890137, -0.073547363, -0.070709229, -0.066375732, - -0.060638428, -0.05368042, -0.045593262, -0.036590576, - -0.026916504, -0.016693115, -0.0061950684, 0.0043334961, - 0.014709473, 0.024688721, 0.0340271, 0.042572021, - 0.050109863, 0.05645752, 0.061553955, 0.065246582, - 0.06741333, 0.068115234, 0.067260742, 0.064880371, - 0.061065674, 0.055908203, 0.049468994, 0.04196167, - 0.033508301, 0.024291992, 0.014556885, 0.004486084, - -0.0057067871, -0.015777588, -0.025512695, -0.034759521, - -0.043212891, -0.050750732, -0.057250977, -0.062469482, - -0.066375732, -0.068908691, -0.069915771, -0.069488525, - -0.067596436, -0.064239502, -0.05960083, -0.053710938, - -0.046691895, -0.038726807, -0.029998779, -0.020690918, - -0.011016846, -0.001159668, 0.0086364746, 0.018188477, - 0.027252197, 0.035675049, 0.043243408, 0.04977417, - 0.055175781, 0.059326172, 0.062103271, 0.063537598, - 0.063476562, 0.062011719, 0.059173584, 0.054992676, - 0.049591064, 0.043121338, 0.035675049, 0.027404785, - 0.018554688, 0.0092468262, -0.00024414062, - -0.0097351074, -0.019042969, -0.027954102, -0.036254883, - -0.043792725, -0.050415039, -0.055938721, -0.060272217, - -0.063323975, -0.065032959, -0.065368652, -0.064300537, - -0.061889648, -0.058197021, -0.053283691, -0.047241211, - -0.040283203, -0.032470703, -0.024017334, -0.015136719, - -0.0059814453, 0.0032653809, 0.012329102, 0.021087646, - 0.029327393, 0.036834717, 0.043487549, 0.049133301, - 0.053649902, 0.056945801, 0.058959961, 0.059631348, - 0.058990479, 0.057006836, 0.053741455, 0.049316406, - 0.043762207, 0.037231445, 0.029876709, 0.021881104, - 0.013366699, 0.0045471191, -0.0043640137, -0.013214111, - -0.021759033, -0.029876709, -0.037353516, -0.044006348, - -0.049743652, -0.054412842, -0.057922363, -0.060180664, - -0.061187744, -0.060913086, -0.059295654, -0.056488037, - -0.052459717, -0.047363281, -0.041290283, -0.034362793, - -0.026733398, -0.018615723, -0.010131836, -0.0014953613, - 0.0070800781, 0.01550293, 0.023498535, 0.030883789, - 0.037597656, 0.043426514, 0.048217773, 0.051940918, - 0.054473877, 0.055786133, 0.055847168, 0.054656982, - 0.052215576, 0.04864502, 0.04397583, 0.038330078, - 0.031829834, 0.024627686, 0.016845703, 0.0087280273, - 0.00039672852, -0.0079650879, -0.016143799, - -0.024017334, -0.03137207, -0.038024902, -0.043914795, - -0.048828125, -0.052703857, -0.055480957, -0.057067871, - -0.057434082, -0.05657959, -0.05456543, -0.051361084, - -0.047119141, -0.041900635, -0.035797119, -0.028961182, - -0.021575928, -0.013763428, -0.0057067871, 0.0023803711, - 0.010406494, 0.018127441, 0.025390625, 0.032073975, - 0.037994385, 0.043029785, 0.047088623, 0.050048828, - 0.0519104, 0.052581787, 0.052093506, 0.050415039, - 0.047637939, 0.043792725, 0.03894043, 0.03326416, - 0.026824951, 0.019775391, 0.012329102, 0.0045776367, - -0.0032958984, -0.011108398, -0.018676758, -0.025878906, - -0.032501221, -0.038421631, -0.043548584, -0.047729492, - -0.05090332, -0.053009033, -0.053955078, -0.053771973, - -0.052459717, -0.050018311, -0.046539307, -0.042114258, - -0.036773682, -0.030731201, -0.024047852, -0.016876221, - -0.0094299316, -0.0018005371, 0.0058288574, 0.013244629, - 0.020324707, 0.026916504, 0.032867432, 0.03805542, - 0.042388916, 0.04574585, 0.048034668, 0.049285889, - 0.049407959, 0.048400879, 0.046356201, 0.043243408, - 0.03918457, 0.034240723, 0.028533936, 0.022216797, - 0.015380859, 0.0082092285, 0.00082397461, -0.0065612793, - -0.013824463, -0.020812988, -0.02734375, -0.033294678, - -0.038543701, -0.042938232, -0.046478271, -0.048980713, - -0.050445557, -0.050842285, -0.050170898, -0.048431396, - -0.045684814, -0.041992188, -0.037384033, -0.032073975, - -0.026062012, -0.01953125, -0.012634277, -0.0055236816, - 0.0016784668, 0.0087890625, 0.015655518, 0.022125244, - 0.028076172, 0.033355713, 0.037902832, 0.041534424, - 0.044250488, 0.045959473, 0.046630859, 0.046264648, - 0.04486084, 0.042419434, 0.039093018, 0.034851074, - 0.029846191, 0.024200439, 0.018005371, 0.011383057, - 0.0045166016, -0.0024719238, -0.0093994141, - -0.016143799, -0.022521973, -0.0284729, -0.033752441, - -0.038360596, -0.042144775, -0.045013428, -0.046936035, - -0.047851562, -0.04776001, -0.046630859, -0.044555664, - -0.041534424, -0.037628174, -0.032989502, -0.027618408, - -0.021728516, -0.015411377, -0.0087585449, - -0.0020141602, 0.0047607422, 0.011383057, 0.017700195, - 0.023590088, 0.028930664, 0.033569336, 0.037475586, - 0.040527344, 0.042633057, 0.043792725, 0.04397583, - 0.043151855, 0.041381836, 0.038696289, 0.035125732, - 0.030792236, 0.025756836, 0.020172119, 0.014099121, - 0.0077514648, 0.0011901855, -0.0053710938, -0.01184082, - -0.018066406, -0.023925781, -0.02923584, -0.033966064, - -0.037963867, -0.041107178, -0.043426514, -0.044799805, - -0.045196533, -0.044677734, -0.043182373, -0.040802002, - -0.037567139, -0.033538818, -0.028808594, -0.023498535, - -0.017730713, -0.01159668, -0.005279541, 0.0011291504, - 0.0074768066, 0.013580322, 0.019378662, 0.024719238, - 0.02947998, 0.033538818, 0.036865234, 0.039306641, - 0.040893555, 0.041564941, 0.041290283, 0.040100098, - 0.038024902, 0.035064697, 0.031341553, 0.026947021, - 0.021942139, 0.016418457, 0.0105896, 0.0044555664, - -0.001739502, -0.0079345703, -0.013946533, -0.019683838, - -0.024963379, -0.029754639, -0.033905029, -0.03729248, - -0.039916992, -0.041687012, -0.042572021, -0.042541504, - -0.041625977, -0.039794922, -0.03717041, -0.033752441, - -0.029632568, -0.024902344, -0.019683838, -0.014038086, - -0.0081787109, -0.0021362305, 0.00390625, 0.0097961426, - 0.015472412, 0.020751953, 0.025512695, 0.029724121, - 0.033233643, 0.036010742, 0.037963867, 0.039031982, - 0.039245605, 0.038574219, 0.03704834, 0.034698486, - 0.031585693, 0.027740479, 0.02331543, 0.018341064, - 0.012969971, 0.0073242188, 0.0014953613, -0.0043640137, - -0.010162354, -0.015716553, -0.020965576, -0.025756836, - -0.029968262, -0.033569336, -0.036468506, -0.038543701, - -0.039825439, -0.040283203, -0.039825439, -0.038574219, - -0.036499023, -0.033630371, -0.030090332, -0.025939941, - -0.021240234, -0.016113281, -0.010681152, -0.0050354004, - 0.00067138672, 0.0063171387, 0.011810303, 0.016998291, - 0.021759033, 0.026031494, 0.029724121, 0.032684326, - 0.034942627, 0.036407471, 0.03704834, 0.036865234, - 0.035858154, 0.0340271, 0.031463623, 0.028198242, - 0.024291992, 0.019866943, 0.014984131, 0.0097961426, - 0.0043640137, -0.0011901855, -0.0066833496, - -0.012054443, -0.017181396, -0.021942139, -0.0262146, - -0.029937744, -0.03302002, -0.035400391, -0.037017822, - -0.037841797, -0.037872314, -0.037109375, -0.035552979, - -0.033233643, -0.03024292, -0.026611328, -0.02243042, - -0.017791748, -0.012817383, -0.0075683594, - -0.0022277832, 0.0031433105, 0.0084228516, 0.013458252, - 0.018188477, 0.022491455, 0.026245117, 0.029418945, - 0.031921387, 0.033691406, 0.034729004, 0.034973145, - 0.034423828, 0.033111572, 0.031066895, 0.028320312, - 0.024932861, 0.021026611, 0.01663208, 0.011871338, - 0.0068664551, 0.0016784668, -0.0035400391, - -0.0086669922, -0.013641357, -0.018310547, -0.022613525, - -0.026428223, -0.029632568, -0.032226562, -0.03414917, - -0.035339355, -0.035766602, -0.035430908, -0.034362793, - -0.032531738, -0.030059814, -0.026947021, -0.023284912, - -0.019134521, -0.014587402, -0.009765625, -0.0047912598, - 0.00030517578, 0.0053405762, 0.010192871, 0.014831543, - 0.019104004, 0.022918701, 0.0262146, 0.028930664, - 0.030944824, 0.032318115, 0.032928467, 0.032806396, - 0.031951904, 0.030395508, 0.028137207, 0.025268555, - 0.021850586, 0.017944336, 0.013641357, 0.0090332031, - 0.0042114258, -0.0007019043, -0.0056152344, - -0.010406494, -0.014953613, -0.019195557, -0.023040771, - -0.026367188, -0.029144287, -0.031280518, -0.032775879, - -0.033538818, -0.033630371, -0.032958984, -0.031646729, - -0.029632568, -0.027008057, -0.023803711, -0.020141602, - -0.016052246, -0.011627197, -0.007019043, -0.0022583008, - 0.0025024414, 0.0072021484, 0.011688232, 0.015899658, - 0.019744873, 0.023132324, 0.025970459, 0.02822876, - 0.029846191, 0.030792236, 0.031036377, 0.030609131, - 0.02947998, 0.027679443, 0.025299072, 0.022338867, - 0.018890381, 0.015045166, 0.01083374, 0.0063781738, - 0.0018005371, -0.0028381348, -0.0073852539, - -0.011810303, -0.015991211, -0.019805908, -0.023193359, - -0.026092529, -0.028442383, -0.030181885, -0.031280518, - -0.031677246, -0.031433105, -0.030517578, -0.028961182, - -0.026794434, -0.024078369, -0.020843506, -0.017181396, - -0.013183594, -0.0089416504, -0.0045166016, - -3.0517578e-05, 0.0044555664, 0.0087890625, 0.012908936, - 0.016723633, 0.020141602, 0.023071289, 0.025512695, - 0.02734375, 0.028564453, 0.029174805, 0.02911377, - 0.028381348, 0.027038574, 0.025085449, 0.022583008, - 0.019561768, 0.016143799, 0.012329102, 0.0082702637, - 0.0040283203, -0.00033569336, -0.0046691895, - -0.0089111328, -0.012969971, -0.01675415, -0.020172119, - -0.023162842, -0.025634766, -0.027557373, -0.028930664, - -0.029663086, -0.029754639, -0.02923584, -0.028076172, - -0.02633667, -0.024047852, -0.021240234, -0.018005371, - -0.014434814, -0.010528564, -0.006439209, -0.0022583008, - 0.0019836426, 0.0061340332, 0.010101318, 0.01385498, - 0.017272949, 0.020294189, 0.022857666, 0.024871826, - 0.02633667, 0.02722168, 0.027496338, 0.027130127, - 0.026184082, 0.024658203, 0.02255249, 0.019989014, - 0.016967773, 0.013549805, 0.0098571777, 0.0059509277, - 0.0018920898, -0.0021972656, -0.0062561035, - -0.010162354, -0.01385498, -0.017272949, -0.020294189, - -0.022888184, -0.024993896, -0.026550293, -0.027557373, - -0.027954102, -0.027770996, -0.027008057, -0.025665283, - -0.023773193, -0.021392822, -0.018585205, -0.015380859, - -0.01184082, -0.0080871582, -0.0042114258, - -0.00021362305, 0.0037231445, 0.0075378418, 0.011199951, - 0.014587402, 0.01763916, 0.020263672, 0.02243042, - 0.024108887, 0.025238037, 0.025756836, 0.025756836, - 0.025146484, 0.023986816, 0.02230835, 0.020141602, - 0.017486572, 0.01449585, 0.011169434, 0.0075683594, - 0.0038146973, 0, -0.0038452148, -0.007598877, - -0.011169434, -0.014526367, -0.017578125, -0.020233154, - -0.022460938, -0.024200439, -0.025421143, -0.026123047, - -0.026245117, -0.025787354, -0.024810791, -0.02331543, - -0.021331787, -0.018890381, -0.016052246, -0.012908936, - -0.0094909668, -0.0058898926, -0.0021972656, - 0.0015258789, 0.0051879883, 0.0087280273, 0.012054443, - 0.015075684, 0.01776123, 0.020019531, 0.021850586, - 0.023193359, 0.023986816, 0.024261475, 0.023986816, - 0.023162842, 0.021850586, 0.020050049, 0.017791748, - 0.015136719, 0.012176514, 0.0089111328, 0.0054931641, - 0.0019226074, -0.0016784668, -0.0052490234, - -0.0087280273, -0.011993408, -0.014984131, -0.017700195, - -0.019989014, -0.021881104, -0.023284912, -0.024200439, - -0.024597168, -0.024475098, -0.023834229, -0.022674561, - -0.021026611, -0.018981934, -0.01651001, -0.013702393, - -0.010620117, -0.0073242188, -0.00390625, - -0.00042724609, 0.0030517578, 0.006439209, 0.0096740723, - 0.012664795, 0.015350342, 0.017700195, 0.019622803, - 0.021118164, 0.022125244, 0.022644043, 0.022674561, - 0.022155762, 0.021179199, 0.019714355, 0.017822266, - 0.015563965, 0.012908936, 0.010009766, 0.0068664551, - 0.0036010742, 0.00021362305, -0.0031433105, - -0.0064697266, -0.0096130371, -0.012573242, - -0.015258789, -0.01763916, -0.019592285, -0.021148682, - -0.022277832, -0.022888184, -0.023040771, -0.022674561, - -0.021850586, -0.020568848, -0.018829346, -0.016723633, - -0.014251709, -0.011505127, -0.0085144043, - -0.0053710938, -0.0021362305, 0.001159668, 0.0043640137, - 0.0074768066, 0.010406494, 0.013061523, 0.015441895, - 0.017456055, 0.019073486, 0.020263672, 0.020996094, - 0.021270752, 0.021057129, 0.020385742, 0.019226074, - 0.017669678, 0.01574707, 0.013427734, 0.01083374, - 0.008026123, 0.0050048828, 0.0018920898, -0.0012512207, - -0.0043945312, -0.0074462891, -0.010314941, - -0.012969971, -0.015350342, -0.01739502, -0.019073486, - -0.020324707, -0.021148682, -0.021514893, -0.02142334, - -0.020874023, -0.019897461, -0.018493652, -0.016723633, - -0.014587402, -0.012145996, -0.0094604492, - -0.0065917969, -0.0036010742, -0.00054931641, - 0.0025024414, 0.0054626465, 0.0083007812, 0.010925293, - 0.013305664, 0.015380859, 0.017089844, 0.0184021, - 0.019317627, 0.019805908, 0.019836426, 0.019439697, - 0.018585205, 0.017333984, 0.015716553, 0.01373291, - 0.011444092, 0.0089111328, 0.0061950684, 0.003326416, - 0.00039672852, -0.0025634766, -0.0054321289, - -0.0082092285, -0.010803223, -0.013183594, -0.015258789, - -0.016998291, -0.018371582, -0.019378662, -0.019958496, - -0.020080566, -0.019805908, -0.019104004, -0.018005371, - -0.01651001, -0.014709473, -0.012573242, -0.010162354, - -0.007598877, -0.0048522949, -0.0020141602, - 0.00082397461, 0.0036315918, 0.0063476562, 0.0089111328, - 0.011260986, 0.013336182, 0.015106201, 0.016571045, - 0.017608643, 0.018280029, 0.01852417, 0.018371582, - 0.017791748, 0.016845703, 0.01550293, 0.013824463, - 0.01184082, 0.0096130371, 0.0071411133, 0.0045471191, - 0.0018310547, -0.00091552734, -0.0036315918, - -0.0062866211, -0.0087890625, -0.011108398, - -0.013214111, -0.015014648, -0.016479492, -0.017578125, - -0.018341064, -0.018676758, -0.018615723, -0.018188477, - -0.017333984, -0.016143799, -0.01461792, -0.012786865, - -0.010681152, -0.0083618164, -0.005859375, - -0.0032958984, -0.00064086914, 0.0020141602, - 0.0045776367, 0.0070495605, 0.0093383789, 0.011413574, - 0.013214111, 0.01473999, 0.015899658, 0.016723633, - 0.017150879, 0.017211914, 0.016876221, 0.016174316, - 0.015106201, 0.01373291, 0.012023926, 0.010070801, - 0.0078735352, 0.0055236816, 0.0030517578, 0.00051879883, - -0.0020446777, -0.0045471191, -0.0069580078, - -0.0092163086, -0.011260986, -0.013061523, -0.014587402, - -0.015808105, -0.016693115, -0.017211914, -0.017364502, - -0.017150879, -0.016540527, -0.015625, -0.014343262, - -0.012786865, -0.010955811, -0.0089111328, - -0.0066833496, -0.0043334961, -0.0018920898, - 0.00057983398, 0.0029907227, 0.0053405762, 0.0075683594, - 0.0096130371, 0.011413574, 0.012969971, 0.014221191, - 0.015167236, 0.01574707, 0.015991211, 0.015869141, - 0.015411377, 0.014587402, 0.013458252, 0.012023926, - 0.010345459, 0.0084228516, 0.0063171387, 0.0040588379, - 0.001739502, -0.00061035156, -0.0029602051, - -0.0052490234, -0.0074157715, -0.0094299316, - -0.011230469, -0.012786865, -0.014068604, -0.015045166, - -0.015716553, -0.016021729, -0.015991211, -0.015655518, - -0.014953613, -0.013946533, -0.012634277, -0.011077881, - -0.0092773438, -0.0072937012, -0.0051574707, - -0.0029602051, -0.00067138672, 0.0015869141, - 0.0038146973, 0.0059204102, 0.0079040527, 0.0097045898, - 0.011260986, 0.012573242, 0.01361084, 0.014312744, - 0.014709473, 0.014770508, 0.01449585, 0.013916016, - 0.013031006, 0.01184082, 0.010406494, 0.0087585449, - 0.0068969727, 0.0048828125, 0.0027770996, 0.00061035156, - -0.0015869141, -0.0037231445, -0.0057983398, - -0.0077514648, -0.0094909668, -0.011077881, - -0.012390137, -0.013427734, -0.014221191, -0.014678955, - -0.014801025, -0.014648438, -0.014160156, -0.013366699, - -0.012329102, -0.010986328, -0.0094604492, - -0.0077209473, -0.0058288574, -0.0038146973, - -0.001739502, 0.00036621094, 0.0024414062, 0.0044250488, - 0.0063476562, 0.0080871582, 0.0096435547, 0.010986328, - 0.012054443, 0.0128479, 0.013397217, 0.01361084, - 0.013519287, 0.013153076, 0.012481689, 0.011505127, - 0.010314941, 0.0088806152, 0.0072631836, 0.0054931641, - 0.0036010742, 0.0016174316, -0.00039672852, - -0.0023803711, -0.0043334961, -0.0061645508, - -0.0079040527, -0.0094299316, -0.010772705, - -0.011871338, -0.01272583, -0.013275146, -0.013580322, - -0.013580322, -0.013275146, -0.012695312, -0.011871338, - -0.010772705, -0.0094604492, -0.0079650879, - -0.0062866211, -0.004486084, -0.0026245117, - -0.0007019043, 0.0012207031, 0.003112793, 0.0049133301, - 0.0065917969, 0.0080871582, 0.0094299316, 0.010559082, - 0.011413574, 0.012054443, 0.012390137, 0.012451172, - 0.012268066, 0.011779785, 0.011047363, 0.010070801, - 0.0088500977, 0.0074768066, 0.0059204102, 0.0042114258, - 0.0024414062, 0.00061035156, -0.0012207031, - -0.0030212402, -0.0047607422, -0.0064086914, - -0.0079040527, -0.0092163086, -0.010345459, - -0.011260986, -0.011901855, -0.012298584, -0.012451172, - -0.012298584, -0.011901855, -0.011260986, -0.010406494, - -0.0093078613, -0.008026123, -0.0065612793, - -0.0049743652, -0.0032958984, -0.0015563965, - 0.00018310547, 0.0019226074, 0.0036010742, 0.0052185059, - 0.0066833496, 0.0079956055, 0.0091247559, 0.010040283, - 0.01071167, 0.011169434, 0.011352539, 0.011322021, - 0.010986328, 0.010437012, 0.0096740723, 0.0086669922, - 0.0075073242, 0.0061645508, 0.0046691895, 0.003112793, - 0.0014648438, -0.00021362305, -0.0018920898, - -0.0035095215, -0.0050354004, -0.0064697266, - -0.0077514648, -0.0088806152, -0.0098266602, - -0.010528564, -0.011016846, -0.011260986, -0.011260986, - -0.011047363, -0.0105896, -0.0098876953, -0.0090026855, - -0.0079040527, -0.0066833496, -0.005279541, - -0.0038146973, -0.0022583008, -0.00067138672, - 0.00091552734, 0.0024719238, 0.0039672852, 0.0053710938, - 0.0066223145, 0.0077514648, 0.0086669922, 0.0093994141, - 0.0099182129, 0.010223389, 0.010314941, 0.010131836, - 0.009765625, 0.0091552734, 0.0083618164, 0.0073852539, - 0.0062255859, 0.0049438477, 0.0035705566, 0.0021057129, - 0.00061035156, -0.00088500977, -0.0023803711, - -0.0038146973, -0.0051574707, -0.0064086914, - -0.0075073242, -0.0084228516, -0.009185791, - -0.0097351074, -0.010070801, -0.010192871, -0.010101318, - -0.0097961426, -0.0092773438, -0.0085449219, - -0.0076599121, -0.0066223145, -0.0054321289, - -0.0041503906, -0.0027770996, -0.001373291, - 6.1035156e-05, 0.0014953613, 0.0028686523, 0.0041809082, - 0.0053710938, 0.006439209, 0.0073852539, 0.0081481934, - 0.0086975098, 0.0090942383, 0.0092468262, 0.0092163086, - 0.008972168, 0.0085449219, 0.0079040527, 0.0071105957, - 0.0061645508, 0.005065918, 0.0038757324, 0.0025939941, - 0.0012817383, -9.1552734e-05, -0.0014343262, - -0.002746582, -0.0039978027, -0.0051574707, - -0.0062255859, -0.0071105957, -0.0078735352, - -0.0084533691, -0.0088806152, -0.0090637207, - -0.0090942383, -0.0089111328, -0.0085449219, - -0.0079956055, -0.0072937012, -0.006439209, - -0.0054321289, -0.0043334961, -0.0031433105, - -0.0018920898, -0.00061035156, 0.00067138672, - 0.0019226074, 0.003112793, 0.0042419434, 0.0052490234, - 0.0061645508, 0.0069274902, 0.0075073242, 0.0079345703, - 0.0081787109, 0.0082397461, 0.0081176758, 0.0078125, - 0.0073547363, 0.0067138672, 0.0059509277, 0.0050354004, - 0.0040283203, 0.0029296875, 0.0017700195, 0.00057983398, - -0.00064086914, -0.0018310547, -0.0029602051, - -0.0040283203, -0.0050354004, -0.0058898926, - -0.006652832, -0.007232666, -0.0076904297, - -0.0079650879, -0.0080566406, -0.0079956055, - -0.0077514648, -0.0073547363, -0.0068054199, - -0.0061035156, -0.005279541, -0.0043334961, - -0.003326416, -0.0022583008, -0.0011291504, 0, - 0.0010986328, 0.0021972656, 0.0032348633, 0.0041809082, - 0.0050354004, 0.0057678223, 0.0063476562, 0.0068054199, - 0.0071105957, 0.007232666, 0.007232666, 0.0070495605, - 0.0067138672, 0.0062255859, 0.0056152344, 0.0048522949, - 0.0040283203, 0.0030822754, 0.0021057129, 0.0010681152, - 0, -0.0010375977, -0.0020751953, -0.0030517578, - -0.0039367676, -0.0047607422, -0.0054626465, - -0.006072998, -0.0065307617, -0.0068359375, - -0.007019043, -0.007019043, -0.0068969727, - -0.0066223145, -0.0061950684, -0.005645752, - -0.0049743652, -0.0042114258, -0.0033874512, - -0.0024719238, -0.0014953613, -0.00051879883, - 0.00045776367, 0.0014038086, 0.0023193359, 0.0032043457, - 0.0039672852, 0.0046691895, 0.0052490234, 0.0057067871, - 0.0060424805, 0.0062255859, 0.0062866211, 0.0061950684, - 0.0059814453, 0.0056152344, 0.0051269531, 0.0045471191, - 0.0038757324, 0.003112793, 0.0022888184, 0.0014038086, - 0.00048828125, -0.00042724609, -0.0013122559, - -0.002166748, -0.0029907227, -0.0037231445, - -0.0043945312, -0.0049438477, -0.0054016113, - -0.0057373047, -0.0059509277, -0.0060424805, - -0.0059814453, -0.0057983398, -0.0054931641, - -0.0050964355, -0.0045776367, -0.0039672852, - -0.0032653809, -0.002532959, -0.001739502, - -0.00088500977, -6.1035156e-05, 0.00076293945, - 0.0015869141, 0.0023498535, 0.0030517578, 0.0036621094, - 0.0042114258, 0.0046386719, 0.0050048828, 0.0052185059, - 0.0053100586, 0.0053100586, 0.0051879883, 0.0049133301, - 0.0045776367, 0.004119873, 0.0036010742, 0.0029602051, - 0.0022888184, 0.0015869141, 0.00082397461, - 6.1035156e-05, -0.0007019043, -0.0014343262, - -0.002166748, -0.0028076172, -0.0033874512, -0.00390625, - -0.0043334961, -0.0046691895, -0.0049133301, - -0.0050354004, -0.0050354004, -0.0049438477, - -0.0047302246, -0.0044555664, -0.0040588379, - -0.0035705566, -0.0030517578, -0.0024414062, - -0.0018005371, -0.0010986328, -0.00042724609, - 0.0002746582, 0.00094604492, 0.0016174316, 0.0022277832, - 0.0027770996, 0.0032653809, 0.0036621094, 0.0039978027, - 0.0042114258, 0.0043334961, 0.0043945312, 0.0043334961, - 0.0041809082, 0.0039367676, 0.0036010742, 0.0031738281, - 0.0027160645, 0.002166748, 0.0016174316, 0.0010070801, - 0.00039672852, -0.00024414062, -0.00085449219, - -0.0014343262, -0.0020141602, -0.0025024414, - -0.0029602051, -0.0033569336, -0.0036621094, - -0.0038757324, -0.0040283203, -0.0040588379, - -0.0040283203, -0.00390625, -0.0037231445, - -0.0034484863, -0.0030822754, -0.0026855469, - -0.0022277832, -0.0017089844, -0.0011901855, - -0.00064086914, -6.1035156e-05, 0.00048828125, - 0.0010070801, 0.0014953613, 0.0019836426, 0.0023803711, - 0.002746582, 0.0030212402, 0.0032348633, 0.0033874512, - 0.0034484863, 0.0034484863, 0.0033569336, 0.0032043457, - 0.0029602051, 0.0026855469, 0.0023193359, 0.0019226074, - 0.0014953613, 0.0010375977, 0.00054931641, - 6.1035156e-05, -0.00039672852, -0.00088500977, - -0.0013122559, -0.001739502, -0.0021057129, - -0.0024108887, -0.0026855469, -0.0028991699, - -0.0030212402, -0.003112793, -0.003112793, - -0.0030517578, -0.0029296875, -0.0027160645, - -0.0025024414, -0.0021972656, -0.0018615723, - -0.0014953613, -0.0010986328, -0.0007019043, - -0.0002746582, 0.00015258789, 0.00054931641, - 0.00094604492, 0.0012817383, 0.0016174316, 0.0018920898, - 0.0021362305, 0.0023193359, 0.0024414062, 0.002532959, - 0.002532959, 0.0025024414, 0.0024108887, 0.0022583008, - 0.0020751953, 0.0018310547, 0.0015563965, 0.0012512207, - 0.00091552734, 0.00057983398, 0.00024414062, - -0.00012207031, -0.00045776367, -0.00076293945, - -0.0010681152, -0.0013427734, -0.0015869141, - -0.0018005371, -0.001953125, -0.0020751953, - -0.0021362305, -0.002166748, -0.0021362305, - -0.0020751953, -0.001953125, -0.0018005371, - -0.0016174316, -0.0014038086, -0.001159668, - -0.00088500977, -0.00061035156, -0.00033569336, - -6.1035156e-05, 0.00021362305, 0.00048828125, - 0.00073242188, 0.00094604492, 0.001159668, 0.0013122559, - 0.0014648438, 0.0015563965, 0.0016174316, 0.0016479492, - 0.0016174316, 0.0015563965, 0.0014953613, 0.001373291, - 0.0012207031, 0.0010681152, 0.00088500977, - 0.00067138672, 0.00045776367, 0.0002746582, - 6.1035156e-05, -0.00015258789, -0.00036621094, - -0.00054931641, -0.0007019043, -0.00085449219, - -0.0009765625, -0.0010986328, -0.001159668, - -0.0012207031, -0.0012207031, -0.0012207031, - -0.0011901855, -0.0011291504, -0.0010375977, - -0.00094604492, -0.00082397461, -0.00067138672, - -0.00054931641, -0.00039672852, -0.00024414062, - -9.1552734e-05, 3.0517578e-05, 0.00018310547, - 0.00030517578, 0.00042724609, 0.00051879883, - 0.00057983398, 0.00064086914, 0.0007019043, - 0.00073242188, 0.00073242188, 0.00073242188, - 0.0007019043, 0.00067138672, 0.00061035156, - 0.00054931641, 0.00045776367, 0.00039672852, - 0.00030517578, 0.00021362305, 0.00015258789, - 6.1035156e-05, -3.0517578e-05, -9.1552734e-05, - -0.00015258789, -0.00021362305, -0.00024414062, - -0.0002746582, -0.00030517578, -0.00030517578, - -0.00030517578, -0.00030517578, -0.0002746582, - -0.0002746582, -0.00024414062, -0.00021362305, - -0.00018310547, -0.00015258789, -9.1552734e-05, - -9.1552734e-05, -6.1035156e-05, -3.0517578e-05, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; - -const nframes_t Session::default_click_length = sizeof (default_click) / sizeof (default_click[0]); diff --git a/libs/ardour/directory_names.cc b/libs/ardour/directory_names.cc deleted file mode 100644 index 2b6dfcbb39..0000000000 --- a/libs/ardour/directory_names.cc +++ /dev/null @@ -1,19 +0,0 @@ -#include <ardour/directory_names.h> - -#include "i18n.h" - -namespace ARDOUR { - -const char* const old_sound_dir_name = X_("sounds"); -const char* const sound_dir_name = X_("audiofiles"); -const char* const midi_dir_name = X_("midifiles"); -const char* const peak_dir_name = X_("peaks"); -const char* const dead_sound_dir_name = X_("dead_sounds"); -const char* const dead_midi_dir_name = X_("dead_midi"); -const char* const interchange_dir_name = X_("interchange"); -const char* const export_dir_name = X_("export"); -const char* const templates_dir_name = X_("templates"); -const char* const surfaces_dir_name = X_("surfaces"); -const char* const user_config_dir_name = X_(".ardour3"); - -} diff --git a/libs/ardour/diskstream.cc b/libs/ardour/diskstream.cc deleted file mode 100644 index 9665176a67..0000000000 --- a/libs/ardour/diskstream.cc +++ /dev/null @@ -1,411 +0,0 @@ -/* - 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. - -*/ - -#include <fstream> -#include <cassert> -#include <cstdio> -#include <unistd.h> -#include <cmath> -#include <cerrno> -#include <string> -#include <climits> -#include <fcntl.h> -#include <cstdlib> -#include <ctime> -#include <sys/stat.h> -#include <sys/mman.h> - -#include <sigc++/bind.h> - -#include <pbd/error.h> -#include <pbd/basename.h> -#include <glibmm/thread.h> -#include <pbd/xml++.h> - -#include <ardour/ardour.h> -#include <ardour/audioengine.h> -#include <ardour/diskstream.h> -#include <ardour/utils.h> -#include <ardour/configuration.h> -#include <ardour/audiofilesource.h> -#include <ardour/send.h> -#include <ardour/playlist.h> -#include <ardour/cycle_timer.h> -#include <ardour/region.h> - -#include "i18n.h" -#include <locale.h> - -using namespace std; -using namespace ARDOUR; -using namespace PBD; - -/* XXX This goes uninitialized when there is no ~/.ardour3 directory. - * I can't figure out why, so this will do for now (just stole the - * default from configuration_vars.h). 0 is not a good value for - * allocating buffer sizes.. - */ -ARDOUR::nframes_t Diskstream::disk_io_chunk_frames = 1024 * 256; - -sigc::signal<void> Diskstream::DiskOverrun; -sigc::signal<void> Diskstream::DiskUnderrun; - -Diskstream::Diskstream (Session &sess, const string &name, Flag flag) - : SessionObject(sess, name) -{ - init (flag); -} - -Diskstream::Diskstream (Session& sess, const XMLNode& node) - : SessionObject(sess, "unnamed diskstream") -{ - init (Recordable); -} - -void -Diskstream::init (Flag f) -{ - _flags = f; - _io = 0; - _alignment_style = ExistingMaterial; - _persistent_alignment_style = ExistingMaterial; - first_input_change = true; - i_am_the_modifier = 0; - g_atomic_int_set (&_record_enabled, 0); - was_recording = false; - capture_start_frame = 0; - capture_captured = 0; - _visible_speed = 1.0f; - _actual_speed = 1.0f; - _buffer_reallocation_required = false; - _seek_required = false; - first_recordable_frame = max_frames; - last_recordable_frame = max_frames; - _roll_delay = 0; - _capture_offset = 0; - _processed = false; - _slaved = false; - adjust_capture_position = 0; - last_possibly_recording = 0; - loop_location = 0; - wrap_buffer_size = 0; - speed_buffer_size = 0; - last_phase = 0; - phi = (uint64_t) (0x1000000); - target_phi = phi; - file_frame = 0; - playback_sample = 0; - playback_distance = 0; - _read_data_count = 0; - _write_data_count = 0; - commit_should_unlock = false; - - pending_overwrite = false; - overwrite_frame = 0; - overwrite_queued = false; - input_change_pending = NoChange; -} - -Diskstream::~Diskstream () -{ - if (_playlist) - _playlist->release (); -} - -void -Diskstream::set_io (IO& io) -{ - _io = &io; - set_align_style_from_io (); -} - -void -Diskstream::handle_input_change (IOChange change, void *src) -{ - Glib::Mutex::Lock lm (state_lock); - - if (!(input_change_pending & change)) { - input_change_pending = IOChange (input_change_pending|change); - _session.request_input_change_handling (); - } -} - -void -Diskstream::non_realtime_set_speed () -{ - if (_buffer_reallocation_required) - { - Glib::Mutex::Lock lm (state_lock); - allocate_temporary_buffers (); - - _buffer_reallocation_required = false; - } - - if (_seek_required) { - if (speed() != 1.0f || speed() != -1.0f) { - seek ((nframes_t) (_session.transport_frame() * (double) speed()), true); - } - else { - seek (_session.transport_frame(), true); - } - - _seek_required = false; - } -} - -bool -Diskstream::realtime_set_speed (double sp, bool global) -{ - bool changed = false; - double new_speed = sp * _session.transport_speed(); - - if (_visible_speed != sp) { - _visible_speed = sp; - changed = true; - } - - if (new_speed != _actual_speed) { - - nframes_t required_wrap_size = (nframes_t) floor (_session.get_block_size() * - fabs (new_speed)) + 1; - - if (required_wrap_size > wrap_buffer_size) { - _buffer_reallocation_required = true; - } - - _actual_speed = new_speed; - target_phi = (uint64_t) (0x1000000 * fabs(_actual_speed)); - } - - if (changed) { - if (!global) { - _seek_required = true; - } - SpeedChanged (); /* EMIT SIGNAL */ - } - - return _buffer_reallocation_required || _seek_required; -} - -void -Diskstream::prepare () -{ - _processed = false; - playback_distance = 0; -} - -void -Diskstream::recover () -{ - if (commit_should_unlock) { - state_lock.unlock(); - } - _processed = false; -} - -void -Diskstream::set_capture_offset () -{ - if (_io == 0) { - /* can't capture, so forget it */ - return; - } - - _capture_offset = _io->input_latency(); -} - -void -Diskstream::set_align_style (AlignStyle a) -{ - if (record_enabled() && _session.actively_recording()) { - return; - } - - if (a != _alignment_style) { - _alignment_style = a; - AlignmentStyleChanged (); - } -} - -int -Diskstream::set_loop (Location *location) -{ - if (location) { - if (location->start() >= location->end()) { - error << string_compose(_("Location \"%1\" not valid for track loop (start >= end)"), location->name()) << endl; - return -1; - } - } - - loop_location = location; - - LoopSet (location); /* EMIT SIGNAL */ - return 0; -} - -ARDOUR::nframes_t -Diskstream::get_capture_start_frame (uint32_t n) -{ - Glib::Mutex::Lock lm (capture_info_lock); - - if (capture_info.size() > n) { - return capture_info[n]->start; - } - else { - return capture_start_frame; - } -} - -ARDOUR::nframes_t -Diskstream::get_captured_frames (uint32_t n) -{ - Glib::Mutex::Lock lm (capture_info_lock); - - if (capture_info.size() > n) { - return capture_info[n]->frames; - } - else { - return capture_captured; - } -} - -void -Diskstream::set_roll_delay (ARDOUR::nframes_t nframes) -{ - _roll_delay = nframes; -} - -void -Diskstream::set_speed (double sp) -{ - _session.request_diskstream_speed (*this, sp); - - /* to force a rebuffering at the right place */ - playlist_modified(); -} - -int -Diskstream::use_playlist (boost::shared_ptr<Playlist> playlist) -{ - { - Glib::Mutex::Lock lm (state_lock); - - if (playlist == _playlist) { - return 0; - } - - plmod_connection.disconnect (); - plgone_connection.disconnect (); - - if (_playlist) { - _playlist->release(); - } - - _playlist = playlist; - _playlist->use(); - - if (!in_set_state && recordable()) { - reset_write_sources (false); - } - - plmod_connection = _playlist->Modified.connect (mem_fun (*this, &Diskstream::playlist_modified)); - plgone_connection = _playlist->GoingAway.connect (bind (mem_fun (*this, &Diskstream::playlist_deleted), boost::weak_ptr<Playlist>(_playlist))); - } - - /* don't do this if we've already asked for it *or* if we are setting up - the diskstream for the very first time - the input changed handling will - take care of the buffer refill. - */ - - if (!overwrite_queued && !(_session.state_of_the_state() & Session::CannotSave)) { - _session.request_overwrite_buffer (this); - overwrite_queued = true; - } - - PlaylistChanged (); /* EMIT SIGNAL */ - _session.set_dirty (); - - return 0; -} - -void -Diskstream::playlist_changed (Change ignored) -{ - playlist_modified (); -} - -void -Diskstream::playlist_modified () -{ - if (!i_am_the_modifier && !overwrite_queued) { - _session.request_overwrite_buffer (this); - overwrite_queued = true; - } -} - -void -Diskstream::playlist_deleted (boost::weak_ptr<Playlist> wpl) -{ - boost::shared_ptr<Playlist> pl (wpl.lock()); - - if (pl == _playlist) { - - /* this catches an ordering issue with session destruction. playlists - are destroyed before diskstreams. we have to invalidate any handles - we have to the playlist. - */ - - if (_playlist) { - _playlist.reset (); - } - } -} - -bool -Diskstream::set_name (const string& str) -{ - if (str != _name) { - assert(playlist()); - playlist()->set_name (str); - - SessionObject::set_name(str); - - if (!in_set_state && recordable()) { - /* rename existing capture files so that they have the correct name */ - return rename_write_sources (); - } else { - return false; - } - } - - return true; -} - -void -Diskstream::remove_region_from_last_capture (boost::weak_ptr<Region> wregion) -{ - boost::shared_ptr<Region> region (wregion.lock()); - - if (!region) { - return; - } - - _last_capture_regions.remove (region); -} - diff --git a/libs/ardour/enums.cc b/libs/ardour/enums.cc deleted file mode 100644 index 71b699396b..0000000000 --- a/libs/ardour/enums.cc +++ /dev/null @@ -1,388 +0,0 @@ -/* - 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. - -*/ - -#include <pbd/enumwriter.h> - -#include <ardour/types.h> -#include <ardour/session.h> -#include <ardour/location.h> -#include <ardour/audiofilesource.h> -#include <ardour/diskstream.h> -#include <ardour/audioregion.h> -#include <ardour/route_group.h> -#include <ardour/panner.h> -#include <ardour/track.h> -#include <ardour/midi_track.h> - -using namespace std; -using namespace PBD; -using namespace ARDOUR; - -void -setup_enum_writer () -{ - EnumWriter* enum_writer = new EnumWriter(); - vector<int> i; - vector<string> s; - - OverlapType _OverlapType; - AlignStyle _AlignStyle; - MeterPoint _MeterPoint; - TrackMode _TrackMode; - NoteMode _NoteMode; - ChannelMode _ChannelMode; - MeterFalloff _MeterFalloff; - MeterHold _MeterHold; - EditMode _EditMode; - RegionPoint _RegionPoint; - Placement _Placement; - MonitorModel _MonitorModel; - RemoteModel _RemoteModel; - DenormalModel _DenormalModel; - CrossfadeModel _CrossfadeModel; - LayerModel _LayerModel; - SoloModel _SoloModel; - SampleFormat _SampleFormat; - HeaderFormat _HeaderFormat; - PluginType _PluginType; - SlaveSource _SlaveSource; - ShuttleBehaviour _ShuttleBehaviour; - ShuttleUnits _ShuttleUnits; - mute_type _mute_type; - Session::RecordState _Session_RecordState; - Session::Event::Type _Session_Event_Type; - SmpteFormat _Session_SmpteFormat; - Session::PullupFormat _Session_PullupFormat; - AudioRegion::FadeShape _AudioRegion_FadeShape; - Panner::LinkDirection _Panner_LinkDirection; - IOChange _IOChange; - AutomationType _AutomationType; - AutoState _AutoState; - AutoStyle _AutoStyle; - AutoConnectOption _AutoConnectOption; - Session::StateOfTheState _Session_StateOfTheState; - Route::Flag _Route_Flag; - AudioFileSource::Flag _AudioFileSource_Flag; - Diskstream::Flag _Diskstream_Flag; - Location::Flags _Location_Flags; - RouteGroup::Flag _RouteGroup_Flag; - Region::Flag _Region_Flag; - Region::PositionLockStyle _Region_PositionLockStyle; - Track::FreezeState _Track_FreezeState; - AutomationList::InterpolationStyle _AutomationList_InterpolationStyle; - -#define REGISTER(e) enum_writer->register_distinct (typeid(e).name(), i, s); i.clear(); s.clear() -#define REGISTER_BITS(e) enum_writer->register_bits (typeid(e).name(), i, s); i.clear(); s.clear() -#define REGISTER_ENUM(e) i.push_back (e); s.push_back (#e) -#define REGISTER_CLASS_ENUM(t,e) i.push_back (t::e); s.push_back (#e) - - REGISTER_ENUM (NoChange); - REGISTER_ENUM (ConfigurationChanged); - REGISTER_ENUM (ConnectionsChanged); - REGISTER_BITS (_IOChange); - - REGISTER_ENUM (OverlapNone); - REGISTER_ENUM (OverlapInternal); - REGISTER_ENUM (OverlapStart); - REGISTER_ENUM (OverlapEnd); - REGISTER_ENUM (OverlapExternal); - REGISTER (_OverlapType); - - REGISTER_ENUM (GainAutomation); - REGISTER_ENUM (PanAutomation); - REGISTER_ENUM (PluginAutomation); - REGISTER_ENUM (SoloAutomation); - REGISTER_ENUM (MuteAutomation); - REGISTER_ENUM (MidiCCAutomation); - REGISTER_ENUM (FadeInAutomation); - REGISTER_ENUM (FadeOutAutomation); - REGISTER_ENUM (EnvelopeAutomation); - REGISTER_BITS (_AutomationType); - - REGISTER_ENUM (Off); - REGISTER_ENUM (Write); - REGISTER_ENUM (Touch); - REGISTER_ENUM (Play); - REGISTER_BITS (_AutoState); - - REGISTER_ENUM (Absolute); - REGISTER_ENUM (Trim); - REGISTER_BITS (_AutoStyle); - - REGISTER_ENUM (CaptureTime); - REGISTER_ENUM (ExistingMaterial); - REGISTER (_AlignStyle); - - REGISTER_ENUM (MeterInput); - REGISTER_ENUM (MeterPreFader); - REGISTER_ENUM (MeterPostFader); - REGISTER (_MeterPoint); - - REGISTER_ENUM (Normal); - REGISTER_ENUM (Destructive); - REGISTER (_TrackMode); - - REGISTER_ENUM (Sustained); - REGISTER_ENUM (Percussive); - REGISTER (_NoteMode); - - REGISTER_ENUM (AllChannels); - REGISTER_ENUM (FilterChannels); - REGISTER_ENUM (ForceChannel); - REGISTER (_ChannelMode); - - REGISTER_ENUM (MeterFalloffOff); - REGISTER_ENUM (MeterFalloffSlowest); - REGISTER_ENUM (MeterFalloffSlow); - REGISTER_ENUM (MeterFalloffMedium); - REGISTER_ENUM (MeterFalloffFast); - REGISTER_ENUM (MeterFalloffFaster); - REGISTER_ENUM (MeterFalloffFastest); - REGISTER (_MeterFalloff); - - REGISTER_ENUM (MeterHoldOff); - REGISTER_ENUM (MeterHoldShort); - REGISTER_ENUM (MeterHoldMedium); - REGISTER_ENUM (MeterHoldLong); - REGISTER (_MeterHold); - - REGISTER_ENUM (Slide); - REGISTER_ENUM (Splice); - REGISTER (_EditMode); - - REGISTER_ENUM (Start); - REGISTER_ENUM (End); - REGISTER_ENUM (SyncPoint); - REGISTER (_RegionPoint); - - REGISTER_ENUM (PreFader); - REGISTER_ENUM (PostFader); - REGISTER (_Placement); - - REGISTER_ENUM (HardwareMonitoring); - REGISTER_ENUM (SoftwareMonitoring); - REGISTER_ENUM (ExternalMonitoring); - REGISTER (_MonitorModel); - - REGISTER_ENUM (DenormalNone); - REGISTER_ENUM (DenormalFTZ); - REGISTER_ENUM (DenormalDAZ); - REGISTER_ENUM (DenormalFTZDAZ); - REGISTER (_DenormalModel); - - REGISTER_ENUM (UserOrdered); - REGISTER_ENUM (MixerOrdered); - REGISTER_ENUM (EditorOrdered); - REGISTER (_RemoteModel); - - REGISTER_ENUM (FullCrossfade); - REGISTER_ENUM (ShortCrossfade); - REGISTER (_CrossfadeModel); - - REGISTER_ENUM (LaterHigher); - REGISTER_ENUM (MoveAddHigher); - REGISTER_ENUM (AddHigher); - REGISTER (_LayerModel); - - REGISTER_ENUM (InverseMute); - REGISTER_ENUM (SoloBus); - REGISTER (_SoloModel); - - REGISTER_ENUM (AutoConnectPhysical); - REGISTER_ENUM (AutoConnectMaster); - REGISTER_BITS (_AutoConnectOption); - - REGISTER_ENUM (FormatFloat); - REGISTER_ENUM (FormatInt24); - REGISTER_ENUM (FormatInt16); - REGISTER (_SampleFormat); - - REGISTER_ENUM (BWF); - REGISTER_ENUM (WAVE); - REGISTER_ENUM (WAVE64); - REGISTER_ENUM (CAF); - REGISTER_ENUM (AIFF); - REGISTER_ENUM (iXML); - REGISTER_ENUM (RF64); - REGISTER (_HeaderFormat); - - REGISTER_ENUM (AudioUnit); - REGISTER_ENUM (LADSPA); - REGISTER_ENUM (VST); - REGISTER (_PluginType); - - REGISTER_ENUM (None); - REGISTER_ENUM (MTC); - REGISTER_ENUM (JACK); - REGISTER (_SlaveSource); - - REGISTER_ENUM (Sprung); - REGISTER_ENUM (Wheel); - REGISTER (_ShuttleBehaviour); - - REGISTER_ENUM (Percentage); - REGISTER_ENUM (Semitones); - REGISTER (_ShuttleUnits); - - REGISTER_CLASS_ENUM (Session, Disabled); - REGISTER_CLASS_ENUM (Session, Enabled); - REGISTER_CLASS_ENUM (Session, Recording); - REGISTER (_Session_RecordState); - - REGISTER_CLASS_ENUM (Session::Event, SetTransportSpeed); - REGISTER_CLASS_ENUM (Session::Event, SetDiskstreamSpeed); - REGISTER_CLASS_ENUM (Session::Event, Locate); - REGISTER_CLASS_ENUM (Session::Event, LocateRoll); - REGISTER_CLASS_ENUM (Session::Event, LocateRollLocate); - REGISTER_CLASS_ENUM (Session::Event, SetLoop); - REGISTER_CLASS_ENUM (Session::Event, PunchIn); - REGISTER_CLASS_ENUM (Session::Event, PunchOut); - REGISTER_CLASS_ENUM (Session::Event, RangeStop); - REGISTER_CLASS_ENUM (Session::Event, RangeLocate); - REGISTER_CLASS_ENUM (Session::Event, Overwrite); - REGISTER_CLASS_ENUM (Session::Event, SetSlaveSource); - REGISTER_CLASS_ENUM (Session::Event, Audition); - REGISTER_CLASS_ENUM (Session::Event, InputConfigurationChange); - REGISTER_CLASS_ENUM (Session::Event, SetAudioRange); - REGISTER_CLASS_ENUM (Session::Event, SetPlayRange); - REGISTER_CLASS_ENUM (Session::Event, StopOnce); - REGISTER_CLASS_ENUM (Session::Event, AutoLoop); - REGISTER (_Session_Event_Type); - - REGISTER_CLASS_ENUM (Session, Clean); - REGISTER_CLASS_ENUM (Session, Dirty); - REGISTER_CLASS_ENUM (Session, CannotSave); - REGISTER_CLASS_ENUM (Session, Deletion); - REGISTER_CLASS_ENUM (Session, InitialConnecting); - REGISTER_CLASS_ENUM (Session, Loading); - REGISTER_CLASS_ENUM (Session, InCleanup); - REGISTER_BITS (_Session_StateOfTheState); - - REGISTER_ENUM (smpte_23976); - REGISTER_ENUM (smpte_24); - REGISTER_ENUM (smpte_24976); - REGISTER_ENUM (smpte_25); - REGISTER_ENUM (smpte_2997); - REGISTER_ENUM (smpte_2997drop); - REGISTER_ENUM (smpte_30); - REGISTER_ENUM (smpte_30drop); - REGISTER_ENUM (smpte_5994); - REGISTER_ENUM (smpte_60); - REGISTER (_Session_SmpteFormat); - - REGISTER_CLASS_ENUM (Session, pullup_Plus4Plus1); - REGISTER_CLASS_ENUM (Session, pullup_Plus4); - REGISTER_CLASS_ENUM (Session, pullup_Plus4Minus1); - REGISTER_CLASS_ENUM (Session, pullup_Plus1); - REGISTER_CLASS_ENUM (Session, pullup_None); - REGISTER_CLASS_ENUM (Session, pullup_Minus1); - REGISTER_CLASS_ENUM (Session, pullup_Minus4Plus1); - REGISTER_CLASS_ENUM (Session, pullup_Minus4); - REGISTER_CLASS_ENUM (Session, pullup_Minus4Minus1); - REGISTER (_Session_PullupFormat); - - REGISTER_ENUM (PRE_FADER); - REGISTER_ENUM (POST_FADER); - REGISTER_ENUM (CONTROL_OUTS); - REGISTER_ENUM (MAIN_OUTS); - REGISTER (_mute_type); - - REGISTER_CLASS_ENUM (Route, Hidden); - REGISTER_CLASS_ENUM (Route, MasterOut); - REGISTER_CLASS_ENUM (Route, ControlOut); - REGISTER_BITS (_Route_Flag); - - REGISTER_CLASS_ENUM (AudioFileSource, Writable); - REGISTER_CLASS_ENUM (AudioFileSource, CanRename); - REGISTER_CLASS_ENUM (AudioFileSource, Broadcast); - REGISTER_CLASS_ENUM (AudioFileSource, Removable); - REGISTER_CLASS_ENUM (AudioFileSource, RemovableIfEmpty); - REGISTER_CLASS_ENUM (AudioFileSource, RemoveAtDestroy); - REGISTER_CLASS_ENUM (AudioFileSource, NoPeakFile); - REGISTER_CLASS_ENUM (AudioFileSource, Destructive); - REGISTER_BITS (_AudioFileSource_Flag); - - REGISTER_CLASS_ENUM (AudioRegion, Linear); - REGISTER_CLASS_ENUM (AudioRegion, Fast); - REGISTER_CLASS_ENUM (AudioRegion, Slow); - REGISTER_CLASS_ENUM (AudioRegion, LogA); - REGISTER_CLASS_ENUM (AudioRegion, LogB); - REGISTER (_AudioRegion_FadeShape); - - REGISTER_CLASS_ENUM (Diskstream, Recordable); - REGISTER_CLASS_ENUM (Diskstream, Hidden); - REGISTER_CLASS_ENUM (Diskstream, Destructive); - REGISTER_BITS (_Diskstream_Flag); - - REGISTER_CLASS_ENUM (Location, IsMark); - REGISTER_CLASS_ENUM (Location, IsAutoPunch); - REGISTER_CLASS_ENUM (Location, IsAutoLoop); - REGISTER_CLASS_ENUM (Location, IsHidden); - REGISTER_CLASS_ENUM (Location, IsCDMarker); - REGISTER_CLASS_ENUM (Location, IsEnd); - REGISTER_CLASS_ENUM (Location, IsRangeMarker); - REGISTER_CLASS_ENUM (Location, IsStart); - REGISTER_BITS (_Location_Flags); - - - REGISTER_CLASS_ENUM (RouteGroup, Relative); - REGISTER_CLASS_ENUM (RouteGroup, Active); - REGISTER_CLASS_ENUM (RouteGroup, Hidden); - REGISTER_BITS (_RouteGroup_Flag); - - REGISTER_CLASS_ENUM (Panner, SameDirection); - REGISTER_CLASS_ENUM (Panner, OppositeDirection); - REGISTER (_Panner_LinkDirection); - - REGISTER_CLASS_ENUM (Region, Muted); - REGISTER_CLASS_ENUM (Region, Opaque); - REGISTER_CLASS_ENUM (Region, EnvelopeActive); - REGISTER_CLASS_ENUM (Region, DefaultFadeIn); - REGISTER_CLASS_ENUM (Region, DefaultFadeOut); - REGISTER_CLASS_ENUM (Region, Locked); - REGISTER_CLASS_ENUM (Region, PositionLocked); - REGISTER_CLASS_ENUM (Region, Automatic); - REGISTER_CLASS_ENUM (Region, WholeFile); - REGISTER_CLASS_ENUM (Region, FadeIn); - REGISTER_CLASS_ENUM (Region, FadeOut); - REGISTER_CLASS_ENUM (Region, Copied); - REGISTER_CLASS_ENUM (Region, Import); - REGISTER_CLASS_ENUM (Region, External); - REGISTER_CLASS_ENUM (Region, SyncMarked); - REGISTER_CLASS_ENUM (Region, LeftOfSplit); - REGISTER_CLASS_ENUM (Region, RightOfSplit); - REGISTER_CLASS_ENUM (Region, Hidden); - REGISTER_CLASS_ENUM (Region, DoNotSaveState); - REGISTER_BITS (_Region_Flag); - - REGISTER_CLASS_ENUM (Region, AudioTime); - REGISTER_CLASS_ENUM (Region, MusicTime); - REGISTER_BITS (_Region_PositionLockStyle); - - REGISTER_CLASS_ENUM (Track, NoFreeze); - REGISTER_CLASS_ENUM (Track, Frozen); - REGISTER_CLASS_ENUM (Track, UnFrozen); - REGISTER (_Track_FreezeState); - - REGISTER_CLASS_ENUM (AutomationList, Discrete); - REGISTER_CLASS_ENUM (AutomationList, Linear); - REGISTER_CLASS_ENUM (AutomationList, Curved); - REGISTER (_AutomationList_InterpolationStyle); - -} diff --git a/libs/ardour/filename_extensions.cc b/libs/ardour/filename_extensions.cc deleted file mode 100644 index c51e7aa915..0000000000 --- a/libs/ardour/filename_extensions.cc +++ /dev/null @@ -1,15 +0,0 @@ -#include <ardour/filename_extensions.h> - -#include "i18n.h" - -namespace ARDOUR { - -const char* const template_suffix = X_(".template"); -const char* const statefile_suffix = X_(".ardour"); -const char* const pending_suffix = X_(".pending"); -const char* const peakfile_suffix = X_(".peak"); -const char* const backup_suffix = X_(".bak"); -const char* const temp_suffix = X_(".tmp"); -const char* const history_suffix = X_(".history"); - -} diff --git a/libs/ardour/filesystem_paths.cc b/libs/ardour/filesystem_paths.cc deleted file mode 100644 index d36bce2146..0000000000 --- a/libs/ardour/filesystem_paths.cc +++ /dev/null @@ -1,106 +0,0 @@ -/* - 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. - -*/ - -#include <pbd/error.h> -#include <pbd/filesystem_paths.h> - -#include <glibmm/miscutils.h> - -#include <ardour/directory_names.h> -#include <ardour/filesystem_paths.h> - -#define WITH_STATIC_PATHS 1 - -namespace ARDOUR { - -using std::string; - -sys::path -user_config_directory () -{ - const string home_dir = Glib::get_home_dir (); - - if (home_dir.empty ()) - { - const string error_msg = "Unable to determine home directory"; - - // log the error - error << error_msg << endmsg; - - throw sys::filesystem_error(error_msg); - } - - sys::path p(home_dir); - p /= user_config_dir_name; - - return p; -} - -sys::path -ardour_module_directory () -{ - sys::path module_directory(MODULE_DIR); - module_directory /= "ardour3"; - return module_directory; -} - -SearchPath -ardour_search_path () -{ - SearchPath spath_env(Glib::getenv("ARDOUR_PATH")); - return spath_env; -} - -SearchPath -system_config_search_path () -{ -#ifdef WITH_STATIC_PATHS - - SearchPath config_path(string(CONFIG_DIR)); - -#else - - SearchPath config_path(system_config_directories()); - -#endif - - config_path.add_subdirectory_to_paths("ardour3"); - - return config_path; -} - -SearchPath -system_data_search_path () -{ -#ifdef WITH_STATIC_PATHS - - SearchPath data_path(string(DATA_DIR)); - -#else - - SearchPath data_path(system_data_directories()); - -#endif - - data_path.add_subdirectory_to_paths("ardour3"); - - return data_path; -} - -} // namespace ARDOUR diff --git a/libs/ardour/filter.cc b/libs/ardour/filter.cc deleted file mode 100644 index be382f72da..0000000000 --- a/libs/ardour/filter.cc +++ /dev/null @@ -1,123 +0,0 @@ -/* - Copyright (C) 2004-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. - -*/ - -#include <time.h> -#include <cerrno> - -#include <pbd/basename.h> -#include <ardour/sndfilesource.h> -#include <ardour/smf_source.h> -#include <ardour/session.h> -#include <ardour/region.h> -#include <ardour/filter.h> -#include <ardour/region_factory.h> -#include <ardour/source_factory.h> -#include <ardour/analyser.h> - -#include "i18n.h" - -using namespace ARDOUR; -using namespace PBD; - -int -Filter::make_new_sources (boost::shared_ptr<Region> region, SourceList& nsrcs, string suffix) -{ - vector<string> names = region->master_source_names(); - - for (uint32_t i = 0; i < region->n_channels(); ++i) { - - string name = PBD::basename_nosuffix (names[i]); - - /* remove any existing version of suffix by assuming it starts - with some kind of "special" character. - */ - - if (!suffix.empty()) { - string::size_type pos = name.find (suffix[0]); - if (pos != string::npos && pos > 2) { - name = name.substr (0, pos - 1); - } - } - - string path = session.path_from_region_name (region->data_type(), - PBD::basename_nosuffix (names[i]), string ("")); - - if (path.length() == 0) { - error << string_compose (_("filter: error creating name for new file based on %1"), region->name()) - << endmsg; - return -1; - } - - try { - nsrcs.push_back (boost::dynamic_pointer_cast<Source> ( - SourceFactory::createWritable (region->data_type(), session, path, false, session.frame_rate()))); - } - - catch (failed_constructor& err) { - error << string_compose (_("filter: error creating new file %1 (%2)"), path, strerror (errno)) << endmsg; - return -1; - } - } - - return 0; -} - -int -Filter::finish (boost::shared_ptr<Region> region, SourceList& nsrcs, string region_name) -{ - /* update headers on new sources */ - - time_t xnow; - struct tm* now; - - time (&xnow); - now = localtime (&xnow); - - /* this is ugly. */ - for (SourceList::iterator si = nsrcs.begin(); si != nsrcs.end(); ++si) { - boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*si); - if (afs) { - afs->update_header (region->position(), *now, xnow); - afs->mark_immutable (); - } - - boost::shared_ptr<SMFSource> smfs = boost::dynamic_pointer_cast<SMFSource>(*si); - if (smfs) { - smfs->set_timeline_position (region->position()); - smfs->flush_footer (); - } - - /* now that there is data there, requeue the file for analysis */ - - Analyser::queue_source_for_analysis (*si, false); - } - - /* create a new region */ - - if (region_name.empty()) { - region_name = session.new_region_name (region->name()); - } - results.clear (); - results.push_back (RegionFactory::create (nsrcs, 0, region->length(), region_name, 0, - Region::Flag (Region::WholeFile|Region::DefaultFlags))); - - return 0; -} - - diff --git a/libs/ardour/find_session.cc b/libs/ardour/find_session.cc deleted file mode 100644 index 4388d8e299..0000000000 --- a/libs/ardour/find_session.cc +++ /dev/null @@ -1,167 +0,0 @@ -#include <unistd.h> -#include <sys/stat.h> - -#include <cstring> -#include <climits> -#include <cerrno> - -#include <pbd/compose.h> -#include <pbd/error.h> - -#include <ardour/session_utils.h> -#include <ardour/filename_extensions.h> -#include <ardour/utils.h> - -#include "i18n.h" - -using namespace PBD; - -int -ARDOUR::find_session (string str, string& path, string& snapshot, bool& isnew) -{ - struct stat statbuf; - char buf[PATH_MAX+1]; - - isnew = false; - - if (!realpath (str.c_str(), buf) && (errno != ENOENT && errno != ENOTDIR)) { - error << string_compose (_("Could not resolve path: %1 (%2)"), buf, strerror(errno)) << endmsg; - return -1; - } - - str = buf; - - /* check to see if it exists, and what it is */ - - if (stat (str.c_str(), &statbuf)) { - if (errno == ENOENT) { - isnew = true; - } else { - error << string_compose (_("cannot check session path %1 (%2)"), str, strerror (errno)) - << endmsg; - return -1; - } - } - - if (!isnew) { - - /* it exists, so it must either be the name - of the directory, or the name of the statefile - within it. - */ - - if (S_ISDIR (statbuf.st_mode)) { - - string::size_type slash = str.find_last_of ('/'); - - if (slash == string::npos) { - - /* a subdirectory of cwd, so statefile should be ... */ - - string tmp; - tmp = str; - tmp += '/'; - tmp += str; - tmp += statefile_suffix; - - /* is it there ? */ - - if (stat (tmp.c_str(), &statbuf)) { - error << string_compose (_("cannot check statefile %1 (%2)"), tmp, strerror (errno)) - << endmsg; - return -1; - } - - path = str; - snapshot = str; - - } else { - - /* some directory someplace in the filesystem. - the snapshot name is the directory name - itself. - */ - - path = str; - snapshot = str.substr (slash+1); - - } - - } else if (S_ISREG (statbuf.st_mode)) { - - string::size_type slash = str.find_last_of ('/'); - string::size_type suffix; - - /* remove the suffix */ - - if (slash != string::npos) { - snapshot = str.substr (slash+1); - } else { - snapshot = str; - } - - suffix = snapshot.find (statefile_suffix); - - if (suffix == string::npos) { - error << string_compose (_("%1 is not an Ardour snapshot file"), str) << endmsg; - return -1; - } - - /* remove suffix */ - - snapshot = snapshot.substr (0, suffix); - - if (slash == string::npos) { - - /* we must be in the directory where the - statefile lives. get it using cwd(). - */ - - char cwd[PATH_MAX+1]; - - if (getcwd (cwd, sizeof (cwd)) == 0) { - error << string_compose (_("cannot determine current working directory (%1)"), strerror (errno)) - << endmsg; - return -1; - } - - path = cwd; - - } else { - - /* full path to the statefile */ - - path = str.substr (0, slash); - } - - } else { - - /* what type of file is it? */ - error << string_compose (_("unknown file type for session %1"), str) << endmsg; - return -1; - } - - } else { - - /* its the name of a new directory. get the name - as "dirname" does. - */ - - string::size_type slash = str.find_last_of ('/'); - - if (slash == string::npos) { - - /* no slash, just use the name, but clean it up */ - - path = legalize_for_path (str); - snapshot = path; - - } else { - - path = str; - snapshot = str.substr (slash+1); - } - } - - return 0; -} diff --git a/libs/ardour/gain.cc b/libs/ardour/gain.cc deleted file mode 100644 index 49596d6614..0000000000 --- a/libs/ardour/gain.cc +++ /dev/null @@ -1,61 +0,0 @@ -/* - 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. - -*/ - -#include <ardour/gain.h> - -using namespace ARDOUR; - -Gain::Gain () - : AutomationList (Parameter(GainAutomation), 0.0, 2.0, 1.0f) /* XXX yuck; clamps gain to -inf .. +6db */ -{ -} - -Gain::Gain (const Gain& other) - : AutomationList (other) -{ -} - -Gain& -Gain::operator= (const Gain& other) -{ - if (this != &other) { - AutomationList::operator= (other); - } - return *this; -} - -void -Gain::fill_linear_volume_fade_in (Gain& gain, nframes_t frames) -{ -} - -void -Gain::fill_linear_volume_fade_out (Gain& gain, nframes_t frames) -{ -} - -void -Gain::fill_linear_fade_in (Gain& gain, nframes_t frames) -{ -} - -void -Gain::fill_linear_fade_out (Gain& gain, nframes_t frames) -{ -} diff --git a/libs/ardour/gdither.cc b/libs/ardour/gdither.cc deleted file mode 100644 index ac47a0a61e..0000000000 --- a/libs/ardour/gdither.cc +++ /dev/null @@ -1,474 +0,0 @@ -/* - * Copyright (C) 2002 Steve Harris <steve@plugin.org.uk> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include <ardour/gdither_types_internal.h> -#include <ardour/gdither.h> -#include <ardour/noise.h> - -/* this monstrosity is necessary to get access to lrintf() and random(). - whoever is writing the glibc headers <cmath> and <cstdlib> should be - hauled off to a programmer re-education camp. for the rest of - their natural lives. or longer. <paul@linuxaudiosystems.com> -*/ - -#define _ISOC9X_SOURCE 1 -#define _ISOC99_SOURCE 1 -#ifdef __cplusplus -#include <cmath> -#else -#include <math.h> -#endif - -#undef __USE_SVID -#define __USE_SVID 1 -#ifdef __cplusplus -#include <cstdlib> -#else -#include <stdlib.h> -#endif - -#include <sys/types.h> - -/* Lipshitz's minimally audible FIR, only really works for 46kHz-ish signals */ -static const float shaped_bs[] = { 2.033f, -2.165f, 1.959f, -1.590f, 0.6149f }; - -/* Some useful constants */ -#define MAX_U8 255 -#define MIN_U8 0 -#define SCALE_U8 128.0f - -#define MAX_S16 32767 -#define MIN_S16 -32768 -#define SCALE_S16 32768.0f - -#define MAX_S24 8388607 -#define MIN_S24 -8388608 -#define SCALE_S24 8388608.0f - -GDither gdither_new(GDitherType type, uint32_t channels, - - GDitherSize bit_depth, int dither_depth) -{ - GDither s; - - s = (GDither)calloc(1, sizeof(struct GDither_s)); - s->type = type; - s->channels = channels; - s->bit_depth = (int)bit_depth; - - if (dither_depth <= 0 || dither_depth > (int)bit_depth) { - dither_depth = (int)bit_depth; - } - s->dither_depth = dither_depth; - - s->scale = (float)(1LL << (dither_depth - 1)); - if (bit_depth == GDitherFloat || bit_depth == GDitherDouble) { - s->post_scale_fp = 1.0f / s->scale; - s->post_scale = 0; - } else { - s->post_scale_fp = 0.0f; - s->post_scale = 1 << ((int)bit_depth - dither_depth); - } - - switch (bit_depth) { - case GDither8bit: - /* Unsigned 8 bit */ - s->bias = 1.0f; - s->clamp_u = 255; - s->clamp_l = 0; - break; - case GDither16bit: - /* Signed 16 bit */ - s->bias = 0.0f; - s->clamp_u = 32767; - s->clamp_l = -32768; - break; - case GDither32bit: - /* Signed 24 bit, in upper 24 bits of 32 bit word */ - s->bias = 0.0f; - s->clamp_u = 8388607; - s->clamp_l = -8388608; - break; - case GDitherFloat: - /* normalised float */ - s->bias = 0.0f; - s->clamp_u = lrintf(s->scale); - s->clamp_l = lrintf(-s->scale); - break; - case GDitherDouble: - /* normalised float */ - s->bias = 0.0f; - s->clamp_u = lrintf(s->scale); - s->clamp_l = lrintf(-s->scale); - break; - case 23: - /* special performance test case */ - s->scale = SCALE_S24; - s->post_scale = 256; - s->bias = 0.0f; - s->clamp_u = 8388607; - s->clamp_l = -8388608; - break; - default: - /* Not a bit depth we can handle */ - free(s); - - return NULL; - break; - } - - switch (type) { - case GDitherNone: - case GDitherRect: - /* No state */ - break; - - case GDitherTri: - /* The last whitenoise sample */ - s->tri_state = (float *) calloc(channels, sizeof(float)); - break; - - case GDitherShaped: - /* The error from the last few samples encoded */ - s->shaped_state = (GDitherShapedState*) - calloc(channels, sizeof(GDitherShapedState)); - break; - } - - return s; -} - -void gdither_free(GDither s) -{ - if (s) { - free(s->tri_state); - free(s->shaped_state); - free(s); - } -} - -inline static void gdither_innner_loop(const GDitherType dt, - const uint32_t stride, const float bias, const float scale, - - const uint32_t post_scale, const int bit_depth, - const uint32_t channel, const uint32_t length, float *ts, - - GDitherShapedState *ss, float *x, void *y, const int clamp_u, - - const int clamp_l) -{ - uint32_t pos, i; - uint8_t *o8 = (uint8_t*) y; - int16_t *o16 = (int16_t*) y; - int32_t *o32 = (int32_t*) y; - float tmp, r, ideal; - int64_t clamped; - - i = channel; - for (pos = 0; pos < length; pos++, i += stride) { - tmp = x[i] * scale + bias; - - switch (dt) { - case GDitherNone: - break; - case GDitherRect: - tmp -= GDITHER_NOISE; - break; - case GDitherTri: - r = GDITHER_NOISE - 0.5f; - tmp -= r - ts[channel]; - ts[channel] = r; - break; - case GDitherShaped: - /* Save raw value for error calculations */ - ideal = tmp; - - /* Run FIR and add white noise */ - ss->buffer[ss->phase] = GDITHER_NOISE * 0.5f; - tmp += ss->buffer[ss->phase] * shaped_bs[0] - + ss->buffer[(ss->phase - 1) & GDITHER_SH_BUF_MASK] - * shaped_bs[1] - + ss->buffer[(ss->phase - 2) & GDITHER_SH_BUF_MASK] - * shaped_bs[2] - + ss->buffer[(ss->phase - 3) & GDITHER_SH_BUF_MASK] - * shaped_bs[3] - + ss->buffer[(ss->phase - 4) & GDITHER_SH_BUF_MASK] - * shaped_bs[4]; - - /* Roll buffer and store last error */ - ss->phase = (ss->phase + 1) & GDITHER_SH_BUF_MASK; - ss->buffer[ss->phase] = (float)lrintf(tmp) - ideal; - break; - } - - clamped = lrintf(tmp); - if (clamped > clamp_u) { - clamped = clamp_u; - } else if (clamped < clamp_l) { - clamped = clamp_l; - } - - switch (bit_depth) { - case GDither8bit: - o8[i] = (u_int8_t) (clamped * post_scale); - break; - case GDither16bit: - o16[i] = (int16_t) (clamped * post_scale); - break; - case GDither32bit: - o32[i] = (int32_t) (clamped * post_scale); - break; - } - } -} - -/* floating pint version of the inner loop function */ -inline static void gdither_innner_loop_fp(const GDitherType dt, - const uint32_t stride, const float bias, const float scale, - - const float post_scale, const int bit_depth, - const uint32_t channel, const uint32_t length, float *ts, - - GDitherShapedState *ss, float *x, void *y, const int clamp_u, - - const int clamp_l) -{ - uint32_t pos, i; - float *oflt = (float*) y; - double *odbl = (double*) y; - float tmp, r, ideal; - double clamped; - - i = channel; - for (pos = 0; pos < length; pos++, i += stride) { - tmp = x[i] * scale + bias; - - switch (dt) { - case GDitherNone: - break; - case GDitherRect: - tmp -= GDITHER_NOISE; - break; - case GDitherTri: - r = GDITHER_NOISE - 0.5f; - tmp -= r - ts[channel]; - ts[channel] = r; - break; - case GDitherShaped: - /* Save raw value for error calculations */ - ideal = tmp; - - /* Run FIR and add white noise */ - ss->buffer[ss->phase] = GDITHER_NOISE * 0.5f; - tmp += ss->buffer[ss->phase] * shaped_bs[0] - + ss->buffer[(ss->phase - 1) & GDITHER_SH_BUF_MASK] - * shaped_bs[1] - + ss->buffer[(ss->phase - 2) & GDITHER_SH_BUF_MASK] - * shaped_bs[2] - + ss->buffer[(ss->phase - 3) & GDITHER_SH_BUF_MASK] - * shaped_bs[3] - + ss->buffer[(ss->phase - 4) & GDITHER_SH_BUF_MASK] - * shaped_bs[4]; - - /* Roll buffer and store last error */ - ss->phase = (ss->phase + 1) & GDITHER_SH_BUF_MASK; - ss->buffer[ss->phase] = (float)lrintf(tmp) - ideal; - break; - } - - clamped = rintf(tmp); - if (clamped > clamp_u) { - clamped = clamp_u; - } else if (clamped < clamp_l) { - clamped = clamp_l; - } - - switch (bit_depth) { - case GDitherFloat: - oflt[i] = (float) (clamped * post_scale); - break; - case GDitherDouble: - odbl[i] = (double) (clamped * post_scale); - break; - } - } -} - -#define GDITHER_CONV_BLOCK 512 - -void gdither_run(GDither s, uint32_t channel, uint32_t length, - double *x, void *y) -{ - float conv[GDITHER_CONV_BLOCK]; - uint32_t i, pos; - char *ycast = (char *)y; - - int step; - - switch (s->bit_depth) { - case GDither8bit: - step = 1; - break; - case GDither16bit: - step = 2; - break; - case GDither32bit: - case GDitherFloat: - step = 4; - break; - case GDitherDouble: - step = 8; - break; - default: - step = 0; - break; - } - - pos = 0; - while (pos < length) { - for (i=0; (i + pos) < length && i < GDITHER_CONV_BLOCK; i++) { - conv[i] = x[pos + i]; - } - gdither_runf(s, channel, i, conv, ycast + s->channels * step); - pos += i; - } -} - -void gdither_runf(GDither s, uint32_t channel, uint32_t length, - float *x, void *y) -{ - uint32_t pos, i; - float tmp; - int64_t clamped; - GDitherShapedState *ss = NULL; - - if (!s || channel >= s->channels) { - return; - } - - if (s->shaped_state) { - ss = s->shaped_state + channel; - } - - if (s->type == GDitherNone && s->bit_depth == 23) { - int32_t *o32 = (int32_t*) y; - - for (pos = 0; pos < length; pos++) { - i = channel + (pos * s->channels); - tmp = x[i] * 8388608.0f; - - clamped = lrintf(tmp); - if (clamped > 8388607) { - clamped = 8388607; - } else if (clamped < -8388608) { - clamped = -8388608; - } - - o32[i] = (int32_t) (clamped * 256); - } - - return; - } - - /* some common case handling code - looks a bit wierd, but it allows - * the compiler to optimise out the branches in the inner loop */ - if (s->bit_depth == 8 && s->dither_depth == 8) { - switch (s->type) { - case GDitherNone: - gdither_innner_loop(GDitherNone, s->channels, 128.0f, SCALE_U8, - 1, 8, channel, length, NULL, NULL, x, y, - MAX_U8, MIN_U8); - break; - case GDitherRect: - gdither_innner_loop(GDitherRect, s->channels, 128.0f, SCALE_U8, - 1, 8, channel, length, NULL, NULL, x, y, - MAX_U8, MIN_U8); - break; - case GDitherTri: - gdither_innner_loop(GDitherTri, s->channels, 128.0f, SCALE_U8, - 1, 8, channel, length, s->tri_state, - NULL, x, y, MAX_U8, MIN_U8); - break; - case GDitherShaped: - gdither_innner_loop(GDitherShaped, s->channels, 128.0f, SCALE_U8, - 1, 8, channel, length, NULL, - ss, x, y, MAX_U8, MIN_U8); - break; - } - } else if (s->bit_depth == 16 && s->dither_depth == 16) { - switch (s->type) { - case GDitherNone: - gdither_innner_loop(GDitherNone, s->channels, 0.0f, SCALE_S16, - 1, 16, channel, length, NULL, NULL, x, y, - MAX_S16, MIN_S16); - break; - case GDitherRect: - gdither_innner_loop(GDitherRect, s->channels, 0.0f, SCALE_S16, - 1, 16, channel, length, NULL, NULL, x, y, - MAX_S16, MIN_S16); - break; - case GDitherTri: - gdither_innner_loop(GDitherTri, s->channels, 0.0f, SCALE_S16, - 1, 16, channel, length, s->tri_state, - NULL, x, y, MAX_S16, MIN_S16); - break; - case GDitherShaped: - gdither_innner_loop(GDitherShaped, s->channels, 0.0f, - SCALE_S16, 1, 16, channel, length, NULL, - ss, x, y, MAX_S16, MIN_S16); - break; - } - } else if (s->bit_depth == 32 && s->dither_depth == 24) { - switch (s->type) { - case GDitherNone: - gdither_innner_loop(GDitherNone, s->channels, 0.0f, SCALE_S24, - 256, 32, channel, length, NULL, NULL, x, - y, MAX_S24, MIN_S24); - break; - case GDitherRect: - gdither_innner_loop(GDitherRect, s->channels, 0.0f, SCALE_S24, - 256, 32, channel, length, NULL, NULL, x, - y, MAX_S24, MIN_S24); - break; - case GDitherTri: - gdither_innner_loop(GDitherTri, s->channels, 0.0f, SCALE_S24, - 256, 32, channel, length, s->tri_state, - NULL, x, y, MAX_S24, MIN_S24); - break; - case GDitherShaped: - gdither_innner_loop(GDitherShaped, s->channels, 0.0f, SCALE_S24, - 256, 32, channel, length, - NULL, ss, x, y, MAX_S24, MIN_S24); - break; - } - } else if (s->bit_depth == GDitherFloat || s->bit_depth == GDitherDouble) { - gdither_innner_loop_fp(s->type, s->channels, s->bias, s->scale, - s->post_scale_fp, s->bit_depth, channel, length, - s->tri_state, ss, x, y, s->clamp_u, s->clamp_l); - } else { - /* no special case handling, just process it from the struct */ - - gdither_innner_loop(s->type, s->channels, s->bias, s->scale, - s->post_scale, s->bit_depth, channel, - length, s->tri_state, ss, x, y, s->clamp_u, - s->clamp_l); - } -} - -/* vi:set ts=8 sts=4 sw=4: */ diff --git a/libs/ardour/gettext.h b/libs/ardour/gettext.h deleted file mode 100644 index 339c74ffe7..0000000000 --- a/libs/ardour/gettext.h +++ /dev/null @@ -1,82 +0,0 @@ -/* Convenience header for conditional use of GNU <libintl.h>. - Copyright (C) 1995-1998, 2000-2002 Free Software Foundation, Inc. - - This program 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, or (at your option) - any later version. - - This program is distributed in the hope that 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 program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -#ifndef _LIBGETTEXT_H -#define _LIBGETTEXT_H 1 - -/* NLS can be disabled through the configure --disable-nls option. */ -#if ENABLE_NLS - -/* Get declarations of GNU message catalog functions. */ -# include <libintl.h> - -#else - -/* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which - chokes if dcgettext is defined as a macro. So include it now, to make - later inclusions of <locale.h> a NOP. We don't include <libintl.h> - as well because people using "gettext.h" will not include <libintl.h>, - and also including <libintl.h> would fail on SunOS 4, whereas <locale.h> - is OK. */ -#if defined(__sun) -# include <locale.h> -#endif - -/* Disabled NLS. - The casts to 'const char *' serve the purpose of producing warnings - for invalid uses of the value returned from these functions. - On pre-ANSI systems without 'const', the config.h file is supposed to - contain "#define const". */ - -/* other headers may have included libintl.h */ - -# undef gettext -# undef dgettext -# undef dcgettext -# undef ngettext -# undef dngettext -# undef dcngettext -# undef textdomain -# undef bindtextdomain -# undef bind_textdomain_codeset - -# define gettext(Msgid) ((const char *) (Msgid)) -# define dgettext(Domainname, Msgid) ((const char *) (Msgid)) -# define dcgettext(Domainname, Msgid, Category) ((const char *) (Msgid)) -# define ngettext(Msgid1, Msgid2, N) \ - ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2)) -# define dngettext(Domainname, Msgid1, Msgid2, N) \ - ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2)) -# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \ - ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2)) -# define textdomain(Domainname) ((const char *) (Domainname)) -# define bindtextdomain(Domainname, Dirname) ((const char *) (Dirname)) -# define bind_textdomain_codeset(Domainname, Codeset) ((const char *) (Codeset)) - -#endif - -/* A pseudo function call that serves as a marker for the automated - extraction of messages, but does not call gettext(). The run-time - translation is done at a different place in the code. - The argument, String, should be a literal string. Concatenated strings - and other string expressions won't work. - The macro's expansion is not parenthesized, so that it is suitable as - initializer for static 'char[]' or 'const char[]' variables. */ -#define gettext_noop(String) String - -#endif /* _LIBGETTEXT_H */ diff --git a/libs/ardour/globals.cc b/libs/ardour/globals.cc deleted file mode 100644 index 02c4a5ced6..0000000000 --- a/libs/ardour/globals.cc +++ /dev/null @@ -1,619 +0,0 @@ -/* - 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. -*/ - -#include <cstdio> // Needed so that libraptor (included in lrdf) won't complain -#include <sys/stat.h> -#include <sys/types.h> -#include <sys/time.h> -#include <sys/resource.h> -#include <unistd.h> -#include <fcntl.h> -#include <locale.h> -#include <errno.h> - -#ifdef VST_SUPPORT -#include <fst.h> -#endif - -#ifdef __SSE__ -#include <xmmintrin.h> -#endif - -#include <glibmm/fileutils.h> -#include <glibmm/miscutils.h> - -#include <lrdf.h> - -#include <pbd/error.h> -#include <pbd/id.h> -#include <pbd/strsplit.h> -#include <pbd/fpu.h> -#include <pbd/file_utils.h> - -#include <midi++/port.h> -#include <midi++/manager.h> -#include <midi++/mmc.h> - -#include <ardour/ardour.h> -#include <ardour/analyser.h> -#include <ardour/audio_library.h> -#include <ardour/configuration.h> -#include <ardour/profile.h> -#include <ardour/plugin_manager.h> -#include <ardour/audiosource.h> -#include <ardour/utils.h> -#include <ardour/session.h> -#include <ardour/source_factory.h> -#include <ardour/control_protocol_manager.h> -#include <ardour/audioengine.h> -#include <ardour/filesystem_paths.h> - -#ifdef HAVE_LIBLO -#include <ardour/osc.h> -#endif - -#include <ardour/mix.h> -#include <ardour/runtime_functions.h> - -#if defined (__APPLE__) - #include <Carbon/Carbon.h> // For Gestalt -#endif - -#include "i18n.h" - -ARDOUR::Configuration* ARDOUR::Config = 0; -ARDOUR::RuntimeProfile* ARDOUR::Profile = 0; -ARDOUR::AudioLibrary* ARDOUR::Library = 0; - -#ifdef HAVE_LIBLO -ARDOUR::OSC* ARDOUR::osc = 0; -#endif - -using namespace ARDOUR; -using namespace std; -using namespace PBD; - -MIDI::Port *default_mmc_port = 0; -MIDI::Port *default_mtc_port = 0; -MIDI::Port *default_midi_port = 0; - -Change ARDOUR::StartChanged = ARDOUR::new_change (); -Change ARDOUR::LengthChanged = ARDOUR::new_change (); -Change ARDOUR::PositionChanged = ARDOUR::new_change (); -Change ARDOUR::NameChanged = ARDOUR::new_change (); -Change ARDOUR::BoundsChanged = Change (0); // see init(), below - -compute_peak_t ARDOUR::compute_peak = 0; -find_peaks_t ARDOUR::find_peaks = 0; -apply_gain_to_buffer_t ARDOUR::apply_gain_to_buffer = 0; -mix_buffers_with_gain_t ARDOUR::mix_buffers_with_gain = 0; -mix_buffers_no_gain_t ARDOUR::mix_buffers_no_gain = 0; - -sigc::signal<void,std::string> ARDOUR::BootMessage; - -#ifdef HAVE_LIBLO -static int -setup_osc () -{ - /* no real cost to creating this object, and it avoids - conditionals anywhere that uses it - */ - - osc = new OSC (Config->get_osc_port()); - - if (Config->get_use_osc ()) { - BootMessage (_("Starting OSC")); - return osc->start (); - } else { - return 0; - } -} -#endif - -int -setup_midi () -{ - if (Config->midi_ports.size() == 0) { - warning << _("no MIDI ports specified: no MMC or MTC control possible") << endmsg; - return 0; - } - - BootMessage (_("Configuring MIDI ports")); - - for (std::map<string,XMLNode>::iterator i = Config->midi_ports.begin(); i != Config->midi_ports.end(); ++i) { - MIDI::Manager::instance()->add_port (i->second); - } - - MIDI::Port* first; - const MIDI::Manager::PortMap& ports = MIDI::Manager::instance()->get_midi_ports(); - - if (ports.size() > 1) { - - first = ports.begin()->second; - - /* More than one port, so try using specific names for each port */ - - if (Config->get_mmc_port_name() != N_("default")) { - default_mmc_port = MIDI::Manager::instance()->port (Config->get_mmc_port_name()); - } - - if (Config->get_mtc_port_name() != N_("default")) { - default_mtc_port = MIDI::Manager::instance()->port (Config->get_mtc_port_name()); - } - - if (Config->get_midi_port_name() != N_("default")) { - default_midi_port = MIDI::Manager::instance()->port (Config->get_midi_port_name()); - } - - /* If that didn't work, just use the first listed port */ - - if (default_mmc_port == 0) { - default_mmc_port = first; - } - - if (default_mtc_port == 0) { - default_mtc_port = first; - } - - if (default_midi_port == 0) { - default_midi_port = first; - } - - } else if (ports.size() == 1) { - - first = ports.begin()->second; - - /* Only one port described, so use it for both MTC and MMC */ - - default_mmc_port = first; - default_mtc_port = default_mmc_port; - default_midi_port = default_mmc_port; - } - - if (default_mmc_port == 0) { - warning << string_compose (_("No MMC control (MIDI port \"%1\" not available)"), Config->get_mmc_port_name()) - << endmsg; - return 0; - } - - if (default_mtc_port == 0) { - warning << string_compose (_("No MTC support (MIDI port \"%1\" not available)"), Config->get_mtc_port_name()) - << endmsg; - } - - if (default_midi_port == 0) { - warning << string_compose (_("No MIDI parameter support (MIDI port \"%1\" not available)"), Config->get_midi_port_name()) - << endmsg; - } - - return 0; -} - -void -setup_hardware_optimization (bool try_optimization) -{ - bool generic_mix_functions = true; - - if (try_optimization) { - - FPU fpu; - -#if defined (ARCH_X86) && defined (BUILD_SSE_OPTIMIZATIONS) - - if (fpu.has_sse()) { - - info << "Using SSE optimized routines" << endmsg; - - // SSE SET - compute_peak = x86_sse_compute_peak; - find_peaks = x86_sse_find_peaks; - apply_gain_to_buffer = x86_sse_apply_gain_to_buffer; - mix_buffers_with_gain = x86_sse_mix_buffers_with_gain; - mix_buffers_no_gain = x86_sse_mix_buffers_no_gain; - - generic_mix_functions = false; - - } - -#elif defined (__APPLE__) && defined (BUILD_VECLIB_OPTIMIZATIONS) - long sysVersion = 0; - - if (noErr != Gestalt(gestaltSystemVersion, &sysVersion)) - sysVersion = 0; - - if (sysVersion >= 0x00001040) { // Tiger at least - compute_peak = veclib_compute_peak; - find_peaks = veclib_find_peaks; - apply_gain_to_buffer = veclib_apply_gain_to_buffer; - mix_buffers_with_gain = veclib_mix_buffers_with_gain; - mix_buffers_no_gain = veclib_mix_buffers_no_gain; - - generic_mix_functions = false; - - info << "Apple VecLib H/W specific optimizations in use" << endmsg; - } -#endif - - /* consider FPU denormal handling to be "h/w optimization" */ - - setup_fpu (); - } - - if (generic_mix_functions) { - - compute_peak = default_compute_peak; - find_peaks = default_find_peaks; - apply_gain_to_buffer = default_apply_gain_to_buffer; - mix_buffers_with_gain = default_mix_buffers_with_gain; - mix_buffers_no_gain = default_mix_buffers_no_gain; - - info << "No H/W specific optimizations in use" << endmsg; - } -} - -static void -lotsa_files_please () -{ - struct rlimit rl; - - if (getrlimit (RLIMIT_NOFILE, &rl) == 0) { - - rl.rlim_cur = rl.rlim_max; - - if (setrlimit (RLIMIT_NOFILE, &rl) != 0) { - if (rl.rlim_cur == RLIM_INFINITY) { - error << _("Could not set system open files limit to \"unlimited\"") << endmsg; - } else { - error << string_compose (_("Could not set system open files limit to %1"), rl.rlim_cur) << endmsg; - } - } else { - if (rl.rlim_cur == RLIM_INFINITY) { - info << _("Removed open file count limit. Excellent!") << endmsg; - } else { - info << string_compose (_("Ardour will be limited to %1 open files"), rl.rlim_cur) << endmsg; - } - } - } else { - error << string_compose (_("Could not get system open files limit (%1)"), strerror (errno)) << endmsg; - } -} - -int -ARDOUR::init (bool use_vst, bool try_optimization) -{ - extern void setup_enum_writer (); - - (void) bindtextdomain(PACKAGE, LOCALEDIR); - - setup_enum_writer (); - - // allow ardour the absolute maximum number of open files - lotsa_files_please (); - - lrdf_init(); - Library = new AudioLibrary; - - BootMessage (_("Loading configuration")); - - Config = new Configuration; - - if (Config->load_state ()) { - return -1; - } - - Config->set_use_vst (use_vst); - - Profile = new RuntimeProfile; - -#ifdef HAVE_LIBLO - if (setup_osc ()) { - return -1; - } -#endif - -#ifdef VST_SUPPORT - if (Config->get_use_vst() && fst_init ()) { - return -1; - } -#endif - - /* Make VAMP look in our library ahead of anything else */ - - char *p = getenv ("VAMP_PATH"); - string vamppath = VAMP_DIR; - if (p) { - vamppath += ':'; - vamppath += p; - } - setenv ("VAMP_PATH", vamppath.c_str(), 1); - - - setup_hardware_optimization (try_optimization); - - SourceFactory::init (); - Analyser::init (); - - /* singleton - first object is "it" */ - new PluginManager (); - - /* singleton - first object is "it" */ - new ControlProtocolManager (); - ControlProtocolManager::instance().discover_control_protocols (); - - XMLNode* node; - if ((node = Config->control_protocol_state()) != 0) { - ControlProtocolManager::instance().set_state (*node); - } - - BoundsChanged = Change (StartChanged|PositionChanged|LengthChanged); - - return 0; -} - -int -ARDOUR::cleanup () -{ - delete Library; - lrdf_cleanup (); - delete &ControlProtocolManager::instance(); - return 0; -} - - -microseconds_t -ARDOUR::get_microseconds () -{ - /* XXX need JACK to export its functionality */ - - struct timeval now; - gettimeofday (&now, 0); - return now.tv_sec * 1000000ULL + now.tv_usec; -} - -ARDOUR::Change -ARDOUR::new_change () -{ - Change c; - static uint32_t change_bit = 1; - - /* catch out-of-range */ - if (!change_bit) - { - fatal << _("programming error: ") - << "change_bit out of range in ARDOUR::new_change()" - << endmsg; - /*NOTREACHED*/ - } - - c = Change (change_bit); - change_bit <<= 1; // if it shifts too far, change_bit == 0 - - return c; -} - -string -ARDOUR::get_ardour_revision () -{ - return "$Rev$"; -} - -void -ARDOUR::find_bindings_files (map<string,string>& files) -{ - vector<sys::path> found; - - SearchPath spath = ardour_search_path() + user_config_directory() + system_config_search_path(); - - if (getenv ("ARDOUR_SAE")) { - Glib::PatternSpec pattern("*SAE-*.bindings"); - find_matching_files_in_search_path (spath, pattern, found); - } else { - Glib::PatternSpec pattern("*.bindings"); - find_matching_files_in_search_path (spath, pattern, found); - } - - if (found.empty()) { - return; - } - - for (vector<sys::path>::iterator x = found.begin(); x != found.end(); ++x) { - sys::path path = *x; - pair<string,string> namepath; - namepath.second = path.to_string(); - namepath.first = path.leaf().substr (0, path.leaf().find_first_of ('.')); - files.insert (namepath); - } -} - -ARDOUR::LocaleGuard::LocaleGuard (const char* str) -{ - old = strdup (setlocale (LC_NUMERIC, NULL)); - if (strcmp (old, str)) { - setlocale (LC_NUMERIC, str); - } -} - -ARDOUR::LocaleGuard::~LocaleGuard () -{ - setlocale (LC_NUMERIC, old); - free ((char*)old); -} - -void -ARDOUR::setup_fpu () -{ - - if (getenv ("ARDOUR_RUNNING_UNDER_VALGRIND")) { - // valgrind doesn't understand this assembler stuff - // September 10th, 2007 - return; - } - -#if defined(ARCH_X86) && defined(USE_XMMINTRIN) - - int MXCSR; - FPU fpu; - - /* XXX use real code to determine if the processor supports - DenormalsAreZero and FlushToZero - */ - - if (!fpu.has_flush_to_zero() && !fpu.has_denormals_are_zero()) { - return; - } - - MXCSR = _mm_getcsr(); - - switch (Config->get_denormal_model()) { - case DenormalNone: - MXCSR &= ~(_MM_FLUSH_ZERO_ON|0x8000); - break; - - case DenormalFTZ: - if (fpu.has_flush_to_zero()) { - MXCSR |= _MM_FLUSH_ZERO_ON; - } - break; - - case DenormalDAZ: - MXCSR &= ~_MM_FLUSH_ZERO_ON; - if (fpu.has_denormals_are_zero()) { - MXCSR |= 0x8000; - } - break; - - case DenormalFTZDAZ: - if (fpu.has_flush_to_zero()) { - if (fpu.has_denormals_are_zero()) { - MXCSR |= _MM_FLUSH_ZERO_ON | 0x8000; - } else { - MXCSR |= _MM_FLUSH_ZERO_ON; - } - } - break; - } - - _mm_setcsr (MXCSR); - -#endif -} - -ARDOUR::OverlapType -ARDOUR::coverage (nframes_t sa, nframes_t ea, - nframes_t sb, nframes_t eb) -{ - /* OverlapType returned reflects how the second (B) - range overlaps the first (A). - - The diagrams show various relative placements - of A and B for each OverlapType. - - Notes: - Internal: the start points cannot coincide - External: the start and end points can coincide - Start: end points can coincide - End: start points can coincide - - XXX Logically, Internal should disallow end - point equality. - */ - - /* - |--------------------| A - |------| B - |-----------------| B - - - "B is internal to A" - - */ -#ifdef OLD_COVERAGE - if ((sb >= sa) && (eb <= ea)) { -#else - if ((sb > sa) && (eb <= ea)) { -#endif - return OverlapInternal; - } - - /* - |--------------------| A - ----| B - -----------------------| B - --| B - - "B overlaps the start of A" - - */ - - if ((eb >= sa) && (eb <= ea)) { - return OverlapStart; - } - /* - |---------------------| A - |----------------- B - |----------------------- B - |- B - - "B overlaps the end of A" - - */ - if ((sb > sa) && (sb <= ea)) { - return OverlapEnd; - } - /* - |--------------------| A - -------------------------- B - |----------------------- B - ----------------------| B - |--------------------| B - - - "B overlaps all of A" - */ - if ((sa >= sb) && (sa <= eb) && (ea <= eb)) { - return OverlapExternal; - } - - return OverlapNone; -} - -/* not sure where to put these */ - -template<class T> -std::istream& int_to_type (std::istream& o, T& hf) { - int val; - o >> val; - hf = (T) val; - return o; -} - -std::istream& operator>>(std::istream& o, HeaderFormat& var) { return int_to_type<HeaderFormat> (o, var); } -std::istream& operator>>(std::istream& o, SampleFormat& var) { return int_to_type<SampleFormat> (o, var); } -std::istream& operator>>(std::istream& o, AutoConnectOption& var) { return int_to_type<AutoConnectOption> (o, var); } -std::istream& operator>>(std::istream& o, MonitorModel& var) { return int_to_type<MonitorModel> (o, var); } -std::istream& operator>>(std::istream& o, RemoteModel& var) { return int_to_type<RemoteModel> (o, var); } -std::istream& operator>>(std::istream& o, EditMode& var) { return int_to_type<EditMode> (o, var); } -std::istream& operator>>(std::istream& o, SoloModel& var) { return int_to_type<SoloModel> (o, var); } -std::istream& operator>>(std::istream& o, LayerModel& var) { return int_to_type<LayerModel> (o, var); } -std::istream& operator>>(std::istream& o, CrossfadeModel& var) { return int_to_type<CrossfadeModel> (o, var); } -std::istream& operator>>(std::istream& o, SlaveSource& var) { return int_to_type<SlaveSource> (o, var); } -std::istream& operator>>(std::istream& o, ShuttleBehaviour& var) { return int_to_type<ShuttleBehaviour> (o, var); } -std::istream& operator>>(std::istream& o, ShuttleUnits& var) { return int_to_type<ShuttleUnits> (o, var); } -std::istream& operator>>(std::istream& o, SmpteFormat& var) { return int_to_type<SmpteFormat> (o, var); } -std::istream& operator>>(std::istream& o, DenormalModel& var) { return int_to_type<DenormalModel> (o, var); } - diff --git a/libs/ardour/i18n.h b/libs/ardour/i18n.h deleted file mode 100644 index 5d68c79edd..0000000000 --- a/libs/ardour/i18n.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef __i18n_h__ -#define __i18n_h__ - -#include <pbd/compose.h> -#include <pbd/convert.h> -#include "gettext.h" - -#include <vector> -#include <string> - -#define _(Text) dgettext (PACKAGE,Text) -#define N_(Text) gettext_noop (Text) -#define X_(Text) Text -#define I18N(Array) PBD::internationalize (PACKAGE, Array) - -#endif // __i18n_h__ diff --git a/libs/ardour/import.cc b/libs/ardour/import.cc deleted file mode 100644 index d79c930e6d..0000000000 --- a/libs/ardour/import.cc +++ /dev/null @@ -1,491 +0,0 @@ -/* - 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. - -*/ - -#include <cstdio> -#include <cstdlib> -#include <string> -#include <climits> -#include <cerrno> -#include <unistd.h> -#include <sys/stat.h> -#include <time.h> - -#include <sndfile.h> -#include <samplerate.h> - -#include <glibmm.h> - -#include <boost/scoped_array.hpp> -#include <boost/shared_array.hpp> - -#include <pbd/basename.h> -#include <pbd/convert.h> - -#include <ardour/ardour.h> -#include <ardour/session.h> -#include <ardour/session_directory.h> -#include <ardour/audio_diskstream.h> -#include <ardour/audioengine.h> -#include <ardour/sndfilesource.h> -#include <ardour/sndfile_helpers.h> -#include <ardour/audioregion.h> -#include <ardour/region_factory.h> -#include <ardour/source_factory.h> -#include <ardour/resampled_source.h> -#include <ardour/sndfileimportable.h> -#include <ardour/analyser.h> -#include <ardour/smf_reader.h> -#include <ardour/smf_source.h> -#include <ardour/tempo.h> - -#ifdef HAVE_COREAUDIO -#include <ardour/caimportable.h> -#endif - -#include "i18n.h" - -using namespace ARDOUR; -using namespace PBD; - - -static boost::shared_ptr<ImportableSource> -open_importable_source (const string& path, nframes_t samplerate, ARDOUR::SrcQuality quality) -{ -#ifdef HAVE_COREAUDIO - - /* see if we can use CoreAudio to handle the IO */ - - try { - boost::shared_ptr<CAImportableSource> source(new CAImportableSource(path)); - - if (source->samplerate() == samplerate) { - return source; - } - - /* rewrap as a resampled source */ - - return boost::shared_ptr<ImportableSource>(new ResampledImportableSource(source, samplerate, quality)); - } - - catch (...) { - - /* fall back to SndFile */ - -#endif - - try { - boost::shared_ptr<SndFileImportableSource> source(new SndFileImportableSource(path)); - - if (source->samplerate() == samplerate) { - return source; - } - - /* rewrap as a resampled source */ - - return boost::shared_ptr<ImportableSource>(new ResampledImportableSource(source, samplerate, quality)); - } - - catch (...) { - throw; // rethrow - } - -#ifdef HAVE_COREAUDIO - } -#endif -} - -static std::string -get_non_existent_filename (DataType type, const bool allow_replacing, const std::string destdir, const std::string& basename, uint channel, uint channels) -{ - char buf[PATH_MAX+1]; - bool goodfile = false; - string base(basename); - const char* ext = (type == DataType::AUDIO) ? "wav" : "mid"; - - do { - - if (type == DataType::AUDIO && channels == 2) { - if (channel == 0) { - snprintf (buf, sizeof(buf), "%s-L.wav", base.c_str()); - } else { - snprintf (buf, sizeof(buf), "%s-R.wav", base.c_str()); - } - } else if (channels > 1) { - snprintf (buf, sizeof(buf), "%s-c%d.%s", base.c_str(), channel, ext); - } else { - snprintf (buf, sizeof(buf), "%s.%s", base.c_str(), ext); - } - - - string tempname = destdir + "/" + buf; - if (!allow_replacing && Glib::file_test (tempname, Glib::FILE_TEST_EXISTS)) { - - /* if the file already exists, we must come up with - * a new name for it. for now we just keep appending - * _ to basename - */ - - base += "_"; - - } else { - - goodfile = true; - } - - } while ( !goodfile); - - return buf; -} - -static vector<string> -get_paths_for_new_sources (const bool allow_replacing, const string& import_file_path, const string& session_dir, uint channels) -{ - vector<string> new_paths; - const string basename = basename_nosuffix (import_file_path); - - SessionDirectory sdir(session_dir); - - for (uint n = 0; n < channels; ++n) { - - const DataType type = (import_file_path.rfind(".mid") != string::npos) - ? DataType::MIDI : DataType::AUDIO; - - std::string filepath = (type == DataType::MIDI) - ? sdir.midi_path().to_string() : sdir.sound_path().to_string(); - - filepath += '/'; - filepath += get_non_existent_filename (type, allow_replacing, filepath, basename, n, channels); - new_paths.push_back (filepath); - } - - return new_paths; -} - -static bool -map_existing_mono_sources (const vector<string>& new_paths, Session& sess, - uint samplerate, vector<boost::shared_ptr<Source> >& newfiles, Session *session) -{ - for (vector<string>::const_iterator i = new_paths.begin(); - i != new_paths.end(); ++i) - { - boost::shared_ptr<Source> source = session->source_by_path_and_channel(*i, 0); - - if (source == 0) { - error << string_compose(_("Could not find a source for %1 even though we are updating this file!"), (*i)) << endl; - return false; - } - - newfiles.push_back(boost::dynamic_pointer_cast<Source>(source)); - } - return true; -} - -static bool -create_mono_sources_for_writing (const vector<string>& new_paths, Session& sess, - uint samplerate, vector<boost::shared_ptr<Source> >& newfiles) -{ - for (vector<string>::const_iterator i = new_paths.begin(); - i != new_paths.end(); ++i) - { - boost::shared_ptr<Source> source; - - try - { - const DataType type = ((*i).rfind(".mid") != string::npos) - ? DataType::MIDI : DataType::AUDIO; - - source = SourceFactory::createWritable ( - type, - sess, - i->c_str(), - false, // destructive - samplerate - ); - } - catch (const failed_constructor& err) - { - error << string_compose (_("Unable to create file %1 during import"), *i) << endmsg; - return false; - } - - newfiles.push_back(boost::dynamic_pointer_cast<Source>(source)); - } - return true; -} - -static Glib::ustring -compose_status_message (const string& path, - uint file_samplerate, - uint session_samplerate, - uint current_file, - uint total_files) -{ - if (file_samplerate != session_samplerate) { - return string_compose (_("converting %1\n(resample from %2KHz to %3KHz)\n(%4 of %5)"), - Glib::path_get_basename (path), - file_samplerate/1000.0f, - session_samplerate/1000.0f, - current_file, total_files); - } - - return string_compose (_("converting %1\n(%2 of %3)"), - Glib::path_get_basename (path), - current_file, total_files); -} - -static void -write_audio_data_to_new_files (ImportableSource* source, Session::import_status& status, - vector<boost::shared_ptr<Source> >& newfiles) -{ - const nframes_t nframes = ResampledImportableSource::blocksize; - boost::shared_ptr<AudioFileSource> afs; - uint channels = source->channels(); - - boost::scoped_array<float> data(new float[nframes * channels]); - vector<boost::shared_array<Sample> > channel_data; - - for (uint n = 0; n < channels; ++n) { - channel_data.push_back(boost::shared_array<Sample>(new Sample[nframes])); - } - - uint read_count = 0; - status.progress = 0.0f; - - while (!status.cancel) { - - nframes_t nread, nfread; - uint x; - uint chn; - - if ((nread = source->read (data.get(), nframes)) == 0) { - break; - } - nfread = nread / channels; - - /* de-interleave */ - - for (chn = 0; chn < channels; ++chn) { - - nframes_t n; - for (x = chn, n = 0; n < nfread; x += channels, ++n) { - channel_data[chn][n] = (Sample) data[x]; - } - } - - /* flush to disk */ - - for (chn = 0; chn < channels; ++chn) { - if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(newfiles[chn])) != 0) { - afs->write (channel_data[chn].get(), nfread); - } - } - - read_count += nread; - status.progress = read_count / (source->ratio () * source->length() * channels); - } -} - -static void -write_midi_data_to_new_files (SMFReader* source, Session::import_status& status, - vector<boost::shared_ptr<Source> >& newfiles) -{ - MIDI::Event ev(0.0, 4, NULL, true); - - status.progress = 0.0f; - - try { - - for (unsigned i = 1; i <= source->num_tracks(); ++i) { - - boost::shared_ptr<SMFSource> smfs = boost::dynamic_pointer_cast<SMFSource>(newfiles[i-1]); - - source->seek_to_track(i); - - uint64_t t = 0; - uint32_t delta_t = 0; - uint32_t size = 0; - - while (!status.cancel) { - - if (source->read_event(4, ev.buffer(), &size, &delta_t) < 0) - break; - - t += delta_t; - ev.time() = (double)t / (double)source->ppqn(); - ev.size() = size; - - smfs->append_event_unlocked(Beats, ev); - if (status.progress < 0.99) - status.progress += 0.01; - } - - nframes_t timeline_position = 0; // FIXME: ? - - // FIXME: kluuuuudge: assumes tempo never changes after start - const double frames_per_beat = smfs->session().tempo_map().tempo_at( - timeline_position).frames_per_beat( - smfs->session().engine().frame_rate(), - smfs->session().tempo_map().meter_at(timeline_position)); - - smfs->update_length(0, (nframes_t) ceil ((t / (double)source->ppqn()) * frames_per_beat)); - - smfs->flush_header(); - smfs->flush_footer(); - - if (status.cancel) - break; - } - - } catch (...) { - error << "Corrupt MIDI file " << source->filename() << endl; - } -} - -static void -remove_file_source (boost::shared_ptr<Source> source) -{ - ::unlink (source->path().c_str()); -} - -// This function is still unable to cleanly update an existing source, even though -// it is possible to set the import_status flag accordingly. The functinality -// is disabled at the GUI until the Source implementations are able to provide -// the necessary API. -void -Session::import_audiofiles (import_status& status) -{ - uint32_t cnt = 1; - typedef vector<boost::shared_ptr<Source> > Sources; - Sources all_new_sources; - boost::shared_ptr<AudioFileSource> afs; - boost::shared_ptr<SMFSource> smfs; - uint channels = 0; - - status.sources.clear (); - - for (vector<Glib::ustring>::iterator p = status.paths.begin(); - p != status.paths.end() && !status.cancel; - ++p, ++cnt) - { - boost::shared_ptr<ImportableSource> source; - std::auto_ptr<SMFReader> smf_reader; - const DataType type = ((*p).rfind(".mid") != string::npos) ? - DataType::MIDI : DataType::AUDIO; - - if (type == DataType::AUDIO) { - try { - source = open_importable_source (*p, frame_rate(), status.quality); - channels = source->channels(); - } catch (const failed_constructor& err) { - error << string_compose(_("Import: cannot open input sound file \"%1\""), (*p)) << endmsg; - status.done = status.cancel = true; - return; - } - - } else { - try { - smf_reader = std::auto_ptr<SMFReader>(new SMFReader(*p)); - channels = smf_reader->num_tracks(); - } catch (const SMFReader::UnsupportedTime& err) { - error << _("Import: unsupported MIDI time stamp format") << endmsg; - status.done = status.cancel = true; - return; - } catch (...) { - error << _("Import: error reading MIDI file") << endmsg; - status.done = status.cancel = true; - return; - } - } - - vector<string> new_paths = get_paths_for_new_sources (status.replace_existing_source, *p, - get_best_session_directory_for_new_source (), - channels); - Sources newfiles; - - if (status.replace_existing_source) { - fatal << "THIS IS NOT IMPLEMENTED YET, IT SHOULD NEVER GET CALLED!!! DYING!" << endl; - status.cancel = !map_existing_mono_sources (new_paths, *this, frame_rate(), newfiles, this); - } else { - status.cancel = !create_mono_sources_for_writing (new_paths, *this, frame_rate(), newfiles); - } - - // copy on cancel/failure so that any files that were created will be removed below - std::copy (newfiles.begin(), newfiles.end(), std::back_inserter(all_new_sources)); - - if (status.cancel) break; - - for (Sources::iterator i = newfiles.begin(); i != newfiles.end(); ++i) { - if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(*i)) != 0) { - afs->prepare_for_peakfile_writes (); - } - } - - if (source) { // audio - status.doing_what = compose_status_message (*p, source->samplerate(), - frame_rate(), cnt, status.paths.size()); - write_audio_data_to_new_files (source.get(), status, newfiles); - } else if (smf_reader.get()) { // midi - status.doing_what = string_compose(_("loading MIDI file %1"), *p); - write_midi_data_to_new_files (smf_reader.get(), status, newfiles); - } - } - - if (!status.cancel) { - struct tm* now; - time_t xnow; - time (&xnow); - now = localtime (&xnow); - status.freeze = true; - - /* flush the final length(s) to the header(s) */ - - for (Sources::iterator x = all_new_sources.begin(); x != all_new_sources.end(); ) { - if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(*x)) != 0) { - afs->update_header(0, *now, xnow); - afs->done_with_peakfile_writes (); - } - - /* now that there is data there, requeue the file for analysis */ - - if (Config->get_auto_analyse_audio()) { - Analyser::queue_source_for_analysis (boost::static_pointer_cast<Source>(*x), false); - } - - /* don't create tracks for empty MIDI sources (channels) */ - if ((smfs = boost::dynamic_pointer_cast<SMFSource>(*x)) != 0 && smfs->is_empty()) { - x = all_new_sources.erase(x); - } else { - ++x; - } - } - - /* save state so that we don't lose these new Sources */ - - save_state (_name); - - std::copy (all_new_sources.begin(), all_new_sources.end(), - std::back_inserter(status.sources)); - } else { - // this can throw...but it seems very unlikely - std::for_each (all_new_sources.begin(), all_new_sources.end(), remove_file_source); - } - - status.done = true; -} - diff --git a/libs/ardour/internal_audio_port.cc b/libs/ardour/internal_audio_port.cc deleted file mode 100644 index e5362cde95..0000000000 --- a/libs/ardour/internal_audio_port.cc +++ /dev/null @@ -1,71 +0,0 @@ -/* - 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. -*/ - -#include <cassert> -#include <ardour/internal_audio_port.h> -#include <ardour/audioengine.h> - -using namespace ARDOUR; -using namespace std; - -void -InternalAudioPort::default_mixdown (const list<InternalPort*>& ports, AudioBuffer& dest, nframes_t cnt, nframes_t offset) -{ - list<InternalPort*>::const_iterator p = ports.begin(); - - dest.read_from ((dynamic_cast<AudioPort*>(*p))->get_audio_buffer(), cnt, offset); - - for (; p != ports.end(); ++p) { - dest.accumulate_from ((dynamic_cast<AudioPort*>(*p))->get_audio_buffer(), cnt, offset); - } -} - -InternalAudioPort::InternalAudioPort(const string& name, Flags flags) - : Port (DataType::AUDIO, flags) - , AudioPort (flags, engine->frames_per_cycle()) - , InternalPort (name, DataType::AUDIO, flags) -{ - _mixdown = default_mixdown; -} - -void -InternalAudioPort::set_mixdown_function (void (*func)(const list<InternalPort*>&, AudioBuffer&, nframes_t, nframes_t)) -{ - _mixdown = func; -} - -void -InternalAudioPort::reset () -{ - _buffer.resize (engine->frames_per_cycle()); - _buffer.silence (_buffer.size()); -} - -AudioBuffer& -InternalAudioPort::get_audio_buffer () -{ - if (_connections.empty()) { - return AudioPort::get_audio_buffer(); - } - - /* XXX what about offset/size being more dynamic ? */ - - (*_mixdown) (_connections, _buffer, _buffer.size(), 0); - - return _buffer; -} diff --git a/libs/ardour/internal_port.cc b/libs/ardour/internal_port.cc deleted file mode 100644 index cec11742e0..0000000000 --- a/libs/ardour/internal_port.cc +++ /dev/null @@ -1,163 +0,0 @@ -/* - 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. - -*/ - -#include <pbd/error.h> -#include <ardour/internal_port.h> -#include <ardour/audioengine.h> - -#include "i18n.h" - -using namespace ARDOUR; -using namespace std; - -AudioEngine* InternalPort::engine = 0; - -void -InternalPort::set_engine (AudioEngine* e) -{ - engine = e; -} - -InternalPort::InternalPort (const string& str, DataType type, Flags flags) - : Port (type, flags) -{ - set_name (str); -} - -InternalPort::~InternalPort () -{ - disconnect (); -} - -void -InternalPort::set_latency (nframes_t val) -{ - _latency = val; -} - -bool -InternalPort::connected_to (const string& portname) const -{ - /* caller must hold process lock */ - - for (list<InternalPort*>::const_iterator p = _connections.begin(); p != _connections.end(); ++p) { - if ((*p)->name() == portname) { - return true; - } - } - - return false; -} - -const char** -InternalPort::get_connections () const -{ - /* caller must hold process lock */ - - int i; - list<InternalPort*>::const_iterator p; - - if (_connections.empty()) { - return 0; - } - - char **names = (char**) malloc (sizeof (char*) * ( _connections.size() + 1)); - - - for (i = 0, p = _connections.begin(); p != _connections.end(); ++p, ++i) { - names[i] = (char*) (*p)->name().c_str(); - } - - names[i] = 0; - - return (const char**) names; -} - -int -InternalPort::connected() const -{ - /* caller must hold process lock */ - return !_connections.empty(); -} - -int -InternalPort::set_name (string str) -{ - _name = "internal:"; - _name += str; - - return 0; -} - -string -InternalPort::short_name () -{ - return _name.substr (9); -} - -void -InternalPort::connect (InternalPort& src, InternalPort& dst) -{ - /* caller must hold process lock */ - - src._connections.push_back (&dst); - dst._connections.push_back (&src); -} - -void -InternalPort::disconnect (InternalPort& a, InternalPort& b) -{ - /* caller must hold process lock */ - a._connections.remove (&b); - b._connections.remove (&a); -} - -int -InternalPort::disconnect () -{ - /* caller must hold process lock */ - - for (list<InternalPort*>::const_iterator p = _connections.begin(); p != _connections.end(); ) { - list<InternalPort*>::const_iterator tmp; - - tmp = p; - ++tmp; - - disconnect (*this, **p); - - p = tmp; - } - - _connections.clear (); - - return 0; -} - -int -InternalPort::reestablish () -{ - return 0; -} - -void -InternalPort::recompute_total_latency () const -{ - return; -} - diff --git a/libs/ardour/io.cc b/libs/ardour/io.cc deleted file mode 100644 index 5d4b41cf32..0000000000 --- a/libs/ardour/io.cc +++ /dev/null @@ -1,2612 +0,0 @@ -/* - 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. -*/ - -#include <fstream> -#include <algorithm> -#include <unistd.h> -#include <locale.h> -#include <errno.h> - -#include <sigc++/bind.h> - -#include <glibmm/thread.h> - -#include <pbd/xml++.h> -#include <pbd/replace_all.h> -#include <pbd/unknown_type.h> - -#include <ardour/audioengine.h> -#include <ardour/io.h> -#include <ardour/route.h> -#include <ardour/port.h> -#include <ardour/audio_port.h> -#include <ardour/midi_port.h> -#include <ardour/auto_bundle.h> -#include <ardour/session.h> -#include <ardour/cycle_timer.h> -#include <ardour/panner.h> -#include <ardour/buffer_set.h> -#include <ardour/meter.h> -#include <ardour/amp.h> - -#include "i18n.h" - -#include <cmath> - -/* - A bug in OS X's cmath that causes isnan() and isinf() to be - "undeclared". the following works around that -*/ - -#if defined(__APPLE__) && defined(__MACH__) -extern "C" int isnan (double); -extern "C" int isinf (double); -#endif - -#define BLOCK_PROCESS_CALLBACK() Glib::Mutex::Lock em (_session.engine().process_lock()) - -using namespace std; -using namespace ARDOUR; -using namespace PBD; - -const string IO::state_node_name = "IO"; -bool IO::connecting_legal = false; -bool IO::ports_legal = false; -bool IO::panners_legal = false; -sigc::signal<void> IO::Meter; -sigc::signal<int> IO::ConnectingLegal; -sigc::signal<int> IO::PortsLegal; -sigc::signal<int> IO::PannersLegal; -sigc::signal<void,ChanCount> IO::PortCountChanged; -sigc::signal<int> IO::PortsCreated; - -Glib::StaticMutex IO::m_meter_signal_lock = GLIBMM_STATIC_MUTEX_INIT; - -/* this is a default mapper of [0 .. 1.0] control values to a gain coefficient. - others can be imagined. -*/ - -#if 0 -static gain_t direct_control_to_gain (double fract) { - /* XXX Marcus writes: this doesn't seem right to me. but i don't have a better answer ... */ - /* this maxes at +6dB */ - return pow (2.0,(sqrt(sqrt(sqrt(fract)))*198.0-192.0)/6.0); -} - -static double direct_gain_to_control (gain_t gain) { - /* XXX Marcus writes: this doesn't seem right to me. but i don't have a better answer ... */ - if (gain == 0) return 0.0; - - return pow((6.0*log(gain)/log(2.0)+192.0)/198.0, 8.0); -} -#endif - -/** @param default_type The type of port that will be created by ensure_io - * and friends if no type is explicitly requested (to avoid breakage). - */ -IO::IO (Session& s, const string& name, - int input_min, int input_max, int output_min, int output_max, - DataType default_type, bool public_ports) - : Automatable (s, name), - _output_buffers (new BufferSet()), - _active(true), - _default_type (default_type), - _public_ports (public_ports), - _input_minimum (ChanCount::ZERO), - _input_maximum (ChanCount::INFINITE), - _output_minimum (ChanCount::ZERO), - _output_maximum (ChanCount::INFINITE) -{ - _panner = new Panner (name, _session); - _meter = new PeakMeter (_session); - - if (input_min > 0) { - _input_minimum = ChanCount(_default_type, input_min); - } - if (input_max >= 0) { - _input_maximum = ChanCount(_default_type, input_max); - } - if (output_min > 0) { - _output_minimum = ChanCount(_default_type, output_min); - } - if (output_max >= 0) { - _output_maximum = ChanCount(_default_type, output_max); - } - - _gain = 1.0; - _desired_gain = 1.0; - pending_state_node = 0; - no_panner_reset = false; - _phase_invert = false; - deferred_state = 0; - - boost::shared_ptr<AutomationList> gl( - new AutomationList(Parameter(GainAutomation), 0.0, 2.0, 1.0)); - - _gain_control = boost::shared_ptr<GainControl>( - new GainControl(X_("gaincontrol"), *this, gl)); - - add_control(_gain_control); - - apply_gain_automation = false; - - { - // IO::Meter is emitted from another thread so the - // Meter signal must be protected. - Glib::Mutex::Lock guard (m_meter_signal_lock); - m_meter_connection = Meter.connect (mem_fun (*this, &IO::meter)); - } - - // Connect to our own PortCountChanged signal to connect output buffers - IO::PortCountChanged.connect (mem_fun (*this, &IO::attach_buffers)); - - _session.add_controllable (_gain_control); - - create_bundles_for_inputs_and_outputs (); -} - -IO::IO (Session& s, const XMLNode& node, DataType dt) - : Automatable (s, "unnamed io"), - _output_buffers (new BufferSet()), - _active(true), - _default_type (dt) -{ - _meter = new PeakMeter (_session); - _public_ports = true; // XXX get this from node - _panner = 0; - deferred_state = 0; - no_panner_reset = false; - _desired_gain = 1.0; - _gain = 1.0; - - apply_gain_automation = false; - - boost::shared_ptr<AutomationList> gl( - new AutomationList(Parameter(GainAutomation), 0.0, 2.0, 1.0)); - - _gain_control = boost::shared_ptr<GainControl>( - new GainControl(X_("gaincontrol"), *this, gl)); - - add_control(_gain_control); - - set_state (node); - - { - // IO::Meter is emitted from another thread so the - // Meter signal must be protected. - Glib::Mutex::Lock guard (m_meter_signal_lock); - m_meter_connection = Meter.connect (mem_fun (*this, &IO::meter)); - } - - // Connect to our own PortCountChanged signal to connect output buffers - IO::PortCountChanged.connect (mem_fun (*this, &IO::attach_buffers)); - - _session.add_controllable (_gain_control); - - create_bundles_for_inputs_and_outputs (); -} - -IO::~IO () -{ - Glib::Mutex::Lock guard (m_meter_signal_lock); - Glib::Mutex::Lock lm (io_lock); - - BLOCK_PROCESS_CALLBACK (); - - for (PortSet::iterator i = _inputs.begin(); i != _inputs.end(); ++i) { - _session.engine().unregister_port (*i); - } - - for (PortSet::iterator i = _outputs.begin(); i != _outputs.end(); ++i) { - _session.engine().unregister_port (*i); - } - - m_meter_connection.disconnect(); - - delete _meter; - delete _panner; - delete _output_buffers; -} - -void -IO::silence (nframes_t nframes, nframes_t offset) -{ - /* io_lock, not taken: function must be called from Session::process() calltree */ - - for (PortSet::iterator i = _outputs.begin(); i != _outputs.end(); ++i) { - i->get_buffer().silence (nframes, offset); - } -} - -/** Deliver bufs to the IO's output ports - * - * This function should automatically do whatever it necessary to correctly deliver bufs - * to the outputs, eg applying gain or pan or whatever else needs to be done. - */ -void -IO::deliver_output (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset) -{ - // FIXME: type specific code doesn't actually need to be here, it will go away in time - - /* ********** AUDIO ********** */ - - // Apply gain if gain automation isn't playing - if ( ! apply_gain_automation) { - - gain_t dg = _gain; // desired gain - - { - Glib::Mutex::Lock dm (declick_lock, Glib::TRY_LOCK); - - if (dm.locked()) { - dg = _desired_gain; - } - - } - - if (dg != _gain || dg != 1.0) - Amp::run_in_place(bufs, nframes, _gain, dg, _phase_invert); - } - - // Use the panner to distribute audio to output port buffers - if (_panner && !_panner->empty() && !_panner->bypassed()) { - _panner->distribute (bufs, output_buffers(), start_frame, end_frame, nframes, offset); - } else { - const DataType type = DataType::AUDIO; - - // Copy any audio 1:1 to outputs - - BufferSet::iterator o = output_buffers().begin(type); - BufferSet::iterator i = bufs.begin(type); - BufferSet::iterator prev = i; - - while (i != bufs.end(type) && o != output_buffers().end (type)) { - o->read_from(*i, nframes, offset); - prev = i; - ++i; - ++o; - } - - /* extra outputs get a copy of the last buffer */ - - while (o != output_buffers().end(type)) { - o->read_from(*prev, nframes, offset); - ++o; - } - } - - /* ********** MIDI ********** */ - - // No MIDI, we're done here - if (bufs.count().n_midi() == 0) { - return; - } - - const DataType type = DataType::MIDI; - - // Copy any MIDI 1:1 to outputs - assert(bufs.count().n_midi() == output_buffers().count().n_midi()); - BufferSet::iterator o = output_buffers().begin(type); - for (BufferSet::iterator i = bufs.begin(type); i != bufs.end(type); ++i, ++o) { - o->read_from(*i, nframes, offset); - } -} - -void -IO::collect_input (BufferSet& outs, nframes_t nframes, nframes_t offset) -{ - assert(outs.available() >= n_inputs()); - - if (n_inputs() == ChanCount::ZERO) - return; - - outs.set_count(n_inputs()); - - for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) { - - BufferSet::iterator o = outs.begin(*t); - for (PortSet::iterator i = _inputs.begin(*t); i != _inputs.end(*t); ++i, ++o) { - o->read_from(i->get_buffer(), nframes, offset); - } - - } -} - -void -IO::just_meter_input (nframes_t start_frame, nframes_t end_frame, - nframes_t nframes, nframes_t offset) -{ - BufferSet& bufs = _session.get_scratch_buffers (n_inputs()); - - collect_input (bufs, nframes, offset); - - _meter->run_in_place(bufs, start_frame, end_frame, nframes, offset); -} - - -void -IO::check_bundles_connected_to_inputs () -{ - check_bundles (_bundles_connected_to_inputs, inputs()); -} - -void -IO::check_bundles_connected_to_outputs () -{ - check_bundles (_bundles_connected_to_outputs, outputs()); -} - -void -IO::check_bundles (std::vector<UserBundleInfo>& list, const PortSet& ports) -{ - std::vector<UserBundleInfo> new_list; - - for (std::vector<UserBundleInfo>::iterator i = list.begin(); i != list.end(); ++i) { - - uint32_t const N = i->bundle->nchannels (); - - if (ports.num_ports() < N) { - continue; - } - - bool ok = true; - for (uint32_t j = 0; j < N; ++j) { - /* Every port on bundle channel j must be connected to our input j */ - PortList const pl = i->bundle->channel_ports (j); - for (uint32_t k = 0; k < pl.size(); ++k) { - if (ports.port(j)->connected_to (pl[k]) == false) { - ok = false; - break; - } - } - - if (ok == false) { - break; - } - } - - if (ok) { - new_list.push_back (*i); - } else { - i->configuration_will_change.disconnect (); - i->configuration_has_changed.disconnect (); - i->ports_will_change.disconnect (); - i->ports_have_changed.disconnect (); - } - } - - list = new_list; -} - - -int -IO::disconnect_input (Port* our_port, string other_port, void* src) -{ - if (other_port.length() == 0 || our_port == 0) { - return 0; - } - - { - BLOCK_PROCESS_CALLBACK (); - - { - Glib::Mutex::Lock lm (io_lock); - - /* check that our_port is really one of ours */ - - if ( ! _inputs.contains(our_port)) { - return -1; - } - - /* disconnect it from the source */ - - if (_session.engine().disconnect (other_port, our_port->name())) { - error << string_compose(_("IO: cannot disconnect input port %1 from %2"), our_port->name(), other_port) << endmsg; - return -1; - } - - check_bundles_connected_to_inputs (); - } - } - - input_changed (ConnectionsChanged, src); /* EMIT SIGNAL */ - _session.set_dirty (); - - return 0; -} - -int -IO::connect_input (Port* our_port, string other_port, void* src) -{ - if (other_port.length() == 0 || our_port == 0) { - return 0; - } - - { - BLOCK_PROCESS_CALLBACK (); - - { - Glib::Mutex::Lock lm (io_lock); - - /* check that our_port is really one of ours */ - - if ( ! _inputs.contains(our_port) ) { - return -1; - } - - /* connect it to the source */ - - if (_session.engine().connect (other_port, our_port->name())) { - return -1; - } - } - } - - input_changed (ConnectionsChanged, src); /* EMIT SIGNAL */ - _session.set_dirty (); - return 0; -} - -int -IO::disconnect_output (Port* our_port, string other_port, void* src) -{ - if (other_port.length() == 0 || our_port == 0) { - return 0; - } - - { - BLOCK_PROCESS_CALLBACK (); - - { - Glib::Mutex::Lock lm (io_lock); - - /* check that our_port is really one of ours */ - - if ( ! _outputs.contains(our_port) ) { - return -1; - } - - /* disconnect it from the destination */ - - if (_session.engine().disconnect (our_port->name(), other_port)) { - error << string_compose(_("IO: cannot disconnect output port %1 from %2"), our_port->name(), other_port) << endmsg; - return -1; - } - - check_bundles_connected_to_outputs (); - } - } - - output_changed (ConnectionsChanged, src); /* EMIT SIGNAL */ - _session.set_dirty (); - return 0; -} - -int -IO::connect_output (Port* our_port, string other_port, void* src) -{ - if (other_port.length() == 0 || our_port == 0) { - return 0; - } - - { - BLOCK_PROCESS_CALLBACK (); - - - { - Glib::Mutex::Lock lm (io_lock); - - /* check that our_port is really one of ours */ - - if ( ! _outputs.contains(our_port) ) { - return -1; - } - - /* connect it to the destination */ - - if (_session.engine().connect (our_port->name(), other_port)) { - return -1; - } - } - } - - output_changed (ConnectionsChanged, src); /* EMIT SIGNAL */ - _session.set_dirty (); - return 0; -} - -int -IO::set_input (Port* other_port, void* src) -{ - /* this removes all but one ports, and connects that one port - to the specified source. - */ - - if (_input_minimum.n_total() > 1) { - /* sorry, you can't do this */ - return -1; - } - - if (other_port == 0) { - if (_input_minimum == ChanCount::ZERO) { - return ensure_inputs (ChanCount::ZERO, false, true, src); - } else { - return -1; - } - } - - if (ensure_inputs (ChanCount(other_port->type(), 1), true, true, src)) { - return -1; - } - - return connect_input (_inputs.port(0), other_port->name(), src); -} - -int -IO::remove_output_port (Port* port, void* src) -{ - IOChange change (NoChange); - - { - BLOCK_PROCESS_CALLBACK (); - - - { - Glib::Mutex::Lock lm (io_lock); - - if (n_outputs() <= _output_minimum) { - /* sorry, you can't do this */ - return -1; - } - - if (_outputs.remove(port)) { - change = IOChange (change|ConfigurationChanged); - - if (port->connected()) { - change = IOChange (change|ConnectionsChanged); - } - - _session.engine().unregister_port (*port); - check_bundles_connected_to_outputs (); - - setup_peak_meters (); - reset_panner (); - } - } - - PortCountChanged (n_outputs()); /* EMIT SIGNAL */ - } - - if (change == ConnectionsChanged) { - setup_bundles_for_inputs_and_outputs (); - } - - if (change != NoChange) { - output_changed (change, src); - _session.set_dirty (); - return 0; - } - - return -1; -} - -/** Add an output port. - * - * @param destination Name of input port to connect new port to. - * @param src Source for emitted ConfigurationChanged signal. - * @param type Data type of port. Default value (NIL) will use this IO's default type. - */ -int -IO::add_output_port (string destination, void* src, DataType type) -{ - Port* our_port; - - if (type == DataType::NIL) - type = _default_type; - - { - BLOCK_PROCESS_CALLBACK (); - - - { - Glib::Mutex::Lock lm (io_lock); - - if (n_outputs() >= _output_maximum) { - return -1; - } - - /* Create a new output port */ - - string portname = build_legal_port_name (type, false); - - if ((our_port = _session.engine().register_output_port (type, portname, _public_ports)) == 0) { - error << string_compose(_("IO: cannot register output port %1"), portname) << endmsg; - return -1; - } - - _outputs.add (our_port); - setup_peak_meters (); - reset_panner (); - } - - PortCountChanged (n_outputs()); /* EMIT SIGNAL */ - } - - if (destination.length()) { - if (_session.engine().connect (our_port->name(), destination)) { - return -1; - } - } - - // pan_changed (src); /* EMIT SIGNAL */ - output_changed (ConfigurationChanged, src); /* EMIT SIGNAL */ - setup_bundles_for_inputs_and_outputs (); - _session.set_dirty (); - - return 0; -} - -int -IO::remove_input_port (Port* port, void* src) -{ - IOChange change (NoChange); - - { - BLOCK_PROCESS_CALLBACK (); - - - { - Glib::Mutex::Lock lm (io_lock); - - if (n_inputs() <= _input_minimum) { - /* sorry, you can't do this */ - return -1; - } - - if (_inputs.remove(port)) { - change = IOChange (change|ConfigurationChanged); - - if (port->connected()) { - change = IOChange (change|ConnectionsChanged); - } - - _session.engine().unregister_port (*port); - check_bundles_connected_to_inputs (); - - setup_peak_meters (); - reset_panner (); - } - } - - PortCountChanged (n_inputs ()); /* EMIT SIGNAL */ - } - - if (change == ConfigurationChanged) { - setup_bundles_for_inputs_and_outputs (); - } - - if (change != NoChange) { - input_changed (change, src); - _session.set_dirty (); - return 0; - } - - return -1; -} - - -/** Add an input port. - * - * @param type Data type of port. The appropriate port type, and @ref Port will be created. - * @param destination Name of input port to connect new port to. - * @param src Source for emitted ConfigurationChanged signal. - */ -int -IO::add_input_port (string source, void* src, DataType type) -{ - Port* our_port; - - if (type == DataType::NIL) - type = _default_type; - - { - BLOCK_PROCESS_CALLBACK (); - - { - Glib::Mutex::Lock lm (io_lock); - - if (n_inputs() >= _input_maximum) { - return -1; - } - - /* Create a new input port */ - - string portname = build_legal_port_name (type, true); - - if ((our_port = _session.engine().register_input_port (type, portname, _public_ports)) == 0) { - error << string_compose(_("IO: cannot register input port %1"), portname) << endmsg; - return -1; - } - - _inputs.add (our_port); - setup_peak_meters (); - reset_panner (); - } - - PortCountChanged (n_inputs()); /* EMIT SIGNAL */ - } - - if (source.length()) { - - if (_session.engine().connect (source, our_port->name())) { - return -1; - } - } - - // pan_changed (src); /* EMIT SIGNAL */ - input_changed (ConfigurationChanged, src); /* EMIT SIGNAL */ - setup_bundles_for_inputs_and_outputs (); - _session.set_dirty (); - - return 0; -} - -int -IO::disconnect_inputs (void* src) -{ - { - BLOCK_PROCESS_CALLBACK (); - - { - Glib::Mutex::Lock lm (io_lock); - - for (PortSet::iterator i = _inputs.begin(); i != _inputs.end(); ++i) { - _session.engine().disconnect (*i); - } - - check_bundles_connected_to_inputs (); - } - } - - input_changed (ConnectionsChanged, src); /* EMIT SIGNAL */ - - return 0; -} - -int -IO::disconnect_outputs (void* src) -{ - { - BLOCK_PROCESS_CALLBACK (); - - { - Glib::Mutex::Lock lm (io_lock); - - for (PortSet::iterator i = _outputs.begin(); i != _outputs.end(); ++i) { - _session.engine().disconnect (*i); - } - - check_bundles_connected_to_outputs (); - } - } - - output_changed (ConnectionsChanged, src); /* EMIT SIGNAL */ - _session.set_dirty (); - - return 0; -} - -bool -IO::ensure_inputs_locked (ChanCount count, bool clear, void* src) -{ - Port* input_port = 0; - bool changed = false; - - - for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) { - - const size_t n = count.get(*t); - - /* remove unused ports */ - for (size_t i = n_inputs().get(*t); i > n; --i) { - input_port = _inputs.port(*t, i-1); - - assert(input_port); - _inputs.remove(input_port); - _session.engine().unregister_port (*input_port); - - changed = true; - } - - /* create any necessary new ports */ - while (n_inputs().get(*t) < n) { - - string portname = build_legal_port_name (*t, true); - - try { - - if ((input_port = _session.engine().register_input_port (*t, portname, _public_ports)) == 0) { - error << string_compose(_("IO: cannot register input port %1"), portname) << endmsg; - return -1; - } - } - - catch (AudioEngine::PortRegistrationFailure& err) { - setup_peak_meters (); - reset_panner (); - /* pass it on */ - throw AudioEngine::PortRegistrationFailure(); - } - - _inputs.add (input_port); - changed = true; - } - } - - if (changed) { - check_bundles_connected_to_inputs (); - setup_peak_meters (); - reset_panner (); - PortCountChanged (n_inputs()); /* EMIT SIGNAL */ - _session.set_dirty (); - } - - if (clear) { - /* disconnect all existing ports so that we get a fresh start */ - for (PortSet::iterator i = _inputs.begin(); i != _inputs.end(); ++i) { - _session.engine().disconnect (*i); - } - } - - return changed; -} - -/** Attach output_buffers to port buffers. - * - * Connected to IO's own PortCountChanged signal. - */ -void -IO::attach_buffers(ChanCount ignored) -{ - _output_buffers->attach_buffers(_outputs); -} - -int -IO::ensure_io (ChanCount in, ChanCount out, bool clear, void* src) -{ - bool in_changed = false; - bool out_changed = false; - bool need_pan_reset = false; - - in = min (_input_maximum, in); - - out = min (_output_maximum, out); - - if (in == n_inputs() && out == n_outputs() && !clear) { - return 0; - } - - { - BLOCK_PROCESS_CALLBACK (); - Glib::Mutex::Lock lm (io_lock); - - Port* port; - - if (n_outputs() != out) { - need_pan_reset = true; - } - - for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) { - - const size_t nin = in.get(*t); - const size_t nout = out.get(*t); - - Port* output_port = 0; - Port* input_port = 0; - - /* remove unused output ports */ - for (size_t i = n_outputs().get(*t); i > nout; --i) { - output_port = _outputs.port(*t, i-1); - - assert(output_port); - _outputs.remove(output_port); - _session.engine().unregister_port (*output_port); - - out_changed = true; - } - - /* remove unused input ports */ - for (size_t i = n_inputs().get(*t); i > nin; --i) { - input_port = _inputs.port(*t, i-1); - - assert(input_port); - _inputs.remove(input_port); - _session.engine().unregister_port (*input_port); - - in_changed = true; - } - - /* create any necessary new input ports */ - - while (n_inputs().get(*t) < nin) { - - string portname = build_legal_port_name (*t, true); - - try { - if ((port = _session.engine().register_input_port (*t, portname, _public_ports)) == 0) { - error << string_compose(_("IO: cannot register input port %1"), portname) << endmsg; - return -1; - } - } - - catch (AudioEngine::PortRegistrationFailure& err) { - setup_peak_meters (); - reset_panner (); - /* pass it on */ - throw AudioEngine::PortRegistrationFailure(); - } - - _inputs.add (port); - in_changed = true; - } - - /* create any necessary new output ports */ - - while (n_outputs().get(*t) < nout) { - - string portname = build_legal_port_name (*t, false); - - try { - if ((port = _session.engine().register_output_port (*t, portname, _public_ports)) == 0) { - error << string_compose(_("IO: cannot register output port %1"), portname) << endmsg; - return -1; - } - } - - catch (AudioEngine::PortRegistrationFailure& err) { - setup_peak_meters (); - reset_panner (); - /* pass it on */ - throw AudioEngine::PortRegistrationFailure (); - } - - _outputs.add (port); - out_changed = true; - } - } - - if (clear) { - - /* disconnect all existing ports so that we get a fresh start */ - - for (PortSet::iterator i = _inputs.begin(); i != _inputs.end(); ++i) { - _session.engine().disconnect (*i); - } - - for (PortSet::iterator i = _outputs.begin(); i != _outputs.end(); ++i) { - _session.engine().disconnect (*i); - } - } - - if (in_changed || out_changed) { - setup_peak_meters (); - reset_panner (); - } - } - - if (out_changed) { - check_bundles_connected_to_outputs (); - output_changed (ConfigurationChanged, src); /* EMIT SIGNAL */ - } - - if (in_changed) { - check_bundles_connected_to_inputs (); - input_changed (ConfigurationChanged, src); /* EMIT SIGNAL */ - } - - if (in_changed || out_changed) { - PortCountChanged (max (n_outputs(), n_inputs())); /* EMIT SIGNAL */ - setup_bundles_for_inputs_and_outputs (); - _session.set_dirty (); - } - - return 0; -} - -int -IO::ensure_inputs (ChanCount count, bool clear, bool lockit, void* src) -{ - bool changed = false; - - count = min (_input_maximum, count); - - if (count == n_inputs() && !clear) { - return 0; - } - - if (lockit) { - BLOCK_PROCESS_CALLBACK (); - Glib::Mutex::Lock im (io_lock); - changed = ensure_inputs_locked (count, clear, src); - } else { - changed = ensure_inputs_locked (count, clear, src); - } - - if (changed) { - input_changed (ConfigurationChanged, src); /* EMIT SIGNAL */ - setup_bundles_for_inputs_and_outputs (); - _session.set_dirty (); - } - return 0; -} - -bool -IO::ensure_outputs_locked (ChanCount count, bool clear, void* src) -{ - Port* output_port = 0; - bool changed = false; - bool need_pan_reset = false; - - if (n_outputs() != count) { - need_pan_reset = true; - } - - for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) { - - const size_t n = count.get(*t); - - /* remove unused ports */ - for (size_t i = n_outputs().get(*t); i > n; --i) { - output_port = _outputs.port(*t, i-1); - - assert(output_port); - _outputs.remove(output_port); - _session.engine().unregister_port (*output_port); - - changed = true; - } - - /* create any necessary new ports */ - while (n_outputs().get(*t) < n) { - - string portname = build_legal_port_name (*t, false); - - if ((output_port = _session.engine().register_output_port (*t, portname, _public_ports)) == 0) { - error << string_compose(_("IO: cannot register output port %1"), portname) << endmsg; - return -1; - } - - _outputs.add (output_port); - changed = true; - setup_peak_meters (); - - if (need_pan_reset) { - reset_panner (); - } - } - } - - if (changed) { - check_bundles_connected_to_outputs (); - PortCountChanged (n_outputs()); /* EMIT SIGNAL */ - _session.set_dirty (); - } - - if (clear) { - /* disconnect all existing ports so that we get a fresh start */ - for (PortSet::iterator i = _outputs.begin(); i != _outputs.end(); ++i) { - _session.engine().disconnect (*i); - } - } - - return changed; -} - -int -IO::ensure_outputs (ChanCount count, bool clear, bool lockit, void* src) -{ - bool changed = false; - - if (_output_maximum < ChanCount::INFINITE) { - count = min (_output_maximum, count); - if (count == n_outputs() && !clear) { - return 0; - } - } - - /* XXX caller should hold io_lock, but generally doesn't */ - - if (lockit) { - BLOCK_PROCESS_CALLBACK (); - Glib::Mutex::Lock im (io_lock); - changed = ensure_outputs_locked (count, clear, src); - } else { - changed = ensure_outputs_locked (count, clear, src); - } - - if (changed) { - output_changed (ConfigurationChanged, src); /* EMIT SIGNAL */ - setup_bundles_for_inputs_and_outputs (); - } - - return 0; -} - -gain_t -IO::effective_gain () const -{ - if (_gain_control->list()->automation_playback()) { - return _gain_control->get_value(); - } else { - return _desired_gain; - } -} - -void -IO::reset_panner () -{ - if (panners_legal) { - if (!no_panner_reset) { - _panner->reset (n_outputs().n_audio(), pans_required()); - } - } else { - panner_legal_c.disconnect (); - panner_legal_c = PannersLegal.connect (mem_fun (*this, &IO::panners_became_legal)); - } -} - -int -IO::panners_became_legal () -{ - _panner->reset (n_outputs().n_audio(), pans_required()); - _panner->load (); // automation - panner_legal_c.disconnect (); - return 0; -} - -void -IO::defer_pan_reset () -{ - no_panner_reset = true; -} - -void -IO::allow_pan_reset () -{ - no_panner_reset = false; - reset_panner (); -} - - -XMLNode& -IO::get_state (void) -{ - return state (true); -} - -XMLNode& -IO::state (bool full_state) -{ - XMLNode* node = new XMLNode (state_node_name); - char buf[64]; - string str; - vector<string>::iterator ci; - int n; - LocaleGuard lg (X_("POSIX")); - Glib::Mutex::Lock lm (io_lock); - - node->add_property("name", _name); - id().print (buf, sizeof (buf)); - node->add_property("id", buf); - - for ( - std::vector<UserBundleInfo>::iterator i = _bundles_connected_to_inputs.begin(); - i != _bundles_connected_to_inputs.end(); - ++i - ) - { - XMLNode* n = new XMLNode ("InputBundle"); - n->add_property ("name", i->bundle->name ()); - node->add_child_nocopy (*n); - } - - for ( - std::vector<UserBundleInfo>::iterator i = _bundles_connected_to_outputs.begin(); - i != _bundles_connected_to_outputs.end(); - ++i - ) - { - XMLNode* n = new XMLNode ("OutputBundle"); - n->add_property ("name", i->bundle->name ()); - node->add_child_nocopy (*n); - } - - str = ""; - - for (PortSet::iterator i = _inputs.begin(); i != _inputs.end(); ++i) { - - vector<string> connections; - - if (i->get_connections (connections)) { - - str += '{'; - - for (n = 0, ci = connections.begin(); ci != connections.end(); ++ci, ++n) { - if (n) { - str += ','; - } - - /* if its a connection to our own port, - return only the port name, not the - whole thing. this allows connections - to be re-established even when our - client name is different. - */ - - str += _session.engine().make_port_name_relative (*ci); - } - - str += '}'; - - } else { - str += "{}"; - } - } - - node->add_property ("inputs", str); - - str = ""; - - for (PortSet::iterator i = _outputs.begin(); i != _outputs.end(); ++i) { - - vector<string> connections; - - if (i->get_connections (connections)) { - - str += '{'; - - for (n = 0, ci = connections.begin(); ci != connections.end(); ++ci, ++n) { - if (n) { - str += ','; - } - - str += _session.engine().make_port_name_relative (*ci); - } - - str += '}'; - - } else { - str += "{}"; - } - } - - node->add_property ("outputs", str); - - node->add_child_nocopy (_panner->state (full_state)); - node->add_child_nocopy (_gain_control->get_state ()); - - snprintf (buf, sizeof(buf), "%2.12f", gain()); - node->add_property ("gain", buf); - - /* To make backwards compatibility a bit easier, write ChanCount::INFINITE to the session file - as -1. - */ - - int const in_max = _input_maximum == ChanCount::INFINITE ? -1 : _input_maximum.get(_default_type); - int const out_max = _output_maximum == ChanCount::INFINITE ? -1 : _output_maximum.get(_default_type); - - snprintf (buf, sizeof(buf)-1, "%d,%d,%d,%d", _input_minimum.get(_default_type), in_max, _output_minimum.get(_default_type), out_max); - - node->add_property ("iolimits", buf); - - /* automation */ - - if (full_state) - node->add_child_nocopy (get_automation_state()); - - return *node; -} - -int -IO::set_state (const XMLNode& node) -{ - const XMLProperty* prop; - XMLNodeConstIterator iter; - LocaleGuard lg (X_("POSIX")); - - /* force use of non-localized representation of decimal point, - since we use it a lot in XML files and so forth. - */ - - if (node.name() != state_node_name) { - error << string_compose(_("incorrect XML node \"%1\" passed to IO object"), node.name()) << endmsg; - return -1; - } - - if ((prop = node.property ("name")) != 0) { - _name = prop->value(); - /* used to set panner name with this, but no more */ - } - - if ((prop = node.property ("id")) != 0) { - _id = prop->value (); - } - - int in_min = -1; - int in_max = -1; - int out_min = -1; - int out_max = -1; - - if ((prop = node.property ("iolimits")) != 0) { - sscanf (prop->value().c_str(), "%d,%d,%d,%d", - &in_min, &in_max, &out_min, &out_max); - - /* Correct for the difference between the way we write things to session files and the - way things are described by ChanCount; see comments in io.h about what the different - ChanCount values mean. */ - - if (in_min < 0) { - _input_minimum = ChanCount::ZERO; - } else { - _input_minimum = ChanCount (_default_type, in_min); - } - - if (in_max < 0) { - _input_maximum = ChanCount::INFINITE; - } else { - _input_maximum = ChanCount (_default_type, in_max); - } - - if (out_min < 0) { - _output_minimum = ChanCount::ZERO; - } else { - _output_minimum = ChanCount (_default_type, out_min); - } - - if (out_max < 0) { - _output_maximum = ChanCount::INFINITE; - } else { - _output_maximum = ChanCount (_default_type, out_max); - } - } - - if ((prop = node.property ("gain")) != 0) { - set_gain (atof (prop->value().c_str()), this); - _gain = _desired_gain; - } - - if ((prop = node.property ("automation-state")) != 0 || (prop = node.property ("automation-style")) != 0) { - /* old school automation handling */ - } - - for (iter = node.children().begin(); iter != node.children().end(); ++iter) { - - if ((*iter)->name() == "Panner") { - if (_panner == 0) { - _panner = new Panner (_name, _session); - } - _panner->set_state (**iter); - } - - if ((*iter)->name() == X_("Automation")) { - - set_automation_state (*(*iter), Parameter(GainAutomation)); - } - - if ((*iter)->name() == X_("controllable")) { - if ((prop = (*iter)->property("name")) != 0 && prop->value() == "gaincontrol") { - _gain_control->set_state (**iter); - } - } - } - - if (ports_legal) { - - if (create_ports (node)) { - return -1; - } - - } else { - - port_legal_c = PortsLegal.connect (mem_fun (*this, &IO::ports_became_legal)); - } - - if (panners_legal) { - reset_panner (); - } else { - panner_legal_c = PannersLegal.connect (mem_fun (*this, &IO::panners_became_legal)); - } - - if (connecting_legal) { - - if (make_connections (node)) { - return -1; - } - - } else { - - connection_legal_c = ConnectingLegal.connect (mem_fun (*this, &IO::connecting_became_legal)); - } - - if (!ports_legal || !connecting_legal) { - pending_state_node = new XMLNode (node); - } - - return 0; -} - -int -IO::load_automation (string path) -{ - string fullpath; - ifstream in; - char line[128]; - uint32_t linecnt = 0; - float version; - LocaleGuard lg (X_("POSIX")); - - fullpath = _session.automation_dir(); - fullpath += path; - - in.open (fullpath.c_str()); - - if (!in) { - fullpath = _session.automation_dir(); - fullpath += _session.snap_name(); - fullpath += '-'; - fullpath += path; - - in.open (fullpath.c_str()); - - if (!in) { - error << string_compose(_("%1: cannot open automation event file \"%2\""), _name, fullpath) << endmsg; - return -1; - } - } - - clear_automation (); - - while (in.getline (line, sizeof(line), '\n')) { - char type; - nframes_t when; - double value; - - if (++linecnt == 1) { - if (memcmp (line, "version", 7) == 0) { - if (sscanf (line, "version %f", &version) != 1) { - error << string_compose(_("badly formed version number in automation event file \"%1\""), path) << endmsg; - return -1; - } - } else { - error << string_compose(_("no version information in automation event file \"%1\""), path) << endmsg; - return -1; - } - - continue; - } - - if (sscanf (line, "%c %" PRIu32 " %lf", &type, &when, &value) != 3) { - warning << string_compose(_("badly formatted automation event record at line %1 of %2 (ignored)"), linecnt, path) << endmsg; - continue; - } - - switch (type) { - case 'g': - _gain_control->list()->fast_simple_add (when, value); - break; - - case 's': - break; - - case 'm': - break; - - case 'p': - /* older (pre-1.0) versions of ardour used this */ - break; - - default: - warning << _("dubious automation event found (and ignored)") << endmsg; - } - } - - return 0; -} - -int -IO::connecting_became_legal () -{ - int ret; - - if (pending_state_node == 0) { - fatal << _("IO::connecting_became_legal() called without a pending state node") << endmsg; - /*NOTREACHED*/ - return -1; - } - - connection_legal_c.disconnect (); - - ret = make_connections (*pending_state_node); - - if (ports_legal) { - delete pending_state_node; - pending_state_node = 0; - } - - return ret; -} -int -IO::ports_became_legal () -{ - int ret; - - if (pending_state_node == 0) { - fatal << _("IO::ports_became_legal() called without a pending state node") << endmsg; - /*NOTREACHED*/ - return -1; - } - - port_legal_c.disconnect (); - - ret = create_ports (*pending_state_node); - - if (connecting_legal) { - delete pending_state_node; - pending_state_node = 0; - } - - return ret; -} - -int -IO::create_ports (const XMLNode& node) -{ - XMLProperty const * prop; - int num_inputs = 0; - int num_outputs = 0; - - if ((prop = node.property ("inputs")) != 0) { - num_inputs = count (prop->value().begin(), prop->value().end(), '{'); - } else if ((prop = node.property ("outputs")) != 0) { - num_outputs = count (prop->value().begin(), prop->value().end(), '{'); - } - - no_panner_reset = true; - - // FIXME: audio-only - if (ensure_io (ChanCount(DataType::AUDIO, num_inputs), ChanCount(DataType::AUDIO, num_outputs), true, this)) { - error << string_compose(_("%1: cannot create I/O ports"), _name) << endmsg; - return -1; - } - - no_panner_reset = false; - - set_deferred_state (); - - PortsCreated(); - return 0; -} - - -int -IO::make_connections (const XMLNode& node) -{ - XMLProperty const * prop; - - if ((prop = node.property ("inputs")) != 0) { - if (set_inputs (prop->value())) { - error << string_compose(_("improper input channel list in XML node (%1)"), prop->value()) << endmsg; - return -1; - } - } - - - if ((prop = node.property ("outputs")) != 0) { - if (set_outputs (prop->value())) { - error << string_compose(_("improper output channel list in XML node (%1)"), prop->value()) << endmsg; - return -1; - } - } - - for (XMLNodeConstIterator i = node.children().begin(); i != node.children().end(); ++i) { - - if ((*i)->name() == "InputBundle") { - XMLProperty const * prop = (*i)->property ("name"); - if (prop) { - boost::shared_ptr<Bundle> b = _session.bundle_by_name (prop->value()); - if (b) { - connect_input_ports_to_bundle (b, this); - } else { - error << string_compose(_("Unknown bundle \"%1\" listed for input of %2"), prop->value(), _name) << endmsg; - } - } - - } else if ((*i)->name() == "OutputBundle") { - XMLProperty const * prop = (*i)->property ("name"); - if (prop) { - boost::shared_ptr<Bundle> b = _session.bundle_by_name (prop->value()); - if (b) { - connect_output_ports_to_bundle (b, this); - } else { - error << string_compose(_("Unknown bundle \"%1\" listed for output of %2"), prop->value(), _name) << endmsg; - } - } - } - } - - return 0; -} - -int -IO::set_inputs (const string& str) -{ - vector<string> ports; - int i; - int n; - uint32_t nports; - - if ((nports = count (str.begin(), str.end(), '{')) == 0) { - return 0; - } - - // FIXME: audio-only - if (ensure_inputs (ChanCount(DataType::AUDIO, nports), true, true, this)) { - return -1; - } - - string::size_type start, end, ostart; - - ostart = 0; - start = 0; - end = 0; - i = 0; - - while ((start = str.find_first_of ('{', ostart)) != string::npos) { - start += 1; - - if ((end = str.find_first_of ('}', start)) == string::npos) { - error << string_compose(_("IO: badly formed string in XML node for inputs \"%1\""), str) << endmsg; - return -1; - } - - if ((n = parse_io_string (str.substr (start, end - start), ports)) < 0) { - error << string_compose(_("bad input string in XML node \"%1\""), str) << endmsg; - - return -1; - - } else if (n > 0) { - - for (int x = 0; x < n; ++x) { - connect_input (input (i), ports[x], this); - } - } - - ostart = end+1; - i++; - } - - return 0; -} - -int -IO::set_outputs (const string& str) -{ - vector<string> ports; - int i; - int n; - uint32_t nports; - - if ((nports = count (str.begin(), str.end(), '{')) == 0) { - return 0; - } - - // FIXME: audio-only - if (ensure_outputs (ChanCount(DataType::AUDIO, nports), true, true, this)) { - return -1; - } - - string::size_type start, end, ostart; - - ostart = 0; - start = 0; - end = 0; - i = 0; - - while ((start = str.find_first_of ('{', ostart)) != string::npos) { - start += 1; - - if ((end = str.find_first_of ('}', start)) == string::npos) { - error << string_compose(_("IO: badly formed string in XML node for outputs \"%1\""), str) << endmsg; - return -1; - } - - if ((n = parse_io_string (str.substr (start, end - start), ports)) < 0) { - error << string_compose(_("IO: bad output string in XML node \"%1\""), str) << endmsg; - - return -1; - - } else if (n > 0) { - - for (int x = 0; x < n; ++x) { - connect_output (output (i), ports[x], this); - } - } - - ostart = end+1; - i++; - } - - return 0; -} - -int -IO::parse_io_string (const string& str, vector<string>& ports) -{ - string::size_type pos, opos; - - if (str.length() == 0) { - return 0; - } - - pos = 0; - opos = 0; - - ports.clear (); - - while ((pos = str.find_first_of (',', opos)) != string::npos) { - ports.push_back (str.substr (opos, pos - opos)); - opos = pos + 1; - } - - if (opos < str.length()) { - ports.push_back (str.substr(opos)); - } - - return ports.size(); -} - -int -IO::parse_gain_string (const string& str, vector<string>& ports) -{ - string::size_type pos, opos; - - pos = 0; - opos = 0; - ports.clear (); - - while ((pos = str.find_first_of (',', opos)) != string::npos) { - ports.push_back (str.substr (opos, pos - opos)); - opos = pos + 1; - } - - if (opos < str.length()) { - ports.push_back (str.substr(opos)); - } - - return ports.size(); -} - -bool -IO::set_name (const string& requested_name) -{ - if (requested_name == _name) { - return true; - } - - string name; - Route *rt; - if ( (rt = dynamic_cast<Route *>(this))) { - name = Route::ensure_track_or_route_name(requested_name, _session); - } else { - name = requested_name; - } - - - /* replace all colons in the name. i wish we didn't have to do this */ - - if (replace_all (name, ":", "-")) { - warning << _("you cannot use colons to name objects with I/O connections") << endmsg; - } - - for (PortSet::iterator i = _inputs.begin(); i != _inputs.end(); ++i) { - string current_name = i->short_name(); - current_name.replace (current_name.find (_name), _name.length(), name); - i->set_name (current_name); - } - - for (PortSet::iterator i = _outputs.begin(); i != _outputs.end(); ++i) { - string current_name = i->short_name(); - current_name.replace (current_name.find (_name), _name.length(), name); - i->set_name (current_name); - } - - bool const r = SessionObject::set_name(name); - - setup_bundles_for_inputs_and_outputs (); - - return r; -} - -void -IO::set_input_minimum (ChanCount n) -{ - _input_minimum = n; -} - -void -IO::set_input_maximum (ChanCount n) -{ - _input_maximum = n; -} - -void -IO::set_output_minimum (ChanCount n) -{ - _output_minimum = n; -} - -void -IO::set_output_maximum (ChanCount n) -{ - _output_maximum = n; -} - -void -IO::set_port_latency (nframes_t nframes) -{ - Glib::Mutex::Lock lm (io_lock); - - for (PortSet::iterator i = _outputs.begin(); i != _outputs.end(); ++i) { - i->set_latency (nframes); - } -} - -nframes_t -IO::output_latency () const -{ - nframes_t max_latency; - nframes_t latency; - - max_latency = 0; - - /* io lock not taken - must be protected by other means */ - - for (PortSet::const_iterator i = _outputs.begin(); i != _outputs.end(); ++i) { - if ((latency = _session.engine().get_port_total_latency (*i)) > max_latency) { - max_latency = latency; - } - } - - return max_latency; -} - -nframes_t -IO::input_latency () const -{ - nframes_t max_latency; - nframes_t latency; - - max_latency = 0; - - /* io lock not taken - must be protected by other means */ - - for (PortSet::const_iterator i = _inputs.begin(); i != _inputs.end(); ++i) { - if ((latency = _session.engine().get_port_total_latency (*i)) > max_latency) { - max_latency = latency; - } - } - - return max_latency; -} - -int -IO::connect_input_ports_to_bundle (boost::shared_ptr<Bundle> c, void* src) -{ - { - BLOCK_PROCESS_CALLBACK (); - Glib::Mutex::Lock lm2 (io_lock); - - /* Connect to the bundle, not worrying about any connections - that are already made. */ - - uint32_t const channels = c->nchannels (); - - for (uint32_t n = 0; n < channels; ++n) { - const PortList& pl = c->channel_ports (n); - - for (PortList::const_iterator i = pl.begin(); i != pl.end(); ++i) { - - if (!_inputs.port(n)->connected_to (*i)) { - - if (_session.engine().connect (*i, _inputs.port(n)->name())) { - return -1; - } - } - - } - } - - /* If this is a UserBundle, make a note of what we've done */ - - boost::shared_ptr<UserBundle> ub = boost::dynamic_pointer_cast<UserBundle> (c); - if (ub) { - - /* See if we already know about this one */ - std::vector<UserBundleInfo>::iterator i = _bundles_connected_to_inputs.begin(); - while (i != _bundles_connected_to_inputs.end() && i->bundle != ub) { - ++i; - } - - if (i == _bundles_connected_to_inputs.end()) { - /* We don't, so make a note */ - _bundles_connected_to_inputs.push_back (UserBundleInfo (this, ub)); - } - } - } - - input_changed (IOChange (ConfigurationChanged|ConnectionsChanged), src); /* EMIT SIGNAL */ - return 0; -} - -int -IO::connect_output_ports_to_bundle (boost::shared_ptr<Bundle> c, void* src) -{ - { - BLOCK_PROCESS_CALLBACK (); - Glib::Mutex::Lock lm2 (io_lock); - - /* Connect to the bundle, not worrying about any connections - that are already made. */ - - uint32_t const channels = c->nchannels (); - - for (uint32_t n = 0; n < channels; ++n) { - - const PortList& pl = c->channel_ports (n); - - for (PortList::const_iterator i = pl.begin(); i != pl.end(); ++i) { - - if (!_outputs.port(n)->connected_to (*i)) { - - if (_session.engine().connect (_outputs.port(n)->name(), *i)) { - return -1; - } - } - } - } - - /* If this is a UserBundle, make a note of what we've done */ - - boost::shared_ptr<UserBundle> ub = boost::dynamic_pointer_cast<UserBundle> (c); - if (ub) { - - /* See if we already know about this one */ - std::vector<UserBundleInfo>::iterator i = _bundles_connected_to_outputs.begin(); - while (i != _bundles_connected_to_outputs.end() && i->bundle != ub) { - ++i; - } - - if (i == _bundles_connected_to_outputs.end()) { - /* We don't, so make a note */ - _bundles_connected_to_outputs.push_back (UserBundleInfo (this, ub)); - } - } - } - - output_changed (IOChange (ConnectionsChanged|ConfigurationChanged), src); /* EMIT SIGNAL */ - - return 0; -} - -int -IO::disable_connecting () -{ - connecting_legal = false; - return 0; -} - -int -IO::enable_connecting () -{ - connecting_legal = true; - return ConnectingLegal (); -} - -int -IO::disable_ports () -{ - ports_legal = false; - return 0; -} - -int -IO::enable_ports () -{ - ports_legal = true; - return PortsLegal (); -} - -int -IO::disable_panners (void) -{ - panners_legal = false; - return 0; -} - -int -IO::reset_panners () -{ - panners_legal = true; - return PannersLegal (); -} - -void -IO::bundle_configuration_will_change () -{ - //XXX -// connect_input_ports_to_bundle (_input_bundle, this); -} - -void -IO::bundle_configuration_has_changed () -{ - //XXX -// connect_input_ports_to_bundle (_input_bundle, this); -} - -void -IO::bundle_ports_will_change (int ignored) -{ -//XXX -// connect_output_ports_to_bundle (_output_bundle, this); -} - -void -IO::bundle_ports_have_changed (int ignored) -{ - //XXX -// connect_output_ports_to_bundle (_output_bundle, this); -} - -void -IO::GainControl::set_value (float val) -{ - // max gain at about +6dB (10.0 ^ ( 6 dB * 0.05)) - if (val > 1.99526231f) - val = 1.99526231f; - - _user_value = val; - _io.set_gain (val, this); - - Changed(); /* EMIT SIGNAL */ -} - -float -IO::GainControl::get_value (void) const -{ - return AutomationControl::get_value(); -} - -void -IO::setup_peak_meters() -{ - ChanCount max_streams = std::max(_inputs.count(), _outputs.count()); - _meter->configure_io(max_streams, max_streams); -} - -/** - Update the peak meters. - - The meter signal lock is taken to prevent modification of the - Meter signal while updating the meters, taking the meter signal - lock prior to taking the io_lock ensures that all IO will remain - valid while metering. -*/ -void -IO::update_meters() -{ - Glib::Mutex::Lock guard (m_meter_signal_lock); - Meter(); /* EMIT SIGNAL */ -} - -void -IO::meter () -{ - // FIXME: Ugly. Meter should manage the lock, if it's necessary - - Glib::Mutex::Lock lm (io_lock); // READER: meter thread. - _meter->meter(); -} - -void -IO::clear_automation () -{ - Automatable::clear_automation (); // clears gain automation - _panner->clear_automation (); -} - -void -IO::set_parameter_automation_state (Parameter param, AutoState state) -{ - // XXX: would be nice to get rid of this special hack - - if (param.type() == GainAutomation) { - - bool changed = false; - - { - Glib::Mutex::Lock lm (_automation_lock); - - boost::shared_ptr<AutomationList> gain_auto = _gain_control->list(); - - if (state != gain_auto->automation_state()) { - changed = true; - _last_automation_snapshot = 0; - gain_auto->set_automation_state (state); - - if (state != Off) { - // FIXME: shouldn't this use Curve? - set_gain (gain_auto->eval (_session.transport_frame()), this); - } - } - } - - if (changed) { - _session.set_dirty (); - } - - } else { - Automatable::set_parameter_automation_state(param, state); - } -} - -void -IO::inc_gain (gain_t factor, void *src) -{ - if (_desired_gain == 0.0f) - set_gain (0.000001f + (0.000001f * factor), src); - else - set_gain (_desired_gain + (_desired_gain * factor), src); -} - -void -IO::set_gain (gain_t val, void *src) -{ - // max gain at about +6dB (10.0 ^ ( 6 dB * 0.05)) - if (val > 1.99526231f) - val = 1.99526231f; - - if (src != _gain_control.get()) { - _gain_control->set_value(val); - // bit twisty, this will come back and call us again - // (this keeps control in sync with reality) - return; - } - - { - Glib::Mutex::Lock dm (declick_lock); - _desired_gain = val; - } - - if (_session.transport_stopped()) { - _gain = val; - } - - if (_session.transport_stopped() && src != 0 && src != this && _gain_control->list()->automation_write()) { - _gain_control->list()->add (_session.transport_frame(), val); - - } - - _session.set_dirty(); -} - -void -IO::start_pan_touch (uint32_t which) -{ - if (which < _panner->size()) { - (*_panner)[which]->pan_control()->list()->start_touch(); - } -} - -void -IO::end_pan_touch (uint32_t which) -{ - if (which < _panner->size()) { - (*_panner)[which]->pan_control()->list()->stop_touch(); - } - -} - -void -IO::automation_snapshot (nframes_t now, bool force) -{ - Automatable::automation_snapshot (now, force); - - if (_last_automation_snapshot > now || (now - _last_automation_snapshot) > _automation_interval) { - _panner->snapshot (now); - } - - _panner->snapshot (now); - _last_automation_snapshot = now; -} - -void -IO::transport_stopped (nframes_t frame) -{ - _gain_control->list()->reposition_for_rt_add (frame); - - if (_gain_control->list()->automation_state() != Off) { - - /* the src=0 condition is a special signal to not propagate - automation gain changes into the mix group when locating. - */ - - // FIXME: shouldn't this use Curve? - set_gain (_gain_control->list()->eval (frame), 0); - } - - _panner->transport_stopped (frame); -} - -string -IO::build_legal_port_name (DataType type, bool in) -{ - const int name_size = jack_port_name_size(); - int limit; - string suffix; - int maxports; - - if (type == DataType::AUDIO) { - suffix = _("audio"); - } else if (type == DataType::MIDI) { - suffix = _("midi"); - } else { - throw unknown_type(); - } - - if (in) { - suffix += _("_in"); - maxports = _input_maximum.get(type); - } else { - suffix += _("_out"); - maxports = _output_maximum.get(type); - } - - if (maxports == 1) { - // allow space for the slash + the suffix - limit = name_size - _session.engine().client_name().length() - (suffix.length() + 1); - char buf[name_size+1]; - snprintf (buf, name_size+1, ("%.*s/%s"), limit, _name.c_str(), suffix.c_str()); - return string (buf); - } - - // allow up to 4 digits for the output port number, plus the slash, suffix and extra space - - limit = name_size - _session.engine().client_name().length() - (suffix.length() + 5); - - char buf1[name_size+1]; - char buf2[name_size+1]; - - snprintf (buf1, name_size+1, ("%.*s/%s"), limit, _name.c_str(), suffix.c_str()); - - int port_number; - - if (in) { - port_number = find_input_port_hole (buf1); - } else { - port_number = find_output_port_hole (buf1); - } - - snprintf (buf2, name_size+1, "%s %d", buf1, port_number); - - return string (buf2); -} - -int32_t -IO::find_input_port_hole (const char* base) -{ - /* CALLER MUST HOLD IO LOCK */ - - uint32_t n; - - if (_inputs.empty()) { - return 1; - } - - /* we only allow up to 4 characters for the port number - */ - - for (n = 1; n < 9999; ++n) { - char buf[jack_port_name_size()]; - PortSet::iterator i = _inputs.begin(); - - snprintf (buf, jack_port_name_size(), _("%s %u"), base, n); - - for ( ; i != _inputs.end(); ++i) { - if (i->short_name() == buf) { - break; - } - } - - if (i == _inputs.end()) { - break; - } - } - return n; -} - -int32_t -IO::find_output_port_hole (const char* base) -{ - /* CALLER MUST HOLD IO LOCK */ - - uint32_t n; - - if (_outputs.empty()) { - return 1; - } - - /* we only allow up to 4 characters for the port number - */ - - for (n = 1; n < 9999; ++n) { - char buf[jack_port_name_size()]; - PortSet::iterator i = _outputs.begin(); - - snprintf (buf, jack_port_name_size(), _("%s %u"), base, n); - - for ( ; i != _outputs.end(); ++i) { - if (i->short_name() == buf) { - break; - } - } - - if (i == _outputs.end()) { - break; - } - } - - return n; -} - -void -IO::set_active (bool yn) -{ - _active = yn; - active_changed(); /* EMIT SIGNAL */ -} - - -AudioPort* -IO::audio_input(uint32_t n) const -{ - return dynamic_cast<AudioPort*>(input(n)); -} - -AudioPort* -IO::audio_output(uint32_t n) const -{ - return dynamic_cast<AudioPort*>(output(n)); -} - -MidiPort* -IO::midi_input(uint32_t n) const -{ - return dynamic_cast<MidiPort*>(input(n)); -} - -MidiPort* -IO::midi_output(uint32_t n) const -{ - return dynamic_cast<MidiPort*>(output(n)); -} - -void -IO::set_phase_invert (bool yn, void *src) -{ - if (_phase_invert != yn) { - _phase_invert = yn; - // phase_invert_changed (src); /* EMIT SIGNAL */ - } -} - -void -IO::set_denormal_protection (bool yn, void *src) -{ - if (_denormal_protection != yn) { - _denormal_protection = yn; - // denormal_protection_changed (src); /* EMIT SIGNAL */ - } -} - -void -IO::update_port_total_latencies () -{ - /* io_lock, not taken: function must be called from Session::process() calltree */ - - for (PortSet::iterator i = _inputs.begin(); i != _inputs.end(); ++i) { - _session.engine().update_total_latency (*i); - } - - for (PortSet::iterator i = _outputs.begin(); i != _outputs.end(); ++i) { - _session.engine().update_total_latency (*i); - } -} - - -/** - * Setup bundles that describe our inputs and outputs. - */ - -void -IO::setup_bundles_for_inputs_and_outputs () -{ - char buf[32]; - - snprintf(buf, sizeof (buf), _("%s in"), _name.c_str()); - _bundle_for_inputs->set_name (buf); - uint32_t const ni = inputs().num_ports(); - _bundle_for_inputs->set_channels (ni); - for (uint32_t i = 0; i < ni; ++i) { - _bundle_for_inputs->set_port (i, inputs().port(i)->name()); - } - - snprintf(buf, sizeof (buf), _("%s out"), _name.c_str()); - _bundle_for_outputs->set_name (buf); - uint32_t const no = outputs().num_ports(); - _bundle_for_outputs->set_channels (no); - for (uint32_t i = 0; i < no; ++i) { - _bundle_for_outputs->set_port (i, outputs().port(i)->name()); - } -} - - -/** - * Create and setup bundles that describe our inputs and outputs. - */ - -void -IO::create_bundles_for_inputs_and_outputs () -{ - _bundle_for_inputs = boost::shared_ptr<AutoBundle> (new AutoBundle (true)); - _bundle_for_outputs = boost::shared_ptr<AutoBundle> (new AutoBundle (false)); - setup_bundles_for_inputs_and_outputs (); -} - -/** Add a bundle to a list if is connected to our inputs. - * @param b Bundle to check. - * @param bundles List to add to. - */ -void -IO::maybe_add_input_bundle_to_list (boost::shared_ptr<Bundle> b, std::vector<boost::shared_ptr<Bundle> >* bundles) -{ - boost::shared_ptr<AutoBundle> ab = boost::dynamic_pointer_cast<AutoBundle, Bundle> (b); - if (ab == 0 || ab->ports_are_outputs() == false) { - return; - } - - if (ab->nchannels () != n_inputs().n_total ()) { - return; - } - - for (uint32_t i = 0; i < n_inputs().n_total (); ++i) { - - PortList const & pl = b->channel_ports (i); - - if (pl.empty()) { - return; - } - - if (!input(i)->connected_to (pl[0])) { - return; - } - } - - bundles->push_back (b); -} - -/** @return Bundles connected to our inputs */ -std::vector<boost::shared_ptr<Bundle> > -IO::bundles_connected_to_inputs () -{ - std::vector<boost::shared_ptr<Bundle> > bundles; - - /* User bundles */ - for (std::vector<UserBundleInfo>::iterator i = _bundles_connected_to_inputs.begin(); i != _bundles_connected_to_inputs.end(); ++i) { - bundles.push_back (i->bundle); - } - - /* Auto bundles */ - _session.foreach_bundle ( - sigc::bind (sigc::mem_fun (*this, &IO::maybe_add_input_bundle_to_list), &bundles) - ); - - return bundles; -} - - -/** Add a bundle to a list if is connected to our outputs. - * @param b Bundle to check. - * @param bundles List to add to. - */ -void -IO::maybe_add_output_bundle_to_list (boost::shared_ptr<Bundle> b, std::vector<boost::shared_ptr<Bundle> >* bundles) -{ - boost::shared_ptr<AutoBundle> ab = boost::dynamic_pointer_cast<AutoBundle, Bundle> (b); - if (ab == 0 || ab->ports_are_inputs() == false) { - return; - } - - if (ab->nchannels () != n_outputs().n_total ()) { - return; - } - - for (uint32_t i = 0; i < n_outputs().n_total (); ++i) { - - PortList const & pl = b->channel_ports (i); - - if (pl.empty()) { - return; - } - - if (!output(i)->connected_to (pl[0])) { - return; - } - } - - bundles->push_back (b); -} - - -/* @return Bundles connected to our outputs */ -std::vector<boost::shared_ptr<Bundle> > -IO::bundles_connected_to_outputs () -{ - std::vector<boost::shared_ptr<Bundle> > bundles; - - /* User bundles */ - for (std::vector<UserBundleInfo>::iterator i = _bundles_connected_to_outputs.begin(); i != _bundles_connected_to_outputs.end(); ++i) { - bundles.push_back (i->bundle); - } - - /* Auto bundles */ - _session.foreach_bundle ( - sigc::bind (sigc::mem_fun (*this, &IO::maybe_add_output_bundle_to_list), &bundles) - ); - - return bundles; -} - - -IO::UserBundleInfo::UserBundleInfo (IO* io, boost::shared_ptr<UserBundle> b) -{ - bundle = b; - configuration_will_change = b->ConfigurationWillChange.connect ( - sigc::mem_fun (*io, &IO::bundle_configuration_will_change) - ); - configuration_has_changed = b->ConfigurationHasChanged.connect ( - sigc::mem_fun (*io, &IO::bundle_configuration_has_changed) - ); - ports_will_change = b->PortsWillChange.connect ( - sigc::mem_fun (*io, &IO::bundle_ports_will_change) - ); - ports_have_changed = b->PortsHaveChanged.connect ( - sigc::mem_fun (*io, &IO::bundle_ports_have_changed) - ); -} - diff --git a/libs/ardour/io_processor.cc b/libs/ardour/io_processor.cc deleted file mode 100644 index 9802c83330..0000000000 --- a/libs/ardour/io_processor.cc +++ /dev/null @@ -1,107 +0,0 @@ -/* - 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. - -*/ - -#include <fstream> -#include <algorithm> -#include <string> -#include <cerrno> -#include <unistd.h> -#include <sstream> - -#include <sigc++/bind.h> - -#include <pbd/xml++.h> -#include <pbd/enumwriter.h> - -#include <ardour/io_processor.h> -#include <ardour/session.h> -#include <ardour/utils.h> -#include <ardour/send.h> -#include <ardour/port_insert.h> -#include <ardour/plugin_insert.h> - -#include "i18n.h" - -using namespace std; -using namespace ARDOUR; -using namespace PBD; - -IOProcessor::IOProcessor (Session& s, const string& name, Placement p, - int input_min, int input_max, - int output_min, int output_max) - : Processor(s, name, p) - , _io(new IO(s, name, input_min, input_max, output_min, output_max)) -{ - _active = false; - _sort_key = 0; - _gui = 0; - _extra_xml = 0; -} - -IOProcessor::~IOProcessor () -{ - notify_callbacks (); -} - -XMLNode& -IOProcessor::state (bool full_state) -{ - XMLNode& node = Processor::state(full_state); - - node.add_child_nocopy (_io->state (full_state)); - - return node; -} - -int -IOProcessor::set_state (const XMLNode& node) -{ - const XMLProperty *prop; - - Processor::set_state(node); - - XMLNodeList nlist = node.children(); - XMLNodeIterator niter; - bool have_io = false; - - for (niter = nlist.begin(); niter != nlist.end(); ++niter) { - if ((*niter)->name() == IO::state_node_name) { - have_io = true; - _io->set_state(**niter); - - // legacy sessions: use IO name - if ((prop = node.property ("name")) == 0) { - set_name(_io->name()); - } - } - } - - if (!have_io) { - error << _("XML node describing a redirect is missing an IO node") << endmsg; - return -1; - } - - return 0; -} - -void -IOProcessor::silence (nframes_t nframes, nframes_t offset) -{ - _io->silence(nframes, offset); -} diff --git a/libs/ardour/jack_audio_port.cc b/libs/ardour/jack_audio_port.cc deleted file mode 100644 index 7ce00b8f11..0000000000 --- a/libs/ardour/jack_audio_port.cc +++ /dev/null @@ -1,55 +0,0 @@ -/* - 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. -*/ - -#include <cassert> -#include <ardour/audioengine.h> -#include <ardour/jack_audio_port.h> - -using namespace ARDOUR; - -JackAudioPort::JackAudioPort (const std::string& name, Flags flgs, AudioBuffer* buf) - : Port (name, flgs) - , JackPort (name, DataType::AUDIO, flgs) - , BaseAudioPort (name, flgs) -{ - if (buf) { - - _buffer = buf; - _own_buffer = false; - - } else { - - /* data space will be provided by JACK */ - - _buffer = new AudioBuffer (0); - _own_buffer = true; - } -} - -int -JackAudioPort::reestablish () -{ - int ret = JackPort::reestablish (); - - if (ret == 0 && _flags & IsOutput) { - _buffer->clear (); - } - - return ret; -} - diff --git a/libs/ardour/jack_midi_port.cc b/libs/ardour/jack_midi_port.cc deleted file mode 100644 index 6d8e4c8c5d..0000000000 --- a/libs/ardour/jack_midi_port.cc +++ /dev/null @@ -1,91 +0,0 @@ -/* - 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. -*/ - -#include <cassert> -#include <ardour/jack_midi_port.h> - -using namespace ARDOUR; -JackMidiPort::JackMidiPort (const std::string& name, Flags flgs, MidiBuffer* buf) - : Port (name, flgs) - , JackPort (name, DataType::MIDI, flgs) - , BaseMidiPort (name, flgs) -{ - // MIDI ports always need a buffer since jack buffer format is different - assert(buf); - - _buffer = buf; - _own_buffer = false; -} - -void -JackMidiPort::cycle_start (nframes_t nframes, nframes_t offset) -{ - /* FIXME: offset */ - - _buffer->clear(); - assert(_buffer->size() == 0); - - if (_flags & IsOutput) { - return; - } - - // We're an input - copy Jack events to internal buffer - - void* jack_buffer = jack_port_get_buffer(_port, nframes); - const nframes_t event_count = jack_midi_get_event_count(jack_buffer); - - assert(event_count < _buffer->capacity()); - - jack_midi_event_t ev; - - for (nframes_t i=0; i < event_count; ++i) { - - jack_midi_event_get (&ev, jack_buffer, i); - - _buffer->push_back (ev); - } - - assert(_buffer->size() == event_count); - - /*if (_buffer->size() > 0) - cerr << "JackMIDIPort got " << event_count << " events (buf " << _buffer << ")" << endl;*/ -} - -void -JackMidiPort::cycle_end (nframes_t nframes, nframes_t offset) -{ - /* FIXME: offset */ - - if (_flags & IsInput) { - return; - } - - // We're an output - copy events from source buffer to Jack buffer - - void* jack_buffer = jack_port_get_buffer (_port, nframes); - - jack_midi_clear_buffer (jack_buffer); - - for (MidiBuffer::iterator i = _buffer->begin(); i != _buffer->end(); ++i) { - const MIDI::Event& ev = *i; - // event times should be frames, relative to cycle start - assert(ev.time() >= 0); - assert(ev.time() < nframes); - jack_midi_event_write (jack_buffer, (jack_nframes_t) ev.time(), ev.buffer(), ev.size()); - } -} diff --git a/libs/ardour/jack_port.cc b/libs/ardour/jack_port.cc deleted file mode 100644 index 5fac52af68..0000000000 --- a/libs/ardour/jack_port.cc +++ /dev/null @@ -1,179 +0,0 @@ -/* - 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. - -*/ - -#include <pbd/error.h> - -#include <ardour/jack_port.h> -#include <ardour/audioengine.h> - -#include "i18n.h" - -using namespace ARDOUR; -using namespace PBD; -using namespace std; - -JackPort::JackPort (const std::string& name, DataType type, Flags flgs) - : Port (name, flgs), _port (0) -{ - _port = jack_port_register (engine->jack(), name.c_str(), type.to_jack_type(), flgs, 0); - - if (_port == 0) { - throw failed_constructor(); - } - - _flags = flgs; - _type = type; - _name = jack_port_name (_port); -} - -JackPort::~JackPort () -{ - cerr << "deleting jack port " << _name << endl; - - jack_port_unregister (engine->jack(), _port); -} - -int -JackPort::set_name (const string& str) -{ - int ret; - - if ((ret = jack_port_set_name (_port, str.c_str())) == 0) { - _name = str; - } - - return ret; -} - -int -JackPort::disconnect () -{ - return jack_port_disconnect (engine->jack(), _port); -} - -nframes_t -JackPort::total_latency () const -{ - return jack_port_get_total_latency (engine->jack(), _port); -} - -int -JackPort::reestablish () -{ - string short_name; - - short_name = _name.substr (_name.find_last_of (':') + 1); - - _port = jack_port_register (engine->jack(), short_name.c_str(), type().to_jack_type(), _flags, 0); - - if (_port == 0) { - error << string_compose (_("could not reregister %1"), _name) << endmsg; - return -1; - } - - reset (); - - - return 0; -} - -void -JackPort::recompute_total_latency () const -{ -#ifdef HAVE_JACK_RECOMPUTE_LATENCY - jack_recompute_total_latency (engine->jack(), _port); -#endif -} - -int -JackPort::reconnect () -{ - /* caller must hold process lock; intended to be used only after reestablish() */ - - for (set<string>::iterator i = _named_connections.begin(); i != _named_connections.end(); ++i) { - if (connect (*i)) { - return -1; - } - } - - return 0; -} - -int -JackPort::connect (const std::string& other) -{ - int ret; - - if (_flags & IsOutput) { - /* this is the source */ - ret = jack_connect (engine->jack(), _name.c_str(), other.c_str()); - } else { - ret = jack_connect (engine->jack(), other.c_str(), _name.c_str()); - } - - if (ret == 0) { - _named_connections.insert (other); - } - - return ret; -} - -int -JackPort::disconnect (const std::string& other) -{ - int ret; - - if (_flags & IsInput) { - ret = jack_disconnect (engine->jack(), other.c_str(), _name.c_str()); - } else { - ret = jack_disconnect (engine->jack(), _name.c_str(), other.c_str()); - } - - set<string>::iterator i = _named_connections.find (other); - - if (i != _named_connections.end()) { - _named_connections.erase (i); - } - - return ret; -} - -int -JackPort::disconnect_all () -{ - _named_connections.clear (); - return jack_port_disconnect (engine->jack(), _port); -} - -int -JackPort::get_connections (vector<string>& names) const -{ - const char** cstrs = jack_port_get_connections (_port); - int i; - - if (!cstrs) { - return 0; - } - - for (i = 0; cstrs[i]; ++i) { - names.push_back (string (cstrs[i])); - } - - return i; -} diff --git a/libs/ardour/jack_slave.cc b/libs/ardour/jack_slave.cc deleted file mode 100644 index f65be1deea..0000000000 --- a/libs/ardour/jack_slave.cc +++ /dev/null @@ -1,95 +0,0 @@ -/* - 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. - -*/ - -#include <iostream> - -#include <errno.h> -#include <jack/jack.h> -#include <jack/transport.h> - -#include <ardour/slave.h> -#include <ardour/session.h> - -#include "i18n.h" - -using namespace ARDOUR; -using namespace sigc; - -JACK_Slave::JACK_Slave (jack_client_t* j) - : jack (j) -{ - float x; - nframes_t p; - /* call this to initialize things */ - speed_and_position (x, p); -} - -JACK_Slave::~JACK_Slave () -{ -} - -void -JACK_Slave::reset_client (jack_client_t* j) -{ - jack = j; -} - -bool -JACK_Slave::locked() const -{ - return true; -} - -bool -JACK_Slave::ok() const -{ - return true; -} - -bool -JACK_Slave::speed_and_position (float& sp, nframes_t& position) -{ - jack_position_t pos; - jack_transport_state_t state; - - state = jack_transport_query (jack, &pos); - - switch (state) { - case JackTransportStopped: - speed = 0; - _starting = false; - break; - case JackTransportRolling: - speed = 1.0; - _starting = false; - break; - case JackTransportLooping: - speed = 1.0; - _starting = false; - break; - case JackTransportStarting: - _starting = true; - // don't adjust speed here, just leave it as it was - break; - } - - sp = speed; - position = pos.frame; - return true; -} diff --git a/libs/ardour/ladspa_plugin.cc b/libs/ardour/ladspa_plugin.cc deleted file mode 100644 index 29f2d16767..0000000000 --- a/libs/ardour/ladspa_plugin.cc +++ /dev/null @@ -1,663 +0,0 @@ -/* - 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. - -*/ - -#define __STDC_FORMAT_MACROS 1 -#include <inttypes.h> - -#include <vector> -#include <string> - -#include <cstdlib> -#include <cstdio> // so libraptor doesn't complain -#include <cmath> -#include <dirent.h> -#include <sys/stat.h> -#include <cerrno> - -#include <lrdf.h> - -#include <pbd/compose.h> -#include <pbd/error.h> -#include <pbd/xml++.h> - -#include <midi++/manager.h> - -#include <ardour/ardour.h> -#include <ardour/session.h> -#include <ardour/audioengine.h> -#include <ardour/ladspa_plugin.h> -#include <ardour/buffer_set.h> - -#include <pbd/stl_delete.h> - -#include "i18n.h" -#include <locale.h> - -using namespace std; -using namespace ARDOUR; -using namespace PBD; - -LadspaPlugin::LadspaPlugin (void *mod, AudioEngine& e, Session& session, uint32_t index, nframes_t rate) - : Plugin (e, session) -{ - init (mod, index, rate); -} - -LadspaPlugin::LadspaPlugin (const LadspaPlugin &other) - : Plugin (other) -{ - init (other._module, other._index, other._sample_rate); - - for (uint32_t i = 0; i < parameter_count(); ++i) { - _control_data[i] = other._shadow_data[i]; - _shadow_data[i] = other._shadow_data[i]; - } -} - -void -LadspaPlugin::init (void *mod, uint32_t index, nframes_t rate) -{ - LADSPA_Descriptor_Function dfunc; - uint32_t i, port_cnt; - const char *errstr; - - _module = mod; - _control_data = 0; - _shadow_data = 0; - _latency_control_port = 0; - _was_activated = false; - - dfunc = (LADSPA_Descriptor_Function) dlsym (_module, "ladspa_descriptor"); - - if ((errstr = dlerror()) != NULL) { - error << _("LADSPA: module has no descriptor function.") << endmsg; - throw failed_constructor(); - } - - if ((_descriptor = dfunc (index)) == 0) { - error << _("LADSPA: plugin has gone away since discovery!") << endmsg; - throw failed_constructor(); - } - - _index = index; - - if (LADSPA_IS_INPLACE_BROKEN(_descriptor->Properties)) { - error << string_compose(_("LADSPA: \"%1\" cannot be used, since it cannot do inplace processing"), _descriptor->Name) << endmsg; - throw failed_constructor(); - } - - _sample_rate = rate; - - if (_descriptor->instantiate == 0) { - throw failed_constructor(); - } - - if ((_handle = _descriptor->instantiate (_descriptor, rate)) == 0) { - throw failed_constructor(); - } - - port_cnt = parameter_count(); - - _control_data = new LADSPA_Data[port_cnt]; - _shadow_data = new LADSPA_Data[port_cnt]; - - for (i = 0; i < port_cnt; ++i) { - if (LADSPA_IS_PORT_CONTROL(port_descriptor (i))) { - connect_port (i, &_control_data[i]); - - if (LADSPA_IS_PORT_OUTPUT(port_descriptor (i)) && - strcmp (port_names()[i], X_("latency")) == 0) { - _latency_control_port = &_control_data[i]; - *_latency_control_port = 0; - } - - if (!LADSPA_IS_PORT_INPUT(port_descriptor (i))) { - continue; - } - - _shadow_data[i] = default_value (i); - } - } - - latency_compute_run (); -} - -LadspaPlugin::~LadspaPlugin () -{ - deactivate (); - cleanup (); - - GoingAway (); /* EMIT SIGNAL */ - - /* XXX who should close a plugin? */ - - // dlclose (module); - - if (_control_data) { - delete [] _control_data; - } - - if (_shadow_data) { - delete [] _shadow_data; - } -} - -string -LadspaPlugin::unique_id() const -{ - char buf[32]; - snprintf (buf, sizeof (buf), "%lu", _descriptor->UniqueID); - return string (buf); -} - -float -LadspaPlugin::default_value (uint32_t port) -{ - const LADSPA_PortRangeHint *prh = port_range_hints(); - float ret = 0.0f; - bool bounds_given = false; - bool sr_scaling = false; - bool earlier_hint = false; - - /* defaults - case 1 */ - - if (LADSPA_IS_HINT_HAS_DEFAULT(prh[port].HintDescriptor)) { - if (LADSPA_IS_HINT_DEFAULT_MINIMUM(prh[port].HintDescriptor)) { - ret = prh[port].LowerBound; - bounds_given = true; - sr_scaling = true; - earlier_hint = true; - } - - /* FIXME: add support for logarithmic defaults */ - - else if (LADSPA_IS_HINT_DEFAULT_LOW(prh[port].HintDescriptor)) { - ret = prh[port].LowerBound * 0.75f + prh[port].UpperBound * 0.25f; - bounds_given = true; - sr_scaling = true; - earlier_hint = true; - } - else if (LADSPA_IS_HINT_DEFAULT_MIDDLE(prh[port].HintDescriptor)) { - ret = prh[port].LowerBound * 0.50f + prh[port].UpperBound * 0.50f; - bounds_given = true; - sr_scaling = true; - earlier_hint = true; - } - else if (LADSPA_IS_HINT_DEFAULT_HIGH(prh[port].HintDescriptor)) { - ret = prh[port].LowerBound * 0.25f + prh[port].UpperBound * 0.75f; - bounds_given = true; - sr_scaling = true; - earlier_hint = true; - } - else if (LADSPA_IS_HINT_DEFAULT_MAXIMUM(prh[port].HintDescriptor)) { - ret = prh[port].UpperBound; - bounds_given = true; - sr_scaling = true; - earlier_hint = true; - } - else if (LADSPA_IS_HINT_DEFAULT_0(prh[port].HintDescriptor)) { - ret = 0.0f; - earlier_hint = true; - } - else if (LADSPA_IS_HINT_DEFAULT_1(prh[port].HintDescriptor)) { - ret = 1.0f; - earlier_hint = true; - } - else if (LADSPA_IS_HINT_DEFAULT_100(prh[port].HintDescriptor)) { - ret = 100.0f; - earlier_hint = true; - } - else if (LADSPA_IS_HINT_DEFAULT_440(prh[port].HintDescriptor)) { - ret = 440.0f; - earlier_hint = true; - } - else { - /* no hint found */ - ret = 0.0f; - } - } - - /* defaults - case 2 */ - else if (LADSPA_IS_HINT_BOUNDED_BELOW(prh[port].HintDescriptor) && - !LADSPA_IS_HINT_BOUNDED_ABOVE(prh[port].HintDescriptor)) { - - if (prh[port].LowerBound < 0) { - ret = 0.0f; - } else { - ret = prh[port].LowerBound; - } - - bounds_given = true; - sr_scaling = true; - } - - /* defaults - case 3 */ - else if (!LADSPA_IS_HINT_BOUNDED_BELOW(prh[port].HintDescriptor) && - LADSPA_IS_HINT_BOUNDED_ABOVE(prh[port].HintDescriptor)) { - - if (prh[port].UpperBound > 0) { - ret = 0.0f; - } else { - ret = prh[port].UpperBound; - } - - bounds_given = true; - sr_scaling = true; - } - - /* defaults - case 4 */ - else if (LADSPA_IS_HINT_BOUNDED_BELOW(prh[port].HintDescriptor) && - LADSPA_IS_HINT_BOUNDED_ABOVE(prh[port].HintDescriptor)) { - - if (prh[port].LowerBound < 0 && prh[port].UpperBound > 0) { - ret = 0.0f; - } else if (prh[port].LowerBound < 0 && prh[port].UpperBound < 0) { - ret = prh[port].UpperBound; - } else { - ret = prh[port].LowerBound; - } - bounds_given = true; - sr_scaling = true; - } - - /* defaults - case 5 */ - - if (LADSPA_IS_HINT_SAMPLE_RATE(prh[port].HintDescriptor) && !earlier_hint) { - if (bounds_given) { - if (sr_scaling) { - ret *= _sample_rate; - } - } else { - ret = _sample_rate; - } - } - - return ret; -} - -void -LadspaPlugin::set_parameter (uint32_t which, float val) -{ - if (which < _descriptor->PortCount) { - _shadow_data[which] = (LADSPA_Data) val; -#if 0 - ParameterChanged (Parameter(PluginAutomation, which), val); /* EMIT SIGNAL */ - - if (which < parameter_count() && controls[which]) { - controls[which]->Changed (); - } -#endif - - } else { - warning << string_compose (_("illegal parameter number used with plugin \"%1\". This may" - "indicate a change in the plugin design, and presets may be" - "invalid"), name()) - << endmsg; - } -} - -float -LadspaPlugin::get_parameter (uint32_t which) const -{ - if (LADSPA_IS_PORT_INPUT(port_descriptor (which))) { - return (float) _shadow_data[which]; - } else { - return (float) _control_data[which]; - } -} - -uint32_t -LadspaPlugin::nth_parameter (uint32_t n, bool& ok) const -{ - uint32_t x, c; - - ok = false; - - for (c = 0, x = 0; x < _descriptor->PortCount; ++x) { - if (LADSPA_IS_PORT_CONTROL (port_descriptor (x))) { - if (c++ == n) { - ok = true; - return x; - } - } - } - return 0; -} - -XMLNode& -LadspaPlugin::get_state() -{ - XMLNode *root = new XMLNode(state_node_name()); - XMLNode *child; - char buf[16]; - LocaleGuard lg (X_("POSIX")); - - for (uint32_t i = 0; i < parameter_count(); ++i){ - - if (LADSPA_IS_PORT_INPUT(port_descriptor (i)) && - LADSPA_IS_PORT_CONTROL(port_descriptor (i))){ - - child = new XMLNode("port"); - snprintf(buf, sizeof(buf), "%u", i); - child->add_property("number", string(buf)); - snprintf(buf, sizeof(buf), "%+f", _shadow_data[i]); - child->add_property("value", string(buf)); - root->add_child_nocopy (*child); - } - } - - return *root; -} - -bool -LadspaPlugin::save_preset (string name) -{ - return Plugin::save_preset (name, "ladspa"); -} - -int -LadspaPlugin::set_state(const XMLNode& node) -{ - XMLNodeList nodes; - XMLProperty *prop; - XMLNodeConstIterator iter; - XMLNode *child; - const char *port; - const char *data; - uint32_t port_id; - LocaleGuard lg (X_("POSIX")); - - if (node.name() != state_node_name()) { - error << _("Bad node sent to LadspaPlugin::set_state") << endmsg; - return -1; - } - - nodes = node.children ("port"); - - for(iter = nodes.begin(); iter != nodes.end(); ++iter){ - - child = *iter; - - if ((prop = child->property("number")) != 0) { - port = prop->value().c_str(); - } else { - warning << _("LADSPA: no ladspa port number") << endmsg; - continue; - } - if ((prop = child->property("value")) != 0) { - data = prop->value().c_str(); - } else { - warning << _("LADSPA: no ladspa port data") << endmsg; - continue; - } - - sscanf (port, "%" PRIu32, &port_id); - set_parameter (port_id, atof(data)); - } - - latency_compute_run (); - - return 0; -} - -int -LadspaPlugin::get_parameter_descriptor (uint32_t which, ParameterDescriptor& desc) const -{ - LADSPA_PortRangeHint prh; - - prh = port_range_hints()[which]; - - - if (LADSPA_IS_HINT_BOUNDED_BELOW(prh.HintDescriptor)) { - desc.min_unbound = false; - if (LADSPA_IS_HINT_SAMPLE_RATE(prh.HintDescriptor)) { - desc.lower = prh.LowerBound * _session.frame_rate(); - } else { - desc.lower = prh.LowerBound; - } - } else { - desc.min_unbound = true; - desc.lower = 0; - } - - - if (LADSPA_IS_HINT_BOUNDED_ABOVE(prh.HintDescriptor)) { - desc.max_unbound = false; - if (LADSPA_IS_HINT_SAMPLE_RATE(prh.HintDescriptor)) { - desc.upper = prh.UpperBound * _session.frame_rate(); - } else { - desc.upper = prh.UpperBound; - } - } else { - desc.max_unbound = true; - desc.upper = 4; /* completely arbitrary */ - } - - if (LADSPA_IS_HINT_INTEGER (prh.HintDescriptor)) { - desc.step = 1.0; - desc.smallstep = 0.1; - desc.largestep = 10.0; - } else { - float delta = desc.upper - desc.lower; - desc.step = delta / 1000.0f; - desc.smallstep = delta / 10000.0f; - desc.largestep = delta/10.0f; - } - - desc.toggled = LADSPA_IS_HINT_TOGGLED (prh.HintDescriptor); - desc.logarithmic = LADSPA_IS_HINT_LOGARITHMIC (prh.HintDescriptor); - desc.sr_dependent = LADSPA_IS_HINT_SAMPLE_RATE (prh.HintDescriptor); - desc.integer_step = LADSPA_IS_HINT_INTEGER (prh.HintDescriptor); - - desc.label = port_names()[which]; - - return 0; -} - -string -LadspaPlugin::describe_parameter (Parameter which) -{ - if (which.type() == PluginAutomation && which.id() < parameter_count()) { - return port_names()[which.id()]; - } else { - return "??"; - } -} - -ARDOUR::nframes_t -LadspaPlugin::signal_latency () const -{ - if (_user_latency) { - return _user_latency; - } - - if (_latency_control_port) { - return (nframes_t) floor (*_latency_control_port); - } else { - return 0; - } -} - -set<Parameter> -LadspaPlugin::automatable () const -{ - set<Parameter> ret; - - for (uint32_t i = 0; i < parameter_count(); ++i){ - if (LADSPA_IS_PORT_INPUT(port_descriptor (i)) && - LADSPA_IS_PORT_CONTROL(port_descriptor (i))){ - - ret.insert (ret.end(), Parameter(PluginAutomation, i)); - } - } - - return ret; -} - -int -LadspaPlugin::connect_and_run (BufferSet& bufs, uint32_t& in_index, uint32_t& out_index, nframes_t nframes, nframes_t offset) -{ - uint32_t port_index = 0; - cycles_t then, now; - - then = get_cycles (); - - const uint32_t nbufs = bufs.count().n_audio(); - - while (port_index < parameter_count()) { - if (LADSPA_IS_PORT_AUDIO (port_descriptor(port_index))) { - if (LADSPA_IS_PORT_INPUT (port_descriptor(port_index))) { - const size_t index = min(in_index, nbufs - 1); - connect_port (port_index, bufs.get_audio(index).data(nframes, offset)); - //cerr << this << ' ' << name() << " @ " << offset << " inport " << in_index << " = buf " - // << min((uint32_t)in_index,nbufs) << " = " << &bufs[min((uint32_t)in_index,nbufs)][offset] << endl; - in_index++; - - - } else if (LADSPA_IS_PORT_OUTPUT (port_descriptor (port_index))) { - const size_t index = min(out_index,nbufs - 1); - connect_port (port_index, bufs.get_audio(index).data(nframes, offset)); - // cerr << this << ' ' << name() << " @ " << offset << " outport " << out_index << " = buf " - // << min((uint32_t)out_index,nbufs) << " = " << &bufs[min((uint32_t)out_index,nbufs)][offset] << endl; - out_index++; - } - } - port_index++; - } - - run_in_place (nframes); - now = get_cycles (); - set_cycles ((uint32_t) (now - then)); - - return 0; -} - -bool -LadspaPlugin::parameter_is_control (uint32_t param) const -{ - return LADSPA_IS_PORT_CONTROL(port_descriptor (param)); -} - -bool -LadspaPlugin::parameter_is_audio (uint32_t param) const -{ - return LADSPA_IS_PORT_AUDIO(port_descriptor (param)); -} - -bool -LadspaPlugin::parameter_is_output (uint32_t param) const -{ - return LADSPA_IS_PORT_OUTPUT(port_descriptor (param)); -} - -bool -LadspaPlugin::parameter_is_input (uint32_t param) const -{ - return LADSPA_IS_PORT_INPUT(port_descriptor (param)); -} - -void -LadspaPlugin::print_parameter (uint32_t param, char *buf, uint32_t len) const -{ - if (buf && len) { - if (param < parameter_count()) { - snprintf (buf, len, "%.3f", get_parameter (param)); - } else { - strcat (buf, "0"); - } - } -} - -void -LadspaPlugin::run_in_place (nframes_t nframes) -{ - for (uint32_t i = 0; i < parameter_count(); ++i) { - if (LADSPA_IS_PORT_INPUT(port_descriptor (i)) && LADSPA_IS_PORT_CONTROL(port_descriptor (i))) { - _control_data[i] = _shadow_data[i]; - } - } - _descriptor->run (_handle, nframes); -} - -void -LadspaPlugin::latency_compute_run () -{ - if (!_latency_control_port) { - return; - } - - /* we need to run the plugin so that it can set its latency - parameter. - */ - - activate (); - - uint32_t port_index = 0; - uint32_t in_index = 0; - uint32_t out_index = 0; - const nframes_t bufsize = 1024; - LADSPA_Data buffer[bufsize]; - - memset(buffer,0,sizeof(LADSPA_Data)*bufsize); - - /* Note that we've already required that plugins - be able to handle in-place processing. - */ - - port_index = 0; - - while (port_index < parameter_count()) { - if (LADSPA_IS_PORT_AUDIO (port_descriptor (port_index))) { - if (LADSPA_IS_PORT_INPUT (port_descriptor (port_index))) { - connect_port (port_index, buffer); - in_index++; - } else if (LADSPA_IS_PORT_OUTPUT (port_descriptor (port_index))) { - connect_port (port_index, buffer); - out_index++; - } - } - port_index++; - } - - run_in_place (bufsize); - deactivate (); -} - -PluginPtr -LadspaPluginInfo::load (Session& session) -{ - try { - PluginPtr plugin; - void *module; - - if ((module = dlopen (path.c_str(), RTLD_NOW)) == 0) { - error << string_compose(_("LADSPA: cannot load module from \"%1\""), path) << endmsg; - error << dlerror() << endmsg; - } else { - plugin.reset (new LadspaPlugin (module, session.engine(), session, index, session.frame_rate())); - } - - plugin->set_info(PluginInfoPtr(new LadspaPluginInfo(*this))); - return plugin; - } - - catch (failed_constructor &err) { - return PluginPtr ((Plugin*) 0); - } -} diff --git a/libs/ardour/location.cc b/libs/ardour/location.cc deleted file mode 100644 index 0da75810ca..0000000000 --- a/libs/ardour/location.cc +++ /dev/null @@ -1,915 +0,0 @@ -/* - 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. - -*/ - -#include <algorithm> -#include <set> -#include <cstdio> /* for sprintf */ -#include <unistd.h> -#include <cerrno> -#include <ctime> -#include <sigc++/bind.h> - -#include <pbd/stl_delete.h> -#include <pbd/xml++.h> -#include <pbd/enumwriter.h> - -#include <ardour/location.h> -#include <ardour/session.h> -#include <ardour/audiofilesource.h> - -#include "i18n.h" - -#define SUFFIX_MAX 32 - -using namespace std; -using namespace ARDOUR; -using namespace sigc; -using namespace PBD; - -Location::Location (const Location& other) - : _name (other._name), - _start (other._start), - _end (other._end), - _flags (other._flags) -{ - /* start and end flags can never be copied, because there can only ever be one of each */ - - _flags = Flags (_flags & ~IsStart); - _flags = Flags (_flags & ~IsEnd); - - /* copy is not locked even if original was */ - - _locked = false; -} - -Location::Location (const XMLNode& node) -{ - if (set_state (node)) { - throw failed_constructor (); - } -} - -Location* -Location::operator= (const Location& other) -{ - if (this == &other) { - return this; - } - - _name = other._name; - _start = other._start; - _end = other._end; - _flags = other._flags; - - /* copy is not locked even if original was */ - - _locked = false; - - /* "changed" not emitted on purpose */ - - return this; -} - -int -Location::set_start (nframes_t s) -{ - if (_locked) { - return -1; - } - - if (is_mark()) { - if (_start != s) { - - _start = s; - _end = s; - - start_changed(this); /* EMIT SIGNAL */ - - if ( is_start() ) { - - Session::StartTimeChanged (); /* EMIT SIGNAL */ - AudioFileSource::set_header_position_offset ( s ); - } - - if ( is_end() ) { - Session::EndTimeChanged (); /* EMIT SIGNAL */ - } - } - return 0; - } - - if (((is_auto_punch() || is_auto_loop()) && s >= _end) || s > _end) { - return -1; - } - - if (s != _start) { - _start = s; - start_changed(this); /* EMIT SIGNAL */ - } - - return 0; -} - -int -Location::set_end (nframes_t e) -{ - if (_locked) { - return -1; - } - - if (is_mark()) { - if (_start != e) { - _start = e; - _end = e; - end_changed(this); /* EMIT SIGNAL */ - } - return 0; - } - - if (((is_auto_punch() || is_auto_loop()) && e <= _start) || e < _start) { - return -1; - } - - if (e != _end) { - _end = e; - end_changed(this); /* EMIT SIGNAL */ - } - return 0; -} - -int -Location::set (nframes_t start, nframes_t end) -{ - if (_locked) { - return -1; - } - - if (is_mark() && start != end) { - return -1; - } else if (((is_auto_punch() || is_auto_loop()) && start >= end) || (start > end)) { - return -1; - } - - if (_start != start) { - _start = start; - start_changed(this); /* EMIT SIGNAL */ - } - - if (_end != end) { - _end = end; - end_changed(this); /* EMIT SIGNAL */ - } - return 0; -} - -int -Location::move_to (nframes_t pos) -{ - if (_locked) { - return -1; - } - - if (_start != pos) { - _start = pos; - _end = _start + length(); - - changed (this); /* EMIT SIGNAL */ - } - - return 0; -} - -void -Location::set_hidden (bool yn, void *src) -{ - if (set_flag_internal (yn, IsHidden)) { - FlagsChanged (this, src); /* EMIT SIGNAL */ - } -} - -void -Location::set_cd (bool yn, void *src) -{ - // XXX this really needs to be session start - // but its not available here - leave to GUI - - if (_start == 0) { - error << _("You cannot put a CD marker at this position") << endmsg; - return; - } - - if (set_flag_internal (yn, IsCDMarker)) { - FlagsChanged (this, src); /* EMIT SIGNAL */ - } -} - -void -Location::set_is_end (bool yn, void *src) -{ - if (set_flag_internal (yn, IsEnd)) { - FlagsChanged (this, src); /* EMIT SIGNAL */ - } -} - -void -Location::set_is_start (bool yn, void *src) -{ - if (set_flag_internal (yn, IsStart)) { - FlagsChanged (this, src); /* EMIT SIGNAL */ - } -} - -void -Location::set_auto_punch (bool yn, void *src) -{ - if (is_mark() || _start == _end) { - return; - } - - if (set_flag_internal (yn, IsAutoPunch)) { - FlagsChanged (this, src); /* EMIT SIGNAL */ - } -} - -void -Location::set_auto_loop (bool yn, void *src) -{ - if (is_mark() || _start == _end) { - return; - } - - if (set_flag_internal (yn, IsAutoLoop)) { - FlagsChanged (this, src); /* EMIT SIGNAL */ - } -} - -bool -Location::set_flag_internal (bool yn, Flags flag) -{ - if (yn) { - if (!(_flags & flag)) { - _flags = Flags (_flags | flag); - return true; - } - } else { - if (_flags & flag) { - _flags = Flags (_flags & ~flag); - return true; - } - } - return false; -} - -void -Location::set_mark (bool yn) -{ - /* This function is private, and so does not emit signals */ - - if (_start != _end) { - return; - } - - set_flag_internal (yn, IsMark); -} - - -XMLNode& -Location::cd_info_node(const string & name, const string & value) -{ - XMLNode* root = new XMLNode("CD-Info"); - - root->add_property("name", name); - root->add_property("value", value); - - return *root; -} - - -XMLNode& -Location::get_state (void) -{ - XMLNode *node = new XMLNode ("Location"); - char buf[64]; - - typedef map<string, string>::const_iterator CI; - - for(CI m = cd_info.begin(); m != cd_info.end(); ++m){ - node->add_child_nocopy(cd_info_node(m->first, m->second)); - } - - id().print (buf, sizeof (buf)); - node->add_property("id", buf); - node->add_property ("name", name()); - snprintf (buf, sizeof (buf), "%u", start()); - node->add_property ("start", buf); - snprintf (buf, sizeof (buf), "%u", end()); - node->add_property ("end", buf); - node->add_property ("flags", enum_2_string (_flags)); - node->add_property ("locked", (_locked ? "yes" : "no")); - - return *node; -} - -int -Location::set_state (const XMLNode& node) -{ - const XMLProperty *prop; - - XMLNodeList cd_list = node.children(); - XMLNodeConstIterator cd_iter; - XMLNode *cd_node; - - string cd_name; - string cd_value; - - if (node.name() != "Location") { - error << _("incorrect XML node passed to Location::set_state") << endmsg; - return -1; - } - - if ((prop = node.property ("id")) == 0) { - warning << _("XML node for Location has no ID information") << endmsg; - } else { - _id = prop->value (); - } - - if ((prop = node.property ("name")) == 0) { - error << _("XML node for Location has no name information") << endmsg; - return -1; - } - - set_name (prop->value()); - - if ((prop = node.property ("start")) == 0) { - error << _("XML node for Location has no start information") << endmsg; - return -1; - } - - /* can't use set_start() here, because _end - may make the value of _start illegal. - */ - - _start = atoi (prop->value().c_str()); - - if ((prop = node.property ("end")) == 0) { - error << _("XML node for Location has no end information") << endmsg; - return -1; - } - - _end = atoi (prop->value().c_str()); - - if ((prop = node.property ("flags")) == 0) { - error << _("XML node for Location has no flags information") << endmsg; - return -1; - } - - _flags = Flags (string_2_enum (prop->value(), _flags)); - - if ((prop = node.property ("locked")) != 0) { - _locked = (prop->value() == "yes"); - } else { - _locked = false; - } - - for (cd_iter = cd_list.begin(); cd_iter != cd_list.end(); ++cd_iter) { - - cd_node = *cd_iter; - - if (cd_node->name() != "CD-Info") { - continue; - } - - if ((prop = cd_node->property ("name")) != 0) { - cd_name = prop->value(); - } else { - throw failed_constructor (); - } - - if ((prop = cd_node->property ("value")) != 0) { - cd_value = prop->value(); - } else { - throw failed_constructor (); - } - - - cd_info[cd_name] = cd_value; - - } - - changed(this); /* EMIT SIGNAL */ - - return 0; -} - -/*---------------------------------------------------------------------- */ - -Locations::Locations () - -{ - current_location = 0; -} - -Locations::~Locations () -{ - for (LocationList::iterator i = locations.begin(); i != locations.end(); ) { - LocationList::iterator tmp = i; - ++tmp; - delete *i; - i = tmp; - } -} - -int -Locations::set_current (Location *loc, bool want_lock) - -{ - int ret; - - if (want_lock) { - Glib::Mutex::Lock lm (lock); - ret = set_current_unlocked (loc); - } else { - ret = set_current_unlocked (loc); - } - - if (ret == 0) { - current_changed (current_location); /* EMIT SIGNAL */ - } - return ret; -} - -int -Locations::next_available_name(string& result,string base) -{ - LocationList::iterator i; - Location* location; - string temp; - string::size_type l; - int suffix; - char buf[32]; - bool available[SUFFIX_MAX+1]; - - result = base; - for (int k=1; k<SUFFIX_MAX; k++) { - available[k] = true; - } - l = base.length(); - for (i = locations.begin(); i != locations.end(); ++i) { - location =* i; - temp = location->name(); - if (l && !temp.find(base,0)) { - suffix = atoi(temp.substr(l,3).c_str()); - if (suffix) available[suffix] = false; - } - } - for (int k=1; k<=SUFFIX_MAX; k++) { - if (available[k]) { - snprintf (buf, 31, "%d", k); - result += buf; - return 1; - } - } - return 0; -} - -int -Locations::set_current_unlocked (Location *loc) -{ - if (find (locations.begin(), locations.end(), loc) == locations.end()) { - error << _("Locations: attempt to use unknown location as selected location") << endmsg; - return -1; - } - - current_location = loc; - return 0; -} - -void -Locations::clear () -{ - { - Glib::Mutex::Lock lm (lock); - - for (LocationList::iterator i = locations.begin(); i != locations.end(); ) { - - LocationList::iterator tmp = i; - ++tmp; - - if (!(*i)->is_end() && !(*i)->is_start()) { - locations.erase (i); - } - - i = tmp; - } - - current_location = 0; - } - - changed (); /* EMIT SIGNAL */ - current_changed (0); /* EMIT SIGNAL */ -} - -void -Locations::clear_markers () -{ - { - Glib::Mutex::Lock lm (lock); - LocationList::iterator tmp; - - for (LocationList::iterator i = locations.begin(); i != locations.end(); ) { - tmp = i; - ++tmp; - - if ((*i)->is_mark() && !(*i)->is_end() && !(*i)->is_start()) { - locations.erase (i); - } - - i = tmp; - } - } - - changed (); /* EMIT SIGNAL */ -} - -void -Locations::clear_ranges () -{ - { - Glib::Mutex::Lock lm (lock); - LocationList::iterator tmp; - - for (LocationList::iterator i = locations.begin(); i != locations.end(); ) { - - tmp = i; - ++tmp; - - if (!(*i)->is_mark()) { - locations.erase (i); - - } - - i = tmp; - } - - current_location = 0; - } - - changed (); /* EMIT SIGNAL */ - current_changed (0); /* EMIT SIGNAL */ -} - -void -Locations::add (Location *loc, bool make_current) -{ - { - Glib::Mutex::Lock lm (lock); - locations.push_back (loc); - - if (make_current) { - current_location = loc; - } - } - - added (loc); /* EMIT SIGNAL */ - - if (make_current) { - current_changed (current_location); /* EMIT SIGNAL */ - } -} - -void -Locations::remove (Location *loc) - -{ - bool was_removed = false; - bool was_current = false; - LocationList::iterator i; - - if (loc->is_end() || loc->is_start()) { - return; - } - - { - Glib::Mutex::Lock lm (lock); - - for (i = locations.begin(); i != locations.end(); ++i) { - if ((*i) == loc) { - locations.erase (i); - was_removed = true; - if (current_location == loc) { - current_location = 0; - was_current = true; - } - break; - } - } - } - - if (was_removed) { - - removed (loc); /* EMIT SIGNAL */ - - if (was_current) { - current_changed (0); /* EMIT SIGNAL */ - } - - changed (); /* EMIT_SIGNAL */ - } -} - -void -Locations::location_changed (Location* loc) -{ - changed (); /* EMIT SIGNAL */ -} - -XMLNode& -Locations::get_state () -{ - XMLNode *node = new XMLNode ("Locations"); - LocationList::iterator iter; - Glib::Mutex::Lock lm (lock); - - for (iter = locations.begin(); iter != locations.end(); ++iter) { - node->add_child_nocopy ((*iter)->get_state ()); - } - - return *node; -} - -int -Locations::set_state (const XMLNode& node) -{ - XMLNodeList nlist; - XMLNodeConstIterator niter; - - if (node.name() != "Locations") { - error << _("incorrect XML mode passed to Locations::set_state") << endmsg; - return -1; - } - - nlist = node.children(); - - locations.clear (); - current_location = 0; - - { - Glib::Mutex::Lock lm (lock); - - for (niter = nlist.begin(); niter != nlist.end(); ++niter) { - - try { - - Location *loc = new Location (**niter); - locations.push_back (loc); - } - - catch (failed_constructor& err) { - error << _("could not load location from session file - ignored") << endmsg; - } - } - - if (locations.size()) { - - current_location = locations.front(); - } else { - current_location = 0; - } - } - - changed (); /* EMIT SIGNAL */ - - return 0; -} - -struct LocationStartEarlierComparison -{ - bool operator() (Location *a, Location *b) { - return a->start() < b->start(); - } -}; - -struct LocationStartLaterComparison -{ - bool operator() (Location *a, Location *b) { - return a->start() > b->start(); - } -}; - -Location * -Locations::first_location_before (nframes_t frame, bool include_special_ranges) -{ - LocationList locs; - - { - Glib::Mutex::Lock lm (lock); - locs = locations; - } - - LocationStartLaterComparison cmp; - locs.sort (cmp); - - /* locs is now sorted latest..earliest */ - - for (LocationList::iterator i = locs.begin(); i != locs.end(); ++i) { - if (!include_special_ranges && ((*i)->is_auto_loop() || (*i)->is_auto_punch())) { - continue; - } - if (!(*i)->is_hidden() && (*i)->start() < frame) { - return (*i); - } - } - - return 0; -} - -Location * -Locations::first_location_after (nframes_t frame, bool include_special_ranges) -{ - LocationList locs; - - { - Glib::Mutex::Lock lm (lock); - locs = locations; - } - - LocationStartEarlierComparison cmp; - locs.sort (cmp); - - /* locs is now sorted earliest..latest */ - - for (LocationList::iterator i = locs.begin(); i != locs.end(); ++i) { - if (!include_special_ranges && ((*i)->is_auto_loop() || (*i)->is_auto_punch())) { - continue; - } - if (!(*i)->is_hidden() && (*i)->start() > frame) { - return (*i); - } - } - - return 0; -} - -nframes_t -Locations::first_mark_before (nframes_t frame, bool include_special_ranges) -{ - LocationList locs; - - { - Glib::Mutex::Lock lm (lock); - locs = locations; - } - - LocationStartLaterComparison cmp; - locs.sort (cmp); - - /* locs is now sorted latest..earliest */ - - for (LocationList::iterator i = locs.begin(); i != locs.end(); ++i) { - if (!include_special_ranges && ((*i)->is_auto_loop() || (*i)->is_auto_punch())) { - continue; - } - if (!(*i)->is_hidden()) { - if ((*i)->is_mark()) { - /* MARK: start == end */ - if ((*i)->start() < frame) { - return (*i)->start(); - } - } else { - /* RANGE: start != end, compare start and end */ - if ((*i)->end() < frame) { - return (*i)->end(); - } - if ((*i)->start () < frame) { - return (*i)->start(); - } - } - } - } - - return 0; -} - -nframes_t -Locations::first_mark_after (nframes_t frame, bool include_special_ranges) -{ - LocationList locs; - - { - Glib::Mutex::Lock lm (lock); - locs = locations; - } - - LocationStartEarlierComparison cmp; - locs.sort (cmp); - - /* locs is now sorted earliest..latest */ - - for (LocationList::iterator i = locs.begin(); i != locs.end(); ++i) { - if (!include_special_ranges && ((*i)->is_auto_loop() || (*i)->is_auto_punch())) { - continue; - } - if (!(*i)->is_hidden()) { - if ((*i)->is_mark()) { - /* MARK, start == end so just compare start */ - if ((*i)->start() > frame) { - return (*i)->start(); - } - } else { - /* RANGE, start != end, compare start and end */ - if ((*i)->start() > frame ) { - return (*i)->start (); - } - if ((*i)->end() > frame) { - return (*i)->end (); - } - } - } - } - - return max_frames; -} - -Location* -Locations::end_location () const -{ - for (LocationList::const_iterator i = locations.begin(); i != locations.end(); ++i) { - if ((*i)->is_end()) { - return const_cast<Location*> (*i); - } - } - return 0; -} - -Location* -Locations::start_location () const -{ - for (LocationList::const_iterator i = locations.begin(); i != locations.end(); ++i) { - if ((*i)->is_start()) { - return const_cast<Location*> (*i); - } - } - return 0; -} - -Location* -Locations::auto_loop_location () const -{ - for (LocationList::const_iterator i = locations.begin(); i != locations.end(); ++i) { - if ((*i)->is_auto_loop()) { - return const_cast<Location*> (*i); - } - } - return 0; -} - -Location* -Locations::auto_punch_location () const -{ - for (LocationList::const_iterator i = locations.begin(); i != locations.end(); ++i) { - if ((*i)->is_auto_punch()) { - return const_cast<Location*> (*i); - } - } - return 0; -} - -uint32_t -Locations::num_range_markers () const -{ - uint32_t cnt = 0; - Glib::Mutex::Lock lm (lock); - for (LocationList::const_iterator i = locations.begin(); i != locations.end(); ++i) { - if ((*i)->is_range_marker()) { - ++cnt; - } - } - return cnt; -} - -Location * -Locations::get_location_by_id(PBD::ID id) -{ - LocationList::iterator it; - for (it = locations.begin(); it != locations.end(); it++) - if (id == (*it)->id()) - return *it; - - return 0; -} diff --git a/libs/ardour/lv2_plugin.cc b/libs/ardour/lv2_plugin.cc deleted file mode 100644 index 4553458831..0000000000 --- a/libs/ardour/lv2_plugin.cc +++ /dev/null @@ -1,625 +0,0 @@ -/* - 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. - -*/ - -#include <vector> -#include <string> - -#include <cstdlib> -#include <cmath> - -#include <pbd/compose.h> -#include <pbd/error.h> -#include <pbd/pathscanner.h> -#include <pbd/xml++.h> - -#include <ardour/ardour.h> -#include <ardour/session.h> -#include <ardour/audioengine.h> -#include <ardour/lv2_plugin.h> - -#include <pbd/stl_delete.h> - -#include "i18n.h" -#include <locale.h> - -using namespace std; -using namespace ARDOUR; -using namespace PBD; - -LV2Plugin::LV2Plugin (AudioEngine& e, Session& session, LV2World& world, SLV2Plugin plugin, nframes_t rate) - : Plugin (e, session) - , _world(world) -{ - init (world, plugin, rate); -} - -LV2Plugin::LV2Plugin (const LV2Plugin &other) - : Plugin (other) - , _world(other._world) -{ - init (other._world, other._plugin, other._sample_rate); - - for (uint32_t i = 0; i < parameter_count(); ++i) { - _control_data[i] = other._shadow_data[i]; - _shadow_data[i] = other._shadow_data[i]; - } -} - -void -LV2Plugin::init (LV2World& world, SLV2Plugin plugin, nframes_t rate) -{ - _world = world; - _plugin = plugin; - _control_data = 0; - _shadow_data = 0; - _latency_control_port = 0; - _was_activated = false; - - _instance = slv2_plugin_instantiate(plugin, rate, NULL); - _name = slv2_plugin_get_name(plugin); - assert(_name); - _author = slv2_plugin_get_author_name(plugin); - - if (_instance == 0) { - error << _("LV2: Failed to instantiate plugin ") << slv2_plugin_get_uri(plugin) << endl; - throw failed_constructor(); - } - - if (slv2_plugin_has_feature(plugin, world.in_place_broken)) { - error << string_compose(_("LV2: \"%1\" cannot be used, since it cannot do inplace processing"), - slv2_value_as_string(_name)); - slv2_value_free(_name); - slv2_value_free(_author); - throw failed_constructor(); - } - - _sample_rate = rate; - - const uint32_t num_ports = slv2_plugin_get_num_ports(plugin); - - _control_data = new float[num_ports]; - _shadow_data = new float[num_ports]; - _defaults = new float[num_ports]; - - const bool latent = slv2_plugin_has_latency(plugin); - uint32_t latency_port = (latent ? slv2_plugin_get_latency_port_index(plugin) : 0); - - for (uint32_t i = 0; i < num_ports; ++i) { - if (parameter_is_control(i)) { - SLV2Port port = slv2_plugin_get_port_by_index(plugin, i); - SLV2Value def; - slv2_port_get_range(plugin, port, &def, NULL, NULL); - _defaults[i] = def ? slv2_value_as_float(def) : 0.0f; - slv2_value_free(def); - - slv2_instance_connect_port (_instance, i, &_control_data[i]); - - if (latent && i == latency_port) { - _latency_control_port = &_control_data[i]; - *_latency_control_port = 0; - } - - if (parameter_is_input(i)) { - _shadow_data[i] = default_value (i); - } - } else { - _defaults[i] = 0.0f; - } - } - - latency_compute_run (); -} - -LV2Plugin::~LV2Plugin () -{ - deactivate (); - cleanup (); - - GoingAway (); /* EMIT SIGNAL */ - - slv2_instance_free(_instance); - slv2_value_free(_name); - slv2_value_free(_author); - - if (_control_data) { - delete [] _control_data; - } - - if (_shadow_data) { - delete [] _shadow_data; - } -} - -string -LV2Plugin::unique_id() const -{ - return slv2_value_as_uri(slv2_plugin_get_uri(_plugin)); -} - - -float -LV2Plugin::default_value (uint32_t port) -{ - return _defaults[port]; -} - -void -LV2Plugin::set_parameter (uint32_t which, float val) -{ - if (which < slv2_plugin_get_num_ports(_plugin)) { - _shadow_data[which] = val; -#if 0 - ParameterChanged (which, val); /* EMIT SIGNAL */ - - if (which < parameter_count() && controls[which]) { - controls[which]->Changed (); - } -#endif - - } else { - warning << string_compose (_("Illegal parameter number used with plugin \"%1\"." - "This is a bug in either Ardour or the LV2 plugin (%2)"), - name(), unique_id()) << endmsg; - } -} - -float -LV2Plugin::get_parameter (uint32_t which) const -{ - if (parameter_is_input(which)) { - return (float) _shadow_data[which]; - } else { - return (float) _control_data[which]; - } - return 0.0f; -} - -uint32_t -LV2Plugin::nth_parameter (uint32_t n, bool& ok) const -{ - uint32_t x, c; - - ok = false; - - for (c = 0, x = 0; x < slv2_plugin_get_num_ports(_plugin); ++x) { - if (parameter_is_control (x)) { - if (c++ == n) { - ok = true; - return x; - } - } - } - - return 0; -} - -XMLNode& -LV2Plugin::get_state() -{ - XMLNode *root = new XMLNode(state_node_name()); - XMLNode *child; - char buf[16]; - LocaleGuard lg (X_("POSIX")); - - for (uint32_t i = 0; i < parameter_count(); ++i){ - - if (parameter_is_input(i) && parameter_is_control(i)) { - child = new XMLNode("port"); - snprintf(buf, sizeof(buf), "%u", i); - child->add_property("number", string(buf)); - snprintf(buf, sizeof(buf), "%+f", _shadow_data[i]); - child->add_property("value", string(buf)); - root->add_child_nocopy (*child); - - /*if (i < controls.size() && controls[i]) { - root->add_child_nocopy (controls[i]->get_state()); - }*/ - } - } - - return *root; -} - -bool -LV2Plugin::save_preset (string name) -{ - return Plugin::save_preset (name, "lv2"); -} - -int -LV2Plugin::set_state(const XMLNode& node) -{ - XMLNodeList nodes; - XMLProperty *prop; - XMLNodeConstIterator iter; - XMLNode *child; - const char *port; - const char *data; - uint32_t port_id; - LocaleGuard lg (X_("POSIX")); - - if (node.name() != state_node_name()) { - error << _("Bad node sent to LV2Plugin::set_state") << endmsg; - return -1; - } - - nodes = node.children ("port"); - - for(iter = nodes.begin(); iter != nodes.end(); ++iter){ - - child = *iter; - - if ((prop = child->property("number")) != 0) { - port = prop->value().c_str(); - } else { - warning << _("LV2: no lv2 port number") << endmsg; - continue; - } - - if ((prop = child->property("value")) != 0) { - data = prop->value().c_str(); - } else { - warning << _("LV2: no lv2 port data") << endmsg; - continue; - } - - sscanf (port, "%" PRIu32, &port_id); - set_parameter (port_id, atof(data)); - } - - latency_compute_run (); - - return 0; -} - -int -LV2Plugin::get_parameter_descriptor (uint32_t which, ParameterDescriptor& desc) const -{ - SLV2Port port = slv2_plugin_get_port_by_index(_plugin, which); - - SLV2Value def, min, max; - slv2_port_get_range(_plugin, port, &def, &min, &max); - - desc.integer_step = slv2_port_has_property(_plugin, port, _world.integer); - desc.toggled = slv2_port_has_property(_plugin, port, _world.toggled); - desc.logarithmic = false; // TODO (LV2 extension) - desc.sr_dependent = slv2_port_has_property(_plugin, port, _world.srate); - desc.label = slv2_value_as_string(slv2_port_get_name(_plugin, port)); - desc.lower = min ? slv2_value_as_float(min) : 0.0f; - desc.upper = max ? slv2_value_as_float(max) : 1.0f; - desc.min_unbound = false; // TODO (LV2 extension) - desc.max_unbound = false; // TODO (LV2 extension) - - if (desc.integer_step) { - desc.step = 1.0; - desc.smallstep = 0.1; - desc.largestep = 10.0; - } else { - const float delta = desc.upper - desc.lower; - desc.step = delta / 1000.0f; - desc.smallstep = delta / 10000.0f; - desc.largestep = delta/10.0f; - } - - slv2_value_free(def); - slv2_value_free(min); - slv2_value_free(max); - - return 0; -} - - -string -LV2Plugin::describe_parameter (Parameter which) -{ - if (which.type() == PluginAutomation && which.id() < parameter_count()) { - SLV2Value name = slv2_port_get_name(_plugin, - slv2_plugin_get_port_by_index(_plugin, which)); - string ret(slv2_value_as_string(name)); - slv2_value_free(name); - return ret; - } else { - return "??"; - } -} - -nframes_t -LV2Plugin::signal_latency () const -{ - if (_latency_control_port) { - return (nframes_t) floor (*_latency_control_port); - } else { - return 0; - } -} - -set<Parameter> -LV2Plugin::automatable () const -{ - set<Parameter> ret; - - for (uint32_t i = 0; i < parameter_count(); ++i){ - if (parameter_is_input(i) && parameter_is_control(i)) { - ret.insert (ret.end(), Parameter(PluginAutomation, i)); - } - } - - return ret; -} - -int -LV2Plugin::connect_and_run (BufferSet& bufs, uint32_t& in_index, uint32_t& out_index, nframes_t nframes, nframes_t offset) -{ - uint32_t port_index; - cycles_t then, now; - - port_index = 0; - - then = get_cycles (); - - const uint32_t nbufs = bufs.count().n_audio(); - - while (port_index < parameter_count()) { - if (parameter_is_audio(port_index)) { - if (parameter_is_input(port_index)) { - const size_t index = min(in_index, nbufs - 1); - slv2_instance_connect_port(_instance, port_index, - bufs.get_audio(index).data(nframes, offset)); - in_index++; - } else if (parameter_is_output(port_index)) { - const size_t index = min(out_index,nbufs - 1); - slv2_instance_connect_port(_instance, port_index, - bufs.get_audio(index).data(nframes, offset)); - out_index++; - } - } else if (parameter_is_midi(port_index)) { - // FIXME: Switch MIDI buffer format to LV2 event buffer - if (parameter_is_input(port_index)) { - //const size_t index = min(in_index, nbufs - 1); - //slv2_instance_connect_port(_instance, port_index, - // bufs.get_midi(index).data(nframes, offset)); - // FIXME: hope it's connection optional... - slv2_instance_connect_port(_instance, port_index, NULL); - in_index++; - } else if (parameter_is_output(port_index)) { - //const size_t index = min(out_index,nbufs - 1); - //slv2_instance_connect_port(_instance, port_index, - // bufs.get_midi(index).data(nframes, offset)); - // FIXME: hope it's connection optional... - slv2_instance_connect_port(_instance, port_index, NULL); - out_index++; - } - } - port_index++; - } - - run (nframes); - now = get_cycles (); - set_cycles ((uint32_t) (now - then)); - - return 0; -} - -bool -LV2Plugin::parameter_is_control (uint32_t param) const -{ - SLV2Port port = slv2_plugin_get_port_by_index(_plugin, param); - return slv2_port_is_a(_plugin, port, _world.control_class); -} - -bool -LV2Plugin::parameter_is_audio (uint32_t param) const -{ - SLV2Port port = slv2_plugin_get_port_by_index(_plugin, param); - return slv2_port_is_a(_plugin, port, _world.audio_class); -} - -bool -LV2Plugin::parameter_is_midi (uint32_t param) const -{ - SLV2Port port = slv2_plugin_get_port_by_index(_plugin, param); - return slv2_port_is_a(_plugin, port, _world.event_class) - && slv2_port_supports_event(_plugin, port, _world.midi_class); -} - -bool -LV2Plugin::parameter_is_output (uint32_t param) const -{ - SLV2Port port = slv2_plugin_get_port_by_index(_plugin, param); - return slv2_port_is_a(_plugin, port, _world.output_class); -} - -bool -LV2Plugin::parameter_is_input (uint32_t param) const -{ - SLV2Port port = slv2_plugin_get_port_by_index(_plugin, param); - return slv2_port_is_a(_plugin, port, _world.input_class); -} - -void -LV2Plugin::print_parameter (uint32_t param, char *buf, uint32_t len) const -{ - if (buf && len) { - if (param < parameter_count()) { - snprintf (buf, len, "%.3f", get_parameter (param)); - } else { - strcat (buf, "0"); - } - } -} - -void -LV2Plugin::run (nframes_t nframes) -{ - for (uint32_t i = 0; i < parameter_count(); ++i) { - if (parameter_is_control(i) && parameter_is_input(i)) { - _control_data[i] = _shadow_data[i]; - } - } - - slv2_instance_run(_instance, nframes); -} - -void -LV2Plugin::latency_compute_run () -{ - if (!_latency_control_port) { - return; - } - - /* we need to run the plugin so that it can set its latency - parameter. - */ - - activate (); - - uint32_t port_index = 0; - uint32_t in_index = 0; - uint32_t out_index = 0; - const nframes_t bufsize = 1024; - float buffer[bufsize]; - - memset(buffer,0,sizeof(float)*bufsize); - - /* Note that we've already required that plugins - be able to handle in-place processing. - */ - - port_index = 0; - - while (port_index < parameter_count()) { - if (parameter_is_audio (port_index)) { - if (parameter_is_input (port_index)) { - slv2_instance_connect_port (_instance, port_index, buffer); - in_index++; - } else if (parameter_is_output (port_index)) { - slv2_instance_connect_port (_instance, port_index, buffer); - out_index++; - } - } - port_index++; - } - - run (bufsize); - deactivate (); -} - -LV2World::LV2World() - : world(slv2_world_new()) -{ - slv2_world_load_all(world); - input_class = slv2_value_new_uri(world, SLV2_PORT_CLASS_INPUT); - output_class = slv2_value_new_uri(world, SLV2_PORT_CLASS_OUTPUT); - control_class = slv2_value_new_uri(world, SLV2_PORT_CLASS_CONTROL); - audio_class = slv2_value_new_uri(world, SLV2_PORT_CLASS_AUDIO); - event_class = slv2_value_new_uri(world, SLV2_PORT_CLASS_EVENT); - midi_class = slv2_value_new_uri(world, SLV2_EVENT_CLASS_MIDI); - in_place_broken = slv2_value_new_uri(world, SLV2_NAMESPACE_LV2 "inPlaceBroken"); - integer = slv2_value_new_uri(world, SLV2_NAMESPACE_LV2 "integer"); - toggled = slv2_value_new_uri(world, SLV2_NAMESPACE_LV2 "toggled"); - srate = slv2_value_new_uri(world, SLV2_NAMESPACE_LV2 "sampleRate"); -} - -LV2World::~LV2World() -{ - slv2_value_free(input_class); - slv2_value_free(output_class); - slv2_value_free(control_class); - slv2_value_free(audio_class); - slv2_value_free(event_class); - slv2_value_free(midi_class); - slv2_value_free(in_place_broken); -} - -LV2PluginInfo::LV2PluginInfo (void* lv2_world, void* slv2_plugin) - : _lv2_world(lv2_world) - , _slv2_plugin(slv2_plugin) -{ -} - -LV2PluginInfo::~LV2PluginInfo() -{ -} - -PluginPtr -LV2PluginInfo::load (Session& session) -{ - try { - PluginPtr plugin; - - plugin.reset (new LV2Plugin (session.engine(), session, - *(LV2World*)_lv2_world, (SLV2Plugin)_slv2_plugin, session.frame_rate())); - - plugin->set_info(PluginInfoPtr(new LV2PluginInfo(*this))); - return plugin; - } - - catch (failed_constructor &err) { - return PluginPtr ((Plugin*) 0); - } - - return PluginPtr(); -} - -PluginInfoList -LV2PluginInfo::discover (void* lv2_world) -{ - PluginInfoList plugs; - - LV2World* world = (LV2World*)lv2_world; - SLV2Plugins plugins = slv2_world_get_all_plugins(world->world); - - for (unsigned i=0; i < slv2_plugins_size(plugins); ++i) { - SLV2Plugin p = slv2_plugins_get_at(plugins, i); - LV2PluginInfoPtr info (new LV2PluginInfo(lv2_world, p)); - - SLV2Value name = slv2_plugin_get_name(p); - info->name = string(slv2_value_as_string(name)); - slv2_value_free(name); - - SLV2PluginClass pclass = slv2_plugin_get_class(p); - SLV2Value label = slv2_plugin_class_get_label(pclass); - info->category = slv2_value_as_string(label); - - SLV2Value author_name = slv2_plugin_get_author_name(p); - info->creator = author_name ? string(slv2_value_as_string(author_name)) : "Unknown"; - slv2_value_free(author_name); - - info->path = "/NOPATH"; // Meaningless for LV2 - - info->n_inputs.set_audio(slv2_plugin_get_num_ports_of_class(p, - world->input_class, world->audio_class, NULL)); - info->n_inputs.set_midi(slv2_plugin_get_num_ports_of_class(p, - world->input_class, world->event_class, NULL)); - - info->n_outputs.set_audio(slv2_plugin_get_num_ports_of_class(p, - world->output_class, world->audio_class, NULL)); - info->n_outputs.set_midi(slv2_plugin_get_num_ports_of_class(p, - world->output_class, world->event_class, NULL)); - - info->unique_id = slv2_value_as_uri(slv2_plugin_get_uri(p)); - info->index = 0; // Meaningless for LV2 - - plugs.push_back (info); - } - - return plugs; -} - diff --git a/libs/ardour/macosx/English.lproj/InfoPlist.strings b/libs/ardour/macosx/English.lproj/InfoPlist.strings Binary files differdeleted file mode 100644 index 0c0cacad8b..0000000000 --- a/libs/ardour/macosx/English.lproj/InfoPlist.strings +++ /dev/null diff --git a/libs/ardour/macosx/Info.plist b/libs/ardour/macosx/Info.plist deleted file mode 100644 index 931491039f..0000000000 --- a/libs/ardour/macosx/Info.plist +++ /dev/null @@ -1,26 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> - <key>CFBundleDevelopmentRegion</key> - <string>English</string> - <key>CFBundleExecutable</key> - <string>ardour</string> - <key>CFBundleIconFile</key> - <string></string> - <key>CFBundleIdentifier</key> - <string>com.apple.carbonframeworktemplate</string> - <key>CFBundleInfoDictionaryVersion</key> - <string>6.0</string> - <key>CFBundlePackageType</key> - <string>FMWK</string> - <key>CFBundleSignature</key> - <string>????</string> - <key>CFBundleVersion</key> - <string>1.0</string> - <key>CFBundleShortVersionString</key> - <string>1.01</string> - <key>CSResourcesFileMapped</key> - <true/> -</dict> -</plist> diff --git a/libs/ardour/macosx/ardour.xcodeproj/project.pbxproj b/libs/ardour/macosx/ardour.xcodeproj/project.pbxproj deleted file mode 100644 index 4026b65f59..0000000000 --- a/libs/ardour/macosx/ardour.xcodeproj/project.pbxproj +++ /dev/null @@ -1,1214 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 42; - objects = { - -/* Begin PBXBuildFile section */ - 696149E90B97CEF500ECBDF0 /* glib in Frameworks */ = {isa = PBXBuildFile; fileRef = 696149E50B97CEF500ECBDF0 /* glib */; }; - 696149EA0B97CEF500ECBDF0 /* gmodule in Frameworks */ = {isa = PBXBuildFile; fileRef = 696149E60B97CEF500ECBDF0 /* gmodule */; }; - 696149EB0B97CEF500ECBDF0 /* gobject in Frameworks */ = {isa = PBXBuildFile; fileRef = 696149E70B97CEF500ECBDF0 /* gobject */; }; - 696149EC0B97CEF500ECBDF0 /* gthread in Frameworks */ = {isa = PBXBuildFile; fileRef = 696149E80B97CEF500ECBDF0 /* gthread */; }; - 6964FECA0B8E7A7900799BAE /* version.h in Headers */ = {isa = PBXBuildFile; fileRef = 6964FEC80B8E7A7900799BAE /* version.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 6964FECB0B8E7A7900799BAE /* version.cc in Sources */ = {isa = PBXBuildFile; fileRef = 6964FEC90B8E7A7900799BAE /* version.cc */; }; - 696C90530B8D526000D66CAF /* ardour.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FAF0B8D526000D66CAF /* ardour.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C90540B8D526000D66CAF /* audio_diskstream.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FB00B8D526000D66CAF /* audio_diskstream.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C90550B8D526000D66CAF /* audio_library.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FB10B8D526000D66CAF /* audio_library.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C90560B8D526000D66CAF /* audio_track.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FB20B8D526000D66CAF /* audio_track.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C90580B8D526000D66CAF /* audioengine.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FB40B8D526000D66CAF /* audioengine.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C90590B8D526000D66CAF /* audiofilesource.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FB50B8D526000D66CAF /* audiofilesource.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C905A0B8D526000D66CAF /* audiofilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FB60B8D526000D66CAF /* audiofilter.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C905B0B8D526000D66CAF /* audioplaylist.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FB70B8D526000D66CAF /* audioplaylist.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C905C0B8D526000D66CAF /* audioregion.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FB80B8D526000D66CAF /* audioregion.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C905D0B8D526000D66CAF /* audiosource.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FB90B8D526000D66CAF /* audiosource.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C905E0B8D526000D66CAF /* auditioner.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FBA0B8D526000D66CAF /* auditioner.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C905F0B8D526000D66CAF /* automation_event.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FBB0B8D526000D66CAF /* automation_event.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C90600B8D526000D66CAF /* buffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FBC0B8D526000D66CAF /* buffer.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C90610B8D526000D66CAF /* click.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FBD0B8D526000D66CAF /* click.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C90620B8D526000D66CAF /* configuration.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FBE0B8D526000D66CAF /* configuration.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C90630B8D526000D66CAF /* configuration_variable.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FBF0B8D526000D66CAF /* configuration_variable.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C90640B8D526000D66CAF /* configuration_vars.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FC00B8D526000D66CAF /* configuration_vars.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C90650B8D526000D66CAF /* connection.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FC10B8D526000D66CAF /* connection.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C90660B8D526000D66CAF /* control_protocol_manager.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FC20B8D526000D66CAF /* control_protocol_manager.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C90680B8D526000D66CAF /* crossfade.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FC40B8D526000D66CAF /* crossfade.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C90690B8D526000D66CAF /* crossfade_compare.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FC50B8D526000D66CAF /* crossfade_compare.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C906A0B8D526000D66CAF /* curve.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FC60B8D526000D66CAF /* curve.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C906B0B8D526000D66CAF /* cycle_timer.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FC70B8D526000D66CAF /* cycle_timer.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C906C0B8D526000D66CAF /* cycles.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FC80B8D526000D66CAF /* cycles.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C906D0B8D526000D66CAF /* data_type.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FC90B8D526000D66CAF /* data_type.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C906E0B8D526000D66CAF /* dB.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FCA0B8D526000D66CAF /* dB.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C90700B8D526000D66CAF /* diskstream.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FCC0B8D526000D66CAF /* diskstream.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C90710B8D526000D66CAF /* export.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FCD0B8D526000D66CAF /* export.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C90720B8D526000D66CAF /* gain.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FCE0B8D526000D66CAF /* gain.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C90730B8D526000D66CAF /* gdither.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FCF0B8D526000D66CAF /* gdither.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C90740B8D526000D66CAF /* gdither_types.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FD00B8D526000D66CAF /* gdither_types.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C90750B8D526000D66CAF /* gdither_types_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FD10B8D526000D66CAF /* gdither_types_internal.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C90760B8D526000D66CAF /* insert.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FD20B8D526000D66CAF /* insert.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C90770B8D526000D66CAF /* io.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FD30B8D526000D66CAF /* io.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C90780B8D526000D66CAF /* ladspa.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FD40B8D526000D66CAF /* ladspa.h */; settings = {ATTRIBUTES = (); }; }; - 696C90790B8D526000D66CAF /* ladspa_plugin.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FD50B8D526000D66CAF /* ladspa_plugin.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C907A0B8D526000D66CAF /* location.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FD60B8D526000D66CAF /* location.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C907B0B8D526000D66CAF /* logcurve.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FD70B8D526000D66CAF /* logcurve.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C907C0B8D526000D66CAF /* mix.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FD80B8D526000D66CAF /* mix.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C907D0B8D526000D66CAF /* named_selection.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FD90B8D526000D66CAF /* named_selection.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C907E0B8D526000D66CAF /* noise.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FDA0B8D526000D66CAF /* noise.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C907F0B8D526000D66CAF /* osc.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FDB0B8D526000D66CAF /* osc.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C90800B8D526000D66CAF /* panner.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FDC0B8D526000D66CAF /* panner.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C90810B8D526000D66CAF /* pcm_utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FDD0B8D526000D66CAF /* pcm_utils.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C90820B8D526000D66CAF /* peak.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FDE0B8D526000D66CAF /* peak.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C90830B8D526000D66CAF /* playlist.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FDF0B8D526000D66CAF /* playlist.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C90840B8D526000D66CAF /* playlist_factory.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FE00B8D526000D66CAF /* playlist_factory.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C90850B8D526000D66CAF /* playlist_templates.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FE10B8D526000D66CAF /* playlist_templates.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C90860B8D526000D66CAF /* plugin.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FE20B8D526000D66CAF /* plugin.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C90870B8D526000D66CAF /* plugin_manager.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FE30B8D526000D66CAF /* plugin_manager.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C90880B8D526000D66CAF /* port.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FE40B8D526000D66CAF /* port.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C90890B8D526000D66CAF /* recent_sessions.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FE50B8D526000D66CAF /* recent_sessions.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C908A0B8D526000D66CAF /* redirect.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FE60B8D526000D66CAF /* redirect.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C908B0B8D526000D66CAF /* region.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FE70B8D526000D66CAF /* region.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C908C0B8D526000D66CAF /* region_factory.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FE80B8D526000D66CAF /* region_factory.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C908D0B8D526000D66CAF /* reverse.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FE90B8D526000D66CAF /* reverse.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C908E0B8D526000D66CAF /* route.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FEA0B8D526000D66CAF /* route.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C908F0B8D526000D66CAF /* route_group.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FEB0B8D526000D66CAF /* route_group.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C90900B8D526000D66CAF /* route_group_specialized.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FEC0B8D526000D66CAF /* route_group_specialized.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C90910B8D526000D66CAF /* send.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FED0B8D526000D66CAF /* send.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C90920B8D526000D66CAF /* session.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FEE0B8D526000D66CAF /* session.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C90930B8D526000D66CAF /* session_connection.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FEF0B8D526000D66CAF /* session_connection.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C90940B8D526000D66CAF /* session_playlist.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FF00B8D526000D66CAF /* session_playlist.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C90950B8D526000D66CAF /* session_region.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FF10B8D526000D66CAF /* session_region.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C90960B8D526000D66CAF /* session_route.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FF20B8D526000D66CAF /* session_route.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C90970B8D526000D66CAF /* session_selection.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FF30B8D526000D66CAF /* session_selection.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C90980B8D526000D66CAF /* silentfilesource.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FF40B8D526000D66CAF /* silentfilesource.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C90990B8D526000D66CAF /* slave.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FF50B8D526000D66CAF /* slave.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C909A0B8D526000D66CAF /* sndfile_helpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FF60B8D526000D66CAF /* sndfile_helpers.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C909B0B8D526000D66CAF /* sndfilesource.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FF70B8D526000D66CAF /* sndfilesource.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C909C0B8D526000D66CAF /* soundseq.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FF80B8D526000D66CAF /* soundseq.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C909D0B8D526000D66CAF /* source.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FF90B8D526000D66CAF /* source.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C909E0B8D526000D66CAF /* source_factory.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FFA0B8D526000D66CAF /* source_factory.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C909F0B8D526000D66CAF /* spline.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FFB0B8D526000D66CAF /* spline.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C90A00B8D526000D66CAF /* tempo.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FFC0B8D526000D66CAF /* tempo.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C90A10B8D526000D66CAF /* timestamps.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FFD0B8D526000D66CAF /* timestamps.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C90A20B8D526000D66CAF /* track.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FFE0B8D526000D66CAF /* track.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C90A30B8D526000D66CAF /* types.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C8FFF0B8D526000D66CAF /* types.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C90A40B8D526000D66CAF /* utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C90000B8D526000D66CAF /* utils.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 696C90A60B8D526000D66CAF /* audio_diskstream.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C90020B8D526000D66CAF /* audio_diskstream.cc */; }; - 696C90A70B8D526000D66CAF /* audio_library.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C90030B8D526000D66CAF /* audio_library.cc */; }; - 696C90A80B8D526000D66CAF /* audio_playlist.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C90040B8D526000D66CAF /* audio_playlist.cc */; }; - 696C90A90B8D526000D66CAF /* audio_track.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C90050B8D526000D66CAF /* audio_track.cc */; }; - 696C90AB0B8D526000D66CAF /* audioengine.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C90070B8D526000D66CAF /* audioengine.cc */; }; - 696C90AC0B8D526000D66CAF /* audiofilesource.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C90080B8D526000D66CAF /* audiofilesource.cc */; }; - 696C90AD0B8D526000D66CAF /* audiofilter.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C90090B8D526000D66CAF /* audiofilter.cc */; }; - 696C90AE0B8D526000D66CAF /* audioregion.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C900A0B8D526000D66CAF /* audioregion.cc */; }; - 696C90AF0B8D526000D66CAF /* audiosource.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C900B0B8D526000D66CAF /* audiosource.cc */; }; - 696C90B00B8D526000D66CAF /* auditioner.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C900C0B8D526000D66CAF /* auditioner.cc */; }; - 696C90B10B8D526000D66CAF /* automation.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C900D0B8D526000D66CAF /* automation.cc */; }; - 696C90B20B8D526000D66CAF /* automation_event.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C900E0B8D526000D66CAF /* automation_event.cc */; }; - 696C90B30B8D526000D66CAF /* configuration.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C900F0B8D526000D66CAF /* configuration.cc */; }; - 696C90B40B8D526000D66CAF /* connection.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C90100B8D526000D66CAF /* connection.cc */; }; - 696C90B50B8D526000D66CAF /* control_protocol_manager.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C90110B8D526000D66CAF /* control_protocol_manager.cc */; }; - 696C90B70B8D526000D66CAF /* crossfade.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C90130B8D526000D66CAF /* crossfade.cc */; }; - 696C90B80B8D526000D66CAF /* curve.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C90140B8D526000D66CAF /* curve.cc */; }; - 696C90B90B8D526000D66CAF /* cycle_timer.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C90150B8D526000D66CAF /* cycle_timer.cc */; }; - 696C90BA0B8D526000D66CAF /* default_click.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C90160B8D526000D66CAF /* default_click.cc */; }; - 696C90BC0B8D526000D66CAF /* diskstream.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C90180B8D526000D66CAF /* diskstream.cc */; }; - 696C90BD0B8D526000D66CAF /* enums.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C90190B8D526000D66CAF /* enums.cc */; }; - 696C90BE0B8D526000D66CAF /* gain.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C901A0B8D526000D66CAF /* gain.cc */; }; - 696C90BF0B8D526000D66CAF /* gdither.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C901B0B8D526000D66CAF /* gdither.cc */; }; - 696C90C00B8D526000D66CAF /* gettext.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C901C0B8D526000D66CAF /* gettext.h */; settings = {ATTRIBUTES = (); }; }; - 696C90C10B8D526000D66CAF /* globals.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C901D0B8D526000D66CAF /* globals.cc */; }; - 696C90C20B8D526000D66CAF /* i18n.h in Headers */ = {isa = PBXBuildFile; fileRef = 696C901E0B8D526000D66CAF /* i18n.h */; settings = {ATTRIBUTES = (); }; }; - 696C90C30B8D526000D66CAF /* import.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C901F0B8D526000D66CAF /* import.cc */; }; - 696C90C40B8D526000D66CAF /* insert.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C90200B8D526000D66CAF /* insert.cc */; }; - 696C90C50B8D526000D66CAF /* io.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C90210B8D526000D66CAF /* io.cc */; }; - 696C90C60B8D526000D66CAF /* jack_slave.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C90220B8D526000D66CAF /* jack_slave.cc */; }; - 696C90C70B8D526000D66CAF /* ladspa_plugin.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C90230B8D526000D66CAF /* ladspa_plugin.cc */; }; - 696C90C80B8D526000D66CAF /* location.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C90240B8D526000D66CAF /* location.cc */; }; - 696C90C90B8D526000D66CAF /* mix.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C90250B8D526000D66CAF /* mix.cc */; }; - 696C90CA0B8D526000D66CAF /* mtc_slave.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C90260B8D526000D66CAF /* mtc_slave.cc */; }; - 696C90CB0B8D526000D66CAF /* named_selection.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C90270B8D526000D66CAF /* named_selection.cc */; }; - 696C90CC0B8D526000D66CAF /* osc.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C90280B8D526000D66CAF /* osc.cc */; }; - 696C90CD0B8D526000D66CAF /* panner.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C90290B8D526000D66CAF /* panner.cc */; }; - 696C90CE0B8D526000D66CAF /* pcm_utils.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C902A0B8D526000D66CAF /* pcm_utils.cc */; }; - 696C90CF0B8D526000D66CAF /* playlist.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C902B0B8D526000D66CAF /* playlist.cc */; }; - 696C90D00B8D526000D66CAF /* playlist_factory.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C902C0B8D526000D66CAF /* playlist_factory.cc */; }; - 696C90D10B8D526000D66CAF /* plugin.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C902D0B8D526000D66CAF /* plugin.cc */; }; - 696C90D20B8D526000D66CAF /* plugin_manager.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C902E0B8D526000D66CAF /* plugin_manager.cc */; }; - 696C90D30B8D526000D66CAF /* port.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C902F0B8D526000D66CAF /* port.cc */; }; - 696C90D40B8D526000D66CAF /* recent_sessions.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C90300B8D526000D66CAF /* recent_sessions.cc */; }; - 696C90D50B8D526000D66CAF /* redirect.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C90310B8D526000D66CAF /* redirect.cc */; }; - 696C90D60B8D526000D66CAF /* region.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C90320B8D526000D66CAF /* region.cc */; }; - 696C90D70B8D526000D66CAF /* region_factory.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C90330B8D526000D66CAF /* region_factory.cc */; }; - 696C90D80B8D526000D66CAF /* reverse.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C90340B8D526000D66CAF /* reverse.cc */; }; - 696C90D90B8D526000D66CAF /* route.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C90350B8D526000D66CAF /* route.cc */; }; - 696C90DA0B8D526000D66CAF /* route_group.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C90360B8D526000D66CAF /* route_group.cc */; }; - 696C90DB0B8D526000D66CAF /* send.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C90370B8D526000D66CAF /* send.cc */; }; - 696C90DC0B8D526000D66CAF /* session.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C90380B8D526000D66CAF /* session.cc */; }; - 696C90DD0B8D526000D66CAF /* session_butler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C90390B8D526000D66CAF /* session_butler.cc */; }; - 696C90DE0B8D526000D66CAF /* session_click.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C903A0B8D526000D66CAF /* session_click.cc */; }; - 696C90DF0B8D526000D66CAF /* session_command.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C903B0B8D526000D66CAF /* session_command.cc */; }; - 696C90E10B8D526000D66CAF /* session_events.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C903D0B8D526000D66CAF /* session_events.cc */; }; - 696C90E20B8D526000D66CAF /* session_export.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C903E0B8D526000D66CAF /* session_export.cc */; }; - 696C90E30B8D526000D66CAF /* session_feedback.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C903F0B8D526000D66CAF /* session_feedback.cc */; }; - 696C90E40B8D526000D66CAF /* session_midi.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C90400B8D526000D66CAF /* session_midi.cc */; }; - 696C90E50B8D526000D66CAF /* session_process.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C90410B8D526000D66CAF /* session_process.cc */; }; - 696C90E60B8D526000D66CAF /* session_state.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C90420B8D526000D66CAF /* session_state.cc */; }; - 696C90E70B8D526000D66CAF /* session_time.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C90430B8D526000D66CAF /* session_time.cc */; }; - 696C90E80B8D526000D66CAF /* session_timefx.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C90440B8D526000D66CAF /* session_timefx.cc */; }; - 696C90E90B8D526000D66CAF /* session_transport.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C90450B8D526000D66CAF /* session_transport.cc */; }; - 696C90EB0B8D526000D66CAF /* silentfilesource.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C90470B8D526000D66CAF /* silentfilesource.cc */; }; - 696C90EC0B8D526000D66CAF /* sndfile_helpers.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C90480B8D526000D66CAF /* sndfile_helpers.cc */; }; - 696C90ED0B8D526000D66CAF /* sndfilesource.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C90490B8D526000D66CAF /* sndfilesource.cc */; }; - 696C90EE0B8D526000D66CAF /* source.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C904A0B8D526000D66CAF /* source.cc */; }; - 696C90EF0B8D526000D66CAF /* source_factory.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C904B0B8D526000D66CAF /* source_factory.cc */; }; - 696C90F20B8D526000D66CAF /* tempo.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C904E0B8D526000D66CAF /* tempo.cc */; }; - 696C90F30B8D526000D66CAF /* track.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C904F0B8D526000D66CAF /* track.cc */; }; - 696C90F40B8D526000D66CAF /* utils.cc in Sources */ = {isa = PBXBuildFile; fileRef = 696C90500B8D526000D66CAF /* utils.cc */; }; - 696C91000B8D52F300D66CAF /* glibmm.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 696C90F70B8D52F300D66CAF /* glibmm.framework */; }; - 696C91010B8D52F300D66CAF /* Jack.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 696C90F80B8D52F300D66CAF /* Jack.framework */; }; - 696C91020B8D52F300D66CAF /* lo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 696C90F90B8D52F300D66CAF /* lo.framework */; }; - 696C91030B8D52F300D66CAF /* LRdf.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 696C90FA0B8D52F300D66CAF /* LRdf.framework */; }; - 696C91040B8D52F300D66CAF /* Raptor.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 696C90FB0B8D52F300D66CAF /* Raptor.framework */; }; - 696C91050B8D52F300D66CAF /* SampleRate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 696C90FC0B8D52F300D66CAF /* SampleRate.framework */; }; - 696C91060B8D52F300D66CAF /* sigc.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 696C90FD0B8D52F300D66CAF /* sigc.framework */; }; - 696C91070B8D52F300D66CAF /* Sndfile-ardour.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 696C90FE0B8D52F300D66CAF /* Sndfile-ardour.framework */; }; - 696C91080B8D52F300D66CAF /* soundtouch.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 696C90FF0B8D52F300D66CAF /* soundtouch.framework */; }; - 697D98090B8DCD8C0006A892 /* libxml2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 697D98080B8DCD8C0006A892 /* libxml2.dylib */; }; - 698D9AB60B969A6F00C53B63 /* midi++.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 698D9AB50B969A5B00C53B63 /* midi++.framework */; }; - 69AD45850B97D10600806E7E /* FLAC in Frameworks */ = {isa = PBXBuildFile; fileRef = 69AD45840B97D10600806E7E /* FLAC */; }; - 69B1B5210B8E7DFD007E41C1 /* pbd.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 691B3B7C0B8D5508009155B5 /* pbd.framework */; }; - 69B1B5500B8E80AD007E41C1 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 69B1B54F0B8E80AD007E41C1 /* CoreAudio.framework */; }; - 69DBC41B0BA794A500C19E65 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 69DBC41A0BA794A500C19E65 /* Accelerate.framework */; }; - 69DBC42B0BA7992800C19E65 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 69DBC42A0BA7992800C19E65 /* Carbon.framework */; }; - 69F7CE5A0B8DCB3300D76871 /* basic_ui.cc in Sources */ = {isa = PBXBuildFile; fileRef = 69F7CE520B8DCB3300D76871 /* basic_ui.cc */; }; - 69F7CE5B0B8DCB3300D76871 /* basic_ui.h in Headers */ = {isa = PBXBuildFile; fileRef = 69F7CE540B8DCB3300D76871 /* basic_ui.h */; }; - 69F7CE5C0B8DCB3300D76871 /* control_protocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 69F7CE550B8DCB3300D76871 /* control_protocol.h */; }; - 69F7CE5D0B8DCB3300D76871 /* smpte.h in Headers */ = {isa = PBXBuildFile; fileRef = 69F7CE560B8DCB3300D76871 /* smpte.h */; }; - 69F7CE5E0B8DCB3300D76871 /* control_protocol.cc in Sources */ = {isa = PBXBuildFile; fileRef = 69F7CE570B8DCB3300D76871 /* control_protocol.cc */; }; - 69F7CE600B8DCB3300D76871 /* smpte.cc in Sources */ = {isa = PBXBuildFile; fileRef = 69F7CE590B8DCB3300D76871 /* smpte.cc */; }; - 8D07F2BE0486CC7A007CD1D0 /* ardour_Prefix.pch in Headers */ = {isa = PBXBuildFile; fileRef = 32BAE0B70371A74B00C91783 /* ardour_Prefix.pch */; settings = {ATTRIBUTES = (); }; }; - 8D07F2C00486CC7A007CD1D0 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C1666FE841158C02AAC07 /* InfoPlist.strings */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - 691B3B7B0B8D5508009155B5 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 691B3B770B8D5508009155B5 /* pbd.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 8D07F2C80486CC7A007CD1D0; - remoteInfo = pbd; - }; - 698D9AB40B969A5B00C53B63 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 698D9AB00B969A5B00C53B63 /* midi++.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 8D07F2C80486CC7A007CD1D0; - remoteInfo = "midi++"; - }; - 698D9AB90B969ADC00C53B63 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 698D9AB00B969A5B00C53B63 /* midi++.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; - remoteInfo = "midi++"; - }; - 69D5F6250B8D58A500301E71 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 691B3B770B8D5508009155B5 /* pbd.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0; - remoteInfo = pbd; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXFileReference section */ - 089C1667FE841158C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; }; - 32BAE0B70371A74B00C91783 /* ardour_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ardour_Prefix.pch; sourceTree = "<group>"; }; - 691B3B770B8D5508009155B5 /* pbd.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = pbd.xcodeproj; path = ../../pbd/macosx/pbd.xcodeproj; sourceTree = SOURCE_ROOT; }; - 696149E50B97CEF500ECBDF0 /* glib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = glib; path = /Library/Frameworks/GLib.framework/Versions/2.12.3/Libraries/glib; sourceTree = "<absolute>"; }; - 696149E60B97CEF500ECBDF0 /* gmodule */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = gmodule; path = /Library/Frameworks/GLib.framework/Versions/2.12.3/Libraries/gmodule; sourceTree = "<absolute>"; }; - 696149E70B97CEF500ECBDF0 /* gobject */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = gobject; path = /Library/Frameworks/GLib.framework/Versions/2.12.3/Libraries/gobject; sourceTree = "<absolute>"; }; - 696149E80B97CEF500ECBDF0 /* gthread */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = gthread; path = /Library/Frameworks/GLib.framework/Versions/2.12.3/Libraries/gthread; sourceTree = "<absolute>"; }; - 6964FEC80B8E7A7900799BAE /* version.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = version.h; sourceTree = "<group>"; }; - 6964FEC90B8E7A7900799BAE /* version.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = version.cc; sourceTree = "<group>"; }; - 696C8FAF0B8D526000D66CAF /* ardour.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ardour.h; sourceTree = "<group>"; }; - 696C8FB00B8D526000D66CAF /* audio_diskstream.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = audio_diskstream.h; sourceTree = "<group>"; }; - 696C8FB10B8D526000D66CAF /* audio_library.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = audio_library.h; sourceTree = "<group>"; }; - 696C8FB20B8D526000D66CAF /* audio_track.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = audio_track.h; sourceTree = "<group>"; }; - 696C8FB40B8D526000D66CAF /* audioengine.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = audioengine.h; sourceTree = "<group>"; }; - 696C8FB50B8D526000D66CAF /* audiofilesource.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = audiofilesource.h; sourceTree = "<group>"; }; - 696C8FB60B8D526000D66CAF /* audiofilter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = audiofilter.h; sourceTree = "<group>"; }; - 696C8FB70B8D526000D66CAF /* audioplaylist.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = audioplaylist.h; sourceTree = "<group>"; }; - 696C8FB80B8D526000D66CAF /* audioregion.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = audioregion.h; sourceTree = "<group>"; }; - 696C8FB90B8D526000D66CAF /* audiosource.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = audiosource.h; sourceTree = "<group>"; }; - 696C8FBA0B8D526000D66CAF /* auditioner.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = auditioner.h; sourceTree = "<group>"; }; - 696C8FBB0B8D526000D66CAF /* automation_event.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = automation_event.h; sourceTree = "<group>"; }; - 696C8FBC0B8D526000D66CAF /* buffer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = buffer.h; sourceTree = "<group>"; }; - 696C8FBD0B8D526000D66CAF /* click.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = click.h; sourceTree = "<group>"; }; - 696C8FBE0B8D526000D66CAF /* configuration.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = configuration.h; sourceTree = "<group>"; }; - 696C8FBF0B8D526000D66CAF /* configuration_variable.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = configuration_variable.h; sourceTree = "<group>"; }; - 696C8FC00B8D526000D66CAF /* configuration_vars.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = configuration_vars.h; sourceTree = "<group>"; }; - 696C8FC10B8D526000D66CAF /* connection.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = connection.h; sourceTree = "<group>"; }; - 696C8FC20B8D526000D66CAF /* control_protocol_manager.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = control_protocol_manager.h; sourceTree = "<group>"; }; - 696C8FC40B8D526000D66CAF /* crossfade.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = crossfade.h; sourceTree = "<group>"; }; - 696C8FC50B8D526000D66CAF /* crossfade_compare.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = crossfade_compare.h; sourceTree = "<group>"; }; - 696C8FC60B8D526000D66CAF /* curve.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = curve.h; sourceTree = "<group>"; }; - 696C8FC70B8D526000D66CAF /* cycle_timer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = cycle_timer.h; sourceTree = "<group>"; }; - 696C8FC80B8D526000D66CAF /* cycles.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = cycles.h; sourceTree = "<group>"; }; - 696C8FC90B8D526000D66CAF /* data_type.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = data_type.h; sourceTree = "<group>"; }; - 696C8FCA0B8D526000D66CAF /* dB.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = dB.h; sourceTree = "<group>"; }; - 696C8FCC0B8D526000D66CAF /* diskstream.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = diskstream.h; sourceTree = "<group>"; }; - 696C8FCD0B8D526000D66CAF /* export.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = export.h; sourceTree = "<group>"; }; - 696C8FCE0B8D526000D66CAF /* gain.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = gain.h; sourceTree = "<group>"; }; - 696C8FCF0B8D526000D66CAF /* gdither.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = gdither.h; sourceTree = "<group>"; }; - 696C8FD00B8D526000D66CAF /* gdither_types.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = gdither_types.h; sourceTree = "<group>"; }; - 696C8FD10B8D526000D66CAF /* gdither_types_internal.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = gdither_types_internal.h; sourceTree = "<group>"; }; - 696C8FD20B8D526000D66CAF /* insert.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = insert.h; sourceTree = "<group>"; }; - 696C8FD30B8D526000D66CAF /* io.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = io.h; sourceTree = "<group>"; }; - 696C8FD40B8D526000D66CAF /* ladspa.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ladspa.h; sourceTree = "<group>"; }; - 696C8FD50B8D526000D66CAF /* ladspa_plugin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ladspa_plugin.h; sourceTree = "<group>"; }; - 696C8FD60B8D526000D66CAF /* location.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = location.h; sourceTree = "<group>"; }; - 696C8FD70B8D526000D66CAF /* logcurve.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = logcurve.h; sourceTree = "<group>"; }; - 696C8FD80B8D526000D66CAF /* mix.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = mix.h; sourceTree = "<group>"; }; - 696C8FD90B8D526000D66CAF /* named_selection.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = named_selection.h; sourceTree = "<group>"; }; - 696C8FDA0B8D526000D66CAF /* noise.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = noise.h; sourceTree = "<group>"; }; - 696C8FDB0B8D526000D66CAF /* osc.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = osc.h; sourceTree = "<group>"; }; - 696C8FDC0B8D526000D66CAF /* panner.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = panner.h; sourceTree = "<group>"; }; - 696C8FDD0B8D526000D66CAF /* pcm_utils.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = pcm_utils.h; sourceTree = "<group>"; }; - 696C8FDE0B8D526000D66CAF /* peak.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = peak.h; sourceTree = "<group>"; }; - 696C8FDF0B8D526000D66CAF /* playlist.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = playlist.h; sourceTree = "<group>"; }; - 696C8FE00B8D526000D66CAF /* playlist_factory.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = playlist_factory.h; sourceTree = "<group>"; }; - 696C8FE10B8D526000D66CAF /* playlist_templates.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = playlist_templates.h; sourceTree = "<group>"; }; - 696C8FE20B8D526000D66CAF /* plugin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = plugin.h; sourceTree = "<group>"; }; - 696C8FE30B8D526000D66CAF /* plugin_manager.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = plugin_manager.h; sourceTree = "<group>"; }; - 696C8FE40B8D526000D66CAF /* port.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = port.h; sourceTree = "<group>"; }; - 696C8FE50B8D526000D66CAF /* recent_sessions.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = recent_sessions.h; sourceTree = "<group>"; }; - 696C8FE60B8D526000D66CAF /* redirect.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = redirect.h; sourceTree = "<group>"; }; - 696C8FE70B8D526000D66CAF /* region.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = region.h; sourceTree = "<group>"; }; - 696C8FE80B8D526000D66CAF /* region_factory.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = region_factory.h; sourceTree = "<group>"; }; - 696C8FE90B8D526000D66CAF /* reverse.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = reverse.h; sourceTree = "<group>"; }; - 696C8FEA0B8D526000D66CAF /* route.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = route.h; sourceTree = "<group>"; }; - 696C8FEB0B8D526000D66CAF /* route_group.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = route_group.h; sourceTree = "<group>"; }; - 696C8FEC0B8D526000D66CAF /* route_group_specialized.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = route_group_specialized.h; sourceTree = "<group>"; }; - 696C8FED0B8D526000D66CAF /* send.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = send.h; sourceTree = "<group>"; }; - 696C8FEE0B8D526000D66CAF /* session.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = session.h; sourceTree = "<group>"; }; - 696C8FEF0B8D526000D66CAF /* session_connection.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = session_connection.h; sourceTree = "<group>"; }; - 696C8FF00B8D526000D66CAF /* session_playlist.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = session_playlist.h; sourceTree = "<group>"; }; - 696C8FF10B8D526000D66CAF /* session_region.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = session_region.h; sourceTree = "<group>"; }; - 696C8FF20B8D526000D66CAF /* session_route.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = session_route.h; sourceTree = "<group>"; }; - 696C8FF30B8D526000D66CAF /* session_selection.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = session_selection.h; sourceTree = "<group>"; }; - 696C8FF40B8D526000D66CAF /* silentfilesource.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = silentfilesource.h; sourceTree = "<group>"; }; - 696C8FF50B8D526000D66CAF /* slave.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = slave.h; sourceTree = "<group>"; }; - 696C8FF60B8D526000D66CAF /* sndfile_helpers.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = sndfile_helpers.h; sourceTree = "<group>"; }; - 696C8FF70B8D526000D66CAF /* sndfilesource.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = sndfilesource.h; sourceTree = "<group>"; }; - 696C8FF80B8D526000D66CAF /* soundseq.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = soundseq.h; sourceTree = "<group>"; }; - 696C8FF90B8D526000D66CAF /* source.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = source.h; sourceTree = "<group>"; }; - 696C8FFA0B8D526000D66CAF /* source_factory.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = source_factory.h; sourceTree = "<group>"; }; - 696C8FFB0B8D526000D66CAF /* spline.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = spline.h; sourceTree = "<group>"; }; - 696C8FFC0B8D526000D66CAF /* tempo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = tempo.h; sourceTree = "<group>"; }; - 696C8FFD0B8D526000D66CAF /* timestamps.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = timestamps.h; sourceTree = "<group>"; }; - 696C8FFE0B8D526000D66CAF /* track.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = track.h; sourceTree = "<group>"; }; - 696C8FFF0B8D526000D66CAF /* types.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = types.h; sourceTree = "<group>"; }; - 696C90000B8D526000D66CAF /* utils.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = utils.h; sourceTree = "<group>"; }; - 696C90020B8D526000D66CAF /* audio_diskstream.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = audio_diskstream.cc; path = ../audio_diskstream.cc; sourceTree = SOURCE_ROOT; }; - 696C90030B8D526000D66CAF /* audio_library.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = audio_library.cc; path = ../audio_library.cc; sourceTree = SOURCE_ROOT; }; - 696C90040B8D526000D66CAF /* audio_playlist.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = audio_playlist.cc; path = ../audio_playlist.cc; sourceTree = SOURCE_ROOT; }; - 696C90050B8D526000D66CAF /* audio_track.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = audio_track.cc; path = ../audio_track.cc; sourceTree = SOURCE_ROOT; }; - 696C90070B8D526000D66CAF /* audioengine.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = audioengine.cc; path = ../audioengine.cc; sourceTree = SOURCE_ROOT; }; - 696C90080B8D526000D66CAF /* audiofilesource.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = audiofilesource.cc; path = ../audiofilesource.cc; sourceTree = SOURCE_ROOT; }; - 696C90090B8D526000D66CAF /* audiofilter.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = audiofilter.cc; path = ../audiofilter.cc; sourceTree = SOURCE_ROOT; }; - 696C900A0B8D526000D66CAF /* audioregion.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = audioregion.cc; path = ../audioregion.cc; sourceTree = SOURCE_ROOT; }; - 696C900B0B8D526000D66CAF /* audiosource.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = audiosource.cc; path = ../audiosource.cc; sourceTree = SOURCE_ROOT; }; - 696C900C0B8D526000D66CAF /* auditioner.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = auditioner.cc; path = ../auditioner.cc; sourceTree = SOURCE_ROOT; }; - 696C900D0B8D526000D66CAF /* automation.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = automation.cc; path = ../automation.cc; sourceTree = SOURCE_ROOT; }; - 696C900E0B8D526000D66CAF /* automation_event.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = automation_event.cc; path = ../automation_event.cc; sourceTree = SOURCE_ROOT; }; - 696C900F0B8D526000D66CAF /* configuration.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = configuration.cc; path = ../configuration.cc; sourceTree = SOURCE_ROOT; }; - 696C90100B8D526000D66CAF /* connection.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = connection.cc; path = ../connection.cc; sourceTree = SOURCE_ROOT; }; - 696C90110B8D526000D66CAF /* control_protocol_manager.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = control_protocol_manager.cc; path = ../control_protocol_manager.cc; sourceTree = SOURCE_ROOT; }; - 696C90130B8D526000D66CAF /* crossfade.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = crossfade.cc; path = ../crossfade.cc; sourceTree = SOURCE_ROOT; }; - 696C90140B8D526000D66CAF /* curve.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = curve.cc; path = ../curve.cc; sourceTree = SOURCE_ROOT; }; - 696C90150B8D526000D66CAF /* cycle_timer.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = cycle_timer.cc; path = ../cycle_timer.cc; sourceTree = SOURCE_ROOT; }; - 696C90160B8D526000D66CAF /* default_click.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = default_click.cc; path = ../default_click.cc; sourceTree = SOURCE_ROOT; }; - 696C90180B8D526000D66CAF /* diskstream.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = diskstream.cc; path = ../diskstream.cc; sourceTree = SOURCE_ROOT; }; - 696C90190B8D526000D66CAF /* enums.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = enums.cc; path = ../enums.cc; sourceTree = SOURCE_ROOT; }; - 696C901A0B8D526000D66CAF /* gain.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = gain.cc; path = ../gain.cc; sourceTree = SOURCE_ROOT; }; - 696C901B0B8D526000D66CAF /* gdither.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = gdither.cc; path = ../gdither.cc; sourceTree = SOURCE_ROOT; }; - 696C901C0B8D526000D66CAF /* gettext.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = gettext.h; path = ../gettext.h; sourceTree = SOURCE_ROOT; }; - 696C901D0B8D526000D66CAF /* globals.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = globals.cc; path = ../globals.cc; sourceTree = SOURCE_ROOT; }; - 696C901E0B8D526000D66CAF /* i18n.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = i18n.h; path = ../i18n.h; sourceTree = SOURCE_ROOT; }; - 696C901F0B8D526000D66CAF /* import.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = import.cc; path = ../import.cc; sourceTree = SOURCE_ROOT; }; - 696C90200B8D526000D66CAF /* insert.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = insert.cc; path = ../insert.cc; sourceTree = SOURCE_ROOT; }; - 696C90210B8D526000D66CAF /* io.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = io.cc; path = ../io.cc; sourceTree = SOURCE_ROOT; }; - 696C90220B8D526000D66CAF /* jack_slave.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = jack_slave.cc; path = ../jack_slave.cc; sourceTree = SOURCE_ROOT; }; - 696C90230B8D526000D66CAF /* ladspa_plugin.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ladspa_plugin.cc; path = ../ladspa_plugin.cc; sourceTree = SOURCE_ROOT; }; - 696C90240B8D526000D66CAF /* location.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = location.cc; path = ../location.cc; sourceTree = SOURCE_ROOT; }; - 696C90250B8D526000D66CAF /* mix.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = mix.cc; path = ../mix.cc; sourceTree = SOURCE_ROOT; }; - 696C90260B8D526000D66CAF /* mtc_slave.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = mtc_slave.cc; path = ../mtc_slave.cc; sourceTree = SOURCE_ROOT; }; - 696C90270B8D526000D66CAF /* named_selection.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = named_selection.cc; path = ../named_selection.cc; sourceTree = SOURCE_ROOT; }; - 696C90280B8D526000D66CAF /* osc.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = osc.cc; path = ../osc.cc; sourceTree = SOURCE_ROOT; }; - 696C90290B8D526000D66CAF /* panner.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = panner.cc; path = ../panner.cc; sourceTree = SOURCE_ROOT; }; - 696C902A0B8D526000D66CAF /* pcm_utils.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = pcm_utils.cc; path = ../pcm_utils.cc; sourceTree = SOURCE_ROOT; }; - 696C902B0B8D526000D66CAF /* playlist.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = playlist.cc; path = ../playlist.cc; sourceTree = SOURCE_ROOT; }; - 696C902C0B8D526000D66CAF /* playlist_factory.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = playlist_factory.cc; path = ../playlist_factory.cc; sourceTree = SOURCE_ROOT; }; - 696C902D0B8D526000D66CAF /* plugin.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = plugin.cc; path = ../plugin.cc; sourceTree = SOURCE_ROOT; }; - 696C902E0B8D526000D66CAF /* plugin_manager.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = plugin_manager.cc; path = ../plugin_manager.cc; sourceTree = SOURCE_ROOT; }; - 696C902F0B8D526000D66CAF /* port.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = port.cc; path = ../port.cc; sourceTree = SOURCE_ROOT; }; - 696C90300B8D526000D66CAF /* recent_sessions.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = recent_sessions.cc; path = ../recent_sessions.cc; sourceTree = SOURCE_ROOT; }; - 696C90310B8D526000D66CAF /* redirect.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = redirect.cc; path = ../redirect.cc; sourceTree = SOURCE_ROOT; }; - 696C90320B8D526000D66CAF /* region.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = region.cc; path = ../region.cc; sourceTree = SOURCE_ROOT; }; - 696C90330B8D526000D66CAF /* region_factory.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = region_factory.cc; path = ../region_factory.cc; sourceTree = SOURCE_ROOT; }; - 696C90340B8D526000D66CAF /* reverse.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = reverse.cc; path = ../reverse.cc; sourceTree = SOURCE_ROOT; }; - 696C90350B8D526000D66CAF /* route.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = route.cc; path = ../route.cc; sourceTree = SOURCE_ROOT; }; - 696C90360B8D526000D66CAF /* route_group.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = route_group.cc; path = ../route_group.cc; sourceTree = SOURCE_ROOT; }; - 696C90370B8D526000D66CAF /* send.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = send.cc; path = ../send.cc; sourceTree = SOURCE_ROOT; }; - 696C90380B8D526000D66CAF /* session.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = session.cc; path = ../session.cc; sourceTree = SOURCE_ROOT; }; - 696C90390B8D526000D66CAF /* session_butler.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = session_butler.cc; path = ../session_butler.cc; sourceTree = SOURCE_ROOT; }; - 696C903A0B8D526000D66CAF /* session_click.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = session_click.cc; path = ../session_click.cc; sourceTree = SOURCE_ROOT; }; - 696C903B0B8D526000D66CAF /* session_command.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = session_command.cc; path = ../session_command.cc; sourceTree = SOURCE_ROOT; }; - 696C903D0B8D526000D66CAF /* session_events.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = session_events.cc; path = ../session_events.cc; sourceTree = SOURCE_ROOT; }; - 696C903E0B8D526000D66CAF /* session_export.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = session_export.cc; path = ../session_export.cc; sourceTree = SOURCE_ROOT; }; - 696C903F0B8D526000D66CAF /* session_feedback.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = session_feedback.cc; path = ../session_feedback.cc; sourceTree = SOURCE_ROOT; }; - 696C90400B8D526000D66CAF /* session_midi.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = session_midi.cc; path = ../session_midi.cc; sourceTree = SOURCE_ROOT; }; - 696C90410B8D526000D66CAF /* session_process.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = session_process.cc; path = ../session_process.cc; sourceTree = SOURCE_ROOT; }; - 696C90420B8D526000D66CAF /* session_state.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = session_state.cc; path = ../session_state.cc; sourceTree = SOURCE_ROOT; }; - 696C90430B8D526000D66CAF /* session_time.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = session_time.cc; path = ../session_time.cc; sourceTree = SOURCE_ROOT; }; - 696C90440B8D526000D66CAF /* session_timefx.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = session_timefx.cc; path = ../session_timefx.cc; sourceTree = SOURCE_ROOT; }; - 696C90450B8D526000D66CAF /* session_transport.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = session_transport.cc; path = ../session_transport.cc; sourceTree = SOURCE_ROOT; }; - 696C90470B8D526000D66CAF /* silentfilesource.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = silentfilesource.cc; path = ../silentfilesource.cc; sourceTree = SOURCE_ROOT; }; - 696C90480B8D526000D66CAF /* sndfile_helpers.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = sndfile_helpers.cc; path = ../sndfile_helpers.cc; sourceTree = SOURCE_ROOT; }; - 696C90490B8D526000D66CAF /* sndfilesource.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = sndfilesource.cc; path = ../sndfilesource.cc; sourceTree = SOURCE_ROOT; }; - 696C904A0B8D526000D66CAF /* source.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = source.cc; path = ../source.cc; sourceTree = SOURCE_ROOT; }; - 696C904B0B8D526000D66CAF /* source_factory.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = source_factory.cc; path = ../source_factory.cc; sourceTree = SOURCE_ROOT; }; - 696C904E0B8D526000D66CAF /* tempo.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = tempo.cc; path = ../tempo.cc; sourceTree = SOURCE_ROOT; }; - 696C904F0B8D526000D66CAF /* track.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = track.cc; path = ../track.cc; sourceTree = SOURCE_ROOT; }; - 696C90500B8D526000D66CAF /* utils.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = utils.cc; path = ../utils.cc; sourceTree = SOURCE_ROOT; }; - 696C90F70B8D52F300D66CAF /* glibmm.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = glibmm.framework; path = /Library/Frameworks/glibmm.framework; sourceTree = "<absolute>"; }; - 696C90F80B8D52F300D66CAF /* Jack.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Jack.framework; path = /Library/Frameworks/Jack.framework; sourceTree = "<absolute>"; }; - 696C90F90B8D52F300D66CAF /* lo.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = lo.framework; path = /Library/Frameworks/lo.framework; sourceTree = "<absolute>"; }; - 696C90FA0B8D52F300D66CAF /* LRdf.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = LRdf.framework; path = /Library/Frameworks/LRdf.framework; sourceTree = "<absolute>"; }; - 696C90FB0B8D52F300D66CAF /* Raptor.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Raptor.framework; path = /Library/Frameworks/Raptor.framework; sourceTree = "<absolute>"; }; - 696C90FC0B8D52F300D66CAF /* SampleRate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SampleRate.framework; path = /Library/Frameworks/SampleRate.framework; sourceTree = "<absolute>"; }; - 696C90FD0B8D52F300D66CAF /* sigc.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = sigc.framework; path = /Library/Frameworks/sigc.framework; sourceTree = "<absolute>"; }; - 696C90FE0B8D52F300D66CAF /* Sndfile-ardour.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = "Sndfile-ardour.framework"; path = "/Library/Frameworks/Sndfile-ardour.framework"; sourceTree = "<absolute>"; }; - 696C90FF0B8D52F300D66CAF /* soundtouch.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = soundtouch.framework; path = /Library/Frameworks/soundtouch.framework; sourceTree = "<absolute>"; }; - 697D98080B8DCD8C0006A892 /* libxml2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libxml2.dylib; path = /usr/lib/libxml2.dylib; sourceTree = "<absolute>"; }; - 698D9AB00B969A5B00C53B63 /* midi++.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = "midi++.xcodeproj"; path = "../../midi++2/macosx/midi++.xcodeproj"; sourceTree = SOURCE_ROOT; }; - 69AD45840B97D10600806E7E /* FLAC */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = FLAC; path = "/Library/Frameworks/Sndfile-ardour.framework/Versions/A/Libraries/FLAC"; sourceTree = "<absolute>"; }; - 69B1B54F0B8E80AD007E41C1 /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = /System/Library/Frameworks/CoreAudio.framework; sourceTree = "<absolute>"; }; - 69DBC41A0BA794A500C19E65 /* Accelerate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = /Developer/SDKs/MacOSX10.4u.sdk/System/Library/Frameworks/Accelerate.framework; sourceTree = "<absolute>"; }; - 69DBC42A0BA7992800C19E65 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /Developer/SDKs/MacOSX10.4u.sdk/System/Library/Frameworks/Carbon.framework; sourceTree = "<absolute>"; }; - 69F7CE520B8DCB3300D76871 /* basic_ui.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = basic_ui.cc; sourceTree = "<group>"; }; - 69F7CE540B8DCB3300D76871 /* basic_ui.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = basic_ui.h; sourceTree = "<group>"; }; - 69F7CE550B8DCB3300D76871 /* control_protocol.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = control_protocol.h; sourceTree = "<group>"; }; - 69F7CE560B8DCB3300D76871 /* smpte.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = smpte.h; sourceTree = "<group>"; }; - 69F7CE570B8DCB3300D76871 /* control_protocol.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = control_protocol.cc; sourceTree = "<group>"; }; - 69F7CE590B8DCB3300D76871 /* smpte.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = smpte.cc; sourceTree = "<group>"; }; - 8D07F2C70486CC7A007CD1D0 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; }; - 8D07F2C80486CC7A007CD1D0 /* ardour.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ardour.framework; sourceTree = BUILT_PRODUCTS_DIR; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 8D07F2C30486CC7A007CD1D0 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 698D9AB60B969A6F00C53B63 /* midi++.framework in Frameworks */, - 69B1B5500B8E80AD007E41C1 /* CoreAudio.framework in Frameworks */, - 696C91000B8D52F300D66CAF /* glibmm.framework in Frameworks */, - 696C91010B8D52F300D66CAF /* Jack.framework in Frameworks */, - 696C91020B8D52F300D66CAF /* lo.framework in Frameworks */, - 696C91030B8D52F300D66CAF /* LRdf.framework in Frameworks */, - 696C91040B8D52F300D66CAF /* Raptor.framework in Frameworks */, - 696C91050B8D52F300D66CAF /* SampleRate.framework in Frameworks */, - 696C91060B8D52F300D66CAF /* sigc.framework in Frameworks */, - 696C91070B8D52F300D66CAF /* Sndfile-ardour.framework in Frameworks */, - 696C91080B8D52F300D66CAF /* soundtouch.framework in Frameworks */, - 697D98090B8DCD8C0006A892 /* libxml2.dylib in Frameworks */, - 69B1B5210B8E7DFD007E41C1 /* pbd.framework in Frameworks */, - 696149E90B97CEF500ECBDF0 /* glib in Frameworks */, - 696149EA0B97CEF500ECBDF0 /* gmodule in Frameworks */, - 696149EB0B97CEF500ECBDF0 /* gobject in Frameworks */, - 696149EC0B97CEF500ECBDF0 /* gthread in Frameworks */, - 69AD45850B97D10600806E7E /* FLAC in Frameworks */, - 69DBC41B0BA794A500C19E65 /* Accelerate.framework in Frameworks */, - 69DBC42B0BA7992800C19E65 /* Carbon.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 034768DDFF38A45A11DB9C8B /* Products */ = { - isa = PBXGroup; - children = ( - 8D07F2C80486CC7A007CD1D0 /* ardour.framework */, - ); - name = Products; - sourceTree = "<group>"; - }; - 0867D691FE84028FC02AAC07 /* ardour */ = { - isa = PBXGroup; - children = ( - 6964FEC80B8E7A7900799BAE /* version.h */, - 6964FEC90B8E7A7900799BAE /* version.cc */, - 08FB77ACFE841707C02AAC07 /* Source */, - 089C1665FE841158C02AAC07 /* Resources */, - 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */, - 034768DDFF38A45A11DB9C8B /* Products */, - ); - name = ardour; - sourceTree = "<group>"; - }; - 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */ = { - isa = PBXGroup; - children = ( - 69DBC42A0BA7992800C19E65 /* Carbon.framework */, - 69DBC41A0BA794A500C19E65 /* Accelerate.framework */, - 69AD45840B97D10600806E7E /* FLAC */, - 696149E50B97CEF500ECBDF0 /* glib */, - 696149E60B97CEF500ECBDF0 /* gmodule */, - 696149E70B97CEF500ECBDF0 /* gobject */, - 696149E80B97CEF500ECBDF0 /* gthread */, - 698D9AB00B969A5B00C53B63 /* midi++.xcodeproj */, - 69B1B54F0B8E80AD007E41C1 /* CoreAudio.framework */, - 697D98080B8DCD8C0006A892 /* libxml2.dylib */, - 691B3B770B8D5508009155B5 /* pbd.xcodeproj */, - 696C90F70B8D52F300D66CAF /* glibmm.framework */, - 696C90F80B8D52F300D66CAF /* Jack.framework */, - 696C90F90B8D52F300D66CAF /* lo.framework */, - 696C90FA0B8D52F300D66CAF /* LRdf.framework */, - 696C90FB0B8D52F300D66CAF /* Raptor.framework */, - 696C90FC0B8D52F300D66CAF /* SampleRate.framework */, - 696C90FD0B8D52F300D66CAF /* sigc.framework */, - 696C90FE0B8D52F300D66CAF /* Sndfile-ardour.framework */, - 696C90FF0B8D52F300D66CAF /* soundtouch.framework */, - ); - name = "External Frameworks and Libraries"; - sourceTree = "<group>"; - }; - 089C1665FE841158C02AAC07 /* Resources */ = { - isa = PBXGroup; - children = ( - 8D07F2C70486CC7A007CD1D0 /* Info.plist */, - 089C1666FE841158C02AAC07 /* InfoPlist.strings */, - ); - name = Resources; - sourceTree = "<group>"; - }; - 08FB77ACFE841707C02AAC07 /* Source */ = { - isa = PBXGroup; - children = ( - 69F7CE510B8DCB3300D76871 /* control_protocol */, - 696C8FAD0B8D526000D66CAF /* ardour */, - 696C90020B8D526000D66CAF /* audio_diskstream.cc */, - 696C90030B8D526000D66CAF /* audio_library.cc */, - 696C90040B8D526000D66CAF /* audio_playlist.cc */, - 696C90050B8D526000D66CAF /* audio_track.cc */, - 696C90070B8D526000D66CAF /* audioengine.cc */, - 696C90080B8D526000D66CAF /* audiofilesource.cc */, - 696C90090B8D526000D66CAF /* audiofilter.cc */, - 696C900A0B8D526000D66CAF /* audioregion.cc */, - 696C900B0B8D526000D66CAF /* audiosource.cc */, - 696C900C0B8D526000D66CAF /* auditioner.cc */, - 696C900D0B8D526000D66CAF /* automation.cc */, - 696C900E0B8D526000D66CAF /* automation_event.cc */, - 696C900F0B8D526000D66CAF /* configuration.cc */, - 696C90100B8D526000D66CAF /* connection.cc */, - 696C90110B8D526000D66CAF /* control_protocol_manager.cc */, - 696C90130B8D526000D66CAF /* crossfade.cc */, - 696C90140B8D526000D66CAF /* curve.cc */, - 696C90150B8D526000D66CAF /* cycle_timer.cc */, - 696C90160B8D526000D66CAF /* default_click.cc */, - 696C90180B8D526000D66CAF /* diskstream.cc */, - 696C90190B8D526000D66CAF /* enums.cc */, - 696C901A0B8D526000D66CAF /* gain.cc */, - 696C901B0B8D526000D66CAF /* gdither.cc */, - 696C901C0B8D526000D66CAF /* gettext.h */, - 696C901D0B8D526000D66CAF /* globals.cc */, - 696C901E0B8D526000D66CAF /* i18n.h */, - 696C901F0B8D526000D66CAF /* import.cc */, - 696C90200B8D526000D66CAF /* insert.cc */, - 696C90210B8D526000D66CAF /* io.cc */, - 696C90220B8D526000D66CAF /* jack_slave.cc */, - 696C90230B8D526000D66CAF /* ladspa_plugin.cc */, - 696C90240B8D526000D66CAF /* location.cc */, - 696C90250B8D526000D66CAF /* mix.cc */, - 696C90260B8D526000D66CAF /* mtc_slave.cc */, - 696C90270B8D526000D66CAF /* named_selection.cc */, - 696C90280B8D526000D66CAF /* osc.cc */, - 696C90290B8D526000D66CAF /* panner.cc */, - 696C902A0B8D526000D66CAF /* pcm_utils.cc */, - 696C902B0B8D526000D66CAF /* playlist.cc */, - 696C902C0B8D526000D66CAF /* playlist_factory.cc */, - 696C902D0B8D526000D66CAF /* plugin.cc */, - 696C902E0B8D526000D66CAF /* plugin_manager.cc */, - 696C902F0B8D526000D66CAF /* port.cc */, - 696C90300B8D526000D66CAF /* recent_sessions.cc */, - 696C90310B8D526000D66CAF /* redirect.cc */, - 696C90320B8D526000D66CAF /* region.cc */, - 696C90330B8D526000D66CAF /* region_factory.cc */, - 696C90340B8D526000D66CAF /* reverse.cc */, - 696C90350B8D526000D66CAF /* route.cc */, - 696C90360B8D526000D66CAF /* route_group.cc */, - 696C90370B8D526000D66CAF /* send.cc */, - 696C90380B8D526000D66CAF /* session.cc */, - 696C90390B8D526000D66CAF /* session_butler.cc */, - 696C903A0B8D526000D66CAF /* session_click.cc */, - 696C903B0B8D526000D66CAF /* session_command.cc */, - 696C903D0B8D526000D66CAF /* session_events.cc */, - 696C903E0B8D526000D66CAF /* session_export.cc */, - 696C903F0B8D526000D66CAF /* session_feedback.cc */, - 696C90400B8D526000D66CAF /* session_midi.cc */, - 696C90410B8D526000D66CAF /* session_process.cc */, - 696C90420B8D526000D66CAF /* session_state.cc */, - 696C90430B8D526000D66CAF /* session_time.cc */, - 696C90440B8D526000D66CAF /* session_timefx.cc */, - 696C90450B8D526000D66CAF /* session_transport.cc */, - 696C90470B8D526000D66CAF /* silentfilesource.cc */, - 696C90480B8D526000D66CAF /* sndfile_helpers.cc */, - 696C90490B8D526000D66CAF /* sndfilesource.cc */, - 696C904A0B8D526000D66CAF /* source.cc */, - 696C904B0B8D526000D66CAF /* source_factory.cc */, - 696C904E0B8D526000D66CAF /* tempo.cc */, - 696C904F0B8D526000D66CAF /* track.cc */, - 696C90500B8D526000D66CAF /* utils.cc */, - 32BAE0B70371A74B00C91783 /* ardour_Prefix.pch */, - ); - name = Source; - sourceTree = "<group>"; - }; - 691B3B780B8D5508009155B5 /* Products */ = { - isa = PBXGroup; - children = ( - 691B3B7C0B8D5508009155B5 /* pbd.framework */, - ); - name = Products; - sourceTree = "<group>"; - }; - 696C8FAD0B8D526000D66CAF /* ardour */ = { - isa = PBXGroup; - children = ( - 696C8FAF0B8D526000D66CAF /* ardour.h */, - 696C8FB00B8D526000D66CAF /* audio_diskstream.h */, - 696C8FB10B8D526000D66CAF /* audio_library.h */, - 696C8FB20B8D526000D66CAF /* audio_track.h */, - 696C8FB40B8D526000D66CAF /* audioengine.h */, - 696C8FB50B8D526000D66CAF /* audiofilesource.h */, - 696C8FB60B8D526000D66CAF /* audiofilter.h */, - 696C8FB70B8D526000D66CAF /* audioplaylist.h */, - 696C8FB80B8D526000D66CAF /* audioregion.h */, - 696C8FB90B8D526000D66CAF /* audiosource.h */, - 696C8FBA0B8D526000D66CAF /* auditioner.h */, - 696C8FBB0B8D526000D66CAF /* automation_event.h */, - 696C8FBC0B8D526000D66CAF /* buffer.h */, - 696C8FBD0B8D526000D66CAF /* click.h */, - 696C8FBE0B8D526000D66CAF /* configuration.h */, - 696C8FBF0B8D526000D66CAF /* configuration_variable.h */, - 696C8FC00B8D526000D66CAF /* configuration_vars.h */, - 696C8FC10B8D526000D66CAF /* connection.h */, - 696C8FC20B8D526000D66CAF /* control_protocol_manager.h */, - 696C8FC40B8D526000D66CAF /* crossfade.h */, - 696C8FC50B8D526000D66CAF /* crossfade_compare.h */, - 696C8FC60B8D526000D66CAF /* curve.h */, - 696C8FC70B8D526000D66CAF /* cycle_timer.h */, - 696C8FC80B8D526000D66CAF /* cycles.h */, - 696C8FC90B8D526000D66CAF /* data_type.h */, - 696C8FCA0B8D526000D66CAF /* dB.h */, - 696C8FCC0B8D526000D66CAF /* diskstream.h */, - 696C8FCD0B8D526000D66CAF /* export.h */, - 696C8FCE0B8D526000D66CAF /* gain.h */, - 696C8FCF0B8D526000D66CAF /* gdither.h */, - 696C8FD00B8D526000D66CAF /* gdither_types.h */, - 696C8FD10B8D526000D66CAF /* gdither_types_internal.h */, - 696C8FD20B8D526000D66CAF /* insert.h */, - 696C8FD30B8D526000D66CAF /* io.h */, - 696C8FD40B8D526000D66CAF /* ladspa.h */, - 696C8FD50B8D526000D66CAF /* ladspa_plugin.h */, - 696C8FD60B8D526000D66CAF /* location.h */, - 696C8FD70B8D526000D66CAF /* logcurve.h */, - 696C8FD80B8D526000D66CAF /* mix.h */, - 696C8FD90B8D526000D66CAF /* named_selection.h */, - 696C8FDA0B8D526000D66CAF /* noise.h */, - 696C8FDB0B8D526000D66CAF /* osc.h */, - 696C8FDC0B8D526000D66CAF /* panner.h */, - 696C8FDD0B8D526000D66CAF /* pcm_utils.h */, - 696C8FDE0B8D526000D66CAF /* peak.h */, - 696C8FDF0B8D526000D66CAF /* playlist.h */, - 696C8FE00B8D526000D66CAF /* playlist_factory.h */, - 696C8FE10B8D526000D66CAF /* playlist_templates.h */, - 696C8FE20B8D526000D66CAF /* plugin.h */, - 696C8FE30B8D526000D66CAF /* plugin_manager.h */, - 696C8FE40B8D526000D66CAF /* port.h */, - 696C8FE50B8D526000D66CAF /* recent_sessions.h */, - 696C8FE60B8D526000D66CAF /* redirect.h */, - 696C8FE70B8D526000D66CAF /* region.h */, - 696C8FE80B8D526000D66CAF /* region_factory.h */, - 696C8FE90B8D526000D66CAF /* reverse.h */, - 696C8FEA0B8D526000D66CAF /* route.h */, - 696C8FEB0B8D526000D66CAF /* route_group.h */, - 696C8FEC0B8D526000D66CAF /* route_group_specialized.h */, - 696C8FED0B8D526000D66CAF /* send.h */, - 696C8FEE0B8D526000D66CAF /* session.h */, - 696C8FEF0B8D526000D66CAF /* session_connection.h */, - 696C8FF00B8D526000D66CAF /* session_playlist.h */, - 696C8FF10B8D526000D66CAF /* session_region.h */, - 696C8FF20B8D526000D66CAF /* session_route.h */, - 696C8FF30B8D526000D66CAF /* session_selection.h */, - 696C8FF40B8D526000D66CAF /* silentfilesource.h */, - 696C8FF50B8D526000D66CAF /* slave.h */, - 696C8FF60B8D526000D66CAF /* sndfile_helpers.h */, - 696C8FF70B8D526000D66CAF /* sndfilesource.h */, - 696C8FF80B8D526000D66CAF /* soundseq.h */, - 696C8FF90B8D526000D66CAF /* source.h */, - 696C8FFA0B8D526000D66CAF /* source_factory.h */, - 696C8FFB0B8D526000D66CAF /* spline.h */, - 696C8FFC0B8D526000D66CAF /* tempo.h */, - 696C8FFD0B8D526000D66CAF /* timestamps.h */, - 696C8FFE0B8D526000D66CAF /* track.h */, - 696C8FFF0B8D526000D66CAF /* types.h */, - 696C90000B8D526000D66CAF /* utils.h */, - ); - name = ardour; - path = ../ardour; - sourceTree = SOURCE_ROOT; - }; - 698D9AB10B969A5B00C53B63 /* Products */ = { - isa = PBXGroup; - children = ( - 698D9AB50B969A5B00C53B63 /* midi++.framework */, - ); - name = Products; - sourceTree = "<group>"; - }; - 69F7CE510B8DCB3300D76871 /* control_protocol */ = { - isa = PBXGroup; - children = ( - 69F7CE520B8DCB3300D76871 /* basic_ui.cc */, - 69F7CE530B8DCB3300D76871 /* control_protocol */, - 69F7CE570B8DCB3300D76871 /* control_protocol.cc */, - 69F7CE590B8DCB3300D76871 /* smpte.cc */, - ); - name = control_protocol; - path = ../../surfaces/control_protocol; - sourceTree = SOURCE_ROOT; - }; - 69F7CE530B8DCB3300D76871 /* control_protocol */ = { - isa = PBXGroup; - children = ( - 69F7CE540B8DCB3300D76871 /* basic_ui.h */, - 69F7CE550B8DCB3300D76871 /* control_protocol.h */, - 69F7CE560B8DCB3300D76871 /* smpte.h */, - ); - path = control_protocol; - sourceTree = "<group>"; - }; -/* End PBXGroup section */ - -/* Begin PBXHeadersBuildPhase section */ - 8D07F2BD0486CC7A007CD1D0 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 8D07F2BE0486CC7A007CD1D0 /* ardour_Prefix.pch in Headers */, - 696C90530B8D526000D66CAF /* ardour.h in Headers */, - 696C90540B8D526000D66CAF /* audio_diskstream.h in Headers */, - 696C90550B8D526000D66CAF /* audio_library.h in Headers */, - 696C90560B8D526000D66CAF /* audio_track.h in Headers */, - 696C90580B8D526000D66CAF /* audioengine.h in Headers */, - 696C90590B8D526000D66CAF /* audiofilesource.h in Headers */, - 696C905A0B8D526000D66CAF /* audiofilter.h in Headers */, - 696C905B0B8D526000D66CAF /* audioplaylist.h in Headers */, - 696C905C0B8D526000D66CAF /* audioregion.h in Headers */, - 696C905D0B8D526000D66CAF /* audiosource.h in Headers */, - 696C905E0B8D526000D66CAF /* auditioner.h in Headers */, - 696C905F0B8D526000D66CAF /* automation_event.h in Headers */, - 696C90600B8D526000D66CAF /* buffer.h in Headers */, - 696C90610B8D526000D66CAF /* click.h in Headers */, - 696C90620B8D526000D66CAF /* configuration.h in Headers */, - 696C90630B8D526000D66CAF /* configuration_variable.h in Headers */, - 696C90640B8D526000D66CAF /* configuration_vars.h in Headers */, - 696C90650B8D526000D66CAF /* connection.h in Headers */, - 696C90660B8D526000D66CAF /* control_protocol_manager.h in Headers */, - 696C90680B8D526000D66CAF /* crossfade.h in Headers */, - 696C90690B8D526000D66CAF /* crossfade_compare.h in Headers */, - 696C906A0B8D526000D66CAF /* curve.h in Headers */, - 696C906B0B8D526000D66CAF /* cycle_timer.h in Headers */, - 696C906C0B8D526000D66CAF /* cycles.h in Headers */, - 696C906D0B8D526000D66CAF /* data_type.h in Headers */, - 696C906E0B8D526000D66CAF /* dB.h in Headers */, - 696C90700B8D526000D66CAF /* diskstream.h in Headers */, - 696C90710B8D526000D66CAF /* export.h in Headers */, - 696C90720B8D526000D66CAF /* gain.h in Headers */, - 696C90730B8D526000D66CAF /* gdither.h in Headers */, - 696C90740B8D526000D66CAF /* gdither_types.h in Headers */, - 696C90750B8D526000D66CAF /* gdither_types_internal.h in Headers */, - 696C90760B8D526000D66CAF /* insert.h in Headers */, - 696C90770B8D526000D66CAF /* io.h in Headers */, - 696C90780B8D526000D66CAF /* ladspa.h in Headers */, - 696C90790B8D526000D66CAF /* ladspa_plugin.h in Headers */, - 696C907A0B8D526000D66CAF /* location.h in Headers */, - 696C907B0B8D526000D66CAF /* logcurve.h in Headers */, - 696C907C0B8D526000D66CAF /* mix.h in Headers */, - 696C907D0B8D526000D66CAF /* named_selection.h in Headers */, - 696C907E0B8D526000D66CAF /* noise.h in Headers */, - 696C907F0B8D526000D66CAF /* osc.h in Headers */, - 696C90800B8D526000D66CAF /* panner.h in Headers */, - 696C90810B8D526000D66CAF /* pcm_utils.h in Headers */, - 696C90820B8D526000D66CAF /* peak.h in Headers */, - 696C90830B8D526000D66CAF /* playlist.h in Headers */, - 696C90840B8D526000D66CAF /* playlist_factory.h in Headers */, - 696C90850B8D526000D66CAF /* playlist_templates.h in Headers */, - 696C90860B8D526000D66CAF /* plugin.h in Headers */, - 696C90870B8D526000D66CAF /* plugin_manager.h in Headers */, - 696C90880B8D526000D66CAF /* port.h in Headers */, - 696C90890B8D526000D66CAF /* recent_sessions.h in Headers */, - 696C908A0B8D526000D66CAF /* redirect.h in Headers */, - 696C908B0B8D526000D66CAF /* region.h in Headers */, - 696C908C0B8D526000D66CAF /* region_factory.h in Headers */, - 696C908D0B8D526000D66CAF /* reverse.h in Headers */, - 696C908E0B8D526000D66CAF /* route.h in Headers */, - 696C908F0B8D526000D66CAF /* route_group.h in Headers */, - 696C90900B8D526000D66CAF /* route_group_specialized.h in Headers */, - 696C90910B8D526000D66CAF /* send.h in Headers */, - 696C90920B8D526000D66CAF /* session.h in Headers */, - 696C90930B8D526000D66CAF /* session_connection.h in Headers */, - 696C90940B8D526000D66CAF /* session_playlist.h in Headers */, - 696C90950B8D526000D66CAF /* session_region.h in Headers */, - 696C90960B8D526000D66CAF /* session_route.h in Headers */, - 696C90970B8D526000D66CAF /* session_selection.h in Headers */, - 696C90980B8D526000D66CAF /* silentfilesource.h in Headers */, - 696C90990B8D526000D66CAF /* slave.h in Headers */, - 696C909A0B8D526000D66CAF /* sndfile_helpers.h in Headers */, - 696C909B0B8D526000D66CAF /* sndfilesource.h in Headers */, - 696C909C0B8D526000D66CAF /* soundseq.h in Headers */, - 696C909D0B8D526000D66CAF /* source.h in Headers */, - 696C909E0B8D526000D66CAF /* source_factory.h in Headers */, - 696C909F0B8D526000D66CAF /* spline.h in Headers */, - 696C90A00B8D526000D66CAF /* tempo.h in Headers */, - 696C90A10B8D526000D66CAF /* timestamps.h in Headers */, - 696C90A20B8D526000D66CAF /* track.h in Headers */, - 696C90A30B8D526000D66CAF /* types.h in Headers */, - 696C90A40B8D526000D66CAF /* utils.h in Headers */, - 696C90C00B8D526000D66CAF /* gettext.h in Headers */, - 696C90C20B8D526000D66CAF /* i18n.h in Headers */, - 69F7CE5B0B8DCB3300D76871 /* basic_ui.h in Headers */, - 69F7CE5C0B8DCB3300D76871 /* control_protocol.h in Headers */, - 69F7CE5D0B8DCB3300D76871 /* smpte.h in Headers */, - 6964FECA0B8E7A7900799BAE /* version.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXHeadersBuildPhase section */ - -/* Begin PBXNativeTarget section */ - 8D07F2BC0486CC7A007CD1D0 /* ardour */ = { - isa = PBXNativeTarget; - buildConfigurationList = 4FADC24208B4156D00ABE55E /* Build configuration list for PBXNativeTarget "ardour" */; - buildPhases = ( - 8D07F2BD0486CC7A007CD1D0 /* Headers */, - 8D07F2BF0486CC7A007CD1D0 /* Resources */, - 8D07F2C10486CC7A007CD1D0 /* Sources */, - 8D07F2C30486CC7A007CD1D0 /* Frameworks */, - 8D07F2C50486CC7A007CD1D0 /* Rez */, - ); - buildRules = ( - ); - dependencies = ( - 69D5F6260B8D58A500301E71 /* PBXTargetDependency */, - 698D9ABA0B969ADC00C53B63 /* PBXTargetDependency */, - ); - name = ardour; - productInstallPath = "$(HOME)/Library/Frameworks"; - productName = ardour; - productReference = 8D07F2C80486CC7A007CD1D0 /* ardour.framework */; - productType = "com.apple.product-type.framework"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 0867D690FE84028FC02AAC07 /* Project object */ = { - isa = PBXProject; - buildConfigurationList = 4FADC24608B4156D00ABE55E /* Build configuration list for PBXProject "ardour" */; - hasScannedForEncodings = 1; - mainGroup = 0867D691FE84028FC02AAC07 /* ardour */; - productRefGroup = 034768DDFF38A45A11DB9C8B /* Products */; - projectDirPath = ""; - projectReferences = ( - { - ProductGroup = 698D9AB10B969A5B00C53B63 /* Products */; - ProjectRef = 698D9AB00B969A5B00C53B63 /* midi++.xcodeproj */; - }, - { - ProductGroup = 691B3B780B8D5508009155B5 /* Products */; - ProjectRef = 691B3B770B8D5508009155B5 /* pbd.xcodeproj */; - }, - ); - projectRoot = ""; - targets = ( - 8D07F2BC0486CC7A007CD1D0 /* ardour */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXReferenceProxy section */ - 691B3B7C0B8D5508009155B5 /* pbd.framework */ = { - isa = PBXReferenceProxy; - fileType = wrapper.framework; - path = pbd.framework; - remoteRef = 691B3B7B0B8D5508009155B5 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 698D9AB50B969A5B00C53B63 /* midi++.framework */ = { - isa = PBXReferenceProxy; - fileType = wrapper.framework; - path = "midi++.framework"; - remoteRef = 698D9AB40B969A5B00C53B63 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; -/* End PBXReferenceProxy section */ - -/* Begin PBXResourcesBuildPhase section */ - 8D07F2BF0486CC7A007CD1D0 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 8D07F2C00486CC7A007CD1D0 /* InfoPlist.strings in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXRezBuildPhase section */ - 8D07F2C50486CC7A007CD1D0 /* Rez */ = { - isa = PBXRezBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXRezBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 8D07F2C10486CC7A007CD1D0 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 696C90A60B8D526000D66CAF /* audio_diskstream.cc in Sources */, - 696C90A70B8D526000D66CAF /* audio_library.cc in Sources */, - 696C90A80B8D526000D66CAF /* audio_playlist.cc in Sources */, - 696C90A90B8D526000D66CAF /* audio_track.cc in Sources */, - 696C90AB0B8D526000D66CAF /* audioengine.cc in Sources */, - 696C90AC0B8D526000D66CAF /* audiofilesource.cc in Sources */, - 696C90AD0B8D526000D66CAF /* audiofilter.cc in Sources */, - 696C90AE0B8D526000D66CAF /* audioregion.cc in Sources */, - 696C90AF0B8D526000D66CAF /* audiosource.cc in Sources */, - 696C90B00B8D526000D66CAF /* auditioner.cc in Sources */, - 696C90B10B8D526000D66CAF /* automation.cc in Sources */, - 696C90B20B8D526000D66CAF /* automation_event.cc in Sources */, - 696C90B30B8D526000D66CAF /* configuration.cc in Sources */, - 696C90B40B8D526000D66CAF /* connection.cc in Sources */, - 696C90B50B8D526000D66CAF /* control_protocol_manager.cc in Sources */, - 696C90B70B8D526000D66CAF /* crossfade.cc in Sources */, - 696C90B80B8D526000D66CAF /* curve.cc in Sources */, - 696C90B90B8D526000D66CAF /* cycle_timer.cc in Sources */, - 696C90BA0B8D526000D66CAF /* default_click.cc in Sources */, - 696C90BC0B8D526000D66CAF /* diskstream.cc in Sources */, - 696C90BD0B8D526000D66CAF /* enums.cc in Sources */, - 696C90BE0B8D526000D66CAF /* gain.cc in Sources */, - 696C90BF0B8D526000D66CAF /* gdither.cc in Sources */, - 696C90C10B8D526000D66CAF /* globals.cc in Sources */, - 696C90C30B8D526000D66CAF /* import.cc in Sources */, - 696C90C40B8D526000D66CAF /* insert.cc in Sources */, - 696C90C50B8D526000D66CAF /* io.cc in Sources */, - 696C90C60B8D526000D66CAF /* jack_slave.cc in Sources */, - 696C90C70B8D526000D66CAF /* ladspa_plugin.cc in Sources */, - 696C90C80B8D526000D66CAF /* location.cc in Sources */, - 696C90C90B8D526000D66CAF /* mix.cc in Sources */, - 696C90CA0B8D526000D66CAF /* mtc_slave.cc in Sources */, - 696C90CB0B8D526000D66CAF /* named_selection.cc in Sources */, - 696C90CC0B8D526000D66CAF /* osc.cc in Sources */, - 696C90CD0B8D526000D66CAF /* panner.cc in Sources */, - 696C90CE0B8D526000D66CAF /* pcm_utils.cc in Sources */, - 696C90CF0B8D526000D66CAF /* playlist.cc in Sources */, - 696C90D00B8D526000D66CAF /* playlist_factory.cc in Sources */, - 696C90D10B8D526000D66CAF /* plugin.cc in Sources */, - 696C90D20B8D526000D66CAF /* plugin_manager.cc in Sources */, - 696C90D30B8D526000D66CAF /* port.cc in Sources */, - 696C90D40B8D526000D66CAF /* recent_sessions.cc in Sources */, - 696C90D50B8D526000D66CAF /* redirect.cc in Sources */, - 696C90D60B8D526000D66CAF /* region.cc in Sources */, - 696C90D70B8D526000D66CAF /* region_factory.cc in Sources */, - 696C90D80B8D526000D66CAF /* reverse.cc in Sources */, - 696C90D90B8D526000D66CAF /* route.cc in Sources */, - 696C90DA0B8D526000D66CAF /* route_group.cc in Sources */, - 696C90DB0B8D526000D66CAF /* send.cc in Sources */, - 696C90DC0B8D526000D66CAF /* session.cc in Sources */, - 696C90DD0B8D526000D66CAF /* session_butler.cc in Sources */, - 696C90DE0B8D526000D66CAF /* session_click.cc in Sources */, - 696C90DF0B8D526000D66CAF /* session_command.cc in Sources */, - 696C90E10B8D526000D66CAF /* session_events.cc in Sources */, - 696C90E20B8D526000D66CAF /* session_export.cc in Sources */, - 696C90E30B8D526000D66CAF /* session_feedback.cc in Sources */, - 696C90E40B8D526000D66CAF /* session_midi.cc in Sources */, - 696C90E50B8D526000D66CAF /* session_process.cc in Sources */, - 696C90E60B8D526000D66CAF /* session_state.cc in Sources */, - 696C90E70B8D526000D66CAF /* session_time.cc in Sources */, - 696C90E80B8D526000D66CAF /* session_timefx.cc in Sources */, - 696C90E90B8D526000D66CAF /* session_transport.cc in Sources */, - 696C90EB0B8D526000D66CAF /* silentfilesource.cc in Sources */, - 696C90EC0B8D526000D66CAF /* sndfile_helpers.cc in Sources */, - 696C90ED0B8D526000D66CAF /* sndfilesource.cc in Sources */, - 696C90EE0B8D526000D66CAF /* source.cc in Sources */, - 696C90EF0B8D526000D66CAF /* source_factory.cc in Sources */, - 696C90F20B8D526000D66CAF /* tempo.cc in Sources */, - 696C90F30B8D526000D66CAF /* track.cc in Sources */, - 696C90F40B8D526000D66CAF /* utils.cc in Sources */, - 69F7CE5A0B8DCB3300D76871 /* basic_ui.cc in Sources */, - 69F7CE5E0B8DCB3300D76871 /* control_protocol.cc in Sources */, - 69F7CE600B8DCB3300D76871 /* smpte.cc in Sources */, - 6964FECB0B8E7A7900799BAE /* version.cc in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 698D9ABA0B969ADC00C53B63 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = "midi++"; - targetProxy = 698D9AB90B969ADC00C53B63 /* PBXContainerItemProxy */; - }; - 69D5F6260B8D58A500301E71 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = pbd; - targetProxy = 69D5F6250B8D58A500301E71 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin PBXVariantGroup section */ - 089C1666FE841158C02AAC07 /* InfoPlist.strings */ = { - isa = PBXVariantGroup; - children = ( - 089C1667FE841158C02AAC07 /* English */, - ); - name = InfoPlist.strings; - sourceTree = "<group>"; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 4FADC24408B4156D00ABE55E /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ARCHS = ( - ppc, - i386, - ); - DEBUG_INFORMATION_FORMAT = stabs; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_1 = "\"$(SYSTEM_DEVELOPER_DIR)/SDKs/MacOSX10.4u.sdk/System/Library/Frameworks\""; - FRAMEWORK_VERSION = A; - GCC_GENERATE_DEBUGGING_SYMBOLS = NO; - GCC_MODEL_TUNING = G5; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = ardour_Prefix.pch; - INFOPLIST_FILE = Info.plist; - INSTALL_PATH = "@executable_path/../Frameworks"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - "$(LIBRARY_SEARCH_PATHS_QUOTED_1)", - "$(LIBRARY_SEARCH_PATHS_QUOTED_2)", - ); - LIBRARY_SEARCH_PATHS_QUOTED_1 = "\"$(LOCAL_LIBRARY_DIR)/Frameworks/GLib.framework/Versions/2.12.3/Libraries\""; - LIBRARY_SEARCH_PATHS_QUOTED_2 = "\"$(LOCAL_LIBRARY_DIR)/Frameworks/Sndfile-ardour.framework/Versions/A/Libraries\""; - LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(LOCAL_LIBRARY_DIR)/Frameworks/GLib.framework/Versions/2.12.3/Libraries\""; - LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(LOCAL_LIBRARY_DIR)/Frameworks/Sndfile-ardour.framework/Versions/A/Libraries\""; - LIBRARY_STYLE = DYNAMIC; - MACH_O_TYPE = mh_dylib; - PRODUCT_NAME = ardour; - WRAPPER_EXTENSION = framework; - }; - name = Release; - }; - 4FADC24808B4156D00ABE55E /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = ( - "$(NATIVE_ARCH)", - ppc, - ); - FRAMEWORK_SEARCH_PATHS = /opt/ardour/build; - GCC_FAST_OBJC_DISPATCH = NO; - GCC_GENERATE_DEBUGGING_SYMBOLS = NO; - GCC_MODEL_TUNING = G4; - GCC_OPTIMIZATION_LEVEL = 3; - GCC_PREPROCESSOR_DEFINITIONS = ( - BUILD_VECLIB_OPTIMIZATIONS, - HAVE_WORDEXP, - HAVE_WEAK_COREAUDIO, - "$(GCC_PREPROCESSOR_DEFINITIONS_QUOTED_FOR_PROJECT_1)", - "$(GCC_PREPROCESSOR_DEFINITIONS_QUOTED_FOR_PROJECT_2)", - "$(GCC_PREPROCESSOR_DEFINITIONS_QUOTED_FOR_PROJECT_3)", - "$(GCC_PREPROCESSOR_DEFINITIONS_QUOTED_FOR_PROJECT_4)", - "$(GCC_PREPROCESSOR_DEFINITIONS_QUOTED_FOR_PROJECT_5)", - NO_POSIX_MEMALIGN, - ); - GCC_PREPROCESSOR_DEFINITIONS_QUOTED_FOR_PROJECT_1 = "PACKAGE=\"\\\"libardour\\\"\""; - GCC_PREPROCESSOR_DEFINITIONS_QUOTED_FOR_PROJECT_2 = "CONFIG_DIR=\"\\\"/Library/Application\\ Support/Ardour/config\\\"\""; - GCC_PREPROCESSOR_DEFINITIONS_QUOTED_FOR_PROJECT_3 = "MODULE_DIR=\"\\\"/Library/Application\\ Support/Ardour/modules\\\"\""; - GCC_PREPROCESSOR_DEFINITIONS_QUOTED_FOR_PROJECT_4 = "DATA_DIR=\"\\\"/Library/Application\\ Support/Ardour/data\\\"\""; - GCC_PREPROCESSOR_DEFINITIONS_QUOTED_FOR_PROJECT_5 = "LOCALEDIR=\"\\\"/Library/Application\\ Support/Ardour/locales\\\"\""; - GCC_STRICT_ALIASING = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - HEADER_SEARCH_PATHS = ( - /usr/include/libxml2, - /Library/Frameworks/sigc.framework/Headers, - /Library/Frameworks/GLib.framework/Headers, - /Library/Frameworks/glibmm.framework/Headers, - "/Library/Frameworks/Sndfile-ardour.framework/Headers", - /Library/Frameworks/SampleRate.framework/Headers, - /Library/Frameworks/Raptor.framework/Headers, - /Library/Frameworks/LRdf.framework/Headers, - /opt/ardour/src/ardour2/libs/surfaces/control_protocol, - ); - INSTALL_PATH = "@executable_path/../Frameworks"; - MACOSX_DEPLOYMENT_TARGET = ""; - PREBINDING = NO; - SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; - }; - name = Release; - }; - 694E7C8A0B97B0FE0018D03D /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(NATIVE_ARCH)"; - COPY_PHASE_STRIP = NO; - FRAMEWORK_SEARCH_PATHS = /opt/ardour/build; - GCC_ENABLE_FIX_AND_CONTINUE = YES; - GCC_ENABLE_OBJC_EXCEPTIONS = NO; - GCC_FAST_OBJC_DISPATCH = NO; - GCC_MODEL_TUNING = G4; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - BUILD_VECLIB_OPTIMIZATIONS, - HAVE_WORDEXP, - HAVE_WEAK_COREAUDIO, - "$(GCC_PREPROCESSOR_DEFINITIONS_QUOTED_FOR_PROJECT_1)", - "$(GCC_PREPROCESSOR_DEFINITIONS_QUOTED_FOR_PROJECT_2)", - "$(GCC_PREPROCESSOR_DEFINITIONS_QUOTED_FOR_PROJECT_3)", - "$(GCC_PREPROCESSOR_DEFINITIONS_QUOTED_FOR_PROJECT_4)", - "$(GCC_PREPROCESSOR_DEFINITIONS_QUOTED_FOR_PROJECT_5)", - NO_POSIX_MEMALIGN, - ); - GCC_PREPROCESSOR_DEFINITIONS_QUOTED_FOR_PROJECT_1 = "PACKAGE=\"\\\"libardour\\\"\""; - GCC_PREPROCESSOR_DEFINITIONS_QUOTED_FOR_PROJECT_2 = "CONFIG_DIR=\"\\\"/Library/Application\\ Support/Ardour/config\\\"\""; - GCC_PREPROCESSOR_DEFINITIONS_QUOTED_FOR_PROJECT_3 = "MODULE_DIR=\"\\\"/Library/Application\\ Support/Ardour/modules\\\"\""; - GCC_PREPROCESSOR_DEFINITIONS_QUOTED_FOR_PROJECT_4 = "DATA_DIR=\"\\\"/Library/Application\\ Support/Ardour/data\\\"\""; - GCC_PREPROCESSOR_DEFINITIONS_QUOTED_FOR_PROJECT_5 = "LOCALEDIR=\"\\\"/Library/Application\\ Support/Ardour/locales\\\"\""; - GCC_STRICT_ALIASING = YES; - GCC_WARN_ABOUT_MISSING_NEWLINE = YES; - GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; - GCC_WARN_ABOUT_POINTER_SIGNEDNESS = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_ALLOW_INCOMPLETE_PROTOCOL = NO; - GCC_WARN_CHECK_SWITCH_STATEMENTS = YES; - GCC_WARN_EFFECTIVE_CPLUSPLUS_VIOLATIONS = NO; - GCC_WARN_MISSING_PARENTHESES = YES; - GCC_WARN_NON_VIRTUAL_DESTRUCTOR = NO; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - HEADER_SEARCH_PATHS = ( - /usr/include/libxml2, - /Library/Frameworks/sigc.framework/Headers, - /Library/Frameworks/GLib.framework/Headers, - /Library/Frameworks/glibmm.framework/Headers, - "/Library/Frameworks/Sndfile-ardour.framework/Headers", - /Library/Frameworks/SampleRate.framework/Headers, - /Library/Frameworks/Raptor.framework/Headers, - /Library/Frameworks/LRdf.framework/Headers, - /opt/ardour/src/ardour2/libs/surfaces/control_protocol, - ); - INSTALL_PATH = "@executable_path/../Frameworks"; - MACOSX_DEPLOYMENT_TARGET = ""; - PREBINDING = NO; - SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; - STRIP_INSTALLED_PRODUCT = NO; - }; - name = Debug; - }; - 694E7C8B0B97B0FE0018D03D /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ARCHS = i386; - DEBUG_INFORMATION_FORMAT = stabs; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - "$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)", - ); - FRAMEWORK_SEARCH_PATHS_QUOTED_1 = "\"$(SYSTEM_DEVELOPER_DIR)/SDKs/MacOSX10.4u.sdk/System/Library/Frameworks\""; - FRAMEWORK_VERSION = A; - GCC_GENERATE_DEBUGGING_SYMBOLS = YES; - GCC_MODEL_TUNING = G5; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = ardour_Prefix.pch; - INFOPLIST_FILE = Info.plist; - INSTALL_PATH = "@executable_path/../Frameworks"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", - "$(LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", - "$(LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_3)", - "$(LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_4)", - ); - LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(LOCAL_LIBRARY_DIR)/Frameworks/GLib.framework/Versions/2.12.3/Libraries\""; - LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(LOCAL_LIBRARY_DIR)/Frameworks/Sndfile-ardour.framework/Versions/A/Libraries\""; - LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_3 = "\"$(LOCAL_LIBRARY_DIR)/Frameworks/GLib.framework/Versions/2.12.3/Libraries\""; - LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_4 = "\"$(LOCAL_LIBRARY_DIR)/Frameworks/Sndfile-ardour.framework/Versions/A/Libraries\""; - LIBRARY_STYLE = DYNAMIC; - MACH_O_TYPE = mh_dylib; - PRODUCT_NAME = ardour; - WRAPPER_EXTENSION = framework; - }; - name = Debug; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 4FADC24208B4156D00ABE55E /* Build configuration list for PBXNativeTarget "ardour" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 4FADC24408B4156D00ABE55E /* Release */, - 694E7C8B0B97B0FE0018D03D /* Debug */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 4FADC24608B4156D00ABE55E /* Build configuration list for PBXProject "ardour" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 4FADC24808B4156D00ABE55E /* Release */, - 694E7C8A0B97B0FE0018D03D /* Debug */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 0867D690FE84028FC02AAC07 /* Project object */; -} diff --git a/libs/ardour/macosx/ardour_Prefix.pch b/libs/ardour/macosx/ardour_Prefix.pch deleted file mode 100644 index b03e5d3d98..0000000000 --- a/libs/ardour/macosx/ardour_Prefix.pch +++ /dev/null @@ -1,4 +0,0 @@ -// -// Prefix header for all source files of the 'ardour' target in the 'ardour' project. -// - diff --git a/libs/ardour/macosx/version.cc b/libs/ardour/macosx/version.cc deleted file mode 100644 index 9da3d2c359..0000000000 --- a/libs/ardour/macosx/version.cc +++ /dev/null @@ -1,3 +0,0 @@ -int libardour_major_version = 2; -int libardour_minor_version = 0; -int libardour_micro_version = 0; diff --git a/libs/ardour/macosx/version.h b/libs/ardour/macosx/version.h deleted file mode 100644 index 9c575ee077..0000000000 --- a/libs/ardour/macosx/version.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * version.h - * ardour - * - * Created by Taybin Rutkin on 2/22/07. - * Copyright 2007 Paul Davis. All rights reserved. - * - */ - -#ifndef __libardour_version_h__ -#define __libardour_version_h__ - -extern int libardour_major_version; -extern int libardour_minor_version; -extern int libardour_micro_version; - -#endif /* __libardour_version_h__ */ diff --git a/libs/ardour/meter.cc b/libs/ardour/meter.cc deleted file mode 100644 index e75c1d89ca..0000000000 --- a/libs/ardour/meter.cc +++ /dev/null @@ -1,165 +0,0 @@ -/* - 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. -*/ - -#include <ardour/meter.h> -#include <algorithm> -#include <cmath> -#include <ardour/buffer_set.h> -#include <ardour/peak.h> -#include <ardour/dB.h> -#include <ardour/session.h> - -namespace ARDOUR { - - -/** Get peaks from @a bufs - * Input acceptance is lenient - the first n buffers from @a bufs will - * be metered, where n was set by the last call to setup(), excess meters will - * be set to 0. - */ -void -PeakMeter::run_in_place (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset) -{ - size_t meterable = std::min((size_t)bufs.count().n_total(), _peak_power.size()); - - size_t n = 0; - - // Meter what we have (midi) - for ( ; n < meterable && n < bufs.count().n_midi(); ++n) { - - float val = 0; - - // GUI needs a better MIDI meter, not much information can be - // expressed through peaks alone - for (MidiBuffer::iterator i = bufs.get_midi(n).begin(); i != bufs.get_midi(n).end(); ++i) { - const MIDI::Event& ev = *i; - if (ev.is_note_on()) { - const float this_vel = log(ev.buffer()[2] / 127.0 * (M_E*M_E-M_E) + M_E) - 1.0; - //printf("V %d -> %f\n", (int)((Byte)ev.buffer[2]), this_vel); - if (this_vel > val) - val = this_vel; - } else { - val += 1.0 / bufs.get_midi(n).capacity(); - if (val > 1.0) - val = 1.0; - } - } - - _peak_power[n] = val; - - } - - // Meter what we have (audio) - for ( ; n < meterable && n < bufs.count().n_audio(); ++n) { - _peak_power[n] = compute_peak (bufs.get_audio(n).data(nframes, offset), nframes, _peak_power[n]); - } - - // Zero any excess peaks - for (size_t n = meterable; n < _peak_power.size(); ++n) { - _peak_power[n] = 0; - } -} - -void -PeakMeter::reset () -{ - for (size_t i = 0; i < _peak_power.size(); ++i) { - _peak_power[i] = 0; - } -} - -void -PeakMeter::reset_max () -{ - for (size_t i = 0; i < _max_peak_power.size(); ++i) { - _max_peak_power[i] = -INFINITY; - } -} - -bool -PeakMeter::configure_io (ChanCount in, ChanCount out) -{ - /* we're transparent no matter what. fight the power. */ - if (out != in) - return false; - - uint32_t limit = in.n_total(); - - while (_peak_power.size() > limit) { - _peak_power.pop_back(); - _visible_peak_power.pop_back(); - _max_peak_power.pop_back(); - } - - while (_peak_power.size() < limit) { - _peak_power.push_back(0); - _visible_peak_power.push_back(minus_infinity()); - _max_peak_power.push_back(minus_infinity()); - } - - assert(_peak_power.size() == limit); - assert(_visible_peak_power.size() == limit); - assert(_max_peak_power.size() == limit); - - Processor::configure_io(in, out); - - return true; -} - -/** To be driven by the Meter signal from IO. - * Caller MUST hold io_lock! - */ -void -PeakMeter::meter () -{ - assert(_visible_peak_power.size() == _peak_power.size()); - - const size_t limit = _peak_power.size(); - - for (size_t n = 0; n < limit; ++n) { - - /* XXX we should use atomic exchange here */ - - /* grab peak since last read */ - - float new_peak = _peak_power[n]; - _peak_power[n] = 0; - - /* compute new visible value using falloff */ - - if (new_peak > 0.0) { - new_peak = coefficient_to_dB (new_peak); - } else { - new_peak = minus_infinity(); - } - - /* update max peak */ - - _max_peak_power[n] = std::max (new_peak, _max_peak_power[n]); - - if (Config->get_meter_falloff() == 0.0f || new_peak > _visible_peak_power[n]) { - _visible_peak_power[n] = new_peak; - } else { - // do falloff - new_peak = _visible_peak_power[n] - (Config->get_meter_falloff() * 0.01f); - _visible_peak_power[n] = std::max (new_peak, -INFINITY); - } - } -} - -} // namespace ARDOUR diff --git a/libs/ardour/midi_buffer.cc b/libs/ardour/midi_buffer.cc deleted file mode 100644 index 1530babe34..0000000000 --- a/libs/ardour/midi_buffer.cc +++ /dev/null @@ -1,282 +0,0 @@ -/* - Copyright (C) 2006-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. -*/ - -#include <iostream> -#include <ardour/midi_buffer.h> - -#ifdef __x86_64__ -static const int CPU_CACHE_ALIGN = 64; -#else -static const int CPU_CACHE_ALIGN = 16; /* arguably 32 on most arches, but it matters less */ -#endif - -using namespace std; -using namespace ARDOUR; - - -// FIXME: mirroring for MIDI buffers? -MidiBuffer::MidiBuffer(size_t capacity) - : Buffer(DataType::MIDI, capacity) - , _events(0) - , _data(0) -// , _owns_data(false) -{ - if (capacity) { - resize (_capacity); - silence(_capacity); - } -} - -MidiBuffer::~MidiBuffer() -{ - if (_events) { - free(_events); - } - if (_data) { - free(_data); - } -} - -void -MidiBuffer::resize (size_t size) -{ - assert(size > 0); - - if (size < _capacity) { - return; - } - - if (_data) { - free (_data); - } - - if (_events) { - free (_events); - } - - _size = 0; - _capacity = size; - -#ifdef NO_POSIX_MEMALIGN - _events = (MIDI::Event *) malloc(sizeof(MIDI::Event) * _capacity); - _data = (uint8_t *) malloc(sizeof(uint8_t) * _capacity * MAX_EVENT_SIZE); -#else - posix_memalign((void**)&_events, CPU_CACHE_ALIGN, sizeof(MIDI::Event) * _capacity); - posix_memalign((void**)&_data, CPU_CACHE_ALIGN, sizeof(uint8_t) * _capacity * MAX_EVENT_SIZE); -#endif - assert(_data); - assert(_events); -} - -void -MidiBuffer::copy(const MidiBuffer& copy) -{ - assert(_capacity >= copy._capacity); - _size = 0; - - for (size_t i = 0; i < copy.size(); ++i) - push_back(copy[i]); -} - - -/** Read events from @a src starting at time @a offset into the START of this buffer, for - * time direction @a nframes. Relative time, where 0 = start of buffer. - * - * Note that offset and nframes refer to sample time, NOT buffer offsets or event counts. - */ -void -MidiBuffer::read_from(const Buffer& src, nframes_t nframes, nframes_t offset) -{ - assert(src.type() == DataType::MIDI); - assert(&src != this); - - const MidiBuffer& msrc = (MidiBuffer&)src; - - assert(_capacity >= msrc.size()); - - clear(); - assert(_size == 0); - - // FIXME: slow - for (size_t i=0; i < msrc.size(); ++i) { - const MIDI::Event& ev = msrc[i]; - if (ev.time() >= offset && ev.time() < offset+nframes) { - //cout << "MidiBuffer::read_from got event, " << int(ev.type()) << " time: " << ev.time() << " buffer size: " << _size << endl; - push_back(ev); - } else { - cerr << "MidiBuffer event out of range, " << ev.time() << endl; - } - } - - _silent = src.silent(); -} - - -/** Push an event into the buffer. - * - * Note that the raw MIDI pointed to by ev will be COPIED and unmodified. - * That is, the caller still owns it, if it needs freeing it's Not My Problem(TM). - * Realtime safe. - * @return false if operation failed (not enough room) - */ -bool -MidiBuffer::push_back(const MIDI::Event& ev) -{ - if (_size == _capacity) - return false; - - uint8_t* const write_loc = _data + (_size * MAX_EVENT_SIZE); - - memcpy(write_loc, ev.buffer(), ev.size()); - _events[_size] = ev; - _events[_size].set_buffer(ev.size(), write_loc, false); - ++_size; - - //cerr << "MidiBuffer: pushed, size = " << _size << endl; - - _silent = false; - - return true; -} - - -/** Push an event into the buffer. - * - * Note that the raw MIDI pointed to by ev will be COPIED and unmodified. - * That is, the caller still owns it, if it needs freeing it's Not My Problem(TM). - * Realtime safe. - * @return false if operation failed (not enough room) - */ -bool -MidiBuffer::push_back(const jack_midi_event_t& ev) -{ - if (_size == _capacity) - return false; - - uint8_t* const write_loc = _data + (_size * MAX_EVENT_SIZE); - - memcpy(write_loc, ev.buffer, ev.size); - _events[_size].time() = (double)ev.time; - _events[_size].set_buffer(ev.size, write_loc, false); - ++_size; - - //cerr << "MidiBuffer: pushed, size = " << _size << endl; - - _silent = false; - - return true; -} - - -/** Reserve space for a new event in the buffer. - * - * This call is for copying MIDI directly into the buffer, the data location - * (of sufficient size to write \a size bytes) is returned, or 0 on failure. - * This call MUST be immediately followed by a write to the returned data - * location, or the buffer will be corrupted and very nasty things will happen. - */ -uint8_t* -MidiBuffer::reserve(double time, size_t size) -{ - if (size > MAX_EVENT_SIZE) { - cerr << "WARNING: Failed to reserve " << size << " bytes for event"; - return 0; - } - - if (_size == _capacity) - return 0; - - uint8_t* const write_loc = _data + (_size * MAX_EVENT_SIZE); - - _events[_size].time() = time; - _events[_size].set_buffer(size, write_loc, false); - ++_size; - - //cerr << "MidiBuffer: reserved, size = " << _size << endl; - - _silent = false; - - return write_loc; -} - - -void -MidiBuffer::silence(nframes_t dur, nframes_t offset) -{ - // FIXME use parameters - if (offset != 0) - cerr << "WARNING: MidiBuffer::silence w/ offset != 0 (not implemented)" << endl; - - memset(_events, 0, sizeof(MIDI::Event) * _capacity); - memset(_data, 0, sizeof(uint8_t) * _capacity * MAX_EVENT_SIZE); - _size = 0; - _silent = true; -} - - -/** Clear, and merge \a a and \a b into this buffer. - * - * FIXME: This is slow. - * - * \return true if complete merge was successful - */ -bool -MidiBuffer::merge(const MidiBuffer& a, const MidiBuffer& b) -{ - _size = 0; - - // Die if a merge isn't necessary as it's expensive - assert(a.size() > 0 && b.size() > 0); - - size_t a_index = 0; - size_t b_index = 0; - size_t count = a.size() + b.size(); - - while (count > 0 && a_index < a.size() && b_index < b.size()) { - - if (size() == capacity()) { - cerr << "WARNING: MIDI buffer overrun, events lost!" << endl; - return false; - } - - if (a_index == a.size()) { - push_back(a[a_index]); - ++a_index; - } else if (b_index == b.size()) { - push_back(b[b_index]); - ++b_index; - } else { - const MIDI::Event& a_ev = a[a_index]; - const MIDI::Event& b_ev = b[b_index]; - - if (a_ev.time() <= b_ev.time()) { - push_back(a_ev); - ++a_index; - } else { - push_back(b_ev); - ++b_index; - } - } - - --count; - } - - return true; -} - diff --git a/libs/ardour/midi_diskstream.cc b/libs/ardour/midi_diskstream.cc deleted file mode 100644 index 5b4716d51e..0000000000 --- a/libs/ardour/midi_diskstream.cc +++ /dev/null @@ -1,1461 +0,0 @@ -/* - Copyright (C) 2000-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. -*/ - -#include <fstream> -#include <cstdio> -#include <unistd.h> -#include <cmath> -#include <cerrno> -#include <string> -#include <climits> -#include <fcntl.h> -#include <cstdlib> -#include <ctime> -#include <sys/stat.h> -#include <sys/mman.h> - -#include <pbd/error.h> -#include <pbd/basename.h> -#include <glibmm/thread.h> -#include <pbd/xml++.h> -#include <pbd/memento_command.h> -#include <pbd/enumwriter.h> - -#include <ardour/ardour.h> -#include <ardour/audioengine.h> -#include <ardour/midi_diskstream.h> -#include <ardour/utils.h> -#include <ardour/configuration.h> -#include <ardour/smf_source.h> -#include <ardour/send.h> -#include <ardour/region_factory.h> -#include <ardour/midi_playlist.h> -#include <ardour/playlist_factory.h> -#include <ardour/cycle_timer.h> -#include <ardour/midi_region.h> -#include <ardour/midi_port.h> - -#include "i18n.h" -#include <locale.h> - -using namespace std; -using namespace ARDOUR; -using namespace PBD; - -MidiDiskstream::MidiDiskstream (Session &sess, const string &name, Diskstream::Flag flag) - : Diskstream(sess, name, flag) - , _playback_buf(0) - , _capture_buf(0) - , _source_port(0) - , _last_flush_frame(0) - , _note_mode(Sustained) -{ - /* prevent any write sources from being created */ - - in_set_state = true; - - init(flag); - use_new_playlist (); - - in_set_state = false; - - assert(!destructive()); -} - -MidiDiskstream::MidiDiskstream (Session& sess, const XMLNode& node) - : Diskstream(sess, node) - , _playback_buf(0) - , _capture_buf(0) - , _source_port(0) - , _last_flush_frame(0) - , _note_mode(Sustained) -{ - in_set_state = true; - init (Recordable); - - if (set_state (node)) { - in_set_state = false; - throw failed_constructor(); - } - - in_set_state = false; - - if (destructive()) { - use_destructive_playlist (); - } -} - -void -MidiDiskstream::init (Diskstream::Flag f) -{ - Diskstream::init(f); - - /* there are no channels at this point, so these - two calls just get speed_buffer_size and wrap_buffer - size setup without duplicating their code. - */ - - set_block_size (_session.get_block_size()); - allocate_temporary_buffers (); - - _playback_buf = new MidiRingBuffer (_session.midi_diskstream_buffer_size()); - _capture_buf = new MidiRingBuffer (_session.midi_diskstream_buffer_size()); - - _n_channels = ChanCount(DataType::MIDI, 1); - - assert(recordable()); -} - -MidiDiskstream::~MidiDiskstream () -{ - Glib::Mutex::Lock lm (state_lock); -} - - -void -MidiDiskstream::non_realtime_locate (nframes_t position) -{ - assert(_write_source); - _write_source->set_timeline_position (position); - seek(position, false); -} - - -void -MidiDiskstream::non_realtime_input_change () -{ - { - Glib::Mutex::Lock lm (state_lock); - - if (input_change_pending == NoChange) { - return; - } - - if (input_change_pending & ConfigurationChanged) { - assert(_io->n_inputs() == _n_channels); - } - - get_input_sources (); - set_capture_offset (); - - if (first_input_change) { - set_align_style (_persistent_alignment_style); - first_input_change = false; - } else { - set_align_style_from_io (); - } - - input_change_pending = NoChange; - - /* implicit unlock */ - } - - /* reset capture files */ - - reset_write_sources (false); - - /* now refill channel buffers */ - - if (speed() != 1.0f || speed() != -1.0f) { - seek ((nframes_t) (_session.transport_frame() * (double) speed())); - } - else { - seek (_session.transport_frame()); - } - - _last_flush_frame = _session.transport_frame(); -} - -void -MidiDiskstream::get_input_sources () -{ - uint32_t ni = _io->n_inputs().n_midi(); - - if (ni == 0) { - return; - } - - // This is all we do for now at least - assert(ni == 1); - - _source_port = _io->midi_input(0); - - // do... stuff? -} - -int -MidiDiskstream::find_and_use_playlist (const string& name) -{ - boost::shared_ptr<MidiPlaylist> playlist; - - if ((playlist = boost::dynamic_pointer_cast<MidiPlaylist> (_session.playlist_by_name (name))) == 0) { - playlist = boost::dynamic_pointer_cast<MidiPlaylist> (PlaylistFactory::create (DataType::MIDI, _session, name)); - } - - if (!playlist) { - error << string_compose(_("MidiDiskstream: Playlist \"%1\" isn't an midi playlist"), name) << endmsg; - return -1; - } - - return use_playlist (playlist); -} - -int -MidiDiskstream::use_playlist (boost::shared_ptr<Playlist> playlist) -{ - assert(boost::dynamic_pointer_cast<MidiPlaylist>(playlist)); - - Diskstream::use_playlist(playlist); - - return 0; -} - -int -MidiDiskstream::use_new_playlist () -{ - string newname; - boost::shared_ptr<MidiPlaylist> playlist; - - if (!in_set_state && destructive()) { - return 0; - } - - if (_playlist) { - newname = Playlist::bump_name (_playlist->name(), _session); - } else { - newname = Playlist::bump_name (_name, _session); - } - - if ((playlist = boost::dynamic_pointer_cast<MidiPlaylist> (PlaylistFactory::create ( - DataType::MIDI, _session, newname, hidden()))) != 0) { - - playlist->set_orig_diskstream_id (id()); - return use_playlist (playlist); - - } else { - return -1; - } -} - -int -MidiDiskstream::use_copy_playlist () -{ - assert(midi_playlist()); - - if (destructive()) { - return 0; - } - - if (_playlist == 0) { - error << string_compose(_("MidiDiskstream %1: there is no existing playlist to make a copy of!"), _name) << endmsg; - return -1; - } - - string newname; - boost::shared_ptr<MidiPlaylist> playlist; - - newname = Playlist::bump_name (_playlist->name(), _session); - - if ((playlist = boost::dynamic_pointer_cast<MidiPlaylist>(PlaylistFactory::create (midi_playlist(), newname))) != 0) { - playlist->set_orig_diskstream_id (id()); - return use_playlist (playlist); - } else { - return -1; - } -} - -/** Overloaded from parent to die horribly - */ -int -MidiDiskstream::set_destructive (bool yn) -{ - assert( ! destructive()); - assert( ! yn); - return -1; -} - -void -MidiDiskstream::set_note_mode (NoteMode m) -{ - _note_mode = m; - midi_playlist()->set_note_mode(m); - if (_write_source && _write_source->model()) - _write_source->model()->set_note_mode(m); -} - -void -MidiDiskstream::check_record_status (nframes_t transport_frame, nframes_t nframes, bool can_record) -{ - // FIXME: waaay too much code to duplicate (AudioDiskstream) - - int possibly_recording; - int rolling; - int change; - const int transport_rolling = 0x4; - const int track_rec_enabled = 0x2; - const int global_rec_enabled = 0x1; - - /* merge together the 3 factors that affect record status, and compute - what has changed. - */ - - rolling = _session.transport_speed() != 0.0f; - possibly_recording = (rolling << 2) | (record_enabled() << 1) | can_record; - change = possibly_recording ^ last_possibly_recording; - - if (possibly_recording == last_possibly_recording) { - return; - } - - /* change state */ - - /* if per-track or global rec-enable turned on while the other was already on, we've started recording */ - - if (((change & track_rec_enabled) && record_enabled() && (!(change & global_rec_enabled) && can_record)) || - ((change & global_rec_enabled) && can_record && (!(change & track_rec_enabled) && record_enabled()))) { - - /* starting to record: compute first+last frames */ - - first_recordable_frame = transport_frame + _capture_offset; - last_recordable_frame = max_frames; - capture_start_frame = transport_frame; - - if (!(last_possibly_recording & transport_rolling) && (possibly_recording & transport_rolling)) { - - /* was stopped, now rolling (and recording) */ - - if (_alignment_style == ExistingMaterial) { - first_recordable_frame += _session.worst_output_latency(); - } else { - first_recordable_frame += _roll_delay; - } - - } else { - - /* was rolling, but record state changed */ - - if (_alignment_style == ExistingMaterial) { - - - if (!Config->get_punch_in()) { - - /* manual punch in happens at the correct transport frame - because the user hit a button. but to get alignment correct - we have to back up the position of the new region to the - appropriate spot given the roll delay. - */ - - capture_start_frame -= _roll_delay; - - /* XXX paul notes (august 2005): i don't know why - this is needed. - */ - - first_recordable_frame += _capture_offset; - - } else { - - /* autopunch toggles recording at the precise - transport frame, and then the DS waits - to start recording for a time that depends - on the output latency. - */ - - first_recordable_frame += _session.worst_output_latency(); - } - - } else { - - if (Config->get_punch_in()) { - first_recordable_frame += _roll_delay; - } else { - capture_start_frame -= _roll_delay; - } - } - - } - - } else if (!record_enabled() || !can_record) { - - /* stop recording */ - - last_recordable_frame = transport_frame + _capture_offset; - - if (_alignment_style == ExistingMaterial) { - last_recordable_frame += _session.worst_output_latency(); - } else { - last_recordable_frame += _roll_delay; - } - } - - last_possibly_recording = possibly_recording; -} - -int -MidiDiskstream::process (nframes_t transport_frame, nframes_t nframes, nframes_t offset, bool can_record, bool rec_monitors_input) -{ - // FIXME: waay too much code to duplicate (AudioDiskstream::process) - int ret = -1; - nframes_t rec_offset = 0; - nframes_t rec_nframes = 0; - bool nominally_recording; - bool re = record_enabled (); - bool collect_playback = false; - - /* if we've already processed the frames corresponding to this call, - just return. this allows multiple routes that are taking input - from this diskstream to call our ::process() method, but have - this stuff only happen once. more commonly, it allows both - the AudioTrack that is using this AudioDiskstream *and* the Session - to call process() without problems. - */ - - if (_processed) { - return 0; - } - - commit_should_unlock = false; - - check_record_status (transport_frame, nframes, can_record); - - nominally_recording = (can_record && re); - - if (nframes == 0) { - _processed = true; - return 0; - } - - /* This lock is held until the end of ::commit, so these two functions - must always be called as a pair. The only exception is if this function - returns a non-zero value, in which case, ::commit should not be called. - */ - - // If we can't take the state lock return. - if (!state_lock.trylock()) { - return 1; - } - commit_should_unlock = true; - adjust_capture_position = 0; - - if (nominally_recording || (_session.get_record_enabled() && Config->get_punch_in())) { - OverlapType ot; - - ot = coverage (first_recordable_frame, last_recordable_frame, transport_frame, transport_frame + nframes); - - switch (ot) { - case OverlapNone: - rec_nframes = 0; - break; - - case OverlapInternal: - /* ---------- recrange - |---| transrange - */ - rec_nframes = nframes; - rec_offset = 0; - break; - - case OverlapStart: - /* |--------| recrange - -----| transrange - */ - rec_nframes = transport_frame + nframes - first_recordable_frame; - if (rec_nframes) { - rec_offset = first_recordable_frame - transport_frame; - } - break; - - case OverlapEnd: - /* |--------| recrange - |-------- transrange - */ - rec_nframes = last_recordable_frame - transport_frame; - rec_offset = 0; - break; - - case OverlapExternal: - /* |--------| recrange - -------------- transrange - */ - rec_nframes = last_recordable_frame - last_recordable_frame; - rec_offset = first_recordable_frame - transport_frame; - break; - } - - if (rec_nframes && !was_recording) { - capture_captured = 0; - was_recording = true; - } - } - - - if (can_record && !_last_capture_regions.empty()) { - _last_capture_regions.clear (); - } - - if (nominally_recording || rec_nframes) { - - assert(_source_port); - - // Pump entire port buffer into the ring buffer (FIXME: split cycles?) - //_capture_buf->write(_source_port->get_midi_buffer(), transport_frame); - size_t num_events = _source_port->get_midi_buffer().size(); - size_t to_write = std::min(_capture_buf->write_space(), num_events); - - MidiBuffer::iterator port_iter = _source_port->get_midi_buffer().begin(); - - for (size_t i=0; i < to_write; ++i) { - const MIDI::Event& ev = *port_iter; - assert(ev.buffer()); - _capture_buf->write(ev.time() + transport_frame, ev.size(), ev.buffer()); - ++port_iter; - } - - } else { - - if (was_recording) { - finish_capture (rec_monitors_input); - } - - } - - if (rec_nframes) { - - /* XXX XXX XXX XXX XXX XXX XXX XXX */ - - /* data will be written to disk */ - - if (rec_nframes == nframes && rec_offset == 0) { - - playback_distance = nframes; - } else { - - collect_playback = true; - } - - adjust_capture_position = rec_nframes; - - } else if (nominally_recording) { - - /* can't do actual capture yet - waiting for latency effects to finish before we start*/ - - playback_distance = nframes; - - } else { - - collect_playback = true; - } - - if (collect_playback) { - - /* we're doing playback */ - - nframes_t necessary_samples; - - /* no varispeed playback if we're recording, because the output .... TBD */ - - if (rec_nframes == 0 && _actual_speed != 1.0f) { - necessary_samples = (nframes_t) floor ((nframes * fabs (_actual_speed))) + 1; - } else { - necessary_samples = nframes; - } - - // XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX - // Write into playback buffer here, and whatnot? - //cerr << "MDS FIXME: collect playback" << endl; - - } - - ret = 0; - - _processed = true; - - if (ret) { - - /* we're exiting with failure, so ::commit will not - be called. unlock the state lock. - */ - - commit_should_unlock = false; - state_lock.unlock(); - } - - return ret; -} - -bool -MidiDiskstream::commit (nframes_t nframes) -{ - bool need_butler = false; - - if (_actual_speed < 0.0) { - playback_sample -= playback_distance; - } else { - playback_sample += playback_distance; - } - - if (adjust_capture_position != 0) { - capture_captured += adjust_capture_position; - adjust_capture_position = 0; - } - - /* what audio does: - * can't do this with midi: write space is in bytes, chunk_frames is in frames - if (_slaved) { - need_butler = _playback_buf->write_space() >= _playback_buf->capacity() / 2; - } else { - need_butler = _playback_buf->write_space() >= disk_io_chunk_frames - || _capture_buf->read_space() >= disk_io_chunk_frames; - }*/ - - /* we'll just keep the playback buffer full for now. - * this should be decreased to reduce edit latency */ - need_butler = _playback_buf->write_space() >= _playback_buf->capacity() / 2; - - if (commit_should_unlock) { - state_lock.unlock(); - } - - _processed = false; - - return need_butler; -} - -void -MidiDiskstream::set_pending_overwrite (bool yn) -{ - /* called from audio thread, so we can use the read ptr and playback sample as we wish */ - - pending_overwrite = yn; - - overwrite_frame = playback_sample; -} - -int -MidiDiskstream::overwrite_existing_buffers () -{ - read(overwrite_frame, disk_io_chunk_frames, false); - overwrite_queued = false; - pending_overwrite = false; - - return 0; -} - -int -MidiDiskstream::seek (nframes_t frame, bool complete_refill) -{ - Glib::Mutex::Lock lm (state_lock); - int ret = -1; - - _playback_buf->reset(); - _capture_buf->reset(); - - playback_sample = frame; - file_frame = frame; - - if (complete_refill) { - while ((ret = do_refill_with_alloc ()) > 0) ; - } else { - ret = do_refill_with_alloc (); - } - - return ret; -} - -int -MidiDiskstream::can_internal_playback_seek (nframes_t distance) -{ - if (_playback_buf->read_space() < distance) { - return false; - } else { - return true; - } -} - -int -MidiDiskstream::internal_playback_seek (nframes_t distance) -{ - cerr << "MDS: internal_playback_seek " << distance << endl; - - first_recordable_frame += distance; - playback_sample += distance; - - return 0; -} - -/** @a start is set to the new frame position (TIME) read up to */ -int -MidiDiskstream::read (nframes_t& start, nframes_t dur, bool reversed) -{ - nframes_t this_read = 0; - bool reloop = false; - nframes_t loop_end = 0; - nframes_t loop_start = 0; - nframes_t loop_length = 0; - Location *loc = 0; - - if (!reversed) { - /* Make the use of a Location atomic for this read operation. - - Note: Locations don't get deleted, so all we care about - when I say "atomic" is that we are always pointing to - the same one and using a start/length values obtained - just once. - */ - - if ((loc = loop_location) != 0) { - loop_start = loc->start(); - loop_end = loc->end(); - loop_length = loop_end - loop_start; - } - - /* if we are looping, ensure that the first frame we read is at the correct - position within the loop. - */ - - if (loc && start >= loop_end) { - //cerr << "start adjusted from " << start; - start = loop_start + ((start - loop_start) % loop_length); - //cerr << "to " << start << endl; - } - //cerr << "start is " << start << " loopstart: " << loop_start << " loopend: " << loop_end << endl; - } - - while (dur) { - - /* take any loop into account. we can't read past the end of the loop. */ - - if (loc && (loop_end - start < dur)) { - this_read = loop_end - start; - //cerr << "reloop true: thisread: " << this_read << " dur: " << dur << endl; - reloop = true; - } else { - reloop = false; - this_read = dur; - } - - if (this_read == 0) { - break; - } - - this_read = min(dur,this_read); - - if (midi_playlist()->read (*_playback_buf, start, this_read) != this_read) { - error << string_compose(_("MidiDiskstream %1: cannot read %2 from playlist at frame %3"), _id, this_read, - start) << endmsg; - return -1; - } - - _read_data_count = _playlist->read_data_count(); - - if (reversed) { - - // Swap note ons with note offs here. etc? - // Fully reversing MIDI required look-ahead (well, behind) to find previous - // CC values etc. hard. - - } else { - - /* if we read to the end of the loop, go back to the beginning */ - - if (reloop) { - start = loop_start; - } else { - start += this_read; - } - } - - dur -= this_read; - //offset += this_read; - } - - return 0; -} - -int -MidiDiskstream::do_refill_with_alloc () -{ - return do_refill(); -} - -int -MidiDiskstream::do_refill () -{ - int ret = 0; - size_t write_space = _playback_buf->write_space(); - bool reversed = (_visible_speed * _session.transport_speed()) < 0.0f; - - if (write_space == 0) { - return 0; - } - - if (reversed) { - return 0; - } - - /* at end: nothing to do */ - if (file_frame == max_frames) { - return 0; - } - - // At this point we... - assert(_playback_buf->write_space() > 0); // ... have something to write to, and - assert(file_frame <= max_frames); // ... something to write - - nframes_t to_read = min(disk_io_chunk_frames, (max_frames - file_frame)); - - if (read (file_frame, to_read, reversed)) { - ret = -1; - } - - return ret; -} - -/** Flush pending data to disk. - * - * Important note: this function will write *AT MOST* disk_io_chunk_frames - * of data to disk. it will never write more than that. If it writes that - * much and there is more than that waiting to be written, it will return 1, - * otherwise 0 on success or -1 on failure. - * - * If there is less than disk_io_chunk_frames to be written, no data will be - * written at all unless @a force_flush is true. - */ -int -MidiDiskstream::do_flush (Session::RunContext context, bool force_flush) -{ - uint32_t to_write; - int32_t ret = 0; - nframes_t total; - - _write_data_count = 0; - - if (_last_flush_frame > _session.transport_frame() - || _last_flush_frame < capture_start_frame) { - _last_flush_frame = _session.transport_frame(); - } - - total = _session.transport_frame() - _last_flush_frame; - - if (total == 0 || (_capture_buf->read_space() == 0 && _session.transport_speed() == 0) || (total < disk_io_chunk_frames && !force_flush && was_recording)) { - goto out; - } - - /* if there are 2+ chunks of disk i/o possible for - this track, let the caller know so that it can arrange - for us to be called again, ASAP. - - if we are forcing a flush, then if there is* any* extra - work, let the caller know. - - if we are no longer recording and there is any extra work, - let the caller know too. - */ - - if (total >= 2 * disk_io_chunk_frames || ((force_flush || !was_recording) && total > disk_io_chunk_frames)) { - ret = 1; - } - - to_write = disk_io_chunk_frames; - - assert(!destructive()); - - if (record_enabled() && _session.transport_frame() - _last_flush_frame > disk_io_chunk_frames) { - if ((!_write_source) || _write_source->midi_write (*_capture_buf, to_write) != to_write) { - error << string_compose(_("MidiDiskstream %1: cannot write to disk"), _id) << endmsg; - return -1; - } else { - _last_flush_frame = _session.transport_frame(); - } - } - -out: - return ret; -} - -void -MidiDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_capture) -{ - uint32_t buffer_position; - bool more_work = true; - int err = 0; - boost::shared_ptr<MidiRegion> region; - nframes_t total_capture; - MidiRegion::SourceList srcs; - MidiRegion::SourceList::iterator src; - vector<CaptureInfo*>::iterator ci; - bool mark_write_completed = false; - - finish_capture (true); - - /* butler is already stopped, but there may be work to do - to flush remaining data to disk. - */ - - while (more_work && !err) { - switch (do_flush (Session::TransportContext, true)) { - case 0: - more_work = false; - break; - case 1: - break; - case -1: - error << string_compose(_("MidiDiskstream \"%1\": cannot flush captured data to disk!"), _name) << endmsg; - err++; - } - } - - /* XXX is there anything we can do if err != 0 ? */ - Glib::Mutex::Lock lm (capture_info_lock); - - if (capture_info.empty()) { - return; - } - - if (abort_capture) { - - if (_write_source) { - - _write_source->mark_for_remove (); - _write_source->drop_references (); - _write_source.reset(); - } - - /* new source set up in "out" below */ - - } else { - - assert(_write_source); - - for (total_capture = 0, ci = capture_info.begin(); ci != capture_info.end(); ++ci) { - total_capture += (*ci)->frames; - } - - /* figure out the name for this take */ - - srcs.push_back (_write_source); - _write_source->set_timeline_position (capture_info.front()->start); - _write_source->set_captured_for (_name); - - string whole_file_region_name; - whole_file_region_name = region_name_from_path (_write_source->name(), true); - - /* Register a new region with the Session that - describes the entire source. Do this first - so that any sub-regions will obviously be - children of this one (later!) - */ - - try { - boost::shared_ptr<Region> rx (RegionFactory::create (srcs, _write_source->last_capture_start_frame(), total_capture, - whole_file_region_name, - 0, Region::Flag (Region::DefaultFlags|Region::Automatic|Region::WholeFile))); - - region = boost::dynamic_pointer_cast<MidiRegion> (rx); - region->special_set_position (capture_info.front()->start); - } - - - catch (failed_constructor& err) { - error << string_compose(_("%1: could not create region for complete midi file"), _name) << endmsg; - /* XXX what now? */ - } - - _last_capture_regions.push_back (region); - - // cerr << _name << ": there are " << capture_info.size() << " capture_info records\n"; - - XMLNode &before = _playlist->get_state(); - _playlist->freeze (); - - for (buffer_position = _write_source->last_capture_start_frame(), ci = capture_info.begin(); ci != capture_info.end(); ++ci) { - - string region_name; - - _session.region_name (region_name, _write_source->name(), false); - - // cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->frames << " add a region\n"; - - try { - boost::shared_ptr<Region> rx (RegionFactory::create (srcs, buffer_position, (*ci)->frames, region_name)); - region = boost::dynamic_pointer_cast<MidiRegion> (rx); - } - - catch (failed_constructor& err) { - error << _("MidiDiskstream: could not create region for captured midi!") << endmsg; - continue; /* XXX is this OK? */ - } - - region->GoingAway.connect (bind (mem_fun (*this, &Diskstream::remove_region_from_last_capture), boost::weak_ptr<Region>(region))); - - _last_capture_regions.push_back (region); - - // cerr << "add new region, buffer position = " << buffer_position << " @ " << (*ci)->start << endl; - - i_am_the_modifier++; - _playlist->add_region (region, (*ci)->start); - i_am_the_modifier--; - - buffer_position += (*ci)->frames; - } - - _playlist->thaw (); - XMLNode &after = _playlist->get_state(); - _session.add_command (new MementoCommand<Playlist>(*_playlist, &before, &after)); - - } - - mark_write_completed = true; - - reset_write_sources (mark_write_completed); - - for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) { - delete *ci; - } - - capture_info.clear (); - capture_start_frame = 0; -} - -void -MidiDiskstream::transport_looped (nframes_t transport_frame) -{ - if (was_recording) { - - // adjust the capture length knowing that the data will be recorded to disk - // only necessary after the first loop where we're recording - if (capture_info.size() == 0) { - capture_captured += _capture_offset; - - if (_alignment_style == ExistingMaterial) { - capture_captured += _session.worst_output_latency(); - } else { - capture_captured += _roll_delay; - } - } - - finish_capture (true); - - // the next region will start recording via the normal mechanism - // we'll set the start position to the current transport pos - // no latency adjustment or capture offset needs to be made, as that already happened the first time - capture_start_frame = transport_frame; - first_recordable_frame = transport_frame; // mild lie - last_recordable_frame = max_frames; - was_recording = true; - } -} - -void -MidiDiskstream::finish_capture (bool rec_monitors_input) -{ - was_recording = false; - - if (capture_captured == 0) { - return; - } - - // Why must we destroy? - assert(!destructive()); - - CaptureInfo* ci = new CaptureInfo; - - ci->start = capture_start_frame; - ci->frames = capture_captured; - - /* XXX theoretical race condition here. Need atomic exchange ? - However, the circumstances when this is called right - now (either on record-disable or transport_stopped) - mean that no actual race exists. I think ... - We now have a capture_info_lock, but it is only to be used - to synchronize in the transport_stop and the capture info - accessors, so that invalidation will not occur (both non-realtime). - */ - - // cerr << "Finish capture, add new CI, " << ci->start << '+' << ci->frames << endl; - - capture_info.push_back (ci); - capture_captured = 0; -} - -void -MidiDiskstream::set_record_enabled (bool yn) -{ - if (!recordable() || !_session.record_enabling_legal()) { - return; - } - - assert(!destructive()); - - if (yn && _source_port == 0) { - - /* pick up connections not initiated *from* the IO object - we're associated with. - */ - - get_input_sources (); - } - - /* yes, i know that this not proof against race conditions, but its - good enough. i think. - */ - - if (record_enabled() != yn) { - if (yn) { - engage_record_enable (); - } else { - disengage_record_enable (); - } - } -} - -void -MidiDiskstream::engage_record_enable () -{ - bool rolling = _session.transport_speed() != 0.0f; - - g_atomic_int_set (&_record_enabled, 1); - - if (_source_port && Config->get_monitoring_model() == HardwareMonitoring) { - _source_port->request_monitor_input (!(Config->get_auto_input() && rolling)); - } - - // FIXME: Why is this necessary? Isn't needed for AudioDiskstream... - if (!_write_source) - use_new_write_source(); - - _write_source->mark_streaming_midi_write_started (_note_mode, _session.transport_frame()); - - RecordEnableChanged (); /* EMIT SIGNAL */ -} - -void -MidiDiskstream::disengage_record_enable () -{ - g_atomic_int_set (&_record_enabled, 0); - if (_source_port && Config->get_monitoring_model() == HardwareMonitoring) { - if (_source_port) { - _source_port->request_monitor_input (false); - } - } - - RecordEnableChanged (); /* EMIT SIGNAL */ -} - -XMLNode& -MidiDiskstream::get_state () -{ - XMLNode* node = new XMLNode ("MidiDiskstream"); - char buf[64]; - LocaleGuard lg (X_("POSIX")); - - snprintf (buf, sizeof(buf), "0x%x", _flags); - node->add_property ("flags", buf); - - node->add_property("channel-mode", enum_2_string(get_channel_mode())); - - snprintf (buf, sizeof(buf), "0x%x", get_channel_mask()); - node->add_property("channel-mask", buf); - - node->add_property ("playlist", _playlist->name()); - - snprintf (buf, sizeof(buf), "%f", _visible_speed); - node->add_property ("speed", buf); - - node->add_property("name", _name); - id().print(buf, sizeof(buf)); - node->add_property("id", buf); - - if (_write_source && _session.get_record_enabled()) { - - XMLNode* cs_child = new XMLNode (X_("CapturingSources")); - XMLNode* cs_grandchild; - - cs_grandchild = new XMLNode (X_("file")); - cs_grandchild->add_property (X_("path"), _write_source->path()); - cs_child->add_child_nocopy (*cs_grandchild); - - /* store the location where capture will start */ - - Location* pi; - - if (Config->get_punch_in() && ((pi = _session.locations()->auto_punch_location()) != 0)) { - snprintf (buf, sizeof (buf), "%" PRIu32, pi->start()); - } else { - snprintf (buf, sizeof (buf), "%" PRIu32, _session.transport_frame()); - } - - cs_child->add_property (X_("at"), buf); - node->add_child_nocopy (*cs_child); - } - - if (_extra_xml) { - node->add_child_copy (*_extra_xml); - } - - return* node; -} - -int -MidiDiskstream::set_state (const XMLNode& node) -{ - const XMLProperty* prop; - XMLNodeList nlist = node.children(); - XMLNodeIterator niter; - uint32_t nchans = 1; - XMLNode* capture_pending_node = 0; - LocaleGuard lg (X_("POSIX")); - - in_set_state = true; - - for (niter = nlist.begin(); niter != nlist.end(); ++niter) { - /*if ((*niter)->name() == IO::state_node_name) { - deprecated_io_node = new XMLNode (**niter); - }*/ - assert ((*niter)->name() != IO::state_node_name); - - if ((*niter)->name() == X_("CapturingSources")) { - capture_pending_node = *niter; - } - } - - /* prevent write sources from being created */ - - in_set_state = true; - - if ((prop = node.property ("name")) != 0) { - _name = prop->value(); - } - - if ((prop = node.property ("id")) != 0) { - _id = prop->value (); - } - - if ((prop = node.property ("flags")) != 0) { - _flags = Flag (string_2_enum (prop->value(), _flags)); - } - - ChannelMode channel_mode = AllChannels; - if ((prop = node.property ("channel-mode")) != 0) { - channel_mode = ChannelMode (string_2_enum(prop->value(), channel_mode)); - } - - unsigned int channel_mask = 0xFFFF; - if ((prop = node.property ("channel-mask")) != 0) { - sscanf (prop->value().c_str(), "0x%x", &channel_mask); - if (channel_mask & (~0xFFFF)) { - warning << _("MidiDiskstream: XML property channel-mask out of range") << endmsg; - } - } - - set_channel_mode(channel_mode, channel_mask); - - if ((prop = node.property ("channels")) != 0) { - nchans = atoi (prop->value().c_str()); - } - - if ((prop = node.property ("playlist")) == 0) { - return -1; - } - - { - bool had_playlist = (_playlist != 0); - - if (find_and_use_playlist (prop->value())) { - return -1; - } - - if (!had_playlist) { - _playlist->set_orig_diskstream_id (_id); - } - - if (capture_pending_node) { - use_pending_capture_data (*capture_pending_node); - } - - } - - if ((prop = node.property ("speed")) != 0) { - double sp = atof (prop->value().c_str()); - - if (realtime_set_speed (sp, false)) { - non_realtime_set_speed (); - } - } - - in_set_state = false; - - /* make sure this is clear before we do anything else */ - - // FIXME? - //_capturing_source = 0; - - /* write sources are handled when we handle the input set - up of the IO that owns this DS (::non_realtime_input_change()) - */ - - in_set_state = false; - - return 0; -} - -int -MidiDiskstream::use_new_write_source (uint32_t n) -{ - if (!recordable()) { - return 1; - } - - assert(n == 0); - - if (_write_source) { - - if (_write_source->is_empty ()) { - _write_source->mark_for_remove (); - _write_source.reset(); - } else { - _write_source.reset(); - } - } - - try { - _write_source = boost::dynamic_pointer_cast<SMFSource>(_session.create_midi_source_for_session (*this)); - if (!_write_source) { - throw failed_constructor(); - } - } - - catch (failed_constructor &err) { - error << string_compose (_("%1:%2 new capture file not initialized correctly"), _name, n) << endmsg; - _write_source.reset(); - return -1; - } - - _write_source->set_allow_remove_if_empty (true); - - return 0; -} - -void -MidiDiskstream::reset_write_sources (bool mark_write_complete, bool force) -{ - if (!recordable()) { - return; - } - - if (_write_source && mark_write_complete) { - _write_source->mark_streaming_write_completed (); - } - - use_new_write_source (0); - - if (record_enabled()) { - //_capturing_sources.push_back (_write_source); - } -} - -int -MidiDiskstream::rename_write_sources () -{ - if (_write_source != 0) { - _write_source->set_source_name (_name, destructive()); - /* XXX what to do if this fails ? */ - } - return 0; -} - -void -MidiDiskstream::set_block_size (nframes_t nframes) -{ -} - -void -MidiDiskstream::allocate_temporary_buffers () -{ -} - -void -MidiDiskstream::monitor_input (bool yn) -{ - if (_source_port) - _source_port->request_monitor_input (yn); - else - cerr << "MidiDiskstream NO SOURCE PORT TO MONITOR\n"; -} - -void -MidiDiskstream::set_align_style_from_io () -{ - bool have_physical = false; - - if (_io == 0) { - return; - } - - get_input_sources (); - - if (_source_port && _source_port->flags() & JackPortIsPhysical) { - have_physical = true; - } - - if (have_physical) { - set_align_style (ExistingMaterial); - } else { - set_align_style (CaptureTime); - } -} - - -float -MidiDiskstream::playback_buffer_load () const -{ - return (float) ((double) _playback_buf->read_space()/ - (double) _playback_buf->capacity()); -} - -float -MidiDiskstream::capture_buffer_load () const -{ - return (float) ((double) _capture_buf->write_space()/ - (double) _capture_buf->capacity()); -} - - -int -MidiDiskstream::use_pending_capture_data (XMLNode& node) -{ - return 0; -} - -/** Writes playback events in the given range to \a dst, translating time stamps - * so that an event at \a start has time = 0 - */ -void -MidiDiskstream::get_playback(MidiBuffer& dst, nframes_t start, nframes_t end) -{ - dst.clear(); - assert(dst.size() == 0); - - // Reverse. ... We just don't do reverse, ok? Back off. - if (end <= start) { - return; - } - - // Translates stamps to be relative to start - _playback_buf->read(dst, start, end); -} diff --git a/libs/ardour/midi_model.cc b/libs/ardour/midi_model.cc deleted file mode 100644 index b21bf38873..0000000000 --- a/libs/ardour/midi_model.cc +++ /dev/null @@ -1,953 +0,0 @@ -/* - Copyright (C) 2007 Paul Davis - Written by Dave Robillard, 2007 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - */ - -#define __STDC_LIMIT_MACROS 1 - -#include <iostream> -#include <algorithm> -#include <stdexcept> -#include <stdint.h> -#include <pbd/enumwriter.h> -#include <midi++/events.h> - -#include <ardour/midi_model.h> -#include <ardour/midi_source.h> -#include <ardour/types.h> -#include <ardour/session.h> - -using namespace std; -using namespace ARDOUR; - -void MidiModel::write_lock() { - _lock.writer_lock(); - _automation_lock.lock(); -} - -void MidiModel::write_unlock() { - _lock.writer_unlock(); - _automation_lock.unlock(); -} - -void MidiModel::read_lock() const { - _lock.reader_lock(); - /*_automation_lock.lock();*/ -} - -void MidiModel::read_unlock() const { - _lock.reader_unlock(); - /*_automation_lock.unlock();*/ -} - -// Read iterator (const_iterator) - -MidiModel::const_iterator::const_iterator(const MidiModel& model, double t) - : _model(&model) - , _is_end( (t == DBL_MAX) || model.empty() ) - , _locked( !_is_end ) -{ - //cerr << "Created MIDI iterator @ " << t << " (is end: " << _is_end << ")" << endl; - - if (_is_end) { - return; - } - - model.read_lock(); - - _note_iter = model.notes().end(); - // find first note which begins after t - for (MidiModel::Notes::const_iterator i = model.notes().begin(); i != model.notes().end(); ++i) { - if ((*i)->time() >= t) { - _note_iter = i; - break; - } - } - - MidiControlIterator earliest_control(boost::shared_ptr<AutomationList>(), DBL_MAX, 0.0); - - _control_iters.reserve(model.controls().size()); - - // find the earliest control event available - for (Automatable::Controls::const_iterator i = model.controls().begin(); - i != model.controls().end(); ++i) { - - assert( - i->first.type() == MidiCCAutomation || - i->first.type() == MidiPgmChangeAutomation || - i->first.type() == MidiPitchBenderAutomation || - i->first.type() == MidiChannelAftertouchAutomation); - - double x, y; - bool ret = i->second->list()->rt_safe_earliest_event_unlocked(t, DBL_MAX, x, y); - if (!ret) { - //cerr << "MIDI Iterator: CC " << i->first.id() << " (size " << i->second->list()->size() - // << ") has no events past " << t << endl; - continue; - } - - assert(x >= 0); - - if (y < i->first.min() || y > i->first.max()) { - cerr << "ERROR: Controller (" << i->first.to_string() << ") value '" << y - << "' out of range [" << i->first.min() << "," << i->first.max() - << "], event ignored" << endl; - continue; - } - - const MidiControlIterator new_iter(i->second->list(), x, y); - - //cerr << "MIDI Iterator: CC " << i->first.id() << " added (" << x << ", " << y << ")" << endl; - _control_iters.push_back(new_iter); - - // if the x of the current control is less than earliest_control - // we have a new earliest_control - if (x < earliest_control.x) { - earliest_control = new_iter; - _control_iter = _control_iters.end(); - --_control_iter; - // now _control_iter points to the last Element in _control_iters - } - } - - if (_note_iter != model.notes().end()) { - _event = boost::shared_ptr<MIDI::Event>(new MIDI::Event((*_note_iter)->on_event(), true)); - } - - double time = DBL_MAX; - // in case we have no notes in the region, we still want to get controller messages - if (_event.get()) { - time = _event->time(); - // if the note is going to make it this turn, advance _note_iter - if (earliest_control.x > time) { - _active_notes.push(*_note_iter); - ++_note_iter; - } - } - - // <=, because we probably would want to send control events first - if (earliest_control.automation_list.get() && earliest_control.x <= time) { - model.control_to_midi_event(_event, earliest_control); - } else { - _control_iter = _control_iters.end(); - } - - if ( (! _event.get()) || _event->size() == 0) { - //cerr << "Created MIDI iterator @ " << t << " is at end." << endl; - _is_end = true; - - // eliminate possible race condition here (ugly) - static Glib::Mutex mutex; - Glib::Mutex::Lock lock(mutex); - if (_locked) { - _model->read_unlock(); - _locked = false; - } - } else { - //printf("New MIDI Iterator = %X @ %lf\n", _event->type(), _event->time()); - } - - assert(_is_end || (_event->buffer() && _event->buffer()[0] != '\0')); -} - -MidiModel::const_iterator::~const_iterator() -{ - if (_locked) { - _model->read_unlock(); - } -} - -const MidiModel::const_iterator& MidiModel::const_iterator::operator++() -{ - if (_is_end) { - throw std::logic_error("Attempt to iterate past end of MidiModel"); - } - - assert(_event->buffer() && _event->buffer()[0] != '\0'); - - /*cerr << "const_iterator::operator++: " << _event->to_string() << endl;*/ - - if (! (_event->is_note() || _event->is_cc() || _event->is_pgm_change() || _event->is_pitch_bender() || _event->is_channel_aftertouch()) ) { - cerr << "FAILED event buffer: " << hex << int(_event->buffer()[0]) << int(_event->buffer()[1]) << int(_event->buffer()[2]) << endl; - } - assert((_event->is_note() || _event->is_cc() || _event->is_pgm_change() || _event->is_pitch_bender() || _event->is_channel_aftertouch())); - - // Increment past current control event - if (!_event->is_note() && _control_iter != _control_iters.end() && _control_iter->automation_list.get()) { - double x = 0.0, y = 0.0; - const bool ret = _control_iter->automation_list->rt_safe_earliest_event_unlocked( - _control_iter->x, DBL_MAX, x, y, false); - - if (ret) { - _control_iter->x = x; - _control_iter->y = y; - } else { - _control_iter->automation_list.reset(); - _control_iter->x = DBL_MAX; - } - } - - const std::vector<MidiControlIterator>::iterator old_control_iter = _control_iter; - _control_iter = _control_iters.begin(); - - // find the _control_iter with the earliest event time - for (std::vector<MidiControlIterator>::iterator i = _control_iters.begin(); - i != _control_iters.end(); ++i) { - if (i->x < _control_iter->x) { - _control_iter = i; - } - } - - enum Type {NIL, NOTE_ON, NOTE_OFF, AUTOMATION}; - - Type type = NIL; - double t = 0; - - // Next earliest note on - if (_note_iter != _model->notes().end()) { - type = NOTE_ON; - t = (*_note_iter)->time(); - } - - // Use the next earliest note off iff it's earlier than the note on - if (_model->note_mode() == Sustained && (! _active_notes.empty())) { - if (type == NIL || _active_notes.top()->end_time() <= (*_note_iter)->time()) { - type = NOTE_OFF; - t = _active_notes.top()->end_time(); - } - } - - // Use the next earliest controller iff it's earlier than the note event - if (_control_iter != _control_iters.end() && _control_iter->x != DBL_MAX /*&& _control_iter != old_control_iter */) { - if (type == NIL || _control_iter->x < t) { - type = AUTOMATION; - } - } - - if (type == NOTE_ON) { - //cerr << "********** MIDI Iterator = note on" << endl; - *_event = (*_note_iter)->on_event(); - cerr << "Event contents on note on: " << _event->to_string() << endl; - _active_notes.push(*_note_iter); - ++_note_iter; - } else if (type == NOTE_OFF) { - //cerr << "********** MIDI Iterator = note off" << endl; - *_event = _active_notes.top()->off_event(); - _active_notes.pop(); - } else if (type == AUTOMATION) { - //cerr << "********** MIDI Iterator = Automation" << endl; - _model->control_to_midi_event(_event, *_control_iter); - } else { - //cerr << "********** MIDI Iterator = End" << endl; - _is_end = true; - } - - assert(_is_end || _event->size() > 0); - - return *this; -} - -bool MidiModel::const_iterator::operator==(const const_iterator& other) const -{ - if (_is_end || other._is_end) { - return (_is_end == other._is_end); - } else { - return (_event == other._event); - } -} - -MidiModel::const_iterator& MidiModel::const_iterator::operator=(const const_iterator& other) -{ - if (_locked && _model != other._model) { - _model->read_unlock(); - } - - _model = other._model; - _active_notes = other._active_notes; - _is_end = other._is_end; - _locked = other._locked; - _note_iter = other._note_iter; - _control_iters = other._control_iters; - size_t index = other._control_iter - other._control_iters.begin(); - _control_iter = _control_iters.begin() + index; - - if (!_is_end) { - _event = boost::shared_ptr<MIDI::Event>(new MIDI::Event(*other._event, true)); - } - - return *this; -} - -// MidiModel - -MidiModel::MidiModel(MidiSource *s, size_t size) - : Automatable(s->session(), "midi model") - , _notes(size) - , _note_mode(Sustained) - , _writing(false) - , _edited(false) - , _end_iter(*this, DBL_MAX) - , _next_read(UINT32_MAX) - , _read_iter(*this, DBL_MAX) - , _midi_source(s) -{ - assert(_end_iter._is_end); - assert( ! _end_iter._locked); -} - -/** Read events in frame range \a start .. \a start+cnt into \a dst, - * adding \a stamp_offset to each event's timestamp. - * \return number of events written to \a dst - */ -size_t MidiModel::read(MidiRingBuffer& dst, nframes_t start, nframes_t nframes, - nframes_t stamp_offset, nframes_t negative_stamp_offset) const -{ - //cerr << this << " MM::read @ " << start << " frames: " << nframes << " -> " << stamp_offset << endl; - //cerr << this << " MM # notes: " << n_notes() << endl; - - size_t read_events = 0; - - if (start != _next_read) { - _read_iter = const_iterator(*this, (double)start); - //cerr << "Repositioning iterator from " << _next_read << " to " << start << endl; - } else { - //cerr << "Using cached iterator at " << _next_read << endl; - } - - _next_read = start + nframes; - - while (_read_iter != end() && _read_iter->time() < start + nframes) { - assert(_read_iter->size() > 0); - assert(_read_iter->buffer()); - dst.write(_read_iter->time() + stamp_offset - negative_stamp_offset, - _read_iter->size(), - _read_iter->buffer()); - - /*cerr << this << " MidiModel::read event @ " << _read_iter->time() - << " type: " << hex << int(_read_iter->type()) << dec - << " note: " << int(_read_iter->note()) - << " velocity: " << int(_read_iter->velocity()) - << endl;*/ - - ++_read_iter; - ++read_events; - } - - return read_events; -} - -/** Write the controller event pointed to by \a iter to \a ev. - * The buffer of \a ev will be allocated or resized as necessary. - * \return true on success - */ -bool -MidiModel::control_to_midi_event(boost::shared_ptr<MIDI::Event>& ev, const MidiControlIterator& iter) const -{ - assert(iter.automation_list.get()); - if (!ev) { - ev = boost::shared_ptr<MIDI::Event>(new MIDI::Event(0, 3, NULL, true)); - } - - switch (iter.automation_list->parameter().type()) { - case MidiCCAutomation: - assert(iter.automation_list.get()); - assert(iter.automation_list->parameter().channel() < 16); - assert(iter.automation_list->parameter().id() <= INT8_MAX); - assert(iter.y <= INT8_MAX); - - ev->time() = iter.x; - ev->realloc(3); - ev->buffer()[0] = MIDI_CMD_CONTROL + iter.automation_list->parameter().channel(); - ev->buffer()[1] = (uint8_t)iter.automation_list->parameter().id(); - ev->buffer()[2] = (uint8_t)iter.y; - break; - - case MidiPgmChangeAutomation: - assert(iter.automation_list.get()); - assert(iter.automation_list->parameter().channel() < 16); - assert(iter.automation_list->parameter().id() == 0); - assert(iter.y <= INT8_MAX); - - ev->time() = iter.x; - ev->realloc(2); - ev->buffer()[0] = MIDI_CMD_PGM_CHANGE + iter.automation_list->parameter().channel(); - ev->buffer()[1] = (uint8_t)iter.y; - break; - - case MidiPitchBenderAutomation: - assert(iter.automation_list.get()); - assert(iter.automation_list->parameter().channel() < 16); - assert(iter.automation_list->parameter().id() == 0); - assert(iter.y < (1<<14)); - - ev->time() = iter.x; - ev->realloc(3); - ev->buffer()[0] = MIDI_CMD_BENDER + iter.automation_list->parameter().channel(); - ev->buffer()[1] = uint16_t(iter.y) & 0x7F; // LSB - ev->buffer()[2] = (uint16_t(iter.y) >> 7) & 0x7F; // MSB - //cerr << "Pitch bender event: " << ev->to_string() << " value: " << ev->pitch_bender_value() << " original value: " << iter.y << std::endl; - break; - - case MidiChannelAftertouchAutomation: - assert(iter.automation_list.get()); - assert(iter.automation_list->parameter().channel() < 16); - assert(iter.automation_list->parameter().id() == 0); - assert(iter.y <= INT8_MAX); - - ev->time() = iter.x; - ev->realloc(2); - ev->buffer()[0] - = MIDI_CMD_CHANNEL_PRESSURE + iter.automation_list->parameter().channel(); - ev->buffer()[1] = (uint8_t)iter.y; - break; - - default: - return false; - } - - return true; -} - - -/** Clear all events from the model. - */ -void MidiModel::clear() -{ - _lock.writer_lock(); - _notes.clear(); - clear_automation(); - _next_read = 0; - _read_iter = end(); - _lock.writer_unlock(); -} - - -/** Begin a write of events to the model. - * - * If \a mode is Sustained, complete notes with duration are constructed as note - * on/off events are received. Otherwise (Percussive), only note on events are - * stored; note off events are discarded entirely and all contained notes will - * have duration 0. - */ -void MidiModel::start_write() -{ - //cerr << "MM " << this << " START WRITE, MODE = " << enum_2_string(_note_mode) << endl; - write_lock(); - _writing = true; - for (int i = 0; i < 16; ++i) - _write_notes[i].clear(); - - _dirty_automations.clear(); - write_unlock(); -} - -/** Finish a write of events to the model. - * - * If \a delete_stuck is true and the current mode is Sustained, note on events - * that were never resolved with a corresonding note off will be deleted. - * Otherwise they will remain as notes with duration 0. - */ -void MidiModel::end_write(bool delete_stuck) -{ - write_lock(); - assert(_writing); - - //cerr << "MM " << this << " END WRITE: " << _notes.size() << " NOTES\n"; - - if (_note_mode == Sustained && delete_stuck) { - for (Notes::iterator n = _notes.begin(); n != _notes.end() ;) { - if ((*n)->duration() == 0) { - cerr << "WARNING: Stuck note lost: " << (*n)->note() << endl; - n = _notes.erase(n); - // we have to break here because erase invalidates the iterator - break; - } else { - ++n; - } - } - } - - for (int i = 0; i < 16; ++i) { - if (!_write_notes[i].empty()) { - cerr << "WARNING: MidiModel::end_write: Channel " << i << " has " - << _write_notes[i].size() << " stuck notes" << endl; - } - _write_notes[i].clear(); - } - - for (AutomationLists::const_iterator i = _dirty_automations.begin(); i != _dirty_automations.end(); ++i) { - (*i)->Dirty.emit(); - (*i)->lookup_cache().left = -1; - (*i)->search_cache().left = -1; - } - - _writing = false; - write_unlock(); -} - -/** Append \a in_event to model. NOT realtime safe. - * - * Timestamps of events in \a buf are expected to be relative to - * the start of this model (t=0) and MUST be monotonically increasing - * and MUST be >= the latest event currently in the model. - */ -void MidiModel::append(const MIDI::Event& ev) -{ - write_lock(); - _edited = true; - - assert(_notes.empty() || ev.time() >= _notes.back()->time()); - assert(_writing); - - if (ev.is_note_on()) { - append_note_on_unlocked(ev.channel(), ev.time(), ev.note(), - ev.velocity()); - } else if (ev.is_note_off()) { - append_note_off_unlocked(ev.channel(), ev.time(), ev.note()); - } else if (ev.is_cc()) { - append_automation_event_unlocked(MidiCCAutomation, ev.channel(), - ev.time(), ev.cc_number(), ev.cc_value()); - } else if (ev.is_pgm_change()) { - append_automation_event_unlocked(MidiPgmChangeAutomation, ev.channel(), - ev.time(), ev.pgm_number(), 0); - } else if (ev.is_pitch_bender()) { - append_automation_event_unlocked(MidiPitchBenderAutomation, - ev.channel(), ev.time(), ev.pitch_bender_lsb(), - ev.pitch_bender_msb()); - } else if (ev.is_channel_aftertouch()) { - append_automation_event_unlocked(MidiChannelAftertouchAutomation, - ev.channel(), ev.time(), ev.channel_aftertouch(), 0); - } else { - printf("WARNING: MidiModel: Unknown event type %X\n", ev.type()); - } - - write_unlock(); -} - -void MidiModel::append_note_on_unlocked(uint8_t chan, double time, - uint8_t note_num, uint8_t velocity) -{ - /*cerr << "MidiModel " << this << " chan " << (int)chan << - " note " << (int)note_num << " on @ " << time << endl;*/ - - assert(note_num <= 127); - assert(chan < 16); - assert(_writing); - _edited = true; - - boost::shared_ptr<Note> new_note(new Note(chan, time, 0, note_num, velocity)); - _notes.push_back(new_note); - if (_note_mode == Sustained) { - //cerr << "MM Sustained: Appending active note on " << (unsigned)(uint8_t)note_num << endl; - _write_notes[chan].push_back(_notes.size() - 1); - }/* else { - cerr << "MM Percussive: NOT appending active note on" << endl; - }*/ -} - -void MidiModel::append_note_off_unlocked(uint8_t chan, double time, - uint8_t note_num) -{ - /*cerr << "MidiModel " << this << " chan " << (int)chan << - " note " << (int)note_num << " off @ " << time << endl;*/ - - assert(note_num <= 127); - assert(chan < 16); - assert(_writing); - _edited = true; - - if (_note_mode == Percussive) { - cerr << "MidiModel Ignoring note off (percussive mode)" << endl; - return; - } - - /* FIXME: make _write_notes fixed size (127 noted) for speed */ - - /* FIXME: note off velocity for that one guy out there who actually has - * keys that send it */ - - bool resolved = false; - - for (WriteNotes::iterator n = _write_notes[chan].begin(); n - != _write_notes[chan].end(); ++n) { - Note& note = *_notes[*n].get(); - if (note.note() == note_num) { - assert(time >= note.time()); - note.set_duration(time - note.time()); - _write_notes[chan].erase(n); - //cerr << "MM resolved note, duration: " << note.duration() << endl; - resolved = true; - break; - } - } - - if (!resolved) { - cerr << "MidiModel " << this << " spurious note off chan " << (int)chan - << ", note " << (int)note_num << " @ " << time << endl; - } -} - -void MidiModel::append_automation_event_unlocked(AutomationType type, - uint8_t chan, double time, uint8_t first_byte, uint8_t second_byte) -{ - //cerr << "MidiModel " << this << " chan " << (int)chan << - // " CC " << (int)number << " = " << (int)value << " @ " << time << endl; - - assert(chan < 16); - assert(_writing); - _edited = true; - double value; - - uint32_t id = 0; - - switch (type) { - case MidiCCAutomation: - id = first_byte; - value = double(second_byte); - break; - case MidiChannelAftertouchAutomation: - case MidiPgmChangeAutomation: - id = 0; - value = double(first_byte); - break; - case MidiPitchBenderAutomation: - id = 0; - value = double((0x7F & second_byte) << 7 | (0x7F & first_byte)); - break; - default: - assert(false); - } - - Parameter param(type, id, chan); - boost::shared_ptr<AutomationControl> control = Automatable::control(param, true); - control->list()->rt_add(time, value); -} - -void MidiModel::add_note_unlocked(const boost::shared_ptr<Note> note) -{ - //cerr << "MidiModel " << this << " add note " << (int)note.note() << " @ " << note.time() << endl; - _edited = true; - Notes::iterator i = upper_bound(_notes.begin(), _notes.end(), note, - note_time_comparator); - _notes.insert(i, note); -} - -void MidiModel::remove_note_unlocked(const boost::shared_ptr<const Note> note) -{ - _edited = true; - //cerr << "MidiModel " << this << " remove note " << (int)note.note() << " @ " << note.time() << endl; - for (Notes::iterator n = _notes.begin(); n != _notes.end(); ++n) { - Note& _n = *(*n); - const Note& _note = *note; - // TODO: There is still the issue, that after restarting ardour - // persisted undo does not work, because of rounding errors in the - // event times after saving/restoring to/from MIDI files - /*cerr << "======================================= " << endl; - cerr << int(_n.note()) << "@" << int(_n.time()) << "[" << int(_n.channel()) << "] --" << int(_n.duration()) << "-- #" << int(_n.velocity()) << endl; - cerr << int(_note.note()) << "@" << int(_note.time()) << "[" << int(_note.channel()) << "] --" << int(_note.duration()) << "-- #" << int(_note.velocity()) << endl; - cerr << "Equal: " << bool(_n == _note) << endl; - cerr << endl << endl;*/ - if (_n == _note) { - _notes.erase(n); - // we have to break here, because erase invalidates all iterators, ie. n itself - break; - } - } -} - -/** Slow! for debugging only. */ -#ifndef NDEBUG -bool MidiModel::is_sorted() const { - bool t = 0; - for (Notes::const_iterator n = _notes.begin(); n != _notes.end(); ++n) - if ((*n)->time() < t) - return false; - else - t = (*n)->time(); - - return true; -} -#endif - -/** Start a new command. - * - * This has no side-effects on the model or Session, the returned command - * can be held on to for as long as the caller wishes, or discarded without - * formality, until apply_command is called and ownership is taken. - */ -MidiModel::DeltaCommand* MidiModel::new_delta_command(const string name) -{ - DeltaCommand* cmd = new DeltaCommand(_midi_source->model(), name); - return cmd; -} - -/** Apply a command. - * - * Ownership of cmd is taken, it must not be deleted by the caller. - * The command will constitute one item on the undo stack. - */ -void MidiModel::apply_command(Command* cmd) -{ - _session.begin_reversible_command(cmd->name()); - (*cmd)(); - assert(is_sorted()); - _session.commit_reversible_command(cmd); - _edited = true; -} - -// MidiEditCommand - -MidiModel::DeltaCommand::DeltaCommand(boost::shared_ptr<MidiModel> m, - const std::string& name) - : Command(name) - , _model(m) - , _name(name) -{ -} - -MidiModel::DeltaCommand::DeltaCommand(boost::shared_ptr<MidiModel> m, - const XMLNode& node) - : _model(m) -{ - set_state(node); -} - -void MidiModel::DeltaCommand::add(const boost::shared_ptr<Note> note) -{ - //cerr << "MEC: apply" << endl; - _removed_notes.remove(note); - _added_notes.push_back(note); -} - -void MidiModel::DeltaCommand::remove(const boost::shared_ptr<Note> note) -{ - //cerr << "MEC: remove" << endl; - _added_notes.remove(note); - _removed_notes.push_back(note); -} - -void MidiModel::DeltaCommand::operator()() -{ - // This could be made much faster by using a priority_queue for added and - // removed notes (or sort here), and doing a single iteration over _model - - // Need to reset iterator to drop the read lock it holds, or we'll deadlock - const bool reset_iter = (_model->_read_iter.locked()); - double iter_time = -1.0; - - if (reset_iter) { - if (_model->_read_iter.get_event_pointer().get()) { - iter_time = _model->_read_iter->time(); - } else { - cerr << "MidiModel::DeltaCommand::operator(): WARNING: _read_iter points to no event" << endl; - } - _model->_read_iter = _model->end(); // drop read lock - } - - assert( ! _model->_read_iter.locked()); - - _model->write_lock(); - - for (std::list< boost::shared_ptr<Note> >::iterator i = _added_notes.begin(); i != _added_notes.end(); ++i) - _model->add_note_unlocked(*i); - - for (std::list< boost::shared_ptr<Note> >::iterator i = _removed_notes.begin(); i != _removed_notes.end(); ++i) - _model->remove_note_unlocked(*i); - - _model->write_unlock(); - - if (reset_iter && iter_time != -1.0) { - _model->_read_iter = const_iterator(*_model.get(), iter_time); - } - - _model->ContentsChanged(); /* EMIT SIGNAL */ -} - -void MidiModel::DeltaCommand::undo() -{ - // This could be made much faster by using a priority_queue for added and - // removed notes (or sort here), and doing a single iteration over _model - - // Need to reset iterator to drop the read lock it holds, or we'll deadlock - const bool reset_iter = (_model->_read_iter.locked()); - double iter_time = -1.0; - - if (reset_iter) { - if (_model->_read_iter.get_event_pointer().get()) { - iter_time = _model->_read_iter->time(); - } else { - cerr << "MidiModel::DeltaCommand::undo(): WARNING: _read_iter points to no event" << endl; - } - _model->_read_iter = _model->end(); // drop read lock - } - - assert( ! _model->_read_iter.locked()); - - _model->write_lock(); - - for (std::list< boost::shared_ptr<Note> >::iterator i = _added_notes.begin(); i - != _added_notes.end(); ++i) - _model->remove_note_unlocked(*i); - - for (std::list< boost::shared_ptr<Note> >::iterator i = - _removed_notes.begin(); i != _removed_notes.end(); ++i) - _model->add_note_unlocked(*i); - - _model->write_unlock(); - - if (reset_iter && iter_time != -1.0) { - _model->_read_iter = const_iterator(*_model.get(), iter_time); - } - - _model->ContentsChanged(); /* EMIT SIGNAL */ -} - -XMLNode & MidiModel::DeltaCommand::marshal_note(const boost::shared_ptr<Note> note) -{ - XMLNode *xml_note = new XMLNode("note"); - ostringstream note_str(ios::ate); - note_str << int(note->note()); - xml_note->add_property("note", note_str.str()); - - ostringstream channel_str(ios::ate); - channel_str << int(note->channel()); - xml_note->add_property("channel", channel_str.str()); - - ostringstream time_str(ios::ate); - time_str << int(note->time()); - xml_note->add_property("time", time_str.str()); - - ostringstream duration_str(ios::ate); - duration_str <<(unsigned int) note->duration(); - xml_note->add_property("duration", duration_str.str()); - - ostringstream velocity_str(ios::ate); - velocity_str << (unsigned int) note->velocity(); - xml_note->add_property("velocity", velocity_str.str()); - - return *xml_note; -} - -boost::shared_ptr<Note> MidiModel::DeltaCommand::unmarshal_note(XMLNode *xml_note) -{ - unsigned int note; - istringstream note_str(xml_note->property("note")->value()); - note_str >> note; - - unsigned int channel; - istringstream channel_str(xml_note->property("channel")->value()); - channel_str >> channel; - - unsigned int time; - istringstream time_str(xml_note->property("time")->value()); - time_str >> time; - - unsigned int duration; - istringstream duration_str(xml_note->property("duration")->value()); - duration_str >> duration; - - unsigned int velocity; - istringstream velocity_str(xml_note->property("velocity")->value()); - velocity_str >> velocity; - - boost::shared_ptr<Note> note_ptr(new Note(channel, time, duration, note, velocity)); - return note_ptr; -} - -#define ADDED_NOTES_ELEMENT "added_notes" -#define REMOVED_NOTES_ELEMENT "removed_notes" -#define DELTA_COMMAND_ELEMENT "DeltaCommand" - -int MidiModel::DeltaCommand::set_state(const XMLNode& delta_command) -{ - if (delta_command.name() != string(DELTA_COMMAND_ELEMENT)) { - return 1; - } - - _added_notes.clear(); - XMLNode *added_notes = delta_command.child(ADDED_NOTES_ELEMENT); - XMLNodeList notes = added_notes->children(); - transform(notes.begin(), notes.end(), back_inserter(_added_notes), - sigc::mem_fun(*this, &DeltaCommand::unmarshal_note)); - - _removed_notes.clear(); - XMLNode *removed_notes = delta_command.child(REMOVED_NOTES_ELEMENT); - notes = removed_notes->children(); - transform(notes.begin(), notes.end(), back_inserter(_removed_notes), - sigc::mem_fun(*this, &DeltaCommand::unmarshal_note)); - - return 0; -} - -XMLNode& MidiModel::DeltaCommand::get_state() -{ - XMLNode *delta_command = new XMLNode(DELTA_COMMAND_ELEMENT); - delta_command->add_property("midi_source", _model->midi_source()->id().to_s()); - - XMLNode *added_notes = delta_command->add_child(ADDED_NOTES_ELEMENT); - for_each(_added_notes.begin(), _added_notes.end(), sigc::compose( - sigc::mem_fun(*added_notes, &XMLNode::add_child_nocopy), - sigc::mem_fun(*this, &DeltaCommand::marshal_note))); - - XMLNode *removed_notes = delta_command->add_child(REMOVED_NOTES_ELEMENT); - for_each(_removed_notes.begin(), _removed_notes.end(), sigc::compose( - sigc::mem_fun(*removed_notes, &XMLNode::add_child_nocopy), - sigc::mem_fun(*this, &DeltaCommand::marshal_note))); - - return *delta_command; -} - -struct EventTimeComparator { - typedef const MIDI::Event* value_type; - inline bool operator()(const MIDI::Event& a, const MIDI::Event& b) const { - return a.time() >= b.time(); - } -}; - -/** Write the model to a MidiSource (i.e. save the model). - * This is different from manually using read to write to a source in that - * note off events are written regardless of the track mode. This is so the - * user can switch a recorded track (with note durations from some instrument) - * to percussive, save, reload, then switch it back to sustained without - * destroying the original note durations. - */ -bool MidiModel::write_to(boost::shared_ptr<MidiSource> source) -{ - read_lock(); - - const NoteMode old_note_mode = _note_mode; - _note_mode = Sustained; - - for (const_iterator i = begin(); i != end(); ++i) { - source->append_event_unlocked(Frames, *i); - } - - _note_mode = old_note_mode; - - read_unlock(); - _edited = false; - - return true; -} - -XMLNode& MidiModel::get_state() -{ - XMLNode *node = new XMLNode("MidiModel"); - return *node; -} - diff --git a/libs/ardour/midi_playlist.cc b/libs/ardour/midi_playlist.cc deleted file mode 100644 index d258d49524..0000000000 --- a/libs/ardour/midi_playlist.cc +++ /dev/null @@ -1,318 +0,0 @@ -/* - 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. -*/ - -#include <cassert> - -#include <algorithm> - -#include <stdlib.h> - -#include <sigc++/bind.h> - -#include <ardour/types.h> -#include <ardour/configuration.h> -#include <ardour/midi_playlist.h> -#include <ardour/midi_region.h> -#include <ardour/session.h> -#include <ardour/midi_ring_buffer.h> - -#include <pbd/error.h> - -#include "i18n.h" - -using namespace ARDOUR; -using namespace sigc; -using namespace std; - -MidiPlaylist::MidiPlaylist (Session& session, const XMLNode& node, bool hidden) - : Playlist (session, node, DataType::MIDI, hidden) - , _note_mode(Sustained) -{ - const XMLProperty* prop = node.property("type"); - assert(prop && DataType(prop->value()) == DataType::MIDI); - - in_set_state++; - set_state (node); - in_set_state--; -} - -MidiPlaylist::MidiPlaylist (Session& session, string name, bool hidden) - : Playlist (session, name, DataType::MIDI, hidden) -{ -} - -MidiPlaylist::MidiPlaylist (boost::shared_ptr<const MidiPlaylist> other, string name, bool hidden) - : Playlist (other, name, hidden) -{ - throw; // nope - - /* - list<Region*>::const_iterator in_o = other.regions.begin(); - list<Region*>::iterator in_n = regions.begin(); - - while (in_o != other.regions.end()) { - MidiRegion *ar = dynamic_cast<MidiRegion *>( (*in_o) ); - - for (list<Crossfade *>::const_iterator xfades = other._crossfades.begin(); xfades != other._crossfades.end(); ++xfades) { - if ( &(*xfades)->in() == ar) { - // We found one! Now copy it! - - list<Region*>::const_iterator out_o = other.regions.begin(); - list<Region*>::const_iterator out_n = regions.begin(); - - while (out_o != other.regions.end()) { - - MidiRegion *ar2 = dynamic_cast<MidiRegion *>( (*out_o) ); - - if ( &(*xfades)->out() == ar2) { - MidiRegion *in = dynamic_cast<MidiRegion*>( (*in_n) ); - MidiRegion *out = dynamic_cast<MidiRegion*>( (*out_n) ); - Crossfade *new_fade = new Crossfade( *(*xfades), in, out); - add_crossfade(*new_fade); - break; - } - - out_o++; - out_n++; - } - // cerr << "HUH!? second region in the crossfade not found!" << endl; - } - } - - in_o++; - in_n++; - } -*/ -} - -MidiPlaylist::MidiPlaylist (boost::shared_ptr<const MidiPlaylist> other, nframes_t start, nframes_t dur, string name, bool hidden) - : Playlist (other, start, dur, name, hidden) -{ - /* this constructor does NOT notify others (session) */ -} - -MidiPlaylist::~MidiPlaylist () -{ - GoingAway (); /* EMIT SIGNAL */ - - /* drop connections to signals */ - - notify_callbacks (); -} - -struct RegionSortByLayer { - bool operator() (boost::shared_ptr<Region> a, boost::shared_ptr<Region> b) { - return a->layer() < b->layer(); - } -}; - -/** Returns the number of frames in time duration read (eg could be large when 0 events are read) */ -nframes_t -MidiPlaylist::read (MidiRingBuffer& dst, nframes_t start, - nframes_t dur, unsigned chan_n) -{ - /* this function is never called from a realtime thread, so - its OK to block (for short intervals). - */ - - Glib::Mutex::Lock rm (region_lock); - - nframes_t end = start + dur - 1; - - _read_data_count = 0; - - // relevent regions overlapping start <--> end - vector<boost::shared_ptr<Region> > regs; - - for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { - - if ((*i)->coverage (start, end) != OverlapNone) { - regs.push_back(*i); - } - } - - RegionSortByLayer layer_cmp; - sort(regs.begin(), regs.end(), layer_cmp); - - for (vector<boost::shared_ptr<Region> >::iterator i = regs.begin(); i != regs.end(); ++i) { - // FIXME: ensure time is monotonic here? - boost::shared_ptr<MidiRegion> mr = boost::dynamic_pointer_cast<MidiRegion>(*i); - if (mr) { - mr->read_at (dst, start, dur, chan_n, _note_mode); - _read_data_count += mr->read_data_count(); - } - } - - return dur; -} - - -void -MidiPlaylist::remove_dependents (boost::shared_ptr<Region> region) -{ - /* MIDI regions have no dependents (crossfades) */ -} - - -void -MidiPlaylist::refresh_dependents (boost::shared_ptr<Region> r) -{ - /* MIDI regions have no dependents (crossfades) */ -} - -void -MidiPlaylist::finalize_split_region (boost::shared_ptr<Region> original, boost::shared_ptr<Region> left, boost::shared_ptr<Region> right) -{ - /* No MIDI crossfading (yet?), so nothing to do here */ -} - -void -MidiPlaylist::check_dependents (boost::shared_ptr<Region> r, bool norefresh) -{ - /* MIDI regions have no dependents (crossfades) */ -} - - -int -MidiPlaylist::set_state (const XMLNode& node) -{ - in_set_state++; - freeze (); - - Playlist::set_state (node); - - thaw(); - in_set_state--; - - return 0; -} - -void -MidiPlaylist::dump () const -{ - boost::shared_ptr<Region> r; - - cerr << "Playlist \"" << _name << "\" " << endl - << regions.size() << " regions " - << endl; - - for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) { - r = *i; - cerr << " " << r->name() << " @ " << r << " [" - << r->start() << "+" << r->length() - << "] at " - << r->position() - << " on layer " - << r->layer () - << endl; - } -} - -bool -MidiPlaylist::destroy_region (boost::shared_ptr<Region> region) -{ - boost::shared_ptr<MidiRegion> r = boost::dynamic_pointer_cast<MidiRegion> (region); - bool changed = false; - - if (r == 0) { - PBD::fatal << _("programming error: non-midi Region passed to remove_overlap in midi playlist") - << endmsg; - /*NOTREACHED*/ - return false; - } - - { - RegionLock rlock (this); - RegionList::iterator i; - RegionList::iterator tmp; - - for (i = regions.begin(); i != regions.end(); ) { - - tmp = i; - ++tmp; - - if ((*i) == region) { - regions.erase (i); - changed = true; - } - - i = tmp; - } - } - - - if (changed) { - /* overload this, it normally means "removed", not destroyed */ - notify_region_removed (region); - } - - return changed; -} - -set<Parameter> -MidiPlaylist::contained_automation() -{ - /* this function is never called from a realtime thread, so - its OK to block (for short intervals). - */ - - Glib::Mutex::Lock rm (region_lock); - - set<Parameter> ret; - - for (RegionList::const_iterator r = regions.begin(); r != regions.end(); ++r) { - boost::shared_ptr<MidiRegion> mr = boost::dynamic_pointer_cast<MidiRegion>(*r); - - for (Automatable::Controls::iterator c = mr->controls().begin(); - c != mr->controls().end(); ++c) { - ret.insert(c->first); - } - } - - return ret; -} - - -bool -MidiPlaylist::region_changed (Change what_changed, boost::shared_ptr<Region> region) -{ - if (in_flush || in_set_state) { - return false; - } - - // Feeling rather uninterested today, but thanks for the heads up anyway! - - Change our_interests = Change (/*MidiRegion::FadeInChanged| - MidiRegion::FadeOutChanged| - MidiRegion::FadeInActiveChanged| - MidiRegion::FadeOutActiveChanged| - MidiRegion::EnvelopeActiveChanged| - MidiRegion::ScaleAmplitudeChanged| - MidiRegion::EnvelopeChanged*/); - bool parent_wants_notify; - - parent_wants_notify = Playlist::region_changed (what_changed, region); - - if ((parent_wants_notify || (what_changed & our_interests))) { - notify_modified (); - } - - return true; -} - diff --git a/libs/ardour/midi_port.cc b/libs/ardour/midi_port.cc deleted file mode 100644 index 14f88f2ad5..0000000000 --- a/libs/ardour/midi_port.cc +++ /dev/null @@ -1,112 +0,0 @@ -/* - 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. -*/ - -#include <cassert> -#include <iostream> - -#include <ardour/midi_port.h> -#include <ardour/jack_midi_port.h> -#include <ardour/data_type.h> - -using namespace ARDOUR; -using namespace std; - -MidiPort::MidiPort (const std::string& name, Flags flags, bool external, nframes_t capacity) - : Port (name, flags) - , BaseMidiPort (name, flags) - , PortFacade (name, flags) -{ - // FIXME: size kludge (see BufferSet::ensure_buffers) - // Jack needs to tell us this - _buffer = new MidiBuffer (capacity * 8); - - if (external) { - /* external ports use the same buffer for the jack port (_ext_port) - * and internal ports (this) */ - _ext_port = new JackMidiPort (name, flags, _buffer); - Port::set_name (_ext_port->name()); - } else { - /* internal ports just have a single buffer, no jack port */ - _ext_port = 0; - set_name (name); - } - - reset (); -} - -MidiPort::~MidiPort() -{ - if (_ext_port) { - delete _ext_port; - _ext_port = 0; - } -} - -void -MidiPort::reset() -{ - BaseMidiPort::reset(); - - if (_ext_port) { - _ext_port->reset (); - } -} - -void -MidiPort::cycle_start (nframes_t nframes, nframes_t offset) -{ - if (_ext_port) { - _ext_port->cycle_start (nframes, offset); - } - - if (_flags & IsInput) { - - if (_ext_port) { - - BaseMidiPort* mprt = dynamic_cast<BaseMidiPort*>(_ext_port); - assert(mprt); - assert(&mprt->get_midi_buffer() == _buffer); - - if (!_connections.empty()) { - (*_mixdown) (_connections, _buffer, nframes, offset, false); - } - - } else { - - if (_connections.empty()) { - _buffer->silence (nframes, offset); - } else { - (*_mixdown) (_connections, _buffer, nframes, offset, true); - } - } - - } else { - - _buffer->silence (nframes, offset); - } -} - - -void -MidiPort::cycle_end (nframes_t nframes, nframes_t offset) -{ - if (_ext_port) { - _ext_port->cycle_end (nframes, offset); - } -} - diff --git a/libs/ardour/midi_region.cc b/libs/ardour/midi_region.cc deleted file mode 100644 index e29fb1e659..0000000000 --- a/libs/ardour/midi_region.cc +++ /dev/null @@ -1,363 +0,0 @@ -/* - 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.cc 746 2006-08-02 02:44:23Z drobilla $ -*/ - -#include <cmath> -#include <climits> -#include <cfloat> - -#include <set> - -#include <sigc++/bind.h> -#include <sigc++/class_slot.h> - -#include <glibmm/thread.h> - -#include <pbd/basename.h> -#include <pbd/xml++.h> -#include <pbd/enumwriter.h> - -#include <ardour/midi_region.h> -#include <ardour/session.h> -#include <ardour/gain.h> -#include <ardour/dB.h> -#include <ardour/playlist.h> -#include <ardour/midi_source.h> -#include <ardour/types.h> -#include <ardour/midi_ring_buffer.h> - -#include "i18n.h" -#include <locale.h> - -using namespace std; -using namespace ARDOUR; - -/** Basic MidiRegion constructor (one channel) */ -MidiRegion::MidiRegion (boost::shared_ptr<MidiSource> src, nframes_t start, nframes_t length) - : Region (src, start, length, PBD::basename_nosuffix(src->name()), DataType::MIDI, 0, Region::Flag(Region::DefaultFlags|Region::External)) -{ - assert(_name.find("/") == string::npos); - midi_source(0)->Switched.connect(sigc::mem_fun(this, &MidiRegion::switch_source)); -} - -/* Basic MidiRegion constructor (one channel) */ -MidiRegion::MidiRegion (boost::shared_ptr<MidiSource> src, nframes_t start, nframes_t length, const string& name, layer_t layer, Flag flags) - : Region (src, start, length, name, DataType::MIDI, layer, flags) -{ - assert(_name.find("/") == string::npos); - midi_source(0)->Switched.connect(sigc::mem_fun(this, &MidiRegion::switch_source)); -} - -/* Basic MidiRegion constructor (many channels) */ -MidiRegion::MidiRegion (const SourceList& srcs, nframes_t start, nframes_t length, const string& name, layer_t layer, Flag flags) - : Region (srcs, start, length, name, DataType::MIDI, layer, flags) -{ - assert(_name.find("/") == string::npos); - midi_source(0)->Switched.connect(sigc::mem_fun(this, &MidiRegion::switch_source)); -} - - -/** Create a new MidiRegion, that is part of an existing one */ -MidiRegion::MidiRegion (boost::shared_ptr<const MidiRegion> other, nframes_t offset, nframes_t length, const string& name, layer_t layer, Flag flags) - : Region (other, offset, length, name, layer, flags) -{ - assert(_name.find("/") == string::npos); - midi_source(0)->Switched.connect(sigc::mem_fun(this, &MidiRegion::switch_source)); -} - -MidiRegion::MidiRegion (boost::shared_ptr<const MidiRegion> other) - : Region (other) -{ - assert(_name.find("/") == string::npos); - midi_source(0)->Switched.connect(sigc::mem_fun(this, &MidiRegion::switch_source)); -} - -MidiRegion::MidiRegion (boost::shared_ptr<MidiSource> src, const XMLNode& node) - : Region (src, node) -{ - if (set_state (node)) { - throw failed_constructor(); - } - - midi_source(0)->Switched.connect(sigc::mem_fun(this, &MidiRegion::switch_source)); - assert(_name.find("/") == string::npos); - assert(_type == DataType::MIDI); -} - -MidiRegion::MidiRegion (const SourceList& srcs, const XMLNode& node) - : Region (srcs, node) -{ - if (set_state (node)) { - throw failed_constructor(); - } - - midi_source(0)->Switched.connect(sigc::mem_fun(this, &MidiRegion::switch_source)); - assert(_name.find("/") == string::npos); - assert(_type == DataType::MIDI); -} - -MidiRegion::~MidiRegion () -{ -} - -nframes_t -MidiRegion::read_at (MidiRingBuffer& out, nframes_t position, nframes_t dur, uint32_t chan_n, NoteMode mode) const -{ - return _read_at (_sources, out, position, dur, chan_n, mode); -} - -nframes_t -MidiRegion::master_read_at (MidiRingBuffer& out, nframes_t position, nframes_t dur, uint32_t chan_n, NoteMode mode) const -{ - return _read_at (_master_sources, out, position, dur, chan_n, mode); -} - -nframes_t -MidiRegion::_read_at (const SourceList& srcs, MidiRingBuffer& dst, nframes_t position, nframes_t dur, uint32_t chan_n, NoteMode mode) const -{ - /*cerr << "MidiRegion " << _name << "._read_at(" << position << ") - " - << position << " duration: " << dur << endl;*/ - - nframes_t internal_offset = 0; - nframes_t src_offset = 0; - nframes_t to_read = 0; - - /* precondition: caller has verified that we cover the desired section */ - - assert(chan_n == 0); - - if (position < _position) { - internal_offset = 0; - src_offset = _position - position; - dur -= src_offset; - } else { - internal_offset = position - _position; - src_offset = 0; - } - - if (internal_offset >= _length) { - return 0; /* read nothing */ - } - - - if ((to_read = min (dur, _length - internal_offset)) == 0) { - return 0; /* read nothing */ - } - - // FIXME: non-opaque MIDI regions not yet supported - assert(opaque()); - - if (muted()) { - return 0; /* read nothing */ - } - - _read_data_count = 0; - - boost::shared_ptr<MidiSource> src = midi_source(chan_n); - src->set_note_mode(mode); - - nframes_t output_buffer_position = 0; - nframes_t negative_output_buffer_position = 0; - if (_position >= _start) { - // handle resizing of beginnings of regions correctly - output_buffer_position = _position - _start; - } else { - // when _start is greater than _position, we have to subtract - // _start from the note times in the midi source - negative_output_buffer_position = _start; - } - - if (src->midi_read ( - // the destination buffer - dst, - // where to start reading in the region - _start + internal_offset, - // how many bytes - to_read, - // the offset in the output buffer - output_buffer_position, - // what to substract from note times written in the output buffer - negative_output_buffer_position - ) != to_read) { - return 0; /* "read nothing" */ - } - - _read_data_count += src->read_data_count(); - - return to_read; -} - -XMLNode& -MidiRegion::state (bool full) -{ - XMLNode& node (Region::state (full)); - char buf[64]; - char buf2[64]; - LocaleGuard lg (X_("POSIX")); - - node.add_property ("flags", enum_2_string (_flags)); - - // XXX these should move into Region - - for (uint32_t n=0; n < _sources.size(); ++n) { - snprintf (buf2, sizeof(buf2), "source-%d", n); - _sources[n]->id().print (buf, sizeof(buf)); - node.add_property (buf2, buf); - } - - for (uint32_t n=0; n < _master_sources.size(); ++n) { - snprintf (buf2, sizeof(buf2), "master-source-%d", n); - _master_sources[n]->id().print (buf, sizeof (buf)); - node.add_property (buf2, buf); - } - - if (full && _extra_xml) { - node.add_child_copy (*_extra_xml); - } - - return node; -} - -int -MidiRegion::set_live_state (const XMLNode& node, Change& what_changed, bool send) -{ - const XMLProperty *prop; - LocaleGuard lg (X_("POSIX")); - - Region::set_live_state (node, what_changed, false); - - uint32_t old_flags = _flags; - - if ((prop = node.property ("flags")) != 0) { - _flags = Flag (string_2_enum (prop->value(), _flags)); - - //_flags = Flag (strtol (prop->value().c_str(), (char **) 0, 16)); - - _flags = Flag (_flags & ~Region::LeftOfSplit); - _flags = Flag (_flags & ~Region::RightOfSplit); - } - - if ((old_flags ^ _flags) & Muted) { - what_changed = Change (what_changed|MuteChanged); - } - if ((old_flags ^ _flags) & Opaque) { - what_changed = Change (what_changed|OpacityChanged); - } - if ((old_flags ^ _flags) & Locked) { - what_changed = Change (what_changed|LockChanged); - } - - if (send) { - send_change (what_changed); - } - - return 0; -} - -int -MidiRegion::set_state (const XMLNode& node) -{ - /* Region::set_state() calls the virtual set_live_state(), - which will get us back to AudioRegion::set_live_state() - to handle the relevant stuff. - */ - - return Region::set_state (node); -} - -void -MidiRegion::recompute_at_end () -{ - /* our length has changed - * (non destructively) "chop" notes that pass the end boundary, to - * prevent stuck notes. - */ -} - -void -MidiRegion::recompute_at_start () -{ - /* as above, but the shift was from the front - * maybe bump currently active note's note-ons up so they sound here? - * that could be undesireable in certain situations though.. maybe - * remove the note entirely, including it's note off? something needs to - * be done to keep the played MIDI sane to avoid messing up voices of - * polyhonic things etc........ - */ -} - -int -MidiRegion::separate_by_channel (Session& session, vector<MidiRegion*>& v) const -{ - // Separate by MIDI channel? bit different from audio since this is separating based - // on the actual contained data and destructively modifies and creates new sources.. - -#if 0 - SourceList srcs; - string new_name; - - for (SourceList::const_iterator i = _master_sources.begin(); i != _master_sources.end(); ++i) { - - srcs.clear (); - srcs.push_back (*i); - - /* generate a new name */ - - if (session.region_name (new_name, _name)) { - return -1; - } - - /* create a copy with just one source */ - - v.push_back (new MidiRegion (srcs, _start, _length, new_name, _layer, _flags)); - } -#endif - - // Actually, I would prefer not if that's alright - return -1; -} - -int -MidiRegion::exportme (ARDOUR::Session&, ARDOUR::ExportSpecification&) -{ - return -1; -} - -boost::shared_ptr<MidiSource> -MidiRegion::midi_source (uint32_t n) const -{ - // Guaranteed to succeed (use a static cast?) - return boost::dynamic_pointer_cast<MidiSource>(source(n)); -} - - -void -MidiRegion::switch_source(boost::shared_ptr<Source> src) -{ - boost::shared_ptr<MidiSource> msrc = boost::dynamic_pointer_cast<MidiSource>(src); - if (!msrc) - return; - - // MIDI regions have only one source - _sources.clear(); - _sources.push_back(msrc); - - set_name(msrc->name()); -} - diff --git a/libs/ardour/midi_source.cc b/libs/ardour/midi_source.cc deleted file mode 100644 index 4e83413c13..0000000000 --- a/libs/ardour/midi_source.cc +++ /dev/null @@ -1,206 +0,0 @@ -/* - 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. -*/ - -#include <sys/stat.h> -#include <unistd.h> -#include <fcntl.h> -#include <poll.h> -#include <float.h> -#include <cerrno> -#include <ctime> -#include <cmath> -#include <iomanip> -#include <algorithm> - -#include <pbd/xml++.h> -#include <pbd/pthread_utils.h> -#include <pbd/basename.h> - -#include <ardour/midi_source.h> -#include <ardour/midi_ring_buffer.h> -#include <ardour/session.h> -#include <ardour/session_directory.h> -#include <ardour/source_factory.h> - -#include "i18n.h" - -using namespace std; -using namespace ARDOUR; -using namespace PBD; - -sigc::signal<void,MidiSource *> MidiSource::MidiSourceCreated; - -MidiSource::MidiSource (Session& s, string name) - : Source (s, name, DataType::MIDI) - , _timeline_position(0) - , _model(new MidiModel(this)) - , _writing (false) -{ - _read_data_count = 0; - _write_data_count = 0; -} - -MidiSource::MidiSource (Session& s, const XMLNode& node) - : Source (s, node) - , _timeline_position(0) - , _model(new MidiModel(this)) - , _writing (false) -{ - _read_data_count = 0; - _write_data_count = 0; - - if (set_state (node)) { - throw failed_constructor(); - } -} - -MidiSource::~MidiSource () -{ -} - -XMLNode& -MidiSource::get_state () -{ - XMLNode& node (Source::get_state()); - - if (_captured_for.length()) { - node.add_property ("captured-for", _captured_for); - } - - return node; -} - -int -MidiSource::set_state (const XMLNode& node) -{ - const XMLProperty* prop; - - Source::set_state (node); - - if ((prop = node.property ("captured-for")) != 0) { - _captured_for = prop->value(); - } - - return 0; -} - -nframes_t -MidiSource::midi_read (MidiRingBuffer& dst, nframes_t start, nframes_t cnt, nframes_t stamp_offset, nframes_t negative_stamp_offset) const -{ - Glib::Mutex::Lock lm (_lock); - if (_model) { - //const size_t n_events = - _model->read(dst, start, cnt, stamp_offset, negative_stamp_offset); - //cout << "Read " << n_events << " events from model." << endl; - return cnt; - } else { - return read_unlocked (dst, start, cnt, stamp_offset, negative_stamp_offset); - } -} - -nframes_t -MidiSource::midi_write (MidiRingBuffer& dst, nframes_t cnt) -{ - Glib::Mutex::Lock lm (_lock); - return write_unlocked (dst, cnt); -} - -bool -MidiSource::file_changed (string path) -{ - struct stat stat_file; - - int e1 = stat (path.c_str(), &stat_file); - - return ( !e1 ); -} - -void -MidiSource::mark_streaming_midi_write_started (NoteMode mode, nframes_t start_frame) -{ - set_timeline_position(start_frame); // why do I have a feeling this can break somehow... - - if (_model) { - _model->set_note_mode(mode); - _model->start_write(); - } - - _writing = true; -} - -void -MidiSource::mark_streaming_write_started () -{ - if (_model) - _model->start_write(); - - _writing = true; -} - -void -MidiSource::mark_streaming_write_completed () -{ - if (_model) - _model->end_write(false); // FIXME: param? - - _writing = false; -} - -void -MidiSource::session_saved() -{ - flush_header(); - flush_footer(); - - if (_model && _model->edited()) { - string newname; - const string basename = PBD::basename_nosuffix(_name); - string::size_type last_dash = basename.find_last_of("-"); - if (last_dash == string::npos || last_dash == basename.find_first_of("-")) { - newname = basename + "-1"; - } else { - stringstream ss(basename.substr(last_dash+1)); - unsigned write_count = 0; - ss >> write_count; - cerr << "WRITE COUNT: " << write_count << endl; - ++write_count; // start at 1 - ss.clear(); - ss << basename.substr(0, last_dash) << "-" << write_count; - newname = ss.str(); - } - - string newpath = _session.session_directory().midi_path().to_string() +"/"+ newname + ".mid"; - - boost::shared_ptr<MidiSource> newsrc = boost::dynamic_pointer_cast<MidiSource>( - SourceFactory::createWritable(DataType::MIDI, _session, newpath, 1, 0, true)); - - newsrc->set_timeline_position(_timeline_position); - _model->write_to(newsrc); - - // cyclic dependency here, ugly :( - newsrc->set_model(_model); - _model->set_midi_source(newsrc.get()); - - newsrc->flush_header(); - newsrc->flush_footer(); - - Switched.emit(newsrc); - } -} - diff --git a/libs/ardour/midi_stretch.cc b/libs/ardour/midi_stretch.cc deleted file mode 100644 index f33c58a0fd..0000000000 --- a/libs/ardour/midi_stretch.cc +++ /dev/null @@ -1,108 +0,0 @@ -/* - 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. - -*/ - -#include <pbd/error.h> - -#include <ardour/types.h> -#include <ardour/midi_stretch.h> -#include <ardour/session.h> -#include <ardour/midi_region.h> - -#include "i18n.h" - -using namespace std; -using namespace ARDOUR; -using namespace PBD; - -MidiStretch::MidiStretch (Session& s, TimeFXRequest& req) - : Filter (s) - , _request (req) -{ -} - -MidiStretch::~MidiStretch () -{ -} - -int -MidiStretch::run (boost::shared_ptr<Region> r) -{ - SourceList nsrcs; - char suffix[32]; - - boost::shared_ptr<MidiRegion> region = boost::dynamic_pointer_cast<MidiRegion>(r); - if (!region) - return -1; - - /* the name doesn't need to be super-precise, but allow for 2 fractional - digits just to disambiguate close but not identical stretches. - */ - - snprintf (suffix, sizeof (suffix), "@%d", (int) floor (_request.time_fraction * 100.0f)); - - string new_name = region->name(); - string::size_type at = new_name.find ('@'); - - // remove any existing stretch indicator - - if (at != string::npos && at > 2) { - new_name = new_name.substr (0, at - 1); - } - - new_name += suffix; - - /* create new sources */ - - if (make_new_sources (region, nsrcs, suffix)) - return -1; - - // FIXME: how to make a whole file region if it isn't? - //assert(region->whole_file()); - - boost::shared_ptr<MidiSource> src = region->midi_source(0); - src->load_model(); - - boost::shared_ptr<MidiModel> old_model = src->model(); - - boost::shared_ptr<MidiSource> new_src = boost::dynamic_pointer_cast<MidiSource>(nsrcs[0]); - assert(new_src); - - boost::shared_ptr<MidiModel> new_model = new_src->model(); - new_model->start_write(); - - for (MidiModel::const_iterator i = old_model->begin(); i != old_model->end(); ++i) { - const double new_time = i->time() * _request.time_fraction; - - // FIXME: double copy - MIDI::Event ev = MIDI::Event(*i, true); - ev.time() = new_time; - new_model->append(ev); - } - - new_model->end_write(); - new_model->set_edited(true); - - const int ret = finish (region, nsrcs, new_name); - - results[0]->set_length((nframes_t) floor (r->length() * _request.time_fraction), NULL); - - return ret; -} - diff --git a/libs/ardour/midi_track.cc b/libs/ardour/midi_track.cc deleted file mode 100644 index 1000e68ba6..0000000000 --- a/libs/ardour/midi_track.cc +++ /dev/null @@ -1,769 +0,0 @@ -/* - Copyright (C) 2006 Paul Davis - 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. -*/ -#include <pbd/error.h> -#include <sigc++/retype.h> -#include <sigc++/retype_return.h> -#include <sigc++/bind.h> - -#include <pbd/enumwriter.h> -#include <midi++/events.h> - -#include <ardour/midi_track.h> -#include <ardour/midi_diskstream.h> -#include <ardour/session.h> -#include <ardour/io_processor.h> -#include <ardour/midi_region.h> -#include <ardour/midi_source.h> -#include <ardour/route_group_specialized.h> -#include <ardour/processor.h> -#include <ardour/midi_playlist.h> -#include <ardour/panner.h> -#include <ardour/utils.h> -#include <ardour/buffer_set.h> -#include <ardour/meter.h> - - -#include "i18n.h" - -using namespace std; -using namespace ARDOUR; -using namespace PBD; - -MidiTrack::MidiTrack (Session& sess, string name, Route::Flag flag, TrackMode mode) - : Track (sess, name, flag, mode, DataType::MIDI) - , _immediate_events(1024) // FIXME: size? - , _note_mode(Sustained) -{ - MidiDiskstream::Flag dflags = MidiDiskstream::Flag (0); - - if (_flags & Hidden) { - dflags = MidiDiskstream::Flag (dflags | MidiDiskstream::Hidden); - } else { - dflags = MidiDiskstream::Flag (dflags | MidiDiskstream::Recordable); - } - - assert(mode != Destructive); - - boost::shared_ptr<MidiDiskstream> ds (new MidiDiskstream (_session, name, dflags)); - _session.add_diskstream (ds); - - set_diskstream (boost::dynamic_pointer_cast<MidiDiskstream> (ds)); - - _declickable = true; - _freeze_record.state = NoFreeze; - _saved_meter_point = _meter_point; - _mode = mode; - - set_input_minimum(ChanCount(DataType::MIDI, 1)); - set_input_maximum(ChanCount(DataType::MIDI, 1)); - set_output_minimum(ChanCount(DataType::MIDI, 1)); - set_output_maximum(ChanCount(DataType::MIDI, 1)); - - PortCountChanged(ChanCount(DataType::MIDI, 2)); /* EMIT SIGNAL */ -} - -MidiTrack::MidiTrack (Session& sess, const XMLNode& node) - : Track (sess, node) - , _immediate_events(1024) // FIXME: size? - , _note_mode(Sustained) -{ - _set_state(node, false); - - set_input_minimum(ChanCount(DataType::MIDI, 1)); - set_input_maximum(ChanCount(DataType::MIDI, 1)); - set_output_minimum(ChanCount(DataType::MIDI, 1)); - set_output_maximum(ChanCount(DataType::MIDI, 1)); - - PortCountChanged(ChanCount(DataType::MIDI, 2)); /* EMIT SIGNAL */ -} - -MidiTrack::~MidiTrack () -{ -} - - -int -MidiTrack::set_diskstream (boost::shared_ptr<MidiDiskstream> ds) -{ - _diskstream = ds; - _diskstream->set_io (*this); - _diskstream->set_destructive (_mode == Destructive); - - _diskstream->set_record_enabled (false); - //_diskstream->monitor_input (false); - - ic_connection.disconnect(); - ic_connection = input_changed.connect (mem_fun (*_diskstream, &MidiDiskstream::handle_input_change)); - - DiskstreamChanged (); /* EMIT SIGNAL */ - - return 0; -} - -int -MidiTrack::use_diskstream (string name) -{ - boost::shared_ptr<MidiDiskstream> dstream; - - if ((dstream = boost::dynamic_pointer_cast<MidiDiskstream>(_session.diskstream_by_name (name))) == 0) { - error << string_compose(_("MidiTrack: midi diskstream \"%1\" not known by session"), name) << endmsg; - return -1; - } - - return set_diskstream (dstream); -} - -int -MidiTrack::use_diskstream (const PBD::ID& id) -{ - boost::shared_ptr<MidiDiskstream> dstream; - - if ((dstream = boost::dynamic_pointer_cast<MidiDiskstream> (_session.diskstream_by_id (id))) == 0) { - error << string_compose(_("MidiTrack: midi diskstream \"%1\" not known by session"), id) << endmsg; - return -1; - } - - return set_diskstream (dstream); -} - -boost::shared_ptr<MidiDiskstream> -MidiTrack::midi_diskstream() const -{ - return boost::dynamic_pointer_cast<MidiDiskstream>(_diskstream); -} - -int -MidiTrack::set_state (const XMLNode& node) -{ - return _set_state (node, true); -} - -int -MidiTrack::_set_state (const XMLNode& node, bool call_base) -{ - const XMLProperty *prop; - XMLNodeConstIterator iter; - - if (Route::_set_state (node, call_base)) { - return -1; - } - - // No destructive MIDI tracks (yet?) - _mode = Normal; - - if ((prop = node.property (X_("note-mode"))) != 0) { - _note_mode = NoteMode (string_2_enum (prop->value(), _note_mode)); - } else { - _note_mode = Sustained; - } - - if ((prop = node.property ("diskstream-id")) == 0) { - - /* some old sessions use the diskstream name rather than the ID */ - - if ((prop = node.property ("diskstream")) == 0) { - fatal << _("programming error: MidiTrack given state without diskstream!") << endmsg; - /*NOTREACHED*/ - return -1; - } - - if (use_diskstream (prop->value())) { - return -1; - } - - } else { - - PBD::ID id (prop->value()); - - if (use_diskstream (id)) { - return -1; - } - } - - - XMLNodeList nlist; - XMLNodeConstIterator niter; - XMLNode *child; - - nlist = node.children(); - for (niter = nlist.begin(); niter != nlist.end(); ++niter){ - child = *niter; - - if (child->name() == X_("recenable")) { - _rec_enable_control->set_state (*child); - _session.add_controllable (_rec_enable_control); - } - } - - pending_state = const_cast<XMLNode*> (&node); - - _session.StateReady.connect (mem_fun (*this, &MidiTrack::set_state_part_two)); - - return 0; -} - -XMLNode& -MidiTrack::state(bool full_state) -{ - XMLNode& root (Route::state(full_state)); - XMLNode* freeze_node; - char buf[64]; - - if (_freeze_record.playlist) { - XMLNode* inode; - - freeze_node = new XMLNode (X_("freeze-info")); - freeze_node->add_property ("playlist", _freeze_record.playlist->name()); - freeze_node->add_property ("state", enum_2_string (_freeze_record.state)); - - for (vector<FreezeRecordProcessorInfo*>::iterator i = _freeze_record.processor_info.begin(); i != _freeze_record.processor_info.end(); ++i) { - inode = new XMLNode (X_("processor")); - (*i)->id.print (buf, sizeof(buf)); - inode->add_property (X_("id"), buf); - inode->add_child_copy ((*i)->state); - - freeze_node->add_child_nocopy (*inode); - } - - root.add_child_nocopy (*freeze_node); - } - - /* Alignment: act as a proxy for the diskstream */ - - XMLNode* align_node = new XMLNode (X_("alignment")); - AlignStyle as = _diskstream->alignment_style (); - align_node->add_property (X_("style"), enum_2_string (as)); - root.add_child_nocopy (*align_node); - - root.add_property (X_("note-mode"), enum_2_string (_note_mode)); - - /* we don't return diskstream state because we don't - own the diskstream exclusively. control of the diskstream - state is ceded to the Session, even if we create the - diskstream. - */ - - _diskstream->id().print (buf, sizeof(buf)); - root.add_property ("diskstream-id", buf); - - root.add_child_nocopy (_rec_enable_control->get_state()); - - return root; -} - -void -MidiTrack::set_state_part_two () -{ - XMLNode* fnode; - XMLProperty* prop; - LocaleGuard lg (X_("POSIX")); - - /* This is called after all session state has been restored but before - have been made ports and connections are established. - */ - - if (pending_state == 0) { - return; - } - - if ((fnode = find_named_node (*pending_state, X_("freeze-info"))) != 0) { - - - _freeze_record.have_mementos = false; - _freeze_record.state = Frozen; - - for (vector<FreezeRecordProcessorInfo*>::iterator i = _freeze_record.processor_info.begin(); i != _freeze_record.processor_info.end(); ++i) { - delete *i; - } - _freeze_record.processor_info.clear (); - - if ((prop = fnode->property (X_("playlist"))) != 0) { - boost::shared_ptr<Playlist> pl = _session.playlist_by_name (prop->value()); - if (pl) { - _freeze_record.playlist = boost::dynamic_pointer_cast<MidiPlaylist> (pl); - } else { - _freeze_record.playlist.reset(); - _freeze_record.state = NoFreeze; - return; - } - } - - if ((prop = fnode->property (X_("state"))) != 0) { - _freeze_record.state = FreezeState (string_2_enum (prop->value(), _freeze_record.state)); - } - - XMLNodeConstIterator citer; - XMLNodeList clist = fnode->children(); - - for (citer = clist.begin(); citer != clist.end(); ++citer) { - if ((*citer)->name() != X_("processor")) { - continue; - } - - if ((prop = (*citer)->property (X_("id"))) == 0) { - continue; - } - - FreezeRecordProcessorInfo* frii = new FreezeRecordProcessorInfo (*((*citer)->children().front()), - boost::shared_ptr<Processor>()); - frii->id = prop->value (); - _freeze_record.processor_info.push_back (frii); - } - } - - /* Alignment: act as a proxy for the diskstream */ - - if ((fnode = find_named_node (*pending_state, X_("alignment"))) != 0) { - - if ((prop = fnode->property (X_("style"))) != 0) { - - /* fix for older sessions from before EnumWriter */ - - string pstr; - - if (prop->value() == "capture") { - pstr = "CaptureTime"; - } else if (prop->value() == "existing") { - pstr = "ExistingMaterial"; - } else { - pstr = prop->value(); - } - - AlignStyle as = AlignStyle (string_2_enum (pstr, as)); - _diskstream->set_persistent_align_style (as); - } - } - return; -} - -int -MidiTrack::no_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, nframes_t offset, - bool session_state_changing, bool can_record, bool rec_monitors_input) -{ - if (n_outputs().n_midi() == 0) { - return 0; - } - - if (!_active) { - silence (nframes, offset); - } - - if (session_state_changing) { - - /* XXX is this safe to do against transport state changes? */ - - passthru_silence (start_frame, end_frame, nframes, offset, 0, false); - return 0; - } - - midi_diskstream()->check_record_status (start_frame, nframes, can_record); - - bool send_silence; - - if (_have_internal_generator) { - /* since the instrument has no input streams, - there is no reason to send any signal - into the route. - */ - send_silence = true; - } else { - - if (Config->get_auto_input()) { - if (Config->get_monitoring_model() == SoftwareMonitoring) { - send_silence = false; - } else { - send_silence = true; - } - } else { - if (_diskstream->record_enabled()) { - if (Config->get_monitoring_model() == SoftwareMonitoring) { - send_silence = false; - } else { - send_silence = true; - } - } else { - send_silence = true; - } - } - } - - apply_gain_automation = false; - - if (send_silence) { - - /* if we're sending silence, but we want the meters to show levels for the signal, - meter right here. - */ - - if (_have_internal_generator) { - passthru_silence (start_frame, end_frame, nframes, offset, 0, true); - } else { - if (_meter_point == MeterInput) { - just_meter_input (start_frame, end_frame, nframes, offset); - } - passthru_silence (start_frame, end_frame, nframes, offset, 0, false); - } - - } else { - - /* we're sending signal, but we may still want to meter the input. - */ - - passthru (start_frame, end_frame, nframes, offset, 0, (_meter_point == MeterInput)); - } - - return 0; -} - -int -MidiTrack::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 dret; - boost::shared_ptr<MidiDiskstream> diskstream = midi_diskstream(); - - { - Glib::RWLock::ReaderLock lm (_processor_lock, Glib::TRY_LOCK); - if (lm.locked()) { - // automation snapshot can also be called from the non-rt context - // and it uses the redirect list, so we take the lock out here - automation_snapshot (start_frame); - } - } - - if (n_outputs().n_total() == 0 && _processors.empty()) { - return 0; - } - - if (!_active) { - silence (nframes, offset); - return 0; - } - - nframes_t transport_frame = _session.transport_frame(); - - if ((nframes = check_initial_delay (nframes, offset, transport_frame)) == 0) { - /* need to do this so that the diskstream sets its - playback distance to zero, thus causing diskstream::commit - to do nothing. - */ - return diskstream->process (transport_frame, 0, 0, can_record, rec_monitors_input); - } - - _silent = false; - - if ((dret = diskstream->process (transport_frame, nframes, offset, can_record, rec_monitors_input)) != 0) { - - silence (nframes, offset); - - return dret; - } - - /* special condition applies */ - - if (_meter_point == MeterInput) { - just_meter_input (start_frame, end_frame, nframes, offset); - } - - if (diskstream->record_enabled() && !can_record && !Config->get_auto_input()) { - - /* not actually recording, but we want to hear the input material anyway, - at least potentially (depending on monitoring options) - */ - - passthru (start_frame, end_frame, nframes, offset, 0, true); - - } else { - /* - XXX is it true that the earlier test on n_outputs() - means that we can avoid checking it again here? i think - so, because changing the i/o configuration of an IO - requires holding the AudioEngine lock, which we hold - while in the process() tree. - */ - - - /* copy the diskstream data to all output buffers */ - - //const size_t limit = n_process_buffers().n_audio(); - BufferSet& bufs = _session.get_scratch_buffers (n_process_buffers()); - - diskstream->get_playback(bufs.get_midi(0), start_frame, end_frame); - - process_output_buffers (bufs, start_frame, end_frame, nframes, offset, - (!_session.get_record_enabled() || !Config->get_do_not_record_plugins()), declick, (_meter_point != MeterInput)); - - } - - return 0; -} - -int -MidiTrack::silent_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, nframes_t offset, - bool can_record, bool rec_monitors_input) -{ - if (n_outputs().n_midi() == 0 && _processors.empty()) { - return 0; - } - - if (!_active) { - silence (nframes, offset); - return 0; - } - - _silent = true; - apply_gain_automation = false; - - silence (nframes, offset); - - return midi_diskstream()->process (_session.transport_frame() + offset, nframes, offset, can_record, rec_monitors_input); -} - -void -MidiTrack::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) -{ - /* There's no such thing as a MIDI bus for the time being. - * We'll do all the MIDI route work here for now, but the long-term goal is to have - * Route::process_output_buffers handle everything */ - - if (meter && (_meter_point == MeterInput || _meter_point == MeterPreFader)) { - _meter->run_in_place(bufs, start_frame, end_frame, nframes, offset); - } - - // Run all processors - if (with_processors) { - Glib::RWLock::ReaderLock rm (_processor_lock, Glib::TRY_LOCK); - if (rm.locked()) { - for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { - (*i)->run_in_place (bufs, start_frame, end_frame, nframes, offset); - } - } - } - - if (meter && (_meter_point == MeterPostFader)) { - _meter->run_in_place(bufs, start_frame, end_frame, nframes, offset); - } - - // Main output stage - if (muted()) { - IO::silence(nframes, offset); - } else { - - // Write 'automation' controllers (e.g. CC events from a UI slider) - write_controller_messages(bufs.get_midi(0), start_frame, end_frame, nframes, offset); - - deliver_output(bufs, start_frame, end_frame, nframes, offset); - } -} - -void -MidiTrack::write_controller_messages(MidiBuffer& output_buf, nframes_t start_frame, nframes_t end_frame, - nframes_t nframes, nframes_t offset) -{ -#if 0 - BufferSet& mix_buffers = _session.get_mix_buffers(ChanCount(DataType::MIDI, 2)); - - /* FIXME: this could be more realtimey */ - - // Write immediate events (UI controls) - MidiBuffer& cc_buf = mix_buffers.get_midi(0); - cc_buf.silence(nframes, offset); - - uint8_t buf[3]; // CC = 3 bytes - buf[0] = MIDI_CMD_CONTROL; - MIDI::Event ev(0, 3, buf, false); - - // Write track controller automation - // This now lives in MidiModel. Any need for track automation like this? - // Relative Velocity? - if (_session.transport_rolling()) { - for (Controls::const_iterator i = _controls.begin(); i != _controls.end(); ++i) { - const boost::shared_ptr<AutomationList> list = (*i).second->list(); - - if ( (!list->automation_playback()) - || (list->parameter().type() != MidiCCAutomation)) - continue; - - double start = start_frame; - double x, y; - while ((*i).second->list()->rt_safe_earliest_event(start, end_frame, x, y)) { - assert(x >= start_frame); - assert(x <= end_frame); - - const nframes_t stamp = (nframes_t)floor(x - start_frame); - assert(stamp < nframes); - - assert(y >= 0.0); - assert(y <= 127.0); - - ev.time() = stamp; - ev.buffer()[1] = (uint8_t)list->parameter().id(); - ev.buffer()[2] = (uint8_t)y; - - cc_buf.push_back(ev); - - start = x + 1; // FIXME? maybe? - } - } - } - - /* FIXME: too much copying! */ - - // Merge cc buf into output - if (cc_buf.size() > 0) { - - // Both CC and route, must merge - if (output_buf.size() > 0) { - - MidiBuffer& mix_buf = mix_buffers.get_midi(1); - mix_buf.merge(output_buf, cc_buf); - output_buf.copy(mix_buf); - - } else { - output_buf.copy(cc_buf); - } - } -#endif - - // Append immediate events (UI controls) - _immediate_events.read(output_buf, 0, 0, offset + nframes-1); // all stamps = 0 -} - -int -MidiTrack::export_stuff (BufferSet& bufs, nframes_t nframes, nframes_t end_frame) -{ - return -1; -} - -void -MidiTrack::set_latency_delay (nframes_t longest_session_latency) -{ - Route::set_latency_delay (longest_session_latency); - _diskstream->set_roll_delay (_roll_delay); -} - -void -MidiTrack::bounce (InterThreadInfo& itt) -{ - throw; - //vector<MidiSource*> srcs; - //_session.write_one_midi_track (*this, 0, _session.current_end_frame(), false, srcs, itt); -} - - -void -MidiTrack::bounce_range (nframes_t start, nframes_t end, InterThreadInfo& itt) -{ - throw; - //vector<MidiSource*> srcs; - //_session.write_one_midi_track (*this, start, end, false, srcs, itt); -} - -void -MidiTrack::freeze (InterThreadInfo& itt) -{ -} - -void -MidiTrack::unfreeze () -{ - _freeze_record.state = UnFrozen; - FreezeChange (); /* EMIT SIGNAL */ -} - -void -MidiTrack::set_note_mode (NoteMode m) -{ - cout << _name << " SET NOTE MODE " << m << endl; - _note_mode = m; - midi_diskstream()->set_note_mode(m); -} - -void -MidiTrack::midi_panic() -{ - for (uint8_t channel = 0; channel <= 0xF; channel++) { - uint8_t ev[3] = { MIDI_CMD_CONTROL | channel, MIDI_CTL_SUSTAIN, 0 }; - write_immediate_event(3, ev); - ev[1] = MIDI_CTL_ALL_NOTES_OFF; - write_immediate_event(3, ev); - ev[1] = MIDI_CTL_RESET_CONTROLLERS; - write_immediate_event(3, ev); - } -} - -/** \return true on success, false on failure (no buffer space left) - */ -bool -MidiTrack::write_immediate_event(size_t size, const uint8_t* buf) -{ - printf("Write immediate event: "); - for (size_t i=0; i < size; ++i) { - printf("%X ", buf[i]); - } - printf("\n"); - return (_immediate_events.write(0, size, buf) == size); -} - -void -MidiTrack::MidiControl::set_value(float val) -{ - assert(val >= _list->parameter().min()); - assert(val <= _list->parameter().max()); - size_t size = 3; - - if ( ! _list->automation_playback()) { - uint8_t ev[3] = { _list->parameter().channel(), int(val), 0.0 }; - switch(_list->parameter().type()) { - case MidiCCAutomation: - ev[0] += MIDI_CMD_CONTROL; - ev[1] = _list->parameter().id(); - ev[2] = int(val); - break; - - case MidiPgmChangeAutomation: - size = 2; - ev[0] += MIDI_CMD_PGM_CHANGE; - ev[1] = int(val); - break; - - case MidiChannelAftertouchAutomation: - size = 2; - ev[0] += MIDI_CMD_CHANNEL_PRESSURE; - ev[1] = int(val); - break; - - case MidiPitchBenderAutomation: - ev[0] += MIDI_CMD_BENDER; - ev[1] = 0x7F & int(val); - ev[2] = 0x7F & (int(val) >> 7); - break; - - default: - assert(false); - } - _route->write_immediate_event(size, ev); - } - - AutomationControl::set_value(val); -} - diff --git a/libs/ardour/mix.cc b/libs/ardour/mix.cc deleted file mode 100644 index 726d375453..0000000000 --- a/libs/ardour/mix.cc +++ /dev/null @@ -1,176 +0,0 @@ -/* - Copyright (C) 2000-2005 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include <cmath> -#include <ardour/types.h> -#include <ardour/utils.h> -#include <ardour/mix.h> -#include <stdint.h> - -using namespace ARDOUR; - -#if defined (ARCH_X86) && defined (BUILD_SSE_OPTIMIZATIONS) -// Debug wrappers - -float -debug_compute_peak (ARDOUR::Sample *buf, nframes_t nsamples, float current) -{ - if ( ((intptr_t)buf % 16) != 0) { - cerr << "compute_peak(): buffer unaligned!" << endl; - } - - return x86_sse_compute_peak(buf, nsamples, current); -} - -void -debug_apply_gain_to_buffer (ARDOUR::Sample *buf, nframes_t nframes, float gain) -{ - if ( ((intptr_t)buf % 16) != 0) { - cerr << "apply_gain_to_buffer(): buffer unaligned!" << endl; - } - - x86_sse_apply_gain_to_buffer(buf, nframes, gain); -} - -void -debug_mix_buffers_with_gain (ARDOUR::Sample *dst, ARDOUR::Sample *src, nframes_t nframes, float gain) -{ - if ( ((intptr_t)dst & 15) != 0) { - cerr << "mix_buffers_with_gain(): dst unaligned!" << endl; - } - - if ( ((intptr_t)dst & 15) != ((intptr_t)src & 15) ) { - cerr << "mix_buffers_with_gain(): dst & src don't have the same alignment!" << endl; - mix_buffers_with_gain(dst, src, nframes, gain); - } else { - x86_sse_mix_buffers_with_gain(dst, src, nframes, gain); - } -} - -void -debug_mix_buffers_no_gain (ARDOUR::Sample *dst, ARDOUR::Sample *src, nframes_t nframes) -{ - if ( ((intptr_t)dst & 15) != 0) { - cerr << "mix_buffers_no_gain(): dst unaligned!" << endl; - } - - if ( ((intptr_t)dst & 15) != ((intptr_t)src & 15) ) { - cerr << "mix_buffers_no_gain(): dst & src don't have the same alignment!" << endl; - mix_buffers_no_gain(dst, src, nframes); - } else { - x86_sse_mix_buffers_no_gain(dst, src, nframes); - } -} - -#endif - - -float -default_compute_peak (const ARDOUR::Sample * buf, nframes_t nsamples, float current) -{ - for (nframes_t i = 0; i < nsamples; ++i) { - current = f_max (current, fabsf (buf[i])); - } - - return current; -} - -void -default_find_peaks (const ARDOUR::Sample * buf, nframes_t nframes, float *min, float *max) -{ - nframes_t i; - float a, b; - - a = *max; - b = *min; - - for (i = 0; i < nframes; i++) - { - a = fmax (buf[i], a); - b = fmin (buf[i], b); - } - - *max = a; - *min = b; -} - -void -default_apply_gain_to_buffer (ARDOUR::Sample * buf, nframes_t nframes, float gain) -{ - for (nframes_t i=0; i<nframes; i++) - buf[i] *= gain; -} - -void -default_mix_buffers_with_gain (ARDOUR::Sample * dst, const ARDOUR::Sample * src, nframes_t nframes, float gain) -{ - for (nframes_t i = 0; i < nframes; i++) { - dst[i] += src[i] * gain; - } -} - -void -default_mix_buffers_no_gain (ARDOUR::Sample * dst, const ARDOUR::Sample * src, nframes_t nframes) -{ - for (nframes_t i=0; i < nframes; i++) { - dst[i] += src[i]; - } -} - -#if defined (__APPLE__) && defined (BUILD_VECLIB_OPTIMIZATIONS) -#include <Accelerate/Accelerate.h> - -float -veclib_compute_peak (const ARDOUR::Sample * buf, nframes_t nsamples, float current) -{ - float tmpmax = 0.0f; - vDSP_maxmgv(buf, 1, &tmpmax, nsamples); - return f_max(current, tmpmax); -} - -void -veclib_find_peaks (const ARDOUR::Sample * buf, nframes_t nframes, float *min, float *max) -{ - vDSP_maxv (const_cast<ARDOUR::Sample*>(buf), 1, max, nframes); - vDSP_minv (const_cast<ARDOUR::Sample*>(buf), 1, min, nframes); -} - -void -veclib_apply_gain_to_buffer (ARDOUR::Sample * buf, nframes_t nframes, float gain) -{ - vDSP_vsmul(buf, 1, &gain, buf, 1, nframes); -} - -void -veclib_mix_buffers_with_gain (ARDOUR::Sample * dst, const ARDOUR::Sample * src, nframes_t nframes, float gain) -{ - vDSP_vsma(src, 1, &gain, dst, 1, dst, 1, nframes); -} - -void -veclib_mix_buffers_no_gain (ARDOUR::Sample * dst, const ARDOUR::Sample * src, nframes_t nframes) -{ - // It seems that a vector mult only operation does not exist... - float gain = 1.0f; - vDSP_vsma(src, 1, &gain, dst, 1, dst, 1, nframes); -} - -#endif - - diff --git a/libs/ardour/mtc_slave.cc b/libs/ardour/mtc_slave.cc deleted file mode 100644 index 0a0fbc1529..0000000000 --- a/libs/ardour/mtc_slave.cc +++ /dev/null @@ -1,357 +0,0 @@ -/* - Copyright (C) 2002-4 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include <errno.h> -#include <poll.h> -#include <sys/types.h> -#include <unistd.h> -#include <pbd/error.h> -#include <pbd/failed_constructor.h> -#include <pbd/pthread_utils.h> - -#include <midi++/port.h> -#include <ardour/slave.h> -#include <ardour/session.h> -#include <ardour/audioengine.h> -#include <ardour/cycles.h> - -#include "i18n.h" - -using namespace ARDOUR; -using namespace sigc; -using namespace MIDI; -using namespace PBD; - -MTC_Slave::MTC_Slave (Session& s, MIDI::Port& p) - : session (s) -{ - can_notify_on_unknown_rate = true; - - rebind (p); - reset (); -} - -MTC_Slave::~MTC_Slave() -{ -} - -void -MTC_Slave::rebind (MIDI::Port& p) -{ - for (vector<sigc::connection>::iterator i = connections.begin(); i != connections.end(); ++i) { - (*i).disconnect (); - } - - port = &p; - - connections.push_back (port->input()->mtc_time.connect (mem_fun (*this, &MTC_Slave::update_mtc_time))); - connections.push_back (port->input()->mtc_qtr.connect (mem_fun (*this, &MTC_Slave::update_mtc_qtr))); - connections.push_back (port->input()->mtc_status.connect (mem_fun (*this, &MTC_Slave::update_mtc_status))); -} - -void -MTC_Slave::update_mtc_qtr (Parser& p) -{ - cycles_t cnow = get_cycles (); - nframes_t now = session.engine().frame_time(); - nframes_t qtr; - static cycles_t last_qtr = 0; - - qtr = (long) (session.frames_per_smpte_frame() / 4); - mtc_frame += qtr; - last_qtr = cnow; - - current.guard1++; - current.position = mtc_frame; - current.timestamp = now; - current.guard2++; - - last_inbound_frame = now; -} - -void -MTC_Slave::update_mtc_time (const byte *msg, bool was_full) -{ - nframes_t now = session.engine().frame_time(); - SMPTE::Time smpte; - - smpte.hours = msg[3]; - smpte.minutes = msg[2]; - smpte.seconds = msg[1]; - smpte.frames = msg[0]; - - switch (msg[4]) { - case MTC_24_FPS: - smpte.rate = 24; - smpte.drop = false; - can_notify_on_unknown_rate = true; - break; - case MTC_25_FPS: - smpte.rate = 25; - smpte.drop = false; - can_notify_on_unknown_rate = true; - break; - case MTC_30_FPS_DROP: - smpte.rate = 30; - smpte.drop = true; - can_notify_on_unknown_rate = true; - break; - case MTC_30_FPS: - smpte.rate = 30; - smpte.drop = false; - can_notify_on_unknown_rate = true; - break; - default: - /* throttle error messages about unknown MTC rates */ - if (can_notify_on_unknown_rate) { - error << _("Unknown rate/drop value in incoming MTC stream, session values used instead") << endmsg; - can_notify_on_unknown_rate = false; - } - smpte.rate = session.smpte_frames_per_second(); - smpte.drop = session.smpte_drop_frames(); - } - - session.smpte_to_sample (smpte, mtc_frame, true, false); - - if (was_full) { - - current.guard1++; - current.position = mtc_frame; - current.timestamp = 0; - current.guard2++; - - session.request_locate (mtc_frame, false); - session.request_transport_speed (0); - update_mtc_status (MIDI::Parser::MTC_Stopped); - - reset (); - - } else { - - /* We received the last quarter frame 7 quarter frames (1.75 mtc - frames) after the instance when the contents of the mtc quarter - frames were decided. Add time to compensate for the elapsed 1.75 - frames. - Also compensate for audio latency. - */ - - mtc_frame += (long) (1.75 * session.frames_per_smpte_frame()) + session.worst_output_latency(); - - if (first_mtc_frame == 0) { - first_mtc_frame = mtc_frame; - first_mtc_time = now; - } - - current.guard1++; - current.position = mtc_frame; - current.timestamp = now; - current.guard2++; - } - - last_inbound_frame = now; -} - -void -MTC_Slave::handle_locate (const MIDI::byte* mmc_tc) -{ - MIDI::byte mtc[4]; - - mtc[3] = mmc_tc[0] & 0xf; /* hrs only */ - mtc[2] = mmc_tc[1]; - mtc[1] = mmc_tc[2]; - mtc[0] = mmc_tc[3]; - - update_mtc_time (mtc, true); -} - -void -MTC_Slave::update_mtc_status (MIDI::Parser::MTC_Status status) -{ - - switch (status) { - case MTC_Stopped: - mtc_speed = 0.0f; - mtc_frame = 0; - - current.guard1++; - current.position = mtc_frame; - current.timestamp = 0; - current.guard2++; - - break; - - case MTC_Forward: - mtc_speed = 0.0f; - mtc_frame = 0; - - current.guard1++; - current.position = mtc_frame; - current.timestamp = 0; - current.guard2++; - - break; - - case MTC_Backward: - mtc_speed = 0.0f; - mtc_frame = 0; - - current.guard1++; - current.position = mtc_frame; - current.timestamp = 0; - current.guard2++; - - break; - } -} - -void -MTC_Slave::read_current (SafeTime *st) const -{ - int tries = 0; - do { - if (tries == 10) { - error << _("MTC Slave: atomic read of current time failed, sleeping!") << endmsg; - usleep (20); - tries = 0; - } - - *st = current; - tries++; - - } while (st->guard1 != st->guard2); -} - -bool -MTC_Slave::locked () const -{ - return port->input()->mtc_locked(); -} - -bool -MTC_Slave::ok() const -{ - return true; -} - -bool -MTC_Slave::speed_and_position (float& speed, nframes_t& pos) -{ - nframes_t now = session.engine().frame_time(); - SafeTime last; - nframes_t frame_rate; - nframes_t elapsed; - float speed_now; - - read_current (&last); - - if (first_mtc_time == 0) { - speed = 0; - pos = last.position; - return true; - } - - /* no timecode for 1/4 second ? conclude that its stopped */ - - if (last_inbound_frame && now > last_inbound_frame && now - last_inbound_frame > session.frame_rate() / 4) { - mtc_speed = 0; - pos = last.position; - session.request_locate (pos, false); - session.request_transport_speed (0); - update_mtc_status (MIDI::Parser::MTC_Stopped); - reset(); - return false; - } - - frame_rate = session.frame_rate(); - - speed_now = (float) ((last.position - first_mtc_frame) / (double) (now - first_mtc_time)); - - accumulator[accumulator_index++] = speed_now; - - if (accumulator_index >= accumulator_size) { - have_first_accumulated_speed = true; - accumulator_index = 0; - } - - if (have_first_accumulated_speed) { - float total = 0; - - for (int32_t i = 0; i < accumulator_size; ++i) { - total += accumulator[i]; - } - - mtc_speed = total / accumulator_size; - - } else { - - mtc_speed = speed_now; - - } - - if (mtc_speed == 0.0f) { - - elapsed = 0; - - } else { - - /* scale elapsed time by the current MTC speed */ - - if (last.timestamp && (now > last.timestamp)) { - elapsed = (nframes_t) floor (mtc_speed * (now - last.timestamp)); - } else { - elapsed = 0; /* XXX is this right? */ - } - } - - /* now add the most recent timecode value plus the estimated elapsed interval */ - - pos = elapsed + last.position; - - speed = mtc_speed; - return true; -} - -ARDOUR::nframes_t -MTC_Slave::resolution() const -{ - return (nframes_t) session.frames_per_smpte_frame(); -} - -void -MTC_Slave::reset () -{ - /* XXX massive thread safety issue here. MTC could - be being updated as we call this. but this - supposed to be a realtime-safe call. - */ - - port->input()->reset_mtc_state (); - - last_inbound_frame = 0; - current.guard1++; - current.position = 0; - current.timestamp = 0; - current.guard2++; - first_mtc_frame = 0; - first_mtc_time = 0; - - accumulator_index = 0; - have_first_accumulated_speed = false; - mtc_speed = 0; -} diff --git a/libs/ardour/named_selection.cc b/libs/ardour/named_selection.cc deleted file mode 100644 index fbb4b748df..0000000000 --- a/libs/ardour/named_selection.cc +++ /dev/null @@ -1,130 +0,0 @@ -/* - 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. - -*/ - -#include <pbd/failed_constructor.h> -#include <pbd/error.h> - -#include <ardour/session.h> -#include <ardour/utils.h> -#include <ardour/playlist.h> -#include <ardour/named_selection.h> - -#include "i18n.h" - -using namespace ARDOUR; -using namespace PBD; - -sigc::signal<void,NamedSelection*> NamedSelection::NamedSelectionCreated; - -typedef std::list<boost::shared_ptr<Playlist> > PlaylistList; - -NamedSelection::NamedSelection (string n, PlaylistList& l) - : name (n) -{ - playlists = l; - for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) { - string new_name; - - /* rename playlists to reflect our ownership */ - - new_name = name; - new_name += '/'; - new_name += (*i)->name(); - - (*i)->set_name (new_name); - (*i)->use(); - } - - NamedSelectionCreated (this); -} - -NamedSelection::NamedSelection (Session& session, const XMLNode& node) -{ - XMLNode* lists_node; - const XMLProperty* property; - - if ((property = node.property ("name")) == 0) { - throw failed_constructor(); - } - - name = property->value(); - - if ((lists_node = find_named_node (node, "Playlists")) == 0) { - return; - } - - XMLNodeList nlist = lists_node->children(); - XMLNodeConstIterator niter; - - for (niter = nlist.begin(); niter != nlist.end(); ++niter) { - - const XMLNode* plnode; - string playlist_name; - boost::shared_ptr<Playlist> playlist; - - plnode = *niter; - - if ((property = plnode->property ("name")) != 0) { - if ((playlist = session.playlist_by_name (property->value())) != 0) { - playlist->use(); - playlists.push_back (playlist); - } else { - warning << string_compose (_("Chunk %1 uses an unknown playlist \"%2\""), name, property->value()) << endmsg; - } - } else { - error << string_compose (_("Chunk %1 contains misformed playlist information"), name) << endmsg; - throw failed_constructor(); - } - } - - NamedSelectionCreated (this); -} - -NamedSelection::~NamedSelection () -{ - for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) { - (*i)->release (); - (*i)->GoingAway (); - } -} - -int -NamedSelection::set_state (const XMLNode& node) -{ - return 0; -} - -XMLNode& -NamedSelection::get_state () -{ - XMLNode* root = new XMLNode ("NamedSelection"); - XMLNode* child; - - root->add_property ("name", name); - child = root->add_child ("Playlists"); - - for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) { - XMLNode* plnode = new XMLNode ("Playlist"); - - plnode->add_property ("name", (*i)->name()); - child->add_child_nocopy (*plnode); - } - - return *root; -} diff --git a/libs/ardour/note.cc b/libs/ardour/note.cc deleted file mode 100644 index ea1e7133af..0000000000 --- a/libs/ardour/note.cc +++ /dev/null @@ -1,110 +0,0 @@ -/* - 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. - -*/ - -#include <ardour/note.h> -#include <iostream> - -namespace ARDOUR { - -Note::Note(uint8_t chan, double t, double d, uint8_t n, uint8_t v) - : _on_event(t, 3, NULL, true) - , _off_event(t + d, 3, NULL, true) -{ - assert(chan < 16); - - _on_event.buffer()[0] = MIDI_CMD_NOTE_ON + chan; - _on_event.buffer()[1] = n; - _on_event.buffer()[2] = v; - - _off_event.buffer()[0] = MIDI_CMD_NOTE_OFF + chan; - _off_event.buffer()[1] = n; - _off_event.buffer()[2] = 0x40; - - assert(time() == t); - assert(duration() == d); - assert(note() == n); - assert(velocity() == v); - assert(_on_event.channel() == _off_event.channel()); - assert(channel() == chan); -} - - -Note::Note(const Note& copy) - : _on_event(copy._on_event, true) - , _off_event(copy._off_event, true) -{ - assert(_on_event.buffer()); - assert(_off_event.buffer()); - /* - assert(copy._on_event.size == 3); - _on_event.buffer = _on_event_buffer; - memcpy(_on_event_buffer, copy._on_event_buffer, 3); - - assert(copy._off_event.size == 3); - _off_event.buffer = _off_event_buffer; - memcpy(_off_event_buffer, copy._off_event_buffer, 3); - */ - - assert(time() == copy.time()); - assert(end_time() == copy.end_time()); - assert(note() == copy.note()); - assert(velocity() == copy.velocity()); - assert(duration() == copy.duration()); - assert(_on_event.channel() == _off_event.channel()); - assert(channel() == copy.channel()); -} - -Note::~Note() -{ - std::cerr << "Note::~Note() Note time: " << time() - << " pitch: " << int(note()) - << " duration: " << duration() - << " end-time: " << end_time() - << " velocity: " << int(velocity()) - << std::endl; -} - - -const Note& -Note::operator=(const Note& copy) -{ - _on_event = copy._on_event; - _off_event = copy._off_event; - /*_on_event.time = copy._on_event.time; - assert(copy._on_event.size == 3); - memcpy(_on_event_buffer, copy._on_event_buffer, 3); - - _off_event.time = copy._off_event.time; - assert(copy._off_event.size == 3); - memcpy(_off_event_buffer, copy._off_event_buffer, 3); - */ - - assert(time() == copy.time()); - assert(end_time() == copy.end_time()); - assert(note() == copy.note()); - assert(velocity() == copy.velocity()); - assert(duration() == copy.duration()); - assert(_on_event.channel() == _off_event.channel()); - assert(channel() == copy.channel()); - - return *this; -} - -} // namespace ARDOUR diff --git a/libs/ardour/osc.cc b/libs/ardour/osc.cc deleted file mode 100644 index b0bd35b8c6..0000000000 --- a/libs/ardour/osc.cc +++ /dev/null @@ -1,480 +0,0 @@ -/* - * 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. - * - */ - -#include <iostream> -#include <fstream> -#include <cstdio> -#include <cstdlib> -#include <cerrno> -#include <algorithm> - -#include <sys/poll.h> -#include <unistd.h> -#include <fcntl.h> - -#include <pbd/pthread_utils.h> -#include <pbd/file_utils.h> - -#include <ardour/osc.h> -#include <ardour/session.h> -#include <ardour/route.h> -#include <ardour/audio_track.h> -#include <ardour/filesystem_paths.h> - -#include "i18n.h" - -using namespace ARDOUR; -using namespace sigc; -using namespace std; - -static void error_callback(int num, const char *m, const char *path) -{ -#ifdef DEBUG - fprintf(stderr, "liblo server error %d in path %s: %s\n", num, path, m); -#endif -} - -OSC::OSC (uint32_t port) - : _port(port) -{ - _shutdown = false; - _osc_server = 0; - _osc_unix_server = 0; - _osc_thread = 0; -} - -int -OSC::start () -{ - char tmpstr[255]; - - if (_osc_server) { - /* already started */ - return 0; - } - - for (int j=0; j < 20; ++j) { - snprintf(tmpstr, sizeof(tmpstr), "%d", _port); - - if ((_osc_server = lo_server_new (tmpstr, error_callback))) { - break; - } -#ifdef DEBUG - cerr << "can't get osc at port: " << _port << endl; -#endif - _port++; - continue; - } - -#ifdef ARDOUR_OSC_UNIX_SERVER - - // APPEARS sluggish for now - - // attempt to create unix socket server too - - snprintf(tmpstr, sizeof(tmpstr), "/tmp/sooperlooper_XXXXXX"); - int fd = mkstemp(tmpstr); - - if (fd >= 0 ) { - unlink (tmpstr); - close (fd); - - _osc_unix_server = lo_server_new (tmpstr, error_callback); - - if (_osc_unix_server) { - _osc_unix_socket_path = tmpstr; - } - } -#endif - - cerr << "OSC @ " << get_server_url () << endl; - - sys::path url_file; - - if (find_file_in_search_path (ardour_search_path() + system_config_search_path(), - "osc_url", url_file)) { - _osc_url_file = url_file.to_string(); - ofstream urlfile; - urlfile.open(_osc_url_file.c_str(), ios::trunc); - if ( urlfile ) - { - urlfile << get_server_url () << endl; - urlfile.close(); - } - else - { - cerr << "Couldn't write '" << _osc_url_file << "'" <<endl; - } - } - - register_callbacks(); - - // lo_server_thread_add_method(_sthread, NULL, NULL, OSC::_dummy_handler, this); - - if (!init_osc_thread()) { - return -1; - } - return 0; -} - -int -OSC::stop () -{ - if (_osc_server == 0) { - /* already stopped */ - return 0; - } - - // stop server thread - terminate_osc_thread(); - - lo_server_free (_osc_server); - _osc_server = 0; - - if (!_osc_unix_socket_path.empty()) { - // unlink it - unlink(_osc_unix_socket_path.c_str()); - } - - if (! _osc_url_file.empty() ) { - unlink(_osc_url_file.c_str() ); - } - return 0; -} - -OSC::~OSC() -{ - stop (); -} - -void -OSC::register_callbacks() -{ - lo_server srvs[2]; - lo_server serv; - - srvs[0] = _osc_server; - srvs[1] = _osc_unix_server; - - for (size_t i = 0; i < 2; ++i) { - - if (!srvs[i]) { - continue; - } - - serv = srvs[i]; - -#define REGISTER_CALLBACK(serv,path,types, function) lo_server_add_method (serv, path, types, OSC::_ ## function, this) - - REGISTER_CALLBACK (serv, "/ardour/add_marker", "", add_marker); - REGISTER_CALLBACK (serv, "/ardour/loop_toggle", "", loop_toggle); - REGISTER_CALLBACK (serv, "/ardour/goto_start", "", goto_start); - REGISTER_CALLBACK (serv, "/ardour/goto_end", "", goto_end); - REGISTER_CALLBACK (serv, "/ardour/rewind", "", rewind); - REGISTER_CALLBACK (serv, "/ardour/ffwd", "", ffwd); - REGISTER_CALLBACK (serv, "/ardour/transport_stop", "", transport_stop); - REGISTER_CALLBACK (serv, "/ardour/transport_play", "", transport_play); - REGISTER_CALLBACK (serv, "/ardour/set_transport_speed", "f", set_transport_speed); - REGISTER_CALLBACK (serv, "/ardour/save_state", "", save_state); - REGISTER_CALLBACK (serv, "/ardour/prev_marker", "", prev_marker); - REGISTER_CALLBACK (serv, "/ardour/next_marker", "", next_marker); - REGISTER_CALLBACK (serv, "/ardour/undo", "", undo); - REGISTER_CALLBACK (serv, "/ardour/redo", "", redo); - REGISTER_CALLBACK (serv, "/ardour/toggle_punch_in", "", toggle_punch_in); - REGISTER_CALLBACK (serv, "/ardour/toggle_punch_out", "", toggle_punch_out); - REGISTER_CALLBACK (serv, "/ardour/rec_enable_toggle", "", rec_enable_toggle); - REGISTER_CALLBACK (serv, "/ardour/toggle_all_rec_enables", "", toggle_all_rec_enables); - -#if 0 - REGISTER_CALLBACK (serv, "/ardour/*/#current_value", "", current_value); - REGISTER_CALLBACK (serv, "/ardour/set", "", set); -#endif - -#if 0 - // un/register_update args= s:ctrl s:returl s:retpath - lo_server_add_method(serv, "/register_update", "sss", OSC::global_register_update_handler, this); - lo_server_add_method(serv, "/unregister_update", "sss", OSC::global_unregister_update_handler, this); - lo_server_add_method(serv, "/register_auto_update", "siss", OSC::global_register_auto_update_handler, this); - lo_server_add_method(serv, "/unregister_auto_update", "sss", OSC::_global_unregister_auto_update_handler, this); -#endif - } -} - -bool -OSC::init_osc_thread () -{ - // create new thread to run server - if (pipe (_request_pipe)) { - cerr << "Cannot create osc request signal pipe" << strerror (errno) << endl; - return false; - } - - if (fcntl (_request_pipe[0], F_SETFL, O_NONBLOCK)) { - cerr << "osc: cannot set O_NONBLOCK on signal read pipe " << strerror (errno) << endl; - return false; - } - - if (fcntl (_request_pipe[1], F_SETFL, O_NONBLOCK)) { - cerr << "osc: cannot set O_NONBLOCK on signal write pipe " << strerror (errno) << endl; - return false; - } - - pthread_attr_t attr; - pthread_attr_init(&attr); - pthread_attr_setstacksize(&attr, 500000); - - pthread_create (&_osc_thread, &attr, &OSC::_osc_receiver, this); - if (!_osc_thread) { - return false; - } - pthread_attr_destroy(&attr); - - //pthread_detach (_osc_thread); - return true; -} - -void -OSC::terminate_osc_thread () -{ - void* status; - - _shutdown = true; - - poke_osc_thread (); - - pthread_join (_osc_thread, &status); -} - -void -OSC::poke_osc_thread () -{ - char c; - - if (write (_request_pipe[1], &c, 1) != 1) { - cerr << "cannot send signal to osc thread! " << strerror (errno) << endl; - } -} - -std::string -OSC::get_server_url() -{ - string url; - char * urlstr; - - if (_osc_server) { - urlstr = lo_server_get_url (_osc_server); - url = urlstr; - free (urlstr); - } - - return url; -} - -std::string -OSC::get_unix_server_url() -{ - string url; - char * urlstr; - - if (_osc_unix_server) { - urlstr = lo_server_get_url (_osc_unix_server); - url = urlstr; - free (urlstr); - } - - return url; -} - - -/* server thread */ - -void * -OSC::_osc_receiver(void * arg) -{ - PBD::ThreadCreated (pthread_self(), X_("OSC")); - - static_cast<OSC*> (arg)->osc_receiver(); - return 0; -} - -void -OSC::osc_receiver() -{ - struct pollfd pfd[3]; - int fds[3]; - lo_server srvs[3]; - int nfds = 0; - int timeout = -1; - int ret; - - fds[0] = _request_pipe[0]; - nfds++; - - if (_osc_server && lo_server_get_socket_fd(_osc_server) >= 0) { - fds[nfds] = lo_server_get_socket_fd(_osc_server); - srvs[nfds] = _osc_server; - nfds++; - } - - if (_osc_unix_server && lo_server_get_socket_fd(_osc_unix_server) >= 0) { - fds[nfds] = lo_server_get_socket_fd(_osc_unix_server); - srvs[nfds] = _osc_unix_server; - nfds++; - } - - - while (!_shutdown) { - - for (int i=0; i < nfds; ++i) { - pfd[i].fd = fds[i]; - pfd[i].events = POLLIN|POLLPRI|POLLHUP|POLLERR; - pfd[i].revents = 0; - } - - again: - //cerr << "poll on " << nfds << " for " << timeout << endl; - if ((ret = poll (pfd, nfds, timeout)) < 0) { - if (errno == EINTR) { - /* gdb at work, perhaps */ - goto again; - } - - cerr << "OSC thread poll failed: " << strerror (errno) << endl; - - break; - } - - //cerr << "poll returned " << ret << " pfd[0].revents = " << pfd[0].revents << " pfd[1].revents = " << pfd[1].revents << endl; - - if (_shutdown) { - break; - } - - if ((pfd[0].revents & ~POLLIN)) { - cerr << "OSC: error polling extra port" << endl; - break; - } - - for (int i=1; i < nfds; ++i) { - if (pfd[i].revents & POLLIN) - { - // this invokes callbacks - //cerr << "invoking recv on " << pfd[i].fd << endl; - lo_server_recv(srvs[i]); - } - } - - } - - //cerr << "SL engine shutdown" << endl; - - if (_osc_server) { - int fd = lo_server_get_socket_fd(_osc_server); - if (fd >=0) { - // hack around - close(fd); - } - lo_server_free (_osc_server); - _osc_server = 0; - } - - if (_osc_unix_server) { - cerr << "freeing unix server" << endl; - lo_server_free (_osc_unix_server); - _osc_unix_server = 0; - } - - close(_request_pipe[0]); - close(_request_pipe[1]); -} - -void -OSC::set_session (Session& s) -{ - session = &s; - session->GoingAway.connect (mem_fun (*this, &OSC::session_going_away)); -} - -void -OSC::session_going_away () -{ - session = 0; -} - -/* path callbacks */ - -int -OSC::current_value (const char *path, const char *types, lo_arg **argv, int argc, void *data, void* user_data) -{ -#if 0 - const char* returl; - - if (argc < 3 || types == 0 || strlen (types) < 3 || types[0] != 's' || types[1] != 's' || types[2] != s) { - return 1; - } - - const char *returl = argv[1]->s; - lo_address addr = find_or_cache_addr (returl); - - const char *retpath = argv[2]->s; - - - if (strcmp (argv[0]->s, "transport_frame")) { - - if (session) { - lo_send (addr, retpath, "i", session->transport_frame()); - } - - } else if (strcmp (argv[0]->s, "transport_speed")) { - - if (session) { - lo_send (addr, retpath, "i", session->transport_frame()); - } - - } else if (strcmp (argv[0]->s, "transport_locked")) { - - if (session) { - lo_send (addr, retpath, "i", session->transport_frame()); - } - - } else if (strcmp (argv[0]->s, "punch_in") { - - if (session) { - lo_send (addr, retpath, "i", session->transport_frame()); - } - - } else if (strcmp (argv[0]->s, "punch_out") { - - if (session) { - lo_send (addr, retpath, "i", session->transport_frame()); - } - - } else if (strcmp (argv[0]->s, "rec_enable") { - - if (session) { - lo_send (addr, retpath, "i", session->transport_frame()); - } - - } else { - - /* error */ - } -#endif - return 0; -} diff --git a/libs/ardour/panner.cc b/libs/ardour/panner.cc deleted file mode 100644 index ac8e4d05e3..0000000000 --- a/libs/ardour/panner.cc +++ /dev/null @@ -1,1489 +0,0 @@ -/* - 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. - -*/ - -#define __STDC_FORMAT_MACROS 1 -#include <inttypes.h> - -#include <cmath> -#include <cerrno> -#include <fstream> -#include <cstdlib> -#include <string> -#include <cstdio> -#include <locale.h> -#include <unistd.h> -#include <float.h> - -#include <glibmm.h> - -#include <pbd/error.h> -#include <pbd/failed_constructor.h> -#include <pbd/xml++.h> -#include <pbd/enumwriter.h> - -#include <ardour/session.h> -#include <ardour/panner.h> -#include <ardour/utils.h> - -#include <ardour/runtime_functions.h> -#include <ardour/buffer_set.h> - -#include "i18n.h" - -#include <pbd/mathfix.h> - -using namespace std; -using namespace ARDOUR; -using namespace PBD; - -float Panner::current_automation_version_number = 1.0; - -string EqualPowerStereoPanner::name = "Equal Power Stereo"; -string Multi2dPanner::name = "Multiple (2D)"; - -/* this is a default mapper of control values to a pan position - others can be imagined. -*/ - -static pan_t direct_control_to_pan (double fract) { - return fract; -} - -static double direct_pan_to_control (pan_t val) { - return val; -} - -StreamPanner::StreamPanner (Panner& p, Parameter param) - : parent (p) - , _control (new PanControllable(p.session(), X_("panner"), *this, param)) -{ - assert(param.type() != NullAutomation); - - _muted = false; - - parent.session().add_controllable (_control); - - x = 0.5; - y = 0.5; - z = 0.5; -} - -StreamPanner::~StreamPanner () -{ -} - -void -StreamPanner::PanControllable::set_value (float val) -{ - panner.set_position (direct_control_to_pan (val)); -} - -float -StreamPanner::PanControllable::get_value (void) const -{ - float xpos; - panner.get_effective_position (xpos); - return direct_pan_to_control (xpos); -} - -bool -StreamPanner::PanControllable::can_send_feedback () const -{ - AutoState astate = panner.get_parent().automation_state (); - - if ((astate == Play) || (astate == Touch && !panner.get_parent().touching())) { - return true; - } - - return false; -} - -void -StreamPanner::set_muted (bool yn) -{ - if (yn != _muted) { - _muted = yn; - StateChanged (); - } -} - -void -StreamPanner::set_position (float xpos, bool link_call) -{ - if (!link_call && parent.linked()) { - parent.set_position (xpos, *this); - } - - if (x != xpos) { - x = xpos; - update (); - Changed (); - _control->Changed (); - } -} - -void -StreamPanner::set_position (float xpos, float ypos, bool link_call) -{ - if (!link_call && parent.linked()) { - parent.set_position (xpos, ypos, *this); - } - - if (x != xpos || y != ypos) { - - x = xpos; - y = ypos; - update (); - Changed (); - } -} - -void -StreamPanner::set_position (float xpos, float ypos, float zpos, bool link_call) -{ - if (!link_call && parent.linked()) { - parent.set_position (xpos, ypos, zpos, *this); - } - - if (x != xpos || y != ypos || z != zpos) { - x = xpos; - y = ypos; - z = zpos; - update (); - Changed (); - } -} - -int -StreamPanner::set_state (const XMLNode& node) -{ - const XMLProperty* prop; - XMLNodeConstIterator iter; - - if ((prop = node.property (X_("muted")))) { - set_muted (prop->value() == "yes"); - } - - return 0; -} - -void -StreamPanner::add_state (XMLNode& node) -{ - node.add_property (X_("muted"), (muted() ? "yes" : "no")); -} - -/*---------------------------------------------------------------------- */ - -BaseStereoPanner::BaseStereoPanner (Panner& p, Parameter param) - : StreamPanner (p, param) -{ -} - -BaseStereoPanner::~BaseStereoPanner () -{ -} - -int -BaseStereoPanner::load (istream& in, string path, uint32_t& linecnt) -{ - char line[128]; - LocaleGuard lg (X_("POSIX")); - - _control->list()->clear (); - - while (in.getline (line, sizeof (line), '\n')) { - nframes_t when; - double value; - - ++linecnt; - - if (strcmp (line, "end") == 0) { - break; - } - - if (sscanf (line, "%" PRIu32 " %lf", &when, &value) != 2) { - warning << string_compose(_("badly formatted pan automation event record at line %1 of %2 (ignored) [%3]"), linecnt, path, line) << endmsg; - continue; - } - - _control->list()->fast_simple_add (when, value); - } - - /* now that we are done loading */ - - _control->list()->StateChanged (); - - return 0; -} - -void -BaseStereoPanner::distribute (AudioBuffer& srcbuf, BufferSet& obufs, gain_t gain_coeff, nframes_t nframes) -{ - assert(obufs.count().n_audio() == 2); - - pan_t delta; - Sample* dst; - pan_t pan; - - if (_muted) { - return; - } - - Sample* const src = srcbuf.data(); - - /* LEFT */ - - dst = obufs.get_audio(0).data(); - - if (fabsf ((delta = (left - desired_left))) > 0.002) { // about 1 degree of arc - - /* interpolate over 64 frames or nframes, whichever is smaller */ - - nframes_t limit = min ((nframes_t)64, nframes); - nframes_t n; - - delta = -(delta / (float) (limit)); - - for (n = 0; n < limit; n++) { - left_interp = left_interp + delta; - left = left_interp + 0.9 * (left - left_interp); - dst[n] += src[n] * left * gain_coeff; - } - - pan = left * gain_coeff; - - mix_buffers_with_gain (dst+n,src+n,nframes-n,pan); - - } else { - - left = desired_left; - left_interp = left; - - if ((pan = (left * gain_coeff)) != 1.0f) { - - if (pan != 0.0f) { - - mix_buffers_with_gain(dst,src,nframes,pan); - - /* mark that we wrote into the buffer */ - - // obufs[0] = 0; - - } - - } else { - - mix_buffers_no_gain(dst,src,nframes); - - /* mark that we wrote into the buffer */ - - // obufs[0] = 0; - } - } - - /* RIGHT */ - - dst = obufs.get_audio(1).data(); - - if (fabsf ((delta = (right - desired_right))) > 0.002) { // about 1 degree of arc - - /* interpolate over 64 frames or nframes, whichever is smaller */ - - nframes_t limit = min ((nframes_t)64, nframes); - nframes_t n; - - delta = -(delta / (float) (limit)); - - for (n = 0; n < limit; n++) { - right_interp = right_interp + delta; - right = right_interp + 0.9 * (right - right_interp); - dst[n] += src[n] * right * gain_coeff; - } - - pan = right * gain_coeff; - - mix_buffers_with_gain(dst+n,src+n,nframes-n,pan); - - /* XXX it would be nice to mark the buffer as written to */ - - } else { - - right = desired_right; - right_interp = right; - - if ((pan = (right * gain_coeff)) != 1.0f) { - - if (pan != 0.0f) { - - mix_buffers_with_gain(dst,src,nframes,pan); - - /* XXX it would be nice to mark the buffer as written to */ - } - - } else { - - mix_buffers_no_gain(dst,src,nframes); - - /* XXX it would be nice to mark the buffer as written to */ - } - } -} - -/*---------------------------------------------------------------------- */ - -EqualPowerStereoPanner::EqualPowerStereoPanner (Panner& p, Parameter param) - : BaseStereoPanner (p, param) -{ - update (); - - left = desired_left; - right = desired_right; - left_interp = left; - right_interp = right; -} - -EqualPowerStereoPanner::~EqualPowerStereoPanner () -{ -} - -void -EqualPowerStereoPanner::update () -{ - /* it would be very nice to split this out into a virtual function - that can be accessed from BaseStereoPanner and used in distribute_automated(). - - but the place where its used in distribute_automated() is a tight inner loop, - and making "nframes" virtual function calls to compute values is an absurd - overhead. - */ - - /* x == 0 => hard left - x == 1 => hard right - */ - - float panR = x; - float panL = 1 - panR; - - const float pan_law_attenuation = -3.0f; - const float scale = 2.0f - 4.0f * powf (10.0f,pan_law_attenuation/20.0f); - - desired_left = panL * (scale * panL + 1.0f - scale); - desired_right = panR * (scale * panR + 1.0f - scale); - - effective_x = x; - _control->set_value(x); -} - -void -EqualPowerStereoPanner::distribute_automated (AudioBuffer& srcbuf, BufferSet& obufs, - nframes_t start, nframes_t end, nframes_t nframes, - pan_t** buffers) -{ - assert(obufs.count().n_audio() == 2); - - Sample* dst; - pan_t* pbuf; - Sample* const src = srcbuf.data(); - - /* fetch positional data */ - - if (!_control->list()->curve().rt_safe_get_vector (start, end, buffers[0], nframes)) { - /* fallback */ - if (!_muted) { - distribute (srcbuf, obufs, 1.0, nframes); - } - return; - } - - /* store effective pan position. do this even if we are muted */ - - if (nframes > 0) { - effective_x = buffers[0][nframes-1]; - _control->set_value(effective_x); // signal, update UI - } - - if (_muted) { - return; - } - - /* apply pan law to convert positional data into pan coefficients for - each buffer (output) - */ - - const float pan_law_attenuation = -3.0f; - const float scale = 2.0f - 4.0f * powf (10.0f,pan_law_attenuation/20.0f); - - for (nframes_t n = 0; n < nframes; ++n) { - - float panR = buffers[0][n]; - float panL = 1 - panR; - - buffers[0][n] = panL * (scale * panL + 1.0f - scale); - buffers[1][n] = panR * (scale * panR + 1.0f - scale); - } - - /* LEFT */ - - dst = obufs.get_audio(0).data(); - pbuf = buffers[0]; - - for (nframes_t n = 0; n < nframes; ++n) { - dst[n] += src[n] * pbuf[n]; - } - - /* XXX it would be nice to mark the buffer as written to */ - - /* RIGHT */ - - dst = obufs.get_audio(1).data(); - pbuf = buffers[1]; - - for (nframes_t n = 0; n < nframes; ++n) { - dst[n] += src[n] * pbuf[n]; - } - - /* XXX it would be nice to mark the buffer as written to */ -} - -StreamPanner* -EqualPowerStereoPanner::factory (Panner& parent, Parameter param) -{ - return new EqualPowerStereoPanner (parent, param); -} - -XMLNode& -EqualPowerStereoPanner::get_state (void) -{ - return state (true); -} - -XMLNode& -EqualPowerStereoPanner::state (bool full_state) -{ - XMLNode* root = new XMLNode ("StreamPanner"); - char buf[64]; - LocaleGuard lg (X_("POSIX")); - - snprintf (buf, sizeof (buf), "%.12g", x); - root->add_property (X_("x"), buf); - root->add_property (X_("type"), EqualPowerStereoPanner::name); - - XMLNode* autonode = new XMLNode (X_("Automation")); - autonode->add_child_nocopy (_control->list()->state (full_state)); - root->add_child_nocopy (*autonode); - - StreamPanner::add_state (*root); - - root->add_child_nocopy (_control->get_state ()); - - return *root; -} - -int -EqualPowerStereoPanner::set_state (const XMLNode& node) -{ - const XMLProperty* prop; - float pos; - LocaleGuard lg (X_("POSIX")); - - if ((prop = node.property (X_("x")))) { - pos = atof (prop->value().c_str()); - set_position (pos, true); - } - - StreamPanner::set_state (node); - - for (XMLNodeConstIterator iter = node.children().begin(); iter != node.children().end(); ++iter) { - - if ((*iter)->name() == X_("controllable")) { - if ((prop = (*iter)->property("name")) != 0 && prop->value() == "panner") { - _control->set_state (**iter); - } - - } else if ((*iter)->name() == X_("Automation")) { - - _control->list()->set_state (*((*iter)->children().front())); - - if (_control->list()->automation_state() != Off) { - set_position (_control->list()->eval (parent.session().transport_frame())); - } - } - } - - return 0; -} - -/*----------------------------------------------------------------------*/ - -Multi2dPanner::Multi2dPanner (Panner& p, Parameter param) - : StreamPanner (p, param) -{ - update (); -} - -Multi2dPanner::~Multi2dPanner () -{ -} - -void -Multi2dPanner::update () -{ - static const float BIAS = FLT_MIN; - uint32_t i; - uint32_t nouts = parent.outputs.size(); - float dsq[nouts]; - float f, fr; - vector<pan_t> pans; - - f = 0.0f; - - for (i = 0; i < nouts; i++) { - dsq[i] = ((x - parent.outputs[i].x) * (x - parent.outputs[i].x) + (y - parent.outputs[i].y) * (y - parent.outputs[i].y) + BIAS); - if (dsq[i] < 0.0) { - dsq[i] = 0.0; - } - f += dsq[i] * dsq[i]; - } -#ifdef __APPLE__ - // terrible hack to support OSX < 10.3.9 builds - fr = (float) (1.0 / sqrt((double)f)); -#else - fr = 1.0 / sqrtf(f); -#endif - for (i = 0; i < nouts; ++i) { - parent.outputs[i].desired_pan = 1.0f - (dsq[i] * fr); - } - - effective_x = x; - _control->set_value(x); -} - -void -Multi2dPanner::distribute (AudioBuffer& srcbuf, BufferSet& obufs, gain_t gain_coeff, nframes_t nframes) -{ - Sample* dst; - pan_t pan; - vector<Panner::Output>::iterator o; - uint32_t n; - - if (_muted) { - return; - } - - Sample* const src = srcbuf.data(); - - - for (n = 0, o = parent.outputs.begin(); o != parent.outputs.end(); ++o, ++n) { - - dst = obufs.get_audio(n).data(); - -#ifdef CAN_INTERP - if (fabsf ((delta = (left_interp - desired_left))) > 0.002) { // about 1 degree of arc - - /* interpolate over 64 frames or nframes, whichever is smaller */ - - nframes_t limit = min ((nframes_t)64, nframes); - nframes_t n; - - delta = -(delta / (float) (limit)); - - for (n = 0; n < limit; n++) { - left_interp = left_interp + delta; - left = left_interp + 0.9 * (left - left_interp); - dst[n] += src[n] * left * gain_coeff; - } - - pan = left * gain_coeff; - mix_buffers_with_gain(dst+n,src+n,nframes-n,pan); - - } else { - -#else - pan = (*o).desired_pan; - - if ((pan *= gain_coeff) != 1.0f) { - - if (pan != 0.0f) { - mix_buffers_with_gain(dst,src,nframes,pan); - } - } else { - mix_buffers_no_gain(dst,src,nframes); - } -#endif -#ifdef CAN_INTERP - } -#endif - } - - return; -} - -void -Multi2dPanner::distribute_automated (AudioBuffer& src, BufferSet& obufs, - nframes_t start, nframes_t end, nframes_t nframes, - pan_t** buffers) -{ - if (_muted) { - return; - } - - /* what ? */ - - return; -} - -StreamPanner* -Multi2dPanner::factory (Panner& p, Parameter param) -{ - return new Multi2dPanner (p, param); -} - -int -Multi2dPanner::load (istream& in, string path, uint32_t& linecnt) -{ - return 0; -} - -XMLNode& -Multi2dPanner::get_state (void) -{ - return state (true); -} - -XMLNode& -Multi2dPanner::state (bool full_state) -{ - XMLNode* root = new XMLNode ("StreamPanner"); - char buf[64]; - LocaleGuard lg (X_("POSIX")); - - snprintf (buf, sizeof (buf), "%.12g", x); - root->add_property (X_("x"), buf); - snprintf (buf, sizeof (buf), "%.12g", y); - root->add_property (X_("y"), buf); - root->add_property (X_("type"), Multi2dPanner::name); - - /* XXX no meaningful automation yet */ - - return *root; -} - -int -Multi2dPanner::set_state (const XMLNode& node) -{ - const XMLProperty* prop; - float newx,newy; - LocaleGuard lg (X_("POSIX")); - - newx = -1; - newy = -1; - - if ((prop = node.property (X_("x")))) { - newx = atof (prop->value().c_str()); - } - - if ((prop = node.property (X_("y")))) { - newy = atof (prop->value().c_str()); - } - - if (x < 0 || y < 0) { - error << _("badly-formed positional data for Multi2dPanner - ignored") - << endmsg; - return -1; - } - - set_position (newx, newy); - return 0; -} - -/*---------------------------------------------------------------------- */ - -Panner::Panner (string name, Session& s) - : _session (s) -{ - set_name (name); - - _linked = false; - _link_direction = SameDirection; - _bypassed = false; -} - -Panner::~Panner () -{ -} - -void -Panner::set_linked (bool yn) -{ - if (yn != _linked) { - _linked = yn; - _session.set_dirty (); - LinkStateChanged (); /* EMIT SIGNAL */ - } -} - -void -Panner::set_link_direction (LinkDirection ld) -{ - if (ld != _link_direction) { - _link_direction = ld; - _session.set_dirty (); - LinkStateChanged (); /* EMIT SIGNAL */ - } -} - -void -Panner::set_bypassed (bool yn) -{ - if (yn != _bypassed) { - _bypassed = yn; - StateChanged (); - } -} - - -void -Panner::reset (uint32_t nouts, uint32_t npans) -{ - uint32_t n; - bool changed = false; - - if (nouts < 2 || (nouts == outputs.size() && npans == size())) { - return; - } - - n = size(); - clear (); - - if (n != npans) { - changed = true; - } - - n = outputs.size(); - outputs.clear (); - - if (n != nouts) { - changed = true; - } - - switch (nouts) { - case 0: - break; - - case 1: - fatal << _("programming error:") - << X_("Panner::reset() called with a single output") - << endmsg; - /*NOTREACHED*/ - break; - - case 2: - /* line */ - outputs.push_back (Output (0, 0)); - outputs.push_back (Output (1.0, 0)); - - for (n = 0; n < npans; ++n) { - push_back (new EqualPowerStereoPanner (*this, Parameter(PanAutomation, n))); - } - break; - - case 3: // triangle - outputs.push_back (Output (0.5, 0)); - outputs.push_back (Output (0, 1.0)); - outputs.push_back (Output (1.0, 1.0)); - - for (n = 0; n < npans; ++n) { - push_back (new Multi2dPanner (*this, Parameter(PanAutomation, n))); - } - - break; - - case 4: // square - outputs.push_back (Output (0, 0)); - outputs.push_back (Output (1.0, 0)); - outputs.push_back (Output (1.0, 1.0)); - outputs.push_back (Output (0, 1.0)); - - for (n = 0; n < npans; ++n) { - push_back (new Multi2dPanner (*this, Parameter(PanAutomation, n))); - } - - break; - - case 5: //square+offcenter center - outputs.push_back (Output (0, 0)); - outputs.push_back (Output (1.0, 0)); - outputs.push_back (Output (1.0, 1.0)); - outputs.push_back (Output (0, 1.0)); - outputs.push_back (Output (0.5, 0.75)); - - for (n = 0; n < npans; ++n) { - push_back (new Multi2dPanner (*this, Parameter(PanAutomation, n))); - } - - break; - - default: - /* XXX horrible placement. FIXME */ - for (n = 0; n < nouts; ++n) { - outputs.push_back (Output (0.1 * n, 0.1 * n)); - } - - for (n = 0; n < npans; ++n) { - push_back (new Multi2dPanner (*this, Parameter(PanAutomation, n))); - } - - break; - } - - for (iterator x = begin(); x != end(); ++x) { - (*x)->update (); - } - - /* force hard left/right panning in a common case: 2in/2out - */ - - if (npans == 2 && outputs.size() == 2) { - - /* Do this only if we changed configuration, or our configuration - appears to be the default set up (center). - */ - - float left; - float right; - - front()->get_position (left); - back()->get_position (right); - - if (changed || ((left == 0.5) && (right == 0.5))) { - - front()->set_position (0.0); - front()->pan_control()->list()->reset_default (0.0); - - back()->set_position (1.0); - back()->pan_control()->list()->reset_default (1.0); - - changed = true; - } - } - - if (changed) { - Changed (); /* EMIT SIGNAL */ - } - - return; -} - -void -Panner::remove (uint32_t which) -{ - vector<StreamPanner*>::iterator i; - for (i = begin(); i != end() && which; ++i, --which); - - if (i != end()) { - delete *i; - erase (i); - } -} - -void -Panner::clear () -{ - for (vector<StreamPanner*>::iterator i = begin(); i != end(); ++i) { - delete *i; - } - - vector<StreamPanner*>::clear (); -} - -void -Panner::set_automation_style (AutoStyle style) -{ - for (vector<StreamPanner*>::iterator i = begin(); i != end(); ++i) { - (*i)->pan_control()->list()->set_automation_style (style); - } - _session.set_dirty (); -} - -void -Panner::set_automation_state (AutoState state) -{ - for (vector<StreamPanner*>::iterator i = begin(); i != end(); ++i) { - (*i)->pan_control()->list()->set_automation_state (state); - } - _session.set_dirty (); -} - -AutoState -Panner::automation_state () const -{ - if (!empty()) { - return front()->pan_control()->list()->automation_state (); - } else { - return Off; - } -} - -AutoStyle -Panner::automation_style () const -{ - if (!empty()) { - return front()->pan_control()->list()->automation_style (); - } else { - return Absolute; - } -} - -void -Panner::transport_stopped (nframes_t frame) -{ - for (vector<StreamPanner*>::iterator i = begin(); i != end(); ++i) { - (*i)->pan_control()->list()->reposition_for_rt_add (frame); - } -} - -void -Panner::snapshot (nframes_t now) -{ - for (vector<StreamPanner*>::iterator i = begin(); i != end(); ++i) { - boost::shared_ptr<AutomationList> list = (*i)->pan_control()->list(); - if (list->automation_write()) - list->rt_add(now, (*i)->pan_control()->get_value()); - } -} - -void -Panner::clear_automation () -{ - for (vector<StreamPanner*>::iterator i = begin(); i != end(); ++i) { - (*i)->pan_control()->list()->clear (); - } - _session.set_dirty (); -} - -struct PanPlugins { - string name; - uint32_t nouts; - StreamPanner* (*factory)(Panner&, Parameter); -}; - -PanPlugins pan_plugins[] = { - { EqualPowerStereoPanner::name, 2, EqualPowerStereoPanner::factory }, - { Multi2dPanner::name, 3, Multi2dPanner::factory }, - { string (""), 0, 0 } -}; - -XMLNode& -Panner::get_state (void) -{ - return state (true); -} - -XMLNode& -Panner::state (bool full) -{ - XMLNode* root = new XMLNode (X_("Panner")); - char buf[32]; - - root->add_property (X_("linked"), (_linked ? "yes" : "no")); - root->add_property (X_("link_direction"), enum_2_string (_link_direction)); - root->add_property (X_("bypassed"), (bypassed() ? "yes" : "no")); - - /* add each output */ - - for (vector<Panner::Output>::iterator o = outputs.begin(); o != outputs.end(); ++o) { - XMLNode* onode = new XMLNode (X_("Output")); - snprintf (buf, sizeof (buf), "%.12g", (*o).x); - onode->add_property (X_("x"), buf); - snprintf (buf, sizeof (buf), "%.12g", (*o).y); - onode->add_property (X_("y"), buf); - root->add_child_nocopy (*onode); - } - - for (vector<StreamPanner*>::const_iterator i = begin(); i != end(); ++i) { - root->add_child_nocopy ((*i)->state (full)); - } - - return *root; -} - -int -Panner::set_state (const XMLNode& node) -{ - XMLNodeList nlist; - XMLNodeConstIterator niter; - const XMLProperty *prop; - uint32_t i; - StreamPanner* sp; - LocaleGuard lg (X_("POSIX")); - - clear (); - outputs.clear (); - - if ((prop = node.property (X_("linked"))) != 0) { - set_linked (prop->value() == "yes"); - } - - - if ((prop = node.property (X_("bypassed"))) != 0) { - set_bypassed (prop->value() == "yes"); - } - - if ((prop = node.property (X_("link_direction"))) != 0) { - LinkDirection ld; /* here to provide type information */ - set_link_direction (LinkDirection (string_2_enum (prop->value(), ld))); - } - - nlist = node.children(); - - for (niter = nlist.begin(); niter != nlist.end(); ++niter) { - if ((*niter)->name() == X_("Output")) { - - float x, y; - - prop = (*niter)->property (X_("x")); - sscanf (prop->value().c_str(), "%g", &x); - - prop = (*niter)->property (X_("y")); - sscanf (prop->value().c_str(), "%g", &y); - - outputs.push_back (Output (x, y)); - } - } - - for (niter = nlist.begin(); niter != nlist.end(); ++niter) { - - if ((*niter)->name() == X_("StreamPanner")) { - - if ((prop = (*niter)->property (X_("type")))) { - - for (i = 0; pan_plugins[i].factory; ++i) { - if (prop->value() == pan_plugins[i].name) { - - - /* note that we assume that all the stream panners - are of the same type. pretty good - assumption, but its still an assumption. - */ - - sp = pan_plugins[i].factory (*this, Parameter(PanAutomation, 0)); - - if (sp->set_state (**niter) == 0) { - push_back (sp); - } - - break; - } - } - - - if (!pan_plugins[i].factory) { - error << string_compose (_("Unknown panner plugin \"%1\" found in pan state - ignored"), - prop->value()) - << endmsg; - } - - } else { - error << _("panner plugin node has no type information!") - << endmsg; - return -1; - } - - } - } - - /* don't try to do old-school automation loading if it wasn't marked as existing */ - - if ((prop = node.property (X_("automation")))) { - - /* automation path is relative */ - - automation_path = _session.automation_dir(); - automation_path += prop->value (); - } - - return 0; -} - - - -bool -Panner::touching () const -{ - for (vector<StreamPanner*>::const_iterator i = begin(); i != end(); ++i) { - if ((*i)->pan_control()->list()->touching ()) { - return true; - } - } - - return false; -} - -void -Panner::set_position (float xpos, StreamPanner& orig) -{ - float xnow; - float xdelta ; - float xnew; - - orig.get_position (xnow); - xdelta = xpos - xnow; - - if (_link_direction == SameDirection) { - - for (vector<StreamPanner*>::iterator i = begin(); i != end(); ++i) { - if (*i == &orig) { - (*i)->set_position (xpos, true); - } else { - (*i)->get_position (xnow); - xnew = min (1.0f, xnow + xdelta); - xnew = max (0.0f, xnew); - (*i)->set_position (xnew, true); - } - } - - } else { - - for (vector<StreamPanner*>::iterator i = begin(); i != end(); ++i) { - if (*i == &orig) { - (*i)->set_position (xpos, true); - } else { - (*i)->get_position (xnow); - xnew = min (1.0f, xnow - xdelta); - xnew = max (0.0f, xnew); - (*i)->set_position (xnew, true); - } - } - } -} - -void -Panner::set_position (float xpos, float ypos, StreamPanner& orig) -{ - float xnow, ynow; - float xdelta, ydelta; - float xnew, ynew; - - orig.get_position (xnow, ynow); - xdelta = xpos - xnow; - ydelta = ypos - ynow; - - if (_link_direction == SameDirection) { - - for (vector<StreamPanner*>::iterator i = begin(); i != end(); ++i) { - if (*i == &orig) { - (*i)->set_position (xpos, ypos, true); - } else { - (*i)->get_position (xnow, ynow); - - xnew = min (1.0f, xnow + xdelta); - xnew = max (0.0f, xnew); - - ynew = min (1.0f, ynow + ydelta); - ynew = max (0.0f, ynew); - - (*i)->set_position (xnew, ynew, true); - } - } - - } else { - - for (vector<StreamPanner*>::iterator i = begin(); i != end(); ++i) { - if (*i == &orig) { - (*i)->set_position (xpos, ypos, true); - } else { - (*i)->get_position (xnow, ynow); - - xnew = min (1.0f, xnow - xdelta); - xnew = max (0.0f, xnew); - - ynew = min (1.0f, ynow - ydelta); - ynew = max (0.0f, ynew); - - (*i)->set_position (xnew, ynew, true); - } - } - } -} - -void -Panner::set_position (float xpos, float ypos, float zpos, StreamPanner& orig) -{ - float xnow, ynow, znow; - float xdelta, ydelta, zdelta; - float xnew, ynew, znew; - - orig.get_position (xnow, ynow, znow); - xdelta = xpos - xnow; - ydelta = ypos - ynow; - zdelta = zpos - znow; - - if (_link_direction == SameDirection) { - - for (vector<StreamPanner*>::iterator i = begin(); i != end(); ++i) { - if (*i == &orig) { - (*i)->set_position (xpos, ypos, zpos, true); - } else { - (*i)->get_position (xnow, ynow, znow); - - xnew = min (1.0f, xnow + xdelta); - xnew = max (0.0f, xnew); - - ynew = min (1.0f, ynow + ydelta); - ynew = max (0.0f, ynew); - - znew = min (1.0f, znow + zdelta); - znew = max (0.0f, znew); - - (*i)->set_position (xnew, ynew, znew, true); - } - } - - } else { - - for (vector<StreamPanner*>::iterator i = begin(); i != end(); ++i) { - if (*i == &orig) { - (*i)->set_position (xpos, ypos, true); - } else { - (*i)->get_position (xnow, ynow, znow); - - xnew = min (1.0f, xnow - xdelta); - xnew = max (0.0f, xnew); - - ynew = min (1.0f, ynow - ydelta); - ynew = max (0.0f, ynew); - - znew = min (1.0f, znow + zdelta); - znew = max (0.0f, znew); - - (*i)->set_position (xnew, ynew, znew, true); - } - } - } -} - -void -Panner::distribute_no_automation (BufferSet& inbufs, BufferSet& outbufs, nframes_t nframes, nframes_t offset, gain_t gain_coeff) -{ - if (outbufs.count().n_audio() == 0) { - // Don't want to lose audio... - assert(inbufs.count().n_audio() == 0); - return; - } - - // We shouldn't be called in the first place... - assert(!bypassed()); - assert(!empty()); - - - if (outbufs.count().n_audio() == 1) { - - AudioBuffer& dst = outbufs.get_audio(0); - - if (gain_coeff == 0.0f) { - - /* only one output, and gain was zero, so make it silent */ - - dst.silence(offset); - - } else if (gain_coeff == 1.0f){ - - /* mix all buffers into the output */ - - // copy the first - dst.read_from(inbufs.get_audio(0), nframes, offset); - - // accumulate starting with the second - BufferSet::audio_iterator i = inbufs.audio_begin(); - for (++i; i != inbufs.audio_end(); ++i) { - dst.accumulate_from(*i, nframes, offset); - } - - } else { - - /* mix all buffers into the output, scaling them all by the gain */ - - // copy the first - dst.read_from(inbufs.get_audio(0), nframes, offset); - - // accumulate (with gain) starting with the second - BufferSet::audio_iterator i = inbufs.audio_begin(); - for (++i; i != inbufs.audio_end(); ++i) { - dst.accumulate_with_gain_from(*i, nframes, offset, gain_coeff); - } - - } - - return; - } - - /* the terrible silence ... */ - for (BufferSet::audio_iterator i = outbufs.audio_begin(); i != outbufs.audio_end(); ++i) { - i->silence(nframes, offset); - } - - BufferSet::audio_iterator i = inbufs.audio_begin(); - - for (iterator pan = begin(); pan != end() && i != inbufs.audio_end(); ++pan, ++i) { - (*pan)->distribute (*i, outbufs, gain_coeff, nframes); - } -} - -void -Panner::distribute (BufferSet& inbufs, BufferSet& outbufs, nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset) -{ - if (outbufs.count().n_audio() == 0) { - // Failing to deliver audio we were asked to deliver is a bug - assert(inbufs.count().n_audio() == 0); - return; - } - - // We shouldn't be called in the first place... - assert(!bypassed()); - assert(!empty()); - - // If we shouldn't play automation defer to distribute_no_automation - if ( !( automation_state() & Play || - ((automation_state() & Touch) && !touching()) ) ) { - - // Speed quietning - gain_t gain_coeff = 1.0; - if (fabsf(_session.transport_speed()) > 1.5f) { - gain_coeff = speed_quietning; - } - - distribute_no_automation(inbufs, outbufs, nframes, offset, gain_coeff); - return; - } - - // Otherwise.. let the automation flow, baby - - if (outbufs.count().n_audio() == 1) { - - AudioBuffer& dst = outbufs.get_audio(0); - - // FIXME: apply gain automation? - - // copy the first - dst.read_from(inbufs.get_audio(0), nframes, offset); - - // accumulate starting with the second - BufferSet::audio_iterator i = inbufs.audio_begin(); - for (++i; i != inbufs.audio_end(); ++i) { - dst.accumulate_from(*i, nframes, offset); - } - - return; - } - - // More than 1 output, we should have 1 panner for each input - assert(size() == inbufs.count().n_audio()); - - /* the terrible silence ... */ - for (BufferSet::audio_iterator i = outbufs.audio_begin(); i != outbufs.audio_end(); ++i) { - i->silence(nframes, offset); - } - - BufferSet::audio_iterator i = inbufs.audio_begin(); - for (iterator pan = begin(); pan != end(); ++pan, ++i) { - (*pan)->distribute_automated (*i, outbufs, start_frame, end_frame, nframes, _session.pan_automation_buffer()); - } -} - -/* old school automation handling */ - -void -Panner::set_name (string str) -{ - automation_path = _session.automation_dir(); - automation_path += _session.snap_name(); - automation_path += "-pan-"; - automation_path += legalize_for_path (str); - automation_path += ".automation"; -} - -int -Panner::load () -{ - char line[128]; - uint32_t linecnt = 0; - float version; - iterator sp; - LocaleGuard lg (X_("POSIX")); - - if (automation_path.length() == 0) { - return 0; - } - - if (access (automation_path.c_str(), F_OK)) { - return 0; - } - - ifstream in (automation_path.c_str()); - - if (!in) { - error << string_compose (_("cannot open pan automation file %1 (%2)"), - automation_path, strerror (errno)) - << endmsg; - return -1; - } - - sp = begin(); - - while (in.getline (line, sizeof(line), '\n')) { - - if (++linecnt == 1) { - if (memcmp (line, X_("version"), 7) == 0) { - if (sscanf (line, "version %f", &version) != 1) { - error << string_compose(_("badly formed version number in pan automation event file \"%1\""), automation_path) << endmsg; - return -1; - } - } else { - error << string_compose(_("no version information in pan automation event file \"%1\" (first line = %2)"), - automation_path, line) << endmsg; - return -1; - } - - continue; - } - - if (strlen (line) == 0 || line[0] == '#') { - continue; - } - - if (strcmp (line, "begin") == 0) { - - if (sp == end()) { - error << string_compose (_("too many panner states found in pan automation file %1"), - automation_path) - << endmsg; - return -1; - } - - if ((*sp)->load (in, automation_path, linecnt)) { - return -1; - } - - ++sp; - } - } - - return 0; -} diff --git a/libs/ardour/parameter.cc b/libs/ardour/parameter.cc deleted file mode 100644 index 1b94e5dc4d..0000000000 --- a/libs/ardour/parameter.cc +++ /dev/null @@ -1,121 +0,0 @@ -/* - 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. -*/ - -#include <ardour/parameter.h> - -using namespace ARDOUR; - - -/** Construct an Parameter from a string returned from Parameter::to_string - * (AutomationList automation-id property) - */ -Parameter::Parameter(const std::string& str) - : _type(NullAutomation) - , _id(0) - , _channel(0) -{ - if (str == "gain") { - _type = GainAutomation; - } else if (str == "solo") { - _type = SoloAutomation; - } else if (str == "mute") { - _type = MuteAutomation; - } else if (str == "fadein") { - _type = FadeInAutomation; - } else if (str == "fadeout") { - _type = FadeOutAutomation; - } else if (str == "envelope") { - _type = EnvelopeAutomation; - } else if (str == "pan") { - _type = PanAutomation; - } else if (str.length() > 4 && str.substr(0, 4) == "pan-") { - _type = PanAutomation; - _id = atoi(str.c_str()+4); - } else if (str.length() > 10 && str.substr(0, 10) == "parameter-") { - _type = PluginAutomation; - _id = atoi(str.c_str()+10); - } else if (str.length() > 7 && str.substr(0, 7) == "midicc-") { - _type = MidiCCAutomation; - uint32_t channel = 0; - sscanf(str.c_str(), "midicc-%d-%d", &channel, &_id); - assert(channel < 16); - _channel = channel; - } else if (str.length() > 16 && str.substr(0, 16) == "midi-pgm-change-") { - _type = MidiPgmChangeAutomation; - uint32_t channel = 0; - sscanf(str.c_str(), "midi-pgm-change-%d", &channel); - assert(channel < 16); - _id = 0; - _channel = channel; - } else if (str.length() > 18 && str.substr(0, 18) == "midi-pitch-bender-") { - _type = MidiPitchBenderAutomation; - uint32_t channel = 0; - sscanf(str.c_str(), "midi-pitch-bender-%d", &channel); - assert(channel < 16); - _id = 0; - _channel = channel; - } else if (str.length() > 24 && str.substr(0, 24) == "midi-channel-aftertouch-") { - _type = MidiChannelAftertouchAutomation; - uint32_t channel = 0; - sscanf(str.c_str(), "midi-channel-aftertouch-%d", &channel); - assert(channel < 16); - _id = 0; - _channel = channel; - } else { - PBD::warning << "Unknown Parameter '" << str << "'" << endmsg; - } -} - - -/** Unique string representation, suitable as an XML property value. - * e.g. <AutomationList automation-id="whatthisreturns"> - */ -std::string -Parameter::to_string() const -{ - if (_type == GainAutomation) { - return "gain"; - } else if (_type == PanAutomation) { - return string_compose("pan-%1", _id); - } else if (_type == SoloAutomation) { - return "solo"; - } else if (_type == MuteAutomation) { - return "mute"; - } else if (_type == FadeInAutomation) { - return "fadein"; - } else if (_type == FadeOutAutomation) { - return "fadeout"; - } else if (_type == EnvelopeAutomation) { - return "envelope"; - } else if (_type == PluginAutomation) { - return string_compose("parameter-%1", _id); - } else if (_type == MidiCCAutomation) { - return string_compose("midicc-%1-%2", int(_channel), _id); - } else if (_type == MidiPgmChangeAutomation) { - return string_compose("midi-pgm-change-%1", int(_channel)); - } else if (_type == MidiPitchBenderAutomation) { - return string_compose("midi-pitch-bender-%1", int(_channel)); - } else if (_type == MidiChannelAftertouchAutomation) { - return string_compose("midi-channel-aftertouch-%1", int(_channel)); - } else { - PBD::warning << "Uninitialized Parameter to_string() called." << endmsg; - return ""; - } -} - diff --git a/libs/ardour/pcm_utils.cc b/libs/ardour/pcm_utils.cc deleted file mode 100644 index 08d8a63d6e..0000000000 --- a/libs/ardour/pcm_utils.cc +++ /dev/null @@ -1,177 +0,0 @@ -/* - 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. - -*/ - -#include <ardour/pcm_utils.h> - -#include <cmath> - -using namespace std; - -// TODO: check CPU_CLIPS_POSITIVE and CPU_CLIPS_NEGATIVE with scons -#define CPU_CLIPS_NEGATIVE 0 -#define CPU_CLIPS_POSITIVE 0 - -/* these routines deal with 24 bit int handling (tribytes) - * originally from libsndfile, but modified. XXX - Copyright Erik de Castro Lopo - */ - -void -pcm_let2f_array (tribyte *src, int count, float *dest) -{ - /* Special normfactor because tribyte value is read into an int. */ - static const float normfact = 1.0 / ((float) 0x80000000); - - unsigned char *ucptr ; - int value ; - - ucptr = ((unsigned char*) src) + 3 * count ; - while (--count >= 0) - { ucptr -= 3 ; - value = LET2H_INT_PTR (ucptr) ; - dest [count] = ((float) value) * normfact ; - } ; -} /* let2f_array */ - -void -pcm_bet2f_array (tribyte *src, int count, float *dest) -{ - /* Special normfactor because tribyte value is read into an int. */ - static const float normfact = 1.0 / ((float) 0x80000000); - - unsigned char *ucptr ; - int value ; - - - ucptr = ((unsigned char*) src) + 3 * count ; - while (--count >= 0) - { ucptr -= 3 ; - value = BET2H_INT_PTR (ucptr) ; - dest [count] = ((float) value) * normfact ; - } ; -} /* bet2f_array */ - -void -pcm_f2let_array (float *src, tribyte *dest, int count) -{ - static const float normfact = (1.0 * 0x7FFFFF); - - unsigned char *ucptr ; - int value ; - - ucptr = ((unsigned char*) dest) + 3 * count ; - - while (count) - { count -- ; - ucptr -= 3 ; - value = lrintf (src [count] * normfact) ; - ucptr [0] = value ; - ucptr [1] = value >> 8 ; - ucptr [2] = value >> 16 ; - } ; -} /* f2let_array */ - -void -pcm_f2let_clip_array (float *src, tribyte *dest, int count) -{ - static const float normfact = (8.0 * 0x10000000); - - unsigned char *ucptr ; - float scaled_value ; - int value ; - - ucptr = ((unsigned char*) dest) + 3 * count ; - - while (count) - { count -- ; - ucptr -= 3 ; - scaled_value = src [count] * normfact ; - if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF)) - { ucptr [0] = 0xFF ; - ucptr [1] = 0xFF ; - ucptr [2] = 0x7F ; - continue ; - } ; - if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000)) - { ucptr [0] = 0x00 ; - ucptr [1] = 0x00 ; - ucptr [2] = 0x80 ; - continue ; - } ; - - value = lrintf (scaled_value) ; - ucptr [0] = value >> 8 ; - ucptr [1] = value >> 16 ; - ucptr [2] = value >> 24 ; - } ; -} /* f2let_clip_array */ - -void -pcm_f2bet_array (const float *src, tribyte *dest, int count) -{ - static const float normfact = (1.0 * 0x7FFFFF); - - unsigned char *ucptr ; - int value ; - - ucptr = ((unsigned char*) dest) + 3 * count ; - - while (--count >= 0) - { ucptr -= 3 ; - value = lrintf (src [count] * normfact) ; - ucptr [0] = value >> 16 ; - ucptr [1] = value >> 8 ; - ucptr [2] = value ; - } ; -} /* f2bet_array */ - -void -pcm_f2bet_clip_array (const float *src, tribyte *dest, int count) -{ - static const float normfact = (8.0 * 0x10000000); - - unsigned char *ucptr ; - float scaled_value ; - int value ; - - ucptr = ((unsigned char*) dest) + 3 * count ; - - while (--count >= 0) - { ucptr -= 3 ; - scaled_value = src [count] * normfact ; - if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF)) - { ucptr [0] = 0x7F ; - ucptr [1] = 0xFF ; - ucptr [2] = 0xFF ; - continue ; - } ; - if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000)) - { ucptr [0] = 0x80 ; - ucptr [1] = 0x00 ; - ucptr [2] = 0x00 ; - continue ; - } ; - - value = lrint (scaled_value) ; - ucptr [0] = value >> 24 ; - ucptr [1] = value >> 16 ; - ucptr [2] = value >> 8 ; - } ; -} /* f2bet_clip_array */ - -//@@@@@@@ diff --git a/libs/ardour/playlist.cc b/libs/ardour/playlist.cc deleted file mode 100644 index 0b0d5ecc22..0000000000 --- a/libs/ardour/playlist.cc +++ /dev/null @@ -1,2367 +0,0 @@ -/* - Copyright (C) 2000-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. - -*/ - -#include <set> -#include <fstream> -#include <algorithm> -#include <unistd.h> -#include <cerrno> -#include <string> -#include <climits> - -#include <sigc++/bind.h> - -#include <pbd/failed_constructor.h> -#include <pbd/stl_delete.h> -#include <pbd/xml++.h> -#include <pbd/stacktrace.h> - -#include <ardour/playlist.h> -#include <ardour/session.h> -#include <ardour/region.h> -#include <ardour/region_factory.h> -#include <ardour/playlist_factory.h> -#include <ardour/transient_detector.h> - -#include "i18n.h" - -using namespace std; -using namespace ARDOUR; -using namespace PBD; - -struct ShowMeTheList { - ShowMeTheList (boost::shared_ptr<Playlist> pl, const string& n) : playlist (pl), name (n) {} - ~ShowMeTheList () { - cerr << ">>>>" << name << endl; playlist->dump(); cerr << "<<<<" << name << endl << endl; - }; - boost::shared_ptr<Playlist> playlist; - string name; -}; - -struct RegionSortByLayer { - bool operator() (boost::shared_ptr<Region> a, boost::shared_ptr<Region> b) { - return a->layer() < b->layer(); - } -}; - -struct RegionSortByPosition { - bool operator() (boost::shared_ptr<Region> a, boost::shared_ptr<Region> b) { - return a->position() < b->position(); - } -}; - -struct RegionSortByLastLayerOp { - bool operator() (boost::shared_ptr<Region> a, boost::shared_ptr<Region> b) { - return a->last_layer_op() < b->last_layer_op(); - } -}; - - -Playlist::Playlist (Session& sess, string nom, DataType type, bool hide) - : SessionObject(sess, nom) - , _type(type) -{ - init (hide); - first_set_state = false; - _name = nom; - -} - -Playlist::Playlist (Session& sess, const XMLNode& node, DataType type, bool hide) - : SessionObject(sess, "unnamed playlist") - , _type(type) -{ - const XMLProperty* prop = node.property("type"); - assert(!prop || DataType(prop->value()) == _type); - - init (hide); - _name = "unnamed"; /* reset by set_state */ - - /* set state called by derived class */ -} - -Playlist::Playlist (boost::shared_ptr<const Playlist> other, string namestr, bool hide) - : SessionObject(other->_session, namestr), _type(other->_type), _orig_diskstream_id(other->_orig_diskstream_id) -{ - init (hide); - - RegionList tmp; - other->copy_regions (tmp); - - in_set_state++; - - for (list<boost::shared_ptr<Region> >::iterator x = tmp.begin(); x != tmp.end(); ++x) { - add_region_internal( (*x), (*x)->position()); - } - - in_set_state--; - - _splicing = other->_splicing; - _nudging = other->_nudging; - _edit_mode = other->_edit_mode; - - in_set_state = 0; - first_set_state = false; - in_flush = false; - in_partition = false; - subcnt = 0; - _read_data_count = 0; - _frozen = other->_frozen; - - layer_op_counter = other->layer_op_counter; - freeze_length = other->freeze_length; -} - -Playlist::Playlist (boost::shared_ptr<const Playlist> other, nframes_t start, nframes_t cnt, string str, bool hide) - : SessionObject(other->_session, str), _type(other->_type), _orig_diskstream_id(other->_orig_diskstream_id) -{ - RegionLock rlock2 (const_cast<Playlist*> (other.get())); - - nframes_t end = start + cnt - 1; - - init (hide); - - in_set_state++; - - for (RegionList::const_iterator i = other->regions.begin(); i != other->regions.end(); i++) { - - boost::shared_ptr<Region> region; - boost::shared_ptr<Region> new_region; - nframes_t offset = 0; - nframes_t position = 0; - nframes_t len = 0; - string new_name; - OverlapType overlap; - - region = *i; - - overlap = region->coverage (start, end); - - switch (overlap) { - case OverlapNone: - continue; - - case OverlapInternal: - offset = start - region->position(); - position = 0; - len = cnt; - break; - - case OverlapStart: - offset = 0; - position = region->position() - start; - len = end - region->position(); - break; - - case OverlapEnd: - offset = start - region->position(); - position = 0; - len = region->length() - offset; - break; - - case OverlapExternal: - offset = 0; - position = region->position() - start; - len = region->length(); - break; - } - - _session.region_name (new_name, region->name(), false); - - new_region = RegionFactory::RegionFactory::create (region, offset, len, new_name, region->layer(), region->flags()); - - add_region_internal (new_region, position); - } - - in_set_state--; - first_set_state = false; - - /* this constructor does NOT notify others (session) */ -} - -void -Playlist::use () -{ - ++_refcnt; - InUse (true); /* EMIT SIGNAL */ -} - -void -Playlist::release () -{ - if (_refcnt > 0) { - _refcnt--; - } - - if (_refcnt == 0) { - InUse (false); /* EMIT SIGNAL */ - } -} - -void -Playlist::copy_regions (RegionList& newlist) const -{ - RegionLock rlock (const_cast<Playlist *> (this)); - - for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) { - newlist.push_back (RegionFactory::RegionFactory::create (*i)); - } -} - -void -Playlist::init (bool hide) -{ - g_atomic_int_set (&block_notifications, 0); - g_atomic_int_set (&ignore_state_changes, 0); - pending_modified = false; - pending_length = false; - first_set_state = true; - _refcnt = 0; - _hidden = hide; - _splicing = false; - _shuffling = false; - _nudging = false; - in_set_state = 0; - _edit_mode = Config->get_edit_mode(); - in_flush = false; - in_partition = false; - subcnt = 0; - _read_data_count = 0; - _frozen = false; - layer_op_counter = 0; - freeze_length = 0; - - Modified.connect (mem_fun (*this, &Playlist::mark_session_dirty)); -} - -Playlist::Playlist (const Playlist& pl) - : SessionObject(pl._session, pl._name) - , _type(pl.data_type()) -{ - fatal << _("playlist const copy constructor called") << endmsg; -} - -Playlist::Playlist (Playlist& pl) - : SessionObject(pl._session, pl._name) - , _type(pl.data_type()) -{ - fatal << _("playlist non-const copy constructor called") << endmsg; -} - -Playlist::~Playlist () -{ - { - RegionLock rl (this); - - for (set<boost::shared_ptr<Region> >::iterator i = all_regions.begin(); i != all_regions.end(); ++i) { - (*i)->set_playlist (boost::shared_ptr<Playlist>()); - } - } - - /* GoingAway must be emitted by derived classes */ -} - -bool -Playlist::set_name (const string& str) -{ - /* in a typical situation, a playlist is being used - by one diskstream and also is referenced by the - Session. if there are more references than that, - then don't change the name. - */ - - if (_refcnt > 2) { - return false; - } else { - return SessionObject::set_name(str); - } -} - -/*********************************************************************** - CHANGE NOTIFICATION HANDLING - - Notifications must be delayed till the region_lock is released. This - is necessary because handlers for the signals may need to acquire - the lock (e.g. to read from the playlist). - ***********************************************************************/ - -void -Playlist::freeze () -{ - delay_notifications (); - g_atomic_int_inc (&ignore_state_changes); -} - -void -Playlist::thaw () -{ - g_atomic_int_dec_and_test (&ignore_state_changes); - release_notifications (); -} - - -void -Playlist::delay_notifications () -{ - g_atomic_int_inc (&block_notifications); - freeze_length = _get_maximum_extent(); -} - -void -Playlist::release_notifications () -{ - if (g_atomic_int_dec_and_test (&block_notifications)) { - flush_notifications (); - } -} - -void -Playlist::notify_modified () -{ - if (holding_state ()) { - pending_modified = true; - } else { - pending_modified = false; - Modified(); /* EMIT SIGNAL */ - } -} - -void -Playlist::notify_region_removed (boost::shared_ptr<Region> r) -{ - if (holding_state ()) { - pending_removes.insert (r); - pending_modified = true; - pending_length = true; - } else { - /* this might not be true, but we have to act - as though it could be. - */ - pending_length = false; - LengthChanged (); /* EMIT SIGNAL */ - pending_modified = false; - Modified (); /* EMIT SIGNAL */ - } -} - -void -Playlist::notify_region_added (boost::shared_ptr<Region> r) -{ - /* the length change might not be true, but we have to act - as though it could be. - */ - - if (holding_state()) { - pending_adds.insert (r); - pending_modified = true; - pending_length = true; - } else { - pending_length = false; - LengthChanged (); /* EMIT SIGNAL */ - pending_modified = false; - Modified (); /* EMIT SIGNAL */ - } -} - -void -Playlist::notify_length_changed () -{ - if (holding_state ()) { - pending_length = true; - } else { - pending_length = false; - LengthChanged(); /* EMIT SIGNAL */ - pending_modified = false; - Modified (); /* EMIT SIGNAL */ - } -} - -void -Playlist::flush_notifications () -{ - set<boost::shared_ptr<Region> > dependent_checks_needed; - set<boost::shared_ptr<Region> >::iterator s; - uint32_t n = 0; - - if (in_flush) { - return; - } - - in_flush = true; - - /* we have no idea what order the regions ended up in pending - bounds (it could be based on selection order, for example). - so, to preserve layering in the "most recently moved is higher" - model, sort them by existing layer, then timestamp them. - */ - - // RegionSortByLayer cmp; - // pending_bounds.sort (cmp); - - for (RegionList::iterator r = pending_bounds.begin(); r != pending_bounds.end(); ++r) { - if (Config->get_layer_model() == MoveAddHigher) { - timestamp_layer_op (*r); - } - pending_length = true; - dependent_checks_needed.insert (*r); - n++; - } - - for (s = pending_adds.begin(); s != pending_adds.end(); ++s) { - dependent_checks_needed.insert (*s); - n++; - } - - for (s = pending_removes.begin(); s != pending_removes.end(); ++s) { - remove_dependents (*s); - n++; - } - - if ((freeze_length != _get_maximum_extent()) || pending_length) { - pending_length = 0; - LengthChanged(); /* EMIT SIGNAL */ - n++; - } - - if (n || pending_modified) { - if (!in_set_state) { - relayer (); - } - pending_modified = false; - Modified (); /* EMIT SIGNAL */ - - } - - for (s = dependent_checks_needed.begin(); s != dependent_checks_needed.end(); ++s) { - check_dependents (*s, false); - } - - pending_adds.clear (); - pending_removes.clear (); - pending_bounds.clear (); - - in_flush = false; -} - -/************************************************************* - PLAYLIST OPERATIONS - *************************************************************/ - -void -Playlist::add_region (boost::shared_ptr<Region> region, nframes_t position, float times) -{ - RegionLock rlock (this); - delay_notifications(); - times = fabs (times); - - int itimes = (int) floor (times); - - nframes_t pos = position; - - if (itimes >= 1) { - add_region_internal (region, pos); - pos += region->length(); - --itimes; - } - - - /* note that itimes can be zero if we being asked to just - insert a single fraction of the region. - */ - - for (int i = 0; i < itimes; ++i) { - boost::shared_ptr<Region> copy = RegionFactory::create (region); - add_region_internal (copy, pos); - pos += region->length(); - } - - nframes_t length = 0; - - if (floor (times) != times) { - length = (nframes_t) floor (region->length() * (times - floor (times))); - string name; - _session.region_name (name, region->name(), false); - boost::shared_ptr<Region> sub = RegionFactory::create (region, 0, length, name, region->layer(), region->flags()); - add_region_internal (sub, pos); - } - - - possibly_splice_unlocked (position, (pos + length) - position, boost::shared_ptr<Region>()); - release_notifications (); -} - -void -Playlist::set_region_ownership () -{ - RegionLock rl (this); - RegionList::iterator i; - boost::weak_ptr<Playlist> pl (shared_from_this()); - - for (i = regions.begin(); i != regions.end(); ++i) { - (*i)->set_playlist (pl); - } -} - -void -Playlist::add_region_internal (boost::shared_ptr<Region> region, nframes_t position) -{ - assert(region->data_type() == _type); - - RegionSortByPosition cmp; - nframes_t old_length = 0; - - if (!holding_state()) { - old_length = _get_maximum_extent(); - } - - if (!first_set_state) { - boost::shared_ptr<Playlist> foo (shared_from_this()); - region->set_playlist (boost::weak_ptr<Playlist>(foo)); - } - - region->set_position (position, this); - - timestamp_layer_op (region); - - regions.insert (upper_bound (regions.begin(), regions.end(), region, cmp), region); - all_regions.insert (region); - - possibly_splice_unlocked (position, region->length(), region); - - if (!holding_state () && !in_set_state) { - /* layers get assigned from XML state */ - relayer (); - } - - /* we need to notify the existence of new region before checking dependents. Ick. */ - - notify_region_added (region); - - if (!holding_state ()) { - check_dependents (region, false); - if (old_length != _get_maximum_extent()) { - notify_length_changed (); - } - } - - region->StateChanged.connect (sigc::bind (mem_fun (this, &Playlist::region_changed_proxy), - boost::weak_ptr<Region> (region))); -} - -void -Playlist::replace_region (boost::shared_ptr<Region> old, boost::shared_ptr<Region> newr, nframes_t pos) -{ - RegionLock rlock (this); - - bool old_sp = _splicing; - _splicing = true; - - remove_region_internal (old); - add_region_internal (newr, pos); - - _splicing = old_sp; - - possibly_splice_unlocked (pos, (nframes64_t) old->length() - (nframes64_t) newr->length()); -} - -void -Playlist::remove_region (boost::shared_ptr<Region> region) -{ - RegionLock rlock (this); - remove_region_internal (region); -} - -int -Playlist::remove_region_internal (boost::shared_ptr<Region> region) -{ - RegionList::iterator i; - nframes_t old_length = 0; - - if (!holding_state()) { - old_length = _get_maximum_extent(); - } - - if (!in_set_state) { - /* unset playlist */ - region->set_playlist (boost::weak_ptr<Playlist>()); - } - - for (i = regions.begin(); i != regions.end(); ++i) { - if (*i == region) { - - nframes_t pos = (*i)->position(); - nframes64_t distance = (*i)->length(); - - regions.erase (i); - - possibly_splice_unlocked (pos, -distance); - - if (!holding_state ()) { - relayer (); - remove_dependents (region); - - if (old_length != _get_maximum_extent()) { - notify_length_changed (); - } - } - - notify_region_removed (region); - return 0; - } - } - - - - return -1; -} - -void -Playlist::get_equivalent_regions (boost::shared_ptr<Region> other, vector<boost::shared_ptr<Region> >& results) -{ - if (Config->get_use_overlap_equivalency()) { - for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { - if ((*i)->overlap_equivalent (other)) { - results.push_back ((*i)); - } - } - } else { - for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { - if ((*i)->equivalent (other)) { - results.push_back ((*i)); - } - } - } -} - -void -Playlist::get_region_list_equivalent_regions (boost::shared_ptr<Region> other, vector<boost::shared_ptr<Region> >& results) -{ - for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { - - if ((*i) && (*i)->region_list_equivalent (other)) { - results.push_back (*i); - } - } -} - -void -Playlist::partition (nframes_t start, nframes_t end, bool just_top_level) -{ - RegionList thawlist; - - partition_internal (start, end, false, thawlist); - - for (RegionList::iterator i = thawlist.begin(); i != thawlist.end(); ++i) { - (*i)->thaw ("separation"); - } -} - -void -Playlist::partition_internal (nframes_t start, nframes_t end, bool cutting, RegionList& thawlist) -{ - RegionList new_regions; - - { - RegionLock rlock (this); - boost::shared_ptr<Region> region; - boost::shared_ptr<Region> current; - string new_name; - RegionList::iterator tmp; - OverlapType overlap; - nframes_t pos1, pos2, pos3, pos4; - - in_partition = true; - - /* need to work from a copy, because otherwise the regions we add during the process - get operated on as well. - */ - - RegionList copy = regions; - - for (RegionList::iterator i = copy.begin(); i != copy.end(); i = tmp) { - - tmp = i; - ++tmp; - - current = *i; - - if (current->first_frame() >= start && current->last_frame() < end) { - if (cutting) { - remove_region_internal (current); - } - continue; - } - - /* coverage will return OverlapStart if the start coincides - with the end point. we do not partition such a region, - so catch this special case. - */ - - if (current->first_frame() >= end) { - continue; - } - - if ((overlap = current->coverage (start, end)) == OverlapNone) { - continue; - } - - pos1 = current->position(); - pos2 = start; - pos3 = end; - pos4 = current->last_frame(); - - if (overlap == OverlapInternal) { - - /* split: we need 3 new regions, the front, middle and end. - cut: we need 2 regions, the front and end. - */ - - /* - start end - ---------------*************************------------ - P1 P2 P3 P4 - SPLIT: - ---------------*****++++++++++++++++====------------ - CUT - ---------------*****----------------====------------ - - */ - - if (!cutting) { - - /* "middle" ++++++ */ - - _session.region_name (new_name, current->name(), false); - region = RegionFactory::create (current, pos2 - pos1, pos3 - pos2, new_name, - regions.size(), Region::Flag(current->flags()|Region::Automatic|Region::LeftOfSplit|Region::RightOfSplit)); - add_region_internal (region, start); - new_regions.push_back (region); - } - - /* "end" ====== */ - - _session.region_name (new_name, current->name(), false); - region = RegionFactory::create (current, pos3 - pos1, pos4 - pos3, new_name, - regions.size(), Region::Flag(current->flags()|Region::Automatic|Region::RightOfSplit)); - - add_region_internal (region, end); - new_regions.push_back (region); - - /* "front" ***** */ - - current->freeze (); - thawlist.push_back (current); - current->trim_end (pos2, this); - - } else if (overlap == OverlapEnd) { - - /* - start end - ---------------*************************------------ - P1 P2 P4 P3 - SPLIT: - ---------------**************+++++++++++------------ - CUT: - ---------------**************----------------------- - */ - - if (!cutting) { - - /* end +++++ */ - - _session.region_name (new_name, current->name(), false); - region = RegionFactory::create (current, pos2 - pos1, pos4 - pos2, new_name, (layer_t) regions.size(), - Region::Flag(current->flags()|Region::Automatic|Region::LeftOfSplit)); - add_region_internal (region, start); - new_regions.push_back (region); - } - - /* front ****** */ - - current->freeze (); - thawlist.push_back (current); - current->trim_end (pos2, this); - - } else if (overlap == OverlapStart) { - - /* split: we need 2 regions: the front and the end. - cut: just trim current to skip the cut area - */ - - /* - start end - ---------------*************************------------ - P2 P1 P3 P4 - - SPLIT: - ---------------****+++++++++++++++++++++------------ - CUT: - -------------------*********************------------ - - */ - - if (!cutting) { - - /* front **** */ - _session.region_name (new_name, current->name(), false); - region = RegionFactory::create (current, 0, pos3 - pos1, new_name, - regions.size(), Region::Flag(current->flags()|Region::Automatic|Region::RightOfSplit)); - add_region_internal (region, pos1); - new_regions.push_back (region); - } - - /* end */ - - current->freeze (); - thawlist.push_back (current); - current->trim_front (pos3, this); - - } else if (overlap == OverlapExternal) { - - /* split: no split required. - cut: remove the region. - */ - - /* - start end - ---------------*************************------------ - P2 P1 P3 P4 - - SPLIT: - ---------------*************************------------ - CUT: - ---------------------------------------------------- - - */ - - if (cutting) { - remove_region_internal (current); - } - new_regions.push_back (current); - } - } - - in_partition = false; - } - - for (RegionList::iterator i = new_regions.begin(); i != new_regions.end(); ++i) { - check_dependents (*i, false); - } -} - -boost::shared_ptr<Playlist> -Playlist::cut_copy (boost::shared_ptr<Playlist> (Playlist::*pmf)(nframes_t, nframes_t,bool), list<AudioRange>& ranges, bool result_is_hidden) -{ - boost::shared_ptr<Playlist> ret; - boost::shared_ptr<Playlist> pl; - nframes_t start; - - if (ranges.empty()) { - return boost::shared_ptr<Playlist>(); - } - - start = ranges.front().start; - - for (list<AudioRange>::iterator i = ranges.begin(); i != ranges.end(); ++i) { - - pl = (this->*pmf)((*i).start, (*i).length(), result_is_hidden); - - if (i == ranges.begin()) { - ret = pl; - } else { - - /* paste the next section into the nascent playlist, - offset to reflect the start of the first range we - chopped. - */ - - ret->paste (pl, (*i).start - start, 1.0f); - } - } - - return ret; -} - -boost::shared_ptr<Playlist> -Playlist::cut (list<AudioRange>& ranges, bool result_is_hidden) -{ - boost::shared_ptr<Playlist> (Playlist::*pmf)(nframes_t,nframes_t,bool) = &Playlist::cut; - return cut_copy (pmf, ranges, result_is_hidden); -} - -boost::shared_ptr<Playlist> -Playlist::copy (list<AudioRange>& ranges, bool result_is_hidden) -{ - boost::shared_ptr<Playlist> (Playlist::*pmf)(nframes_t,nframes_t,bool) = &Playlist::copy; - return cut_copy (pmf, ranges, result_is_hidden); -} - -boost::shared_ptr<Playlist> -Playlist::cut (nframes_t start, nframes_t cnt, bool result_is_hidden) -{ - boost::shared_ptr<Playlist> the_copy; - RegionList thawlist; - char buf[32]; - - snprintf (buf, sizeof (buf), "%" PRIu32, ++subcnt); - string new_name = _name; - new_name += '.'; - new_name += buf; - - if ((the_copy = PlaylistFactory::create (shared_from_this(), start, cnt, new_name, result_is_hidden)) == 0) { - return boost::shared_ptr<Playlist>(); - } - - partition_internal (start, start+cnt-1, true, thawlist); - - for (RegionList::iterator i = thawlist.begin(); i != thawlist.end(); ++i) { - (*i)->thaw ("playlist cut"); - } - - return the_copy; -} - -boost::shared_ptr<Playlist> -Playlist::copy (nframes_t start, nframes_t cnt, bool result_is_hidden) -{ - char buf[32]; - - snprintf (buf, sizeof (buf), "%" PRIu32, ++subcnt); - string new_name = _name; - new_name += '.'; - new_name += buf; - - cnt = min (_get_maximum_extent() - start, cnt); - return PlaylistFactory::create (shared_from_this(), start, cnt, new_name, result_is_hidden); -} - -int -Playlist::paste (boost::shared_ptr<Playlist> other, nframes_t position, float times) -{ - times = fabs (times); - nframes_t old_length; - - { - RegionLock rl1 (this); - RegionLock rl2 (other.get()); - - old_length = _get_maximum_extent(); - - int itimes = (int) floor (times); - nframes_t pos = position; - nframes_t shift = other->_get_maximum_extent(); - layer_t top_layer = regions.size(); - - while (itimes--) { - for (RegionList::iterator i = other->regions.begin(); i != other->regions.end(); ++i) { - boost::shared_ptr<Region> copy_of_region = RegionFactory::create (*i); - - /* put these new regions on top of all existing ones, but preserve - the ordering they had in the original playlist. - */ - - copy_of_region->set_layer (copy_of_region->layer() + top_layer); - add_region_internal (copy_of_region, copy_of_region->position() + pos); - } - pos += shift; - } - - - /* XXX shall we handle fractional cases at some point? */ - - if (old_length != _get_maximum_extent()) { - notify_length_changed (); - } - - - } - - return 0; -} - - -void -Playlist::duplicate (boost::shared_ptr<Region> region, nframes_t position, float times) -{ - times = fabs (times); - - RegionLock rl (this); - int itimes = (int) floor (times); - nframes_t pos = position; - - while (itimes--) { - boost::shared_ptr<Region> copy = RegionFactory::create (region); - add_region_internal (copy, pos); - pos += region->length(); - } - - if (floor (times) != times) { - nframes_t length = (nframes_t) floor (region->length() * (times - floor (times))); - string name; - _session.region_name (name, region->name(), false); - boost::shared_ptr<Region> sub = RegionFactory::create (region, 0, length, name, region->layer(), region->flags()); - add_region_internal (sub, pos); - } -} - -void -Playlist::shift (nframes64_t at, nframes64_t distance, bool move_intersected, bool ignore_music_glue) -{ - RegionLock rlock (this); - RegionList copy (regions); - RegionList fixup; - - for (RegionList::iterator r = copy.begin(); r != copy.end(); ++r) { - - if ((*r)->last_frame() < at) { - /* too early */ - continue; - } - - if (at > (*r)->first_frame() && at < (*r)->last_frame()) { - /* intersected region */ - if (!move_intersected) { - continue; - } - } - - /* do not move regions glued to music time - that - has to be done separately. - */ - - if (!ignore_music_glue && (*r)->positional_lock_style() != Region::AudioTime) { - fixup.push_back (*r); - continue; - } - - (*r)->set_position ((*r)->position() + distance, this); - } - - for (RegionList::iterator r = fixup.begin(); r != fixup.end(); ++r) { - (*r)->recompute_position_from_lock_style (); - } -} - -void -Playlist::split (nframes64_t at) -{ - RegionLock rlock (this); - RegionList copy (regions); - - /* use a copy since this operation can modify the region list - */ - - for (RegionList::iterator r = copy.begin(); r != copy.end(); ++r) { - _split_region (*r, at); - } -} - -void -Playlist::split_region (boost::shared_ptr<Region> region, nframes_t playlist_position) -{ - RegionLock rl (this); - _split_region (region, playlist_position); -} - -void -Playlist::_split_region (boost::shared_ptr<Region> region, nframes_t playlist_position) -{ - if (!region->covers (playlist_position)) { - return; - } - - if (region->position() == playlist_position || - region->last_frame() == playlist_position) { - return; - } - - boost::shared_ptr<Region> left; - boost::shared_ptr<Region> right; - nframes_t before; - nframes_t after; - string before_name; - string after_name; - - /* split doesn't change anything about length, so don't try to splice */ - - bool old_sp = _splicing; - _splicing = true; - - before = playlist_position - region->position(); - after = region->length() - before; - - _session.region_name (before_name, region->name(), false); - left = RegionFactory::create (region, 0, before, before_name, region->layer(), Region::Flag (region->flags()|Region::LeftOfSplit)); - - _session.region_name (after_name, region->name(), false); - right = RegionFactory::create (region, before, after, after_name, region->layer(), Region::Flag (region->flags()|Region::RightOfSplit)); - - add_region_internal (left, region->position()); - add_region_internal (right, region->position() + before); - - uint64_t orig_layer_op = region->last_layer_op(); - for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { - if ((*i)->last_layer_op() > orig_layer_op) { - (*i)->set_last_layer_op( (*i)->last_layer_op() + 1 ); - } - } - - left->set_last_layer_op ( orig_layer_op ); - right->set_last_layer_op ( orig_layer_op + 1); - - layer_op_counter++; - - finalize_split_region (region, left, right); - - remove_region_internal (region); - - _splicing = old_sp; -} - -void -Playlist::possibly_splice (nframes_t at, nframes64_t distance, boost::shared_ptr<Region> exclude) -{ - if (_splicing || in_set_state) { - /* don't respond to splicing moves or state setting */ - return; - } - - if (_edit_mode == Splice) { - splice_locked (at, distance, exclude); - } -} - -void -Playlist::possibly_splice_unlocked (nframes_t at, nframes64_t distance, boost::shared_ptr<Region> exclude) -{ - if (_splicing || in_set_state) { - /* don't respond to splicing moves or state setting */ - return; - } - - if (_edit_mode == Splice) { - splice_unlocked (at, distance, exclude); - } -} - -void -Playlist::splice_locked (nframes_t at, nframes64_t distance, boost::shared_ptr<Region> exclude) -{ - { - RegionLock rl (this); - core_splice (at, distance, exclude); - } -} - -void -Playlist::splice_unlocked (nframes_t at, nframes64_t distance, boost::shared_ptr<Region> exclude) -{ - core_splice (at, distance, exclude); -} - -void -Playlist::core_splice (nframes_t at, nframes64_t distance, boost::shared_ptr<Region> exclude) -{ - _splicing = true; - - for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { - - if (exclude && (*i) == exclude) { - continue; - } - - if ((*i)->position() >= at) { - nframes64_t new_pos = (*i)->position() + distance; - if (new_pos < 0) { - new_pos = 0; - } else if (new_pos >= max_frames - (*i)->length()) { - new_pos = max_frames - (*i)->length(); - } - - (*i)->set_position (new_pos, this); - } - } - - _splicing = false; - - notify_length_changed (); -} - -void -Playlist::region_bounds_changed (Change what_changed, boost::shared_ptr<Region> region) -{ - if (in_set_state || _splicing || _nudging || _shuffling) { - return; - } - - if (what_changed & ARDOUR::PositionChanged) { - - /* remove it from the list then add it back in - the right place again. - */ - - RegionSortByPosition cmp; - - RegionList::iterator i = find (regions.begin(), regions.end(), region); - - if (i == regions.end()) { - warning << string_compose (_("%1: bounds changed received for region (%2)not in playlist"), - _name, region->name()) - << endmsg; - return; - } - - regions.erase (i); - regions.insert (upper_bound (regions.begin(), regions.end(), region, cmp), region); - } - - if (what_changed & Change (ARDOUR::PositionChanged|ARDOUR::LengthChanged)) { - - nframes64_t delta = 0; - - if (what_changed & ARDOUR::PositionChanged) { - delta = (nframes64_t) region->position() - (nframes64_t) region->last_position(); - } - - if (what_changed & ARDOUR::LengthChanged) { - delta += (nframes64_t) region->length() - (nframes64_t) region->last_length(); - } - - if (delta) { - possibly_splice (region->last_position() + region->last_length(), delta, region); - } - - if (holding_state ()) { - pending_bounds.push_back (region); - } else { - if (Config->get_layer_model() == MoveAddHigher) { - /* it moved or changed length, so change the timestamp */ - timestamp_layer_op (region); - } - - notify_length_changed (); - relayer (); - check_dependents (region, false); - } - } -} - -void -Playlist::region_changed_proxy (Change what_changed, boost::weak_ptr<Region> weak_region) -{ - boost::shared_ptr<Region> region (weak_region.lock()); - - if (!region) { - return; - } - - - /* this makes a virtual call to the right kind of playlist ... */ - - region_changed (what_changed, region); -} - -bool -Playlist::region_changed (Change what_changed, boost::shared_ptr<Region> region) -{ - Change our_interests = Change (Region::MuteChanged|Region::LayerChanged|Region::OpacityChanged); - bool save = false; - - if (in_set_state || in_flush) { - return false; - } - - { - if (what_changed & BoundsChanged) { - region_bounds_changed (what_changed, region); - save = !(_splicing || _nudging); - } - - if ((what_changed & our_interests) && - !(what_changed & Change (ARDOUR::PositionChanged|ARDOUR::LengthChanged))) { - check_dependents (region, false); - } - - if (what_changed & our_interests) { - save = true; - } - } - - return save; -} - -void -Playlist::drop_regions () -{ - RegionLock rl (this); - regions.clear (); - all_regions.clear (); -} - -void -Playlist::clear (bool with_signals) -{ - { - RegionLock rl (this); - for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { - pending_removes.insert (*i); - } - regions.clear (); - } - - if (with_signals) { - pending_length = false; - LengthChanged (); - pending_modified = false; - Modified (); - } - -} - -/*********************************************************************** - FINDING THINGS - **********************************************************************/ - -Playlist::RegionList * -Playlist::regions_at (nframes_t frame) - -{ - RegionLock rlock (this); - return find_regions_at (frame); -} - -boost::shared_ptr<Region> -Playlist::top_region_at (nframes_t frame) - -{ - RegionLock rlock (this); - RegionList *rlist = find_regions_at (frame); - boost::shared_ptr<Region> region; - - if (rlist->size()) { - RegionSortByLayer cmp; - rlist->sort (cmp); - region = rlist->back(); - } - - delete rlist; - return region; -} - -Playlist::RegionList* -Playlist::regions_to_read (nframes_t start, nframes_t end) -{ - /* Caller must hold lock */ - - RegionList covering; - set<nframes_t> to_check; - set<boost::shared_ptr<Region> > unique; - RegionList here; - - to_check.insert (start); - to_check.insert (end); - - for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { - - /* find all/any regions that span start+end */ - - switch ((*i)->coverage (start, end)) { - case OverlapNone: - break; - - case OverlapInternal: - covering.push_back (*i); - break; - - case OverlapStart: - to_check.insert ((*i)->position()); - covering.push_back (*i); - break; - - case OverlapEnd: - to_check.insert ((*i)->last_frame()); - covering.push_back (*i); - break; - - case OverlapExternal: - covering.push_back (*i); - to_check.insert ((*i)->position()); - to_check.insert ((*i)->last_frame()); - break; - } - - /* don't go too far */ - - if ((*i)->position() > end) { - break; - } - } - - RegionList* rlist = new RegionList; - - /* find all the regions that cover each position .... */ - - if (covering.size() == 1) { - - rlist->push_back (covering.front()); - - } else { - - for (set<nframes_t>::iterator t = to_check.begin(); t != to_check.end(); ++t) { - - here.clear (); - - for (RegionList::iterator x = covering.begin(); x != covering.end(); ++x) { - - if ((*x)->covers (*t)) { - here.push_back (*x); - } - } - - RegionSortByLayer cmp; - here.sort (cmp); - - /* ... and get the top/transparent regions at "here" */ - - for (RegionList::reverse_iterator c = here.rbegin(); c != here.rend(); ++c) { - - unique.insert (*c); - - if ((*c)->opaque()) { - - /* the other regions at this position are hidden by this one */ - - break; - } - } - } - - for (set<boost::shared_ptr<Region> >::iterator s = unique.begin(); s != unique.end(); ++s) { - rlist->push_back (*s); - } - - if (rlist->size() > 1) { - /* now sort by time order */ - - RegionSortByPosition cmp; - rlist->sort (cmp); - } - } - - return rlist; -} - -Playlist::RegionList * -Playlist::find_regions_at (nframes_t frame) -{ - /* Caller must hold lock */ - - RegionList *rlist = new RegionList; - - for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { - if ((*i)->covers (frame)) { - rlist->push_back (*i); - } - } - - return rlist; -} - -Playlist::RegionList * -Playlist::regions_touched (nframes_t start, nframes_t end) -{ - RegionLock rlock (this); - RegionList *rlist = new RegionList; - - for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { - if ((*i)->coverage (start, end) != OverlapNone) { - rlist->push_back (*i); - } - } - - return rlist; -} - -nframes64_t -Playlist::find_next_transient (nframes64_t from, int dir) -{ - RegionLock rlock (this); - AnalysisFeatureList points; - AnalysisFeatureList these_points; - - for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { - if (dir > 0) { - if ((*i)->last_frame() < from) { - continue; - } - } else { - if ((*i)->first_frame() > from) { - continue; - } - } - - (*i)->get_transients (these_points); - - /* add first frame, just, err, because */ - - these_points.push_back ((*i)->first_frame()); - - points.insert (points.end(), these_points.begin(), these_points.end()); - these_points.clear (); - } - - if (points.empty()) { - return -1; - } - - TransientDetector::cleanup_transients (points, _session.frame_rate(), 3.0); - bool reached = false; - - if (dir > 0) { - for (AnalysisFeatureList::iterator x = points.begin(); x != points.end(); ++x) { - if ((*x) >= from) { - reached = true; - } - - if (reached && (*x) > from) { - return *x; - } - } - } else { - for (AnalysisFeatureList::reverse_iterator x = points.rbegin(); x != points.rend(); ++x) { - if ((*x) <= from) { - reached = true; - } - - if (reached && (*x) < from) { - return *x; - } - } - } - - return -1; -} - -boost::shared_ptr<Region> -Playlist::find_next_region (nframes_t frame, RegionPoint point, int dir) -{ - RegionLock rlock (this); - boost::shared_ptr<Region> ret; - nframes_t closest = max_frames; - - - for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { - - nframes_t distance; - boost::shared_ptr<Region> r = (*i); - nframes_t pos = 0; - - switch (point) { - case Start: - pos = r->first_frame (); - break; - case End: - pos = r->last_frame (); - break; - case SyncPoint: - pos = r->adjust_to_sync (r->first_frame()); - break; - } - - switch (dir) { - case 1: /* forwards */ - - if (pos >= frame) { - if ((distance = pos - frame) < closest) { - closest = distance; - ret = r; - } - } - - break; - - default: /* backwards */ - - if (pos <= frame) { - if ((distance = frame - pos) < closest) { - closest = distance; - ret = r; - } - } - break; - } - } - - return ret; -} - -nframes64_t -Playlist::find_next_region_boundary (nframes64_t frame, int dir) -{ - RegionLock rlock (this); - - nframes64_t closest = max_frames; - nframes64_t ret = -1; - - if (dir > 0) { - - for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { - - boost::shared_ptr<Region> r = (*i); - nframes64_t distance; - nframes64_t end = r->position() + r->length(); - bool reset; - - reset = false; - - if (r->first_frame() > frame) { - - distance = r->first_frame() - frame; - - if (distance < closest) { - ret = r->first_frame(); - closest = distance; - reset = true; - } - } - - if (end > frame) { - - distance = end - frame; - - if (distance < closest) { - ret = end; - closest = distance; - reset = true; - } - } - - if (reset) { - break; - } - } - - } else { - - for (RegionList::reverse_iterator i = regions.rbegin(); i != regions.rend(); ++i) { - - boost::shared_ptr<Region> r = (*i); - nframes64_t distance; - bool reset; - - reset = false; - - if (r->last_frame() < frame) { - - distance = frame - r->last_frame(); - - if (distance < closest) { - ret = r->last_frame(); - closest = distance; - reset = true; - } - } - - if (r->first_frame() < frame) { - distance = frame - r->last_frame(); - - if (distance < closest) { - ret = r->first_frame(); - closest = distance; - reset = true; - } - } - - if (reset) { - break; - } - } - } - - return ret; -} - -/***********************************************************************/ - - - -void -Playlist::mark_session_dirty () -{ - if (!in_set_state && !holding_state ()) { - _session.set_dirty(); - } -} - -int -Playlist::set_state (const XMLNode& node) -{ - XMLNode *child; - XMLNodeList nlist; - XMLNodeConstIterator niter; - XMLPropertyList plist; - XMLPropertyConstIterator piter; - XMLProperty *prop; - boost::shared_ptr<Region> region; - string region_name; - - in_set_state++; - - if (node.name() != "Playlist") { - in_set_state--; - return -1; - } - - freeze (); - - plist = node.properties(); - - for (piter = plist.begin(); piter != plist.end(); ++piter) { - - prop = *piter; - - if (prop->name() == X_("name")) { - _name = prop->value(); - } else if (prop->name() == X_("orig_diskstream_id")) { - _orig_diskstream_id = prop->value (); - } else if (prop->name() == X_("frozen")) { - _frozen = (prop->value() == X_("yes")); - } - } - - clear (false); - - nlist = node.children(); - - for (niter = nlist.begin(); niter != nlist.end(); ++niter) { - - child = *niter; - - if (child->name() == "Region") { - - if ((prop = child->property ("id")) == 0) { - error << _("region state node has no ID, ignored") << endmsg; - continue; - } - - ID id = prop->value (); - - if ((region = region_by_id (id))) { - - Change what_changed = Change (0); - - if (region->set_live_state (*child, what_changed, true)) { - error << _("Playlist: cannot reset region state from XML") << endmsg; - continue; - } - - } else if ((region = RegionFactory::create (_session, *child, true)) == 0) { - error << _("Playlist: cannot create region from XML") << endmsg; - continue; - } - - add_region (region, region->position(), 1.0); - - // So that layer_op ordering doesn't get screwed up - region->set_last_layer_op( region->layer()); - - } - } - - notify_modified (); - - thaw (); - - /* update dependents, which was not done during add_region_internal - due to in_set_state being true - */ - - for (RegionList::iterator r = regions.begin(); r != regions.end(); ++r) { - check_dependents (*r, false); - } - - in_set_state--; - first_set_state = false; - return 0; -} - -XMLNode& -Playlist::get_state() -{ - return state(true); -} - -XMLNode& -Playlist::get_template() -{ - return state(false); -} - -XMLNode& -Playlist::state (bool full_state) -{ - XMLNode *node = new XMLNode (X_("Playlist")); - char buf[64]; - - node->add_property (X_("name"), _name); - node->add_property (X_("type"), _type.to_string()); - - _orig_diskstream_id.print (buf, sizeof (buf)); - node->add_property (X_("orig_diskstream_id"), buf); - node->add_property (X_("frozen"), _frozen ? "yes" : "no"); - - if (full_state) { - RegionLock rlock (this, false); - for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { - node->add_child_nocopy ((*i)->get_state()); - } - } - - if (_extra_xml) { - node->add_child_copy (*_extra_xml); - } - - return *node; -} - -bool -Playlist::empty() const -{ - RegionLock rlock (const_cast<Playlist *>(this), false); - return regions.empty(); -} - -uint32_t -Playlist::n_regions() const -{ - RegionLock rlock (const_cast<Playlist *>(this), false); - return regions.size(); -} - -nframes_t -Playlist::get_maximum_extent () const -{ - RegionLock rlock (const_cast<Playlist *>(this), false); - return _get_maximum_extent (); -} - -ARDOUR::nframes_t -Playlist::_get_maximum_extent () const -{ - RegionList::const_iterator i; - nframes_t max_extent = 0; - nframes_t end = 0; - - for (i = regions.begin(); i != regions.end(); ++i) { - if ((end = (*i)->position() + (*i)->length()) > max_extent) { - max_extent = end; - } - } - - return max_extent; -} - -string -Playlist::bump_name (string name, Session &session) -{ - string newname = name; - - do { - newname = bump_name_once (newname); - } while (session.playlist_by_name (newname)!=NULL); - - return newname; -} - - -layer_t -Playlist::top_layer() const -{ - RegionLock rlock (const_cast<Playlist *> (this)); - layer_t top = 0; - - for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) { - top = max (top, (*i)->layer()); - } - return top; -} - -void -Playlist::set_edit_mode (EditMode mode) -{ - _edit_mode = mode; -} - -/******************** - * Region Layering - ********************/ - -void -Playlist::relayer () -{ - /* don't send multiple Modified notifications - when multiple regions are relayered. - */ - - freeze (); - - /* build up a new list of regions on each layer */ - - std::vector<RegionList> layers; - - /* we want to go through regions from desired lowest to desired highest layer, - which depends on the layer model - */ - - RegionList copy = regions; - - /* sort according to the model */ - - if (Config->get_layer_model() == MoveAddHigher || Config->get_layer_model() == AddHigher) { - RegionSortByLastLayerOp cmp; - copy.sort (cmp); - } - - for (RegionList::iterator i = copy.begin(); i != copy.end(); ++i) { - - /* find the lowest layer that this region can go on */ - size_t j = layers.size(); - while (j > 0) { - /* try layer j - 1; it can go on if it overlaps no other region - that is already on that layer - */ - RegionList::iterator k = layers[j - 1].begin(); - while (k != layers[j - 1].end()) { - if ((*k)->overlap_equivalent (*i)) { - break; - } - k++; - } - - if (k != layers[j - 1].end()) { - /* no overlap, so we can use this layer */ - break; - } - - j--; - } - - if (j == layers.size()) { - /* we need a new layer for this region */ - layers.push_back (RegionList ()); - } - - layers[j].push_back (*i); - } - - /* first pass: set up the layer numbers in the regions */ - for (size_t j = 0; j < layers.size(); ++j) { - for (RegionList::iterator i = layers[j].begin(); i != layers[j].end(); ++i) { - (*i)->set_layer (j); - } - } - - /* sending Modified means that various kinds of layering - models operate correctly at the GUI - level. slightly inefficient, but only slightly. - - We force a Modified signal here in case no layers actually - changed. - */ - - notify_modified (); - - thaw (); -} - -/* XXX these layer functions are all deprecated */ - -void -Playlist::raise_region (boost::shared_ptr<Region> region) -{ - uint32_t rsz = regions.size(); - layer_t target = region->layer() + 1U; - - if (target >= rsz) { - /* its already at the effective top */ - return; - } - - move_region_to_layer (target, region, 1); -} - -void -Playlist::lower_region (boost::shared_ptr<Region> region) -{ - if (region->layer() == 0) { - /* its already at the bottom */ - return; - } - - layer_t target = region->layer() - 1U; - - move_region_to_layer (target, region, -1); -} - -void -Playlist::raise_region_to_top (boost::shared_ptr<Region> region) -{ - /* does nothing useful if layering mode is later=higher */ - if ((Config->get_layer_model() == MoveAddHigher) || - (Config->get_layer_model() == AddHigher)) { - timestamp_layer_op (region); - relayer (); - } -} - -void -Playlist::lower_region_to_bottom (boost::shared_ptr<Region> region) -{ - /* does nothing useful if layering mode is later=higher */ - if ((Config->get_layer_model() == MoveAddHigher) || - (Config->get_layer_model() == AddHigher)) { - region->set_last_layer_op (0); - relayer (); - } -} - -int -Playlist::move_region_to_layer (layer_t target_layer, boost::shared_ptr<Region> region, int dir) -{ - RegionList::iterator i; - typedef pair<boost::shared_ptr<Region>,layer_t> LayerInfo; - list<LayerInfo> layerinfo; - layer_t dest; - - { - RegionLock rlock (const_cast<Playlist *> (this)); - - for (i = regions.begin(); i != regions.end(); ++i) { - - if (region == *i) { - continue; - } - - if (dir > 0) { - - /* region is moving up, move all regions on intermediate layers - down 1 - */ - - if ((*i)->layer() > region->layer() && (*i)->layer() <= target_layer) { - dest = (*i)->layer() - 1; - } else { - /* not affected */ - continue; - } - } else { - - /* region is moving down, move all regions on intermediate layers - up 1 - */ - - if ((*i)->layer() < region->layer() && (*i)->layer() >= target_layer) { - dest = (*i)->layer() + 1; - } else { - /* not affected */ - continue; - } - } - - LayerInfo newpair; - - newpair.first = *i; - newpair.second = dest; - - layerinfo.push_back (newpair); - } - } - - /* now reset the layers without holding the region lock */ - - for (list<LayerInfo>::iterator x = layerinfo.begin(); x != layerinfo.end(); ++x) { - x->first->set_layer (x->second); - } - - region->set_layer (target_layer); - -#if 0 - /* now check all dependents */ - - for (list<LayerInfo>::iterator x = layerinfo.begin(); x != layerinfo.end(); ++x) { - check_dependents (x->first, false); - } - - check_dependents (region, false); -#endif - - return 0; -} - -void -Playlist::nudge_after (nframes_t start, nframes_t distance, bool forwards) -{ - RegionList::iterator i; - nframes_t new_pos; - bool moved = false; - - _nudging = true; - - { - RegionLock rlock (const_cast<Playlist *> (this)); - - for (i = regions.begin(); i != regions.end(); ++i) { - - if ((*i)->position() >= start) { - - if (forwards) { - - if ((*i)->last_frame() > max_frames - distance) { - new_pos = max_frames - (*i)->length(); - } else { - new_pos = (*i)->position() + distance; - } - - } else { - - if ((*i)->position() > distance) { - new_pos = (*i)->position() - distance; - } else { - new_pos = 0; - } - } - - (*i)->set_position (new_pos, this); - moved = true; - } - } - } - - if (moved) { - _nudging = false; - notify_length_changed (); - } - -} - -boost::shared_ptr<Region> -Playlist::find_region (const ID& id) const -{ - RegionLock rlock (const_cast<Playlist*> (this)); - - /* searches all regions currently in use by the playlist */ - - for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) { - if ((*i)->id() == id) { - return *i; - } - } - - return boost::shared_ptr<Region> (); -} - -boost::shared_ptr<Region> -Playlist::region_by_id (ID id) -{ - /* searches all regions ever added to this playlist */ - - for (set<boost::shared_ptr<Region> >::iterator i = all_regions.begin(); i != all_regions.end(); ++i) { - if ((*i)->id() == id) { - return *i; - } - } - return boost::shared_ptr<Region> (); -} - -void -Playlist::dump () const -{ - boost::shared_ptr<Region> r; - - cerr << "Playlist \"" << _name << "\" " << endl - << regions.size() << " regions " - << endl; - - for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) { - r = *i; - cerr << " " << r->name() << " [" - << r->start() << "+" << r->length() - << "] at " - << r->position() - << " on layer " - << r->layer () - << endl; - } -} - -void -Playlist::set_frozen (bool yn) -{ - _frozen = yn; -} - -void -Playlist::timestamp_layer_op (boost::shared_ptr<Region> region) -{ -// struct timeval tv; -// gettimeofday (&tv, 0); - region->set_last_layer_op (++layer_op_counter); -} - - -void -Playlist::shuffle (boost::shared_ptr<Region> region, int dir) -{ - bool moved = false; - nframes_t new_pos; - - if (region->locked()) { - return; - } - - _shuffling = true; - - { - RegionLock rlock (const_cast<Playlist*> (this)); - - - if (dir > 0) { - - RegionList::iterator next; - - for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { - if ((*i) == region) { - next = i; - ++next; - - if (next != regions.end()) { - - if ((*next)->locked()) { - break; - } - - if ((*next)->position() != region->last_frame() + 1) { - /* they didn't used to touch, so after shuffle, - just have them swap positions. - */ - new_pos = (*next)->position(); - } else { - /* they used to touch, so after shuffle, - make sure they still do. put the earlier - region where the later one will end after - it is moved. - */ - new_pos = region->position() + (*next)->length(); - } - - (*next)->set_position (region->position(), this); - region->set_position (new_pos, this); - - /* avoid a full sort */ - - regions.erase (i); // removes the region from the list */ - next++; - regions.insert (next, region); // adds it back after next - - moved = true; - } - break; - } - } - } else { - - RegionList::iterator prev = regions.end(); - - for (RegionList::iterator i = regions.begin(); i != regions.end(); prev = i, ++i) { - if ((*i) == region) { - - if (prev != regions.end()) { - - if ((*prev)->locked()) { - break; - } - - if (region->position() != (*prev)->last_frame() + 1) { - /* they didn't used to touch, so after shuffle, - just have them swap positions. - */ - new_pos = region->position(); - } else { - /* they used to touch, so after shuffle, - make sure they still do. put the earlier - one where the later one will end after - */ - new_pos = (*prev)->position() + region->length(); - } - - region->set_position ((*prev)->position(), this); - (*prev)->set_position (new_pos, this); - - /* avoid a full sort */ - - regions.erase (i); // remove region - regions.insert (prev, region); // insert region before prev - - moved = true; - } - - break; - } - } - } - } - - _shuffling = false; - - if (moved) { - - relayer (); - check_dependents (region, false); - - notify_modified(); - } - -} - -bool -Playlist::region_is_shuffle_constrained (boost::shared_ptr<Region>) -{ - RegionLock rlock (const_cast<Playlist*> (this)); - - if (regions.size() > 1) { - return true; - } - - return false; -} - -void -Playlist::update_after_tempo_map_change () -{ - RegionLock rlock (const_cast<Playlist*> (this)); - RegionList copy (regions); - - freeze (); - - for (RegionList::iterator i = copy.begin(); i != copy.end(); ++i) { - (*i)->update_position_after_tempo_map_change (); - } - - thaw (); -} diff --git a/libs/ardour/playlist_factory.cc b/libs/ardour/playlist_factory.cc deleted file mode 100644 index a801bae76c..0000000000 --- a/libs/ardour/playlist_factory.cc +++ /dev/null @@ -1,111 +0,0 @@ -/* - 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. - -*/ - -#include <pbd/error.h> - -#include <ardour/playlist.h> -#include <ardour/audioplaylist.h> -#include <ardour/midi_playlist.h> -#include <ardour/playlist_factory.h> - -#include "i18n.h" - -using namespace ARDOUR; -using namespace PBD; - -sigc::signal<void,boost::shared_ptr<Playlist> > PlaylistFactory::PlaylistCreated; - -boost::shared_ptr<Playlist> -PlaylistFactory::create (Session& s, const XMLNode& node, bool hidden) -{ - const XMLProperty* type = node.property("type"); - - boost::shared_ptr<Playlist> pl; - - if ( !type || type->value() == "audio" ) - pl = boost::shared_ptr<Playlist> (new AudioPlaylist (s, node, hidden)); - else if ( type->value() == "midi" ) - pl = boost::shared_ptr<Playlist> (new MidiPlaylist (s, node, hidden)); - - pl->set_region_ownership (); - - if (pl && !hidden) { - PlaylistCreated (pl); - } - return pl; -} - -boost::shared_ptr<Playlist> -PlaylistFactory::create (DataType type, Session& s, string name, bool hidden) -{ - boost::shared_ptr<Playlist> pl; - - if (type == DataType::AUDIO) - pl = boost::shared_ptr<Playlist> (new AudioPlaylist (s, name, hidden)); - else if (type == DataType::MIDI) - pl = boost::shared_ptr<Playlist> (new MidiPlaylist (s, name, hidden)); - - if (pl && !hidden) { - PlaylistCreated (pl); - } - - return pl; -} - -boost::shared_ptr<Playlist> -PlaylistFactory::create (boost::shared_ptr<const Playlist> old, string name, bool hidden) -{ - boost::shared_ptr<Playlist> pl; - boost::shared_ptr<const AudioPlaylist> apl; - boost::shared_ptr<const MidiPlaylist> mpl; - - if ((apl = boost::dynamic_pointer_cast<const AudioPlaylist> (old)) != 0) { - pl = boost::shared_ptr<Playlist> (new AudioPlaylist (apl, name, hidden)); - pl->set_region_ownership (); - } else if ((mpl = boost::dynamic_pointer_cast<const MidiPlaylist> (old)) != 0) { - pl = boost::shared_ptr<Playlist> (new MidiPlaylist (mpl, name, hidden)); - pl->set_region_ownership (); - } - - if (pl && !hidden) { - PlaylistCreated (pl); - } - - return pl; -} - -boost::shared_ptr<Playlist> -PlaylistFactory::create (boost::shared_ptr<const Playlist> old, nframes_t start, nframes_t cnt, string name, bool hidden) -{ - boost::shared_ptr<Playlist> pl; - boost::shared_ptr<const AudioPlaylist> apl; - boost::shared_ptr<const MidiPlaylist> mpl; - - if ((apl = boost::dynamic_pointer_cast<const AudioPlaylist> (old)) != 0) { - pl = boost::shared_ptr<Playlist> (new AudioPlaylist (apl, start, cnt, name, hidden)); - pl->set_region_ownership (); - } else if ((mpl = boost::dynamic_pointer_cast<const MidiPlaylist> (old)) != 0) { - pl = boost::shared_ptr<Playlist> (new MidiPlaylist (mpl, start, cnt, name, hidden)); - pl->set_region_ownership (); - } - - /* this factory method does NOT notify others */ - - return pl; -} diff --git a/libs/ardour/plugin.cc b/libs/ardour/plugin.cc deleted file mode 100644 index 3d218448dd..0000000000 --- a/libs/ardour/plugin.cc +++ /dev/null @@ -1,243 +0,0 @@ -/* - 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. - -*/ - -#include <vector> -#include <string> - -#include <cstdlib> -#include <cstdio> // so libraptor doesn't complain -#include <cmath> -#include <dirent.h> -#include <sys/stat.h> -#include <cerrno> - -#include <lrdf.h> - -#include <pbd/compose.h> -#include <pbd/error.h> -#include <pbd/xml++.h> - -#include <ardour/ardour.h> -#include <ardour/session.h> -#include <ardour/audioengine.h> -#include <ardour/plugin.h> -#include <ardour/ladspa_plugin.h> -#include <ardour/plugin_manager.h> - -#ifdef HAVE_AUDIOUNITS -#include <ardour/audio_unit.h> -#endif - -#ifdef HAVE_SLV2 -#include <ardour/lv2_plugin.h> -#endif - -#include <pbd/stl_delete.h> - -#include "i18n.h" -#include <locale.h> - -using namespace ARDOUR; -using namespace PBD; - -Plugin::Plugin (AudioEngine& e, Session& s) - : _engine (e), _session (s) -{ -} - -Plugin::Plugin (const Plugin& other) - : _engine (other._engine), _session (other._session), _info (other._info) -{ -} - -Plugin::~Plugin () -{ -} - -vector<string> -Plugin::get_presets() -{ - vector<string> labels; - uint32_t id; - std::string unique (unique_id()); - - /* XXX problem: AU plugins don't have numeric ID's. - Solution: they have a different method of providing presets. - XXX sub-problem: implement it. - */ - - if (!isdigit (unique[0])) { - return labels; - } - - id = atol (unique.c_str()); - - lrdf_uris* set_uris = lrdf_get_setting_uris(id); - - if (set_uris) { - for (uint32_t i = 0; i < (uint32_t) set_uris->count; ++i) { - if (char* label = lrdf_get_label(set_uris->items[i])) { - labels.push_back(label); - presets[label] = set_uris->items[i]; - } - } - lrdf_free_uris(set_uris); - } - - // GTK2FIX find an equivalent way to do this with a vector (needed by GUI apis) - // labels.unique(); - - return labels; -} - -bool -Plugin::load_preset(const string preset_label) -{ - lrdf_defaults* defs = lrdf_get_setting_values(presets[preset_label].c_str()); - - if (defs) { - for (uint32_t i = 0; i < (uint32_t) defs->count; ++i) { - // The defs->items[i].pid < defs->count check is to work around - // a bug in liblrdf that saves invalid values into the presets file. - if (((uint32_t) defs->items[i].pid < (uint32_t) defs->count) && parameter_is_input (defs->items[i].pid)) { - set_parameter(defs->items[i].pid, defs->items[i].value); - } - } - lrdf_free_setting_values(defs); - } - - return true; -} - -bool -Plugin::save_preset (string name, string domain) -{ - lrdf_portvalue portvalues[parameter_count()]; - lrdf_defaults defaults; - uint32_t id; - std::string unique (unique_id()); - - /* XXX problem: AU plugins don't have numeric ID's. - Solution: they have a different method of providing/saving presets. - XXX sub-problem: implement it. - */ - - if (!isdigit (unique[0])) { - return false; - } - - id = atol (unique.c_str()); - - defaults.count = parameter_count(); - defaults.items = portvalues; - - for (uint32_t i = 0; i < parameter_count(); ++i) { - if (parameter_is_input (i)) { - portvalues[i].pid = i; - portvalues[i].value = get_parameter(i); - } - } - - char* envvar; - if ((envvar = getenv ("HOME")) == 0) { - warning << _("Could not locate HOME. Preset not saved.") << endmsg; - return false; - } - - string source(string_compose("file:%1/.%2/rdf/ardour-presets.n3", envvar, domain)); - - free(lrdf_add_preset(source.c_str(), name.c_str(), id, &defaults)); - - string path = string_compose("%1/.%2", envvar, domain); - if (g_mkdir_with_parents (path.c_str(), 0775)) { - warning << string_compose(_("Could not create %1. Preset not saved. (%2)"), path, strerror(errno)) << endmsg; - return false; - } - - path += "/rdf"; - if (g_mkdir_with_parents (path.c_str(), 0775)) { - warning << string_compose(_("Could not create %1. Preset not saved. (%2)"), path, strerror(errno)) << endmsg; - return false; - } - - if (lrdf_export_by_source(source.c_str(), source.substr(5).c_str())) { - warning << string_compose(_("Error saving presets file %1."), source) << endmsg; - return false; - } - - return true; -} - -PluginPtr -ARDOUR::find_plugin(Session& session, string identifier, PluginType type) -{ - PluginManager *mgr = PluginManager::the_manager(); - PluginInfoList plugs; - - switch (type) { - case ARDOUR::LADSPA: - plugs = mgr->ladspa_plugin_info(); - break; - -#ifdef HAVE_SLV2 - case ARDOUR::LV2: - plugs = mgr->lv2_plugin_info(); - break; -#endif - -#ifdef VST_SUPPORT - case ARDOUR::VST: - plugs = mgr->vst_plugin_info(); - break; -#endif - -#ifdef HAVE_AUDIOUNITS - case ARDOUR::AudioUnit: - plugs = mgr->au_plugin_info(); - break; -#endif - - default: - return PluginPtr ((Plugin *) 0); - } - - PluginInfoList::iterator i; - - for (i = plugs.begin(); i != plugs.end(); ++i) { - if (identifier == (*i)->unique_id){ - return (*i)->load (session); - } - } - -#ifdef VST_SUPPORT - /* hmm, we didn't find it. could be because in older versions of Ardour. - we used to store the name of a VST plugin, not its unique ID. so try - again. - */ - - for (i = plugs.begin(); i != plugs.end(); ++i) { - if (identifier == (*i)->name){ - return (*i)->load (session); - } - } -#endif - - return PluginPtr ((Plugin*) 0); -} - diff --git a/libs/ardour/plugin_insert.cc b/libs/ardour/plugin_insert.cc deleted file mode 100644 index 26d344dee4..0000000000 --- a/libs/ardour/plugin_insert.cc +++ /dev/null @@ -1,917 +0,0 @@ -/* - 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. - -*/ - -#include <string> - -#include <sigc++/bind.h> - -#include <pbd/failed_constructor.h> -#include <pbd/xml++.h> - -#include <ardour/plugin_insert.h> -#include <ardour/plugin.h> -#include <ardour/port.h> -#include <ardour/route.h> -#include <ardour/ladspa_plugin.h> -#include <ardour/buffer_set.h> -#include <ardour/automation_event.h> - -#ifdef HAVE_SLV2 -#include <ardour/lv2_plugin.h> -#endif - -#ifdef VST_SUPPORT -#include <ardour/vst_plugin.h> -#endif - -#ifdef HAVE_AUDIOUNITS -#include <ardour/audio_unit.h> -#endif - -#include <ardour/audioengine.h> -#include <ardour/session.h> -#include <ardour/types.h> - -#include "i18n.h" - -using namespace std; -using namespace ARDOUR; -using namespace PBD; - -const string PluginInsert::port_automation_node_name = "PortAutomation"; - -PluginInsert::PluginInsert (Session& s, boost::shared_ptr<Plugin> plug, Placement placement) - : Processor (s, plug->name(), placement) -{ - /* the first is the master */ - - _plugins.push_back (plug); - - init (); - - { - Glib::Mutex::Lock em (_session.engine().process_lock()); - IO::PortCountChanged (max(input_streams(), output_streams())); - } - - ProcessorCreated (this); /* EMIT SIGNAL */ -} - -PluginInsert::PluginInsert (Session& s, const XMLNode& node) - : Processor (s, "unnamed plugin insert", PreFader) -{ - if (set_state (node)) { - throw failed_constructor(); - } - - // set_automatable (); - - { - Glib::Mutex::Lock em (_session.engine().process_lock()); - IO::PortCountChanged (max(input_streams(), output_streams())); - } -} - -PluginInsert::PluginInsert (const PluginInsert& other) - : Processor (other._session, other._name, other.placement()) -{ - uint32_t count = other._plugins.size(); - - /* make as many copies as requested */ - for (uint32_t n = 0; n < count; ++n) { - _plugins.push_back (plugin_factory (other.plugin (n))); - } - - init (); - - ProcessorCreated (this); /* EMIT SIGNAL */ -} - -bool -PluginInsert::set_count (uint32_t num) -{ - bool require_state = !_plugins.empty(); - - /* this is a bad idea.... we shouldn't do this while active. - only a route holding their redirect_lock should be calling this - */ - - if (num == 0) { - return false; - } else if (num > _plugins.size()) { - uint32_t diff = num - _plugins.size(); - - for (uint32_t n = 0; n < diff; ++n) { - _plugins.push_back (plugin_factory (_plugins[0])); - - if (require_state) { - /* XXX do something */ - } - } - - } else if (num < _plugins.size()) { - uint32_t diff = _plugins.size() - num; - for (uint32_t n= 0; n < diff; ++n) { - _plugins.pop_back(); - } - } - - return true; -} - -void -PluginInsert::init () -{ - set_automatable (); -} - -PluginInsert::~PluginInsert () -{ - GoingAway (); /* EMIT SIGNAL */ -} - -void -PluginInsert::auto_state_changed (Parameter which) -{ - if (which.type() != PluginAutomation) - return; - - boost::shared_ptr<AutomationControl> c = control (which); - - if (c && c->list()->automation_state() != Off) { - _plugins[0]->set_parameter (which.id(), c->list()->eval (_session.transport_frame())); - } -} - -ChanCount -PluginInsert::output_streams() const -{ - if (_configured) - return output_for_input_configuration(_configured_input); - else - return natural_output_streams(); -} - -ChanCount -PluginInsert::input_streams() const -{ - if (_configured) - return _configured_input; - else - return natural_input_streams(); -} - -ChanCount -PluginInsert::natural_output_streams() const -{ - return _plugins[0]->get_info()->n_outputs; -} - -ChanCount -PluginInsert::natural_input_streams() const -{ - return _plugins[0]->get_info()->n_inputs; -} - -bool -PluginInsert::is_generator() const -{ - /* XXX more finesse is possible here. VST plugins have a - a specific "instrument" flag, for example. - */ - - return _plugins[0]->get_info()->n_inputs.n_audio() == 0; -} - -void -PluginInsert::set_automatable () -{ - set<Parameter> a = _plugins.front()->automatable (); - - Plugin::ParameterDescriptor desc; - - for (set<Parameter>::iterator i = a.begin(); i != a.end(); ++i) { - if (i->type() == PluginAutomation) { - can_automate (*i); - _plugins.front()->get_parameter_descriptor(i->id(), desc); - boost::shared_ptr<AutomationList> list(new AutomationList( - *i, - //(desc.min_unbound ? FLT_MIN : desc.lower), - //(desc.max_unbound ? FLT_MAX : desc.upper), - desc.lower, desc.upper, - _plugins.front()->default_value(i->id()))); - - add_control(boost::shared_ptr<AutomationControl>( - new PluginControl(*this, list))); - } - } -} - -void -PluginInsert::parameter_changed (Parameter which, float val) -{ - if (which.type() != PluginAutomation) - return; - - vector<boost::shared_ptr<Plugin> >::iterator i = _plugins.begin(); - - /* don't set the first plugin, just all the slaves */ - - if (i != _plugins.end()) { - ++i; - for (; i != _plugins.end(); ++i) { - (*i)->set_parameter (which, val); - } - } -} - -void -PluginInsert::set_block_size (nframes_t nframes) -{ - for (vector<boost::shared_ptr<Plugin> >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) { - (*i)->set_block_size (nframes); - } -} - -void -PluginInsert::activate () -{ - for (vector<boost::shared_ptr<Plugin> >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) { - (*i)->activate (); - } -} - -void -PluginInsert::deactivate () -{ - for (vector<boost::shared_ptr<Plugin> >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) { - (*i)->deactivate (); - } -} - -void -PluginInsert::connect_and_run (BufferSet& bufs, nframes_t nframes, nframes_t offset, bool with_auto, nframes_t now) -{ - uint32_t in_index = 0; - uint32_t out_index = 0; - - /* Note that we've already required that plugins - be able to handle in-place processing. - */ - - if (with_auto) { - - uint32_t n = 0; - - for (Controls::iterator li = _controls.begin(); li != _controls.end(); ++li, ++n) { - - boost::shared_ptr<AutomationControl> c = li->second; - - if (c->parameter().type() == PluginAutomation && c->list()->automation_playback()) { - bool valid; - - const float val = c->list()->rt_safe_eval (now, valid); - - if (valid) { - c->set_value(val); - } - - } - } - } - - for (vector<boost::shared_ptr<Plugin> >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) { - (*i)->connect_and_run (bufs, in_index, out_index, nframes, offset); - } - - /* leave remaining channel buffers alone */ -} - -void -PluginInsert::silence (nframes_t nframes, nframes_t offset) -{ - uint32_t in_index = 0; - uint32_t out_index = 0; - - if (active()) { - for (vector<boost::shared_ptr<Plugin> >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) { - (*i)->connect_and_run (_session.get_silent_buffers ((*i)->get_info()->n_inputs), in_index, out_index, nframes, offset); - } - } -} - -void -PluginInsert::run_in_place (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset) -{ - if (active()) { - - if (_session.transport_rolling()) { - automation_run (bufs, nframes, offset); - } else { - connect_and_run (bufs, nframes, offset, false); - } - } else { - - /* FIXME: type, audio only */ - - uint32_t in = _plugins[0]->get_info()->n_inputs.n_audio(); - uint32_t out = _plugins[0]->get_info()->n_outputs.n_audio(); - - if (out > in) { - - /* not active, but something has make up for any channel count increase */ - - for (uint32_t n = out - in; n < out; ++n) { - memcpy (bufs.get_audio(n).data(nframes, offset), bufs.get_audio(in - 1).data(nframes, offset), sizeof (Sample) * nframes); - } - } - - bufs.count().set_audio(out); - } -} - -void -PluginInsert::set_parameter (Parameter param, float val) -{ - if (param.type() != PluginAutomation) - return; - - /* the others will be set from the event triggered by this */ - - _plugins[0]->set_parameter (param.id(), val); - - boost::shared_ptr<AutomationControl> c = control (param); - - if (c) - c->set_value(val); - - _session.set_dirty(); -} - -float -PluginInsert::get_parameter (Parameter param) -{ - if (param.type() != PluginAutomation) - return 0.0; - else - return - _plugins[0]->get_parameter (param.id()); -} - -void -PluginInsert::automation_run (BufferSet& bufs, nframes_t nframes, nframes_t offset) -{ - ControlEvent next_event (0, 0.0f); - nframes_t now = _session.transport_frame (); - nframes_t end = now + nframes; - - Glib::Mutex::Lock lm (_automation_lock, Glib::TRY_LOCK); - - if (!lm.locked()) { - connect_and_run (bufs, nframes, offset, false); - return; - } - - if (!find_next_event (now, end, next_event)) { - - /* no events have a time within the relevant range */ - - connect_and_run (bufs, nframes, offset, true, now); - return; - } - - while (nframes) { - - nframes_t cnt = min (((nframes_t) ceil (next_event.when) - now), nframes); - - connect_and_run (bufs, cnt, offset, true, now); - - nframes -= cnt; - offset += cnt; - now += cnt; - - if (!find_next_event (now, end, next_event)) { - break; - } - } - - /* cleanup anything that is left to do */ - - if (nframes) { - connect_and_run (bufs, nframes, offset, true, now); - } -} - -float -PluginInsert::default_parameter_value (Parameter param) -{ - if (param.type() != PluginAutomation) - return 1.0; - - if (_plugins.empty()) { - fatal << _("programming error: ") << X_("PluginInsert::default_parameter_value() called with no plugin") - << endmsg; - /*NOTREACHED*/ - } - - return _plugins[0]->default_value (param.id()); -} - -boost::shared_ptr<Plugin> -PluginInsert::plugin_factory (boost::shared_ptr<Plugin> other) -{ - boost::shared_ptr<LadspaPlugin> lp; -#ifdef HAVE_SLV2 - boost::shared_ptr<LV2Plugin> lv2p; -#endif -#ifdef VST_SUPPORT - boost::shared_ptr<VSTPlugin> vp; -#endif -#ifdef HAVE_AUDIOUNITS - boost::shared_ptr<AUPlugin> ap; -#endif - - if ((lp = boost::dynamic_pointer_cast<LadspaPlugin> (other)) != 0) { - return boost::shared_ptr<Plugin> (new LadspaPlugin (*lp)); -#ifdef HAVE_SLV2 - } else if ((lv2p = boost::dynamic_pointer_cast<LV2Plugin> (other)) != 0) { - return boost::shared_ptr<Plugin> (new LV2Plugin (*lv2p)); -#endif -#ifdef VST_SUPPORT - } else if ((vp = boost::dynamic_pointer_cast<VSTPlugin> (other)) != 0) { - return boost::shared_ptr<Plugin> (new VSTPlugin (*vp)); -#endif -#ifdef HAVE_AUDIOUNITS - } else if ((ap = boost::dynamic_pointer_cast<AUPlugin> (other)) != 0) { - return boost::shared_ptr<Plugin> (new AUPlugin (*ap)); -#endif - } - - fatal << string_compose (_("programming error: %1"), - X_("unknown plugin type in PluginInsert::plugin_factory")) - << endmsg; - /*NOTREACHED*/ - return boost::shared_ptr<Plugin> ((Plugin*) 0); -} - -bool -PluginInsert::configure_io (ChanCount in, ChanCount out) -{ - ChanCount matching_out = output_for_input_configuration(out); - if (matching_out != out) { - _configured = false; - return false; - } else { - bool success = set_count (count_for_configuration(in, out)); - if (success) - Processor::configure_io(in, out); - return success; - } -} - -bool -PluginInsert::can_support_input_configuration (ChanCount in) const -{ - ChanCount outputs = _plugins[0]->get_info()->n_outputs; - ChanCount inputs = _plugins[0]->get_info()->n_inputs; - - /* see output_for_input_configuration below */ - if ((inputs.n_total() == 0) - || (inputs.n_total() == 1 && outputs == inputs) - || (inputs.n_total() == 1 && outputs == inputs - && ((inputs.n_audio() == 0 && in.n_audio() == 0) - || (inputs.n_midi() == 0 && in.n_midi() == 0))) - || (inputs == in)) { - return true; - } - - bool can_replicate = true; - - /* if number of inputs is a factor of the requested input - configuration for every type, we can replicate. - */ - for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) { - if (inputs.get(*t) >= in.get(*t) || (inputs.get(*t) % in.get(*t) != 0)) { - can_replicate = false; - break; - } - } - - if (can_replicate && (in.n_total() % inputs.n_total() == 0)) { - return true; - } else { - return false; - } -} - -ChanCount -PluginInsert::output_for_input_configuration (ChanCount in) const -{ - ChanCount outputs = _plugins[0]->get_info()->n_outputs; - ChanCount inputs = _plugins[0]->get_info()->n_inputs; - - if (inputs.n_total() == 0) { - /* instrument plugin, always legal, but throws away any existing streams */ - return outputs; - } - - if (inputs.n_total() == 1 && outputs == inputs - && ((inputs.n_audio() == 0 && in.n_audio() == 0) - || (inputs.n_midi() == 0 && in.n_midi() == 0))) { - /* mono plugin, replicate as needed to match in */ - return in; - } - - if (inputs == in) { - /* exact match */ - return outputs; - } - - bool can_replicate = true; - - /* if number of inputs is a factor of the requested input - configuration for every type, we can replicate. - */ - for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) { - if (inputs.get(*t) >= in.get(*t) || (in.get(*t) % inputs.get(*t) != 0)) { - can_replicate = false; - break; - } - } - - if (can_replicate && (inputs.n_total() % in.n_total() == 0)) { - ChanCount output; - - for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) { - output.set(*t, outputs.get(*t) * (in.get(*t) / inputs.get(*t))); - } - - return output; - } - - /* sorry */ - return ChanCount(); -} - -/* Number of plugin instances required to support a given channel configuration. - * (private helper) - */ -int32_t -PluginInsert::count_for_configuration (ChanCount in, ChanCount out) const -{ - // FIXME: take 'out' into consideration - - ChanCount outputs = _plugins[0]->get_info()->n_outputs; - ChanCount inputs = _plugins[0]->get_info()->n_inputs; - - if (inputs.n_total() == 0) { - /* instrument plugin, always legal, but throws away any existing streams */ - return 1; - } - - if (inputs.n_total() == 1 && outputs == inputs - && ((inputs.n_audio() == 0 && in.n_audio() == 0) - || (inputs.n_midi() == 0 && in.n_midi() == 0))) { - /* mono plugin, replicate as needed to match in */ - return in.n_total(); - } - - if (inputs == in) { - /* exact match */ - return 1; - } - - // assumes in is valid, so we must be replicating - if (inputs.n_total() < in.n_total() - && (in.n_total() % inputs.n_total() == 0)) { - - return in.n_total() / inputs.n_total(); - } - - /* err... */ - return 0; -} - -XMLNode& -PluginInsert::get_state(void) -{ - return state (true); -} - -XMLNode& -PluginInsert::state (bool full) -{ - XMLNode& node = Processor::state (full); - - node.add_property ("type", _plugins[0]->state_node_name()); - node.add_property("unique-id", _plugins[0]->unique_id()); - node.add_property("count", string_compose("%1", _plugins.size())); - node.add_child_nocopy (_plugins[0]->get_state()); - - /* add port automation state */ - XMLNode *autonode = new XMLNode(port_automation_node_name); - set<Parameter> automatable = _plugins[0]->automatable(); - - for (set<Parameter>::iterator x = automatable.begin(); x != automatable.end(); ++x) { - - /*XMLNode* child = new XMLNode("port"); - snprintf(buf, sizeof(buf), "%" PRIu32, *x); - child->add_property("number", string(buf)); - - child->add_child_nocopy (automation_list (*x).state (full)); - autonode->add_child_nocopy (*child); - */ - autonode->add_child_nocopy (control(*x)->list()->state (full)); - } - - node.add_child_nocopy (*autonode); - - return node; -} - -int -PluginInsert::set_state(const XMLNode& node) -{ - XMLNodeList nlist = node.children(); - XMLNodeIterator niter; - XMLPropertyList plist; - const XMLProperty *prop; - ARDOUR::PluginType type; - - if ((prop = node.property ("type")) == 0) { - error << _("XML node describing insert is missing the `type' field") << endmsg; - return -1; - } - - if (prop->value() == X_("ladspa") || prop->value() == X_("Ladspa")) { /* handle old school sessions */ - type = ARDOUR::LADSPA; - } else if (prop->value() == X_("lv2")) { - type = ARDOUR::LV2; - } else if (prop->value() == X_("vst")) { - type = ARDOUR::VST; - } else { - error << string_compose (_("unknown plugin type %1 in plugin insert state"), - prop->value()) - << endmsg; - return -1; - } - - prop = node.property ("unique-id"); - if (prop == 0) { - error << _("Plugin has no unique ID field") << endmsg; - return -1; - } - - boost::shared_ptr<Plugin> plugin; - - plugin = find_plugin (_session, prop->value(), type); - - if (plugin == 0) { - error << string_compose(_("Found a reference to a plugin (\"%1\") that is unknown.\n" - "Perhaps it was removed or moved since it was last used."), prop->value()) - << endmsg; - return -1; - } - - uint32_t count = 1; - - if ((prop = node.property ("count")) != 0) { - sscanf (prop->value().c_str(), "%u", &count); - } - - if (_plugins.size() != count) { - - _plugins.push_back (plugin); - - for (uint32_t n=1; n < count; ++n) { - _plugins.push_back (plugin_factory (plugin)); - } - } - - for (niter = nlist.begin(); niter != nlist.end(); ++niter) { - if ((*niter)->name() == plugin->state_node_name()) { - for (vector<boost::shared_ptr<Plugin> >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) { - (*i)->set_state (**niter); - } - break; - } - } - - const XMLNode* insert_node = &node; - - // legacy sessions: search for child IOProcessor node - for (niter = nlist.begin(); niter != nlist.end(); ++niter) { - if ((*niter)->name() == "IOProcessor") { - insert_node = *niter; - break; - } - } - - Processor::set_state (*insert_node); - - /* look for port automation node */ - - for (niter = nlist.begin(); niter != nlist.end(); ++niter) { - - if ((*niter)->name() != port_automation_node_name) { - continue; - } - - XMLNodeList cnodes; - XMLProperty *cprop; - XMLNodeConstIterator iter; - XMLNode *child; - const char *port; - uint32_t port_id; - - cnodes = (*niter)->children ("port"); - - for(iter = cnodes.begin(); iter != cnodes.end(); ++iter){ - - child = *iter; - - if ((cprop = child->property("number")) != 0) { - port = cprop->value().c_str(); - } else { - warning << _("PluginInsert: Auto: no ladspa port number") << endmsg; - continue; - } - - sscanf (port, "%" PRIu32, &port_id); - - if (port_id >= _plugins[0]->parameter_count()) { - warning << _("PluginInsert: Auto: port id out of range") << endmsg; - continue; - } - - if (!child->children().empty()) { - control (Parameter(PluginAutomation, port_id), true)->list()->set_state (*child->children().front()); - } else { - if ((cprop = child->property("auto")) != 0) { - - /* old school */ - - int x; - sscanf (cprop->value().c_str(), "0x%x", &x); - control (Parameter(PluginAutomation, port_id), true)->list()->set_automation_state (AutoState (x)); - - } else { - - /* missing */ - - control (Parameter(PluginAutomation, port_id), true)->list()->set_automation_state (Off); - } - } - - } - - /* done */ - - break; - } - - if (niter == nlist.end()) { - warning << string_compose(_("XML node describing a port automation is missing the `%1' information"), port_automation_node_name) << endmsg; - } - - // The name of the PluginInsert comes from the plugin, nothing else - _name = plugin->get_info()->name; - - return 0; -} - -string -PluginInsert::describe_parameter (Parameter param) -{ - if (param.type() != PluginAutomation) - return Automatable::describe_parameter(param); - - return _plugins[0]->describe_parameter (param); -} - -ARDOUR::nframes_t -PluginInsert::signal_latency() const -{ - if (_user_latency) { - return _user_latency; - } - - return _plugins[0]->signal_latency (); -} - -ARDOUR::PluginType -PluginInsert::type () -{ - boost::shared_ptr<LadspaPlugin> lp; -#ifdef VST_SUPPORT - boost::shared_ptr<VSTPlugin> vp; -#endif -#ifdef HAVE_AUDIOUNITS - boost::shared_ptr<AUPlugin> ap; -#endif - - PluginPtr other = plugin (); - - if ((lp = boost::dynamic_pointer_cast<LadspaPlugin> (other)) != 0) { - return ARDOUR::LADSPA; -#ifdef VST_SUPPORT - } else if ((vp = boost::dynamic_pointer_cast<VSTPlugin> (other)) != 0) { - return ARDOUR::VST; -#endif -#ifdef HAVE_AUDIOUNITS - } else if ((ap = boost::dynamic_pointer_cast<AUPlugin> (other)) != 0) { - return ARDOUR::AudioUnit; -#endif - } else { - /* NOT REACHED */ - return (ARDOUR::PluginType) 0; - } -} - -PluginInsert::PluginControl::PluginControl (PluginInsert& p, boost::shared_ptr<AutomationList> list) - : AutomationControl (p.session(), list, p.describe_parameter(list->parameter())) - , _plugin (p) - , _list (list) -{ - Plugin::ParameterDescriptor desc; - p.plugin(0)->get_parameter_descriptor (list->parameter().id(), desc); - _logarithmic = desc.logarithmic; - _toggled = desc.toggled; -} - -void -PluginInsert::PluginControl::set_value (float val) -{ - /* FIXME: probably should be taking out some lock here.. */ - - if (_toggled) { - if (val > 0.5) { - val = 1.0; - } else { - val = 0.0; - } - } else { - - /*const float range = _list->get_max_y() - _list->get_min_y(); - const float lower = _list->get_min_y(); - - if (!_logarithmic) { - val = lower + (range * val); - } else { - float log_lower = 0.0f; - if (lower > 0.0f) { - log_lower = log(lower); - } - - val = exp(log_lower + log(range) * val); - }*/ - - } - - for (vector<boost::shared_ptr<Plugin> >::iterator i = _plugin._plugins.begin(); - i != _plugin._plugins.end(); ++i) { - (*i)->set_parameter (_list->parameter().id(), val); - } - - AutomationControl::set_value(val); -} - -float -PluginInsert::PluginControl::get_value (void) const -{ - /* FIXME: probably should be taking out some lock here.. */ - - float val = _plugin.get_parameter (_list->parameter()); - - return val; - - /*if (_toggled) { - - return val; - - } else { - - if (_logarithmic) { - val = log(val); - } - - return ((val - lower) / range); - }*/ -} - diff --git a/libs/ardour/plugin_manager.cc b/libs/ardour/plugin_manager.cc deleted file mode 100644 index 6ff780a25f..0000000000 --- a/libs/ardour/plugin_manager.cc +++ /dev/null @@ -1,489 +0,0 @@ -/* - 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. - -*/ - -#define __STDC_FORMAT_MACROS 1 -#include <stdint.h> - -#include <sys/types.h> -#include <cstdio> -#include <lrdf.h> -#include <dlfcn.h> - -#ifdef VST_SUPPORT -#include <fst.h> -#include <pbd/basename.h> -#include <string.h> -#endif // VST_SUPPORT - -#include <pbd/pathscanner.h> - -#include <ardour/ladspa.h> -#include <ardour/session.h> -#include <ardour/plugin_manager.h> -#include <ardour/plugin.h> -#include <ardour/ladspa_plugin.h> - -#ifdef HAVE_SLV2 -#include <slv2/slv2.h> -#include <ardour/lv2_plugin.h> -#endif - -#ifdef VST_SUPPORT -#include <ardour/vst_plugin.h> -#endif - -#ifdef HAVE_AUDIOUNITS -#include <ardour/audio_unit.h> -#endif - -#include <pbd/error.h> -#include <pbd/stl_delete.h> - -#include "i18n.h" - -using namespace ARDOUR; -using namespace PBD; - -PluginManager* PluginManager::_manager = 0; - -PluginManager::PluginManager () -{ - char* s; - string lrdf_path; - - if ((s = getenv ("LADSPA_RDF_PATH"))){ - lrdf_path = s; - } - - if (lrdf_path.length() == 0) { - lrdf_path = "/usr/local/share/ladspa/rdf:/usr/share/ladspa/rdf"; - } - - add_lrdf_data(lrdf_path); - add_ladspa_presets(); -#ifdef VST_SUPPORT - if (Config->get_use_vst()) { - add_vst_presets(); - } -#endif /* VST_SUPPORT */ - - if ((s = getenv ("LADSPA_PATH"))) { - ladspa_path = s; - } - - if ((s = getenv ("VST_PATH"))) { - vst_path = s; - } else if ((s = getenv ("VST_PLUGINS"))) { - vst_path = s; - } - - if (_manager == 0) { - _manager = this; - } - - /* the plugin manager is constructed too early to use Profile */ - - if (getenv ("ARDOUR_SAE")) { - ladspa_plugin_whitelist.push_back (1203); // single band parametric - ladspa_plugin_whitelist.push_back (1772); // caps compressor - ladspa_plugin_whitelist.push_back (1913); // fast lookahead limiter - ladspa_plugin_whitelist.push_back (1075); // simple RMS expander - ladspa_plugin_whitelist.push_back (1061); // feedback delay line (max 5s) - ladspa_plugin_whitelist.push_back (1216); // gverb - ladspa_plugin_whitelist.push_back (2150); // tap pitch shifter - } - -#ifdef HAVE_SLV2 - _lv2_world = new LV2World(); -#endif - - refresh (); -} - -void -PluginManager::refresh () -{ - ladspa_refresh (); -#ifdef HAVE_SLV2 - lv2_refresh (); -#endif -#ifdef VST_SUPPORT - if (Config->get_use_vst()) { - vst_refresh (); - } -#endif // VST_SUPPORT -#ifdef HAVE_AUDIOUNITS - au_refresh (); -#endif -} - -void -PluginManager::ladspa_refresh () -{ - _ladspa_plugin_info.clear (); - - if (ladspa_path.length() == 0) { - ladspa_path = "/usr/local/lib64/ladspa:/usr/local/lib/ladspa:/usr/lib64/ladspa:/usr/lib/ladspa:/Library/Audio/Plug-Ins/LADSPA"; - } - - ladspa_discover_from_path (ladspa_path); -} - - -int -PluginManager::add_ladspa_directory (string path) -{ - if (ladspa_discover_from_path (path) == 0) { - ladspa_path += ':'; - ladspa_path += path; - return 0; - } - return -1; -} - -static bool ladspa_filter (const string& str, void *arg) -{ - /* Not a dotfile, has a prefix before a period, suffix is "so" */ - - return str[0] != '.' && (str.length() > 3 && str.find (".so") == (str.length() - 3)); -} - -int -PluginManager::ladspa_discover_from_path (string path) -{ - PathScanner scanner; - vector<string *> *plugin_objects; - vector<string *>::iterator x; - int ret = 0; - - plugin_objects = scanner (ladspa_path, ladspa_filter, 0, true, true); - - if (plugin_objects) { - for (x = plugin_objects->begin(); x != plugin_objects->end (); ++x) { - ladspa_discover (**x); - } - } - - vector_delete (plugin_objects); - return ret; -} - -static bool rdf_filter (const string &str, void *arg) -{ - return str[0] != '.' && - ((str.find(".rdf") == (str.length() - 4)) || - (str.find(".rdfs") == (str.length() - 5)) || - (str.find(".n3") == (str.length() - 3))); -} - -void -PluginManager::add_ladspa_presets() -{ - add_presets ("ladspa"); -} - -void -PluginManager::add_vst_presets() -{ - add_presets ("vst"); -} -void -PluginManager::add_presets(string domain) -{ - - PathScanner scanner; - vector<string *> *presets; - vector<string *>::iterator x; - - char* envvar; - if ((envvar = getenv ("HOME")) == 0) { - return; - } - - string path = string_compose("%1/.%2/rdf", envvar, domain); - presets = scanner (path, rdf_filter, 0, true, true); - - if (presets) { - for (x = presets->begin(); x != presets->end (); ++x) { - string file = "file:" + **x; - if (lrdf_read_file(file.c_str())) { - warning << string_compose(_("Could not parse rdf file: %1"), *x) << endmsg; - } - } - } - - vector_delete (presets); -} - -void -PluginManager::add_lrdf_data (const string &path) -{ - PathScanner scanner; - vector<string *>* rdf_files; - vector<string *>::iterator x; - string uri; - - rdf_files = scanner (path, rdf_filter, 0, true, true); - - if (rdf_files) { - for (x = rdf_files->begin(); x != rdf_files->end (); ++x) { - uri = "file://" + **x; - - if (lrdf_read_file(uri.c_str())) { - warning << "Could not parse rdf file: " << uri << endmsg; - } - } - } - - vector_delete (rdf_files); -} - -int -PluginManager::ladspa_discover (string path) -{ - void *module; - const LADSPA_Descriptor *descriptor; - LADSPA_Descriptor_Function dfunc; - const char *errstr; - - if ((module = dlopen (path.c_str(), RTLD_NOW)) == 0) { - error << string_compose(_("LADSPA: cannot load module \"%1\" (%2)"), path, dlerror()) << endmsg; - return -1; - } - - dfunc = (LADSPA_Descriptor_Function) dlsym (module, "ladspa_descriptor"); - - if ((errstr = dlerror()) != 0) { - error << string_compose(_("LADSPA: module \"%1\" has no descriptor function."), path) << endmsg; - error << errstr << endmsg; - dlclose (module); - return -1; - } - - for (uint32_t i = 0; ; ++i) { - if ((descriptor = dfunc (i)) == 0) { - break; - } - - if (!ladspa_plugin_whitelist.empty()) { - if (find (ladspa_plugin_whitelist.begin(), ladspa_plugin_whitelist.end(), descriptor->UniqueID) == ladspa_plugin_whitelist.end()) { - continue; - } - } - - PluginInfoPtr info(new LadspaPluginInfo); - info->name = descriptor->Name; - info->category = get_ladspa_category(descriptor->UniqueID); - info->creator = descriptor->Maker; - info->path = path; - info->index = i; - info->n_inputs = ChanCount(); - info->n_outputs = ChanCount(); - info->type = ARDOUR::LADSPA; - - char buf[32]; - snprintf (buf, sizeof (buf), "%lu", descriptor->UniqueID); - info->unique_id = buf; - - for (uint32_t n=0; n < descriptor->PortCount; ++n) { - if ( LADSPA_IS_PORT_AUDIO (descriptor->PortDescriptors[n]) ) { - if ( LADSPA_IS_PORT_INPUT (descriptor->PortDescriptors[n]) ) { - info->n_inputs.set_audio(info->n_inputs.n_audio() + 1); - } - else if ( LADSPA_IS_PORT_OUTPUT (descriptor->PortDescriptors[n]) ) { - info->n_outputs.set_audio(info->n_outputs.n_audio() + 1); - } - } - } - - _ladspa_plugin_info.push_back (info); - } - -// GDB WILL NOT LIKE YOU IF YOU DO THIS -// dlclose (module); - - return 0; -} - -string -PluginManager::get_ladspa_category (uint32_t plugin_id) -{ - char buf[256]; - lrdf_statement pattern; - - snprintf(buf, sizeof(buf), "%s%" PRIu32, LADSPA_BASE, plugin_id); - pattern.subject = buf; - pattern.predicate = (char*)RDF_TYPE; - pattern.object = 0; - pattern.object_type = lrdf_uri; - - lrdf_statement* matches1 = lrdf_matches (&pattern); - - if (!matches1) { - return ""; - } - - pattern.subject = matches1->object; - pattern.predicate = (char*)(LADSPA_BASE "hasLabel"); - pattern.object = 0; - pattern.object_type = lrdf_literal; - - lrdf_statement* matches2 = lrdf_matches (&pattern); - lrdf_free_statements(matches1); - - if (!matches2) { - return (""); - } - - string label = matches2->object; - lrdf_free_statements(matches2); - - return label; -} - -#ifdef HAVE_SLV2 -void -PluginManager::lv2_refresh () -{ - lv2_discover(); -} - -int -PluginManager::lv2_discover () -{ - _lv2_plugin_info = LV2PluginInfo::discover(_lv2_world); - return 0; -} -#endif - -#ifdef HAVE_AUDIOUNITS -void -PluginManager::au_refresh () -{ - au_discover(); -} - -int -PluginManager::au_discover () -{ - _au_plugin_info = AUPluginInfo::discover(); - return 0; -} - -#endif - -#ifdef VST_SUPPORT - -void -PluginManager::vst_refresh () -{ - _vst_plugin_info.clear (); - - if (vst_path.length() == 0) { - vst_path = "/usr/local/lib/vst:/usr/lib/vst"; - } - - vst_discover_from_path (vst_path); -} - -int -PluginManager::add_vst_directory (string path) -{ - if (vst_discover_from_path (path) == 0) { - vst_path += ':'; - vst_path += path; - return 0; - } - return -1; -} - -static bool vst_filter (const string& str, void *arg) -{ - /* Not a dotfile, has a prefix before a period, suffix is "dll" */ - - return str[0] != '.' && (str.length() > 4 && str.find (".dll") == (str.length() - 4)); -} - -int -PluginManager::vst_discover_from_path (string path) -{ - PathScanner scanner; - vector<string *> *plugin_objects; - vector<string *>::iterator x; - int ret = 0; - - info << "detecting VST plugins along " << path << endmsg; - - plugin_objects = scanner (vst_path, vst_filter, 0, true, true); - - if (plugin_objects) { - for (x = plugin_objects->begin(); x != plugin_objects->end (); ++x) { - vst_discover (**x); - } - } - - vector_delete (plugin_objects); - return ret; -} - -int -PluginManager::vst_discover (string path) -{ - FSTInfo* finfo; - char buf[32]; - - if ((finfo = fst_get_info (const_cast<char *> (path.c_str()))) == 0) { - warning << "Cannot get VST information from " << path << endmsg; - return -1; - } - - if (!finfo->canProcessReplacing) { - warning << string_compose (_("VST plugin %1 does not support processReplacing, and so cannot be used in ardour at this time"), - finfo->name) - << endl; - } - - PluginInfoPtr info(new VSTPluginInfo); - - /* what a goddam joke freeware VST is */ - - if (!strcasecmp ("The Unnamed plugin", finfo->name)) { - info->name = PBD::basename_nosuffix (path); - } else { - info->name = finfo->name; - } - - - snprintf (buf, sizeof (buf), "%d", finfo->UniqueID); - info->unique_id = buf; - info->category = "VST"; - info->path = path; - // need to set info->creator but FST doesn't provide it - info->index = 0; - info->n_inputs = finfo->numInputs; - info->n_outputs = finfo->numOutputs; - info->type = ARDOUR::VST; - - _vst_plugin_info.push_back (info); - fst_free_info (finfo); - - return 0; -} - -#endif // VST_SUPPORT diff --git a/libs/ardour/po/el_GR.po b/libs/ardour/po/el_GR.po deleted file mode 100644 index 9ddd3e7188..0000000000 --- a/libs/ardour/po/el_GR.po +++ /dev/null @@ -1,2195 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR Paul Davis -# This file is distributed under the same license as the PACKAGE package. -# Klearchos Gourgourinis <muadib@in.gr>, 2004. -# -msgid "" -msgstr "" -"Project-Id-Version: libardour 0.664.0\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2003-06-29 21:03+0200\n" -"PO-Revision-Date: 2007-04-16 00:38+0200\n" -"Last-Translator: Klearchos Gourgourinis <muadib@in.gr>\n" -"Language-Team: Hellenic(Greek)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#: libs/ardour/audio_diskstream.cc:337 -msgid "AudioDiskstream: Session doesn't know about a Playlist called \"%1\"" -msgstr "AudioDiskStream: Η ΣυνεδÏία δεν γνωÏίζει για λίστα ΑναπαÏ/γής με όνομα \"%1\"" - -#: libs/ardour/audio_diskstream.cc:342 -msgid "AudioDiskstream: Playlist \"%1\" isn't an audio playlist" -msgstr "AudioDiskStream: Η Λίστα \"%1\" δεν είναι ηχητική λίστα αναπαÏ/γής" - -#: libs/ardour/audio_diskstream.cc:433 -msgid "AudioDiskstream %1: there is no existing playlist to make a copy of!" -msgstr "AudioDiskstream %1: δεν υπάÏχει λίστα αναπαÏ/γής για να γίνει αντιγÏαφή!" - -#: libs/ardour/audio_diskstream.cc:1114 -#: libs/ardour/audio_diskstream.cc:1125 -msgid "AudioDiskstream %1: when refilling, cannot read %2 from playlist at frame %3" -msgstr "AudioDiskstream %1: κατα την αναγόμωση, δεν μπόÏεσα να διαβάσω %2 από τη λίστα αναπαÏ/γής στο frame %3" - -#: libs/ardour/audio_diskstream.cc:1254 -msgid "AudioDiskstream %1: cannot read %2 from playlist at frame %3" -msgstr "AudioDiskstream %1: δεν μπόÏεσα να διαβάσω %2 από τη λίστα αναπαÏ/γής στο frame %3" - -#: libs/ardour/audio_diskstream.cc:1621 -#: libs/ardour/audio_diskstream.cc:1638 -msgid "AudioDiskstream %1: cannot write to disk" -msgstr "AudioDiskstream %1: δεν μποÏÏŽ να γÏάψω στο δίσκο" - -#: libs/ardour/audio_diskstream.cc:1698 -msgid "AudioDiskstream \"%1\": cannot flush captured data to disk!" -msgstr "AudioDiskstream \"%1\": αδÏνατη η εκκαθάÏιση δειγματοληπτικών δεδομÎνων στο δίσκο!" - -#: libs/ardour/audio_diskstream.cc:1796 -msgid "%1: could not create region for complete audio file" -msgstr "%1: δεν μπόÏεσα να δημιουÏγήσω πεÏιοχή για ολόκληÏο audio file" - -#: libs/ardour/audio_diskstream.cc:1819 -msgid "AudioDiskstream: could not create region for captured audio!" -msgstr "AudioDiskstream: δεν μπόÏεσα να δημιουÏγήσω πεÏιοχή για δειγματοληψίες!" - -#: libs/ardour/audio_diskstream.cc:1874 -msgid "programmer error: %1" -msgstr "σφάλμα Ï€ÏογÏαμματιστή: %1" - -#: libs/ardour/audio_diskstream.cc:2146 -msgid "AudioDiskstream: channel %1 out of range" -msgstr "AudioDiskstream: κανάλι %1 εκτός διαστήματος" - -#: libs/ardour/audio_diskstream.cc:2171 -msgid "%1:%2 new capture file not initialized correctly" -msgstr "%1:%2 νÎα δειγματοληψία δεν εκκινήθη σωστά" - -#: libs/ardour/audio_diskstream.cc:2404 -msgid "Location \"%1\" not valid for track loop (start >= end)" -msgstr "Η Τοποθεσία \"%1\" δεν είναι ικανή για track loop (αÏχή >= Ï„Îλος)" - -#: libs/ardour/audio_diskstream.cc:2485 -msgid "%1: cannot restore pending capture source file %2" -msgstr "%1: δεν μποÏÏŽ να ανοίξω το αÏχείο %2 από την απαιτοÏμενη πηγή" - -#: libs/ardour/audio_diskstream.cc:2507 -msgid "%1: incorrect number of pending sources listed - ignoring them all" -msgstr "%1: ετυπώθη λανθασμÎνος αÏιθμός απαιτοÏμενων πηγών - αγνοήθηκαν όλες" - -#: libs/ardour/audio_diskstream.cc:2523 -msgid "%1: cannot create whole-file region from pending capture sources" -msgstr "%1: αδÏνατη η δημιουÏγία ακÎÏαιας πεÏιοχής από τις απαιτοÏμενες πηγÎÏ‚ ηχοληψίας" - -#: libs/ardour/audio_diskstream.cc:2535 -msgid "%1: cannot create region from pending capture sources" -msgstr "%1: δεν μπόÏεσα να δημιουÏγήσω πεÏιοχή για τις απαιτοÏμενες πηγÎÏ‚" - -#: libs/ardour/audio_library.cc:92 -msgid "channels" -msgstr "κανάλια" - -#: libs/ardour/audio_library.cc:93 -msgid "samplerate" -msgstr "" - -#: libs/ardour/audio_library.cc:94 -msgid "resolution" -msgstr "ανάλυση" - -#: libs/ardour/audio_library.cc:95 -msgid "format" -msgstr "" - -#: libs/ardour/audio_library.cc:102 -msgid "Could not open %1. Audio Library not saved" -msgstr "Δεν μπόÏεσα να ανοίξω το %1. Η Audio Library δεν αποθηκεÏθηκε" - -#: libs/ardour/audio_playlist.cc:53 -#: libs/ardour/audio_playlist.cc:63 -#: libs/ardour/audio_playlist.cc:74 -#: libs/ardour/audio_playlist.cc:121 -#: libs/ardour/insert.cc:76 -#: libs/ardour/insert.cc:95 -#: libs/ardour/insert.cc:120 -#: libs/ardour/insert.cc:838 -#: libs/ardour/insert.cc:846 -#: libs/ardour/send.cc:39 -#: libs/ardour/send.cc:53 -#: libs/ardour/send.cc:62 -#: libs/ardour/session_state.cc:1621 -#: libs/ardour/session_state.cc:1667 -msgid "initial state" -msgstr "Ï€ÏωταÏχική κατάσταση" - -#: libs/ardour/audio_playlist.cc:275 -#: libs/ardour/audio_playlist.cc:769 -msgid "programming error: non-audio Region passed to remove_overlap in audio playlist" -msgstr "σφάλμα Ï€ÏογÏαμματισμοÏ: μη-ηχητική ΠεÏιοχή Ï€ÎÏασε σε remove_overlap στην audio playlist" - -#: libs/ardour/audio_playlist.cc:402 -msgid "programming error: non-audio Region tested for overlap in audio playlist" -msgstr "σφάλμα Ï€ÏογÏαμματισμοÏ: μη-ηχητική ΠεÏιοχή ελÎγχθη για υπεÏπήδηση(overlap) στην λίστα αναπαÏ/γής του ήχου" - -#: libs/ardour/audio_playlist.cc:878 -msgid "xfade change" -msgstr "αλλαγή xfade" - -#: libs/ardour/audio_playlist.cc:933 -msgid "region modified" -msgstr "η πεÏιοχή μετεβλήθη" - -#: libs/ardour/audio_track.cc:125 -#: libs/ardour/io.cc:1716 -#: libs/ardour/io.cc:1826 -msgid "Unknown connection \"%1\" listed for input of %2" -msgstr "Άγνωστη σÏνδεση \"%1\" στη λίστα εισόδου του %2" - -#: libs/ardour/audio_track.cc:127 -#: libs/ardour/io.cc:1718 -#: libs/ardour/io.cc:1828 -msgid "in 1" -msgstr "" - -#: libs/ardour/audio_track.cc:128 -#: libs/ardour/io.cc:1719 -#: libs/ardour/io.cc:1829 -msgid "No input connections available as a replacement" -msgstr "Καμία διαθÎσιμη input σÏνδεση ως εναλλακτική" - -#: libs/ardour/audio_track.cc:132 -#: libs/ardour/io.cc:1723 -#: libs/ardour/io.cc:1833 -msgid "Connection %1 was not available - \"in 1\" used instead" -msgstr "Η ΣÏνδεση %1 δεν ήταν διαθÎσιμη - Αντ'αυτής χÏησιμοποιήθηκε η \"in 1\" " - -#: libs/ardour/audio_track.cc:141 -#: libs/ardour/io.cc:1842 -msgid "improper input channel list in XML node (%1)" -msgstr "ακατάλληλη λίστα καναλιών εισόδου στον κόμβο XML (%1)" - -#: libs/ardour/audio_track.cc:186 -#: libs/ardour/audio_track.cc:199 -msgid "AudioTrack: diskstream \"%1\" not known by session" -msgstr "AudioTrack: το diskstream \"%1\" είναι μή αναγνωÏίσιμο από τη συνεδÏία" - -#: libs/ardour/audio_track.cc:297 -msgid "MIDI rec_enable control specification for %1 is incomplete, so it has been ignored" -msgstr "Η Ï€ÏοδιαγÏαφή ελÎγχου του MIDI rec_enable για το %1 είναι ημιτελής, με αποτÎλεσμα να αγνοηθεί" - -#: libs/ardour/audio_track.cc:309 -msgid "programming error: AudioTrack given state without diskstream!" -msgstr "σφάλμα Ï€ÏογÏαμματισμοÏ: εδόθη κατάσταση στην AudioTrack δίχως diskstream!" - -#: libs/ardour/audioengine.cc:144 -msgid "cannot activate JACK client" -msgstr "Ο JACK δεν μποÏεί να ενεÏγοποιηθεί" - -#: libs/ardour/audioengine.cc:395 -msgid "register audio input port called before engine was started" -msgstr "η register audio input port εκλήθη Ï€Ïιν να εκκινηθεί η engine" - -#: libs/ardour/audioengine.cc:426 -msgid "register audio output port called before engine was started" -msgstr "η register audio output port εκλήθη Ï€Ïίν να εκκινηθεί η engine" - -#: libs/ardour/audioengine.cc:487 -msgid "connect called before engine was started" -msgstr "η σÏνδεση εκλήθη Ï€Ïιν να εκκινηθεί η engine" - -#: libs/ardour/audioengine.cc:503 -msgid "AudioEngine: cannot connect %1 (%2) to %3 (%4)" -msgstr "AudioEngine: αδÏνατη η σÏνδεση %1 (%2) σε %3 (%4)" - -#: libs/ardour/audioengine.cc:516 -#: libs/ardour/audioengine.cc:545 -msgid "disconnect called before engine was started" -msgstr "η αποσÏνδεση εκλήθη Ï€Ïιν να εκκινηθεί η engine" - -#: libs/ardour/audioengine.cc:603 -msgid "get_port_by_name() called before engine was started" -msgstr "η Ïουτίνα get_port_by_name() εκλήθη Ï€Ïιν να εκκινηθεί η engine" - -#: libs/ardour/audioengine.cc:636 -msgid "get_ports called before engine was started" -msgstr "η Ïουτίνα get_ports εκλήθη Ï€Ïιν να εκκινηθεί η engine" - -#: libs/ardour/audioengine.cc:711 -msgid "get_nth_physical called before engine was started" -msgstr "η Ïουτίνα get_nth_physical εκλήθη Ï€Ïιν να εκκινηθεί η engine" - -#: libs/ardour/audioengine.cc:739 -msgid "get_port_total_latency() called with no JACK client connection" -msgstr "η Ïουτίνα get_port_total_latency() εκλήθη χωÏίς την εκκίνηση κάποιου JACK client" - -#: libs/ardour/audioengine.cc:745 -msgid "get_port_total_latency() called before engine was started" -msgstr "η Ïουτίνα get_port_total_latency() εκλήθη Ï€Ïιν να εκκινηθεί η engine" - -#: libs/ardour/audioengine.cc:869 -msgid "Unable to connect to JACK server" -msgstr "ΑδÏνατη η σÏνδεση στον JACK server" - -#: libs/ardour/audioengine.cc:872 -msgid "Could not connect to JACK server as \"%1\"" -msgstr "ΑδÏνατη η σÏνδεση στον JACK server ως \"%1\"" - -#: libs/ardour/audioengine.cc:877 -msgid "JACK server started" -msgstr "ΈναÏξη JACK server" - -#: libs/ardour/audioengine.cc:911 -msgid "cannot shutdown connection to JACK" -msgstr "ΑδÏνατος ο τεÏματισμός συνδÎσεως με τον JACK" - -#: libs/ardour/audioengine.cc:936 -msgid "failed to connect to JACK" -msgstr "Αποτυχία συνδÎσεως με τον JACK" - -#: libs/ardour/audioengine.cc:952 -msgid "could not reregister %1" -msgstr "αδÏνατη η επανακαταγÏαφή %1" - -#: libs/ardour/audioengine.cc:1009 -msgid "could not reconnect %1 and %2 (err = %3)" -msgstr "ΑδÏνατη η επανασÏνδεση %1 και %2 (err = %3)" - -#: libs/ardour/audiofilesource.cc:444 -#: libs/ardour/session_state.cc:3095 -msgid "there are already 1000 files with names like %1; versioning discontinued" -msgstr "ΥπάÏχουν ήδη 1000 αÏχεία με ονόματα όπως %1; μη-συνεχÎÏ‚ versioning" - -#: libs/ardour/audiofilesource.cc:458 -#: libs/ardour/session_state.cc:3109 -msgid "cannot rename audio file source from %1 to %2 (%3)" -msgstr "δεν μποÏÏŽ να μετονομάσω την πηγή του audio file από %1 σε %2 (%3)" - -#: libs/ardour/audiofilesource.cc:465 -#: libs/ardour/session_state.cc:3124 -msgid "cannot remove peakfile %1 for %2 (%3)" -msgstr "δεν μποÏÏŽ να απαλοίψω το peakfile %1 για %2 (%3)" - -#: libs/ardour/audiofilesource.cc:509 -msgid "FileSource: search path not set" -msgstr "FileSource: μονοπάτι αναζητήσεως δεν ετÎθη" - -#: libs/ardour/audiofilesource.cc:533 -msgid "" -"FileSource: \"%1\" is ambigous when searching %2\n" -"\t" -msgstr "" -"FileSource: \"%1\" είναι αμφίβολο κατά την αναζήτηση του %2\n" -"\t" - -#: libs/ardour/audiofilesource.cc:539 -msgid "Filesource: cannot find required file (%1): while searching %2" -msgstr "Filesource: δεν ευÏÎθη το απαιτοÏμενο αÏχείο (%1): κατά την αναζήτηση του %2" - -#: libs/ardour/audiofilesource.cc:562 -msgid "Filesource: cannot find required file (%1): %2" -msgstr "Filesource: δεν ευÏÎθη το απαιτοÏμενο αÏχείο (%1): %2" - -#: libs/ardour/audiofilesource.cc:567 -msgid "Filesource: cannot check for existing file (%1): %2" -msgstr "Filesource: δεν μποÏÏŽ να ελÎγξω για το υπάÏχον αÏχείο (%1): %2" - -#: libs/ardour/audiofilesource.cc:636 -#: libs/ardour/insert.cc:525 -#: libs/ardour/sndfilesource.cc:113 -msgid "programming error: %1" -msgstr "σφάλμα Ï€ÏογÏαμματισμοÏ: %1" - -#: libs/ardour/audiofilesource.cc:641 -msgid "cannot rename audio file for %1 to %2" -msgstr "δεν μποÏÏŽ να μετονομάσω το audio file για το %1 σε %2" - -#: libs/ardour/audiofilter.cc:45 -msgid "audiofilter: error creating name for new audio file based on %1" -msgstr "audiofilter: σφάλμα στη δημιουÏγία ονόματος για νÎο audio file βασισμÎνο σε %1" - -#: libs/ardour/audiofilter.cc:58 -msgid "audiofilter: error creating new audio file %1 (%2)" -msgstr "audiofilter: σφάλμα στη δημιουÏγία νÎου audio file %1 (%2)" - -#: libs/ardour/audioregion.cc:857 -#: libs/ardour/audioregion.cc:919 -msgid "fade in change" -msgstr "αλλαγή fade in" - -#: libs/ardour/audioregion.cc:1349 -#, c-format -msgid "normalized to %.2fdB" -msgstr "εξομαλÏνθηκε στα %.2fdB" - -#: libs/ardour/audioregion.cc:1367 -msgid "envelope change" -msgstr "αλλαγή envelope" - -#: libs/ardour/audiosource.cc:143 -msgid "poll on peak request pipe failed (%1)" -msgstr "" - -#: libs/ardour/audiosource.cc:150 -msgid "Error on peak thread request pipe" -msgstr "Σφάλμα στο peak thread request pipe" - -#: libs/ardour/audiosource.cc:183 -msgid "Error reading from peak request pipe" -msgstr "Σφάλμα στην ανάγνωση από peak request pipe" - -#: libs/ardour/audiosource.cc:215 -#: libs/ardour/session_butler.cc:80 -#: libs/ardour/session_midi.cc:1183 -msgid "Cannot create transport request signal pipe (%1)" -msgstr "Δεν μποÏÏŽ να δημιουÏγήσω transport request signal pipe (%1)" - -#: libs/ardour/audiosource.cc:220 -#: libs/ardour/audiosource.cc:225 -msgid "UI: cannot set O_NONBLOCK on peak request pipe (%1)" -msgstr "UI: δεν μποÏÏŽ να θÎσω O_NONBLOCK στο peak read pipe (%1)" - -#: libs/ardour/audiosource.cc:230 -msgid "AudioSource: could not create peak thread" -msgstr "AudioSource: δεν μπόÏεσα να δημιουÏγήσω peak thread" - -#: libs/ardour/audiosource.cc:308 -msgid "cannot rename peakfile for %1 from %2 to %3 (%4)" -msgstr "αδÏνατη η μετονομασία του peakfile για %1 από %2 σε %3 (%4)" - -#: libs/ardour/audiosource.cc:350 -msgid "AudioSource: cannot stat peakfile \"%1\"" -msgstr "" - -#: libs/ardour/audiosource.cc:451 -msgid "cannot read sample data for unscaled peak computation" -msgstr "δεν μποÏÏŽ να διαβάσω δεδομÎνα δείγματος για υπολογισμό μη-κλιμακώτου peak" - -#: libs/ardour/audiosource.cc:472 -#: libs/ardour/audiosource.cc:543 -#: libs/ardour/audiosource.cc:787 -#: libs/ardour/audiosource.cc:878 -msgid "AudioSource: cannot open peakpath \"%1\" (%2)" -msgstr "AudioSource: δεν μποÏÏŽ να ανοίξω το peakpath \"%1\" (%2)" - -#: libs/ardour/audiosource.cc:644 -msgid "AudioSource[%1]: peak read - cannot read %2 samples at offset %3" -msgstr "AudioSource[%1]: ανάγνωση peak - δεν μποÏÏŽ να διαβάσω %2 δείγματα στο (offset) %3" - -#: libs/ardour/audiosource.cc:798 -msgid "%1: could not write read raw data for peak computation (%2)" -msgstr "%1: δεν μποÏεσα να γÏάψω ανεγνωσμÎνα raw δεδομÎνα για τον υπολογισμό του peak (%2)" - -#: libs/ardour/audiosource.cc:823 -msgid "%1: could not write peak file data (%2)" -msgstr "%1: δεν μπόÏεσα να γÏάψω δεδομÎνα του αÏχείου peak (%2)" - -#: libs/ardour/automation_event.cc:65 -#: libs/ardour/location.cc:345 -#: libs/ardour/tempo.cc:226 -msgid "initial" -msgstr "Ï€ÏωταÏχικό" - -#: libs/ardour/automation_event.cc:232 -msgid "cleared" -msgstr "εκκαθαÏίσθη" - -#: libs/ardour/automation_event.cc:404 -msgid "added event" -msgstr "συμβάν Ï€ÏοστÎθηκε" - -#: libs/ardour/automation_event.cc:421 -msgid "removed event" -msgstr "συμβάν απαλοίφθηκε" - -#: libs/ardour/automation_event.cc:436 -msgid "removed multiple events" -msgstr "πολλαπλά συμβάντα απαλοίφθηκαν" - -#: libs/ardour/automation_event.cc:467 -#: libs/ardour/automation_event.cc:498 -msgid "removed range" -msgstr "διάστημα απαλοίφθηκε" - -#: libs/ardour/automation_event.cc:528 -msgid "event range adjusted" -msgstr "διάστημα συμβάντων Ïυθμίστηκε" - -#: libs/ardour/automation_event.cc:550 -msgid "event adjusted" -msgstr "συμβάν Ïυθμίστηκε" - -#: libs/ardour/automation_event.cc:665 -#: libs/ardour/automation_event.cc:770 -#: libs/ardour/panner.cc:1041 -msgid "programming error:" -msgstr "σφάλμα Ï€ÏογÏαμματισμοÏ:" - -#: libs/ardour/automation_event.cc:1079 -msgid "cut/copy/clear" -msgstr "κοπή/αντιγÏαφή/εκκαθάÏιση" - -#: libs/ardour/automation_event.cc:1112 -msgid "copy" -msgstr "αντιγÏαφή" - -#: libs/ardour/automation_event.cc:1180 -#: libs/ardour/playlist.cc:939 -msgid "paste" -msgstr "επικόλληση" - -#: libs/ardour/automation_event.cc:1235 -msgid "automation list: no x-coordinate stored for control point (point ignored)" -msgstr "λίστα αυτοματισμοÏ: καμία x-συντεταγμÎνη αποθηκευμÎνη για σημείο ελÎγχου (το σημείο αγνοήθηκε)" - -#: libs/ardour/automation_event.cc:1241 -msgid "automation list: no y-coordinate stored for control point (point ignored)" -msgstr "λίστα αυτοματισμοÏ: καμία y-συντεταγμÎνη αποθηκευμÎνη για σημείο ελÎγχου (το σημείο αγνοήθηκε)" - -#: libs/ardour/configuration.cc:80 -msgid "loading system configuration file %1" -msgstr "Ανάκληση αÏχείου Ïυθμίσεων συστήματος %1" - -#: libs/ardour/configuration.cc:83 -msgid "Ardour: cannot read system configuration file \"%1\"" -msgstr "Ardour: δεν μποÏÏŽ να διαβάσω το αÏχείο διαÏÏυθμίσεως του συστήματος \"%1\"" - -#: libs/ardour/configuration.cc:88 -msgid "Ardour: system configuration file \"%1\" not loaded successfully." -msgstr "Ardour: το αÏχείο διαÏÏυθμίσεως του συστήματος \"%1\" δεν φοÏτώθηκε επιτυχώς." - -#: libs/ardour/configuration.cc:105 -msgid "loading user configuration file %1" -msgstr "Ανάκληση αÏχείου Ïυθμίσεων χÏήστη %1" - -#: libs/ardour/configuration.cc:108 -msgid "Ardour: cannot read configuration file \"%1\"" -msgstr "Ardour: αÏχείο διαÏÏυθμίσεως μή αναγνώσιμο \"%1\"" - -#: libs/ardour/configuration.cc:113 -msgid "Ardour: user configuration file \"%1\" not loaded successfully." -msgstr "Ardour: αÏχείο Ïυθμίσεων χÏήστη \"%1\" δεν φοÏτώθηκε επιτυχώς." - -#: libs/ardour/configuration.cc:137 -msgid "Config file %1 not saved" -msgstr "ΑÏχείο Ïυθμίσεων %1 δεν αποθηκεÏθηκε" - -#: libs/ardour/configuration.cc:210 -msgid "ill-formed MIDI port specification in ardour rcfile (ignored)" -msgstr "κακοσχηματισμÎνος καθοÏισμός MIDI θÏÏας στο ardour rcfile (αγνοήθηκε)" - -#: libs/ardour/connection.cc:183 -msgid "Node for Connection has no \"name\" property" -msgstr "Κόμβος Ï€Ïος ΣÏνδεση δεν Îχει \"όνομα\" ιδιότητα" - -#: libs/ardour/connection.cc:191 -msgid "Node for Connection has no \"connections\" property" -msgstr "Κόμβος Ï€Ïος ΣÏνδεση δεν Îχει \"συνδÎσεις\" ιδιότητα" - -#: libs/ardour/connection.cc:227 -#: libs/ardour/io.cc:1902 -msgid "IO: badly formed string in XML node for inputs \"%1\"" -msgstr "IO: κακοφτιαγμÎνη γÏαμμή στον XML κόμβο για εισόδους \"%1\"" - -#: libs/ardour/connection.cc:232 -#: libs/ardour/io.cc:1907 -msgid "bad input string in XML node \"%1\"" -msgstr "κακή γÏαμμή εισόδου στον XML κόμβο \"%1\"" - -#: libs/ardour/control_protocol_manager.cc:80 -msgid "control protocol name \"%1\" has no descriptor" -msgstr "Το όνομα Ï€Ïωτοκόλλου ελÎγχου \"%1\" δεν Îχει descriptor" - -#: libs/ardour/control_protocol_manager.cc:85 -msgid "control protocol name \"%1\" could not be initialized" -msgstr "Το όνομα Ï€Ïωτοκόλλου ελÎγχου \"%1\" ήταν αδÏνατο να αÏχίσει" - -#: libs/ardour/control_protocol_manager.cc:141 -msgid "Instantiating mandatory control protocol %1" -msgstr "" - -#: libs/ardour/control_protocol_manager.cc:175 -msgid "Control protocol %1 not usable" -msgstr "Î Ïωτόκολλο ελÎγχου %1 μη χÏησιμοποιήσιμο" - -#: libs/ardour/control_protocol_manager.cc:187 -msgid "Control surface protocol discovered: \"%1\"" -msgstr "" - -#: libs/ardour/control_protocol_manager.cc:205 -msgid "ControlProtocolManager: cannot load module \"%1\" (%2)" -msgstr "ControlProtocolManager: δεν μποÏÏŽ να φοÏτώσω το module \"%1\" (%2)" - -#: libs/ardour/control_protocol_manager.cc:213 -msgid "ControlProtocolManager: module \"%1\" has no descriptor function." -msgstr "ControlProtocolManager: το module \"%1\" δεν Îχει descriptor function." - -#: libs/ardour/crossfade.cc:121 -msgid "Crossfade: no \"in\" region in state" -msgstr "Crossfade: χωÏίς \"in\" πεÏιοχή σε κατάσταση" - -#: libs/ardour/crossfade.cc:128 -msgid "Crossfade: no \"in\" region %1 found in playlist %2" -msgstr "Crossfade: no \"in\" πεÏιοχή %1 δεν ευÏÎθη στη λίστα αναπαÏ/γής %2" - -#: libs/ardour/crossfade.cc:138 -msgid "Crossfade: no \"out\" region in state" -msgstr "Crossfade: χωÏίς \"out\" πεÏιοχή σε κατάσταση" - -#: libs/ardour/crossfade.cc:145 -msgid "Crossfade: no \"out\" region %1 found in playlist %2" -msgstr "Crossfade: no \"out\" πεÏιοχή %1 δεν ευÏÎθη στη λίστα αναπαÏ/γής %2" - -#: libs/ardour/crossfade.cc:492 -msgid "active changed" -msgstr "αλλαγή ενεÏγοÏ" - -#: libs/ardour/crossfade.cc:741 -msgid "old-style crossfade information - no position information" -msgstr "παλαιοÏ-Ï„Ïπου crossfade πληÏοφοÏία - καμία πληÏοφοÏία θÎσεως" - -#: libs/ardour/curve.cc:112 -#: libs/ardour/globals.cc:340 -#: libs/ardour/insert.cc:454 -#: libs/ardour/session.cc:2466 -#: libs/ardour/session.cc:2518 -msgid "programming error: " -msgstr "σφάλμα Ï€ÏογÏαμματισμοÏ: " - -#: libs/ardour/cycle_timer.cc:37 -msgid "CycleTimer::get_mhz(): can't open /proc/cpuinfo" -msgstr "CycleTimer::get_mhz(): δεν ανοίγει το /proc/cpuinfo" - -#: libs/ardour/cycle_timer.cc:49 -msgid "CycleTimer::get_mhz(): cannot locate cpu MHz in /proc/cpuinfo" -msgstr "CycleTimer::get_mhz(): δεν ευÏÎθη το cpu MHz στο /proc/cpuinfo" - -#: libs/ardour/cycle_timer.cc:72 -msgid "cannot locate cpu MHz in /proc/cpuinfo" -msgstr "δεν ευÏÎθη το cpu MHz στο /proc/cpuinfo" - -#: libs/ardour/destructive_filesource.cc:188 -msgid "DestructiveFileSource: \"%1\" bad read retval: %2 of %5 (%3: %4)" -msgstr "ΚαταστÏεπτικήΠηγήΑÏχείου: \"%1\" κακή ανάγνωση retval: %2 of %5 (%3: %4)" - -#: libs/ardour/destructive_filesource.cc:201 -#: libs/ardour/destructive_filesource.cc:243 -#: libs/ardour/destructive_filesource.cc:250 -msgid "DestructiveFileSource: \"%1\" bad write (%2)" -msgstr "DestructiveFileSource: \"%1\" κακή εγγÏαφή (%2)" - -#: libs/ardour/globals.cc:109 -msgid "no MIDI ports specified: no MMC or MTC control possible" -msgstr "καμία MIDI θÏÏα δεν επελÎχθη: Îλεγχος MMC ή MTC αδÏνατος" - -#: libs/ardour/globals.cc:124 -msgid "MIDI port specifications for \"%1\" are not understandable." -msgstr "Οι Ï€ÏοδιαγÏαφÎÏ‚ της θÏÏας MIDI για το \"%1\" δεν είναι κατανοητÎÏ‚." - -#: libs/ardour/globals.cc:137 -#: libs/ardour/globals.cc:141 -#: libs/ardour/globals.cc:145 -msgid "default" -msgstr "Ï€ÏοκαθοÏισμÎνο" - -#: libs/ardour/globals.cc:173 -msgid "No MMC control (MIDI port \"%1\" not available)" -msgstr "ΧωÏίς Îλεγχο MMC (θÏÏα MIDI \"%1\" μη διαθÎσιμη)" - -#: libs/ardour/globals.cc:179 -msgid "No MTC support (MIDI port \"%1\" not available)" -msgstr "ΧωÏίς Îλεγχο MTC (θÏÏα MIDI \"%1\" μη διαθÎσιμη)" - -#: libs/ardour/globals.cc:184 -msgid "No MIDI parameter support (MIDI port \"%1\" not available)" -msgstr "ΧωÏίς υποστήÏιξη MIDI παÏαμÎÏ„Ïων (θÏÏα MIDI \"%1\" μη διαθÎσιμη)" - -#: libs/ardour/import.cc:75 -msgid "Import: cannot open input sound file \"%1\"" -msgstr "Εισαγωγή: δεν μποÏÏŽ να ανοίξω το εισαγμÎνο αÏχείο ήχου \"%1\"" - -#: libs/ardour/import.cc:80 -msgid "resampling audio" -msgstr "επανά-ληψη(resampling) ήχου" - -#: libs/ardour/import.cc:84 -msgid "Import: cannot open converted sound file \"%1\"" -msgstr "Εισαγωγή: δεν μποÏÏŽ να ανοίξω το Ï„ÏοποποιημÎνο αÏχείο ήχου \"%1\"" - -#: libs/ardour/import.cc:89 -msgid "Import: error while resampling sound file \"%1\"" -msgstr "Εισαγωγή: σφάλμα κατά την Ï„Ïοποποίηση αÏχείου \"%1\"" - -#: libs/ardour/import.cc:148 -msgid "Session::import_audiofile: cannot open new file source for channel %1" -msgstr "ΣυνεδÏία::εισαγωγή_αÏχείου: δεν μποÏÏŽ να ανοίξω νÎα πηγή αÏχείου για το κανάλι %1" - -#: libs/ardour/import.cc:167 -msgid "converting audio" -msgstr "μετατÏοπή ήχου" - -#: libs/ardour/import.cc:199 -msgid "building region" -msgstr "χτίσιμο πεÏιοχής" - -#: libs/ardour/import.cc:201 -msgid "building regions" -msgstr "χτίσιμο πεÏιοχών" - -#: libs/ardour/import.cc:325 -msgid "Import: could not open temp file: %1" -msgstr "Εισαγωγή: δεν μπόÏεσα να ανοίξω το temp αÏχείο: %1" - -#: libs/ardour/import.cc:334 -msgid "Import: src_new() failed : %1" -msgstr "Εισαγωγή: src_new() απÎτυχε : %1" - -#: libs/ardour/import.cc:362 -msgid "Import: %1" -msgstr "Εισαγωγή: %1" - -#: libs/ardour/insert.cc:644 -#: libs/ardour/insert.cc:936 -msgid "XML node describing insert is missing the `type' field" -msgstr "Στον κόμβο XML που πεÏιγÏάφει το insert λείπει το πεδίο `type'" - -#: libs/ardour/insert.cc:653 -msgid "unknown plugin type %1 in plugin insert state" -msgstr "άγνωστος Ï„Ïπος plugin %1 στην κατάσταση εισαχθÎντων plugins" - -#: libs/ardour/insert.cc:665 -msgid "XML node describing insert is missing the `id' field" -msgstr "Στον κόμβο XML που πεÏιγÏάφει το insert λείπει το πεδίο `id'" - -#: libs/ardour/insert.cc:678 -msgid "" -"Found a reference to a plugin (\"%1\") that is unknown.\n" -"Perhaps it was removed or moved since it was last used." -msgstr "" -"ΕυÏÎθη μια αναφοÏά σε plugin (\"%1\") που είναι άγνωστο.\n" -"Ίσως Îχει διαγÏαφεί ή μετακινηθεί από την τελευταία του χÏήση." - -#: libs/ardour/insert.cc:716 -#: libs/ardour/insert.cc:953 -msgid "XML node describing insert is missing a Redirect node" -msgstr "Στον κόμβο XML που πεÏιγÏάφει το insert λείπει Îνας κόμβος Redirect" - -#: libs/ardour/insert.cc:721 -msgid "XML node describing a plugin insert is missing the `%1' information" -msgstr "Στον κόμβο XML που πεÏιγÏάφει Îνα plugin insert λείπουν οι πληÏοφοÏίες `%1' " - -#: libs/ardour/insert.cc:745 -msgid "PluginInsert: Auto: no ladspa port number" -msgstr "PluginInsert: Auto: χωÏίς αÏιθμό θÏÏας ladspa" - -#: libs/ardour/insert.cc:752 -msgid "PluginInsert: Auto: port id out of range" -msgstr "PluginInsert: Auto: το id θÏÏας είναι εκτός πεδίου" - -#: libs/ardour/insert.cc:768 -msgid "XML node describing a port automation is missing the `%1' information" -msgstr "Στον κόμβο XML που πεÏιγÏάφει Îναν αυτοματισμό θÏÏας λείπουν οι πληÏοφοÏίες `%1' " - -#: libs/ardour/insert.cc:854 -msgid "PortInsert: cannot add input port" -msgstr "PortInsert: δεν μποÏεί να Ï€Ïοστεθει θÏÏα εισόδου" - -#: libs/ardour/insert.cc:859 -msgid "PortInsert: cannot add output port" -msgstr "PortInsert: δεν μποÏεί να Ï€Ïοστεθεί θÏÏα εξόδου" - -#: libs/ardour/insert.cc:941 -msgid "non-port insert XML used for port plugin insert" -msgstr "εισαγωγή μη-θÏÏας XML για χÏήση σε εισαγωγή plugin θÏÏας" - -#: libs/ardour/io.cc:598 -msgid "IO: cannot disconnect input port %1 from %2" -msgstr "IO: δεν μποÏει να αποσυνδεθεί η θÏÏα εισόδου %1 από %2" - -#: libs/ardour/io.cc:666 -msgid "IO: cannot disconnect output port %1 from %2" -msgstr "IO: δεν μποÏεί να αποσυνδεθεί η θÏÏα εξόδου %1 από %2" - -#: libs/ardour/io.cc:807 -#: libs/ardour/io.cc:1151 -#: libs/ardour/io.cc:1277 -#, c-format -msgid "%s/out" -msgstr "%s/out" - -#: libs/ardour/io.cc:809 -#: libs/ardour/io.cc:1153 -#: libs/ardour/io.cc:1279 -#: libs/ardour/io.cc:2849 -#, c-format -msgid "%s/out %u" -msgstr "%s/out %u" - -#: libs/ardour/io.cc:813 -#: libs/ardour/io.cc:1158 -#: libs/ardour/io.cc:1283 -msgid "IO: cannot register output port %1" -msgstr "IO: δεν μποÏει να καταχώÏηθεί η θÏÏα εξόδου %1" - -#: libs/ardour/io.cc:908 -#: libs/ardour/io.cc:1011 -#: libs/ardour/io.cc:1117 -#, c-format -msgid "%s/in" -msgstr "%s/in" - -#: libs/ardour/io.cc:910 -#: libs/ardour/io.cc:1014 -#: libs/ardour/io.cc:1120 -#: libs/ardour/io.cc:2819 -#, c-format -msgid "%s/in %u" -msgstr "%s/in %u" - -#: libs/ardour/io.cc:914 -#: libs/ardour/io.cc:1020 -#: libs/ardour/io.cc:1125 -msgid "IO: cannot register input port %1" -msgstr "IO: δεν μποÏεί να καταχώÏηθεί η θÏÏα εισόδου %1" - -#: libs/ardour/io.cc:1541 -msgid "IO::connecting_became_legal() called without a pending state node" -msgstr "IO::connecting_became_legal() εκλήθη χωÏίς κόμβο καταστάσεως εν αναμονή" - -#: libs/ardour/io.cc:1564 -msgid "IO::ports_became_legal() called without a pending state node" -msgstr "IO::ports_became_legal() εκλήθη χωÏίς κόμβο καταστάσεως εν αναμονή" - -#: libs/ardour/io.cc:1594 -msgid "incorrect XML node \"%1\" passed to IO object" -msgstr "μη-σωστός κόμβος XML \"%1\" Ï€ÎÏασε στο IO αντικείμενο" - -#: libs/ardour/io.cc:1649 -msgid "MIDI gain control specification for %1 is incomplete, so it has been ignored" -msgstr "Η Ï€ÏοδιαγÏαφή ελÎγχου του MIDI gain για το %1 είναι ημιτελής, με αποτÎλεσμα να αγνοηθεί" - -#: libs/ardour/io.cc:1739 -#: libs/ardour/io.cc:1851 -msgid "Unknown connection \"%1\" listed for output of %2" -msgstr "Άγνωστη σÏνδεση \"%1\" καταχωÏήθη για την Îξοδο του %2" - -#: libs/ardour/io.cc:1741 -#: libs/ardour/io.cc:1853 -msgid "out 1" -msgstr "" - -#: libs/ardour/io.cc:1742 -#: libs/ardour/io.cc:1854 -msgid "No output connections available as a replacement" -msgstr "Καμία σÏνδεση output διαθÎσιμη σαν εναλλακτική" - -#: libs/ardour/io.cc:1746 -#: libs/ardour/io.cc:1858 -msgid "Connection %1 was not available - \"out 1\" used instead" -msgstr "Η σÏνδεση %1 δεν ήταν διαθÎσιμη - αντ'αυτής χÏησιμοποιήθηκε η \"out 1\" " - -#: libs/ardour/io.cc:1760 -msgid "%1: cannot create I/O ports" -msgstr "%1: θÏÏες I/O δεν μποÏοÏν να δημιουÏγηθοÏν" - -#: libs/ardour/io.cc:1867 -msgid "improper output channel list in XML node (%1)" -msgstr "ασαφής λίστα καναλιών εξόδου στον κόμβο XML (%1)" - -#: libs/ardour/io.cc:1952 -msgid "IO: badly formed string in XML node for outputs \"%1\"" -msgstr "IO: δÏσμοÏφη γÏαμμή στον κόμβο XML για τις εξόδους \"%1\"" - -#: libs/ardour/io.cc:1957 -msgid "IO: bad output string in XML node \"%1\"" -msgstr "IO: κακή γÏαμμή εξόδουστον κόμβο XML \"%1\"" - -#: libs/ardour/io.cc:2525 -msgid "%1: could not open automation event file \"%2\"" -msgstr "%1: δεν μπόÏεσα να ανοίξω το αÏχείο συμβάντων Î±Ï…Ï„Î¿Î¼Î±Ï„Î¹ÏƒÎ¼Î¿Ï \"%2\"" - -#: libs/ardour/io.cc:2564 -msgid "%1: cannot open automation event file \"%2\"" -msgstr "%1: δεν μποÏÏŽ να ανοίξω το αÏχείο συμβάντων Î±Ï…Ï„Î¿Î¼Î±Ï„Î¹ÏƒÎ¼Î¿Ï \"%2\"" - -#: libs/ardour/io.cc:2579 -msgid "badly formed version number in automation event file \"%1\"" -msgstr "δÏσμοÏφος αÏιθμός εκδόσεως στο αÏχείο συμβάντων Î±Ï…Ï„Î¿Î¼Î±Ï„Î¹ÏƒÎ¼Î¿Ï \"%1\"" - -#: libs/ardour/io.cc:2583 -msgid "no version information in automation event file \"%1\"" -msgstr "δεν υπάÏχουν πληÏοφοÏίες πεÏί εκδόσεων στο αÏχείο συμβάντων Î±Ï…Ï„Î¿Î¼Î±Ï„Î¹ÏƒÎ¼Î¿Ï \"%1\"" - -#: libs/ardour/io.cc:2588 -msgid "mismatched automation event file version (%1)" -msgstr "αταίÏιαστη Îκδοση αÏχείου συμβάντων Î±Ï…Ï„Î¿Î¼Î±Ï„Î¹ÏƒÎ¼Î¿Ï (%1)" - -#: libs/ardour/io.cc:2596 -msgid "badly formatted automation event record at line %1 of %2 (ignored)" -msgstr "κακώς φοÏμαÏισμÎνη καταγÏαφή συμβάντων Î±Ï…Ï„Î¿Î¼Î±Ï„Î¹ÏƒÎ¼Î¿Ï ÏƒÏ„Î· γÏαμμή %1 of %2 (αγνοήθηκε)" - -#: libs/ardour/io.cc:2616 -msgid "dubious automation event found (and ignored)" -msgstr "αβÎβαιο συμβάν Î±Ï…Ï„Î¿Î¼Î±Ï„Î¹ÏƒÎ¼Î¿Ï ÎµÏ…ÏÎθηκε (και αγνοήθηκε)" - -#: libs/ardour/io.cc:2620 -#: libs/ardour/panner.cc:438 -#: libs/ardour/redirect.cc:148 -msgid "loaded from disk" -msgstr "φοÏτώθηκε από το δίσκο" - -#: libs/ardour/io.cc:2791 -msgid "automation write/touch" -msgstr "αυτοματισμός εγγÏαφή/αφή(write/touch)" - -#: libs/ardour/ladspa_plugin.cc:87 -msgid "LADSPA: module has no descriptor function." -msgstr "LADSPA: το module δεν Îχει ενδεικτική λειτουÏγία." - -#: libs/ardour/ladspa_plugin.cc:92 -msgid "LADSPA: plugin has gone away since discovery!" -msgstr "LADSPA: το plugin την 'κοπάνισε' μετά την ανακάλυψη του!" - -#: libs/ardour/ladspa_plugin.cc:99 -msgid "LADSPA: \"%1\" cannot be used, since it cannot do inplace processing" -msgstr "LADSPA: \"%1\" δεν μποÏεί να χÏησιμοποιηθεί, εφ'όσον δεν μποÏεί να κάνει επι τόπου επεξεÏγασία" - -#: libs/ardour/ladspa_plugin.cc:329 -msgid "illegal parameter number used with plugin \"%1\". This mayindicate a change in the plugin design, and presets may beinvalid" -msgstr "παÏάνομος αÏιθμός παÏαμÎÏ„Ïου σε χÏήση με το plugin \"%1\". Ίσως να ενδείκνυται αλλαγή στο σχεδιασμό του plugin, και οι Ïυθμίσεις ίσως να είναι άκυÏες" - -#: libs/ardour/ladspa_plugin.cc:430 -msgid "Bad node sent to LadspaPlugin::set_state" -msgstr "Κακός κόμβος εστάλη στο LadspaPlugin::set_state" - -#: libs/ardour/ladspa_plugin.cc:443 -msgid "LADSPA: no ladspa port number" -msgstr "LADSPA: κανείς αÏιθμός θÏÏας ladspa" - -#: libs/ardour/ladspa_plugin.cc:449 -msgid "LADSPA: no ladspa port data" -msgstr "LADSPA: κανÎνα δεδομÎνο θÏÏας ladspa" - -#: libs/ardour/ladspa_plugin.cc:498 -msgid "LADSPA LadspaPlugin MIDI control specification for port %1 is incomplete, so it has been ignored" -msgstr "Ο καθοÏισμός ελÎγχου LADSPA LadspaPlugin για MIDI για την θÏÏα %1 είναι ημιτελής, Îτσι αγνοήθηκε." - -#: libs/ardour/location.cc:269 -msgid "incorrect XML node passed to Location::set_state" -msgstr "λανθασμÎνος κόμβος XML Ï€ÎÏασε στην Τοποθεσία::set_state" - -#: libs/ardour/location.cc:276 -msgid "XML node for Location has no name information" -msgstr "Ο κόμβος XML για την Τοποθεσία δεν Îχει πληÏοφοÏίες ονόματος" - -#: libs/ardour/location.cc:283 -msgid "XML node for Location has no start information" -msgstr "Ο κόμβος XML για την Τοποθεσία δεν Îχει πληÏοφοÏίες ενάÏξεως" - -#: libs/ardour/location.cc:294 -msgid "XML node for Location has no end information" -msgstr "Ο κόμβος XML για την Τοποθεσία δεν Îχει πληÏοφοÏίες Ï„Îλους" - -#: libs/ardour/location.cc:303 -msgid "XML node for Location has no flags information" -msgstr "Ο κόμβος XML για την Τοποθεσία δεν Îχει πληÏοφοÏίες για σημαίες(flags)" - -#: libs/ardour/location.cc:391 -msgid "Locations: attempt to use unknown location as selected location" -msgstr "Τοποθεσίες: απόπειÏα να χÏησιμοποιηθεί άγνωστη τοποθεσία σαν επιλεγμÎνη τοποθεσία" - -#: libs/ardour/location.cc:418 -#: libs/ardour/playlist.cc:1187 -msgid "clear" -msgstr "εκκαθάÏιση" - -#: libs/ardour/location.cc:443 -msgid "clear markers" -msgstr "εκκαθάÏιση στιγμάτων" - -#: libs/ardour/location.cc:471 -msgid "clear ranges" -msgstr "εκκαθάÏιση διαστημάτων" - -#: libs/ardour/location.cc:489 -msgid "add" -msgstr "Ï€Ïόσθεση" - -#: libs/ardour/location.cc:527 -msgid "remove" -msgstr "απαλοιφή" - -#: libs/ardour/location.cc:567 -msgid "incorrect XML mode passed to Locations::set_state" -msgstr "λανθασμÎνο XML mode Ï€ÎÏασε στις Τοποθεσίες::set_state" - -#: libs/ardour/mtc_slave.cc:196 -msgid "MTC Slave: atomic read of current time failed, sleeping!" -msgstr "MTC Slave: ατομική ανάγνωση του Ï„ÏÎχοντος χÏόνου απÎτυχε, πίσω για Ïπνο!" - -#: libs/ardour/named_selection.cc:77 -msgid "Chunk %1 uses an unknown playlist \"%2\"" -msgstr "Το κομμάτι %1 χÏησιμοποιεί άγνωστη λίστα αναπαÏ/γής \"%2\"" - -#: libs/ardour/named_selection.cc:80 -msgid "Chunk %1 contains misformed playlist information" -msgstr "Το κομμάτι %1 πεÏιÎχει δÏσμοÏφες πληÏοφοÏίες για τη λίστα αναπαÏ/γής" - -#: libs/ardour/panner.cc:256 -msgid "MIDI pan control specification is incomplete, so it has been ignored" -msgstr "Η Ï€ÏοδιαγÏαφή ελÎγχου του MIDI pan είναι ημιτελής, με αποτÎλεσμα να αγνοηθεί" - -#: libs/ardour/panner.cc:361 -msgid "automation write pass" -msgstr "Ï€ÎÏασμα εγγÏαφής αυτοματισμοÏ" - -#: libs/ardour/panner.cc:401 -#, c-format -msgid "error writing pan automation file (%s)" -msgstr "σφάλμα στην εγγÏαφή του pan στο αÏχείο Î±Ï…Ï„Î¿Î¼Î±Ï„Î¹ÏƒÎ¼Î¿Ï (%s)" - -#: libs/ardour/panner.cc:429 -msgid "badly formatted pan automation event record at line %1 of %2 (ignored) [%3]" -msgstr "δÏσμοÏφη εγγÏαφή συμβάντος pan Î±Ï…Ï„Î¿Î¼Î±Ï„Î¹ÏƒÎ¼Î¿Ï ÏƒÏ„Î· γÏαμμή %1 of %2 (αγνοήθηκε) [%3]" - -#: libs/ardour/panner.cc:944 -msgid "badly-formed positional data for Multi2dPanner - ignored" -msgstr "δÏσμοÏφα δεδομÎνα θÎσεως για το Multi2dPanner - αγνοήθηκε" - -#: libs/ardour/panner.cc:1237 -msgid "cannot open pan automation file \"%1\" for saving (%s)" -msgstr "δεν μποÏÏŽ να ανοίξω αÏχείο Î±Ï…Ï„Î¿Î¼Î±Ï„Î¹ÏƒÎ¼Î¿Ï Ï„Î¿Ï… pan \"%1\" για αποθήκευση (%s)" - -#: libs/ardour/panner.cc:1273 -msgid "cannot open pan automation file %1 (%2)" -msgstr "δεν μποÏÏŽ να ανοίξω αÏχείο Î±Ï…Ï„Î¿Î¼Î±Ï„Î¹ÏƒÎ¼Î¿Ï Ï„Î¿Ï… pan %1 (%2)" - -#: libs/ardour/panner.cc:1286 -msgid "badly formed version number in pan automation event file \"%1\"" -msgstr "δÏσμοÏφος αÏιθμός εκδόσεως στο αÏχείο συμβάντων Î±Ï…Ï„Î¿Î¼Î±Ï„Î¹ÏƒÎ¼Î¿Ï Ï„Î¿Ï… pan \"%1\"" - -#: libs/ardour/panner.cc:1290 -msgid "no version information in pan automation event file \"%1\" (first line = %2)" -msgstr "καμία πληÏοφοÏία εκδόσεως στο αÏχείο συμβάντων Î±Ï…Ï„Î¿Î¼Î±Ï„Î¹ÏƒÎ¼Î¿Ï Ï„Î¿Ï… pan \"%1\" (Ï€Ïώτη γÏαμμή = %2)" - -#: libs/ardour/panner.cc:1296 -msgid "mismatched pan automation event file version (%1)" -msgstr "αταίÏιαστη Îκδοση αÏχείου συμβάντων Î±Ï…Ï„Î¿Î¼Î±Ï„Î¹ÏƒÎ¼Î¿Ï Î³Î¹Î± το pan (%1)" - -#: libs/ardour/panner.cc:1310 -msgid "too many panner states found in pan automation file %1" -msgstr "πάÏα πολλÎÏ‚ καταστάσεις panner ευÏÎθησαν στο αÏχείο των αυτοματισμών pan %1" - -#: libs/ardour/panner.cc:1451 -msgid "Unknown panner plugin \"%1\" found in pan state - ignored" -msgstr "Άγνωστο plugin για panner \"%1\" ευÏÎθη στην κατάσταση pan - αγνοήθηκε" - -#: libs/ardour/panner.cc:1457 -msgid "panner plugin node has no type information!" -msgstr "ο κόμβος για τα plugin του panner δεν Îχει πληÏοφοÏίες Ï„Ïπου!" - -#: libs/ardour/playlist.cc:253 -msgid "playlist const copy constructor called" -msgstr "λίστα αναπαÏ/γής const εκλήθη από κατασκευαστή αντιγÏάφου" - -#: libs/ardour/playlist.cc:259 -msgid "playlist non-const copy constructor called" -msgstr "λίστα αναπαÏ/γής non-const εκλήθη από κατασκευαστή αντιγÏάφου" - -#: libs/ardour/playlist.cc:499 -msgid "add region" -msgstr "Ï€Ïόσθεση πεÏιοχής" - -#: libs/ardour/playlist.cc:554 -msgid "replace region" -msgstr "αντικατάσταση πεÏιοχής" - -#: libs/ardour/playlist.cc:567 -msgid "remove region" -msgstr "απαλοιφή πεÏιοχής" - -#: libs/ardour/playlist.cc:614 -msgid "separate" -msgstr "ξεχωÏιστό" - -#: libs/ardour/playlist.cc:878 -msgid "cut" -msgstr "κοπή" - -#: libs/ardour/playlist.cc:968 -msgid "duplicate" -msgstr "αντιγÏαφή" - -#: libs/ardour/playlist.cc:1023 -msgid "split" -msgstr "διαχωÏισμός" - -#: libs/ardour/playlist.cc:1100 -msgid "%1: bounds changed received for region (%2)not in playlist" -msgstr "%1: τα αλλαγμÎνα ÏŒÏια που ελήφθησαν για την πεÏιοχή (%2)δεν είναι στη λίστα αναπαÏ/γής" - -#: libs/ardour/playlist.cc:1361 -msgid "Playlist: cannot create region from state file" -msgstr "Playlist: αδÏνατη η δημιουÏγία ΠεÏιοχής από αÏχείο καταστάσεως" - -#: libs/ardour/playlist.cc:1721 -msgid "nudged" -msgstr "νυχθÎν" - -#: libs/ardour/playlist_factory.cc:49 -#: libs/ardour/playlist_factory.cc:64 -msgid "programming error: Playlist::createRegion called with unknown Region type" -msgstr "σφάλμα Ï€ÏογÏαμματισμοÏ: Playlist::createRegion εκλήθη με άγνωστο Ï„Ïπο Πε" - -#: libs/ardour/playlist_factory.cc:86 -msgid "programming error: Playlist::copyPlaylist called with unknown Playlist type" -msgstr "σφάλμα Ï€ÏογÏαμματισμοÏ: Playlist::copyPlaylist με άγνωστο Ï„Ïπο Playlist" - -#: libs/ardour/plugin.cc:328 -msgid "Could not locate HOME. Preset not saved." -msgstr "Δεν μπόÏεσα να βÏÏŽ το HOME. Î Ïο-ÏÏθμιση δεν αποθηκεÏθηκε." - -#: libs/ardour/plugin.cc:338 -#: libs/ardour/plugin.cc:344 -msgid "Could not create %1. Preset not saved. (%2)" -msgstr "Δεν μπόÏεσα να δημιουÏγήσω το %1. Î Ïο-ÏÏθμιση δεν αποθηκεÏθηκε. (%2)" - -#: libs/ardour/plugin.cc:349 -msgid "Error saving presets file %1." -msgstr "Σφάλμα στην αποθήκευση αÏχείου Ï€Ïο-Ïυθμίσεων %1." - -#: libs/ardour/plugin_manager.cc:194 -msgid "Could not parse rdf file: %1" -msgstr "Δεν μπόÏεσα να αναλÏσω το αÏχείο rdf: %1" - -#: libs/ardour/plugin_manager.cc:235 -msgid "LADSPA: cannot load module \"%1\" (%2)" -msgstr "LADSPA: δεν μποÏÏŽ να φοÏτώσω το module \"%1\" (%2)" - -#: libs/ardour/plugin_manager.cc:242 -msgid "LADSPA: module \"%1\" has no descriptor function." -msgstr "LADSPA: το module \"%1\" δεν Îχει λειτουÏγία πεÏιγÏαφής." - -#: libs/ardour/plugin_manager.cc:297 -msgid "VST: cannot load module from \"%1\"" -msgstr "VST: δεν μποÏÏŽ να φοÏτώσω module από \"%1\"" - -#: libs/ardour/plugin_manager.cc:302 -msgid "You asked ardour to not use any VST plugins" -msgstr "Ζητήσατε απ'το Ardour να μή χÏησιμοποιήσει VST plugins" - -#: libs/ardour/plugin_manager.cc:305 -msgid "This version of ardour has no support for VST plugins" -msgstr "Η παÏοÏσα Îκδοση του ardour δεν υποστηÏίζει VST plugins" - -#: libs/ardour/plugin_manager.cc:312 -msgid "LADSPA: cannot load module from \"%1\"" -msgstr "LADSPA: δεν μποÏÏŽ να φοÏτώσω module από \"%1\"" - -#: libs/ardour/plugin_manager.cc:374 -#: libs/ardour/plugin_manager.cc:386 -msgid "Unknown" -msgstr "Άγνωστο" - -#: libs/ardour/plugin_manager.cc:464 -msgid "VST plugin %1 does not support processReplacing, and so cannot be used in ardour at this time" -msgstr "Το VST plugin %1 δεν υποστηÏίζει processReplacing, και Îτσι δεν μποÏεί να χÏησιμοποιηθεί στον ardour αυτή τη φοÏά" - -#: libs/ardour/recent_sessions.cc:44 -msgid "cannot open recent session file %1 (%2)" -msgstr "δεν μποÏÏŽ να ανοίξω το Ï€Ïόσφατο αÏχείο συνεδÏίας %1 (%2)" - -#: libs/ardour/redirect.cc:77 -msgid "programming error: unknown Redirect type in Redirect::Clone!\n" -msgstr "σφάλμα Ï€ÏογÏαμματισμοÏ: άγνωστος Ï„Ïπος Redirect στο Redirect::Clone!\n" - -#: libs/ardour/redirect.cc:102 -#: libs/ardour/utils.cc:203 -msgid "pre" -msgstr "pre" - -#: libs/ardour/redirect.cc:104 -#: libs/ardour/utils.cc:206 -msgid "post" -msgstr "post" - -#: libs/ardour/redirect.cc:107 -msgid "Redirect: unknown placement string \"%1\" (ignored)" -msgstr "Redirect: άγνωστη γÏαμμή τοποθετήσεως \"%1\" (αγνοήθηκε)" - -#: libs/ardour/redirect.cc:125 -msgid "%1: cannot open %2 to load automation data (%3)" -msgstr "%1: δεν μποÏÏŽ να ανοίξω %2 για ανάκληση δεδομÎνων Î±Ï…Ï„Î¿Î¼Î±Ï„Î¹ÏƒÎ¼Î¿Ï (%3)" - -#: libs/ardour/redirect.cc:154 -msgid "%1: cannot load automation data from %2" -msgstr "%1: δεν μποÏοÏν να ανακληθοÏν δεδομÎνα Î±Ï…Ï„Î¿Î¼Î±Ï„Î¹ÏƒÎ¼Î¿Ï Î±Ï€ÏŒ %2" - -#: libs/ardour/redirect.cc:175 -msgid "%1: cannot open %2 to store automation data (%3)" -msgstr "%1: δεν μποÏÏŽ να ανοίξω %2 για αποθήκευση δεδομÎνων Î±Ï…Ï„Î¿Î¼Î±Ï„Î¹ÏƒÎ¼Î¿Ï (%3)" - -#: libs/ardour/redirect.cc:194 -#: libs/ardour/redirect.cc:201 -msgid "%1: could not save automation state to %2" -msgstr "%1: δεν μπόÏεσα να αποθηκεÏσω την κατάσταση Î±Ï…Ï„Î¿Î¼Î±Ï„Î¹ÏƒÎ¼Î¿Ï ÏƒÏ„Î¿ %2" - -#: libs/ardour/redirect.cc:246 -msgid "Could not get state from Redirect (%1). Problem with save_automation" -msgstr "Δεν μπόÏεσα να πάÏω κατάσταση από το Redirect (%1). Î Ïόβλημα με την αποθήκευση_αυτοματισμοÏ" - -#: libs/ardour/redirect.cc:296 -msgid "incorrect XML node \"%1\" passed to Redirect object" -msgstr "λανθασμÎνος κόμβος XML \"%1\" Ï€ÎÏασε στο αντικείμενο Redirect" - -#: libs/ardour/redirect.cc:318 -msgid "%1: Automation node has no path property" -msgstr "%1: Ο Κόμβος Î±Ï…Ï„Î¿Î¼Î±Ï„Î¹ÏƒÎ¼Î¿Ï Î´ÎµÎ½ Îχει οÏισμÎνο path" - -#: libs/ardour/redirect.cc:343 -msgid "XML node describing an IO is missing an IO node" -msgstr "Στον κόμβο XML που πεÏιγÏάφει I/O λείπει Îνας κόμβος IO" - -#: libs/ardour/redirect.cc:348 -msgid "XML node describing a redirect is missing the `active' field" -msgstr "Στον κόμβο XML που πεÏιγÏάφει Îνα redirect λείπει το πεδίο `ενεÏγό'(active)" - -#: libs/ardour/redirect.cc:358 -msgid "XML node describing a redirect is missing the `placement' field" -msgstr "Στον κόμβο XML που πεÏιγÏάφει Îνα redirect λείπει το πεδίο `τοποθÎτηση'(placement)" - -#: libs/ardour/redirect.cc:467 -msgid "active_changed" -msgstr "αλλαγή_ενεÏγοÏ" - -#: libs/ardour/region.cc:885 -msgid "Session: XMLNode describing a Region is incomplete (no id)" -msgstr "ΣυνεδÏία: XMLΚόμβος που πεÏιγÏάφει ΠεÏιοχή είναι ημιτελής (χωÏίς id)" - -#: libs/ardour/region.cc:892 -msgid "Session: XMLNode describing a Region is incomplete (no name)" -msgstr "ΣυνεδÏία: XMLΚόμβος που πεÏιγÏάφει ΠεÏιοχή είναι ημιτελής (χωÏίς όνομα)" - -#: libs/ardour/route.cc:79 -#: libs/ardour/session.cc:1554 -#: libs/ardour/session.cc:1560 -#: libs/ardour/session.cc:3093 -msgid "signal" -msgstr "σήμα" - -#: libs/ardour/route.cc:1430 -msgid "Could not get state of route. Problem with save_automation" -msgstr "Δεν μπόÏεσα να πάÏω κατάσταση διαδÏομής. Î Ïόβλημα με αποθήκευση_αυτοματισμοÏ" - -#: libs/ardour/route.cc:1482 -msgid "Send construction failed" -msgstr "Αποστολή κατασκευής απÎτυχε" - -#: libs/ardour/route.cc:1504 -msgid "unknown Insert type \"%1\"; ignored" -msgstr "άγνωστος Ï„Ïπος Λήψης(Insert) \"%1\"... αγνοήθηκε" - -#: libs/ardour/route.cc:1510 -msgid "Insert XML node has no type property" -msgstr "ΕισηχθÎντας κόμβος XML δεν Îχει στοιχεία Ï„Ïπου" - -#: libs/ardour/route.cc:1515 -msgid "insert could not be created. Ignored." -msgstr "εισαγωγή δεν μπόÏεσε να δημιουÏγηθεί. Αγνοήθηκε." - -#: libs/ardour/route.cc:1533 -msgid "Bad node sent to Route::set_state() [%1]" -msgstr "Κακός κόμβος εστάλη στο Route::set_state() [%1]" - -#: libs/ardour/route.cc:1592 -msgid "Route %1: unknown edit group \"%2 in saved state (ignored)" -msgstr "Route %1: άγνωστη ομάδα επεξεÏγασίας \"%2 στην αποθηκευμÎνη κατάσταση (αγνοήθηκε)" - -#: libs/ardour/route.cc:1608 -#: libs/ardour/route.cc:1612 -msgid "badly formed order key string in state file! [%1] ... ignored." -msgstr "δÏσμοÏφη γÏαμμή ÎºÎ»ÎµÎ¹Î´Î¹Î¿Ï Ï„Î±Î¾Î¹Î½Î¿Î¼Î®ÏƒÎµÏ‰Ï‚ στο αÏχείο καταστάσεως ! [%1] ... αγνοήθηκε." - -#: libs/ardour/route.cc:1693 -#: libs/ardour/route.cc:1820 -msgid "[control]" -msgstr "[Îλεγχος]" - -#: libs/ardour/route.cc:1713 -msgid "Route %1: unknown mix group \"%2 in saved state (ignored)" -msgstr "Route %1: άγνωστη ομάδα μίξεως \"%2 στην αποθηκευμÎνη κατάσταση (αγνοήθηκε)" - -#: libs/ardour/route.cc:1742 -#: libs/ardour/route.cc:1750 -msgid "MIDI mute control specification for %1 is incomplete, so it has been ignored" -msgstr "Η Ï€ÏοδιαγÏαφή ελÎγχου του MIDI mute για το %1 είναι ημιτελής, με αποτÎλεσμα να αγνοηθεί" - -#: libs/ardour/send.cc:99 -msgid "XML node describing a send is missing a Redirect node" -msgstr "Στον κόμβο XML όπου πεÏιγÏάφεται Îνα send λείπει Îνας κόμβος Redirect" - -#: libs/ardour/session.cc:103 -msgid "Could not resolve path: %1 (%2)" -msgstr "ΑδÏνατη η εÏÏεση path: %1 (%2)" - -#: libs/ardour/session.cc:115 -msgid "cannot check session path %1 (%2)" -msgstr "δεν μποÏÏŽ να ελÎγξω το μονοπάτι συνεδÏίας %1 (%2)" - -#: libs/ardour/session.cc:145 -msgid "cannot check statefile %1 (%2)" -msgstr "δεν μποÏÏŽ να ελÎγξω το αÏχείο κατάστασεως %1 (%2)" - -#: libs/ardour/session.cc:181 -msgid "%1 is not an Ardour snapshot file" -msgstr "Το %1 δεν Îιναι αÏχείο-στιγμιότυπο του Ardour" - -#: libs/ardour/session.cc:198 -msgid "cannot determine current working directory (%1)" -msgstr "δεν μποÏÏŽ να καθοÏίσω τον Ï„ÏÎχοντα ενεÏγό φάκελο(directory) (%1)" - -#: libs/ardour/session.cc:215 -msgid "unknown file type for session %1" -msgstr "άγνωστος Ï„Ïπος αÏχείου για την συνεδÏία %1" - -#: libs/ardour/session.cc:320 -msgid "monitor" -msgstr "monitor" - -#: libs/ardour/session.cc:327 -msgid "master" -msgstr "master" - -#: libs/ardour/session.cc:611 -msgid "could not setup Click I/O" -msgstr "Δεν μπόÏεσα να διαμοÏφώσω το I/O του ΜετÏονόμου(click)" - -#: libs/ardour/session.cc:632 -msgid "cannot setup Click I/O" -msgstr "Δεν μποÏÏŽ να διαμοÏφώσω το I/O του ΜετÏονόμου(click)" - -#: libs/ardour/session.cc:654 -msgid "cannot create Auditioner: no auditioning of regions possible" -msgstr "δεν μποÏÏŽ να δημιουÏγήσω τον ΑκÏοατή: καμία ακÏόαση πεÏιοχών δυνατή" - -#: libs/ardour/session.cc:666 -#, c-format -msgid "out %<PRIu32>" -msgstr "" - -#: libs/ardour/session.cc:678 -#, c-format -msgid "in %<PRIu32>" -msgstr "" - -#: libs/ardour/session.cc:692 -#, c-format -msgid "out %<PRIu32>+%<PRIu32>" -msgstr "" - -#: libs/ardour/session.cc:706 -#, c-format -msgid "in %<PRIu32>+%<PRIu32>" -msgstr "" - -#: libs/ardour/session.cc:739 -msgid "cannot setup master inputs" -msgstr "δεν μποÏÏŽ να διαμοÏφώσω τις master εισόδους" - -#: libs/ardour/session.cc:747 -msgid "cannot setup master outputs" -msgstr "δεν μποÏÏŽ να διαμοÏφώσω τις master εξόδους" - -#: libs/ardour/session.cc:758 -msgid "Master Out" -msgstr "" - -#: libs/ardour/session.cc:830 -msgid "cannot setup control inputs" -msgstr "δεν μποÏÏŽ να διαμοÏφώσω τις εισόδους ελÎγχου" - -#: libs/ardour/session.cc:838 -msgid "cannot set up master outputs" -msgstr "δεν μποÏÏŽ να διαμοÏφώσω τις εξόδους ελÎγχου" - -#: libs/ardour/session.cc:1110 -msgid "Session: you can't use that location for auto punch (start <= end)" -msgstr "ΣυνεδÏία: δεν μποÏείτε να χÏησιμοποιήσετε αυτήν την τοποθεσία για auto punch (αÏχή <= Ï„Îλος)" - -#: libs/ardour/session.cc:1189 -msgid "Session: you can't use a mark for auto loop" -msgstr "ΣυνεδÏία: δεν μποÏείτε να χÏησιμοποιήσετε στίγμα για auto loop" - -#: libs/ardour/session.cc:1572 -msgid "feedback loop setup between %1 and %2" -msgstr "διαμόÏφωση feedback loop ανάμεσα σε %1 και %2" - -#: libs/ardour/session.cc:1724 -#: libs/ardour/session.cc:1821 -msgid "cannot configure %1 in/%2 out configuration for new audio track" -msgstr "δεν μποÏÏŽ να διαμοÏφώσω %1 in/%2 out διάταξη για νÎο κανάλι ήχου" - -#: libs/ardour/session.cc:1780 -msgid "Session: could not create new audio track." -msgstr "ΣυνεδÏία: δεν μπόÏεσα να δημιουÏγήσω νÎο κανάλι ήχου." - -#: libs/ardour/session.cc:1870 -msgid "Session: could not create new route." -msgstr "ΣυνεδÏία: δεν μπόÏεσα να δημιουÏγήσω διαδÏομή." - -#: libs/ardour/session.cc:2354 -msgid "cannot create new name for region \"%1\"" -msgstr "δεν μποÏÏŽ να δημιουÏγήσω νÎο όνομα για την πεÏιοχή \"%1\"" - -#: libs/ardour/session.cc:2418 -msgid "too many regions with names like %1" -msgstr "πάÏα πολλÎÏ‚ πεÏιοχÎÏ‚ με ονόματα σαν %1" - -#: libs/ardour/session.cc:2883 -msgid "There are already %1 recordings for %2, which I consider too many." -msgstr "ΥπάÏχουν ήδη %1 εγγÏαφÎÏ‚ για %2, τις οποίες θεωÏÏŽ πάÏα πολλÎÏ‚." - -#: libs/ardour/session.cc:3258 -msgid "programming error: unknown type of Insert created!" -msgstr "σφάλμα Ï€ÏογÏαμματισμοÏ: άγνωστος Ï„Ïπος Εισόδου εδημιουÏγήθη!" - -#: libs/ardour/session.cc:3264 -msgid "programming error: unknown type of Redirect created!" -msgstr "σφάλμα Ï€ÏογÏαμματισμοÏ: άγνωστος Ï„Ïπος Redirect εδημιουÏγήθη!" - -#: libs/ardour/session.cc:3287 -msgid "programming error: unknown type of Insert deleted!" -msgstr "σφάλμα Ï€ÏογÏαμματισμοÏ: άγνωστος Ï„Ïπος of Insert διεγÏάφη!" - -#: libs/ardour/session.cc:3293 -msgid "programming error: unknown type of Redirect deleted!" -msgstr "σφάλμα Ï€ÏογÏαμματισμοÏ: άγνωστος Ï„Ïπος of Redirect διεγÏάφη!" - -#: libs/ardour/session.cc:3636 -msgid "too many bounced versions of playlist \"%1\"" -msgstr "πάÏα πολλÎÏ‚ bounced εκδόσεις της Playlist \"%1\"" - -#: libs/ardour/session.cc:3649 -msgid "cannot create new audio file \"%1\" for %2" -msgstr "δεν μποÏÏŽ να δημιουÏγήσω νÎο αÏχείο ήχου \"%1\" για %2" - -#: libs/ardour/session_butler.cc:85 -#: libs/ardour/session_butler.cc:90 -msgid "UI: cannot set O_NONBLOCK on butler request pipe (%1)" -msgstr "UI: δεν μποÏÏŽ να θÎσω O_NONBLOCK στο butler request pipe (%1)" - -#: libs/ardour/session_butler.cc:95 -msgid "Session: could not create butler thread" -msgstr "ΣυνεδÏία: δεν μπόÏεσα να δημιουÏγήσω δÎσμη με τον butler" - -#: libs/ardour/session_butler.cc:189 -msgid "poll on butler request pipe failed (%1)" -msgstr "" - -#: libs/ardour/session_butler.cc:196 -msgid "Error on butler thread request pipe" -msgstr "Σφάλμα στο butler thread request pipe" - -#: libs/ardour/session_butler.cc:238 -msgid "Error reading from butler request pipe" -msgstr "Σφάλμα στην ανάγνωση από butler request pipe" - -#: libs/ardour/session_butler.cc:275 -msgid "Butler read ahead failure on dstream %1" -msgstr "Αποτυχία Ï€Ïοανάγνωσης Butler στο dstream %1" - -#: libs/ardour/session_butler.cc:319 -msgid "Butler write-behind failure on dstream %1" -msgstr "Αποτυχία οπισθεγγÏαφής Butler στο dstream %1" - -#: libs/ardour/session_click.cc:158 -msgid "cannot open click soundfile %1 (%2)" -msgstr "δεν μποÏÏŽ να ανοίξω τοsoundfile μετÏονόμου%1 (%2)" - -#: libs/ardour/session_click.cc:167 -msgid "cannot read data from click soundfile" -msgstr "δεν μποÏÏŽ να διαβάσω δεδομÎνα από το soundfile μετÏονόμου" - -#: libs/ardour/session_click.cc:192 -msgid "cannot open click emphasis soundfile %1 (%2)" -msgstr "δεν μποÏÏŽ να ανοίξω το soundfile εμφάσεως μετÏονόμου %1 (%2)" - -#: libs/ardour/session_click.cc:200 -msgid "cannot read data from click emphasis soundfile" -msgstr "δεν μποÏÏŽ να διαβάσω δεδομÎνα από το soundfile εμφάσεως μετÏονόμου" - -#: libs/ardour/session_events.cc:161 -msgid "Session: cannot have two events of type %1 at the same frame (%2)." -msgstr "ΣυνεδÏία: δεν γίνεται να υπάÏχουν δÏο συμβάντα του Ï„Ïπου %1 στο ίδιο frame (%2)." - -#: libs/ardour/session_events.cc:422 -msgid "Programming error: illegal event type in process_event (%1)" -msgstr "Σφάλμα Ï€ÏογÏαμματισμοÏ: παÏάνομος Ï„Ïπος συμβάντος στο process_event (%1)" - -#: libs/ardour/session_export.cc:63 -msgid "Export: no output file specified" -msgstr "Εξαγωγή: κανÎνα αÏχείο εξόδου δεν Ï€ÏοσδιοÏίστηκε" - -#: libs/ardour/session_export.cc:164 -#: libs/ardour/session_export.cc:169 -msgid "illegal frame range in export specification" -msgstr "παÏάνομο διάστημα frame στον Ï€ÏοσδιοÏισμό εξαγωγής" - -#: libs/ardour/session_export.cc:174 -msgid "Bad data width size. Report me!" -msgstr "Κακό μÎγεθος εÏÏους δεδομÎνων. ΑνάφεÏΠμε!" - -#: libs/ardour/session_export.cc:204 -msgid "Export: cannot open output file \"%1\" (%2)" -msgstr "Εξαγωγή: δεν μποÏÏŽ να ανοίξω αÏχείο εξόδου \"%1\" (%2)" - -#: libs/ardour/session_export.cc:214 -msgid "cannot initialize sample rate conversion: %1" -msgstr "δεν μποÏÏŽ να καλÎσω την μετατÏοπή του ÏÏ…Î¸Î¼Î¿Ï Î´ÎµÎ¹Î³Î¼Î±Ï„Î¿Î»Î·ÏˆÎ¯Î±Ï‚: %1" - -#: libs/ardour/session_export.cc:316 -msgid "an error occured during sample rate conversion: %1" -msgstr "παÏουσιάστηκε σφάλμα κάτα την μετατÏοπή του ÏÏ…Î¸Î¼Î¿Ï Î´ÎµÎ¹Î³Î¼Î±Ï„Î¿Î»Î·ÏˆÎ¯Î±Ï‚: %1" - -#: libs/ardour/session_export.cc:327 -msgid "warning, leftover frames overflowed, glitches might occur in output" -msgstr "Ï€Ïοσοχή, παÏατημÎνα frames διÎÏÏευσαν, πιθανόν να παÏουσιαστοÏν ατÎλειες στην Îξοδο" - -#: libs/ardour/session_export.cc:418 -msgid "Export: could not write data to output file (%1)" -msgstr "Εξαγωγή: δεν μπόÏεσα να γÏάψω δεδομÎνα στο αÏχείο εξόδου (%1)" - -#: libs/ardour/session_export.cc:500 -msgid "%1: cannot seek to %2 for export" -msgstr "%1: δεν μποÏÏŽ να αναζητήσω στο %2 για εξαγωγή" - -#: libs/ardour/session_midi.cc:200 -msgid "Ardour is slaved to MTC - port cannot be reset" -msgstr "Το Ardour υπακοÏει το MTC - η θÏÏα δεν γίνεται reset" - -#: libs/ardour/session_midi.cc:215 -msgid "unknown port %1 requested for MTC" -msgstr "Εζητήθη άγνωστη θÏÏα %1 για το MTC" - -#: libs/ardour/session_midi.cc:541 -msgid "Error reading from MIDI port %1" -msgstr "Σφάλμα στην ανάγνωση της θÏÏας MIDI %1" - -#: libs/ardour/session_midi.cc:914 -msgid "Session: could not send full MIDI time code" -msgstr "ΣυνεδÏία: δεν μπόÏεσα να στείλω ολόκληÏο MIDI time code" - -#: libs/ardour/session_midi.cc:973 -msgid "Session: cannot send quarter-frame MTC message (%1)" -msgstr "ΣυνεδÏία: δεν μποÏÏŽ να στείλω Ï„ÎταÏτο-frame MTC μήνυμα (%1)" - -#: libs/ardour/session_midi.cc:1081 -msgid "MMC: cannot send command %1%2%3" -msgstr "MMC: δεν μποÏÏŽ να στείλω την εντολή %1%2%3" - -#: libs/ardour/session_midi.cc:1188 -msgid "UI: cannot set O_NONBLOCK on signal read pipe (%1)" -msgstr "UI: δεν μποÏÏŽ να θÎσω O_NONBLOCK στο signal read pipe (%1)" - -#: libs/ardour/session_midi.cc:1193 -msgid "UI: cannot set O_NONBLOCK on signal write pipe (%1)" -msgstr "UI: δεν μποÏÏŽ να θÎσω O_NONBLOCK στο signal write pipe (%1)" - -#: libs/ardour/session_midi.cc:1198 -msgid "Session: could not create transport thread" -msgstr "ΣυνεδÏία: δεν μπόÏεσα να δημιουÏγήσω δÎσμη με transport" - -#: libs/ardour/session_midi.cc:1227 -msgid "cannot send signal to midi thread! (%1)" -msgstr "δεν μποÏÏŽ να στείλω σήμα στη δÎσμη midi! (%1)" - -#: libs/ardour/session_midi.cc:1322 -msgid "MIDI thread poll failed (%1)" -msgstr "Αίτηση δÎσμης MIDI απÎτυχε (%1)" - -#: libs/ardour/session_midi.cc:1334 -msgid "Error on transport thread request pipe" -msgstr "Σφάλμα στο transport thread request pipe" - -#: libs/ardour/session_midi.cc:1361 -msgid "Error reading from transport request pipe" -msgstr "Σφάλμα στην ανάγνωση από transport request pipe" - -#: libs/ardour/session_process.cc:104 -msgid "Session: error in no roll for %1" -msgstr "ΣυνεδÏία: σφάλμα στο no roll για %1" - -#: libs/ardour/session_state.cc:101 -msgid "Could not use path %1 (%s)" -msgstr "ΑδÏνατη η χÏήση του path %1 (%s)" - -#: libs/ardour/session_state.cc:129 -msgid "end" -msgstr "Ï„Îλος" - -#: libs/ardour/session_state.cc:130 -msgid "start" -msgstr "" - -#: libs/ardour/session_state.cc:502 -msgid "Session: cannot create session dir \"%1\" (%2)" -msgstr "ΣυνεδÏία: δεν μποÏÏŽ να δημιουÏγήσω φάκελο συνεδÏίας \"%1\" (%2)" - -#: libs/ardour/session_state.cc:513 -msgid "Session: cannot create session peakfile dir \"%1\" (%2)" -msgstr "ΣυνεδÏία: δεν μποÏÏŽ να δημιουÏγήσω peakfile dir συνεδÏίας \"%1\" (%2)" - -#: libs/ardour/session_state.cc:522 -msgid "Session: cannot create session sounds dir \"%1\" (%2)" -msgstr "ΣυνεδÏία: δεν μποÏÏŽ να δημιουÏγήσω φάκελο ήχων συνεδÏίας \"%1\" (%2)" - -#: libs/ardour/session_state.cc:531 -msgid "Session: cannot create session tape dir \"%1\" (%2)" -msgstr "ΣυνεδÏία: δεν μποÏÏŽ να δημιουÏγήσω tape dir συνεδÏίας \"%1\" (%2)" - -#: libs/ardour/session_state.cc:540 -msgid "Session: cannot create session dead sounds dir \"%1\" (%2)" -msgstr "ΣυνεδÏία: δεν μποÏÏŽ να δημιουÏγήσω φάκελο 'νεκÏών' ήχων συνεδÏίας \"%1\" (%2)" - -#: libs/ardour/session_state.cc:549 -msgid "Session: cannot create session automation dir \"%1\" (%2)" -msgstr "ΣυνεδÏία: δεν μποÏÏŽ να δημιουÏγήσω φάκελο αυτοματισμών της συνεδÏίας \"%1\" (%2)" - -#: libs/ardour/session_state.cc:580 -msgid "Could not open %1 for writing mix template" -msgstr "Δεν μπόÏεσα να ανοίξω %1 για γÏάψιμο του Ï€Ïοσχεδίου μίξεως" - -#: libs/ardour/session_state.cc:586 -msgid "Could not open mix template %1 for reading" -msgstr "Δεν μπόÏεσα να ανοίξω Ï€ÏοσχÎδιο μίξεως %1 για ανάγνωση" - -#: libs/ardour/session_state.cc:593 -msgid "Session already exists. Not overwriting" -msgstr "Η ΣυνεδÏία ήδη υπάÏχει. ΑκÏÏωση overwriting" - -#: libs/ardour/session_state.cc:636 -msgid "Session: could not load diskstream via XML state" -msgstr "ΣυνεδÏία: δεν μπόÏεσα να φοÏτώσω diskstream μÎσω καταστάσεως XML" - -#: libs/ardour/session_state.cc:685 -msgid "could not backup old state file, current state not saved." -msgstr "δεν μπόÏεσα να διασώσω το παλαιό αÏχείο καταστάσεως, η Ï„ÏÎχουσα κατάσταση δεν αποθηκεÏτηκε." - -#: libs/ardour/session_state.cc:698 -msgid "state could not be saved to %1" -msgstr "η κατάσταση δεν μποÏοÏσε να σωθεί στο %1" - -#: libs/ardour/session_state.cc:705 -msgid "could not remove corrupt state file %1" -msgstr "αδÏνατη η διαγÏαφή αÏχείου διεφθαÏμÎνης state %1" - -#: libs/ardour/session_state.cc:709 -msgid "could not restore state file from backup %1" -msgstr "αδÏνατη η επαναφοÏά του state file από backup %1" - -#: libs/ardour/session_state.cc:778 -msgid "%1: session state information file \"%2\" doesn't exist!" -msgstr "%1: το αÏχείο πληÏοφοÏιών καταστάσεως συνεδÏίας \"%2\" δεν υπάÏχει!" - -#: libs/ardour/session_state.cc:789 -msgid "Could not understand ardour file %1" -msgstr "Δεν μπόÏεσα να κατανοήσω το ardour αÏχείο %1" - -#: libs/ardour/session_state.cc:1493 -msgid "programming error: Session: incorrect XML node sent to set_state()" -msgstr "σφάλμα Ï€ÏογÏαμματισμοÏ: ΣυνεδÏία: λανθασμÎνος κόμβος XML εστάλη στην set_state()" - -#: libs/ardour/session_state.cc:1539 -msgid "Session: XML state has no options section" -msgstr "ΣυνεδÏία: η XML κατάσταση δεν Îχει τομÎα επιλογών(options)" - -#: libs/ardour/session_state.cc:1544 -msgid "Session: XML state has no sources section" -msgstr "ΣυνεδÏία: η XML κατάσταση δεν Îχει τομÎα πηγών" - -#: libs/ardour/session_state.cc:1551 -msgid "Session: XML state has no Regions section" -msgstr "ΣυνεδÏία: η XML κατάσταση δεν Îχει τομÎα ΠεÏιοχών" - -#: libs/ardour/session_state.cc:1558 -msgid "Session: XML state has no playlists section" -msgstr "ΣυνεδÏία: η XML κατάσταση δεν Îχει τομÎα playlists" - -#: libs/ardour/session_state.cc:1577 -msgid "Session: XML state has no diskstreams section" -msgstr "ΣυνεδÏία: η XML κατάσταση δεν Îχει τομÎα diskstreams" - -#: libs/ardour/session_state.cc:1584 -msgid "Session: XML state has no connections section" -msgstr "ΣυνεδÏία: η XML κατάσταση δεν Îχει τομÎα συνδÎσεων" - -#: libs/ardour/session_state.cc:1591 -msgid "Session: XML state has no locations section" -msgstr "ΣυνεδÏία: η XML κατάσταση δεν Îχει τομÎα τοποθεσιών" - -#: libs/ardour/session_state.cc:1624 -msgid "Session: XML state has no edit groups section" -msgstr "ΣυνεδÏία: η XML κατάσταση δεν Îχει τομÎα επεξεÏ/σίας ομάδων" - -#: libs/ardour/session_state.cc:1631 -msgid "Session: XML state has no mix groups section" -msgstr "ΣυνεδÏία: η XML κατάσταση δεν Îχει τομÎα μίξεως ομάδων" - -#: libs/ardour/session_state.cc:1638 -msgid "Session: XML state has no Tempo Map section" -msgstr "ΣυνεδÏία: η XML κατάσταση δεν Îχει τομÎα Tempo Map" - -#: libs/ardour/session_state.cc:1645 -msgid "Session: XML state has no routes section" -msgstr "ΣυνεδÏία: η XML κατάσταση δεν Îχει τομÎα διαδÏομών" - -#: libs/ardour/session_state.cc:1652 -msgid "Session: XML state has no click section" -msgstr "ΣυνεδÏία: η XML κατάσταση δεν Îχει τομÎα μετÏονόμου" - -#: libs/ardour/session_state.cc:1697 -msgid "Session: cannot create Route from XML description." -msgstr "ΣυνεδÏία: δεν μποÏÏŽ να δημιουÏγήσω ΔιαδÏομή από XML πεÏιγÏαφή." - -#: libs/ardour/session_state.cc:1735 -msgid "Session: cannot create Region from XML description." -msgstr "ΣυνεδÏία: δεν μποÏÏŽ να δημιουÏγήσω ΠεÏιοχή από XML πεÏιγÏαφή." - -#: libs/ardour/session_state.cc:1764 -msgid "Session: XMLNode describing a AudioRegion is incomplete (no source)" -msgstr "ΣυνεδÏία: Ο XMLΚόμβος που πεÏιγÏάφει AudioΠεÏιοχή είναι ημιτελής (δίχως πηγή)" - -#: libs/ardour/session_state.cc:1772 -#: libs/ardour/session_state.cc:1792 -msgid "Session: XMLNode describing a AudioRegion references an unknown source id =%1" -msgstr "ΣυνεδÏία: Ο XMLΚόμβος που πεÏιγÏάφει AudioΠεÏιοχή αναφÎÏει άγνωστο id πηγής =%1" - -#: libs/ardour/session_state.cc:1778 -#: libs/ardour/session_state.cc:1798 -msgid "Session: XMLNode describing a AudioRegion references a non-audio source id =%1" -msgstr "ΣυνεδÏία: Ο XMLNode που πεÏιγÏάφει AudioRegion αναφÎÏει μη-ηχητική πηγή με id =%1" - -#: libs/ardour/session_state.cc:1868 -msgid "Session: cannot create Source from XML description." -msgstr "ΣυνεδÏία: δεν μποÏÏŽ να δημιουÏγήσω Πηγή από XML πεÏιγÏαφή." - -#: libs/ardour/session_state.cc:1889 -msgid "Found a sound file that cannot be used by Ardour. Talk to the progammers." -msgstr "ΕυÏÎθη sound file που δεν μποÏεί να χÏησιμοποιηθεί από τον Ardour. Επικοινωνήστε με τους Ï€ÏογÏαμματιστÎÏ‚." - -#: libs/ardour/session_state.cc:1913 -msgid "Could not create mix templates directory \"%1\" (%2)" -msgstr "Δεν μπόÏεσα να δημιουÏγήσω φάκελο Ï€Ïοσχεδίων μίξεως \"%1\" (%2)" - -#: libs/ardour/session_state.cc:1927 -msgid "Template \"%1\" already exists - new version not created" -msgstr "Το Ï€ÏοσχÎδιο \"%1\" ήδη υπάÏχει - νÎα Îκδοση δεν δημιουÏγήθηκε" - -#: libs/ardour/session_state.cc:1934 -msgid "mix template not saved" -msgstr "Ï€ÏοσχÎδιο μίξεως δεν αποθηκεÏτηκε" - -#: libs/ardour/session_state.cc:1994 -msgid "cannot create session directory \"%1\"; ignored" -msgstr "δεν μποÏÏŽ να δημιουÏγήσω φάκελο συνεδÏίας \"%1\"; αγνοήθηκε" - -#: libs/ardour/session_state.cc:2007 -msgid "cannot create sounds directory \"%1\"; ignored" -msgstr "δεν μποÏÏŽ να δημιουÏγήσω τον φάκελο 'sounds' \"%1\"; αγνοήθηκε" - -#: libs/ardour/session_state.cc:2018 -msgid "cannot create dead sounds directory \"%1\"; ignored" -msgstr "δεν μποÏÏŽ να δημιουÏγήσω τον φάκελο 'dead sounds' \"%1\"; αγνοήθηκε" - -#: libs/ardour/session_state.cc:2029 -msgid "cannot create peak file directory \"%1\"; ignored" -msgstr "αδÏνατη η δημιουÏγία φακÎλου peak file \"%1\"; αγνοήθηκε" - -#: libs/ardour/session_state.cc:2168 -#: libs/ardour/session_state.cc:2189 -msgid "Session: cannot create Playlist from XML description." -msgstr "ΣυνεδÏία: δεν μποÏÏŽ να δημιουÏγήσω την Playlist από την XML πεÏιγÏαφή." - -#: libs/ardour/session_state.cc:2228 -msgid "Session: cannot create Named Selection from XML description." -msgstr "ΣυνεδÏία: δεν μποÏÏŽ να δημιουÏγήσω την ονομασμÎνη επιλογή από την XML πεÏιγÏαφή." - -#: libs/ardour/session_state.cc:2360 -msgid "Unknown node \"%1\" found in Connections list from state file" -msgstr "Άγνωστος κόμβος \"%1\" ευÏÎθη στη λίστα 'ΣυνδÎσεις' από το αÏχείο καταστάσεως" - -#: libs/ardour/session_state.cc:3197 -msgid "cannot remove dead sound file %1 (%2)" -msgstr "δεν μποÏÏŽ να απαλοίψω το 'νεκÏο' ηχο-αÏχείο %1 (%2)" - -#: libs/ardour/session_time.cc:374 -msgid "Unknown JACK transport state %1 in sync callback" -msgstr "Άγνωστη κατάσταση του JACK transport %1 στην ανάκληση sync" - -#: libs/ardour/session_timefx.cc:77 -msgid "tempoize: error creating name for new audio file based on %1" -msgstr "tempoize: σφάλμα στη δημιουÏγία ονόματος για νÎο αÏχείο ήχου βασισμÎνο σε %1" - -#: libs/ardour/session_timefx.cc:88 -msgid "tempoize: error creating new audio file %1 (%2)" -msgstr "tempoize: σφάλμα στη δημιουÏγία νÎου αÏχείου ήχου %1 (%2)" - -#: libs/ardour/session_timefx.cc:114 -msgid "tempoize: error reading data from %1" -msgstr "tempoize: σφάλμα στην ανάγνωση δεδομÎνων από %1" - -#: libs/ardour/session_timefx.cc:127 -#: libs/ardour/session_timefx.cc:139 -msgid "error writing tempo-adjusted data to %1" -msgstr "σφάλμα στην εγγÏαφή χÏονο-ÏυθμισμÎνων δεδομÎνων στο %1" - -#: libs/ardour/session_timefx.cc:145 -msgid "timefx code failure. please notify ardour-developers." -msgstr "αποτυχία κώδικα timefx. παÏακαλώ ειδοποιήστε τους Ï€ÏογÏαμματιστÎÏ‚ του ardour." - -#: libs/ardour/session_transport.cc:117 -msgid "Cannot loop - no loop range defined" -msgstr "Δεν γίνεται loop - κανÎνα διάστημα loop δεν Ï€ÏοσδιοÏίστηκε" - -#: libs/ardour/session_transport.cc:479 -msgid "" -"Seamless looping cannot be supported while Ardour is using JACK transport.\n" -"Recommend changing the configured options" -msgstr "" -"Μονοκόμματο looping δεν υποστηÏίζεται ενώ ο Ardour χÏησιμοποιεί το JACK transport.\n" -"ΣυνιστοÏμε την αλλαγή των διαμοÏφωμÎνων Ïυθμίσεων" - -#: libs/ardour/session_transport.cc:755 -msgid "Global varispeed cannot be supported while Ardour is connected to JACK transport control" -msgstr "Η Global varispeed δεν μποÏεί να υποστηÏιχθεί ενώ ο Ardour είναι συνδεδεμÎνος με τον JACK transport control" - -#: libs/ardour/session_transport.cc:955 -msgid "please stop the transport before adjusting slave settings" -msgstr "παÏακαλώ σταματήστε το transport Ï€Ïιν την ÏÏθμιση των επιλογων εξαÏτήσεως" - -#: libs/ardour/session_transport.cc:991 -msgid "No MTC port defined: MTC slaving is impossible." -msgstr "Καμμία θÏÏα MTC δεν Ï€ÏοσδιοÏίστηκε: η εξάÏτηση του MTC (slaving) είναι αδÏνατη." - -#: libs/ardour/sndfile_helpers.cc:15 -msgid "WAV" -msgstr "WAV" - -#: libs/ardour/sndfile_helpers.cc:16 -msgid "AIFF" -msgstr "AIFF" - -#: libs/ardour/sndfile_helpers.cc:17 -msgid "raw (no header)" -msgstr "raw (no header)" - -#: libs/ardour/sndfile_helpers.cc:18 -msgid "PAF (Ensoniq Paris)" -msgstr "PAF (Ensoniq Paris)" - -#: libs/ardour/sndfile_helpers.cc:19 -msgid "AU (Sun/NeXT)" -msgstr "AU (Sun/NeXT)" - -#: libs/ardour/sndfile_helpers.cc:20 -msgid "IRCAM" -msgstr "IRCAM" - -#: libs/ardour/sndfile_helpers.cc:21 -msgid "W64 (64 bit WAV)" -msgstr "W64 (64 bit WAV)" - -#: libs/ardour/sndfile_helpers.cc:26 -msgid ".wav" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:27 -msgid ".aiff" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:28 -msgid ".raw" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:29 -msgid ".paf" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:30 -msgid ".au" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:31 -msgid ".ircam" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:32 -msgid ".w64" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:47 -msgid "16 bit" -msgstr "16 bit" - -#: libs/ardour/sndfile_helpers.cc:48 -msgid "24 bit" -msgstr "24 bit" - -#: libs/ardour/sndfile_helpers.cc:49 -msgid "32 bit" -msgstr "32 bit" - -#: libs/ardour/sndfile_helpers.cc:50 -msgid "8 bit" -msgstr "8 bit" - -#: libs/ardour/sndfile_helpers.cc:51 -msgid "float" -msgstr "float" - -#: libs/ardour/sndfile_helpers.cc:64 -msgid "Little-endian (Intel)" -msgstr "Little-endian (Intel)" - -#: libs/ardour/sndfile_helpers.cc:65 -msgid "Big-endian (Mac)" -msgstr "Big-endian (Mac)" - -#: libs/ardour/sndfilesource.cc:147 -msgid "FileSource: cannot get host information for BWF header (%1)" -msgstr "FileSource: δεν μποÏÏŽ να βÏÏŽ πληÏοφοÏίες οικοδεσπότη(host) για επικεφαλίδα BWF (%1)" - -#: libs/ardour/sndfilesource.cc:169 -msgid "cannot set broadcast info for audio file %1 (%2); dropping broadcast info for this file" -msgstr "Δεν ετÎθησαν broadcast info για το audio file %1 (%2); απόÏÏιψη broadcast info για αυτό το αÏχείο" - -#: libs/ardour/sndfilesource.cc:220 -msgid "SndFileSource: cannot open file \"%1\" for %2 (%3)" -msgstr "SndFileSource: δεν μποÏÏŽ να ανοίξω το αÏχείο \"%1\" για %2 (%3)" - -#: libs/ardour/sndfilesource.cc:226 -msgid "SndFileSource: file only contains %1 channels; %2 is invalid as a channel number" -msgstr "SndFileSource: το αÏχείο πεÏιÎχει μόνο %1 κανάλια; %2 δεν Îχει αξία σαν κανάλι number" - -#: libs/ardour/sndfilesource.cc:327 -msgid "SndFileSource: could not seek to frame %1 within %2 (%3)" -msgstr "SndFileSource: δεν μποÏοÏσα να αναζητήσω στο frame %1 μÎσα στο %2 (%3)" - -#: libs/ardour/sndfilesource.cc:378 -msgid "programming error: %1 %2" -msgstr "σφάλμα Ï€ÏογÏαμματισμοÏ: %1 %2" - -#: libs/ardour/sndfilesource.cc:487 -#: libs/ardour/sndfilesource.cc:533 -msgid "cannot set broadcast info for audio file %1; Dropping broadcast info for this file" -msgstr "Δεν ετÎθησαν broadcast info για το audio file %1; ΑπόÏÏιψη broadcast info για αυτό το αÏχείο" - -#: libs/ardour/sndfilesource.cc:544 -msgid "%1: cannot seek to %2" -msgstr "%1: αδÏνατη η αναζήτηση στο %2" - -#: libs/ardour/state_manager.cc:47 -msgid "cleared history" -msgstr "εκκαθάÏιση ιστοÏικοÏ" - -#: libs/ardour/state_manager.cc:60 -msgid "programming error: illegal state ID (%1) passed to StateManager::set_state() (range = 0-%2)" -msgstr "σφάλμα Ï€ÏογÏαμματισμοÏ: αθÎμιτη κατάσταση ID (%1) Ï€ÎÏασε στον StateManager::set_state() (range = 0-%2)" - -#: libs/ardour/stateful.cc:102 -msgid "Error: could not write %1" -msgstr "Σφάλμα: δεν μπόÏεσα να γÏάψω %1" - -#: libs/ardour/stateful.cc:116 -msgid "Could not understand XML file %1" -msgstr "Δεν μπόÏεσα να κατανοήσω το XML αÏχείο %1" - -#: libs/ardour/tempo.cc:67 -msgid "TempoSection XML node has no \"start\" property" -msgstr "Κόμβος του TempoSection XML δεν Îχει ιδιότητα \"ÎναÏξη\"" - -#: libs/ardour/tempo.cc:75 -msgid "TempoSection XML node has an illegal \"start\" value" -msgstr "Κόμβος του TempoSection XML Îχει αθÎμιτη αξία \"ÎναÏξη\"" - -#: libs/ardour/tempo.cc:82 -msgid "TempoSection XML node has no \"beats-per-minute\" property" -msgstr "Κόμβος του TempoSection XML δεν Îχει \"κτÏπων-ανά-λεπτό\" ιδιότητα" - -#: libs/ardour/tempo.cc:87 -msgid "TempoSection XML node has an illegal \"beats_per_minute\" value" -msgstr "Κόμβος του TempoSection XML Îχει αθÎμιτη \"κτÏπων_ανά_λεπτό\" αξία" - -#: libs/ardour/tempo.cc:92 -msgid "TempoSection XML node has no \"movable\" property" -msgstr "Κόμβος του TempoSection XML δεν Îχει \"κινητή\" ιδιότητα" - -#: libs/ardour/tempo.cc:131 -msgid "MeterSection XML node has no \"start\" property" -msgstr "Κόμβος του MeterSection XML δεν Îχει \"ÎναÏξη\" ιδιότητα" - -#: libs/ardour/tempo.cc:139 -msgid "MeterSection XML node has an illegal \"start\" value" -msgstr "Κόμβος του MeterSection XML Îχει αθÎμιτη \"ÎναÏξη\" αξία" - -#: libs/ardour/tempo.cc:146 -msgid "MeterSection XML node has no \"beats-per-bar\" property" -msgstr "Κόμβος του MeterSection XML δεν Îχει \"κτÏπων-ανά-μπάÏα\" ιδιότητα" - -#: libs/ardour/tempo.cc:151 -msgid "MeterSection XML node has an illegal \"beats-per-bar\" value" -msgstr "Κόμβος του MeterSection XML Îχει αθÎμιτη \"κτÏπων-ανά-μπάÏα\" αξία" - -#: libs/ardour/tempo.cc:156 -msgid "MeterSection XML node has no \"note-type\" property" -msgstr "Κόμβος του MeterSection XML δεν Îχει \"Ï„Ïπος-νότας\" ιδιότητα" - -#: libs/ardour/tempo.cc:161 -msgid "MeterSection XML node has an illegal \"note-type\" value" -msgstr "Κόμβος του MeterSection XML Îχει αθÎμιτη \"Ï„Ïπος-νότας\" αξία" - -#: libs/ardour/tempo.cc:166 -msgid "MeterSection XML node has no \"movable\" property" -msgstr "Κόμβος του MeterSection XML δεν Îχει \"κινητή\" ιδιότητα" - -#: libs/ardour/tempo.cc:259 -msgid "move metric" -msgstr "μετακίνηση μετÏικοÏ" - -#: libs/ardour/tempo.cc:330 -msgid "metric removed" -msgstr "μετÏικό απεσÏÏθη" - -#: libs/ardour/tempo.cc:373 -msgid "add tempo" -msgstr "Ï€Ïόσθεση ÏυθμοÏ" - -#: libs/ardour/tempo.cc:402 -msgid "replace tempo" -msgstr "αντικατάσταση ÏυθμοÏ" - -#: libs/ardour/tempo.cc:435 -msgid "add meter" -msgstr "Ï€Ïόσθεση μετÏητή" - -#: libs/ardour/tempo.cc:463 -msgid "replaced meter" -msgstr "αντικατεστημÎνος μετÏητής" - -#: libs/ardour/tempo.cc:483 -#: libs/ardour/tempo.cc:499 -msgid "programming error: no tempo section in tempo map!" -msgstr "σφάλμα Ï€ÏογÏαμματισμοÏ: κανÎνας τομÎας ÏÏ…Î¸Î¼Î¿Ï ÏƒÏ„Î¿ χάÏτη Ïυθμών!" - -#: libs/ardour/tempo.cc:538 -msgid "programming error: unhandled MetricSection type" -msgstr "σφάλμα Ï€ÏογÏαμματισμοÏ: αχείÏιστος Ï„Ïπος MetricSection" - -#: libs/ardour/tempo.cc:1226 -#: libs/ardour/tempo.cc:1238 -msgid "Tempo map: could not set new state, restoring old one." -msgstr "ΧάÏτης Ïυθμών: δεν μπόÏεσα να θÎσω νÎα κατάσταση, επιστÏοφή Ï€ÏοηγοÏμενης." - -#: libs/ardour/tempo.cc:1262 -msgid "load XML data" -msgstr "ΦόÏτωμα δεδομÎνων XML" - -#: libs/ardour/utils.cc:246 -msgid "illegal or badly-formed string used for path (%1)" -msgstr "αθÎμιτη ή κακοσχηματισμÎνη γÏαμμή για το μονοπάτι (%1)" - -#: libs/ardour/utils.cc:251 -msgid "path (%1) is ambiguous" -msgstr "Το μονοπάτι (%1) είναι αμφίβολο" - -#: libs/ardour/vst_plugin.cc:187 -msgid "cannot create VST chunk directory: %1" -msgstr "δεν μποÏÏŽ να δημιουÏγήσω φάκελο κομματιών VST: %1" - -#: libs/ardour/vst_plugin.cc:195 -msgid "cannot check VST chunk directory: %1" -msgstr "δεν μποÏÏŽ να ελÎγξω το φάκελο κομματιών VST: %1" - -#: libs/ardour/vst_plugin.cc:202 -msgid "%1 exists but is not a directory" -msgstr "%1 υπάÏχει αλλά δεν είναι φάκελος" - -#: libs/ardour/vst_plugin.cc:240 -msgid "Bad node sent to VSTPlugin::set_state" -msgstr "Κακός κόμβος εστάλη στο VSTPlugin::set_state" - -#: libs/ardour/vst_plugin.cc:343 -#: libs/ardour/vst_plugin.cc:354 -msgid "no support for presets using chunks at this time" -msgstr "καμμία υποστήÏιξη αυτή τη στιγμή για Ïυθμίσεις που χÏησιμοποιοÏν κομμάτια" - -#: libs/ardour/coreaudiosource.cc:97 -msgid "CoreAudioSource: file only contains %1 channels; %2 is invalid as a channel number" -msgstr "CoreAudioSource: το αÏχείο πεÏιÎχει μόνο %1 κανάλια; το %2 δεν Îχει αξία σαν αÏιθμός καναλιών" - -#: libs/ardour/coreaudiosource.cc:162 -msgid "CoreAudioSource: could not seek to frame %1 within %2 (%3)" -msgstr "CoreAudioSource: δεν μποÏοÏσα να αναζητήσω στο frame %1 μÎσα στο %2 (%3)" - -#~ msgid "FileSource: \"%1\" not found when searching %2 using %3" -#~ msgstr "FileSource: \"%1\" δεν ευÏÎθη όταν αναζητείτο %2 χÏησιμοποιώντας %3" -#~ msgid "FileSource: could not open \"%1\": (%2)" -#~ msgstr "FileSource: δεν μπόÏεσα να ανοίξω \"%1\": (%2)" -#~ msgid "FileSource: cannot write header in %1" -#~ msgstr "FileSource: δεν μποÏÏŽ να γÏάψω επικεφαλίδα στο %1" -#~ msgid "FileSource: cannot locate chunks in %1" -#~ msgstr "FileSource: δεν μποÏÏŽ να ανιχνεÏσω κομμάτια στο %1" -#~ msgid "FileSource: cannot read header in %1" -#~ msgstr "FileSource: δεν μποÏÏŽ να διαβάσω επικεφαλίδα στο %1" -#~ msgid "FileSource: cannot check header in %1" -#~ msgstr "FileSource: δεν μποÏÏŽ να ελÎγξω επικεφαλίδα στο %1" - -#, fuzzy -#~ msgid "FileSource: cannot initialize peakfile for %1 as %2" -#~ msgstr "FileSource: δεν μποÏÏŽ να εκκινήσω το peakfile για %1" -#~ msgid "FileSource: cannot seek to end of file" -#~ msgstr "FileSource: δεν μποÏÏŽ να ανιχνεÏσω το Ï„Îλος του αÏχείου" -#~ msgid "FileSource: cannot read RIFF/WAVE chunk from file" -#~ msgstr "FileSource: δεν μποÏÏŽ να διαβάσω κομμάτι RIFF/WAVE από το αÏχείο" -#~ msgid "FileSource %1: not a RIFF/WAVE file" -#~ msgstr "FileSource %1: δεν είναι RIFF/WAVE αÏχείο" -#~ msgid "FileSource: can't read a chunk" -#~ msgstr "FileSource: δεν μποÏÏŽ να διαβάσω κομμάτι" -#~ msgid "FileSource: cannot get user information for BWF header (%1)" -#~ msgstr "" -#~ "FileSource: δεν μποÏÏŽ να βÏÏŽ πληÏοφοÏίες χÏήστη για επικεφαλίδα BWF (%1)" -#~ msgid "FileSource[%1]: cannot update data size: %2" -#~ msgstr "FileSource[%1]: δεν μποÏÏŽ να ανανεώσω το μÎγεθος δεδομÎνων: %2" -#~ msgid "FileSource: can't find RIFF chunk info" -#~ msgstr "FileSource: δεν ευÏÎθησαν πληÏοφοÏίες για RIFF κομμάτι" - -#, fuzzy -#~ msgid "FileSource: can't find RIFX chunk info" -#~ msgstr "FileSource: δεν ευÏÎθησαν πληÏοφοÏίες για RIFF κομμάτι" -#~ msgid "FileSource: can't read RIFF chunk" -#~ msgstr "FileSource: δεν μποÏÏŽ να διαβάσω RIFF κομμάτι" -#~ msgid "FileSource: can't find format chunk info" -#~ msgstr "FileSource: δεν ευÏÎθησαν πληÏοφοÏίες για το κομμάτι φοÏμαÏίσματος" -#~ msgid "FileSource: can't read format chunk" -#~ msgstr "FileSource: δεν μποÏÏŽ να διαβάσω το κομμάτι φοÏμαÏίσματος" -#~ msgid "FileSource: can't find data chunk info" -#~ msgstr "FileSource: δεν μποÏÏŽ να βÏÏŽ πληÏοφοÏίες για το κομμάτι δεδομÎνων" -#~ msgid "FileSource: can't read data chunk" -#~ msgstr "FileSource: δεν μποÏÏŽ να διαβάσω το κομμάτι δεδομÎνων" -#~ msgid "" -#~ "FileSource: cannot read Broadcast Wave data from existing audio file \"%1" -#~ "\" (%2)" -#~ msgstr "" -#~ "FileSource: δεν μποÏÏŽ να διαβάσω δεδομÎνα Broadcast Wave από το υπάÏχον " -#~ "αÏχείο \"%1\" (%2)" -#~ msgid "" -#~ "FileSource: cannot read Broadcast Wave coding history from audio file \"%1" -#~ "\" (%2)" -#~ msgstr "" -#~ "FileSource: δεν μποÏÏŽ να διαβάσω το ιστοÏικό του κώδικα Broadcast Wave " -#~ "από το αÏχείο \"%1\" (%2)" - -#, fuzzy -#~ msgid "" -#~ "FileSource \"%1\" does not use valid sample format.\n" -#~ "This is probably a programming error." -#~ msgstr "" -#~ "FileSource \"%1\" δεν χÏησιμοποιεί format μεταβλητής υποδιαστολής.\n" -#~ "Αυτό πιθανόν να είναι σφάλμα Ï€ÏογÏαμματισμοÏ." -#~ msgid "FileSource \"%1\" has no \"data\" chunk" -#~ msgstr "FileSource \"%1\" δεν Îχει \"data\" κομμάτι" -#~ msgid "" -#~ "%1: data length in header (%2) differs from implicit size in file (%3)" -#~ msgstr "" -#~ "%1: το μÎγεθος δεδομÎνων της επικεφαλίδας (%2) διαφÎÏει από το δεδηλωμÎνο " -#~ "μÎγεθος στο αÏχείο (%3)" -#~ msgid "\"%1\" has a sample rate of %2 instead of %3 as used by this session" -#~ msgstr "" -#~ "\"%1\" Îχει Ïυθμό δειγματοληψίας %2 αντί του %3 όπως στην παÏοÏσα συνεδÏία" -#~ msgid "FileSource: cannot write WAVE chunk: %1" -#~ msgstr "FileSource: δεν μποÏÏŽ να γÏάψω WAVE κομμάτι: %1" -#~ msgid "FileSource: cannot write format chunk: %1" -#~ msgstr "FileSource: δεν μποÏÏŽ να γÏάψω format κομμάτι: %1" -#~ msgid "FileSource: cannot data chunk: %1" -#~ msgstr "FileSource: cδεν μποÏÏŽ να γÏάψω κομμάτι δεδομÎνων: %1" -#~ msgid "FileSource: \"%1\" bad write (%2)" -#~ msgstr "FileSource: \"%1\" κακή εγγÏαφή (%2)" - -#, fuzzy -#~ msgid "cannot create feedback request pipe (%1)" -#~ msgstr "Δεν μποÏÏŽ να δημιουÏγήσω transport request signal pipe (%1)" - -#, fuzzy -#~ msgid "Session: could not create feedback thread" -#~ msgstr "ΣυνεδÏία: δεν μπόÏεσα να δημιουÏγήσω δÎσμη με τον butler" - -#, fuzzy -#~ msgid "Feedback thread poll failed (%1)" -#~ msgstr "Αίτηση δÎσμης MIDI απÎτυχε (%1)" - -#, fuzzy -#~ msgid "Error on feedback thread request pipe" -#~ msgstr "Σφάλμα στο transport thread request pipe" - -#, fuzzy -#~ msgid "Error reading from feedback request pipe" -#~ msgstr "Σφάλμα στην ανάγνωση από transport request pipe" -#~ msgid "Could not find member filename" -#~ msgstr "Δεν ευÏÎθη το αÏχείο μÎλους" -#~ msgid "could not create crossfade object in playlist %1" -#~ msgstr "δεν Îγινε δημιουÏγία αντικειμÎνου crossfade στη λίστα αναπαÏ/γής%1" -#~ msgid "" -#~ "There are too many frozen versions of playlist \"%1\" to create another " -#~ "one" -#~ msgstr "" -#~ "ΠάÏα πολλÎÏ‚ εκδόσεις λίστας αναπαÏ/γής \"%1\" για τη δημιουÏγία άλλης" -#~ msgid "alsa_pcm:playback_1" -#~ msgstr "alsa_pcm:playback_1" -#~ msgid "alsa_pcm:playback_2" -#~ msgstr "alsa_pcm:playback_2" - -#, fuzzy -#~ msgid "Could not find a template called %1 in %2" -#~ msgstr "Δεν μπόÏεσα να ανοίξω Ï€ÏοσχÎδιο μίξεως %1 για ανάγνωση" - -#, fuzzy -#~ msgid "Source: cannot stat peakfile \"%1\" or \"%2\"" -#~ msgstr "Source: δεν μποÏÏŽ να μετÏήσω το αυτοστιγμεί peakfile \"%1\"" -#~ msgid "Transport: error polling extra MIDI port #1 (revents =%1%2%3" -#~ msgstr "" -#~ "Transport: σφάλμα στην αίτηση επιπλÎον θÏÏας MIDI #1 (revents =%1%2%3" -#~ msgid "Transport: error polling extra MIDI port #2 (revents =%1%2%3" -#~ msgstr "" -#~ "Transport: σφάλμα στην αίτηση επιπλÎον θÏÏας MIDI #2 (revents =%1%2%3" -#~ msgid "Source: cannot seek to frame %1 in peakfile!" -#~ msgstr "Source: δεν μποÏÏŽ να αναζητήσω το frame %1 στο peakfile!" -#~ msgid "Source[%1]: cannot seek to frame %2 in peakfile!" -#~ msgstr "Source[%1]: δεν μποÏÏŽ να αναζητήσω το frame %2 στο peakfile!" -#~ msgid "%1: could not seek to byte %2 in peakfile (%3" -#~ msgstr "%1: δεν μποÏÏŽ να αναζητήσω σε byte %2 στο peakfile (%3" -#~ msgid "could not register an input port called \"%1\"" -#~ msgstr "δεν μπόÏεσα να register μία θÏÏα εισόδου με όνομα \"%1\"" -#~ msgid "could not register an output port called \"%1\"" -#~ msgstr "δεν μπόÏεσα να register μία θÏÏα εξόδου με όνομα \"%1\"" -#~ msgid "%1: disk stream error at frame %2 (%3)" -#~ msgstr "%1: σφάλμα disk stream στο frame %2 (%3)" -#~ msgid "IO: cannot connect input port %1 to %2" -#~ msgstr "IO: δεν μποÏεί να συνδεθεί η θÏÏα εισόδου %1 στο %2" -#~ msgid "IO: cannot connect output port %1 to %2" -#~ msgstr "IO: δεν μποÏεί να συνδεθεί η θÏÏα εξόδου %1 στο %2" -#~ msgid "Playlist: cannot create from state." -#~ msgstr "Playlist: δεν μποÏÏŽ να δημιουÏγήσω από κατάσταση." -#~ msgid "" -#~ "for various reasons, it is no longer valid to use one of the plugins " -#~ "listed for this session. it will be ignored" -#~ msgstr "" -#~ "για διάφοÏους λόγους, δεν είναι πλÎον χÏήσιμο να χÏησιμοποιηθεί Îνα από " -#~ "τα καταχωÏημÎνα pluginsγια αυτή τη συνεδÏία. Θα αγνοηθεί." -#~ msgid "cannot connect click track to %1" -#~ msgstr "δεν μποÏÏŽ να διασυνδÎσω το κανάλι MετÏονόμου(click track) στο %1" -#~ msgid "out %lu+%lu" -#~ msgstr "out %lu+%lu" -#~ msgid "in %lu+%lu" -#~ msgstr "in %lu+%lu" -#~ msgid "Session: error for %1 at frame %2 (%3)" -#~ msgstr "ΣυνεδÏία: σφάλμα για %1 στο frame %2 (%3)" - diff --git a/libs/ardour/po/it_IT.po b/libs/ardour/po/it_IT.po deleted file mode 100644 index 2ce02827bd..0000000000 --- a/libs/ardour/po/it_IT.po +++ /dev/null @@ -1,2236 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR Paul Davis -# This file is distributed under the same license as the PACKAGE package. -# Filippo Pappalardo <filippo@email.it>, 2003. -# -msgid "" -msgstr "" -"Project-Id-Version: libardour 0.664.0\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2006-06-29 21:03-0400\n" -"PO-Revision-Date: 2003-05-21 12:50+0500\n" -"Last-Translator: Filippo Pappalardo <filippo@email.it>\n" -"Language-Team: Italian\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=ISO-8859-1\n" -"Content-Transfer-Encoding: 8bit\n" - -#: libs/ardour/audio_diskstream.cc:337 -#, fuzzy -msgid "AudioDiskstream: Session doesn't know about a Playlist called \"%1\"" -msgstr "DiskStream: La sessione non riconosce la Playlist chiamata \"%1\"" - -#: libs/ardour/audio_diskstream.cc:342 -msgid "AudioDiskstream: Playlist \"%1\" isn't an audio playlist" -msgstr "" - -#: libs/ardour/audio_diskstream.cc:433 -#, fuzzy -msgid "AudioDiskstream %1: there is no existing playlist to make a copy of!" -msgstr "DiskStream %1: non esiste alcuna playlist di cui fare una copia!" - -#: libs/ardour/audio_diskstream.cc:1114 libs/ardour/audio_diskstream.cc:1125 -#, fuzzy -msgid "" -"AudioDiskstream %1: when refilling, cannot read %2 from playlist at frame %3" -msgstr "DiskStream %1: impossibile leggere %2 dalla playlista al frame %3" - -#: libs/ardour/audio_diskstream.cc:1254 -#, fuzzy -msgid "AudioDiskstream %1: cannot read %2 from playlist at frame %3" -msgstr "DiskStream %1: impossibile leggere %2 dalla playlista al frame %3" - -#: libs/ardour/audio_diskstream.cc:1621 libs/ardour/audio_diskstream.cc:1638 -#, fuzzy -msgid "AudioDiskstream %1: cannot write to disk" -msgstr "DiskStream %1: impossibile scrivere sul disco" - -#: libs/ardour/audio_diskstream.cc:1698 -#, fuzzy -msgid "AudioDiskstream \"%1\": cannot flush captured data to disk!" -msgstr "DiskStream \"%1\": impossibile scaricare i dati acquisiti sul disco!" - -#: libs/ardour/audio_diskstream.cc:1796 -msgid "%1: could not create region for complete audio file" -msgstr "%1: impossibile creare una regione per il file audio completo" - -#: libs/ardour/audio_diskstream.cc:1819 -#, fuzzy -msgid "AudioDiskstream: could not create region for captured audio!" -msgstr "DiskStream: impossibile creare una regione per l'audio registrato!" - -#: libs/ardour/audio_diskstream.cc:1874 -#, fuzzy -msgid "programmer error: %1" -msgstr "errore di programmazione: %1" - -#: libs/ardour/audio_diskstream.cc:2146 -#, fuzzy -msgid "AudioDiskstream: channel %1 out of range" -msgstr "DiskStream: canale fuori margine" - -#: libs/ardour/audio_diskstream.cc:2171 -msgid "%1:%2 new capture file not initialized correctly" -msgstr "%1:%2 nuovo file di registrazione non è stato avviato correttamente" - -#: libs/ardour/audio_diskstream.cc:2404 -msgid "Location \"%1\" not valid for track loop (start >= end)" -msgstr "La Location \"%1\" non valida per il loop (inizio >= fine)" - -#: libs/ardour/audio_diskstream.cc:2485 -#, fuzzy -msgid "%1: cannot restore pending capture source file %2" -msgstr "Import: impossibile aprire il file audio di input \"%1\"" - -#: libs/ardour/audio_diskstream.cc:2507 -msgid "%1: incorrect number of pending sources listed - ignoring them all" -msgstr "" - -#: libs/ardour/audio_diskstream.cc:2523 -#, fuzzy -msgid "%1: cannot create whole-file region from pending capture sources" -msgstr "Playlist: impossibile creare la Regione dal file di stato" - -#: libs/ardour/audio_diskstream.cc:2535 -#, fuzzy -msgid "%1: cannot create region from pending capture sources" -msgstr "Playlist: impossibile creare la Regione dal file di stato" - -#: libs/ardour/audio_library.cc:92 -msgid "channels" -msgstr "" - -#: libs/ardour/audio_library.cc:93 -#, fuzzy -msgid "samplerate" -msgstr "separa" - -#: libs/ardour/audio_library.cc:94 -msgid "resolution" -msgstr "" - -#: libs/ardour/audio_library.cc:95 -msgid "format" -msgstr "" - -#: libs/ardour/audio_library.cc:102 -msgid "Could not open %1. Audio Library not saved" -msgstr "Impossibile accedere a %1. Libreria Audio non salvata" - -#: libs/ardour/audio_playlist.cc:53 libs/ardour/audio_playlist.cc:63 -#: libs/ardour/audio_playlist.cc:74 libs/ardour/audio_playlist.cc:121 -#: libs/ardour/insert.cc:76 libs/ardour/insert.cc:95 libs/ardour/insert.cc:120 -#: libs/ardour/insert.cc:838 libs/ardour/insert.cc:846 libs/ardour/send.cc:39 -#: libs/ardour/send.cc:53 libs/ardour/send.cc:62 -#: libs/ardour/session_state.cc:1621 libs/ardour/session_state.cc:1667 -msgid "initial state" -msgstr "stato iniziale" - -#: libs/ardour/audio_playlist.cc:275 libs/ardour/audio_playlist.cc:769 -msgid "" -"programming error: non-audio Region passed to remove_overlap in audio " -"playlist" -msgstr "" - -#: libs/ardour/audio_playlist.cc:402 -msgid "" -"programming error: non-audio Region tested for overlap in audio playlist" -msgstr "" - -#: libs/ardour/audio_playlist.cc:878 -msgid "xfade change" -msgstr "cambio dello smorzamento incrociato" - -#: libs/ardour/audio_playlist.cc:933 -msgid "region modified" -msgstr "regione modificata" - -#: libs/ardour/audio_track.cc:125 libs/ardour/io.cc:1716 -#: libs/ardour/io.cc:1826 -msgid "Unknown connection \"%1\" listed for input of %2" -msgstr "Connessione sconosciuta \"%1\" come input di %2" - -#: libs/ardour/audio_track.cc:127 libs/ardour/io.cc:1718 -#: libs/ardour/io.cc:1828 -msgid "in 1" -msgstr "" - -#: libs/ardour/audio_track.cc:128 libs/ardour/io.cc:1719 -#: libs/ardour/io.cc:1829 -msgid "No input connections available as a replacement" -msgstr "" - -#: libs/ardour/audio_track.cc:132 libs/ardour/io.cc:1723 -#: libs/ardour/io.cc:1833 -msgid "Connection %1 was not available - \"in 1\" used instead" -msgstr "" - -#: libs/ardour/audio_track.cc:141 libs/ardour/io.cc:1842 -msgid "improper input channel list in XML node (%1)" -msgstr "" - -#: libs/ardour/audio_track.cc:186 libs/ardour/audio_track.cc:199 -msgid "AudioTrack: diskstream \"%1\" not known by session" -msgstr "AudioTrack: diskstream \"%1\" non riconosciuto dalla sessione" - -#: libs/ardour/audio_track.cc:297 -msgid "" -"MIDI rec_enable control specification for %1 is incomplete, so it has been " -"ignored" -msgstr "" - -#: libs/ardour/audio_track.cc:309 -msgid "programming error: AudioTrack given state without diskstream!" -msgstr "" - -#: libs/ardour/audioengine.cc:144 -msgid "cannot activate JACK client" -msgstr "impossibile attivare il client JACK" - -#: libs/ardour/audioengine.cc:395 -msgid "register audio input port called before engine was started" -msgstr "" -"la richiesta di registrazione di una porta di entrata avvenuta prima " -"dell'avvio dell'applicazione" - -#: libs/ardour/audioengine.cc:426 -msgid "register audio output port called before engine was started" -msgstr "" -"la richiesta di registrazione di una porta di uscita avvenuta prima " -"dell'avvio dell'applicazione" - -#: libs/ardour/audioengine.cc:487 -msgid "connect called before engine was started" -msgstr "richiesta di connessione avvenuta prima dell'avvio dell'applicazione" - -#: libs/ardour/audioengine.cc:503 -msgid "AudioEngine: cannot connect %1 (%2) to %3 (%4)" -msgstr "" - -#: libs/ardour/audioengine.cc:516 libs/ardour/audioengine.cc:545 -msgid "disconnect called before engine was started" -msgstr "" -"richiesta di disconnessione avvenuta prima dell'avvio dell'applicazione" - -#: libs/ardour/audioengine.cc:603 -msgid "get_port_by_name() called before engine was started" -msgstr "" -"richiesta get_port_by_name() avvenuta prima dell'avvio dell'applicazione" - -#: libs/ardour/audioengine.cc:636 -msgid "get_ports called before engine was started" -msgstr "richiesta di get_ports avvenuta prima dell'avvio dell'applicazione" - -#: libs/ardour/audioengine.cc:711 -msgid "get_nth_physical called before engine was started" -msgstr "" -"richiesta di get_nth_physical avvenuta prima dell'avvio dell'applicazione" - -#: libs/ardour/audioengine.cc:739 -#, fuzzy -msgid "get_port_total_latency() called with no JACK client connection" -msgstr "" -"richiesta di get_port_total_latency() avvenuta prima dell'avvio " -"dell'applicazione" - -#: libs/ardour/audioengine.cc:745 -msgid "get_port_total_latency() called before engine was started" -msgstr "" -"richiesta di get_port_total_latency() avvenuta prima dell'avvio " -"dell'applicazione" - -#: libs/ardour/audioengine.cc:869 -msgid "Unable to connect to JACK server" -msgstr "" - -#: libs/ardour/audioengine.cc:872 -msgid "Could not connect to JACK server as \"%1\"" -msgstr "" - -#: libs/ardour/audioengine.cc:877 -msgid "JACK server started" -msgstr "" - -#: libs/ardour/audioengine.cc:911 -msgid "cannot shutdown connection to JACK" -msgstr "" - -#: libs/ardour/audioengine.cc:936 -msgid "failed to connect to JACK" -msgstr "" - -#: libs/ardour/audioengine.cc:952 -#, fuzzy -msgid "could not reregister %1" -msgstr "Esportazione: impossibile scrivere dati sul file di output (%1)" - -#: libs/ardour/audioengine.cc:1009 -msgid "could not reconnect %1 and %2 (err = %3)" -msgstr "" - -#: libs/ardour/audiofilesource.cc:444 libs/ardour/session_state.cc:3095 -msgid "" -"there are already 1000 files with names like %1; versioning discontinued" -msgstr "" -"ci sono gia' 1000 file con nomi come %1; tracciamento di versione interrotto" - -#: libs/ardour/audiofilesource.cc:458 libs/ardour/session_state.cc:3109 -msgid "cannot rename audio file source from %1 to %2 (%3)" -msgstr "impossibile rinominare file audio sorgente da %1 a %2 (%3)" - -#: libs/ardour/audiofilesource.cc:465 libs/ardour/session_state.cc:3124 -msgid "cannot remove peakfile %1 for %2 (%3)" -msgstr "impossibile eliminare il peakfile %1 per %2 (%3)" - -#: libs/ardour/audiofilesource.cc:509 -msgid "FileSource: search path not set" -msgstr "FileSource: percorso di ricerca non specificato" - -#: libs/ardour/audiofilesource.cc:533 -msgid "" -"FileSource: \"%1\" is ambigous when searching %2\n" -"\t" -msgstr "" -"FileSource: \"%1\" è risultato ambiguo nel cercare %2\n" -"\t" - -#: libs/ardour/audiofilesource.cc:539 -#, fuzzy -msgid "Filesource: cannot find required file (%1): while searching %2" -msgstr "FileSource: impossibile trovare il file richiesto (%1): %2" - -#: libs/ardour/audiofilesource.cc:562 -msgid "Filesource: cannot find required file (%1): %2" -msgstr "FileSource: impossibile trovare il file richiesto (%1): %2" - -#: libs/ardour/audiofilesource.cc:567 -msgid "Filesource: cannot check for existing file (%1): %2" -msgstr "FileSource: impossibile controllare il file esistente (%1): %2" - -#: libs/ardour/audiofilesource.cc:636 libs/ardour/insert.cc:525 -#: libs/ardour/sndfilesource.cc:113 -msgid "programming error: %1" -msgstr "errore di programmazione: %1" - -#: libs/ardour/audiofilesource.cc:641 -#, fuzzy -msgid "cannot rename audio file for %1 to %2" -msgstr "impossibile rinominare file audio sorgente da %1 a %2 (%3)" - -#: libs/ardour/audiofilter.cc:45 -msgid "audiofilter: error creating name for new audio file based on %1" -msgstr "" -"audiofilter: errore nel creare il nome per il nuovo file audio basato su %1" - -#: libs/ardour/audiofilter.cc:58 -msgid "audiofilter: error creating new audio file %1 (%2)" -msgstr "audiofilter: errore nel creare un nuovo file audio %1 (%2)" - -#: libs/ardour/audioregion.cc:857 libs/ardour/audioregion.cc:919 -#, fuzzy -msgid "fade in change" -msgstr "cambio dello smorzamento incrociato" - -#: libs/ardour/audioregion.cc:1349 -#, c-format -msgid "normalized to %.2fdB" -msgstr "normalizzato a %.2fdB" - -#: libs/ardour/audioregion.cc:1367 -#, fuzzy -msgid "envelope change" -msgstr "livello cambiato" - -#: libs/ardour/audiosource.cc:143 -msgid "poll on peak request pipe failed (%1)" -msgstr "" - -#: libs/ardour/audiosource.cc:150 -msgid "Error on peak thread request pipe" -msgstr "" - -#: libs/ardour/audiosource.cc:183 -#, fuzzy -msgid "Error reading from peak request pipe" -msgstr "Errore nel leggere dalla porta MIDI %1" - -#: libs/ardour/audiosource.cc:215 libs/ardour/session_butler.cc:80 -#: libs/ardour/session_midi.cc:1183 -msgid "Cannot create transport request signal pipe (%1)" -msgstr "" - -#: libs/ardour/audiosource.cc:220 libs/ardour/audiosource.cc:225 -msgid "UI: cannot set O_NONBLOCK on peak request pipe (%1)" -msgstr "" - -#: libs/ardour/audiosource.cc:230 -#, fuzzy -msgid "AudioSource: could not create peak thread" -msgstr "Sessione: impossibile creare un nuovo route" - -#: libs/ardour/audiosource.cc:308 -#, fuzzy -msgid "cannot rename peakfile for %1 from %2 to %3 (%4)" -msgstr "impossibile eliminare il peakfile %1 per %2 (%3)" - -#: libs/ardour/audiosource.cc:350 -#, fuzzy -msgid "AudioSource: cannot stat peakfile \"%1\"" -msgstr "FileSource: impossibile avviare il peakfile per %1" - -#: libs/ardour/audiosource.cc:451 -msgid "cannot read sample data for unscaled peak computation" -msgstr "" - -#: libs/ardour/audiosource.cc:472 libs/ardour/audiosource.cc:543 -#: libs/ardour/audiosource.cc:787 libs/ardour/audiosource.cc:878 -#, fuzzy -msgid "AudioSource: cannot open peakpath \"%1\" (%2)" -msgstr "SndFileSource: impossibile accedere al file \"%1\" (%2)" - -#: libs/ardour/audiosource.cc:644 -#, fuzzy -msgid "AudioSource[%1]: peak read - cannot read %2 samples at offset %3" -msgstr "DiskStream %1: impossibile leggere %2 dalla playlista al frame %3" - -#: libs/ardour/audiosource.cc:798 -msgid "%1: could not write read raw data for peak computation (%2)" -msgstr "" - -#: libs/ardour/audiosource.cc:823 -msgid "%1: could not write peak file data (%2)" -msgstr "" - -#: libs/ardour/automation_event.cc:65 libs/ardour/location.cc:345 -#: libs/ardour/tempo.cc:226 -msgid "initial" -msgstr "iniziale" - -#: libs/ardour/automation_event.cc:232 -msgid "cleared" -msgstr "pulito" - -#: libs/ardour/automation_event.cc:404 -msgid "added event" -msgstr "aggiunto evento" - -#: libs/ardour/automation_event.cc:421 -msgid "removed event" -msgstr "rimosso evento" - -#: libs/ardour/automation_event.cc:436 -msgid "removed multiple events" -msgstr "rimossi molteplici eventi" - -#: libs/ardour/automation_event.cc:467 libs/ardour/automation_event.cc:498 -msgid "removed range" -msgstr "rimosso intervallo" - -#: libs/ardour/automation_event.cc:528 -msgid "event range adjusted" -msgstr "" - -#: libs/ardour/automation_event.cc:550 -msgid "event adjusted" -msgstr "" - -#: libs/ardour/automation_event.cc:665 libs/ardour/automation_event.cc:770 -#: libs/ardour/panner.cc:1041 -msgid "programming error:" -msgstr "errore di programmazione:" - -#: libs/ardour/automation_event.cc:1079 -msgid "cut/copy/clear" -msgstr "taglia/copia/pulisci" - -#: libs/ardour/automation_event.cc:1112 -msgid "copy" -msgstr "copia" - -#: libs/ardour/automation_event.cc:1180 libs/ardour/playlist.cc:939 -msgid "paste" -msgstr "incolla" - -#: libs/ardour/automation_event.cc:1235 -msgid "" -"automation list: no x-coordinate stored for control point (point ignored)" -msgstr "" -"lista automazione: nessuna coordinata X salvata per punto di controllo " -"(ignorato)" - -#: libs/ardour/automation_event.cc:1241 -msgid "" -"automation list: no y-coordinate stored for control point (point ignored)" -msgstr "" -"lista automazione: nessuna coordinata Y salvata per punto di controllo " -"(ignorato)" - -#: libs/ardour/configuration.cc:80 -#, fuzzy -msgid "loading system configuration file %1" -msgstr "" -"Ardour: impossibile leggere il file di configurazione di sistema \"%1\"" - -#: libs/ardour/configuration.cc:83 -msgid "Ardour: cannot read system configuration file \"%1\"" -msgstr "" -"Ardour: impossibile leggere il file di configurazione di sistema \"%1\"" - -#: libs/ardour/configuration.cc:88 -msgid "Ardour: system configuration file \"%1\" not loaded successfully." -msgstr "" -"Ardour: il file di configurazione di sistema \"%1\" non stato caricato con " -"successo" - -#: libs/ardour/configuration.cc:105 -#, fuzzy -msgid "loading user configuration file %1" -msgstr "Ardour: impossibile la lettura del file di configurazione \"%1\"" - -#: libs/ardour/configuration.cc:108 -msgid "Ardour: cannot read configuration file \"%1\"" -msgstr "Ardour: impossibile la lettura del file di configurazione \"%1\"" - -#: libs/ardour/configuration.cc:113 -#, fuzzy -msgid "Ardour: user configuration file \"%1\" not loaded successfully." -msgstr "" -"Ardour: il file di configurazione \"%1\" non stato caricato con successo" - -#: libs/ardour/configuration.cc:137 -#, fuzzy -msgid "Config file %1 not saved" -msgstr "File di configurazione non salvato" - -#: libs/ardour/configuration.cc:210 -msgid "ill-formed MIDI port specification in ardour rcfile (ignored)" -msgstr "" -"porta MIDI mal configurata nel file di configurazione di ardour (ignorato)" - -#: libs/ardour/connection.cc:183 -msgid "Node for Connection has no \"name\" property" -msgstr "Il nodo per la connessione non possiede l'attributo \"nome\"" - -#: libs/ardour/connection.cc:191 -msgid "Node for Connection has no \"connections\" property" -msgstr "Il nodo per la connessione non ha l'attributo \"connessioni\"" - -#: libs/ardour/connection.cc:227 libs/ardour/io.cc:1902 -msgid "IO: badly formed string in XML node for inputs \"%1\"" -msgstr "IO: stringa malformata nel nodo XML per le entrate \"%1\"" - -#: libs/ardour/connection.cc:232 libs/ardour/io.cc:1907 -msgid "bad input string in XML node \"%1\"" -msgstr "stringa malformata nel nodo XML \"%1\"" - -#: libs/ardour/control_protocol_manager.cc:80 -msgid "control protocol name \"%1\" has no descriptor" -msgstr "" - -#: libs/ardour/control_protocol_manager.cc:85 -msgid "control protocol name \"%1\" could not be initialized" -msgstr "" - -#: libs/ardour/control_protocol_manager.cc:141 -msgid "Instantiating mandatory control protocol %1" -msgstr "" - -#: libs/ardour/control_protocol_manager.cc:175 -#, fuzzy -msgid "Control protocol %1 not usable" -msgstr "La porta MIDI \"%1\" non disponibile: nessun controllo MTC possibile" - -#: libs/ardour/control_protocol_manager.cc:187 -msgid "Control surface protocol discovered: \"%1\"" -msgstr "" - -#: libs/ardour/control_protocol_manager.cc:205 -#, fuzzy -msgid "ControlProtocolManager: cannot load module \"%1\" (%2)" -msgstr "LADSPA: impossibile caricare il modulo \"%1\" (%2)" - -#: libs/ardour/control_protocol_manager.cc:213 -#, fuzzy -msgid "ControlProtocolManager: module \"%1\" has no descriptor function." -msgstr "LADSPA: il modulo \"%1\" non ha alcuna funzione descriptor." - -#: libs/ardour/crossfade.cc:121 -msgid "Crossfade: no \"in\" region in state" -msgstr "" - -#: libs/ardour/crossfade.cc:128 -msgid "Crossfade: no \"in\" region %1 found in playlist %2" -msgstr "" - -#: libs/ardour/crossfade.cc:138 -msgid "Crossfade: no \"out\" region in state" -msgstr "" - -#: libs/ardour/crossfade.cc:145 -msgid "Crossfade: no \"out\" region %1 found in playlist %2" -msgstr "" - -#: libs/ardour/crossfade.cc:492 -#, fuzzy -msgid "active changed" -msgstr "livello cambiato" - -#: libs/ardour/crossfade.cc:741 -#, fuzzy -msgid "old-style crossfade information - no position information" -msgstr "il nodo XML per la Location non ha informazioni sull'inizio" - -#: libs/ardour/curve.cc:112 libs/ardour/globals.cc:340 -#: libs/ardour/insert.cc:454 libs/ardour/session.cc:2466 -#: libs/ardour/session.cc:2518 -msgid "programming error: " -msgstr "errore di programmazione: " - -#: libs/ardour/cycle_timer.cc:37 -msgid "CycleTimer::get_mhz(): can't open /proc/cpuinfo" -msgstr "CycleTimer::get_mhz(): impossibile accedere a /proc/cpuinfo" - -#: libs/ardour/cycle_timer.cc:49 -msgid "CycleTimer::get_mhz(): cannot locate cpu MHz in /proc/cpuinfo" -msgstr "" -"CycleTimer::get_mhz(): impossibile localizzare \"cpu MHz\" in /proc/cpuinfo" - -#: libs/ardour/cycle_timer.cc:72 -msgid "cannot locate cpu MHz in /proc/cpuinfo" -msgstr "impossibile localizzare \"cpu MHz\" in /proc/cpuinfo" - -#: libs/ardour/destructive_filesource.cc:188 -msgid "DestructiveFileSource: \"%1\" bad read retval: %2 of %5 (%3: %4)" -msgstr "" - -#: libs/ardour/destructive_filesource.cc:201 -#: libs/ardour/destructive_filesource.cc:243 -#: libs/ardour/destructive_filesource.cc:250 -msgid "DestructiveFileSource: \"%1\" bad write (%2)" -msgstr "" - -#: libs/ardour/globals.cc:109 -msgid "no MIDI ports specified: no MMC or MTC control possible" -msgstr "Nessuna porta MIDI specificata: impossibile alcun controllo MMC o MTC" - -#: libs/ardour/globals.cc:124 -msgid "MIDI port specifications for \"%1\" are not understandable." -msgstr "Le specifiche per la porta MIDI \"%1\" non sono state capite" - -#: libs/ardour/globals.cc:137 libs/ardour/globals.cc:141 -#: libs/ardour/globals.cc:145 -msgid "default" -msgstr "" - -#: libs/ardour/globals.cc:173 -msgid "No MMC control (MIDI port \"%1\" not available)" -msgstr "La porta MIDI \"%1\" non disponibile: nessun controllo MTC possibile" - -#: libs/ardour/globals.cc:179 -msgid "No MTC support (MIDI port \"%1\" not available)" -msgstr "La porta MIDI \"%1\" non disponibile: nessun controllo MTC possibile" - -#: libs/ardour/globals.cc:184 -#, fuzzy -msgid "No MIDI parameter support (MIDI port \"%1\" not available)" -msgstr "La porta MIDI \"%1\" non disponibile: nessun controllo MTC possibile" - -#: libs/ardour/import.cc:75 -msgid "Import: cannot open input sound file \"%1\"" -msgstr "Import: impossibile aprire il file audio di input \"%1\"" - -#: libs/ardour/import.cc:80 -msgid "resampling audio" -msgstr "" - -#: libs/ardour/import.cc:84 -msgid "Import: cannot open converted sound file \"%1\"" -msgstr "Import: impossibile aprire il file audio convertito \"%1\"" - -#: libs/ardour/import.cc:89 -msgid "Import: error while resampling sound file \"%1\"" -msgstr "Import: errore nel resampling deil file audio \"%1\"" - -#: libs/ardour/import.cc:148 -msgid "Session::import_audiofile: cannot open new file source for channel %1" -msgstr "" -"Session::import_audiofile: impossibile aprire il nuovo file per il canale %1" - -#: libs/ardour/import.cc:167 -msgid "converting audio" -msgstr "conversione dell'audio" - -#: libs/ardour/import.cc:199 -msgid "building region" -msgstr "costruzione della regione" - -#: libs/ardour/import.cc:201 -msgid "building regions" -msgstr "costruzione delle regioni" - -#: libs/ardour/import.cc:325 -msgid "Import: could not open temp file: %1" -msgstr "Import: impossibile aprire il file audio temporaneo \"%1\"" - -#: libs/ardour/import.cc:334 -msgid "Import: src_new() failed : %1" -msgstr "" - -#: libs/ardour/import.cc:362 -msgid "Import: %1" -msgstr "" - -#: libs/ardour/insert.cc:644 libs/ardour/insert.cc:936 -msgid "XML node describing insert is missing the `type' field" -msgstr "Il nodo XML descrivente l'insert manca del campo `type'" - -#: libs/ardour/insert.cc:653 -msgid "unknown plugin type %1 in plugin insert state" -msgstr "" - -#: libs/ardour/insert.cc:665 -msgid "XML node describing insert is missing the `id' field" -msgstr "Il nodo XML descrivente l'insert manca del campo `id'" - -#: libs/ardour/insert.cc:678 -msgid "" -"Found a reference to a plugin (\"%1\") that is unknown.\n" -"Perhaps it was removed or moved since it was last used." -msgstr "" -"Trovato un riferimento ad un plugin (\"%1\") sconosciuto.\n" -"Forse stato rimosso o spostato dall'ultima volta che lo si e' usato" - -#: libs/ardour/insert.cc:716 libs/ardour/insert.cc:953 -msgid "XML node describing insert is missing a Redirect node" -msgstr "Il nodo XML descrivente l'insert manca di un nodo Redirect" - -#: libs/ardour/insert.cc:721 -msgid "XML node describing a plugin insert is missing the `%1' information" -msgstr "Il nodo XML descrivente un insert plugin manca della informazione `%1'" - -#: libs/ardour/insert.cc:745 -msgid "PluginInsert: Auto: no ladspa port number" -msgstr "" - -#: libs/ardour/insert.cc:752 -msgid "PluginInsert: Auto: port id out of range" -msgstr "" - -#: libs/ardour/insert.cc:768 -#, fuzzy -msgid "XML node describing a port automation is missing the `%1' information" -msgstr "Il nodo XML descrivente un insert LADSPA manca della informazione `%1'" - -#: libs/ardour/insert.cc:854 -msgid "PortInsert: cannot add input port" -msgstr "PortInsert: impossibile aggiungere una porta d'entrata" - -#: libs/ardour/insert.cc:859 -msgid "PortInsert: cannot add output port" -msgstr "PortInsert: impossibile aggiungere una porta d'uscita" - -#: libs/ardour/insert.cc:941 -msgid "non-port insert XML used for port plugin insert" -msgstr "insert non-port XML usato per insert di plugin di porta" - -#: libs/ardour/io.cc:598 -msgid "IO: cannot disconnect input port %1 from %2" -msgstr "IO: impossibile disconnettere la porta d'entrata %1 da %2" - -#: libs/ardour/io.cc:666 -msgid "IO: cannot disconnect output port %1 from %2" -msgstr "IO: impossibile disconnettere la porta d'uscita %1 da %2" - -#: libs/ardour/io.cc:807 libs/ardour/io.cc:1151 libs/ardour/io.cc:1277 -#, c-format -msgid "%s/out" -msgstr "" - -#: libs/ardour/io.cc:809 libs/ardour/io.cc:1153 libs/ardour/io.cc:1279 -#: libs/ardour/io.cc:2849 -#, c-format -msgid "%s/out %u" -msgstr "" - -#: libs/ardour/io.cc:813 libs/ardour/io.cc:1158 libs/ardour/io.cc:1283 -msgid "IO: cannot register output port %1" -msgstr "IO: impossibile registrare la porta %1" - -#: libs/ardour/io.cc:908 libs/ardour/io.cc:1011 libs/ardour/io.cc:1117 -#, c-format -msgid "%s/in" -msgstr "" - -#: libs/ardour/io.cc:910 libs/ardour/io.cc:1014 libs/ardour/io.cc:1120 -#: libs/ardour/io.cc:2819 -#, c-format -msgid "%s/in %u" -msgstr "" - -#: libs/ardour/io.cc:914 libs/ardour/io.cc:1020 libs/ardour/io.cc:1125 -msgid "IO: cannot register input port %1" -msgstr "IO: impossibile registrare la porta %1" - -#: libs/ardour/io.cc:1541 -msgid "IO::connecting_became_legal() called without a pending state node" -msgstr "" - -#: libs/ardour/io.cc:1564 -msgid "IO::ports_became_legal() called without a pending state node" -msgstr "" - -#: libs/ardour/io.cc:1594 -msgid "incorrect XML node \"%1\" passed to IO object" -msgstr "" - -#: libs/ardour/io.cc:1649 -msgid "" -"MIDI gain control specification for %1 is incomplete, so it has been ignored" -msgstr "" - -#: libs/ardour/io.cc:1739 libs/ardour/io.cc:1851 -msgid "Unknown connection \"%1\" listed for output of %2" -msgstr "" - -#: libs/ardour/io.cc:1741 libs/ardour/io.cc:1853 -msgid "out 1" -msgstr "" - -#: libs/ardour/io.cc:1742 libs/ardour/io.cc:1854 -msgid "No output connections available as a replacement" -msgstr "" - -#: libs/ardour/io.cc:1746 libs/ardour/io.cc:1858 -msgid "Connection %1 was not available - \"out 1\" used instead" -msgstr "" - -#: libs/ardour/io.cc:1760 -msgid "%1: cannot create I/O ports" -msgstr "" - -#: libs/ardour/io.cc:1867 -msgid "improper output channel list in XML node (%1)" -msgstr "" - -#: libs/ardour/io.cc:1952 -msgid "IO: badly formed string in XML node for outputs \"%1\"" -msgstr "IO: stringa mal formata nel nodo XML per le uscite \"%1\"" - -#: libs/ardour/io.cc:1957 -msgid "IO: bad output string in XML node \"%1\"" -msgstr "IO: stringa mal formata nel nodo XML \"%1\"" - -#: libs/ardour/io.cc:2525 -msgid "%1: could not open automation event file \"%2\"" -msgstr "" - -#: libs/ardour/io.cc:2564 -msgid "%1: cannot open automation event file \"%2\"" -msgstr "" - -#: libs/ardour/io.cc:2579 -msgid "badly formed version number in automation event file \"%1\"" -msgstr "" - -#: libs/ardour/io.cc:2583 -msgid "no version information in automation event file \"%1\"" -msgstr "" - -#: libs/ardour/io.cc:2588 -msgid "mismatched automation event file version (%1)" -msgstr "" - -#: libs/ardour/io.cc:2596 -msgid "badly formatted automation event record at line %1 of %2 (ignored)" -msgstr "" - -#: libs/ardour/io.cc:2616 -msgid "dubious automation event found (and ignored)" -msgstr "" - -#: libs/ardour/io.cc:2620 libs/ardour/panner.cc:438 -#: libs/ardour/redirect.cc:148 -msgid "loaded from disk" -msgstr "" - -#: libs/ardour/io.cc:2791 -msgid "automation write/touch" -msgstr "" - -#: libs/ardour/ladspa_plugin.cc:87 -msgid "LADSPA: module has no descriptor function." -msgstr "LADSPA: il modulo non ha alcuna funzione descriptor." - -#: libs/ardour/ladspa_plugin.cc:92 -msgid "LADSPA: plugin has gone away since discovery!" -msgstr "LADSPA: il plugin è stato rimosso" - -#: libs/ardour/ladspa_plugin.cc:99 -msgid "LADSPA: \"%1\" cannot be used, since it cannot do inplace processing" -msgstr "" - -#: libs/ardour/ladspa_plugin.cc:329 -msgid "" -"illegal parameter number used with plugin \"%1\". This mayindicate a change " -"in the plugin design, and presets may beinvalid" -msgstr "" - -#: libs/ardour/ladspa_plugin.cc:430 -msgid "Bad node sent to LadspaPlugin::set_state" -msgstr "" - -#: libs/ardour/ladspa_plugin.cc:443 -msgid "LADSPA: no ladspa port number" -msgstr "" - -#: libs/ardour/ladspa_plugin.cc:449 -msgid "LADSPA: no ladspa port data" -msgstr "" - -#: libs/ardour/ladspa_plugin.cc:498 -msgid "" -"LADSPA LadspaPlugin MIDI control specification for port %1 is incomplete, so " -"it has been ignored" -msgstr "" - -#: libs/ardour/location.cc:269 -msgid "incorrect XML node passed to Location::set_state" -msgstr "" - -#: libs/ardour/location.cc:276 -msgid "XML node for Location has no name information" -msgstr "il nodo XML per la Location non ha informazioni sul nome" - -#: libs/ardour/location.cc:283 -msgid "XML node for Location has no start information" -msgstr "il nodo XML per la Location non ha informazioni sull'inizio" - -#: libs/ardour/location.cc:294 -msgid "XML node for Location has no end information" -msgstr "il nodo XML per la Location non ha informazioni sulla fine" - -#: libs/ardour/location.cc:303 -msgid "XML node for Location has no flags information" -msgstr "il nodo XML per la Location non ha informazioni sui flags" - -#: libs/ardour/location.cc:391 -msgid "Locations: attempt to use unknown location as selected location" -msgstr "" - -#: libs/ardour/location.cc:418 libs/ardour/playlist.cc:1187 -msgid "clear" -msgstr "pulisci" - -#: libs/ardour/location.cc:443 -msgid "clear markers" -msgstr "" - -#: libs/ardour/location.cc:471 -msgid "clear ranges" -msgstr "" - -#: libs/ardour/location.cc:489 -msgid "add" -msgstr "" - -#: libs/ardour/location.cc:527 -msgid "remove" -msgstr "rimuovi" - -#: libs/ardour/location.cc:567 -msgid "incorrect XML mode passed to Locations::set_state" -msgstr "" - -#: libs/ardour/mtc_slave.cc:196 -msgid "MTC Slave: atomic read of current time failed, sleeping!" -msgstr "" - -#: libs/ardour/named_selection.cc:77 -msgid "Chunk %1 uses an unknown playlist \"%2\"" -msgstr "Lo spezzone %1 usa una playlist sconosciuta \"%2\"" - -#: libs/ardour/named_selection.cc:80 -msgid "Chunk %1 contains misformed playlist information" -msgstr "Lo spezzone %1 contiene informazioni sulla playlist mal formate" - -#: libs/ardour/panner.cc:256 -msgid "MIDI pan control specification is incomplete, so it has been ignored" -msgstr "" - -#: libs/ardour/panner.cc:361 -msgid "automation write pass" -msgstr "" - -#: libs/ardour/panner.cc:401 -#, c-format -msgid "error writing pan automation file (%s)" -msgstr "errore nello scrivere il file per l'automazione pan (%s)" - -#: libs/ardour/panner.cc:429 -msgid "" -"badly formatted pan automation event record at line %1 of %2 (ignored) [%3]" -msgstr "" - -#: libs/ardour/panner.cc:944 -msgid "badly-formed positional data for Multi2dPanner - ignored" -msgstr "" - -#: libs/ardour/panner.cc:1237 -msgid "cannot open pan automation file \"%1\" for saving (%s)" -msgstr "" -"impossibile aprire il file dell'automazione pan \"%1\" per salvare (%s)" - -#: libs/ardour/panner.cc:1273 -msgid "cannot open pan automation file %1 (%2)" -msgstr "impossibile accedere al file dell'automazione pan %1 (%2)" - -#: libs/ardour/panner.cc:1286 -msgid "badly formed version number in pan automation event file \"%1\"" -msgstr "" - -#: libs/ardour/panner.cc:1290 -msgid "" -"no version information in pan automation event file \"%1\" (first line = %2)" -msgstr "" - -#: libs/ardour/panner.cc:1296 -msgid "mismatched pan automation event file version (%1)" -msgstr "" - -#: libs/ardour/panner.cc:1310 -msgid "too many panner states found in pan automation file %1" -msgstr "" - -#: libs/ardour/panner.cc:1451 -#, fuzzy -msgid "Unknown panner plugin \"%1\" found in pan state - ignored" -msgstr "Nodo sconosciuto \"%1\" trovato in Connections list dal file di stato" - -#: libs/ardour/panner.cc:1457 -#, fuzzy -msgid "panner plugin node has no type information!" -msgstr "il nodo XML per la Location non ha informazioni sulla fine" - -#: libs/ardour/playlist.cc:253 -msgid "playlist const copy constructor called" -msgstr "" - -#: libs/ardour/playlist.cc:259 -msgid "playlist non-const copy constructor called" -msgstr "" - -#: libs/ardour/playlist.cc:499 -msgid "add region" -msgstr "aggiungi regione" - -#: libs/ardour/playlist.cc:554 -msgid "replace region" -msgstr "sostituisci la regione" - -#: libs/ardour/playlist.cc:567 -msgid "remove region" -msgstr "rimuovi la regione" - -#: libs/ardour/playlist.cc:614 -msgid "separate" -msgstr "separa" - -#: libs/ardour/playlist.cc:878 -msgid "cut" -msgstr "taglia" - -#: libs/ardour/playlist.cc:968 -msgid "duplicate" -msgstr "duplica" - -#: libs/ardour/playlist.cc:1023 -msgid "split" -msgstr "spezza" - -#: libs/ardour/playlist.cc:1100 -msgid "%1: bounds changed received for region (%2)not in playlist" -msgstr "" - -#: libs/ardour/playlist.cc:1361 -#, fuzzy -msgid "Playlist: cannot create region from state file" -msgstr "Playlist: impossibile creare la Regione dal file di stato" - -#: libs/ardour/playlist.cc:1721 -msgid "nudged" -msgstr "spostato" - -#: libs/ardour/playlist_factory.cc:49 libs/ardour/playlist_factory.cc:64 -msgid "" -"programming error: Playlist::createRegion called with unknown Region type" -msgstr "" - -#: libs/ardour/playlist_factory.cc:86 -msgid "" -"programming error: Playlist::copyPlaylist called with unknown Playlist type" -msgstr "" - -#: libs/ardour/plugin.cc:328 -msgid "Could not locate HOME. Preset not saved." -msgstr "impossibile localizzare HOME. Preset non salvato." - -#: libs/ardour/plugin.cc:338 libs/ardour/plugin.cc:344 -msgid "Could not create %1. Preset not saved. (%2)" -msgstr "Impossibile creare %1 . Preset non salvato. (%2)" - -#: libs/ardour/plugin.cc:349 -msgid "Error saving presets file %1." -msgstr "Errore nel salvare il file di preset %1." - -#: libs/ardour/plugin_manager.cc:194 -#, fuzzy -msgid "Could not parse rdf file: %1" -msgstr "IO: impossibile registrare la porta %1" - -#: libs/ardour/plugin_manager.cc:235 -msgid "LADSPA: cannot load module \"%1\" (%2)" -msgstr "LADSPA: impossibile caricare il modulo \"%1\" (%2)" - -#: libs/ardour/plugin_manager.cc:242 -msgid "LADSPA: module \"%1\" has no descriptor function." -msgstr "LADSPA: il modulo \"%1\" non ha alcuna funzione descriptor." - -#: libs/ardour/plugin_manager.cc:297 -#, fuzzy -msgid "VST: cannot load module from \"%1\"" -msgstr "LADPSA: impossibile caricare il modulo da \"%1\"" - -#: libs/ardour/plugin_manager.cc:302 -msgid "You asked ardour to not use any VST plugins" -msgstr "" - -#: libs/ardour/plugin_manager.cc:305 -msgid "This version of ardour has no support for VST plugins" -msgstr "" - -#: libs/ardour/plugin_manager.cc:312 -msgid "LADSPA: cannot load module from \"%1\"" -msgstr "LADPSA: impossibile caricare il modulo da \"%1\"" - -#: libs/ardour/plugin_manager.cc:374 libs/ardour/plugin_manager.cc:386 -msgid "Unknown" -msgstr "" - -#: libs/ardour/plugin_manager.cc:464 -msgid "" -"VST plugin %1 does not support processReplacing, and so cannot be used in " -"ardour at this time" -msgstr "" - -#: libs/ardour/recent_sessions.cc:44 -#, fuzzy -msgid "cannot open recent session file %1 (%2)" -msgstr "impossibile accedere al file di sessione recente %1 (%2)" - -#: libs/ardour/redirect.cc:77 -msgid "programming error: unknown Redirect type in Redirect::Clone!\n" -msgstr "" - -#: libs/ardour/redirect.cc:102 libs/ardour/utils.cc:203 -msgid "pre" -msgstr "" - -#: libs/ardour/redirect.cc:104 libs/ardour/utils.cc:206 -#, fuzzy -msgid "post" -msgstr "incolla" - -#: libs/ardour/redirect.cc:107 -msgid "Redirect: unknown placement string \"%1\" (ignored)" -msgstr "" - -#: libs/ardour/redirect.cc:125 -msgid "%1: cannot open %2 to load automation data (%3)" -msgstr "" - -#: libs/ardour/redirect.cc:154 -msgid "%1: cannot load automation data from %2" -msgstr "" - -#: libs/ardour/redirect.cc:175 -msgid "%1: cannot open %2 to store automation data (%3)" -msgstr "" - -#: libs/ardour/redirect.cc:194 libs/ardour/redirect.cc:201 -msgid "%1: could not save automation state to %2" -msgstr "" - -#: libs/ardour/redirect.cc:246 -msgid "Could not get state from Redirect (%1). Problem with save_automation" -msgstr "" - -#: libs/ardour/redirect.cc:296 -msgid "incorrect XML node \"%1\" passed to Redirect object" -msgstr "" - -#: libs/ardour/redirect.cc:318 -msgid "%1: Automation node has no path property" -msgstr "" - -#: libs/ardour/redirect.cc:343 -msgid "XML node describing an IO is missing an IO node" -msgstr "" - -#: libs/ardour/redirect.cc:348 -#, fuzzy -msgid "XML node describing a redirect is missing the `active' field" -msgstr "Il nodo XML descrivente l'insert manca del campo `type'" - -#: libs/ardour/redirect.cc:358 -msgid "XML node describing a redirect is missing the `placement' field" -msgstr "" - -#: libs/ardour/redirect.cc:467 -#, fuzzy -msgid "active_changed" -msgstr "livello cambiato" - -#: libs/ardour/region.cc:885 -msgid "Session: XMLNode describing a Region is incomplete (no id)" -msgstr "" - -#: libs/ardour/region.cc:892 -msgid "Session: XMLNode describing a Region is incomplete (no name)" -msgstr "" - -#: libs/ardour/route.cc:79 libs/ardour/session.cc:1554 -#: libs/ardour/session.cc:1560 libs/ardour/session.cc:3093 -msgid "signal" -msgstr "segnale" - -#: libs/ardour/route.cc:1430 -msgid "Could not get state of route. Problem with save_automation" -msgstr "" - -#: libs/ardour/route.cc:1482 -msgid "Send construction failed" -msgstr "" - -#: libs/ardour/route.cc:1504 -msgid "unknown Insert type \"%1\"; ignored" -msgstr "" - -#: libs/ardour/route.cc:1510 -msgid "Insert XML node has no type property" -msgstr "" - -#: libs/ardour/route.cc:1515 -msgid "insert could not be created. Ignored." -msgstr "" - -#: libs/ardour/route.cc:1533 -msgid "Bad node sent to Route::set_state() [%1]" -msgstr "" - -#: libs/ardour/route.cc:1592 -msgid "Route %1: unknown edit group \"%2 in saved state (ignored)" -msgstr "" - -#: libs/ardour/route.cc:1608 libs/ardour/route.cc:1612 -msgid "badly formed order key string in state file! [%1] ... ignored." -msgstr "" - -#: libs/ardour/route.cc:1693 libs/ardour/route.cc:1820 -msgid "[control]" -msgstr "" - -#: libs/ardour/route.cc:1713 -msgid "Route %1: unknown mix group \"%2 in saved state (ignored)" -msgstr "" - -#: libs/ardour/route.cc:1742 libs/ardour/route.cc:1750 -msgid "" -"MIDI mute control specification for %1 is incomplete, so it has been ignored" -msgstr "" - -#: libs/ardour/send.cc:99 -msgid "XML node describing a send is missing a Redirect node" -msgstr "" - -#: libs/ardour/session.cc:103 -#, fuzzy -msgid "Could not resolve path: %1 (%2)" -msgstr "impossibile controllare il percorso %1 (%2)" - -#: libs/ardour/session.cc:115 -msgid "cannot check session path %1 (%2)" -msgstr "impossibile controllare il percorso %1 (%2)" - -#: libs/ardour/session.cc:145 -msgid "cannot check statefile %1 (%2)" -msgstr "impossibile controllare il file di stato %1 (%2)" - -#: libs/ardour/session.cc:181 -msgid "%1 is not an Ardour snapshot file" -msgstr "%1 non è un file di istantanea di Ardour" - -#: libs/ardour/session.cc:198 -msgid "cannot determine current working directory (%1)" -msgstr "impossibile determinare la cartella di lavoro corrente (%1)" - -#: libs/ardour/session.cc:215 -msgid "unknown file type for session %1" -msgstr "tipo di fle sconosciuto per la sessione %1" - -#: libs/ardour/session.cc:320 -msgid "monitor" -msgstr "" - -#: libs/ardour/session.cc:327 -msgid "master" -msgstr "" - -#: libs/ardour/session.cc:611 -msgid "could not setup Click I/O" -msgstr "impossibile impostare entrata/uscita del click" - -#: libs/ardour/session.cc:632 -msgid "cannot setup Click I/O" -msgstr "impossibile impostare entrata/uscita del click" - -#: libs/ardour/session.cc:654 -msgid "cannot create Auditioner: no auditioning of regions possible" -msgstr "impossibile creare l'Auditioner" - -#: libs/ardour/session.cc:666 -#, c-format -msgid "out %<PRIu32>" -msgstr "" - -#: libs/ardour/session.cc:678 -#, c-format -msgid "in %<PRIu32>" -msgstr "" - -#: libs/ardour/session.cc:692 -#, c-format -msgid "out %<PRIu32>+%<PRIu32>" -msgstr "" - -#: libs/ardour/session.cc:706 -#, c-format -msgid "in %<PRIu32>+%<PRIu32>" -msgstr "" - -#: libs/ardour/session.cc:739 -#, fuzzy -msgid "cannot setup master inputs" -msgstr "IO: impossibile registrare la porta %1" - -#: libs/ardour/session.cc:747 -#, fuzzy -msgid "cannot setup master outputs" -msgstr "IO: impossibile registrare la porta %1" - -#: libs/ardour/session.cc:758 -msgid "Master Out" -msgstr "" - -#: libs/ardour/session.cc:830 -#, fuzzy -msgid "cannot setup control inputs" -msgstr "impossibile impostare entrata/uscita del click" - -#: libs/ardour/session.cc:838 -#, fuzzy -msgid "cannot set up master outputs" -msgstr "IO: impossibile registrare la porta %1" - -#: libs/ardour/session.cc:1110 -msgid "Session: you can't use that location for auto punch (start <= end)" -msgstr "" -"Sessione: non si può usare quella location per l'auto punch (inizio <= fine)" - -#: libs/ardour/session.cc:1189 -msgid "Session: you can't use a mark for auto loop" -msgstr "Sessione: non si può usare un marcatore per l'auto loop" - -#: libs/ardour/session.cc:1572 -msgid "feedback loop setup between %1 and %2" -msgstr "" - -#: libs/ardour/session.cc:1724 libs/ardour/session.cc:1821 -msgid "cannot configure %1 in/%2 out configuration for new audio track" -msgstr "" - -#: libs/ardour/session.cc:1780 -msgid "Session: could not create new audio track." -msgstr "Sessione: impossibile creare una nuova traccia audio" - -#: libs/ardour/session.cc:1870 -msgid "Session: could not create new route." -msgstr "Sessione: impossibile creare un nuovo route" - -#: libs/ardour/session.cc:2354 -msgid "cannot create new name for region \"%1\"" -msgstr "impossibile creare un nuovo nome per la regione \"%1\"" - -#: libs/ardour/session.cc:2418 -msgid "too many regions with names like %1" -msgstr "troppe regioni con nomi come %1" - -#: libs/ardour/session.cc:2883 -msgid "There are already %1 recordings for %2, which I consider too many." -msgstr "Ci sono già %1 registrazioni per %2, che io considero troppe" - -#: libs/ardour/session.cc:3258 -msgid "programming error: unknown type of Insert created!" -msgstr "" - -#: libs/ardour/session.cc:3264 -msgid "programming error: unknown type of Redirect created!" -msgstr "" - -#: libs/ardour/session.cc:3287 -msgid "programming error: unknown type of Insert deleted!" -msgstr "" - -#: libs/ardour/session.cc:3293 -msgid "programming error: unknown type of Redirect deleted!" -msgstr "" - -#: libs/ardour/session.cc:3636 -msgid "too many bounced versions of playlist \"%1\"" -msgstr "" - -#: libs/ardour/session.cc:3649 -msgid "cannot create new audio file \"%1\" for %2" -msgstr "impossibile creare un nuovo file audio \"%1\" per %2" - -#: libs/ardour/session_butler.cc:85 libs/ardour/session_butler.cc:90 -msgid "UI: cannot set O_NONBLOCK on butler request pipe (%1)" -msgstr "" - -#: libs/ardour/session_butler.cc:95 -msgid "Session: could not create butler thread" -msgstr "" - -#: libs/ardour/session_butler.cc:189 -msgid "poll on butler request pipe failed (%1)" -msgstr "" - -#: libs/ardour/session_butler.cc:196 -msgid "Error on butler thread request pipe" -msgstr "" - -#: libs/ardour/session_butler.cc:238 -#, fuzzy -msgid "Error reading from butler request pipe" -msgstr "Errore nel leggere dalla porta MIDI %1" - -#: libs/ardour/session_butler.cc:275 -msgid "Butler read ahead failure on dstream %1" -msgstr "" - -#: libs/ardour/session_butler.cc:319 -msgid "Butler write-behind failure on dstream %1" -msgstr "" - -#: libs/ardour/session_click.cc:158 -msgid "cannot open click soundfile %1 (%2)" -msgstr "impossibile accedere al file audio per il click %1 (%2)" - -#: libs/ardour/session_click.cc:167 -msgid "cannot read data from click soundfile" -msgstr "impossibile leggere dati dal file audio per il click" - -#: libs/ardour/session_click.cc:192 -msgid "cannot open click emphasis soundfile %1 (%2)" -msgstr "impossibile accedere al file audio di enfasi per il click %1 (%2)" - -#: libs/ardour/session_click.cc:200 -msgid "cannot read data from click emphasis soundfile" -msgstr "impossibile leggere dati dal file audio di enfasi per il click" - -#: libs/ardour/session_events.cc:161 -msgid "Session: cannot have two events of type %1 at the same frame (%2)." -msgstr "" - -#: libs/ardour/session_events.cc:422 -msgid "Programming error: illegal event type in process_event (%1)" -msgstr "" - -#: libs/ardour/session_export.cc:63 -msgid "Export: no output file specified" -msgstr "Esportazione: nessun file di output scpecificato" - -#: libs/ardour/session_export.cc:164 libs/ardour/session_export.cc:169 -msgid "illegal frame range in export specification" -msgstr "" - -#: libs/ardour/session_export.cc:174 -msgid "Bad data width size. Report me!" -msgstr "" - -#: libs/ardour/session_export.cc:204 -msgid "Export: cannot open output file \"%1\" (%2)" -msgstr "Esportazione: impossibile accedere al fil di output \"%1\" (%2)" - -#: libs/ardour/session_export.cc:214 -msgid "cannot initialize sample rate conversion: %1" -msgstr "impossibile avviare la conversione di campionatura: %1" - -#: libs/ardour/session_export.cc:316 -msgid "an error occured during sample rate conversion: %1" -msgstr "c'è stato un errore durante la conversione di campionatura: %1" - -#: libs/ardour/session_export.cc:327 -msgid "warning, leftover frames overflowed, glitches might occur in output" -msgstr "" - -#: libs/ardour/session_export.cc:418 -msgid "Export: could not write data to output file (%1)" -msgstr "Esportazione: impossibile scrivere dati sul file di output (%1)" - -#: libs/ardour/session_export.cc:500 -msgid "%1: cannot seek to %2 for export" -msgstr "" - -#: libs/ardour/session_midi.cc:200 -msgid "Ardour is slaved to MTC - port cannot be reset" -msgstr "" - -#: libs/ardour/session_midi.cc:215 -msgid "unknown port %1 requested for MTC" -msgstr "" - -#: libs/ardour/session_midi.cc:541 -msgid "Error reading from MIDI port %1" -msgstr "Errore nel leggere dalla porta MIDI %1" - -#: libs/ardour/session_midi.cc:914 -msgid "Session: could not send full MIDI time code" -msgstr "" - -#: libs/ardour/session_midi.cc:973 -msgid "Session: cannot send quarter-frame MTC message (%1)" -msgstr "" - -#: libs/ardour/session_midi.cc:1081 -msgid "MMC: cannot send command %1%2%3" -msgstr "" - -#: libs/ardour/session_midi.cc:1188 -msgid "UI: cannot set O_NONBLOCK on signal read pipe (%1)" -msgstr "" - -#: libs/ardour/session_midi.cc:1193 -msgid "UI: cannot set O_NONBLOCK on signal write pipe (%1)" -msgstr "" - -#: libs/ardour/session_midi.cc:1198 -msgid "Session: could not create transport thread" -msgstr "" - -#: libs/ardour/session_midi.cc:1227 -msgid "cannot send signal to midi thread! (%1)" -msgstr "" - -#: libs/ardour/session_midi.cc:1322 -msgid "MIDI thread poll failed (%1)" -msgstr "" - -#: libs/ardour/session_midi.cc:1334 -msgid "Error on transport thread request pipe" -msgstr "" - -#: libs/ardour/session_midi.cc:1361 -msgid "Error reading from transport request pipe" -msgstr "" - -#: libs/ardour/session_process.cc:104 -msgid "Session: error in no roll for %1" -msgstr "" - -#: libs/ardour/session_state.cc:101 -#, fuzzy -msgid "Could not use path %1 (%s)" -msgstr "impossibile controllare il percorso %1 (%2)" - -#: libs/ardour/session_state.cc:129 -msgid "end" -msgstr "" - -#: libs/ardour/session_state.cc:130 -#, fuzzy -msgid "start" -msgstr "separa" - -#: libs/ardour/session_state.cc:502 -msgid "Session: cannot create session dir \"%1\" (%2)" -msgstr "Sessione: impossibile creare la cartella per la sessione \"%1\" (%2)" - -#: libs/ardour/session_state.cc:513 -#, fuzzy -msgid "Session: cannot create session peakfile dir \"%1\" (%2)" -msgstr "Sessione: impossibile creare la cartella per la sessione \"%1\" (%2)" - -#: libs/ardour/session_state.cc:522 -msgid "Session: cannot create session sounds dir \"%1\" (%2)" -msgstr "" -"Sessione: impossibile creare la cartella sounds per la sessione \"%1\" (%2)" - -#: libs/ardour/session_state.cc:531 -#, fuzzy -msgid "Session: cannot create session tape dir \"%1\" (%2)" -msgstr "Sessione: impossibile creare la cartella per la sessione \"%1\" (%2)" - -#: libs/ardour/session_state.cc:540 -#, fuzzy -msgid "Session: cannot create session dead sounds dir \"%1\" (%2)" -msgstr "" -"Sessione: impossibile creare la cartella sounds per la sessione \"%1\" (%2)" - -#: libs/ardour/session_state.cc:549 -msgid "Session: cannot create session automation dir \"%1\" (%2)" -msgstr "" -"Sessione: impossibile creare la cartella automation per la sessione \"%1\" (%" -"2)" - -#: libs/ardour/session_state.cc:580 -#, fuzzy -msgid "Could not open %1 for writing mix template" -msgstr "Impossibile accedere a %1 per scrivere il modello di mixaggio" - -#: libs/ardour/session_state.cc:586 -#, fuzzy -msgid "Could not open mix template %1 for reading" -msgstr "Impossibile aprire il modello di mixaggio %1 per leggere" - -#: libs/ardour/session_state.cc:593 -msgid "Session already exists. Not overwriting" -msgstr "La sessione esiste già. Non sovrascrivo" - -#: libs/ardour/session_state.cc:636 -msgid "Session: could not load diskstream via XML state" -msgstr "" - -#: libs/ardour/session_state.cc:685 -msgid "could not backup old state file, current state not saved." -msgstr "" -"impossibile fare copia di sicurezza del file di stato, stato attuale non " -"salvato" - -#: libs/ardour/session_state.cc:698 -#, fuzzy -msgid "state could not be saved to %1" -msgstr "stato non salvato" - -#: libs/ardour/session_state.cc:705 -#, fuzzy -msgid "could not remove corrupt state file %1" -msgstr "IO: impossibile registrare la porta %1" - -#: libs/ardour/session_state.cc:709 -#, fuzzy -msgid "could not restore state file from backup %1" -msgstr "Esportazione: impossibile scrivere dati sul file di output (%1)" - -#: libs/ardour/session_state.cc:778 -msgid "%1: session state information file \"%2\" doesn't exist!" -msgstr "" -"%1: il file di informazioni sullo stato della sessione \"%2\" non esiste!" - -#: libs/ardour/session_state.cc:789 -#, fuzzy -msgid "Could not understand ardour file %1" -msgstr "IO: impossibile registrare la porta %1" - -#: libs/ardour/session_state.cc:1493 -msgid "programming error: Session: incorrect XML node sent to set_state()" -msgstr "" - -#: libs/ardour/session_state.cc:1539 -msgid "Session: XML state has no options section" -msgstr "Sessione: il file di stato XML non ha alcuna sezione option" - -#: libs/ardour/session_state.cc:1544 -msgid "Session: XML state has no sources section" -msgstr "Sessione: il file di stato XML non ha alcuna sezione sources" - -#: libs/ardour/session_state.cc:1551 -msgid "Session: XML state has no Regions section" -msgstr "Sessione: il file di stato XML non ha alcuna sezione Regions" - -#: libs/ardour/session_state.cc:1558 -msgid "Session: XML state has no playlists section" -msgstr "Sessione: il file di stato XML non ha alcuna sezione playlist" - -#: libs/ardour/session_state.cc:1577 -msgid "Session: XML state has no diskstreams section" -msgstr "Sessione: il file di stato XML non ha alcuna sezione diskstream" - -#: libs/ardour/session_state.cc:1584 -msgid "Session: XML state has no connections section" -msgstr "Sessione: il file di stato XML non ha alcuna sezione connections" - -#: libs/ardour/session_state.cc:1591 -msgid "Session: XML state has no locations section" -msgstr "Sessione: il file di stato XML non ha alcuna sezione locations" - -#: libs/ardour/session_state.cc:1624 -msgid "Session: XML state has no edit groups section" -msgstr "Sessione: il file di stato XML non ha alcuna sezione edit groups" - -#: libs/ardour/session_state.cc:1631 -msgid "Session: XML state has no mix groups section" -msgstr "Sessione: il file di stato XML non ha alcuna sezione mix groups" - -#: libs/ardour/session_state.cc:1638 -msgid "Session: XML state has no Tempo Map section" -msgstr "Sessione: il file di stato XML non ha alcuna sezione Tempo Map" - -#: libs/ardour/session_state.cc:1645 -msgid "Session: XML state has no routes section" -msgstr "Sessione: il file di stato XML non ha alcuna sezione routes" - -#: libs/ardour/session_state.cc:1652 -#, fuzzy -msgid "Session: XML state has no click section" -msgstr "Sessione: il file di stato XML non ha alcuna sezione click" - -#: libs/ardour/session_state.cc:1697 -msgid "Session: cannot create Route from XML description." -msgstr "Sessione: impossibile creare Route dalla descrizione XML" - -#: libs/ardour/session_state.cc:1735 -msgid "Session: cannot create Region from XML description." -msgstr "Sessione: impossibile creare regione dalla descrizione XML" - -#: libs/ardour/session_state.cc:1764 -#, fuzzy -msgid "Session: XMLNode describing a AudioRegion is incomplete (no source)" -msgstr "" -"Sessione: il nodo XML descrivente una Regione è incompleto (nessun source)" - -#: libs/ardour/session_state.cc:1772 libs/ardour/session_state.cc:1792 -#, fuzzy -msgid "" -"Session: XMLNode describing a AudioRegion references an unknown source id =%1" -msgstr "" -"Sessione: il nodo XML descrivente una Regione fa riferimento ad un source " -"con id sconosciuto =%1" - -#: libs/ardour/session_state.cc:1778 libs/ardour/session_state.cc:1798 -#, fuzzy -msgid "" -"Session: XMLNode describing a AudioRegion references a non-audio source id =%" -"1" -msgstr "" -"Sessione: il nodo XML descrivente una Regione fa riferimento ad un source " -"con id sconosciuto =%1" - -#: libs/ardour/session_state.cc:1868 -msgid "Session: cannot create Source from XML description." -msgstr "Sessione: impossibile creare Source dalla descrizione XML" - -#: libs/ardour/session_state.cc:1889 -#, fuzzy -msgid "" -"Found a sound file that cannot be used by Ardour. Talk to the progammers." -msgstr "E' stato trovato un file audio che non può essere usato da Ardour." - -#: libs/ardour/session_state.cc:1913 -msgid "Could not create mix templates directory \"%1\" (%2)" -msgstr "Impossibile creare la cartella per i modelli di mixaggio \"%1\" (%2)" - -#: libs/ardour/session_state.cc:1927 -msgid "Template \"%1\" already exists - new version not created" -msgstr "Il modello \"%1\" esiste già - non è stata creata una nuova versione" - -#: libs/ardour/session_state.cc:1934 -msgid "mix template not saved" -msgstr "modello di mixaggio non salvato" - -#: libs/ardour/session_state.cc:1994 -msgid "cannot create session directory \"%1\"; ignored" -msgstr "impossibile creare la cartella per la sessione %1; ignorato" - -#: libs/ardour/session_state.cc:2007 -msgid "cannot create sounds directory \"%1\"; ignored" -msgstr "impossibile creare la cartella sounds \"%1\"; ignorato" - -#: libs/ardour/session_state.cc:2018 -#, fuzzy -msgid "cannot create dead sounds directory \"%1\"; ignored" -msgstr "impossibile creare la cartella sounds \"%1\"; ignorato" - -#: libs/ardour/session_state.cc:2029 -#, fuzzy -msgid "cannot create peak file directory \"%1\"; ignored" -msgstr "impossibile creare la cartella per la sessione %1; ignorato" - -#: libs/ardour/session_state.cc:2168 libs/ardour/session_state.cc:2189 -msgid "Session: cannot create Playlist from XML description." -msgstr "Sessione: impossibile creare Playlist dalla descrizione XML" - -#: libs/ardour/session_state.cc:2228 -msgid "Session: cannot create Named Selection from XML description." -msgstr "Sessione: impossibile creare Named Selection dalla descizione XML" - -#: libs/ardour/session_state.cc:2360 -msgid "Unknown node \"%1\" found in Connections list from state file" -msgstr "Nodo sconosciuto \"%1\" trovato in Connections list dal file di stato" - -#: libs/ardour/session_state.cc:3197 -#, fuzzy -msgid "cannot remove dead sound file %1 (%2)" -msgstr "impossibile accedere al file audio per il click %1 (%2)" - -#: libs/ardour/session_time.cc:374 -msgid "Unknown JACK transport state %1 in sync callback" -msgstr "" - -#: libs/ardour/session_timefx.cc:77 -msgid "tempoize: error creating name for new audio file based on %1" -msgstr "" -"tempoize: errore nel creare il nome per il nuovo file audio basato su %1" - -#: libs/ardour/session_timefx.cc:88 -msgid "tempoize: error creating new audio file %1 (%2)" -msgstr "tempoize: errore nel creare un nuovo file audio %1 (%2)" - -#: libs/ardour/session_timefx.cc:114 -msgid "tempoize: error reading data from %1" -msgstr "tempoize: errore nel leggere dati da %1" - -#: libs/ardour/session_timefx.cc:127 libs/ardour/session_timefx.cc:139 -msgid "error writing tempo-adjusted data to %1" -msgstr "" - -#: libs/ardour/session_timefx.cc:145 -msgid "timefx code failure. please notify ardour-developers." -msgstr "" - -#: libs/ardour/session_transport.cc:117 -msgid "Cannot loop - no loop range defined" -msgstr "" - -#: libs/ardour/session_transport.cc:479 -msgid "" -"Seamless looping cannot be supported while Ardour is using JACK transport.\n" -"Recommend changing the configured options" -msgstr "" - -#: libs/ardour/session_transport.cc:755 -msgid "" -"Global varispeed cannot be supported while Ardour is connected to JACK " -"transport control" -msgstr "" - -#: libs/ardour/session_transport.cc:955 -msgid "please stop the transport before adjusting slave settings" -msgstr "" - -#: libs/ardour/session_transport.cc:991 -msgid "No MTC port defined: MTC slaving is impossible." -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:15 -msgid "WAV" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:16 -msgid "AIFF" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:17 -msgid "raw (no header)" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:18 -msgid "PAF (Ensoniq Paris)" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:19 -msgid "AU (Sun/NeXT)" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:20 -msgid "IRCAM" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:21 -msgid "W64 (64 bit WAV)" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:26 -msgid ".wav" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:27 -msgid ".aiff" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:28 -msgid ".raw" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:29 -msgid ".paf" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:30 -msgid ".au" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:31 -msgid ".ircam" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:32 -msgid ".w64" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:47 -msgid "16 bit" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:48 -msgid "24 bit" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:49 -msgid "32 bit" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:50 -msgid "8 bit" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:51 -msgid "float" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:64 -msgid "Little-endian (Intel)" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:65 -msgid "Big-endian (Mac)" -msgstr "" - -#: libs/ardour/sndfilesource.cc:147 -msgid "FileSource: cannot get host information for BWF header (%1)" -msgstr "FileSource: impossibile ottenere info sull'host dall'header BWF (%1)" - -#: libs/ardour/sndfilesource.cc:169 -msgid "" -"cannot set broadcast info for audio file %1 (%2); dropping broadcast info " -"for this file" -msgstr "" - -#: libs/ardour/sndfilesource.cc:220 -#, fuzzy -msgid "SndFileSource: cannot open file \"%1\" for %2 (%3)" -msgstr "SndFileSource: impossibile accedere al file \"%1\" (%2)" - -#: libs/ardour/sndfilesource.cc:226 -msgid "" -"SndFileSource: file only contains %1 channels; %2 is invalid as a channel " -"number" -msgstr "" -"SndFileSource: il file contiene solo %1 canali; %2 non è valido come numero " -"di canale" - -#: libs/ardour/sndfilesource.cc:327 -msgid "SndFileSource: could not seek to frame %1 within %2 (%3)" -msgstr "" - -#: libs/ardour/sndfilesource.cc:378 -#, fuzzy -msgid "programming error: %1 %2" -msgstr "errore di programmazione: %1" - -#: libs/ardour/sndfilesource.cc:487 libs/ardour/sndfilesource.cc:533 -msgid "" -"cannot set broadcast info for audio file %1; Dropping broadcast info for " -"this file" -msgstr "" - -#: libs/ardour/sndfilesource.cc:544 -msgid "%1: cannot seek to %2" -msgstr "" - -#: libs/ardour/state_manager.cc:47 -#, fuzzy -msgid "cleared history" -msgstr "pulito" - -#: libs/ardour/state_manager.cc:60 -msgid "" -"programming error: illegal state ID (%1) passed to StateManager::set_state() " -"(range = 0-%2)" -msgstr "" - -#: libs/ardour/stateful.cc:102 -#, fuzzy -msgid "Error: could not write %1" -msgstr "Esportazione: impossibile scrivere dati sul file di output (%1)" - -#: libs/ardour/stateful.cc:116 -msgid "Could not understand XML file %1" -msgstr "" - -#: libs/ardour/tempo.cc:67 -msgid "TempoSection XML node has no \"start\" property" -msgstr "" - -#: libs/ardour/tempo.cc:75 -msgid "TempoSection XML node has an illegal \"start\" value" -msgstr "" - -#: libs/ardour/tempo.cc:82 -msgid "TempoSection XML node has no \"beats-per-minute\" property" -msgstr "" - -#: libs/ardour/tempo.cc:87 -msgid "TempoSection XML node has an illegal \"beats_per_minute\" value" -msgstr "" - -#: libs/ardour/tempo.cc:92 -msgid "TempoSection XML node has no \"movable\" property" -msgstr "" - -#: libs/ardour/tempo.cc:131 -msgid "MeterSection XML node has no \"start\" property" -msgstr "" - -#: libs/ardour/tempo.cc:139 -msgid "MeterSection XML node has an illegal \"start\" value" -msgstr "" - -#: libs/ardour/tempo.cc:146 -msgid "MeterSection XML node has no \"beats-per-bar\" property" -msgstr "" - -#: libs/ardour/tempo.cc:151 -msgid "MeterSection XML node has an illegal \"beats-per-bar\" value" -msgstr "" - -#: libs/ardour/tempo.cc:156 -msgid "MeterSection XML node has no \"note-type\" property" -msgstr "" - -#: libs/ardour/tempo.cc:161 -msgid "MeterSection XML node has an illegal \"note-type\" value" -msgstr "" - -#: libs/ardour/tempo.cc:166 -msgid "MeterSection XML node has no \"movable\" property" -msgstr "" - -#: libs/ardour/tempo.cc:259 -msgid "move metric" -msgstr "" - -#: libs/ardour/tempo.cc:330 -msgid "metric removed" -msgstr "" - -#: libs/ardour/tempo.cc:373 -#, fuzzy -msgid "add tempo" -msgstr "aggiungi regione" - -#: libs/ardour/tempo.cc:402 -#, fuzzy -msgid "replace tempo" -msgstr "sostituisci la regione" - -#: libs/ardour/tempo.cc:435 -msgid "add meter" -msgstr "" - -#: libs/ardour/tempo.cc:463 -#, fuzzy -msgid "replaced meter" -msgstr "sostituisci la regione" - -#: libs/ardour/tempo.cc:483 libs/ardour/tempo.cc:499 -msgid "programming error: no tempo section in tempo map!" -msgstr "" - -#: libs/ardour/tempo.cc:538 -msgid "programming error: unhandled MetricSection type" -msgstr "" - -#: libs/ardour/tempo.cc:1226 libs/ardour/tempo.cc:1238 -msgid "Tempo map: could not set new state, restoring old one." -msgstr "" - -#: libs/ardour/tempo.cc:1262 -msgid "load XML data" -msgstr "" - -#: libs/ardour/utils.cc:246 -#, fuzzy -msgid "illegal or badly-formed string used for path (%1)" -msgstr "il percorso indicato per il RAID è non valido o malformato" - -#: libs/ardour/utils.cc:251 -#, fuzzy -msgid "path (%1) is ambiguous" -msgstr "il percorso indicato per la ricerca RAID è ambiguo" - -#: libs/ardour/vst_plugin.cc:187 -#, fuzzy -msgid "cannot create VST chunk directory: %1" -msgstr "impossibile creare la cartella sounds \"%1\"; ignorato" - -#: libs/ardour/vst_plugin.cc:195 -#, fuzzy -msgid "cannot check VST chunk directory: %1" -msgstr "impossibile determinare la cartella di lavoro corrente (%1)" - -#: libs/ardour/vst_plugin.cc:202 -msgid "%1 exists but is not a directory" -msgstr "" - -#: libs/ardour/vst_plugin.cc:240 -msgid "Bad node sent to VSTPlugin::set_state" -msgstr "" - -#: libs/ardour/vst_plugin.cc:343 libs/ardour/vst_plugin.cc:354 -msgid "no support for presets using chunks at this time" -msgstr "" - -#: libs/ardour/coreaudiosource.cc:97 -#, fuzzy -msgid "" -"CoreAudioSource: file only contains %1 channels; %2 is invalid as a channel " -"number" -msgstr "" -"SndFileSource: il file contiene solo %1 canali; %2 non è valido come numero " -"di canale" - -#: libs/ardour/coreaudiosource.cc:162 -msgid "CoreAudioSource: could not seek to frame %1 within %2 (%3)" -msgstr "" - -#~ msgid "FileSource: \"%1\" not found when searching %2 using %3" -#~ msgstr "FileSource: \"%1\" non trovato nel cercare %2 utilizzando %3" - -#~ msgid "FileSource: could not open \"%1\": (%2)" -#~ msgstr "FileSource: impossibile aprire \"%1\": (%2)" - -#~ msgid "FileSource: cannot write header in %1" -#~ msgstr "FileSource: impossibile scrivere header in %1" - -#~ msgid "FileSource: cannot locate chunks in %1" -#~ msgstr "FileSource: impossibile trovare spezzoni in %1" - -#~ msgid "FileSource: cannot read header in %1" -#~ msgstr "FileSource: impossibile leggere header in %1" - -#~ msgid "FileSource: cannot check header in %1" -#~ msgstr "FileSource: impossibile controllare header in %1" - -#, fuzzy -#~ msgid "FileSource: cannot initialize peakfile for %1 as %2" -#~ msgstr "FileSource: impossibile avviare il peakfile per %1" - -#~ msgid "FileSource: cannot seek to end of file" -#~ msgstr "FileSource: impossibile cercare fino alla fine del file" - -#~ msgid "FileSource: cannot read RIFF/WAVE chunk from file" -#~ msgstr "FileSource: impossibile accedere allo spezzone RIFF/WAVE dal file" - -#~ msgid "FileSource %1: not a RIFF/WAVE file" -#~ msgstr "FileSource %1: il file non un file RIFF/WAVE" - -#~ msgid "FileSource: can't read a chunk" -#~ msgstr "FileSource: impossibile accedere ad uno spezzone" - -#~ msgid "FileSource: cannot get user information for BWF header (%1)" -#~ msgstr "FileSource: impossibile otterene info utente dall'header BWF (%1)" - -#~ msgid "FileSource[%1]: cannot update data size: %2" -#~ msgstr "FileSource[%1]: impossibile aggiornare la dimensione dei dati: %2" - -#~ msgid "FileSource: can't find RIFF chunk info" -#~ msgstr "FileSource: impossibile trovare info sullo spezzone RIFF" - -#, fuzzy -#~ msgid "FileSource: can't find RIFX chunk info" -#~ msgstr "FileSource: impossibile trovare info sullo spezzone RIFF" - -#~ msgid "FileSource: can't read RIFF chunk" -#~ msgstr "FileSource: impossibile accedere allo spezzone RIFF" - -#~ msgid "FileSource: can't find format chunk info" -#~ msgstr "FileSource: impossibile trovare info sul formato dello spezzone" - -#~ msgid "FileSource: can't read format chunk" -#~ msgstr "FileSource: impossibile leggere il formato dello spezzone" - -#~ msgid "FileSource: can't find data chunk info" -#~ msgstr "FileSource: impossibile trovare info sui dati dello spezzone" - -#~ msgid "FileSource: can't read data chunk" -#~ msgstr "FileSource: impossibile leggere dati dello spezzone" - -#~ msgid "" -#~ "FileSource: cannot read Broadcast Wave data from existing audio file \"%1" -#~ "\" (%2)" -#~ msgstr "" -#~ "FileSource: impossibile leggere dati Broadcast Wave dal file audio " -#~ "esistente \"%1\" (%2) " - -#~ msgid "" -#~ "FileSource: cannot read Broadcast Wave coding history from audio file \"%1" -#~ "\" (%2)" -#~ msgstr "" -#~ "FileSource: impossibile leggere lo storico del Broadcast Wave dal file " -#~ "audio \"%1\" (%2)" - -#, fuzzy -#~ msgid "" -#~ "FileSource \"%1\" does not use valid sample format.\n" -#~ "This is probably a programming error." -#~ msgstr "" -#~ "FileSource \"%1\" non usa il formato floating point.\n" -#~ "Questo probabilmente un errore di programmazione." - -#~ msgid "FileSource \"%1\" has no \"data\" chunk" -#~ msgstr "FileSource \"%1\" non ha uno spezzone di \"dati\"" - -#~ msgid "" -#~ "%1: data length in header (%2) differs from implicit size in file (%3)" -#~ msgstr "" -#~ "%1: la lunghezza dei dati nell'header (%2) diversa dalla dimensione " -#~ "implicita nel file (%3)" - -#~ msgid "\"%1\" has a sample rate of %2 instead of %3 as used by this session" -#~ msgstr "" -#~ "\"%1\" ha una sample rate di %2 anzicch di %3 come il resto della sessione" - -#~ msgid "FileSource: cannot write WAVE chunk: %1" -#~ msgstr "FileSource: impossibile scrivere lo spezzone WAVE: %1" - -#~ msgid "FileSource: cannot write format chunk: %1" -#~ msgstr "FileSource: impossibile scrivere il formato dello spezzone: %1" - -#, fuzzy -#~ msgid "cannot create feedback request pipe (%1)" -#~ msgstr "Errore nel leggere dalla porta MIDI %1" - -#, fuzzy -#~ msgid "Error on feedback thread request pipe" -#~ msgstr "Errore nel leggere dalla porta MIDI %1" - -#, fuzzy -#~ msgid "Error reading from feedback request pipe" -#~ msgstr "Errore nel leggere dalla porta MIDI %1" - -#~ msgid "could not create crossfade object in playlist %1" -#~ msgstr "impossibile creare smorzamento incrociato nella playlist %1" - -#, fuzzy -#~ msgid "Could not find a template called %1 in %2" -#~ msgstr "Impossibile aprire il modello di mixaggio %1 per leggere" diff --git a/libs/ardour/po/pl_PL.po b/libs/ardour/po/pl_PL.po deleted file mode 100644 index 3a39989f02..0000000000 --- a/libs/ardour/po/pl_PL.po +++ /dev/null @@ -1,2063 +0,0 @@ -# translation of libardour2.po to Polish -# Copyright (C) YEAR "Paul Davis" -# This file is distributed under the same license as the PACKAGE package. -# -# Piotr Zaryk <pzaryk@gmail.com>, 2008. -msgid "" -msgstr "" -"Project-Id-Version: libardour2\n" -"Report-Msgid-Bugs-To: Piotr Zaryk <pzaryk@gmail.com>\n" -"POT-Creation-Date: 2008-04-03 16:16+0200\n" -"PO-Revision-Date: 2008-04-10 10:51+0100\n" -"Last-Translator: Piotr Zaryk <pzaryk@gmail.com>\n" -"Language-Team: Polish <pl@li.org>\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#: libs/ardour/audioanalyser.cc:26 -msgid "cannot load VAMP plugin \"%1\"" -msgstr "" - -#: libs/ardour/audioanalyser.cc:46 -msgid "VAMP Plugin \"%1\" could not be loaded" -msgstr "" - -#: libs/ardour/audio_diskstream.cc:249 -msgid "AudioDiskstream: Playlist \"%1\" isn't an audio playlist" -msgstr "" - -#: libs/ardour/audio_diskstream.cc:302 -msgid "AudioDiskstream %1: there is no existing playlist to make a copy of!" -msgstr "" - -#: libs/ardour/audio_diskstream.cc:937 -#: libs/ardour/audio_diskstream.cc:948 -msgid "AudioDiskstream %1: when refilling, cannot read %2 from playlist at frame %3" -msgstr "" - -#: libs/ardour/audio_diskstream.cc:1096 -msgid "AudioDiskstream %1: cannot read %2 from playlist at frame %3" -msgstr "" - -#: libs/ardour/audio_diskstream.cc:1138 -msgid "AudioDiskstream %1: cannot read xfade samples %2 from playlist at frame %3" -msgstr "" - -#: libs/ardour/audio_diskstream.cc:1491 -#: libs/ardour/audio_diskstream.cc:1508 -msgid "AudioDiskstream %1: cannot write to disk" -msgstr "" - -#: libs/ardour/audio_diskstream.cc:1553 -msgid "AudioDiskstream \"%1\": cannot flush captured data to disk!" -msgstr "" - -#: libs/ardour/audio_diskstream.cc:1641 -msgid "%1: could not create region for complete audio file" -msgstr "" - -#: libs/ardour/audio_diskstream.cc:1666 -msgid "AudioDiskstream: could not create region for captured audio!" -msgstr "" - -#: libs/ardour/audio_diskstream.cc:1774 -msgid "programmer error: %1" -msgstr "bÅ‚Ä…d programisty: %1" - -#: libs/ardour/audio_diskstream.cc:2051 -msgid "AudioDiskstream: channel %1 out of range" -msgstr "" - -#: libs/ardour/audio_diskstream.cc:2070 -msgid "%1:%2 new capture file not initialized correctly" -msgstr "" - -#: libs/ardour/audio_diskstream.cc:2322 -msgid "%1: cannot restore pending capture source file %2" -msgstr "" - -#: libs/ardour/audio_diskstream.cc:2344 -msgid "%1: incorrect number of pending sources listed - ignoring them all" -msgstr "" - -#: libs/ardour/audio_diskstream.cc:2359 -msgid "%1: cannot create whole-file region from pending capture sources" -msgstr "" - -#: libs/ardour/audio_diskstream.cc:2371 -msgid "%1: cannot create region from pending capture sources" -msgstr "" - -#: libs/ardour/audioengine.cc:114 -msgid "Connect session to engine" -msgstr "" - -#: libs/ardour/audioengine.cc:498 -msgid "a port with this name already exists: check for duplicated track/bus names" -msgstr "" - -#: libs/ardour/audioengine.cc:500 -msgid "unknown error" -msgstr "" - -#: libs/ardour/audioengine.cc:503 -msgid "AudioEngine: cannot register port \"%1\": %2" -msgstr "" - -#: libs/ardour/audioengine.cc:511 -msgid "register input port called before engine was started" -msgstr "" - -#: libs/ardour/audioengine.cc:545 -msgid "register output port called before engine was started" -msgstr "" - -#: libs/ardour/audioengine.cc:625 -msgid "connect called before engine was started" -msgstr "" - -#: libs/ardour/audioengine.cc:641 -msgid "AudioEngine: connection already exists: %1 (%2) to %3 (%4)" -msgstr "" - -#: libs/ardour/audioengine.cc:645 -msgid "AudioEngine: cannot connect %1 (%2) to %3 (%4)" -msgstr "" - -#: libs/ardour/audioengine.cc:658 -#: libs/ardour/audioengine.cc:687 -msgid "disconnect called before engine was started" -msgstr "" - -#: libs/ardour/audioengine.cc:745 -msgid "get_port_by_name() called before engine was started" -msgstr "" - -#: libs/ardour/audioengine.cc:789 -msgid "get_ports called before engine was started" -msgstr "" - -#: libs/ardour/audioengine.cc:911 -msgid "get_nth_physical called before engine was started" -msgstr "" - -#: libs/ardour/audioengine.cc:939 -msgid "get_port_total_latency() called with no JACK client connection" -msgstr "" - -#: libs/ardour/audioengine.cc:945 -msgid "get_port_total_latency() called before engine was started" -msgstr "" - -#: libs/ardour/audioengine.cc:1134 -msgid "failed to connect to JACK" -msgstr "nie udaÅ‚o siÄ™ poÅ‚Ä…czyć z JACK" - -#: libs/ardour/audioengine.cc:1152 -msgid "could not reregister %1" -msgstr "nie można byÅ‚o zarejestrować %1" - -#: libs/ardour/audioengine.cc:1211 -msgid "could not reconnect %1 and %2 (err = %3)" -msgstr "nie można byÅ‚o poÅ‚Ä…czyć ponownie %1 i %2 (bÅ‚Ä…d = %3)" - -#: libs/ardour/audiofilesource.cc:408 -#: libs/ardour/session_state.cc:2881 -msgid "there are already 1000 files with names like %1; versioning discontinued" -msgstr "" - -#: libs/ardour/audiofilesource.cc:422 -#: libs/ardour/session_state.cc:2895 -msgid "cannot rename audio file source from %1 to %2 (%3)" -msgstr "" - -#: libs/ardour/audiofilesource.cc:429 -#: libs/ardour/session_state.cc:2909 -msgid "cannot remove peakfile %1 for %2 (%3)" -msgstr "" - -#: libs/ardour/audiofilesource.cc:465 -msgid "FileSource: search path not set" -msgstr "" - -#: libs/ardour/audiofilesource.cc:537 -msgid "" -"FileSource: \"%1\" is ambigous when searching %2\n" -"\t" -msgstr "" - -#: libs/ardour/audiofilesource.cc:543 -msgid "Filesource: cannot find required file (%1): while searching %2" -msgstr "" - -#: libs/ardour/audiofilesource.cc:583 -msgid "Filesource: cannot find required file (%1): %2" -msgstr "" - -#: libs/ardour/audiofilesource.cc:588 -msgid "Filesource: cannot check for existing file (%1): %2" -msgstr "" - -#: libs/ardour/audiofilesource.cc:651 -#: libs/ardour/audiosource.cc:876 -#: libs/ardour/automation_event.cc:636 -#: libs/ardour/insert.cc:547 -#: libs/ardour/session.cc:2172 -#: libs/ardour/session.cc:3576 -#: libs/ardour/session.cc:3615 -#: libs/ardour/session_command.cc:432 -#: libs/ardour/sndfilesource.cc:111 -msgid "programming error: %1" -msgstr "" - -#: libs/ardour/audiofilesource.cc:657 -msgid "Programming error! Ardour tried to rename a file over another file! It's safe to continue working, but please report this to the developers." -msgstr "" - -#: libs/ardour/audiofilesource.cc:662 -msgid "cannot rename audio file %1 to %2" -msgstr "" - -#: libs/ardour/audiofilter.cc:43 -msgid "" -"This is an old Ardour session that does not have\n" -"sufficient information for rendered FX" -msgstr "" - -#: libs/ardour/audiofilter.cc:66 -msgid "audiofilter: error creating name for new audio file based on %1" -msgstr "" - -#: libs/ardour/audiofilter.cc:77 -msgid "audiofilter: error creating new audio file %1 (%2)" -msgstr "" - -#: libs/ardour/audio_library.cc:57 -msgid "Could not open %1. Audio Library not saved" -msgstr "" - -#: libs/ardour/audio_playlist.cc:226 -#: libs/ardour/audio_playlist.cc:615 -msgid "programming error: non-audio Region passed to remove_overlap in audio playlist" -msgstr "" - -#: libs/ardour/audio_playlist.cc:356 -msgid "programming error: non-audio Region tested for overlap in audio playlist" -msgstr "" - -#: libs/ardour/audioregion.cc:1596 -msgid "" -"You have requested an operation that requires audio analysis.\n" -"\n" -"You currently have \"auto-analyse-audio\" disabled, which means\n" -"that transient data must be generated every time it is required.\n" -"\n" -"If you are doing work that will require transient data on a\n" -"regular basis, you should probably enable \"auto-analyse-audio\"\n" -"then quit ardour and restart." -msgstr "" - -#: libs/ardour/audiosource.cc:178 -msgid "cannot rename peakfile for %1 from %2 to %3 (%4)" -msgstr "" - -#: libs/ardour/audiosource.cc:205 -msgid "AudioSource: cannot stat peakfile \"%1\"" -msgstr "" - -#: libs/ardour/audiosource.cc:329 -msgid "cannot read sample data for unscaled peak computation" -msgstr "" - -#: libs/ardour/audiosource.cc:349 -msgid "AudioSource: cannot open peakpath (a) \"%1\" (%2)" -msgstr "" - -#: libs/ardour/audiosource.cc:423 -msgid "AudioSource: cannot open peakpath (b) \"%1\" (%2)" -msgstr "" - -#: libs/ardour/audiosource.cc:537 -msgid "AudioSource[%1]: peak read - cannot read %2 samples at offset %3 of %4 (%5)" -msgstr "" - -#: libs/ardour/audiosource.cc:624 -msgid "%1: could not write read raw data for peak computation (%2)" -msgstr "" - -#: libs/ardour/audiosource.cc:670 -msgid "AudioSource: cannot open peakpath (c) \"%1\" (%2)" -msgstr "" - -#: libs/ardour/audiosource.cc:736 -#: libs/ardour/audiosource.cc:848 -msgid "%1: could not write peak file data (%2)" -msgstr "" - -#: libs/ardour/audio_track.cc:140 -#: libs/ardour/io.cc:1797 -#: libs/ardour/io.cc:1863 -msgid "Unknown connection \"%1\" listed for input of %2" -msgstr "" - -#: libs/ardour/audio_track.cc:145 -msgid "in 1+2" -msgstr "wejÅ›cie 1+2" - -#: libs/ardour/audio_track.cc:147 -#: libs/ardour/io.cc:1799 -#: libs/ardour/io.cc:1865 -msgid "in 1" -msgstr "wejÅ›cie 1" - -#: libs/ardour/audio_track.cc:151 -#: libs/ardour/io.cc:1800 -#: libs/ardour/io.cc:1866 -msgid "No input connections available as a replacement" -msgstr "" - -#: libs/ardour/audio_track.cc:155 -msgid "Connection %1 was not available - \"%2\" used instead" -msgstr "" - -#: libs/ardour/audio_track.cc:164 -#: libs/ardour/io.cc:1879 -msgid "improper input channel list in XML node (%1)" -msgstr "" - -#: libs/ardour/audio_track.cc:205 -#: libs/ardour/audio_track.cc:218 -msgid "AudioTrack: audio diskstream \"%1\" not known by session" -msgstr "" - -#: libs/ardour/audio_track.cc:260 -msgid "programming error: AudioTrack given state without diskstream!" -msgstr "" - -#: libs/ardour/auditioner.cc:56 -msgid "no outputs available for auditioner - manual connection required" -msgstr "" - -#: libs/ardour/auditioner.cc:127 -msgid "Auditioning of non-audio regions not yet supported" -msgstr "" - -#: libs/ardour/automation_event.cc:782 -#: libs/ardour/panner.cc:833 -msgid "programming error:" -msgstr "" - -#: libs/ardour/automation_event.cc:1305 -msgid "automation list: cannot load coordinates from XML, all points ignored" -msgstr "" - -#: libs/ardour/automation_event.cc:1351 -msgid "automation list: no x-coordinate stored for control point (point ignored)" -msgstr "" - -#: libs/ardour/automation_event.cc:1357 -msgid "automation list: no y-coordinate stored for control point (point ignored)" -msgstr "" - -#: libs/ardour/automation_event.cc:1371 -msgid "AutomationList: passed XML node called %1, not \"AutomationList\" - ignored" -msgstr "" - -#: libs/ardour/configuration.cc:97 -msgid "loading system configuration file %1" -msgstr "" - -#: libs/ardour/configuration.cc:100 -msgid "Ardour: cannot read system configuration file \"%1\"" -msgstr "" - -#: libs/ardour/configuration.cc:107 -msgid "Ardour: system configuration file \"%1\" not loaded successfully." -msgstr "" - -#: libs/ardour/configuration.cc:111 -msgid "your system Ardour configuration file is empty. This probably means that there as an error installing Ardour" -msgstr "" - -#: libs/ardour/configuration.cc:131 -msgid "loading user configuration file %1" -msgstr "" - -#: libs/ardour/configuration.cc:134 -msgid "Ardour: cannot read configuration file \"%1\"" -msgstr "" - -#: libs/ardour/configuration.cc:141 -msgid "Ardour: user configuration file \"%1\" not loaded successfully." -msgstr "" - -#: libs/ardour/configuration.cc:145 -msgid "your Ardour configuration file is empty. This is not normal." -msgstr "" - -#: libs/ardour/configuration.cc:164 -msgid "Config file %1 not saved" -msgstr "Plik konfiguracji %1 nie zapisany" - -#: libs/ardour/configuration.cc:253 -msgid "ill-formed MIDI port specification in ardour rcfile (ignored)" -msgstr "" - -#: libs/ardour/connection.cc:182 -msgid "Node for Connection has no \"name\" property" -msgstr "" - -#: libs/ardour/connection.cc:190 -msgid "Node for Connection has no \"connections\" property" -msgstr "" - -#: libs/ardour/connection.cc:226 -#: libs/ardour/io.cc:1939 -msgid "IO: badly formed string in XML node for inputs \"%1\"" -msgstr "" - -#: libs/ardour/connection.cc:231 -#: libs/ardour/io.cc:1944 -msgid "bad input string in XML node \"%1\"" -msgstr "" - -#: libs/ardour/control_protocol_manager.cc:117 -msgid "control protocol name \"%1\" has no descriptor" -msgstr "" - -#: libs/ardour/control_protocol_manager.cc:122 -msgid "control protocol name \"%1\" could not be initialized" -msgstr "" - -#: libs/ardour/control_protocol_manager.cc:189 -msgid "Instantiating mandatory control protocol %1" -msgstr "" - -#: libs/ardour/control_protocol_manager.cc:201 -msgid "looking for control protocols in %1" -msgstr "" - -#: libs/ardour/control_protocol_manager.cc:223 -msgid "Control protocol %1 not usable" -msgstr "" - -#: libs/ardour/control_protocol_manager.cc:237 -msgid "Control surface protocol discovered: \"%1\"" -msgstr "" - -#: libs/ardour/control_protocol_manager.cc:255 -msgid "ControlProtocolManager: cannot load module \"%1\" (%2)" -msgstr "" - -#: libs/ardour/control_protocol_manager.cc:263 -msgid "ControlProtocolManager: module \"%1\" has no descriptor function." -msgstr "" - -#: libs/ardour/control_protocol_manager.cc:380 -msgid "control protocol XML node has no name property. Ignored." -msgstr "" - -#: libs/ardour/control_protocol_manager.cc:387 -msgid "control protocol \"%1\" is not known. Ignored" -msgstr "" - -#: libs/ardour/crossfade.cc:124 -msgid "Crossfade: no \"in\" region in state" -msgstr "" - -#: libs/ardour/crossfade.cc:131 -msgid "Crossfade: no \"in\" region %1 found in playlist %2" -msgstr "" - -#: libs/ardour/crossfade.cc:141 -msgid "Crossfade: no \"out\" region in state" -msgstr "" - -#: libs/ardour/crossfade.cc:148 -msgid "Crossfade: no \"out\" region %1 found in playlist %2" -msgstr "" - -#: libs/ardour/crossfade.cc:684 -msgid "old-style crossfade information - no position information" -msgstr "" - -#: libs/ardour/curve.cc:116 -#: libs/ardour/globals.cc:394 -#: libs/ardour/insert.cc:461 -#: libs/ardour/session.cc:2655 -#: libs/ardour/session.cc:2741 -msgid "programming error: " -msgstr "" - -#: libs/ardour/cycle_timer.cc:36 -msgid "CycleTimer::get_mhz(): can't open /proc/cpuinfo" -msgstr "" - -#: libs/ardour/cycle_timer.cc:48 -msgid "CycleTimer::get_mhz(): cannot locate cpu MHz in /proc/cpuinfo" -msgstr "" - -#: libs/ardour/cycle_timer.cc:71 -msgid "cannot locate cpu MHz in /proc/cpuinfo" -msgstr "nie można zlokalizować taktowania CPU w /proc/cpuinfo" - -#: libs/ardour/diskstream.cc:253 -msgid "Location \"%1\" not valid for track loop (start >= end)" -msgstr "" - -#: libs/ardour/globals.cc:112 -msgid "Starting OSC" -msgstr "" - -#: libs/ardour/globals.cc:124 -msgid "no MIDI ports specified: no MMC or MTC control possible" -msgstr "" - -#: libs/ardour/globals.cc:128 -msgid "Configuring MIDI ports" -msgstr "" - -#: libs/ardour/globals.cc:143 -#: libs/ardour/globals.cc:147 -#: libs/ardour/globals.cc:151 -msgid "default" -msgstr "domyÅ›lnie" - -#: libs/ardour/globals.cc:181 -msgid "No MMC control (MIDI port \"%1\" not available)" -msgstr "" - -#: libs/ardour/globals.cc:187 -msgid "No MTC support (MIDI port \"%1\" not available)" -msgstr "" - -#: libs/ardour/globals.cc:192 -msgid "No MIDI parameter support (MIDI port \"%1\" not available)" -msgstr "" - -#: libs/ardour/globals.cc:273 -msgid "Could not set system open files limit to \"unlimited\"" -msgstr "" - -#: libs/ardour/globals.cc:275 -msgid "Could not set system open files limit to %1" -msgstr "" - -#: libs/ardour/globals.cc:279 -msgid "Removed open file count limit. Excellent!" -msgstr "" - -#: libs/ardour/globals.cc:281 -msgid "Ardour will be limited to %1 open files" -msgstr "" - -#: libs/ardour/globals.cc:285 -msgid "Could not get system open files limit (%1)" -msgstr "" - -#: libs/ardour/globals.cc:304 -msgid "Loading configuration" -msgstr "" - -#: libs/ardour/import.cc:179 -msgid "Could not find a source for %1 even though we are updating this file!" -msgstr "" - -#: libs/ardour/import.cc:208 -msgid "Unable to create file %1 during import" -msgstr "" - -#: libs/ardour/import.cc:225 -msgid "" -"converting %1\n" -"(resample from %2KHz to %3KHz)\n" -"(%4 of %5)" -msgstr "" - -#: libs/ardour/import.cc:232 -msgid "" -"converting %1\n" -"(%2 of %3)" -msgstr "" - -#: libs/ardour/import.cc:318 -msgid "Import: cannot open input sound file \"%1\"" -msgstr "" - -#: libs/ardour/insert.cc:680 -#: libs/ardour/insert.cc:1005 -msgid "XML node describing insert is missing the `type' field" -msgstr "" - -#: libs/ardour/insert.cc:693 -msgid "unknown plugin type %1 in plugin insert state" -msgstr "" - -#: libs/ardour/insert.cc:713 -msgid "Plugin has no unique ID field" -msgstr "" - -#: libs/ardour/insert.cc:723 -msgid "" -"Found a reference to a plugin (\"%1\") that is unknown.\n" -"Perhaps it was removed or moved since it was last used." -msgstr "" - -#: libs/ardour/insert.cc:754 -msgid "XML node describing a plugin insert is missing the `%1' information" -msgstr "" - -#: libs/ardour/insert.cc:766 -#: libs/ardour/insert.cc:1033 -msgid "XML node describing insert is missing a Redirect node" -msgstr "" - -#: libs/ardour/insert.cc:818 -msgid "PluginInsert: Auto: no ladspa port number" -msgstr "" - -#: libs/ardour/insert.cc:825 -msgid "PluginInsert: Auto: port id out of range" -msgstr "" - -#: libs/ardour/insert.cc:856 -msgid "XML node describing a port automation is missing the `%1' information" -msgstr "" - -#: libs/ardour/insert.cc:911 -#: libs/ardour/insert.cc:919 -msgid "insert %1" -msgstr "" - -#: libs/ardour/insert.cc:1010 -msgid "non-port insert XML used for port plugin insert" -msgstr "" - -#: libs/ardour/io.cc:638 -msgid "IO: cannot disconnect input port %1 from %2" -msgstr "" - -#: libs/ardour/io.cc:706 -msgid "IO: cannot disconnect output port %1 from %2" -msgstr "" - -#: libs/ardour/io.cc:860 -#: libs/ardour/io.cc:1189 -#: libs/ardour/io.cc:1308 -msgid "IO: cannot register output port %1" -msgstr "" - -#: libs/ardour/io.cc:967 -#: libs/ardour/io.cc:1066 -#: libs/ardour/io.cc:1164 -msgid "IO: cannot register input port %1" -msgstr "" - -#: libs/ardour/io.cc:1558 -msgid "incorrect XML node \"%1\" passed to IO object" -msgstr "" - -#: libs/ardour/io.cc:1686 -msgid "%1: cannot open automation event file \"%2\"" -msgstr "" - -#: libs/ardour/io.cc:1701 -msgid "badly formed version number in automation event file \"%1\"" -msgstr "" - -#: libs/ardour/io.cc:1705 -msgid "no version information in automation event file \"%1\"" -msgstr "" - -#: libs/ardour/io.cc:1713 -msgid "badly formatted automation event record at line %1 of %2 (ignored)" -msgstr "" - -#: libs/ardour/io.cc:1733 -msgid "dubious automation event found (and ignored)" -msgstr "" - -#: libs/ardour/io.cc:1746 -msgid "IO::connecting_became_legal() called without a pending state node" -msgstr "" - -#: libs/ardour/io.cc:1768 -msgid "IO::ports_became_legal() called without a pending state node" -msgstr "" - -#: libs/ardour/io.cc:1804 -#: libs/ardour/io.cc:1870 -msgid "Connection %1 was not available - \"in 1\" used instead" -msgstr "" - -#: libs/ardour/io.cc:1820 -#: libs/ardour/io.cc:1888 -msgid "Unknown connection \"%1\" listed for output of %2" -msgstr "" - -#: libs/ardour/io.cc:1822 -#: libs/ardour/io.cc:1890 -msgid "out 1" -msgstr "" - -#: libs/ardour/io.cc:1823 -#: libs/ardour/io.cc:1891 -msgid "No output connections available as a replacement" -msgstr "" - -#: libs/ardour/io.cc:1827 -#: libs/ardour/io.cc:1895 -msgid "Connection %1 was not available - \"out 1\" used instead" -msgstr "" - -#: libs/ardour/io.cc:1841 -msgid "%1: cannot create I/O ports" -msgstr "" - -#: libs/ardour/io.cc:1904 -msgid "improper output channel list in XML node (%1)" -msgstr "" - -#: libs/ardour/io.cc:1989 -msgid "IO: badly formed string in XML node for outputs \"%1\"" -msgstr "" - -#: libs/ardour/io.cc:1994 -msgid "IO: bad output string in XML node \"%1\"" -msgstr "" - -#: libs/ardour/io.cc:2078 -msgid "you cannot use colons to name objects with I/O connections" -msgstr "" - -#: libs/ardour/io.cc:2642 -msgid "in" -msgstr "wejÅ›cie" - -#: libs/ardour/io.cc:2645 -msgid "out" -msgstr "wyjÅ›cie" - -#: libs/ardour/io.cc:2697 -#: libs/ardour/io.cc:2730 -#, c-format -msgid "%s %u" -msgstr "%s %u" - -#: libs/ardour/ladspa_plugin.cc:86 -msgid "LADSPA: module has no descriptor function." -msgstr "" - -#: libs/ardour/ladspa_plugin.cc:91 -msgid "LADSPA: plugin has gone away since discovery!" -msgstr "" - -#: libs/ardour/ladspa_plugin.cc:98 -msgid "LADSPA: \"%1\" cannot be used, since it cannot do inplace processing" -msgstr "" - -#: libs/ardour/ladspa_plugin.cc:306 -msgid "illegal parameter number used with plugin \"%1\". This mayindicate a change in the plugin design, and presets may beinvalid" -msgstr "" - -#: libs/ardour/ladspa_plugin.cc:389 -msgid "Bad node sent to LadspaPlugin::set_state" -msgstr "" - -#: libs/ardour/ladspa_plugin.cc:402 -msgid "LADSPA: no ladspa port number" -msgstr "" - -#: libs/ardour/ladspa_plugin.cc:409 -msgid "LADSPA: no ladspa port data" -msgstr "" - -#: libs/ardour/ladspa_plugin.cc:648 -msgid "LADSPA: cannot load module from \"%1\"" -msgstr "" - -#: libs/ardour/location.cc:213 -msgid "You cannot put a CD marker at this position" -msgstr "" - -#: libs/ardour/location.cc:342 -msgid "incorrect XML node passed to Location::set_state" -msgstr "" - -#: libs/ardour/location.cc:347 -msgid "XML node for Location has no ID information" -msgstr "" - -#: libs/ardour/location.cc:353 -msgid "XML node for Location has no name information" -msgstr "" - -#: libs/ardour/location.cc:360 -msgid "XML node for Location has no start information" -msgstr "" - -#: libs/ardour/location.cc:371 -msgid "XML node for Location has no end information" -msgstr "" - -#: libs/ardour/location.cc:378 -msgid "XML node for Location has no flags information" -msgstr "" - -#: libs/ardour/location.cc:495 -msgid "Locations: attempt to use unknown location as selected location" -msgstr "" - -#: libs/ardour/location.cc:663 -msgid "incorrect XML mode passed to Locations::set_state" -msgstr "" - -#: libs/ardour/location.cc:684 -msgid "could not load location from session file - ignored" -msgstr "" - -#: libs/ardour/mtc_slave.cc:123 -msgid "Unknown rate/drop value in incoming MTC stream, session values used instead" -msgstr "" - -#: libs/ardour/mtc_slave.cc:229 -msgid "MTC Slave: atomic read of current time failed, sleeping!" -msgstr "" - -#: libs/ardour/named_selection.cc:88 -msgid "Chunk %1 uses an unknown playlist \"%2\"" -msgstr "" - -#: libs/ardour/named_selection.cc:91 -msgid "Chunk %1 contains misformed playlist information" -msgstr "" - -#: libs/ardour/panner.cc:253 -msgid "badly formatted pan automation event record at line %1 of %2 (ignored) [%3]" -msgstr "" - -#: libs/ardour/panner.cc:749 -msgid "badly-formed positional data for Multi2dPanner - ignored" -msgstr "" - -#: libs/ardour/panner.cc:1138 -msgid "Unknown panner plugin \"%1\" found in pan state - ignored" -msgstr "" - -#: libs/ardour/panner.cc:1144 -msgid "panner plugin node has no type information!" -msgstr "" - -#: libs/ardour/panner.cc:1354 -msgid "cannot open pan automation file %1 (%2)" -msgstr "" - -#: libs/ardour/panner.cc:1367 -msgid "badly formed version number in pan automation event file \"%1\"" -msgstr "" - -#: libs/ardour/panner.cc:1371 -msgid "no version information in pan automation event file \"%1\" (first line = %2)" -msgstr "" - -#: libs/ardour/panner.cc:1386 -msgid "too many panner states found in pan automation file %1" -msgstr "" - -#: libs/ardour/playlist.cc:250 -msgid "playlist const copy constructor called" -msgstr "" - -#: libs/ardour/playlist.cc:256 -msgid "playlist non-const copy constructor called" -msgstr "" - -#: libs/ardour/playlist.cc:1217 -msgid "%1: bounds changed received for region (%2)not in playlist" -msgstr "" - -#: libs/ardour/playlist.cc:1750 -msgid "region state node has no ID, ignored" -msgstr "" - -#: libs/ardour/playlist.cc:1761 -msgid "Playlist: cannot reset region state from XML" -msgstr "" - -#: libs/ardour/playlist.cc:1766 -msgid "Playlist: cannot create region from XML" -msgstr "" - -#: libs/ardour/plugin.cc:281 -msgid "Could not locate HOME. Preset not saved." -msgstr "" - -#: libs/ardour/plugin.cc:291 -#: libs/ardour/plugin.cc:297 -msgid "Could not create %1. Preset not saved. (%2)" -msgstr "" - -#: libs/ardour/plugin.cc:302 -msgid "Error saving presets file %1." -msgstr "" - -#: libs/ardour/plugin_manager.cc:223 -msgid "Could not parse rdf file: %1" -msgstr "" - -#: libs/ardour/plugin_manager.cc:263 -msgid "LADSPA: cannot load module \"%1\" (%2)" -msgstr "" - -#: libs/ardour/plugin_manager.cc:270 -msgid "LADSPA: module \"%1\" has no descriptor function." -msgstr "" - -#: libs/ardour/plugin_manager.cc:454 -msgid "VST plugin %1 does not support processReplacing, and so cannot be used in ardour at this time" -msgstr "" - -#: libs/ardour/recent_sessions.cc:44 -msgid "cannot open recent session file %1 (%2)" -msgstr "" - -#: libs/ardour/redirect.cc:78 -msgid "programming error: unknown Redirect type in Redirect::Clone!\n" -msgstr "" - -#: libs/ardour/redirect.cc:128 -msgid "%2: badly formatted node name in XML automation state, ignored" -msgstr "" - -#: libs/ardour/redirect.cc:141 -msgid "%1: cannot load automation data from XML" -msgstr "" - -#: libs/ardour/redirect.cc:219 -msgid "incorrect XML node \"%1\" passed to Redirect object" -msgstr "" - -#: libs/ardour/redirect.cc:267 -msgid "XML node describing an IO is missing an IO node" -msgstr "" - -#: libs/ardour/redirect.cc:272 -msgid "XML node describing a redirect is missing the `active' field" -msgstr "" - -#: libs/ardour/redirect.cc:285 -msgid "XML node describing a redirect is missing the `placement' field" -msgstr "" - -#: libs/ardour/redirect.cc:315 -msgid "%1: Automation node has no path property" -msgstr "" - -#: libs/ardour/redirect.cc:351 -msgid "%1: cannot open %2 to load automation data (%3)" -msgstr "" - -#: libs/ardour/redirect.cc:376 -msgid "%1: cannot load automation data from %2" -msgstr "" - -#: libs/ardour/region.cc:923 -msgid "XMLNode describing a Region is incomplete (no name)" -msgstr "" - -#: libs/ardour/region.cc:1068 -msgid "Session: XMLNode describing a Region is incomplete (no id)" -msgstr "" - -#: libs/ardour/region_factory.cc:52 -#: libs/ardour/region_factory.cc:69 -msgid "programming error: RegionFactory::create() called with unknown Region type" -msgstr "" - -#: libs/ardour/resampled_source.cc:61 -msgid "Import: src_new() failed : %1" -msgstr "" - -#: libs/ardour/resampled_source.cc:113 -msgid "Import: %1" -msgstr "" - -#: libs/ardour/route.cc:83 -#: libs/ardour/session.cc:1560 -#: libs/ardour/session.cc:1566 -#: libs/ardour/session.cc:1871 -#: libs/ardour/session.cc:3369 -msgid "signal" -msgstr "" - -#: libs/ardour/route.cc:1573 -msgid "Send construction failed" -msgstr "" - -#: libs/ardour/route.cc:1601 -msgid "unknown Insert type \"%1\"; ignored" -msgstr "" - -#: libs/ardour/route.cc:1609 -msgid "Insert XML node has no type property" -msgstr "" - -#: libs/ardour/route.cc:1614 -msgid "insert could not be created. Ignored." -msgstr "" - -#: libs/ardour/route.cc:1636 -msgid "Bad node sent to Route::set_state() [%1]" -msgstr "" - -#: libs/ardour/route.cc:1698 -msgid "Route %1: unknown edit group \"%2 in saved state (ignored)" -msgstr "" - -#: libs/ardour/route.cc:1714 -#: libs/ardour/route.cc:1718 -msgid "badly formed order key string in state file! [%1] ... ignored." -msgstr "" - -#: libs/ardour/route.cc:1784 -#: libs/ardour/route.cc:2001 -msgid "[control]" -msgstr "" - -#: libs/ardour/route.cc:1823 -msgid "Route %1: unknown mix group \"%2 in saved state (ignored)" -msgstr "" - -#: libs/ardour/route.cc:2019 -msgid "could not connect %1 to %2" -msgstr "" - -#: libs/ardour/send.cc:34 -#: libs/ardour/send.cc:57 -msgid "send %1" -msgstr "" - -#: libs/ardour/send.cc:117 -msgid "XML node describing a send is missing a Redirect node" -msgstr "" - -#: libs/ardour/session_butler.cc:80 -#: libs/ardour/session_midi.cc:1085 -msgid "Cannot create transport request signal pipe (%1)" -msgstr "" - -#: libs/ardour/session_butler.cc:85 -#: libs/ardour/session_butler.cc:90 -msgid "UI: cannot set O_NONBLOCK on butler request pipe (%1)" -msgstr "" - -#: libs/ardour/session_butler.cc:95 -msgid "Session: could not create butler thread" -msgstr "" - -#: libs/ardour/session_butler.cc:184 -msgid "poll on butler request pipe failed (%1)" -msgstr "" - -#: libs/ardour/session_butler.cc:191 -msgid "Error on butler thread request pipe: fd=%1 err=%2" -msgstr "" - -#: libs/ardour/session_butler.cc:232 -msgid "Error reading from butler request pipe" -msgstr "" - -#: libs/ardour/session_butler.cc:277 -msgid "Butler read ahead failure on dstream %1" -msgstr "" - -#: libs/ardour/session_butler.cc:323 -msgid "Butler write-behind failure on dstream %1" -msgstr "" - -#: libs/ardour/session.cc:130 -msgid "Could not resolve path: %1 (%2)" -msgstr "" - -#: libs/ardour/session.cc:142 -msgid "cannot check session path %1 (%2)" -msgstr "" - -#: libs/ardour/session.cc:172 -msgid "cannot check statefile %1 (%2)" -msgstr "" - -#: libs/ardour/session.cc:208 -msgid "%1 is not an Ardour snapshot file" -msgstr "" - -#: libs/ardour/session.cc:225 -msgid "cannot determine current working directory (%1)" -msgstr "" - -#: libs/ardour/session.cc:242 -msgid "unknown file type for session %1" -msgstr "" - -#: libs/ardour/session.cc:387 -msgid "monitor" -msgstr "monitor" - -#: libs/ardour/session.cc:394 -#: libs/ardour/session.cc:1900 -msgid "master" -msgstr "główna" - -#: libs/ardour/session.cc:674 -msgid "Set block size and sample rate" -msgstr "" - -#: libs/ardour/session.cc:679 -msgid "Using configuration" -msgstr "" - -#: libs/ardour/session.cc:712 -msgid "could not setup Click I/O" -msgstr "nie można byÅ‚o ustawić I/O metronomu" - -#: libs/ardour/session.cc:733 -msgid "cannot setup Click I/O" -msgstr "nie można ustawić I/O metronomu" - -#: libs/ardour/session.cc:736 -msgid "Compute I/O Latencies" -msgstr "" - -#: libs/ardour/session.cc:748 -msgid "Set up standard connections" -msgstr "" - -#: libs/ardour/session.cc:754 -#, c-format -msgid "out %<PRIu32>" -msgstr "wyjÅ›cie %<PRIu32>" - -#: libs/ardour/session.cc:766 -#, c-format -msgid "in %<PRIu32>" -msgstr "wejÅ›cie %<PRIu32>" - -#: libs/ardour/session.cc:780 -#, c-format -msgid "out %<PRIu32>+%<PRIu32>" -msgstr "wyjÅ›cie %<PRIu32>+%<PRIu32>" - -#: libs/ardour/session.cc:794 -#, c-format -msgid "in %<PRIu32>+%<PRIu32>" -msgstr "wejÅ›cie %<PRIu32>+%<PRIu32>" - -#: libs/ardour/session.cc:827 -msgid "cannot setup master inputs" -msgstr "nie można ustawić głównych wejść" - -#: libs/ardour/session.cc:835 -msgid "cannot setup master outputs" -msgstr "nie można ustawić głównych wyjść" - -#: libs/ardour/session.cc:846 -msgid "Master Out" -msgstr "Główne wyjÅ›cie" - -#: libs/ardour/session.cc:855 -msgid "Setup signal flow and plugins" -msgstr "" - -#: libs/ardour/session.cc:861 -msgid "Catch up with send/insert state" -msgstr "" - -#: libs/ardour/session.cc:892 -msgid "Connect to engine" -msgstr "" - -#: libs/ardour/session.cc:899 -msgid "OSC startup" -msgstr "poczÄ…tek OSC" - -#: libs/ardour/session.cc:928 -msgid "cannot create Auditioner: no auditioning of regions possible" -msgstr "" - -#: libs/ardour/session.cc:942 -msgid "cannot setup control inputs" -msgstr "" - -#: libs/ardour/session.cc:950 -msgid "cannot set up master outputs" -msgstr "" - -#: libs/ardour/session.cc:1153 -msgid "Session: you can't use that location for auto punch (start <= end)" -msgstr "" - -#: libs/ardour/session.cc:1194 -msgid "Session: you can't use a mark for auto loop" -msgstr "" - -#: libs/ardour/session.cc:1578 -msgid "feedback loop setup between %1 and %2" -msgstr "" - -#: libs/ardour/session.cc:1765 -#: libs/ardour/session.cc:1931 -msgid "cannot configure %1 in/%2 out configuration for new audio track" -msgstr "" - -#: libs/ardour/session.cc:1817 -msgid "Session: could not create new audio track." -msgstr "" - -#: libs/ardour/session.cc:1835 -#: libs/ardour/session.cc:1980 -msgid "No more JACK ports are available. You will need to stop Ardour and restart JACK with ports if you need this many tracks." -msgstr "" - -#: libs/ardour/session.cc:1874 -msgid "editor" -msgstr "" - -#: libs/ardour/session.cc:1975 -msgid "Session: could not create new audio route." -msgstr "" - -#: libs/ardour/session.cc:2526 -msgid "cannot create new name for region \"%1\"" -msgstr "" - -#: libs/ardour/session.cc:2590 -msgid "too many regions with names like %1" -msgstr "" - -#: libs/ardour/session.cc:2621 -#: libs/ardour/session.cc:2682 -msgid "Session::add_region() ignored a null region. Warning: you might have lost a region." -msgstr "" - -#: libs/ardour/session.cc:3159 -msgid "There are already %1 recordings for %2, which I consider too many." -msgstr "" - -#: libs/ardour/session.cc:3390 -msgid "Cannot compile tape track regexp for use (%1)" -msgstr "" - -#: libs/ardour/session.cc:3543 -msgid "programming error: unknown type of Insert created!" -msgstr "" - -#: libs/ardour/session.cc:3549 -msgid "programming error: unknown type of Redirect created!" -msgstr "" - -#: libs/ardour/session.cc:3588 -msgid "programming error: unknown type of Redirect deleted!" -msgstr "" - -#: libs/ardour/session.cc:3708 -#: libs/ardour/session.cc:3722 -#: libs/ardour/session.cc:4122 -msgid "Memory allocation error: posix_memalign (%1 * %2) failed (%3)" -msgstr "" - -#: libs/ardour/session.cc:3792 -msgid "send ID %1 appears to be in use already" -msgstr "" - -#: libs/ardour/session.cc:3804 -msgid "insert ID %1 appears to be in use already" -msgstr "" - -#: libs/ardour/session.cc:3986 -msgid "too many bounced versions of playlist \"%1\"" -msgstr "" - -#: libs/ardour/session.cc:3995 -msgid "cannot create new audio file \"%1\" for %2" -msgstr "" - -#: libs/ardour/session.cc:4107 -msgid "Programming error: get_silent_buffers() called for %1 buffers but only %2 exist" -msgstr "" - -#: libs/ardour/session_click.cc:160 -msgid "cannot open click soundfile %1 (%2)" -msgstr "nie można otworzyć pliku dźwiÄ™kowego metronomu %1 (%2)" - -#: libs/ardour/session_click.cc:169 -msgid "cannot read data from click soundfile" -msgstr "nie można odczytać danych z pliku dźwiÄ™kowego metronomu" - -#: libs/ardour/session_click.cc:196 -msgid "cannot open click emphasis soundfile %1 (%2)" -msgstr "nie można otworzyć pliku dźwiÄ™kowego akcentowanego uderzenia metronomu %1 (%2)" - -#: libs/ardour/session_click.cc:204 -msgid "cannot read data from click emphasis soundfile" -msgstr "nie można odczytać danych z pliku dźwiÄ™kowego akcentowanego uderzenia metronomu" - -#: libs/ardour/session_command.cc:75 -msgid "Tried to reconstitute a MementoCommand with no contents, failing. id=" -msgstr "" - -#: libs/ardour/session_command.cc:111 -msgid "could not reconstitute MementoCommand from XMLNode. object type = %1 id = %2" -msgstr "" - -#: libs/ardour/session_command.cc:123 -msgid "GlobalRouteStateCommand has no \"type\" node, ignoring" -msgstr "" - -#: libs/ardour/session_command.cc:138 -msgid "unknown type of GlobalRouteStateCommand (%1), ignored" -msgstr "" - -#: libs/ardour/session_command.cc:186 -msgid "global route state command has no \"%1\" node, ignoring entire command" -msgstr "" - -#: libs/ardour/session_command.cc:202 -#: libs/ardour/session_command.cc:515 -msgid "cannot find track/bus \"%1\" while rebuilding a global route state command, ignored" -msgstr "" - -#: libs/ardour/session_command.cc:499 -msgid "global route meter state command has no \"%1\" node, ignoring entire command" -msgstr "" - -#: libs/ardour/session_events.cc:161 -msgid "Session: cannot have two events of type %1 at the same frame (%2)." -msgstr "" - -#: libs/ardour/session_events.cc:437 -msgid "Programming error: illegal event type in process_event (%1)" -msgstr "" - -#: libs/ardour/session_export.cc:62 -msgid "Export: no output file specified" -msgstr "" - -#: libs/ardour/session_export.cc:163 -#: libs/ardour/session_export.cc:168 -msgid "illegal frame range in export specification" -msgstr "" - -#: libs/ardour/session_export.cc:173 -msgid "Bad data width size. Report me!" -msgstr "" - -#: libs/ardour/session_export.cc:203 -msgid "Export: cannot open output file \"%1\" (%2)" -msgstr "" - -#: libs/ardour/session_export.cc:213 -msgid "cannot initialize sample rate conversion: %1" -msgstr "" - -#: libs/ardour/session_export.cc:315 -msgid "an error occured during sample rate conversion: %1" -msgstr "" - -#: libs/ardour/session_export.cc:326 -msgid "warning, leftover frames overflowed, glitches might occur in output" -msgstr "" - -#: libs/ardour/session_export.cc:417 -msgid "Export: could not write data to output file (%1)" -msgstr "" - -#: libs/ardour/session_export.cc:484 -msgid "%1: cannot seek to %2 for export" -msgstr "" - -#: libs/ardour/session_midi.cc:94 -msgid "Ardour is slaved to MTC - port cannot be reset" -msgstr "" - -#: libs/ardour/session_midi.cc:109 -msgid "unknown port %1 requested for MTC" -msgstr "" - -#: libs/ardour/session_midi.cc:446 -msgid "Error reading from MIDI port %1" -msgstr "" - -#: libs/ardour/session_midi.cc:816 -msgid "Session: could not send full MIDI time code" -msgstr "" - -#: libs/ardour/session_midi.cc:875 -msgid "Session: cannot send quarter-frame MTC message (%1)" -msgstr "" - -#: libs/ardour/session_midi.cc:983 -msgid "MMC: cannot send command %1%2%3" -msgstr "" - -#: libs/ardour/session_midi.cc:1090 -msgid "UI: cannot set O_NONBLOCK on signal read pipe (%1)" -msgstr "" - -#: libs/ardour/session_midi.cc:1095 -msgid "UI: cannot set O_NONBLOCK on signal write pipe (%1)" -msgstr "" - -#: libs/ardour/session_midi.cc:1100 -msgid "Session: could not create transport thread" -msgstr "" - -#: libs/ardour/session_midi.cc:1131 -msgid "cannot send signal to midi thread! (%1)" -msgstr "" - -#: libs/ardour/session_midi.cc:1226 -msgid "MIDI thread poll failed (%1)" -msgstr "" - -#: libs/ardour/session_midi.cc:1238 -msgid "Error on transport thread request pipe" -msgstr "" - -#: libs/ardour/session_midi.cc:1265 -msgid "Error reading from transport request pipe" -msgstr "" - -#: libs/ardour/session_process.cc:105 -msgid "Session: error in no roll for %1" -msgstr "" - -#: libs/ardour/session_state.cc:109 -msgid "Could not use path %1 (%s)" -msgstr "" - -#: libs/ardour/session_state.cc:145 -#: libs/ardour/session_state.cc:1050 -msgid "end" -msgstr "koniec" - -#: libs/ardour/session_state.cc:146 -#: libs/ardour/session_state.cc:1049 -msgid "start" -msgstr "poczÄ…tek" - -#: libs/ardour/session_state.cc:338 -msgid "Reset Remote Controls" -msgstr "" - -#: libs/ardour/session_state.cc:345 -msgid "Reset Control Protocols" -msgstr "" - -#: libs/ardour/session_state.cc:365 -msgid "Session loading complete" -msgstr "" - -#: libs/ardour/session_state.cc:484 -#: libs/ardour/session_state.cc:2857 -msgid "Session: cannot create session peakfile folder \"%1\" (%2)" -msgstr "" - -#: libs/ardour/session_state.cc:495 -msgid "Session: cannot create session sounds folder \"%1\" (%2)" -msgstr "Nie można utworzyć folderu dźwiÄ™ków sesji \"%1\" (%2)" - -#: libs/ardour/session_state.cc:503 -msgid "Session: cannot create session dead sounds folder \"%1\" (%2)" -msgstr "" - -#: libs/ardour/session_state.cc:510 -msgid "Session: cannot create session export folder \"%1\" (%2)" -msgstr "" - -#: libs/ardour/session_state.cc:517 -msgid "Session: cannot create session analysis folder \"%1\" (%2)" -msgstr "" - -#: libs/ardour/session_state.cc:529 -msgid "Session: cannot create session folder \"%1\" (%2)" -msgstr "" - -#: libs/ardour/session_state.cc:561 -msgid "Could not open %1 for writing mix template" -msgstr "" - -#: libs/ardour/session_state.cc:567 -msgid "Could not open mix template %1 for reading" -msgstr "" - -#: libs/ardour/session_state.cc:606 -msgid "Session: could not load diskstream via XML state" -msgstr "" - -#: libs/ardour/session_state.cc:649 -msgid "could not rename snapshot %1 to %2" -msgstr "" - -#: libs/ardour/session_state.cc:688 -msgid "Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved" -msgstr "" - -#: libs/ardour/session_state.cc:732 -msgid "state could not be saved to %1" -msgstr "" - -#: libs/ardour/session_state.cc:739 -msgid "could not rename temporary session file %1 to %2" -msgstr "" - -#: libs/ardour/session_state.cc:809 -msgid "%1: session state information file \"%2\" doesn't exist!" -msgstr "" - -#: libs/ardour/session_state.cc:818 -msgid "Could not understand ardour file %1" -msgstr "" - -#: libs/ardour/session_state.cc:827 -msgid "Session file %1 is not an Ardour session" -msgstr "" - -#: libs/ardour/session_state.cc:858 -msgid "" -"Copying old session file %1 to %2\n" -"Use %2 with Ardour versions before 2.0 from now on" -msgstr "" - -#: libs/ardour/session_state.cc:1168 -msgid "programming error: Session: incorrect XML node sent to set_state()" -msgstr "" - -#: libs/ardour/session_state.cc:1237 -msgid "Session: XML state has no options section" -msgstr "" - -#: libs/ardour/session_state.cc:1241 -msgid "Session: XML state has no locations section" -msgstr "" - -#: libs/ardour/session_state.cc:1274 -msgid "Session: XML state has no sources section" -msgstr "" - -#: libs/ardour/session_state.cc:1281 -msgid "Session: XML state has no Regions section" -msgstr "" - -#: libs/ardour/session_state.cc:1288 -msgid "Session: XML state has no playlists section" -msgstr "" - -#: libs/ardour/session_state.cc:1307 -msgid "Session: XML state has no diskstreams section" -msgstr "" - -#: libs/ardour/session_state.cc:1314 -msgid "Session: XML state has no connections section" -msgstr "" - -#: libs/ardour/session_state.cc:1321 -msgid "Session: XML state has no edit groups section" -msgstr "" - -#: libs/ardour/session_state.cc:1328 -msgid "Session: XML state has no mix groups section" -msgstr "" - -#: libs/ardour/session_state.cc:1335 -msgid "Session: XML state has no Tempo Map section" -msgstr "" - -#: libs/ardour/session_state.cc:1342 -msgid "Session: XML state has no routes section" -msgstr "" - -#: libs/ardour/session_state.cc:1349 -msgid "Session: XML state has no click section" -msgstr "" - -#: libs/ardour/session_state.cc:1384 -msgid "Session: cannot create Route from XML description." -msgstr "" - -#: libs/ardour/session_state.cc:1388 -msgid "Loaded track/bus %1" -msgstr "" - -#: libs/ardour/session_state.cc:1427 -msgid "Session: cannot create Region from XML description." -msgstr "" - -#: libs/ardour/session_state.cc:1431 -msgid "Can not load state for region '%1'" -msgstr "" - -#: libs/ardour/session_state.cc:1468 -msgid "Session: XMLNode describing a AudioRegion is incomplete (no source)" -msgstr "" - -#: libs/ardour/session_state.cc:1476 -#: libs/ardour/session_state.cc:1497 -#: libs/ardour/session_state.cc:1517 -msgid "Session: XMLNode describing a AudioRegion references an unknown source id =%1" -msgstr "" - -#: libs/ardour/session_state.cc:1482 -#: libs/ardour/session_state.cc:1503 -#: libs/ardour/session_state.cc:1523 -msgid "Session: XMLNode describing a AudioRegion references a non-audio source id =%1" -msgstr "" - -#: libs/ardour/session_state.cc:1546 -msgid "Session: XMLNode describing an AudioRegion is missing some master sources; ignored" -msgstr "" - -#: libs/ardour/session_state.cc:1597 -msgid "cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names" -msgstr "" - -#: libs/ardour/session_state.cc:1620 -msgid "Session: cannot create Source from XML description." -msgstr "" - -#: libs/ardour/session_state.cc:1625 -msgid "A sound file is missing. It will be replaced by silence." -msgstr "" - -#: libs/ardour/session_state.cc:1646 -msgid "Found a sound file that cannot be used by Ardour. Talk to the progammers." -msgstr "" - -#: libs/ardour/session_state.cc:1668 -msgid "Could not create mix templates directory \"%1\" (%2)" -msgstr "" - -#: libs/ardour/session_state.cc:1682 -msgid "Template \"%1\" already exists - new version not created" -msgstr "" - -#: libs/ardour/session_state.cc:1689 -msgid "mix template not saved" -msgstr "" - -#: libs/ardour/session_state.cc:1748 -msgid "cannot create session directory \"%1\"; ignored" -msgstr "" - -#: libs/ardour/session_state.cc:1759 -msgid "cannot create sounds directory \"%1\"; ignored" -msgstr "" - -#: libs/ardour/session_state.cc:1768 -msgid "cannot create dead sounds directory \"%1\"; ignored" -msgstr "" - -#: libs/ardour/session_state.cc:1777 -msgid "cannot create peak file directory \"%1\"; ignored" -msgstr "" - -#: libs/ardour/session_state.cc:1909 -#: libs/ardour/session_state.cc:1930 -msgid "Session: cannot create Playlist from XML description." -msgstr "" - -#: libs/ardour/session_state.cc:1969 -msgid "Session: cannot create Named Selection from XML description." -msgstr "" - -#: libs/ardour/session_state.cc:2171 -msgid "Unknown node \"%1\" found in Connections list from state file" -msgstr "" - -#: libs/ardour/session_state.cc:2982 -msgid "cannot remove dead sound file %1 (%2)" -msgstr "" - -#: libs/ardour/session_state.cc:3098 -msgid "could not backup old history file, current history not saved." -msgstr "" - -#: libs/ardour/session_state.cc:3110 -msgid "history could not be saved to %1" -msgstr "" - -#: libs/ardour/session_state.cc:3117 -msgid "could not remove corrupt history file %1" -msgstr "" - -#: libs/ardour/session_state.cc:3121 -msgid "could not restore history file from backup %1" -msgstr "" - -#: libs/ardour/session_state.cc:3143 -msgid "Loading history from '%1'." -msgstr "" - -#: libs/ardour/session_state.cc:3150 -msgid "Could not understand session history file \"%1\"" -msgstr "" - -#: libs/ardour/session_state.cc:3193 -msgid "Couldn't figure out how to make a Command out of a %1 XMLNode." -msgstr "" - -#: libs/ardour/session_time.cc:483 -msgid "Unknown JACK transport state %1 in sync callback" -msgstr "" - -#: libs/ardour/session_transport.cc:119 -msgid "Cannot loop - no loop range defined" -msgstr "" - -#: libs/ardour/session_transport.cc:537 -msgid "" -"Seamless looping cannot be supported while Ardour is using JACK transport.\n" -"Recommend changing the configured options" -msgstr "" - -#: libs/ardour/session_transport.cc:822 -msgid "Global varispeed cannot be supported while Ardour is connected to JACK transport control" -msgstr "" - -#: libs/ardour/session_transport.cc:1015 -msgid "please stop the transport before adjusting slave settings" -msgstr "" - -#: libs/ardour/session_transport.cc:1048 -msgid "No MTC port defined: MTC slaving is impossible." -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:34 -msgid "WAV" -msgstr "WAV" - -#: libs/ardour/sndfile_helpers.cc:35 -msgid "AIFF" -msgstr "AIFF" - -#: libs/ardour/sndfile_helpers.cc:36 -msgid "CAF" -msgstr "CAF" - -#: libs/ardour/sndfile_helpers.cc:37 -msgid "W64 (64 bit WAV)" -msgstr "W64 (64 bit WAV)" - -#: libs/ardour/sndfile_helpers.cc:38 -msgid "raw (no header)" -msgstr "raw (brak nagłówka)" - -#: libs/ardour/sndfile_helpers.cc:43 -msgid ".wav" -msgstr ".wav" - -#: libs/ardour/sndfile_helpers.cc:44 -msgid ".aiff" -msgstr ".aiff" - -#: libs/ardour/sndfile_helpers.cc:45 -msgid ".caf" -msgstr ".caf" - -#: libs/ardour/sndfile_helpers.cc:46 -msgid ".w64" -msgstr ".w64" - -#: libs/ardour/sndfile_helpers.cc:47 -msgid ".raw" -msgstr ".raw" - -#: libs/ardour/sndfile_helpers.cc:60 -msgid "16 bit" -msgstr "16 bit" - -#: libs/ardour/sndfile_helpers.cc:61 -msgid "24 bit" -msgstr "24 bit" - -#: libs/ardour/sndfile_helpers.cc:62 -msgid "32 bit" -msgstr "32 bit" - -#: libs/ardour/sndfile_helpers.cc:63 -msgid "8 bit" -msgstr "8 bit" - -#: libs/ardour/sndfile_helpers.cc:64 -msgid "float" -msgstr "float" - -#: libs/ardour/sndfile_helpers.cc:77 -msgid "Little-endian (Intel)" -msgstr "Little-endian (Intel)" - -#: libs/ardour/sndfile_helpers.cc:78 -msgid "Big-endian (Mac)" -msgstr "Big-endian (Mac)" - -#: libs/ardour/sndfilesource.cc:149 -msgid "FileSource: cannot get host information for BWF header (%1)" -msgstr "" - -#: libs/ardour/sndfilesource.cc:173 -msgid "cannot set broadcast info for audio file %1 (%2); dropping broadcast info for this file" -msgstr "" - -#: libs/ardour/sndfilesource.cc:226 -msgid "SndFileSource: cannot open file \"%1\" for %2 (%3)" -msgstr "" - -#: libs/ardour/sndfilesource.cc:234 -msgid "SndFileSource: file only contains %1 channels; %2 is invalid as a channel number" -msgstr "" - -#: libs/ardour/sndfilesource.cc:332 -msgid "SndFileSource: could not seek to frame %1 within %2 (%3)" -msgstr "" - -#: libs/ardour/sndfilesource.cc:377 -#: libs/ardour/sndfilesource.cc:412 -msgid "attempt to write a non-writable audio file source (%1)" -msgstr "" - -#: libs/ardour/sndfilesource.cc:382 -#: libs/ardour/utils.cc:523 -#: libs/ardour/utils.cc:547 -#: libs/ardour/utils.cc:561 -#: libs/ardour/utils.cc:580 -msgid "programming error: %1 %2" -msgstr "" - -#: libs/ardour/sndfilesource.cc:516 -msgid "attempt to flush a non-writable audio file source (%1)" -msgstr "" - -#: libs/ardour/sndfilesource.cc:526 -msgid "attempt to store broadcast info in a non-writable audio file source (%1)" -msgstr "" - -#: libs/ardour/sndfilesource.cc:562 -#: libs/ardour/sndfilesource.cc:583 -msgid "cannot set broadcast info for audio file %1; Dropping broadcast info for this file" -msgstr "" - -#: libs/ardour/sndfilesource.cc:596 -msgid "%1: cannot seek to %2 (libsndfile error: %3" -msgstr "" - -#: libs/ardour/sndfilesource.cc:705 -msgid "SndFileSource: \"%1\" bad read retval: %2 of %5 (%3: %4)" -msgstr "" - -#: libs/ardour/sndfilesource.cc:718 -#: libs/ardour/sndfilesource.cc:768 -#: libs/ardour/sndfilesource.cc:775 -msgid "SndFileSource: \"%1\" bad write (%2)" -msgstr "" - -#: libs/ardour/sndfilesource.cc:798 -msgid "Filesource: start time is already set for existing file (%1): Cannot change start time." -msgstr "" - -#: libs/ardour/tempo.cc:71 -msgid "TempoSection XML node has no \"start\" property" -msgstr "" - -#: libs/ardour/tempo.cc:79 -msgid "TempoSection XML node has an illegal \"start\" value" -msgstr "" - -#: libs/ardour/tempo.cc:86 -msgid "TempoSection XML node has no \"beats-per-minute\" property" -msgstr "" - -#: libs/ardour/tempo.cc:91 -msgid "TempoSection XML node has an illegal \"beats_per_minute\" value" -msgstr "" - -#: libs/ardour/tempo.cc:100 -msgid "TempoSection XML node has an illegal \"note-type\" value" -msgstr "" - -#: libs/ardour/tempo.cc:106 -msgid "TempoSection XML node has no \"movable\" property" -msgstr "" - -#: libs/ardour/tempo.cc:147 -msgid "MeterSection XML node has no \"start\" property" -msgstr "" - -#: libs/ardour/tempo.cc:155 -msgid "MeterSection XML node has an illegal \"start\" value" -msgstr "" - -#: libs/ardour/tempo.cc:162 -msgid "MeterSection XML node has no \"beats-per-bar\" property" -msgstr "" - -#: libs/ardour/tempo.cc:167 -msgid "MeterSection XML node has an illegal \"beats-per-bar\" value" -msgstr "" - -#: libs/ardour/tempo.cc:172 -msgid "MeterSection XML node has no \"note-type\" property" -msgstr "" - -#: libs/ardour/tempo.cc:177 -msgid "MeterSection XML node has an illegal \"note-type\" value" -msgstr "" - -#: libs/ardour/tempo.cc:182 -msgid "MeterSection XML node has no \"movable\" property" -msgstr "" - -#: libs/ardour/tempo.cc:561 -msgid "no tempo sections defined in tempo map - cannot change tempo @ %1" -msgstr "" - -#: libs/ardour/tempo.cc:585 -#: libs/ardour/tempo.cc:601 -msgid "programming error: no tempo section in tempo map!" -msgstr "" - -#: libs/ardour/tempo.cc:644 -#: libs/ardour/tempo.cc:702 -msgid "programming error: unhandled MetricSection type" -msgstr "" - -#: libs/ardour/tempo.cc:1461 -#: libs/ardour/tempo.cc:1473 -msgid "Tempo map: could not set new state, restoring old one." -msgstr "" - -#: libs/ardour/utils.cc:300 -msgid "illegal or badly-formed string used for path (%1)" -msgstr "" - -#: libs/ardour/utils.cc:305 -msgid "path (%1) is ambiguous" -msgstr "" - -#: libs/ardour/utils.cc:367 -#: libs/ardour/utils.cc:391 -msgid "Splice Edit" -msgstr "Edycja klockowa" - -#: libs/ardour/utils.cc:369 -#: libs/ardour/utils.cc:384 -msgid "Slide Edit" -msgstr "Edycja Å›lizgowa" - -#: libs/ardour/utils.cc:371 -#: libs/ardour/utils.cc:387 -msgid "Lock Edit" -msgstr "Edycja zablokowana" - -#: libs/ardour/utils.cc:374 -msgid "programming error: unknown edit mode string \"%1\"" -msgstr "" - -#: libs/ardour/utils.cc:398 -#: libs/ardour/utils.cc:427 -msgid "Internal" -msgstr "Wew." - -#: libs/ardour/utils.cc:402 -#: libs/ardour/utils.cc:423 -msgid "MTC" -msgstr "MTC" - -#: libs/ardour/utils.cc:406 -#: libs/ardour/utils.cc:420 -msgid "JACK" -msgstr "JACK" - -#: libs/ardour/utils.cc:410 -msgid "programming error: unknown slave source string \"%1\"" -msgstr "" - -#: libs/ardour/vst_plugin.cc:167 -msgid "cannot create VST chunk directory: %1" -msgstr "" - -#: libs/ardour/vst_plugin.cc:175 -msgid "cannot check VST chunk directory: %1" -msgstr "" - -#: libs/ardour/vst_plugin.cc:181 -msgid "%1 exists but is not a directory" -msgstr "" - -#: libs/ardour/vst_plugin.cc:219 -msgid "Bad node sent to VSTPlugin::set_state" -msgstr "" - -#: libs/ardour/vst_plugin.cc:323 -#: libs/ardour/vst_plugin.cc:334 -msgid "no support for presets using chunks at this time" -msgstr "" - -#: libs/ardour/vst_plugin.cc:486 -msgid "VST: cannot load module from \"%1\"" -msgstr "" - -#: libs/ardour/vst_plugin.cc:491 -msgid "You asked ardour to not use any VST plugins" -msgstr "" - -#: libs/ardour/coreaudiosource.cc:80 -msgid "CoreAudioSource: cannot open file \"%1\" for %2" -msgstr "" - -#: libs/ardour/rb_effect.cc:155 -#: libs/ardour/rb_effect.cc:193 -msgid "tempoize: error reading data from %1 at %2 (wanted %3, got %4)" -msgstr "" - -#: libs/ardour/rb_effect.cc:218 -#: libs/ardour/rb_effect.cc:235 -msgid "error writing tempo-adjusted data to %1" -msgstr "" - -#: libs/ardour/rb_effect.cc:242 -msgid "timefx code failure. please notify ardour-developers." -msgstr "" - -#: libs/ardour/audio_unit.cc:104 -msgid "AudioUnit: Could not convert CAComponent to CAAudioUnit" -msgstr "" - -#: libs/ardour/audio_unit.cc:147 -msgid "AUPlugin: cannot set processing block size" -msgstr "" - -#: libs/ardour/audio_unit.cc:351 -msgid "AUPlugin: %1 cannot initialize plugin (err = %2)" -msgstr "" - -#: libs/ardour/audio_unit.cc:431 -msgid "AUPlugin: could not set stream format for %1/%2 (err = %3)" -msgstr "" - -#: libs/ardour/audio_unit.cc:476 -msgid "AUPlugin: %1 output_streams() called without any format set!" -msgstr "" - -#: libs/ardour/audio_unit.cc:488 -msgid "AUPlugin: input_streams() called without any format set!" -msgstr "" - -#: libs/ardour/audio_unit.cc:504 -msgid "AUPlugin: render callback called illegally!" -msgstr "" - -#~ msgid "%s/out %u" -#~ msgstr "%s/wyjÅ›cie %u" -#~ msgid "%s/in" -#~ msgstr "%s/wejÅ›cie" - diff --git a/libs/ardour/po/ru_RU.po b/libs/ardour/po/ru_RU.po deleted file mode 100644 index aeeb1bf547..0000000000 --- a/libs/ardour/po/ru_RU.po +++ /dev/null @@ -1,2000 +0,0 @@ -# Copyright (C) 2004 Paul Davis -# This file is distributed under the same license as the libardour package. -# Igor Blinov pitstop@nm.ru, 2004. -# -msgid "" -msgstr "" -"Project-Id-Version: libardour 0.716.1\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2006-06-29 21:03-0400\n" -"PO-Revision-Date: 2004-03-31 00:55+0300\n" -"Last-Translator: Igor Blinov pitstop@nm.ru\n" -"Language-Team: Russian\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=koi8-r\n" -"Content-Transfer-Encoding: 8bit\n" - -#: libs/ardour/audio_diskstream.cc:337 -msgid "AudioDiskstream: Session doesn't know about a Playlist called \"%1\"" -msgstr "" - -#: libs/ardour/audio_diskstream.cc:342 -msgid "AudioDiskstream: Playlist \"%1\" isn't an audio playlist" -msgstr "" - -#: libs/ardour/audio_diskstream.cc:433 -msgid "AudioDiskstream %1: there is no existing playlist to make a copy of!" -msgstr "" - -#: libs/ardour/audio_diskstream.cc:1114 libs/ardour/audio_diskstream.cc:1125 -msgid "" -"AudioDiskstream %1: when refilling, cannot read %2 from playlist at frame %3" -msgstr "" - -#: libs/ardour/audio_diskstream.cc:1254 -msgid "AudioDiskstream %1: cannot read %2 from playlist at frame %3" -msgstr "" - -#: libs/ardour/audio_diskstream.cc:1621 libs/ardour/audio_diskstream.cc:1638 -msgid "AudioDiskstream %1: cannot write to disk" -msgstr "" - -#: libs/ardour/audio_diskstream.cc:1698 -msgid "AudioDiskstream \"%1\": cannot flush captured data to disk!" -msgstr "" - -#: libs/ardour/audio_diskstream.cc:1796 -msgid "%1: could not create region for complete audio file" -msgstr "" - -#: libs/ardour/audio_diskstream.cc:1819 -msgid "AudioDiskstream: could not create region for captured audio!" -msgstr "" - -#: libs/ardour/audio_diskstream.cc:1874 -#, fuzzy -msgid "programmer error: %1" -msgstr "ÏÛÉÂËÁ ÐÒÏÇÒÁÍÍÙ: " - -#: libs/ardour/audio_diskstream.cc:2146 -msgid "AudioDiskstream: channel %1 out of range" -msgstr "" - -#: libs/ardour/audio_diskstream.cc:2171 -msgid "%1:%2 new capture file not initialized correctly" -msgstr "" - -#: libs/ardour/audio_diskstream.cc:2404 -msgid "Location \"%1\" not valid for track loop (start >= end)" -msgstr "" - -#: libs/ardour/audio_diskstream.cc:2485 -msgid "%1: cannot restore pending capture source file %2" -msgstr "" - -#: libs/ardour/audio_diskstream.cc:2507 -msgid "%1: incorrect number of pending sources listed - ignoring them all" -msgstr "" - -#: libs/ardour/audio_diskstream.cc:2523 -msgid "%1: cannot create whole-file region from pending capture sources" -msgstr "" - -#: libs/ardour/audio_diskstream.cc:2535 -msgid "%1: cannot create region from pending capture sources" -msgstr "" - -#: libs/ardour/audio_library.cc:92 -msgid "channels" -msgstr "" - -#: libs/ardour/audio_library.cc:93 -#, fuzzy -msgid "samplerate" -msgstr "ÒÁÚÄÅÌÉÔØ" - -#: libs/ardour/audio_library.cc:94 -msgid "resolution" -msgstr "" - -#: libs/ardour/audio_library.cc:95 -msgid "format" -msgstr "" - -#: libs/ardour/audio_library.cc:102 -msgid "Could not open %1. Audio Library not saved" -msgstr "" - -#: libs/ardour/audio_playlist.cc:53 libs/ardour/audio_playlist.cc:63 -#: libs/ardour/audio_playlist.cc:74 libs/ardour/audio_playlist.cc:121 -#: libs/ardour/insert.cc:76 libs/ardour/insert.cc:95 libs/ardour/insert.cc:120 -#: libs/ardour/insert.cc:838 libs/ardour/insert.cc:846 libs/ardour/send.cc:39 -#: libs/ardour/send.cc:53 libs/ardour/send.cc:62 -#: libs/ardour/session_state.cc:1621 libs/ardour/session_state.cc:1667 -msgid "initial state" -msgstr "" - -#: libs/ardour/audio_playlist.cc:275 libs/ardour/audio_playlist.cc:769 -msgid "" -"programming error: non-audio Region passed to remove_overlap in audio " -"playlist" -msgstr "" - -#: libs/ardour/audio_playlist.cc:402 -msgid "" -"programming error: non-audio Region tested for overlap in audio playlist" -msgstr "" - -#: libs/ardour/audio_playlist.cc:878 -msgid "xfade change" -msgstr "" - -#: libs/ardour/audio_playlist.cc:933 -msgid "region modified" -msgstr "" - -#: libs/ardour/audio_track.cc:125 libs/ardour/io.cc:1716 -#: libs/ardour/io.cc:1826 -msgid "Unknown connection \"%1\" listed for input of %2" -msgstr "" - -#: libs/ardour/audio_track.cc:127 libs/ardour/io.cc:1718 -#: libs/ardour/io.cc:1828 -msgid "in 1" -msgstr "" - -#: libs/ardour/audio_track.cc:128 libs/ardour/io.cc:1719 -#: libs/ardour/io.cc:1829 -msgid "No input connections available as a replacement" -msgstr "" - -#: libs/ardour/audio_track.cc:132 libs/ardour/io.cc:1723 -#: libs/ardour/io.cc:1833 -msgid "Connection %1 was not available - \"in 1\" used instead" -msgstr "" - -#: libs/ardour/audio_track.cc:141 libs/ardour/io.cc:1842 -msgid "improper input channel list in XML node (%1)" -msgstr "" - -#: libs/ardour/audio_track.cc:186 libs/ardour/audio_track.cc:199 -msgid "AudioTrack: diskstream \"%1\" not known by session" -msgstr "" - -#: libs/ardour/audio_track.cc:297 -msgid "" -"MIDI rec_enable control specification for %1 is incomplete, so it has been " -"ignored" -msgstr "" - -#: libs/ardour/audio_track.cc:309 -msgid "programming error: AudioTrack given state without diskstream!" -msgstr "" - -#: libs/ardour/audioengine.cc:144 -msgid "cannot activate JACK client" -msgstr "ÎÅ ÕÄÁÌÏÓØ ÁËÔÉ×ÉÒÏ×ÁÔØ ËÌÉÅÎÔÁ JACK ÓÅÒ×ÅÒÁ" - -#: libs/ardour/audioengine.cc:395 -msgid "register audio input port called before engine was started" -msgstr "" - -#: libs/ardour/audioengine.cc:426 -msgid "register audio output port called before engine was started" -msgstr "" - -#: libs/ardour/audioengine.cc:487 -msgid "connect called before engine was started" -msgstr "" - -#: libs/ardour/audioengine.cc:503 -msgid "AudioEngine: cannot connect %1 (%2) to %3 (%4)" -msgstr "" - -#: libs/ardour/audioengine.cc:516 libs/ardour/audioengine.cc:545 -msgid "disconnect called before engine was started" -msgstr "" - -#: libs/ardour/audioengine.cc:603 -msgid "get_port_by_name() called before engine was started" -msgstr "" - -#: libs/ardour/audioengine.cc:636 -msgid "get_ports called before engine was started" -msgstr "" - -#: libs/ardour/audioengine.cc:711 -msgid "get_nth_physical called before engine was started" -msgstr "" - -#: libs/ardour/audioengine.cc:739 -msgid "get_port_total_latency() called with no JACK client connection" -msgstr "" - -#: libs/ardour/audioengine.cc:745 -msgid "get_port_total_latency() called before engine was started" -msgstr "" - -#: libs/ardour/audioengine.cc:869 -msgid "Unable to connect to JACK server" -msgstr "" - -#: libs/ardour/audioengine.cc:872 -msgid "Could not connect to JACK server as \"%1\"" -msgstr "" - -#: libs/ardour/audioengine.cc:877 -msgid "JACK server started" -msgstr "" - -#: libs/ardour/audioengine.cc:911 -msgid "cannot shutdown connection to JACK" -msgstr "" - -#: libs/ardour/audioengine.cc:936 -msgid "failed to connect to JACK" -msgstr "" - -#: libs/ardour/audioengine.cc:952 -msgid "could not reregister %1" -msgstr "" - -#: libs/ardour/audioengine.cc:1009 -msgid "could not reconnect %1 and %2 (err = %3)" -msgstr "" - -#: libs/ardour/audiofilesource.cc:444 libs/ardour/session_state.cc:3095 -msgid "" -"there are already 1000 files with names like %1; versioning discontinued" -msgstr "" - -#: libs/ardour/audiofilesource.cc:458 libs/ardour/session_state.cc:3109 -msgid "cannot rename audio file source from %1 to %2 (%3)" -msgstr "" - -#: libs/ardour/audiofilesource.cc:465 libs/ardour/session_state.cc:3124 -msgid "cannot remove peakfile %1 for %2 (%3)" -msgstr "" - -#: libs/ardour/audiofilesource.cc:509 -msgid "FileSource: search path not set" -msgstr "" - -#: libs/ardour/audiofilesource.cc:533 -msgid "" -"FileSource: \"%1\" is ambigous when searching %2\n" -"\t" -msgstr "" - -#: libs/ardour/audiofilesource.cc:539 -msgid "Filesource: cannot find required file (%1): while searching %2" -msgstr "" - -#: libs/ardour/audiofilesource.cc:562 -msgid "Filesource: cannot find required file (%1): %2" -msgstr "" - -#: libs/ardour/audiofilesource.cc:567 -msgid "Filesource: cannot check for existing file (%1): %2" -msgstr "" - -#: libs/ardour/audiofilesource.cc:636 libs/ardour/insert.cc:525 -#: libs/ardour/sndfilesource.cc:113 -#, fuzzy -msgid "programming error: %1" -msgstr "ÏÛÉÂËÁ ÐÒÏÇÒÁÍÍÙ: " - -#: libs/ardour/audiofilesource.cc:641 -msgid "cannot rename audio file for %1 to %2" -msgstr "" - -#: libs/ardour/audiofilter.cc:45 -msgid "audiofilter: error creating name for new audio file based on %1" -msgstr "" - -#: libs/ardour/audiofilter.cc:58 -msgid "audiofilter: error creating new audio file %1 (%2)" -msgstr "" - -#: libs/ardour/audioregion.cc:857 libs/ardour/audioregion.cc:919 -msgid "fade in change" -msgstr "" - -#: libs/ardour/audioregion.cc:1349 -#, c-format -msgid "normalized to %.2fdB" -msgstr "" - -#: libs/ardour/audioregion.cc:1367 -msgid "envelope change" -msgstr "" - -#: libs/ardour/audiosource.cc:143 -msgid "poll on peak request pipe failed (%1)" -msgstr "" - -#: libs/ardour/audiosource.cc:150 -msgid "Error on peak thread request pipe" -msgstr "" - -#: libs/ardour/audiosource.cc:183 -msgid "Error reading from peak request pipe" -msgstr "" - -#: libs/ardour/audiosource.cc:215 libs/ardour/session_butler.cc:80 -#: libs/ardour/session_midi.cc:1183 -msgid "Cannot create transport request signal pipe (%1)" -msgstr "" - -#: libs/ardour/audiosource.cc:220 libs/ardour/audiosource.cc:225 -msgid "UI: cannot set O_NONBLOCK on peak request pipe (%1)" -msgstr "" - -#: libs/ardour/audiosource.cc:230 -msgid "AudioSource: could not create peak thread" -msgstr "" - -#: libs/ardour/audiosource.cc:308 -msgid "cannot rename peakfile for %1 from %2 to %3 (%4)" -msgstr "" - -#: libs/ardour/audiosource.cc:350 -#, fuzzy -msgid "AudioSource: cannot stat peakfile \"%1\"" -msgstr "Ardour: ÎÅ ÕÄÁÌÏÓØ ÐÒÏÞÉÔÁÔØ ÆÁÊÌ ËÏÎÆÉÇÕÒÁÃÉÉ ÐÏÌØÚÏ×ÁÔÅÌÑ \"%1\"" - -#: libs/ardour/audiosource.cc:451 -msgid "cannot read sample data for unscaled peak computation" -msgstr "" - -#: libs/ardour/audiosource.cc:472 libs/ardour/audiosource.cc:543 -#: libs/ardour/audiosource.cc:787 libs/ardour/audiosource.cc:878 -#, fuzzy -msgid "AudioSource: cannot open peakpath \"%1\" (%2)" -msgstr "LADSPA: ÎÅ ÕÄÁÌÏÓØ ÚÁÇÒÕÚÉÔØ ÍÏÄÕÌØ \"%1\" (%2)" - -#: libs/ardour/audiosource.cc:644 -msgid "AudioSource[%1]: peak read - cannot read %2 samples at offset %3" -msgstr "" - -#: libs/ardour/audiosource.cc:798 -msgid "%1: could not write read raw data for peak computation (%2)" -msgstr "" - -#: libs/ardour/audiosource.cc:823 -msgid "%1: could not write peak file data (%2)" -msgstr "" - -#: libs/ardour/automation_event.cc:65 libs/ardour/location.cc:345 -#: libs/ardour/tempo.cc:226 -msgid "initial" -msgstr "" - -#: libs/ardour/automation_event.cc:232 -msgid "cleared" -msgstr "" - -#: libs/ardour/automation_event.cc:404 -msgid "added event" -msgstr "" - -#: libs/ardour/automation_event.cc:421 -#, fuzzy -msgid "removed event" -msgstr "ÕÄÁÌÉÔØ ÏÂÌÁÓÔØ" - -#: libs/ardour/automation_event.cc:436 -msgid "removed multiple events" -msgstr "" - -#: libs/ardour/automation_event.cc:467 libs/ardour/automation_event.cc:498 -#, fuzzy -msgid "removed range" -msgstr "ÕÄÁÌÉÔØ ÏÂÌÁÓÔØ" - -#: libs/ardour/automation_event.cc:528 -msgid "event range adjusted" -msgstr "" - -#: libs/ardour/automation_event.cc:550 -msgid "event adjusted" -msgstr "" - -#: libs/ardour/automation_event.cc:665 libs/ardour/automation_event.cc:770 -#: libs/ardour/panner.cc:1041 -#, fuzzy -msgid "programming error:" -msgstr "ÏÛÉÂËÁ ÐÒÏÇÒÁÍÍÙ: " - -#: libs/ardour/automation_event.cc:1079 -msgid "cut/copy/clear" -msgstr "" - -#: libs/ardour/automation_event.cc:1112 -msgid "copy" -msgstr "" - -#: libs/ardour/automation_event.cc:1180 libs/ardour/playlist.cc:939 -msgid "paste" -msgstr "×ÓÔÁ×ÉÔØ" - -#: libs/ardour/automation_event.cc:1235 -msgid "" -"automation list: no x-coordinate stored for control point (point ignored)" -msgstr "" - -#: libs/ardour/automation_event.cc:1241 -msgid "" -"automation list: no y-coordinate stored for control point (point ignored)" -msgstr "" - -#: libs/ardour/configuration.cc:80 -#, fuzzy -msgid "loading system configuration file %1" -msgstr "Ardour: ÎÅ ÕÄÁÌÏÓØ ÐÒÏÞÉÔÁÔØ ÆÁÊÌ ËÏÎÆÉÇÕÒÁÃÉÉ ÐÒÏÇÒÁÍÍÙ \"%1\"" - -#: libs/ardour/configuration.cc:83 -msgid "Ardour: cannot read system configuration file \"%1\"" -msgstr "Ardour: ÎÅ ÕÄÁÌÏÓØ ÐÒÏÞÉÔÁÔØ ÆÁÊÌ ËÏÎÆÉÇÕÒÁÃÉÉ ÐÒÏÇÒÁÍÍÙ \"%1\"" - -#: libs/ardour/configuration.cc:88 -msgid "Ardour: system configuration file \"%1\" not loaded successfully." -msgstr "Ardour: ÎÅ ÕÄÁÌÏÓØ ÚÁÇÒÕÚÉÔØ ÆÁÊÌ ËÏÎÆÉÇÕÒÁÃÉÉ ÐÒÏÇÒÁÍÍÙ \"%1\"." - -#: libs/ardour/configuration.cc:105 -#, fuzzy -msgid "loading user configuration file %1" -msgstr "Ardour: ÎÅ ÕÄÁÌÏÓØ ÐÒÏÞÉÔÁÔØ ÆÁÊÌ ËÏÎÆÉÇÕÒÁÃÉÉ ÐÏÌØÚÏ×ÁÔÅÌÑ \"%1\"" - -#: libs/ardour/configuration.cc:108 -msgid "Ardour: cannot read configuration file \"%1\"" -msgstr "Ardour: ÎÅ ÕÄÁÌÏÓØ ÐÒÏÞÉÔÁÔØ ÆÁÊÌ ËÏÎÆÉÇÕÒÁÃÉÉ ÐÏÌØÚÏ×ÁÔÅÌÑ \"%1\"" - -#: libs/ardour/configuration.cc:113 -#, fuzzy -msgid "Ardour: user configuration file \"%1\" not loaded successfully." -msgstr "Ardour: ÎÅ ÕÄÁÌÏÓØ ÚÁÇÒÕÚÉÔØ ÆÁÊÌ ËÏÎÆÉÇÕÒÁÃÉÉ ÐÏÌØÚÏ×ÁÔÅÌÑ \"%1\"." - -#: libs/ardour/configuration.cc:137 -#, fuzzy -msgid "Config file %1 not saved" -msgstr "æÁÊÌ ËÏÎÆÉÇÕÒÁÃÉÉ ÎÅ ÓÏÈÒÁΣÎ" - -#: libs/ardour/configuration.cc:210 -msgid "ill-formed MIDI port specification in ardour rcfile (ignored)" -msgstr "" - -#: libs/ardour/connection.cc:183 -msgid "Node for Connection has no \"name\" property" -msgstr "" - -#: libs/ardour/connection.cc:191 -msgid "Node for Connection has no \"connections\" property" -msgstr "" - -#: libs/ardour/connection.cc:227 libs/ardour/io.cc:1902 -msgid "IO: badly formed string in XML node for inputs \"%1\"" -msgstr "" - -#: libs/ardour/connection.cc:232 libs/ardour/io.cc:1907 -msgid "bad input string in XML node \"%1\"" -msgstr "" - -#: libs/ardour/control_protocol_manager.cc:80 -msgid "control protocol name \"%1\" has no descriptor" -msgstr "" - -#: libs/ardour/control_protocol_manager.cc:85 -msgid "control protocol name \"%1\" could not be initialized" -msgstr "" - -#: libs/ardour/control_protocol_manager.cc:141 -msgid "Instantiating mandatory control protocol %1" -msgstr "" - -#: libs/ardour/control_protocol_manager.cc:175 -msgid "Control protocol %1 not usable" -msgstr "" - -#: libs/ardour/control_protocol_manager.cc:187 -msgid "Control surface protocol discovered: \"%1\"" -msgstr "" - -#: libs/ardour/control_protocol_manager.cc:205 -#, fuzzy -msgid "ControlProtocolManager: cannot load module \"%1\" (%2)" -msgstr "LADSPA: ÎÅ ÕÄÁÌÏÓØ ÚÁÇÒÕÚÉÔØ ÍÏÄÕÌØ \"%1\" (%2)" - -#: libs/ardour/control_protocol_manager.cc:213 -msgid "ControlProtocolManager: module \"%1\" has no descriptor function." -msgstr "" - -#: libs/ardour/crossfade.cc:121 -msgid "Crossfade: no \"in\" region in state" -msgstr "" - -#: libs/ardour/crossfade.cc:128 -msgid "Crossfade: no \"in\" region %1 found in playlist %2" -msgstr "" - -#: libs/ardour/crossfade.cc:138 -msgid "Crossfade: no \"out\" region in state" -msgstr "" - -#: libs/ardour/crossfade.cc:145 -msgid "Crossfade: no \"out\" region %1 found in playlist %2" -msgstr "" - -#: libs/ardour/crossfade.cc:492 -msgid "active changed" -msgstr "" - -#: libs/ardour/crossfade.cc:741 -msgid "old-style crossfade information - no position information" -msgstr "" - -#: libs/ardour/curve.cc:112 libs/ardour/globals.cc:340 -#: libs/ardour/insert.cc:454 libs/ardour/session.cc:2466 -#: libs/ardour/session.cc:2518 -msgid "programming error: " -msgstr "ÏÛÉÂËÁ ÐÒÏÇÒÁÍÍÙ: " - -#: libs/ardour/cycle_timer.cc:37 -msgid "CycleTimer::get_mhz(): can't open /proc/cpuinfo" -msgstr "" - -#: libs/ardour/cycle_timer.cc:49 -msgid "CycleTimer::get_mhz(): cannot locate cpu MHz in /proc/cpuinfo" -msgstr "" - -#: libs/ardour/cycle_timer.cc:72 -msgid "cannot locate cpu MHz in /proc/cpuinfo" -msgstr "" - -#: libs/ardour/destructive_filesource.cc:188 -msgid "DestructiveFileSource: \"%1\" bad read retval: %2 of %5 (%3: %4)" -msgstr "" - -#: libs/ardour/destructive_filesource.cc:201 -#: libs/ardour/destructive_filesource.cc:243 -#: libs/ardour/destructive_filesource.cc:250 -msgid "DestructiveFileSource: \"%1\" bad write (%2)" -msgstr "" - -#: libs/ardour/globals.cc:109 -msgid "no MIDI ports specified: no MMC or MTC control possible" -msgstr "" - -#: libs/ardour/globals.cc:124 -msgid "MIDI port specifications for \"%1\" are not understandable." -msgstr "" - -#: libs/ardour/globals.cc:137 libs/ardour/globals.cc:141 -#: libs/ardour/globals.cc:145 -msgid "default" -msgstr "" - -#: libs/ardour/globals.cc:173 -msgid "No MMC control (MIDI port \"%1\" not available)" -msgstr "" - -#: libs/ardour/globals.cc:179 -msgid "No MTC support (MIDI port \"%1\" not available)" -msgstr "" - -#: libs/ardour/globals.cc:184 -msgid "No MIDI parameter support (MIDI port \"%1\" not available)" -msgstr "" - -#: libs/ardour/import.cc:75 -msgid "Import: cannot open input sound file \"%1\"" -msgstr "" - -#: libs/ardour/import.cc:80 -msgid "resampling audio" -msgstr "" - -#: libs/ardour/import.cc:84 -msgid "Import: cannot open converted sound file \"%1\"" -msgstr "" - -#: libs/ardour/import.cc:89 -msgid "Import: error while resampling sound file \"%1\"" -msgstr "" - -#: libs/ardour/import.cc:148 -msgid "Session::import_audiofile: cannot open new file source for channel %1" -msgstr "" - -#: libs/ardour/import.cc:167 -msgid "converting audio" -msgstr "" - -#: libs/ardour/import.cc:199 -msgid "building region" -msgstr "" - -#: libs/ardour/import.cc:201 -msgid "building regions" -msgstr "" - -#: libs/ardour/import.cc:325 -msgid "Import: could not open temp file: %1" -msgstr "" - -#: libs/ardour/import.cc:334 -msgid "Import: src_new() failed : %1" -msgstr "" - -#: libs/ardour/import.cc:362 -msgid "Import: %1" -msgstr "éÍÐÏÒÔ: %1" - -#: libs/ardour/insert.cc:644 libs/ardour/insert.cc:936 -msgid "XML node describing insert is missing the `type' field" -msgstr "" - -#: libs/ardour/insert.cc:653 -msgid "unknown plugin type %1 in plugin insert state" -msgstr "" - -#: libs/ardour/insert.cc:665 -msgid "XML node describing insert is missing the `id' field" -msgstr "" - -#: libs/ardour/insert.cc:678 -msgid "" -"Found a reference to a plugin (\"%1\") that is unknown.\n" -"Perhaps it was removed or moved since it was last used." -msgstr "" - -#: libs/ardour/insert.cc:716 libs/ardour/insert.cc:953 -msgid "XML node describing insert is missing a Redirect node" -msgstr "" - -#: libs/ardour/insert.cc:721 -msgid "XML node describing a plugin insert is missing the `%1' information" -msgstr "" - -#: libs/ardour/insert.cc:745 -msgid "PluginInsert: Auto: no ladspa port number" -msgstr "" - -#: libs/ardour/insert.cc:752 -msgid "PluginInsert: Auto: port id out of range" -msgstr "" - -#: libs/ardour/insert.cc:768 -msgid "XML node describing a port automation is missing the `%1' information" -msgstr "" - -#: libs/ardour/insert.cc:854 -msgid "PortInsert: cannot add input port" -msgstr "" - -#: libs/ardour/insert.cc:859 -msgid "PortInsert: cannot add output port" -msgstr "" - -#: libs/ardour/insert.cc:941 -msgid "non-port insert XML used for port plugin insert" -msgstr "" - -#: libs/ardour/io.cc:598 -msgid "IO: cannot disconnect input port %1 from %2" -msgstr "" - -#: libs/ardour/io.cc:666 -msgid "IO: cannot disconnect output port %1 from %2" -msgstr "" - -#: libs/ardour/io.cc:807 libs/ardour/io.cc:1151 libs/ardour/io.cc:1277 -#, c-format -msgid "%s/out" -msgstr "" - -#: libs/ardour/io.cc:809 libs/ardour/io.cc:1153 libs/ardour/io.cc:1279 -#: libs/ardour/io.cc:2849 -#, c-format -msgid "%s/out %u" -msgstr "" - -#: libs/ardour/io.cc:813 libs/ardour/io.cc:1158 libs/ardour/io.cc:1283 -msgid "IO: cannot register output port %1" -msgstr "" - -#: libs/ardour/io.cc:908 libs/ardour/io.cc:1011 libs/ardour/io.cc:1117 -#, c-format -msgid "%s/in" -msgstr "" - -#: libs/ardour/io.cc:910 libs/ardour/io.cc:1014 libs/ardour/io.cc:1120 -#: libs/ardour/io.cc:2819 -#, c-format -msgid "%s/in %u" -msgstr "" - -#: libs/ardour/io.cc:914 libs/ardour/io.cc:1020 libs/ardour/io.cc:1125 -msgid "IO: cannot register input port %1" -msgstr "" - -#: libs/ardour/io.cc:1541 -msgid "IO::connecting_became_legal() called without a pending state node" -msgstr "" - -#: libs/ardour/io.cc:1564 -msgid "IO::ports_became_legal() called without a pending state node" -msgstr "" - -#: libs/ardour/io.cc:1594 -msgid "incorrect XML node \"%1\" passed to IO object" -msgstr "" - -#: libs/ardour/io.cc:1649 -msgid "" -"MIDI gain control specification for %1 is incomplete, so it has been ignored" -msgstr "" - -#: libs/ardour/io.cc:1739 libs/ardour/io.cc:1851 -msgid "Unknown connection \"%1\" listed for output of %2" -msgstr "" - -#: libs/ardour/io.cc:1741 libs/ardour/io.cc:1853 -msgid "out 1" -msgstr "" - -#: libs/ardour/io.cc:1742 libs/ardour/io.cc:1854 -msgid "No output connections available as a replacement" -msgstr "" - -#: libs/ardour/io.cc:1746 libs/ardour/io.cc:1858 -msgid "Connection %1 was not available - \"out 1\" used instead" -msgstr "" - -#: libs/ardour/io.cc:1760 -msgid "%1: cannot create I/O ports" -msgstr "" - -#: libs/ardour/io.cc:1867 -msgid "improper output channel list in XML node (%1)" -msgstr "" - -#: libs/ardour/io.cc:1952 -msgid "IO: badly formed string in XML node for outputs \"%1\"" -msgstr "" - -#: libs/ardour/io.cc:1957 -msgid "IO: bad output string in XML node \"%1\"" -msgstr "" - -#: libs/ardour/io.cc:2525 -msgid "%1: could not open automation event file \"%2\"" -msgstr "" - -#: libs/ardour/io.cc:2564 -msgid "%1: cannot open automation event file \"%2\"" -msgstr "" - -#: libs/ardour/io.cc:2579 -msgid "badly formed version number in automation event file \"%1\"" -msgstr "" - -#: libs/ardour/io.cc:2583 -msgid "no version information in automation event file \"%1\"" -msgstr "" - -#: libs/ardour/io.cc:2588 -msgid "mismatched automation event file version (%1)" -msgstr "" - -#: libs/ardour/io.cc:2596 -msgid "badly formatted automation event record at line %1 of %2 (ignored)" -msgstr "" - -#: libs/ardour/io.cc:2616 -msgid "dubious automation event found (and ignored)" -msgstr "" - -#: libs/ardour/io.cc:2620 libs/ardour/panner.cc:438 -#: libs/ardour/redirect.cc:148 -msgid "loaded from disk" -msgstr "" - -#: libs/ardour/io.cc:2791 -msgid "automation write/touch" -msgstr "" - -#: libs/ardour/ladspa_plugin.cc:87 -msgid "LADSPA: module has no descriptor function." -msgstr "" - -#: libs/ardour/ladspa_plugin.cc:92 -msgid "LADSPA: plugin has gone away since discovery!" -msgstr "" - -#: libs/ardour/ladspa_plugin.cc:99 -msgid "LADSPA: \"%1\" cannot be used, since it cannot do inplace processing" -msgstr "" - -#: libs/ardour/ladspa_plugin.cc:329 -msgid "" -"illegal parameter number used with plugin \"%1\". This mayindicate a change " -"in the plugin design, and presets may beinvalid" -msgstr "" - -#: libs/ardour/ladspa_plugin.cc:430 -msgid "Bad node sent to LadspaPlugin::set_state" -msgstr "" - -#: libs/ardour/ladspa_plugin.cc:443 -msgid "LADSPA: no ladspa port number" -msgstr "" - -#: libs/ardour/ladspa_plugin.cc:449 -msgid "LADSPA: no ladspa port data" -msgstr "" - -#: libs/ardour/ladspa_plugin.cc:498 -msgid "" -"LADSPA LadspaPlugin MIDI control specification for port %1 is incomplete, so " -"it has been ignored" -msgstr "" - -#: libs/ardour/location.cc:269 -msgid "incorrect XML node passed to Location::set_state" -msgstr "" - -#: libs/ardour/location.cc:276 -msgid "XML node for Location has no name information" -msgstr "" - -#: libs/ardour/location.cc:283 -msgid "XML node for Location has no start information" -msgstr "" - -#: libs/ardour/location.cc:294 -msgid "XML node for Location has no end information" -msgstr "" - -#: libs/ardour/location.cc:303 -msgid "XML node for Location has no flags information" -msgstr "" - -#: libs/ardour/location.cc:391 -msgid "Locations: attempt to use unknown location as selected location" -msgstr "" - -#: libs/ardour/location.cc:418 libs/ardour/playlist.cc:1187 -msgid "clear" -msgstr "" - -#: libs/ardour/location.cc:443 -msgid "clear markers" -msgstr "" - -#: libs/ardour/location.cc:471 -msgid "clear ranges" -msgstr "" - -#: libs/ardour/location.cc:489 -msgid "add" -msgstr "ÄÏÂÁ×ÉÔØ" - -#: libs/ardour/location.cc:527 -msgid "remove" -msgstr "ÕÄÁÌÉÔØ" - -#: libs/ardour/location.cc:567 -msgid "incorrect XML mode passed to Locations::set_state" -msgstr "" - -#: libs/ardour/mtc_slave.cc:196 -msgid "MTC Slave: atomic read of current time failed, sleeping!" -msgstr "" - -#: libs/ardour/named_selection.cc:77 -msgid "Chunk %1 uses an unknown playlist \"%2\"" -msgstr "" - -#: libs/ardour/named_selection.cc:80 -msgid "Chunk %1 contains misformed playlist information" -msgstr "" - -#: libs/ardour/panner.cc:256 -msgid "MIDI pan control specification is incomplete, so it has been ignored" -msgstr "" - -#: libs/ardour/panner.cc:361 -msgid "automation write pass" -msgstr "" - -#: libs/ardour/panner.cc:401 -#, c-format -msgid "error writing pan automation file (%s)" -msgstr "" - -#: libs/ardour/panner.cc:429 -msgid "" -"badly formatted pan automation event record at line %1 of %2 (ignored) [%3]" -msgstr "" - -#: libs/ardour/panner.cc:944 -msgid "badly-formed positional data for Multi2dPanner - ignored" -msgstr "" - -#: libs/ardour/panner.cc:1237 -msgid "cannot open pan automation file \"%1\" for saving (%s)" -msgstr "" - -#: libs/ardour/panner.cc:1273 -msgid "cannot open pan automation file %1 (%2)" -msgstr "" - -#: libs/ardour/panner.cc:1286 -msgid "badly formed version number in pan automation event file \"%1\"" -msgstr "" - -#: libs/ardour/panner.cc:1290 -msgid "" -"no version information in pan automation event file \"%1\" (first line = %2)" -msgstr "" - -#: libs/ardour/panner.cc:1296 -msgid "mismatched pan automation event file version (%1)" -msgstr "" - -#: libs/ardour/panner.cc:1310 -msgid "too many panner states found in pan automation file %1" -msgstr "" - -#: libs/ardour/panner.cc:1451 -msgid "Unknown panner plugin \"%1\" found in pan state - ignored" -msgstr "" - -#: libs/ardour/panner.cc:1457 -msgid "panner plugin node has no type information!" -msgstr "" - -#: libs/ardour/playlist.cc:253 -msgid "playlist const copy constructor called" -msgstr "" - -#: libs/ardour/playlist.cc:259 -msgid "playlist non-const copy constructor called" -msgstr "" - -#: libs/ardour/playlist.cc:499 -msgid "add region" -msgstr "ÄÏÂÁ×ÉÔØ ÏÂÌÁÓÔØ" - -#: libs/ardour/playlist.cc:554 -msgid "replace region" -msgstr "ÚÁÍÅÎÉÔØ ÏÂÌÁÓÔØ" - -#: libs/ardour/playlist.cc:567 -msgid "remove region" -msgstr "ÕÄÁÌÉÔØ ÏÂÌÁÓÔØ" - -#: libs/ardour/playlist.cc:614 -msgid "separate" -msgstr "ÒÁÚÄÅÌÉÔØ" - -#: libs/ardour/playlist.cc:878 -msgid "cut" -msgstr "×ÙÒÅÚÁÔØ" - -#: libs/ardour/playlist.cc:968 -msgid "duplicate" -msgstr "ÒÁÚÍÎÏÖÉÔØ" - -#: libs/ardour/playlist.cc:1023 -msgid "split" -msgstr "ÓËÌÅÉÔØ" - -#: libs/ardour/playlist.cc:1100 -msgid "%1: bounds changed received for region (%2)not in playlist" -msgstr "" - -#: libs/ardour/playlist.cc:1361 -msgid "Playlist: cannot create region from state file" -msgstr "" - -#: libs/ardour/playlist.cc:1721 -msgid "nudged" -msgstr "" - -#: libs/ardour/playlist_factory.cc:49 libs/ardour/playlist_factory.cc:64 -msgid "" -"programming error: Playlist::createRegion called with unknown Region type" -msgstr "" - -#: libs/ardour/playlist_factory.cc:86 -msgid "" -"programming error: Playlist::copyPlaylist called with unknown Playlist type" -msgstr "" - -#: libs/ardour/plugin.cc:328 -msgid "Could not locate HOME. Preset not saved." -msgstr "" - -#: libs/ardour/plugin.cc:338 libs/ardour/plugin.cc:344 -msgid "Could not create %1. Preset not saved. (%2)" -msgstr "" - -#: libs/ardour/plugin.cc:349 -msgid "Error saving presets file %1." -msgstr "" - -#: libs/ardour/plugin_manager.cc:194 -msgid "Could not parse rdf file: %1" -msgstr "" - -#: libs/ardour/plugin_manager.cc:235 -msgid "LADSPA: cannot load module \"%1\" (%2)" -msgstr "LADSPA: ÎÅ ÕÄÁÌÏÓØ ÚÁÇÒÕÚÉÔØ ÍÏÄÕÌØ \"%1\" (%2)" - -#: libs/ardour/plugin_manager.cc:242 -msgid "LADSPA: module \"%1\" has no descriptor function." -msgstr "" - -#: libs/ardour/plugin_manager.cc:297 -#, fuzzy -msgid "VST: cannot load module from \"%1\"" -msgstr "LADSPA: ÎÅ ÕÄÁÌÏÓØ ÚÁÇÒÕÚÉÔØ ÍÏÄÕÌØ \"%1\" (%2)" - -#: libs/ardour/plugin_manager.cc:302 -msgid "You asked ardour to not use any VST plugins" -msgstr "" - -#: libs/ardour/plugin_manager.cc:305 -msgid "This version of ardour has no support for VST plugins" -msgstr "" - -#: libs/ardour/plugin_manager.cc:312 -msgid "LADSPA: cannot load module from \"%1\"" -msgstr "" - -#: libs/ardour/plugin_manager.cc:374 libs/ardour/plugin_manager.cc:386 -msgid "Unknown" -msgstr "" - -#: libs/ardour/plugin_manager.cc:464 -msgid "" -"VST plugin %1 does not support processReplacing, and so cannot be used in " -"ardour at this time" -msgstr "" - -#: libs/ardour/recent_sessions.cc:44 -msgid "cannot open recent session file %1 (%2)" -msgstr "" - -#: libs/ardour/redirect.cc:77 -msgid "programming error: unknown Redirect type in Redirect::Clone!\n" -msgstr "" - -#: libs/ardour/redirect.cc:102 libs/ardour/utils.cc:203 -msgid "pre" -msgstr "ÐÒÅ" - -#: libs/ardour/redirect.cc:104 libs/ardour/utils.cc:206 -msgid "post" -msgstr "ÐÏÓÔ" - -#: libs/ardour/redirect.cc:107 -msgid "Redirect: unknown placement string \"%1\" (ignored)" -msgstr "" - -#: libs/ardour/redirect.cc:125 -msgid "%1: cannot open %2 to load automation data (%3)" -msgstr "" - -#: libs/ardour/redirect.cc:154 -msgid "%1: cannot load automation data from %2" -msgstr "" - -#: libs/ardour/redirect.cc:175 -msgid "%1: cannot open %2 to store automation data (%3)" -msgstr "" - -#: libs/ardour/redirect.cc:194 libs/ardour/redirect.cc:201 -msgid "%1: could not save automation state to %2" -msgstr "" - -#: libs/ardour/redirect.cc:246 -msgid "Could not get state from Redirect (%1). Problem with save_automation" -msgstr "" - -#: libs/ardour/redirect.cc:296 -msgid "incorrect XML node \"%1\" passed to Redirect object" -msgstr "" - -#: libs/ardour/redirect.cc:318 -msgid "%1: Automation node has no path property" -msgstr "" - -#: libs/ardour/redirect.cc:343 -msgid "XML node describing an IO is missing an IO node" -msgstr "" - -#: libs/ardour/redirect.cc:348 -msgid "XML node describing a redirect is missing the `active' field" -msgstr "" - -#: libs/ardour/redirect.cc:358 -msgid "XML node describing a redirect is missing the `placement' field" -msgstr "" - -#: libs/ardour/redirect.cc:467 -msgid "active_changed" -msgstr "" - -#: libs/ardour/region.cc:885 -msgid "Session: XMLNode describing a Region is incomplete (no id)" -msgstr "" - -#: libs/ardour/region.cc:892 -msgid "Session: XMLNode describing a Region is incomplete (no name)" -msgstr "" - -#: libs/ardour/route.cc:79 libs/ardour/session.cc:1554 -#: libs/ardour/session.cc:1560 libs/ardour/session.cc:3093 -msgid "signal" -msgstr "" - -#: libs/ardour/route.cc:1430 -msgid "Could not get state of route. Problem with save_automation" -msgstr "" - -#: libs/ardour/route.cc:1482 -msgid "Send construction failed" -msgstr "" - -#: libs/ardour/route.cc:1504 -msgid "unknown Insert type \"%1\"; ignored" -msgstr "" - -#: libs/ardour/route.cc:1510 -msgid "Insert XML node has no type property" -msgstr "" - -#: libs/ardour/route.cc:1515 -msgid "insert could not be created. Ignored." -msgstr "" - -#: libs/ardour/route.cc:1533 -msgid "Bad node sent to Route::set_state() [%1]" -msgstr "" - -#: libs/ardour/route.cc:1592 -msgid "Route %1: unknown edit group \"%2 in saved state (ignored)" -msgstr "" - -#: libs/ardour/route.cc:1608 libs/ardour/route.cc:1612 -msgid "badly formed order key string in state file! [%1] ... ignored." -msgstr "" - -#: libs/ardour/route.cc:1693 libs/ardour/route.cc:1820 -msgid "[control]" -msgstr "" - -#: libs/ardour/route.cc:1713 -msgid "Route %1: unknown mix group \"%2 in saved state (ignored)" -msgstr "" - -#: libs/ardour/route.cc:1742 libs/ardour/route.cc:1750 -msgid "" -"MIDI mute control specification for %1 is incomplete, so it has been ignored" -msgstr "" - -#: libs/ardour/send.cc:99 -msgid "XML node describing a send is missing a Redirect node" -msgstr "" - -#: libs/ardour/session.cc:103 -msgid "Could not resolve path: %1 (%2)" -msgstr "" - -#: libs/ardour/session.cc:115 -msgid "cannot check session path %1 (%2)" -msgstr "" - -#: libs/ardour/session.cc:145 -msgid "cannot check statefile %1 (%2)" -msgstr "" - -#: libs/ardour/session.cc:181 -msgid "%1 is not an Ardour snapshot file" -msgstr "" - -#: libs/ardour/session.cc:198 -msgid "cannot determine current working directory (%1)" -msgstr "" - -#: libs/ardour/session.cc:215 -msgid "unknown file type for session %1" -msgstr "" - -#: libs/ardour/session.cc:320 -msgid "monitor" -msgstr "ÍÏÎÉÔÏÒ" - -#: libs/ardour/session.cc:327 -msgid "master" -msgstr "ÍÁÓÔÅÒ" - -#: libs/ardour/session.cc:611 -msgid "could not setup Click I/O" -msgstr "" - -#: libs/ardour/session.cc:632 -msgid "cannot setup Click I/O" -msgstr "" - -#: libs/ardour/session.cc:654 -msgid "cannot create Auditioner: no auditioning of regions possible" -msgstr "" - -#: libs/ardour/session.cc:666 -#, c-format -msgid "out %<PRIu32>" -msgstr "" - -#: libs/ardour/session.cc:678 -#, c-format -msgid "in %<PRIu32>" -msgstr "" - -#: libs/ardour/session.cc:692 -#, c-format -msgid "out %<PRIu32>+%<PRIu32>" -msgstr "" - -#: libs/ardour/session.cc:706 -#, c-format -msgid "in %<PRIu32>+%<PRIu32>" -msgstr "" - -#: libs/ardour/session.cc:739 -msgid "cannot setup master inputs" -msgstr "" - -#: libs/ardour/session.cc:747 -msgid "cannot setup master outputs" -msgstr "" - -#: libs/ardour/session.cc:758 -#, fuzzy -msgid "Master Out" -msgstr "ÍÁÓÔÅÒ" - -#: libs/ardour/session.cc:830 -msgid "cannot setup control inputs" -msgstr "" - -#: libs/ardour/session.cc:838 -msgid "cannot set up master outputs" -msgstr "" - -#: libs/ardour/session.cc:1110 -msgid "Session: you can't use that location for auto punch (start <= end)" -msgstr "" - -#: libs/ardour/session.cc:1189 -msgid "Session: you can't use a mark for auto loop" -msgstr "" - -#: libs/ardour/session.cc:1572 -msgid "feedback loop setup between %1 and %2" -msgstr "" - -#: libs/ardour/session.cc:1724 libs/ardour/session.cc:1821 -msgid "cannot configure %1 in/%2 out configuration for new audio track" -msgstr "" - -#: libs/ardour/session.cc:1780 -msgid "Session: could not create new audio track." -msgstr "" - -#: libs/ardour/session.cc:1870 -msgid "Session: could not create new route." -msgstr "" - -#: libs/ardour/session.cc:2354 -msgid "cannot create new name for region \"%1\"" -msgstr "" - -#: libs/ardour/session.cc:2418 -msgid "too many regions with names like %1" -msgstr "" - -#: libs/ardour/session.cc:2883 -msgid "There are already %1 recordings for %2, which I consider too many." -msgstr "" - -#: libs/ardour/session.cc:3258 -msgid "programming error: unknown type of Insert created!" -msgstr "" - -#: libs/ardour/session.cc:3264 -msgid "programming error: unknown type of Redirect created!" -msgstr "" - -#: libs/ardour/session.cc:3287 -msgid "programming error: unknown type of Insert deleted!" -msgstr "" - -#: libs/ardour/session.cc:3293 -msgid "programming error: unknown type of Redirect deleted!" -msgstr "" - -#: libs/ardour/session.cc:3636 -msgid "too many bounced versions of playlist \"%1\"" -msgstr "" - -#: libs/ardour/session.cc:3649 -msgid "cannot create new audio file \"%1\" for %2" -msgstr "" - -#: libs/ardour/session_butler.cc:85 libs/ardour/session_butler.cc:90 -msgid "UI: cannot set O_NONBLOCK on butler request pipe (%1)" -msgstr "" - -#: libs/ardour/session_butler.cc:95 -msgid "Session: could not create butler thread" -msgstr "" - -#: libs/ardour/session_butler.cc:189 -msgid "poll on butler request pipe failed (%1)" -msgstr "" - -#: libs/ardour/session_butler.cc:196 -msgid "Error on butler thread request pipe" -msgstr "" - -#: libs/ardour/session_butler.cc:238 -msgid "Error reading from butler request pipe" -msgstr "" - -#: libs/ardour/session_butler.cc:275 -msgid "Butler read ahead failure on dstream %1" -msgstr "" - -#: libs/ardour/session_butler.cc:319 -msgid "Butler write-behind failure on dstream %1" -msgstr "" - -#: libs/ardour/session_click.cc:158 -msgid "cannot open click soundfile %1 (%2)" -msgstr "" - -#: libs/ardour/session_click.cc:167 -msgid "cannot read data from click soundfile" -msgstr "" - -#: libs/ardour/session_click.cc:192 -msgid "cannot open click emphasis soundfile %1 (%2)" -msgstr "" - -#: libs/ardour/session_click.cc:200 -msgid "cannot read data from click emphasis soundfile" -msgstr "" - -#: libs/ardour/session_events.cc:161 -msgid "Session: cannot have two events of type %1 at the same frame (%2)." -msgstr "" - -#: libs/ardour/session_events.cc:422 -msgid "Programming error: illegal event type in process_event (%1)" -msgstr "" - -#: libs/ardour/session_export.cc:63 -msgid "Export: no output file specified" -msgstr "" - -#: libs/ardour/session_export.cc:164 libs/ardour/session_export.cc:169 -msgid "illegal frame range in export specification" -msgstr "" - -#: libs/ardour/session_export.cc:174 -msgid "Bad data width size. Report me!" -msgstr "" - -#: libs/ardour/session_export.cc:204 -msgid "Export: cannot open output file \"%1\" (%2)" -msgstr "" - -#: libs/ardour/session_export.cc:214 -msgid "cannot initialize sample rate conversion: %1" -msgstr "" - -#: libs/ardour/session_export.cc:316 -msgid "an error occured during sample rate conversion: %1" -msgstr "" - -#: libs/ardour/session_export.cc:327 -msgid "warning, leftover frames overflowed, glitches might occur in output" -msgstr "" - -#: libs/ardour/session_export.cc:418 -msgid "Export: could not write data to output file (%1)" -msgstr "" - -#: libs/ardour/session_export.cc:500 -msgid "%1: cannot seek to %2 for export" -msgstr "" - -#: libs/ardour/session_midi.cc:200 -msgid "Ardour is slaved to MTC - port cannot be reset" -msgstr "" - -#: libs/ardour/session_midi.cc:215 -msgid "unknown port %1 requested for MTC" -msgstr "" - -#: libs/ardour/session_midi.cc:541 -msgid "Error reading from MIDI port %1" -msgstr "" - -#: libs/ardour/session_midi.cc:914 -msgid "Session: could not send full MIDI time code" -msgstr "" - -#: libs/ardour/session_midi.cc:973 -msgid "Session: cannot send quarter-frame MTC message (%1)" -msgstr "" - -#: libs/ardour/session_midi.cc:1081 -msgid "MMC: cannot send command %1%2%3" -msgstr "" - -#: libs/ardour/session_midi.cc:1188 -msgid "UI: cannot set O_NONBLOCK on signal read pipe (%1)" -msgstr "" - -#: libs/ardour/session_midi.cc:1193 -msgid "UI: cannot set O_NONBLOCK on signal write pipe (%1)" -msgstr "" - -#: libs/ardour/session_midi.cc:1198 -msgid "Session: could not create transport thread" -msgstr "" - -#: libs/ardour/session_midi.cc:1227 -msgid "cannot send signal to midi thread! (%1)" -msgstr "" - -#: libs/ardour/session_midi.cc:1322 -msgid "MIDI thread poll failed (%1)" -msgstr "" - -#: libs/ardour/session_midi.cc:1334 -msgid "Error on transport thread request pipe" -msgstr "" - -#: libs/ardour/session_midi.cc:1361 -msgid "Error reading from transport request pipe" -msgstr "" - -#: libs/ardour/session_process.cc:104 -msgid "Session: error in no roll for %1" -msgstr "" - -#: libs/ardour/session_state.cc:101 -msgid "Could not use path %1 (%s)" -msgstr "" - -#: libs/ardour/session_state.cc:129 -msgid "end" -msgstr "" - -#: libs/ardour/session_state.cc:130 -#, fuzzy -msgid "start" -msgstr "ÒÁÚÄÅÌÉÔØ" - -#: libs/ardour/session_state.cc:502 -msgid "Session: cannot create session dir \"%1\" (%2)" -msgstr "" - -#: libs/ardour/session_state.cc:513 -msgid "Session: cannot create session peakfile dir \"%1\" (%2)" -msgstr "" - -#: libs/ardour/session_state.cc:522 -msgid "Session: cannot create session sounds dir \"%1\" (%2)" -msgstr "" - -#: libs/ardour/session_state.cc:531 -msgid "Session: cannot create session tape dir \"%1\" (%2)" -msgstr "" - -#: libs/ardour/session_state.cc:540 -msgid "Session: cannot create session dead sounds dir \"%1\" (%2)" -msgstr "" - -#: libs/ardour/session_state.cc:549 -msgid "Session: cannot create session automation dir \"%1\" (%2)" -msgstr "" - -#: libs/ardour/session_state.cc:580 -msgid "Could not open %1 for writing mix template" -msgstr "" - -#: libs/ardour/session_state.cc:586 -msgid "Could not open mix template %1 for reading" -msgstr "" - -#: libs/ardour/session_state.cc:593 -msgid "Session already exists. Not overwriting" -msgstr "" - -#: libs/ardour/session_state.cc:636 -msgid "Session: could not load diskstream via XML state" -msgstr "" - -#: libs/ardour/session_state.cc:685 -msgid "could not backup old state file, current state not saved." -msgstr "" - -#: libs/ardour/session_state.cc:698 -msgid "state could not be saved to %1" -msgstr "" - -#: libs/ardour/session_state.cc:705 -msgid "could not remove corrupt state file %1" -msgstr "" - -#: libs/ardour/session_state.cc:709 -msgid "could not restore state file from backup %1" -msgstr "" - -#: libs/ardour/session_state.cc:778 -msgid "%1: session state information file \"%2\" doesn't exist!" -msgstr "" - -#: libs/ardour/session_state.cc:789 -msgid "Could not understand ardour file %1" -msgstr "" - -#: libs/ardour/session_state.cc:1493 -msgid "programming error: Session: incorrect XML node sent to set_state()" -msgstr "" - -#: libs/ardour/session_state.cc:1539 -msgid "Session: XML state has no options section" -msgstr "" - -#: libs/ardour/session_state.cc:1544 -msgid "Session: XML state has no sources section" -msgstr "" - -#: libs/ardour/session_state.cc:1551 -msgid "Session: XML state has no Regions section" -msgstr "" - -#: libs/ardour/session_state.cc:1558 -msgid "Session: XML state has no playlists section" -msgstr "" - -#: libs/ardour/session_state.cc:1577 -msgid "Session: XML state has no diskstreams section" -msgstr "" - -#: libs/ardour/session_state.cc:1584 -msgid "Session: XML state has no connections section" -msgstr "" - -#: libs/ardour/session_state.cc:1591 -msgid "Session: XML state has no locations section" -msgstr "" - -#: libs/ardour/session_state.cc:1624 -msgid "Session: XML state has no edit groups section" -msgstr "" - -#: libs/ardour/session_state.cc:1631 -msgid "Session: XML state has no mix groups section" -msgstr "" - -#: libs/ardour/session_state.cc:1638 -msgid "Session: XML state has no Tempo Map section" -msgstr "" - -#: libs/ardour/session_state.cc:1645 -msgid "Session: XML state has no routes section" -msgstr "" - -#: libs/ardour/session_state.cc:1652 -msgid "Session: XML state has no click section" -msgstr "" - -#: libs/ardour/session_state.cc:1697 -msgid "Session: cannot create Route from XML description." -msgstr "" - -#: libs/ardour/session_state.cc:1735 -msgid "Session: cannot create Region from XML description." -msgstr "" - -#: libs/ardour/session_state.cc:1764 -msgid "Session: XMLNode describing a AudioRegion is incomplete (no source)" -msgstr "" - -#: libs/ardour/session_state.cc:1772 libs/ardour/session_state.cc:1792 -msgid "" -"Session: XMLNode describing a AudioRegion references an unknown source id =%1" -msgstr "" - -#: libs/ardour/session_state.cc:1778 libs/ardour/session_state.cc:1798 -msgid "" -"Session: XMLNode describing a AudioRegion references a non-audio source id =%" -"1" -msgstr "" - -#: libs/ardour/session_state.cc:1868 -msgid "Session: cannot create Source from XML description." -msgstr "" - -#: libs/ardour/session_state.cc:1889 -msgid "" -"Found a sound file that cannot be used by Ardour. Talk to the progammers." -msgstr "" - -#: libs/ardour/session_state.cc:1913 -msgid "Could not create mix templates directory \"%1\" (%2)" -msgstr "" - -#: libs/ardour/session_state.cc:1927 -msgid "Template \"%1\" already exists - new version not created" -msgstr "" - -#: libs/ardour/session_state.cc:1934 -msgid "mix template not saved" -msgstr "" - -#: libs/ardour/session_state.cc:1994 -msgid "cannot create session directory \"%1\"; ignored" -msgstr "" - -#: libs/ardour/session_state.cc:2007 -msgid "cannot create sounds directory \"%1\"; ignored" -msgstr "" - -#: libs/ardour/session_state.cc:2018 -msgid "cannot create dead sounds directory \"%1\"; ignored" -msgstr "" - -#: libs/ardour/session_state.cc:2029 -msgid "cannot create peak file directory \"%1\"; ignored" -msgstr "" - -#: libs/ardour/session_state.cc:2168 libs/ardour/session_state.cc:2189 -msgid "Session: cannot create Playlist from XML description." -msgstr "" - -#: libs/ardour/session_state.cc:2228 -msgid "Session: cannot create Named Selection from XML description." -msgstr "" - -#: libs/ardour/session_state.cc:2360 -msgid "Unknown node \"%1\" found in Connections list from state file" -msgstr "" - -#: libs/ardour/session_state.cc:3197 -msgid "cannot remove dead sound file %1 (%2)" -msgstr "" - -#: libs/ardour/session_time.cc:374 -msgid "Unknown JACK transport state %1 in sync callback" -msgstr "" - -#: libs/ardour/session_timefx.cc:77 -msgid "tempoize: error creating name for new audio file based on %1" -msgstr "" - -#: libs/ardour/session_timefx.cc:88 -msgid "tempoize: error creating new audio file %1 (%2)" -msgstr "" - -#: libs/ardour/session_timefx.cc:114 -msgid "tempoize: error reading data from %1" -msgstr "" - -#: libs/ardour/session_timefx.cc:127 libs/ardour/session_timefx.cc:139 -msgid "error writing tempo-adjusted data to %1" -msgstr "" - -#: libs/ardour/session_timefx.cc:145 -msgid "timefx code failure. please notify ardour-developers." -msgstr "" - -#: libs/ardour/session_transport.cc:117 -msgid "Cannot loop - no loop range defined" -msgstr "" - -#: libs/ardour/session_transport.cc:479 -msgid "" -"Seamless looping cannot be supported while Ardour is using JACK transport.\n" -"Recommend changing the configured options" -msgstr "" - -#: libs/ardour/session_transport.cc:755 -msgid "" -"Global varispeed cannot be supported while Ardour is connected to JACK " -"transport control" -msgstr "" - -#: libs/ardour/session_transport.cc:955 -msgid "please stop the transport before adjusting slave settings" -msgstr "" - -#: libs/ardour/session_transport.cc:991 -msgid "No MTC port defined: MTC slaving is impossible." -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:15 -msgid "WAV" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:16 -msgid "AIFF" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:17 -msgid "raw (no header)" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:18 -msgid "PAF (Ensoniq Paris)" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:19 -msgid "AU (Sun/NeXT)" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:20 -msgid "IRCAM" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:21 -msgid "W64 (64 bit WAV)" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:26 -msgid ".wav" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:27 -msgid ".aiff" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:28 -msgid ".raw" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:29 -msgid ".paf" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:30 -msgid ".au" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:31 -msgid ".ircam" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:32 -msgid ".w64" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:47 -msgid "16 bit" -msgstr "16 ÂÉÔ" - -#: libs/ardour/sndfile_helpers.cc:48 -msgid "24 bit" -msgstr "24 ÂÉÔÁ" - -#: libs/ardour/sndfile_helpers.cc:49 -msgid "32 bit" -msgstr "32 ÂÉÔÁ" - -#: libs/ardour/sndfile_helpers.cc:50 -msgid "8 bit" -msgstr "8 ÂÉÔ" - -#: libs/ardour/sndfile_helpers.cc:51 -msgid "float" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:64 -msgid "Little-endian (Intel)" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:65 -msgid "Big-endian (Mac)" -msgstr "" - -#: libs/ardour/sndfilesource.cc:147 -msgid "FileSource: cannot get host information for BWF header (%1)" -msgstr "" - -#: libs/ardour/sndfilesource.cc:169 -msgid "" -"cannot set broadcast info for audio file %1 (%2); dropping broadcast info " -"for this file" -msgstr "" - -#: libs/ardour/sndfilesource.cc:220 -msgid "SndFileSource: cannot open file \"%1\" for %2 (%3)" -msgstr "" - -#: libs/ardour/sndfilesource.cc:226 -msgid "" -"SndFileSource: file only contains %1 channels; %2 is invalid as a channel " -"number" -msgstr "" - -#: libs/ardour/sndfilesource.cc:327 -msgid "SndFileSource: could not seek to frame %1 within %2 (%3)" -msgstr "" - -#: libs/ardour/sndfilesource.cc:378 -#, fuzzy -msgid "programming error: %1 %2" -msgstr "ÏÛÉÂËÁ ÐÒÏÇÒÁÍÍÙ: " - -#: libs/ardour/sndfilesource.cc:487 libs/ardour/sndfilesource.cc:533 -msgid "" -"cannot set broadcast info for audio file %1; Dropping broadcast info for " -"this file" -msgstr "" - -#: libs/ardour/sndfilesource.cc:544 -msgid "%1: cannot seek to %2" -msgstr "" - -#: libs/ardour/state_manager.cc:47 -msgid "cleared history" -msgstr "" - -#: libs/ardour/state_manager.cc:60 -msgid "" -"programming error: illegal state ID (%1) passed to StateManager::set_state() " -"(range = 0-%2)" -msgstr "" - -#: libs/ardour/stateful.cc:102 -msgid "Error: could not write %1" -msgstr "" - -#: libs/ardour/stateful.cc:116 -msgid "Could not understand XML file %1" -msgstr "" - -#: libs/ardour/tempo.cc:67 -msgid "TempoSection XML node has no \"start\" property" -msgstr "" - -#: libs/ardour/tempo.cc:75 -msgid "TempoSection XML node has an illegal \"start\" value" -msgstr "" - -#: libs/ardour/tempo.cc:82 -msgid "TempoSection XML node has no \"beats-per-minute\" property" -msgstr "" - -#: libs/ardour/tempo.cc:87 -msgid "TempoSection XML node has an illegal \"beats_per_minute\" value" -msgstr "" - -#: libs/ardour/tempo.cc:92 -msgid "TempoSection XML node has no \"movable\" property" -msgstr "" - -#: libs/ardour/tempo.cc:131 -msgid "MeterSection XML node has no \"start\" property" -msgstr "" - -#: libs/ardour/tempo.cc:139 -msgid "MeterSection XML node has an illegal \"start\" value" -msgstr "" - -#: libs/ardour/tempo.cc:146 -msgid "MeterSection XML node has no \"beats-per-bar\" property" -msgstr "" - -#: libs/ardour/tempo.cc:151 -msgid "MeterSection XML node has an illegal \"beats-per-bar\" value" -msgstr "" - -#: libs/ardour/tempo.cc:156 -msgid "MeterSection XML node has no \"note-type\" property" -msgstr "" - -#: libs/ardour/tempo.cc:161 -msgid "MeterSection XML node has an illegal \"note-type\" value" -msgstr "" - -#: libs/ardour/tempo.cc:166 -msgid "MeterSection XML node has no \"movable\" property" -msgstr "" - -#: libs/ardour/tempo.cc:259 -msgid "move metric" -msgstr "" - -#: libs/ardour/tempo.cc:330 -msgid "metric removed" -msgstr "" - -#: libs/ardour/tempo.cc:373 -msgid "add tempo" -msgstr "" - -#: libs/ardour/tempo.cc:402 -msgid "replace tempo" -msgstr "" - -#: libs/ardour/tempo.cc:435 -msgid "add meter" -msgstr "" - -#: libs/ardour/tempo.cc:463 -msgid "replaced meter" -msgstr "" - -#: libs/ardour/tempo.cc:483 libs/ardour/tempo.cc:499 -msgid "programming error: no tempo section in tempo map!" -msgstr "" - -#: libs/ardour/tempo.cc:538 -msgid "programming error: unhandled MetricSection type" -msgstr "" - -#: libs/ardour/tempo.cc:1226 libs/ardour/tempo.cc:1238 -msgid "Tempo map: could not set new state, restoring old one." -msgstr "" - -#: libs/ardour/tempo.cc:1262 -msgid "load XML data" -msgstr "" - -#: libs/ardour/utils.cc:246 -msgid "illegal or badly-formed string used for path (%1)" -msgstr "" - -#: libs/ardour/utils.cc:251 -msgid "path (%1) is ambiguous" -msgstr "" - -#: libs/ardour/vst_plugin.cc:187 -msgid "cannot create VST chunk directory: %1" -msgstr "" - -#: libs/ardour/vst_plugin.cc:195 -msgid "cannot check VST chunk directory: %1" -msgstr "" - -#: libs/ardour/vst_plugin.cc:202 -msgid "%1 exists but is not a directory" -msgstr "" - -#: libs/ardour/vst_plugin.cc:240 -msgid "Bad node sent to VSTPlugin::set_state" -msgstr "" - -#: libs/ardour/vst_plugin.cc:343 libs/ardour/vst_plugin.cc:354 -msgid "no support for presets using chunks at this time" -msgstr "" - -#: libs/ardour/coreaudiosource.cc:97 -msgid "" -"CoreAudioSource: file only contains %1 channels; %2 is invalid as a channel " -"number" -msgstr "" - -#: libs/ardour/coreaudiosource.cc:162 -msgid "CoreAudioSource: could not seek to frame %1 within %2 (%3)" -msgstr "" diff --git a/libs/ardour/po/sv_SE.po b/libs/ardour/po/sv_SE.po deleted file mode 100644 index ddc7f108bb..0000000000 --- a/libs/ardour/po/sv_SE.po +++ /dev/null @@ -1,2025 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR "Paul Davis" -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. -# -msgid "" -msgstr "" -"Project-Id-Version: ardour\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2006-10-03 00:39+0200\n" -"PO-Revision-Date: 2006-10-03 01:09+GMT+1\n" -"Last-Translator: Petter Sundlöf <petter.sundlof@findus.dhs.org>\n" -"Language-Team: Swedish <sv@li.org>\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#: libs/ardour/diskstream.cc:258 -msgid "Location \"%1\" not valid for track loop (start >= end)" -msgstr "" - -#: libs/ardour/audio_diskstream.cc:298 -msgid "AudioDiskstream: Playlist \"%1\" isn't an audio playlist" -msgstr "" - -#: libs/ardour/audio_diskstream.cc:349 -msgid "AudioDiskstream %1: there is no existing playlist to make a copy of!" -msgstr "" - -#: libs/ardour/audio_diskstream.cc:924 libs/ardour/audio_diskstream.cc:935 -msgid "" -"AudioDiskstream %1: when refilling, cannot read %2 from playlist at frame %3" -msgstr "" - -#: libs/ardour/audio_diskstream.cc:1069 -msgid "AudioDiskstream %1: cannot read %2 from playlist at frame %3" -msgstr "" - -#: libs/ardour/audio_diskstream.cc:1412 libs/ardour/audio_diskstream.cc:1429 -msgid "AudioDiskstream %1: cannot write to disk" -msgstr "" - -#: libs/ardour/audio_diskstream.cc:1473 -msgid "AudioDiskstream \"%1\": cannot flush captured data to disk!" -msgstr "" - -#: libs/ardour/audio_diskstream.cc:1563 -msgid "%1: could not create region for complete audio file" -msgstr "" - -#: libs/ardour/audio_diskstream.cc:1587 -msgid "AudioDiskstream: could not create region for captured audio!" -msgstr "" - -#: libs/ardour/audio_diskstream.cc:1643 -msgid "programmer error: %1" -msgstr "" - -#: libs/ardour/audio_diskstream.cc:1929 -msgid "AudioDiskstream: channel %1 out of range" -msgstr "" - -#: libs/ardour/audio_diskstream.cc:1952 -msgid "%1:%2 new capture file not initialized correctly" -msgstr "" - -#: libs/ardour/audio_diskstream.cc:2178 -msgid "%1: cannot restore pending capture source file %2" -msgstr "" - -#: libs/ardour/audio_diskstream.cc:2200 -msgid "%1: incorrect number of pending sources listed - ignoring them all" -msgstr "" - -#: libs/ardour/audio_diskstream.cc:2215 -msgid "%1: cannot create whole-file region from pending capture sources" -msgstr "" - -#: libs/ardour/audio_diskstream.cc:2227 -msgid "%1: cannot create region from pending capture sources" -msgstr "" - -#: libs/ardour/audio_library.cc:92 -msgid "channels" -msgstr "" - -#: libs/ardour/audio_library.cc:93 -msgid "samplerate" -msgstr "" - -#: libs/ardour/audio_library.cc:94 -msgid "resolution" -msgstr "" - -#: libs/ardour/audio_library.cc:95 -msgid "format" -msgstr "" - -#: libs/ardour/audio_library.cc:102 -msgid "Could not open %1. Audio Library not saved" -msgstr "" - -#: libs/ardour/audio_playlist.cc:53 libs/ardour/audio_playlist.cc:63 -#: libs/ardour/audio_playlist.cc:74 libs/ardour/audio_playlist.cc:121 -#: libs/ardour/insert.cc:84 libs/ardour/insert.cc:103 -#: libs/ardour/insert.cc:128 libs/ardour/insert.cc:862 -#: libs/ardour/insert.cc:870 libs/ardour/send.cc:39 libs/ardour/send.cc:53 -#: libs/ardour/send.cc:62 libs/ardour/session_state.cc:1128 -#: libs/ardour/session_state.cc:1170 -msgid "initial state" -msgstr "" - -#: libs/ardour/audio_playlist.cc:261 libs/ardour/audio_playlist.cc:743 -msgid "" -"programming error: non-audio Region passed to remove_overlap in audio " -"playlist" -msgstr "" - -#: libs/ardour/audio_playlist.cc:388 -msgid "" -"programming error: non-audio Region tested for overlap in audio playlist" -msgstr "" - -#: libs/ardour/audio_playlist.cc:851 -msgid "xfade change" -msgstr "" - -#: libs/ardour/audio_playlist.cc:874 -msgid "region modified" -msgstr "" - -#: libs/ardour/audio_track.cc:105 libs/ardour/io.cc:1696 -#: libs/ardour/io.cc:1762 -msgid "Unknown connection \"%1\" listed for input of %2" -msgstr "" - -#: libs/ardour/audio_track.cc:107 libs/ardour/io.cc:1698 -#: libs/ardour/io.cc:1764 -msgid "in 1" -msgstr "" - -#: libs/ardour/audio_track.cc:108 libs/ardour/io.cc:1699 -#: libs/ardour/io.cc:1765 -msgid "No input connections available as a replacement" -msgstr "" - -#: libs/ardour/audio_track.cc:112 libs/ardour/io.cc:1703 -#: libs/ardour/io.cc:1769 -msgid "Connection %1 was not available - \"in 1\" used instead" -msgstr "" - -#: libs/ardour/audio_track.cc:121 libs/ardour/io.cc:1778 -msgid "improper input channel list in XML node (%1)" -msgstr "" - -#: libs/ardour/audio_track.cc:162 libs/ardour/audio_track.cc:175 -msgid "AudioTrack: audio diskstream \"%1\" not known by session" -msgstr "" - -#: libs/ardour/audio_track.cc:216 -msgid "programming error: AudioTrack given state without diskstream!" -msgstr "" - -#: libs/ardour/audioengine.cc:146 -msgid "cannot activate JACK client" -msgstr "" - -#: libs/ardour/audioengine.cc:421 -msgid "register input port called before engine was started" -msgstr "" - -#: libs/ardour/audioengine.cc:457 -msgid "register output port called before engine was started" -msgstr "" - -#: libs/ardour/audioengine.cc:539 -msgid "connect called before engine was started" -msgstr "" - -#: libs/ardour/audioengine.cc:555 -msgid "AudioEngine: cannot connect %1 (%2) to %3 (%4)" -msgstr "" - -#: libs/ardour/audioengine.cc:568 libs/ardour/audioengine.cc:597 -msgid "disconnect called before engine was started" -msgstr "" - -#: libs/ardour/audioengine.cc:655 -msgid "get_port_by_name() called before engine was started" -msgstr "" - -#: libs/ardour/audioengine.cc:699 -msgid "get_ports called before engine was started" -msgstr "" - -#: libs/ardour/audioengine.cc:817 -msgid "get_nth_physical called before engine was started" -msgstr "" - -#: libs/ardour/audioengine.cc:845 -msgid "get_port_total_latency() called with no JACK client connection" -msgstr "" - -#: libs/ardour/audioengine.cc:851 -msgid "get_port_total_latency() called before engine was started" -msgstr "" - -#: libs/ardour/audioengine.cc:982 -msgid "Unable to connect to JACK server" -msgstr "" - -#: libs/ardour/audioengine.cc:985 -msgid "Could not connect to JACK server as \"%1\"" -msgstr "" - -#: libs/ardour/audioengine.cc:990 -msgid "JACK server started" -msgstr "" - -#: libs/ardour/audioengine.cc:1024 -msgid "cannot shutdown connection to JACK" -msgstr "" - -#: libs/ardour/audioengine.cc:1049 -msgid "failed to connect to JACK" -msgstr "" - -#: libs/ardour/audioengine.cc:1067 -msgid "could not reregister %1" -msgstr "" - -#: libs/ardour/audioengine.cc:1125 -msgid "could not reconnect %1 and %2 (err = %3)" -msgstr "" - -#: libs/ardour/audiofilesource.cc:355 libs/ardour/session_state.cc:2575 -msgid "" -"there are already 1000 files with names like %1; versioning discontinued" -msgstr "" - -#: libs/ardour/audiofilesource.cc:369 libs/ardour/session_state.cc:2589 -msgid "cannot rename audio file source from %1 to %2 (%3)" -msgstr "" - -#: libs/ardour/audiofilesource.cc:376 libs/ardour/session_state.cc:2604 -msgid "cannot remove peakfile %1 for %2 (%3)" -msgstr "" - -#: libs/ardour/audiofilesource.cc:420 -msgid "FileSource: search path not set" -msgstr "" - -#: libs/ardour/audiofilesource.cc:444 -msgid "" -"FileSource: \"%1\" is ambigous when searching %2\n" -"\t" -msgstr "" - -#: libs/ardour/audiofilesource.cc:450 -msgid "Filesource: cannot find required file (%1): while searching %2" -msgstr "" - -#: libs/ardour/audiofilesource.cc:473 -msgid "Filesource: cannot find required file (%1): %2" -msgstr "" - -#: libs/ardour/audiofilesource.cc:478 -msgid "Filesource: cannot check for existing file (%1): %2" -msgstr "" - -#: libs/ardour/audiofilesource.cc:534 libs/ardour/insert.cc:532 -#: libs/ardour/session.cc:1967 libs/ardour/sndfilesource.cc:109 -msgid "programming error: %1" -msgstr "" - -#: libs/ardour/audiofilesource.cc:540 -msgid "" -"Programming error! Ardour tried to rename a file over another file! It's " -"safe to continue working, but please report this to the developers." -msgstr "" - -#: libs/ardour/audiofilesource.cc:545 -msgid "cannot rename audio file for %1 to %2" -msgstr "" - -#: libs/ardour/audiofilter.cc:47 -msgid "audiofilter: error creating name for new audio file based on %1" -msgstr "" - -#: libs/ardour/audiofilter.cc:57 -msgid "audiofilter: error creating new audio file %1 (%2)" -msgstr "" - -#: libs/ardour/audioregion.cc:888 libs/ardour/audioregion.cc:950 -msgid "fade in change" -msgstr "" - -#: libs/ardour/audioregion.cc:1321 -#, c-format -msgid "normalized to %.2fdB" -msgstr "" - -#: libs/ardour/audioregion.cc:1339 -msgid "envelope change" -msgstr "" - -#: libs/ardour/audiosource.cc:144 -msgid "poll on peak request pipe failed (%1)" -msgstr "" - -#: libs/ardour/audiosource.cc:151 -msgid "Error on peak thread request pipe" -msgstr "" - -#: libs/ardour/audiosource.cc:184 -msgid "Error reading from peak request pipe" -msgstr "" - -#: libs/ardour/audiosource.cc:216 libs/ardour/session_butler.cc:80 -#: libs/ardour/session_midi.cc:1073 -msgid "Cannot create transport request signal pipe (%1)" -msgstr "" - -#: libs/ardour/audiosource.cc:221 libs/ardour/audiosource.cc:226 -msgid "UI: cannot set O_NONBLOCK on peak request pipe (%1)" -msgstr "" - -#: libs/ardour/audiosource.cc:231 -msgid "AudioSource: could not create peak thread" -msgstr "" - -#: libs/ardour/audiosource.cc:326 -msgid "cannot rename peakfile for %1 from %2 to %3 (%4)" -msgstr "" - -#: libs/ardour/audiosource.cc:368 -msgid "AudioSource: cannot stat peakfile \"%1\"" -msgstr "" - -#: libs/ardour/audiosource.cc:466 -msgid "cannot read sample data for unscaled peak computation" -msgstr "" - -#: libs/ardour/audiosource.cc:486 libs/ardour/audiosource.cc:557 -#: libs/ardour/audiosource.cc:793 libs/ardour/audiosource.cc:882 -msgid "AudioSource: cannot open peakpath \"%1\" (%2)" -msgstr "" - -#: libs/ardour/audiosource.cc:657 -msgid "AudioSource[%1]: peak read - cannot read %2 samples at offset %3" -msgstr "" - -#: libs/ardour/audiosource.cc:804 -msgid "%1: could not write read raw data for peak computation (%2)" -msgstr "" - -#: libs/ardour/audiosource.cc:829 -msgid "%1: could not write peak file data (%2)" -msgstr "" - -#: libs/ardour/auditioner.cc:118 -msgid "Auditioning of non-audio regions not yet supported" -msgstr "" - -#: libs/ardour/automation_event.cc:67 libs/ardour/location.cc:375 -#: libs/ardour/tempo.cc:226 -msgid "initial" -msgstr "" - -#: libs/ardour/automation_event.cc:240 -msgid "cleared" -msgstr "" - -#: libs/ardour/automation_event.cc:412 -msgid "added event" -msgstr "" - -#: libs/ardour/automation_event.cc:429 -msgid "removed event" -msgstr "" - -#: libs/ardour/automation_event.cc:444 -msgid "removed multiple events" -msgstr "" - -#: libs/ardour/automation_event.cc:475 libs/ardour/automation_event.cc:506 -msgid "removed range" -msgstr "" - -#: libs/ardour/automation_event.cc:536 -msgid "event range adjusted" -msgstr "" - -#: libs/ardour/automation_event.cc:558 -msgid "event adjusted" -msgstr "" - -#: libs/ardour/automation_event.cc:673 libs/ardour/automation_event.cc:778 -#: libs/ardour/panner.cc:889 -msgid "programming error:" -msgstr "" - -#: libs/ardour/automation_event.cc:1087 -msgid "cut/copy/clear" -msgstr "" - -#: libs/ardour/automation_event.cc:1120 -msgid "copy" -msgstr "" - -#: libs/ardour/automation_event.cc:1188 libs/ardour/playlist.cc:960 -msgid "paste" -msgstr "" - -#: libs/ardour/automation_event.cc:1243 -msgid "" -"automation list: no x-coordinate stored for control point (point ignored)" -msgstr "" - -#: libs/ardour/automation_event.cc:1249 -msgid "" -"automation list: no y-coordinate stored for control point (point ignored)" -msgstr "" - -#: libs/ardour/configuration.cc:87 -msgid "loading system configuration file %1" -msgstr "" - -#: libs/ardour/configuration.cc:90 -msgid "Ardour: cannot read system configuration file \"%1\"" -msgstr "" - -#: libs/ardour/configuration.cc:97 -msgid "Ardour: system configuration file \"%1\" not loaded successfully." -msgstr "" - -#: libs/ardour/configuration.cc:111 -msgid "loading user configuration file %1" -msgstr "" - -#: libs/ardour/configuration.cc:114 -msgid "Ardour: cannot read configuration file \"%1\"" -msgstr "" - -#: libs/ardour/configuration.cc:121 -msgid "Ardour: user configuration file \"%1\" not loaded successfully." -msgstr "" - -#: libs/ardour/configuration.cc:141 -msgid "Config file %1 not saved" -msgstr "" - -#: libs/ardour/configuration.cc:226 -msgid "ill-formed MIDI port specification in ardour rcfile (ignored)" -msgstr "" - -#: libs/ardour/connection.cc:183 -msgid "Node for Connection has no \"name\" property" -msgstr "" - -#: libs/ardour/connection.cc:191 -msgid "Node for Connection has no \"connections\" property" -msgstr "" - -#: libs/ardour/connection.cc:227 libs/ardour/io.cc:1838 -msgid "IO: badly formed string in XML node for inputs \"%1\"" -msgstr "" - -#: libs/ardour/connection.cc:232 libs/ardour/io.cc:1843 -msgid "bad input string in XML node \"%1\"" -msgstr "" - -#: libs/ardour/control_protocol_manager.cc:84 -msgid "control protocol name \"%1\" has no descriptor" -msgstr "" - -#: libs/ardour/control_protocol_manager.cc:89 -msgid "control protocol name \"%1\" could not be initialized" -msgstr "" - -#: libs/ardour/control_protocol_manager.cc:145 -msgid "Instantiating mandatory control protocol %1" -msgstr "" - -#: libs/ardour/control_protocol_manager.cc:179 -msgid "Control protocol %1 not usable" -msgstr "" - -#: libs/ardour/control_protocol_manager.cc:192 -msgid "Control surface protocol discovered: \"%1\"" -msgstr "" - -#: libs/ardour/control_protocol_manager.cc:210 -msgid "ControlProtocolManager: cannot load module \"%1\" (%2)" -msgstr "" - -#: libs/ardour/control_protocol_manager.cc:218 -msgid "ControlProtocolManager: module \"%1\" has no descriptor function." -msgstr "" - -#: libs/ardour/crossfade.cc:120 -msgid "Crossfade: no \"in\" region in state" -msgstr "" - -#: libs/ardour/crossfade.cc:127 -msgid "Crossfade: no \"in\" region %1 found in playlist %2" -msgstr "" - -#: libs/ardour/crossfade.cc:137 -msgid "Crossfade: no \"out\" region in state" -msgstr "" - -#: libs/ardour/crossfade.cc:144 -msgid "Crossfade: no \"out\" region %1 found in playlist %2" -msgstr "" - -#: libs/ardour/crossfade.cc:491 -msgid "active changed" -msgstr "" - -#: libs/ardour/crossfade.cc:740 -msgid "old-style crossfade information - no position information" -msgstr "" - -#: libs/ardour/curve.cc:117 libs/ardour/globals.cc:348 -#: libs/ardour/insert.cc:454 libs/ardour/session.cc:2432 -#: libs/ardour/session.cc:2486 -msgid "programming error: " -msgstr "" - -#: libs/ardour/cycle_timer.cc:37 -msgid "CycleTimer::get_mhz(): can't open /proc/cpuinfo" -msgstr "" - -#: libs/ardour/cycle_timer.cc:49 -msgid "CycleTimer::get_mhz(): cannot locate cpu MHz in /proc/cpuinfo" -msgstr "" - -#: libs/ardour/cycle_timer.cc:72 -msgid "cannot locate cpu MHz in /proc/cpuinfo" -msgstr "" - -#: libs/ardour/destructive_filesource.cc:200 -msgid "DestructiveFileSource: \"%1\" bad read retval: %2 of %5 (%3: %4)" -msgstr "" - -#: libs/ardour/destructive_filesource.cc:213 -#: libs/ardour/destructive_filesource.cc:258 -#: libs/ardour/destructive_filesource.cc:265 -msgid "DestructiveFileSource: \"%1\" bad write (%2)" -msgstr "" - -#: libs/ardour/destructive_filesource.cc:403 -msgid "" -"Filesource: start time is already set for existing file (%1): Cannot change " -"start time." -msgstr "" - -#: libs/ardour/globals.cc:110 -msgid "no MIDI ports specified: no MMC or MTC control possible" -msgstr "" - -#: libs/ardour/globals.cc:125 -msgid "MIDI port specifications for \"%1\" are not understandable." -msgstr "" - -#: libs/ardour/globals.cc:138 libs/ardour/globals.cc:142 -#: libs/ardour/globals.cc:146 -msgid "default" -msgstr "" - -#: libs/ardour/globals.cc:174 -msgid "No MMC control (MIDI port \"%1\" not available)" -msgstr "" - -#: libs/ardour/globals.cc:180 -msgid "No MTC support (MIDI port \"%1\" not available)" -msgstr "" - -#: libs/ardour/globals.cc:185 -msgid "No MIDI parameter support (MIDI port \"%1\" not available)" -msgstr "" - -#: libs/ardour/import.cc:77 -msgid "Import: cannot open input sound file \"%1\"" -msgstr "" - -#: libs/ardour/import.cc:82 -msgid "resampling audio" -msgstr "" - -#: libs/ardour/import.cc:86 -msgid "Import: cannot open converted sound file \"%1\"" -msgstr "" - -#: libs/ardour/import.cc:91 -msgid "Import: error while resampling sound file \"%1\"" -msgstr "" - -#: libs/ardour/import.cc:145 -msgid "Session::import_audiofile: cannot open new file source for channel %1" -msgstr "" - -#: libs/ardour/import.cc:163 -msgid "converting audio" -msgstr "" - -#: libs/ardour/import.cc:195 -msgid "building region" -msgstr "" - -#: libs/ardour/import.cc:197 -msgid "building regions" -msgstr "" - -#: libs/ardour/import.cc:309 -msgid "Import/SRC: could not open input file: %1" -msgstr "" - -#: libs/ardour/import.cc:317 -msgid "Import/SRC: could not open output file: %1" -msgstr "" - -#: libs/ardour/import.cc:326 -msgid "Import: src_new() failed : %1" -msgstr "" - -#: libs/ardour/import.cc:354 -msgid "Import: %1" -msgstr "" - -#: libs/ardour/insert.cc:651 libs/ardour/insert.cc:960 -msgid "XML node describing insert is missing the `type' field" -msgstr "" - -#: libs/ardour/insert.cc:660 -msgid "unknown plugin type %1 in plugin insert state" -msgstr "" - -#: libs/ardour/insert.cc:672 -msgid "XML node describing insert is missing the `id' field" -msgstr "" - -#: libs/ardour/insert.cc:685 -msgid "" -"Found a reference to a plugin (\"%1\") that is unknown.\n" -"Perhaps it was removed or moved since it was last used." -msgstr "" - -#: libs/ardour/insert.cc:723 libs/ardour/insert.cc:977 -msgid "XML node describing insert is missing a Redirect node" -msgstr "" - -#: libs/ardour/insert.cc:728 -msgid "XML node describing a plugin insert is missing the `%1' information" -msgstr "" - -#: libs/ardour/insert.cc:752 -msgid "PluginInsert: Auto: no ladspa port number" -msgstr "" - -#: libs/ardour/insert.cc:759 -msgid "PluginInsert: Auto: port id out of range" -msgstr "" - -#: libs/ardour/insert.cc:775 -msgid "XML node describing a port automation is missing the `%1' information" -msgstr "" - -#: libs/ardour/insert.cc:878 -msgid "PortInsert: cannot add input port" -msgstr "" - -#: libs/ardour/insert.cc:883 -msgid "PortInsert: cannot add output port" -msgstr "" - -#: libs/ardour/insert.cc:965 -msgid "non-port insert XML used for port plugin insert" -msgstr "" - -#: libs/ardour/io.cc:603 -msgid "IO: cannot disconnect input port %1 from %2" -msgstr "" - -#: libs/ardour/io.cc:671 -msgid "IO: cannot disconnect output port %1 from %2" -msgstr "" - -#: libs/ardour/io.cc:822 libs/ardour/io.cc:1177 libs/ardour/io.cc:1303 -#, c-format -msgid "%s/out" -msgstr "" - -#: libs/ardour/io.cc:824 libs/ardour/io.cc:1179 libs/ardour/io.cc:1305 -#: libs/ardour/io.cc:2688 -#, c-format -msgid "%s/out %u" -msgstr "" - -#: libs/ardour/io.cc:828 libs/ardour/io.cc:1184 libs/ardour/io.cc:1309 -msgid "IO: cannot register output port %1" -msgstr "" - -#: libs/ardour/io.cc:934 libs/ardour/io.cc:1037 libs/ardour/io.cc:1143 -#, c-format -msgid "%s/in" -msgstr "" - -#: libs/ardour/io.cc:936 libs/ardour/io.cc:1040 libs/ardour/io.cc:1146 -#: libs/ardour/io.cc:2658 -#, c-format -msgid "%s/in %u" -msgstr "" - -#: libs/ardour/io.cc:940 libs/ardour/io.cc:1046 libs/ardour/io.cc:1151 -msgid "IO: cannot register input port %1" -msgstr "" - -#: libs/ardour/io.cc:1551 -msgid "IO::connecting_became_legal() called without a pending state node" -msgstr "" - -#: libs/ardour/io.cc:1574 -msgid "IO::ports_became_legal() called without a pending state node" -msgstr "" - -#: libs/ardour/io.cc:1603 -msgid "incorrect XML node \"%1\" passed to IO object" -msgstr "" - -#: libs/ardour/io.cc:1719 libs/ardour/io.cc:1787 -msgid "Unknown connection \"%1\" listed for output of %2" -msgstr "" - -#: libs/ardour/io.cc:1721 libs/ardour/io.cc:1789 -msgid "out 1" -msgstr "" - -#: libs/ardour/io.cc:1722 libs/ardour/io.cc:1790 -msgid "No output connections available as a replacement" -msgstr "" - -#: libs/ardour/io.cc:1726 libs/ardour/io.cc:1794 -msgid "Connection %1 was not available - \"out 1\" used instead" -msgstr "" - -#: libs/ardour/io.cc:1740 -msgid "%1: cannot create I/O ports" -msgstr "" - -#: libs/ardour/io.cc:1803 -msgid "improper output channel list in XML node (%1)" -msgstr "" - -#: libs/ardour/io.cc:1888 -msgid "IO: badly formed string in XML node for outputs \"%1\"" -msgstr "" - -#: libs/ardour/io.cc:1893 -msgid "IO: bad output string in XML node \"%1\"" -msgstr "" - -#: libs/ardour/io.cc:2391 -msgid "%1: could not open automation event file \"%2\"" -msgstr "" - -#: libs/ardour/io.cc:2430 -msgid "%1: cannot open automation event file \"%2\" (%2)" -msgstr "" - -#: libs/ardour/io.cc:2445 -msgid "badly formed version number in automation event file \"%1\"" -msgstr "" - -#: libs/ardour/io.cc:2449 -msgid "no version information in automation event file \"%1\"" -msgstr "" - -#: libs/ardour/io.cc:2454 -msgid "mismatched automation event file version (%1)" -msgstr "" - -#: libs/ardour/io.cc:2462 -msgid "badly formatted automation event record at line %1 of %2 (ignored)" -msgstr "" - -#: libs/ardour/io.cc:2482 -msgid "dubious automation event found (and ignored)" -msgstr "" - -#: libs/ardour/io.cc:2486 libs/ardour/panner.cc:288 -#: libs/ardour/redirect.cc:148 -msgid "loaded from disk" -msgstr "" - -#: libs/ardour/io.cc:2630 -msgid "automation write/touch" -msgstr "" - -#: libs/ardour/ladspa_plugin.cc:87 -msgid "LADSPA: module has no descriptor function." -msgstr "" - -#: libs/ardour/ladspa_plugin.cc:92 -msgid "LADSPA: plugin has gone away since discovery!" -msgstr "" - -#: libs/ardour/ladspa_plugin.cc:99 -msgid "LADSPA: \"%1\" cannot be used, since it cannot do inplace processing" -msgstr "" - -#: libs/ardour/ladspa_plugin.cc:315 -msgid "" -"illegal parameter number used with plugin \"%1\". This mayindicate a change " -"in the plugin design, and presets may beinvalid" -msgstr "" - -#: libs/ardour/ladspa_plugin.cc:394 -msgid "Bad node sent to LadspaPlugin::set_state" -msgstr "" - -#: libs/ardour/ladspa_plugin.cc:407 -msgid "LADSPA: no ladspa port number" -msgstr "" - -#: libs/ardour/ladspa_plugin.cc:413 -msgid "LADSPA: no ladspa port data" -msgstr "" - -#: libs/ardour/ladspa_plugin.cc:653 -msgid "LADSPA: cannot load module from \"%1\"" -msgstr "" - -#: libs/ardour/location.cc:295 -msgid "incorrect XML node passed to Location::set_state" -msgstr "" - -#: libs/ardour/location.cc:300 -msgid "XML node for Location has no ID information" -msgstr "" - -#: libs/ardour/location.cc:306 -msgid "XML node for Location has no name information" -msgstr "" - -#: libs/ardour/location.cc:313 -msgid "XML node for Location has no start information" -msgstr "" - -#: libs/ardour/location.cc:324 -msgid "XML node for Location has no end information" -msgstr "" - -#: libs/ardour/location.cc:333 -msgid "XML node for Location has no flags information" -msgstr "" - -#: libs/ardour/location.cc:421 -msgid "Locations: attempt to use unknown location as selected location" -msgstr "" - -#: libs/ardour/location.cc:448 libs/ardour/playlist.cc:1204 -msgid "clear" -msgstr "" - -#: libs/ardour/location.cc:473 -msgid "clear markers" -msgstr "" - -#: libs/ardour/location.cc:501 -msgid "clear ranges" -msgstr "" - -#: libs/ardour/location.cc:519 -msgid "add" -msgstr "" - -#: libs/ardour/location.cc:557 -msgid "remove" -msgstr "" - -#: libs/ardour/location.cc:597 -msgid "incorrect XML mode passed to Locations::set_state" -msgstr "" - -#: libs/ardour/location.cc:615 -msgid "could not load location from session file - ignored" -msgstr "" - -#: libs/ardour/mtc_slave.cc:196 -msgid "MTC Slave: atomic read of current time failed, sleeping!" -msgstr "" - -#: libs/ardour/named_selection.cc:77 -msgid "Chunk %1 uses an unknown playlist \"%2\"" -msgstr "" - -#: libs/ardour/named_selection.cc:80 -msgid "Chunk %1 contains misformed playlist information" -msgstr "" - -#: libs/ardour/panner.cc:211 -msgid "automation write pass" -msgstr "" - -#: libs/ardour/panner.cc:251 -#, c-format -msgid "error writing pan automation file (%s)" -msgstr "" - -#: libs/ardour/panner.cc:279 -msgid "" -"badly formatted pan automation event record at line %1 of %2 (ignored) [%3]" -msgstr "" - -#: libs/ardour/panner.cc:794 -msgid "badly-formed positional data for Multi2dPanner - ignored" -msgstr "" - -#: libs/ardour/panner.cc:1083 -msgid "cannot open pan automation file \"%1\" for saving (%2)" -msgstr "" - -#: libs/ardour/panner.cc:1119 -msgid "cannot open pan automation file %1 (%2)" -msgstr "" - -#: libs/ardour/panner.cc:1132 -msgid "badly formed version number in pan automation event file \"%1\"" -msgstr "" - -#: libs/ardour/panner.cc:1136 -msgid "" -"no version information in pan automation event file \"%1\" (first line = %2)" -msgstr "" - -#: libs/ardour/panner.cc:1142 -msgid "mismatched pan automation event file version (%1)" -msgstr "" - -#: libs/ardour/panner.cc:1156 -msgid "too many panner states found in pan automation file %1" -msgstr "" - -#: libs/ardour/panner.cc:1297 -msgid "Unknown panner plugin \"%1\" found in pan state - ignored" -msgstr "" - -#: libs/ardour/panner.cc:1303 -msgid "panner plugin node has no type information!" -msgstr "" - -#: libs/ardour/playlist.cc:251 -msgid "playlist const copy constructor called" -msgstr "" - -#: libs/ardour/playlist.cc:257 -msgid "playlist non-const copy constructor called" -msgstr "" - -#: libs/ardour/playlist.cc:498 -msgid "add region" -msgstr "" - -#: libs/ardour/playlist.cc:550 -msgid "replace region" -msgstr "" - -#: libs/ardour/playlist.cc:563 -msgid "remove region" -msgstr "" - -#: libs/ardour/playlist.cc:635 -msgid "separate" -msgstr "" - -#: libs/ardour/playlist.cc:899 -msgid "cut" -msgstr "" - -#: libs/ardour/playlist.cc:989 -msgid "duplicate" -msgstr "" - -#: libs/ardour/playlist.cc:1044 -msgid "split" -msgstr "" - -#: libs/ardour/playlist.cc:1121 -msgid "%1: bounds changed received for region (%2)not in playlist" -msgstr "" - -#: libs/ardour/playlist.cc:1377 -msgid "Playlist: cannot create region from state file" -msgstr "" - -#: libs/ardour/playlist.cc:1737 -msgid "nudged" -msgstr "" - -#: libs/ardour/playlist_factory.cc:40 -msgid "" -"programming error: Playlist::copyPlaylist called with unknown Playlist type" -msgstr "" - -#: libs/ardour/plugin.cc:218 -msgid "Could not locate HOME. Preset not saved." -msgstr "" - -#: libs/ardour/plugin.cc:228 libs/ardour/plugin.cc:234 -msgid "Could not create %1. Preset not saved. (%2)" -msgstr "" - -#: libs/ardour/plugin.cc:239 -msgid "Error saving presets file %1." -msgstr "" - -#: libs/ardour/plugin_manager.cc:192 -msgid "Could not parse rdf file: %1" -msgstr "" - -#: libs/ardour/plugin_manager.cc:232 -msgid "LADSPA: cannot load module \"%1\" (%2)" -msgstr "" - -#: libs/ardour/plugin_manager.cc:239 -msgid "LADSPA: module \"%1\" has no descriptor function." -msgstr "" - -#: libs/ardour/plugin_manager.cc:295 libs/ardour/plugin_manager.cc:307 -msgid "Unknown" -msgstr "" - -#: libs/ardour/plugin_manager.cc:380 -msgid "" -"VST plugin %1 does not support processReplacing, and so cannot be used in " -"ardour at this time" -msgstr "" - -#: libs/ardour/recent_sessions.cc:44 -msgid "cannot open recent session file %1 (%2)" -msgstr "" - -#: libs/ardour/redirect.cc:77 -msgid "programming error: unknown Redirect type in Redirect::Clone!\n" -msgstr "" - -#: libs/ardour/redirect.cc:102 libs/ardour/utils.cc:194 -msgid "pre" -msgstr "" - -#: libs/ardour/redirect.cc:104 libs/ardour/utils.cc:197 -msgid "post" -msgstr "" - -#: libs/ardour/redirect.cc:107 -msgid "Redirect: unknown placement string \"%1\" (ignored)" -msgstr "" - -#: libs/ardour/redirect.cc:125 -msgid "%1: cannot open %2 to load automation data (%3)" -msgstr "" - -#: libs/ardour/redirect.cc:154 -msgid "%1: cannot load automation data from %2" -msgstr "" - -#: libs/ardour/redirect.cc:175 -msgid "%1: cannot open %2 to store automation data (%3)" -msgstr "" - -#: libs/ardour/redirect.cc:194 libs/ardour/redirect.cc:201 -msgid "%1: could not save automation state to %2" -msgstr "" - -#: libs/ardour/redirect.cc:246 -msgid "Could not get state from Redirect (%1). Problem with save_automation" -msgstr "" - -#: libs/ardour/redirect.cc:296 -msgid "incorrect XML node \"%1\" passed to Redirect object" -msgstr "" - -#: libs/ardour/redirect.cc:318 -msgid "%1: Automation node has no path property" -msgstr "" - -#: libs/ardour/redirect.cc:343 -msgid "XML node describing an IO is missing an IO node" -msgstr "" - -#: libs/ardour/redirect.cc:348 -msgid "XML node describing a redirect is missing the `active' field" -msgstr "" - -#: libs/ardour/redirect.cc:358 -msgid "XML node describing a redirect is missing the `placement' field" -msgstr "" - -#: libs/ardour/redirect.cc:467 -msgid "active_changed" -msgstr "" - -#: libs/ardour/region.cc:901 -msgid "Session: XMLNode describing a Region is incomplete (no id)" -msgstr "" - -#: libs/ardour/region.cc:908 -msgid "Session: XMLNode describing a Region is incomplete (no name)" -msgstr "" - -#: libs/ardour/region_factory.cc:53 libs/ardour/region_factory.cc:70 -msgid "" -"programming error: RegionFactory::create() called with unknown Region type" -msgstr "" - -#: libs/ardour/route.cc:81 libs/ardour/session.cc:1434 -#: libs/ardour/session.cc:1440 libs/ardour/session.cc:3064 -msgid "signal" -msgstr "" - -#: libs/ardour/route.cc:1407 -msgid "Could not get state of route. Problem with save_automation" -msgstr "" - -#: libs/ardour/route.cc:1459 -msgid "Send construction failed" -msgstr "" - -#: libs/ardour/route.cc:1481 -msgid "unknown Insert type \"%1\"; ignored" -msgstr "" - -#: libs/ardour/route.cc:1487 -msgid "Insert XML node has no type property" -msgstr "" - -#: libs/ardour/route.cc:1492 -msgid "insert could not be created. Ignored." -msgstr "" - -#: libs/ardour/route.cc:1508 -msgid "Bad node sent to Route::set_state() [%1]" -msgstr "" - -#: libs/ardour/route.cc:1572 -msgid "Route %1: unknown edit group \"%2 in saved state (ignored)" -msgstr "" - -#: libs/ardour/route.cc:1588 libs/ardour/route.cc:1592 -msgid "badly formed order key string in state file! [%1] ... ignored." -msgstr "" - -#: libs/ardour/route.cc:1673 libs/ardour/route.cc:1761 -msgid "[control]" -msgstr "" - -#: libs/ardour/route.cc:1693 -msgid "Route %1: unknown mix group \"%2 in saved state (ignored)" -msgstr "" - -#: libs/ardour/send.cc:99 -msgid "XML node describing a send is missing a Redirect node" -msgstr "" - -#: libs/ardour/session.cc:111 -msgid "Could not resolve path: %1 (%2)" -msgstr "" - -#: libs/ardour/session.cc:123 -msgid "cannot check session path %1 (%2)" -msgstr "" - -#: libs/ardour/session.cc:153 -msgid "cannot check statefile %1 (%2)" -msgstr "" - -#: libs/ardour/session.cc:189 -msgid "%1 is not an Ardour snapshot file" -msgstr "" - -#: libs/ardour/session.cc:206 -msgid "cannot determine current working directory (%1)" -msgstr "" - -#: libs/ardour/session.cc:223 -msgid "unknown file type for session %1" -msgstr "" - -#: libs/ardour/session.cc:343 -msgid "monitor" -msgstr "" - -#: libs/ardour/session.cc:351 -msgid "master" -msgstr "" - -#: libs/ardour/session.cc:633 -msgid "could not setup Click I/O" -msgstr "" - -#: libs/ardour/session.cc:654 -msgid "cannot setup Click I/O" -msgstr "" - -#: libs/ardour/session.cc:676 -msgid "cannot create Auditioner: no auditioning of regions possible" -msgstr "" - -#: libs/ardour/session.cc:688 -#, c-format -msgid "out %<PRIu32>" -msgstr "" - -#: libs/ardour/session.cc:700 -#, c-format -msgid "in %<PRIu32>" -msgstr "" - -#: libs/ardour/session.cc:714 -#, c-format -msgid "out %<PRIu32>+%<PRIu32>" -msgstr "" - -#: libs/ardour/session.cc:728 -#, c-format -msgid "in %<PRIu32>+%<PRIu32>" -msgstr "" - -#: libs/ardour/session.cc:761 -msgid "cannot setup master inputs" -msgstr "" - -#: libs/ardour/session.cc:769 -msgid "cannot setup master outputs" -msgstr "" - -#: libs/ardour/session.cc:780 -msgid "Master Out" -msgstr "" - -#: libs/ardour/session.cc:852 -msgid "cannot setup control inputs" -msgstr "" - -#: libs/ardour/session.cc:860 -msgid "cannot set up master outputs" -msgstr "" - -#: libs/ardour/session.cc:1043 -msgid "Session: you can't use that location for auto punch (start <= end)" -msgstr "" - -#: libs/ardour/session.cc:1080 -msgid "Session: you can't use a mark for auto loop" -msgstr "" - -#: libs/ardour/session.cc:1452 -msgid "feedback loop setup between %1 and %2" -msgstr "" - -#: libs/ardour/session.cc:1629 libs/ardour/session.cc:1750 -msgid "cannot configure %1 in/%2 out configuration for new audio track" -msgstr "" - -#: libs/ardour/session.cc:1687 -msgid "Session: could not create new audio track." -msgstr "" - -#: libs/ardour/session.cc:1800 -msgid "Session: could not create new audio route." -msgstr "" - -#: libs/ardour/session.cc:2319 -msgid "cannot create new name for region \"%1\"" -msgstr "" - -#: libs/ardour/session.cc:2383 -msgid "too many regions with names like %1" -msgstr "" - -#: libs/ardour/session.cc:2883 -msgid "There are already %1 recordings for %2, which I consider too many." -msgstr "" - -#: libs/ardour/session.cc:3085 -msgid "Cannot compile tape track regexp for use (%1)" -msgstr "" - -#: libs/ardour/session.cc:3232 -msgid "programming error: unknown type of Insert created!" -msgstr "" - -#: libs/ardour/session.cc:3238 -msgid "programming error: unknown type of Redirect created!" -msgstr "" - -#: libs/ardour/session.cc:3261 -msgid "programming error: unknown type of Insert deleted!" -msgstr "" - -#: libs/ardour/session.cc:3267 -msgid "programming error: unknown type of Redirect deleted!" -msgstr "" - -#: libs/ardour/session.cc:3573 -msgid "too many bounced versions of playlist \"%1\"" -msgstr "" - -#: libs/ardour/session.cc:3582 -msgid "cannot create new audio file \"%1\" for %2" -msgstr "" - -#: libs/ardour/session_butler.cc:85 libs/ardour/session_butler.cc:90 -msgid "UI: cannot set O_NONBLOCK on butler request pipe (%1)" -msgstr "" - -#: libs/ardour/session_butler.cc:95 -msgid "Session: could not create butler thread" -msgstr "" - -#: libs/ardour/session_butler.cc:183 -msgid "poll on butler request pipe failed (%1)" -msgstr "" - -#: libs/ardour/session_butler.cc:190 -msgid "Error on butler thread request pipe: fd=%1 err=%2" -msgstr "" - -#: libs/ardour/session_butler.cc:231 -msgid "Error reading from butler request pipe" -msgstr "" - -#: libs/ardour/session_butler.cc:268 -msgid "Butler read ahead failure on dstream %1" -msgstr "" - -#: libs/ardour/session_butler.cc:311 -msgid "Butler write-behind failure on dstream %1" -msgstr "" - -#: libs/ardour/session_click.cc:160 -msgid "cannot open click soundfile %1 (%2)" -msgstr "" - -#: libs/ardour/session_click.cc:169 -msgid "cannot read data from click soundfile" -msgstr "" - -#: libs/ardour/session_click.cc:196 -msgid "cannot open click emphasis soundfile %1 (%2)" -msgstr "" - -#: libs/ardour/session_click.cc:204 -msgid "cannot read data from click emphasis soundfile" -msgstr "" - -#: libs/ardour/session_command.cc:49 -msgid "Tried to reconstitute a MementoCommand with no contents, failing. id=" -msgstr "" - -#: libs/ardour/session_command.cc:95 -msgid "could not reconstitute MementoCommand from XMLNode. id=" -msgstr "" - -#: libs/ardour/session_events.cc:161 -msgid "Session: cannot have two events of type %1 at the same frame (%2)." -msgstr "" - -#: libs/ardour/session_events.cc:422 -msgid "Programming error: illegal event type in process_event (%1)" -msgstr "" - -#: libs/ardour/session_export.cc:63 -msgid "Export: no output file specified" -msgstr "" - -#: libs/ardour/session_export.cc:164 libs/ardour/session_export.cc:169 -msgid "illegal frame range in export specification" -msgstr "" - -#: libs/ardour/session_export.cc:174 -msgid "Bad data width size. Report me!" -msgstr "" - -#: libs/ardour/session_export.cc:204 -msgid "Export: cannot open output file \"%1\" (%2)" -msgstr "" - -#: libs/ardour/session_export.cc:214 -msgid "cannot initialize sample rate conversion: %1" -msgstr "" - -#: libs/ardour/session_export.cc:316 -msgid "an error occured during sample rate conversion: %1" -msgstr "" - -#: libs/ardour/session_export.cc:327 -msgid "warning, leftover frames overflowed, glitches might occur in output" -msgstr "" - -#: libs/ardour/session_export.cc:418 -msgid "Export: could not write data to output file (%1)" -msgstr "" - -#: libs/ardour/session_export.cc:502 -msgid "%1: cannot seek to %2 for export" -msgstr "" - -#: libs/ardour/session_midi.cc:95 -msgid "Ardour is slaved to MTC - port cannot be reset" -msgstr "" - -#: libs/ardour/session_midi.cc:110 -msgid "unknown port %1 requested for MTC" -msgstr "" - -#: libs/ardour/session_midi.cc:435 -msgid "Error reading from MIDI port %1" -msgstr "" - -#: libs/ardour/session_midi.cc:804 -msgid "Session: could not send full MIDI time code" -msgstr "" - -#: libs/ardour/session_midi.cc:863 -msgid "Session: cannot send quarter-frame MTC message (%1)" -msgstr "" - -#: libs/ardour/session_midi.cc:971 -msgid "MMC: cannot send command %1%2%3" -msgstr "" - -#: libs/ardour/session_midi.cc:1078 -msgid "UI: cannot set O_NONBLOCK on signal read pipe (%1)" -msgstr "" - -#: libs/ardour/session_midi.cc:1083 -msgid "UI: cannot set O_NONBLOCK on signal write pipe (%1)" -msgstr "" - -#: libs/ardour/session_midi.cc:1088 -msgid "Session: could not create transport thread" -msgstr "" - -#: libs/ardour/session_midi.cc:1117 -msgid "cannot send signal to midi thread! (%1)" -msgstr "" - -#: libs/ardour/session_midi.cc:1212 -msgid "MIDI thread poll failed (%1)" -msgstr "" - -#: libs/ardour/session_midi.cc:1224 -msgid "Error on transport thread request pipe" -msgstr "" - -#: libs/ardour/session_midi.cc:1251 -msgid "Error reading from transport request pipe" -msgstr "" - -#: libs/ardour/session_process.cc:104 -msgid "Session: error in no roll for %1" -msgstr "" - -#: libs/ardour/session_state.cc:103 -msgid "Could not use path %1 (%s)" -msgstr "" - -#: libs/ardour/session_state.cc:131 -msgid "end" -msgstr "" - -#: libs/ardour/session_state.cc:132 -msgid "start" -msgstr "" - -#: libs/ardour/session_state.cc:443 -msgid "Session: cannot create session dir \"%1\" (%2)" -msgstr "" - -#: libs/ardour/session_state.cc:450 -msgid "Session: cannot create session peakfile dir \"%1\" (%2)" -msgstr "" - -#: libs/ardour/session_state.cc:457 -msgid "Session: cannot create session sounds dir \"%1\" (%2)" -msgstr "" - -#: libs/ardour/session_state.cc:464 -msgid "Session: cannot create session dead sounds dir \"%1\" (%2)" -msgstr "" - -#: libs/ardour/session_state.cc:471 -msgid "Session: cannot create session automation dir \"%1\" (%2)" -msgstr "" - -#: libs/ardour/session_state.cc:500 -msgid "Could not open %1 for writing mix template" -msgstr "" - -#: libs/ardour/session_state.cc:506 -msgid "Could not open mix template %1 for reading" -msgstr "" - -#: libs/ardour/session_state.cc:548 -msgid "Session: could not load diskstream via XML state" -msgstr "" - -#: libs/ardour/session_state.cc:597 -msgid "could not backup old state file, current state not saved." -msgstr "" - -#: libs/ardour/session_state.cc:612 -msgid "state could not be saved to %1" -msgstr "" - -#: libs/ardour/session_state.cc:619 -msgid "could not remove corrupt state file %1" -msgstr "" - -#: libs/ardour/session_state.cc:623 -msgid "could not restore state file from backup %1" -msgstr "" - -#: libs/ardour/session_state.cc:693 -msgid "%1: session state information file \"%2\" doesn't exist!" -msgstr "" - -#: libs/ardour/session_state.cc:704 libs/ardour/session_state.cc:2824 -msgid "Could not understand ardour file %1" -msgstr "" - -#: libs/ardour/session_state.cc:988 -msgid "programming error: Session: incorrect XML node sent to set_state()" -msgstr "" - -#: libs/ardour/session_state.cc:1047 -msgid "Session: XML state has no options section" -msgstr "" - -#: libs/ardour/session_state.cc:1051 -msgid "Session: XML state has no sources section" -msgstr "" - -#: libs/ardour/session_state.cc:1058 -msgid "Session: XML state has no Regions section" -msgstr "" - -#: libs/ardour/session_state.cc:1065 -msgid "Session: XML state has no playlists section" -msgstr "" - -#: libs/ardour/session_state.cc:1084 -msgid "Session: XML state has no diskstreams section" -msgstr "" - -#: libs/ardour/session_state.cc:1091 -msgid "Session: XML state has no connections section" -msgstr "" - -#: libs/ardour/session_state.cc:1098 -msgid "Session: XML state has no locations section" -msgstr "" - -#: libs/ardour/session_state.cc:1131 -msgid "Session: XML state has no edit groups section" -msgstr "" - -#: libs/ardour/session_state.cc:1138 -msgid "Session: XML state has no mix groups section" -msgstr "" - -#: libs/ardour/session_state.cc:1145 -msgid "Session: XML state has no Tempo Map section" -msgstr "" - -#: libs/ardour/session_state.cc:1152 -msgid "Session: XML state has no routes section" -msgstr "" - -#: libs/ardour/session_state.cc:1159 -msgid "Session: XML state has no click section" -msgstr "" - -#: libs/ardour/session_state.cc:1202 -msgid "Session: cannot create Route from XML description." -msgstr "" - -#: libs/ardour/session_state.cc:1243 -msgid "Session: cannot create Region from XML description." -msgstr "" - -#: libs/ardour/session_state.cc:1271 -msgid "Session: XMLNode describing a AudioRegion is incomplete (no source)" -msgstr "" - -#: libs/ardour/session_state.cc:1279 libs/ardour/session_state.cc:1300 -msgid "" -"Session: XMLNode describing a AudioRegion references an unknown source id =%1" -msgstr "" - -#: libs/ardour/session_state.cc:1285 libs/ardour/session_state.cc:1306 -msgid "" -"Session: XMLNode describing a AudioRegion references a non-audio source id =%" -"1" -msgstr "" - -#: libs/ardour/session_state.cc:1377 -msgid "Session: cannot create Source from XML description." -msgstr "" - -#: libs/ardour/session_state.cc:1396 -msgid "" -"Found a sound file that cannot be used by Ardour. Talk to the progammers." -msgstr "" - -#: libs/ardour/session_state.cc:1418 -msgid "Could not create mix templates directory \"%1\" (%2)" -msgstr "" - -#: libs/ardour/session_state.cc:1432 -msgid "Template \"%1\" already exists - new version not created" -msgstr "" - -#: libs/ardour/session_state.cc:1439 -msgid "mix template not saved" -msgstr "" - -#: libs/ardour/session_state.cc:1498 -msgid "cannot create session directory \"%1\"; ignored" -msgstr "" - -#: libs/ardour/session_state.cc:1509 -msgid "cannot create sounds directory \"%1\"; ignored" -msgstr "" - -#: libs/ardour/session_state.cc:1518 -msgid "cannot create dead sounds directory \"%1\"; ignored" -msgstr "" - -#: libs/ardour/session_state.cc:1527 -msgid "cannot create peak file directory \"%1\"; ignored" -msgstr "" - -#: libs/ardour/session_state.cc:1659 libs/ardour/session_state.cc:1680 -msgid "Session: cannot create Playlist from XML description." -msgstr "" - -#: libs/ardour/session_state.cc:1719 -msgid "Session: cannot create Named Selection from XML description." -msgstr "" - -#: libs/ardour/session_state.cc:1872 -msgid "Unknown node \"%1\" found in Connections list from state file" -msgstr "" - -#: libs/ardour/session_state.cc:2677 -msgid "cannot remove dead sound file %1 (%2)" -msgstr "" - -#: libs/ardour/session_state.cc:2778 -msgid "could not backup old history file, current history not saved." -msgstr "" - -#: libs/ardour/session_state.cc:2786 -msgid "history could not be saved to %1" -msgstr "" - -#: libs/ardour/session_state.cc:2794 -msgid "could not remove corrupt history file %1" -msgstr "" - -#: libs/ardour/session_state.cc:2798 -msgid "could not restore history file from backup %1" -msgstr "" - -#: libs/ardour/session_state.cc:2816 -msgid "Loading history from '%1'." -msgstr "" - -#: libs/ardour/session_state.cc:2819 -msgid "%1: session history file \"%2\" doesn't exist!" -msgstr "" - -#: libs/ardour/session_state.cc:2861 -msgid "Couldn't figure out how to make a Command out of a %1 XMLNode." -msgstr "" - -#: libs/ardour/session_time.cc:370 -msgid "Unknown JACK transport state %1 in sync callback" -msgstr "" - -#: libs/ardour/session_timefx.cc:79 -msgid "tempoize: error creating name for new audio file based on %1" -msgstr "" - -#: libs/ardour/session_timefx.cc:88 -msgid "tempoize: error creating new audio file %1 (%2)" -msgstr "" - -#: libs/ardour/session_timefx.cc:113 -msgid "tempoize: error reading data from %1" -msgstr "" - -#: libs/ardour/session_timefx.cc:126 libs/ardour/session_timefx.cc:138 -msgid "error writing tempo-adjusted data to %1" -msgstr "" - -#: libs/ardour/session_timefx.cc:144 -msgid "timefx code failure. please notify ardour-developers." -msgstr "" - -#: libs/ardour/session_transport.cc:117 -msgid "Cannot loop - no loop range defined" -msgstr "" - -#: libs/ardour/session_transport.cc:474 -msgid "" -"Seamless looping cannot be supported while Ardour is using JACK transport.\n" -"Recommend changing the configured options" -msgstr "" - -#: libs/ardour/session_transport.cc:743 -msgid "" -"Global varispeed cannot be supported while Ardour is connected to JACK " -"transport control" -msgstr "" - -#: libs/ardour/session_transport.cc:933 -msgid "please stop the transport before adjusting slave settings" -msgstr "" - -#: libs/ardour/session_transport.cc:966 -msgid "No MTC port defined: MTC slaving is impossible." -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:15 -msgid "WAV" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:16 -msgid "AIFF" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:17 -msgid "raw (no header)" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:18 -msgid "PAF (Ensoniq Paris)" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:19 -msgid "AU (Sun/NeXT)" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:20 -msgid "IRCAM" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:21 -msgid "W64 (64 bit WAV)" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:26 -msgid ".wav" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:27 -msgid ".aiff" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:28 -msgid ".raw" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:29 -msgid ".paf" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:30 -msgid ".au" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:31 -msgid ".ircam" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:32 -msgid ".w64" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:47 -msgid "16 bit" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:48 -msgid "24 bit" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:49 -msgid "32 bit" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:50 -msgid "8 bit" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:51 -msgid "float" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:64 -msgid "Little-endian (Intel)" -msgstr "" - -#: libs/ardour/sndfile_helpers.cc:65 -msgid "Big-endian (Mac)" -msgstr "" - -#: libs/ardour/sndfilesource.cc:143 -msgid "FileSource: cannot get host information for BWF header (%1)" -msgstr "" - -#: libs/ardour/sndfilesource.cc:167 -msgid "" -"cannot set broadcast info for audio file %1 (%2); dropping broadcast info " -"for this file" -msgstr "" - -#: libs/ardour/sndfilesource.cc:216 -msgid "SndFileSource: cannot open file \"%1\" for %2 (%3)" -msgstr "" - -#: libs/ardour/sndfilesource.cc:222 -msgid "" -"SndFileSource: file only contains %1 channels; %2 is invalid as a channel " -"number" -msgstr "" - -#: libs/ardour/sndfilesource.cc:327 -msgid "SndFileSource: could not seek to frame %1 within %2 (%3)" -msgstr "" - -#: libs/ardour/sndfilesource.cc:378 -msgid "programming error: %1 %2" -msgstr "" - -#: libs/ardour/sndfilesource.cc:486 libs/ardour/sndfilesource.cc:507 -msgid "" -"cannot set broadcast info for audio file %1; Dropping broadcast info for " -"this file" -msgstr "" - -#: libs/ardour/sndfilesource.cc:521 -msgid "%1: cannot seek to %2" -msgstr "" - -#: libs/ardour/state_manager.cc:47 -msgid "cleared history" -msgstr "" - -#: libs/ardour/state_manager.cc:60 -msgid "" -"programming error: illegal state ID (%1) passed to StateManager::set_state() " -"(range = 0-%2)" -msgstr "" - -#: libs/ardour/tempo.cc:67 -msgid "TempoSection XML node has no \"start\" property" -msgstr "" - -#: libs/ardour/tempo.cc:75 -msgid "TempoSection XML node has an illegal \"start\" value" -msgstr "" - -#: libs/ardour/tempo.cc:82 -msgid "TempoSection XML node has no \"beats-per-minute\" property" -msgstr "" - -#: libs/ardour/tempo.cc:87 -msgid "TempoSection XML node has an illegal \"beats_per_minute\" value" -msgstr "" - -#: libs/ardour/tempo.cc:92 -msgid "TempoSection XML node has no \"movable\" property" -msgstr "" - -#: libs/ardour/tempo.cc:131 -msgid "MeterSection XML node has no \"start\" property" -msgstr "" - -#: libs/ardour/tempo.cc:139 -msgid "MeterSection XML node has an illegal \"start\" value" -msgstr "" - -#: libs/ardour/tempo.cc:146 -msgid "MeterSection XML node has no \"beats-per-bar\" property" -msgstr "" - -#: libs/ardour/tempo.cc:151 -msgid "MeterSection XML node has an illegal \"beats-per-bar\" value" -msgstr "" - -#: libs/ardour/tempo.cc:156 -msgid "MeterSection XML node has no \"note-type\" property" -msgstr "" - -#: libs/ardour/tempo.cc:161 -msgid "MeterSection XML node has an illegal \"note-type\" value" -msgstr "" - -#: libs/ardour/tempo.cc:166 -msgid "MeterSection XML node has no \"movable\" property" -msgstr "" - -#: libs/ardour/tempo.cc:259 -msgid "move metric" -msgstr "" - -#: libs/ardour/tempo.cc:330 -msgid "metric removed" -msgstr "" - -#: libs/ardour/tempo.cc:373 -msgid "add tempo" -msgstr "" - -#: libs/ardour/tempo.cc:402 -msgid "replace tempo" -msgstr "" - -#: libs/ardour/tempo.cc:435 -msgid "add meter" -msgstr "" - -#: libs/ardour/tempo.cc:463 -msgid "replaced meter" -msgstr "" - -#: libs/ardour/tempo.cc:483 libs/ardour/tempo.cc:499 -msgid "programming error: no tempo section in tempo map!" -msgstr "" - -#: libs/ardour/tempo.cc:538 -msgid "programming error: unhandled MetricSection type" -msgstr "" - -#: libs/ardour/tempo.cc:1265 libs/ardour/tempo.cc:1277 -msgid "Tempo map: could not set new state, restoring old one." -msgstr "" - -#: libs/ardour/tempo.cc:1301 -msgid "load XML data" -msgstr "" - -#: libs/ardour/utils.cc:237 -msgid "illegal or badly-formed string used for path (%1)" -msgstr "" - -#: libs/ardour/utils.cc:242 -msgid "path (%1) is ambiguous" -msgstr "" - -#: libs/ardour/utils.cc:304 libs/ardour/utils.cc:323 -msgid "Splice Edit" -msgstr "Fogredigering" - -#: libs/ardour/utils.cc:306 libs/ardour/utils.cc:319 -msgid "Slide Edit" -msgstr "Glidredigering" - -#: libs/ardour/utils.cc:309 -msgid "programming error: unknown edit mode string \"%1\"" -msgstr "" - -#: libs/ardour/utils.cc:330 libs/ardour/utils.cc:359 -msgid "Internal" -msgstr "Intern" - -#: libs/ardour/utils.cc:334 libs/ardour/utils.cc:355 -msgid "MTC" -msgstr "" - -#: libs/ardour/utils.cc:338 libs/ardour/utils.cc:352 -msgid "JACK" -msgstr "" - -#: libs/ardour/utils.cc:342 -msgid "programming error: unknown slave source string \"%1\"" -msgstr "" - -#: libs/ardour/vst_plugin.cc:178 -msgid "cannot create VST chunk directory: %1" -msgstr "" - -#: libs/ardour/vst_plugin.cc:186 -msgid "cannot check VST chunk directory: %1" -msgstr "" - -#: libs/ardour/vst_plugin.cc:193 -msgid "%1 exists but is not a directory" -msgstr "" - -#: libs/ardour/vst_plugin.cc:231 -msgid "Bad node sent to VSTPlugin::set_state" -msgstr "" - -#: libs/ardour/vst_plugin.cc:334 libs/ardour/vst_plugin.cc:345 -msgid "no support for presets using chunks at this time" -msgstr "" - -#: libs/ardour/vst_plugin.cc:495 -msgid "VST: cannot load module from \"%1\"" -msgstr "" - -#: libs/ardour/vst_plugin.cc:500 -msgid "You asked ardour to not use any VST plugins" -msgstr "" - -#: libs/ardour/audio_unit.cc:48 -msgid "AudioUnit: Could not convert CAComponent to CAAudioUnit" -msgstr "" diff --git a/libs/ardour/port.cc b/libs/ardour/port.cc deleted file mode 100644 index 7aadb9183f..0000000000 --- a/libs/ardour/port.cc +++ /dev/null @@ -1,379 +0,0 @@ -/* - 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. - -*/ - -#include <ardour/port.h> - -using namespace ARDOUR; -using namespace std; - -AudioEngine* Port::engine = 0; - -Port::Port (const std::string& name, Flags flgs) - : _flags (flgs) - , _name (name) - , _metering (0) - , _last_monitor (false) -{ -} - -Port::~Port () -{ - disconnect_all (); -} - -void -Port::reset () -{ - _last_monitor = false; -} - -void -Port::set_engine (AudioEngine* e) -{ - engine = e; -} - -int -Port::connect (Port& other) -{ - /* caller must hold process lock */ - - pair<set<Port*>::iterator,bool> result; - - result = _connections.insert (&other); - - if (result.second) { - return 0; - } else { - return 1; - } -} - -int -Port::disconnect (Port& other) -{ - /* caller must hold process lock */ - - for (set<Port*>::iterator i = _connections.begin(); i != _connections.end(); ++i) { - if ((*i) == &other) { - _connections.erase (i); - return 0; - } - } - - return -1; -} - - -int -Port::disconnect_all () -{ - /* caller must hold process lock */ - - _connections.clear (); - return 0; -} - -void -Port::set_latency (nframes_t val) -{ - _latency = val; -} - -bool -Port::connected() const -{ - /* caller must hold process lock */ - return !_connections.empty(); -} - -bool -Port::connected_to (const string& portname) const -{ - /* caller must hold process lock */ - - for (set<Port*>::const_iterator p = _connections.begin(); p != _connections.end(); ++p) { - if ((*p)->name() == portname) { - return true; - } - } - - return false; -} - -int -Port::get_connections (vector<string>& names) const -{ - /* caller must hold process lock */ - int i = 0; - set<Port*>::const_iterator p; - - for (i = 0, p = _connections.begin(); p != _connections.end(); ++p, ++i) { - names.push_back ((*p)->name()); - } - - return i; -} - - -//------------------------------------- - -int -PortFacade::set_name (const std::string& str) -{ - int ret; - - if (_ext_port) { - if ((ret = _ext_port->set_name (str)) == 0) { - _name = _ext_port->name(); - } - } else { - _name = str; - ret = 0; - } - - return ret; -} - -string -PortFacade::short_name () const -{ - if (_ext_port) { - return _ext_port->short_name(); - } else { - return _name; - } -} - - -int -PortFacade::reestablish () -{ - if (_ext_port) { - return _ext_port->reestablish (); - } else { - return 0; - } -} - - -int -PortFacade::reconnect() -{ - if (_ext_port) { - return _ext_port->reconnect (); - } else { - return 0; - } -} - -void -PortFacade::set_latency (nframes_t val) -{ - if (_ext_port) { - _ext_port->set_latency (val); - } else { - _latency = val; - } -} - -nframes_t -PortFacade::latency() const -{ - if (_ext_port) { - return _ext_port->latency(); - } else { - return _latency; - } -} - -nframes_t -PortFacade::total_latency() const -{ - if (_ext_port) { - return _ext_port->total_latency(); - } else { - return _latency; - } -} - -bool -PortFacade::monitoring_input() const -{ - if (_ext_port) { - return _ext_port->monitoring_input (); - } else { - return false; - } -} - -void -PortFacade::ensure_monitor_input (bool yn) -{ - if (_ext_port) { - _ext_port->ensure_monitor_input (yn); - } -} - -void -PortFacade::request_monitor_input (bool yn) -{ - if (_ext_port) { - _ext_port->request_monitor_input (yn); - } -} - -int -PortFacade::connect (Port& other) -{ - int ret; - - if (_ext_port) { - ret = _ext_port->connect (other); - } else { - ret = 0; - } - - if (ret == 0) { - ret = Port::connect (other); - } - - return ret; -} - -int -PortFacade::connect (const std::string& other) -{ - PortConnectableByName* pcn; - - if (!_ext_port) { - return -1; - } - - pcn = dynamic_cast<PortConnectableByName*>(_ext_port); - - if (pcn) { - return pcn->connect (other); - } else { - return -1; - } -} - - -int -PortFacade::disconnect (Port& other) -{ - int reta; - int retb; - - if (_ext_port) { - reta = _ext_port->disconnect (other); - } else { - reta = 0; - } - - retb = Port::disconnect (other); - - return reta || retb; -} - -int -PortFacade::disconnect_all () -{ - int reta = 0; - int retb = 0; - - if (_ext_port) { - reta = _ext_port->disconnect_all (); - } - - retb = Port::disconnect_all (); - - return reta || retb; -} - -int -PortFacade::disconnect (const std::string& other) -{ - PortConnectableByName* pcn; - - if (!_ext_port) { - return -1; - } - - pcn = dynamic_cast<PortConnectableByName*>(_ext_port); - - if (pcn) { - return pcn->disconnect (other); - } else { - return -1; - } -} - -bool -PortFacade::connected () const -{ - if (Port::connected()) { - return true; - } - - if (_ext_port) { - return _ext_port->connected(); - } - - return false; -} -bool -PortFacade::connected_to (const std::string& portname) const -{ - if (Port::connected_to (portname)) { - return true; - } - - if (_ext_port) { - return _ext_port->connected_to (portname); - } - - return false; - -} - -int -PortFacade::get_connections (vector<string>& names) const -{ - int i = 0; - - if (_ext_port) { - i = _ext_port->get_connections (names); - } - - i += Port::get_connections (names); - - return i; -} - -void -PortFacade::reset () -{ - Port::reset (); - - if (_ext_port) { - _ext_port->reset (); - } -} diff --git a/libs/ardour/port_insert.cc b/libs/ardour/port_insert.cc deleted file mode 100644 index e14835b083..0000000000 --- a/libs/ardour/port_insert.cc +++ /dev/null @@ -1,246 +0,0 @@ -/* - 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. - -*/ - -#include <string> - -#include <sigc++/bind.h> - -#include <pbd/failed_constructor.h> -#include <pbd/xml++.h> - -#include <ardour/port_insert.h> -#include <ardour/plugin.h> -#include <ardour/port.h> -#include <ardour/route.h> -#include <ardour/buffer_set.h> - -#include <ardour/audioengine.h> -#include <ardour/session.h> -#include <ardour/types.h> - -#include "i18n.h" - -using namespace std; -using namespace ARDOUR; -using namespace PBD; - -PortInsert::PortInsert (Session& s, Placement p) - : IOProcessor (s, string_compose (_("insert %1"), (bitslot = s.next_insert_id()) + 1), p, 1, -1, 1, -1) -{ - init (); - ProcessorCreated (this); /* EMIT SIGNAL */ -} - -PortInsert::PortInsert (const PortInsert& other) - : IOProcessor (other._session, string_compose (_("insert %1"), (bitslot = other._session.next_insert_id()) + 1), other.placement(), 1, -1, 1, -1) -{ - init (); - ProcessorCreated (this); /* EMIT SIGNAL */ -} - -void -PortInsert::init () -{ - if (_io->add_input_port ("", this)) { - error << _("PortInsert: cannot add input port") << endmsg; - throw failed_constructor(); - } - - if (_io->add_output_port ("", this)) { - error << _("PortInsert: cannot add output port") << endmsg; - throw failed_constructor(); - } -} - -PortInsert::PortInsert (Session& s, const XMLNode& node) - : IOProcessor (s, "unnamed port insert", PreFader) -{ - if (set_state (node)) { - throw failed_constructor(); - } - - ProcessorCreated (this); /* EMIT SIGNAL */ -} - -PortInsert::~PortInsert () -{ - GoingAway (); -} - -void -PortInsert::run_in_place (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset) -{ - if (_io->n_outputs().n_total() == 0) { - return; - } - - if (!active()) { - /* deliver silence */ - _io->silence (nframes, offset); - return; - } - - _io->deliver_output(bufs, start_frame, end_frame, nframes, offset); - - _io->collect_input(bufs, nframes, offset); -} - -XMLNode& -PortInsert::get_state(void) -{ - return state (true); -} - -XMLNode& -PortInsert::state (bool full) -{ - XMLNode& node = IOProcessor::state(full); - char buf[32]; - node.add_property ("type", "port"); - snprintf (buf, sizeof (buf), "%" PRIu32, bitslot); - node.add_property ("bitslot", buf); - - return node; -} - -int -PortInsert::set_state(const XMLNode& node) -{ - XMLNodeList nlist = node.children(); - XMLNodeIterator niter; - XMLPropertyList plist; - const XMLProperty *prop; - - if ((prop = node.property ("type")) == 0) { - error << _("XML node describing port insert is missing the `type' field") << endmsg; - return -1; - } - - if (prop->value() != "port") { - error << _("non-port insert XML used for port plugin insert") << endmsg; - return -1; - } - - if ((prop = node.property ("bitslot")) == 0) { - bitslot = _session.next_insert_id(); - } else { - sscanf (prop->value().c_str(), "%" PRIu32, &bitslot); - _session.mark_insert_id (bitslot); - } - - const XMLNode* insert_node = &node; - - // legacy sessions: search for child IOProcessor node - for (niter = nlist.begin(); niter != nlist.end(); ++niter) { - if ((*niter)->name() == "IOProcessor") { - insert_node = *niter; - break; - } - } - - IOProcessor::set_state (*insert_node); - - return 0; -} - -ARDOUR::nframes_t -PortInsert::signal_latency() const -{ - /* because we deliver and collect within the same cycle, - all I/O is necessarily delayed by at least frames_per_cycle(). - - if the return port for insert has its own latency, we - need to take that into account too. - */ - - return _session.engine().frames_per_cycle() + _io->input_latency(); -} - -bool -PortInsert::can_support_input_configuration (ChanCount in) const -{ - if (_io->input_maximum() == ChanCount::INFINITE && _io->output_maximum() == ChanCount::INFINITE) { - - /* not configured yet */ - - return true; /* we can support anything the first time we're asked */ - - } else { - - /* the "input" config for a port insert corresponds to how - many output ports it will have. - */ - - if (_io->output_maximum() == in) { - - return true; - } - } - - return false; -} - -ChanCount -PortInsert::output_for_input_configuration (ChanCount in) const -{ - return in; -} - -bool -PortInsert::configure_io (ChanCount in, ChanCount out) -{ - /* do not allow configuration to be changed outside the range of - the last request config. or something like that. - */ - - - /* this is a bit odd: - - the number of inputs we are required to handle corresponds - to the number of output ports we need. - - the number of outputs we are required to have corresponds - to the number of input ports we need. - */ - - _io->set_output_maximum (in); - _io->set_output_minimum (in); - _io->set_input_maximum (out); - _io->set_input_minimum (out); - - bool success = (_io->ensure_io (out, in, false, this) == 0); - - if (success) - return Processor::configure_io(in, out); - else - return false; -} - -ChanCount -PortInsert::output_streams() const -{ - return _io->n_inputs (); -} - -ChanCount -PortInsert::input_streams() const -{ - return _io->n_outputs (); -} - diff --git a/libs/ardour/port_set.cc b/libs/ardour/port_set.cc deleted file mode 100644 index 3182c2b959..0000000000 --- a/libs/ardour/port_set.cc +++ /dev/null @@ -1,126 +0,0 @@ -/* - 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. -*/ - -#include <ardour/port_set.h> - -namespace ARDOUR { - -PortSet::PortSet() -{ - for (size_t i=0; i < DataType::num_types; ++i) - _ports.push_back( PortVec() ); -} - -static bool sort_ports_by_name (Port* a, Port* b) -{ - return (a->name() < b->name()); -} - -void -PortSet::add(Port* port) -{ - PortVec& v = _ports[port->type()]; - - v.push_back(port); - sort(v.begin(), v.end(), sort_ports_by_name); - - _count.set(port->type(), _count.get(port->type()) + 1); - - assert(_count.get(port->type()) == _ports[port->type()].size()); -} - -bool -PortSet::remove(Port* port) -{ - for (std::vector<PortVec>::iterator l = _ports.begin(); l != _ports.end(); ++l) { - PortVec::iterator i = find(l->begin(), l->end(), port); - if (i != l->end()) { - l->erase(i); - _count.set(port->type(), _count.get(port->type()) - 1); - return true; - } - } - - return false; -} - -/** Get the total number of ports (of all types) in the PortSet - */ -size_t -PortSet::num_ports() const -{ - size_t ret = 0; - - for (std::vector<PortVec>::const_iterator l = _ports.begin(); l != _ports.end(); ++l) - ret += (*l).size(); - - return ret; -} - -bool -PortSet::contains(const Port* port) const -{ - for (std::vector<PortVec>::const_iterator l = _ports.begin(); l != _ports.end(); ++l) - if (find((*l).begin(), (*l).end(), port) != (*l).end()) - return true; - - return false; -} - -Port* -PortSet::port(size_t n) const -{ - // This is awesome. Awesomely slow. - - size_t size_so_far = 0; - - for (std::vector<PortVec>::const_iterator l = _ports.begin(); l != _ports.end(); ++l) { - if (n < size_so_far + (*l).size()) - return (*l)[n - size_so_far]; - else - size_so_far += (*l).size(); - } - - return NULL; // n out of range -} - -Port* -PortSet::port(DataType type, size_t n) const -{ - if (type == DataType::NIL) { - return port(n); - } else { - const PortVec& v = _ports[type]; - assert(n < v.size()); - return v[n]; - } -} - -AudioPort* -PortSet::nth_audio_port(size_t n) const -{ - return dynamic_cast<AudioPort*>(port(DataType::AUDIO, n)); -} - -MidiPort* -PortSet::nth_midi_port(size_t n) const -{ - return dynamic_cast<MidiPort*>(port(DataType::MIDI, n)); -} - -} // namepace ARDOUR diff --git a/libs/ardour/processor.cc b/libs/ardour/processor.cc deleted file mode 100644 index cbbbb374fb..0000000000 --- a/libs/ardour/processor.cc +++ /dev/null @@ -1,255 +0,0 @@ -/* - 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. - -*/ - -#include <string> - -#include <sigc++/bind.h> - -#include <pbd/failed_constructor.h> -#include <pbd/enumwriter.h> -#include <pbd/xml++.h> - -#include <ardour/processor.h> -#include <ardour/plugin.h> -#include <ardour/port.h> -#include <ardour/route.h> -#include <ardour/ladspa_plugin.h> -#include <ardour/buffer_set.h> -#include <ardour/send.h> -#include <ardour/port_insert.h> -#include <ardour/plugin_insert.h> - -#ifdef VST_SUPPORT -#include <ardour/vst_plugin.h> -#endif - -#ifdef HAVE_AUDIOUNITS -#include <ardour/audio_unit.h> -#endif - -#include <ardour/audioengine.h> -#include <ardour/session.h> -#include <ardour/types.h> - -#include "i18n.h" - -using namespace std; -using namespace ARDOUR; -using namespace PBD; - -sigc::signal<void,Processor*> Processor::ProcessorCreated; - -// Always saved as Processor, but may be IOProcessor or Send in legacy sessions -const string Processor::state_node_name = "Processor"; - -Processor::Processor(Session& session, const string& name, Placement p) - : Automatable(session, name) - , _active(false) - , _next_ab_is_active(false) - , _configured(false) - , _placement(p) - , _gui(0) -{ -} - -boost::shared_ptr<Processor> -Processor::clone (boost::shared_ptr<const Processor> other) -{ - boost::shared_ptr<const Send> send; - boost::shared_ptr<const PortInsert> port_insert; - boost::shared_ptr<const PluginInsert> plugin_insert; - - if ((send = boost::dynamic_pointer_cast<const Send>(other)) != 0) { - return boost::shared_ptr<Processor> (new Send (*send)); - } else if ((port_insert = boost::dynamic_pointer_cast<const PortInsert>(other)) != 0) { - return boost::shared_ptr<Processor> (new PortInsert (*port_insert)); - } else if ((plugin_insert = boost::dynamic_pointer_cast<const PluginInsert>(other)) != 0) { - return boost::shared_ptr<Processor> (new PluginInsert (*plugin_insert)); - } else { - fatal << _("programming error: unknown Processor type in Processor::Clone!\n") - << endmsg; - /*NOTREACHED*/ - } - return boost::shared_ptr<Processor>(); -} - -void -Processor::set_sort_key (uint32_t key) -{ - _sort_key = key; -} - -void -Processor::set_placement (Placement p) -{ - if (_placement != p) { - _placement = p; - PlacementChanged (); /* EMIT SIGNAL */ - } -} - -void -Processor::set_active (bool yn) -{ - _active = yn; - ActiveChanged (); -} - -XMLNode& -Processor::get_state (void) -{ - return state (true); -} - -/* NODE STRUCTURE - - <Automation [optionally with visible="...." ]> - <parameter-N> - <AutomationList id=N> - <events> - X1 Y1 - X2 Y2 - .... - </events> - </parameter-N> - <Automation> -*/ - -XMLNode& -Processor::state (bool full_state) -{ - XMLNode* node = new XMLNode (state_node_name); - stringstream sstr; - - // FIXME: This conflicts with "id" used by plugin for name in legacy sessions (ugh). - // Do we need to serialize this? - /* - char buf[64]; - id().print (buf, sizeof (buf)); - node->add_property("id", buf); - */ - - node->add_property("name", _name); - node->add_property("active", active() ? "yes" : "no"); - node->add_property("placement", enum_2_string (_placement)); - - if (_extra_xml){ - node->add_child_copy (*_extra_xml); - } - - if (full_state) { - - XMLNode& automation = Automatable::get_automation_state(); - - for (set<Parameter>::iterator x = _visible_controls.begin(); x != _visible_controls.end(); ++x) { - if (x != _visible_controls.begin()) { - sstr << ' '; - } - sstr << *x; - } - - automation.add_property ("visible", sstr.str()); - - node->add_child_nocopy (automation); - } - - return *node; -} - -int -Processor::set_state (const XMLNode& node) -{ - const XMLProperty *prop; - - // may not exist for legacy sessions - if ((prop = node.property ("name")) != 0) { - set_name(prop->value()); - } - - XMLNodeList nlist = node.children(); - XMLNodeIterator niter; - - for (niter = nlist.begin(); niter != nlist.end(); ++niter) { - - if ((*niter)->name() == X_("Automation")) { - - - XMLProperty *prop; - - if ((prop = (*niter)->property ("path")) != 0) { - old_set_automation_state (*(*niter)); - } else { - set_automation_state (*(*niter), Parameter(PluginAutomation)); - } - - if ((prop = (*niter)->property ("visible")) != 0) { - uint32_t what; - stringstream sstr; - - _visible_controls.clear (); - - sstr << prop->value(); - while (1) { - sstr >> what; - if (sstr.fail()) { - break; - } - // FIXME: other automation types? - mark_automation_visible (Parameter(PluginAutomation, what), true); - } - } - - } else if ((*niter)->name() == "extra") { - _extra_xml = new XMLNode (*(*niter)); - } - } - - if ((prop = node.property ("active")) == 0) { - error << _("XML node describing a processor is missing the `active' field") << endmsg; - return -1; - } - - if (_active != (prop->value() == "yes")) { - _active = !_active; - ActiveChanged (); /* EMIT_SIGNAL */ - } - - if ((prop = node.property ("placement")) == 0) { - error << _("XML node describing a processor is missing the `placement' field") << endmsg; - return -1; - } - - /* hack to handle older sessions before we only used EnumWriter */ - - string pstr; - - if (prop->value() == "pre") { - pstr = "PreFader"; - } else if (prop->value() == "post") { - pstr = "PostFader"; - } else { - pstr = prop->value(); - } - - Placement p = Placement (string_2_enum (pstr, p)); - set_placement (p); - - return 0; -} - diff --git a/libs/ardour/quantize.cc b/libs/ardour/quantize.cc deleted file mode 100644 index ccbda9711a..0000000000 --- a/libs/ardour/quantize.cc +++ /dev/null @@ -1,85 +0,0 @@ -/* - 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. - -*/ - -#include <pbd/basename.h> - -#include <ardour/types.h> -#include <ardour/quantize.h> -#include <ardour/session.h> -#include <ardour/smf_source.h> -#include <ardour/midi_region.h> -#include <ardour/tempo.h> - -#include "i18n.h" - -using namespace std; -using namespace ARDOUR; - - -/** Quantize notes, valid for MIDI regions only. - * - * Q is the quantize value in beats, ie 1.0 = quantize to beats, - * 0.25 = quantize to beats/4, etc. - */ -Quantize::Quantize (Session& s, double q) - : Filter (s) - , _q(q) -{ -} - -Quantize::~Quantize () -{ -} - -int -Quantize::run (boost::shared_ptr<Region> r) -{ - boost::shared_ptr<MidiRegion> region = boost::dynamic_pointer_cast<MidiRegion>(r); - if (!region) - return -1; - - // FIXME: how to make a whole file region if it isn't? - //assert(region->whole_file()); - - boost::shared_ptr<MidiSource> src = region->midi_source(0); - src->load_model(); - - boost::shared_ptr<MidiModel> model = src->model(); - - // FIXME: Model really needs to be switched to beat time (double) ASAP - - const Tempo& t = session.tempo_map().tempo_at(r->start()); - const Meter& m = session.tempo_map().meter_at(r->start()); - - double q_frames = _q * (m.frames_per_bar(t, session.frame_rate()) / (double)m.beats_per_bar()); - - for (MidiModel::Notes::iterator i = model->notes().begin(); i != model->notes().end(); ++i) { - const double new_time = lrint((*i)->time() / q_frames) * q_frames; - double new_dur = lrint((*i)->duration() / q_frames) * q_frames; - if (new_dur == 0.0) - new_dur = q_frames; - - (*i)->set_time(new_time); - (*i)->set_duration(new_dur); - } - - model->set_edited(true); - - return 0; -} diff --git a/libs/ardour/rb_effect.cc b/libs/ardour/rb_effect.cc deleted file mode 100644 index 4daf5cb33a..0000000000 --- a/libs/ardour/rb_effect.cc +++ /dev/null @@ -1,298 +0,0 @@ -/* - Copyright (C) 2004-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. - -*/ - -#include <algorithm> -#include <cmath> - -#include <pbd/error.h> -#include <rubberband/RubberBandStretcher.h> - -#include <ardour/types.h> -#include <ardour/stretch.h> -#include <ardour/pitch.h> -#include <ardour/audiofilesource.h> -#include <ardour/session.h> -#include <ardour/audioregion.h> - -#include "i18n.h" - -using namespace std; -using namespace ARDOUR; -using namespace PBD; -using namespace RubberBand; - -Pitch::Pitch (Session& s, TimeFXRequest& req) - : RBEffect (s, req) -{ -} - -Stretch::Stretch (Session& s, TimeFXRequest& req) - : RBEffect (s, req) -{ -} - -RBEffect::RBEffect (Session& s, TimeFXRequest& req) - : Filter (s) - , tsr (req) - -{ - tsr.progress = 0.0f; -} - -RBEffect::~RBEffect () -{ -} - -int -RBEffect::run (boost::shared_ptr<AudioRegion> region) -{ - SourceList nsrcs; - nframes_t done; - int ret = -1; - const nframes_t bufsize = 256; - gain_t* gain_buffer = 0; - Sample** buffers = 0; - char suffix[32]; - string new_name; - string::size_type at; - nframes_t pos = 0; - int avail = 0; - - // note: this_time_fraction is a ratio of original length. 1.0 = no change, - // 0.5 is half as long, 2.0 is twice as long, etc. - - double this_time_fraction = tsr.time_fraction * region->stretch (); - double this_pitch_fraction = tsr.pitch_fraction * region->shift (); - - RubberBandStretcher stretcher (session.frame_rate(), region->n_channels(), - (RubberBandStretcher::Options) tsr.opts, - this_time_fraction, this_pitch_fraction); - - tsr.progress = 0.0f; - tsr.done = false; - - uint32_t channels = region->n_channels(); - nframes_t duration = region->ancestral_length(); - - stretcher.setExpectedInputDuration(duration); - stretcher.setDebugLevel(1); - - /* the name doesn't need to be super-precise, but allow for 2 fractional - digits just to disambiguate close but not identical FX - */ - - if (this_time_fraction == 1.0) { - snprintf (suffix, sizeof (suffix), "@%d", (int) floor (this_pitch_fraction * 100.0f)); - } else if (this_pitch_fraction == 1.0) { - snprintf (suffix, sizeof (suffix), "@%d", (int) floor (this_time_fraction * 100.0f)); - } else { - snprintf (suffix, sizeof (suffix), "@%d-%d", - (int) floor (this_time_fraction * 100.0f), - (int) floor (this_pitch_fraction * 100.0f)); - } - - /* create new sources */ - - if (make_new_sources (region, nsrcs, suffix)) { - goto out; - } - - gain_buffer = new gain_t[bufsize]; - buffers = new float *[channels]; - - for (uint32_t i = 0; i < channels; ++i) { - buffers[i] = new float[bufsize]; - } - - /* we read from the master (original) sources for the region, - not the ones currently in use, in case it's already been - subject to timefx. */ - - /* study first, process afterwards. */ - - pos = 0; - avail = 0; - done = 0; - - try { - while (pos < duration && !tsr.cancel) { - - nframes_t this_read = 0; - - for (uint32_t i = 0; i < channels; ++i) { - - this_read = 0; - nframes_t this_time; - - this_time = min(bufsize, duration - pos); - - this_read = region->master_read_at - (buffers[i], - buffers[i], - gain_buffer, - pos + region->position(), - this_time, - i); - - if (this_read != this_time) { - error << string_compose - (_("tempoize: error reading data from %1 at %2 (wanted %3, got %4)"), - region->name(), pos + region->position(), this_time, this_read) << endmsg; - goto out; - } - } - - pos += this_read; - done += this_read; - - tsr.progress = ((float) done / duration) * 0.25; - - stretcher.study(buffers, this_read, pos == duration); - } - - done = 0; - pos = 0; - - while (pos < duration && !tsr.cancel) { - - nframes_t this_read = 0; - - for (uint32_t i = 0; i < channels; ++i) { - - this_read = 0; - nframes_t this_time; - - this_time = min(bufsize, duration - pos); - - this_read = region->master_read_at - (buffers[i], - buffers[i], - gain_buffer, - pos + region->position(), - this_time, - i); - - if (this_read != this_time) { - error << string_compose - (_("tempoize: error reading data from %1 at %2 (wanted %3, got %4)"), - region->name(), pos + region->position(), this_time, this_read) << endmsg; - goto out; - } - } - - pos += this_read; - done += this_read; - - tsr.progress = 0.25 + ((float) done / duration) * 0.75; - - stretcher.process(buffers, this_read, pos == duration); - - int avail = 0; - - while ((avail = stretcher.available()) > 0) { - - this_read = min(bufsize, uint32_t(avail)); - - stretcher.retrieve(buffers, this_read); - - for (uint32_t i = 0; i < nsrcs.size(); ++i) { - - if (nsrcs[i]->write(buffers[i], this_read) != - this_read) { - error << string_compose (_("error writing tempo-adjusted data to %1"), nsrcs[i]->name()) << endmsg; - goto out; - } - } - } - } - - while ((avail = stretcher.available()) >= 0) { - - uint32_t this_read = min(bufsize, uint32_t(avail)); - - stretcher.retrieve(buffers, this_read); - - for (uint32_t i = 0; i < nsrcs.size(); ++i) { - - if (nsrcs[i]->write(buffers[i], this_read) != - this_read) { - error << string_compose (_("error writing tempo-adjusted data to %1"), nsrcs[i]->name()) << endmsg; - goto out; - } - } - } - - } catch (runtime_error& err) { - error << _("timefx code failure. please notify ardour-developers.") << endmsg; - error << err.what() << endmsg; - goto out; - } - - new_name = region->name(); - at = new_name.find ('@'); - - // remove any existing stretch indicator - - if (at != string::npos && at > 2) { - new_name = new_name.substr (0, at - 1); - } - - new_name += suffix; - - ret = finish (region, nsrcs, new_name); - - /* now reset ancestral data for each new region */ - - for (vector<boost::shared_ptr<AudioRegion> >::iterator x = results.begin(); x != results.end(); ++x) { - - (*x)->set_ancestral_data (region->ancestral_start(), - region->ancestral_length(), - this_time_fraction, - this_pitch_fraction ); - (*x)->set_master_sources (region->get_master_sources()); - } - - out: - - if (gain_buffer) { - delete [] gain_buffer; - } - - if (buffers) { - for (uint32_t i = 0; i < channels; ++i) { - delete buffers[i]; - } - delete [] buffers; - } - - if (ret || tsr.cancel) { - for (SourceList::iterator si = nsrcs.begin(); si != nsrcs.end(); ++si) { - (*si)->mark_for_remove (); - } - } - - tsr.done = true; - - return ret; -} - - - - - diff --git a/libs/ardour/recent_sessions.cc b/libs/ardour/recent_sessions.cc deleted file mode 100644 index 9b8668dd88..0000000000 --- a/libs/ardour/recent_sessions.cc +++ /dev/null @@ -1,135 +0,0 @@ -/* - 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. - -*/ - -#include <cstring> -#include <cerrno> -#include <unistd.h> -#include <fstream> -#include <algorithm> -#include <pbd/error.h> -#include <ardour/configuration.h> -#include <ardour/filesystem_paths.h> -#include <ardour/recent_sessions.h> -#include <ardour/utils.h> - -#include "i18n.h" - -using namespace std; -using namespace ARDOUR; -using namespace PBD; - -namespace { - - const char * const recent_file_name = "recent"; - -} // anonymous - -int -ARDOUR::read_recent_sessions (RecentSessions& rs) -{ - sys::path recent_file_path(user_config_directory()); - - recent_file_path /= recent_file_name; - - const string path = recent_file_path.to_string(); - - ifstream recent (path.c_str()); - - if (!recent) { - if (errno != ENOENT) { - error << string_compose (_("cannot open recent session file %1 (%2)"), path, strerror (errno)) << endmsg; - return -1; - } else { - return 1; - } - } - - while (true) { - - pair<string,string> newpair; - - getline(recent, newpair.first); - - if (!recent.good()) { - break; - } - - getline(recent, newpair.second); - - if (!recent.good()) { - break; - } - - rs.push_back (newpair); - } - - /* display sorting should be done in the GUI, otherwise the - * natural order will be broken - */ - - return 0; -} - -int -ARDOUR::write_recent_sessions (RecentSessions& rs) -{ - sys::path recent_file_path(user_config_directory()); - - recent_file_path /= recent_file_name; - - const string path = recent_file_path.to_string(); - - ofstream recent (path.c_str()); - - if (!recent) { - return -1; - } - - for (RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) { - recent << (*i).first << '\n' << (*i).second << endl; - } - - return 0; -} - -int -ARDOUR::store_recent_sessions (string name, string path) -{ - RecentSessions rs; - - if (ARDOUR::read_recent_sessions (rs) < 0) { - return -1; - } - - pair<string,string> newpair; - - newpair.first = name; - newpair.second = path; - - rs.erase(remove(rs.begin(), rs.end(), newpair), rs.end()); - - rs.push_front (newpair); - - if (rs.size() > 10) { - rs.erase(rs.begin()+10, rs.end()); - } - - return ARDOUR::write_recent_sessions (rs); -} - diff --git a/libs/ardour/region.cc b/libs/ardour/region.cc deleted file mode 100644 index a6d153f359..0000000000 --- a/libs/ardour/region.cc +++ /dev/null @@ -1,1532 +0,0 @@ -/* - Copyright (C) 2000-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. - -*/ - -#include <iostream> -#include <cmath> -#include <climits> -#include <algorithm> -#include <sstream> - -#include <sigc++/bind.h> -#include <sigc++/class_slot.h> - -#include <glibmm/thread.h> -#include <pbd/xml++.h> -#include <pbd/stacktrace.h> -#include <pbd/enumwriter.h> - -#include <ardour/region.h> -#include <ardour/playlist.h> -#include <ardour/session.h> -#include <ardour/source.h> -#include <ardour/tempo.h> -#include <ardour/region_factory.h> -#include <ardour/filter.h> - -#include "i18n.h" - -using namespace std; -using namespace ARDOUR; -using namespace PBD; - -Change Region::FadeChanged = ARDOUR::new_change (); -Change Region::SyncOffsetChanged = ARDOUR::new_change (); -Change Region::MuteChanged = ARDOUR::new_change (); -Change Region::OpacityChanged = ARDOUR::new_change (); -Change Region::LockChanged = ARDOUR::new_change (); -Change Region::LayerChanged = ARDOUR::new_change (); -Change Region::HiddenChanged = ARDOUR::new_change (); - - -/* derived-from-derived constructor (no sources in constructor) */ -Region::Region (Session& s, nframes_t start, nframes_t length, const string& name, DataType type, layer_t layer, Region::Flag flags) - : Automatable(s, name) - , _type(type) - , _flags(flags) - , _start(start) - , _length(length) - , _position(0) - , _last_position(0) - , _positional_lock_style(AudioTime) - , _sync_position(_start) - , _layer(layer) - , _first_edit(EditChangesNothing) - , _frozen(0) - , _stretch(1.0) - , _read_data_count(0) - , _pending_changed(Change (0)) - , _last_layer_op(0) -{ - /* no sources at this point */ -} - -/** Basic Region constructor (single source) */ -Region::Region (boost::shared_ptr<Source> src, nframes_t start, nframes_t length, const string& name, DataType type, layer_t layer, Region::Flag flags) - : Automatable(src->session(), name) - , _type(type) - , _flags(flags) - , _start(start) - , _length(length) - , _position(0) - , _last_position(0) - , _positional_lock_style(AudioTime) - , _sync_position(_start) - , _layer(layer) - , _first_edit(EditChangesNothing) - , _frozen(0) - , _ancestral_start (start) - , _ancestral_length (length) - , _stretch (1.0) - , _shift (0.0) - , _valid_transients(false) - , _read_data_count(0) - , _pending_changed(Change (0)) - , _last_layer_op(0) - -{ - _sources.push_back (src); - _master_sources.push_back (src); - - src->GoingAway.connect (bind (mem_fun (*this, &Region::source_deleted), src)); - - assert(_sources.size() > 0); - _positional_lock_style = AudioTime; -} - -/** Basic Region constructor (many sources) */ -Region::Region (const SourceList& srcs, nframes_t start, nframes_t length, const string& name, DataType type, layer_t layer, Region::Flag flags) - : Automatable(srcs.front()->session(), name) - , _type(type) - , _flags(flags) - , _start(start) - , _length(length) - , _position(0) - , _last_position(0) - , _positional_lock_style(AudioTime) - , _sync_position(_start) - , _layer(layer) - , _first_edit(EditChangesNothing) - , _frozen(0) - , _stretch(1.0) - , _read_data_count(0) - , _pending_changed(Change (0)) - , _last_layer_op(0) -{ - - set<boost::shared_ptr<Source> > unique_srcs; - - for (SourceList::const_iterator i=srcs.begin(); i != srcs.end(); ++i) { - _sources.push_back (*i); - (*i)->GoingAway.connect (bind (mem_fun (*this, &Region::source_deleted), (*i))); - unique_srcs.insert (*i); - } - - for (SourceList::const_iterator i = srcs.begin(); i != srcs.end(); ++i) { - _master_sources.push_back (*i); - if (unique_srcs.find (*i) == unique_srcs.end()) { - (*i)->GoingAway.connect (bind (mem_fun (*this, &Region::source_deleted), (*i))); - } - } - - assert(_sources.size() > 0); -} - -/** Create a new Region from part of an existing one */ -Region::Region (boost::shared_ptr<const Region> other, nframes_t offset, nframes_t length, const string& name, layer_t layer, Flag flags) - : Automatable(other->session(), name) - , _type(other->data_type()) - , _flags(Flag(flags & ~(Locked|PositionLocked|WholeFile|Hidden))) - , _start(other->_start + offset) - , _length(length) - , _position(0) - , _last_position(0) - , _positional_lock_style(other->_positional_lock_style) - , _sync_position(_start) - , _layer(layer) - , _first_edit(EditChangesNothing) - , _frozen(0) - , _ancestral_start (other->_ancestral_start + offset) - , _ancestral_length (length) - , _stretch (1.0) - , _shift (0.0) - , _valid_transients(false) - , _read_data_count(0) - , _pending_changed(Change (0)) - , _last_layer_op(0) -{ - if (other->_sync_position < offset) - _sync_position = other->_sync_position; - - set<boost::shared_ptr<Source> > unique_srcs; - - for (SourceList::const_iterator i= other->_sources.begin(); i != other->_sources.end(); ++i) { - _sources.push_back (*i); - (*i)->GoingAway.connect (bind (mem_fun (*this, &Region::source_deleted), (*i))); - unique_srcs.insert (*i); - } - - if (other->_sync_position < offset) { - _sync_position = other->_sync_position; - } - - for (SourceList::const_iterator i = other->_master_sources.begin(); i != other->_master_sources.end(); ++i) { - if (unique_srcs.find (*i) == unique_srcs.end()) { - (*i)->GoingAway.connect (bind (mem_fun (*this, &Region::source_deleted), (*i))); - } - _master_sources.push_back (*i); - } - - assert(_sources.size() > 0); -} - -/** Pure copy constructor */ -Region::Region (boost::shared_ptr<const Region> other) - : Automatable(other->session(), other->name()) - , _type(other->data_type()) - , _flags(Flag(other->_flags & ~(Locked|PositionLocked))) - , _start(other->_start) - , _length(other->_length) - , _position(other->_position) - , _last_position(other->_last_position) - , _positional_lock_style(other->_positional_lock_style) - , _sync_position(other->_sync_position) - , _layer(other->_layer) - , _first_edit(EditChangesID) - , _frozen(0) - , _ancestral_start (_start) - , _ancestral_length (_length) - , _stretch (1.0) - , _shift (0.0) - , _valid_transients(false) - , _read_data_count(0) - , _pending_changed(Change(0)) - , _last_layer_op(other->_last_layer_op) -{ - other->_first_edit = EditChangesName; - - if (other->_extra_xml) { - _extra_xml = new XMLNode (*other->_extra_xml); - } else { - _extra_xml = 0; - } - - set<boost::shared_ptr<Source> > unique_srcs; - - for (SourceList::const_iterator i = other->_sources.begin(); i != other->_sources.end(); ++i) { - _sources.push_back (*i); - (*i)->GoingAway.connect (bind (mem_fun (*this, &Region::source_deleted), (*i))); - unique_srcs.insert (*i); - } - - for (SourceList::const_iterator i = other->_master_sources.begin(); i != other->_master_sources.end(); ++i) { - _master_sources.push_back (*i); - if (unique_srcs.find (*i) == unique_srcs.end()) { - (*i)->GoingAway.connect (bind (mem_fun (*this, &Region::source_deleted), (*i))); - } - } - - assert(_sources.size() > 0); -} - -Region::Region (const SourceList& srcs, const XMLNode& node) - : Automatable(srcs.front()->session(), X_("error: XML did not reset this")) - , _type(DataType::NIL) // to be loaded from XML - , _flags(Flag(0)) - , _start(0) - , _length(0) - , _position(0) - , _last_position(0) - , _positional_lock_style(AudioTime) - , _sync_position(_start) - , _layer(0) - , _first_edit(EditChangesNothing) - , _frozen(0) - , _stretch(1.0) - , _read_data_count(0) - , _pending_changed(Change(0)) - , _last_layer_op(0) -{ - set<boost::shared_ptr<Source> > unique_srcs; - - for (SourceList::const_iterator i=srcs.begin(); i != srcs.end(); ++i) { - _sources.push_back (*i); - (*i)->GoingAway.connect (bind (mem_fun (*this, &Region::source_deleted), (*i))); - unique_srcs.insert (*i); - } - - for (SourceList::const_iterator i = srcs.begin(); i != srcs.end(); ++i) { - _master_sources.push_back (*i); - if (unique_srcs.find (*i) == unique_srcs.end()) { - (*i)->GoingAway.connect (bind (mem_fun (*this, &Region::source_deleted), (*i))); - } - } - - if (set_state (node)) { - throw failed_constructor(); - } - - assert(_type != DataType::NIL); - assert(_sources.size() > 0); -} - -Region::Region (boost::shared_ptr<Source> src, const XMLNode& node) - : Automatable(src->session(), X_("error: XML did not reset this")) - , _type(DataType::NIL) - , _flags(Flag(0)) - , _start(0) - , _length(0) - , _position(0) - , _last_position(0) - , _positional_lock_style(AudioTime) - , _sync_position(_start) - , _layer(0) - , _first_edit(EditChangesNothing) - , _frozen(0) - , _stretch(1.0) - , _read_data_count(0) - , _pending_changed(Change(0)) - , _last_layer_op(0) -{ - _sources.push_back (src); - - if (set_state (node)) { - throw failed_constructor(); - } - - assert(_type != DataType::NIL); - assert(_sources.size() > 0); -} - -Region::~Region () -{ - boost::shared_ptr<Playlist> pl (playlist()); - - if (pl) { - for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) { - (*i)->remove_playlist (pl); - } - for (SourceList::const_iterator i = _master_sources.begin(); i != _master_sources.end(); ++i) { - (*i)->remove_playlist (pl); - } - } - - notify_callbacks (); - GoingAway (); /* EMIT SIGNAL */ -} - -void -Region::set_playlist (boost::weak_ptr<Playlist> wpl) -{ - boost::shared_ptr<Playlist> old_playlist = (_playlist.lock()); - - boost::shared_ptr<Playlist> pl (wpl.lock()); - - if (old_playlist == pl) { - return; - } - - _playlist = pl; - - if (pl) { - if (old_playlist) { - for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) { - (*i)->remove_playlist (_playlist); - (*i)->add_playlist (pl); - } - for (SourceList::const_iterator i = _master_sources.begin(); i != _master_sources.end(); ++i) { - (*i)->remove_playlist (_playlist); - (*i)->add_playlist (pl); - } - } else { - for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) { - (*i)->add_playlist (pl); - } - for (SourceList::const_iterator i = _master_sources.begin(); i != _master_sources.end(); ++i) { - (*i)->add_playlist (pl); - } - } - } else { - if (old_playlist) { - for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) { - (*i)->remove_playlist (old_playlist); - } - for (SourceList::const_iterator i = _master_sources.begin(); i != _master_sources.end(); ++i) { - (*i)->remove_playlist (old_playlist); - } - } - } -} - -bool -Region::set_name (const std::string& str) -{ - if (_name != str) { - SessionObject::set_name(str); // EMIT SIGNAL NameChanged() - assert(_name == str); - send_change (ARDOUR::NameChanged); - } - - return true; -} - -void -Region::set_length (nframes_t len, void *src) -{ - if (_flags & Locked) { - return; - } - - if (_length != len && len != 0) { - - /* check that the current _position wouldn't make the new - length impossible. - */ - - if (max_frames - len < _position) { - return; - } - - if (!verify_length (len)) { - return; - } - - - _last_length = _length; - _length = len; - - _flags = Region::Flag (_flags & ~WholeFile); - - first_edit (); - maybe_uncopy (); - invalidate_transients (); - - if (!_frozen) { - recompute_at_end (); - } - - send_change (LengthChanged); - } -} - -void -Region::maybe_uncopy () -{ -} - -void -Region::first_edit () -{ - boost::shared_ptr<Playlist> pl (playlist()); - - if (_first_edit != EditChangesNothing && pl) { - - _name = pl->session().new_region_name (_name); - _first_edit = EditChangesNothing; - - send_change (ARDOUR::NameChanged); - RegionFactory::CheckNewRegion (shared_from_this()); - } -} - -bool -Region::at_natural_position () const -{ - boost::shared_ptr<Playlist> pl (playlist()); - - if (!pl) { - return false; - } - - boost::shared_ptr<Region> whole_file_region = get_parent(); - - if (whole_file_region) { - if (_position == whole_file_region->position() + _start) { - return true; - } - } - - return false; -} - -void -Region::move_to_natural_position (void *src) -{ - boost::shared_ptr<Playlist> pl (playlist()); - - if (!pl) { - return; - } - - boost::shared_ptr<Region> whole_file_region = get_parent(); - - if (whole_file_region) { - set_position (whole_file_region->position() + _start, src); - } -} - -void -Region::special_set_position (nframes_t pos) -{ - /* this is used when creating a whole file region as - a way to store its "natural" or "captured" position. - */ - - _position = _position; - _position = pos; -} - -void -Region::set_position_lock_style (PositionLockStyle ps) -{ - boost::shared_ptr<Playlist> pl (playlist()); - - if (!pl) { - return; - } - - _positional_lock_style = ps; - - if (_positional_lock_style == MusicTime) { - pl->session().tempo_map().bbt_time (_position, _bbt_time); - } - -} - -void -Region::update_position_after_tempo_map_change () -{ - boost::shared_ptr<Playlist> pl (playlist()); - - if (!pl || _positional_lock_style != MusicTime) { - return; - } - - TempoMap& map (pl->session().tempo_map()); - nframes_t pos = map.frame_time (_bbt_time); - set_position_internal (pos, false); -} - -void -Region::set_position (nframes_t pos, void *src) -{ - if (!can_move()) { - return; - } - - set_position_internal (pos, true); -} - -void -Region::set_position_internal (nframes_t pos, bool allow_bbt_recompute) -{ - if (_position != pos) { - _last_position = _position; - _position = pos; - - /* check that the new _position wouldn't make the current - length impossible - if so, change the length. - - XXX is this the right thing to do? - */ - - if (max_frames - _length < _position) { - _last_length = _length; - _length = max_frames - _position; - } - - if (allow_bbt_recompute) { - recompute_position_from_lock_style (); - } - - invalidate_transients (); - } - - /* do this even if the position is the same. this helps out - a GUI that has moved its representation already. - */ - - send_change (PositionChanged); -} - -void -Region::set_position_on_top (nframes_t pos, void *src) -{ - if (_flags & Locked) { - return; - } - - if (_position != pos) { - _last_position = _position; - _position = pos; - } - - boost::shared_ptr<Playlist> pl (playlist()); - - if (pl) { - pl->raise_region_to_top (shared_from_this ()); - } - - /* do this even if the position is the same. this helps out - a GUI that has moved its representation already. - */ - - send_change (PositionChanged); -} - -void -Region::recompute_position_from_lock_style () -{ - if (_positional_lock_style == MusicTime) { - boost::shared_ptr<Playlist> pl (playlist()); - if (pl) { - pl->session().tempo_map().bbt_time (_position, _bbt_time); - } - } -} - -void -Region::nudge_position (nframes64_t n, void *src) -{ - if (_flags & Locked) { - return; - } - - if (n == 0) { - return; - } - - _last_position = _position; - - if (n > 0) { - if (_position > max_frames - n) { - _position = max_frames; - } else { - _position += n; - } - } else { - if (_position < (nframes_t) -n) { - _position = 0; - } else { - _position += n; - } - } - - send_change (PositionChanged); -} - -void -Region::set_ancestral_data (nframes64_t s, nframes64_t l, float st, float sh) -{ - _ancestral_length = l; - _ancestral_start = s; - _stretch = st; - _shift = sh; -} - -void -Region::set_start (nframes_t pos, void *src) -{ - if (_flags & (Locked|PositionLocked)) { - return; - } - /* This just sets the start, nothing else. It effectively shifts - the contents of the Region within the overall extent of the Source, - without changing the Region's position or length - */ - - if (_start != pos) { - - if (!verify_start (pos)) { - return; - } - - _start = pos; - _flags = Region::Flag (_flags & ~WholeFile); - first_edit (); - invalidate_transients (); - - send_change (StartChanged); - } -} - -void -Region::trim_start (nframes_t new_position, void *src) -{ - if (_flags & (Locked|PositionLocked)) { - return; - } - nframes_t new_start; - int32_t start_shift; - - if (new_position > _position) { - start_shift = new_position - _position; - } else { - start_shift = -(_position - new_position); - } - - if (start_shift > 0) { - - if (_start > max_frames - start_shift) { - new_start = max_frames; - } else { - new_start = _start + start_shift; - } - - if (!verify_start (new_start)) { - return; - } - - } else if (start_shift < 0) { - - if (_start < (nframes_t) -start_shift) { - new_start = 0; - } else { - new_start = _start + start_shift; - } - } else { - return; - } - - if (new_start == _start) { - return; - } - - _start = new_start; - _flags = Region::Flag (_flags & ~WholeFile); - first_edit (); - - send_change (StartChanged); -} - -void -Region::trim_front (nframes_t new_position, void *src) -{ - if (_flags & Locked) { - return; - } - - nframes_t end = last_frame(); - nframes_t source_zero; - - if (_position > _start) { - source_zero = _position - _start; - } else { - source_zero = 0; // its actually negative, but this will work for us - } - - if (new_position < end) { /* can't trim it zero or negative length */ - - nframes_t newlen; - - /* can't trim it back passed where source position zero is located */ - - new_position = max (new_position, source_zero); - - - if (new_position > _position) { - newlen = _length - (new_position - _position); - } else { - newlen = _length + (_position - new_position); - } - - trim_to_internal (new_position, newlen, src); - if (!_frozen) { - recompute_at_start (); - } - } -} - -void -Region::trim_end (nframes_t new_endpoint, void *src) -{ - if (_flags & Locked) { - return; - } - - if (new_endpoint > _position) { - trim_to_internal (_position, new_endpoint - _position, this); - if (!_frozen) { - recompute_at_end (); - } - } -} - -void -Region::trim_to (nframes_t position, nframes_t length, void *src) -{ - if (_flags & Locked) { - return; - } - - trim_to_internal (position, length, src); - - if (!_frozen) { - recompute_at_start (); - recompute_at_end (); - } -} - -void -Region::trim_to_internal (nframes_t position, nframes_t length, void *src) -{ - int32_t start_shift; - nframes_t new_start; - - if (_flags & Locked) { - return; - } - - if (position > _position) { - start_shift = position - _position; - } else { - start_shift = -(_position - position); - } - - if (start_shift > 0) { - - if (_start > max_frames - start_shift) { - new_start = max_frames; - } else { - new_start = _start + start_shift; - } - - - } else if (start_shift < 0) { - - if (_start < (nframes_t) -start_shift) { - new_start = 0; - } else { - new_start = _start + start_shift; - } - } else { - new_start = _start; - } - - if (!verify_start_and_length (new_start, length)) { - return; - } - - Change what_changed = Change (0); - - if (_start != new_start) { - _start = new_start; - what_changed = Change (what_changed|StartChanged); - } - if (_length != length) { - if (!_frozen) { - _last_length = _length; - } - _length = length; - what_changed = Change (what_changed|LengthChanged); - } - if (_position != position) { - if (!_frozen) { - _last_position = _position; - } - _position = position; - what_changed = Change (what_changed|PositionChanged); - } - - _flags = Region::Flag (_flags & ~WholeFile); - - if (what_changed & (StartChanged|LengthChanged)) { - first_edit (); - } - - if (what_changed) { - send_change (what_changed); - } -} - -void -Region::set_hidden (bool yn) -{ - if (hidden() != yn) { - - if (yn) { - _flags = Flag (_flags|Hidden); - } else { - _flags = Flag (_flags & ~Hidden); - } - - send_change (HiddenChanged); - } -} - -void -Region::set_muted (bool yn) -{ - if (muted() != yn) { - - if (yn) { - _flags = Flag (_flags|Muted); - } else { - _flags = Flag (_flags & ~Muted); - } - - send_change (MuteChanged); - } -} - -void -Region::set_opaque (bool yn) -{ - if (opaque() != yn) { - if (yn) { - _flags = Flag (_flags|Opaque); - } else { - _flags = Flag (_flags & ~Opaque); - } - send_change (OpacityChanged); - } -} - -void -Region::set_locked (bool yn) -{ - if (locked() != yn) { - if (yn) { - _flags = Flag (_flags|Locked); - } else { - _flags = Flag (_flags & ~Locked); - } - send_change (LockChanged); - } -} - -void -Region::set_position_locked (bool yn) -{ - if (position_locked() != yn) { - if (yn) { - _flags = Flag (_flags|PositionLocked); - } else { - _flags = Flag (_flags & ~PositionLocked); - } - send_change (LockChanged); - } -} - -void -Region::set_sync_position (nframes_t absolute_pos) -{ - nframes_t file_pos; - - file_pos = _start + (absolute_pos - _position); - - if (file_pos != _sync_position) { - - _sync_position = file_pos; - _flags = Flag (_flags|SyncMarked); - - if (!_frozen) { - maybe_uncopy (); - } - send_change (SyncOffsetChanged); - } -} - -void -Region::clear_sync_position () -{ - if (_flags & SyncMarked) { - _flags = Flag (_flags & ~SyncMarked); - - if (!_frozen) { - maybe_uncopy (); - } - send_change (SyncOffsetChanged); - } -} - -nframes_t -Region::sync_offset (int& dir) const -{ - /* returns the sync point relative the first frame of the region */ - - if (_flags & SyncMarked) { - if (_sync_position > _start) { - dir = 1; - return _sync_position - _start; - } else { - dir = -1; - return _start - _sync_position; - } - } else { - dir = 0; - return 0; - } -} - -nframes_t -Region::adjust_to_sync (nframes_t pos) -{ - int sync_dir; - nframes_t offset = sync_offset (sync_dir); - - // cerr << "adjusting pos = " << pos << " to sync at " << _sync_position << " offset = " << offset << " with dir = " << sync_dir << endl; - - if (sync_dir > 0) { - if (pos > offset) { - pos -= offset; - } else { - pos = 0; - } - } else { - if (max_frames - pos > offset) { - pos += offset; - } - } - - return pos; -} - -nframes_t -Region::sync_position() const -{ - if (_flags & SyncMarked) { - return _sync_position; - } else { - return _start; - } -} - -void -Region::raise () -{ - boost::shared_ptr<Playlist> pl (playlist()); - if (pl) { - pl->raise_region (shared_from_this ()); - } -} - -void -Region::lower () -{ - boost::shared_ptr<Playlist> pl (playlist()); - if (pl) { - pl->lower_region (shared_from_this ()); - } -} - - -void -Region::raise_to_top () -{ - boost::shared_ptr<Playlist> pl (playlist()); - if (pl) { - pl->raise_region_to_top (shared_from_this()); - } -} - -void -Region::lower_to_bottom () -{ - boost::shared_ptr<Playlist> pl (playlist()); - if (pl) { - pl->lower_region_to_bottom (shared_from_this()); - } -} - -void -Region::set_layer (layer_t l) -{ - if (_layer != l) { - _layer = l; - - send_change (LayerChanged); - } -} - -XMLNode& -Region::state (bool full_state) -{ - XMLNode *node = new XMLNode ("Region"); - char buf[64]; - const char* fe = NULL; - - _id.print (buf, sizeof (buf)); - node->add_property ("id", buf); - node->add_property ("name", _name); - node->add_property ("type", _type.to_string()); - snprintf (buf, sizeof (buf), "%u", _start); - node->add_property ("start", buf); - snprintf (buf, sizeof (buf), "%u", _length); - node->add_property ("length", buf); - snprintf (buf, sizeof (buf), "%u", _position); - node->add_property ("position", buf); - snprintf (buf, sizeof (buf), "%" PRIi64, _ancestral_start); - node->add_property ("ancestral-start", buf); - snprintf (buf, sizeof (buf), "%" PRIi64, _ancestral_length); - node->add_property ("ancestral-length", buf); - snprintf (buf, sizeof (buf), "%.12g", _stretch); - node->add_property ("stretch", buf); - snprintf (buf, sizeof (buf), "%.12g", _shift); - node->add_property ("shift", buf); - - switch (_first_edit) { - case EditChangesNothing: - fe = X_("nothing"); - break; - case EditChangesName: - fe = X_("name"); - break; - case EditChangesID: - fe = X_("id"); - break; - default: /* should be unreachable but makes g++ happy */ - fe = X_("nothing"); - break; - } - - node->add_property ("first_edit", fe); - - /* note: flags are stored by derived classes */ - - snprintf (buf, sizeof (buf), "%d", (int) _layer); - node->add_property ("layer", buf); - snprintf (buf, sizeof (buf), "%" PRIu32, _sync_position); - node->add_property ("sync-position", buf); - - if (_positional_lock_style != AudioTime) { - node->add_property ("positional-lock-style", enum_2_string (_positional_lock_style)); - stringstream str; - str << _bbt_time; - node->add_property ("bbt-position", str.str()); - } - - return *node; -} - -XMLNode& -Region::get_state () -{ - return state (true); -} - -int -Region::set_live_state (const XMLNode& node, Change& what_changed, bool send) -{ - const XMLNodeList& nlist = node.children(); - const XMLProperty *prop; - nframes_t val; - - /* this is responsible for setting those aspects of Region state - that are mutable after construction. - */ - - if ((prop = node.property ("name")) == 0) { - error << _("XMLNode describing a Region is incomplete (no name)") << endmsg; - return -1; - } - - _name = prop->value(); - - if ((prop = node.property ("type")) == 0) { - _type = DataType::AUDIO; - } else { - _type = DataType(prop->value()); - } - - if ((prop = node.property ("start")) != 0) { - sscanf (prop->value().c_str(), "%" PRIu32, &val); - if (val != _start) { - what_changed = Change (what_changed|StartChanged); - _start = val; - } - } else { - _start = 0; - } - - if ((prop = node.property ("length")) != 0) { - sscanf (prop->value().c_str(), "%" PRIu32, &val); - if (val != _length) { - what_changed = Change (what_changed|LengthChanged); - _last_length = _length; - _length = val; - } - } else { - _last_length = _length; - _length = 1; - } - - if ((prop = node.property ("position")) != 0) { - sscanf (prop->value().c_str(), "%" PRIu32, &val); - if (val != _position) { - what_changed = Change (what_changed|PositionChanged); - _last_position = _position; - _position = val; - } - } else { - _last_position = _position; - _position = 0; - } - - if ((prop = node.property ("layer")) != 0) { - layer_t x; - x = (layer_t) atoi (prop->value().c_str()); - if (x != _layer) { - what_changed = Change (what_changed|LayerChanged); - _layer = x; - } - } else { - _layer = 0; - } - - if ((prop = node.property ("sync-position")) != 0) { - sscanf (prop->value().c_str(), "%" PRIu32, &val); - if (val != _sync_position) { - what_changed = Change (what_changed|SyncOffsetChanged); - _sync_position = val; - } - } else { - _sync_position = _start; - } - - if ((prop = node.property ("positional-lock-style")) != 0) { - _positional_lock_style = PositionLockStyle (string_2_enum (prop->value(), _positional_lock_style)); - - if (_positional_lock_style == MusicTime) { - if ((prop = node.property ("bbt-position")) == 0) { - /* missing BBT info, revert to audio time locking */ - _positional_lock_style = AudioTime; - } else { - if (sscanf (prop->value().c_str(), "%d|%d|%d", - &_bbt_time.bars, - &_bbt_time.beats, - &_bbt_time.ticks) != 3) { - _positional_lock_style = AudioTime; - } - } - } - - } else { - _positional_lock_style = AudioTime; - } - - /* XXX FIRST EDIT !!! */ - - /* these 3 properties never change as a result of any editing */ - - if ((prop = node.property ("ancestral-start")) != 0) { - _ancestral_start = atoi (prop->value()); - } else { - _ancestral_start = _start; - } - - if ((prop = node.property ("ancestral-length")) != 0) { - _ancestral_length = atoi (prop->value()); - } else { - _ancestral_length = _length; - } - - if ((prop = node.property ("stretch")) != 0) { - _stretch = atof (prop->value()); - } else { - _stretch = 1.0; - } - - if ((prop = node.property ("shift")) != 0) { - _shift = atof (prop->value()); - } else { - _shift = 1.0; - } - - /* note: derived classes set flags */ - - if (_extra_xml) { - delete _extra_xml; - _extra_xml = 0; - } - - for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) { - - XMLNode *child; - - child = (*niter); - - if (child->name () == "extra") { - _extra_xml = new XMLNode (*child); - break; - } - } - - if (send) { - send_change (what_changed); - } - - return 0; -} - -int -Region::set_state (const XMLNode& node) -{ - const XMLProperty *prop; - Change what_changed = Change (0); - - /* ID is not allowed to change, ever */ - - if ((prop = node.property ("id")) == 0) { - error << _("Session: XMLNode describing a Region is incomplete (no id)") << endmsg; - return -1; - } - - _id = prop->value(); - - _first_edit = EditChangesNothing; - - set_live_state (node, what_changed, true); - - return 0; -} - -void -Region::freeze () -{ - _frozen++; - _last_length = _length; - _last_position = _position; -} - -void -Region::thaw (const string& why) -{ - Change what_changed = Change (0); - - { - Glib::Mutex::Lock lm (_lock); - - if (_frozen && --_frozen > 0) { - return; - } - - if (_pending_changed) { - what_changed = _pending_changed; - _pending_changed = Change (0); - } - } - - if (what_changed == Change (0)) { - return; - } - - if (what_changed & LengthChanged) { - if (what_changed & PositionChanged) { - recompute_at_start (); - } - recompute_at_end (); - } - - StateChanged (what_changed); -} - -void -Region::send_change (Change what_changed) -{ - { - Glib::Mutex::Lock lm (_lock); - if (_frozen) { - _pending_changed = Change (_pending_changed|what_changed); - return; - } - } - - StateChanged (what_changed); -} - -void -Region::set_last_layer_op (uint64_t when) -{ - _last_layer_op = when; -} - -bool -Region::overlap_equivalent (boost::shared_ptr<const Region> other) const -{ - return coverage (other->first_frame(), other->last_frame()) != OverlapNone; -} - -bool -Region::equivalent (boost::shared_ptr<const Region> other) const -{ - return _start == other->_start && - _position == other->_position && - _length == other->_length; -} - -bool -Region::size_equivalent (boost::shared_ptr<const Region> other) const -{ - return _start == other->_start && - _length == other->_length; -} - -bool -Region::region_list_equivalent (boost::shared_ptr<const Region> other) const -{ - return size_equivalent (other) && source_equivalent (other) && _name == other->_name; -} - -void -Region::source_deleted (boost::shared_ptr<Source>) -{ - _sources.clear (); - drop_references (); -} - -vector<string> -Region::master_source_names () -{ - SourceList::iterator i; - - vector<string> names; - for (i = _master_sources.begin(); i != _master_sources.end(); ++i) { - names.push_back((*i)->name()); - } - - return names; -} - -void -Region::set_master_sources (SourceList& srcs) -{ - _master_sources = srcs; -} - -bool -Region::source_equivalent (boost::shared_ptr<const Region> other) const -{ - if (!other) - return false; - - SourceList::const_iterator i; - SourceList::const_iterator io; - - for (i = _sources.begin(), io = other->_sources.begin(); i != _sources.end() && io != other->_sources.end(); ++i, ++io) { - if ((*i)->id() != (*io)->id()) { - return false; - } - } - - for (i = _master_sources.begin(), io = other->_master_sources.begin(); i != _master_sources.end() && io != other->_master_sources.end(); ++i, ++io) { - if ((*i)->id() != (*io)->id()) { - return false; - } - } - - return true; -} - -bool -Region::verify_length (nframes_t len) -{ - if (source() && (source()->destructive() || source()->length_mutable())) { - return true; - } - - nframes_t maxlen = 0; - - for (uint32_t n=0; n < _sources.size(); ++n) { - maxlen = max (maxlen, _sources[n]->length() - _start); - } - - len = min (len, maxlen); - - return true; -} - -bool -Region::verify_start_and_length (nframes_t new_start, nframes_t& new_length) -{ - if (source() && (source()->destructive() || source()->length_mutable())) { - return true; - } - - nframes_t maxlen = 0; - - for (uint32_t n=0; n < _sources.size(); ++n) { - maxlen = max (maxlen, _sources[n]->length() - new_start); - } - - new_length = min (new_length, maxlen); - - return true; -} - -bool -Region::verify_start (nframes_t pos) -{ - if (source() && (source()->destructive() || source()->length_mutable())) { - return true; - } - - for (uint32_t n=0; n < _sources.size(); ++n) { - if (pos > _sources[n]->length() - _length) { - return false; - } - } - return true; -} - -bool -Region::verify_start_mutable (nframes_t& new_start) -{ - if (source() && (source()->destructive() || source()->length_mutable())) { - return true; - } - - for (uint32_t n=0; n < _sources.size(); ++n) { - if (new_start > _sources[n]->length() - _length) { - new_start = _sources[n]->length() - _length; - } - } - return true; -} - -boost::shared_ptr<Region> -Region::get_parent() const -{ - boost::shared_ptr<Playlist> pl (playlist()); - - if (pl) { - boost::shared_ptr<Region> r; - boost::shared_ptr<Region const> grrr2 = boost::dynamic_pointer_cast<Region const> (shared_from_this()); - - if (grrr2 && (r = pl->session().find_whole_file_parent (grrr2))) { - return boost::static_pointer_cast<Region> (r); - } - } - - return boost::shared_ptr<Region>(); -} - -int -Region::apply (Filter& filter) -{ - return filter.run (shared_from_this()); -} - - -void -Region::invalidate_transients () -{ - _valid_transients = false; - _transients.clear (); -} - diff --git a/libs/ardour/region_factory.cc b/libs/ardour/region_factory.cc deleted file mode 100644 index 84d8167240..0000000000 --- a/libs/ardour/region_factory.cc +++ /dev/null @@ -1,181 +0,0 @@ -/* - 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. - -*/ - -#include <pbd/error.h> - -#include <ardour/session.h> - -#include <ardour/region_factory.h> -#include <ardour/region.h> -#include <ardour/audioregion.h> -#include <ardour/audiosource.h> -#include <ardour/midi_source.h> -#include <ardour/midi_region.h> - -#include "i18n.h" - -using namespace ARDOUR; -using namespace PBD; - -sigc::signal<void,boost::shared_ptr<Region> > RegionFactory::CheckNewRegion; - -boost::shared_ptr<Region> -RegionFactory::create (boost::shared_ptr<Region> region, nframes_t start, - nframes_t length, std::string name, - layer_t layer, Region::Flag flags, bool announce) -{ - boost::shared_ptr<const AudioRegion> other_a; - boost::shared_ptr<const MidiRegion> other_m; - - if ((other_a = boost::dynamic_pointer_cast<AudioRegion>(region)) != 0) { - AudioRegion* ar = new AudioRegion (other_a, start, length, name, layer, flags); - boost::shared_ptr<AudioRegion> arp (ar); - boost::shared_ptr<Region> ret (boost::static_pointer_cast<Region> (arp)); - if (announce) { - CheckNewRegion (ret); - } - return ret; - } else if ((other_m = boost::dynamic_pointer_cast<MidiRegion>(region)) != 0) { - MidiRegion* ar = new MidiRegion (other_m, start, length, name, layer, flags); - boost::shared_ptr<MidiRegion> arp (ar); - boost::shared_ptr<Region> ret (boost::static_pointer_cast<Region> (arp)); - if (announce) { - CheckNewRegion (ret); - } - return ret; - } else { - fatal << _("programming error: RegionFactory::create() called with unknown Region type") - << endmsg; - /*NOTREACHED*/ - return boost::shared_ptr<Region>(); - } -} - -boost::shared_ptr<Region> -RegionFactory::create (boost::shared_ptr<const Region> region) -{ - boost::shared_ptr<const AudioRegion> ar; - boost::shared_ptr<const MidiRegion> mr; - - if ((ar = boost::dynamic_pointer_cast<const AudioRegion>(region)) != 0) { - boost::shared_ptr<Region> ret (new AudioRegion (ar)); - /* pure copy constructor - no CheckNewRegion emitted */ - return ret; - } else if ((mr = boost::dynamic_pointer_cast<const MidiRegion>(region)) != 0) { - boost::shared_ptr<Region> ret (new MidiRegion (mr)); - /* pure copy constructor - no CheckNewRegion emitted */ - return ret; - } else { - fatal << _("programming error: RegionFactory::create() called with unknown Region type") - << endmsg; - /*NOTREACHED*/ - return boost::shared_ptr<Region>(); - } -} - -boost::shared_ptr<Region> -RegionFactory::create (boost::shared_ptr<AudioRegion> region, nframes_t start, - nframes_t length, std::string name, - layer_t layer, Region::Flag flags, bool announce) -{ - return create (boost::static_pointer_cast<Region> (region), start, length, name, layer, flags, announce); -} - -boost::shared_ptr<Region> -RegionFactory::create (Session& session, XMLNode& node, bool yn) -{ - boost::shared_ptr<Region> r = session.XMLRegionFactory (node, yn); - CheckNewRegion (r); - return r; -} - -boost::shared_ptr<Region> -RegionFactory::create (const SourceList& srcs, nframes_t start, nframes_t length, const string& name, layer_t layer, Region::Flag flags, bool announce) -{ - if (srcs.empty()) { - return boost::shared_ptr<Region>(); - } - - if (srcs[0]->type() == DataType::AUDIO) { - - AudioRegion* ar = new AudioRegion (srcs, start, length, name, layer, flags); - boost::shared_ptr<AudioRegion> arp (ar); - boost::shared_ptr<Region> ret (boost::static_pointer_cast<Region> (arp)); - if (announce) { - CheckNewRegion (ret); - } - return ret; - - } else if (srcs[0]->type() == DataType::MIDI) { - - MidiRegion* ar = new MidiRegion (srcs, start, length, name, layer, flags); - boost::shared_ptr<MidiRegion> mrp (ar); - boost::shared_ptr<Region> ret (boost::static_pointer_cast<Region> (mrp)); - if (announce) { - CheckNewRegion (ret); - } - return ret; - - } - - return boost::shared_ptr<Region> (); -} - -boost::shared_ptr<Region> -RegionFactory::create (SourceList& srcs, const XMLNode& node) -{ - if (srcs.empty()) { - return boost::shared_ptr<Region>(); - } - - if (srcs[0]->type() == DataType::AUDIO) { - boost::shared_ptr<Region> ret (new AudioRegion (srcs, node)); - CheckNewRegion (ret); - return ret; - } else if (srcs[0]->type() == DataType::MIDI) { - boost::shared_ptr<Region> ret (new MidiRegion (srcs, node)); - CheckNewRegion (ret); - return ret; - } - - return boost::shared_ptr<Region> (); -} - -boost::shared_ptr<Region> -RegionFactory::create (boost::shared_ptr<Source> src, nframes_t start, nframes_t length, const string& name, layer_t layer, Region::Flag flags, bool announce) -{ - boost::shared_ptr<AudioSource> as; - boost::shared_ptr<MidiSource> ms; - - if ((as = boost::dynamic_pointer_cast<AudioSource>(src)) != 0) { - boost::shared_ptr<Region> ret (new AudioRegion (as, start, length, name, layer, flags)); - if (announce) { - CheckNewRegion (ret); - } - return ret; - } else if ((ms = boost::dynamic_pointer_cast<MidiSource>(src)) != 0) { - boost::shared_ptr<Region> ret (new MidiRegion (ms, start, length, name, layer, flags)); - if (announce) { - CheckNewRegion (ret); - } - return ret; - } - - return boost::shared_ptr<Region>(); -} diff --git a/libs/ardour/resampled_source.cc b/libs/ardour/resampled_source.cc deleted file mode 100644 index 083fde95a1..0000000000 --- a/libs/ardour/resampled_source.cc +++ /dev/null @@ -1,128 +0,0 @@ -/* - 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. - -*/ - -#include <pbd/error.h> -#include <ardour/resampled_source.h> -#include <pbd/failed_constructor.h> - -#include "i18n.h" - -using namespace ARDOUR; -using namespace PBD; - -const uint32_t ResampledImportableSource::blocksize = 16384U; - -ResampledImportableSource::ResampledImportableSource (boost::shared_ptr<ImportableSource> src, nframes_t rate, SrcQuality srcq) - : source (src) -{ - int err; - - source->seek (0); - - /* Initialize the sample rate converter. */ - - int src_type = SRC_LINEAR; - - switch (srcq) { - case SrcBest: - src_type = SRC_SINC_BEST_QUALITY; - break; - case SrcGood: - src_type = SRC_SINC_MEDIUM_QUALITY; - break; - case SrcQuick: - src_type = SRC_SINC_FASTEST; - break; - case SrcFast: - src_type = SRC_ZERO_ORDER_HOLD; - break; - case SrcFastest: - src_type = SRC_LINEAR; - break; - } - - if ((src_state = src_new (src_type, source->channels(), &err)) == 0) { - error << string_compose(_("Import: src_new() failed : %1"), src_strerror (err)) << endmsg ; - throw failed_constructor (); - } - - src_data.end_of_input = 0 ; /* Set this later. */ - - /* Start with zero to force load in while loop. */ - - src_data.input_frames = 0 ; - src_data.data_in = input ; - - src_data.src_ratio = ((float) rate) / source->samplerate(); - - input = new float[blocksize]; -} - -ResampledImportableSource::~ResampledImportableSource () -{ - src_state = src_delete (src_state) ; - delete [] input; -} - -nframes_t -ResampledImportableSource::read (Sample* output, nframes_t nframes) -{ - int err; - - /* If the input buffer is empty, refill it. */ - - if (src_data.input_frames == 0) { - - src_data.input_frames = source->read (input, blocksize); - - /* The last read will not be a full buffer, so set end_of_input. */ - - if ((nframes_t) src_data.input_frames < blocksize) { - src_data.end_of_input = true; - } - - src_data.input_frames /= source->channels(); - src_data.data_in = input; - } - - src_data.data_out = output; - - if (!src_data.end_of_input) { - src_data.output_frames = nframes / source->channels(); - } else { - src_data.output_frames = src_data.input_frames; - } - - if ((err = src_process (src_state, &src_data))) { - error << string_compose(_("Import: %1"), src_strerror (err)) << endmsg ; - return 0 ; - } - - /* Terminate if at end */ - - if (src_data.end_of_input && src_data.output_frames_gen == 0) { - return 0; - } - - src_data.data_in += src_data.input_frames_used * source->channels(); - src_data.input_frames -= src_data.input_frames_used ; - - return src_data.output_frames_gen * source->channels(); -} - diff --git a/libs/ardour/reverse.cc b/libs/ardour/reverse.cc deleted file mode 100644 index 02ec2924b0..0000000000 --- a/libs/ardour/reverse.cc +++ /dev/null @@ -1,130 +0,0 @@ -/* - 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. - -*/ - -#include <algorithm> - -#include <pbd/basename.h> - -#include <ardour/types.h> -#include <ardour/reverse.h> -#include <ardour/audiofilesource.h> -#include <ardour/session.h> -#include <ardour/audioregion.h> - -#include "i18n.h" - -using namespace std; -using namespace ARDOUR; - -Reverse::Reverse (Session& s) - : Filter (s) -{ -} - -Reverse::~Reverse () -{ -} - -int -Reverse::run (boost::shared_ptr<Region> r) -{ - SourceList nsrcs; - SourceList::iterator si; - nframes_t blocksize = 256 * 1024; - Sample* buf = 0; - nframes_t fpos; - nframes_t fstart; - nframes_t to_read; - int ret = -1; - - boost::shared_ptr<AudioRegion> region = boost::dynamic_pointer_cast<AudioRegion>(r); - if (!region) - return ret; - - /* create new sources */ - - if (make_new_sources (region, nsrcs)) { - goto out; - } - - fstart = region->start(); - - if (blocksize > region->length()) { - blocksize = region->length(); - } - - fpos = max (fstart, (fstart + region->length() - blocksize)); - buf = new Sample[blocksize]; - to_read = blocksize; - - /* now read it backwards */ - - while (to_read) { - - uint32_t n; - - for (n = 0, si = nsrcs.begin(); n < region->n_channels(); ++n, ++si) { - - /* read it in */ - - if (region->audio_source (n)->read (buf, fpos, to_read) != to_read) { - goto out; - } - - /* swap memory order */ - - for (nframes_t i = 0; i < to_read/2; ++i) { - swap (buf[i],buf[to_read-1-i]); - } - - /* write it out */ - - boost::shared_ptr<AudioSource> asrc(boost::dynamic_pointer_cast<AudioSource>(*si)); - - if (asrc && asrc->write (buf, to_read) != to_read) { - goto out; - } - } - - if (fpos > fstart + blocksize) { - fpos -= to_read; - to_read = blocksize; - } else { - to_read = fpos - fstart; - fpos = fstart; - } - }; - - ret = finish (region, nsrcs); - - out: - - if (buf) { - delete [] buf; - } - - if (ret) { - for (si = nsrcs.begin(); si != nsrcs.end(); ++si) { - boost::shared_ptr<AudioSource> asrc(boost::dynamic_pointer_cast<AudioSource>(*si)); - asrc->mark_for_remove (); - } - } - - return ret; -} diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc deleted file mode 100644 index e655efedb2..0000000000 --- a/libs/ardour/route.cc +++ /dev/null @@ -1,2676 +0,0 @@ -/* - 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. - -*/ - -#include <cmath> -#include <fstream> -#include <cassert> - -#include <sigc++/bind.h> -#include <pbd/xml++.h> -#include <pbd/enumwriter.h> -#include <pbd/stacktrace.h> - -#include <ardour/timestamps.h> -#include <ardour/audioengine.h> -#include <ardour/route.h> -#include <ardour/buffer.h> -#include <ardour/processor.h> -#include <ardour/plugin_insert.h> -#include <ardour/port_insert.h> -#include <ardour/send.h> -#include <ardour/session.h> -#include <ardour/utils.h> -#include <ardour/configuration.h> -#include <ardour/cycle_timer.h> -#include <ardour/route_group.h> -#include <ardour/port.h> -#include <ardour/audio_port.h> -#include <ardour/ladspa_plugin.h> -#include <ardour/panner.h> -#include <ardour/dB.h> -#include <ardour/amp.h> -#include <ardour/meter.h> -#include <ardour/buffer_set.h> -#include <ardour/mix.h> -#include <ardour/profile.h> - -#include "i18n.h" - -using namespace std; -using namespace ARDOUR; -using namespace PBD; - -uint32_t Route::order_key_cnt = 0; -sigc::signal<void> Route::SyncOrderKeys; - -Route::Route (Session& sess, string name, int input_min, int input_max, int output_min, int output_max, Flag flg, DataType default_type) - : IO (sess, name, input_min, input_max, output_min, output_max, default_type), - _flags (flg), - _solo_control (new ToggleControllable (X_("solo"), *this, ToggleControllable::SoloControl)), - _mute_control (new ToggleControllable (X_("mute"), *this, ToggleControllable::MuteControl)) -{ - init (); -} - -Route::Route (Session& sess, const XMLNode& node, DataType default_type) - : IO (sess, *node.child ("IO"), default_type), - _solo_control (new ToggleControllable (X_("solo"), *this, ToggleControllable::SoloControl)), - _mute_control (new ToggleControllable (X_("mute"), *this, ToggleControllable::MuteControl)) -{ - init (); - _set_state (node, false); -} - -void -Route::init () -{ - processor_max_outs.reset(); - _muted = false; - _soloed = false; - _solo_safe = false; - _recordable = true; - _active = true; - _phase_invert = false; - _denormal_protection = false; - order_keys[strdup (N_("signal"))] = order_key_cnt++; - _silent = false; - _meter_point = MeterPostFader; - _initial_delay = 0; - _roll_delay = 0; - _own_latency = 0; - _user_latency = 0; - _have_internal_generator = false; - _declickable = false; - _pending_declick = true; - _remote_control_id = 0; - - _edit_group = 0; - _mix_group = 0; - - _mute_affects_pre_fader = Config->get_mute_affects_pre_fader(); - _mute_affects_post_fader = Config->get_mute_affects_post_fader(); - _mute_affects_control_outs = Config->get_mute_affects_control_outs(); - _mute_affects_main_outs = Config->get_mute_affects_main_outs(); - - solo_gain = 1.0; - desired_solo_gain = 1.0; - mute_gain = 1.0; - desired_mute_gain = 1.0; - - _control_outs = 0; - - input_changed.connect (mem_fun (this, &Route::input_change_handler)); - output_changed.connect (mem_fun (this, &Route::output_change_handler)); -} - -Route::~Route () -{ - clear_processors (PreFader); - clear_processors (PostFader); - - for (OrderKeys::iterator i = order_keys.begin(); i != order_keys.end(); ++i) { - free ((void*)(i->first)); - } - - if (_control_outs) { - delete _control_outs; - } -} - -void -Route::set_remote_control_id (uint32_t id) -{ - if (id != _remote_control_id) { - _remote_control_id = id; - RemoteControlIDChanged (); - } -} - -uint32_t -Route::remote_control_id() const -{ - return _remote_control_id; -} - -long -Route::order_key (const char* name) const -{ - OrderKeys::const_iterator i; - - for (i = order_keys.begin(); i != order_keys.end(); ++i) { - if (!strcmp (name, i->first)) { - return i->second; - } - } - - return -1; -} - -void -Route::set_order_key (const char* name, long n) -{ - order_keys[strdup(name)] = n; - - if (Config->get_sync_all_route_ordering()) { - for (OrderKeys::iterator x = order_keys.begin(); x != order_keys.end(); ++x) { - x->second = n; - } - } - - _session.set_dirty (); -} - -void -Route::sync_order_keys () -{ - uint32_t key; - - if (order_keys.empty()) { - return; - } - - OrderKeys::iterator x = order_keys.begin(); - key = x->second; - ++x; - - for (; x != order_keys.end(); ++x) { - x->second = key; - } -} - -string -Route::ensure_track_or_route_name(string name, Session &session) -{ - string newname = name; - - while (session.route_by_name (newname)!=NULL) - { - newname = bump_name_once (newname); - } - - return newname; -} - - -void -Route::inc_gain (gain_t fraction, void *src) -{ - IO::inc_gain (fraction, src); -} - -void -Route::set_gain (gain_t val, void *src) -{ - if (src != 0 && _mix_group && src != _mix_group && _mix_group->is_active()) { - - if (_mix_group->is_relative()) { - - gain_t usable_gain = gain(); - if (usable_gain < 0.000001f) { - usable_gain = 0.000001f; - } - - gain_t delta = val; - if (delta < 0.000001f) { - delta = 0.000001f; - } - - delta -= usable_gain; - - if (delta == 0.0f) - return; - - gain_t factor = delta / usable_gain; - - if (factor > 0.0f) { - factor = _mix_group->get_max_factor(factor); - if (factor == 0.0f) { - _gain_control->Changed(); /* EMIT SIGNAL */ - return; - } - } else { - factor = _mix_group->get_min_factor(factor); - if (factor == 0.0f) { - _gain_control->Changed(); /* EMIT SIGNAL */ - return; - } - } - - _mix_group->apply (&Route::inc_gain, factor, _mix_group); - - } else { - - _mix_group->apply (&Route::set_gain, val, _mix_group); - } - - return; - } - - if (val == gain()) { - return; - } - - IO::set_gain (val, src); -} - -/** Process this route for one (sub) cycle (process thread) - * - * @param bufs Scratch buffers to use for the signal path - * @param start_frame Initial transport frame - * @param end_frame Final transport frame - * @param nframes Number of frames to output (to ports) - * @param offset Output offset (of port buffers, for split cycles) - * - * Note that (end_frame - start_frame) may not be equal to nframes when the - * transport speed isn't 1.0 (eg varispeed). - */ -void -Route::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) -{ - // This is definitely very audio-only for now - assert(_default_type == DataType::AUDIO); - - ProcessorList::iterator i; - bool post_fader_work = false; - bool mute_declick_applied = false; - gain_t dmg, dsg, dg; - IO *co; - bool mute_audible; - bool solo_audible; - bool no_monitor; - gain_t* gab = _session.gain_automation_buffer(); - - switch (Config->get_monitoring_model()) { - case HardwareMonitoring: - case ExternalMonitoring: - no_monitor = true; - break; - default: - no_monitor = false; - } - - declick = _pending_declick; - - { - Glib::Mutex::Lock cm (_control_outs_lock, Glib::TRY_LOCK); - - if (cm.locked()) { - co = _control_outs; - } else { - co = 0; - } - } - - { - Glib::Mutex::Lock dm (declick_lock, Glib::TRY_LOCK); - - if (dm.locked()) { - dmg = desired_mute_gain; - dsg = desired_solo_gain; - dg = _desired_gain; - } else { - dmg = mute_gain; - dsg = solo_gain; - dg = _gain; - } - } - - /* ---------------------------------------------------------------------------------------------------- - GLOBAL DECLICK (for transport changes etc.) - -------------------------------------------------------------------------------------------------- */ - - if (declick > 0) { - Amp::run_in_place (bufs, nframes, 0.0, 1.0, false); - _pending_declick = 0; - } else if (declick < 0) { - Amp::run_in_place (bufs, nframes, 1.0, 0.0, false); - _pending_declick = 0; - } else { - - /* no global declick */ - - if (solo_gain != dsg) { - Amp::run_in_place (bufs, nframes, solo_gain, dsg, false); - solo_gain = dsg; - } - } - - - /* ---------------------------------------------------------------------------------------------------- - INPUT METERING & MONITORING - -------------------------------------------------------------------------------------------------- */ - - if (meter && (_meter_point == MeterInput)) { - _meter->run_in_place(bufs, start_frame, end_frame, nframes, offset); - } - - if (!_soloed && _mute_affects_pre_fader && (mute_gain != dmg)) { - Amp::run_in_place (bufs, nframes, mute_gain, dmg, false); - mute_gain = dmg; - mute_declick_applied = true; - } - - if ((_meter_point == MeterInput) && co) { - - solo_audible = dsg > 0; - mute_audible = dmg > 0;// || !_mute_affects_pre_fader; - - if ( // muted by solo of another track - - !solo_audible || - - // muted by mute of this track - - !mute_audible || - - // rec-enabled but not s/w monitoring - - // TODO: this is probably wrong - - (no_monitor && record_enabled() && (!Config->get_auto_input() || _session.actively_recording())) - - ) { - - co->silence (nframes, offset); - - } else { - - co->deliver_output (bufs, start_frame, end_frame, nframes, offset); - - } - } - - /* ----------------------------------------------------------------------------------------------------- - DENORMAL CONTROL - -------------------------------------------------------------------------------------------------- */ - - if (_denormal_protection || Config->get_denormal_protection()) { - - for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) { - Sample* const sp = i->data(); - - for (nframes_t nx = offset; nx < nframes + offset; ++nx) { - sp[nx] += 1.0e-27f; - } - } - } - - /* ---------------------------------------------------------------------------------------------------- - PRE-FADER REDIRECTS - -------------------------------------------------------------------------------------------------- */ - - if (with_processors) { - Glib::RWLock::ReaderLock rm (_processor_lock, Glib::TRY_LOCK); - if (rm.locked()) { - if (mute_gain > 0 || !_mute_affects_pre_fader) { - for (i = _processors.begin(); i != _processors.end(); ++i) { - switch ((*i)->placement()) { - case PreFader: - (*i)->run_in_place (bufs, start_frame, end_frame, nframes, offset); - break; - case PostFader: - post_fader_work = true; - break; - } - } - } else { - for (i = _processors.begin(); i != _processors.end(); ++i) { - switch ((*i)->placement()) { - case PreFader: - (*i)->silence (nframes, offset); - break; - case PostFader: - post_fader_work = true; - break; - } - } - } - } - } - - // This really should already be true... - bufs.set_count(pre_fader_streams()); - - if (!_soloed && (mute_gain != dmg) && !mute_declick_applied && _mute_affects_post_fader) { - Amp::run_in_place (bufs, nframes, mute_gain, dmg, false); - mute_gain = dmg; - mute_declick_applied = true; - } - - /* ---------------------------------------------------------------------------------------------------- - PRE-FADER METERING & MONITORING - -------------------------------------------------------------------------------------------------- */ - - if (meter && (_meter_point == MeterPreFader)) { - _meter->run_in_place(bufs, start_frame, end_frame, nframes, offset); - } - - - if ((_meter_point == MeterPreFader) && co) { - - solo_audible = dsg > 0; - mute_audible = dmg > 0 || !_mute_affects_pre_fader; - - if ( // muted by solo of another track - - !solo_audible || - - // muted by mute of this track - - !mute_audible || - - // rec-enabled but not s/w monitoring - - (no_monitor && record_enabled() && (!Config->get_auto_input() || _session.actively_recording())) - - ) { - - co->silence (nframes, offset); - - } else { - - co->deliver_output (bufs, start_frame, end_frame, nframes, offset); - } - } - - /* ---------------------------------------------------------------------------------------------------- - GAIN STAGE - -------------------------------------------------------------------------------------------------- */ - - /* if not recording or recording and requiring any monitor signal, then apply gain */ - - if ( // not recording - - !(record_enabled() && _session.actively_recording()) || - - // OR recording - - // AND software monitoring required - - Config->get_monitoring_model() == SoftwareMonitoring) { - - if (apply_gain_automation) { - - if (_phase_invert) { - for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) { - Sample* const sp = i->data(); - - for (nframes_t nx = 0; nx < nframes; ++nx) { - sp[nx] *= -gab[nx]; - } - } - } else { - for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) { - Sample* const sp = i->data(); - - for (nframes_t nx = 0; nx < nframes; ++nx) { - sp[nx] *= gab[nx]; - } - } - } - - if (apply_gain_automation && _session.transport_rolling() && nframes > 0) { - _effective_gain = gab[nframes-1]; - } - - } else { - - /* manual (scalar) gain */ - - if (_gain != dg) { - - Amp::run_in_place (bufs, nframes, _gain, dg, _phase_invert); - _gain = dg; - - } else if (_gain != 0 && (_phase_invert || _gain != 1.0)) { - - /* no need to interpolate current gain value, - but its non-unity, so apply it. if the gain - is zero, do nothing because we'll ship silence - below. - */ - - gain_t this_gain; - - if (_phase_invert) { - this_gain = -_gain; - } else { - this_gain = _gain; - } - - for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) { - Sample* const sp = i->data(); - apply_gain_to_buffer(sp,nframes,this_gain); - } - - } else if (_gain == 0) { - for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) { - i->clear(); - } - } - } - - } else { - - /* actively recording, no monitoring required; leave buffers as-is to save CPU cycles */ - - } - - /* ---------------------------------------------------------------------------------------------------- - POST-FADER REDIRECTS - -------------------------------------------------------------------------------------------------- */ - - /* note that post_fader_work cannot be true unless with_processors was also true, so don't test both */ - - if (post_fader_work) { - - Glib::RWLock::ReaderLock rm (_processor_lock, Glib::TRY_LOCK); - if (rm.locked()) { - if (mute_gain > 0 || !_mute_affects_post_fader) { - for (i = _processors.begin(); i != _processors.end(); ++i) { - switch ((*i)->placement()) { - case PreFader: - break; - case PostFader: - (*i)->run_in_place (bufs, start_frame, end_frame, nframes, offset); - break; - } - } - } else { - for (i = _processors.begin(); i != _processors.end(); ++i) { - switch ((*i)->placement()) { - case PreFader: - break; - case PostFader: - (*i)->silence (nframes, offset); - break; - } - } - } - } - } - - if (!_soloed && (mute_gain != dmg) && !mute_declick_applied && _mute_affects_control_outs) { - Amp::run_in_place (bufs, nframes, mute_gain, dmg, false); - mute_gain = dmg; - mute_declick_applied = true; - } - - /* ---------------------------------------------------------------------------------------------------- - CONTROL OUTPUT STAGE - -------------------------------------------------------------------------------------------------- */ - - if ((_meter_point == MeterPostFader) && co) { - - solo_audible = solo_gain > 0; - mute_audible = dmg > 0 || !_mute_affects_control_outs; - - if ( // silent anyway - - (_gain == 0 && !apply_gain_automation) || - - // muted by solo of another track - - !solo_audible || - - // muted by mute of this track - - !mute_audible || - - // recording but not s/w monitoring - - (no_monitor && record_enabled() && (!Config->get_auto_input() || _session.actively_recording())) - - ) { - - co->silence (nframes, offset); - - } else { - - co->deliver_output (bufs, start_frame, end_frame, nframes, offset); - } - } - - /* ---------------------------------------------------------------------- - GLOBAL MUTE - ----------------------------------------------------------------------*/ - - if (!_soloed && (mute_gain != dmg) && !mute_declick_applied && _mute_affects_main_outs) { - Amp::run_in_place (bufs, nframes, mute_gain, dmg, false); - mute_gain = dmg; - mute_declick_applied = true; - } - - /* ---------------------------------------------------------------------------------------------------- - MAIN OUTPUT STAGE - -------------------------------------------------------------------------------------------------- */ - - solo_audible = dsg > 0; - mute_audible = dmg > 0 || !_mute_affects_main_outs; - - if (n_outputs().get(_default_type) == 0) { - - /* relax */ - - } else if (no_monitor && record_enabled() && (!Config->get_auto_input() || _session.actively_recording())) { - - IO::silence (nframes, offset); - - } else { - - if ( // silent anyway - - (_gain == 0 && !apply_gain_automation) || - - // muted by solo of another track, but not using control outs for solo - - (!solo_audible && (Config->get_solo_model() != SoloBus)) || - - // muted by mute of this track - - !mute_audible - - ) { - - /* don't use Route::silence() here, because that causes - all outputs (sends, port processors, etc. to be silent). - */ - - if (_meter_point == MeterPostFader) { - peak_meter().reset(); - } - - IO::silence (nframes, offset); - - } else { - - deliver_output(bufs, start_frame, end_frame, nframes, offset); - - } - - } - - /* ---------------------------------------------------------------------------------------------------- - POST-FADER METERING - -------------------------------------------------------------------------------------------------- */ - - if (meter && (_meter_point == MeterPostFader)) { - if ((_gain == 0 && !apply_gain_automation) || dmg == 0) { - _meter->reset(); - } else { - _meter->run_in_place(output_buffers(), start_frame, end_frame, nframes, offset); - } - } -} - -ChanCount -Route::n_process_buffers () -{ - return max (n_inputs(), processor_max_outs); -} - -void -Route::passthru (nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset, int declick, bool meter_first) -{ - BufferSet& bufs = _session.get_scratch_buffers(n_process_buffers()); - - _silent = false; - - collect_input (bufs, nframes, offset); - - if (meter_first) { - _meter->run_in_place(bufs, start_frame, end_frame, nframes, offset); - meter_first = false; - } - - process_output_buffers (bufs, start_frame, end_frame, nframes, offset, true, declick, meter_first); -} - -void -Route::passthru_silence (nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset, int declick, bool meter) -{ - process_output_buffers (_session.get_silent_buffers (n_process_buffers()), start_frame, end_frame, nframes, offset, true, declick, meter); -} - -void -Route::set_solo (bool yn, void *src) -{ - if (_solo_safe) { - return; - } - - if (_mix_group && src != _mix_group && _mix_group->is_active()) { - _mix_group->apply (&Route::set_solo, yn, _mix_group); - return; - } - - if (_soloed != yn) { - _soloed = yn; - solo_changed (src); /* EMIT SIGNAL */ - _solo_control->Changed (); /* EMIT SIGNAL */ - } -} - -void -Route::set_solo_mute (bool yn) -{ - Glib::Mutex::Lock lm (declick_lock); - - /* Called by Session in response to another Route being soloed. - */ - - desired_solo_gain = (yn?0.0:1.0); -} - -void -Route::set_solo_safe (bool yn, void *src) -{ - if (_solo_safe != yn) { - _solo_safe = yn; - solo_safe_changed (src); /* EMIT SIGNAL */ - } -} - -void -Route::set_mute (bool yn, void *src) - -{ - if (_mix_group && src != _mix_group && _mix_group->is_active()) { - _mix_group->apply (&Route::set_mute, yn, _mix_group); - return; - } - - if (_muted != yn) { - _muted = yn; - mute_changed (src); /* EMIT SIGNAL */ - - _mute_control->Changed (); /* EMIT SIGNAL */ - - Glib::Mutex::Lock lm (declick_lock); - desired_mute_gain = (yn?0.0f:1.0f); - } -} - -int -Route::add_processor (boost::shared_ptr<Processor> processor, ProcessorStreams* err) -{ - ChanCount old_rmo = processor_max_outs; - - if (!_session.engine().connected()) { - return 1; - } - - { - Glib::RWLock::WriterLock lm (_processor_lock); - - boost::shared_ptr<PluginInsert> pi; - boost::shared_ptr<PortInsert> porti; - - //processor->set_default_type(_default_type); - - if ((pi = boost::dynamic_pointer_cast<PluginInsert>(processor)) != 0) { - pi->set_count (1); - - if (pi->natural_input_streams() == ChanCount::ZERO) { - /* generator plugin */ - _have_internal_generator = true; - } - - } - - _processors.push_back (processor); - - // Set up processor list channels. This will set processor->[input|output]_streams(), - // configure redirect ports properly, etc. - if (_reset_plugin_counts (err)) { - _processors.pop_back (); - _reset_plugin_counts (0); // it worked before we tried to add it ... - return -1; - } - - // Ensure peak vector sizes before the plugin is activated - ChanCount potential_max_streams = max(processor->input_streams(), processor->output_streams()); - _meter->configure_io(potential_max_streams, potential_max_streams); - - processor->activate (); - processor->ActiveChanged.connect (bind (mem_fun (_session, &Session::update_latency_compensation), false, false)); - - _user_latency = 0; - } - - if (processor_max_outs != old_rmo || old_rmo == ChanCount::ZERO) { - reset_panner (); - } - - processors_changed (); /* EMIT SIGNAL */ - - return 0; -} - -int -Route::add_processors (const ProcessorList& others, ProcessorStreams* err) -{ - ChanCount old_rmo = processor_max_outs; - - if (!_session.engine().connected()) { - return 1; - } - - { - Glib::RWLock::WriterLock lm (_processor_lock); - - ProcessorList::iterator existing_end = _processors.end(); - --existing_end; - - ChanCount potential_max_streams; - - for (ProcessorList::const_iterator i = others.begin(); i != others.end(); ++i) { - - boost::shared_ptr<PluginInsert> pi; - - if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) { - pi->set_count (1); - - ChanCount m = max(pi->input_streams(), pi->output_streams()); - if (m > potential_max_streams) - potential_max_streams = m; - } - - // Ensure peak vector sizes before the plugin is activated - _meter->configure_io(potential_max_streams, potential_max_streams); - - _processors.push_back (*i); - - if (_reset_plugin_counts (err)) { - ++existing_end; - _processors.erase (existing_end, _processors.end()); - _reset_plugin_counts (0); // it worked before we tried to add it ... - return -1; - } - - (*i)->activate (); - (*i)->ActiveChanged.connect (bind (mem_fun (_session, &Session::update_latency_compensation), false, false)); - } - - _user_latency = 0; - } - - if (processor_max_outs != old_rmo || old_rmo == ChanCount::ZERO) { - reset_panner (); - } - - processors_changed (); /* EMIT SIGNAL */ - return 0; -} - -/** Turn off all processors with a given placement - * @param p Placement of processors to disable - */ - -void -Route::disable_processors (Placement p) -{ - Glib::RWLock::ReaderLock lm (_processor_lock); - - for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { - if ((*i)->placement() == p) { - (*i)->set_active (false); - } - } - - _session.set_dirty (); -} - -/** Turn off all redirects - */ - -void -Route::disable_processors () -{ - Glib::RWLock::ReaderLock lm (_processor_lock); - - for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { - (*i)->set_active (false); - } - - _session.set_dirty (); -} - -/** Turn off all redirects with a given placement - * @param p Placement of redirects to disable - */ - -void -Route::disable_plugins (Placement p) -{ - Glib::RWLock::ReaderLock lm (_processor_lock); - - for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { - if (boost::dynamic_pointer_cast<PluginInsert> (*i) && (*i)->placement() == p) { - (*i)->set_active (false); - } - } - - _session.set_dirty (); -} - -/** Turn off all plugins - */ - -void -Route::disable_plugins () -{ - Glib::RWLock::ReaderLock lm (_processor_lock); - - for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { - if (boost::dynamic_pointer_cast<PluginInsert> (*i)) { - (*i)->set_active (false); - } - } - - _session.set_dirty (); -} - - -void -Route::ab_plugins (bool forward) -{ - Glib::RWLock::ReaderLock lm (_processor_lock); - - if (forward) { - - /* forward = turn off all active redirects, and mark them so that the next time - we go the other way, we will revert them - */ - - for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { - if (!boost::dynamic_pointer_cast<PluginInsert> (*i)) { - continue; - } - - if ((*i)->active()) { - (*i)->set_active (false); - (*i)->set_next_ab_is_active (true); - } else { - (*i)->set_next_ab_is_active (false); - } - } - - } else { - - /* backward = if the redirect was marked to go active on the next ab, do so */ - - for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { - - if (!boost::dynamic_pointer_cast<PluginInsert> (*i)) { - continue; - } - - if ((*i)->get_next_ab_is_active()) { - (*i)->set_active (true); - } else { - (*i)->set_active (false); - } - } - } - - _session.set_dirty (); -} - - -/* Figure out the streams that will feed into PreFader */ -ChanCount -Route::pre_fader_streams() const -{ - boost::shared_ptr<Processor> processor; - - // Find the last pre-fader redirect - for (ProcessorList::const_iterator i = _processors.begin(); i != _processors.end(); ++i) { - if ((*i)->placement() == PreFader) { - processor = *i; - } - } - - if (processor) { - return processor->output_streams(); - } else { - return n_inputs (); - } -} - - -/** Remove processors with a given placement. - * @param p Placement of processors to remove. - */ -void -Route::clear_processors (Placement p) -{ - const ChanCount old_rmo = processor_max_outs; - - if (!_session.engine().connected()) { - return; - } - - { - Glib::RWLock::WriterLock lm (_processor_lock); - ProcessorList new_list; - - for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { - if ((*i)->placement() == p) { - /* it's the placement we want to get rid of */ - (*i)->drop_references (); - } else { - /* it's a different placement, so keep it */ - new_list.push_back (*i); - } - } - - _processors = new_list; - } - - /* FIXME: can't see how this test can ever fire */ - if (processor_max_outs != old_rmo) { - reset_panner (); - } - - processor_max_outs.reset(); - _have_internal_generator = false; - processors_changed (); /* EMIT SIGNAL */ -} - -int -Route::remove_processor (boost::shared_ptr<Processor> processor, ProcessorStreams* err) -{ - ChanCount old_rmo = processor_max_outs; - - if (!_session.engine().connected()) { - return 1; - } - - processor_max_outs.reset(); - - { - Glib::RWLock::WriterLock lm (_processor_lock); - ProcessorList::iterator i; - bool removed = false; - - for (i = _processors.begin(); i != _processors.end(); ++i) { - if (*i == processor) { - - ProcessorList::iterator tmp; - - /* move along, see failure case for reset_plugin_counts() - where we may need to reprocessor the processor. - */ - - tmp = i; - ++tmp; - - /* stop redirects that send signals to JACK ports - from causing noise as a result of no longer being - run. - */ - - boost::shared_ptr<IOProcessor> redirect; - - if ((redirect = boost::dynamic_pointer_cast<IOProcessor> (*i)) != 0) { - redirect->io()->disconnect_inputs (this); - redirect->io()->disconnect_outputs (this); - } - - _processors.erase (i); - - i = tmp; - removed = true; - break; - } - - _user_latency = 0; - } - - if (!removed) { - /* what? */ - return 1; - } - - if (_reset_plugin_counts (err)) { - /* get back to where we where */ - _processors.insert (i, processor); - /* we know this will work, because it worked before :) */ - _reset_plugin_counts (0); - return -1; - } - - bool foo = false; - - for (i = _processors.begin(); i != _processors.end(); ++i) { - boost::shared_ptr<PluginInsert> pi; - - if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) { - if (pi->is_generator()) { - foo = true; - } - } - } - - _have_internal_generator = foo; - } - - if (old_rmo != processor_max_outs) { - reset_panner (); - } - - processor->drop_references (); - - processors_changed (); /* EMIT SIGNAL */ - return 0; -} - -int -Route::reset_plugin_counts (ProcessorStreams* err) -{ - Glib::RWLock::WriterLock lm (_processor_lock); - return _reset_plugin_counts (err); -} - - -int -Route::_reset_plugin_counts (ProcessorStreams* err) -{ - ProcessorList::iterator r; - map<Placement,list<ProcessorCount> > processor_map; - ChanCount initial_streams; - ChanCount post_fader_input; - int ret = -1; - - /* Process each placement in order, checking to see if we - can really do what has been requested. - */ - - /* divide processors up by placement so we get the signal flow - properly modelled. we need to do this because the _processors - list is not sorted by placement, and because other reasons may - exist now or in the future for this separate treatment. - */ - - /* ... but it should/will be... */ - - for (r = _processors.begin(); r != _processors.end(); ++r) { - - boost::shared_ptr<Processor> processor; - - if ((processor = boost::dynamic_pointer_cast<Processor>(*r)) != 0) { - processor_map[processor->placement()].push_back (ProcessorCount (processor)); - } - } - - /* A: PreFader */ - - if ( ! check_some_plugin_counts (processor_map[PreFader], n_inputs (), err)) { - goto streamcount; - } - - post_fader_input = (err ? err->count : n_inputs()); - - /* B: PostFader */ - - if ( ! check_some_plugin_counts (processor_map[PostFader], post_fader_input, err)) { - goto streamcount; - } - - /* OK, everything can be set up correctly, so lets do it */ - - apply_some_plugin_counts (processor_map[PreFader]); - apply_some_plugin_counts (processor_map[PostFader]); - - /* recompute max outs of any processor */ - - ret = 0; - - streamcount: - processor_max_outs.reset(); - - for (r = _processors.begin(); r != _processors.end(); ++r) { - processor_max_outs = max ((*r)->output_streams (), processor_max_outs); - } - - return 0; -} - -int32_t -Route::apply_some_plugin_counts (list<ProcessorCount>& iclist) -{ - list<ProcessorCount>::iterator i; - - for (i = iclist.begin(); i != iclist.end(); ++i) { - - cerr << "now applying for " << (*i).processor->name() << " in = " << (*i).in.n_audio() << " out = " << (*i).out.n_audio() << endl; - - if ((*i).processor->configure_io ((*i).in, (*i).out)) { - return -1; - } - /* make sure that however many we have, they are all active */ - (*i).processor->activate (); - } - - return 0; -} - -/** Returns whether \a iclist can be configured and run starting with - * \a required_inputs at the first processor's inputs. - * If false is returned, \a iclist can not be run with \a required_inputs, and \a err is set. - * Otherwise, \a err is set to the output of the list. - */ -bool -Route::check_some_plugin_counts (list<ProcessorCount>& iclist, ChanCount required_inputs, ProcessorStreams* err) -{ - list<ProcessorCount>::iterator i; - size_t index = 0; - - if (err) { - err->index = 0; - err->count = required_inputs; - } - - for (i = iclist.begin(); i != iclist.end(); ++i) { - - - cerr << "Checking whether " << (*i).processor->name() << " can support " << required_inputs.n_audio() << " inputs\n"; - - if ((*i).processor->can_support_input_configuration (required_inputs) < 0) { - if (err) { - err->index = index; - err->count = required_inputs; - } - return false; - } - - (*i).in = required_inputs; - (*i).out = (*i).processor->output_for_input_configuration (required_inputs); - - cerr << "config looks like " << (*i).processor->name() << " in = " << (*i).in.n_audio() << " out = " << (*i).out.n_audio() << endl; - - required_inputs = (*i).out; - - ++index; - } - - if (err) { - if (!iclist.empty()) { - err->index = index; - err->count = iclist.back().processor->output_for_input_configuration(required_inputs); - } - } - - return true; -} - -int -Route::copy_processors (const Route& other, Placement placement, ProcessorStreams* err) -{ - ChanCount old_rmo = processor_max_outs; - - ProcessorList to_be_deleted; - - { - Glib::RWLock::WriterLock lm (_processor_lock); - ProcessorList::iterator tmp; - ProcessorList the_copy; - - the_copy = _processors; - - /* remove all relevant processors */ - - for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ) { - tmp = i; - ++tmp; - - if ((*i)->placement() == placement) { - to_be_deleted.push_back (*i); - _processors.erase (i); - } - - i = tmp; - } - - /* now copy the relevant ones from "other" */ - - for (ProcessorList::const_iterator i = other._processors.begin(); i != other._processors.end(); ++i) { - if ((*i)->placement() == placement) { - _processors.push_back (IOProcessor::clone (*i)); - } - } - - /* reset plugin stream handling */ - - if (_reset_plugin_counts (err)) { - - /* FAILED COPY ATTEMPT: we have to restore order */ - - /* delete all cloned processors */ - - for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ) { - - tmp = i; - ++tmp; - - if ((*i)->placement() == placement) { - _processors.erase (i); - } - - i = tmp; - } - - /* restore the natural order */ - - _processors = the_copy; - processor_max_outs = old_rmo; - - /* we failed, even though things are OK again */ - - return -1; - - } else { - - /* SUCCESSFUL COPY ATTEMPT: delete the processors we removed pre-copy */ - to_be_deleted.clear (); - _user_latency = 0; - } - } - - if (processor_max_outs != old_rmo || old_rmo == ChanCount::ZERO) { - reset_panner (); - } - - processors_changed (); /* EMIT SIGNAL */ - return 0; -} - -void -Route::all_processors_flip () -{ - Glib::RWLock::ReaderLock lm (_processor_lock); - - if (_processors.empty()) { - return; - } - - bool first_is_on = _processors.front()->active(); - - for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { - (*i)->set_active (!first_is_on); - } - - _session.set_dirty (); -} - -/** Set all processors with a given placement to a given active state. - * @param p Placement of processors to change. - * @param state New active state for those processors. - */ -void -Route::all_processors_active (Placement p, bool state) -{ - Glib::RWLock::ReaderLock lm (_processor_lock); - - if (_processors.empty()) { - return; - } - - for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { - if ((*i)->placement() == p) { - (*i)->set_active (state); - } - } - - _session.set_dirty (); -} - -struct ProcessorSorter { - bool operator() (boost::shared_ptr<const Processor> a, boost::shared_ptr<const Processor> b) { - return a->sort_key() < b->sort_key(); - } -}; - -int -Route::sort_processors (ProcessorStreams* err) -{ - { - ProcessorSorter comparator; - Glib::RWLock::WriterLock lm (_processor_lock); - ChanCount old_rmo = processor_max_outs; - - /* the sweet power of C++ ... */ - - ProcessorList as_it_was_before = _processors; - - _processors.sort (comparator); - - if (_reset_plugin_counts (err)) { - _processors = as_it_was_before; - processor_max_outs = old_rmo; - return -1; - } - } - - reset_panner (); - processors_changed (); /* EMIT SIGNAL */ - - return 0; -} - -XMLNode& -Route::get_state() -{ - return state(true); -} - -XMLNode& -Route::get_template() -{ - return state(false); -} - -XMLNode& -Route::state(bool full_state) -{ - XMLNode *node = new XMLNode("Route"); - ProcessorList::iterator i; - char buf[32]; - - if (_flags) { - node->add_property("flags", enum_2_string (_flags)); - } - - node->add_property("default-type", _default_type.to_string()); - - node->add_property("active", _active?"yes":"no"); - node->add_property("muted", _muted?"yes":"no"); - node->add_property("soloed", _soloed?"yes":"no"); - node->add_property("phase-invert", _phase_invert?"yes":"no"); - node->add_property("denormal-protection", _denormal_protection?"yes":"no"); - node->add_property("mute-affects-pre-fader", _mute_affects_pre_fader?"yes":"no"); - node->add_property("mute-affects-post-fader", _mute_affects_post_fader?"yes":"no"); - node->add_property("mute-affects-control-outs", _mute_affects_control_outs?"yes":"no"); - node->add_property("mute-affects-main-outs", _mute_affects_main_outs?"yes":"no"); - - if (_edit_group) { - node->add_property("edit-group", _edit_group->name()); - } - if (_mix_group) { - node->add_property("mix-group", _mix_group->name()); - } - - string order_string; - OrderKeys::iterator x = order_keys.begin(); - - while (x != order_keys.end()) { - order_string += string ((*x).first); - order_string += '='; - snprintf (buf, sizeof(buf), "%ld", (*x).second); - order_string += buf; - - ++x; - - if (x == order_keys.end()) { - break; - } - - order_string += ':'; - } - node->add_property ("order-keys", order_string); - - node->add_child_nocopy (IO::state (full_state)); - node->add_child_nocopy (_solo_control->get_state ()); - node->add_child_nocopy (_mute_control->get_state ()); - - XMLNode* remote_control_node = new XMLNode (X_("remote_control")); - snprintf (buf, sizeof (buf), "%d", _remote_control_id); - remote_control_node->add_property (X_("id"), buf); - node->add_child_nocopy (*remote_control_node); - - if (_control_outs) { - XMLNode* cnode = new XMLNode (X_("ControlOuts")); - cnode->add_child_nocopy (_control_outs->state (full_state)); - node->add_child_nocopy (*cnode); - } - - if (_comment.length()) { - XMLNode *cmt = node->add_child ("Comment"); - cmt->add_content (_comment); - } - - for (i = _processors.begin(); i != _processors.end(); ++i) { - node->add_child_nocopy((*i)->state (full_state)); - } - - if (_extra_xml){ - node->add_child_copy (*_extra_xml); - } - - return *node; -} - -XMLNode& -Route::get_processor_state () -{ - XMLNode* root = new XMLNode (X_("redirects")); - for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { - root->add_child_nocopy ((*i)->state (true)); - } - - return *root; -} - -int -Route::set_processor_state (const XMLNode& root) -{ - if (root.name() != X_("redirects")) { - return -1; - } - - XMLNodeList nlist; - XMLNodeList nnlist; - XMLNodeConstIterator iter; - XMLNodeConstIterator niter; - Glib::RWLock::ReaderLock lm (_processor_lock); - - nlist = root.children(); - - for (iter = nlist.begin(); iter != nlist.end(); ++iter){ - - /* iter now points to a IOProcessor state node */ - - nnlist = (*iter)->children (); - - for (niter = nnlist.begin(); niter != nnlist.end(); ++niter) { - - /* find the IO child node, since it contains the ID we need */ - - /* XXX OOP encapsulation violation, ugh */ - - if ((*niter)->name() == IO::state_node_name) { - - XMLProperty* prop = (*niter)->property (X_("id")); - - if (!prop) { - warning << _("IOProcessor node has no ID, ignored") << endmsg; - break; - } - - ID id = prop->value (); - - /* now look for a processor with that ID */ - - for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { - if ((*i)->id() == id) { - (*i)->set_state (**iter); - break; - } - } - - break; - - } - } - - } - - return 0; -} - -void -Route::set_deferred_state () -{ - XMLNodeList nlist; - XMLNodeConstIterator niter; - - if (!deferred_state) { - return; - } - - nlist = deferred_state->children(); - - for (niter = nlist.begin(); niter != nlist.end(); ++niter){ - add_processor_from_xml (**niter); - } - - delete deferred_state; - deferred_state = 0; -} - -void -Route::add_processor_from_xml (const XMLNode& node) -{ - const XMLProperty *prop; - - // legacy sessions use a different node name for sends - if (node.name() == "Send") { - - try { - boost::shared_ptr<Send> send (new Send (_session, node)); - add_processor (send); - } - - catch (failed_constructor &err) { - error << _("Send construction failed") << endmsg; - return; - } - - // use "Processor" in XML? - } else if (node.name() == "Processor") { - - try { - if ((prop = node.property ("type")) != 0) { - - boost::shared_ptr<Processor> processor; - bool have_insert = false; - - if (prop->value() == "ladspa" || prop->value() == "Ladspa" || - prop->value() == "lv2" || - prop->value() == "vst" || - prop->value() == "audiounit") { - - processor.reset (new PluginInsert(_session, node)); - have_insert = true; - - } else if (prop->value() == "port") { - - processor.reset (new PortInsert (_session, node)); - - } else if (prop->value() == "send") { - - processor.reset (new Send (_session, node)); - have_insert = true; - - } else { - - error << string_compose(_("unknown Processor type \"%1\"; ignored"), prop->value()) << endmsg; - } - - add_processor (processor); - - } else { - error << _("Processor XML node has no type property") << endmsg; - } - } - - catch (failed_constructor &err) { - warning << _("processor could not be created. Ignored.") << endmsg; - return; - } - } -} - -int -Route::set_state (const XMLNode& node) -{ - return _set_state (node, true); -} - -int -Route::_set_state (const XMLNode& node, bool call_base) -{ - XMLNodeList nlist; - XMLNodeConstIterator niter; - XMLNode *child; - XMLPropertyList plist; - const XMLProperty *prop; - - if (node.name() != "Route"){ - error << string_compose(_("Bad node sent to Route::set_state() [%1]"), node.name()) << endmsg; - return -1; - } - - if ((prop = node.property (X_("flags"))) != 0) { - _flags = Flag (string_2_enum (prop->value(), _flags)); - } else { - _flags = Flag (0); - } - - if ((prop = node.property (X_("default-type"))) != 0) { - _default_type = DataType(prop->value()); - assert(_default_type != DataType::NIL); - } - - if ((prop = node.property (X_("phase-invert"))) != 0) { - set_phase_invert (prop->value()=="yes"?true:false, this); - } - - if ((prop = node.property (X_("denormal-protection"))) != 0) { - set_denormal_protection (prop->value()=="yes"?true:false, this); - } - - _active = true; - if ((prop = node.property (X_("active"))) != 0) { - set_active (prop->value() == "yes"); - } - - if ((prop = node.property (X_("muted"))) != 0) { - bool yn = prop->value()=="yes"?true:false; - - /* force reset of mute status */ - - _muted = !yn; - set_mute(yn, this); - mute_gain = desired_mute_gain; - } - - if ((prop = node.property (X_("soloed"))) != 0) { - bool yn = prop->value()=="yes"?true:false; - - /* force reset of solo status */ - - _soloed = !yn; - set_solo (yn, this); - solo_gain = desired_solo_gain; - } - - if ((prop = node.property (X_("mute-affects-pre-fader"))) != 0) { - _mute_affects_pre_fader = (prop->value()=="yes")?true:false; - } - - if ((prop = node.property (X_("mute-affects-post-fader"))) != 0) { - _mute_affects_post_fader = (prop->value()=="yes")?true:false; - } - - if ((prop = node.property (X_("mute-affects-control-outs"))) != 0) { - _mute_affects_control_outs = (prop->value()=="yes")?true:false; - } - - if ((prop = node.property (X_("mute-affects-main-outs"))) != 0) { - _mute_affects_main_outs = (prop->value()=="yes")?true:false; - } - - if ((prop = node.property (X_("edit-group"))) != 0) { - RouteGroup* edit_group = _session.edit_group_by_name(prop->value()); - if(edit_group == 0) { - error << string_compose(_("Route %1: unknown edit group \"%2 in saved state (ignored)"), _name, prop->value()) << endmsg; - } else { - set_edit_group(edit_group, this); - } - } - - if ((prop = node.property (X_("order-keys"))) != 0) { - - long n; - - string::size_type colon, equal; - string remaining = prop->value(); - - while (remaining.length()) { - - if ((equal = remaining.find_first_of ('=')) == string::npos || equal == remaining.length()) { - error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining) - << endmsg; - } else { - if (sscanf (remaining.substr (equal+1).c_str(), "%ld", &n) != 1) { - error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining) - << endmsg; - } else { - set_order_key (remaining.substr (0, equal).c_str(), n); - } - } - - colon = remaining.find_first_of (':'); - - if (colon != string::npos) { - remaining = remaining.substr (colon+1); - } else { - break; - } - } - } - - nlist = node.children(); - - if (deferred_state) { - delete deferred_state; - } - - deferred_state = new XMLNode(X_("deferred state")); - - /* set parent class properties before anything else */ - - for (niter = nlist.begin(); niter != nlist.end(); ++niter){ - - child = *niter; - - if (child->name() == IO::state_node_name && call_base) { - - IO::set_state (*child); - break; - } - } - - XMLNodeList processor_nodes; - - for (niter = nlist.begin(); niter != nlist.end(); ++niter){ - - child = *niter; - - if (child->name() == X_("Send") || child->name() == X_("Processor")) { - processor_nodes.push_back(child); - } - - } - - _set_processor_states(processor_nodes); - - - for (niter = nlist.begin(); niter != nlist.end(); ++niter){ - child = *niter; - // All processors have been applied already - - if (child->name() == X_("Automation")) { - - if ((prop = child->property (X_("path"))) != 0) { - load_automation (prop->value()); - } - - } else if (child->name() == X_("ControlOuts")) { - - string coutname = _name; - coutname += _("[control]"); - - _control_outs = new IO (_session, coutname); - _control_outs->set_state (**(child->children().begin())); - - } else if (child->name() == X_("Comment")) { - - /* XXX this is a terrible API design in libxml++ */ - - XMLNode *cmt = *(child->children().begin()); - _comment = cmt->content(); - - } else if (child->name() == X_("extra")) { - - _extra_xml = new XMLNode (*child); - - } else if (child->name() == X_("controllable") && (prop = child->property("name")) != 0) { - - if (prop->value() == "solo") { - _solo_control->set_state (*child); - _session.add_controllable (_solo_control); - } - else if (prop->value() == "mute") { - _mute_control->set_state (*child); - _session.add_controllable (_mute_control); - } - } - else if (child->name() == X_("remote_control")) { - if ((prop = child->property (X_("id"))) != 0) { - int32_t x; - sscanf (prop->value().c_str(), "%d", &x); - set_remote_control_id (x); - } - } - } - - if ((prop = node.property (X_("mix-group"))) != 0) { - RouteGroup* mix_group = _session.mix_group_by_name(prop->value()); - if (mix_group == 0) { - error << string_compose(_("Route %1: unknown mix group \"%2 in saved state (ignored)"), _name, prop->value()) << endmsg; - } else { - set_mix_group(mix_group, this); - } - } - - return 0; -} - -void -Route::_set_processor_states(const XMLNodeList &nlist) -{ - XMLNodeConstIterator niter; - char buf[64]; - - ProcessorList::iterator i, o; - - // Iterate through existing processors, remove those which are not in the state list - for (i = _processors.begin(); i != _processors.end(); ) { - ProcessorList::iterator tmp = i; - ++tmp; - - bool processorInStateList = false; - - (*i)->id().print (buf, sizeof (buf)); - - - for (niter = nlist.begin(); niter != nlist.end(); ++niter) { - - // legacy sessions (IOProcessor as a child of Processor, both is-a IO) - if (strncmp(buf,(*niter)->child(X_("IOProcessor"))->child(X_("IO"))->property(X_("id"))->value().c_str(), sizeof(buf)) == 0) { - processorInStateList = true; - break; - } else if (strncmp(buf,(*niter)->property(X_("id"))->value().c_str(), sizeof(buf)) == 0) { - processorInStateList = true; - break; - } - } - - if (!processorInStateList) { - remove_processor (*i); - } - - - i = tmp; - } - - - // Iterate through state list and make sure all processors are on the track and in the correct order, - // set the state of existing processors according to the new state on the same go - i = _processors.begin(); - for (niter = nlist.begin(); niter != nlist.end(); ++niter, ++i) { - - // Check whether the next processor in the list - o = i; - - while (o != _processors.end()) { - (*o)->id().print (buf, sizeof (buf)); - if ( strncmp(buf, (*niter)->child(X_("IOProcessor"))->child(X_("IO"))->property(X_("id"))->value().c_str(), sizeof(buf)) == 0) - break; - else if (strncmp(buf,(*niter)->property(X_("id"))->value().c_str(), sizeof(buf)) == 0) - break; - - ++o; - } - - if (o == _processors.end()) { - // If the processor (*niter) is not on the route, we need to create it - // and move it to the correct location - - ProcessorList::iterator prev_last = _processors.end(); - --prev_last; // We need this to check whether adding succeeded - - add_processor_from_xml (**niter); - - ProcessorList::iterator last = _processors.end(); - --last; - - if (prev_last == last) { - cerr << "Could not fully restore state as some processors were not possible to create" << endl; - continue; - - } - - boost::shared_ptr<Processor> tmp = (*last); - // remove the processor from the wrong location - _processors.erase(last); - // processor the new processor at the current location - _processors.insert(i, tmp); - - --i; // move pointer to the newly processored processor - continue; - } - - // We found the processor (*niter) on the route, first we must make sure the processor - // is at the location provided in the XML state - if (i != o) { - boost::shared_ptr<Processor> tmp = (*o); - // remove the old copy - _processors.erase(o); - // processor the processor at the correct location - _processors.insert(i, tmp); - - --i; // move pointer so it points to the right processor - } - - (*i)->set_state( (**niter) ); - } - - processors_changed (); -} - -void -Route::curve_reallocate () -{ -// _gain_automation_curve.finish_resize (); -// _pan_automation_curve.finish_resize (); -} - -void -Route::silence (nframes_t nframes, nframes_t offset) -{ - if (!_silent) { - - IO::silence (nframes, offset); - - if (_control_outs) { - _control_outs->silence (nframes, offset); - } - - { - Glib::RWLock::ReaderLock lm (_processor_lock, Glib::TRY_LOCK); - - if (lm.locked()) { - for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { - boost::shared_ptr<PluginInsert> pi; - if (!_active && (pi = boost::dynamic_pointer_cast<PluginInsert> (*i)) != 0) { - // skip plugins, they don't need anything when we're not active - continue; - } - - (*i)->silence (nframes, offset); - } - - if (nframes == _session.get_block_size() && offset == 0) { - // _silent = true; - } - } - } - - } -} - -int -Route::set_control_outs (const vector<string>& ports) -{ - Glib::Mutex::Lock lm (_control_outs_lock); - vector<string>::const_iterator i; - size_t limit; - - if (_control_outs) { - delete _control_outs; - _control_outs = 0; - } - - if (is_control() || is_master()) { - /* no control outs for these two special busses */ - return 0; - } - - if (ports.empty()) { - return 0; - } - - string coutname = _name; - coutname += _("[control]"); - - _control_outs = new IO (_session, coutname); - - /* our control outs need as many outputs as we - have audio outputs. we track the changes in ::output_change_handler(). - */ - - // XXX its stupid that we have to get this value twice - - limit = n_outputs().n_audio(); - - if (_control_outs->ensure_io (ChanCount::ZERO, ChanCount (DataType::AUDIO, n_outputs().get (DataType::AUDIO)), true, this)) { - return -1; - } - - /* now connect to the named ports */ - - for (size_t n = 0; n < limit; ++n) { - if (_control_outs->connect_output (_control_outs->output (n), ports[n % ports.size()], this)) { - error << string_compose (_("could not connect %1 to %2"), _control_outs->output(n)->name(), ports[n]) << endmsg; - return -1; - } - } - - return 0; -} - -void -Route::set_edit_group (RouteGroup *eg, void *src) - -{ - if (eg == _edit_group) { - return; - } - - if (_edit_group) { - _edit_group->remove (this); - } - - if ((_edit_group = eg) != 0) { - _edit_group->add (this); - } - - _session.set_dirty (); - edit_group_changed (src); /* EMIT SIGNAL */ -} - -void -Route::drop_edit_group (void *src) -{ - _edit_group = 0; - _session.set_dirty (); - edit_group_changed (src); /* EMIT SIGNAL */ -} - -void -Route::set_mix_group (RouteGroup *mg, void *src) - -{ - if (mg == _mix_group) { - return; - } - - if (_mix_group) { - _mix_group->remove (this); - } - - if ((_mix_group = mg) != 0) { - _mix_group->add (this); - } - - _session.set_dirty (); - mix_group_changed (src); /* EMIT SIGNAL */ -} - -void -Route::drop_mix_group (void *src) -{ - _mix_group = 0; - _session.set_dirty (); - mix_group_changed (src); /* EMIT SIGNAL */ -} - -void -Route::set_comment (string cmt, void *src) -{ - _comment = cmt; - comment_changed (src); - _session.set_dirty (); -} - -bool -Route::feeds (boost::shared_ptr<Route> other) -{ - uint32_t i, j; - - IO& self = *this; - uint32_t no = self.n_outputs().n_total(); - uint32_t ni = other->n_inputs ().n_total(); - - for (i = 0; i < no; ++i) { - for (j = 0; j < ni; ++j) { - if (self.output(i)->connected_to (other->input(j)->name())) { - return true; - } - } - } - - /* check IOProcessors which may also interconnect Routes */ - - for (ProcessorList::iterator r = _processors.begin(); r != _processors.end(); r++) { - - boost::shared_ptr<IOProcessor> redirect = boost::dynamic_pointer_cast<IOProcessor>(*r); - - if ( ! redirect) - continue; - - // TODO: support internal redirects here - - no = redirect->io()->n_outputs().n_total(); - - for (i = 0; i < no; ++i) { - for (j = 0; j < ni; ++j) { - if (redirect->io()->output(i)->connected_to (other->input (j)->name())) { - return true; - } - } - } - } - - /* check for control room outputs which may also interconnect Routes */ - - if (_control_outs) { - - no = _control_outs->n_outputs().n_total(); - - for (i = 0; i < no; ++i) { - for (j = 0; j < ni; ++j) { - if (_control_outs->output(i)->connected_to (other->input (j)->name())) { - return true; - } - } - } - } - - return false; -} - -void -Route::set_mute_config (mute_type t, bool onoff, void *src) -{ - switch (t) { - case PRE_FADER: - _mute_affects_pre_fader = onoff; - pre_fader_changed(src); /* EMIT SIGNAL */ - break; - - case POST_FADER: - _mute_affects_post_fader = onoff; - post_fader_changed(src); /* EMIT SIGNAL */ - break; - - case CONTROL_OUTS: - _mute_affects_control_outs = onoff; - control_outs_changed(src); /* EMIT SIGNAL */ - break; - - case MAIN_OUTS: - _mute_affects_main_outs = onoff; - main_outs_changed(src); /* EMIT SIGNAL */ - break; - } -} - -bool -Route::get_mute_config (mute_type t) -{ - bool onoff = false; - - switch (t){ - case PRE_FADER: - onoff = _mute_affects_pre_fader; - break; - case POST_FADER: - onoff = _mute_affects_post_fader; - break; - case CONTROL_OUTS: - onoff = _mute_affects_control_outs; - break; - case MAIN_OUTS: - onoff = _mute_affects_main_outs; - break; - } - - return onoff; -} - -void -Route::handle_transport_stopped (bool abort_ignored, bool did_locate, bool can_flush_processors) -{ - nframes_t now = _session.transport_frame(); - - { - Glib::RWLock::ReaderLock lm (_processor_lock); - - if (!did_locate) { - automation_snapshot (now, true); - } - - for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { - - if (Config->get_plugins_stop_with_transport() && can_flush_processors) { - (*i)->deactivate (); - (*i)->activate (); - } - - (*i)->transport_stopped (now); - } - } - - IO::transport_stopped (now); - - _roll_delay = _initial_delay; -} - -void -Route::input_change_handler (IOChange change, void *ignored) -{ - if (change & ConfigurationChanged) { - reset_plugin_counts (0); - } -} - -void -Route::output_change_handler (IOChange change, void *ignored) -{ - if (change & ConfigurationChanged) { - if (_control_outs) { - _control_outs->ensure_io (ChanCount::ZERO, ChanCount(DataType::AUDIO, n_outputs().n_audio()), true, this); - } - - reset_plugin_counts (0); - } -} - -uint32_t -Route::pans_required () const -{ - if (n_outputs().n_audio() < 2) { - return 0; - } - - return max (n_inputs ().n_audio(), processor_max_outs.n_audio()); -} - -int -Route::no_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, nframes_t offset, - bool session_state_changing, bool can_record, bool rec_monitors_input) -{ - if (n_outputs().n_total() == 0) { - return 0; - } - - if (session_state_changing || !_active) { - silence (nframes, offset); - return 0; - } - - apply_gain_automation = false; - - if (n_inputs().n_total()) { - passthru (start_frame, end_frame, nframes, offset, 0, false); - } else { - silence (nframes, offset); - } - - return 0; -} - -nframes_t -Route::check_initial_delay (nframes_t nframes, nframes_t& offset, nframes_t& transport_frame) -{ - if (_roll_delay > nframes) { - - _roll_delay -= nframes; - silence (nframes, offset); - /* transport frame is not legal for caller to use */ - return 0; - - } else if (_roll_delay > 0) { - - nframes -= _roll_delay; - - silence (_roll_delay, offset); - - offset += _roll_delay; - transport_frame += _roll_delay; - - _roll_delay = 0; - } - - return nframes; -} - -int -Route::roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, nframes_t offset, int declick, - bool can_record, bool rec_monitors_input) -{ - { - Glib::RWLock::ReaderLock lm (_processor_lock, Glib::TRY_LOCK); - if (lm.locked()) { - // automation snapshot can also be called from the non-rt context - // and it uses the processor list, so we take the lock out here - automation_snapshot (_session.transport_frame(), false); - } - } - - if ((n_outputs().n_total() == 0 && _processors.empty()) || n_inputs().n_total() == 0 || !_active) { - silence (nframes, offset); - return 0; - } - - nframes_t unused = 0; - - if ((nframes = check_initial_delay (nframes, offset, unused)) == 0) { - return 0; - } - - _silent = false; - - apply_gain_automation = false; - - { - Glib::Mutex::Lock am (_automation_lock, Glib::TRY_LOCK); - - if (am.locked() && _session.transport_rolling()) { - - if (_gain_control->list()->automation_playback()) { - apply_gain_automation = _gain_control->list()->curve().rt_safe_get_vector ( - start_frame, end_frame, _session.gain_automation_buffer(), nframes); - } - } - } - - passthru (start_frame, end_frame, nframes, offset, declick, false); - - return 0; -} - -int -Route::silent_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, nframes_t offset, - bool can_record, bool rec_monitors_input) -{ - silence (nframes, offset); - return 0; -} - -void -Route::toggle_monitor_input () -{ - for (PortSet::iterator i = _inputs.begin(); i != _inputs.end(); ++i) { - i->ensure_monitor_input( ! i->monitoring_input()); - } -} - -bool -Route::has_external_redirects () const -{ - // FIXME: what about sends? - - boost::shared_ptr<const PortInsert> pi; - - for (ProcessorList::const_iterator i = _processors.begin(); i != _processors.end(); ++i) { - if ((pi = boost::dynamic_pointer_cast<const PortInsert>(*i)) != 0) { - - for (PortSet::const_iterator port = pi->io()->outputs().begin(); - port != pi->io()->outputs().end(); ++port) { - - string port_name = port->name(); - string client_name = port_name.substr (0, port_name.find(':')); - - /* only say "yes" if the redirect is actually in use */ - - if (client_name != "ardour" && pi->active()) { - return true; - } - } - } - } - - return false; -} - -void -Route::flush_processors () -{ - /* XXX shouldn't really try to take this lock, since - this is called from the RT audio thread. - */ - - Glib::RWLock::ReaderLock lm (_processor_lock); - - for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { - (*i)->deactivate (); - (*i)->activate (); - } -} - -void -Route::set_meter_point (MeterPoint p, void *src) -{ - if (_meter_point != p) { - _meter_point = p; - meter_change (src); /* EMIT SIGNAL */ - _session.set_dirty (); - } -} - -nframes_t -Route::update_total_latency () -{ - nframes_t old = _own_latency; - - if (_user_latency) { - _own_latency = _user_latency; - } else { - _own_latency = 0; - - for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { - if ((*i)->active ()) { - _own_latency += (*i)->signal_latency (); - } - } - } - - set_port_latency (_own_latency); - - if (!_user_latency) { - /* this (virtual) function is used for pure Routes, - not derived classes like AudioTrack. this means - that the data processed here comes from an input - port, not prerecorded material, and therefore we - have to take into account any input latency. - */ - - - _own_latency += input_latency (); - } - - if (old != _own_latency) { - signal_latency_changed (); /* EMIT SIGNAL */ - } - - return _own_latency; -} - -void -Route::set_user_latency (nframes_t nframes) -{ - Latent::set_user_latency (nframes); - _session.update_latency_compensation (false, false); -} - -void -Route::set_latency_delay (nframes_t longest_session_latency) -{ - nframes_t old = _initial_delay; - - if (_own_latency < longest_session_latency) { - _initial_delay = longest_session_latency - _own_latency; - } else { - _initial_delay = 0; - } - - if (_initial_delay != old) { - initial_delay_changed (); /* EMIT SIGNAL */ - } - - if (_session.transport_stopped()) { - _roll_delay = _initial_delay; - } -} - -void -Route::automation_snapshot (nframes_t now, bool force) -{ - if (!force && !should_snapshot(now)) { - return; - } - - for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { - // IO::automation_snapshot (now, force); ? - (*i)->automation_snapshot (now, force); - } -} - -Route::ToggleControllable::ToggleControllable (std::string name, Route& s, ToggleType tp) - : Controllable (name), route (s), type(tp) -{ - -} - -void -Route::ToggleControllable::set_value (float val) -{ - bool bval = ((val >= 0.5f) ? true: false); - - switch (type) { - case MuteControl: - route.set_mute (bval, this); - break; - case SoloControl: - route.set_solo (bval, this); - break; - default: - break; - } -} - -float -Route::ToggleControllable::get_value (void) const -{ - float val = 0.0f; - - switch (type) { - case MuteControl: - val = route.muted() ? 1.0f : 0.0f; - break; - case SoloControl: - val = route.soloed() ? 1.0f : 0.0f; - break; - default: - break; - } - - return val; -} - -void -Route::set_block_size (nframes_t nframes) -{ - for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { - (*i)->set_block_size (nframes); - } -} - -void -Route::protect_automation () -{ - Automatable::protect_automation(); - - for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) - (*i)->protect_automation(); -} - -void -Route::set_pending_declick (int declick) -{ - if (_declickable) { - /* this call is not allowed to turn off a pending declick unless "force" is true */ - if (declick) { - _pending_declick = declick; - } - // cerr << _name << ": after setting to " << declick << " pending declick = " << _pending_declick << endl; - } else { - _pending_declick = 0; - } - -} diff --git a/libs/ardour/route_group.cc b/libs/ardour/route_group.cc deleted file mode 100644 index f22deb5dbf..0000000000 --- a/libs/ardour/route_group.cc +++ /dev/null @@ -1,213 +0,0 @@ -/* - 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. - -*/ - -#define __STDC_FORMAT_MACROS -#include <inttypes.h> - -#include <algorithm> - -#include <sigc++/bind.h> - -#include <pbd/error.h> -#include <pbd/enumwriter.h> - -#include <ardour/route_group.h> -#include <ardour/audio_track.h> -#include <ardour/audio_diskstream.h> -#include <ardour/configuration.h> - -using namespace ARDOUR; -using namespace sigc; -using namespace std; - -RouteGroup::RouteGroup (Session& s, const string &n, Flag f) - : _session (s), _name (n), _flags (f) -{ -} - -void -RouteGroup::set_name (string str) -{ - _name = str; - _session.set_dirty (); - FlagsChanged (0); /* EMIT SIGNAL */ -} - -int -RouteGroup::add (Route *r) -{ - routes.push_back (r); - r->GoingAway.connect (sigc::bind (mem_fun (*this, &RouteGroup::remove_when_going_away), r)); - _session.set_dirty (); - changed (); /* EMIT SIGNAL */ - return 0; -} - -void -RouteGroup::remove_when_going_away (Route *r) -{ - remove (r); -} - -int -RouteGroup::remove (Route *r) -{ - list<Route *>::iterator i; - - if ((i = find (routes.begin(), routes.end(), r)) != routes.end()) { - routes.erase (i); - _session.set_dirty (); - changed (); /* EMIT SIGNAL */ - return 0; - } - return -1; -} - - -gain_t -RouteGroup::get_min_factor(gain_t factor) -{ - gain_t g; - - for (list<Route *>::iterator i = routes.begin(); i != routes.end(); i++) { - g = (*i)->gain(); - - if ( (g+g*factor) >= 0.0f) - continue; - - if ( g <= 0.0000003f ) - return 0.0f; - - factor = 0.0000003f/g - 1.0f; - } - return factor; -} - -gain_t -RouteGroup::get_max_factor(gain_t factor) -{ - gain_t g; - - for (list<Route *>::iterator i = routes.begin(); i != routes.end(); i++) { - g = (*i)->gain(); - - // if the current factor woulnd't raise this route above maximum - if ( (g+g*factor) <= 1.99526231f) - continue; - - // if route gain is already at peak, return 0.0f factor - if (g>=1.99526231f) - return 0.0f; - - // factor is calculated so that it would raise current route to max - factor = 1.99526231f/g - 1.0f; - } - - return factor; -} - -XMLNode& -RouteGroup::get_state (void) -{ - XMLNode *node = new XMLNode ("RouteGroup"); - node->add_property ("name", _name); - node->add_property ("flags", enum_2_string (_flags)); - return *node; -} - -int -RouteGroup::set_state (const XMLNode& node) -{ - const XMLProperty *prop; - - if ((prop = node.property ("name")) != 0) { - _name = prop->value(); - } - - if ((prop = node.property ("flags")) != 0) { - _flags = Flag (string_2_enum (prop->value(), _flags)); - } - - return 0; -} - -void -RouteGroup::set_active (bool yn, void *src) -{ - if (is_active() == yn) { - return; - } - if (yn) { - _flags = Flag (_flags | Active); - } else { - _flags = Flag (_flags & ~Active); - } - _session.set_dirty (); - FlagsChanged (src); /* EMIT SIGNAL */ -} - -void -RouteGroup::set_relative (bool yn, void *src) - -{ - if (is_relative() == yn) { - return; - } - if (yn) { - _flags = Flag (_flags | Relative); - } else { - _flags = Flag (_flags & ~Relative); - } - _session.set_dirty (); - FlagsChanged (src); /* EMIT SIGNAL */ -} - -void -RouteGroup::set_hidden (bool yn, void *src) - -{ - if (is_hidden() == yn) { - return; - } - if (yn) { - _flags = Flag (_flags | Hidden); - if (Config->get_hiding_groups_deactivates_groups()) { - _flags = Flag (_flags & ~Active); - } - } else { - _flags = Flag (_flags & ~Hidden); - if (Config->get_hiding_groups_deactivates_groups()) { - _flags = Flag (_flags | Active); - } - } - _session.set_dirty (); - FlagsChanged (src); /* EMIT SIGNAL */ -} - -void -RouteGroup::audio_track_group (set<AudioTrack*>& ats) -{ - for (list<Route*>::iterator i = routes.begin(); i != routes.end(); ++i) { - AudioTrack* at = dynamic_cast<AudioTrack*>(*i); - if (at) { - ats.insert (at); - } - } -} - diff --git a/libs/ardour/send.cc b/libs/ardour/send.cc deleted file mode 100644 index 736a443c72..0000000000 --- a/libs/ardour/send.cc +++ /dev/null @@ -1,228 +0,0 @@ -/* - 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. - -*/ - -#include <algorithm> - -#include <pbd/xml++.h> - -#include <ardour/send.h> -#include <ardour/session.h> -#include <ardour/port.h> -#include <ardour/audio_port.h> -#include <ardour/buffer_set.h> -#include <ardour/meter.h> -#include "i18n.h" - -using namespace ARDOUR; -using namespace PBD; - -Send::Send (Session& s, Placement p) - : IOProcessor (s, string_compose (_("send %1"), (bitslot = s.next_send_id()) + 1), p) -{ - _metering = false; - ProcessorCreated (this); /* EMIT SIGNAL */ -} - -Send::Send (Session& s, const XMLNode& node) - : IOProcessor (s, "send", PreFader) -{ - _metering = false; - - if (set_state (node)) { - throw failed_constructor(); - } - - ProcessorCreated (this); /* EMIT SIGNAL */ -} - -Send::Send (const Send& other) - : IOProcessor (other._session, string_compose (_("send %1"), (bitslot = other._session.next_send_id()) + 1), other.placement()) -{ - _metering = false; - ProcessorCreated (this); /* EMIT SIGNAL */ -} - -Send::~Send () -{ - GoingAway (); -} - -XMLNode& -Send::get_state(void) -{ - return state (true); -} - -XMLNode& -Send::state(bool full) -{ - XMLNode& node = IOProcessor::state(full); - char buf[32]; - node.add_property ("type", "send"); - snprintf (buf, sizeof (buf), "%" PRIu32, bitslot); - node.add_property ("bitslot", buf); - - return node; -} - -int -Send::set_state(const XMLNode& node) -{ - XMLNodeList nlist = node.children(); - XMLNodeIterator niter; - const XMLProperty* prop; - - if ((prop = node.property ("bitslot")) == 0) { - bitslot = _session.next_send_id(); - } else { - sscanf (prop->value().c_str(), "%" PRIu32, &bitslot); - _session.mark_send_id (bitslot); - } - - const XMLNode* insert_node = &node; - - /* Send has regular IO automation (gain, pan) */ - - for (niter = nlist.begin(); niter != nlist.end(); ++niter) { - if ((*niter)->name() == "IOProcessor") { - insert_node = *niter; - } else if ((*niter)->name() == X_("Automation")) { - _io->set_automation_state (*(*niter), Parameter(GainAutomation)); - } - } - - IOProcessor::set_state (*insert_node); - - return 0; -} - -void -Send::run_in_place (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset) -{ - if (active()) { - - // we have to copy the input, because IO::deliver_output may alter the buffers - // in-place, which a send must never do. - - BufferSet& sendbufs = _session.get_mix_buffers(bufs.count()); - - sendbufs.read_from(bufs, nframes); - assert(sendbufs.count() == bufs.count()); - - _io->deliver_output (sendbufs, start_frame, end_frame, nframes, offset); - - if (_metering) { - if (_io->_gain == 0) { - _io->_meter->reset(); - } else { - _io->_meter->run_in_place(_io->output_buffers(), start_frame, end_frame, nframes, offset); - } - } - - } else { - _io->silence (nframes, offset); - - if (_metering) { - _io->_meter->reset(); - } - } -} - -void -Send::set_metering (bool yn) -{ - _metering = yn; - - if (!_metering) { - /* XXX possible thread hazard here */ - _io->peak_meter().reset(); - } -} - -bool -Send::can_support_input_configuration (ChanCount in) const -{ - if (_io->input_maximum() == ChanCount::INFINITE && _io->output_maximum() == ChanCount::INFINITE) { - - /* not configured yet */ - - return true; /* we can support anything the first time we're asked */ - - } else { - - /* the "input" config for a port insert corresponds to how - many output ports it will have. - */ - - if (_io->output_maximum() == in) { - - return true; - } - } - - return false; -} - -ChanCount -Send::output_for_input_configuration (ChanCount in) const -{ - // from the internal (Insert) perspective a Send does not modify its input whatsoever - return in; -} - -bool -Send::configure_io (ChanCount in, ChanCount out) -{ - /* we're transparent no matter what. fight the power. */ - if (out != in) - return false; - - _io->set_output_maximum (in); - _io->set_output_minimum (in); - _io->set_input_maximum (ChanCount::ZERO); - _io->set_input_minimum (ChanCount::ZERO); - - bool success = _io->ensure_io (ChanCount::ZERO, in, false, this) == 0; - - if (success) { - Processor::configure_io(in, out); - _io->reset_panner(); - return true; - } else { - return false; - } -} - -ChanCount -Send::output_streams() const -{ - // this method reflects the idea that from the perspective of the Route's ProcessorList, - // a send is just a passthrough. that doesn't match what the Send actually does with its - // data, but since what it does is invisible to the Route, it appears to be a passthrough. - - return _configured_input; -} - -ChanCount -Send::input_streams() const -{ - return _configured_input; -} - - diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc deleted file mode 100644 index ff269cc931..0000000000 --- a/libs/ardour/session.cc +++ /dev/null @@ -1,4273 +0,0 @@ -/* - Copyright (C) 1999-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. - -*/ - -#include <algorithm> -#include <string> -#include <vector> -#include <sstream> -#include <fstream> -#include <cstdio> /* sprintf(3) ... grrr */ -#include <cmath> -#include <cerrno> -#include <unistd.h> -#include <limits.h> - -#include <sigc++/bind.h> -#include <sigc++/retype.h> - -#include <glibmm/thread.h> -#include <glibmm/miscutils.h> -#include <glibmm/fileutils.h> - -#include <pbd/error.h> -#include <glibmm/thread.h> -#include <pbd/pathscanner.h> -#include <pbd/stl_delete.h> -#include <pbd/basename.h> -#include <pbd/stacktrace.h> -#include <pbd/file_utils.h> - -#include <ardour/audioengine.h> -#include <ardour/configuration.h> -#include <ardour/session.h> -#include <ardour/session_directory.h> -#include <ardour/utils.h> -#include <ardour/audio_diskstream.h> -#include <ardour/audioplaylist.h> -#include <ardour/audioregion.h> -#include <ardour/audiofilesource.h> -#include <ardour/midi_diskstream.h> -#include <ardour/midi_playlist.h> -#include <ardour/midi_region.h> -#include <ardour/smf_source.h> -#include <ardour/auditioner.h> -#include <ardour/recent_sessions.h> -#include <ardour/io_processor.h> -#include <ardour/send.h> -#include <ardour/processor.h> -#include <ardour/plugin_insert.h> -#include <ardour/port_insert.h> -#include <ardour/auto_bundle.h> -#include <ardour/slave.h> -#include <ardour/tempo.h> -#include <ardour/audio_track.h> -#include <ardour/midi_track.h> -#include <ardour/cycle_timer.h> -#include <ardour/named_selection.h> -#include <ardour/crossfade.h> -#include <ardour/playlist.h> -#include <ardour/click.h> -#include <ardour/data_type.h> -#include <ardour/buffer_set.h> -#include <ardour/source_factory.h> -#include <ardour/region_factory.h> -#include <ardour/filename_extensions.h> -#include <ardour/session_directory.h> -#include <ardour/tape_file_matcher.h> -#include <ardour/analyser.h> - -#ifdef HAVE_LIBLO -#include <ardour/osc.h> -#endif - -#include "i18n.h" - -using namespace std; -using namespace ARDOUR; -using namespace PBD; -using boost::shared_ptr; - -#ifdef __x86_64__ -static const int CPU_CACHE_ALIGN = 64; -#else -static const int CPU_CACHE_ALIGN = 16; /* arguably 32 on most arches, but it matters less */ -#endif - -bool Session::_disable_all_loaded_plugins = false; - -Session::compute_peak_t Session::compute_peak = 0; -Session::find_peaks_t Session::find_peaks = 0; -Session::apply_gain_to_buffer_t Session::apply_gain_to_buffer = 0; -Session::mix_buffers_with_gain_t Session::mix_buffers_with_gain = 0; -Session::mix_buffers_no_gain_t Session::mix_buffers_no_gain = 0; - -sigc::signal<void,std::string> Session::Dialog; -sigc::signal<int> Session::AskAboutPendingState; -sigc::signal<int,nframes_t,nframes_t> Session::AskAboutSampleRateMismatch; -sigc::signal<void> Session::SendFeedback; - -sigc::signal<void> Session::SMPTEOffsetChanged; -sigc::signal<void> Session::StartTimeChanged; -sigc::signal<void> Session::EndTimeChanged; - -sigc::signal<void> Session::AutoBindingOn; -sigc::signal<void> Session::AutoBindingOff; - -Session::Session (AudioEngine &eng, - const string& fullpath, - const string& snapshot_name, - string mix_template) - - : _engine (eng), - _scratch_buffers(new BufferSet()), - _silent_buffers(new BufferSet()), - _mix_buffers(new BufferSet()), - _mmc_port (default_mmc_port), - _mtc_port (default_mtc_port), - _midi_port (default_midi_port), - _session_dir (new SessionDirectory(fullpath)), - pending_events (2048), - post_transport_work((PostTransportWork)0), - _send_smpte_update (false), - midi_requests (128), - diskstreams (new DiskstreamList), - routes (new RouteList), - auditioner ((Auditioner*) 0), - _bundle_xml_node (0), - _click_io ((IO*) 0), - main_outs (0) -{ - bool new_session; - - if (!eng.connected()) { - throw failed_constructor(); - } - - cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (1)" << endl; - - n_physical_outputs = _engine.n_physical_outputs(); - n_physical_inputs = _engine.n_physical_inputs(); - - first_stage_init (fullpath, snapshot_name); - - new_session = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)); - - if (new_session) { - if (create (new_session, mix_template, compute_initial_length())) { - destroy (); - throw failed_constructor (); - } - } - - if (second_stage_init (new_session)) { - destroy (); - throw failed_constructor (); - } - - store_recent_sessions(_name, _path); - - bool was_dirty = dirty(); - - _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty); - - Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed)); - - if (was_dirty) { - DirtyChanged (); /* EMIT SIGNAL */ - } -} - -Session::Session (AudioEngine &eng, - string fullpath, - string snapshot_name, - AutoConnectOption input_ac, - AutoConnectOption output_ac, - uint32_t control_out_channels, - uint32_t master_out_channels, - uint32_t requested_physical_in, - uint32_t requested_physical_out, - nframes_t initial_length) - - : _engine (eng), - _scratch_buffers(new BufferSet()), - _silent_buffers(new BufferSet()), - _mix_buffers(new BufferSet()), - _mmc_port (default_mmc_port), - _mtc_port (default_mtc_port), - _midi_port (default_midi_port), - _session_dir ( new SessionDirectory(fullpath)), - pending_events (2048), - post_transport_work((PostTransportWork)0), - _send_smpte_update (false), - midi_requests (16), - diskstreams (new DiskstreamList), - routes (new RouteList), - _bundle_xml_node (0), - main_outs (0) - -{ - bool new_session; - - if (!eng.connected()) { - throw failed_constructor(); - } - - cerr << "Loading session " << fullpath << " using snapshot " << snapshot_name << " (2)" << endl; - - n_physical_outputs = _engine.n_physical_outputs(); - n_physical_inputs = _engine.n_physical_inputs(); - - if (n_physical_inputs) { - n_physical_inputs = max (requested_physical_in, n_physical_inputs); - } - - if (n_physical_outputs) { - n_physical_outputs = max (requested_physical_out, n_physical_outputs); - } - - first_stage_init (fullpath, snapshot_name); - - new_session = !g_file_test (_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)); - - if (new_session) { - if (create (new_session, string(), initial_length)) { - destroy (); - throw failed_constructor (); - } - } - - { - /* set up Master Out and Control Out if necessary */ - - RouteList rl; - int control_id = 1; - - if (control_out_channels) { - shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut)); - r->set_remote_control_id (control_id++); - - rl.push_back (r); - } - - if (master_out_channels) { - shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut)); - r->set_remote_control_id (control_id); - - rl.push_back (r); - } else { - /* prohibit auto-connect to master, because there isn't one */ - output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster); - } - - if (!rl.empty()) { - add_routes (rl, false); - } - - } - - Config->set_input_auto_connect (input_ac); - Config->set_output_auto_connect (output_ac); - - if (second_stage_init (new_session)) { - destroy (); - throw failed_constructor (); - } - - store_recent_sessions (_name, _path); - - _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty); - - Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed)); -} - -Session::~Session () -{ - destroy (); -} - -void -Session::destroy () -{ - /* if we got to here, leaving pending capture state around - is a mistake. - */ - - remove_pending_capture_state (); - - _state_of_the_state = StateOfTheState (CannotSave|Deletion); - - _engine.remove_session (); - - GoingAway (); /* EMIT SIGNAL */ - - /* do this */ - - notify_callbacks (); - - /* clear history so that no references to objects are held any more */ - - _history.clear (); - - /* clear state tree so that no references to objects are held any more */ - - if (state_tree) { - delete state_tree; - } - - terminate_butler_thread (); - //terminate_midi_thread (); - - if (click_data && click_data != default_click) { - delete [] click_data; - } - - if (click_emphasis_data && click_emphasis_data != default_click_emphasis) { - delete [] click_emphasis_data; - } - - clear_clicks (); - - delete _scratch_buffers; - delete _silent_buffers; - delete _mix_buffers; - - AudioDiskstream::free_working_buffers(); - - Route::SyncOrderKeys.clear(); - -#undef TRACK_DESTRUCTION -#ifdef TRACK_DESTRUCTION - cerr << "delete named selections\n"; -#endif /* TRACK_DESTRUCTION */ - for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ) { - NamedSelectionList::iterator tmp; - - tmp = i; - ++tmp; - - delete *i; - i = tmp; - } - -#ifdef TRACK_DESTRUCTION - cerr << "delete playlists\n"; -#endif /* TRACK_DESTRUCTION */ - for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ) { - PlaylistList::iterator tmp; - - tmp = i; - ++tmp; - - (*i)->drop_references (); - - i = tmp; - } - - for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) { - PlaylistList::iterator tmp; - - tmp = i; - ++tmp; - - (*i)->drop_references (); - - i = tmp; - } - - playlists.clear (); - unused_playlists.clear (); - -#ifdef TRACK_DESTRUCTION - cerr << "delete regions\n"; -#endif /* TRACK_DESTRUCTION */ - - for (RegionList::iterator i = regions.begin(); i != regions.end(); ) { - RegionList::iterator tmp; - - tmp = i; - ++tmp; - - i->second->drop_references (); - - i = tmp; - } - - regions.clear (); - -#ifdef TRACK_DESTRUCTION - cerr << "delete routes\n"; -#endif /* TRACK_DESTRUCTION */ - { - RCUWriter<RouteList> writer (routes); - boost::shared_ptr<RouteList> r = writer.get_copy (); - for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - (*i)->drop_references (); - } - r->clear (); - /* writer goes out of scope and updates master */ - } - - routes.flush (); - -#ifdef TRACK_DESTRUCTION - cerr << "delete diskstreams\n"; -#endif /* TRACK_DESTRUCTION */ - { - RCUWriter<DiskstreamList> dwriter (diskstreams); - boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy(); - for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) { - (*i)->drop_references (); - } - dsl->clear (); - } - diskstreams.flush (); - -#ifdef TRACK_DESTRUCTION - cerr << "delete audio sources\n"; -#endif /* TRACK_DESTRUCTION */ - for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) { - SourceMap::iterator tmp; - - tmp = i; - ++tmp; - - i->second->drop_references (); - - i = tmp; - } - sources.clear (); - -#ifdef TRACK_DESTRUCTION - cerr << "delete mix groups\n"; -#endif /* TRACK_DESTRUCTION */ - for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ) { - list<RouteGroup*>::iterator tmp; - - tmp = i; - ++tmp; - - delete *i; - - i = tmp; - } - -#ifdef TRACK_DESTRUCTION - cerr << "delete edit groups\n"; -#endif /* TRACK_DESTRUCTION */ - for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ) { - list<RouteGroup*>::iterator tmp; - - tmp = i; - ++tmp; - - delete *i; - - i = tmp; - } - - if (butler_mixdown_buffer) { - delete [] butler_mixdown_buffer; - } - - if (butler_gain_buffer) { - delete [] butler_gain_buffer; - } - - Crossfade::set_buffer_size (0); - - if (mmc) { - delete mmc; - } -} - -void -Session::set_worst_io_latencies () -{ - _worst_output_latency = 0; - _worst_input_latency = 0; - - if (!_engine.connected()) { - return; - } - - boost::shared_ptr<RouteList> r = routes.reader (); - - for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - _worst_output_latency = max (_worst_output_latency, (*i)->output_latency()); - _worst_input_latency = max (_worst_input_latency, (*i)->input_latency()); - } -} - -void -Session::when_engine_running () -{ - string first_physical_output; - - /* we don't want to run execute this again */ - - BootMessage (_("Set block size and sample rate")); - - set_block_size (_engine.frames_per_cycle()); - set_frame_rate (_engine.frame_rate()); - - BootMessage (_("Using configuration")); - - Config->map_parameters (mem_fun (*this, &Session::config_changed)); - - /* every time we reconnect, recompute worst case output latencies */ - - _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies)); - - if (synced_to_jack()) { - _engine.transport_stop (); - } - - if (Config->get_jack_time_master()) { - _engine.transport_locate (_transport_frame); - } - - _clicking = false; - - try { - XMLNode* child = 0; - - _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1)); - - if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) { - - /* existing state for Click */ - - if (_click_io->set_state (*child->children().front()) == 0) { - - _clicking = Config->get_clicking (); - - } else { - - error << _("could not setup Click I/O") << endmsg; - _clicking = false; - } - - } else { - - /* default state for Click */ - - first_physical_output = _engine.get_nth_physical_output (DataType::AUDIO, 0); - - if (first_physical_output.length()) { - if (_click_io->add_output_port (first_physical_output, this)) { - // relax, even though its an error - } else { - _clicking = Config->get_clicking (); - } - } - } - } - - catch (failed_constructor& err) { - error << _("cannot setup Click I/O") << endmsg; - } - - BootMessage (_("Compute I/O Latencies")); - - set_worst_io_latencies (); - - if (_clicking) { - // XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO? - } - - /* Create a set of Bundle objects that map - to the physical outputs currently available - */ - - BootMessage (_("Set up standard connections")); - - /* ONE: MONO */ - - for (uint32_t np = 0; np < n_physical_outputs; ++np) { - char buf[32]; - snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1); - - shared_ptr<AutoBundle> c (new AutoBundle (buf, true)); - c->set_channels (1); - c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np)); - - add_bundle (c); - } - - for (uint32_t np = 0; np < n_physical_inputs; ++np) { - char buf[32]; - snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1); - - shared_ptr<AutoBundle> c (new AutoBundle (buf, false)); - c->set_channels (1); - c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np)); - - add_bundle (c); - } - - /* TWO: STEREO */ - - for (uint32_t np = 0; np < n_physical_outputs; np +=2) { - char buf[32]; - snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2); - - shared_ptr<AutoBundle> c (new AutoBundle (buf, true)); - c->set_channels (2); - c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np)); - c->set_port (1, _engine.get_nth_physical_output (DataType::AUDIO, np + 1)); - - add_bundle (c); - } - - for (uint32_t np = 0; np < n_physical_inputs; np +=2) { - char buf[32]; - snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2); - - shared_ptr<AutoBundle> c (new AutoBundle (buf, false)); - c->set_channels (2); - c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np)); - c->set_port (1, _engine.get_nth_physical_input (DataType::AUDIO, np + 1)); - - add_bundle (c); - } - - /* THREE MASTER */ - - if (_master_out) { - - /* create master/control ports */ - - if (_master_out) { - uint32_t n; - - /* force the master to ignore any later call to this */ - - if (_master_out->pending_state_node) { - _master_out->ports_became_legal(); - } - - /* no panner resets till we are through */ - - _master_out->defer_pan_reset (); - - while (_master_out->n_inputs().n_audio() - < _master_out->input_maximum().n_audio()) { - if (_master_out->add_input_port ("", this, DataType::AUDIO)) { - error << _("cannot setup master inputs") - << endmsg; - break; - } - } - n = 0; - while (_master_out->n_outputs().n_audio() - < _master_out->output_maximum().n_audio()) { - if (_master_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this, DataType::AUDIO)) { - error << _("cannot setup master outputs") - << endmsg; - break; - } - n++; - } - - _master_out->allow_pan_reset (); - - } - - shared_ptr<AutoBundle> c (new AutoBundle (_("Master Out"), true)); - - c->set_channels (_master_out->n_inputs().n_total()); - for (uint32_t n = 0; n < _master_out->n_inputs ().n_total(); ++n) { - c->set_port (n, _master_out->input(n)->name()); - } - add_bundle (c); - } - - BootMessage (_("Setup signal flow and plugins")); - - hookup_io (); - - /* catch up on send+insert cnts */ - - BootMessage (_("Catch up with send/insert state")); - - insert_cnt = 0; - - for (list<PortInsert*>::iterator i = _port_inserts.begin(); i != _port_inserts.end(); ++i) { - uint32_t id; - - if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) { - if (id > insert_cnt) { - insert_cnt = id; - } - } - } - - send_cnt = 0; - - for (list<Send*>::iterator i = _sends.begin(); i != _sends.end(); ++i) { - uint32_t id; - - if (sscanf ((*i)->name().c_str(), "%*s %u", &id) == 1) { - if (id > send_cnt) { - send_cnt = id; - } - } - } - - - _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty)); - - /* hook us up to the engine */ - - BootMessage (_("Connect to engine")); - - _engine.set_session (this); - -#ifdef HAVE_LIBLO - /* and to OSC */ - - BootMessage (_("OSC startup")); - - osc->set_session (*this); -#endif - -} - -void -Session::hookup_io () -{ - /* stop graph reordering notifications from - causing resorts, etc. - */ - - _state_of_the_state = StateOfTheState (_state_of_the_state | InitialConnecting); - - - if (auditioner == 0) { - - /* we delay creating the auditioner till now because - it makes its own connections to ports. - the engine has to be running for this to work. - */ - - try { - auditioner.reset (new Auditioner (*this)); - } - - catch (failed_constructor& err) { - warning << _("cannot create Auditioner: no auditioning of regions possible") << endmsg; - } - } - - /* Tell all IO objects to create their ports */ - - IO::enable_ports (); - - if (_control_out) { - uint32_t n; - vector<string> cports; - - while (_control_out->n_inputs().n_audio() < _control_out->input_maximum().n_audio()) { - if (_control_out->add_input_port ("", this)) { - error << _("cannot setup control inputs") - << endmsg; - break; - } - } - n = 0; - while (_control_out->n_outputs().n_audio() < _control_out->output_maximum().n_audio()) { - if (_control_out->add_output_port (_engine.get_nth_physical_output (DataType::AUDIO, n), this)) { - error << _("cannot set up master outputs") - << endmsg; - break; - } - n++; - } - - - uint32_t ni = _control_out->n_inputs().get (DataType::AUDIO); - - for (n = 0; n < ni; ++n) { - cports.push_back (_control_out->input(n)->name()); - } - - boost::shared_ptr<RouteList> r = routes.reader (); - - for (RouteList::iterator x = r->begin(); x != r->end(); ++x) { - (*x)->set_control_outs (cports); - } - } - - /* load bundles, which we may have postponed earlier on */ - if (_bundle_xml_node) { - load_bundles (*_bundle_xml_node); - delete _bundle_xml_node; - } - - /* Tell all IO objects to connect themselves together */ - - IO::enable_connecting (); - - /* Now reset all panners */ - - IO::reset_panners (); - - /* Anyone who cares about input state, wake up and do something */ - - IOConnectionsComplete (); /* EMIT SIGNAL */ - - _state_of_the_state = StateOfTheState (_state_of_the_state & ~InitialConnecting); - - - /* now handle the whole enchilada as if it was one - graph reorder event. - */ - - graph_reordered (); - - /* update mixer solo state */ - - catch_up_on_solo(); -} - -void -Session::playlist_length_changed () -{ - /* we can't just increase end_location->end() if pl->get_maximum_extent() - if larger. if the playlist used to be the longest playlist, - and its now shorter, we have to decrease end_location->end(). hence, - we have to iterate over all diskstreams and check the - playlists currently in use. - */ - find_current_end (); -} - -void -Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream) -{ - boost::shared_ptr<Playlist> playlist; - - if ((playlist = dstream->playlist()) != 0) { - playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed)); - } - - /* see comment in playlist_length_changed () */ - find_current_end (); -} - -bool -Session::record_enabling_legal () const -{ - /* this used to be in here, but survey says.... we don't need to restrict it */ - // if (record_status() == Recording) { - // return false; - // } - - if (Config->get_all_safe()) { - return false; - } - return true; -} - -void -Session::reset_input_monitor_state () -{ - if (transport_rolling()) { - - boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader(); - - for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) { - if ((*i)->record_enabled ()) { - //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl; - (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring && !Config->get_auto_input()); - } - } - } else { - boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader(); - - for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) { - if ((*i)->record_enabled ()) { - //cerr << "switching to input = " << !Config->get_auto_input() << __FILE__ << __LINE__ << endl << endl; - (*i)->monitor_input (Config->get_monitoring_model() == HardwareMonitoring); - } - } - } -} - -void -Session::auto_punch_start_changed (Location* location) -{ - replace_event (Event::PunchIn, location->start()); - - if (get_record_enabled() && Config->get_punch_in()) { - /* capture start has been changed, so save new pending state */ - save_state ("", true); - } -} - -void -Session::auto_punch_end_changed (Location* location) -{ - nframes_t when_to_stop = location->end(); - // when_to_stop += _worst_output_latency + _worst_input_latency; - replace_event (Event::PunchOut, when_to_stop); -} - -void -Session::auto_punch_changed (Location* location) -{ - nframes_t when_to_stop = location->end(); - - replace_event (Event::PunchIn, location->start()); - //when_to_stop += _worst_output_latency + _worst_input_latency; - replace_event (Event::PunchOut, when_to_stop); -} - -void -Session::auto_loop_changed (Location* location) -{ - replace_event (Event::AutoLoop, location->end(), location->start()); - - if (transport_rolling() && play_loop) { - - //if (_transport_frame < location->start() || _transport_frame > location->end()) { - - if (_transport_frame > location->end()) { - // relocate to beginning of loop - clear_events (Event::LocateRoll); - - request_locate (location->start(), true); - - } - else if (Config->get_seamless_loop() && !loop_changing) { - - // schedule a locate-roll to refill the diskstreams at the - // previous loop end - loop_changing = true; - - if (location->end() > last_loopend) { - clear_events (Event::LocateRoll); - Event *ev = new Event (Event::LocateRoll, Event::Add, last_loopend, last_loopend, 0, true); - queue_event (ev); - } - - } - } - - last_loopend = location->end(); -} - -void -Session::set_auto_punch_location (Location* location) -{ - Location* existing; - - if ((existing = _locations.auto_punch_location()) != 0 && existing != location) { - auto_punch_start_changed_connection.disconnect(); - auto_punch_end_changed_connection.disconnect(); - auto_punch_changed_connection.disconnect(); - existing->set_auto_punch (false, this); - remove_event (existing->start(), Event::PunchIn); - clear_events (Event::PunchOut); - auto_punch_location_changed (0); - } - - set_dirty(); - - if (location == 0) { - return; - } - - if (location->end() <= location->start()) { - error << _("Session: you can't use that location for auto punch (start <= end)") << endmsg; - return; - } - - auto_punch_start_changed_connection.disconnect(); - auto_punch_end_changed_connection.disconnect(); - auto_punch_changed_connection.disconnect(); - - auto_punch_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_punch_start_changed)); - auto_punch_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_punch_end_changed)); - auto_punch_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_punch_changed)); - - location->set_auto_punch (true, this); - - - auto_punch_changed (location); - - auto_punch_location_changed (location); -} - -void -Session::set_auto_loop_location (Location* location) -{ - Location* existing; - - if ((existing = _locations.auto_loop_location()) != 0 && existing != location) { - auto_loop_start_changed_connection.disconnect(); - auto_loop_end_changed_connection.disconnect(); - auto_loop_changed_connection.disconnect(); - existing->set_auto_loop (false, this); - remove_event (existing->end(), Event::AutoLoop); - auto_loop_location_changed (0); - } - - set_dirty(); - - if (location == 0) { - return; - } - - if (location->end() <= location->start()) { - error << _("Session: you can't use a mark for auto loop") << endmsg; - return; - } - - last_loopend = location->end(); - - auto_loop_start_changed_connection.disconnect(); - auto_loop_end_changed_connection.disconnect(); - auto_loop_changed_connection.disconnect(); - - auto_loop_start_changed_connection = location->start_changed.connect (mem_fun (this, &Session::auto_loop_changed)); - auto_loop_end_changed_connection = location->end_changed.connect (mem_fun (this, &Session::auto_loop_changed)); - auto_loop_changed_connection = location->changed.connect (mem_fun (this, &Session::auto_loop_changed)); - - location->set_auto_loop (true, this); - - /* take care of our stuff first */ - - auto_loop_changed (location); - - /* now tell everyone else */ - - auto_loop_location_changed (location); -} - -void -Session::locations_added (Location* ignored) -{ - set_dirty (); -} - -void -Session::locations_changed () -{ - _locations.apply (*this, &Session::handle_locations_changed); -} - -void -Session::handle_locations_changed (Locations::LocationList& locations) -{ - Locations::LocationList::iterator i; - Location* location; - bool set_loop = false; - bool set_punch = false; - - for (i = locations.begin(); i != locations.end(); ++i) { - - location =* i; - - if (location->is_auto_punch()) { - set_auto_punch_location (location); - set_punch = true; - } - if (location->is_auto_loop()) { - set_auto_loop_location (location); - set_loop = true; - } - - } - - if (!set_loop) { - set_auto_loop_location (0); - } - if (!set_punch) { - set_auto_punch_location (0); - } - - set_dirty(); -} - -void -Session::enable_record () -{ - /* XXX really atomic compare+swap here */ - if (g_atomic_int_get (&_record_status) != Recording) { - g_atomic_int_set (&_record_status, Recording); - _last_record_location = _transport_frame; - deliver_mmc(MIDI::MachineControl::cmdRecordStrobe, _last_record_location); - - if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) { - boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader(); - for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) { - if ((*i)->record_enabled ()) { - (*i)->monitor_input (true); - } - } - } - - RecordStateChanged (); - } -} - -void -Session::disable_record (bool rt_context, bool force) -{ - RecordState rs; - - if ((rs = (RecordState) g_atomic_int_get (&_record_status)) != Disabled) { - - if ((!Config->get_latched_record_enable () && !play_loop) || force) { - g_atomic_int_set (&_record_status, Disabled); - } else { - if (rs == Recording) { - g_atomic_int_set (&_record_status, Enabled); - } - } - - // FIXME: timestamp correct? [DR] - // FIXME FIXME FIXME: rt_context? this must be called in the process thread. - // does this /need/ to be sent in all cases? - if (rt_context) - deliver_mmc (MIDI::MachineControl::cmdRecordExit, _transport_frame); - - if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) { - boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader(); - - for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) { - if ((*i)->record_enabled ()) { - (*i)->monitor_input (false); - } - } - } - - RecordStateChanged (); /* emit signal */ - - if (!rt_context) { - remove_pending_capture_state (); - } - } -} - -void -Session::step_back_from_record () -{ - /* XXX really atomic compare+swap here */ - if (g_atomic_int_get (&_record_status) == Recording) { - g_atomic_int_set (&_record_status, Enabled); - - if (Config->get_monitoring_model() == HardwareMonitoring && Config->get_auto_input()) { - boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader(); - - for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) { - if ((*i)->record_enabled ()) { - //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl; - (*i)->monitor_input (false); - } - } - } - } -} - -void -Session::maybe_enable_record () -{ - g_atomic_int_set (&_record_status, Enabled); - - /* this function is currently called from somewhere other than an RT thread. - this save_state() call therefore doesn't impact anything. - */ - - save_state ("", true); - - if (_transport_speed) { - if (!Config->get_punch_in()) { - enable_record (); - } - } else { - deliver_mmc (MIDI::MachineControl::cmdRecordPause, _transport_frame); - RecordStateChanged (); /* EMIT SIGNAL */ - } - - set_dirty(); -} - -nframes_t -Session::audible_frame () const -{ - nframes_t ret; - nframes_t offset; - nframes_t tf; - - /* the first of these two possible settings for "offset" - mean that the audible frame is stationary until - audio emerges from the latency compensation - "pseudo-pipeline". - - the second means that the audible frame is stationary - until audio would emerge from a physical port - in the absence of any plugin latency compensation - */ - - offset = _worst_output_latency; - - if (offset > current_block_size) { - offset -= current_block_size; - } else { - /* XXX is this correct? if we have no external - physical connections and everything is internal - then surely this is zero? still, how - likely is that anyway? - */ - offset = current_block_size; - } - - if (synced_to_jack()) { - tf = _engine.transport_frame(); - } else { - tf = _transport_frame; - } - - if (_transport_speed == 0) { - return tf; - } - - if (tf < offset) { - return 0; - } - - ret = tf; - - if (!non_realtime_work_pending()) { - - /* MOVING */ - - /* take latency into account */ - - ret -= offset; - } - - return ret; -} - -void -Session::set_frame_rate (nframes_t frames_per_second) -{ - /** \fn void Session::set_frame_size(nframes_t) - the AudioEngine object that calls this guarantees - that it will not be called while we are also in - ::process(). Its fine to do things that block - here. - */ - - _base_frame_rate = frames_per_second; - - sync_time_vars(); - - Automatable::set_automation_interval ((jack_nframes_t) ceil ((double) frames_per_second * (0.001 * Config->get_automation_interval()))); - - clear_clicks (); - - // XXX we need some equivalent to this, somehow - // SndFileSource::setup_standard_crossfades (frames_per_second); - - set_dirty(); - - /* XXX need to reset/reinstantiate all LADSPA plugins */ -} - -void -Session::set_block_size (nframes_t nframes) -{ - /* the AudioEngine guarantees - that it will not be called while we are also in - ::process(). It is therefore fine to do things that block - here. - */ - - { - - current_block_size = nframes; - - ensure_buffers(_scratch_buffers->available()); - - if (_gain_automation_buffer) { - delete [] _gain_automation_buffer; - } - _gain_automation_buffer = new gain_t[nframes]; - - allocate_pan_automation_buffers (nframes, _npan_buffers, true); - - boost::shared_ptr<RouteList> r = routes.reader (); - - for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - (*i)->set_block_size (nframes); - } - - boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader(); - for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) { - (*i)->set_block_size (nframes); - } - - set_worst_io_latencies (); - } -} - -void -Session::set_default_fade (float steepness, float fade_msecs) -{ -#if 0 - nframes_t fade_frames; - - /* Don't allow fade of less 1 frame */ - - if (fade_msecs < (1000.0 * (1.0/_current_frame_rate))) { - - fade_msecs = 0; - fade_frames = 0; - - } else { - - fade_frames = (nframes_t) floor (fade_msecs * _current_frame_rate * 0.001); - - } - - default_fade_msecs = fade_msecs; - default_fade_steepness = steepness; - - { - // jlc, WTF is this! - Glib::RWLock::ReaderLock lm (route_lock); - AudioRegion::set_default_fade (steepness, fade_frames); - } - - set_dirty(); - - /* XXX have to do this at some point */ - /* foreach region using default fade, reset, then - refill_all_diskstream_buffers (); - */ -#endif -} - -struct RouteSorter { - bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) { - if (r1->fed_by.find (r2) != r1->fed_by.end()) { - return false; - } else if (r2->fed_by.find (r1) != r2->fed_by.end()) { - return true; - } else { - if (r1->fed_by.empty()) { - if (r2->fed_by.empty()) { - /* no ardour-based connections inbound to either route. just use signal order */ - return r1->order_key(N_("signal")) < r2->order_key(N_("signal")); - } else { - /* r2 has connections, r1 does not; run r1 early */ - return true; - } - } else { - return r1->order_key(N_("signal")) < r2->order_key(N_("signal")); - } - } - } -}; - -static void -trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase) -{ - shared_ptr<Route> r2; - - if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) { - info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg; - return; - } - - /* make a copy of the existing list of routes that feed r1 */ - - set<shared_ptr<Route> > existing = r1->fed_by; - - /* for each route that feeds r1, recurse, marking it as feeding - rbase as well. - */ - - for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) { - r2 =* i; - - /* r2 is a route that feeds r1 which somehow feeds base. mark - base as being fed by r2 - */ - - rbase->fed_by.insert (r2); - - if (r2 != rbase) { - - /* 2nd level feedback loop detection. if r1 feeds or is fed by r2, - stop here. - */ - - if ((r1->fed_by.find (r2) != r1->fed_by.end()) && (r2->fed_by.find (r1) != r2->fed_by.end())) { - continue; - } - - /* now recurse, so that we can mark base as being fed by - all routes that feed r2 - */ - - trace_terminal (r2, rbase); - } - - } -} - -void -Session::resort_routes () -{ - /* don't do anything here with signals emitted - by Routes while we are being destroyed. - */ - - if (_state_of_the_state & Deletion) { - return; - } - - - { - - RCUWriter<RouteList> writer (routes); - shared_ptr<RouteList> r = writer.get_copy (); - resort_routes_using (r); - /* writer goes out of scope and forces update */ - } - -} -void -Session::resort_routes_using (shared_ptr<RouteList> r) -{ - RouteList::iterator i, j; - - for (i = r->begin(); i != r->end(); ++i) { - - (*i)->fed_by.clear (); - - for (j = r->begin(); j != r->end(); ++j) { - - /* although routes can feed themselves, it will - cause an endless recursive descent if we - detect it. so don't bother checking for - self-feeding. - */ - - if (*j == *i) { - continue; - } - - if ((*j)->feeds (*i)) { - (*i)->fed_by.insert (*j); - } - } - } - - for (i = r->begin(); i != r->end(); ++i) { - trace_terminal (*i, *i); - } - - RouteSorter cmp; - r->sort (cmp); - -#if 0 - cerr << "finished route resort\n"; - - for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl; - } - cerr << endl; -#endif - -} - -list<boost::shared_ptr<MidiTrack> > -Session::new_midi_track (TrackMode mode, uint32_t how_many) -{ - char track_name[32]; - uint32_t track_id = 0; - uint32_t n = 0; - string port; - RouteList new_routes; - list<boost::shared_ptr<MidiTrack> > ret; - //uint32_t control_id; - - // FIXME: need physical I/O and autoconnect stuff for MIDI - - /* count existing midi tracks */ - - { - shared_ptr<RouteList> r = routes.reader (); - - for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - if (dynamic_cast<MidiTrack*>((*i).get()) != 0) { - if (!(*i)->is_hidden()) { - n++; - //channels_used += (*i)->n_inputs().n_midi(); - } - } - } - } - - /* - vector<string> physinputs; - vector<string> physoutputs; - uint32_t nphysical_in; - uint32_t nphysical_out; - - _engine.get_physical_outputs (physoutputs); - _engine.get_physical_inputs (physinputs); - control_id = ntracks() + nbusses() + 1; - */ - - while (how_many) { - - /* check for duplicate route names, since we might have pre-existing - routes with this name (e.g. create Audio1, Audio2, delete Audio1, - save, close,restart,add new route - first named route is now - Audio2) - */ - - - do { - ++track_id; - - snprintf (track_name, sizeof(track_name), "Midi %" PRIu32, track_id); - - if (route_by_name (track_name) == 0) { - break; - } - - } while (track_id < (UINT_MAX-1)); - - /* - if (Config->get_input_auto_connect() & AutoConnectPhysical) { - nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size()); - } else { - nphysical_in = 0; - } - - if (Config->get_output_auto_connect() & AutoConnectPhysical) { - nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size()); - } else { - nphysical_out = 0; - } - */ - - shared_ptr<MidiTrack> track; - - try { - track = boost::shared_ptr<MidiTrack>((new MidiTrack (*this, track_name, Route::Flag (0), mode))); - - if (track->ensure_io (ChanCount(DataType::MIDI, 1), ChanCount(DataType::AUDIO, 1), false, this)) { - error << "cannot configure 1 in/1 out configuration for new midi track" << endmsg; - goto failed; - } - - /* - if (nphysical_in) { - for (uint32_t x = 0; x < track->n_inputs().n_midi() && x < nphysical_in; ++x) { - - port = ""; - - if (Config->get_input_auto_connect() & AutoConnectPhysical) { - port = physinputs[(channels_used+x)%nphysical_in]; - } - - if (port.length() && track->connect_input (track->input (x), port, this)) { - break; - } - } - } - - for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) { - - port = ""; - - if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) { - port = physoutputs[(channels_used+x)%nphysical_out]; - } else if (Config->get_output_auto_connect() & AutoConnectMaster) { - if (_master_out) { - port = _master_out->input (x%_master_out->n_inputs().n_midi())->name(); - } - } - - if (port.length() && track->connect_output (track->output (x), port, this)) { - break; - } - } - - channels_used += track->n_inputs ().n_midi(); - - */ - - track->midi_diskstream()->non_realtime_input_change(); - - track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes)); - //track->set_remote_control_id (control_id); - - new_routes.push_back (track); - ret.push_back (track); - } - - catch (failed_constructor &err) { - error << _("Session: could not create new midi track.") << endmsg; - - if (track) { - /* we need to get rid of this, since the track failed to be created */ - /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */ - - { - RCUWriter<DiskstreamList> writer (diskstreams); - boost::shared_ptr<DiskstreamList> ds = writer.get_copy(); - ds->remove (track->midi_diskstream()); - } - } - - goto failed; - } - - catch (AudioEngine::PortRegistrationFailure& pfe) { - - error << _("No more JACK ports are available. You will need to stop Ardour and restart JACK with ports if you need this many tracks.") << endmsg; - - if (track) { - /* we need to get rid of this, since the track failed to be created */ - /* XXX arguably, MidiTrack::MidiTrack should not do the Session::add_diskstream() */ - - { - RCUWriter<DiskstreamList> writer (diskstreams); - boost::shared_ptr<DiskstreamList> ds = writer.get_copy(); - ds->remove (track->midi_diskstream()); - } - } - - goto failed; - } - - --how_many; - } - - failed: - if (!new_routes.empty()) { - add_routes (new_routes, false); - save_state (_current_snapshot_name); - } - - return ret; -} - -list<boost::shared_ptr<AudioTrack> > -Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, uint32_t how_many) -{ - char track_name[32]; - uint32_t track_id = 0; - uint32_t n = 0; - uint32_t channels_used = 0; - string port; - RouteList new_routes; - list<boost::shared_ptr<AudioTrack> > ret; - uint32_t control_id; - - /* count existing audio tracks */ - - { - shared_ptr<RouteList> r = routes.reader (); - - for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - if (dynamic_cast<AudioTrack*>((*i).get()) != 0) { - if (!(*i)->is_hidden()) { - n++; - channels_used += (*i)->n_inputs().n_audio(); - } - } - } - } - - vector<string> physinputs; - vector<string> physoutputs; - uint32_t nphysical_in; - uint32_t nphysical_out; - - _engine.get_physical_outputs (physoutputs); - _engine.get_physical_inputs (physinputs); - control_id = ntracks() + nbusses() + 1; - - while (how_many) { - - /* check for duplicate route names, since we might have pre-existing - routes with this name (e.g. create Audio1, Audio2, delete Audio1, - save, close,restart,add new route - first named route is now - Audio2) - */ - - - do { - ++track_id; - - snprintf (track_name, sizeof(track_name), "Audio %" PRIu32, track_id); - - if (route_by_name (track_name) == 0) { - break; - } - - } while (track_id < (UINT_MAX-1)); - - if (Config->get_input_auto_connect() & AutoConnectPhysical) { - nphysical_in = min (n_physical_inputs, (uint32_t) physinputs.size()); - } else { - nphysical_in = 0; - } - - if (Config->get_output_auto_connect() & AutoConnectPhysical) { - nphysical_out = min (n_physical_outputs, (uint32_t) physinputs.size()); - } else { - nphysical_out = 0; - } - - shared_ptr<AudioTrack> track; - - try { - track = boost::shared_ptr<AudioTrack>((new AudioTrack (*this, track_name, Route::Flag (0), mode))); - - if (track->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) { - error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"), - input_channels, output_channels) - << endmsg; - goto failed; - } - - if (nphysical_in) { - for (uint32_t x = 0; x < track->n_inputs().n_audio() && x < nphysical_in; ++x) { - - port = ""; - - if (Config->get_input_auto_connect() & AutoConnectPhysical) { - port = physinputs[(channels_used+x)%nphysical_in]; - } - - if (port.length() && track->connect_input (track->input (x), port, this)) { - break; - } - } - } - - for (uint32_t x = 0; x < track->n_outputs().n_midi(); ++x) { - - port = ""; - - if (nphysical_out && (Config->get_output_auto_connect() & AutoConnectPhysical)) { - port = physoutputs[(channels_used+x)%nphysical_out]; - } else if (Config->get_output_auto_connect() & AutoConnectMaster) { - if (_master_out) { - port = _master_out->input (x%_master_out->n_inputs().n_audio())->name(); - } - } - - if (port.length() && track->connect_output (track->output (x), port, this)) { - break; - } - } - - channels_used += track->n_inputs ().n_audio(); - - track->audio_diskstream()->non_realtime_input_change(); - - track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes)); - track->set_remote_control_id (control_id); - ++control_id; - - new_routes.push_back (track); - ret.push_back (track); - } - - catch (failed_constructor &err) { - error << _("Session: could not create new audio track.") << endmsg; - - if (track) { - /* we need to get rid of this, since the track failed to be created */ - /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */ - - { - RCUWriter<DiskstreamList> writer (diskstreams); - boost::shared_ptr<DiskstreamList> ds = writer.get_copy(); - ds->remove (track->audio_diskstream()); - } - } - - goto failed; - } - - catch (AudioEngine::PortRegistrationFailure& pfe) { - - error << _("No more JACK ports are available. You will need to stop Ardour and restart JACK with ports if you need this many tracks.") << endmsg; - - if (track) { - /* we need to get rid of this, since the track failed to be created */ - /* XXX arguably, AudioTrack::AudioTrack should not do the Session::add_diskstream() */ - - { - RCUWriter<DiskstreamList> writer (diskstreams); - boost::shared_ptr<DiskstreamList> ds = writer.get_copy(); - ds->remove (track->audio_diskstream()); - } - } - - goto failed; - } - - --how_many; - } - - failed: - if (!new_routes.empty()) { - add_routes (new_routes, true); - } - - return ret; -} - -void -Session::set_remote_control_ids () -{ - RemoteModel m = Config->get_remote_model(); - - shared_ptr<RouteList> r = routes.reader (); - - for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - if ( MixerOrdered == m) { - long order = (*i)->order_key(N_("signal")); - (*i)->set_remote_control_id( order+1 ); - } else if ( EditorOrdered == m) { - long order = (*i)->order_key(N_("editor")); - (*i)->set_remote_control_id( order+1 ); - } else if ( UserOrdered == m) { - //do nothing ... only changes to remote id's are initiated by user - } - } -} - - -Session::RouteList -Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many) -{ - char bus_name[32]; - uint32_t bus_id = 1; - uint32_t n = 0; - string port; - RouteList ret; - uint32_t control_id; - - /* count existing audio busses */ - - { - shared_ptr<RouteList> r = routes.reader (); - - for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - if (dynamic_cast<AudioTrack*>((*i).get()) == 0) { - if (!(*i)->is_hidden() && (*i)->name() != _("master")) { - bus_id++; - } - } - } - } - - vector<string> physinputs; - vector<string> physoutputs; - - _engine.get_physical_outputs (physoutputs); - _engine.get_physical_inputs (physinputs); - control_id = ntracks() + nbusses() + 1; - - while (how_many) { - - do { - snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id); - - bus_id++; - - if (route_by_name (bus_name) == 0) { - break; - } - - } while (bus_id < (UINT_MAX-1)); - - try { - shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO)); - - if (bus->ensure_io (ChanCount(DataType::AUDIO, input_channels), ChanCount(DataType::AUDIO, output_channels), false, this)) { - error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"), - input_channels, output_channels) - << endmsg; - goto failure; - } - - for (uint32_t x = 0; n_physical_inputs && x < bus->n_inputs().n_audio(); ++x) { - - port = ""; - - if (Config->get_input_auto_connect() & AutoConnectPhysical) { - port = physinputs[((n+x)%n_physical_inputs)]; - } - - if (port.length() && bus->connect_input (bus->input (x), port, this)) { - break; - } - } - - for (uint32_t x = 0; n_physical_outputs && x < bus->n_outputs().n_audio(); ++x) { - - port = ""; - - if (Config->get_output_auto_connect() & AutoConnectPhysical) { - port = physoutputs[((n+x)%n_physical_outputs)]; - } else if (Config->get_output_auto_connect() & AutoConnectMaster) { - if (_master_out) { - port = _master_out->input (x%_master_out->n_inputs().n_audio())->name(); - } - } - - if (port.length() && bus->connect_output (bus->output (x), port, this)) { - break; - } - } - - bus->set_remote_control_id (control_id); - ++control_id; - - ret.push_back (bus); - } - - - catch (failed_constructor &err) { - error << _("Session: could not create new audio route.") << endmsg; - goto failure; - } - - catch (AudioEngine::PortRegistrationFailure& pfe) { - error << _("No more JACK ports are available. You will need to stop Ardour and restart JACK with ports if you need this many tracks.") << endmsg; - goto failure; - } - - - --how_many; - } - - failure: - if (!ret.empty()) { - add_routes (ret, true); - } - - return ret; - -} - -void -Session::add_routes (RouteList& new_routes, bool save) -{ - { - RCUWriter<RouteList> writer (routes); - shared_ptr<RouteList> r = writer.get_copy (); - r->insert (r->end(), new_routes.begin(), new_routes.end()); - resort_routes_using (r); - } - - for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) { - - boost::weak_ptr<Route> wpr (*x); - - (*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr)); - (*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed)); - (*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x)); - (*x)->processors_changed.connect (bind (mem_fun (*this, &Session::update_latency_compensation), false, false)); - - if ((*x)->is_master()) { - _master_out = (*x); - } - - if ((*x)->is_control()) { - _control_out = (*x); - } - - add_bundle ((*x)->bundle_for_inputs()); - add_bundle ((*x)->bundle_for_outputs()); - } - - if (_control_out && IO::connecting_legal) { - - vector<string> cports; - uint32_t ni = _control_out->n_inputs().n_audio(); - - for (uint32_t n = 0; n < ni; ++n) { - cports.push_back (_control_out->input(n)->name()); - } - - for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) { - (*x)->set_control_outs (cports); - } - } - - set_dirty(); - - if (save) { - save_state (_current_snapshot_name); - } - - RouteAdded (new_routes); /* EMIT SIGNAL */ -} - -void -Session::add_diskstream (boost::shared_ptr<Diskstream> dstream) -{ - /* need to do this in case we're rolling at the time, to prevent false underruns */ - dstream->do_refill_with_alloc (); - - dstream->set_block_size (current_block_size); - - { - RCUWriter<DiskstreamList> writer (diskstreams); - boost::shared_ptr<DiskstreamList> ds = writer.get_copy(); - ds->push_back (dstream); - /* writer goes out of scope, copies ds back to main */ - } - - dstream->PlaylistChanged.connect (sigc::bind (mem_fun (*this, &Session::diskstream_playlist_changed), dstream)); - /* this will connect to future changes, and check the current length */ - diskstream_playlist_changed (dstream); - - dstream->prepare (); - -} - -void -Session::remove_route (shared_ptr<Route> route) -{ - { - RCUWriter<RouteList> writer (routes); - shared_ptr<RouteList> rs = writer.get_copy (); - - rs->remove (route); - - /* deleting the master out seems like a dumb - idea, but its more of a UI policy issue - than our concern. - */ - - if (route == _master_out) { - _master_out = shared_ptr<Route> (); - } - - if (route == _control_out) { - _control_out = shared_ptr<Route> (); - - /* cancel control outs for all routes */ - - vector<string> empty; - - for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) { - (*r)->set_control_outs (empty); - } - } - - update_route_solo_state (); - - /* writer goes out of scope, forces route list update */ - } - - Track* t; - boost::shared_ptr<Diskstream> ds; - - if ((t = dynamic_cast<Track*>(route.get())) != 0) { - ds = t->diskstream(); - } - - if (ds) { - - { - RCUWriter<DiskstreamList> dsl (diskstreams); - boost::shared_ptr<DiskstreamList> d = dsl.get_copy(); - d->remove (ds); - } - } - - find_current_end (); - - // We need to disconnect the routes inputs and outputs - - route->disconnect_inputs (0); - route->disconnect_outputs (0); - - update_latency_compensation (false, false); - set_dirty(); - - /* get rid of it from the dead wood collection in the route list manager */ - - /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */ - - routes.flush (); - - /* try to cause everyone to drop their references */ - - route->drop_references (); - - /* save the new state of the world */ - - if (save_state (_current_snapshot_name)) { - save_history (_current_snapshot_name); - } -} - -void -Session::route_mute_changed (void* src) -{ - set_dirty (); -} - -void -Session::route_solo_changed (void* src, boost::weak_ptr<Route> wpr) -{ - if (solo_update_disabled) { - // We know already - return; - } - - bool is_track; - boost::shared_ptr<Route> route = wpr.lock (); - - if (!route) { - /* should not happen */ - error << string_compose (_("programming error: %1"), X_("invalid route weak ptr passed to route_solo_changed")) << endmsg; - return; - } - - is_track = (boost::dynamic_pointer_cast<AudioTrack>(route) != 0); - - shared_ptr<RouteList> r = routes.reader (); - - for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - - /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */ - - if (is_track) { - - /* don't mess with busses */ - - if (dynamic_cast<Track*>((*i).get()) == 0) { - continue; - } - - } else { - - /* don't mess with tracks */ - - if (dynamic_cast<Track*>((*i).get()) != 0) { - continue; - } - } - - if ((*i) != route && - ((*i)->mix_group () == 0 || - (*i)->mix_group () != route->mix_group () || - !route->mix_group ()->is_active())) { - - if ((*i)->soloed()) { - - /* if its already soloed, and solo latching is enabled, - then leave it as it is. - */ - - if (Config->get_solo_latched()) { - continue; - } - } - - /* do it */ - - solo_update_disabled = true; - (*i)->set_solo (false, src); - solo_update_disabled = false; - } - } - - bool something_soloed = false; - bool same_thing_soloed = false; - bool signal = false; - - for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - if ((*i)->soloed()) { - something_soloed = true; - if (dynamic_cast<Track*>((*i).get())) { - if (is_track) { - same_thing_soloed = true; - break; - } - } else { - if (!is_track) { - same_thing_soloed = true; - break; - } - } - break; - } - } - - if (something_soloed != currently_soloing) { - signal = true; - currently_soloing = something_soloed; - } - - modify_solo_mute (is_track, same_thing_soloed); - - if (signal) { - SoloActive (currently_soloing); /* EMIT SIGNAL */ - } - - SoloChanged (); /* EMIT SIGNAL */ - - set_dirty(); -} - -void -Session::update_route_solo_state () -{ - bool mute = false; - bool is_track = false; - bool signal = false; - - /* caller must hold RouteLock */ - - /* this is where we actually implement solo by changing - the solo mute setting of each track. - */ - - shared_ptr<RouteList> r = routes.reader (); - - for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - if ((*i)->soloed()) { - mute = true; - if (dynamic_cast<Track*>((*i).get())) { - is_track = true; - } - break; - } - } - - if (mute != currently_soloing) { - signal = true; - currently_soloing = mute; - } - - if (!is_track && !mute) { - - /* nothing is soloed */ - - for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - (*i)->set_solo_mute (false); - } - - if (signal) { - SoloActive (false); - } - - return; - } - - modify_solo_mute (is_track, mute); - - if (signal) { - SoloActive (currently_soloing); - } -} - -void -Session::modify_solo_mute (bool is_track, bool mute) -{ - shared_ptr<RouteList> r = routes.reader (); - - for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - - if (is_track) { - - /* only alter track solo mute */ - - if (dynamic_cast<Track*>((*i).get())) { - if ((*i)->soloed()) { - (*i)->set_solo_mute (!mute); - } else { - (*i)->set_solo_mute (mute); - } - } - - } else { - - /* only alter bus solo mute */ - - if (!dynamic_cast<Track*>((*i).get())) { - - if ((*i)->soloed()) { - - (*i)->set_solo_mute (false); - - } else { - - /* don't mute master or control outs - in response to another bus solo - */ - - if ((*i) != _master_out && - (*i) != _control_out) { - (*i)->set_solo_mute (mute); - } - } - } - - } - } -} - - -void -Session::catch_up_on_solo () -{ - /* this is called after set_state() to catch the full solo - state, which can't be correctly determined on a per-route - basis, but needs the global overview that only the session - has. - */ - update_route_solo_state(); -} - -shared_ptr<Route> -Session::route_by_name (string name) -{ - shared_ptr<RouteList> r = routes.reader (); - - for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - if ((*i)->name() == name) { - return *i; - } - } - - return shared_ptr<Route> ((Route*) 0); -} - -shared_ptr<Route> -Session::route_by_id (PBD::ID id) -{ - shared_ptr<RouteList> r = routes.reader (); - - for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - if ((*i)->id() == id) { - return *i; - } - } - - return shared_ptr<Route> ((Route*) 0); -} - -shared_ptr<Route> -Session::route_by_remote_id (uint32_t id) -{ - shared_ptr<RouteList> r = routes.reader (); - - for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - if ((*i)->remote_control_id() == id) { - return *i; - } - } - - return shared_ptr<Route> ((Route*) 0); -} - -void -Session::find_current_end () -{ - if (_state_of_the_state & Loading) { - return; - } - - nframes_t max = get_maximum_extent (); - - if (max > end_location->end()) { - end_location->set_end (max); - set_dirty(); - DurationChanged(); /* EMIT SIGNAL */ - } -} - -nframes_t -Session::get_maximum_extent () const -{ - nframes_t max = 0; - nframes_t me; - - boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader(); - - for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) { - boost::shared_ptr<Playlist> pl = (*i)->playlist(); - if ((me = pl->get_maximum_extent()) > max) { - max = me; - } - } - - return max; -} - -boost::shared_ptr<Diskstream> -Session::diskstream_by_name (string name) -{ - boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader(); - - for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) { - if ((*i)->name() == name) { - return *i; - } - } - - return boost::shared_ptr<Diskstream>((Diskstream*) 0); -} - -boost::shared_ptr<Diskstream> -Session::diskstream_by_id (const PBD::ID& id) -{ - boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader(); - - for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) { - if ((*i)->id() == id) { - return *i; - } - } - - return boost::shared_ptr<Diskstream>((Diskstream*) 0); -} - -/* Region management */ - -string -Session::new_region_name (string old) -{ - string::size_type last_period; - uint32_t number; - string::size_type len = old.length() + 64; - char buf[len]; - - if ((last_period = old.find_last_of ('.')) == string::npos) { - - /* no period present - add one explicitly */ - - old += '.'; - last_period = old.length() - 1; - number = 0; - - } else { - - number = atoi (old.substr (last_period+1).c_str()); - - } - - while (number < (UINT_MAX-1)) { - - RegionList::const_iterator i; - string sbuf; - - number++; - - snprintf (buf, len, "%s%" PRIu32, old.substr (0, last_period + 1).c_str(), number); - sbuf = buf; - - for (i = regions.begin(); i != regions.end(); ++i) { - if (i->second->name() == sbuf) { - break; - } - } - - if (i == regions.end()) { - break; - } - } - - if (number != (UINT_MAX-1)) { - return buf; - } - - error << string_compose (_("cannot create new name for region \"%1\""), old) << endmsg; - return old; -} - -int -Session::region_name (string& result, string base, bool newlevel) const -{ - char buf[16]; - string subbase; - - assert(base.find("/") == string::npos); - - if (base == "") { - - Glib::Mutex::Lock lm (region_lock); - - snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1); - - - result = "region."; - result += buf; - - } else { - - /* XXX this is going to be slow. optimize me later */ - - if (newlevel) { - subbase = base; - } else { - string::size_type pos; - - pos = base.find_last_of ('.'); - - /* pos may be npos, but then we just use entire base */ - - subbase = base.substr (0, pos); - - } - - bool name_taken = true; - - { - Glib::Mutex::Lock lm (region_lock); - - for (int n = 1; n < 5000; ++n) { - - result = subbase; - snprintf (buf, sizeof (buf), ".%d", n); - result += buf; - - name_taken = false; - - for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) { - if (i->second->name() == result) { - name_taken = true; - break; - } - } - - if (!name_taken) { - break; - } - } - } - - if (name_taken) { - fatal << string_compose(_("too many regions with names like %1"), base) << endmsg; - /*NOTREACHED*/ - } - } - return 0; -} - -void -Session::add_region (boost::shared_ptr<Region> region) -{ - vector<boost::shared_ptr<Region> > v; - v.push_back (region); - add_regions (v); -} - -void -Session::add_regions (vector<boost::shared_ptr<Region> >& new_regions) -{ - bool added = false; - - { - Glib::Mutex::Lock lm (region_lock); - - for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) { - - boost::shared_ptr<Region> region = *ii; - - if (region == 0) { - - error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg; - - } else { - - RegionList::iterator x; - - for (x = regions.begin(); x != regions.end(); ++x) { - - if (region->region_list_equivalent (x->second)) { - break; - } - } - - if (x == regions.end()) { - - pair<RegionList::key_type,RegionList::mapped_type> entry; - - entry.first = region->id(); - entry.second = region; - - pair<RegionList::iterator,bool> x = regions.insert (entry); - - if (!x.second) { - return; - } - - added = true; - } - } - } - } - - /* mark dirty because something has changed even if we didn't - add the region to the region list. - */ - - set_dirty(); - - if (added) { - - vector<boost::weak_ptr<Region> > v; - boost::shared_ptr<Region> first_r; - - for (vector<boost::shared_ptr<Region> >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) { - - boost::shared_ptr<Region> region = *ii; - - if (region == 0) { - - error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg; - - } else { - v.push_back (region); - - if (!first_r) { - first_r = region; - } - } - - region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), boost::weak_ptr<Region>(region))); - region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), boost::weak_ptr<Region>(region))); - } - - if (!v.empty()) { - RegionsAdded (v); /* EMIT SIGNAL */ - } - } -} - -void -Session::region_changed (Change what_changed, boost::weak_ptr<Region> weak_region) -{ - boost::shared_ptr<Region> region (weak_region.lock ()); - - if (!region) { - return; - } - - if (what_changed & Region::HiddenChanged) { - /* relay hidden changes */ - RegionHiddenChange (region); - } -} - -void -Session::remove_region (boost::weak_ptr<Region> weak_region) -{ - RegionList::iterator i; - boost::shared_ptr<Region> region (weak_region.lock ()); - - if (!region) { - return; - } - - bool removed = false; - - { - Glib::Mutex::Lock lm (region_lock); - - if ((i = regions.find (region->id())) != regions.end()) { - regions.erase (i); - removed = true; - } - } - - /* mark dirty because something has changed even if we didn't - remove the region from the region list. - */ - - set_dirty(); - - if (removed) { - RegionRemoved(region); /* EMIT SIGNAL */ - } -} - -boost::shared_ptr<Region> -Session::find_whole_file_parent (boost::shared_ptr<Region const> child) -{ - RegionList::iterator i; - boost::shared_ptr<Region> region; - - Glib::Mutex::Lock lm (region_lock); - - for (i = regions.begin(); i != regions.end(); ++i) { - - region = i->second; - - if (region->whole_file()) { - - if (child->source_equivalent (region)) { - return region; - } - } - } - - return boost::shared_ptr<Region> (); -} - -void -Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result) -{ - for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) - (*i)->get_region_list_equivalent_regions (region, result); -} - -int -Session::destroy_region (boost::shared_ptr<Region> region) -{ - vector<boost::shared_ptr<Source> > srcs; - - { - if (region->playlist()) { - region->playlist()->destroy_region (region); - } - - for (uint32_t n = 0; n < region->n_channels(); ++n) { - srcs.push_back (region->source (n)); - } - } - - region->drop_references (); - - for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) { - - (*i)->mark_for_remove (); - (*i)->drop_references (); - - cerr << "source was not used by any playlist\n"; - } - - return 0; -} - -int -Session::destroy_regions (list<boost::shared_ptr<Region> > regions) -{ - for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) { - destroy_region (*i); - } - return 0; -} - -int -Session::remove_last_capture () -{ - list<boost::shared_ptr<Region> > r; - - boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader(); - - for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) { - list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions(); - - if (!l.empty()) { - r.insert (r.end(), l.begin(), l.end()); - l.clear (); - } - } - - destroy_regions (r); - - save_state (_current_snapshot_name); - - return 0; -} - -int -Session::remove_region_from_region_list (boost::shared_ptr<Region> r) -{ - remove_region (r); - return 0; -} - -/* Source Management */ -void -Session::add_source (boost::shared_ptr<Source> source) -{ - pair<SourceMap::key_type, SourceMap::mapped_type> entry; - pair<SourceMap::iterator,bool> result; - - entry.first = source->id(); - entry.second = source; - - { - Glib::Mutex::Lock lm (source_lock); - result = sources.insert (entry); - } - - if (result.second) { - source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source))); - set_dirty(); - } - - boost::shared_ptr<AudioFileSource> afs; - - if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) { - if (Config->get_auto_analyse_audio()) { - Analyser::queue_source_for_analysis (source, false); - } - } -} - -void -Session::remove_source (boost::weak_ptr<Source> src) -{ - SourceMap::iterator i; - boost::shared_ptr<Source> source = src.lock(); - - if (!source) { - return; - } - - { - Glib::Mutex::Lock lm (source_lock); - - if ((i = sources.find (source->id())) != sources.end()) { - sources.erase (i); - } - } - - if (!_state_of_the_state & InCleanup) { - - /* save state so we don't end up with a session file - referring to non-existent sources. - */ - - save_state (_current_snapshot_name); - } -} - -boost::shared_ptr<Source> -Session::source_by_id (const PBD::ID& id) -{ - Glib::Mutex::Lock lm (source_lock); - SourceMap::iterator i; - boost::shared_ptr<Source> source; - - if ((i = sources.find (id)) != sources.end()) { - source = i->second; - } - - return source; -} - - -boost::shared_ptr<Source> -Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn) -{ - Glib::Mutex::Lock lm (source_lock); - - for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) { - cerr << "comparing " << path << " with " << i->second->name() << endl; - boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(i->second); - - if (afs && afs->path() == path && chn == afs->channel()) { - return afs; - } - - } - return boost::shared_ptr<Source>(); -} - -Glib::ustring -Session::peak_path (Glib::ustring base) const -{ - sys::path peakfile_path(_session_dir->peak_path()); - peakfile_path /= basename_nosuffix (base) + peakfile_suffix; - return peakfile_path.to_string(); -} - -string -Session::change_audio_path_by_name (string path, string oldname, string newname, bool destructive) -{ - string look_for; - string old_basename = PBD::basename_nosuffix (oldname); - string new_legalized = legalize_for_path (newname); - - /* note: we know (or assume) the old path is already valid */ - - if (destructive) { - - /* destructive file sources have a name of the form: - - /path/to/Tnnnn-NAME(%[LR])?.wav - - the task here is to replace NAME with the new name. - */ - - /* find last slash */ - - string dir; - string prefix; - string::size_type slash; - string::size_type dash; - - if ((slash = path.find_last_of ('/')) == string::npos) { - return ""; - } - - dir = path.substr (0, slash+1); - - /* '-' is not a legal character for the NAME part of the path */ - - if ((dash = path.find_last_of ('-')) == string::npos) { - return ""; - } - - prefix = path.substr (slash+1, dash-(slash+1)); - - path = dir; - path += prefix; - path += '-'; - path += new_legalized; - path += ".wav"; /* XXX gag me with a spoon */ - - } else { - - /* non-destructive file sources have a name of the form: - - /path/to/NAME-nnnnn(%[LR])?.wav - - the task here is to replace NAME with the new name. - */ - - string dir; - string suffix; - string::size_type slash; - string::size_type dash; - string::size_type postfix; - - /* find last slash */ - - if ((slash = path.find_last_of ('/')) == string::npos) { - return ""; - } - - dir = path.substr (0, slash+1); - - /* '-' is not a legal character for the NAME part of the path */ - - if ((dash = path.find_last_of ('-')) == string::npos) { - return ""; - } - - suffix = path.substr (dash+1); - - // Suffix is now everything after the dash. Now we need to eliminate - // the nnnnn part, which is done by either finding a '%' or a '.' - - postfix = suffix.find_last_of ("%"); - if (postfix == string::npos) { - postfix = suffix.find_last_of ('.'); - } - - if (postfix != string::npos) { - suffix = suffix.substr (postfix); - } else { - error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl; - return ""; - } - - const uint32_t limit = 10000; - char buf[PATH_MAX+1]; - - for (uint32_t cnt = 1; cnt <= limit; ++cnt) { - - snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str()); - - if (access (buf, F_OK) != 0) { - path = buf; - break; - } - path = ""; - } - - if (path == "") { - error << "FATAL ERROR! Could not find a " << endl; - } - - } - - return path; -} - -string -Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool destructive) -{ - string spath; - uint32_t cnt; - char buf[PATH_MAX+1]; - const uint32_t limit = 10000; - string legalized; - - buf[0] = '\0'; - legalized = legalize_for_path (name); - - /* find a "version" of the file name that doesn't exist in - any of the possible directories. - */ - - for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) { - - vector<space_and_path>::iterator i; - uint32_t existing = 0; - - for (i = session_dirs.begin(); i != session_dirs.end(); ++i) { - - SessionDirectory sdir((*i).path); - - spath = sdir.sound_path().to_string(); - - if (destructive) { - if (nchan < 2) { - snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str()); - } else if (nchan == 2) { - if (chan == 0) { - snprintf (buf, sizeof(buf), "%s/T%04d-%s%%L.wav", spath.c_str(), cnt, legalized.c_str()); - } else { - snprintf (buf, sizeof(buf), "%s/T%04d-%s%%R.wav", spath.c_str(), cnt, legalized.c_str()); - } - } else if (nchan < 26) { - snprintf (buf, sizeof(buf), "%s/T%04d-%s%%%c.wav", spath.c_str(), cnt, legalized.c_str(), 'a' + chan); - } else { - snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str()); - } - - } else { - - spath += '/'; - spath += legalized; - - if (nchan < 2) { - snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt); - } else if (nchan == 2) { - if (chan == 0) { - snprintf (buf, sizeof(buf), "%s-%u%%L.wav", spath.c_str(), cnt); - } else { - snprintf (buf, sizeof(buf), "%s-%u%%R.wav", spath.c_str(), cnt); - } - } else if (nchan < 26) { - snprintf (buf, sizeof(buf), "%s-%u%%%c.wav", spath.c_str(), cnt, 'a' + chan); - } else { - snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt); - } - } - - if (sys::exists(buf)) { - existing++; - } - - } - - if (existing == 0) { - break; - } - - if (cnt > limit) { - error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg; - destroy (); - throw failed_constructor(); - } - } - - /* we now have a unique name for the file, but figure out where to - actually put it. - */ - - string foo = buf; - - SessionDirectory sdir(get_best_session_directory_for_new_source ()); - - spath = sdir.sound_path().to_string(); - spath += '/'; - - string::size_type pos = foo.find_last_of ('/'); - - if (pos == string::npos) { - spath += foo; - } else { - spath += foo.substr (pos + 1); - } - - return spath; -} - -boost::shared_ptr<AudioFileSource> -Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive) -{ - string spath = audio_path_from_name (ds.name(), ds.n_channels().n_audio(), chan, destructive); - return boost::dynamic_pointer_cast<AudioFileSource> ( - SourceFactory::createWritable (DataType::AUDIO, *this, spath, destructive, frame_rate())); -} - -// FIXME: _terrible_ code duplication -string -Session::change_midi_path_by_name (string path, string oldname, string newname, bool destructive) -{ - string look_for; - string old_basename = PBD::basename_nosuffix (oldname); - string new_legalized = legalize_for_path (newname); - - /* note: we know (or assume) the old path is already valid */ - - if (destructive) { - - /* destructive file sources have a name of the form: - - /path/to/Tnnnn-NAME(%[LR])?.wav - - the task here is to replace NAME with the new name. - */ - - /* find last slash */ - - string dir; - string prefix; - string::size_type slash; - string::size_type dash; - - if ((slash = path.find_last_of ('/')) == string::npos) { - return ""; - } - - dir = path.substr (0, slash+1); - - /* '-' is not a legal character for the NAME part of the path */ - - if ((dash = path.find_last_of ('-')) == string::npos) { - return ""; - } - - prefix = path.substr (slash+1, dash-(slash+1)); - - path = dir; - path += prefix; - path += '-'; - path += new_legalized; - path += ".mid"; /* XXX gag me with a spoon */ - - } else { - - /* non-destructive file sources have a name of the form: - - /path/to/NAME-nnnnn(%[LR])?.wav - - the task here is to replace NAME with the new name. - */ - - string dir; - string suffix; - string::size_type slash; - string::size_type dash; - string::size_type postfix; - - /* find last slash */ - - if ((slash = path.find_last_of ('/')) == string::npos) { - return ""; - } - - dir = path.substr (0, slash+1); - - /* '-' is not a legal character for the NAME part of the path */ - - if ((dash = path.find_last_of ('-')) == string::npos) { - return ""; - } - - suffix = path.substr (dash+1); - - // Suffix is now everything after the dash. Now we need to eliminate - // the nnnnn part, which is done by either finding a '%' or a '.' - - postfix = suffix.find_last_of ("%"); - if (postfix == string::npos) { - postfix = suffix.find_last_of ('.'); - } - - if (postfix != string::npos) { - suffix = suffix.substr (postfix); - } else { - error << "Logic error in Session::change_midi_path_by_name(), please report to the developers" << endl; - return ""; - } - - const uint32_t limit = 10000; - char buf[PATH_MAX+1]; - - for (uint32_t cnt = 1; cnt <= limit; ++cnt) { - - snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str()); - - if (access (buf, F_OK) != 0) { - path = buf; - break; - } - path = ""; - } - - if (path == "") { - error << "FATAL ERROR! Could not find a " << endl; - } - - } - - return path; -} - -string -Session::midi_path_from_name (string name) -{ - string spath; - uint32_t cnt; - char buf[PATH_MAX+1]; - const uint32_t limit = 10000; - string legalized; - - buf[0] = '\0'; - legalized = legalize_for_path (name); - - /* find a "version" of the file name that doesn't exist in - any of the possible directories. - */ - - for (cnt = 1; cnt <= limit; ++cnt) { - - vector<space_and_path>::iterator i; - uint32_t existing = 0; - - for (i = session_dirs.begin(); i != session_dirs.end(); ++i) { - - SessionDirectory sdir((*i).path); - - sys::path p = sdir.midi_path(); - - p /= legalized; - - spath = p.to_string(); - - snprintf (buf, sizeof(buf), "%s-%u.mid", spath.c_str(), cnt); - - if (sys::exists (buf)) { - existing++; - } - } - - if (existing == 0) { - break; - } - - if (cnt > limit) { - error << string_compose(_("There are already %1 recordings for %2, which I consider too many."), limit, name) << endmsg; - throw failed_constructor(); - } - } - - /* we now have a unique name for the file, but figure out where to - actually put it. - */ - - string foo = buf; - - SessionDirectory sdir(get_best_session_directory_for_new_source ()); - - spath = sdir.midi_path().to_string(); - spath += '/'; - - string::size_type pos = foo.find_last_of ('/'); - - if (pos == string::npos) { - spath += foo; - } else { - spath += foo.substr (pos + 1); - } - - return spath; -} - -boost::shared_ptr<MidiSource> -Session::create_midi_source_for_session (MidiDiskstream& ds) -{ - string mpath = midi_path_from_name (ds.name()); - - return boost::dynamic_pointer_cast<SMFSource> (SourceFactory::createWritable (DataType::MIDI, *this, mpath, false, frame_rate())); -} - - -/* Playlist management */ - -boost::shared_ptr<Playlist> -Session::playlist_by_name (string name) -{ - Glib::Mutex::Lock lm (playlist_lock); - for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) { - if ((*i)->name() == name) { - return* i; - } - } - for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) { - if ((*i)->name() == name) { - return* i; - } - } - - return boost::shared_ptr<Playlist>(); -} - -void -Session::add_playlist (boost::shared_ptr<Playlist> playlist) -{ - if (playlist->hidden()) { - return; - } - - { - Glib::Mutex::Lock lm (playlist_lock); - if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) { - playlists.insert (playlists.begin(), playlist); - playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist))); - playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist))); - } - } - - set_dirty(); - - PlaylistAdded (playlist); /* EMIT SIGNAL */ -} - -void -Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s) -{ - { - Glib::Mutex::Lock lm (playlist_lock); - for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) { - s.push_back (*i); - } - for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) { - s.push_back (*i); - } - } -} - -void -Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl) -{ - boost::shared_ptr<Playlist> pl(wpl.lock()); - - if (!pl) { - return; - } - - PlaylistList::iterator x; - - if (pl->hidden()) { - /* its not supposed to be visible */ - return; - } - - { - Glib::Mutex::Lock lm (playlist_lock); - - if (!inuse) { - - unused_playlists.insert (pl); - - if ((x = playlists.find (pl)) != playlists.end()) { - playlists.erase (x); - } - - - } else { - - playlists.insert (pl); - - if ((x = unused_playlists.find (pl)) != unused_playlists.end()) { - unused_playlists.erase (x); - } - } - } -} - -void -Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist) -{ - if (_state_of_the_state & Deletion) { - return; - } - - boost::shared_ptr<Playlist> playlist (weak_playlist.lock()); - - if (!playlist) { - return; - } - - { - Glib::Mutex::Lock lm (playlist_lock); - - PlaylistList::iterator i; - - i = find (playlists.begin(), playlists.end(), playlist); - if (i != playlists.end()) { - playlists.erase (i); - } - - i = find (unused_playlists.begin(), unused_playlists.end(), playlist); - if (i != unused_playlists.end()) { - unused_playlists.erase (i); - } - - } - - set_dirty(); - - PlaylistRemoved (playlist); /* EMIT SIGNAL */ -} - -void -Session::set_audition (boost::shared_ptr<Region> r) -{ - pending_audition_region = r; - post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition); - schedule_butler_transport_work (); -} - -void -Session::audition_playlist () -{ - Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0); - ev->region.reset (); - queue_event (ev); -} - -void -Session::non_realtime_set_audition () -{ - if (!pending_audition_region) { - auditioner->audition_current_playlist (); - } else { - auditioner->audition_region (pending_audition_region); - pending_audition_region.reset (); - } - AuditionActive (true); /* EMIT SIGNAL */ -} - -void -Session::audition_region (boost::shared_ptr<Region> r) -{ - Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0); - ev->region = r; - queue_event (ev); -} - -void -Session::cancel_audition () -{ - if (auditioner->active()) { - auditioner->cancel_audition (); - AuditionActive (false); /* EMIT SIGNAL */ - } -} - -bool -Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) -{ - return a->order_key(N_("signal")) < b->order_key(N_("signal")); -} - -void -Session::remove_empty_sounds () -{ - vector<string> audio_filenames; - - get_files_in_directory (_session_dir->sound_path(), audio_filenames); - - Glib::Mutex::Lock lm (source_lock); - - TapeFileMatcher tape_file_matcher; - - remove_if (audio_filenames.begin(), audio_filenames.end(), - sigc::mem_fun (tape_file_matcher, &TapeFileMatcher::matches)); - - for (vector<string>::iterator i = audio_filenames.begin(); i != audio_filenames.end(); ++i) { - - sys::path audio_file_path (_session_dir->sound_path()); - - audio_file_path /= *i; - - if (AudioFileSource::is_empty (*this, audio_file_path.to_string())) { - - try - { - sys::remove (audio_file_path); - const string peakfile = peak_path (audio_file_path.to_string()); - sys::remove (peakfile); - } - catch (const sys::filesystem_error& err) - { - error << err.what() << endmsg; - } - } - } -} - -bool -Session::is_auditioning () const -{ - /* can be called before we have an auditioner object */ - if (auditioner) { - return auditioner->active(); - } else { - return false; - } -} - -void -Session::set_all_solo (bool yn) -{ - shared_ptr<RouteList> r = routes.reader (); - - for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - if (!(*i)->is_hidden()) { - (*i)->set_solo (yn, this); - } - } - - set_dirty(); -} - -void -Session::set_all_mute (bool yn) -{ - shared_ptr<RouteList> r = routes.reader (); - - for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - if (!(*i)->is_hidden()) { - (*i)->set_mute (yn, this); - } - } - - set_dirty(); -} - -uint32_t -Session::n_diskstreams () const -{ - uint32_t n = 0; - - boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader(); - - for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) { - if (!(*i)->hidden()) { - n++; - } - } - return n; -} - -void -Session::graph_reordered () -{ - /* don't do this stuff if we are setting up connections - from a set_state() call or creating new tracks. - */ - - if (_state_of_the_state & InitialConnecting) { - return; - } - - /* every track/bus asked for this to be handled but it was deferred because - we were connecting. do it now. - */ - - request_input_change_handling (); - - resort_routes (); - - /* force all diskstreams to update their capture offset values to - reflect any changes in latencies within the graph. - */ - - boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader(); - - for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) { - (*i)->set_capture_offset (); - } -} - -void -Session::record_disenable_all () -{ - record_enable_change_all (false); -} - -void -Session::record_enable_all () -{ - record_enable_change_all (true); -} - -void -Session::record_enable_change_all (bool yn) -{ - shared_ptr<RouteList> r = routes.reader (); - - for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - Track* at; - - if ((at = dynamic_cast<Track*>((*i).get())) != 0) { - at->set_record_enable (yn, this); - } - } - - /* since we don't keep rec-enable state, don't mark session dirty */ -} - -void -Session::add_processor (Processor* processor) -{ - Send* send; - PortInsert* port_insert; - PluginInsert* plugin_insert; - - if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) { - _port_inserts.insert (_port_inserts.begin(), port_insert); - } else if ((plugin_insert = dynamic_cast<PluginInsert *> (processor)) != 0) { - _plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert); - } else if ((send = dynamic_cast<Send *> (processor)) != 0) { - _sends.insert (_sends.begin(), send); - } else { - fatal << _("programming error: unknown type of Insert created!") << endmsg; - /*NOTREACHED*/ - } - - processor->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_processor), processor)); - - set_dirty(); -} - -void -Session::remove_processor (Processor* processor) -{ - Send* send; - PortInsert* port_insert; - PluginInsert* plugin_insert; - - if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) { - list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert); - if (x != _port_inserts.end()) { - insert_bitset[port_insert->bit_slot()] = false; - _port_inserts.erase (x); - } - } else if ((plugin_insert = dynamic_cast<PluginInsert *> (processor)) != 0) { - _plugin_inserts.remove (plugin_insert); - } else if ((send = dynamic_cast<Send *> (processor)) != 0) { - list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send); - if (x != _sends.end()) { - send_bitset[send->bit_slot()] = false; - _sends.erase (x); - } - } else { - fatal << _("programming error: unknown type of Insert deleted!") << endmsg; - /*NOTREACHED*/ - } - - set_dirty(); -} - -nframes_t -Session::available_capture_duration () -{ - float sample_bytes_on_disk = 4.0; // keep gcc happy - - switch (Config->get_native_file_data_format()) { - case FormatFloat: - sample_bytes_on_disk = 4.0; - break; - - case FormatInt24: - sample_bytes_on_disk = 3.0; - break; - - case FormatInt16: - sample_bytes_on_disk = 2.0; - break; - - default: - /* impossible, but keep some gcc versions happy */ - fatal << string_compose (_("programming error: %1"), - X_("illegal native file data format")) - << endmsg; - /*NOTREACHED*/ - } - - double scale = 4096.0 / sample_bytes_on_disk; - - if (_total_free_4k_blocks * scale > (double) max_frames) { - return max_frames; - } - - return (nframes_t) floor (_total_free_4k_blocks * scale); -} - -void -Session::add_bundle (shared_ptr<Bundle> bundle) -{ - { - Glib::Mutex::Lock guard (bundle_lock); - _bundles.push_back (bundle); - } - - BundleAdded (bundle); /* EMIT SIGNAL */ - - set_dirty(); -} - -void -Session::remove_bundle (shared_ptr<Bundle> bundle) -{ - bool removed = false; - - { - Glib::Mutex::Lock guard (bundle_lock); - BundleList::iterator i = find (_bundles.begin(), _bundles.end(), bundle); - - if (i != _bundles.end()) { - _bundles.erase (i); - removed = true; - } - } - - if (removed) { - BundleRemoved (bundle); /* EMIT SIGNAL */ - } - - set_dirty(); -} - -shared_ptr<Bundle> -Session::bundle_by_name (string name) const -{ - Glib::Mutex::Lock lm (bundle_lock); - - for (BundleList::const_iterator i = _bundles.begin(); i != _bundles.end(); ++i) { - if ((*i)->name() == name) { - return* i; - } - } - - return boost::shared_ptr<Bundle> (); -} - -void -Session::tempo_map_changed (Change ignored) -{ - clear_clicks (); - - for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) { - (*i)->update_after_tempo_map_change (); - } - - for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) { - (*i)->update_after_tempo_map_change (); - } - - set_dirty (); -} - -/** Ensures that all buffers (scratch, send, silent, etc) are allocated for - * the given count with the current block size. - */ -void -Session::ensure_buffers (ChanCount howmany) -{ - if (current_block_size == 0) - return; // too early? (is this ok?) - - // We need at least 2 MIDI scratch buffers to mix/merge - if (howmany.n_midi() < 2) - howmany.set_midi(2); - - // FIXME: JACK needs to tell us maximum MIDI buffer size - // Using nasty assumption (max # events == nframes) for now - _scratch_buffers->ensure_buffers(howmany, current_block_size); - _mix_buffers->ensure_buffers(howmany, current_block_size); - _silent_buffers->ensure_buffers(howmany, current_block_size); - - allocate_pan_automation_buffers (current_block_size, howmany.n_audio(), false); -} - -uint32_t -Session::next_insert_id () -{ - /* this doesn't really loop forever. just think about it */ - - while (true) { - for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < insert_bitset.size(); ++n) { - if (!insert_bitset[n]) { - insert_bitset[n] = true; - return n; - - } - } - - /* none available, so resize and try again */ - - insert_bitset.resize (insert_bitset.size() + 16, false); - } -} - -uint32_t -Session::next_send_id () -{ - /* this doesn't really loop forever. just think about it */ - - while (true) { - for (boost::dynamic_bitset<uint32_t>::size_type n = 0; n < send_bitset.size(); ++n) { - if (!send_bitset[n]) { - send_bitset[n] = true; - return n; - - } - } - - /* none available, so resize and try again */ - - send_bitset.resize (send_bitset.size() + 16, false); - } -} - -void -Session::mark_send_id (uint32_t id) -{ - if (id >= send_bitset.size()) { - send_bitset.resize (id+16, false); - } - if (send_bitset[id]) { - warning << string_compose (_("send ID %1 appears to be in use already"), id) << endmsg; - } - send_bitset[id] = true; -} - -void -Session::mark_insert_id (uint32_t id) -{ - if (id >= insert_bitset.size()) { - insert_bitset.resize (id+16, false); - } - if (insert_bitset[id]) { - warning << string_compose (_("insert ID %1 appears to be in use already"), id) << endmsg; - } - insert_bitset[id] = true; -} - -/* Named Selection management */ - -NamedSelection * -Session::named_selection_by_name (string name) -{ - Glib::Mutex::Lock lm (named_selection_lock); - for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) { - if ((*i)->name == name) { - return* i; - } - } - return 0; -} - -void -Session::add_named_selection (NamedSelection* named_selection) -{ - { - Glib::Mutex::Lock lm (named_selection_lock); - named_selections.insert (named_selections.begin(), named_selection); - } - - for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) { - add_playlist (*i); - } - - set_dirty(); - - NamedSelectionAdded (); /* EMIT SIGNAL */ -} - -void -Session::remove_named_selection (NamedSelection* named_selection) -{ - bool removed = false; - - { - Glib::Mutex::Lock lm (named_selection_lock); - - NamedSelectionList::iterator i = find (named_selections.begin(), named_selections.end(), named_selection); - - if (i != named_selections.end()) { - delete (*i); - named_selections.erase (i); - set_dirty(); - removed = true; - } - } - - if (removed) { - NamedSelectionRemoved (); /* EMIT SIGNAL */ - } -} - -void -Session::reset_native_file_format () -{ - boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader(); - - for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) { - (*i)->reset_write_sources (false); - } -} - -bool -Session::route_name_unique (string n) const -{ - shared_ptr<RouteList> r = routes.reader (); - - for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) { - if ((*i)->name() == n) { - return false; - } - } - - return true; -} - -uint32_t -Session::n_playlists () const -{ - Glib::Mutex::Lock lm (playlist_lock); - return playlists.size(); -} - -void -Session::allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force) -{ - if (!force && howmany <= _npan_buffers) { - return; - } - - if (_pan_automation_buffer) { - - for (uint32_t i = 0; i < _npan_buffers; ++i) { - delete [] _pan_automation_buffer[i]; - } - - delete [] _pan_automation_buffer; - } - - _pan_automation_buffer = new pan_t*[howmany]; - - for (uint32_t i = 0; i < howmany; ++i) { - _pan_automation_buffer[i] = new pan_t[nframes]; - } - - _npan_buffers = howmany; -} - -int -Session::freeze (InterThreadInfo& itt) -{ - shared_ptr<RouteList> r = routes.reader (); - - for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - - Track *at; - - if ((at = dynamic_cast<Track*>((*i).get())) != 0) { - /* XXX this is wrong because itt.progress will keep returning to zero at the start - of every track. - */ - at->freeze (itt); - } - } - - return 0; -} - -int -Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t len, - bool overwrite, vector<boost::shared_ptr<Source> >& srcs, InterThreadInfo& itt) -{ - int ret = -1; - boost::shared_ptr<Playlist> playlist; - boost::shared_ptr<AudioFileSource> fsource; - uint32_t x; - char buf[PATH_MAX+1]; - ChanCount nchans(track.audio_diskstream()->n_channels()); - nframes_t position; - nframes_t this_chunk; - nframes_t to_do; - BufferSet buffers; - SessionDirectory sdir(get_best_session_directory_for_new_source ()); - const string sound_dir = sdir.sound_path().to_string(); - - // any bigger than this seems to cause stack overflows in called functions - const nframes_t chunk_size = (128 * 1024)/4; - - g_atomic_int_set (&processing_prohibited, 1); - - /* call tree *MUST* hold route_lock */ - - if ((playlist = track.diskstream()->playlist()) == 0) { - goto out; - } - - /* external redirects will be a problem */ - - if (track.has_external_redirects()) { - goto out; - } - - for (uint32_t chan_n=0; chan_n < nchans.n_audio(); ++chan_n) { - - for (x = 0; x < 99999; ++x) { - snprintf (buf, sizeof(buf), "%s/%s-%d-bounce-%" PRIu32 ".wav", sound_dir.c_str(), playlist->name().c_str(), chan_n, x+1); - if (access (buf, F_OK) != 0) { - break; - } - } - - if (x == 99999) { - error << string_compose (_("too many bounced versions of playlist \"%1\""), playlist->name()) << endmsg; - goto out; - } - - try { - fsource = boost::dynamic_pointer_cast<AudioFileSource> ( - SourceFactory::createWritable (DataType::AUDIO, *this, buf, false, frame_rate())); - } - - catch (failed_constructor& err) { - error << string_compose (_("cannot create new audio file \"%1\" for %2"), buf, track.name()) << endmsg; - goto out; - } - - srcs.push_back (fsource); - } - - /* XXX need to flush all redirects */ - - position = start; - to_do = len; - - /* create a set of reasonably-sized buffers */ - buffers.ensure_buffers(nchans, chunk_size); - buffers.set_count(nchans); - - for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) { - boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src); - if (afs) - afs->prepare_for_peakfile_writes (); - } - - while (to_do && !itt.cancel) { - - this_chunk = min (to_do, chunk_size); - - if (track.export_stuff (buffers, start, this_chunk)) { - goto out; - } - - uint32_t n = 0; - for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) { - boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src); - - if (afs) { - if (afs->write (buffers.get_audio(n).data(), this_chunk) != this_chunk) { - goto out; - } - } - } - - start += this_chunk; - to_do -= this_chunk; - - itt.progress = (float) (1.0 - ((double) to_do / len)); - - } - - if (!itt.cancel) { - - time_t now; - struct tm* xnow; - time (&now); - xnow = localtime (&now); - - for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) { - boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src); - - if (afs) { - afs->update_header (position, *xnow, now); - afs->flush_header (); - } - } - - /* construct a region to represent the bounced material */ - - boost::shared_ptr<Region> aregion = RegionFactory::create (srcs, 0, srcs.front()->length(), - region_name_from_path (srcs.front()->name(), true)); - - ret = 0; - } - - out: - if (ret) { - for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) { - boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src); - - if (afs) { - afs->mark_for_remove (); - } - - (*src)->drop_references (); - } - - } else { - for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) { - boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src); - - if (afs) - afs->done_with_peakfile_writes (); - } - } - - g_atomic_int_set (&processing_prohibited, 0); - - return ret; -} - -BufferSet& -Session::get_silent_buffers (ChanCount count) -{ - assert(_silent_buffers->available() >= count); - _silent_buffers->set_count(count); - - for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) { - for (size_t i= 0; i < count.get(*t); ++i) { - _silent_buffers->get(*t, i).clear(); - } - } - - return *_silent_buffers; -} - -BufferSet& -Session::get_scratch_buffers (ChanCount count) -{ - assert(_scratch_buffers->available() >= count); - _scratch_buffers->set_count(count); - return *_scratch_buffers; -} - -BufferSet& -Session::get_mix_buffers (ChanCount count) -{ - assert(_mix_buffers->available() >= count); - _mix_buffers->set_count(count); - return *_mix_buffers; -} - -uint32_t -Session::ntracks () const -{ - uint32_t n = 0; - shared_ptr<RouteList> r = routes.reader (); - - for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) { - if (dynamic_cast<Track*> ((*i).get())) { - ++n; - } - } - - return n; -} - -uint32_t -Session::nbusses () const -{ - uint32_t n = 0; - shared_ptr<RouteList> r = routes.reader (); - - for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) { - if (dynamic_cast<Track*> ((*i).get()) == 0) { - ++n; - } - } - - return n; -} - -void -Session::add_automation_list(AutomationList *al) -{ - automation_lists[al->id()] = al; -} - -nframes_t -Session::compute_initial_length () -{ - return _engine.frame_rate() * 60 * 5; -} - -void -Session::sync_order_keys () -{ - if (!Config->get_sync_all_route_ordering()) { - /* leave order keys as they are */ - return; - } - - boost::shared_ptr<RouteList> r = routes.reader (); - - for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - (*i)->sync_order_keys (); - } - - Route::SyncOrderKeys (); // EMIT SIGNAL -} - -void -Session::foreach_bundle (sigc::slot<void, boost::shared_ptr<Bundle> > sl) -{ - Glib::Mutex::Lock lm (bundle_lock); - for (BundleList::iterator i = _bundles.begin(); i != _bundles.end(); ++i) { - sl (*i); - } -} - diff --git a/libs/ardour/session_butler.cc b/libs/ardour/session_butler.cc deleted file mode 100644 index ec5de23caf..0000000000 --- a/libs/ardour/session_butler.cc +++ /dev/null @@ -1,471 +0,0 @@ -/* - Copyright (C) 1999-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. - -*/ - -#include <algorithm> -#include <string> -#include <cmath> -#include <cerrno> -#include <unistd.h> -#include <fcntl.h> -#include <poll.h> - -#include <glibmm/thread.h> - -#include <pbd/error.h> -#include <pbd/pthread_utils.h> -#include <pbd/stacktrace.h> - -#include <ardour/configuration.h> -#include <ardour/audioengine.h> -#include <ardour/session.h> -#include <ardour/audio_diskstream.h> -#include <ardour/crossfade.h> -#include <ardour/timestamps.h> - -#include "i18n.h" - -using namespace std; -using namespace ARDOUR; -using namespace PBD; - -static float _read_data_rate; -static float _write_data_rate; - -/* XXX put this in the right place */ - -static inline uint32_t next_power_of_two (uint32_t n) -{ - --n; - n |= n >> 16; - n |= n >> 8; - n |= n >> 4; - n |= n >> 2; - n |= n >> 1; - ++n; - return n; -} - -/*--------------------------------------------------------------------------- - BUTLER THREAD - ---------------------------------------------------------------------------*/ - -int -Session::start_butler_thread () -{ - /* size is in Samples, not bytes */ - audio_dstream_buffer_size = (uint32_t) floor (Config->get_audio_track_buffer_seconds() * (float) frame_rate()); - - /* size is in bytes - * XXX: Jack needs to tell us the MIDI buffer size - * (i.e. how many MIDI bytes we might see in a cycle) - */ - midi_dstream_buffer_size = (uint32_t) floor (Config->get_midi_track_buffer_seconds() * (float)frame_rate()); - - Crossfade::set_buffer_size (audio_dstream_buffer_size); - - butler_should_run = false; - - if (pipe (butler_request_pipe)) { - error << string_compose(_("Cannot create transport request signal pipe (%1)"), strerror (errno)) << endmsg; - return -1; - } - - if (fcntl (butler_request_pipe[0], F_SETFL, O_NONBLOCK)) { - error << string_compose(_("UI: cannot set O_NONBLOCK on butler request pipe (%1)"), strerror (errno)) << endmsg; - return -1; - } - - if (fcntl (butler_request_pipe[1], F_SETFL, O_NONBLOCK)) { - error << string_compose(_("UI: cannot set O_NONBLOCK on butler request pipe (%1)"), strerror (errno)) << endmsg; - return -1; - } - - if (pthread_create_and_store ("disk butler", &butler_thread, 0, _butler_thread_work, this)) { - error << _("Session: could not create butler thread") << endmsg; - return -1; - } - - // pthread_detach (butler_thread); - - return 0; -} - -void -Session::terminate_butler_thread () -{ - if (butler_thread) { - void* status; - char c = ButlerRequest::Quit; - ::write (butler_request_pipe[1], &c, 1); - pthread_join (butler_thread, &status); - } -} - -void -Session::schedule_butler_transport_work () -{ - g_atomic_int_inc (&butler_should_do_transport_work); - summon_butler (); -} - -void -Session::schedule_curve_reallocation () -{ - post_transport_work = PostTransportWork (post_transport_work | PostTransportCurveRealloc); - schedule_butler_transport_work (); -} - -void -Session::summon_butler () -{ - char c = ButlerRequest::Run; - ::write (butler_request_pipe[1], &c, 1); - // PBD::stacktrace (cerr); -} - -void -Session::stop_butler () -{ - Glib::Mutex::Lock lm (butler_request_lock); - char c = ButlerRequest::Pause; - ::write (butler_request_pipe[1], &c, 1); - butler_paused.wait(butler_request_lock); -} - -void -Session::wait_till_butler_finished () -{ - Glib::Mutex::Lock lm (butler_request_lock); - char c = ButlerRequest::Wake; - ::write (butler_request_pipe[1], &c, 1); - butler_paused.wait(butler_request_lock); -} - -void * -Session::_butler_thread_work (void* arg) -{ - PBD::ThreadCreated (pthread_self(), X_("Butler")); - return ((Session *) arg)->butler_thread_work (); - return 0; -} - -void * -Session::butler_thread_work () -{ - uint32_t err = 0; - int32_t bytes; - bool compute_io; - struct timeval begin, end; - struct pollfd pfd[1]; - bool disk_work_outstanding = false; - DiskstreamList::iterator i; - - while (true) { - pfd[0].fd = butler_request_pipe[0]; - pfd[0].events = POLLIN|POLLERR|POLLHUP; - - if (poll (pfd, 1, (disk_work_outstanding ? 0 : -1)) < 0) { - - if (errno == EINTR) { - continue; - } - - error << string_compose (_("poll on butler request pipe failed (%1)"), - strerror (errno)) - << endmsg; - break; - } - - if (pfd[0].revents & ~POLLIN) { - error << string_compose (_("Error on butler thread request pipe: fd=%1 err=%2"), pfd[0].fd, pfd[0].revents) << endmsg; - break; - } - - if (pfd[0].revents & POLLIN) { - - char req; - - /* empty the pipe of all current requests */ - - while (1) { - size_t nread = ::read (butler_request_pipe[0], &req, sizeof (req)); - if (nread == 1) { - - switch ((ButlerRequest::Type) req) { - - case ButlerRequest::Wake: - break; - - case ButlerRequest::Run: - butler_should_run = true; - break; - - case ButlerRequest::Pause: - butler_should_run = false; - break; - - case ButlerRequest::Quit: - pthread_exit_pbd (0); - /*NOTREACHED*/ - break; - - default: - break; - } - - } else if (nread == 0) { - break; - } else if (errno == EAGAIN) { - break; - } else { - fatal << _("Error reading from butler request pipe") << endmsg; - /*NOTREACHED*/ - } - } - } - - if (transport_work_requested()) { - butler_transport_work (); - } - - disk_work_outstanding = false; - bytes = 0; - compute_io = true; - - gettimeofday (&begin, 0); - - boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader (); - -// for (i = dsl->begin(); i != dsl->end(); ++i) { -// cerr << "BEFORE " << (*i)->name() << ": pb = " << (*i)->playback_buffer_load() << " cp = " << (*i)->capture_buffer_load() << endl; -// } - - for (i = dsl->begin(); !transport_work_requested() && butler_should_run && i != dsl->end(); ++i) { - - boost::shared_ptr<Diskstream> ds = *i; - - /* don't read inactive tracks */ - - IO* io = ds->io(); - - if (io && !io->active()) { - continue; - } - - switch (ds->do_refill ()) { - case 0: - bytes += ds->read_data_count(); - break; - case 1: - bytes += ds->read_data_count(); - disk_work_outstanding = true; - break; - - default: - compute_io = false; - error << string_compose(_("Butler read ahead failure on dstream %1"), (*i)->name()) << endmsg; - break; - } - - } - - if (i != dsl->end()) { - /* we didn't get to all the streams */ - disk_work_outstanding = true; - } - - if (!err && transport_work_requested()) { - continue; - } - - if (compute_io) { - gettimeofday (&end, 0); - - double b = begin.tv_sec + (begin.tv_usec/1000000.0); - double e = end.tv_sec + (end.tv_usec / 1000000.0); - - _read_data_rate = bytes / (e - b); - } - - bytes = 0; - compute_io = true; - gettimeofday (&begin, 0); - - for (i = dsl->begin(); !transport_work_requested() && butler_should_run && i != dsl->end(); ++i) { - // cerr << "write behind for " << (*i)->name () << endl; - - /* note that we still try to flush diskstreams attached to inactive routes - */ - - switch ((*i)->do_flush (Session::ButlerContext)) { - case 0: - bytes += (*i)->write_data_count(); - break; - case 1: - bytes += (*i)->write_data_count(); - disk_work_outstanding = true; - break; - - default: - err++; - compute_io = false; - error << string_compose(_("Butler write-behind failure on dstream %1"), (*i)->name()) << endmsg; - /* don't break - try to flush all streams in case they - are split across disks. - */ - } - } - - if (err && actively_recording()) { - /* stop the transport and try to catch as much possible - captured state as we can. - */ - request_stop (); - } - - if (i != dsl->end()) { - /* we didn't get to all the streams */ - disk_work_outstanding = true; - } - - if (!err && transport_work_requested()) { - continue; - } - - if (compute_io) { - gettimeofday (&end, 0); - - double b = begin.tv_sec + (begin.tv_usec/1000000.0); - double e = end.tv_sec + (end.tv_usec / 1000000.0); - - _write_data_rate = bytes / (e - b); - } - - if (!disk_work_outstanding) { - refresh_disk_space (); - } - - - { - Glib::Mutex::Lock lm (butler_request_lock); - - if (butler_should_run && (disk_work_outstanding || transport_work_requested())) { -// for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) { -// cerr << "AFTER " << (*i)->name() << ": pb = " << (*i)->playback_buffer_load() << " cp = " << (*i)->capture_buffer_load() << endl; -// } - - continue; - } - - butler_paused.signal(); - } - } - - pthread_exit_pbd (0); - /*NOTREACHED*/ - return (0); -} - - -void -Session::request_overwrite_buffer (Diskstream* stream) -{ - Event *ev = new Event (Event::Overwrite, Event::Add, Event::Immediate, 0, 0, 0.0); - ev->set_ptr (stream); - queue_event (ev); -} - -/** Process thread. */ -void -Session::overwrite_some_buffers (Diskstream* ds) -{ - if (actively_recording()) { - return; - } - - if (ds) { - - ds->set_pending_overwrite (true); - - } else { - - boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader(); - for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) { - (*i)->set_pending_overwrite (true); - } - } - - post_transport_work = PostTransportWork (post_transport_work | PostTransportOverWrite); - schedule_butler_transport_work (); -} - -float -Session::read_data_rate () const -{ - /* disk i/o in excess of 10000MB/sec indicate the buffer cache - in action. ignore it. - */ - return _read_data_rate > 10485760000.0f ? 0.0f : _read_data_rate; -} - -float -Session::write_data_rate () const -{ - /* disk i/o in excess of 10000MB/sec indicate the buffer cache - in action. ignore it. - */ - return _write_data_rate > 10485760000.0f ? 0.0f : _write_data_rate; -} - -uint32_t -Session::playback_load () -{ - return (uint32_t) g_atomic_int_get (&_playback_load); -} - -uint32_t -Session::capture_load () -{ - return (uint32_t) g_atomic_int_get (&_capture_load); -} - -uint32_t -Session::playback_load_min () -{ - return (uint32_t) g_atomic_int_get (&_playback_load_min); -} - -uint32_t -Session::capture_load_min () -{ - return (uint32_t) g_atomic_int_get (&_capture_load_min); -} - -void -Session::reset_capture_load_min () -{ - g_atomic_int_set (&_capture_load_min, 100); -} - - -void -Session::reset_playback_load_min () -{ - g_atomic_int_set (&_playback_load_min, 100); -} diff --git a/libs/ardour/session_click.cc b/libs/ardour/session_click.cc deleted file mode 100644 index 7161de6d78..0000000000 --- a/libs/ardour/session_click.cc +++ /dev/null @@ -1,223 +0,0 @@ -/* - Copyright (C) 20002 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include <list> -#include <cerrno> - -#include <ardour/ardour.h> -#include <ardour/session.h> -#include <ardour/tempo.h> -#include <ardour/io.h> -#include <ardour/buffer_set.h> - -#include <sndfile.h> - -#include "i18n.h" - -using namespace std; -using namespace ARDOUR; -using namespace PBD; - -Pool Session::Click::pool ("click", sizeof (Click), 128); - -void -Session::click (nframes_t start, nframes_t nframes, nframes_t offset) -{ - TempoMap::BBTPointList *points; - Sample *buf; - - if (_click_io == 0) { - return; - } - - Glib::RWLock::WriterLock clickm (click_lock, Glib::TRY_LOCK); - - if (!clickm.locked() || _transport_speed != 1.0 || !_clicking || click_data == 0) { - _click_io->silence (nframes, offset); - return; - } - - const nframes_t end = start + (nframes_t)floor(nframes * _transport_speed); - - BufferSet& bufs = get_scratch_buffers(ChanCount(DataType::AUDIO, 1)); - buf = bufs.get_audio(0).data(); - points = _tempo_map->get_points (start, end); - - if (points == 0) { - goto run_clicks; - } - - if (points->empty()) { - delete points; - goto run_clicks; - } - - for (TempoMap::BBTPointList::iterator i = points->begin(); i != points->end(); ++i) { - switch ((*i).type) { - case TempoMap::Beat: - if (click_emphasis_data == 0 || (click_emphasis_data && (*i).beat != 1)) { - clicks.push_back (new Click ((*i).frame, click_length, click_data)); - } - break; - - case TempoMap::Bar: - if (click_emphasis_data) { - clicks.push_back (new Click ((*i).frame, click_emphasis_length, click_emphasis_data)); - } - break; - } - } - - run_clicks: - memset (buf, 0, sizeof (Sample) * nframes); - - for (list<Click*>::iterator i = clicks.begin(); i != clicks.end(); ) { - - nframes_t copy; - nframes_t internal_offset; - Click *clk; - list<Click*>::iterator next; - - clk = *i; - next = i; - ++next; - - if (clk->start < start) { - internal_offset = 0; - } else { - internal_offset = clk->start - start; - } - - if (nframes < internal_offset) { - /* we've just located or something.. - effectively going backwards. - lets get the flock out of here */ - break; - } - - copy = min (clk->duration - clk->offset, nframes - internal_offset); - - memcpy (buf + internal_offset, &clk->data[clk->offset], copy * sizeof (Sample)); - - clk->offset += copy; - - if (clk->offset >= clk->duration) { - delete clk; - clicks.erase (i); - } - - - i = next; - } - - _click_io->deliver_output (bufs, start, end, nframes, offset); -} - -void -Session::setup_click_sounds (int which) -{ - SNDFILE *sndfile; - SF_INFO info; - - clear_clicks(); - - if ((which == 0 || which == 1)) { - - if (click_data && click_data != default_click) { - delete [] click_data; - click_data = 0; - } - - string path = Config->get_click_sound(); - - if (path.empty()) { - - click_data = const_cast<Sample*> (default_click); - click_length = default_click_length; - - } else { - - if ((sndfile = sf_open (path.c_str(), SFM_READ, &info)) == 0) { - char errbuf[256]; - sf_error_str (0, errbuf, sizeof (errbuf) - 1); - warning << string_compose (_("cannot open click soundfile %1 (%2)"), path, errbuf) << endmsg; - _clicking = false; - return; - } - - click_data = new Sample[info.frames]; - click_length = info.frames; - - if (sf_read_float (sndfile, click_data, info.frames) != info.frames) { - warning << _("cannot read data from click soundfile") << endmsg; - delete click_data; - click_data = 0; - _clicking = false; - } - - sf_close (sndfile); - - } - } - - if ((which == 0 || which == -1)) { - - if (click_emphasis_data && click_emphasis_data != default_click_emphasis) { - delete [] click_emphasis_data; - click_emphasis_data = 0; - } - - string path = Config->get_click_emphasis_sound(); - - if (path.empty()) { - click_emphasis_data = const_cast<Sample*> (default_click_emphasis); - click_emphasis_length = default_click_emphasis_length; - } else { - if ((sndfile = sf_open (path.c_str(), SFM_READ, &info)) == 0) { - char errbuf[256]; - sf_error_str (0, errbuf, sizeof (errbuf) - 1); - warning << string_compose (_("cannot open click emphasis soundfile %1 (%2)"), path, errbuf) << endmsg; - return; - } - - click_emphasis_data = new Sample[info.frames]; - click_emphasis_length = info.frames; - - if (sf_read_float (sndfile, click_emphasis_data, info.frames) != info.frames) { - warning << _("cannot read data from click emphasis soundfile") << endmsg; - delete click_emphasis_data; - click_emphasis_data = 0; - } - - sf_close (sndfile); - } - } -} - -void -Session::clear_clicks () -{ - Glib::RWLock::WriterLock lm (click_lock); - - for (Clicks::iterator i = clicks.begin(); i != clicks.end(); ++i) { - delete *i; - } - - clicks.clear (); -} diff --git a/libs/ardour/session_command.cc b/libs/ardour/session_command.cc deleted file mode 100644 index e8670e7199..0000000000 --- a/libs/ardour/session_command.cc +++ /dev/null @@ -1,544 +0,0 @@ -/* - 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. - -*/ - -#include <ardour/session.h> -#include <ardour/route.h> -#include <pbd/memento_command.h> -#include <ardour/diskstream.h> -#include <ardour/playlist.h> -#include <ardour/audioplaylist.h> -#include <ardour/audio_track.h> -#include <ardour/midi_playlist.h> -#include <ardour/midi_track.h> -#include <ardour/tempo.h> -#include <ardour/audiosource.h> -#include <ardour/audioregion.h> -#include <ardour/midi_source.h> -#include <ardour/midi_region.h> -#include <pbd/error.h> -#include <pbd/id.h> -#include <pbd/statefuldestructible.h> -#include <pbd/failed_constructor.h> - -using namespace PBD; -using namespace ARDOUR; - -#include "i18n.h" - -void Session::register_with_memento_command_factory(PBD::ID id, PBD::StatefulThingWithGoingAway *ptr) -{ - registry[id] = ptr; -} - -Command * -Session::memento_command_factory(XMLNode *n) -{ - PBD::ID id; - XMLNode *before = 0, *after = 0; - XMLNode *child = 0; - - /* get id */ - id = PBD::ID(n->property("obj_id")->value()); - - /* get before/after */ - - if (n->name() == "MementoCommand") { - before = new XMLNode(*n->children().front()); - after = new XMLNode(*n->children().back()); - child = before; - } else if (n->name() == "MementoUndoCommand") { - before = new XMLNode(*n->children().front()); - child = before; - } else if (n->name() == "MementoRedoCommand") { - after = new XMLNode(*n->children().front()); - child = after; - } else if (n->name() == "PlaylistCommand") { - before = new XMLNode(*n->children().front()); - after = new XMLNode(*n->children().back()); - child = before; - } - - if (!child) - { - error << _("Tried to reconstitute a MementoCommand with no contents, failing. id=") << id.to_s() << endmsg; - return 0; - } - - /* create command */ - string obj_T = n->property ("type_name")->value(); - if (obj_T == typeid (AudioRegion).name() || obj_T == typeid (MidiRegion).name() || obj_T == typeid (Region).name()) { - if (regions.count(id)) { - return new MementoCommand<Region>(*regions[id], before, after); - } - } else if (obj_T == typeid (AudioSource).name() || obj_T == typeid (MidiSource).name()) { - if (sources.count(id)) - return new MementoCommand<Source>(*sources[id], before, after); - } else if (obj_T == typeid (Location).name()) { - Location* loc = _locations.get_location_by_id(id); - if (loc) { - return new MementoCommand<Location>(*loc, before, after); - } - } else if (obj_T == typeid (Locations).name()) { - return new MementoCommand<Locations>(_locations, before, after); - } else if (obj_T == typeid (TempoMap).name()) { - return new MementoCommand<TempoMap>(*_tempo_map, before, after); - } else if (obj_T == typeid (Playlist).name() || obj_T == typeid (AudioPlaylist).name() || obj_T == typeid (MidiPlaylist).name()) { - if (boost::shared_ptr<Playlist> pl = playlist_by_name(child->property("name")->value())) { - return new MementoCommand<Playlist>(*(pl.get()), before, after); - } - } else if (obj_T == typeid (Route).name() || obj_T == typeid (AudioTrack).name() || obj_T == typeid(MidiTrack).name()) { - return new MementoCommand<Route>(*route_by_id(id), before, after); - } else if (obj_T == typeid (Curve).name() || obj_T == typeid (AutomationList).name()) { - if (automation_lists.count(id)) - return new MementoCommand<AutomationList>(*automation_lists[id], before, after); - } else if (registry.count(id)) { // For Editor and AutomationLine which are off-limits here - return new MementoCommand<PBD::StatefulThingWithGoingAway>(*registry[id], before, after); - } - - /* we failed */ - error << string_compose (_("could not reconstitute MementoCommand from XMLNode. object type = %1 id = %2"), obj_T, id.to_s()) << endmsg; - - return 0 ; -} - -Command * -Session::global_state_command_factory (const XMLNode& node) -{ - const XMLProperty* prop; - Command* command = 0; - - if ((prop = node.property ("type")) == 0) { - error << _("GlobalRouteStateCommand has no \"type\" node, ignoring") << endmsg; - return 0; - } - - try { - - if (prop->value() == "solo") { - command = new GlobalSoloStateCommand (*this, node); - } else if (prop->value() == "mute") { - command = new GlobalMuteStateCommand (*this, node); - } else if (prop->value() == "rec-enable") { - command = new GlobalRecordEnableStateCommand (*this, node); - } else if (prop->value() == "metering") { - command = new GlobalMeteringStateCommand (*this, node); - } else { - error << string_compose (_("unknown type of GlobalRouteStateCommand (%1), ignored"), prop->value()) << endmsg; - } - } - - catch (failed_constructor& err) { - return 0; - } - - return command; -} - -Session::GlobalRouteStateCommand::GlobalRouteStateCommand (Session& s, void* p) - : sess (s), src (p) -{ -} - -Session::GlobalRouteStateCommand::GlobalRouteStateCommand (Session& s, const XMLNode& node) - : sess (s), src (this) -{ - if (set_state (node)) { - throw failed_constructor (); - } -} - -int -Session::GlobalRouteStateCommand::set_state (const XMLNode& node) -{ - GlobalRouteBooleanState states; - XMLNodeList nlist; - const XMLProperty* prop; - XMLNode* child; - XMLNodeConstIterator niter; - int loop; - - before.clear (); - after.clear (); - - for (loop = 0; loop < 2; ++loop) { - - const char *str; - - if (loop) { - str = "after"; - } else { - str = "before"; - } - - if ((child = node.child (str)) == 0) { - warning << string_compose (_("global route state command has no \"%1\" node, ignoring entire command"), str) << endmsg; - return -1; - } - - nlist = child->children(); - - for (niter = nlist.begin(); niter != nlist.end(); ++niter) { - - RouteBooleanState rbs; - boost::shared_ptr<Route> route; - ID id; - - prop = (*niter)->property ("id"); - id = prop->value (); - - if ((route = sess.route_by_id (id)) == 0) { - warning << string_compose (_("cannot find track/bus \"%1\" while rebuilding a global route state command, ignored"), id.to_s()) << endmsg; - continue; - } - - rbs.first = boost::weak_ptr<Route> (route); - - prop = (*niter)->property ("yn"); - rbs.second = (prop->value() == "1"); - - if (loop) { - after.push_back (rbs); - } else { - before.push_back (rbs); - } - } - } - - return 0; -} - -XMLNode& -Session::GlobalRouteStateCommand::get_state () -{ - XMLNode* node = new XMLNode (X_("GlobalRouteStateCommand")); - XMLNode* nbefore = new XMLNode (X_("before")); - XMLNode* nafter = new XMLNode (X_("after")); - - for (Session::GlobalRouteBooleanState::iterator x = before.begin(); x != before.end(); ++x) { - XMLNode* child = new XMLNode ("s"); - boost::shared_ptr<Route> r = x->first.lock(); - - if (r) { - child->add_property (X_("id"), r->id().to_s()); - child->add_property (X_("yn"), (x->second ? "1" : "0")); - nbefore->add_child_nocopy (*child); - } - } - - for (Session::GlobalRouteBooleanState::iterator x = after.begin(); x != after.end(); ++x) { - XMLNode* child = new XMLNode ("s"); - boost::shared_ptr<Route> r = x->first.lock(); - - if (r) { - child->add_property (X_("id"), r->id().to_s()); - child->add_property (X_("yn"), (x->second ? "1" : "0")); - nafter->add_child_nocopy (*child); - } - } - - node->add_child_nocopy (*nbefore); - node->add_child_nocopy (*nafter); - - return *node; -} - -// solo - -Session::GlobalSoloStateCommand::GlobalSoloStateCommand(Session &sess, void *src) - : GlobalRouteStateCommand (sess, src) -{ - after = before = sess.get_global_route_boolean(&Route::soloed); -} - -Session::GlobalSoloStateCommand::GlobalSoloStateCommand (Session& sess, const XMLNode& node) - : Session::GlobalRouteStateCommand (sess, node) -{ -} - -void -Session::GlobalSoloStateCommand::mark() -{ - after = sess.get_global_route_boolean(&Route::soloed); -} - -void -Session::GlobalSoloStateCommand::operator()() -{ - sess.set_global_solo(after, src); -} - -void -Session::GlobalSoloStateCommand::undo() -{ - sess.set_global_solo(before, src); -} - -XMLNode& -Session::GlobalSoloStateCommand::get_state() -{ - XMLNode& node = GlobalRouteStateCommand::get_state(); - node.add_property ("type", "solo"); - return node; -} - -// mute -Session::GlobalMuteStateCommand::GlobalMuteStateCommand(Session &sess, void *src) - : GlobalRouteStateCommand (sess, src) -{ - after = before = sess.get_global_route_boolean(&Route::muted); -} - -Session::GlobalMuteStateCommand::GlobalMuteStateCommand (Session& sess, const XMLNode& node) - : Session::GlobalRouteStateCommand (sess, node) -{ -} - -void -Session::GlobalMuteStateCommand::mark() -{ - after = sess.get_global_route_boolean(&Route::muted); -} - -void -Session::GlobalMuteStateCommand::operator()() -{ - sess.set_global_mute(after, src); -} - -void -Session::GlobalMuteStateCommand::undo() -{ - sess.set_global_mute(before, src); -} - -XMLNode& -Session::GlobalMuteStateCommand::get_state() -{ - XMLNode& node = GlobalRouteStateCommand::get_state(); - node.add_property ("type", "mute"); - return node; -} - -// record enable -Session::GlobalRecordEnableStateCommand::GlobalRecordEnableStateCommand(Session &sess, void *src) - : GlobalRouteStateCommand (sess, src) -{ - after = before = sess.get_global_route_boolean(&Route::record_enabled); -} - -Session::GlobalRecordEnableStateCommand::GlobalRecordEnableStateCommand (Session& sess, const XMLNode& node) - : Session::GlobalRouteStateCommand (sess, node) -{ -} - -void -Session::GlobalRecordEnableStateCommand::mark() -{ - after = sess.get_global_route_boolean(&Route::record_enabled); -} - -void -Session::GlobalRecordEnableStateCommand::operator()() -{ - sess.set_global_record_enable(after, src); -} - -void -Session::GlobalRecordEnableStateCommand::undo() -{ - sess.set_global_record_enable(before, src); -} - -XMLNode& -Session::GlobalRecordEnableStateCommand::get_state() -{ - XMLNode& node = GlobalRouteStateCommand::get_state(); - node.add_property ("type", "rec-enable"); - return node; -} - -// metering -Session::GlobalMeteringStateCommand::GlobalMeteringStateCommand(Session &s, void *p) - : sess (s), src (p) -{ - after = before = sess.get_global_route_metering(); -} - -Session::GlobalMeteringStateCommand::GlobalMeteringStateCommand (Session& s, const XMLNode& node) - : sess (s), src (this) -{ - if (set_state (node)) { - throw failed_constructor(); - } -} - -void -Session::GlobalMeteringStateCommand::mark() -{ - after = sess.get_global_route_metering(); -} - -void -Session::GlobalMeteringStateCommand::operator()() -{ - sess.set_global_route_metering(after, src); -} - -void -Session::GlobalMeteringStateCommand::undo() -{ - sess.set_global_route_metering(before, src); -} - -XMLNode& -Session::GlobalMeteringStateCommand::get_state() -{ - XMLNode* node = new XMLNode (X_("GlobalRouteStateCommand")); - XMLNode* nbefore = new XMLNode (X_("before")); - XMLNode* nafter = new XMLNode (X_("after")); - - for (Session::GlobalRouteMeterState::iterator x = before.begin(); x != before.end(); ++x) { - XMLNode* child = new XMLNode ("s"); - boost::shared_ptr<Route> r = x->first.lock(); - - if (r) { - child->add_property (X_("id"), r->id().to_s()); - - const char* meterstr = 0; - - switch (x->second) { - case MeterInput: - meterstr = X_("input"); - break; - case MeterPreFader: - meterstr = X_("pre"); - break; - case MeterPostFader: - meterstr = X_("post"); - break; - default: - fatal << string_compose (_("programming error: %1") , "no meter state in Session::GlobalMeteringStateCommand::get_state") << endmsg; - } - - child->add_property (X_("meter"), meterstr); - nbefore->add_child_nocopy (*child); - } - } - - for (Session::GlobalRouteMeterState::iterator x = after.begin(); x != after.end(); ++x) { - XMLNode* child = new XMLNode ("s"); - boost::shared_ptr<Route> r = x->first.lock(); - - if (r) { - child->add_property (X_("id"), r->id().to_s()); - - const char* meterstr; - - switch (x->second) { - case MeterInput: - meterstr = X_("input"); - break; - case MeterPreFader: - meterstr = X_("pre"); - break; - case MeterPostFader: - meterstr = X_("post"); - break; - default: meterstr = ""; - } - - child->add_property (X_("meter"), meterstr); - nafter->add_child_nocopy (*child); - } - } - - node->add_child_nocopy (*nbefore); - node->add_child_nocopy (*nafter); - - node->add_property ("type", "metering"); - - return *node; -} - -int -Session::GlobalMeteringStateCommand::set_state (const XMLNode& node) -{ - GlobalRouteBooleanState states; - XMLNodeList nlist; - const XMLProperty* prop; - XMLNode* child; - XMLNodeConstIterator niter; - int loop; - - before.clear (); - after.clear (); - - for (loop = 0; loop < 2; ++loop) { - - const char *str; - - if (loop) { - str = "after"; - } else { - str = "before"; - } - - if ((child = node.child (str)) == 0) { - warning << string_compose (_("global route meter state command has no \"%1\" node, ignoring entire command"), str) << endmsg; - return -1; - } - - nlist = child->children(); - - for (niter = nlist.begin(); niter != nlist.end(); ++niter) { - - RouteMeterState rms; - boost::shared_ptr<Route> route; - ID id; - - prop = (*niter)->property ("id"); - id = prop->value (); - - if ((route = sess.route_by_id (id)) == 0) { - warning << string_compose (_("cannot find track/bus \"%1\" while rebuilding a global route state command, ignored"), id.to_s()) << endmsg; - continue; - } - - rms.first = boost::weak_ptr<Route> (route); - - prop = (*niter)->property ("meter"); - - if (prop->value() == X_("pre")) { - rms.second = MeterPreFader; - } else if (prop->value() == X_("post")) { - rms.second = MeterPostFader; - } else { - rms.second = MeterInput; - } - - if (loop) { - after.push_back (rms); - } else { - before.push_back (rms); - } - } - } - - return 0; -} diff --git a/libs/ardour/session_directory.cc b/libs/ardour/session_directory.cc deleted file mode 100644 index d5f2ddc1ba..0000000000 --- a/libs/ardour/session_directory.cc +++ /dev/null @@ -1,148 +0,0 @@ -/* - 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. -*/ - -#include <pbd/error.h> -#include <pbd/compose.h> -#include <pbd/filesystem.h> - -#include <ardour/directory_names.h> -#include <ardour/session_directory.h> -#include <ardour/utils.h> - -#include "i18n.h" - -namespace ARDOUR { - -using namespace PBD::sys; - -SessionDirectory::SessionDirectory (const path& session_path) - : m_root_path(session_path) -{ - -} - -bool -SessionDirectory::create () -{ - bool is_new = false; - - vector<path> sub_dirs = sub_directories (); - for (vector<path>::const_iterator i = sub_dirs.begin(); i != sub_dirs.end(); ++i) - { - try - { - if(create_directories(*i)) is_new = true; - } - catch (PBD::sys::filesystem_error& ex) - { - // log the error - PBD::error << string_compose(_("Cannot create Session directory at path %1 Error: %2"), (*i).to_string(), ex.what()) << endmsg; - - // and rethrow - throw ex; - } - } - - return is_new; -} - -bool -SessionDirectory::is_valid () const -{ - if (!is_directory (m_root_path)) return false; - - vector<path> sub_dirs = sub_directories (); - - for (vector<path>::iterator i = sub_dirs.begin(); i != sub_dirs.end(); ++i) { - if (!is_directory (*i)) { - PBD::warning << string_compose(_("Session subdirectory does not exist at path %1"), (*i).to_string()) << endmsg; - return false; - } - } - return true; -} - -const path -SessionDirectory::old_sound_path () const -{ - return m_root_path / old_sound_dir_name; -} - -const path -SessionDirectory::sources_root () const -{ - const string legalized_root(legalize_for_path(m_root_path.leaf())); - - return m_root_path / interchange_dir_name / legalized_root; -} - -const path -SessionDirectory::sound_path () const -{ - if(is_directory (old_sound_path ())) return old_sound_path(); - - // the new style sound directory - return sources_root() / sound_dir_name; -} - -const path -SessionDirectory::midi_path () const -{ - return sources_root() / midi_dir_name; -} - -const path -SessionDirectory::peak_path () const -{ - return m_root_path / peak_dir_name; -} - -const path -SessionDirectory::dead_sound_path () const -{ - return m_root_path / dead_sound_dir_name; -} - -const path -SessionDirectory::dead_midi_path () const -{ - return m_root_path / dead_midi_dir_name; -} - -const path -SessionDirectory::export_path () const -{ - return m_root_path / export_dir_name; -} - -const vector<path> -SessionDirectory::sub_directories () const -{ - vector<path> tmp_paths; - - tmp_paths.push_back ( sound_path () ); - tmp_paths.push_back ( midi_path () ); - tmp_paths.push_back ( peak_path () ); - tmp_paths.push_back ( dead_sound_path () ); - tmp_paths.push_back ( dead_midi_path () ); - tmp_paths.push_back ( export_path () ); - - return tmp_paths; -} - -} // namespace ARDOUR diff --git a/libs/ardour/session_events.cc b/libs/ardour/session_events.cc deleted file mode 100644 index 5fc8cd7535..0000000000 --- a/libs/ardour/session_events.cc +++ /dev/null @@ -1,453 +0,0 @@ -/* - Copyright (C) 1999-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. - -*/ - -#include <cmath> -#include <unistd.h> - -#include <ardour/timestamps.h> - -#include <pbd/error.h> -#include <glibmm/thread.h> - -#include <ardour/ardour.h> -#include <ardour/session.h> -#include <ardour/audio_diskstream.h> - -#include "i18n.h" - -using namespace ARDOUR; -using namespace PBD; - -MultiAllocSingleReleasePool Session::Event::pool ("event", sizeof (Session::Event), 512); - -static const char* event_names[] = { - "SetTransportSpeed", - "SetDiskstreamSpeed", - "Locate", - "LocateRoll", - "LocateRollLocate", - "SetLoop", - "PunchIn", - "PunchOut", - "RangeStop", - "RangeLocate", - "Overwrite", - "SetSlaveSource", - "Audition", - "InputConfigurationChange", - "SetAudioRange", - "SetMusicRange", - "SetPlayRange", - "StopOnce", - "AutoLoop" -}; - -void -Session::add_event (nframes_t frame, Event::Type type, nframes_t target_frame) -{ - Event* ev = new Event (type, Event::Add, frame, target_frame, 0); - queue_event (ev); -} - -void -Session::remove_event (nframes_t frame, Event::Type type) -{ - Event* ev = new Event (type, Event::Remove, frame, 0, 0); - queue_event (ev); -} - -void -Session::replace_event (Event::Type type, nframes_t frame, nframes_t target) -{ - Event* ev = new Event (type, Event::Replace, frame, target, 0); - queue_event (ev); -} - -void -Session::clear_events (Event::Type type) -{ - Event* ev = new Event (type, Event::Clear, 0, 0, 0); - queue_event (ev); -} - - -void -Session::dump_events () const -{ - cerr << "EVENT DUMP" << endl; - for (Events::const_iterator i = events.begin(); i != events.end(); ++i) { - cerr << "\tat " << (*i)->action_frame << ' ' << (*i)->type << " target = " << (*i)->target_frame << endl; - } - cerr << "Next event: "; - - if ((Events::const_iterator) next_event == events.end()) { - cerr << "none" << endl; - } else { - cerr << "at " << (*next_event)->action_frame << ' ' - << (*next_event)->type << " target = " - << (*next_event)->target_frame << endl; - } - cerr << "Immediate events pending:\n"; - for (Events::const_iterator i = immediate_events.begin(); i != immediate_events.end(); ++i) { - cerr << "\tat " << (*i)->action_frame << ' ' << (*i)->type << " target = " << (*i)->target_frame << endl; - } - cerr << "END EVENT_DUMP" << endl; -} - -void -Session::queue_event (Event* ev) -{ - if (_state_of_the_state & Loading) { - merge_event (ev); - } else { - pending_events.write (&ev, 1); - } -} - -void -Session::merge_event (Event* ev) -{ - switch (ev->action) { - case Event::Remove: - _remove_event (ev); - delete ev; - return; - - case Event::Replace: - _replace_event (ev); - return; - - case Event::Clear: - _clear_event_type (ev->type); - delete ev; - return; - - case Event::Add: - break; - } - - /* try to handle immediate events right here */ - - if (ev->action_frame == 0) { - process_event (ev); - return; - } - - switch (ev->type) { - case Event::AutoLoop: - case Event::StopOnce: - _clear_event_type (ev->type); - break; - - default: - for (Events::iterator i = events.begin(); i != events.end(); ++i) { - if ((*i)->type == ev->type && (*i)->action_frame == ev->action_frame) { - error << string_compose(_("Session: cannot have two events of type %1 at the same frame (%2)."), - event_names[ev->type], ev->action_frame) << endmsg; - return; - } - } - } - - events.insert (events.begin(), ev); - events.sort (Event::compare); - next_event = events.begin(); - set_next_event (); -} - -/** @return true when @a ev is deleted. */ -bool -Session::_replace_event (Event* ev) -{ - bool ret = false; - Events::iterator i; - - /* private, used only for events that can only exist once in the queue */ - - for (i = events.begin(); i != events.end(); ++i) { - if ((*i)->type == ev->type) { - (*i)->action_frame = ev->action_frame; - (*i)->target_frame = ev->target_frame; - if ((*i) == ev) { - ret = true; - } - delete ev; - break; - } - } - - if (i == events.end()) { - events.insert (events.begin(), ev); - } - - events.sort (Event::compare); - next_event = events.end(); - set_next_event (); - - return ret; -} - -/** @return true when @a ev is deleted. */ -bool -Session::_remove_event (Session::Event* ev) -{ - bool ret = false; - Events::iterator i; - - for (i = events.begin(); i != events.end(); ++i) { - if ((*i)->type == ev->type && (*i)->action_frame == ev->action_frame) { - if ((*i) == ev) { - ret = true; - } - - delete *i; - if (i == next_event) { - ++next_event; - } - events.erase (i); - break; - } - } - - if (i != events.end()) { - set_next_event (); - } - - return ret; -} - -void -Session::_clear_event_type (Event::Type type) -{ - Events::iterator i, tmp; - - for (i = events.begin(); i != events.end(); ) { - - tmp = i; - ++tmp; - - if ((*i)->type == type) { - delete *i; - if (i == next_event) { - ++next_event; - } - events.erase (i); - } - - i = tmp; - } - - for (i = immediate_events.begin(); i != immediate_events.end(); ) { - - tmp = i; - ++tmp; - - if ((*i)->type == type) { - delete *i; - immediate_events.erase (i); - } - - i = tmp; - } - - set_next_event (); -} - -void -Session::set_next_event () -{ - if (events.empty()) { - next_event = events.end(); - return; - } - - if (next_event == events.end()) { - next_event = events.begin(); - } - - if ((*next_event)->action_frame > _transport_frame) { - next_event = events.begin(); - } - - for (; next_event != events.end(); ++next_event) { - if ((*next_event)->action_frame >= _transport_frame) { - break; - } - } -} - -void -Session::process_event (Event* ev) -{ - bool remove = true; - bool del = true; - - /* if we're in the middle of a state change (i.e. waiting - for the butler thread to complete the non-realtime - part of the change), we'll just have to queue this - event for a time when the change is complete. - */ - - if (non_realtime_work_pending()) { - - /* except locates, which we have the capability to handle */ - - if (ev->type != Event::Locate) { - immediate_events.insert (immediate_events.end(), ev); - _remove_event (ev); - return; - } - } - - //printf("Processing event: %s\n", event_names[ev->type]); - - switch (ev->type) { - case Event::SetLoop: - set_play_loop (ev->yes_or_no); - break; - - case Event::AutoLoop: - if (play_loop) { - start_locate (ev->target_frame, true, false, Config->get_seamless_loop()); - } - remove = false; - del = false; - break; - - case Event::Locate: - if (ev->yes_or_no) { - // cerr << "forced locate to " << ev->target_frame << endl; - locate (ev->target_frame, false, true, false); - } else { - // cerr << "soft locate to " << ev->target_frame << endl; - start_locate (ev->target_frame, false, true, false); - } - _send_smpte_update = true; - break; - - case Event::LocateRoll: - if (ev->yes_or_no) { - // cerr << "forced locate to+roll " << ev->target_frame << endl; - locate (ev->target_frame, true, true, false); - } else { - // cerr << "soft locate to+roll " << ev->target_frame << endl; - start_locate (ev->target_frame, true, true, false); - } - _send_smpte_update = true; - break; - - case Event::LocateRollLocate: - // locate is handled by ::request_roll_at_and_return() - _requested_return_frame = ev->target_frame; - cerr << "Set RRF " << ev->target_frame << endl; - request_locate (ev->target2_frame, true); - break; - - - case Event::SetTransportSpeed: - set_transport_speed (ev->speed, ev->yes_or_no); - break; - - case Event::PunchIn: - // cerr << "PunchIN at " << transport_frame() << endl; - if (Config->get_punch_in() && record_status() == Enabled) { - enable_record (); - } - remove = false; - del = false; - break; - - case Event::PunchOut: - // cerr << "PunchOUT at " << transport_frame() << endl; - if (Config->get_punch_out()) { - step_back_from_record (); - } - remove = false; - del = false; - break; - - case Event::StopOnce: - if (!non_realtime_work_pending()) { - stop_transport (ev->yes_or_no); - _clear_event_type (Event::StopOnce); - } - remove = false; - del = false; - break; - - case Event::RangeStop: - if (!non_realtime_work_pending()) { - stop_transport (ev->yes_or_no); - } - remove = false; - del = false; - break; - - case Event::RangeLocate: - start_locate (ev->target_frame, true, true, false); - remove = false; - del = false; - break; - - case Event::Overwrite: - overwrite_some_buffers (static_cast<Diskstream*>(ev->ptr)); - break; - - case Event::SetDiskstreamSpeed: - set_diskstream_speed (static_cast<Diskstream*> (ev->ptr), ev->speed); - break; - - case Event::SetSlaveSource: - set_slave_source (ev->slave); - break; - - case Event::Audition: - set_audition (ev->region); - // drop reference to region - ev->region.reset (); - break; - - case Event::InputConfigurationChange: - post_transport_work = PostTransportWork (post_transport_work | PostTransportInputChange); - schedule_butler_transport_work (); - break; - - case Event::SetAudioRange: - current_audio_range = ev->audio_range; - setup_auto_play (); - break; - - case Event::SetPlayRange: - set_play_range (ev->yes_or_no); - break; - - default: - fatal << string_compose(_("Programming error: illegal event type in process_event (%1)"), ev->type) << endmsg; - /*NOTREACHED*/ - break; - }; - - if (remove) { - del = del && !_remove_event (ev); - } - - if (del) { - delete ev; - } -} diff --git a/libs/ardour/session_export.cc b/libs/ardour/session_export.cc deleted file mode 100644 index 49b6d9b150..0000000000 --- a/libs/ardour/session_export.cc +++ /dev/null @@ -1,652 +0,0 @@ -/* - Copyright (C) 1999-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. - -*/ - -/* see gdither.cc for why we have to do this */ - -#define _ISOC9X_SOURCE 1 -#define _ISOC99_SOURCE 1 -#include <cmath> -#undef _ISOC99_SOURCE -#undef _ISOC9X_SOURCE -#undef __USE_SVID -#define __USE_SVID 1 -#include <cstdlib> -#undef __USE_SVID - -#include <unistd.h> -#include <inttypes.h> -#include <float.h> - -#include <sigc++/bind.h> - -#include <pbd/error.h> -#include <glibmm/thread.h> - -#include <ardour/gdither.h> -#include <ardour/timestamps.h> -#include <ardour/ardour.h> -#include <ardour/session.h> -#include <ardour/export.h> -#include <ardour/sndfile_helpers.h> -#include <ardour/port.h> -#include <ardour/audio_port.h> -#include <ardour/audioengine.h> -#include <ardour/audio_diskstream.h> -#include <ardour/panner.h> - -#include "i18n.h" - -using namespace std; -using namespace ARDOUR; -using namespace PBD; - -static int -convert_spec_to_info (ExportSpecification& spec, SF_INFO& sfinfo) -{ - if (spec.path.length() == 0) { - error << _("Export: no output file specified") << endmsg; - return -1; - } - - /* XXX add checks that the directory path exists, and also - check if we are overwriting an existing file... - */ - - sfinfo.format = spec.format; - sfinfo.samplerate = spec.sample_rate; - sfinfo.frames = spec.end_frame - spec.start_frame + 1; - sfinfo.channels = min (spec.channels, 2U); - - return 0; -} - -ExportSpecification::ExportSpecification () -{ - init (); -} - -ExportSpecification::~ExportSpecification () -{ - clear (); -} - -void -ExportSpecification::init () -{ - src_state = 0; - pos = 0; - total_frames = 0; - out = 0; - channels = 0; - running = false; - stop = false; - progress = 0.0; - status = 0; - dither = 0; - start_frame = 0; - end_frame = 0; - dataF = 0; - dataF2 = 0; - leftoverF = 0; - max_leftover_frames = 0; - leftover_frames = 0; - output_data = 0; - out_samples_max = 0; - data_width = 0; - do_freewheel = false; -} - -void -ExportSpecification::clear () -{ - if (out) { - sf_close (out); - out = 0; - } - - if (src_state) { - src_delete (src_state); - src_state = 0; - } - - if (dither) { - gdither_free (dither); - dither = 0; - } - - if (output_data) { - free (output_data); - output_data = 0; - } - if (dataF) { - delete [] dataF; - dataF = 0; - } - if (dataF2) { - delete [] dataF2; - dataF2 = 0; - } - if (leftoverF) { - delete [] leftoverF; - leftoverF = 0; - } - - freewheel_connection.disconnect (); - - init (); -} - -int -ExportSpecification::prepare (nframes_t blocksize, nframes_t frate) -{ - char errbuf[256]; - GDitherSize dither_size; - - frame_rate = frate; - - if (channels == 0) { - error << _("illegal channel count in export specification") << endmsg; - return -1; - } - - if (start_frame >= end_frame) { - error << _("illegal frame range in export specification") << endmsg; - return -1; - } - - if ((data_width = sndfile_data_width(format)) == 0) { - error << _("Bad data width size. Report me!") << endmsg; - return -1; - } - - switch (data_width) { - case 8: - dither_size = GDither8bit; - break; - - case 16: - dither_size = GDither16bit; - break; - - case 24: - dither_size = GDither32bit; - break; - - default: - dither_size = GDitherFloat; - break; - } - - if (convert_spec_to_info (*this, sfinfo)) { - return -1; - } - - /* XXX make sure we have enough disk space for the output */ - - if ((out = sf_open (path.c_str(), SFM_WRITE, &sfinfo)) == 0) { - sf_error_str (0, errbuf, sizeof (errbuf) - 1); - error << string_compose(_("Export: cannot open output file \"%1\" (%2)"), path, errbuf) << endmsg; - return -1; - } - - dataF = new float[blocksize * channels]; - - if (sample_rate != frame_rate) { - int err; - - if ((src_state = src_new (src_quality, channels, &err)) == 0) { - error << string_compose (_("cannot initialize sample rate conversion: %1"), src_strerror (err)) << endmsg; - return -1; - } - - src_data.src_ratio = sample_rate / (double) frame_rate; - out_samples_max = (nframes_t) ceil (blocksize * src_data.src_ratio * channels); - dataF2 = new float[out_samples_max]; - - max_leftover_frames = 4 * blocksize; - leftoverF = new float[max_leftover_frames * channels]; - leftover_frames = 0; - - } else { - out_samples_max = blocksize * channels; - } - - dither = gdither_new (dither_type, channels, dither_size, data_width); - - /* allocate buffers where dithering and output will occur */ - - switch (data_width) { - case 8: - sample_bytes = 1; - break; - - case 16: - sample_bytes = 2; - break; - - case 24: - case 32: - sample_bytes = 4; - break; - - default: - sample_bytes = 0; // float format - break; - } - - if (sample_bytes) { - output_data = (void*) malloc (sample_bytes * out_samples_max); - } - - return 0; -} - -int -ExportSpecification::process (nframes_t nframes) -{ - float* float_buffer = 0; - uint32_t chn; - uint32_t x; - uint32_t i; - sf_count_t written; - char errbuf[256]; - nframes_t to_write = 0; - int cnt = 0; - - do { - - /* now do sample rate conversion */ - - if (sample_rate != frame_rate) { - - int err; - - src_data.output_frames = out_samples_max / channels; - src_data.end_of_input = ((pos + nframes) >= end_frame); - src_data.data_out = dataF2; - - if (leftover_frames > 0) { - - /* input data will be in leftoverF rather than dataF */ - - src_data.data_in = leftoverF; - - if (cnt == 0) { - - /* first time, append new data from dataF into the leftoverF buffer */ - - memcpy (leftoverF + (leftover_frames * channels), dataF, nframes * channels * sizeof(float)); - src_data.input_frames = nframes + leftover_frames; - } else { - - /* otherwise, just use whatever is still left in leftoverF; the contents - were adjusted using memmove() right after the last SRC call (see - below) - */ - - src_data.input_frames = leftover_frames; - } - - } else { - - src_data.data_in = dataF; - src_data.input_frames = nframes; - - } - - ++cnt; - - if ((err = src_process (src_state, &src_data)) != 0) { - error << string_compose (_("an error occured during sample rate conversion: %1"), - src_strerror (err)) - << endmsg; - return -1; - } - - to_write = src_data.output_frames_gen; - leftover_frames = src_data.input_frames - src_data.input_frames_used; - - if (leftover_frames > 0) { - if (leftover_frames > max_leftover_frames) { - error << _("warning, leftover frames overflowed, glitches might occur in output") << endmsg; - leftover_frames = max_leftover_frames; - } - memmove (leftoverF, (char *) (src_data.data_in + (src_data.input_frames_used * channels)), - leftover_frames * channels * sizeof(float)); - } - - float_buffer = dataF2; - - } else { - - /* no SRC, keep it simple */ - - to_write = nframes; - leftover_frames = 0; - float_buffer = dataF; - } - - if (output_data) { - memset (output_data, 0, sample_bytes * to_write * channels); - } - - switch (data_width) { - case 8: - case 16: - case 24: - for (chn = 0; chn < channels; ++chn) { - gdither_runf (dither, chn, to_write, float_buffer, output_data); - } - break; - - case 32: - for (chn = 0; chn < channels; ++chn) { - - int *ob = (int *) output_data; - const double int_max = (float) INT_MAX; - const double int_min = (float) INT_MIN; - - for (x = 0; x < to_write; ++x) { - i = chn + (x * channels); - - if (float_buffer[i] > 1.0f) { - ob[i] = INT_MAX; - } else if (float_buffer[i] < -1.0f) { - ob[i] = INT_MIN; - } else { - if (float_buffer[i] >= 0.0f) { - ob[i] = lrintf (int_max * float_buffer[i]); - } else { - ob[i] = - lrintf (int_min * float_buffer[i]); - } - } - } - } - break; - - default: - for (x = 0; x < to_write * channels; ++x) { - if (float_buffer[x] > 1.0f) { - float_buffer[x] = 1.0f; - } else if (float_buffer[x] < -1.0f) { - float_buffer[x] = -1.0f; - } - } - break; - } - - /* and export to disk */ - - switch (data_width) { - case 8: - /* XXXX no way to deliver 8 bit audio to libsndfile */ - written = to_write; - break; - - case 16: - written = sf_writef_short (out, (short*) output_data, to_write); - break; - - case 24: - case 32: - written = sf_writef_int (out, (int*) output_data, to_write); - break; - - default: - written = sf_writef_float (out, float_buffer, to_write); - break; - } - - if ((nframes_t) written != to_write) { - sf_error_str (out, errbuf, sizeof (errbuf) - 1); - error << string_compose(_("Export: could not write data to output file (%1)"), errbuf) << endmsg; - return -1; - } - - - } while (leftover_frames >= nframes); - - return 0; -} - -int -Session::start_export (ExportSpecification& spec) -{ - if (!_engine.connected()) { - return -1; - } - - if (spec.prepare (current_block_size, frame_rate())) { - return -1; - } - - spec.pos = spec.start_frame; - spec.end_frame = spec.end_frame; - spec.total_frames = spec.end_frame - spec.start_frame; - spec.running = true; - spec.do_freewheel = false; /* force a call to ::prepare_to_export() before proceeding to normal operation */ - - spec.freewheel_connection = _engine.Freewheel.connect (sigc::bind (mem_fun (*this, &Session::process_export), &spec)); - - return _engine.freewheel (true); -} - -int -Session::stop_export (ExportSpecification& spec) -{ - /* don't stop freewheeling but do stop paying attention to it for now */ - - spec.freewheel_connection.disconnect (); - spec.clear (); /* resets running/stop etc */ - - return 0; -} - -int -Session::prepare_to_export (ExportSpecification& spec) -{ - int ret = -1; - - wait_till_butler_finished (); - - /* take everyone out of awrite to avoid disasters */ - - { - boost::shared_ptr<RouteList> r = routes.reader (); - - for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - (*i)->protect_automation (); - } - } - - /* get everyone to the right position */ - - { - boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader(); - - for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) { - if ((*i)-> seek (spec.start_frame, true)) { - error << string_compose (_("%1: cannot seek to %2 for export"), - (*i)->name(), spec.start_frame) - << endmsg; - goto out; - } - } - } - - /* make sure we are actually rolling */ - - if (get_record_enabled()) { - disable_record (false); - } - - _exporting = true; - - /* no slaving */ - - post_export_slave = Config->get_slave_source (); - post_export_position = _transport_frame; - - Config->set_slave_source (None); - - /* get transport ready */ - - set_transport_speed (1.0, false); - butler_transport_work (); - g_atomic_int_set (&butler_should_do_transport_work, 0); - post_transport (); - - /* we are ready to go ... */ - - ret = 0; - - out: - return ret; -} - -int -Session::process_export (nframes_t nframes, ExportSpecification* spec) -{ - uint32_t chn; - uint32_t x; - int ret = -1; - nframes_t this_nframes; - - /* This is not required to be RT-safe because we are running while freewheeling */ - - if (spec->do_freewheel == false) { - - /* first time in export function: get set up */ - - if (prepare_to_export (*spec)) { - spec->running = false; - spec->status = -1; - return -1; - } - - spec->do_freewheel = true; - } - - if (!_exporting) { - /* finished, but still freewheeling */ - process_without_events (nframes); - return 0; - } - - if (!spec->running || spec->stop || (this_nframes = min ((spec->end_frame - spec->pos), nframes)) == 0) { - process_without_events (nframes); - return stop_export (*spec); - } - - /* make sure we've caught up with disk i/o, since - we're running faster than realtime c/o JACK. - */ - - wait_till_butler_finished (); - - /* do the usual stuff */ - - process_without_events (nframes); - - /* and now export the results */ - - nframes = this_nframes; - - memset (spec->dataF, 0, sizeof (spec->dataF[0]) * nframes * spec->channels); - - /* foreach output channel ... */ - - for (chn = 0; chn < spec->channels; ++chn) { - - ExportPortMap::iterator mi = spec->port_map.find (chn); - - if (mi == spec->port_map.end()) { - /* no ports exported to this channel */ - continue; - } - - vector<PortChannelPair>& mapped_ports ((*mi).second); - - for (vector<PortChannelPair>::iterator t = mapped_ports.begin(); t != mapped_ports.end(); ++t) { - - /* OK, this port's output is supposed to appear on this channel - */ - - AudioPort* const aport = dynamic_cast<AudioPort*>((*t).first); - MidiPort* const mport = dynamic_cast<MidiPort*>((*t).first); - if (aport != 0) { - Sample* port_buffer = aport->get_audio_buffer().data(); - - /* now interleave the data from the channel into the float buffer */ - - for (x = 0; x < nframes; ++x) { - spec->dataF[chn+(x*spec->channels)] += (float) port_buffer[x]; - } - } else if (mport != 0) { - cerr << "EXPORT MIDI PORT" << endl; - } - } - } - - if (spec->process (nframes)) { - goto out; - } - - spec->pos += nframes; - spec->progress = 1.0 - (((float) spec->end_frame - spec->pos) / spec->total_frames); - - /* and we're good to go */ - - ret = 0; - - out: - if (ret) { - sf_close (spec->out); - spec->out = 0; - unlink (spec->path.c_str()); - spec->running = false; - spec->status = ret; - _exporting = false; - } - - return ret; -} - -void -Session::finalize_audio_export () -{ - _engine.freewheel (false); - _exporting = false; - - /* can't use stop_transport() here because we need - an immediate halt and don't require all the declick - stuff that stop_transport() implements. - */ - - realtime_stop (true); - schedule_butler_transport_work (); - - /* restart slaving */ - - if (post_export_slave != None) { - Config->set_slave_source (post_export_slave); - } else { - locate (post_export_position, false, false, false); - } -} diff --git a/libs/ardour/session_feedback.cc b/libs/ardour/session_feedback.cc deleted file mode 100644 index 2bb9886f50..0000000000 --- a/libs/ardour/session_feedback.cc +++ /dev/null @@ -1,49 +0,0 @@ -/* - 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. - -*/ - -#include <string> -#include <cmath> -#include <cerrno> -#include <unistd.h> -#include <fcntl.h> -#include <poll.h> - -#include <midi++/types.h> -#include <midi++/port.h> -#include <midi++/manager.h> - -#include <glibmm/thread.h> - -#include <pbd/pthread_utils.h> - -#include <ardour/configuration.h> -#include <ardour/audioengine.h> -#include <ardour/session.h> -#include <ardour/audio_track.h> -#include <ardour/audio_diskstream.h> -#include <control_protocol/control_protocol.h> - -#include "i18n.h" - -using namespace std; -using namespace ARDOUR; -//using namespace sigc; - - - diff --git a/libs/ardour/session_midi.cc b/libs/ardour/session_midi.cc deleted file mode 100644 index b4938636a2..0000000000 --- a/libs/ardour/session_midi.cc +++ /dev/null @@ -1,1211 +0,0 @@ - -/* - Copyright (C) 1999-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. - -*/ - -#include <string> -#include <cmath> -#include <cerrno> -#include <cassert> -#include <unistd.h> -#include <fcntl.h> -#include <poll.h> - -#include <boost/shared_ptr.hpp> - -#include <midi++/mmc.h> -#include <midi++/port.h> -#include <midi++/manager.h> -#include <pbd/error.h> -#include <glibmm/thread.h> -#include <pbd/pthread_utils.h> - -#include <ardour/configuration.h> -#include <ardour/audioengine.h> -#include <ardour/session.h> -#include <ardour/audio_track.h> -#include <ardour/midi_track.h> -#include <ardour/audio_diskstream.h> -#include <ardour/slave.h> -#include <ardour/cycles.h> -#include <ardour/smpte.h> - -#include "i18n.h" - -using namespace std; -using namespace ARDOUR; -using namespace PBD; -using namespace MIDI; - -MachineControl::CommandSignature MMC_CommandSignature; -MachineControl::ResponseSignature MMC_ResponseSignature; - - -void -Session::midi_panic() -{ - { - boost::shared_ptr<RouteList> r = routes.reader (); - - for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - MidiTrack *track = dynamic_cast<MidiTrack*>((*i).get()); - if (track != 0) { - track->midi_panic(); - } - } - } -} - -int -Session::use_config_midi_ports () -{ - string port_name; - - if (default_mmc_port) { - set_mmc_port (default_mmc_port->name()); - } else { - set_mmc_port (""); - } - - if (default_mtc_port) { - set_mtc_port (default_mtc_port->name()); - } else { - set_mtc_port (""); - } - - if (default_midi_port) { - set_midi_port (default_midi_port->name()); - } else { - set_midi_port (""); - } - - return 0; -} - - -/*********************************************************************** - MTC, MMC, etc. -**********************************************************************/ - -int -Session::set_mtc_port (string port_tag) -{ - MTC_Slave *ms; - - if (port_tag.length() == 0) { - - if (_slave && ((ms = dynamic_cast<MTC_Slave*> (_slave)) != 0)) { - error << _("Ardour is slaved to MTC - port cannot be reset") << endmsg; - return -1; - } - - if (_mtc_port == 0) { - return 0; - } - - _mtc_port = 0; - goto out; - } - - MIDI::Port* port; - - if ((port = MIDI::Manager::instance()->port (port_tag)) == 0) { - error << string_compose (_("unknown port %1 requested for MTC"), port_tag) << endl; - return -1; - } - - _mtc_port = port; - - if (_slave && ((ms = dynamic_cast<MTC_Slave*> (_slave)) != 0)) { - ms->rebind (*port); - } - - Config->set_mtc_port_name (port_tag); - - out: - MTC_PortChanged(); /* EMIT SIGNAL */ - change_midi_ports (); - set_dirty(); - return 0; -} - -void -Session::set_mmc_receive_device_id (uint32_t device_id) -{ - if (mmc) { - mmc->set_receive_device_id (device_id); - } -} - -void -Session::set_mmc_send_device_id (uint32_t device_id) -{ - if (mmc) { - mmc->set_send_device_id (device_id); - } -} - -int -Session::set_mmc_port (string port_tag) -{ - MIDI::byte old_recv_device_id = 0; - MIDI::byte old_send_device_id = 0; - bool reset_id = false; - - if (port_tag.length() == 0) { - if (_mmc_port == 0) { - return 0; - } - _mmc_port = 0; - goto out; - } - - MIDI::Port* port; - - if ((port = MIDI::Manager::instance()->port (port_tag)) == 0) { - return -1; - } - - _mmc_port = port; - - if (mmc) { - old_recv_device_id = mmc->receive_device_id(); - old_recv_device_id = mmc->send_device_id(); - reset_id = true; - delete mmc; - } - - mmc = new MIDI::MachineControl (*_mmc_port, 1.0, - MMC_CommandSignature, - MMC_ResponseSignature); - - if (reset_id) { - mmc->set_receive_device_id (old_recv_device_id); - mmc->set_send_device_id (old_send_device_id); - } - - mmc->Play.connect - (mem_fun (*this, &Session::mmc_deferred_play)); - mmc->DeferredPlay.connect - (mem_fun (*this, &Session::mmc_deferred_play)); - mmc->Stop.connect - (mem_fun (*this, &Session::mmc_stop)); - mmc->FastForward.connect - (mem_fun (*this, &Session::mmc_fast_forward)); - mmc->Rewind.connect - (mem_fun (*this, &Session::mmc_rewind)); - mmc->Pause.connect - (mem_fun (*this, &Session::mmc_pause)); - mmc->RecordPause.connect - (mem_fun (*this, &Session::mmc_record_pause)); - mmc->RecordStrobe.connect - (mem_fun (*this, &Session::mmc_record_strobe)); - mmc->RecordExit.connect - (mem_fun (*this, &Session::mmc_record_exit)); - mmc->Locate.connect - (mem_fun (*this, &Session::mmc_locate)); - mmc->Step.connect - (mem_fun (*this, &Session::mmc_step)); - mmc->Shuttle.connect - (mem_fun (*this, &Session::mmc_shuttle)); - mmc->TrackRecordStatusChange.connect - (mem_fun (*this, &Session::mmc_record_enable)); - - - /* also handle MIDI SPP because its so common */ - - _mmc_port->input()->start.connect (mem_fun (*this, &Session::spp_start)); - _mmc_port->input()->contineu.connect (mem_fun (*this, &Session::spp_continue)); - _mmc_port->input()->stop.connect (mem_fun (*this, &Session::spp_stop)); - - Config->set_mmc_port_name (port_tag); - - out: - MMC_PortChanged(); /* EMIT SIGNAL */ - change_midi_ports (); - set_dirty(); - return 0; -} - -int -Session::set_midi_port (string port_tag) -{ -#if 0 - if (port_tag.length() == 0) { - if (_midi_port == 0) { - return 0; - } - _midi_port = 0; - goto out; - } - - MIDI::Port* port; - - if ((port = MIDI::Manager::instance()->port (port_tag)) == 0) { - return -1; - } - - _midi_port = port; - - /* XXX need something to forward this to control protocols ? or just - use the signal below - */ - - Config->set_midi_port_name (port_tag); - - out: -#endif - MIDI_PortChanged(); /* EMIT SIGNAL */ - change_midi_ports (); - set_dirty(); - return 0; -} - -void -Session::set_trace_midi_input (bool yn, MIDI::Port* port) -{ - MIDI::Parser* input_parser; - - if (port) { - if ((input_parser = port->input()) != 0) { - input_parser->trace (yn, &cout, "input: "); - } - } else { - - if (_mmc_port) { - if ((input_parser = _mmc_port->input()) != 0) { - input_parser->trace (yn, &cout, "input: "); - } - } - - if (_mtc_port && _mtc_port != _mmc_port) { - if ((input_parser = _mtc_port->input()) != 0) { - input_parser->trace (yn, &cout, "input: "); - } - } - - if (_midi_port && _midi_port != _mmc_port && _midi_port != _mtc_port ) { - if ((input_parser = _midi_port->input()) != 0) { - input_parser->trace (yn, &cout, "input: "); - } - } - } - - Config->set_trace_midi_input (yn); -} - -void -Session::set_trace_midi_output (bool yn, MIDI::Port* port) -{ - MIDI::Parser* output_parser; - - if (port) { - if ((output_parser = port->output()) != 0) { - output_parser->trace (yn, &cout, "output: "); - } - } else { - if (_mmc_port) { - if ((output_parser = _mmc_port->output()) != 0) { - output_parser->trace (yn, &cout, "output: "); - } - } - - if (_mtc_port && _mtc_port != _mmc_port) { - if ((output_parser = _mtc_port->output()) != 0) { - output_parser->trace (yn, &cout, "output: "); - } - } - - if (_midi_port && _midi_port != _mmc_port && _midi_port != _mtc_port ) { - if ((output_parser = _midi_port->output()) != 0) { - output_parser->trace (yn, &cout, "output: "); - } - } - - } - - Config->set_trace_midi_output (yn); -} - -bool -Session::get_trace_midi_input(MIDI::Port *port) -{ - MIDI::Parser* input_parser; - if (port) { - if ((input_parser = port->input()) != 0) { - return input_parser->tracing(); - } - } - else { - if (_mmc_port) { - if ((input_parser = _mmc_port->input()) != 0) { - return input_parser->tracing(); - } - } - - if (_mtc_port) { - if ((input_parser = _mtc_port->input()) != 0) { - return input_parser->tracing(); - } - } - - if (_midi_port) { - if ((input_parser = _midi_port->input()) != 0) { - return input_parser->tracing(); - } - } - } - - return false; -} - -bool -Session::get_trace_midi_output(MIDI::Port *port) -{ - MIDI::Parser* output_parser; - if (port) { - if ((output_parser = port->output()) != 0) { - return output_parser->tracing(); - } - } - else { - if (_mmc_port) { - if ((output_parser = _mmc_port->output()) != 0) { - return output_parser->tracing(); - } - } - - if (_mtc_port) { - if ((output_parser = _mtc_port->output()) != 0) { - return output_parser->tracing(); - } - } - - if (_midi_port) { - if ((output_parser = _midi_port->output()) != 0) { - return output_parser->tracing(); - } - } - } - - return false; - -} - -void -Session::setup_midi_control () -{ - outbound_mtc_smpte_frame = 0; - next_quarter_frame_to_send = 0; - - /* setup the MMC buffer */ - - mmc_buffer[0] = 0xf0; // SysEx - mmc_buffer[1] = 0x7f; // Real Time SysEx ID for MMC - mmc_buffer[2] = (mmc ? mmc->send_device_id() : 0x7f); - mmc_buffer[3] = 0x6; // MCC - - /* Set up the qtr frame message */ - - mtc_msg[0] = 0xf1; - mtc_msg[2] = 0xf1; - mtc_msg[4] = 0xf1; - mtc_msg[6] = 0xf1; - mtc_msg[8] = 0xf1; - mtc_msg[10] = 0xf1; - mtc_msg[12] = 0xf1; - mtc_msg[14] = 0xf1; -} - -void -Session::spp_start (Parser& ignored) -{ - if (Config->get_mmc_control() && (Config->get_slave_source() != MTC)) { - request_transport_speed (1.0); - } -} - -void -Session::spp_continue (Parser& ignored) -{ - spp_start (ignored); -} - -void -Session::spp_stop (Parser& ignored) -{ - if (Config->get_mmc_control()) { - request_stop (); - } -} - -void -Session::mmc_deferred_play (MIDI::MachineControl &mmc) -{ - if (Config->get_mmc_control() && (Config->get_slave_source() != MTC)) { - request_transport_speed (1.0); - } -} - -void -Session::mmc_record_pause (MIDI::MachineControl &mmc) -{ - if (Config->get_mmc_control()) { - maybe_enable_record(); - } -} - -void -Session::mmc_record_strobe (MIDI::MachineControl &mmc) -{ - if (!Config->get_mmc_control()) - return; - - /* record strobe does an implicit "Play" command */ - - if (_transport_speed != 1.0) { - - /* start_transport() will move from Enabled->Recording, so we - don't need to do anything here except enable recording. - its not the same as maybe_enable_record() though, because - that *can* switch to Recording, which we do not want. - */ - - save_state ("", true); - g_atomic_int_set (&_record_status, Enabled); - RecordStateChanged (); /* EMIT SIGNAL */ - - request_transport_speed (1.0); - - } else { - - enable_record (); - } -} - -void -Session::mmc_record_exit (MIDI::MachineControl &mmc) -{ - if (Config->get_mmc_control()) { - disable_record (false); - } -} - -void -Session::mmc_stop (MIDI::MachineControl &mmc) -{ - if (Config->get_mmc_control()) { - request_stop (); - } -} - -void -Session::mmc_pause (MIDI::MachineControl &mmc) -{ - if (Config->get_mmc_control()) { - - /* We support RECORD_PAUSE, so the spec says that - we must interpret PAUSE like RECORD_PAUSE if - recording. - */ - - if (actively_recording()) { - maybe_enable_record (); - } else { - request_stop (); - } - } -} - -static bool step_queued = false; - -void -Session::mmc_step (MIDI::MachineControl &mmc, int steps) -{ - if (!Config->get_mmc_control()) { - return; - } - - struct timeval now; - struct timeval diff = { 0, 0 }; - - gettimeofday (&now, 0); - - timersub (&now, &last_mmc_step, &diff); - - gettimeofday (&now, 0); - timersub (&now, &last_mmc_step, &diff); - - if (last_mmc_step.tv_sec != 0 && (diff.tv_usec + (diff.tv_sec * 1000000)) < _engine.usecs_per_cycle()) { - return; - } - - double diff_secs = diff.tv_sec + (diff.tv_usec / 1000000.0); - double cur_speed = (((steps * 0.5) * smpte_frames_per_second()) / diff_secs) / smpte_frames_per_second(); - - if (_transport_speed == 0 || cur_speed * _transport_speed < 0) { - /* change direction */ - step_speed = cur_speed; - } else { - step_speed = (0.6 * step_speed) + (0.4 * cur_speed); - } - - step_speed *= 0.25; - -#if 0 - cerr << "delta = " << diff_secs - << " ct = " << _transport_speed - << " steps = " << steps - << " new speed = " << cur_speed - << " speed = " << step_speed - << endl; -#endif - - request_transport_speed (step_speed); - last_mmc_step = now; - - if (!step_queued) { - midi_timeouts.push_back (mem_fun (*this, &Session::mmc_step_timeout)); - step_queued = true; - } -} - -void -Session::mmc_rewind (MIDI::MachineControl &mmc) -{ - if (Config->get_mmc_control()) { - request_transport_speed(-8.0f); - } -} - -void -Session::mmc_fast_forward (MIDI::MachineControl &mmc) -{ - if (Config->get_mmc_control()) { - request_transport_speed(8.0f); - } -} - -void -Session::mmc_locate (MIDI::MachineControl &mmc, const MIDI::byte* mmc_tc) -{ - if (!Config->get_mmc_control()) { - return; - } - - nframes_t target_frame; - SMPTE::Time smpte; - - smpte.hours = mmc_tc[0] & 0xf; - smpte.minutes = mmc_tc[1]; - smpte.seconds = mmc_tc[2]; - smpte.frames = mmc_tc[3]; - smpte.rate = smpte_frames_per_second(); - smpte.drop = smpte_drop_frames(); - - // Also takes smpte offset into account: - smpte_to_sample( smpte, target_frame, true /* use_offset */, false /* use_subframes */ ); - - if (target_frame > max_frames) { - target_frame = max_frames; - } - - /* Some (all?) MTC/MMC devices do not send a full MTC frame - at the end of a locate, instead sending only an MMC - locate command. This causes the current position - of an MTC slave to become out of date. Catch this. - */ - - MTC_Slave* mtcs = dynamic_cast<MTC_Slave*> (_slave); - - if (mtcs != 0) { - // cerr << "Locate *with* MTC slave\n"; - mtcs->handle_locate (mmc_tc); - } else { - // cerr << "Locate without MTC slave\n"; - request_locate (target_frame, false); - } -} - -void -Session::mmc_shuttle (MIDI::MachineControl &mmc, float speed, bool forw) -{ - if (!Config->get_mmc_control()) { - return; - } - - if (Config->get_shuttle_speed_threshold() >= 0 && speed > Config->get_shuttle_speed_threshold()) { - speed *= Config->get_shuttle_speed_factor(); - } - - if (forw) { - request_transport_speed (speed); - } else { - request_transport_speed (-speed); - } -} - -void -Session::mmc_record_enable (MIDI::MachineControl &mmc, size_t trk, bool enabled) -{ - if (Config->get_mmc_control()) { - - RouteList::iterator i; - boost::shared_ptr<RouteList> r = routes.reader(); - - for (i = r->begin(); i != r->end(); ++i) { - AudioTrack *at; - - if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) { - if (trk == at->remote_control_id()) { - at->set_record_enable (enabled, &mmc); - break; - } - } - } - } -} - -void -Session::change_midi_ports () -{ - MIDIRequest* request = new MIDIRequest; - - request->type = MIDIRequest::PortChange; - midi_requests.write (&request, 1); - poke_midi_thread (); -} - -/** Send MTC Full Frame message (complete SMPTE time) for the start of this cycle. - * This resets the MTC code, the next quarter frame message that is sent will be - * the first one with the beginning of this cycle as the new start point. - */ - -int -Session::send_full_time_code(nframes_t nframes) -{ - /* This function could easily send at a given frame offset, but would - * that be useful? Does ardour do sub-block accurate locating? [DR] */ - - MIDI::byte msg[10]; - SMPTE::Time smpte; - - _send_smpte_update = false; - - if (_mtc_port == 0 || !session_send_mtc) { - return 0; - } - - // Get smpte time for this transport frame - sample_to_smpte(_transport_frame, smpte, true /* use_offset */, false /* no subframes */); - - transmitting_smpte_time = smpte; - outbound_mtc_smpte_frame = _transport_frame; - - // I don't understand this bit yet.. [DR] - if (((mtc_smpte_bits >> 5) != MIDI::MTC_25_FPS) && (transmitting_smpte_time.frames % 2)) { - // start MTC quarter frame transmission on an even frame - SMPTE::increment( transmitting_smpte_time ); - outbound_mtc_smpte_frame += (nframes_t) _frames_per_smpte_frame; - } - - // Compensate for audio latency - outbound_mtc_smpte_frame += _worst_output_latency; - - next_quarter_frame_to_send = 0; - - // Sync slave to the same SMPTE time as we are on - msg[0] = 0xf0; - msg[1] = 0x7f; - msg[2] = 0x7f; - msg[3] = 0x1; - msg[4] = 0x1; - msg[9] = 0xf7; - - msg[5] = mtc_smpte_bits | smpte.hours; - msg[6] = smpte.minutes; - msg[7] = smpte.seconds; - msg[8] = smpte.frames; - - cerr << "MTC: Sending full time code at " << outbound_mtc_smpte_frame << endl; - - // Send message at offset 0, sent time is for the start of this cycle - if (_mtc_port->midimsg (msg, sizeof (msg), 0)) { - error << _("Session: could not send full MIDI time code") << endmsg; - return -1; - } - - return 0; -} - - -/** Sends MTC (quarter-frame) messages for this cycle. - * Must be called exactly once per cycle from the audio thread. Realtime safe. - * This function assumes the state of full SMPTE is sane, eg. the slave is - * expecting quarter frame messages and has the right frame of reference (any - * full MTC SMPTE time messages that needed to be sent should have been sent - * earlier already this cycle by send_full_time_code) - */ -int -Session::send_midi_time_code_for_cycle(nframes_t nframes) -{ - assert (next_quarter_frame_to_send >= 0); - assert (next_quarter_frame_to_send <= 7); - - if (_mtc_port == 0 || !session_send_mtc || transmitting_smpte_time.negative - /*|| (next_quarter_frame_to_send < 0)*/ ) { - // cerr << "(MTC) Not sending MTC\n"; - return 0; - } - - /* Duration of one quarter frame */ - nframes_t quarter_frame_duration = ((long) _frames_per_smpte_frame) >> 2; - - // cerr << "(MTC) TR: " << _transport_frame << " - SF: " << outbound_mtc_smpte_frame - // << " - NQ: " << next_quarter_frame_to_send << " - FD" << quarter_frame_duration << endl; - - // FIXME: this should always be true - //assert((outbound_mtc_smpte_frame + (next_quarter_frame_to_send * quarter_frame_duration)) - // > _transport_frame); - - - // Send quarter frames for this cycle - while (_transport_frame + nframes > (outbound_mtc_smpte_frame + - (next_quarter_frame_to_send * quarter_frame_duration))) { - - // cerr << "(MTC) Next frame to send: " << next_quarter_frame_to_send << endl; - - switch (next_quarter_frame_to_send) { - case 0: - mtc_msg[1] = 0x00 | (transmitting_smpte_time.frames & 0xf); - break; - case 1: - mtc_msg[1] = 0x10 | ((transmitting_smpte_time.frames & 0xf0) >> 4); - break; - case 2: - mtc_msg[1] = 0x20 | (transmitting_smpte_time.seconds & 0xf); - break; - case 3: - mtc_msg[1] = 0x30 | ((transmitting_smpte_time.seconds & 0xf0) >> 4); - break; - case 4: - mtc_msg[1] = 0x40 | (transmitting_smpte_time.minutes & 0xf); - break; - case 5: - mtc_msg[1] = 0x50 | ((transmitting_smpte_time.minutes & 0xf0) >> 4); - break; - case 6: - mtc_msg[1] = 0x60 | ((mtc_smpte_bits|transmitting_smpte_time.hours) & 0xf); - break; - case 7: - mtc_msg[1] = 0x70 | (((mtc_smpte_bits|transmitting_smpte_time.hours) & 0xf0) >> 4); - break; - } - - const nframes_t msg_time = (outbound_mtc_smpte_frame - + (quarter_frame_duration * next_quarter_frame_to_send)); - - // This message must fall within this block or something is broken - assert(msg_time >= _transport_frame); - assert(msg_time < _transport_frame + nframes); - - nframes_t out_stamp = msg_time - _transport_frame; - assert(out_stamp < nframes); - - if (_mtc_port->midimsg (mtc_msg, 2, out_stamp)) { - error << string_compose(_("Session: cannot send quarter-frame MTC message (%1)"), strerror (errno)) - << endmsg; - return -1; - } - - /*cerr << "(MTC) SMPTE: " << transmitting_smpte_time.hours - << ":" << transmitting_smpte_time.minutes - << ":" << transmitting_smpte_time.seconds - << ":" << transmitting_smpte_time.frames - << ", qfm = " << next_quarter_frame_to_send - << ", stamp = " << out_stamp - << ", delta = " << _transport_frame + out_stamp - last_time << endl;*/ - - // Increment quarter frame counter - next_quarter_frame_to_send++; - - if (next_quarter_frame_to_send >= 8) { - // Wrap quarter frame counter - next_quarter_frame_to_send = 0; - // Increment smpte time twice - SMPTE::increment( transmitting_smpte_time ); - SMPTE::increment( transmitting_smpte_time ); - // Re-calculate timing of first quarter frame - //smpte_to_sample( transmitting_smpte_time, outbound_mtc_smpte_frame, true /* use_offset */, false ); - outbound_mtc_smpte_frame += 8 * quarter_frame_duration; - // Compensate for audio latency - outbound_mtc_smpte_frame += _worst_output_latency; - } - } - - return 0; -} - -/*********************************************************************** - OUTBOUND MMC STUFF -**********************************************************************/ - -void -Session::deliver_mmc (MIDI::MachineControl::Command cmd, nframes_t where) -{ - using namespace MIDI; - int nbytes = 4; - SMPTE::Time smpte; - - if (_mmc_port == 0 || !session_send_mmc) { - // cerr << "Not delivering MMC " << _mmc_port << " - " << session_send_mmc << endl; - return; - } - - mmc_buffer[nbytes++] = cmd; - - // cerr << "delivering MMC, cmd = " << hex << (int) cmd << dec << endl; - - switch (cmd) { - case MachineControl::cmdLocate: - smpte_time_subframes (where, smpte); - - mmc_buffer[nbytes++] = 0x6; // byte count - mmc_buffer[nbytes++] = 0x1; // "TARGET" subcommand - mmc_buffer[nbytes++] = smpte.hours; - mmc_buffer[nbytes++] = smpte.minutes; - mmc_buffer[nbytes++] = smpte.seconds; - mmc_buffer[nbytes++] = smpte.frames; - mmc_buffer[nbytes++] = smpte.subframes; - break; - - case MachineControl::cmdStop: - break; - - case MachineControl::cmdPlay: - /* always convert Play into Deferred Play */ - /* Why? [DR] */ - mmc_buffer[4] = MachineControl::cmdDeferredPlay; - break; - - case MachineControl::cmdDeferredPlay: - break; - - case MachineControl::cmdRecordStrobe: - break; - - case MachineControl::cmdRecordExit: - break; - - case MachineControl::cmdRecordPause: - break; - - default: - nbytes = 0; - }; - - if (nbytes) { - - mmc_buffer[nbytes++] = 0xf7; // terminate SysEx/MMC message - - if (_mmc_port->midimsg (mmc_buffer, nbytes, 0)) { - error << string_compose(_("MMC: cannot send command %1%2%3"), &hex, cmd, &dec) << endmsg; - } - } -} - -bool -Session::mmc_step_timeout () -{ - struct timeval now; - struct timeval diff; - double diff_usecs; - gettimeofday (&now, 0); - - timersub (&now, &last_mmc_step, &diff); - diff_usecs = diff.tv_sec * 1000000 + diff.tv_usec; - - if (diff_usecs > 1000000.0 || fabs (_transport_speed) < 0.0000001) { - /* too long or too slow, stop transport */ - request_transport_speed (0.0); - step_queued = false; - return false; - } - - if (diff_usecs < 250000.0) { - /* too short, just keep going */ - return true; - } - - /* slow it down */ - - request_transport_speed (_transport_speed * 0.75); - return true; -} - -/*--------------------------------------------------------------------------- - MIDI THREAD - ---------------------------------------------------------------------------*/ - -int -Session::start_midi_thread () -{ - if (pipe (midi_request_pipe)) { - error << string_compose(_("Cannot create transport request signal pipe (%1)"), strerror (errno)) << endmsg; - return -1; - } - - if (fcntl (midi_request_pipe[0], F_SETFL, O_NONBLOCK)) { - error << string_compose(_("UI: cannot set O_NONBLOCK on " "signal read pipe (%1)"), strerror (errno)) << endmsg; - return -1; - } - - if (fcntl (midi_request_pipe[1], F_SETFL, O_NONBLOCK)) { - error << string_compose(_("UI: cannot set O_NONBLOCK on " "signal write pipe (%1)"), strerror (errno)) << endmsg; - return -1; - } - - if (pthread_create_and_store ("transport", &midi_thread, 0, _midi_thread_work, this)) { - error << _("Session: could not create transport thread") << endmsg; - return -1; - } - - return 0; -} - -void -Session::terminate_midi_thread () -{ - if (midi_thread) { - - MIDIRequest* request = new MIDIRequest; - void* status; - - request->type = MIDIRequest::Quit; - - midi_requests.write (&request, 1); - poke_midi_thread (); - - pthread_join (midi_thread, &status); - } -} - -void -Session::poke_midi_thread () -{ - static char c = 0; - - if (write (midi_request_pipe[1], &c, 1) != 1) { - error << string_compose(_("cannot send signal to midi thread! (%1)"), strerror (errno)) << endmsg; - } -} - -void * -Session::_midi_thread_work (void* arg) -{ - pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, 0); - pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0); - - ((Session *) arg)->midi_thread_work (); - return 0; -} - -void -Session::midi_thread_work () -{ - MIDIRequest* request; - struct pollfd pfd[4]; - int nfds = 0; - int timeout; - int fds_ready; - struct sched_param rtparam; - int x; - bool restart; - vector<MIDI::Port*> ports; - - PBD::ThreadCreatedWithRequestSize (pthread_self(), X_("MIDI"), 2048); - - memset (&rtparam, 0, sizeof (rtparam)); - rtparam.sched_priority = 9; /* XXX should be relative to audio (JACK) thread */ - - if ((x = pthread_setschedparam (pthread_self(), SCHED_FIFO, &rtparam)) != 0) { - // do we care? not particularly. - } - - /* set up the port vector; 4 is the largest possible size for now */ - - ports.assign (4, (MIDI::Port*) 0); - - while (1) { - - nfds = 0; - - pfd[nfds].fd = midi_request_pipe[0]; - pfd[nfds].events = POLLIN|POLLHUP|POLLERR; - nfds++; - - if (Config->get_mmc_control() && _mmc_port && _mmc_port->selectable() >= 0) { - pfd[nfds].fd = _mmc_port->selectable(); - pfd[nfds].events = POLLIN|POLLHUP|POLLERR; - ports[nfds] = _mmc_port; - nfds++; - } - - /* if MTC is being handled on a different port from MMC - or we are not handling MMC at all, poll - the relevant port. - */ - - if (_mtc_port && (_mtc_port != _mmc_port || !Config->get_mmc_control()) && _mtc_port->selectable() >= 0) { - pfd[nfds].fd = _mtc_port->selectable(); - pfd[nfds].events = POLLIN|POLLHUP|POLLERR; - ports[nfds] = _mtc_port; - nfds++; - } - - /* if we are using MMC control, we obviously have to listen - the relevant port. - */ - - if (_midi_port && (_midi_port != _mmc_port || !Config->get_mmc_control()) && (_midi_port != _mtc_port) && _midi_port->selectable() >= 0) { - pfd[nfds].fd = _midi_port->selectable(); - pfd[nfds].events = POLLIN|POLLHUP|POLLERR; - ports[nfds] = _midi_port; - nfds++; - } - - if (!midi_timeouts.empty()) { - timeout = 100; /* 10msecs */ - } else { - timeout = -1; /* if there is no data, we don't care */ - } - - again: - // cerr << "MIDI poll on " << nfds << " for " << timeout << endl; - if (poll (pfd, nfds, timeout) < 0) { - if (errno == EINTR) { - /* gdb at work, perhaps */ - goto again; - } - - error << string_compose(_("MIDI thread poll failed (%1)"), strerror (errno)) << endmsg; - - break; - } - // cerr << "MIDI thread wakes at " << get_cycles () << endl; - - fds_ready = 0; - - /* check the transport request pipe */ - - if (pfd[0].revents & ~POLLIN) { - error << _("Error on transport thread request pipe") << endmsg; - break; - } - - if (pfd[0].revents & POLLIN) { - - char foo[16]; - - // cerr << "MIDI request FIFO ready\n"; - fds_ready++; - - /* empty the pipe of all current requests */ - - while (1) { - size_t nread = read (midi_request_pipe[0], &foo, sizeof (foo)); - - if (nread > 0) { - if ((size_t) nread < sizeof (foo)) { - break; - } else { - continue; - } - } else if (nread == 0) { - break; - } else if (errno == EAGAIN) { - break; - } else { - fatal << _("Error reading from transport request pipe") << endmsg; - /*NOTREACHED*/ - } - } - - while (midi_requests.read (&request, 1) == 1) { - - switch (request->type) { - case MIDIRequest::PortChange: - /* restart poll with new ports */ - // cerr << "rebind\n"; - restart = true; - break; - - case MIDIRequest::Quit: - delete request; - pthread_exit_pbd (0); - /*NOTREACHED*/ - break; - - default: - break; - } - - - delete request; - } - - } - - if (restart) { - continue; - } - - /* now read the rest of the ports */ - - for (int p = 1; p < nfds; ++p) { - if ((pfd[p].revents & ~POLLIN)) { - // error << string_compose(_("Transport: error polling MIDI port %1 (revents =%2%3%4"), p, &hex, pfd[p].revents, &dec) << endmsg; - break; - } - - if (pfd[p].revents & POLLIN) { - fds_ready++; - ports[p]->parse (); - } - } - - /* timeout driven */ - - if (fds_ready < 2 && timeout != -1) { - - for (MidiTimeoutList::iterator i = midi_timeouts.begin(); i != midi_timeouts.end(); ) { - - MidiTimeoutList::iterator tmp; - tmp = i; - ++tmp; - - if (!(*i)()) { - midi_timeouts.erase (i); - } - - i = tmp; - } - } - } -} - diff --git a/libs/ardour/session_process.cc b/libs/ardour/session_process.cc deleted file mode 100644 index d6890b31ae..0000000000 --- a/libs/ardour/session_process.cc +++ /dev/null @@ -1,886 +0,0 @@ -/* - Copyright (C) 1999-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. - -*/ - -#include <cmath> -#include <cerrno> -#include <algorithm> -#include <unistd.h> - -#include <pbd/error.h> - -#include <glibmm/thread.h> - -#include <ardour/ardour.h> -#include <ardour/session.h> -#include <ardour/timestamps.h> -#include <ardour/audio_diskstream.h> -#include <ardour/audioengine.h> -#include <ardour/slave.h> -#include <ardour/auditioner.h> -#include <ardour/cycles.h> -#include <ardour/cycle_timer.h> - -#include <midi++/manager.h> - -#include "i18n.h" - -using namespace ARDOUR; -using namespace PBD; -using namespace std; - -/** Called by the audio engine when there is work to be done with JACK. - * @param nframes Number of frames to process. - */ -void -Session::process (nframes_t nframes) -{ - MIDI::Manager::instance()->cycle_start(nframes); - - _silent = false; - - if (synced_to_jack() && waiting_to_start) { - if ( _engine.transport_state() == AudioEngine::TransportRolling) { - actually_start_transport (); - } - } - - if (non_realtime_work_pending()) { - if (!transport_work_requested ()) { - post_transport (); - } - } - - (this->*process_function) (nframes); - - MIDI::Manager::instance()->cycle_end(); - - SendFeedback (); /* EMIT SIGNAL */ -} - -void -Session::prepare_diskstreams () -{ - boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader(); - for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) { - (*i)->prepare (); - } -} - -int -Session::no_roll (nframes_t nframes, nframes_t offset) -{ - nframes_t end_frame = _transport_frame + nframes; // FIXME: varispeed + no_roll ?? - int ret = 0; - bool declick = get_transport_declick_required(); - boost::shared_ptr<RouteList> r = routes.reader (); - - if (_click_io) { - _click_io->silence (nframes, offset); - } - - if (g_atomic_int_get (&processing_prohibited)) { - for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - (*i)->silence (nframes, offset); - } - return 0; - } - - for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - - if ((*i)->is_hidden()) { - continue; - } - - (*i)->set_pending_declick (declick); - - if ((*i)->no_roll (nframes, _transport_frame, end_frame, offset, non_realtime_work_pending(), - actively_recording(), declick)) { - error << string_compose(_("Session: error in no roll for %1"), (*i)->name()) << endmsg; - ret = -1; - break; - } - } - - return ret; -} - -int -Session::process_routes (nframes_t nframes, nframes_t offset) -{ - bool record_active; - int declick = get_transport_declick_required(); - bool rec_monitors = get_rec_monitors_input(); - boost::shared_ptr<RouteList> r = routes.reader (); - - if (transport_sub_state & StopPendingCapture) { - /* force a declick out */ - declick = -1; - } - - record_active = actively_recording(); // || (get_record_enabled() && get_punch_in()); - - const nframes_t start_frame = _transport_frame; - const nframes_t end_frame = _transport_frame + (nframes_t)floor(nframes * _transport_speed); - - for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - - int ret; - - if ((*i)->is_hidden()) { - continue; - } - - (*i)->set_pending_declick (declick); - - if ((ret = (*i)->roll (nframes, start_frame, end_frame, offset, declick, record_active, rec_monitors)) < 0) { - - /* we have to do this here. Route::roll() for an AudioTrack will have called AudioDiskstream::process(), - and the DS will expect AudioDiskstream::commit() to be called. but we're aborting from that - call path, so make sure we release any outstanding locks here before we return failure. - */ - - boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader(); - for (DiskstreamList::iterator ids = dsl->begin(); ids != dsl->end(); ++ids) { - (*ids)->recover (); - } - - stop_transport (); - return -1; - } - } - - return 0; -} - -int -Session::silent_process_routes (nframes_t nframes, nframes_t offset) -{ - bool record_active = actively_recording(); - int declick = get_transport_declick_required(); - bool rec_monitors = get_rec_monitors_input(); - boost::shared_ptr<RouteList> r = routes.reader (); - - if (transport_sub_state & StopPendingCapture) { - /* force a declick out */ - declick = -1; - } - - const nframes_t start_frame = _transport_frame; - const nframes_t end_frame = _transport_frame + lrintf(nframes * _transport_speed); - - for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - - int ret; - - if ((*i)->is_hidden()) { - continue; - } - - if ((ret = (*i)->silent_roll (nframes, start_frame, end_frame, offset, record_active, rec_monitors)) < 0) { - - /* we have to do this here. Route::roll() for an AudioTrack will have called AudioDiskstream::process(), - and the DS will expect AudioDiskstream::commit() to be called. but we're aborting from that - call path, so make sure we release any outstanding locks here before we return failure. - */ - - boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader(); - for (DiskstreamList::iterator ids = dsl->begin(); ids != dsl->end(); ++ids) { - (*ids)->recover (); - } - - stop_transport (); - return -1; - } - } - - return 0; -} - -void -Session::commit_diskstreams (nframes_t nframes, bool &needs_butler) -{ - int dret; - float pworst = 1.0f; - float cworst = 1.0f; - - boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader(); - for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) { - - if ((*i)->hidden()) { - continue; - } - - /* force all diskstreams not handled by a Route to call do their stuff. - Note: the diskstreams that were handled by a route will just return zero - from this call, because they know they were processed. So in fact, this - also runs commit() for every diskstream. - */ - - if ((dret = (*i)->process (_transport_frame, nframes, 0, actively_recording(), get_rec_monitors_input())) == 0) { - if ((*i)->commit (nframes)) { - needs_butler = true; - } - - } else if (dret < 0) { - (*i)->recover(); - } - - pworst = min (pworst, (*i)->playback_buffer_load()); - cworst = min (cworst, (*i)->capture_buffer_load()); - } - - uint32_t pmin = g_atomic_int_get (&_playback_load); - uint32_t pminold = g_atomic_int_get (&_playback_load_min); - uint32_t cmin = g_atomic_int_get (&_capture_load); - uint32_t cminold = g_atomic_int_get (&_capture_load_min); - - g_atomic_int_set (&_playback_load, (uint32_t) floor (pworst * 100.0f)); - g_atomic_int_set (&_capture_load, (uint32_t) floor (cworst * 100.0f)); - g_atomic_int_set (&_playback_load_min, min (pmin, pminold)); - g_atomic_int_set (&_capture_load_min, min (cmin, cminold)); - - if (actively_recording()) { - set_dirty(); - } -} - -/** Process callback used when the auditioner is not active */ -void -Session::process_with_events (nframes_t nframes) -{ - Event* ev; - nframes_t this_nframes; - nframes_t end_frame; - nframes_t offset; - bool session_needs_butler = false; - nframes_t stop_limit; - long frames_moved; - - /* make sure the auditioner is silent */ - - if (auditioner) { - auditioner->silence (nframes, 0); - } - - /* handle any pending events */ - - while (pending_events.read (&ev, 1) == 1) { - merge_event (ev); - } - - /* if we are not in the middle of a state change, - and there are immediate events queued up, - process them. - */ - - while (!non_realtime_work_pending() && !immediate_events.empty()) { - Event *ev = immediate_events.front (); - immediate_events.pop_front (); - process_event (ev); - } - - /* Events caused a transport change, send an MTC Full Frame (SMPTE) message. - * This is sent whether rolling or not, to give slaves an idea of ardour time - * on locates (and allow slow slaves to position and prepare for rolling) - */ - if (_send_smpte_update) { - send_full_time_code(nframes); - } - - if (!process_can_proceed()) { - _silent = true; - return; - } - - if (events.empty() || next_event == events.end()) { - process_without_events (nframes); - return; - } - - end_frame = _transport_frame + (nframes_t)abs(floor(nframes * _transport_speed)); - - { - Event* this_event; - Events::iterator the_next_one; - - if (!process_can_proceed()) { - _silent = true; - return; - } - - if (!_exporting && _slave) { - if (!follow_slave (nframes, 0)) { - return; - } - } - - if (_transport_speed == 0) { - no_roll (nframes, 0); - return; - } - - if (!_exporting) { - send_midi_time_code_for_cycle (nframes); - } - - if (actively_recording()) { - stop_limit = max_frames; - } else { - - if (Config->get_stop_at_session_end()) { - stop_limit = current_end_frame(); - } else { - stop_limit = max_frames; - } - } - - if (maybe_stop (stop_limit)) { - no_roll (nframes, 0); - return; - } - - this_event = *next_event; - the_next_one = next_event; - ++the_next_one; - - offset = 0; - - /* yes folks, here it is, the actual loop where we really truly - process some audio */ - while (nframes) { - - this_nframes = nframes; /* real (jack) time relative */ - frames_moved = (long) floor (_transport_speed * nframes); /* transport relative */ - - /* running an event, position transport precisely to its time */ - if (this_event && this_event->action_frame <= end_frame && this_event->action_frame >= _transport_frame) { - /* this isn't quite right for reverse play */ - frames_moved = (long) (this_event->action_frame - _transport_frame); - this_nframes = (nframes_t) abs( floor(frames_moved / _transport_speed) ); - } - - if (this_nframes) { - - click (_transport_frame, nframes, offset); - - /* now process frames between now and the first event in this block */ - prepare_diskstreams (); - - if (process_routes (this_nframes, offset)) { - no_roll (nframes, 0); - return; - } - - commit_diskstreams (this_nframes, session_needs_butler); - - nframes -= this_nframes; - offset += this_nframes; - - if (frames_moved < 0) { - decrement_transport_position (-frames_moved); - } else { - increment_transport_position (frames_moved); - } - - maybe_stop (stop_limit); - check_declick_out (); - } - - /* now handle this event and all others scheduled for the same time */ - - while (this_event && this_event->action_frame == _transport_frame) { - process_event (this_event); - - if (the_next_one == events.end()) { - this_event = 0; - } else { - this_event = *the_next_one; - ++the_next_one; - } - } - - /* if an event left our state changing, do the right thing */ - - if (non_realtime_work_pending()) { - no_roll (nframes, offset); - break; - } - - /* this is necessary to handle the case of seamless looping */ - end_frame = _transport_frame + (nframes_t) floor (nframes * _transport_speed); - - } - - set_next_event (); - - } /* implicit release of route lock */ - - if (session_needs_butler) - summon_butler (); -} - -void -Session::reset_slave_state () -{ - average_slave_delta = 1800; - delta_accumulator_cnt = 0; - have_first_delta_accumulator = false; - slave_state = Stopped; -} - -bool -Session::transport_locked () const -{ - Slave* sl = _slave; - - if (!locate_pending() && ((Config->get_slave_source() == None) || (sl && sl->ok() && sl->locked()))) { - return true; - } - - return false; -} - -bool -Session::follow_slave (nframes_t nframes, nframes_t offset) -{ - float slave_speed; - nframes_t slave_transport_frame; - nframes_t this_delta; - int dir; - bool starting; - - if (!_slave->ok()) { - stop_transport (); - Config->set_slave_source (None); - goto noroll; - } - - _slave->speed_and_position (slave_speed, slave_transport_frame); - - if (!_slave->locked()) { - goto noroll; - } - - if (slave_transport_frame > _transport_frame) { - this_delta = slave_transport_frame - _transport_frame; - dir = 1; - } else { - this_delta = _transport_frame - slave_transport_frame; - dir = -1; - } - - if ((starting = _slave->starting())) { - slave_speed = 0.0f; - } - -#if 0 - cerr << "delta = " << (int) (dir * this_delta) - << " speed = " << slave_speed - << " ts = " << _transport_speed - << " M@ "<< slave_transport_frame << " S@ " << _transport_frame - << " avgdelta = " << average_slave_delta - << endl; -#endif - - if (_slave->is_always_synced() || Config->get_timecode_source_is_synced()) { - - /* if the TC source is synced, then we assume that its - speed is binary: 0.0 or 1.0 - */ - - if (slave_speed != 0.0f) { - slave_speed = 1.0f; - } - - } else { - - /* TC source is able to drift relative to us (slave) - so we need to keep track of the drift and adjust - our speed to remain locked. - */ - - if (delta_accumulator_cnt >= delta_accumulator_size) { - have_first_delta_accumulator = true; - delta_accumulator_cnt = 0; - } - - if (delta_accumulator_cnt != 0 || this_delta < _current_frame_rate) { - delta_accumulator[delta_accumulator_cnt++] = dir*this_delta; - } - - if (have_first_delta_accumulator) { - average_slave_delta = 0; - for (int i = 0; i < delta_accumulator_size; ++i) { - average_slave_delta += delta_accumulator[i]; - } - average_slave_delta /= delta_accumulator_size; - if (average_slave_delta < 0) { - average_dir = -1; - average_slave_delta = -average_slave_delta; - } else { - average_dir = 1; - } - // cerr << "avgdelta = " << average_slave_delta*average_dir << endl; - } - } - - if (slave_speed != 0.0f) { - - /* slave is running */ - - switch (slave_state) { - case Stopped: - if (_slave->requires_seekahead()) { - slave_wait_end = slave_transport_frame + _current_frame_rate; - locate (slave_wait_end, false, false); - slave_state = Waiting; - starting = true; - - } else { - - slave_state = Running; - - Location* al = _locations.auto_loop_location(); - - if (al && play_loop && (slave_transport_frame < al->start() || slave_transport_frame > al->end())) { - // cancel looping - request_play_loop(false); - } - - if (slave_transport_frame != _transport_frame) { - locate (slave_transport_frame, false, false); - } - } - break; - - case Waiting: - break; - - default: - break; - - } - - if (slave_state == Waiting) { - - // cerr << "waiting at " << slave_transport_frame << endl; - if (slave_transport_frame >= slave_wait_end) { - // cerr << "\tstart at " << _transport_frame << endl; - - slave_state = Running; - - bool ok = true; - nframes_t frame_delta = slave_transport_frame - _transport_frame; - - boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader(); - - for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) { - if (!(*i)->can_internal_playback_seek (frame_delta)) { - ok = false; - break; - } - } - - if (ok) { - for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) { - (*i)->internal_playback_seek (frame_delta); - } - _transport_frame += frame_delta; - - } else { - // cerr << "cannot micro-seek\n"; - /* XXX what? */ - } - - memset (delta_accumulator, 0, sizeof (nframes_t) * delta_accumulator_size); - average_slave_delta = 0; - this_delta = 0; - } - } - - if (slave_state == Running && _transport_speed == 0.0f) { - - // cerr << "slave starts transport\n"; - - start_transport (); - } - - } else { - - /* slave has stopped */ - - if (_transport_speed != 0.0f) { - - // cerr << "slave stops transport: " << slave_speed << " frame: " << slave_transport_frame - // << " tf = " << _transport_frame - // << endl; - - if (Config->get_slave_source() == JACK) { - last_stop_frame = _transport_frame; - } - - stop_transport(); - } - - if (slave_transport_frame != _transport_frame) { - // cerr << "slave stopped, move to " << slave_transport_frame << endl; - force_locate (slave_transport_frame, false); - } - - slave_state = Stopped; - } - - if (slave_state == Running && !_slave->is_always_synced() && !Config->get_timecode_source_is_synced()) { - - - if (_transport_speed != 0.0f) { - - /* - note that average_dir is +1 or -1 - */ - - const float adjust_seconds = 1.0f; - float delta; - - //if (average_slave_delta == 0) { - delta = this_delta; - delta *= dir; -// } else { -// delta = average_slave_delta; -// delta *= average_dir; -// } - - float adjusted_speed = slave_speed + - (delta / (adjust_seconds * _current_frame_rate)); - - // cerr << "adjust using " << delta - // << " towards " << adjusted_speed - // << " ratio = " << adjusted_speed / slave_speed - // << " current = " << _transport_speed - // << " slave @ " << slave_speed - // << endl; - - request_transport_speed (adjusted_speed); - -#if 1 - if ((nframes_t) average_slave_delta > _slave->resolution()) { - // cerr << "not locked\n"; - goto silent_motion; - } -#endif - } - } - - if (!starting && !non_realtime_work_pending()) { - /* speed is set, we're locked, and good to go */ - return true; - } - - silent_motion: - - if (slave_speed && _transport_speed) { - - /* something isn't right, but we should move with the master - for now. - */ - - bool need_butler; - - prepare_diskstreams (); - silent_process_routes (nframes, offset); - commit_diskstreams (nframes, need_butler); - - if (need_butler) { - summon_butler (); - } - - int32_t frames_moved = (int32_t) floor (_transport_speed * nframes); - - if (frames_moved < 0) { - decrement_transport_position (-frames_moved); - } else { - increment_transport_position (frames_moved); - } - - nframes_t stop_limit; - - if (actively_recording()) { - stop_limit = max_frames; - } else { - if (Config->get_stop_at_session_end()) { - stop_limit = current_end_frame(); - } else { - stop_limit = max_frames; - } - } - - maybe_stop (stop_limit); - } - - noroll: - /* don't move at all */ - no_roll (nframes, 0); - return false; -} - -void -Session::process_without_events (nframes_t nframes) -{ - bool session_needs_butler = false; - nframes_t stop_limit; - long frames_moved; - nframes_t offset = 0; - - if (!process_can_proceed()) { - _silent = true; - return; - } - - if (!_exporting && _slave) { - if (!follow_slave (nframes, 0)) { - return; - } - } - - if (_transport_speed == 0) { - no_roll (nframes, 0); - return; - } - - if (!_exporting) { - send_midi_time_code_for_cycle (nframes); - } - - if (actively_recording()) { - stop_limit = max_frames; - } else { - if (Config->get_stop_at_session_end()) { - stop_limit = current_end_frame(); - } else { - stop_limit = max_frames; - } - } - - if (maybe_stop (stop_limit)) { - no_roll (nframes, 0); - return; - } - - if (maybe_sync_start (nframes, offset)) { - return; - } - - click (_transport_frame, nframes, offset); - - prepare_diskstreams (); - - frames_moved = (long) floor (_transport_speed * nframes); - - if (process_routes (nframes, offset)) { - no_roll (nframes, offset); - return; - } - - commit_diskstreams (nframes, session_needs_butler); - - if (frames_moved < 0) { - decrement_transport_position (-frames_moved); - } else { - increment_transport_position (frames_moved); - } - - maybe_stop (stop_limit); - check_declick_out (); - - if (session_needs_butler) - summon_butler (); -} - -/** Process callback used when the auditioner is active. - * @param nframes number of frames to process. - */ -void -Session::process_audition (nframes_t nframes) -{ - Event* ev; - boost::shared_ptr<RouteList> r = routes.reader (); - - for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - if (!(*i)->is_hidden()) { - (*i)->silence (nframes, 0); - } - } - - /* run the auditioner, and if it says we need butler service, ask for it */ - - if (auditioner->play_audition (nframes) > 0) { - summon_butler (); - } - - /* handle pending events */ - - while (pending_events.read (&ev, 1) == 1) { - merge_event (ev); - } - - /* if we are not in the middle of a state change, - and there are immediate events queued up, - process them. - */ - - while (!non_realtime_work_pending() && !immediate_events.empty()) { - Event *ev = immediate_events.front (); - immediate_events.pop_front (); - process_event (ev); - } - - if (!auditioner->active()) { - /* auditioner no longer active, so go back to the normal process callback */ - process_function = &Session::process_with_events; - } -} - -bool -Session::maybe_sync_start (nframes_t& nframes, nframes_t& offset) -{ - nframes_t sync_offset; - - if (!waiting_for_sync_offset) { - return false; - } - - if (_engine.get_sync_offset (sync_offset) && sync_offset < nframes) { - - no_roll (sync_offset, 0); - nframes -= sync_offset; - offset += sync_offset; - waiting_for_sync_offset = false; - - if (nframes == 0) { - return true; // done - } - - } else { - no_roll (nframes, 0); - return true; // done - } - - return false; -} - diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc deleted file mode 100644 index c228f3c47b..0000000000 --- a/libs/ardour/session_state.cc +++ /dev/null @@ -1,3219 +0,0 @@ -/* - Copyright (C) 1999-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. - -*/ - -#define __STDC_FORMAT_MACROS 1 -#include <stdint.h> - -#include <algorithm> -#include <fstream> -#include <string> -#include <cerrno> - -#include <sigc++/bind.h> - -#include <cstdio> /* snprintf(3) ... grrr */ -#include <cmath> -#include <unistd.h> -#include <sys/stat.h> -#include <climits> -#include <fcntl.h> -#include <poll.h> -#include <signal.h> -#include <sys/mman.h> -#include <sys/time.h> -#include <dirent.h> - -#ifdef HAVE_SYS_VFS_H -#include <sys/vfs.h> -#else -#include <sys/param.h> -#include <sys/mount.h> -#endif - -#include <glibmm.h> -#include <glibmm/thread.h> - -#include <midi++/mmc.h> -#include <midi++/port.h> - -#include <pbd/error.h> -#include <pbd/pathscanner.h> -#include <pbd/pthread_utils.h> -#include <pbd/search_path.h> -#include <pbd/stacktrace.h> - -#include <ardour/audioengine.h> -#include <ardour/configuration.h> -#include <ardour/session.h> -#include <ardour/session_directory.h> -#include <ardour/session_utils.h> -#include <ardour/session_state_utils.h> -#include <ardour/buffer.h> -#include <ardour/audio_diskstream.h> -#include <ardour/midi_diskstream.h> -#include <ardour/utils.h> -#include <ardour/audioplaylist.h> -#include <ardour/midi_playlist.h> -#include <ardour/smf_source.h> -#include <ardour/audiofilesource.h> -#include <ardour/silentfilesource.h> -#include <ardour/sndfilesource.h> -#include <ardour/midi_source.h> -#include <ardour/sndfile_helpers.h> -#include <ardour/auditioner.h> -#include <ardour/export.h> -#include <ardour/io_processor.h> -#include <ardour/send.h> -#include <ardour/processor.h> -#include <ardour/bundle.h> -#include <ardour/slave.h> -#include <ardour/tempo.h> -#include <ardour/audio_track.h> -#include <ardour/midi_track.h> -#include <ardour/cycle_timer.h> -#include <ardour/utils.h> -#include <ardour/named_selection.h> -#include <ardour/version.h> -#include <ardour/location.h> -#include <ardour/audioregion.h> -#include <ardour/midi_region.h> -#include <ardour/crossfade.h> -#include <ardour/control_protocol_manager.h> -#include <ardour/region_factory.h> -#include <ardour/source_factory.h> -#include <ardour/playlist_factory.h> -#include <ardour/filename_extensions.h> -#include <ardour/directory_names.h> -#include <ardour/template_utils.h> - -#include <control_protocol/control_protocol.h> - -#include "i18n.h" -#include <locale.h> - -using namespace std; -using namespace ARDOUR; -using namespace PBD; - -void -Session::first_stage_init (string fullpath, string snapshot_name) -{ - if (fullpath.length() == 0) { - destroy (); - throw failed_constructor(); - } - - char buf[PATH_MAX+1]; - if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) { - error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg; - destroy (); - throw failed_constructor(); - } - - _path = string(buf); - - if (_path[_path.length()-1] != '/') { - _path += '/'; - } - - /* these two are just provisional settings. set_state() - will likely override them. - */ - - _name = _current_snapshot_name = snapshot_name; - - set_history_depth (Config->get_history_depth()); - - _current_frame_rate = _engine.frame_rate (); - _nominal_frame_rate = _current_frame_rate; - _base_frame_rate = _current_frame_rate; - - _tempo_map = new TempoMap (_current_frame_rate); - _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed)); - - - - g_atomic_int_set (&processing_prohibited, 0); - insert_cnt = 0; - _transport_speed = 0; - _last_transport_speed = 0; - auto_play_legal = false; - transport_sub_state = 0; - _transport_frame = 0; - last_stop_frame = 0; - end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd))); - start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart))); - _end_location_is_free = true; - g_atomic_int_set (&_record_status, Disabled); - loop_changing = false; - play_loop = false; - _last_roll_location = 0; - _last_record_location = 0; - pending_locate_frame = 0; - pending_locate_roll = false; - pending_locate_flush = false; - audio_dstream_buffer_size = 0; - midi_dstream_buffer_size = 0; - state_tree = 0; - state_was_pending = false; - set_next_event (); - outbound_mtc_smpte_frame = 0; - next_quarter_frame_to_send = -1; - current_block_size = 0; - solo_update_disabled = false; - currently_soloing = false; - _have_captured = false; - _worst_output_latency = 0; - _worst_input_latency = 0; - _worst_track_latency = 0; - _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading); - - _slave = 0; - butler_mixdown_buffer = 0; - butler_gain_buffer = 0; - mmc = 0; - session_send_mmc = false; - session_send_mtc = false; - post_transport_work = PostTransportWork (0); - g_atomic_int_set (&butler_should_do_transport_work, 0); - g_atomic_int_set (&butler_active, 0); - g_atomic_int_set (&_playback_load, 100); - g_atomic_int_set (&_capture_load, 100); - g_atomic_int_set (&_playback_load_min, 100); - g_atomic_int_set (&_capture_load_min, 100); - _play_range = false; - waiting_to_start = false; - _exporting = false; - _gain_automation_buffer = 0; - _pan_automation_buffer = 0; - _npan_buffers = 0; - pending_abort = false; - destructive_index = 0; - current_trans = 0; - first_file_data_format_reset = true; - first_file_header_format_reset = true; - butler_thread = (pthread_t) 0; - //midi_thread = (pthread_t) 0; - - AudioDiskstream::allocate_working_buffers(); - - /* default short fade = 15ms */ - - Crossfade::set_short_xfade_length ((nframes_t) floor (Config->get_short_xfade_seconds() * frame_rate())); - SndFileSource::setup_standard_crossfades (frame_rate()); - - last_mmc_step.tv_sec = 0; - last_mmc_step.tv_usec = 0; - step_speed = 0.0; - - /* click sounds are unset by default, which causes us to internal - waveforms for clicks. - */ - - click_data = 0; - click_emphasis_data = 0; - click_length = 0; - click_emphasis_length = 0; - _clicking = false; - - process_function = &Session::process_with_events; - - if (Config->get_use_video_sync()) { - waiting_for_sync_offset = true; - } else { - waiting_for_sync_offset = false; - } - - last_smpte_when = 0; - _smpte_offset = 0; - _smpte_offset_negative = true; - last_smpte_valid = false; - - sync_time_vars (); - - last_rr_session_dir = session_dirs.begin(); - refresh_disk_space (); - - // set_default_fade (0.2, 5.0); /* steepness, millisecs */ - - /* slave stuff */ - - average_slave_delta = 1800; - have_first_delta_accumulator = false; - delta_accumulator_cnt = 0; - slave_state = Stopped; - - _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered)); - - /* These are all static "per-class" signals */ - - RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region)); - SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source)); - PlaylistFactory::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist)); - Processor::ProcessorCreated.connect (mem_fun (*this, &Session::add_processor)); - NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection)); - AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list)); - - Controllable::Destroyed.connect (mem_fun (*this, &Session::remove_controllable)); - - IO::PortCountChanged.connect (mem_fun (*this, &Session::ensure_buffers)); - - /* stop IO objects from doing stuff until we're ready for them */ - - IO::disable_panners (); - IO::disable_ports (); - IO::disable_connecting (); -} - -int -Session::second_stage_init (bool new_session) -{ - AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string()); - - if (!new_session) { - if (load_state (_current_snapshot_name)) { - return -1; - } - remove_empty_sounds (); - } - - if (start_butler_thread()) { - return -1; - } - - if (start_midi_thread ()) { - return -1; - } - - // set_state() will call setup_raid_path(), but if it's a new session we need - // to call setup_raid_path() here. - - if (state_tree) { - if (set_state (*state_tree->root())) { - return -1; - } - } else { - setup_raid_path(_path); - } - - /* we can't save till after ::when_engine_running() is called, - because otherwise we save state with no connections made. - therefore, we reset _state_of_the_state because ::set_state() - will have cleared it. - - we also have to include Loading so that any events that get - generated between here and the end of ::when_engine_running() - will be processed directly rather than queued. - */ - - _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading); - - - _locations.changed.connect (mem_fun (this, &Session::locations_changed)); - _locations.added.connect (mem_fun (this, &Session::locations_added)); - setup_click_sounds (0); - setup_midi_control (); - - /* Pay attention ... */ - - _engine.Halted.connect (mem_fun (*this, &Session::engine_halted)); - _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery)); - - try { - when_engine_running(); - } - - /* handle this one in a different way than all others, so that its clear what happened */ - - catch (AudioEngine::PortRegistrationFailure& err) { - error << _("Unable to create all required ports") - << endmsg; - return -1; - } - - catch (...) { - return -1; - } - - BootMessage (_("Reset Remote Controls")); - - send_full_time_code (0); - _engine.transport_locate (0); - deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0); - deliver_mmc (MIDI::MachineControl::cmdLocate, 0); - - BootMessage (_("Reset Control Protocols")); - - ControlProtocolManager::instance().set_session (*this); - - if (new_session) { - _end_location_is_free = true; - } else { - _end_location_is_free = false; - } - - _state_of_the_state = Clean; - - DirtyChanged (); /* EMIT SIGNAL */ - - if (state_was_pending) { - save_state (_current_snapshot_name); - remove_pending_capture_state (); - state_was_pending = false; - } - - BootMessage (_("Session loading complete")); - - return 0; -} - -string -Session::raid_path () const -{ - SearchPath raid_search_path; - - for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) { - raid_search_path += sys::path((*i).path); - } - - return raid_search_path.to_string (); -} - -void -Session::setup_raid_path (string path) -{ - if (path.empty()) { - return; - } - - space_and_path sp; - string fspath; - - session_dirs.clear (); - - SearchPath search_path(path); - SearchPath sound_search_path; - SearchPath midi_search_path; - - for ( - SearchPath::const_iterator i = search_path.begin(); - i != search_path.end(); - ++i - ) - { - sp.path = (*i).to_string (); - sp.blocks = 0; // not needed - session_dirs.push_back (sp); - - SessionDirectory sdir(sp.path); - - sound_search_path += sdir.sound_path (); - midi_search_path += sdir.midi_path (); - } - - // set the AudioFileSource and SMFSource search path - - AudioFileSource::set_search_path (sound_search_path.to_string ()); - SMFSource::set_search_path (midi_search_path.to_string ()); - - // reset the round-robin soundfile path thingie - - last_rr_session_dir = session_dirs.begin(); -} - -int -Session::ensure_subdirs () -{ - string dir; - - dir = session_directory().peak_path().to_string(); - - if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) { - error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg; - return -1; - } - - dir = session_directory().sound_path().to_string(); - - if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) { - error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg; - return -1; - } - - dir = session_directory().midi_path().to_string(); - - if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) { - error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg; - return -1; - } - - dir = session_directory().dead_sound_path().to_string(); - - if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) { - error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg; - return -1; - } - - dir = session_directory().export_path().to_string(); - - if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) { - error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg; - return -1; - } - - dir = analysis_dir (); - - if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) { - error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg; - return -1; - } - - return 0; -} - -int -Session::create (bool& new_session, const string& mix_template, nframes_t initial_length) -{ - - if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) { - error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg; - return -1; - } - - if (ensure_subdirs ()) { - return -1; - } - - /* check new_session so we don't overwrite an existing one */ - - if (!mix_template.empty()) { - std::string in_path = mix_template; - - ifstream in(in_path.c_str()); - - if (in){ - string out_path = _path; - out_path += _name; - out_path += statefile_suffix; - - ofstream out(out_path.c_str()); - - if (out){ - out << in.rdbuf(); - - // okay, session is set up. Treat like normal saved - // session from now on. - - new_session = false; - return 0; - - } else { - error << string_compose (_("Could not open %1 for writing mix template"), out_path) - << endmsg; - return -1; - } - - } else { - error << string_compose (_("Could not open mix template %1 for reading"), in_path) - << endmsg; - return -1; - } - - } - - /* set initial start + end point */ - - start_location->set_end (0); - _locations.add (start_location); - - end_location->set_end (initial_length); - _locations.add (end_location); - - _state_of_the_state = Clean; - - save_state (""); - - return 0; -} - - -int -Session::load_diskstreams (const XMLNode& node) -{ - XMLNodeList clist; - XMLNodeConstIterator citer; - - clist = node.children(); - - for (citer = clist.begin(); citer != clist.end(); ++citer) { - - try { - /* diskstreams added automatically by DiskstreamCreated handler */ - if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") { - boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer)); - add_diskstream (dstream); - } else if ((*citer)->name() == "MidiDiskstream") { - boost::shared_ptr<MidiDiskstream> dstream (new MidiDiskstream (*this, **citer)); - add_diskstream (dstream); - } else { - error << _("Session: unknown diskstream type in XML") << endmsg; - } - } - - catch (failed_constructor& err) { - error << _("Session: could not load diskstream via XML state") << endmsg; - return -1; - } - } - - return 0; -} - -void -Session::maybe_write_autosave() -{ - if (dirty() && record_status() != Recording) { - save_state("", true); - } -} - -void -Session::remove_pending_capture_state () -{ - sys::path pending_state_file_path(_session_dir->root_path()); - - pending_state_file_path /= _current_snapshot_name + pending_suffix; - - try - { - sys::remove (pending_state_file_path); - } - catch(sys::filesystem_error& ex) - { - error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"), - pending_state_file_path.to_string(), ex.what()) << endmsg; - } -} - -/** Rename a state file. - * @param snapshot_name Snapshot name. - */ -void -Session::rename_state (string old_name, string new_name) -{ - if (old_name == _current_snapshot_name || old_name == _name) { - /* refuse to rename the current snapshot or the "main" one */ - return; - } - - const string old_xml_filename = old_name + statefile_suffix; - const string new_xml_filename = new_name + statefile_suffix; - - const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename; - const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename; - - try - { - sys::rename (old_xml_path, new_xml_path); - } - catch (const sys::filesystem_error& err) - { - error << string_compose(_("could not rename snapshot %1 to %2 (%3)"), - old_name, new_name, err.what()) << endmsg; - } -} - -/** Remove a state file. - * @param snapshot_name Snapshot name. - */ -void -Session::remove_state (string snapshot_name) -{ - if (snapshot_name == _current_snapshot_name || snapshot_name == _name) { - // refuse to remove the current snapshot or the "main" one - return; - } - - sys::path xml_path(_session_dir->root_path()); - - xml_path /= snapshot_name + statefile_suffix; - - if (!create_backup_file (xml_path)) { - // don't remove it if a backup can't be made - // create_backup_file will log the error. - return; - } - - // and delete it - sys::remove (xml_path); -} - -int -Session::save_state (string snapshot_name, bool pending) -{ - XMLTree tree; - sys::path xml_path(_session_dir->root_path()); - - if (_state_of_the_state & CannotSave) { - return 1; - } - - if (!_engine.connected ()) { - error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved") - << endmsg; - return 1; - } - - /* tell sources we're saving first, in case they write out to a new file - * which should be saved with the state rather than the old one */ - for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) - i->second->session_saved(); - - tree.set_root (&get_state()); - - if (snapshot_name.empty()) { - snapshot_name = _current_snapshot_name; - } - - if (!pending) { - - /* proper save: use statefile_suffix (.ardour in English) */ - - xml_path /= snapshot_name + statefile_suffix; - - /* make a backup copy of the old file */ - - if (sys::exists(xml_path) && !create_backup_file (xml_path)) { - // create_backup_file will log the error - return -1; - } - - } else { - - /* pending save: use pending_suffix (.pending in English) */ - xml_path /= snapshot_name + pending_suffix; - } - - sys::path tmp_path(_session_dir->root_path()); - - tmp_path /= snapshot_name + temp_suffix; - - // cerr << "actually writing state to " << xml_path.to_string() << endl; - - if (!tree.write (tmp_path.to_string())) { - error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg; - sys::remove (tmp_path); - return -1; - - } else { - - if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) { - error << string_compose (_("could not rename temporary session file %1 to %2"), - tmp_path.to_string(), xml_path.to_string()) << endmsg; - sys::remove (tmp_path); - return -1; - } - } - - if (!pending) { - - save_history (snapshot_name); - - bool was_dirty = dirty(); - - _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty); - - if (was_dirty) { - DirtyChanged (); /* EMIT SIGNAL */ - } - - StateSaved (snapshot_name); /* EMIT SIGNAL */ - } - - return 0; -} - -int -Session::restore_state (string snapshot_name) -{ - if (load_state (snapshot_name) == 0) { - set_state (*state_tree->root()); - } - - return 0; -} - -int -Session::load_state (string snapshot_name) -{ - if (state_tree) { - delete state_tree; - state_tree = 0; - } - - state_was_pending = false; - - /* check for leftover pending state from a crashed capture attempt */ - - sys::path xmlpath(_session_dir->root_path()); - xmlpath /= snapshot_name + pending_suffix; - - if (sys::exists (xmlpath)) { - - /* there is pending state from a crashed capture attempt */ - - if (AskAboutPendingState()) { - state_was_pending = true; - } - } - - if (!state_was_pending) { - xmlpath = _session_dir->root_path(); - xmlpath /= snapshot_name + statefile_suffix; - } - - if (!sys::exists (xmlpath)) { - error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg; - return 1; - } - - state_tree = new XMLTree; - - set_dirty(); - - if (!state_tree->read (xmlpath.to_string())) { - error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg; - delete state_tree; - state_tree = 0; - return -1; - } - - XMLNode& root (*state_tree->root()); - - if (root.name() != X_("Session")) { - error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath.to_string()) << endmsg; - delete state_tree; - state_tree = 0; - return -1; - } - - const XMLProperty* prop; - bool is_old = false; - - if ((prop = root.property ("version")) == 0) { - /* no version implies very old version of Ardour */ - is_old = true; - } else { - int major_version; - major_version = atoi (prop->value().c_str()); // grab just the first number before the period - if (major_version < 2) { - is_old = true; - } - } - - if (is_old) { - - sys::path backup_path(_session_dir->root_path()); - - backup_path /= snapshot_name + "-1" + statefile_suffix; - - // only create a backup once - if (sys::exists (backup_path)) { - return 0; - } - - info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"), - xmlpath.to_string(), backup_path.to_string()) - << endmsg; - - try - { - sys::copy_file (xmlpath, backup_path); - } - catch(sys::filesystem_error& ex) - { - error << string_compose (_("Unable to make backup of state file %1 (%2)"), - xmlpath.to_string(), ex.what()) - << endmsg; - return -1; - } - } - - return 0; -} - -int -Session::load_options (const XMLNode& node) -{ - XMLNode* child; - XMLProperty* prop; - LocaleGuard lg (X_("POSIX")); - - Config->set_variables (node, ConfigVariableBase::Session); - - if ((child = find_named_node (node, "end-marker-is-free")) != 0) { - if ((prop = child->property ("val")) != 0) { - _end_location_is_free = (prop->value() == "yes"); - } - } - - return 0; -} - -bool -Session::save_config_options_predicate (ConfigVariableBase::Owner owner) const -{ - const ConfigVariableBase::Owner modified_by_session_or_user = (ConfigVariableBase::Owner) - (ConfigVariableBase::Session|ConfigVariableBase::Interface); - - return owner & modified_by_session_or_user; -} - -XMLNode& -Session::get_options () const -{ - XMLNode* child; - LocaleGuard lg (X_("POSIX")); - - XMLNode& option_root = Config->get_variables (mem_fun (*this, &Session::save_config_options_predicate)); - - child = option_root.add_child ("end-marker-is-free"); - child->add_property ("val", _end_location_is_free ? "yes" : "no"); - - return option_root; -} - -XMLNode& -Session::get_state() -{ - return state(true); -} - -XMLNode& -Session::get_template() -{ - /* if we don't disable rec-enable, diskstreams - will believe they need to store their capture - sources in their state node. - */ - - disable_record (false); - - return state(false); -} - -XMLNode& -Session::state(bool full_state) -{ - XMLNode* node = new XMLNode("Session"); - XMLNode* child; - - // store libardour version, just in case - char buf[16]; - snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version); - node->add_property("version", string(buf)); - - /* store configuration settings */ - - if (full_state) { - - node->add_property ("name", _name); - snprintf (buf, sizeof (buf), "%" PRId32, _nominal_frame_rate); - node->add_property ("sample-rate", buf); - - if (session_dirs.size() > 1) { - - string p; - - vector<space_and_path>::iterator i = session_dirs.begin(); - vector<space_and_path>::iterator next; - - ++i; /* skip the first one */ - next = i; - ++next; - - while (i != session_dirs.end()) { - - p += (*i).path; - - if (next != session_dirs.end()) { - p += ':'; - } else { - break; - } - - ++next; - ++i; - } - - child = node->add_child ("Path"); - child->add_content (p); - } - } - - /* save the ID counter */ - - snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter()); - node->add_property ("id-counter", buf); - - /* various options */ - - node->add_child_nocopy (get_options()); - - child = node->add_child ("Sources"); - - if (full_state) { - Glib::Mutex::Lock sl (source_lock); - - for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) { - - /* Don't save information about AudioFileSources that are empty */ - - boost::shared_ptr<AudioFileSource> fs; - - if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) { - - /* Don't save sources that are empty, unless they're destructive (which are OK - if they are empty, because we will re-use them every time.) - */ - - if (!fs->destructive()) { - if (fs->length() == 0) { - continue; - } - } - } - - child->add_child_nocopy (siter->second->get_state()); - } - } - - child = node->add_child ("Regions"); - - if (full_state) { - Glib::Mutex::Lock rl (region_lock); - - for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) { - - /* only store regions not attached to playlists */ - - if (i->second->playlist() == 0) { - child->add_child_nocopy (i->second->state (true)); - } - } - } - - child = node->add_child ("DiskStreams"); - - { - boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader(); - for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) { - if (!(*i)->hidden()) { - child->add_child_nocopy ((*i)->get_state()); - } - } - } - - if (full_state) { - node->add_child_nocopy (_locations.get_state()); - } else { - // for a template, just create a new Locations, populate it - // with the default start and end, and get the state for that. - Locations loc; - Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart))); - Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd))); - start->set_end(0); - loc.add (start); - end->set_end(compute_initial_length()); - loc.add (end); - node->add_child_nocopy (loc.get_state()); - } - - child = node->add_child ("Bundles"); - { - Glib::Mutex::Lock lm (bundle_lock); - for (BundleList::iterator i = _bundles.begin(); i != _bundles.end(); ++i) { - boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i); - if (b) { - child->add_child_nocopy (b->get_state()); - } - } - } - - child = node->add_child ("Routes"); - { - boost::shared_ptr<RouteList> r = routes.reader (); - - RoutePublicOrderSorter cmp; - RouteList public_order (*r); - public_order.sort (cmp); - - for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) { - if (!(*i)->is_hidden()) { - if (full_state) { - child->add_child_nocopy ((*i)->get_state()); - } else { - child->add_child_nocopy ((*i)->get_template()); - } - } - } - } - - - child = node->add_child ("EditGroups"); - for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) { - child->add_child_nocopy ((*i)->get_state()); - } - - child = node->add_child ("MixGroups"); - for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) { - child->add_child_nocopy ((*i)->get_state()); - } - - child = node->add_child ("Playlists"); - for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) { - if (!(*i)->hidden()) { - if (!(*i)->empty()) { - if (full_state) { - child->add_child_nocopy ((*i)->get_state()); - } else { - child->add_child_nocopy ((*i)->get_template()); - } - } - } - } - - child = node->add_child ("UnusedPlaylists"); - for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) { - if (!(*i)->hidden()) { - if (!(*i)->empty()) { - if (full_state) { - child->add_child_nocopy ((*i)->get_state()); - } else { - child->add_child_nocopy ((*i)->get_template()); - } - } - } - } - - - if (_click_io) { - child = node->add_child ("Click"); - child->add_child_nocopy (_click_io->state (full_state)); - } - - if (full_state) { - child = node->add_child ("NamedSelections"); - for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) { - if (full_state) { - child->add_child_nocopy ((*i)->get_state()); - } - } - } - - node->add_child_nocopy (_tempo_map->get_state()); - - node->add_child_nocopy (get_control_protocol_state()); - - if (_extra_xml) { - node->add_child_copy (*_extra_xml); - } - - return *node; -} - -XMLNode& -Session::get_control_protocol_state () -{ - ControlProtocolManager& cpm (ControlProtocolManager::instance()); - return cpm.get_state(); -} - -int -Session::set_state (const XMLNode& node) -{ - XMLNodeList nlist; - XMLNode* child; - const XMLProperty* prop; - int ret = -1; - - _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave); - - if (node.name() != X_("Session")){ - fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg; - return -1; - } - - if ((prop = node.property ("name")) != 0) { - _name = prop->value (); - } - - if ((prop = node.property (X_("sample-rate"))) != 0) { - - _nominal_frame_rate = atoi (prop->value()); - - if (_nominal_frame_rate != _current_frame_rate) { - if (AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate)) { - return -1; - } - } - } - - setup_raid_path(_session_dir->root_path().to_string()); - - if ((prop = node.property (X_("id-counter"))) != 0) { - uint64_t x; - sscanf (prop->value().c_str(), "%" PRIu64, &x); - ID::init_counter (x); - } else { - /* old sessions used a timebased counter, so fake - the startup ID counter based on a standard - timestamp. - */ - time_t now; - time (&now); - ID::init_counter (now); - } - - - IO::disable_ports (); - IO::disable_connecting (); - - /* Object loading order: - - MIDI Control - Path - extra - Options/Config - Locations - Sources - AudioRegions - AudioDiskstreams - Connections - Routes - EditGroups - MixGroups - Click - ControlProtocols - */ - - if (use_config_midi_ports ()) { - } - - if ((child = find_named_node (node, "extra")) != 0) { - _extra_xml = new XMLNode (*child); - } - - if (((child = find_named_node (node, "Options")) != 0)) { /* old style */ - load_options (*child); - } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */ - load_options (*child); - } else { - error << _("Session: XML state has no options section") << endmsg; - } - - if ((child = find_named_node (node, "Locations")) == 0) { - error << _("Session: XML state has no locations section") << endmsg; - goto out; - } else if (_locations.set_state (*child)) { - goto out; - } - - Location* location; - - if ((location = _locations.auto_loop_location()) != 0) { - set_auto_loop_location (location); - } - - if ((location = _locations.auto_punch_location()) != 0) { - set_auto_punch_location (location); - } - - if ((location = _locations.end_location()) == 0) { - _locations.add (end_location); - } else { - delete end_location; - end_location = location; - } - - if ((location = _locations.start_location()) == 0) { - _locations.add (start_location); - } else { - delete start_location; - start_location = location; - } - - AudioFileSource::set_header_position_offset (start_location->start()); - - if ((child = find_named_node (node, "Sources")) == 0) { - error << _("Session: XML state has no sources section") << endmsg; - goto out; - } else if (load_sources (*child)) { - goto out; - } - - if ((child = find_named_node (node, "Regions")) == 0) { - error << _("Session: XML state has no Regions section") << endmsg; - goto out; - } else if (load_regions (*child)) { - goto out; - } - - if ((child = find_named_node (node, "Playlists")) == 0) { - error << _("Session: XML state has no playlists section") << endmsg; - goto out; - } else if (load_playlists (*child)) { - goto out; - } - - if ((child = find_named_node (node, "UnusedPlaylists")) == 0) { - // this is OK - } else if (load_unused_playlists (*child)) { - goto out; - } - - if ((child = find_named_node (node, "NamedSelections")) != 0) { - if (load_named_selections (*child)) { - goto out; - } - } - - if ((child = find_named_node (node, "DiskStreams")) == 0) { - error << _("Session: XML state has no diskstreams section") << endmsg; - goto out; - } else if (load_diskstreams (*child)) { - goto out; - } - - if ((child = find_named_node (node, "Bundles")) == 0) { - warning << _("Session: XML state has no bundles section (2.0 session?)") << endmsg; - //goto out; - } else { - /* We can't load Bundles yet as they need to be able - to convert from port names to Port objects, which can't happen until - later */ - _bundle_xml_node = new XMLNode (*child); - } - - if ((child = find_named_node (node, "EditGroups")) == 0) { - error << _("Session: XML state has no edit groups section") << endmsg; - goto out; - } else if (load_edit_groups (*child)) { - goto out; - } - - if ((child = find_named_node (node, "MixGroups")) == 0) { - error << _("Session: XML state has no mix groups section") << endmsg; - goto out; - } else if (load_mix_groups (*child)) { - goto out; - } - - if ((child = find_named_node (node, "TempoMap")) == 0) { - error << _("Session: XML state has no Tempo Map section") << endmsg; - goto out; - } else if (_tempo_map->set_state (*child)) { - goto out; - } - - if ((child = find_named_node (node, "Routes")) == 0) { - error << _("Session: XML state has no routes section") << endmsg; - goto out; - } else if (load_routes (*child)) { - goto out; - } - - if ((child = find_named_node (node, "Click")) == 0) { - warning << _("Session: XML state has no click section") << endmsg; - } else if (_click_io) { - _click_io->set_state (*child); - } - - if ((child = find_named_node (node, "ControlProtocols")) != 0) { - ControlProtocolManager::instance().set_protocol_states (*child); - } - - /* here beginneth the second phase ... */ - - StateReady (); /* EMIT SIGNAL */ - - return 0; - - out: - return ret; -} - -int -Session::load_routes (const XMLNode& node) -{ - XMLNodeList nlist; - XMLNodeConstIterator niter; - RouteList new_routes; - - nlist = node.children(); - - set_dirty(); - - for (niter = nlist.begin(); niter != nlist.end(); ++niter) { - - boost::shared_ptr<Route> route (XMLRouteFactory (**niter)); - - if (route == 0) { - error << _("Session: cannot create Route from XML description.") << endmsg; - return -1; - } - - BootMessage (string_compose (_("Loaded track/bus %1"), route->name())); - - new_routes.push_back (route); - } - - add_routes (new_routes, false); - - return 0; -} - -boost::shared_ptr<Route> -Session::XMLRouteFactory (const XMLNode& node) -{ - if (node.name() != "Route") { - return boost::shared_ptr<Route> ((Route*) 0); - } - - bool has_diskstream = (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0); - - DataType type = DataType::AUDIO; - const XMLProperty* prop = node.property("default-type"); - if (prop) - type = DataType(prop->value()); - - assert(type != DataType::NIL); - - if (has_diskstream) { - if (type == DataType::AUDIO) { - boost::shared_ptr<Route> ret (new AudioTrack (*this, node)); - return ret; - } else { - boost::shared_ptr<Route> ret (new MidiTrack (*this, node)); - return ret; - } - } else { - boost::shared_ptr<Route> ret (new Route (*this, node)); - return ret; - } -} - -int -Session::load_regions (const XMLNode& node) -{ - XMLNodeList nlist; - XMLNodeConstIterator niter; - boost::shared_ptr<Region> region; - - nlist = node.children(); - - set_dirty(); - - for (niter = nlist.begin(); niter != nlist.end(); ++niter) { - if ((region = XMLRegionFactory (**niter, false)) == 0) { - error << _("Session: cannot create Region from XML description."); - const XMLProperty *name = (**niter).property("name"); - - if (name) { - error << " " << string_compose (_("Can not load state for region '%1'"), name->value()); - } - - error << endmsg; - } - } - - return 0; -} - -boost::shared_ptr<Region> -Session::XMLRegionFactory (const XMLNode& node, bool full) -{ - const XMLProperty* type = node.property("type"); - - try { - - if ( !type || type->value() == "audio" ) { - - return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full)); - - } else if (type->value() == "midi") { - - return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full)); - - } - - } catch (failed_constructor& err) { - return boost::shared_ptr<Region> (); - } - - return boost::shared_ptr<Region> (); -} - -boost::shared_ptr<AudioRegion> -Session::XMLAudioRegionFactory (const XMLNode& node, bool full) -{ - const XMLProperty* prop; - boost::shared_ptr<Source> source; - boost::shared_ptr<AudioSource> as; - SourceList sources; - SourceList master_sources; - uint32_t nchans = 1; - char buf[128]; - - if (node.name() != X_("Region")) { - return boost::shared_ptr<AudioRegion>(); - } - - if ((prop = node.property (X_("channels"))) != 0) { - nchans = atoi (prop->value().c_str()); - } - - if ((prop = node.property ("name")) == 0) { - cerr << "no name for this region\n"; - abort (); - } - - if ((prop = node.property (X_("source-0"))) == 0) { - if ((prop = node.property ("source")) == 0) { - error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg; - return boost::shared_ptr<AudioRegion>(); - } - } - - PBD::ID s_id (prop->value()); - - if ((source = source_by_id (s_id)) == 0) { - error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg; - return boost::shared_ptr<AudioRegion>(); - } - - as = boost::dynamic_pointer_cast<AudioSource>(source); - if (!as) { - error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg; - return boost::shared_ptr<AudioRegion>(); - } - - sources.push_back (as); - - /* pickup other channels */ - - for (uint32_t n=1; n < nchans; ++n) { - snprintf (buf, sizeof(buf), X_("source-%d"), n); - if ((prop = node.property (buf)) != 0) { - - PBD::ID id2 (prop->value()); - - if ((source = source_by_id (id2)) == 0) { - error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg; - return boost::shared_ptr<AudioRegion>(); - } - - as = boost::dynamic_pointer_cast<AudioSource>(source); - if (!as) { - error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg; - return boost::shared_ptr<AudioRegion>(); - } - sources.push_back (as); - } - } - - for (uint32_t n=1; n < nchans; ++n) { - snprintf (buf, sizeof(buf), X_("master-source-%d"), n); - if ((prop = node.property (buf)) != 0) { - - PBD::ID id2 (prop->value()); - - if ((source = source_by_id (id2)) == 0) { - error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg; - return boost::shared_ptr<AudioRegion>(); - } - - as = boost::dynamic_pointer_cast<AudioSource>(source); - if (!as) { - error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg; - return boost::shared_ptr<AudioRegion>(); - } - master_sources.push_back (as); - } - } - - try { - boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node))); - - /* a final detail: this is the one and only place that we know how long missing files are */ - - if (region->whole_file()) { - for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) { - boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx); - if (sfp) { - sfp->set_length (region->length()); - } - } - } - - if (!master_sources.empty()) { - if (master_sources.size() == nchans) { - error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg; - } else { - region->set_master_sources (master_sources); - } - } - - return region; - - } - - catch (failed_constructor& err) { - return boost::shared_ptr<AudioRegion>(); - } -} - -boost::shared_ptr<MidiRegion> -Session::XMLMidiRegionFactory (const XMLNode& node, bool full) -{ - const XMLProperty* prop; - boost::shared_ptr<Source> source; - boost::shared_ptr<MidiSource> ms; - SourceList sources; - uint32_t nchans = 1; - - if (node.name() != X_("Region")) { - return boost::shared_ptr<MidiRegion>(); - } - - if ((prop = node.property (X_("channels"))) != 0) { - nchans = atoi (prop->value().c_str()); - } - - if ((prop = node.property ("name")) == 0) { - cerr << "no name for this region\n"; - abort (); - } - - // Multiple midi channels? that's just crazy talk - assert(nchans == 1); - - if ((prop = node.property (X_("source-0"))) == 0) { - if ((prop = node.property ("source")) == 0) { - error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg; - return boost::shared_ptr<MidiRegion>(); - } - } - - PBD::ID s_id (prop->value()); - - if ((source = source_by_id (s_id)) == 0) { - error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg; - return boost::shared_ptr<MidiRegion>(); - } - - ms = boost::dynamic_pointer_cast<MidiSource>(source); - if (!ms) { - error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg; - return boost::shared_ptr<MidiRegion>(); - } - - sources.push_back (ms); - - try { - boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node))); - /* a final detail: this is the one and only place that we know how long missing files are */ - - if (region->whole_file()) { - for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) { - boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx); - if (sfp) { - sfp->set_length (region->length()); - } - } - } - - return region; - } - - catch (failed_constructor& err) { - return boost::shared_ptr<MidiRegion>(); - } -} - -XMLNode& -Session::get_sources_as_xml () - -{ - XMLNode* node = new XMLNode (X_("Sources")); - Glib::Mutex::Lock lm (source_lock); - - for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) { - node->add_child_nocopy (i->second->get_state()); - } - - return *node; -} - -string -Session::path_from_region_name (DataType type, string name, string identifier) -{ - char buf[PATH_MAX+1]; - uint32_t n; - SessionDirectory sdir(get_best_session_directory_for_new_source()); - sys::path source_dir = ((type == DataType::AUDIO) - ? sdir.sound_path() : sdir.midi_path()); - - string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid"); - - for (n = 0; n < 999999; ++n) { - if (identifier.length()) { - snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(), - identifier.c_str(), n, ext.c_str()); - } else { - snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(), - n, ext.c_str()); - } - - sys::path source_path = source_dir / buf; - - if (!sys::exists (source_path)) { - return source_path.to_string(); - } - } - - error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"), - name, identifier) - << endmsg; - - return ""; -} - - -int -Session::load_sources (const XMLNode& node) -{ - XMLNodeList nlist; - XMLNodeConstIterator niter; - boost::shared_ptr<Source> source; - - nlist = node.children(); - - set_dirty(); - - for (niter = nlist.begin(); niter != nlist.end(); ++niter) { - - try { - if ((source = XMLSourceFactory (**niter)) == 0) { - error << _("Session: cannot create Source from XML description.") << endmsg; - } - } - - catch (non_existent_source& err) { - warning << _("A sound file is missing. It will be replaced by silence.") << endmsg; - source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate); - } - } - - return 0; -} - -boost::shared_ptr<Source> -Session::XMLSourceFactory (const XMLNode& node) -{ - if (node.name() != "Source") { - return boost::shared_ptr<Source>(); - } - - try { - /* note: do peak building in another thread when loading session state */ - return SourceFactory::create (*this, node, true); - } - - catch (failed_constructor& err) { - error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg; - return boost::shared_ptr<Source>(); - } -} - -int -Session::save_template (string template_name) -{ - XMLTree tree; - - if (_state_of_the_state & CannotSave) { - return -1; - } - - sys::path user_template_dir(user_template_directory()); - - try - { - sys::create_directories (user_template_dir); - } - catch(sys::filesystem_error& ex) - { - error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"), - user_template_dir.to_string(), ex.what()) << endmsg; - return -1; - } - - tree.set_root (&get_template()); - - sys::path template_file_path(user_template_dir); - template_file_path /= template_name + template_suffix; - - if (sys::exists (template_file_path)) - { - warning << string_compose(_("Template \"%1\" already exists - new version not created"), - template_file_path.to_string()) << endmsg; - return -1; - } - - if (!tree.write (template_file_path.to_string())) { - error << _("mix template not saved") << endmsg; - return -1; - } - - return 0; -} - -void -Session::refresh_disk_space () -{ -#if HAVE_SYS_VFS_H - struct statfs statfsbuf; - vector<space_and_path>::iterator i; - Glib::Mutex::Lock lm (space_lock); - double scale; - - /* get freespace on every FS that is part of the session path */ - - _total_free_4k_blocks = 0; - - for (i = session_dirs.begin(); i != session_dirs.end(); ++i) { - statfs ((*i).path.c_str(), &statfsbuf); - - scale = statfsbuf.f_bsize/4096.0; - - (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale); - _total_free_4k_blocks += (*i).blocks; - } -#endif -} - -string -Session::get_best_session_directory_for_new_source () -{ - vector<space_and_path>::iterator i; - string result = _session_dir->root_path().to_string(); - - /* handle common case without system calls */ - - if (session_dirs.size() == 1) { - return result; - } - - /* OK, here's the algorithm we're following here: - - We want to select which directory to use for - the next file source to be created. Ideally, - we'd like to use a round-robin process so as to - get maximum performance benefits from splitting - the files across multiple disks. - - However, in situations without much diskspace, an - RR approach may end up filling up a filesystem - with new files while others still have space. - Its therefore important to pay some attention to - the freespace in the filesystem holding each - directory as well. However, if we did that by - itself, we'd keep creating new files in the file - system with the most space until it was as full - as all others, thus negating any performance - benefits of this RAID-1 like approach. - - So, we use a user-configurable space threshold. If - there are at least 2 filesystems with more than this - much space available, we use RR selection between them. - If not, then we pick the filesystem with the most space. - - This gets a good balance between the two - approaches. - */ - - refresh_disk_space (); - - int free_enough = 0; - - for (i = session_dirs.begin(); i != session_dirs.end(); ++i) { - if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) { - free_enough++; - } - } - - if (free_enough >= 2) { - /* use RR selection process, ensuring that the one - picked works OK. - */ - - i = last_rr_session_dir; - - do { - if (++i == session_dirs.end()) { - i = session_dirs.begin(); - } - - if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) { - if (create_session_directory ((*i).path)) { - result = (*i).path; - last_rr_session_dir = i; - return result; - } - } - - } while (i != last_rr_session_dir); - - } else { - - /* pick FS with the most freespace (and that - seems to actually work ...) - */ - - vector<space_and_path> sorted; - space_and_path_ascending_cmp cmp; - - sorted = session_dirs; - sort (sorted.begin(), sorted.end(), cmp); - - for (i = sorted.begin(); i != sorted.end(); ++i) { - if (create_session_directory ((*i).path)) { - result = (*i).path; - last_rr_session_dir = i; - return result; - } - } - } - - return result; -} - -int -Session::load_playlists (const XMLNode& node) -{ - XMLNodeList nlist; - XMLNodeConstIterator niter; - boost::shared_ptr<Playlist> playlist; - - nlist = node.children(); - - set_dirty(); - - for (niter = nlist.begin(); niter != nlist.end(); ++niter) { - - if ((playlist = XMLPlaylistFactory (**niter)) == 0) { - error << _("Session: cannot create Playlist from XML description.") << endmsg; - } - } - - return 0; -} - -int -Session::load_unused_playlists (const XMLNode& node) -{ - XMLNodeList nlist; - XMLNodeConstIterator niter; - boost::shared_ptr<Playlist> playlist; - - nlist = node.children(); - - set_dirty(); - - for (niter = nlist.begin(); niter != nlist.end(); ++niter) { - - if ((playlist = XMLPlaylistFactory (**niter)) == 0) { - error << _("Session: cannot create Playlist from XML description.") << endmsg; - continue; - } - - // now manually untrack it - - track_playlist (false, boost::weak_ptr<Playlist> (playlist)); - } - - return 0; -} - -boost::shared_ptr<Playlist> -Session::XMLPlaylistFactory (const XMLNode& node) -{ - try { - return PlaylistFactory::create (*this, node); - } - - catch (failed_constructor& err) { - return boost::shared_ptr<Playlist>(); - } -} - -int -Session::load_named_selections (const XMLNode& node) -{ - XMLNodeList nlist; - XMLNodeConstIterator niter; - NamedSelection *ns; - - nlist = node.children(); - - set_dirty(); - - for (niter = nlist.begin(); niter != nlist.end(); ++niter) { - - if ((ns = XMLNamedSelectionFactory (**niter)) == 0) { - error << _("Session: cannot create Named Selection from XML description.") << endmsg; - } - } - - return 0; -} - -NamedSelection * -Session::XMLNamedSelectionFactory (const XMLNode& node) -{ - try { - return new NamedSelection (*this, node); - } - - catch (failed_constructor& err) { - return 0; - } -} - -string -Session::automation_dir () const -{ - string res = _path; - res += "automation/"; - return res; -} - -string -Session::analysis_dir () const -{ - string res = _path; - res += "analysis/"; - return res; -} - -int -Session::load_bundles (XMLNode const & node) -{ - XMLNodeList nlist = node.children(); - XMLNodeConstIterator niter; - - set_dirty(); - - for (niter = nlist.begin(); niter != nlist.end(); ++niter) { - if ((*niter)->name() == "InputBundle") { - add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true))); - } else if ((*niter)->name() == "OutputBundle") { - add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false))); - } else { - error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg; - return -1; - } - } - - return 0; -} - -int -Session::load_edit_groups (const XMLNode& node) -{ - return load_route_groups (node, true); -} - -int -Session::load_mix_groups (const XMLNode& node) -{ - return load_route_groups (node, false); -} - -int -Session::load_route_groups (const XMLNode& node, bool edit) -{ - XMLNodeList nlist = node.children(); - XMLNodeConstIterator niter; - RouteGroup* rg; - - set_dirty(); - - for (niter = nlist.begin(); niter != nlist.end(); ++niter) { - if ((*niter)->name() == "RouteGroup") { - if (edit) { - rg = add_edit_group (""); - rg->set_state (**niter); - } else { - rg = add_mix_group (""); - rg->set_state (**niter); - } - } - } - - return 0; -} - -void -Session::auto_save() -{ - save_state (_current_snapshot_name); -} - -static bool -state_file_filter (const string &str, void *arg) -{ - return (str.length() > strlen(statefile_suffix) && - str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix))); -} - -struct string_cmp { - bool operator()(const string* a, const string* b) { - return *a < *b; - } -}; - -static string* -remove_end(string* state) -{ - string statename(*state); - - string::size_type start,end; - if ((start = statename.find_last_of ('/')) != string::npos) { - statename = statename.substr (start+1); - } - - if ((end = statename.rfind(".ardour")) == string::npos) { - end = statename.length(); - } - - return new string(statename.substr (0, end)); -} - -vector<string *> * -Session::possible_states (string path) -{ - PathScanner scanner; - vector<string*>* states = scanner (path, state_file_filter, 0, false, false); - - transform(states->begin(), states->end(), states->begin(), remove_end); - - string_cmp cmp; - sort (states->begin(), states->end(), cmp); - - return states; -} - -vector<string *> * -Session::possible_states () const -{ - return possible_states(_path); -} - -RouteGroup * -Session::add_edit_group (string name) -{ - RouteGroup* rg = new RouteGroup (*this, name); - edit_groups.push_back (rg); - edit_group_added (rg); /* EMIT SIGNAL */ - set_dirty(); - return rg; -} - -RouteGroup * -Session::add_mix_group (string name) -{ - RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative); - mix_groups.push_back (rg); - mix_group_added (rg); /* EMIT SIGNAL */ - set_dirty(); - return rg; -} - -void -Session::remove_edit_group (RouteGroup& rg) -{ - list<RouteGroup*>::iterator i; - - if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) { - (*i)->apply (&Route::drop_edit_group, this); - edit_groups.erase (i); - edit_group_removed (); /* EMIT SIGNAL */ - } - - delete &rg; -} - -void -Session::remove_mix_group (RouteGroup& rg) -{ - list<RouteGroup*>::iterator i; - - if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) { - (*i)->apply (&Route::drop_mix_group, this); - mix_groups.erase (i); - mix_group_removed (); /* EMIT SIGNAL */ - } - - delete &rg; -} - -RouteGroup * -Session::mix_group_by_name (string name) -{ - list<RouteGroup *>::iterator i; - - for (i = mix_groups.begin(); i != mix_groups.end(); ++i) { - if ((*i)->name() == name) { - return* i; - } - } - return 0; -} - -RouteGroup * -Session::edit_group_by_name (string name) -{ - list<RouteGroup *>::iterator i; - - for (i = edit_groups.begin(); i != edit_groups.end(); ++i) { - if ((*i)->name() == name) { - return* i; - } - } - return 0; -} - -void -Session::begin_reversible_command (const string& name) -{ - current_trans = new UndoTransaction; - current_trans->set_name (name); -} - -void -Session::commit_reversible_command (Command *cmd) -{ - struct timeval now; - - if (cmd) { - current_trans->add_command (cmd); - } - - if (current_trans->empty()) { - return; - } - - gettimeofday (&now, 0); - current_trans->set_timestamp (now); - - _history.add (current_trans); -} - -Session::GlobalRouteBooleanState -Session::get_global_route_boolean (bool (Route::*method)(void) const) -{ - GlobalRouteBooleanState s; - boost::shared_ptr<RouteList> r = routes.reader (); - - for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - if (!(*i)->is_hidden()) { - RouteBooleanState v; - - v.first =* i; - Route* r = (*i).get(); - v.second = (r->*method)(); - - s.push_back (v); - } - } - - return s; -} - -Session::GlobalRouteMeterState -Session::get_global_route_metering () -{ - GlobalRouteMeterState s; - boost::shared_ptr<RouteList> r = routes.reader (); - - for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - if (!(*i)->is_hidden()) { - RouteMeterState v; - - v.first =* i; - v.second = (*i)->meter_point(); - - s.push_back (v); - } - } - - return s; -} - -void -Session::set_global_route_metering (GlobalRouteMeterState s, void* arg) -{ - for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) { - - boost::shared_ptr<Route> r = (i->first.lock()); - - if (r) { - r->set_meter_point (i->second, arg); - } - } -} - -void -Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg) -{ - for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) { - - boost::shared_ptr<Route> r = (i->first.lock()); - - if (r) { - Route* rp = r.get(); - (rp->*method) (i->second, arg); - } - } -} - -void -Session::set_global_mute (GlobalRouteBooleanState s, void* src) -{ - set_global_route_boolean (s, &Route::set_mute, src); -} - -void -Session::set_global_solo (GlobalRouteBooleanState s, void* src) -{ - set_global_route_boolean (s, &Route::set_solo, src); -} - -void -Session::set_global_record_enable (GlobalRouteBooleanState s, void* src) -{ - set_global_route_boolean (s, &Route::set_record_enable, src); -} - -#if 0 -UndoAction -Session::global_mute_memento (void* src) -{ - return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src); -} - -UndoAction -Session::global_metering_memento (void* src) -{ - return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src); -} - -UndoAction -Session::global_solo_memento (void* src) -{ - return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src); -} - -UndoAction -Session::global_record_enable_memento (void* src) -{ - return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src); -} -#endif - -static bool -accept_all_non_peak_files (const string& path, void *arg) -{ - return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5)); -} - -static bool -accept_all_state_files (const string& path, void *arg) -{ - return (path.length() > 7 && path.find (".ardour") == (path.length() - 7)); -} - -int -Session::find_all_sources (string path, set<string>& result) -{ - XMLTree tree; - XMLNode* node; - - if (!tree.read (path)) { - return -1; - } - - if ((node = find_named_node (*tree.root(), "Sources")) == 0) { - return -2; - } - - XMLNodeList nlist; - XMLNodeConstIterator niter; - - nlist = node->children(); - - set_dirty(); - - for (niter = nlist.begin(); niter != nlist.end(); ++niter) { - - XMLProperty* prop; - - if ((prop = (*niter)->property (X_("name"))) == 0) { - continue; - } - - if (prop->value()[0] == '/') { - /* external file, ignore */ - continue; - } - - sys::path source_path = _session_dir->sound_path (); - - source_path /= prop->value (); - - result.insert (source_path.to_string ()); - } - - return 0; -} - -int -Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot) -{ - PathScanner scanner; - vector<string*>* state_files; - string ripped; - string this_snapshot_path; - - result.clear (); - - ripped = _path; - - if (ripped[ripped.length()-1] == '/') { - ripped = ripped.substr (0, ripped.length() - 1); - } - - state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true); - - if (state_files == 0) { - /* impossible! */ - return 0; - } - - this_snapshot_path = _path; - this_snapshot_path += _current_snapshot_name; - this_snapshot_path += statefile_suffix; - - for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) { - - if (exclude_this_snapshot && **i == this_snapshot_path) { - continue; - } - - if (find_all_sources (**i, result) < 0) { - return -1; - } - } - - return 0; -} - -struct RegionCounter { - typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList; - AudioSourceList::iterator iter; - boost::shared_ptr<Region> region; - uint32_t count; - - RegionCounter() : count (0) {} -}; - -int -Session::cleanup_sources (Session::cleanup_report& rep) -{ - // FIXME: needs adaptation to midi - - vector<boost::shared_ptr<Source> > dead_sources; - vector<boost::shared_ptr<Playlist> > playlists_tbd; - PathScanner scanner; - string sound_path; - vector<space_and_path>::iterator i; - vector<space_and_path>::iterator nexti; - vector<string*>* soundfiles; - vector<string> unused; - set<string> all_sources; - bool used; - string spath; - int ret = -1; - - _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup); - - - /* step 1: consider deleting all unused playlists */ - - for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) { - int status; - - status = AskAboutPlaylistDeletion (*x); - - switch (status) { - case -1: - ret = 0; - goto out; - break; - - case 0: - playlists_tbd.push_back (*x); - break; - - default: - /* leave it alone */ - break; - } - } - - /* now delete any that were marked for deletion */ - - for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) { - (*x)->drop_references (); - } - - playlists_tbd.clear (); - - /* step 2: find all un-used sources */ - - rep.paths.clear (); - rep.space = 0; - - for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) { - - SourceMap::iterator tmp; - - tmp = i; - ++tmp; - - /* do not bother with files that are zero size, otherwise we remove the current "nascent" - capture files. - */ - - if (!i->second->used() && i->second->length() > 0) { - dead_sources.push_back (i->second); - i->second->GoingAway(); - } - - i = tmp; - } - - /* build a list of all the possible sound directories for the session */ - - for (i = session_dirs.begin(); i != session_dirs.end(); ) { - - nexti = i; - ++nexti; - - SessionDirectory sdir ((*i).path); - sound_path += sdir.sound_path().to_string(); - - if (nexti != session_dirs.end()) { - sound_path += ':'; - } - - i = nexti; - } - - /* now do the same thing for the files that ended up in the sounds dir(s) - but are not referenced as sources in any snapshot. - */ - - soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true); - - if (soundfiles == 0) { - return 0; - } - - /* find all sources, but don't use this snapshot because the - state file on disk still references sources we may have already - dropped. - */ - - find_all_sources_across_snapshots (all_sources, true); - - /* add our current source list - */ - - for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) { - boost::shared_ptr<AudioFileSource> fs; - - if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) { - all_sources.insert (fs->path()); - } - } - - char tmppath1[PATH_MAX+1]; - char tmppath2[PATH_MAX+1]; - - for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) { - - used = false; - spath = **x; - - for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) { - - realpath(spath.c_str(), tmppath1); - realpath((*i).c_str(), tmppath2); - - if (strcmp(tmppath1, tmppath2) == 0) { - used = true; - break; - } - } - - if (!used) { - unused.push_back (spath); - } - } - - /* now try to move all unused files into the "dead_sounds" directory(ies) */ - - for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) { - struct stat statbuf; - - rep.paths.push_back (*x); - if (stat ((*x).c_str(), &statbuf) == 0) { - rep.space += statbuf.st_size; - } - - string newpath; - - /* don't move the file across filesystems, just - stick it in the `dead_sound_dir_name' directory - on whichever filesystem it was already on. - */ - - if ((*x).find ("/sounds/") != string::npos) { - - /* old school, go up 1 level */ - - newpath = Glib::path_get_dirname (*x); // "sounds" - newpath = Glib::path_get_dirname (newpath); // "session-name" - - } else { - - /* new school, go up 4 levels */ - - newpath = Glib::path_get_dirname (*x); // "audiofiles" - newpath = Glib::path_get_dirname (newpath); // "session-name" - newpath = Glib::path_get_dirname (newpath); // "interchange" - newpath = Glib::path_get_dirname (newpath); // "session-dir" - } - - newpath += '/'; - newpath += dead_sound_dir_name; - - if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) { - error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg; - return -1; - } - - newpath += '/'; - newpath += Glib::path_get_basename ((*x)); - - if (access (newpath.c_str(), F_OK) == 0) { - - /* the new path already exists, try versioning */ - - char buf[PATH_MAX+1]; - int version = 1; - string newpath_v; - - snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version); - newpath_v = buf; - - while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) { - snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version); - newpath_v = buf; - } - - if (version == 999) { - error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"), - newpath) - << endmsg; - } else { - newpath = newpath_v; - } - - } else { - - /* it doesn't exist, or we can't read it or something */ - - } - - if (::rename ((*x).c_str(), newpath.c_str()) != 0) { - error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"), - (*x), newpath, strerror (errno)) - << endmsg; - goto out; - } - - /* see if there an easy to find peakfile for this file, and remove it. - */ - - string peakpath = (*x).substr (0, (*x).find_last_of ('.')); - peakpath += peakfile_suffix; - - if (access (peakpath.c_str(), W_OK) == 0) { - if (::unlink (peakpath.c_str()) != 0) { - error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"), - peakpath, _path, strerror (errno)) - << endmsg; - /* try to back out */ - rename (newpath.c_str(), _path.c_str()); - goto out; - } - } - } - - ret = 0; - - /* dump the history list */ - - _history.clear (); - - /* save state so we don't end up a session file - referring to non-existent sources. - */ - - save_state (""); - - out: - _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup); - - return ret; -} - -int -Session::cleanup_trash_sources (Session::cleanup_report& rep) -{ - // FIXME: needs adaptation for MIDI - - vector<space_and_path>::iterator i; - string dead_sound_dir; - struct dirent* dentry; - struct stat statbuf; - DIR* dead; - - rep.paths.clear (); - rep.space = 0; - - for (i = session_dirs.begin(); i != session_dirs.end(); ++i) { - - dead_sound_dir = (*i).path; - dead_sound_dir += dead_sound_dir_name; - - if ((dead = opendir (dead_sound_dir.c_str())) == 0) { - continue; - } - - while ((dentry = readdir (dead)) != 0) { - - /* avoid '.' and '..' */ - - if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') || - (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) { - continue; - } - - string fullpath; - - fullpath = dead_sound_dir; - fullpath += '/'; - fullpath += dentry->d_name; - - if (stat (fullpath.c_str(), &statbuf)) { - continue; - } - - if (!S_ISREG (statbuf.st_mode)) { - continue; - } - - if (unlink (fullpath.c_str())) { - error << string_compose (_("cannot remove dead sound file %1 (%2)"), - fullpath, strerror (errno)) - << endmsg; - } - - rep.paths.push_back (dentry->d_name); - rep.space += statbuf.st_size; - } - - closedir (dead); - - } - - return 0; -} - -void -Session::set_dirty () -{ - bool was_dirty = dirty(); - - _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty); - - - if (!was_dirty) { - DirtyChanged(); /* EMIT SIGNAL */ - } -} - - -void -Session::set_clean () -{ - bool was_dirty = dirty(); - - _state_of_the_state = Clean; - - - if (was_dirty) { - DirtyChanged(); /* EMIT SIGNAL */ - } -} - -void -Session::set_deletion_in_progress () -{ - _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion); - -} - -void -Session::add_controllable (boost::shared_ptr<Controllable> c) -{ - /* this adds a controllable to the list managed by the Session. - this is a subset of those managed by the Controllable class - itself, and represents the only ones whose state will be saved - as part of the session. - */ - - Glib::Mutex::Lock lm (controllables_lock); - controllables.insert (c); -} - -struct null_deleter { void operator()(void const *) const {} }; - -void -Session::remove_controllable (Controllable* c) -{ - if (_state_of_the_state | Deletion) { - return; - } - - Glib::Mutex::Lock lm (controllables_lock); - - Controllables::iterator x = controllables.find( - boost::shared_ptr<Controllable>(c, null_deleter())); - - if (x != controllables.end()) { - controllables.erase (x); - } -} - -boost::shared_ptr<Controllable> -Session::controllable_by_id (const PBD::ID& id) -{ - Glib::Mutex::Lock lm (controllables_lock); - - for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) { - if ((*i)->id() == id) { - return *i; - } - } - - return boost::shared_ptr<Controllable>(); -} - -void -Session::add_instant_xml (XMLNode& node) -{ - Stateful::add_instant_xml (node, _path); - Config->add_instant_xml (node); -} - -XMLNode* -Session::instant_xml (const string& node_name) -{ - return Stateful::instant_xml (node_name, _path); -} - -int -Session::save_history (string snapshot_name) -{ - XMLTree tree; - - if (snapshot_name.empty()) { - snapshot_name = _current_snapshot_name; - } - - const string history_filename = snapshot_name + history_suffix; - const string backup_filename = history_filename + backup_suffix; - const sys::path xml_path = _session_dir->root_path() / history_filename; - const sys::path backup_path = _session_dir->root_path() / backup_filename; - - if (sys::exists (xml_path)) { - try - { - sys::rename (xml_path, backup_path); - } - catch (const sys::filesystem_error& err) - { - error << _("could not backup old history file, current history not saved") << endmsg; - return -1; - } - } - - - if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) { - return 0; - } - - tree.set_root (&_history.get_state (Config->get_saved_history_depth())); - - if (!tree.write (xml_path.to_string())) - { - error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg; - - try - { - sys::remove (xml_path); - sys::rename (backup_path, xml_path); - } - catch (const sys::filesystem_error& err) - { - error << string_compose (_("could not restore history file from backup %1 (%2)"), - backup_path.to_string(), err.what()) << endmsg; - } - - return -1; - } - - return 0; -} - -int -Session::restore_history (string snapshot_name) -{ - XMLTree tree; - - if (snapshot_name.empty()) { - snapshot_name = _current_snapshot_name; - } - - const string xml_filename = snapshot_name + history_suffix; - const sys::path xml_path = _session_dir->root_path() / xml_filename; - - cerr << "Loading history from " << xml_path.to_string() << endmsg; - - if (!sys::exists (xml_path)) { - info << string_compose (_("%1: no history file \"%2\" for this session."), - _name, xml_path.to_string()) << endmsg; - return 1; - } - - if (!tree.read (xml_path.to_string())) { - error << string_compose (_("Could not understand session history file \"%1\""), - xml_path.to_string()) << endmsg; - return -1; - } - - // replace history - _history.clear(); - - for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) { - - XMLNode *t = *it; - UndoTransaction* ut = new UndoTransaction (); - struct timeval tv; - - ut->set_name(t->property("name")->value()); - stringstream ss(t->property("tv_sec")->value()); - ss >> tv.tv_sec; - ss.str(t->property("tv_usec")->value()); - ss >> tv.tv_usec; - ut->set_timestamp(tv); - - for (XMLNodeConstIterator child_it = t->children().begin(); - child_it != t->children().end(); - child_it++) - { - XMLNode *n = *child_it; - Command *c; - - if (n->name() == "MementoCommand" || - n->name() == "MementoUndoCommand" || - n->name() == "MementoRedoCommand") { - - if ((c = memento_command_factory(n))) { - ut->add_command(c); - } - - } else if (n->name() == X_("GlobalRouteStateCommand")) { - - if ((c = global_state_command_factory (*n))) { - ut->add_command (c); - } - - } else if (n->name() == "DeltaCommand") { - PBD::ID id(n->property("midi_source")->value()); - boost::shared_ptr<MidiSource> midi_source = - boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id)); - if(midi_source) { - ut->add_command(new MidiModel::DeltaCommand(midi_source->model(), *n)); - } else { - error << "FIXME: Failed to downcast MidiSource for DeltaCommand" << endmsg; - } - } else { - error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg; - } - } - - _history.add (ut); - } - - return 0; -} - -void -Session::config_changed (const char* parameter_name) -{ -#define PARAM_IS(x) (!strcmp (parameter_name, (x))) - - if (PARAM_IS ("seamless-loop")) { - - } else if (PARAM_IS ("rf-speed")) { - - } else if (PARAM_IS ("auto-loop")) { - - } else if (PARAM_IS ("auto-input")) { - - if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) { - /* auto-input only makes a difference if we're rolling */ - - boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader(); - - for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) { - if ((*i)->record_enabled ()) { - (*i)->monitor_input (!Config->get_auto_input()); - } - } - } - - } else if (PARAM_IS ("punch-in")) { - - Location* location; - - if ((location = _locations.auto_punch_location()) != 0) { - - if (Config->get_punch_in ()) { - replace_event (Event::PunchIn, location->start()); - } else { - remove_event (location->start(), Event::PunchIn); - } - } - - } else if (PARAM_IS ("punch-out")) { - - Location* location; - - if ((location = _locations.auto_punch_location()) != 0) { - - if (Config->get_punch_out()) { - replace_event (Event::PunchOut, location->end()); - } else { - clear_events (Event::PunchOut); - } - } - - } else if (PARAM_IS ("edit-mode")) { - - Glib::Mutex::Lock lm (playlist_lock); - - for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) { - (*i)->set_edit_mode (Config->get_edit_mode ()); - } - - } else if (PARAM_IS ("use-video-sync")) { - - waiting_for_sync_offset = Config->get_use_video_sync(); - - } else if (PARAM_IS ("mmc-control")) { - - //poke_midi_thread (); - - } else if (PARAM_IS ("mmc-device-id") || PARAM_IS ("mmc-receive-id")) { - - if (mmc) { - mmc->set_receive_device_id (Config->get_mmc_receive_device_id()); - } - - } else if (PARAM_IS ("mmc-send-id")) { - - if (mmc) { - mmc->set_send_device_id (Config->get_mmc_send_device_id()); - } - - } else if (PARAM_IS ("midi-control")) { - - //poke_midi_thread (); - - } else if (PARAM_IS ("raid-path")) { - - setup_raid_path (Config->get_raid_path()); - - } else if (PARAM_IS ("smpte-format")) { - - sync_time_vars (); - - } else if (PARAM_IS ("video-pullup")) { - - sync_time_vars (); - - } else if (PARAM_IS ("seamless-loop")) { - - if (play_loop && transport_rolling()) { - // to reset diskstreams etc - request_play_loop (true); - } - - } else if (PARAM_IS ("rf-speed")) { - - cumulative_rf_motion = 0; - reset_rf_scale (0); - - } else if (PARAM_IS ("click-sound")) { - - setup_click_sounds (1); - - } else if (PARAM_IS ("click-emphasis-sound")) { - - setup_click_sounds (-1); - - } else if (PARAM_IS ("clicking")) { - - if (Config->get_clicking()) { - if (_click_io && click_data) { // don't require emphasis data - _clicking = true; - } - } else { - _clicking = false; - } - - } else if (PARAM_IS ("send-mtc")) { - - /* only set the internal flag if we have - a port. - */ - - if (_mtc_port != 0) { - session_send_mtc = Config->get_send_mtc(); - if (session_send_mtc) { - /* mark us ready to send */ - next_quarter_frame_to_send = 0; - } - } else { - session_send_mtc = false; - } - - } else if (PARAM_IS ("send-mmc")) { - - /* only set the internal flag if we have - a port. - */ - - if (_mmc_port != 0) { - session_send_mmc = Config->get_send_mmc(); - } else { - mmc = 0; - session_send_mmc = false; - } - - } else if (PARAM_IS ("midi-feedback")) { - - /* only set the internal flag if we have - a port. - */ - - if (_mtc_port != 0) { - session_midi_feedback = Config->get_midi_feedback(); - } - - } else if (PARAM_IS ("jack-time-master")) { - - engine().reset_timebase (); - - } else if (PARAM_IS ("native-file-header-format")) { - - if (!first_file_header_format_reset) { - reset_native_file_format (); - } - - first_file_header_format_reset = false; - - } else if (PARAM_IS ("native-file-data-format")) { - - if (!first_file_data_format_reset) { - reset_native_file_format (); - } - - first_file_data_format_reset = false; - - } else if (PARAM_IS ("slave-source")) { - set_slave_source (Config->get_slave_source()); - } else if (PARAM_IS ("remote-model")) { - set_remote_control_ids (); - } else if (PARAM_IS ("denormal-model")) { - setup_fpu (); - } else if (PARAM_IS ("history-depth")) { - set_history_depth (Config->get_history_depth()); - } else if (PARAM_IS ("sync-all-route-ordering")) { - sync_order_keys (); - } - - set_dirty (); - -#undef PARAM_IS - -} - -void -Session::set_history_depth (uint32_t d) -{ - _history.set_depth (d); -} diff --git a/libs/ardour/session_state_utils.cc b/libs/ardour/session_state_utils.cc deleted file mode 100644 index e57dce039e..0000000000 --- a/libs/ardour/session_state_utils.cc +++ /dev/null @@ -1,76 +0,0 @@ -/* - 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. -*/ - -#include <algorithm> - -#include <pbd/compose.h> -#include <pbd/error.h> -#include <pbd/file_utils.h> - -#include <ardour/session_state_utils.h> -#include <ardour/filename_extensions.h> - -#include "i18n.h" - -namespace ARDOUR { - -bool -create_backup_file (const sys::path & file_path) -{ - if (!sys::exists (file_path)) return false; - - sys::path backup_path(file_path.to_string() + backup_suffix); - - try - { - sys::copy_file (file_path, backup_path); - } - catch(sys::filesystem_error& ex) - { - error << string_compose (_("Unable to create a backup copy of file %1 (%2)"), - file_path.to_string(), ex.what()) - << endmsg; - return false; - } - return true; -} - -void -get_state_files_in_directory (const sys::path & directory_path, - vector<sys::path> & result) -{ - Glib::PatternSpec state_file_pattern('*' + string(statefile_suffix)); - - find_matching_files_in_directory (directory_path, state_file_pattern, - result); -} - -vector<string> -get_file_names_no_extension (const vector<sys::path> & file_paths) -{ - vector<string> result; - - std::transform (file_paths.begin(), file_paths.end(), - std::back_inserter(result), sys::basename); - - sort (result.begin(), result.end(), std::less<string>()); - - return result; -} - -} // namespace ARDOUR diff --git a/libs/ardour/session_time.cc b/libs/ardour/session_time.cc deleted file mode 100644 index a388e31d80..0000000000 --- a/libs/ardour/session_time.cc +++ /dev/null @@ -1,606 +0,0 @@ - -/* - Copyright (C) 1999-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. - -*/ - -#include <iostream> -#include <cmath> -#include <unistd.h> - -#include <ardour/timestamps.h> - -#include <pbd/error.h> -#include <pbd/enumwriter.h> -#include <pbd/stacktrace.h> - -#include <ardour/ardour.h> -#include <ardour/configuration.h> -#include <ardour/audioengine.h> -#include <ardour/session.h> -#include <ardour/tempo.h> - -#include "i18n.h" - -using namespace ARDOUR; -using namespace PBD; - -/* BBT TIME*/ - -void -Session::bbt_time (nframes_t when, BBT_Time& bbt) -{ - _tempo_map->bbt_time (when, bbt); -} - -/* SMPTE TIME */ -float -Session::smpte_frames_per_second() const -{ - switch (Config->get_smpte_format()) { - case smpte_23976: - return 23.976; - - break; - case smpte_24: - return 24; - - break; - case smpte_24976: - return 24.976; - - break; - case smpte_25: - return 25; - - break; - case smpte_2997: - return 29.97; - - break; - case smpte_2997drop: - return 29.97; - - break; - case smpte_30: - return 30; - - break; - case smpte_30drop: - return 30; - - break; - case smpte_5994: - return 59.94; - - break; - case smpte_60: - return 60; - - break; - default: - cerr << "Editor received unexpected smpte type" << endl; - } - return 30.0; -} -bool -Session::smpte_drop_frames() const -{ - switch (Config->get_smpte_format()) { - case smpte_23976: - return false; - - break; - case smpte_24: - return false; - - break; - case smpte_24976: - return false; - - break; - case smpte_25: - return false; - - break; - case smpte_2997: - return false; - - break; - case smpte_2997drop: - return true; - - break; - case smpte_30: - return false; - - break; - case smpte_30drop: - return true; - - break; - case smpte_5994: - return false; - - break; - case smpte_60: - return false; - - break; - default: - cerr << "Editor received unexpected smpte type" << endl; - } - return false; -} -void -Session::sync_time_vars () -{ - _current_frame_rate = (nframes_t) round (_base_frame_rate * (1.0 + (Config->get_video_pullup()/100.0))); - _frames_per_smpte_frame = (double) _current_frame_rate / (double) smpte_frames_per_second(); - if (smpte_drop_frames()) { - _frames_per_hour = (long)(107892 * _frames_per_smpte_frame); - } else { - _frames_per_hour = (long)(3600 * rint(smpte_frames_per_second()) * _frames_per_smpte_frame); - } - _smpte_frames_per_hour = (nframes_t)rint(smpte_frames_per_second() * 3600.0); - - last_smpte_valid = false; - // smpte type bits are the middle two in the upper nibble - switch ((int) ceil (smpte_frames_per_second())) { - case 24: - mtc_smpte_bits = 0; - break; - - case 25: - mtc_smpte_bits = 0x20; - break; - - case 30: - default: - if (smpte_drop_frames()) { - mtc_smpte_bits = 0x40; - } else { - mtc_smpte_bits = 0x60; - } - break; - }; -} - -int -Session::set_smpte_format (SmpteFormat format) -{ - /* this will trigger any other changes needed */ - Config->set_smpte_format (format); - return 0; -} - -void -Session::set_smpte_offset (nframes_t off) -{ - _smpte_offset = off; - last_smpte_valid = false; - - SMPTEOffsetChanged (); /* EMIT SIGNAL */ -} - -void -Session::set_smpte_offset_negative (bool neg) -{ - _smpte_offset_negative = neg; - last_smpte_valid = false; - - SMPTEOffsetChanged (); /* EMIT SIGNAL */ -} - -void -Session::smpte_to_sample( SMPTE::Time& smpte, nframes_t& sample, bool use_offset, bool use_subframes ) const -{ - - if (smpte.drop) { - // The drop frame format was created to better approximate the 30000/1001 = 29.97002997002997.... - // framerate of NTSC color TV. The used frame rate of drop frame is 29.97, which drifts by about - // 0.108 frame per hour, or about 1.3 frames per 12 hours. This is not perfect, but a lot better - // than using 30 non drop, which will drift with about 1.8 frame per minute. - // Using 29.97, drop frame real time can be accurate only every 10th minute (10 minutes of 29.97 fps - // is exactly 17982 frames). One minute is 1798.2 frames, but we count 30 frames per second - // (30 * 60 = 1800). This means that at the first minute boundary (at the end of 0:0:59:29) we - // are 1.8 frames too late relative to real time. By dropping 2 frames (jumping to 0:1:0:2) we are - // approx. 0.2 frames too early. This adds up with 0.2 too early for each minute until we are 1.8 - // frames too early at 0:9:0:2 (9 * 0.2 = 1.8). The 10th minute brings us 1.8 frames later again - // (at end of 0:9:59:29), which sums up to 0 (we are back to zero at 0:10:0:0 :-). - // - // In table form: - // - // SMPTE value frames offset subframes offset seconds (rounded) 44100 sample (rounded) - // 0:00:00:00 0.0 0 0.000 0 (accurate) - // 0:00:59:29 1.8 144 60.027 2647177 - // 0:01:00:02 -0.2 -16 60.060 2648648 - // 0:01:59:29 1.6 128 120.020 5292883 - // 0:02:00:02 -0.4 -32 120.053 5294354 - // 0:02:59:29 1.4 112 180.013 7938588 - // 0:03:00:02 -0.6 -48 180.047 7940060 - // 0:03:59:29 1.2 96 240.007 10584294 - // 0:04:00:02 -0.8 -64 240.040 10585766 - // 0:04:59:29 1.0 80 300.000 13230000 - // 0:05:00:02 -1.0 -80 300.033 13231471 - // 0:05:59:29 0.8 64 359.993 15875706 - // 0:06:00:02 -1.2 -96 360.027 15877177 - // 0:06:59:29 0.6 48 419.987 18521411 - // 0:07:00:02 -1.4 -112 420.020 18522883 - // 0:07:59:29 0.4 32 478.980 21167117 - // 0:08:00:02 -1.6 -128 480.013 21168589 - // 0:08:59:29 0.2 16 539.973 23812823 - // 0:09:00:02 -1.8 -144 540.007 23814294 - // 0:09:59:29 0.0+ 0+ 599.967 26458529 - // 0:10:00:00 0.0 0 600.000 26460000 (accurate) - // - // Per Sigmond <per@sigmond.no> - - // Samples inside time dividable by 10 minutes (real time accurate) - nframes_t base_samples = (nframes_t) (((smpte.hours * 107892) + ((smpte.minutes / 10) * 17982)) * _frames_per_smpte_frame); - - // Samples inside time exceeding the nearest 10 minutes (always offset, see above) - long exceeding_df_minutes = smpte.minutes % 10; - long exceeding_df_seconds = (exceeding_df_minutes * 60) + smpte.seconds; - long exceeding_df_frames = (30 * exceeding_df_seconds) + smpte.frames - (2 * exceeding_df_minutes); - nframes_t exceeding_samples = (nframes_t) rint(exceeding_df_frames * _frames_per_smpte_frame); - sample = base_samples + exceeding_samples; - } else { - /* - Non drop is easy.. just note the use of - rint(smpte.rate) * _frames_per_smpte_frame - (frames per SMPTE second), which is larger than - frame_rate() in the non-integer SMPTE rate case. - */ - - sample = (nframes_t)rint((((smpte.hours * 60 * 60) + (smpte.minutes * 60) + smpte.seconds) * (rint(smpte.rate) * _frames_per_smpte_frame)) + (smpte.frames * _frames_per_smpte_frame)); - } - - if (use_subframes) { - sample += (long) (((double)smpte.subframes * _frames_per_smpte_frame) / Config->get_subframes_per_frame()); - } - - if (use_offset) { - if (smpte_offset_negative()) { - if (sample >= smpte_offset()) { - sample -= smpte_offset(); - } else { - /* Prevent song-time from becoming negative */ - sample = 0; - } - } else { - if (smpte.negative) { - if (sample <= smpte_offset()) { - sample = smpte_offset() - sample; - } else { - sample = 0; - } - } else { - sample += smpte_offset(); - } - } - } - -} - - -void -Session::sample_to_smpte( nframes_t sample, SMPTE::Time& smpte, bool use_offset, bool use_subframes ) const -{ - nframes_t offset_sample; - - if (!use_offset) { - offset_sample = sample; - smpte.negative = false; - } else { - if (_smpte_offset_negative) { - offset_sample = sample + _smpte_offset; - smpte.negative = false; - } else { - if (sample < _smpte_offset) { - offset_sample = (_smpte_offset - sample); - smpte.negative = true; - } else { - offset_sample = sample - _smpte_offset; - smpte.negative = false; - } - } - } - - double smpte_frames_left_exact; - double smpte_frames_fraction; - unsigned long smpte_frames_left; - - // Extract whole hours. Do this to prevent rounding errors with - // high sample numbers in the calculations that follow. - smpte.hours = offset_sample / _frames_per_hour; - offset_sample = offset_sample % _frames_per_hour; - - // Calculate exact number of (exceeding) smpte frames and fractional frames - smpte_frames_left_exact = (double) offset_sample / _frames_per_smpte_frame; - smpte_frames_fraction = smpte_frames_left_exact - floor( smpte_frames_left_exact ); - smpte.subframes = (long) rint(smpte_frames_fraction * Config->get_subframes_per_frame()); - - // XXX Not sure if this is necessary anymore... - if (smpte.subframes == Config->get_subframes_per_frame()) { - // This can happen with 24 fps (and 29.97 fps ?) - smpte_frames_left_exact = ceil( smpte_frames_left_exact ); - smpte.subframes = 0; - } - - // Extract hour-exceeding frames for minute, second and frame calculations - smpte_frames_left = ((long) floor( smpte_frames_left_exact )); - - if (smpte_drop_frames()) { - // See long explanation in smpte_to_sample()... - - // Number of 10 minute chunks - smpte.minutes = (smpte_frames_left / 17982) * 10; // exactly 17982 frames in 10 minutes - // frames exceeding the nearest 10 minute barrier - long exceeding_df_frames = smpte_frames_left % 17982; - - // Find minutes exceeding the nearest 10 minute barrier - if (exceeding_df_frames >= 1800) { // nothing to do if we are inside the first minute (0-1799) - exceeding_df_frames -= 1800; // take away first minute (different number of frames than the others) - long extra_minutes_minus_1 = exceeding_df_frames / 1798; // how many minutes after the first one - exceeding_df_frames -= extra_minutes_minus_1 * 1798; // take away the (extra) minutes just found - smpte.minutes += extra_minutes_minus_1 + 1; // update with exceeding minutes - } - - // Adjust frame numbering for dropped frames (frame 0 and 1 skipped at start of every minute except every 10th) - if (smpte.minutes % 10) { - // Every minute except every 10th - if (exceeding_df_frames < 28) { - // First second, frames 0 and 1 are skipped - smpte.seconds = 0; - smpte.frames = exceeding_df_frames + 2; - } else { - // All other seconds, all 30 frames are counted - exceeding_df_frames -= 28; - smpte.seconds = (exceeding_df_frames / 30) + 1; - smpte.frames = exceeding_df_frames % 30; - } - } else { - // Every 10th minute, all 30 frames counted in all seconds - smpte.seconds = exceeding_df_frames / 30; - smpte.frames = exceeding_df_frames % 30; - } - } else { - // Non drop is easy - smpte.minutes = smpte_frames_left / ((long) rint (smpte_frames_per_second ()) * 60); - smpte_frames_left = smpte_frames_left % ((long) rint (smpte_frames_per_second ()) * 60); - smpte.seconds = smpte_frames_left / (long) rint(smpte_frames_per_second ()); - smpte.frames = smpte_frames_left % (long) rint(smpte_frames_per_second ()); - } - - if (!use_subframes) { - smpte.subframes = 0; - } - /* set frame rate and drop frame */ - smpte.rate = smpte_frames_per_second (); - smpte.drop = smpte_drop_frames(); -} - -void -Session::smpte_time (nframes_t when, SMPTE::Time& smpte) -{ - if (last_smpte_valid && when == last_smpte_when) { - smpte = last_smpte; - return; - } - - sample_to_smpte( when, smpte, true /* use_offset */, false /* use_subframes */ ); - - last_smpte_when = when; - last_smpte = smpte; - last_smpte_valid = true; -} - -void -Session::smpte_time_subframes (nframes_t when, SMPTE::Time& smpte) -{ - if (last_smpte_valid && when == last_smpte_when) { - smpte = last_smpte; - return; - } - - sample_to_smpte( when, smpte, true /* use_offset */, true /* use_subframes */ ); - - last_smpte_when = when; - last_smpte = smpte; - last_smpte_valid = true; -} - -void -Session::smpte_duration (nframes_t when, SMPTE::Time& smpte) const -{ - sample_to_smpte( when, smpte, false /* use_offset */, true /* use_subframes */ ); -} - -void -Session::smpte_duration_string (char* buf, nframes_t when) const -{ - SMPTE::Time smpte; - - smpte_duration (when, smpte); - snprintf (buf, sizeof (buf), "%02" PRIu32 ":%02" PRIu32 ":%02" PRIu32 ":%02" PRIu32, smpte.hours, smpte.minutes, smpte.seconds, smpte.frames); -} - -void -Session::smpte_time (SMPTE::Time &t) - -{ - smpte_time (_transport_frame, t); -} - -int -Session::jack_sync_callback (jack_transport_state_t state, - jack_position_t* pos) -{ - bool slave = synced_to_jack(); - - switch (state) { - case JackTransportStopped: - if (slave && _transport_frame != pos->frame && post_transport_work == 0) { - request_locate (pos->frame, false); - // cerr << "SYNC: stopped, locate to " << pos->frame << " from " << _transport_frame << endl; - return false; - } else { - return true; - } - - case JackTransportStarting: - // cerr << "SYNC: starting @ " << pos->frame << " a@ " << _transport_frame << " our work = " << post_transport_work << " pos matches ? " << (_transport_frame == pos->frame) << endl; - if (slave) { - return _transport_frame == pos->frame && post_transport_work == 0; - } else { - return true; - } - break; - - case JackTransportRolling: - // cerr << "SYNC: rolling slave = " << slave << endl; - if (slave) { - start_transport (); - } - break; - - default: - error << string_compose (_("Unknown JACK transport state %1 in sync callback"), state) - << endmsg; - } - - return true; -} - -void -Session::jack_timebase_callback (jack_transport_state_t state, - nframes_t nframes, - jack_position_t* pos, - int new_position) -{ - BBT_Time bbt; - - /* frame info */ - - pos->frame = _transport_frame; - pos->valid = JackPositionTimecode; - - /* BBT info */ - - if (_tempo_map) { - - TempoMap::Metric metric (_tempo_map->metric_at (_transport_frame)); - _tempo_map->bbt_time_with_metric (_transport_frame, bbt, metric); - - pos->bar = bbt.bars; - pos->beat = bbt.beats; - pos->tick = bbt.ticks; - - // XXX still need to set bar_start_tick - - pos->beats_per_bar = metric.meter().beats_per_bar(); - pos->beat_type = metric.meter().note_divisor(); - pos->ticks_per_beat = Meter::ticks_per_beat; - pos->beats_per_minute = metric.tempo().beats_per_minute(); - - pos->valid = jack_position_bits_t (pos->valid | JackPositionBBT); - } - -#ifdef HAVE_JACK_VIDEO_SUPPORT - //poke audio video ratio so Ardour can track Video Sync - pos->audio_frames_per_video_frame = frame_rate() / smpte_frames_per_second(); - pos->valid = jack_position_bits_t (pos->valid | JackAudioVideoRatio); -#endif - -#if 0 - /* SMPTE info */ - - t.smpte_offset = _smpte_offset; - t.smpte_frame_rate = smpte_frames_per_second(); - - if (_transport_speed) { - - if (play_loop) { - - Location* location = _locations.auto_loop_location(); - - if (location) { - - t.transport_state = JackTransportLooping; - t.loop_start = location->start(); - t.loop_end = location->end(); - t.valid = jack_transport_bits_t (t.valid | JackTransportLoop); - - } else { - - t.loop_start = 0; - t.loop_end = 0; - t.transport_state = JackTransportRolling; - - } - - } else { - - t.loop_start = 0; - t.loop_end = 0; - t.transport_state = JackTransportRolling; - - } - - } - -#endif -} - -ARDOUR::nframes_t -Session::convert_to_frames_at (nframes_t position, AnyTime& any) -{ - double secs; - - switch (any.type) { - case AnyTime::BBT: - return _tempo_map->frame_time ( any.bbt); - break; - - case AnyTime::SMPTE: - /* XXX need to handle negative values */ - secs = any.smpte.hours * 60 * 60; - secs += any.smpte.minutes * 60; - secs += any.smpte.seconds; - secs += any.smpte.frames / smpte_frames_per_second(); - if (_smpte_offset_negative) - { - return (nframes_t) floor (secs * frame_rate()) - _smpte_offset; - } - else - { - return (nframes_t) floor (secs * frame_rate()) + _smpte_offset; - } - break; - - case AnyTime::Seconds: - return (nframes_t) floor (any.seconds * frame_rate()); - break; - - case AnyTime::Frames: - return any.frames; - break; - } - - return any.frames; -} diff --git a/libs/ardour/session_transport.cc b/libs/ardour/session_transport.cc deleted file mode 100644 index c86a868e56..0000000000 --- a/libs/ardour/session_transport.cc +++ /dev/null @@ -1,1355 +0,0 @@ -/* - Copyright (C) 1999-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. - -*/ - -#include <cmath> -#include <cerrno> -#include <unistd.h> - -#include <sigc++/bind.h> -#include <sigc++/retype.h> - -#include <pbd/undo.h> -#include <pbd/error.h> -#include <glibmm/thread.h> -#include <pbd/pthread_utils.h> -#include <pbd/memento_command.h> -#include <pbd/stacktrace.h> - -#include <midi++/mmc.h> -#include <midi++/port.h> - -#include <ardour/ardour.h> -#include <ardour/audioengine.h> -#include <ardour/session.h> -#include <ardour/audio_diskstream.h> -#include <ardour/auditioner.h> -#include <ardour/slave.h> -#include <ardour/location.h> - -#include "i18n.h" - -using namespace std; -using namespace ARDOUR; -using namespace sigc; -using namespace PBD; - -void -Session::request_input_change_handling () -{ - if (!(_state_of_the_state & (InitialConnecting|Deletion))) { - Event* ev = new Event (Event::InputConfigurationChange, Event::Add, Event::Immediate, 0, 0.0); - queue_event (ev); - } -} - -void -Session::request_slave_source (SlaveSource src) -{ - Event* ev = new Event (Event::SetSlaveSource, Event::Add, Event::Immediate, 0, 0.0); - - if (src == JACK) { - /* could set_seamless_loop() be disposed of entirely?*/ - Config->set_seamless_loop (false); - } else { - Config->set_seamless_loop (true); - } - ev->slave = src; - queue_event (ev); -} - -void -Session::request_transport_speed (float speed) -{ - Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, speed); - queue_event (ev); -} - -void -Session::request_diskstream_speed (Diskstream& ds, float speed) -{ - Event* ev = new Event (Event::SetDiskstreamSpeed, Event::Add, Event::Immediate, 0, speed); - ev->set_ptr (&ds); - queue_event (ev); -} - -void -Session::request_stop (bool abort) -{ - Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0, abort); - queue_event (ev); -} - -void -Session::request_locate (nframes_t target_frame, bool with_roll) -{ - Event *ev = new Event (with_roll ? Event::LocateRoll : Event::Locate, Event::Add, Event::Immediate, target_frame, 0, false); - queue_event (ev); -} - -void -Session::force_locate (nframes_t target_frame, bool with_roll) -{ - Event *ev = new Event (with_roll ? Event::LocateRoll : Event::Locate, Event::Add, Event::Immediate, target_frame, 0, true); - queue_event (ev); -} - -void -Session::request_play_loop (bool yn) -{ - Event* ev; - Location *location = _locations.auto_loop_location(); - - if (location == 0 && yn) { - error << _("Cannot loop - no loop range defined") - << endmsg; - return; - } - - ev = new Event (Event::SetLoop, Event::Add, Event::Immediate, 0, 0.0, yn); - queue_event (ev); - - if (!yn && Config->get_seamless_loop() && transport_rolling()) { - // request an immediate locate to refresh the diskstreams - // after disabling looping - request_locate (_transport_frame-1, false); - } -} - -void -Session::realtime_stop (bool abort) -{ - /* assume that when we start, we'll be moving forwards */ - - // FIXME: where should this really be? [DR] - //send_full_time_code(); - deliver_mmc (MIDI::MachineControl::cmdStop, _transport_frame); - deliver_mmc (MIDI::MachineControl::cmdLocate, _transport_frame); - - if (_transport_speed < 0.0f) { - post_transport_work = PostTransportWork (post_transport_work | PostTransportStop | PostTransportReverse); - } else { - post_transport_work = PostTransportWork (post_transport_work | PostTransportStop); - } - - if (actively_recording()) { - - /* move the transport position back to where the - request for a stop was noticed. we rolled - past that point to pick up delayed input. - */ - -#ifndef LEAVE_TRANSPORT_UNADJUSTED - decrement_transport_position (_worst_output_latency); -#endif - - /* the duration change is not guaranteed to have happened, but is likely */ - - post_transport_work = PostTransportWork (post_transport_work | PostTransportDuration); - } - - if (abort) { - post_transport_work = PostTransportWork (post_transport_work | PostTransportAbort); - } - - _clear_event_type (Event::StopOnce); - _clear_event_type (Event::RangeStop); - _clear_event_type (Event::RangeLocate); - - disable_record (true); - - reset_slave_state (); - - _transport_speed = 0; - - if (Config->get_use_video_sync()) { - waiting_for_sync_offset = true; - } - - transport_sub_state = ((Config->get_slave_source() == None && Config->get_auto_return()) ? AutoReturning : 0); -} - -void -Session::butler_transport_work () -{ - restart: - bool finished; - boost::shared_ptr<RouteList> r = routes.reader (); - boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader(); - - int on_entry = g_atomic_int_get (&butler_should_do_transport_work); - finished = true; - - if (post_transport_work & PostTransportCurveRealloc) { - for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - (*i)->curve_reallocate(); - } - } - - if (post_transport_work & PostTransportInputChange) { - for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) { - (*i)->non_realtime_input_change (); - } - } - - if (post_transport_work & PostTransportSpeed) { - non_realtime_set_speed (); - } - - if (post_transport_work & PostTransportReverse) { - - - clear_clicks(); - cumulative_rf_motion = 0; - reset_rf_scale (0); - - /* don't seek if locate will take care of that in non_realtime_stop() */ - - if (!(post_transport_work & PostTransportLocate)) { - - for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) { - if (!(*i)->hidden()) { - if ((*i)->speed() != 1.0f || (*i)->speed() != -1.0f) { - (*i)->seek ((nframes_t) (_transport_frame * (double) (*i)->speed())); - } - else { - (*i)->seek (_transport_frame); - } - } - if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) { - /* new request, stop seeking, and start again */ - g_atomic_int_dec_and_test (&butler_should_do_transport_work); - goto restart; - } - } - } - } - - if (post_transport_work & PostTransportLocate) { - non_realtime_locate (); - } - - if (post_transport_work & PostTransportStop) { - non_realtime_stop (post_transport_work & PostTransportAbort, on_entry, finished); - if (!finished) { - g_atomic_int_dec_and_test (&butler_should_do_transport_work); - goto restart; - } - } - - if (post_transport_work & PostTransportOverWrite) { - non_realtime_overwrite (on_entry, finished); - if (!finished) { - g_atomic_int_dec_and_test (&butler_should_do_transport_work); - goto restart; - } - } - - if (post_transport_work & PostTransportAudition) { - non_realtime_set_audition (); - } - - g_atomic_int_dec_and_test (&butler_should_do_transport_work); -} - -void -Session::non_realtime_set_speed () -{ - boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader(); - - for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) { - (*i)->non_realtime_set_speed (); - } -} - -void -Session::non_realtime_overwrite (int on_entry, bool& finished) -{ - boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader(); - - for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) { - if ((*i)->pending_overwrite) { - (*i)->overwrite_existing_buffers (); - } - if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) { - finished = false; - return; - } - } -} - - -void -Session::non_realtime_locate () -{ - boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader(); - - for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) { - (*i)->non_realtime_locate (_transport_frame); - } -} - - -void -Session::non_realtime_stop (bool abort, int on_entry, bool& finished) -{ - struct tm* now; - time_t xnow; - bool did_record; - bool saved; - - did_record = false; - saved = false; - - boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader(); - - for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) { - if ((*i)->get_captured_frames () != 0) { - did_record = true; - break; - } - } - - /* stop and locate are merged here because they share a lot of common stuff */ - - time (&xnow); - now = localtime (&xnow); - - if (auditioner) { - auditioner->cancel_audition (); - } - - clear_clicks(); - cumulative_rf_motion = 0; - reset_rf_scale (0); - - if (did_record) { - begin_reversible_command ("capture"); - - Location* loc = _locations.end_location(); - bool change_end = false; - - if (_transport_frame < loc->end()) { - - /* stopped recording before current end */ - - if (_end_location_is_free) { - - /* first capture for this session, move end back to where we are */ - - change_end = true; - } - - } else if (_transport_frame > loc->end()) { - - /* stopped recording after the current end, extend it */ - - change_end = true; - } - - if (change_end) { - XMLNode &before = loc->get_state(); - loc->set_end(_transport_frame); - XMLNode &after = loc->get_state(); - add_command (new MementoCommand<Location>(*loc, &before, &after)); - } - - _end_location_is_free = false; - _have_captured = true; - } - - for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) { - (*i)->transport_stopped (*now, xnow, abort); - } - - boost::shared_ptr<RouteList> r = routes.reader (); - - for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - if (!(*i)->is_hidden()) { - (*i)->set_pending_declick (0); - } - } - - if (did_record) { - commit_reversible_command (); - } - - if (_engine.running()) { - update_latency_compensation (true, abort); - } - - if ((Config->get_slave_source() == None && Config->get_auto_return()) || - (post_transport_work & PostTransportLocate) || - (_requested_return_frame >= 0) || - synced_to_jack()) { - - if (pending_locate_flush) { - flush_all_inserts (); - } - - if (((Config->get_slave_source() == None && Config->get_auto_return()) || - synced_to_jack() || - _requested_return_frame >= 0) && - !(post_transport_work & PostTransportLocate)) { - - bool do_locate = false; - - if (_requested_return_frame >= 0) { - _transport_frame = _requested_return_frame; - _requested_return_frame = -1; - do_locate = true; - } else { - _transport_frame = last_stop_frame; - _requested_return_frame = -1; - } - - if (synced_to_jack() && !play_loop) { - do_locate = true; - } - - if (do_locate) { - // cerr << "non-realtimestop: transport locate to " << _transport_frame << endl; - _engine.transport_locate (_transport_frame); - } - } - -#ifndef LEAVE_TRANSPORT_UNADJUSTED - } -#endif - - for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) { - if (!(*i)->hidden()) { - if ((*i)->speed() != 1.0f || (*i)->speed() != -1.0f) { - (*i)->seek ((nframes_t) (_transport_frame * (double) (*i)->speed())); - } - else { - (*i)->seek (_transport_frame); - } - } - if (on_entry != g_atomic_int_get (&butler_should_do_transport_work)) { - finished = false; - /* we will be back */ - return; - } - } - -#ifdef LEAVE_TRANSPORT_UNADJUSTED - } -#endif - - if (_requested_return_frame < 0) { - last_stop_frame = _transport_frame; - } else { - last_stop_frame = _requested_return_frame; - _requested_return_frame = -1; - } - - if (did_record) { - - /* XXX its a little odd that we're doing this here - when realtime_stop(), which has already executed, - will have done this. - JLC - so let's not because it seems unnecessary and breaks loop record - */ -#if 0 - if (!Config->get_latched_record_enable()) { - g_atomic_int_set (&_record_status, Disabled); - } else { - g_atomic_int_set (&_record_status, Enabled); - } - RecordStateChanged (); /* emit signal */ -#endif - } - - if ((post_transport_work & PostTransportLocate) && get_record_enabled()) { - /* capture start has been changed, so save pending state */ - save_state ("", true); - saved = true; - } - - /* always try to get rid of this */ - - remove_pending_capture_state (); - - /* save the current state of things if appropriate */ - - if (did_record && !saved) { - save_state (_current_snapshot_name); - } - - if (post_transport_work & PostTransportDuration) { - DurationChanged (); /* EMIT SIGNAL */ - } - - if (post_transport_work & PostTransportStop) { - _play_range = false; - - /* do not turn off autoloop on stop */ - - } - - nframes_t tf = _transport_frame; - - PositionChanged (tf); /* EMIT SIGNAL */ - TransportStateChange (); /* EMIT SIGNAL */ - - /* and start it up again if relevant */ - - if ((post_transport_work & PostTransportLocate) && Config->get_slave_source() == None && pending_locate_roll) { - request_transport_speed (1.0); - pending_locate_roll = false; - } -} - -void -Session::check_declick_out () -{ - bool locate_required = transport_sub_state & PendingLocate; - - /* this is called after a process() iteration. if PendingDeclickOut was set, - it means that we were waiting to declick the output (which has just been - done) before doing something else. this is where we do that "something else". - - note: called from the audio thread. - */ - - if (transport_sub_state & PendingDeclickOut) { - - if (locate_required) { - start_locate (pending_locate_frame, pending_locate_roll, pending_locate_flush); - transport_sub_state &= ~(PendingDeclickOut|PendingLocate); - } else { - stop_transport (pending_abort); - transport_sub_state &= ~(PendingDeclickOut|PendingLocate); - } - } -} - -void -Session::set_play_loop (bool yn) -{ - /* Called from event-handling context */ - - if ((actively_recording() && yn) || _locations.auto_loop_location() == 0) { - return; - } - - set_dirty(); - - if (yn && Config->get_seamless_loop() && synced_to_jack()) { - warning << _("Seamless looping cannot be supported while Ardour is using JACK transport.\n" - "Recommend changing the configured options") - << endmsg; - return; - } - - - if ((play_loop = yn)) { - - Location *loc; - - - if ((loc = _locations.auto_loop_location()) != 0) { - - if (Config->get_seamless_loop()) { - // set all diskstreams to use internal looping - boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader(); - for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) { - if (!(*i)->hidden()) { - (*i)->set_loop (loc); - } - } - } - else { - // set all diskstreams to NOT use internal looping - boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader(); - for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) { - if (!(*i)->hidden()) { - (*i)->set_loop (0); - } - } - } - - /* stick in the loop event */ - - Event* event = new Event (Event::AutoLoop, Event::Replace, loc->end(), loc->start(), 0.0f); - merge_event (event); - - /* locate to start of loop and roll if current pos is outside of the loop range */ - if (_transport_frame < loc->start() || _transport_frame > loc->end()) { - event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, loc->start(), 0, !synced_to_jack()); - merge_event (event); - } - else { - // locate to current position (+ 1 to force reload) - event = new Event (Event::LocateRoll, Event::Add, Event::Immediate, _transport_frame + 1, 0, !synced_to_jack()); - merge_event (event); - } - } - - - - } else { - clear_events (Event::AutoLoop); - - // set all diskstreams to NOT use internal looping - boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader(); - for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) { - if (!(*i)->hidden()) { - (*i)->set_loop (0); - } - } - - } -} - -void -Session::flush_all_inserts () -{ - boost::shared_ptr<RouteList> r = routes.reader (); - - for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - (*i)->flush_processors (); - } -} - -void -Session::start_locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop) -{ - if (synced_to_jack()) { - - float sp; - nframes_t pos; - - _slave->speed_and_position (sp, pos); - - if (target_frame != pos) { - - /* tell JACK to change transport position, and we will - follow along later in ::follow_slave() - */ - - _engine.transport_locate (target_frame); - - if (sp != 1.0f && with_roll) { - _engine.transport_start (); - } - - } - - } else { - - locate (target_frame, with_roll, with_flush, with_loop); - } -} - -void -Session::locate (nframes_t target_frame, bool with_roll, bool with_flush, bool with_loop) -{ - if (actively_recording() && !with_loop) { - return; - } - - if (_transport_frame == target_frame && !loop_changing && !with_loop) { - if (with_roll) { - set_transport_speed (1.0, false); - } - loop_changing = false; - return; - } - - // Update SMPTE time - // [DR] FIXME: find out exactly where this should go below - _transport_frame = target_frame; - smpte_time(_transport_frame, transmitting_smpte_time); - outbound_mtc_smpte_frame = _transport_frame; - next_quarter_frame_to_send = 0; - - if (_transport_speed && (!with_loop || loop_changing)) { - /* schedule a declick. we'll be called again when its done */ - - if (!(transport_sub_state & PendingDeclickOut)) { - transport_sub_state |= (PendingDeclickOut|PendingLocate); - pending_locate_frame = target_frame; - pending_locate_roll = with_roll; - pending_locate_flush = with_flush; - return; - } - } - - if (transport_rolling() && (!auto_play_legal || !Config->get_auto_play()) && !with_roll && !(synced_to_jack() && play_loop)) { - realtime_stop (false); - } - - if ( !with_loop || loop_changing) { - - post_transport_work = PostTransportWork (post_transport_work | PostTransportLocate); - - if (with_roll) { - post_transport_work = PostTransportWork (post_transport_work | PostTransportRoll); - } - - schedule_butler_transport_work (); - - } else { - - /* this is functionally what clear_clicks() does but with a tentative lock */ - - Glib::RWLock::WriterLock clickm (click_lock, Glib::TRY_LOCK); - - if (clickm.locked()) { - - for (Clicks::iterator i = clicks.begin(); i != clicks.end(); ++i) { - delete *i; - } - - clicks.clear (); - } - } - - if (with_roll) { - /* switch from input if we're going to roll */ - if (Config->get_monitoring_model() == HardwareMonitoring) { - - boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader(); - - for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) { - if ((*i)->record_enabled ()) { - //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl; - (*i)->monitor_input (!Config->get_auto_input()); - } - } - } - } else { - /* otherwise we're going to stop, so do the opposite */ - if (Config->get_monitoring_model() == HardwareMonitoring) { - boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader(); - - for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) { - if ((*i)->record_enabled ()) { - //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl; - (*i)->monitor_input (true); - } - } - } - } - - /* cancel looped playback if transport pos outside of loop range */ - if (play_loop) { - Location* al = _locations.auto_loop_location(); - - if (al && (_transport_frame < al->start() || _transport_frame > al->end())) { - // cancel looping directly, this is called from event handling context - set_play_loop (false); - } - else if (al && _transport_frame == al->start()) { - if (with_loop) { - // this is only necessary for seamless looping - - boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader(); - - for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) { - if ((*i)->record_enabled ()) { - // tell it we've looped, so it can deal with the record state - (*i)->transport_looped(_transport_frame); - } - } - } - - TransportLooped(); // EMIT SIGNAL - } - } - - loop_changing = false; - - _send_smpte_update = true; -} - -/** Set the transport speed. - * @param speed New speed - * @param abort - */ -void -Session::set_transport_speed (float speed, bool abort) -{ - if (_transport_speed == speed) { - return; - } - - if (speed > 0) { - speed = min (8.0f, speed); - } else if (speed < 0) { - speed = max (-8.0f, speed); - } - - if (transport_rolling() && speed == 0.0) { - - /* we are rolling and we want to stop */ - - if (Config->get_monitoring_model() == HardwareMonitoring) - { - boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader(); - - for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) { - if ((*i)->record_enabled ()) { - //cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl; - (*i)->monitor_input (true); - } - } - } - - if (synced_to_jack ()) { - _engine.transport_stop (); - } else { - stop_transport (abort); - } - - } else if (transport_stopped() && speed == 1.0) { - - /* we are stopped and we want to start rolling at speed 1 */ - - if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) { - return; - } - - if (Config->get_monitoring_model() == HardwareMonitoring) { - - boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader(); - - for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) { - if (Config->get_auto_input() && (*i)->record_enabled ()) { - //cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl; - (*i)->monitor_input (false); - } - } - } - - if (synced_to_jack()) { - _engine.transport_start (); - } else { - start_transport (); - } - - } else { - - if (!get_record_enabled() && Config->get_stop_at_session_end() && _transport_frame >= current_end_frame()) { - return; - } - - if ((synced_to_jack()) && speed != 0.0 && speed != 1.0) { - warning << _("Global varispeed cannot be supported while Ardour is connected to JACK transport control") - << endmsg; - return; - } - - if (actively_recording()) { - return; - } - - if (speed > 0.0f && _transport_frame == current_end_frame()) { - return; - } - - if (speed < 0.0f && _transport_frame == 0) { - return; - } - - clear_clicks (); - - /* if we are reversing relative to the current speed, or relative to the speed - before the last stop, then we have to do extra work. - */ - - if ((_transport_speed && speed * _transport_speed < 0.0f) || (_last_transport_speed * speed < 0.0f) || (_last_transport_speed == 0.0f && speed < 0.0f)) { - post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse); - } - - _last_transport_speed = _transport_speed; - _transport_speed = speed; - - boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader(); - for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) { - if ((*i)->realtime_set_speed ((*i)->speed(), true)) { - post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed); - } - } - - if (post_transport_work & (PostTransportSpeed|PostTransportReverse)) { - schedule_butler_transport_work (); - } - } -} - - -/** Stop the transport. */ -void -Session::stop_transport (bool abort) -{ - if (_transport_speed == 0.0f) { - return; - } - - if (actively_recording() && !(transport_sub_state & StopPendingCapture) && - _worst_output_latency > current_block_size) - { - - /* we need to capture the audio that has still not yet been received by the system - at the time the stop is requested, so we have to roll past that time. - - we want to declick before stopping, so schedule the autostop for one - block before the actual end. we'll declick in the subsequent block, - and then we'll really be stopped. - */ - - Event *ev = new Event (Event::StopOnce, Event::Replace, - _transport_frame + _worst_output_latency - current_block_size, - 0, 0, abort); - - merge_event (ev); - transport_sub_state |= StopPendingCapture; - pending_abort = abort; - return; - } - - - if ((transport_sub_state & PendingDeclickOut) == 0) { - transport_sub_state |= PendingDeclickOut; - /* we'll be called again after the declick */ - pending_abort = abort; - return; - } - - realtime_stop (abort); - schedule_butler_transport_work (); -} - -void -Session::start_transport () -{ - _last_roll_location = _transport_frame; - - /* if record status is Enabled, move it to Recording. if its - already Recording, move it to Disabled. - */ - - switch (record_status()) { - case Enabled: - if (!Config->get_punch_in()) { - enable_record (); - } - break; - - case Recording: - if (!play_loop) { - disable_record (false); - } - break; - - default: - break; - } - - if (!synced_to_jack() || _exporting) { - actually_start_transport (); - } else { - waiting_to_start = true; - } -} - -void -Session::actually_start_transport () -{ - waiting_to_start = false; - - transport_sub_state |= PendingDeclickIn; - _transport_speed = 1.0; - - boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader(); - for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) { - (*i)->realtime_set_speed ((*i)->speed(), true); - } - - deliver_mmc(MIDI::MachineControl::cmdDeferredPlay, _transport_frame); - - TransportStateChange (); /* EMIT SIGNAL */ -} - -/** Do any transport work in the audio thread that needs to be done after the - * transport thread is finished. Audio thread, realtime safe. - */ -void -Session::post_transport () -{ - if (post_transport_work & PostTransportAudition) { - if (auditioner && auditioner->active()) { - process_function = &Session::process_audition; - } else { - process_function = &Session::process_with_events; - } - } - - if (post_transport_work & PostTransportStop) { - - transport_sub_state = 0; - } - - if (post_transport_work & PostTransportLocate) { - - if (((Config->get_slave_source() == None && (auto_play_legal && Config->get_auto_play())) && !_exporting) || (post_transport_work & PostTransportRoll)) { - start_transport (); - - } else { - transport_sub_state = 0; - } - } - - set_next_event (); - - post_transport_work = PostTransportWork (0); -} - -void -Session::reset_rf_scale (nframes_t motion) -{ - cumulative_rf_motion += motion; - - if (cumulative_rf_motion < 4 * _current_frame_rate) { - rf_scale = 1; - } else if (cumulative_rf_motion < 8 * _current_frame_rate) { - rf_scale = 4; - } else if (cumulative_rf_motion < 16 * _current_frame_rate) { - rf_scale = 10; - } else { - rf_scale = 100; - } - - if (motion != 0) { - set_dirty(); - } -} - -void -Session::set_slave_source (SlaveSource src) -{ - bool reverse = false; - bool non_rt_required = false; - - if (_transport_speed) { - error << _("please stop the transport before adjusting slave settings") << endmsg; - return; - } - -// if (src == JACK && Config->get_jack_time_master()) { -// return; -// } - - if (_slave) { - delete _slave; - _slave = 0; - } - - if (_transport_speed < 0.0) { - reverse = true; - } - - switch (src) { - case None: - stop_transport (); - break; - - case MTC: - if (_mtc_port) { - try { - _slave = new MTC_Slave (*this, *_mtc_port); - } - - catch (failed_constructor& err) { - return; - } - - } else { - error << _("No MTC port defined: MTC slaving is impossible.") << endmsg; - return; - } - _desired_transport_speed = _transport_speed; - break; - - case JACK: - _slave = new JACK_Slave (_engine.jack()); - _desired_transport_speed = _transport_speed; - break; - }; - - Config->set_slave_source (src); - - boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader(); - for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) { - if (!(*i)->hidden()) { - if ((*i)->realtime_set_speed ((*i)->speed(), true)) { - non_rt_required = true; - } - (*i)->set_slaved (_slave); - } - } - - if (reverse) { - reverse_diskstream_buffers (); - } - - if (non_rt_required) { - post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed); - schedule_butler_transport_work (); - } - - set_dirty(); -} - -void -Session::reverse_diskstream_buffers () -{ - post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse); - schedule_butler_transport_work (); -} - -void -Session::set_diskstream_speed (Diskstream* stream, float speed) -{ - if (stream->realtime_set_speed (speed, false)) { - post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed); - schedule_butler_transport_work (); - set_dirty (); - } -} - -void -Session::set_audio_range (list<AudioRange>& range) -{ - Event *ev = new Event (Event::SetAudioRange, Event::Add, Event::Immediate, 0, 0.0f); - ev->audio_range = range; - queue_event (ev); -} - -void -Session::request_play_range (bool yn) -{ - Event* ev = new Event (Event::SetPlayRange, Event::Add, Event::Immediate, 0, 0.0f, yn); - queue_event (ev); -} - -void -Session::set_play_range (bool yn) -{ - /* Called from event-processing context */ - - if (_play_range != yn) { - _play_range = yn; - setup_auto_play (); - - if (!_play_range) { - /* stop transport */ - Event* ev = new Event (Event::SetTransportSpeed, Event::Add, Event::Immediate, 0, 0.0f, false); - merge_event (ev); - } - } -} - -void -Session::setup_auto_play () -{ - /* Called from event-processing context */ - - Event* ev; - - _clear_event_type (Event::RangeStop); - _clear_event_type (Event::RangeLocate); - - if (!_play_range) { - return; - } - - list<AudioRange>::size_type sz = current_audio_range.size(); - - if (sz > 1) { - - list<AudioRange>::iterator i = current_audio_range.begin(); - list<AudioRange>::iterator next; - - while (i != current_audio_range.end()) { - - next = i; - ++next; - - /* locating/stopping is subject to delays for declicking. - */ - - nframes_t requested_frame = (*i).end; - - if (requested_frame > current_block_size) { - requested_frame -= current_block_size; - } else { - requested_frame = 0; - } - - if (next == current_audio_range.end()) { - ev = new Event (Event::RangeStop, Event::Add, requested_frame, 0, 0.0f); - } else { - ev = new Event (Event::RangeLocate, Event::Add, requested_frame, (*next).start, 0.0f); - } - - merge_event (ev); - - i = next; - } - - } else if (sz == 1) { - - ev = new Event (Event::RangeStop, Event::Add, current_audio_range.front().end, 0, 0.0f); - merge_event (ev); - - } - - /* now start rolling at the right place */ - - ev = new Event (Event::LocateRoll, Event::Add, Event::Immediate, current_audio_range.front().start, 0.0f, false); - merge_event (ev); -} - -void -Session::request_roll_at_and_return (nframes_t start, nframes_t return_to) -{ - Event *ev = new Event (Event::LocateRollLocate, Event::Add, Event::Immediate, return_to, 1.0); - ev->target2_frame = start; - queue_event (ev); -} - -void -Session::request_bounded_roll (nframes_t start, nframes_t end) -{ - request_stop (); - Event *ev = new Event (Event::StopOnce, Event::Replace, end, Event::Immediate, 0.0); - queue_event (ev); - request_locate (start, true); -} - -void -Session::engine_halted () -{ - bool ignored; - - /* there will be no more calls to process(), so - we'd better clean up for ourselves, right now. - - but first, make sure the butler is out of - the picture. - */ - - g_atomic_int_set (&butler_should_do_transport_work, 0); - post_transport_work = PostTransportWork (0); - stop_butler (); - - realtime_stop (false); - non_realtime_stop (false, 0, ignored); - transport_sub_state = 0; - - TransportStateChange (); /* EMIT SIGNAL */ -} - - -void -Session::xrun_recovery () -{ - Xrun (transport_frame()); //EMIT SIGNAL - - if (Config->get_stop_recording_on_xrun() && actively_recording()) { - - /* it didn't actually halt, but we need - to handle things in the same way. - */ - - engine_halted(); - } -} - -void -Session::update_latency_compensation (bool with_stop, bool abort) -{ - bool update_jack = false; - - if (_state_of_the_state & Deletion) { - return; - } - - _worst_track_latency = 0; - - boost::shared_ptr<RouteList> r = routes.reader (); - - for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - - if (with_stop) { - (*i)->handle_transport_stopped (abort, (post_transport_work & PostTransportLocate), - (!(post_transport_work & PostTransportLocate) || pending_locate_flush)); - } - - nframes_t old_latency = (*i)->signal_latency (); - nframes_t track_latency = (*i)->update_total_latency (); - - if (old_latency != track_latency) { - (*i)->update_port_total_latencies (); - update_jack = true; - } - - if (!(*i)->is_hidden() && ((*i)->active())) { - _worst_track_latency = max (_worst_track_latency, track_latency); - } - } - - if (update_jack) { - _engine.update_total_latencies (); - } - - for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - (*i)->set_latency_delay (_worst_track_latency); - } - - set_worst_io_latencies (); - - /* reflect any changes in latencies into capture offsets - */ - - boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader(); - - for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) { - (*i)->set_capture_offset (); - } -} - -void -Session::allow_auto_play (bool yn) -{ - auto_play_legal = yn; -} - -void -Session::reset_jack_connection (jack_client_t* jack) -{ - JACK_Slave* js; - - if (_slave && ((js = dynamic_cast<JACK_Slave*> (_slave)) != 0)) { - js->reset_client (jack); - } -} diff --git a/libs/ardour/session_utils.cc b/libs/ardour/session_utils.cc deleted file mode 100644 index 3b2baad69a..0000000000 --- a/libs/ardour/session_utils.cc +++ /dev/null @@ -1,39 +0,0 @@ - -#include <pbd/error.h> - -#include <ardour/session_directory.h> - -#include "i18n.h" - -namespace ARDOUR { - -using namespace PBD; - -bool -create_session_directory (const string& session_directory_path) -{ - SessionDirectory sdir(session_directory_path); - - try - { - // create all the required session directories - sdir.create(); - } - catch(sys::filesystem_error& ex) - { - // log the exception - warning << string_compose - ( - _("Unable to create session directory at path %1 : %2"), - session_directory_path, - ex.what() - ); - - return false; - } - - // successfully created the session directory - return true; -} - -} // namespace ARDOUR diff --git a/libs/ardour/session_vst.cc b/libs/ardour/session_vst.cc deleted file mode 100644 index 16233feba2..0000000000 --- a/libs/ardour/session_vst.cc +++ /dev/null @@ -1,315 +0,0 @@ -/* - Copyright (C) 2004 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include <stdbool.h> -#include <cstdio> - -#include <fst.h> -#include <vst/aeffectx.h> - -#include <ardour/session.h> -#include <ardour/vst_plugin.h> - -#include "i18n.h" - -// #define DEBUG_CALLBACKS - -#ifdef DEBUG_CALLBACKS -#define SHOW_CALLBACK printf -#else -#define SHOW_CALLBACK(...) -#endif - -using namespace ARDOUR; - -long Session::vst_callback (AEffect* effect, - long opcode, - long index, - long value, - void* ptr, - float opt) -{ - static VstTimeInfo _timeInfo; - VSTPlugin* plug; - Session* session; - - SHOW_CALLBACK ("am callback, opcode = %d", opcode); - - if (effect && effect->user) { - plug = static_cast<VSTPlugin*> (effect->user); - session = &plug->session(); - } else { - plug = 0; - session = 0; - } - - switch(opcode){ - - case audioMasterAutomate: - SHOW_CALLBACK ("amc: audioMasterAutomate\n"); - // index, value, returns 0 - if (effect) { - effect->setParameter (effect, index, opt); - } - return 0; - - case audioMasterVersion: - SHOW_CALLBACK ("amc: audioMasterVersion\n"); - // vst version, currently 2 (0 for older) - return 2; - - case audioMasterCurrentId: - SHOW_CALLBACK ("amc: audioMasterCurrentId\n"); - // returns the unique id of a plug that's currently - // loading - return 0; - - case audioMasterIdle: - SHOW_CALLBACK ("amc: audioMasterIdle\n"); - // call application idle routine (this will - // call effEditIdle for all open editors too) - if (effect) { - effect->dispatcher(effect, effEditIdle, 0, 0, NULL, 0.0f); - } - return 0; - - case audioMasterPinConnected: - SHOW_CALLBACK ("amc: audioMasterPinConnected\n"); - // inquire if an input or output is beeing connected; - // index enumerates input or output counting from zero: - // value is 0 for input and != 0 otherwise. note: the - // return value is 0 for <true> such that older versions - // will always return true. - return 1; - - case audioMasterWantMidi: - SHOW_CALLBACK ("amc: audioMasterWantMidi\n"); - // <value> is a filter which is currently ignored - return 0; - - case audioMasterGetTime: - SHOW_CALLBACK ("amc: audioMasterGetTime\n"); - // returns const VstTimeInfo* (or 0 if not supported) - // <value> should contain a mask indicating which fields are required - // (see valid masks above), as some items may require extensive - // conversions - memset(&_timeInfo, 0, sizeof(_timeInfo)); - if (session) { - _timeInfo.samplePos = session->transport_frame(); - _timeInfo.sampleRate = session->frame_rate(); - } - return (long)&_timeInfo; - - case audioMasterProcessEvents: - SHOW_CALLBACK ("amc: audioMasterProcessEvents\n"); - // VstEvents* in <ptr> - return 0; - - case audioMasterSetTime: - SHOW_CALLBACK ("amc: audioMasterSetTime\n"); - // VstTimenfo* in <ptr>, filter in <value>, not supported - - case audioMasterTempoAt: - SHOW_CALLBACK ("amc: audioMasterTempoAt\n"); - // returns tempo (in bpm * 10000) at sample frame location passed in <value> - return 0; - - case audioMasterGetNumAutomatableParameters: - SHOW_CALLBACK ("amc: audioMasterGetNumAutomatableParameters\n"); - return 0; - - case audioMasterGetParameterQuantization: - SHOW_CALLBACK ("amc: audioMasterGetParameterQuantization\n"); - // returns the integer value for +1.0 representation, - // or 1 if full single float precision is maintained - // in automation. parameter index in <value> (-1: all, any) - return 0; - - case audioMasterIOChanged: - SHOW_CALLBACK ("amc: audioMasterIOChanged\n"); - // numInputs and/or numOutputs has changed - return 0; - - case audioMasterNeedIdle: - SHOW_CALLBACK ("amc: audioMasterNeedIdle\n"); - // plug needs idle calls (outside its editor window) - return 0; - - case audioMasterSizeWindow: - SHOW_CALLBACK ("amc: audioMasterSizeWindow\n"); - // index: width, value: height - return 0; - - case audioMasterGetSampleRate: - SHOW_CALLBACK ("amc: audioMasterGetSampleRate\n"); - return 0; - - case audioMasterGetBlockSize: - SHOW_CALLBACK ("amc: audioMasterGetBlockSize\n"); - return 0; - - case audioMasterGetInputLatency: - SHOW_CALLBACK ("amc: audioMasterGetInputLatency\n"); - return 0; - - case audioMasterGetOutputLatency: - SHOW_CALLBACK ("amc: audioMasterGetOutputLatency\n"); - return 0; - - case audioMasterGetPreviousPlug: - SHOW_CALLBACK ("amc: audioMasterGetPreviousPlug\n"); - // input pin in <value> (-1: first to come), returns cEffect* - return 0; - - case audioMasterGetNextPlug: - SHOW_CALLBACK ("amc: audioMasterGetNextPlug\n"); - // output pin in <value> (-1: first to come), returns cEffect* - - case audioMasterWillReplaceOrAccumulate: - SHOW_CALLBACK ("amc: audioMasterWillReplaceOrAccumulate\n"); - // returns: 0: not supported, 1: replace, 2: accumulate - return 0; - - case audioMasterGetCurrentProcessLevel: - SHOW_CALLBACK ("amc: audioMasterGetCurrentProcessLevel\n"); - // returns: 0: not supported, - // 1: currently in user thread (gui) - // 2: currently in audio thread (where process is called) - // 3: currently in 'sequencer' thread (midi, timer etc) - // 4: currently offline processing and thus in user thread - // other: not defined, but probably pre-empting user thread. - return 0; - - case audioMasterGetAutomationState: - SHOW_CALLBACK ("amc: audioMasterGetAutomationState\n"); - // returns 0: not supported, 1: off, 2:read, 3:write, 4:read/write - // offline - return 0; - - case audioMasterOfflineStart: - SHOW_CALLBACK ("amc: audioMasterOfflineStart\n"); - case audioMasterOfflineRead: - SHOW_CALLBACK ("amc: audioMasterOfflineRead\n"); - // ptr points to offline structure, see below. return 0: error, 1 ok - return 0; - - case audioMasterOfflineWrite: - SHOW_CALLBACK ("amc: audioMasterOfflineWrite\n"); - // same as read - return 0; - - case audioMasterOfflineGetCurrentPass: - SHOW_CALLBACK ("amc: audioMasterOfflineGetCurrentPass\n"); - case audioMasterOfflineGetCurrentMetaPass: - SHOW_CALLBACK ("amc: audioMasterOfflineGetCurrentMetaPass\n"); - return 0; - - case audioMasterSetOutputSampleRate: - SHOW_CALLBACK ("amc: audioMasterSetOutputSampleRate\n"); - // for variable i/o, sample rate in <opt> - return 0; - - case audioMasterGetSpeakerArrangement: - SHOW_CALLBACK ("amc: audioMasterGetSpeakerArrangement\n"); - // (long)input in <value>, output in <ptr> - return 0; - - case audioMasterGetVendorString: - SHOW_CALLBACK ("amc: audioMasterGetVendorString\n"); - // fills <ptr> with a string identifying the vendor (max 64 char) - strcpy ((char*) ptr, "Linux Audio Systems"); - return 0; - - case audioMasterGetProductString: - SHOW_CALLBACK ("amc: audioMasterGetProductString\n"); - // fills <ptr> with a string with product name (max 64 char) - strcpy ((char*) ptr, "Ardour"); - return 0; - - case audioMasterGetVendorVersion: - SHOW_CALLBACK ("amc: audioMasterGetVendorVersion\n"); - // returns vendor-specific version - return 900; - - case audioMasterVendorSpecific: - SHOW_CALLBACK ("amc: audioMasterVendorSpecific\n"); - // no definition, vendor specific handling - return 0; - - case audioMasterSetIcon: - SHOW_CALLBACK ("amc: audioMasterSetIcon\n"); - // void* in <ptr>, format not defined yet - return 0; - - case audioMasterCanDo: - SHOW_CALLBACK ("amc: audioMasterCanDo\n"); - // string in ptr, see below - return 0; - - case audioMasterGetLanguage: - SHOW_CALLBACK ("amc: audioMasterGetLanguage\n"); - // see enum - return 0; - - case audioMasterOpenWindow: - SHOW_CALLBACK ("amc: audioMasterOpenWindow\n"); - // returns platform specific ptr - return 0; - - case audioMasterCloseWindow: - SHOW_CALLBACK ("amc: audioMasterCloseWindow\n"); - // close window, platform specific handle in <ptr> - return 0; - - case audioMasterGetDirectory: - SHOW_CALLBACK ("amc: audioMasterGetDirectory\n"); - // get plug directory, FSSpec on MAC, else char* - return 0; - - case audioMasterUpdateDisplay: - SHOW_CALLBACK ("amc: audioMasterUpdateDisplay\n"); - // something has changed, update 'multi-fx' display - if (effect) { - effect->dispatcher(effect, effEditIdle, 0, 0, NULL, 0.0f); - } - return 0; - - case audioMasterBeginEdit: - SHOW_CALLBACK ("amc: audioMasterBeginEdit\n"); - // begin of automation session (when mouse down), parameter index in <index> - return 0; - - case audioMasterEndEdit: - SHOW_CALLBACK ("amc: audioMasterEndEdit\n"); - // end of automation session (when mouse up), parameter index in <index> - return 0; - - case audioMasterOpenFileSelector: - SHOW_CALLBACK ("amc: audioMasterOpenFileSelector\n"); - // open a fileselector window with VstFileSelect* in <ptr> - return 0; - - default: - SHOW_CALLBACK ("VST master dispatcher: undefed: %d, %d\n", opcode, effKeysRequired); - break; - } - - return 0; -} - diff --git a/libs/ardour/silentfilesource.cc b/libs/ardour/silentfilesource.cc deleted file mode 100644 index b34944e342..0000000000 --- a/libs/ardour/silentfilesource.cc +++ /dev/null @@ -1,39 +0,0 @@ -/* - 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. - -*/ - -#include <ardour/silentfilesource.h> - -using namespace ARDOUR; - -SilentFileSource::SilentFileSource (Session& s, const XMLNode& node, nframes_t len, float sr) - : AudioFileSource (s, node, false) -{ - _length = len; - _sample_rate = sr; -} - -SilentFileSource::~SilentFileSource () -{ -} - -void -SilentFileSource::set_length (nframes_t len) -{ - _length = len; -} diff --git a/libs/ardour/smf_reader.cc b/libs/ardour/smf_reader.cc deleted file mode 100644 index 48ec3dc386..0000000000 --- a/libs/ardour/smf_reader.cc +++ /dev/null @@ -1,285 +0,0 @@ -/* - 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. -*/ - -#include <cstring> -#include <cstdio> -#include <cassert> -#include <iostream> -#include <glibmm/miscutils.h> -#include <midi++/events.h> - -#include <ardour/smf_reader.h> -#include <ardour/midi_util.h> - -using namespace std; - -namespace ARDOUR { - - -SMFReader::SMFReader(const string filename) - : _fd(NULL) - , _ppqn(0) - , _track(0) - , _track_size(0) -{ - if (filename.length() > 0) { - open(filename); - } -} - - -SMFReader::~SMFReader() -{ - if (_fd) - close(); -} - - -bool -SMFReader::open(const string& filename) throw (logic_error, UnsupportedTime) -{ - if (_fd) - throw logic_error("Attempt to start new read while write in progress."); - - cout << "Opening SMF file " << filename << " for reading." << endl; - - _fd = fopen(filename.c_str(), "r+"); - - if (_fd) { - // Read type (bytes 8..9) - fseek(_fd, 0, SEEK_SET); - char mthd[5]; - mthd[4] = '\0'; - fread(mthd, 1, 4, _fd); - if (strcmp(mthd, "MThd")) { - cerr << filename << " is not an SMF file, aborting." << endl; - fclose(_fd); - _fd = NULL; - return false; - } - - // Read type (bytes 8..9) - fseek(_fd, 8, SEEK_SET); - uint16_t type_be = 0; - fread(&type_be, 2, 1, _fd); - _type = GUINT16_FROM_BE(type_be); - - // Read number of tracks (bytes 10..11) - uint16_t num_tracks_be = 0; - fread(&num_tracks_be, 2, 1, _fd); - _num_tracks = GUINT16_FROM_BE(num_tracks_be); - - // Read PPQN (bytes 12..13) - uint16_t ppqn_be = 0; - fread(&ppqn_be, 2, 1, _fd); - _ppqn = GUINT16_FROM_BE(ppqn_be); - - // TODO: Absolute (SMPTE seconds) time support - if ((_ppqn & 0x8000) != 0) - throw UnsupportedTime(); - - seek_to_track(1); - - return true; - } else { - return false; - } -} - - -/** Seek to the start of a given track, starting from 1. - * Returns true if specified track was found. - */ -bool -SMFReader::seek_to_track(unsigned track) throw (std::logic_error) -{ - if (track == 0) - throw logic_error("Seek to track 0 out of range (must be >= 1)"); - - if (!_fd) - throw logic_error("Attempt to seek to track on unopened SMF file."); - - unsigned track_pos = 0; - - fseek(_fd, 14, SEEK_SET); - char id[5]; - id[4] = '\0'; - uint32_t chunk_size = 0; - - while (!feof(_fd)) { - fread(id, 1, 4, _fd); - - if (!strcmp(id, "MTrk")) { - ++track_pos; - } else { - std::cerr << "Unknown chunk ID " << id << endl; - } - - uint32_t chunk_size_be; - fread(&chunk_size_be, 4, 1, _fd); - chunk_size = GUINT32_FROM_BE(chunk_size_be); - - if (track_pos == track) - break; - - fseek(_fd, chunk_size, SEEK_CUR); - } - - if (!feof(_fd) && track_pos == track) { - _track = track; - _track_size = chunk_size; - return true; - } else { - return false; - } -} - - -/** Read an event from the current position in file. - * - * File position MUST be at the beginning of a delta time, or this will die very messily. - * ev.buffer must be of size ev.size, and large enough for the event. The returned event - * will have it's time field set to it's delta time (so it's the caller's responsibility - * to keep track of delta time, even for ignored events). - * - * Returns event length (including status byte) on success, 0 if event was - * skipped (eg a meta event), or -1 on EOF (or end of track). - * - * If @a buf is not large enough to hold the event, 0 will be returned, but ev_size - * set to the actual size of the event. - */ -int -SMFReader::read_event(size_t buf_len, - uint8_t* buf, - uint32_t* ev_size, - uint32_t* delta_time) - throw (std::logic_error, PrematureEOF, CorruptFile) -{ - if (_track == 0) - throw logic_error("Attempt to read from unopened SMF file"); - - if (!_fd || feof(_fd)) { - return -1; - } - - assert(buf_len > 0); - assert(buf); - assert(ev_size); - assert(delta_time); - - // Running status state - static uint8_t last_status = 0; - static uint32_t last_size = 0; - - *delta_time = read_var_len(_fd); - int status = fgetc(_fd); - if (status == EOF) - throw PrematureEOF(); - else if (status > 0xFF) - throw CorruptFile(); - - if (status < 0x80) { - if (last_status == 0) - throw CorruptFile(); - status = last_status; - *ev_size = last_size; - fseek(_fd, -1, SEEK_CUR); - } else { - last_status = status; - *ev_size = midi_event_size(status) + 1; - last_size = *ev_size; - } - - buf[0] = (uint8_t)status; - - if (status == 0xFF) { - *ev_size = 0; - if (feof(_fd)) - throw PrematureEOF(); - uint8_t type = fgetc(_fd); - const uint32_t size = read_var_len(_fd); - /*cerr.flags(ios::hex); - cerr << "SMF - meta 0x" << (int)type << ", size = "; - cerr.flags(ios::dec); - cerr << size << endl;*/ - - if ((uint8_t)type == 0x2F) { - return -1; // we hit the logical EOF anyway... - } else { - fseek(_fd, size, SEEK_CUR); - return 0; - } - } - - if (*ev_size > buf_len || *ev_size == 0 || feof(_fd)) { - //cerr << "SMF - Skipping event" << endl; - // Skip event, return 0 - fseek(_fd, *ev_size - 1, SEEK_CUR); - return 0; - } else { - // Read event, return size - if (ferror(_fd)) - throw CorruptFile(); - - fread(buf+1, 1, *ev_size - 1, _fd); - - if ((buf[0] & 0xF0) == 0x90 && buf[2] == 0) { - buf[0] = (0x80 | (buf[0] & 0x0F)); - buf[2] = 0x40; - } - - return *ev_size; - } -} - - -void -SMFReader::close() -{ - if (_fd) - fclose(_fd); - - _fd = NULL; -} - - -uint32_t -SMFReader::read_var_len(FILE* fd) throw (PrematureEOF) -{ - if (feof(fd)) - throw PrematureEOF(); - - uint32_t value; - uint8_t c; - - if ( (value = getc(fd)) & 0x80 ) { - value &= 0x7F; - do { - if (feof(fd)) - throw PrematureEOF(); - value = (value << 7) + ((c = getc(fd)) & 0x7F); - } while (c & 0x80); - } - - return value; -} - - -} // namespace ARDOUR - diff --git a/libs/ardour/smf_source.cc b/libs/ardour/smf_source.cc deleted file mode 100644 index bb43d4791a..0000000000 --- a/libs/ardour/smf_source.cc +++ /dev/null @@ -1,971 +0,0 @@ -/* - 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. - -*/ - -#include <vector> - -#include <sys/time.h> -#include <sys/stat.h> -#include <unistd.h> -#include <errno.h> - -#include <pbd/mountpoint.h> -#include <pbd/pathscanner.h> -#include <pbd/stl_delete.h> -#include <pbd/strsplit.h> - -#include <glibmm/miscutils.h> - -#include <ardour/smf_source.h> -#include <ardour/session.h> -#include <ardour/midi_ring_buffer.h> -#include <ardour/midi_util.h> -#include <ardour/tempo.h> -#include <ardour/audioengine.h> -#include <ardour/smf_reader.h> - -#include "i18n.h" - -using namespace ARDOUR; - -string SMFSource::_search_path; - -/*sigc::signal<void,struct tm*, time_t> SMFSource::HeaderPositionOffsetChanged; -bool SMFSource::header_position_negative; -uint64_t SMFSource::header_position_offset; -*/ - -SMFSource::SMFSource (Session& s, std::string path, Flag flags) - : MidiSource (s, region_name_from_path(path, false)) - , _flags (Flag(flags | Writable)) // FIXME: this needs to be writable for now - , _allow_remove_if_empty(true) - , _fd (0) - , _last_ev_time(0) - , _track_size(4) // 4 bytes for the ever-present EOT event - , _header_size(22) - , _empty(true) -{ - /* constructor used for new internal-to-session files. file cannot exist */ - - if (init (path, false)) { - throw failed_constructor (); - } - - if (open()) { - throw failed_constructor (); - } - - assert(_name.find("/") == string::npos); -} - -SMFSource::SMFSource (Session& s, const XMLNode& node) - : MidiSource (s, node) - , _flags (Flag (Writable|CanRename)) - , _allow_remove_if_empty(true) - , _fd (0) - , _last_ev_time(0) - , _track_size(4) // 4 bytes for the ever-present EOT event - , _header_size(22) - , _empty(true) -{ - /* constructor used for existing internal-to-session files. file must exist */ - - if (set_state (node)) { - throw failed_constructor (); - } - - if (init (_name, true)) { - throw failed_constructor (); - } - - if (open()) { - throw failed_constructor (); - } - - assert(_name.find("/") == string::npos); -} - -SMFSource::~SMFSource () -{ - if (removable()) { - unlink (_path.c_str()); - } -} - -bool -SMFSource::removable () const -{ - return (_flags & Removable) && ((_flags & RemoveAtDestroy) || - ((_flags & RemovableIfEmpty) && is_empty())); -} - -int -SMFSource::init (string pathstr, bool must_exist) -{ - bool is_new = false; - - if (!find (pathstr, must_exist, is_new)) { - cerr << "cannot find " << pathstr << " with me = " << must_exist << endl; - return -1; - } - - if (is_new && must_exist) { - return -1; - } - - assert(_name.find("/") == string::npos); - return 0; -} - -/** Attempt to open the SMF file for reading and writing. - * - * Currently SMFSource is always read/write. - * - * \return 0 on success - * -1 if the file can not be opened for reading, - * -2 if the file can not be opened for writing - */ -int -SMFSource::open() -{ - //cerr << "Opening SMF file " << path() << " writeable: " << writable() << endl; - - assert(writable()); // FIXME; - - _fd = fopen(path().c_str(), "r+"); - - // File already exists - if (_fd) { - fseek(_fd, _header_size - 4, 0); - uint32_t track_size_be = 0; - fread(&track_size_be, 4, 1, _fd); - _track_size = GUINT32_FROM_BE(track_size_be); - _empty = _track_size > 4; - //cerr << "SMF - read track size " << _track_size << endl; - - // We're making a new file - } else { - _fd = fopen(path().c_str(), "w+"); - if (_fd == NULL) { - cerr << "ERROR: Can not open SMF file " << path() << " for writing: " << - strerror(errno) << endl; - return -2; - } - _track_size = 4; - _empty = true; - - // Write a tentative header just to pad things out so writing happens in the right spot - flush_header(); - flush_footer(); - } - - return (_fd == 0) ? -1 : 0; -} - -void -SMFSource::close() -{ - if (_fd) { - flush_header(); - flush_footer(); - fclose(_fd); - _fd = NULL; - } -} - -void -SMFSource::seek_to_footer_position() -{ - uint8_t buffer[4]; - - // lets check if there is a track end marker at the end of the data - fseek(_fd, -4, SEEK_END); - //cerr << "SMFSource::seek_to_footer_position: At position: " << ftell(_fd); - size_t read_bytes = fread(buffer, sizeof(uint8_t), 4, _fd); - /*cerr << " read size: " << read_bytes << " buffer: "; - for (size_t i=0; i < read_bytes; ++i) { - printf("%x ", buffer[i]); - } - printf("\n"); - */ - - if( (read_bytes == 4) && - buffer[0] == 0x00 && - buffer[1] == 0xFF && - buffer[2] == 0x2F && - buffer[3] == 0x00) { - // there is one, so overwrite it - fseek(_fd, -4, SEEK_END); - } else { - // there is none, so append - fseek(_fd, 0, SEEK_END); - } -} - -int -SMFSource::flush_header() -{ - // FIXME: write timeline position somehow? - - //cerr << path() << " SMF Flushing header\n"; - - assert(_fd); - - const uint16_t type = GUINT16_TO_BE(0); // SMF Type 0 (single track) - const uint16_t ntracks = GUINT16_TO_BE(1); // Number of tracks (always 1 for Type 0) - const uint16_t division = GUINT16_TO_BE(_ppqn); // Pulses per quarter note (beat) - - char data[6]; - memcpy(data, &type, 2); - memcpy(data+2, &ntracks, 2); - memcpy(data+4, &division, 2); - - _fd = freopen(path().c_str(), "r+", _fd); - assert(_fd); - fseek(_fd, 0, SEEK_SET); - write_chunk("MThd", 6, data); - write_chunk_header("MTrk", _track_size); - - fflush(_fd); - - return 0; -} - -int -SMFSource::flush_footer() -{ - //cerr << path() << " SMF Flushing footer\n"; - seek_to_footer_position(); - write_footer(); - seek_to_footer_position(); - - return 0; -} - -void -SMFSource::write_footer() -{ - write_var_len(0); - char eot[3] = { 0xFF, 0x2F, 0x00 }; // end-of-track meta-event - fwrite(eot, 1, 3, _fd); - fflush(_fd); -} - -/** Returns the offset of the first event in the file with a time past @a start, - * relative to the start of the source. - * - * Returns -1 if not found. - */ -/* -long -SMFSource::find_first_event_after(nframes_t start) -{ - // FIXME: obviously this is slooow - - fseek(_fd, _header_size, 0); - - while ( ! feof(_fd) ) { - const uint32_t delta_time = read_var_len(); - - if (delta_time > start) - return delta_time; - } - - return -1; -} -*/ - -/** Read an event from the current position in file. - * - * File position MUST be at the beginning of a delta time, or this will die very messily. - * ev.buffer must be of size ev.size, and large enough for the event. The returned event - * will have it's time field set to it's delta time, in SMF tempo-based ticks, using the - * rate given by ppqn() (it is the caller's responsibility to calculate a real time). - * - * \a size should be the capacity of \a buf. If it is not large enough, \a buf will - * be freed and a new buffer allocated in its place, the size of which will be placed - * in size. - * - * Returns event length (including status byte) on success, 0 if event was - * skipped (eg a meta event), or -1 on EOF (or end of track). - */ -int -SMFSource::read_event(uint32_t* delta_t, uint32_t* size, uint8_t** buf) const -{ - if (feof(_fd)) { - return -1; - } - - assert(delta_t); - assert(size); - assert(buf); - - try { - *delta_t = SMFReader::read_var_len(_fd); - } catch (...) { - return -1; // Premature EOF - } - - if (feof(_fd)) { - return -1; // Premature EOF - } - - const int status = fgetc(_fd); - - if (status == EOF) { - return -1; // Premature EOF - } - - //printf("Status @ %X = %X\n", (unsigned)ftell(_fd) - 1, status); - - if (status == 0xFF) { - if (feof(_fd)) { - return -1; // Premature EOF - } - const int type = fgetc(_fd); - if ((unsigned char)type == 0x2F) { - return -1; // hit end of track - } else { - *size = 0; - return 0; - } - } - - const int event_size = midi_event_size((unsigned char)status) + 1; - if (event_size <= 0) { - *size = 0; - return 0; - } - - // Make sure we have enough scratch buffer - if (*size < (unsigned)event_size) - *buf = (uint8_t*)realloc(*buf, event_size); - - *size = event_size; - - (*buf)[0] = (unsigned char)status; - if (event_size > 1) - fread((*buf) + 1, 1, *size - 1, _fd); - - /*printf("SMFSource %s read event: delta = %u, size = %u, data = ", _name.c_str(), *delta_t, *size); - for (size_t i=0; i < *size; ++i) { - printf("%X ", (*buf)[i]); - } - printf("\n");*/ - - return (int)*size; -} - -/** All stamps in audio frames */ -nframes_t -SMFSource::read_unlocked (MidiRingBuffer& dst, nframes_t start, nframes_t cnt, nframes_t stamp_offset, nframes_t negative_stamp_offset) const -{ - //cerr << "SMF read_unlocked " << name() << " read " << start << ", count=" << cnt << ", offset=" << stamp_offset << endl; - - // 64 bits ought to be enough for anybody - uint64_t time = 0; // in SMF ticks, 1 tick per _ppqn - - _read_data_count = 0; - - // Output parameters for read_event (which will allocate scratch in buffer as needed) - uint32_t ev_delta_t = 0; - uint32_t ev_size = 0; - uint8_t* ev_buffer = 0; - - size_t scratch_size = 0; // keep track of scratch to minimize reallocs - - // FIXME: don't seek to start and search every read (brutal!) - fseek(_fd, _header_size, SEEK_SET); - - // FIXME: assumes tempo never changes after start - const double frames_per_beat = _session.tempo_map().tempo_at(_timeline_position).frames_per_beat( - _session.engine().frame_rate(), - _session.tempo_map().meter_at(_timeline_position)); - - const uint64_t start_ticks = (uint64_t)((start / frames_per_beat) * _ppqn); - - while (!feof(_fd)) { - int ret = read_event(&ev_delta_t, &ev_size, &ev_buffer); - if (ret == -1) { // EOF - //cerr << "SMF - EOF\n"; - break; - } - - time += ev_delta_t; // accumulate delta time - - if (ret == 0) { // meta-event (skipped, just accumulate time) - //cerr << "SMF - META\n"; - continue; - } - - if (time >= start_ticks) { - const nframes_t ev_frame_time = (nframes_t)( - ((time / (double)_ppqn) * frames_per_beat)) + stamp_offset; - - if (ev_frame_time <= start + cnt) - dst.write(ev_frame_time - negative_stamp_offset, ev_size, ev_buffer); - else - break; - } - - _read_data_count += ev_size; - - if (ev_size > scratch_size) - scratch_size = ev_size; - else - ev_size = scratch_size; // minimize realloc in read_event - } - - return cnt; -} - -/** All stamps in audio frames */ -nframes_t -SMFSource::write_unlocked (MidiRingBuffer& src, nframes_t cnt) -{ - _write_data_count = 0; - - double time; - size_t size; - - size_t buf_capacity = 4; - uint8_t* buf = (uint8_t*)malloc(buf_capacity); - - if (_model && ! _model->writing()) - _model->start_write(); - - MIDI::Event ev(0.0, 4, NULL, true); - - while (true) { - bool ret = src.full_peek(sizeof(double), (uint8_t*)&time); - if (!ret || time - _timeline_position > _length + cnt) - break; - - ret = src.read_prefix(&time, &size); - if (!ret) - break; - - if (size > buf_capacity) { - buf_capacity = size; - buf = (uint8_t*)realloc(buf, size); - } - - ret = src.read_contents(size, buf); - if (!ret) { - cerr << "ERROR: Read time/size but not buffer, corrupt MIDI ring buffer" << endl; - break; - } - - assert(time >= _timeline_position); - time -= _timeline_position; - - ev.set(buf, size, time); - if (! (ev.is_channel_event() || ev.is_smf_meta_event() || ev.is_sysex()) ) { - //cerr << "SMFSource: WARNING: caller tried to write non SMF-Event of type " << std::hex << int(ev.buffer()[0]) << endl; - continue; - } - - append_event_unlocked(Frames, ev); - - if (_model) - _model->append(ev); - } - - fflush(_fd); - free(buf); - - const nframes_t oldlen = _length; - update_length(oldlen, cnt); - - ViewDataRangeReady (_timeline_position + oldlen, cnt); /* EMIT SIGNAL */ - - return cnt; -} - - -void -SMFSource::append_event_unlocked(EventTimeUnit unit, const MIDI::Event& ev) -{ - if (ev.size() == 0) - return; - - /*printf("SMFSource: %s - append_event_unlocked chan = %u, time = %lf, size = %u, data = ", - name().c_str(), (unsigned)ev.channel(), ev.time(), ev.size()); - for (size_t i=0; i < ev.size(); ++i) { - printf("%X ", ev.buffer()[i]); - } - printf("\n");*/ - - assert(ev.time() >= 0); - - if (ev.time() < _last_ev_time) { - cerr << "SMFSource: Warning: Skipping event with ev.time() < _last_ev_time" << endl; - return; - } - - uint32_t delta_time = 0; - - if (unit == Frames) { - // FIXME: assumes tempo never changes after start - const double frames_per_beat = _session.tempo_map().tempo_at(_timeline_position).frames_per_beat( - _session.engine().frame_rate(), - _session.tempo_map().meter_at(_timeline_position)); - - delta_time = (uint32_t)((ev.time() - _last_ev_time) / frames_per_beat * _ppqn); - } else { - assert(unit == Beats); - delta_time = (uint32_t)((ev.time() - _last_ev_time) * _ppqn); - } - - - const size_t stamp_size = write_var_len(delta_time); - fwrite(ev.buffer(), 1, ev.size(), _fd); - - _track_size += stamp_size + ev.size(); - _write_data_count += ev.size(); - _last_ev_time = ev.time(); - - if (ev.size() > 0) - _empty = false; -} - - -XMLNode& -SMFSource::get_state () -{ - XMLNode& root (MidiSource::get_state()); - char buf[16]; - snprintf (buf, sizeof (buf), "0x%x", (int)_flags); - root.add_property ("flags", buf); - return root; -} - -int -SMFSource::set_state (const XMLNode& node) -{ - const XMLProperty* prop; - - if (MidiSource::set_state (node)) { - return -1; - } - - if ((prop = node.property (X_("flags"))) != 0) { - - int ival; - sscanf (prop->value().c_str(), "0x%x", &ival); - _flags = Flag (ival); - - } else { - - _flags = Flag (0); - - } - - assert(_name.find("/") == string::npos); - - return 0; -} - -void -SMFSource::mark_for_remove () -{ - if (!writable()) { - return; - } - _flags = Flag (_flags | RemoveAtDestroy); -} - -void -SMFSource::mark_streaming_midi_write_started (NoteMode mode, nframes_t start_frame) -{ - MidiSource::mark_streaming_midi_write_started (mode, start_frame); - _last_ev_time = 0; - fseek(_fd, _header_size, SEEK_SET); -} - -void -SMFSource::mark_streaming_write_completed () -{ - MidiSource::mark_streaming_write_completed(); - - if (!writable()) { - return; - } - - _model->set_edited(false); - flush_header(); - flush_footer(); -} - -void -SMFSource::mark_take (string id) -{ - if (writable()) { - _take_id = id; - } -} - -int -SMFSource::move_to_trash (const string trash_dir_name) -{ - string newpath; - - if (!writable()) { - return -1; - } - - /* don't move the file across filesystems, just - stick it in the 'trash_dir_name' directory - on whichever filesystem it was already on. - */ - - newpath = Glib::path_get_dirname (_path); - newpath = Glib::path_get_dirname (newpath); - - newpath += '/'; - newpath += trash_dir_name; - newpath += '/'; - newpath += Glib::path_get_basename (_path); - - if (access (newpath.c_str(), F_OK) == 0) { - - /* the new path already exists, try versioning */ - - char buf[PATH_MAX+1]; - int version = 1; - string newpath_v; - - snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version); - newpath_v = buf; - - while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) { - snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version); - newpath_v = buf; - } - - if (version == 999) { - PBD::error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"), - newpath) - << endmsg; - } else { - newpath = newpath_v; - } - - } else { - - /* it doesn't exist, or we can't read it or something */ - - } - - if (::rename (_path.c_str(), newpath.c_str()) != 0) { - PBD::error << string_compose (_("cannot rename midi file source from %1 to %2 (%3)"), - _path, newpath, strerror (errno)) - << endmsg; - return -1; - } -#if 0 - if (::unlink (peakpath.c_str()) != 0) { - PBD::error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"), - peakpath, _path, strerror (errno)) - << endmsg; - /* try to back out */ - rename (newpath.c_str(), _path.c_str()); - return -1; - } - - _path = newpath; - peakpath = ""; -#endif - /* file can not be removed twice, since the operation is not idempotent */ - - _flags = Flag (_flags & ~(RemoveAtDestroy|Removable|RemovableIfEmpty)); - - return 0; -} - -bool -SMFSource::safe_file_extension(const Glib::ustring& file) -{ - return (file.rfind(".mid") != Glib::ustring::npos); -} - -// FIXME: Merge this with audiofilesource somehow (make a generic filesource?) -bool -SMFSource::find (string pathstr, bool must_exist, bool& isnew) -{ - string::size_type pos; - bool ret = false; - - isnew = false; - - /* clean up PATH:CHANNEL notation so that we are looking for the correct path */ - - if ((pos = pathstr.find_last_of (':')) == string::npos) { - pathstr = pathstr; - } else { - pathstr = pathstr.substr (0, pos); - } - - if (pathstr[0] != '/') { - - /* non-absolute pathname: find pathstr in search path */ - - vector<string> dirs; - int cnt; - string fullpath; - string keeppath; - - if (_search_path.length() == 0) { - PBD::error << _("FileSource: search path not set") << endmsg; - goto out; - } - - split (_search_path, dirs, ':'); - - cnt = 0; - - for (vector<string>::iterator i = dirs.begin(); i != dirs.end(); ++i) { - - fullpath = *i; - if (fullpath[fullpath.length()-1] != '/') { - fullpath += '/'; - } - fullpath += pathstr; - - if (access (fullpath.c_str(), R_OK) == 0) { - keeppath = fullpath; - ++cnt; - } - } - - if (cnt > 1) { - - PBD::error << string_compose (_("FileSource: \"%1\" is ambigous when searching %2\n\t"), pathstr, _search_path) << endmsg; - goto out; - - } else if (cnt == 0) { - - if (must_exist) { - PBD::error << string_compose(_("Filesource: cannot find required file (%1): while searching %2"), pathstr, _search_path) << endmsg; - goto out; - } else { - isnew = true; - } - } - - _name = pathstr; - _path = keeppath; - ret = true; - - } else { - - /* external files and/or very very old style sessions include full paths */ - - _path = pathstr; - _name = pathstr.substr (pathstr.find_last_of ('/') + 1); - - if (access (_path.c_str(), R_OK) != 0) { - - /* file does not exist or we cannot read it */ - - if (must_exist) { - PBD::error << string_compose(_("Filesource: cannot find required file (%1): %2"), _path, strerror (errno)) << endmsg; - goto out; - } - - if (errno != ENOENT) { - PBD::error << string_compose(_("Filesource: cannot check for existing file (%1): %2"), _path, strerror (errno)) << endmsg; - goto out; - } - - /* a new file */ - - isnew = true; - ret = true; - - } else { - - /* already exists */ - - ret = true; - } - } - - out: - return ret; -} - -void -SMFSource::set_search_path (string p) -{ - _search_path = p; -} - - -void -SMFSource::set_allow_remove_if_empty (bool yn) -{ - if (writable()) { - _allow_remove_if_empty = yn; - } -} - -int -SMFSource::set_source_name (string newname, bool destructive) -{ - //Glib::Mutex::Lock lm (_lock); FIXME - string oldpath = _path; - string newpath = Session::change_midi_path_by_name (oldpath, _name, newname, destructive); - - if (newpath.empty()) { - PBD::error << string_compose (_("programming error: %1"), "cannot generate a changed midi path") << endmsg; - return -1; - } - - if (rename (oldpath.c_str(), newpath.c_str()) != 0) { - PBD::error << string_compose (_("cannot rename midi file for %1 to %2"), _name, newpath) << endmsg; - return -1; - } - - _name = Glib::path_get_basename (newpath); - _path = newpath; - - return 0;//rename_peakfile (peak_path (_path)); -} - -bool -SMFSource::is_empty () const -{ - return _empty; -} - - -void -SMFSource::write_chunk_header(const char id[4], uint32_t length) -{ - const uint32_t length_be = GUINT32_TO_BE(length); - - fwrite(id, 1, 4, _fd); - fwrite(&length_be, 4, 1, _fd); -} - -void -SMFSource::write_chunk(const char id[4], uint32_t length, void* data) -{ - write_chunk_header(id, length); - - fwrite(data, 1, length, _fd); -} - -/** Returns the size (in bytes) of the value written. */ -size_t -SMFSource::write_var_len(uint32_t value) -{ - size_t ret = 0; - - uint32_t buffer = value & 0x7F; - - while ( (value >>= 7) ) { - buffer <<= 8; - buffer |= ((value & 0x7F) | 0x80); - } - - while (true) { - //printf("Writing var len byte %X\n", (unsigned char)buffer); - ++ret; - fputc(buffer, _fd); - if (buffer & 0x80) - buffer >>= 8; - else - break; - } - - return ret; -} - -void -SMFSource::load_model(bool lock, bool force_reload) -{ - if (_writing) - return; - - if (lock) - Glib::Mutex::Lock lm (_lock); - - if (_model && !force_reload && !_model->empty()) - return; - - if (! _model) { - _model = boost::shared_ptr<MidiModel>(new MidiModel(this)); - cerr << _name << " loaded new model " << _model.get() << endl; - } else { - cerr << _name << " reloading model " << _model.get() - << " (" << _model->n_notes() << " notes)" <<endl; - _model->clear(); - } - - _model->start_write(); - - fseek(_fd, _header_size, SEEK_SET); - - uint64_t time = 0; /* in SMF ticks */ - MIDI::Event ev; - - size_t scratch_size = 0; // keep track of scratch and minimize reallocs - - // FIXME: assumes tempo never changes after start - const double frames_per_beat = _session.tempo_map().tempo_at(_timeline_position).frames_per_beat( - _session.engine().frame_rate(), - _session.tempo_map().meter_at(_timeline_position)); - - uint32_t delta_t = 0; - uint32_t size = 0; - uint8_t* buf = NULL; - int ret; - while ((ret = read_event(&delta_t, &size, &buf)) >= 0) { - - ev.set(buf, size, 0.0); - time += delta_t; - - if (ret > 0) { // didn't skip (meta) event - // make ev.time absolute time in frames - ev.time() = (double)time * frames_per_beat / (double)_ppqn; - _model->append(ev); - } - - if (ev.size() > scratch_size) - scratch_size = ev.size(); - else - ev.size() = scratch_size; - } - - _model->end_write(false); - _model->set_edited(false); - - free(buf); -} - - -void -SMFSource::destroy_model() -{ - //cerr << _name << " destroying model " << _model.get() << endl; - _model.reset(); -} - diff --git a/libs/ardour/sndfile_helpers.cc b/libs/ardour/sndfile_helpers.cc deleted file mode 100644 index 58a51f8bbe..0000000000 --- a/libs/ardour/sndfile_helpers.cc +++ /dev/null @@ -1,209 +0,0 @@ -/* - 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. - -*/ - -#include <map> -#include <vector> - -#include <pbd/convert.h> - -#include <sndfile.h> -#include <ardour/sndfile_helpers.h> - -#include "i18n.h" - -using std::map; -using namespace std; - -const char * const sndfile_header_formats_strings[SNDFILE_HEADER_FORMATS+1] = { - N_("WAV"), - N_("AIFF"), - N_("CAF"), - N_("W64 (64 bit WAV)"), - N_("raw (no header)"), - 0 -}; - -const char* const sndfile_file_endings_strings[SNDFILE_HEADER_FORMATS+1] = { - N_(".wav"), - N_(".aiff"), - N_(".caf"), - N_(".w64"), - N_(".raw"), - 0 -}; - -int sndfile_header_formats[SNDFILE_HEADER_FORMATS] = { - SF_FORMAT_WAV, - SF_FORMAT_AIFF, - SF_FORMAT_CAF, - SF_FORMAT_W64, - SF_FORMAT_RAW -}; - -const char * const sndfile_bitdepth_formats_strings[SNDFILE_BITDEPTH_FORMATS+1] = { - N_("Signed 16 bit PCM"), - N_("Signed 24 bit PCM"), - N_("Signed 32 bit PCM"), - N_("Signed 8 bit PCM"), - N_("32 bit float"), - 0 -}; - -int sndfile_bitdepth_formats[SNDFILE_BITDEPTH_FORMATS] = { - SF_FORMAT_PCM_16, - SF_FORMAT_PCM_24, - SF_FORMAT_PCM_32, - SF_FORMAT_PCM_S8, - SF_FORMAT_FLOAT -}; - -const char * const sndfile_endian_formats_strings[SNDFILE_ENDIAN_FORMATS+1] = { - N_("Little-endian (Intel)"), - N_("Big-endian (Mac)"), - 0 -}; - -int sndfile_endian_formats[SNDFILE_ENDIAN_FORMATS] = { - SF_ENDIAN_LITTLE, - SF_ENDIAN_BIG -}; - -int -sndfile_header_format_from_string (string str) -{ - for (int n = 0; sndfile_header_formats_strings[n]; ++n) { - if (str == sndfile_header_formats_strings[n]) { - return sndfile_header_formats[n]; - } - } - return -1; -} - -int -sndfile_bitdepth_format_from_string (string str) -{ - for (int n = 0; sndfile_bitdepth_formats_strings[n]; ++n) { - if (str == sndfile_bitdepth_formats_strings[n]) { - return sndfile_bitdepth_formats[n]; - } - } - return -1; -} - -int -sndfile_endian_format_from_string (string str) -{ - for (int n = 0; sndfile_endian_formats_strings[n]; ++n) { - if (str == sndfile_endian_formats_strings[n]) { - return sndfile_endian_formats[n]; - } - } - return -1; -} - -string -sndfile_file_ending_from_string (string str) -{ - static vector<string> file_endings; - - if (file_endings.empty()) { - file_endings = I18N((const char **) sndfile_file_endings_strings); - } - - for (int n = 0; sndfile_header_formats_strings[n]; ++n) { - if (str == sndfile_header_formats_strings[n]) { - return file_endings[n]; - } - } - return 0; -} - -int -sndfile_data_width (int format) -{ - int tval = format & 0xf; - - switch (tval) { - case SF_FORMAT_PCM_S8: - case SF_FORMAT_PCM_U8: - return 8; - case SF_FORMAT_PCM_16: - return 16; - case SF_FORMAT_PCM_24: - return 24; - case SF_FORMAT_PCM_32: - return 32; - case SF_FORMAT_FLOAT: - return 1; // heh, heh - default: - // we don't handle anything else within ardour - return 0; - } -} - -string -sndfile_major_format(int format) -{ - static map<int, string> m; - - if(m.empty()){ - SF_FORMAT_INFO format_info; - int count; - sf_command(0, SFC_GET_FORMAT_MAJOR_COUNT, &count, sizeof (int)); - for (int i = 0; i < count; ++i){ - format_info.format = i; - sf_command (0, SFC_GET_FORMAT_MAJOR, - &format_info, sizeof (format_info)); - m[format_info.format & SF_FORMAT_TYPEMASK] = format_info.name; - } - } - - map<int, string>::iterator p = m.find(format & SF_FORMAT_TYPEMASK); - if(p != m.end()){ - return m[format & SF_FORMAT_TYPEMASK]; - } else { - return "-Unknown-"; - } -} - -string -sndfile_minor_format(int format) -{ - static map<int, string> m; - - if(m.empty()){ - SF_FORMAT_INFO format_info; - int count; - sf_command(0, SFC_GET_FORMAT_SUBTYPE_COUNT, &count, sizeof (int)); - for (int i = 0; i < count; ++i){ - format_info.format = i; - sf_command (0, SFC_GET_FORMAT_SUBTYPE, - &format_info, sizeof (format_info)); - m[format_info.format & SF_FORMAT_SUBMASK] = format_info.name; - } - } - - map<int, string>::iterator p = m.find(format & SF_FORMAT_SUBMASK); - if(p != m.end()){ - return m[format & SF_FORMAT_SUBMASK]; - } else { - return "-Unknown-"; - } -} - diff --git a/libs/ardour/sndfileimportable.cc b/libs/ardour/sndfileimportable.cc deleted file mode 100644 index eb0e8a8afb..0000000000 --- a/libs/ardour/sndfileimportable.cc +++ /dev/null @@ -1,47 +0,0 @@ -#include <ardour/sndfileimportable.h> -#include <sndfile.h> - -using namespace ARDOUR; -using namespace std; - -SndFileImportableSource::SndFileImportableSource (const string& path) - : in (sf_open (path.c_str(), SFM_READ, &sf_info), sf_close) -{ - if (!in) throw failed_constructor(); -} - -SndFileImportableSource::~SndFileImportableSource () -{ -} - -nframes_t -SndFileImportableSource::read (Sample* buffer, nframes_t nframes) -{ - nframes_t per_channel = nframes / sf_info.channels; - per_channel = sf_readf_float (in.get(), buffer, per_channel); - return per_channel * sf_info.channels; -} - -uint -SndFileImportableSource::channels () const -{ - return sf_info.channels; -} - -nframes_t -SndFileImportableSource::length () const -{ - return sf_info.frames; -} - -nframes_t -SndFileImportableSource::samplerate() const -{ - return sf_info.samplerate; -} - -void -SndFileImportableSource::seek (nframes_t pos) -{ - sf_seek (in.get(), 0, SEEK_SET); -} diff --git a/libs/ardour/sndfilesource.cc b/libs/ardour/sndfilesource.cc deleted file mode 100644 index ab090381b4..0000000000 --- a/libs/ardour/sndfilesource.cc +++ /dev/null @@ -1,900 +0,0 @@ -/* - 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. - -*/ - -#include <cstring> -#include <cerrno> -#include <climits> - -#include <pwd.h> -#include <sys/utsname.h> -#include <sys/stat.h> - -#include <glibmm/miscutils.h> -#include <ardour/sndfilesource.h> -#include <ardour/sndfile_helpers.h> -#include <ardour/utils.h> - -#include "i18n.h" - -using namespace std; -using namespace ARDOUR; -using namespace PBD; -using Glib::ustring; - -gain_t* SndFileSource::out_coefficient = 0; -gain_t* SndFileSource::in_coefficient = 0; -nframes_t SndFileSource::xfade_frames = 64; -const AudioFileSource::Flag SndFileSource::default_writable_flags = AudioFileSource::Flag (AudioFileSource::Writable| - AudioFileSource::Removable| - AudioFileSource::RemovableIfEmpty| - AudioFileSource::CanRename); -SndFileSource::SndFileSource (Session& s, const XMLNode& node) - : AudioFileSource (s, node) -{ - init (); - - if (open()) { - throw failed_constructor (); - } -} - -SndFileSource::SndFileSource (Session& s, ustring path, int chn, Flag flags) - /* files created this way are never writable or removable */ - : AudioFileSource (s, path, Flag (flags & ~(Writable|Removable|RemovableIfEmpty|RemoveAtDestroy))) -{ - _channel = chn; - - init (); - - if (open()) { - throw failed_constructor (); - } -} - -SndFileSource::SndFileSource (Session& s, ustring path, SampleFormat sfmt, HeaderFormat hf, nframes_t rate, Flag flags) - : AudioFileSource (s, path, flags, sfmt, hf) -{ - int fmt = 0; - - init (); - - /* this constructor is used to construct new files, not open - existing ones. - */ - - file_is_new = true; - - switch (hf) { - case CAF: - fmt = SF_FORMAT_CAF; - _flags = Flag (_flags & ~Broadcast); - break; - - case AIFF: - fmt = SF_FORMAT_AIFF; - _flags = Flag (_flags & ~Broadcast); - break; - - case BWF: - fmt = SF_FORMAT_WAV; - _flags = Flag (_flags | Broadcast); - break; - - case WAVE: - fmt = SF_FORMAT_WAV; - _flags = Flag (_flags & ~Broadcast); - break; - - case WAVE64: - fmt = SF_FORMAT_W64; - _flags = Flag (_flags & ~Broadcast); - break; - - default: - fatal << string_compose (_("programming error: %1"), X_("unsupported audio header format requested")) << endmsg; - /*NOTREACHED*/ - break; - - } - - switch (sfmt) { - case FormatFloat: - fmt |= SF_FORMAT_FLOAT; - break; - - case FormatInt24: - fmt |= SF_FORMAT_PCM_24; - break; - - case FormatInt16: - fmt |= SF_FORMAT_PCM_16; - break; - } - - _info.channels = 1; - _info.samplerate = rate; - _info.format = fmt; - - if (open()) { - throw failed_constructor(); - } - - if (writable() && (_flags & Broadcast)) { - - _broadcast_info = new SF_BROADCAST_INFO; - memset (_broadcast_info, 0, sizeof (*_broadcast_info)); - - snprintf (_broadcast_info->description, sizeof (_broadcast_info->description), "BWF %s", _name.c_str()); - - struct utsname utsinfo; - - if (uname (&utsinfo)) { - error << string_compose(_("FileSource: cannot get host information for BWF header (%1)"), strerror(errno)) << endmsg; - return; - } - - snprintf (_broadcast_info->originator, sizeof (_broadcast_info->originator), "ardour:%s:%s:%s:%s:%s)", - Glib::get_real_name().c_str(), - utsinfo.nodename, - utsinfo.sysname, - utsinfo.release, - utsinfo.version); - - _broadcast_info->version = 1; - _broadcast_info->time_reference_low = 0; - _broadcast_info->time_reference_high = 0; - - /* XXX do something about this field */ - - snprintf (_broadcast_info->umid, sizeof (_broadcast_info->umid), "%s", "fnord"); - - /* coding history is added by libsndfile */ - - if (sf_command (sf, SFC_SET_BROADCAST_INFO, _broadcast_info, sizeof (_broadcast_info)) != SF_TRUE) { - char errbuf[256]; - sf_error_str (0, errbuf, sizeof (errbuf) - 1); - error << string_compose (_("cannot set broadcast info for audio file %1 (%2); dropping broadcast info for this file"), _path, errbuf) << endmsg; - _flags = Flag (_flags & ~Broadcast); - delete _broadcast_info; - _broadcast_info = 0; - } - } -} - -void -SndFileSource::init () -{ - ustring file; - - // lets try to keep the object initalizations here at the top - xfade_buf = 0; - sf = 0; - _broadcast_info = 0; - - if (is_embedded()) { - _name = _path; - } else { - _name = Glib::path_get_basename (_path); - } - - /* although libsndfile says we don't need to set this, - valgrind and source code shows us that we do. - */ - - memset (&_info, 0, sizeof(_info)); - - _capture_start = false; - _capture_end = false; - file_pos = 0; - - if (destructive()) { - xfade_buf = new Sample[xfade_frames]; - timeline_position = header_position_offset; - } - - AudioFileSource::HeaderPositionOffsetChanged.connect (mem_fun (*this, &SndFileSource::handle_header_position_change)); -} - -int -SndFileSource::open () -{ - if ((sf = sf_open (_path.c_str(), (writable() ? SFM_RDWR : SFM_READ), &_info)) == 0) { - char errbuf[256]; - sf_error_str (0, errbuf, sizeof (errbuf) - 1); -#ifndef HAVE_COREAUDIO - /* if we have CoreAudio, we will be falling back to that if libsndfile fails, - so we don't want to see this message. - */ - - error << string_compose(_("SndFileSource: cannot open file \"%1\" for %2 (%3)"), - _path, (writable() ? "read+write" : "reading"), errbuf) << endmsg; -#endif - return -1; - } - - if (_channel >= _info.channels) { -#ifndef HAVE_COREAUDIO - error << string_compose(_("SndFileSource: file only contains %1 channels; %2 is invalid as a channel number"), _info.channels, _channel) << endmsg; -#endif - sf_close (sf); - sf = 0; - return -1; - } - - _length = _info.frames; - - _broadcast_info = new SF_BROADCAST_INFO; - memset (_broadcast_info, 0, sizeof (*_broadcast_info)); - - bool timecode_info_exists; - - set_timeline_position (get_timecode_info (sf, _broadcast_info, timecode_info_exists)); - - if (_length != 0 && !timecode_info_exists) { - delete _broadcast_info; - _broadcast_info = 0; - _flags = Flag (_flags & ~Broadcast); - } - - if (writable()) { - sf_command (sf, SFC_SET_UPDATE_HEADER_AUTO, 0, SF_FALSE); - } - - return 0; -} - -SndFileSource::~SndFileSource () -{ - GoingAway (); /* EMIT SIGNAL */ - - if (sf) { - sf_close (sf); - sf = 0; - - /* stupid libsndfile updated the headers on close, - so touch the peakfile if it exists and has data - to make sure its time is as new as the audio - file. - */ - - touch_peakfile (); - } - - if (_broadcast_info) { - delete _broadcast_info; - } - - if (xfade_buf) { - delete [] xfade_buf; - } -} - -float -SndFileSource::sample_rate () const -{ - return _info.samplerate; -} - -nframes_t -SndFileSource::read_unlocked (Sample *dst, nframes_t start, nframes_t cnt) const -{ - int32_t nread; - float *ptr; - uint32_t real_cnt; - nframes_t file_cnt; - - if (start > _length) { - - /* read starts beyond end of data, just memset to zero */ - - file_cnt = 0; - - } else if (start + cnt > _length) { - - /* read ends beyond end of data, read some, memset the rest */ - - file_cnt = _length - start; - - } else { - - /* read is entirely within data */ - - file_cnt = cnt; - } - - if (file_cnt != cnt) { - nframes_t delta = cnt - file_cnt; - memset (dst+file_cnt, 0, sizeof (Sample) * delta); - } - - if (file_cnt) { - - if (sf_seek (sf, (sf_count_t) start, SEEK_SET|SFM_READ) != (sf_count_t) start) { - char errbuf[256]; - sf_error_str (0, errbuf, sizeof (errbuf) - 1); - error << string_compose(_("SndFileSource: could not seek to frame %1 within %2 (%3)"), start, _name.substr (1), errbuf) << endmsg; - return 0; - } - - if (_info.channels == 1) { - nframes_t ret = sf_read_float (sf, dst, file_cnt); - _read_data_count = cnt * sizeof(float); - return ret; - } - } - - real_cnt = cnt * _info.channels; - - Sample* interleave_buf = get_interleave_buffer (real_cnt); - - nread = sf_read_float (sf, interleave_buf, real_cnt); - ptr = interleave_buf + _channel; - nread /= _info.channels; - - /* stride through the interleaved data */ - - for (int32_t n = 0; n < nread; ++n) { - dst[n] = *ptr; - ptr += _info.channels; - } - - _read_data_count = cnt * sizeof(float); - - return nread; -} - -nframes_t -SndFileSource::write_unlocked (Sample *data, nframes_t cnt) -{ - if (destructive()) { - return destructive_write_unlocked (data, cnt); - } else { - return nondestructive_write_unlocked (data, cnt); - } -} - -nframes_t -SndFileSource::nondestructive_write_unlocked (Sample *data, nframes_t cnt) -{ - if (!writable()) { - warning << string_compose (_("attempt to write a non-writable audio file source (%1)"), _path) << endmsg; - return 0; - } - - if (_info.channels != 1) { - fatal << string_compose (_("programming error: %1 %2"), X_("SndFileSource::write called on non-mono file"), _path) << endmsg; - /*NOTREACHED*/ - return 0; - } - - nframes_t oldlen; - int32_t frame_pos = _length; - - if (write_float (data, frame_pos, cnt) != cnt) { - return 0; - } - - oldlen = _length; - update_length (oldlen, cnt); - - if (_build_peakfiles) { - compute_and_write_peaks (data, frame_pos, cnt, false, true); - } - - _write_data_count = cnt; - - return cnt; -} - -nframes_t -SndFileSource::destructive_write_unlocked (Sample* data, nframes_t cnt) -{ - nframes_t old_file_pos; - - if (!writable()) { - warning << string_compose (_("attempt to write a non-writable audio file source (%1)"), _path) << endmsg; - return 0; - } - - if (_capture_start && _capture_end) { - - /* start and end of capture both occur within the data we are writing, - so do both crossfades. - */ - - _capture_start = false; - _capture_end = false; - - /* move to the correct location place */ - file_pos = capture_start_frame - timeline_position; - - // split cnt in half - nframes_t subcnt = cnt / 2; - nframes_t ofilepos = file_pos; - - // fade in - if (crossfade (data, subcnt, 1) != subcnt) { - return 0; - } - - file_pos += subcnt; - Sample * tmpdata = data + subcnt; - - // fade out - subcnt = cnt - subcnt; - if (crossfade (tmpdata, subcnt, 0) != subcnt) { - return 0; - } - - file_pos = ofilepos; // adjusted below - - } else if (_capture_start) { - - /* start of capture both occur within the data we are writing, - so do the fade in - */ - - _capture_start = false; - _capture_end = false; - - /* move to the correct location place */ - file_pos = capture_start_frame - timeline_position; - - if (crossfade (data, cnt, 1) != cnt) { - return 0; - } - - } else if (_capture_end) { - - /* end of capture both occur within the data we are writing, - so do the fade out - */ - - _capture_start = false; - _capture_end = false; - - if (crossfade (data, cnt, 0) != cnt) { - return 0; - } - - } else { - - /* in the middle of recording */ - - if (write_float (data, file_pos, cnt) != cnt) { - return 0; - } - } - - old_file_pos = file_pos; - update_length (file_pos, cnt); - - if (_build_peakfiles) { - compute_and_write_peaks (data, file_pos, cnt, false, true); - } - - file_pos += cnt; - - return cnt; -} - -int -SndFileSource::update_header (nframes_t when, struct tm& now, time_t tnow) -{ - set_timeline_position (when); - - if (_flags & Broadcast) { - if (setup_broadcast_info (when, now, tnow)) { - return -1; - } - } - - return flush_header (); -} - -int -SndFileSource::flush_header () -{ - if (!writable() || (sf == 0)) { - warning << string_compose (_("attempt to flush a non-writable audio file source (%1)"), _path) << endmsg; - return -1; - } - return (sf_command (sf, SFC_UPDATE_HEADER_NOW, 0, 0) != SF_TRUE); -} - -int -SndFileSource::setup_broadcast_info (nframes_t when, struct tm& now, time_t tnow) -{ - if (!writable()) { - warning << string_compose (_("attempt to store broadcast info in a non-writable audio file source (%1)"), _path) << endmsg; - return -1; - } - - if (!(_flags & Broadcast)) { - return 0; - } - - /* random code is 9 digits */ - - int random_code = random() % 999999999; - - snprintf (_broadcast_info->originator_reference, sizeof (_broadcast_info->originator_reference), "%2s%3s%12s%02d%02d%02d%9d", - Config->get_bwf_country_code().c_str(), - Config->get_bwf_organization_code().c_str(), - bwf_serial_number, - now.tm_hour, - now.tm_min, - now.tm_sec, - random_code); - - snprintf (_broadcast_info->origination_date, sizeof (_broadcast_info->origination_date), "%4d-%02d-%02d", - 1900 + now.tm_year, - now.tm_mon, - now.tm_mday); - - snprintf (_broadcast_info->origination_time, sizeof (_broadcast_info->origination_time), "%02d:%02d:%02d", - now.tm_hour, - now.tm_min, - now.tm_sec); - - /* now update header position taking header offset into account */ - - set_header_timeline_position (); - - if (sf_command (sf, SFC_SET_BROADCAST_INFO, _broadcast_info, sizeof (*_broadcast_info)) != SF_TRUE) { - error << string_compose (_("cannot set broadcast info for audio file %1; Dropping broadcast info for this file"), _path) << endmsg; - _flags = Flag (_flags & ~Broadcast); - delete _broadcast_info; - _broadcast_info = 0; - return -1; - } - - return 0; -} - -void -SndFileSource::set_header_timeline_position () -{ - if (!(_flags & Broadcast)) { - return; - } - - _broadcast_info->time_reference_high = (timeline_position >> 32); - _broadcast_info->time_reference_low = (timeline_position & 0xffffffff); - - if (sf_command (sf, SFC_SET_BROADCAST_INFO, _broadcast_info, sizeof (*_broadcast_info)) != SF_TRUE) { - error << string_compose (_("cannot set broadcast info for audio file %1; Dropping broadcast info for this file"), _path) << endmsg; - _flags = Flag (_flags & ~Broadcast); - delete _broadcast_info; - _broadcast_info = 0; - } -} - -nframes_t -SndFileSource::write_float (Sample* data, nframes_t frame_pos, nframes_t cnt) -{ - if (sf_seek (sf, frame_pos, SEEK_SET|SFM_WRITE) < 0) { - char errbuf[256]; - sf_error_str (0, errbuf, sizeof (errbuf) - 1); - error << string_compose (_("%1: cannot seek to %2 (libsndfile error: %3"), _path, frame_pos, errbuf) << endmsg; - return 0; - } - - if (sf_writef_float (sf, data, cnt) != (ssize_t) cnt) { - return 0; - } - - return cnt; -} - -nframes_t -SndFileSource::natural_position() const -{ - return timeline_position; -} - -bool -SndFileSource::set_destructive (bool yn) -{ - if (yn) { - _flags = Flag (_flags | Destructive); - if (!xfade_buf) { - xfade_buf = new Sample[xfade_frames]; - } - clear_capture_marks (); - timeline_position = header_position_offset; - } else { - _flags = Flag (_flags & ~Destructive); - timeline_position = 0; - /* leave xfade buf alone in case we need it again later */ - } - - return true; -} - -void -SndFileSource::clear_capture_marks () -{ - _capture_start = false; - _capture_end = false; -} - -void -SndFileSource::mark_capture_start (nframes_t pos) -{ - if (destructive()) { - if (pos < timeline_position) { - _capture_start = false; - } else { - _capture_start = true; - capture_start_frame = pos; - } - } -} - -void -SndFileSource::mark_capture_end() -{ - if (destructive()) { - _capture_end = true; - } -} - -nframes_t -SndFileSource::crossfade (Sample* data, nframes_t cnt, int fade_in) -{ - nframes_t xfade = min (xfade_frames, cnt); - nframes_t nofade = cnt - xfade; - Sample* fade_data = 0; - nframes_t fade_position = 0; // in frames - ssize_t retval; - nframes_t file_cnt; - - if (fade_in) { - fade_position = file_pos; - fade_data = data; - } else { - fade_position = file_pos + nofade; - fade_data = data + nofade; - } - - if (fade_position > _length) { - - /* read starts beyond end of data, just memset to zero */ - - file_cnt = 0; - - } else if (fade_position + xfade > _length) { - - /* read ends beyond end of data, read some, memset the rest */ - - file_cnt = _length - fade_position; - - } else { - - /* read is entirely within data */ - - file_cnt = xfade; - } - - if (file_cnt) { - - if ((retval = read_unlocked (xfade_buf, fade_position, file_cnt)) != (ssize_t) file_cnt) { - if (retval >= 0 && errno == EAGAIN) { - /* XXX - can we really trust that errno is meaningful here? yes POSIX, i'm talking to you. - * short or no data there */ - memset (xfade_buf, 0, xfade * sizeof(Sample)); - } else { - error << string_compose(_("SndFileSource: \"%1\" bad read retval: %2 of %5 (%3: %4)"), _path, retval, errno, strerror (errno), xfade) << endmsg; - return 0; - } - } - } - - if (file_cnt != xfade) { - nframes_t delta = xfade - file_cnt; - memset (xfade_buf+file_cnt, 0, sizeof (Sample) * delta); - } - - if (nofade && !fade_in) { - if (write_float (data, file_pos, nofade) != nofade) { - error << string_compose(_("SndFileSource: \"%1\" bad write (%2)"), _path, strerror (errno)) << endmsg; - return 0; - } - } - - if (xfade == xfade_frames) { - - nframes_t n; - - /* use the standard xfade curve */ - - if (fade_in) { - - /* fade new material in */ - - for (n = 0; n < xfade; ++n) { - xfade_buf[n] = (xfade_buf[n] * out_coefficient[n]) + (fade_data[n] * in_coefficient[n]); - } - - } else { - - - /* fade new material out */ - - for (n = 0; n < xfade; ++n) { - xfade_buf[n] = (xfade_buf[n] * in_coefficient[n]) + (fade_data[n] * out_coefficient[n]); - } - } - - } else if (xfade < xfade_frames) { - - gain_t in[xfade]; - gain_t out[xfade]; - - /* short xfade, compute custom curve */ - - compute_equal_power_fades (xfade, in, out); - - for (nframes_t n = 0; n < xfade; ++n) { - xfade_buf[n] = (xfade_buf[n] * out[n]) + (fade_data[n] * in[n]); - } - - } else if (xfade) { - - /* long xfade length, has to be computed across several calls */ - - } - - if (xfade) { - if (write_float (xfade_buf, fade_position, xfade) != xfade) { - error << string_compose(_("SndFileSource: \"%1\" bad write (%2)"), _path, strerror (errno)) << endmsg; - return 0; - } - } - - if (fade_in && nofade) { - if (write_float (data + xfade, file_pos + xfade, nofade) != nofade) { - error << string_compose(_("SndFileSource: \"%1\" bad write (%2)"), _path, strerror (errno)) << endmsg; - return 0; - } - } - - return cnt; -} - -nframes_t -SndFileSource::last_capture_start_frame () const -{ - if (destructive()) { - return capture_start_frame; - } else { - return 0; - } -} - -void -SndFileSource::handle_header_position_change () -{ - if (destructive()) { - if ( _length != 0 ) { - error << string_compose(_("Filesource: start time is already set for existing file (%1): Cannot change start time."), _path ) << endmsg; - //in the future, pop up a dialog here that allows user to regenerate file with new start offset - } else if (writable()) { - timeline_position = header_position_offset; - set_header_timeline_position (); //this will get flushed if/when the file is recorded to - } - } -} - -void -SndFileSource::setup_standard_crossfades (nframes_t rate) -{ - /* This static method is assumed to have been called by the Session - before any DFS's are created. - */ - - xfade_frames = (nframes_t) floor ((Config->get_destructive_xfade_msecs () / 1000.0) * rate); - - if (out_coefficient) { - delete [] out_coefficient; - } - - if (in_coefficient) { - delete [] in_coefficient; - } - - out_coefficient = new gain_t[xfade_frames]; - in_coefficient = new gain_t[xfade_frames]; - - compute_equal_power_fades (xfade_frames, in_coefficient, out_coefficient); -} - -void -SndFileSource::set_timeline_position (int64_t pos) -{ - // destructive track timeline postion does not change - // except at instantion or when header_position_offset - // (session start) changes - - if (!destructive()) { - AudioFileSource::set_timeline_position (pos); - } -} - -int -SndFileSource::get_soundfile_info (const ustring& path, SoundFileInfo& info, string& error_msg) -{ - SNDFILE *sf; - SF_INFO sf_info; - SF_BROADCAST_INFO binfo; - bool timecode_exists; - - sf_info.format = 0; // libsndfile says to clear this before sf_open(). - - if ((sf = sf_open ((char*) path.c_str(), SFM_READ, &sf_info)) == 0) { - char errbuf[256]; - error_msg = sf_error_str (0, errbuf, sizeof (errbuf) - 1); - return false; - } - - info.samplerate = sf_info.samplerate; - info.channels = sf_info.channels; - info.length = sf_info.frames; - info.format_name = string_compose("Format: %1, %2", - sndfile_major_format(sf_info.format), - sndfile_minor_format(sf_info.format)); - - memset (&binfo, 0, sizeof (binfo)); - info.timecode = get_timecode_info (sf, &binfo, timecode_exists); - - if (!timecode_exists) { - info.timecode = 0; - } - - sf_close (sf); - - return true; -} - -int64_t -SndFileSource::get_timecode_info (SNDFILE* sf, SF_BROADCAST_INFO* binfo, bool& exists) -{ - if (sf_command (sf, SFC_GET_BROADCAST_INFO, binfo, sizeof (*binfo)) != SF_TRUE) { - exists = false; - return (header_position_offset); - } - - /* XXX 64 bit alert: when JACK switches to a 64 bit frame count, this needs to use the high bits - of the time reference. - */ - - exists = true; - int64_t ret = (uint32_t) binfo->time_reference_high; - ret <<= 32; - ret |= (uint32_t) binfo->time_reference_low; - return ret; -} - -bool -SndFileSource::one_of_several_channels () const -{ - return _info.channels > 1; -} - diff --git a/libs/ardour/source.cc b/libs/ardour/source.cc deleted file mode 100644 index f08d08b86e..0000000000 --- a/libs/ardour/source.cc +++ /dev/null @@ -1,269 +0,0 @@ -/* - 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. - -*/ - -#include <sys/stat.h> -#include <unistd.h> -#include <fcntl.h> -#include <poll.h> -#include <float.h> -#include <cerrno> -#include <ctime> -#include <cmath> -#include <iomanip> -#include <algorithm> -#include <fstream> - -#include <glibmm/thread.h> -#include <glibmm/miscutils.h> -#include <glibmm/fileutils.h> -#include <pbd/xml++.h> -#include <pbd/pthread_utils.h> - -#include <ardour/source.h> -#include <ardour/playlist.h> -#include <ardour/session.h> -#include <ardour/transient_detector.h> - -#include "i18n.h" - -using namespace std; -using namespace ARDOUR; - -Source::Source (Session& s, const string& name, DataType type) - : SessionObject(s, name) - , _type(type) -{ - // not true.. is this supposed to be an assertion? - //assert(_name.find("/") == string::npos); - - _analysed = false; - _timestamp = 0; - _length = 0; - _in_use = 0; -} - -Source::Source (Session& s, const XMLNode& node) - : SessionObject(s, "unnamed source") - , _type(DataType::AUDIO) -{ - _timestamp = 0; - _length = 0; - _analysed = false; - _in_use = 0; - - if (set_state (node) || _type == DataType::NIL) { - throw failed_constructor(); - } -} - -Source::~Source () -{ - notify_callbacks (); -} - -XMLNode& -Source::get_state () -{ - XMLNode *node = new XMLNode ("Source"); - char buf[64]; - - node->add_property ("name", _name); - node->add_property ("type", _type.to_string()); - _id.print (buf, sizeof (buf)); - node->add_property ("id", buf); - - if (_timestamp != 0) { - snprintf (buf, sizeof (buf), "%ld", _timestamp); - node->add_property ("timestamp", buf); - } - - return *node; -} - -int -Source::set_state (const XMLNode& node) -{ - const XMLProperty* prop; - - if ((prop = node.property ("name")) != 0) { - _name = prop->value(); - } else { - return -1; - } - - if ((prop = node.property ("id")) != 0) { - _id = prop->value (); - } else { - return -1; - } - - if ((prop = node.property ("type")) != 0) { - _type = DataType(prop->value()); - } - - if ((prop = node.property ("timestamp")) != 0) { - sscanf (prop->value().c_str(), "%ld", &_timestamp); - } - - // Don't think this is valid, absolute paths fail - //assert(_name.find("/") == string::npos); - - return 0; -} - -void -Source::update_length (nframes_t pos, nframes_t cnt) -{ - if (pos + cnt > _length) { - _length = pos+cnt; - } -} - -void -Source::add_playlist (boost::shared_ptr<Playlist> pl) -{ - std::pair<PlaylistMap::iterator,bool> res; - std::pair<boost::shared_ptr<Playlist>, uint32_t> newpair (pl, 1); - Glib::Mutex::Lock lm (_playlist_lock); - - res = _playlists.insert (newpair); - - if (!res.second) { - /* it already existed, bump count */ - res.first->second++; - } - - pl->GoingAway.connect (bind (mem_fun (*this, &Source::remove_playlist), boost::weak_ptr<Playlist> (pl))); -} - -void -Source::remove_playlist (boost::weak_ptr<Playlist> wpl) -{ - boost::shared_ptr<Playlist> pl (wpl.lock()); - - if (!pl) { - return; - } - - PlaylistMap::iterator x; - Glib::Mutex::Lock lm (_playlist_lock); - - if ((x = _playlists.find (pl)) != _playlists.end()) { - if (x->second > 1) { - x->second--; - } else { - _playlists.erase (x); - } - } -} - -uint32_t -Source::used () const -{ - return _playlists.size(); -} - -bool -Source::has_been_analysed() const -{ - Glib::Mutex::Lock lm (_analysis_lock); - return _analysed; -} - -void -Source::set_been_analysed (bool yn) -{ - { - Glib::Mutex::Lock lm (_analysis_lock); - _analysed = yn; - } - - if (yn) { - load_transients (get_transients_path()); - AnalysisChanged(); // EMIT SIGNAL - } -} - -int -Source::load_transients (const string& path) -{ - ifstream file (path.c_str()); - - if (!file) { - return -1; - } - - transients.clear (); - - stringstream strstr; - double val; - - while (file.good()) { - file >> val; - - if (!file.fail()) { - nframes64_t frame = (nframes64_t) floor (val * _session.frame_rate()); - transients.push_back (frame); - } - } - - return 0; -} - -string -Source::get_transients_path () const -{ - vector<string> parts; - string s; - - /* old sessions may not have the analysis directory */ - - _session.ensure_subdirs (); - - s = _session.analysis_dir (); - parts.push_back (s); - - s = _id.to_s(); - s += '.'; - s += TransientDetector::operational_identifier(); - parts.push_back (s); - - return Glib::build_filename (parts); -} - -bool -Source::check_for_analysis_data_on_disk () -{ - /* looks to see if the analysis files for this source are on disk. - if so, mark us already analysed. - */ - - string path = get_transients_path (); - bool ok = true; - - if (!Glib::file_test (path, Glib::FILE_TEST_EXISTS)) { - ok = false; - } - - // XXX add other tests here as appropriate - - set_been_analysed (ok); - return ok; -} - diff --git a/libs/ardour/source_factory.cc b/libs/ardour/source_factory.cc deleted file mode 100644 index 5338997659..0000000000 --- a/libs/ardour/source_factory.cc +++ /dev/null @@ -1,278 +0,0 @@ -/* - 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$ -*/ - -#include <pbd/error.h> -#include <pbd/convert.h> -#include <pbd/pthread_utils.h> -#include <pbd/stacktrace.h> - -#include <ardour/source_factory.h> -#include <ardour/sndfilesource.h> -#include <ardour/silentfilesource.h> -#include <ardour/configuration.h> -#include <ardour/smf_source.h> - -#ifdef HAVE_COREAUDIO -#define USE_COREAUDIO_FOR_FILES -#endif - -#ifdef USE_COREAUDIO_FOR_FILES -#include <ardour/coreaudiosource.h> -#endif - - -#include "i18n.h" - -using namespace ARDOUR; -using namespace std; -using namespace PBD; - -sigc::signal<void,boost::shared_ptr<Source> > SourceFactory::SourceCreated; -Glib::Cond* SourceFactory::PeaksToBuild; -Glib::StaticMutex SourceFactory::peak_building_lock = GLIBMM_STATIC_MUTEX_INIT; -std::list<boost::weak_ptr<AudioSource> > SourceFactory::files_with_peaks; - -static void -peak_thread_work () -{ - PBD::ThreadCreated (pthread_self(), string ("peakbuilder-") + to_string (pthread_self(), std::dec)); - - while (true) { - - SourceFactory::peak_building_lock.lock (); - - wait: - if (SourceFactory::files_with_peaks.empty()) { - SourceFactory::PeaksToBuild->wait (SourceFactory::peak_building_lock); - } - - if (SourceFactory::files_with_peaks.empty()) { - goto wait; - } - - boost::shared_ptr<AudioSource> as (SourceFactory::files_with_peaks.front().lock()); - SourceFactory::files_with_peaks.pop_front (); - SourceFactory::peak_building_lock.unlock (); - - if (!as) { - continue; - } - - as->setup_peakfile (); - } -} - -void -SourceFactory::init () -{ - PeaksToBuild = new Glib::Cond(); - - for (int n = 0; n < 2; ++n) { - Glib::Thread::create (sigc::ptr_fun (::peak_thread_work), false); - } -} - -int -SourceFactory::setup_peakfile (boost::shared_ptr<Source> s, bool async) -{ - boost::shared_ptr<AudioSource> as (boost::dynamic_pointer_cast<AudioSource> (s)); - - if (as) { - - if (async) { - - Glib::Mutex::Lock lm (peak_building_lock); - files_with_peaks.push_back (boost::weak_ptr<AudioSource> (as)); - PeaksToBuild->broadcast (); - - } else { - - if (as->setup_peakfile ()) { - error << string_compose("SourceFactory: could not set up peakfile for %1", as->name()) << endmsg; - return -1; - } - } - } - - return 0; -} - -boost::shared_ptr<Source> -SourceFactory::createSilent (Session& s, const XMLNode& node, nframes_t nframes, float sr) -{ - boost::shared_ptr<Source> ret (new SilentFileSource (s, node, nframes, sr)); - // no analysis data - the file is non-existent - SourceCreated (ret); - return ret; -} - -boost::shared_ptr<Source> -SourceFactory::create (Session& s, const XMLNode& node, bool defer_peaks) -{ - DataType type = DataType::AUDIO; - const XMLProperty* prop = node.property("type"); - - if (prop) { - type = DataType(prop->value()); - } - - if (type == DataType::AUDIO) { - - try { - - boost::shared_ptr<Source> ret (new SndFileSource (s, node)); - if (setup_peakfile (ret, defer_peaks)) { - return boost::shared_ptr<Source>(); - } - ret->check_for_analysis_data_on_disk (); - SourceCreated (ret); - return ret; - } - - catch (failed_constructor& err) { - -#ifdef USE_COREAUDIO_FOR_FILES - - /* this is allowed to throw */ - - boost::shared_ptr<Source> ret (new CoreAudioSource (s, node)); - - if (setup_peakfile (ret, defer_peaks)) { - return boost::shared_ptr<Source>(); - } - - ret->check_for_analysis_data_on_disk (); - SourceCreated (ret); - return ret; -#else - throw; // rethrow -#endif - } - - } else if (type == DataType::MIDI) { - boost::shared_ptr<Source> ret (new SMFSource (s, node)); - ret->check_for_analysis_data_on_disk (); - SourceCreated (ret); - return ret; - } - - return boost::shared_ptr<Source>(); -} - -boost::shared_ptr<Source> -SourceFactory::createReadable (DataType type, Session& s, string path, int chn, AudioFileSource::Flag flags, bool announce, bool defer_peaks) -{ - if (type == DataType::AUDIO) { - - if (!(flags & Destructive)) { - - try { - - boost::shared_ptr<Source> ret (new SndFileSource (s, path, chn, flags)); - - if (setup_peakfile (ret, defer_peaks)) { - return boost::shared_ptr<Source>(); - } - - ret->check_for_analysis_data_on_disk (); - if (announce) { - SourceCreated (ret); - } - return ret; - } - - catch (failed_constructor& err) { -#ifdef USE_COREAUDIO_FOR_FILES - - boost::shared_ptr<Source> ret (new CoreAudioSource (s, path, chn, flags)); - if (setup_peakfile (ret, defer_peaks)) { - return boost::shared_ptr<Source>(); - } - ret->check_for_analysis_data_on_disk (); - if (announce) { - SourceCreated (ret); - } - return ret; - -#else - throw; // rethrow -#endif - } - - } else { - // eh? - } - - } else if (type == DataType::MIDI) { - - // FIXME: flags? - boost::shared_ptr<Source> ret (new SMFSource (s, path, SMFSource::Flag(0))); - - if (announce) { - SourceCreated (ret); - } - - return ret; - - } - - return boost::shared_ptr<Source>(); -} - -boost::shared_ptr<Source> -SourceFactory::createWritable (DataType type, Session& s, std::string path, bool destructive, nframes_t rate, bool announce, bool defer_peaks) -{ - /* this might throw failed_constructor(), which is OK */ - - if (type == DataType::AUDIO) { - boost::shared_ptr<Source> ret (new SndFileSource - (s, path, - Config->get_native_file_data_format(), - Config->get_native_file_header_format(), - rate, - (destructive ? AudioFileSource::Flag (SndFileSource::default_writable_flags | AudioFileSource::Destructive) : - SndFileSource::default_writable_flags))); - - if (setup_peakfile (ret, defer_peaks)) { - return boost::shared_ptr<Source>(); - } - - // no analysis data - this is a new file - - if (announce) { - SourceCreated (ret); - } - return ret; - - } else if (type == DataType::MIDI) { - - boost::shared_ptr<Source> ret (new SMFSource (s, path)); - - // no analysis data - this is a new file - - if (announce) { - SourceCreated (ret); - } - return ret; - - } - - return boost::shared_ptr<Source> (); -} diff --git a/libs/ardour/sse_functions.s b/libs/ardour/sse_functions.s deleted file mode 100644 index 934ce6887a..0000000000 --- a/libs/ardour/sse_functions.s +++ /dev/null @@ -1,531 +0,0 @@ -/* - Copyright (C) 2005 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - Author: Sampo Savolainen - - $Id$ -*/ - - -#; void x86_sse_mix_buffers_with_gain (float *dst, float *src, long nframes, float gain); - -.globl x86_sse_mix_buffers_with_gain - .type x86_sse_mix_buffers_with_gain,@function - -x86_sse_mix_buffers_with_gain: -#; 8(%ebp) = float *dst = %edi -#; 12(%ebp) = float *src = %esi -#; 16(%ebp) = long nframes = %ecx -#; 20(%ebp) = float gain = st(0) - - pushl %ebp - movl %esp, %ebp - - #; save the registers -#; pushl %eax - pushl %ebx -#; pushl %ecx - pushl %edi - pushl %esi - - #; if nframes == 0, go to end - movl 16(%ebp), %ecx #; nframes - cmp $0, %ecx - je .MBWG_END - - #; Check for alignment - - movl 8(%ebp), %edi #; dst - movl 12(%ebp), %esi #; src - - movl %edi, %eax - andl $12, %eax #; mask alignemnt offset - - movl %esi, %ebx - andl $12, %ebx #; mask alignment offset - - cmp %eax, %ebx - jne .MBWG_NONALIGN #; if not aligned, calculate manually - - #; if we are aligned - cmp $0, %ebx - jz .MBWG_SSE - - #; Pre-loop, we need to run 1-3 frames "manually" without - #; SSE instructions - - movss 20(%ebp), %xmm1 #; xmm1 - -.MBWG_PRELOOP: - - movss (%esi), %xmm0 - mulss %xmm1, %xmm0 - addss (%edi), %xmm0 - movss %xmm0, (%edi) - - addl $4, %edi #; dst++ - addl $4, %esi #; src++ - decl %ecx #; nframes-- - jz .MBWG_END - -#; cmp $0, %ecx -#; je .MBWG_END #; if we run out of frames, go to end - - addl $4, %ebx - - cmp $16, %ebx #; test if we've reached 16 byte alignment - jne .MBWG_PRELOOP - - -.MBWG_SSE: - - cmp $4, %ecx #; we know it's not zero, but if it's not >=4, then - jnge .MBWG_NONALIGN #; we jump straight to the "normal" code - - #; copy gain to fill %xmm1 - movss 20(%ebp), %xmm1 - shufps $0x00, %xmm1, %xmm1 - - -.MBWG_SSELOOP: - - movaps (%esi), %xmm0 #; source => xmm0 - mulps %xmm1, %xmm0 #; apply gain to source - addps (%edi), %xmm0 #; mix with destination - movaps %xmm0, (%edi) #; copy result to destination - - addl $16, %edi #; dst+=4 - addl $16, %esi #; src+=4 - - subl $4, %ecx #; nframes-=4 - cmp $4, %ecx - jge .MBWG_SSELOOP - - cmp $0, %ecx - je .MBWG_END - - #; if there are remaining frames, the nonalign code will do nicely - #; for the rest 1-3 frames. - -.MBWG_NONALIGN: - #; not aligned! - - movss 20(%ebp), %xmm1 #; gain => xmm1 - -.MBWG_NONALIGNLOOP: - - movss (%esi), %xmm0 - mulss %xmm1, %xmm0 - addss (%edi), %xmm0 - movss %xmm0, (%edi) - - addl $4, %edi - addl $4, %esi - - decl %ecx - jnz .MBWG_NONALIGNLOOP - -.MBWG_END: - - popl %esi - popl %edi -#; popl %ecx - popl %ebx -#; popl %eax - - #; return - leave - ret - -.size x86_sse_mix_buffers_with_gain, .-x86_sse_mix_buffers_with_gain - - - - -#; void x86_sse_mix_buffers_no_gain (float *dst, float *src, long nframes); - -.globl x86_sse_mix_buffers_no_gain - .type x86_sse_mix_buffers_no_gain,@function - -x86_sse_mix_buffers_no_gain: -#; 8(%ebp) = float *dst = %edi -#; 12(%ebp) = float *src = %esi -#; 16(%ebp) = long nframes = %ecx - - pushl %ebp - movl %esp, %ebp - - #; save the registers -#; pushl %eax - pushl %ebx -#; pushl %ecx - pushl %edi - pushl %esi - - #; the real function - - #; if nframes == 0, go to end - movl 16(%ebp), %ecx #; nframes - cmp $0, %ecx - je .MBNG_END - - #; Check for alignment - - movl 8(%ebp), %edi #; dst - movl 12(%ebp), %esi #; src - - movl %edi, %eax - andl $12, %eax #; mask alignemnt offset - - movl %esi, %ebx - andl $12, %ebx #; mask alignment offset - - cmp %eax, %ebx - jne .MBNG_NONALIGN #; if not aligned, calculate manually - - cmp $0, %ebx - je .MBNG_SSE - - #; Pre-loop, we need to run 1-3 frames "manually" without - #; SSE instructions - -.MBNG_PRELOOP: - - movss (%esi), %xmm0 - addss (%edi), %xmm0 - movss %xmm0, (%edi) - - addl $4, %edi #; dst++ - addl $4, %esi #; src++ - decl %ecx #; nframes-- - jz .MBNG_END - addl $4, %ebx - - cmp $16, %ebx #; test if we've reached 16 byte alignment - jne .MBNG_PRELOOP - -.MBNG_SSE: - - cmp $4, %ecx #; if there are frames left, but less than 4 - jnge .MBNG_NONALIGN #; we can't run SSE - -.MBNG_SSELOOP: - - movaps (%esi), %xmm0 #; source => xmm0 - addps (%edi), %xmm0 #; mix with destination - movaps %xmm0, (%edi) #; copy result to destination - - addl $16, %edi #; dst+=4 - addl $16, %esi #; src+=4 - - subl $4, %ecx #; nframes-=4 - cmp $4, %ecx - jge .MBNG_SSELOOP - - cmp $0, %ecx - je .MBNG_END - - #; if there are remaining frames, the nonalign code will do nicely - #; for the rest 1-3 frames. - -.MBNG_NONALIGN: - #; not aligned! - - movss (%esi), %xmm0 #; src => xmm0 - addss (%edi), %xmm0 #; xmm0 += dst - movss %xmm0, (%edi) #; xmm0 => dst - - addl $4, %edi - addl $4, %esi - - decl %ecx - jnz .MBNG_NONALIGN - -.MBNG_END: - - popl %esi - popl %edi -#; popl %ecx - popl %ebx -#; popl %eax - - #; return - leave - ret - -.size x86_sse_mix_buffers_no_gain, .-x86_sse_mix_buffers_no_gain - - - - -#; void x86_sse_apply_gain_to_buffer (float *buf, long nframes, float gain); - -.globl x86_sse_apply_gain_to_buffer - .type x86_sse_apply_gain_to_buffer,@function - -x86_sse_apply_gain_to_buffer: -#; 8(%ebp) = float *buf = %edi -#; 12(%ebp) = long nframes = %ecx -#; 16(%ebp) = float gain = st(0) - - pushl %ebp - movl %esp, %ebp - - #; save %edi - pushl %edi - - #; the real function - - #; if nframes == 0, go to end - movl 12(%ebp), %ecx #; nframes - cmp $0, %ecx - je .AG_END - - #; create the gain buffer in %xmm1 - movss 16(%ebp), %xmm1 - shufps $0x00, %xmm1, %xmm1 - - #; Check for alignment - - movl 8(%ebp), %edi #; buf - movl %edi, %edx #; buf => %edx - andl $12, %edx #; mask bits 1 & 2, result = 0, 4, 8 or 12 - jz .AG_SSE #; if buffer IS aligned - - #; PRE-LOOP - #; we iterate 1-3 times, doing normal x87 float comparison - #; so we reach a 16 byte aligned "buf" (=%edi) value - -.AGLP_START: - - #; Load next value from the buffer - movss (%edi), %xmm0 - mulss %xmm1, %xmm0 - movss %xmm0, (%edi) - - #; increment buffer, decrement counter - addl $4, %edi #; buf++; - - decl %ecx #; nframes-- - jz .AG_END #; if we run out of frames, we go to the end - - addl $4, %edx #; one non-aligned byte less - cmp $16, %edx - jne .AGLP_START #; if more non-aligned frames exist, we do a do-over - -.AG_SSE: - - #; We have reached the 16 byte aligned "buf" ("edi") value - - #; Figure out how many loops we should do - movl %ecx, %eax #; copy remaining nframes to %eax for division - movl $0, %edx #; 0 the edx register - - - pushl %edi - movl $4, %edi - divl %edi #; %edx = remainder == 0 - popl %edi - - #; %eax = SSE iterations - cmp $0, %eax - je .AGPOST_START - - -.AGLP_SSE: - - movaps (%edi), %xmm0 - mulps %xmm1, %xmm0 - movaps %xmm0, (%edi) - - addl $16, %edi -#; subl $4, %ecx #; nframes-=4 - - decl %eax - jnz .AGLP_SSE - - #; Next we need to post-process all remaining frames - #; the remaining frame count is in %ecx - - #; if no remaining frames, jump to the end -#; cmp $0, %ecx - andl $3, %ecx #; nframes % 4 - je .AG_END - -.AGPOST_START: - - movss (%edi), %xmm0 - mulss %xmm1, %xmm0 - movss %xmm0, (%edi) - - #; increment buffer, decrement counter - addl $4, %edi #; buf++; - - decl %ecx #; nframes-- - jnz .AGPOST_START #; if we run out of frames, we go to the end - -.AG_END: - - - popl %edi - - #; return - leave - ret - -.size x86_sse_apply_gain_to_buffer, .-x86_sse_apply_gain_to_buffer -#; end proc - - - -#; float x86_sse_compute_peak(float *buf, long nframes, float current); - -.globl x86_sse_compute_peak - .type x86_sse_compute_peak,@function - -x86_sse_compute_peak: -#; 8(%ebp) = float *buf = %edi -#; 12(%ebp) = long nframes = %ecx -#; 16(%ebp) = float current = st(0) - - pushl %ebp - movl %esp, %ebp - - #; save %edi - pushl %edi - - #; the real function - - #; Load "current" in xmm0 - movss 16(%ebp), %xmm0 - - #; if nframes == 0, go to end - movl 12(%ebp), %ecx #; nframes - cmp $0, %ecx - je .CP_END - - #; create the "abs" mask in %xmm2 - pushl $2147483647 - movss (%esp), %xmm2 - addl $4, %esp - shufps $0x00, %xmm2, %xmm2 - - #; Check for alignment - - movl 8(%ebp), %edi #; buf - movl %edi, %edx #; buf => %edx - andl $12, %edx #; mask bits 1 & 2, result = 0, 4, 8 or 12 - jz .CP_SSE #; if buffer IS aligned - - #; PRE-LOOP - #; we iterate 1-3 times, doing normal x87 float comparison - #; so we reach a 16 byte aligned "buf" (=%edi) value - -.LP_START: - - #; Load next value from the buffer - movss (%edi), %xmm1 - andps %xmm2, %xmm1 - maxss %xmm1, %xmm0 - - #; increment buffer, decrement counter - addl $4, %edi #; buf++; - - decl %ecx #; nframes-- - jz .CP_END #; if we run out of frames, we go to the end - - addl $4, %edx #; one non-aligned byte less - cmp $16, %edx - jne .LP_START #; if more non-aligned frames exist, we do a do-over - -.CP_SSE: - - #; We have reached the 16 byte aligned "buf" ("edi") value - - #; Figure out how many loops we should do - movl %ecx, %eax #; copy remaining nframes to %eax for division - - shr $2,%eax #; unsigned divide by 4 - jz .POST_START - - #; %eax = SSE iterations - - #; current maximum is at %xmm0, but we need to .. - shufps $0x00, %xmm0, %xmm0 #; shuffle "current" to all 4 FP's - - #;prefetcht0 16(%edi) - -.LP_SSE: - - movaps (%edi), %xmm1 - andps %xmm2, %xmm1 - maxps %xmm1, %xmm0 - - addl $16, %edi - - decl %eax - jnz .LP_SSE - - #; Calculate the maximum value contained in the 4 FP's in %xmm0 - movaps %xmm0, %xmm1 - shufps $0x4e, %xmm1, %xmm1 #; shuffle left & right pairs (1234 => 3412) - maxps %xmm1, %xmm0 #; maximums of the two pairs - movaps %xmm0, %xmm1 - shufps $0xb1, %xmm1, %xmm1 #; shuffle the floats inside the two pairs (1234 => 2143) - maxps %xmm1, %xmm0 - - #; now every float in %xmm0 is the same value, current maximum value - - #; Next we need to post-process all remaining frames - #; the remaining frame count is in %ecx - - #; if no remaining frames, jump to the end - - andl $3, %ecx #; nframes % 4 - jz .CP_END - -.POST_START: - - movss (%edi), %xmm1 - andps %xmm2, %xmm1 - maxss %xmm1, %xmm0 - - addl $4, %edi #; buf++; - - decl %ecx #; nframes--; - jnz .POST_START - -.CP_END: - - #; Load the value from xmm0 to the float stack for returning - movss %xmm0, 16(%ebp) - flds 16(%ebp) - - popl %edi - - #; return - leave - ret - -.size x86_sse_compute_peak, .-x86_sse_compute_peak -#; end proc - -#ifdef __ELF__ -.section .note.GNU-stack,"",%progbits -#endif - - diff --git a/libs/ardour/sse_functions_64bit.s b/libs/ardour/sse_functions_64bit.s deleted file mode 100644 index 0242db3e77..0000000000 --- a/libs/ardour/sse_functions_64bit.s +++ /dev/null @@ -1,609 +0,0 @@ -/* - Copyright (C) 2005-2006 Paul Davis, John Rigg - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - Author: Sampo Savolainen - 64-bit conversion: John Rigg - - $Id$ -*/ - - -#; void x86_sse_mix_buffers_with_gain (float *dst, float *src, unsigned int nframes, float gain); - -.globl x86_sse_mix_buffers_with_gain - .type x86_sse_mix_buffers_with_gain,@function - -x86_sse_mix_buffers_with_gain: - -#; %rdi float *dst -#; %rsi float *src -#; %rdx unsigned int nframes -#; %xmm0 float gain - - pushq %rbp - movq %rsp, %rbp - - #; save the registers - pushq %rbx - pushq %rdi - pushq %rsi - - #; if nframes == 0, go to end - cmp $0, %rdx - je .MBWG_END - - #; Check for alignment - - movq %rdi, %rax - andq $12, %rax #; mask alignment offset - - movq %rsi, %rbx - andq $12, %rbx #; mask alignment offset - - cmp %rax, %rbx - jne .MBWG_NONALIGN #; if not aligned, calculate manually - - #; if we are aligned - cmp $0, %rbx - jz .MBWG_SSE - - #; Pre-loop, we need to run 1-3 frames "manually" without - #; SSE instructions - -.MBWG_PRELOOP: - - #; gain is already in %xmm0 - movss (%rsi), %xmm1 - mulss %xmm0, %xmm1 - addss (%rdi), %xmm1 - movss %xmm1, (%rdi) - - addq $4, %rdi #; dst++ - addq $4, %rsi #; src++ - decq %rdx #; nframes-- - jz .MBWG_END - - addq $4, %rbx - - cmp $16, %rbx #; test if we've reached 16 byte alignment - jne .MBWG_PRELOOP - - -.MBWG_SSE: - - cmp $4, %rdx #; we know it's not zero, but if it's not >=4, then - jnge .MBWG_NONALIGN #; we jump straight to the "normal" code - - #; gain is already in %xmm0 - shufps $0x00, %xmm0, %xmm0 - - -.MBWG_SSELOOP: - - movaps (%rsi), %xmm1 #; source => xmm0 - mulps %xmm0, %xmm1 #; apply gain to source - addps (%rdi), %xmm1 #; mix with destination - movaps %xmm1, (%rdi) #; copy result to destination - - addq $16, %rdi #; dst+=4 - addq $16, %rsi #; src+=4 - - subq $4, %rdx #; nframes-=4 - cmp $4, %rdx - jge .MBWG_SSELOOP - - cmp $0, %rdx - je .MBWG_END - - #; if there are remaining frames, the nonalign code will do nicely - #; for the rest 1-3 frames. - -.MBWG_NONALIGN: - #; not aligned! - - #; gain is already in %xmm0 - -.MBWG_NONALIGNLOOP: - - movss (%rsi), %xmm1 - mulss %xmm0, %xmm1 - addss (%rdi), %xmm1 - movss %xmm1, (%rdi) - - addq $4, %rdi - addq $4, %rsi - - decq %rdx - jnz .MBWG_NONALIGNLOOP - -.MBWG_END: - - popq %rsi - popq %rdi - popq %rbx - - #; return - leave - ret - -.size x86_sse_mix_buffers_with_gain, .-x86_sse_mix_buffers_with_gain - - -#; void x86_sse_mix_buffers_no_gain (float *dst, float *src, unsigned int nframes); - -.globl x86_sse_mix_buffers_no_gain - .type x86_sse_mix_buffers_no_gain,@function - -x86_sse_mix_buffers_no_gain: - -#; %rdi float *dst -#; %rsi float *src -#; %rdx unsigned int nframes - - pushq %rbp - movq %rsp, %rbp - - #; save the registers - pushq %rbx - pushq %rdi - pushq %rsi - - #; the real function - - #; if nframes == 0, go to end - cmp $0, %rdx - je .MBNG_END - - #; Check for alignment - - movq %rdi, %rax - andq $12, %rax #; mask alignment offset - - movq %rsi, %rbx - andq $12, %rbx #; mask alignment offset - - cmp %rax, %rbx - jne .MBNG_NONALIGN #; if not aligned, calculate manually - - cmp $0, %rbx - je .MBNG_SSE - - #; Pre-loop, we need to run 1-3 frames "manually" without - #; SSE instructions - -.MBNG_PRELOOP: - - movss (%rsi), %xmm0 - addss (%rdi), %xmm0 - movss %xmm0, (%rdi) - - addq $4, %rdi #; dst++ - addq $4, %rsi #; src++ - decq %rdx #; nframes-- - jz .MBNG_END - addq $4, %rbx - - cmp $16, %rbx #; test if we've reached 16 byte alignment - jne .MBNG_PRELOOP - -.MBNG_SSE: - - cmp $4, %rdx #; if there are frames left, but less than 4 - jnge .MBNG_NONALIGN #; we can't run SSE - -.MBNG_SSELOOP: - - movaps (%rsi), %xmm0 #; source => xmm0 - addps (%rdi), %xmm0 #; mix with destination - movaps %xmm0, (%rdi) #; copy result to destination - - addq $16, %rdi #; dst+=4 - addq $16, %rsi #; src+=4 - - subq $4, %rdx #; nframes-=4 - cmp $4, %rdx - jge .MBNG_SSELOOP - - cmp $0, %rdx - je .MBNG_END - - #; if there are remaining frames, the nonalign code will do nicely - #; for the rest 1-3 frames. - -.MBNG_NONALIGN: - #; not aligned! - - movss (%rsi), %xmm0 #; src => xmm0 - addss (%rdi), %xmm0 #; xmm0 += dst - movss %xmm0, (%rdi) #; xmm0 => dst - - addq $4, %rdi - addq $4, %rsi - - decq %rdx - jnz .MBNG_NONALIGN - -.MBNG_END: - - popq %rsi - popq %rdi - popq %rbx - - #; return - leave - ret - -.size x86_sse_mix_buffers_no_gain, .-x86_sse_mix_buffers_no_gain - - -#; void x86_sse_apply_gain_to_buffer (float *buf, unsigned int nframes, float gain); - -.globl x86_sse_apply_gain_to_buffer - .type x86_sse_apply_gain_to_buffer,@function - -x86_sse_apply_gain_to_buffer: - -#; %rdi float *buf 32(%rbp) -#; %rsi unsigned int nframes -#; %xmm0 float gain -#; %xmm1 float buf[0] - - pushq %rbp - movq %rsp, %rbp - - #; save %rdi - pushq %rdi - - #; the real function - - #; if nframes == 0, go to end - movq %rsi, %rcx #; nframes - cmp $0, %rcx - je .AG_END - - #; set up the gain buffer (gain is already in %xmm0) - shufps $0x00, %xmm0, %xmm0 - - #; Check for alignment - - movq %rdi, %rdx #; buf => %rdx - andq $12, %rdx #; mask bits 1 & 2, result = 0, 4, 8 or 12 - jz .AG_SSE #; if buffer IS aligned - - #; PRE-LOOP - #; we iterate 1-3 times, doing normal x87 float comparison - #; so we reach a 16 byte aligned "buf" (=%rdi) value - -.AGLP_START: - - #; Load next value from the buffer into %xmm1 - movss (%rdi), %xmm1 - mulss %xmm0, %xmm1 - movss %xmm1, (%rdi) - - #; increment buffer, decrement counter - addq $4, %rdi #; buf++; - - decq %rcx #; nframes-- - jz .AG_END #; if we run out of frames, we go to the end - - addq $4, %rdx #; one non-aligned byte less - cmp $16, %rdx - jne .AGLP_START #; if more non-aligned frames exist, we do a do-over - -.AG_SSE: - - #; We have reached the 16 byte aligned "buf" ("rdi") value - - #; Figure out how many loops we should do - movq %rcx, %rax #; copy remaining nframes to %rax for division - movq $0, %rdx #; 0 the edx register - - - pushq %rdi - movq $4, %rdi - divq %rdi #; %rdx = remainder == 0 - popq %rdi - - #; %rax = SSE iterations - cmp $0, %rax - je .AGPOST_START - - -.AGLP_SSE: - - movaps (%rdi), %xmm1 - mulps %xmm0, %xmm1 - movaps %xmm1, (%rdi) - - addq $16, %rdi - subq $4, %rcx #; nframes-=4 - - decq %rax - jnz .AGLP_SSE - - #; Next we need to post-process all remaining frames - #; the remaining frame count is in %rcx - - #; if no remaining frames, jump to the end - cmp $0, %rcx - andq $3, %rcx #; nframes % 4 - je .AG_END - -.AGPOST_START: - - movss (%rdi), %xmm1 - mulss %xmm0, %xmm1 - movss %xmm1, (%rdi) - - #; increment buffer, decrement counter - addq $4, %rdi #; buf++; - - decq %rcx #; nframes-- - jnz .AGPOST_START #; if we run out of frames, we go to the end - -.AG_END: - - - popq %rdi - - #; return - leave - ret - -.size x86_sse_apply_gain_to_buffer, .-x86_sse_apply_gain_to_buffer -#; end proc - - -#; x86_sse_apply_gain_vector(float *buf, float *gain_vector, unsigned int nframes) - -.globl x86_sse_apply_gain_vector - .type x86_sse_apply_gain_vector,@function - -x86_sse_apply_gain_vector: - -#; %rdi float *buf -#; %rsi float *gain_vector -#; %rdx unsigned int nframes - - pushq %rbp - movq %rsp, %rbp - - #; Save registers - pushq %rdi - pushq %rsi - pushq %rbx - - #; if nframes == 0 go to end - cmp $0, %rdx - je .AGA_END - - #; Check alignment - movq %rdi, %rax - andq $12, %rax - - movq %rsi, %rbx - andq $12, %rbx - - cmp %rax,%rbx - jne .AGA_ENDLOOP - - cmp $0, %rax - jz .AGA_SSE #; if buffers are aligned, jump to the SSE loop - -#; Buffers aren't 16 byte aligned, but they are unaligned by the same amount -.AGA_ALIGNLOOP: - - movss (%rdi), %xmm0 #; buf => xmm0 - movss (%rsi), %xmm1 #; gain value => xmm1 - mulss %xmm1, %xmm0 #; xmm1 * xmm0 => xmm0 - movss %xmm0, (%rdi) #; signal with gain => buf - - decq %rdx - jz .AGA_END - - addq $4, %rdi #; buf++ - addq $4, %rsi #; gab++ - - addq $4, %rax - cmp $16, %rax - jne .AGA_ALIGNLOOP - -#; There are frames left for sure, as that is checked in the beginning -#; and within the previous loop. BUT, there might be less than 4 frames -#; to process - -.AGA_SSE: - movq %rdx, %rax #; nframes => %rax - shr $2, %rax #; unsigned divide by 4 - - cmp $0, %rax #; Jos toimii ilman tätä, niin kiva - je .AGA_ENDLOOP - -.AGA_SSELOOP: - movaps (%rdi), %xmm0 - movaps (%rsi), %xmm1 - mulps %xmm1, %xmm0 - movaps %xmm0, (%rdi) - - addq $16, %rdi - addq $16, %rsi - - decq %rax - jnz .AGA_SSELOOP - - andq $3, %rdx #; Remaining frames are nframes & 3 - jz .AGA_END - - -#; Inside this loop, we know there are frames left to process -#; but because either there are < 4 frames left, or the buffers -#; are not aligned, we can't use the parallel SSE ops -.AGA_ENDLOOP: - movss (%rdi), %xmm0 #; buf => xmm0 - movss (%rsi), %xmm1 #; gain value => xmm1 - mulss %xmm1, %xmm0 #; xmm1 * xmm0 => xmm0 - movss %xmm0, (%rdi) #; signal with gain => buf - - addq $4,%rdi - addq $4,%rsi - decq %rdx #; nframes-- - jnz .AGA_ENDLOOP - -.AGA_END: - - popq %rbx - popq %rsi - popq %rdi - - leave - ret - -.size x86_sse_apply_gain_vector, .-x86_sse_apply_gain_vector -#; end proc - - -#; float x86_sse_compute_peak(float *buf, long nframes, float current); - -.globl x86_sse_compute_peak - .type x86_sse_compute_peak,@function - - -x86_sse_compute_peak: - -#; %rdi float *buf 32(%rbp) -#; %rsi unsigned int nframes -#; %xmm0 float current -#; %xmm1 float buf[0] - - pushq %rbp - movq %rsp, %rbp - - #; save %rdi - pushq %rdi - - #; if nframes == 0, go to end - movq %rsi, %rcx #; nframes - cmp $0, %rcx - je .CP_END - - #; create the "abs" mask in %xmm2 - pushq $2147483647 - movss (%rsp), %xmm2 - addq $8, %rsp - shufps $0x00, %xmm2, %xmm2 - - #; Check for alignment - - #;movq 8(%rbp), %rdi #; buf - movq %rdi, %rdx #; buf => %rdx - andq $12, %rdx #; mask bits 1 & 2, result = 0, 4, 8 or 12 - jz .CP_SSE #; if buffer IS aligned - - #; PRE-LOOP - #; we iterate 1-3 times, doing normal x87 float comparison - #; so we reach a 16 byte aligned "buf" (=%rdi) value - -.LP_START: - - #; Load next value from the buffer - movss (%rdi), %xmm1 - andps %xmm2, %xmm1 - maxss %xmm1, %xmm0 - - #; increment buffer, decrement counter - addq $4, %rdi #; buf++; - - decq %rcx #; nframes-- - jz .CP_END #; if we run out of frames, we go to the end - - addq $4, %rdx #; one non-aligned byte less - cmp $16, %rdx - jne .LP_START #; if more non-aligned frames exist, we do a do-over - -.CP_SSE: - - #; We have reached the 16 byte aligned "buf" ("rdi") value - - #; Figure out how many loops we should do - movq %rcx, %rax #; copy remaining nframes to %rax for division - - shr $2,%rax #; unsigned divide by 4 - jz .POST_START - - #; %rax = SSE iterations - - #; current maximum is at %xmm0, but we need to .. - shufps $0x00, %xmm0, %xmm0 #; shuffle "current" to all 4 FP's - - #;prefetcht0 16(%rdi) - -.LP_SSE: - - movaps (%rdi), %xmm1 - andps %xmm2, %xmm1 - maxps %xmm1, %xmm0 - - addq $16, %rdi - - decq %rax - jnz .LP_SSE - - #; Calculate the maximum value contained in the 4 FP's in %xmm0 - movaps %xmm0, %xmm1 - shufps $0x4e, %xmm1, %xmm1 #; shuffle left & right pairs (1234 => 3412) - maxps %xmm1, %xmm0 #; maximums of the two pairs - movaps %xmm0, %xmm1 - shufps $0xb1, %xmm1, %xmm1 #; shuffle the floats inside the two pairs (1234 => 2143) - maxps %xmm1, %xmm0 - - #; now every float in %xmm0 is the same value, current maximum value - - #; Next we need to post-process all remaining frames - #; the remaining frame count is in %rcx - - #; if no remaining frames, jump to the end - - andq $3, %rcx #; nframes % 4 - jz .CP_END - -.POST_START: - - movss (%rdi), %xmm1 - andps %xmm2, %xmm1 - maxss %xmm1, %xmm0 - - addq $4, %rdi #; buf++; - - decq %rcx #; nframes--; - jnz .POST_START - -.CP_END: - - popq %rdi - - #; return - leave - ret - -.size x86_sse_compute_peak, .-x86_sse_compute_peak -#; end proc - -#ifdef __ELF__ -.section .note.GNU-stack,"",%progbits -#endif - diff --git a/libs/ardour/sse_functions_xmm.cc b/libs/ardour/sse_functions_xmm.cc deleted file mode 100644 index 9b37c37912..0000000000 --- a/libs/ardour/sse_functions_xmm.cc +++ /dev/null @@ -1,116 +0,0 @@ -/* - Copyright (C) 2007 Paul sDavis - Written by 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. - -*/ - -#include <xmmintrin.h> -#include <ardour/types.h> - -void -x86_sse_find_peaks(const ARDOUR::Sample* buf, nframes_t nframes, float *min, float *max) -{ - __m128 current_max, current_min, work; - - // Load max and min values into all four slots of the XMM registers - current_min = _mm_set1_ps(*min); - current_max = _mm_set1_ps(*max); - - // Work input until "buf" reaches 16 byte alignment - while ( ((unsigned long)buf) % 16 != 0 && nframes > 0) { - - // Load the next float into the work buffer - work = _mm_set1_ps(*buf); - - current_min = _mm_min_ps(current_min, work); - current_max = _mm_max_ps(current_max, work); - - buf++; - nframes--; - } - - // use 64 byte prefetch for quadruple quads - while (nframes >= 16) { - __builtin_prefetch(buf+64,0,0); - - work = _mm_load_ps(buf); - current_min = _mm_min_ps(current_min, work); - current_max = _mm_max_ps(current_max, work); - buf+=4; - work = _mm_load_ps(buf); - current_min = _mm_min_ps(current_min, work); - current_max = _mm_max_ps(current_max, work); - buf+=4; - work = _mm_load_ps(buf); - current_min = _mm_min_ps(current_min, work); - current_max = _mm_max_ps(current_max, work); - buf+=4; - work = _mm_load_ps(buf); - current_min = _mm_min_ps(current_min, work); - current_max = _mm_max_ps(current_max, work); - buf+=4; - nframes-=16; - } - - // work through aligned buffers - while (nframes >= 4) { - - work = _mm_load_ps(buf); - - current_min = _mm_min_ps(current_min, work); - current_max = _mm_max_ps(current_max, work); - - buf+=4; - nframes-=4; - } - - // work through the rest < 4 samples - while ( nframes > 0) { - - // Load the next float into the work buffer - work = _mm_set1_ps(*buf); - - current_min = _mm_min_ps(current_min, work); - current_max = _mm_max_ps(current_max, work); - - buf++; - nframes--; - } - - // Find min & max value in current_max through shuffle tricks - - work = current_min; - work = _mm_shuffle_ps(work, work, _MM_SHUFFLE(2, 3, 0, 1)); - work = _mm_min_ps (work, current_min); - current_min = work; - work = _mm_shuffle_ps(work, work, _MM_SHUFFLE(1, 0, 3, 2)); - work = _mm_min_ps (work, current_min); - - _mm_store_ss(min, work); - - work = current_max; - work = _mm_shuffle_ps(work, work, _MM_SHUFFLE(2, 3, 0, 1)); - work = _mm_max_ps (work, current_max); - current_max = work; - work = _mm_shuffle_ps(work, work, _MM_SHUFFLE(1, 0, 3, 2)); - work = _mm_max_ps (work, current_max); - - _mm_store_ss(max, work); -} - - - diff --git a/libs/ardour/st_pitch.cc b/libs/ardour/st_pitch.cc deleted file mode 100644 index 3999c1a746..0000000000 --- a/libs/ardour/st_pitch.cc +++ /dev/null @@ -1,52 +0,0 @@ -/* - Copyright (C) 2004-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. - -*/ - -#include <algorithm> -#include <cmath> - -#include <pbd/error.h> - -#include <ardour/types.h> -#include <ardour/pitch.h> -#include <ardour/audiofilesource.h> -#include <ardour/session.h> -#include <ardour/audioregion.h> - -#include "i18n.h" - -using namespace std; -using namespace ARDOUR; -using namespace PBD; - -Pitch::Pitch (Session& s, TimeFXRequest& req) - : Filter (s) - , tsr (req) - -{ - tsr.progress = 0.0f; -} - -int -Pitch::run (boost::shared_ptr<Region> region) -{ - tsr.progress = 1.0f; - tsr.done = true; - - return 1; -} diff --git a/libs/ardour/st_stretch.cc b/libs/ardour/st_stretch.cc deleted file mode 100644 index e96cd79f2d..0000000000 --- a/libs/ardour/st_stretch.cc +++ /dev/null @@ -1,215 +0,0 @@ -/* - Copyright (C) 2004-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. - -*/ - -#include <algorithm> -#include <cmath> - -#include <pbd/error.h> - -#include <ardour/types.h> -#include <ardour/stretch.h> -#include <ardour/audiofilesource.h> -#include <ardour/session.h> -#include <ardour/audioregion.h> - -#include "i18n.h" - -using namespace std; -using namespace ARDOUR; -using namespace PBD; -using namespace soundtouch; - -Stretch::Stretch (Session& s, TimeFXRequest& req) - : Filter (s) - , tsr (req) -{ - float percentage; - - /* the soundtouch code wants a *tempo* change percentage, which is - of opposite sign to the length change. - */ - - percentage = -tsr.time_fraction; - - st.setSampleRate (s.frame_rate()); - st.setChannels (1); - st.setTempoChange (percentage); - st.setPitchSemiTones (0); - st.setRateChange (0); - - st.setSetting(SETTING_USE_QUICKSEEK, tsr.quick_seek); - st.setSetting(SETTING_USE_AA_FILTER, tsr.antialias); - - tsr.progress = 0.0f; -} - -Stretch::~Stretch () -{ -} - -int -Stretch::run (boost::shared_ptr<Region> a_region) -{ - SourceList nsrcs; - nframes_t total_frames; - nframes_t done; - int ret = -1; - const nframes_t bufsize = 16384; - gain_t *gain_buffer = 0; - Sample *buffer = 0; - char suffix[32]; - string new_name; - string::size_type at; - - tsr.progress = 0.0f; - tsr.done = false; - - boost::shared_ptr<AudioRegion> region = boost::dynamic_pointer_cast<AudioRegion>(a_region); - - total_frames = region->length() * region->n_channels(); - done = 0; - - /* the name doesn't need to be super-precise, but allow for 2 fractional - digits just to disambiguate close but not identical stretches. - */ - - snprintf (suffix, sizeof (suffix), "@%d", (int) floor (tsr.time_fraction * 100.0f)); - - /* create new sources */ - - if (make_new_sources (region, nsrcs, suffix)) { - goto out; - } - - gain_buffer = new gain_t[bufsize]; - buffer = new Sample[bufsize]; - - // soundtouch throws runtime_error on error - - try { - for (uint32_t i = 0; i < nsrcs.size(); ++i) { - - boost::shared_ptr<AudioSource> asrc - = boost::dynamic_pointer_cast<AudioSource>(nsrcs[i]); - - nframes_t pos = 0; - nframes_t this_read = 0; - - st.clear(); - - while (!tsr.cancel && pos < region->length()) { - nframes_t this_time; - - this_time = min (bufsize, region->length() - pos); - - /* read from the master (original) sources for the region, - not the ones currently in use, in case it's already been - subject to timefx. - */ - - if ((this_read = region->master_read_at (buffer, buffer, gain_buffer, pos + region->position(), this_time)) != this_time) { - error << string_compose (_("tempoize: error reading data from %1"), asrc->name()) << endmsg; - goto out; - } - - pos += this_read; - done += this_read; - - tsr.progress = (float) done / total_frames; - - st.putSamples (buffer, this_read); - - while ((this_read = st.receiveSamples (buffer, bufsize)) > 0 && !tsr.cancel) { - if (asrc->write (buffer, this_read) != this_read) { - error << string_compose (_("error writing tempo-adjusted data to %1"), asrc->name()) << endmsg; - goto out; - } - } - } - - if (!tsr.cancel) { - st.flush (); - } - - while (!tsr.cancel && (this_read = st.receiveSamples (buffer, bufsize)) > 0) { - if (asrc->write (buffer, this_read) != this_read) { - error << string_compose (_("error writing tempo-adjusted data to %1"), asrc->name()) << endmsg; - goto out; - } - } - } - - } catch (runtime_error& err) { - error << _("timefx code failure. please notify ardour-developers.") << endmsg; - error << err.what() << endmsg; - goto out; - } - - new_name = region->name(); - at = new_name.find ('@'); - - // remove any existing stretch indicator - - if (at != string::npos && at > 2) { - new_name = new_name.substr (0, at - 1); - } - - new_name += suffix; - - ret = finish (region, nsrcs, new_name); - - /* now reset ancestral data for each new region */ - - for (vector<boost::shared_ptr<Region> >::iterator x = results.begin(); x != results.end(); ++x) { - nframes64_t astart = (*x)->ancestral_start(); - nframes64_t alength = (*x)->ancestral_length(); - nframes_t start; - nframes_t length; - - // note: tsr.fraction is a percentage of original length. 100 = no change, - // 50 is half as long, 200 is twice as long, etc. - - float stretch = (*x)->stretch() * (tsr.time_fraction/100.0); - - start = (nframes_t) floor (astart + ((astart - (*x)->start()) / stretch)); - length = (nframes_t) floor (alength / stretch); - - (*x)->set_ancestral_data (start, length, stretch, (*x)->shift()); - } - - out: - - if (gain_buffer) { - delete [] gain_buffer; - } - - if (buffer) { - delete [] buffer; - } - - if (ret || tsr.cancel) { - for (SourceList::iterator si = nsrcs.begin(); si != nsrcs.end(); ++si) { - (*si)->mark_for_remove (); - } - } - - tsr.done = true; - - return ret; -} diff --git a/libs/ardour/tape_file_matcher.cc b/libs/ardour/tape_file_matcher.cc deleted file mode 100644 index 835a951f8a..0000000000 --- a/libs/ardour/tape_file_matcher.cc +++ /dev/null @@ -1,62 +0,0 @@ -/* - 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. -*/ - -#include <pbd/error.h> - -#include <ardour/tape_file_matcher.h> - -#include "i18n.h" - -namespace { - -const char* const tape_file_regex_string = X_("/T[0-9][0-9][0-9][0-9]-"); - -} - -namespace ARDOUR { - -TapeFileMatcher::TapeFileMatcher() -{ - int err; - - if ((err = regcomp (&m_compiled_pattern, - tape_file_regex_string, REG_EXTENDED|REG_NOSUB))) - { - char msg[256]; - - regerror (err, &m_compiled_pattern, msg, sizeof (msg)); - - PBD::error << string_compose (_("Cannot compile tape track regexp for use (%1)"), msg) << endmsg; - // throw - } - -} - -bool -TapeFileMatcher::matches (const string& audio_filename) const -{ - - if (regexec (&m_compiled_pattern, audio_filename.c_str(), 0, 0, 0) == 0) - { - // matches - return true; - } - return false; -} - -} // namespace ARDOUR diff --git a/libs/ardour/template_utils.cc b/libs/ardour/template_utils.cc deleted file mode 100644 index 171939dac2..0000000000 --- a/libs/ardour/template_utils.cc +++ /dev/null @@ -1,34 +0,0 @@ -#include <algorithm> - -#include <pbd/filesystem.h> - -#include <ardour/template_utils.h> -#include <ardour/directory_names.h> -#include <ardour/filesystem_paths.h> - -namespace ARDOUR { - -sys::path -system_template_directory () -{ - SearchPath spath(system_data_search_path()); - spath.add_subdirectory_to_paths(templates_dir_name); - - // just return the first directory in the search path that exists - SearchPath::const_iterator i = std::find_if(spath.begin(), spath.end(), sys::exists); - - if (i == spath.end()) return sys::path(); - - return *i; -} - -sys::path -user_template_directory () -{ - sys::path p(user_config_directory()); - p /= templates_dir_name; - - return p; -} - -} // namespace ARDOUR diff --git a/libs/ardour/tempo.cc b/libs/ardour/tempo.cc deleted file mode 100644 index ab7b7c096e..0000000000 --- a/libs/ardour/tempo.cc +++ /dev/null @@ -1,1539 +0,0 @@ -/* - 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. - -*/ - -#include <algorithm> -#include <unistd.h> - -#include <cmath> - -#include <sigc++/bind.h> - -#include <glibmm/thread.h> -#include <pbd/xml++.h> -#include <ardour/tempo.h> -#include <ardour/utils.h> - -#include "i18n.h" -#include <locale.h> - -using namespace std; -using namespace ARDOUR; -using namespace PBD; - -/* _default tempo is 4/4 qtr=120 */ - -Meter TempoMap::_default_meter (4.0, 4.0); -Tempo TempoMap::_default_tempo (120.0); - -const double Meter::ticks_per_beat = 1920.0; - -double Tempo::frames_per_beat (nframes_t sr, const Meter& meter) const -{ - return ((60.0 * sr) / (_beats_per_minute * meter.note_divisor()/_note_type)); -} - -/***********************************************************************/ - -double -Meter::frames_per_bar (const Tempo& tempo, nframes_t sr) const -{ - return ((60.0 * sr * _beats_per_bar) / (tempo.beats_per_minute() * _note_type/tempo.note_type())); -} - -/***********************************************************************/ - -const string TempoSection::xml_state_node_name = "Tempo"; - -TempoSection::TempoSection (const XMLNode& node) - : MetricSection (BBT_Time()), Tempo (TempoMap::default_tempo()) -{ - const XMLProperty *prop; - BBT_Time start; - LocaleGuard lg (X_("POSIX")); - - if ((prop = node.property ("start")) == 0) { - error << _("TempoSection XML node has no \"start\" property") << endmsg; - throw failed_constructor(); - } - - if (sscanf (prop->value().c_str(), "%" PRIu32 "|%" PRIu32 "|%" PRIu32, - &start.bars, - &start.beats, - &start.ticks) < 3) { - error << _("TempoSection XML node has an illegal \"start\" value") << endmsg; - throw failed_constructor(); - } - - set_start (start); - - if ((prop = node.property ("beats-per-minute")) == 0) { - error << _("TempoSection XML node has no \"beats-per-minute\" property") << endmsg; - throw failed_constructor(); - } - - if (sscanf (prop->value().c_str(), "%lf", &_beats_per_minute) != 1 || _beats_per_minute < 0.0) { - error << _("TempoSection XML node has an illegal \"beats_per_minute\" value") << endmsg; - throw failed_constructor(); - } - - if ((prop = node.property ("note-type")) == 0) { - /* older session, make note type be quarter by default */ - _note_type = 4.0; - } else { - if (sscanf (prop->value().c_str(), "%lf", &_note_type) != 1 || _note_type < 1.0) { - error << _("TempoSection XML node has an illegal \"note-type\" value") << endmsg; - throw failed_constructor(); - } - } - - if ((prop = node.property ("movable")) == 0) { - error << _("TempoSection XML node has no \"movable\" property") << endmsg; - throw failed_constructor(); - } - - set_movable (prop->value() == "yes"); -} - -XMLNode& -TempoSection::get_state() const -{ - XMLNode *root = new XMLNode (xml_state_node_name); - char buf[256]; - LocaleGuard lg (X_("POSIX")); - - snprintf (buf, sizeof (buf), "%" PRIu32 "|%" PRIu32 "|%" PRIu32, - start().bars, - start().beats, - start().ticks); - root->add_property ("start", buf); - snprintf (buf, sizeof (buf), "%f", _beats_per_minute); - root->add_property ("beats-per-minute", buf); - snprintf (buf, sizeof (buf), "%f", _note_type); - root->add_property ("note-type", buf); - snprintf (buf, sizeof (buf), "%s", movable()?"yes":"no"); - root->add_property ("movable", buf); - - return *root; -} - -/***********************************************************************/ - -const string MeterSection::xml_state_node_name = "Meter"; - -MeterSection::MeterSection (const XMLNode& node) - : MetricSection (BBT_Time()), Meter (TempoMap::default_meter()) -{ - const XMLProperty *prop; - BBT_Time start; - LocaleGuard lg (X_("POSIX")); - - if ((prop = node.property ("start")) == 0) { - error << _("MeterSection XML node has no \"start\" property") << endmsg; - throw failed_constructor(); - } - - if (sscanf (prop->value().c_str(), "%" PRIu32 "|%" PRIu32 "|%" PRIu32, - &start.bars, - &start.beats, - &start.ticks) < 3) { - error << _("MeterSection XML node has an illegal \"start\" value") << endmsg; - throw failed_constructor(); - } - - set_start (start); - - if ((prop = node.property ("beats-per-bar")) == 0) { - error << _("MeterSection XML node has no \"beats-per-bar\" property") << endmsg; - throw failed_constructor(); - } - - if (sscanf (prop->value().c_str(), "%lf", &_beats_per_bar) != 1 || _beats_per_bar < 0.0) { - error << _("MeterSection XML node has an illegal \"beats-per-bar\" value") << endmsg; - throw failed_constructor(); - } - - if ((prop = node.property ("note-type")) == 0) { - error << _("MeterSection XML node has no \"note-type\" property") << endmsg; - throw failed_constructor(); - } - - if (sscanf (prop->value().c_str(), "%lf", &_note_type) != 1 || _note_type < 0.0) { - error << _("MeterSection XML node has an illegal \"note-type\" value") << endmsg; - throw failed_constructor(); - } - - if ((prop = node.property ("movable")) == 0) { - error << _("MeterSection XML node has no \"movable\" property") << endmsg; - throw failed_constructor(); - } - - set_movable (prop->value() == "yes"); -} - -XMLNode& -MeterSection::get_state() const -{ - XMLNode *root = new XMLNode (xml_state_node_name); - char buf[256]; - LocaleGuard lg (X_("POSIX")); - - snprintf (buf, sizeof (buf), "%" PRIu32 "|%" PRIu32 "|%" PRIu32, - start().bars, - start().beats, - start().ticks); - root->add_property ("start", buf); - snprintf (buf, sizeof (buf), "%f", _note_type); - root->add_property ("note-type", buf); - snprintf (buf, sizeof (buf), "%f", _beats_per_bar); - root->add_property ("beats-per-bar", buf); - snprintf (buf, sizeof (buf), "%s", movable()?"yes":"no"); - root->add_property ("movable", buf); - - return *root; -} - -/***********************************************************************/ - -struct MetricSectionSorter { - bool operator() (const MetricSection* a, const MetricSection* b) { - return a->start() < b->start(); - } -}; - -TempoMap::TempoMap (nframes_t fr) -{ - metrics = new Metrics; - _frame_rate = fr; - last_bbt_valid = false; - BBT_Time start; - - start.bars = 1; - start.beats = 1; - start.ticks = 0; - - TempoSection *t = new TempoSection (start, _default_tempo.beats_per_minute(), _default_tempo.note_type()); - MeterSection *m = new MeterSection (start, _default_meter.beats_per_bar(), _default_meter.note_divisor()); - - t->set_movable (false); - m->set_movable (false); - - /* note: frame time is correct (zero) for both of these */ - - metrics->push_back (t); - metrics->push_back (m); -} - -TempoMap::~TempoMap () -{ -} - -int -TempoMap::move_metric_section (MetricSection& section, const BBT_Time& when) -{ - if (when == section.start() || !section.movable()) { - return -1; - } - - Glib::RWLock::WriterLock lm (lock); - MetricSectionSorter cmp; - - if (when.beats != 1) { - - /* position by audio frame, then recompute BBT timestamps from the audio ones */ - - nframes_t frame = frame_time (when); - // cerr << "nominal frame time = " << frame << endl; - - nframes_t prev_frame = round_to_type (frame, -1, Beat); - nframes_t next_frame = round_to_type (frame, 1, Beat); - - // cerr << "previous beat at " << prev_frame << " next at " << next_frame << endl; - - /* use the closest beat */ - - if ((frame - prev_frame) < (next_frame - frame)) { - frame = prev_frame; - } else { - frame = next_frame; - } - - // cerr << "actual frame time = " << frame << endl; - section.set_frame (frame); - // cerr << "frame time = " << section.frame() << endl; - timestamp_metrics (false); - // cerr << "new BBT time = " << section.start() << endl; - metrics->sort (cmp); - - } else { - - /* positioned at bar start already, so just put it there */ - - section.set_start (when); - metrics->sort (cmp); - timestamp_metrics (true); - } - - - return 0; -} - -void -TempoMap::move_tempo (TempoSection& tempo, const BBT_Time& when) -{ - if (move_metric_section (tempo, when) == 0) { - StateChanged (Change (0)); - } -} - -void -TempoMap::move_meter (MeterSection& meter, const BBT_Time& when) -{ - if (move_metric_section (meter, when) == 0) { - StateChanged (Change (0)); - } -} - -void -TempoMap::remove_tempo (const TempoSection& tempo) -{ - bool removed = false; - - { - Glib::RWLock::WriterLock lm (lock); - Metrics::iterator i; - - for (i = metrics->begin(); i != metrics->end(); ++i) { - if (dynamic_cast<TempoSection*> (*i) != 0) { - if (tempo.frame() == (*i)->frame()) { - if ((*i)->movable()) { - metrics->erase (i); - removed = true; - break; - } - } - } - } - } - - if (removed) { - StateChanged (Change (0)); - } -} - -void -TempoMap::remove_meter (const MeterSection& tempo) -{ - bool removed = false; - - { - Glib::RWLock::WriterLock lm (lock); - Metrics::iterator i; - - for (i = metrics->begin(); i != metrics->end(); ++i) { - if (dynamic_cast<MeterSection*> (*i) != 0) { - if (tempo.frame() == (*i)->frame()) { - if ((*i)->movable()) { - metrics->erase (i); - removed = true; - break; - } - } - } - } - } - - if (removed) { - StateChanged (Change (0)); - } -} - -void -TempoMap::do_insert (MetricSection* section, bool with_bbt) -{ - Metrics::iterator i; - - for (i = metrics->begin(); i != metrics->end(); ++i) { - - if (with_bbt) { - if ((*i)->start() < section->start()) { - continue; - } - } else { - if ((*i)->frame() < section->frame()) { - continue; - } - } - - metrics->insert (i, section); - break; - } - - if (i == metrics->end()) { - metrics->insert (metrics->end(), section); - } - - timestamp_metrics (with_bbt); -} - -void -TempoMap::add_tempo (const Tempo& tempo, BBT_Time where) -{ - { - Glib::RWLock::WriterLock lm (lock); - - /* new tempos always start on a beat */ - - where.ticks = 0; - - do_insert (new TempoSection (where, tempo.beats_per_minute(), tempo.note_type()), true); - } - - StateChanged (Change (0)); -} - -void -TempoMap::add_tempo (const Tempo& tempo, nframes_t where) -{ - { - Glib::RWLock::WriterLock lm (lock); - do_insert (new TempoSection (where, tempo.beats_per_minute(), tempo.note_type()), false); - } - - StateChanged (Change (0)); -} - -void -TempoMap::replace_tempo (TempoSection& existing, const Tempo& replacement) -{ - bool replaced = false; - - { - Glib::RWLock::WriterLock lm (lock); - Metrics::iterator i; - - for (i = metrics->begin(); i != metrics->end(); ++i) { - TempoSection *ts; - - if ((ts = dynamic_cast<TempoSection*>(*i)) != 0 && ts == &existing) { - - *((Tempo *) ts) = replacement; - - replaced = true; - timestamp_metrics (true); - - break; - } - } - } - - if (replaced) { - StateChanged (Change (0)); - } -} - -void -TempoMap::add_meter (const Meter& meter, BBT_Time where) -{ - { - Glib::RWLock::WriterLock lm (lock); - - /* a new meter always starts a new bar on the first beat. so - round the start time appropriately. remember that - `where' is based on the existing tempo map, not - the result after we insert the new meter. - - */ - - if (where.beats != 1) { - where.beats = 1; - where.bars++; - } - - /* new meters *always* start on a beat. */ - - where.ticks = 0; - - do_insert (new MeterSection (where, meter.beats_per_bar(), meter.note_divisor()), true); - } - - StateChanged (Change (0)); -} - -void -TempoMap::add_meter (const Meter& meter, nframes_t where) -{ - { - Glib::RWLock::WriterLock lm (lock); - do_insert (new MeterSection (where, meter.beats_per_bar(), meter.note_divisor()), false); - } - - StateChanged (Change (0)); -} - -void -TempoMap::replace_meter (MeterSection& existing, const Meter& replacement) -{ - bool replaced = false; - - { - Glib::RWLock::WriterLock lm (lock); - Metrics::iterator i; - - for (i = metrics->begin(); i != metrics->end(); ++i) { - MeterSection *ms; - if ((ms = dynamic_cast<MeterSection*>(*i)) != 0 && ms == &existing) { - - *((Meter*) ms) = replacement; - - replaced = true; - timestamp_metrics (true); - break; - } - } - } - - if (replaced) { - StateChanged (Change (0)); - } -} - -void -TempoMap::change_initial_tempo (double beats_per_minute, double note_type) -{ - Tempo newtempo (beats_per_minute, note_type); - TempoSection* t; - - for (Metrics::iterator i = metrics->begin(); i != metrics->end(); ++i) { - if ((t = dynamic_cast<TempoSection*> (*i)) != 0) { - *((Tempo*) t) = newtempo; - StateChanged (Change (0)); - break; - } - } -} - -void -TempoMap::change_existing_tempo_at (nframes_t where, double beats_per_minute, double note_type) -{ - Tempo newtempo (beats_per_minute, note_type); - - TempoSection* prev; - TempoSection* first; - Metrics::iterator i; - - /* find the TempoSection immediately preceding "where" - */ - - for (first = 0, i = metrics->begin(), prev = 0; i != metrics->end(); ++i) { - - if ((*i)->frame() > where) { - break; - } - - TempoSection* t; - - if ((t = dynamic_cast<TempoSection*>(*i)) != 0) { - if (!first) { - first = t; - } - prev = t; - } - } - - if (!prev) { - if (!first) { - error << string_compose (_("no tempo sections defined in tempo map - cannot change tempo @ %1"), where) << endmsg; - return; - } - - prev = first; - } - - /* reset */ - - *((Tempo*)prev) = newtempo; - StateChanged (Change (0)); -} - -const MeterSection& -TempoMap::first_meter () const -{ - const MeterSection *m = 0; - - for (Metrics::const_iterator i = metrics->begin(); i != metrics->end(); ++i) { - if ((m = dynamic_cast<const MeterSection *> (*i)) != 0) { - return *m; - } - } - - fatal << _("programming error: no tempo section in tempo map!") << endmsg; - /*NOTREACHED*/ - return *m; -} - -const TempoSection& -TempoMap::first_tempo () const -{ - const TempoSection *t = 0; - - for (Metrics::const_iterator i = metrics->begin(); i != metrics->end(); ++i) { - if ((t = dynamic_cast<const TempoSection *> (*i)) != 0) { - return *t; - } - } - - fatal << _("programming error: no tempo section in tempo map!") << endmsg; - /*NOTREACHED*/ - return *t; -} - -void -TempoMap::timestamp_metrics (bool use_bbt) -{ - Metrics::iterator i; - const Meter* meter; - const Tempo* tempo; - Meter *m; - Tempo *t; - - meter = &first_meter (); - tempo = &first_tempo (); - - if (use_bbt) { - - // cerr << "\n\n\n ######################\nTIMESTAMP via BBT ##############\n" << endl; - - nframes_t current = 0; - nframes_t section_frames; - BBT_Time start; - BBT_Time end; - - for (i = metrics->begin(); i != metrics->end(); ++i) { - - end = (*i)->start(); - - section_frames = count_frames_between_metrics (*meter, *tempo, start, end); - - current += section_frames; - - start = end; - - (*i)->set_frame (current); - - if ((t = dynamic_cast<TempoSection*>(*i)) != 0) { - tempo = t; - } else if ((m = dynamic_cast<MeterSection*>(*i)) != 0) { - meter = m; - } else { - fatal << _("programming error: unhandled MetricSection type") << endmsg; - /*NOTREACHED*/ - } - } - - } else { - - // cerr << "\n\n\n ######################\nTIMESTAMP via AUDIO ##############\n" << endl; - - bool first = true; - MetricSection* prev = 0; - - for (i = metrics->begin(); i != metrics->end(); ++i) { - - BBT_Time bbt; - Metric metric (*meter, *tempo); - - if (prev) { - metric.set_start (prev->start()); - } else { - // metric will be at frames=0 bbt=1|1|0 by default - // which is correct for our purpose - } - - bbt_time_with_metric ((*i)->frame(), bbt, metric); - - // cerr << "timestamp @ " << (*i)->frame() << " with " << bbt.bars << "|" << bbt.beats << "|" << bbt.ticks << " => "; - - - if (first) { - first = false; - } else { - - if (bbt.ticks > Meter::ticks_per_beat/2) { - /* round up to next beat */ - bbt.beats += 1; - } - - bbt.ticks = 0; - - if (bbt.beats != 1) { - /* round up to next bar */ - bbt.bars += 1; - bbt.beats = 1; - } - } - - //s cerr << bbt.bars << "|" << bbt.beats << "|" << bbt.ticks << endl; - - (*i)->set_start (bbt); - - if ((t = dynamic_cast<TempoSection*>(*i)) != 0) { - tempo = t; - // cerr << "NEW TEMPO, frame = " << (*i)->frame() << " start = " << (*i)->start() <<endl; - } else if ((m = dynamic_cast<MeterSection*>(*i)) != 0) { - meter = m; - // cerr << "NEW METER, frame = " << (*i)->frame() << " start = " << (*i)->start() <<endl; - } else { - fatal << _("programming error: unhandled MetricSection type") << endmsg; - /*NOTREACHED*/ - } - - prev = (*i); - } - } - - // dump (cerr); - // cerr << "###############################################\n\n\n" << endl; - -} - -TempoMap::Metric -TempoMap::metric_at (nframes_t frame) const -{ - Metric m (first_meter(), first_tempo()); - const Meter* meter; - const Tempo* tempo; - - /* at this point, we are *guaranteed* to have m.meter and m.tempo pointing - at something, because we insert the default tempo and meter during - TempoMap construction. - - now see if we can find better candidates. - */ - - for (Metrics::const_iterator i = metrics->begin(); i != metrics->end(); ++i) { - - if ((*i)->frame() > frame) { - break; - } - - if ((tempo = dynamic_cast<const TempoSection*>(*i)) != 0) { - m.set_tempo (*tempo); - } else if ((meter = dynamic_cast<const MeterSection*>(*i)) != 0) { - m.set_meter (*meter); - } - - m.set_frame ((*i)->frame ()); - m.set_start ((*i)->start ()); - } - - return m; -} - -TempoMap::Metric -TempoMap::metric_at (BBT_Time bbt) const -{ - Metric m (first_meter(), first_tempo()); - const Meter* meter; - const Tempo* tempo; - - /* at this point, we are *guaranteed* to have m.meter and m.tempo pointing - at something, because we insert the default tempo and meter during - TempoMap construction. - - now see if we can find better candidates. - */ - - for (Metrics::const_iterator i = metrics->begin(); i != metrics->end(); ++i) { - - BBT_Time section_start ((*i)->start()); - - if (section_start.bars > bbt.bars || (section_start.bars == bbt.bars && section_start.beats > bbt.beats)) { - break; - } - - if ((tempo = dynamic_cast<const TempoSection*>(*i)) != 0) { - m.set_tempo (*tempo); - } else if ((meter = dynamic_cast<const MeterSection*>(*i)) != 0) { - m.set_meter (*meter); - } - - m.set_frame ((*i)->frame ()); - m.set_start (section_start); - } - - return m; -} - -void -TempoMap::bbt_time (nframes_t frame, BBT_Time& bbt) const -{ - { - Glib::RWLock::ReaderLock lm (lock); - bbt_time_unlocked (frame, bbt); - } -} - -void -TempoMap::bbt_time_unlocked (nframes_t frame, BBT_Time& bbt) const -{ - bbt_time_with_metric (frame, bbt, metric_at (frame)); -} - -void -TempoMap::bbt_time_with_metric (nframes_t frame, BBT_Time& bbt, const Metric& metric) const -{ - nframes_t frame_diff; - - uint32_t xtra_bars = 0; - double xtra_beats = 0; - double beats = 0; - - // cerr << "---- BBT time for " << frame << " using metric @ " << metric.frame() << " BBT " << metric.start() << endl; - - const double beats_per_bar = metric.meter().beats_per_bar(); - const double frames_per_bar = metric.meter().frames_per_bar (metric.tempo(), _frame_rate); - const double beat_frames = metric.tempo().frames_per_beat (_frame_rate, metric.meter()); - - /* now compute how far beyond that point we actually are. */ - - frame_diff = frame - metric.frame(); - - // cerr << "----\tdelta = " << frame_diff << endl; - - xtra_bars = (uint32_t) floor (frame_diff / frames_per_bar); - frame_diff -= (uint32_t) floor (xtra_bars * frames_per_bar); - xtra_beats = (double) frame_diff / beat_frames; - - // cerr << "---\tmeaning " << xtra_bars << " xtra bars and " << xtra_beats << " xtra beats\n"; - - /* and set the returned value */ - - /* and correct beat/bar shifts to match the meter. - remember: beat and bar counting is 1-based, - not zero-based - also the meter may contain a fraction - */ - - bbt.bars = metric.start().bars + xtra_bars; - - beats = (double) metric.start().beats + xtra_beats; - - bbt.bars += (uint32_t) floor(beats/ (beats_per_bar+1) ); - - beats = fmod(beats - 1, beats_per_bar )+ 1.0; - bbt.ticks = (uint32_t)( round((beats - floor(beats)) *(double) Meter::ticks_per_beat)); - bbt.beats = (uint32_t) floor(beats); - - // cerr << "-----\t RETURN " << bbt << endl; -} - -nframes_t -TempoMap::count_frames_between ( const BBT_Time& start, const BBT_Time& end) const -{ - /* for this to work with fractional measure types, start and end have to be "legal" BBT types, - that means that the beats and ticks should be inside a bar - */ - - nframes_t frames = 0; - nframes_t start_frame = 0; - nframes_t end_frame = 0; - - Metric m = metric_at (start); - - uint32_t bar_offset = start.bars - m.start().bars; - - double beat_offset = bar_offset*m.meter().beats_per_bar() - (m.start().beats-1) + (start.beats -1) - + start.ticks/Meter::ticks_per_beat; - - - start_frame = m.frame() + (nframes_t) rint( beat_offset * m.tempo().frames_per_beat(_frame_rate, m.meter())); - - m = metric_at(end); - - bar_offset = end.bars - m.start().bars; - - beat_offset = bar_offset * m.meter().beats_per_bar() - (m.start().beats -1) + (end.beats - 1) - + end.ticks/Meter::ticks_per_beat; - - end_frame = m.frame() + (nframes_t) rint(beat_offset * m.tempo().frames_per_beat(_frame_rate, m.meter())); - - frames = end_frame - start_frame; - - return frames; - -} - -nframes_t -TempoMap::count_frames_between_metrics (const Meter& meter, const Tempo& tempo, const BBT_Time& start, const BBT_Time& end) const -{ - /* this is used in timestamping the metrics by actually counting the beats */ - - nframes_t frames = 0; - uint32_t bar = start.bars; - double beat = (double) start.beats; - double beats_counted = 0; - double beats_per_bar = 0; - double beat_frames = 0; - - beats_per_bar = meter.beats_per_bar(); - beat_frames = tempo.frames_per_beat (_frame_rate,meter); - - frames = 0; - - while (bar < end.bars || (bar == end.bars && beat < end.beats)) { - - if (beat >= beats_per_bar) { - beat = 1; - ++bar; - ++beats_counted; - - if (beat > beats_per_bar) { - - /* this is a fractional beat at the end of a fractional bar - so it should only count for the fraction - */ - - beats_counted -= (ceil(beats_per_bar) - beats_per_bar); - } - - } else { - ++beat; - ++beats_counted; - } - } - - // cerr << "Counted " << beats_counted << " from " << start << " to " << end - // << " bpb were " << beats_per_bar - // << " fpb was " << beat_frames - // << endl; - - frames = (nframes_t) floor (beats_counted * beat_frames); - - return frames; - -} - -nframes_t -TempoMap::frame_time (const BBT_Time& bbt) const -{ - BBT_Time start ; /* 1|1|0 */ - - return count_frames_between ( start, bbt); -} - -nframes_t -TempoMap::bbt_duration_at (nframes_t pos, const BBT_Time& bbt, int dir) const -{ - nframes_t frames = 0; - - BBT_Time when; - bbt_time(pos,when); - - { - Glib::RWLock::ReaderLock lm (lock); - frames = bbt_duration_at_unlocked (when, bbt,dir); - } - - return frames; -} - -nframes_t -TempoMap::bbt_duration_at_unlocked (const BBT_Time& when, const BBT_Time& bbt, int dir) const -{ - - nframes_t frames = 0; - - double beats_per_bar; - BBT_Time result; - - result.bars = max(1U,when.bars + dir * bbt.bars) ; - result.beats = 1; - result.ticks = 0; - - Metric metric = metric_at(result); - beats_per_bar = metric.meter().beats_per_bar(); - - - - /*reduce things to legal bbt values - we have to handle possible fractional=shorter beats at the end of measures - and things like 0|11|9000 as a duration in a 4.5/4 measure - the musical decision is that the fractional beat is also a beat , although a shorter one - */ - - - if (dir >= 0) { - result.beats = when.beats + bbt.beats; - result.ticks = when.ticks + bbt.ticks; - - while (result.beats >= (beats_per_bar+1)) { - result.bars++; - result.beats -= (uint32_t) ceil(beats_per_bar); - metric = metric_at(result); // maybe there is a meter change - beats_per_bar = metric.meter().beats_per_bar(); - - } - /*we now counted the beats and landed in the target measure, now deal with ticks - this seems complicated, but we want to deal with the corner case of a sequence of time signatures like 0.2/4-0.7/4 - and with request like bbt = 3|2|9000 ,so we repeat the same loop but add ticks - */ - - /* of course gtk_ardour only allows bar with at least 1.0 beats ..... - */ - - uint32_t ticks_at_beat = (uint32_t) ( result.beats == ceil(beats_per_bar) ? - (1 - (ceil(beats_per_bar) - beats_per_bar))* Meter::ticks_per_beat - : Meter::ticks_per_beat ); - - while (result.ticks >= ticks_at_beat) { - result.beats++; - result.ticks -= ticks_at_beat; - if (result.beats >= (beats_per_bar+1)) { - result.bars++; - result.beats = 1; - metric = metric_at(result); // maybe there is a meter change - beats_per_bar = metric.meter().beats_per_bar(); - } - ticks_at_beat= (uint32_t) ( result.beats == ceil(beats_per_bar) ? - (1 - (ceil(beats_per_bar) - beats_per_bar) )* Meter::ticks_per_beat - : Meter::ticks_per_beat); - - } - - - } else { - uint32_t b = bbt.beats; - - /* count beats */ - while( b > when.beats ) { - - result.bars = max(1U,result.bars-- ) ; - metric = metric_at(result); // maybe there is a meter change - beats_per_bar = metric.meter().beats_per_bar(); - if (b >= ceil(beats_per_bar)) { - - b -= (uint32_t) ceil(beats_per_bar); - } else { - b = (uint32_t) ceil(beats_per_bar)- b + when.beats ; - } - } - result.beats = when.beats - b; - - /*count ticks */ - - if (bbt.ticks <= when.ticks) { - result.ticks = when.ticks - bbt.ticks; - } else { - - uint32_t ticks_at_beat= (uint32_t) Meter::ticks_per_beat; - uint32_t t = bbt.ticks - when.ticks; - - do { - - if (result.beats == 1) { - result.bars = max(1U,result.bars-- ) ; - metric = metric_at(result); // maybe there is a meter change - beats_per_bar = metric.meter().beats_per_bar(); - result.beats = (uint32_t) ceil(beats_per_bar); - ticks_at_beat = (uint32_t) ((1 - (ceil(beats_per_bar) - beats_per_bar))* Meter::ticks_per_beat) ; - } else { - result.beats --; - ticks_at_beat = (uint32_t) Meter::ticks_per_beat; - } - - if (t <= ticks_at_beat) { - result.ticks = ticks_at_beat - t; - } else { - t-= ticks_at_beat; - } - } while (t > ticks_at_beat); - - } - - - } - - if (dir < 0 ) { - frames = count_frames_between( result,when); - } else { - frames = count_frames_between(when,result); - } - - return frames; -} - - - -nframes_t -TempoMap::round_to_bar (nframes_t fr, int dir) -{ - { - Glib::RWLock::ReaderLock lm (lock); - return round_to_type (fr, dir, Bar); - } -} - - -nframes_t -TempoMap::round_to_beat (nframes_t fr, int dir) -{ - { - Glib::RWLock::ReaderLock lm (lock); - return round_to_type (fr, dir, Beat); - } -} - -nframes_t - -TempoMap::round_to_beat_subdivision (nframes_t fr, int sub_num) -{ - - BBT_Time the_beat; - uint32_t ticks_one_half_subdivisions_worth; - uint32_t ticks_one_subdivisions_worth; - - bbt_time(fr, the_beat); - - ticks_one_subdivisions_worth = (uint32_t)Meter::ticks_per_beat / sub_num; - ticks_one_half_subdivisions_worth = ticks_one_subdivisions_worth / 2; - - if (the_beat.ticks % ticks_one_subdivisions_worth > ticks_one_half_subdivisions_worth) { - uint32_t difference = ticks_one_subdivisions_worth - (the_beat.ticks % ticks_one_subdivisions_worth); - if (the_beat.ticks + difference >= (uint32_t)Meter::ticks_per_beat) { - the_beat.beats++; - the_beat.ticks += difference; - the_beat.ticks -= (uint32_t)Meter::ticks_per_beat; - } else { - the_beat.ticks += difference; - } - } else { - the_beat.ticks -= the_beat.ticks % ticks_one_subdivisions_worth; - } - - return frame_time (the_beat); -} - -nframes_t -TempoMap::round_to_type (nframes_t frame, int dir, BBTPointType type) -{ - Metric metric = metric_at (frame); - BBT_Time bbt; - BBT_Time start; - bbt_time_with_metric (frame, bbt, metric); - - switch (type) { - case Bar: - if (dir < 0) { - /* relax */ - } else if (dir > 0) { - if (bbt.beats > 0) { - bbt.bars++; - } else if (metric.frame() < frame) { - bbt.bars++; - } - } else { - if (bbt.beats > metric.meter().beats_per_bar()/2) { - bbt.bars++; - } - } - bbt.beats = 1; - bbt.ticks = 0; - break; - - case Beat: - if (dir < 0) { - /* relax */ - } else if (dir > 0) { - if (bbt.ticks > 0) { - bbt.beats++; - } else if (metric.frame() < frame) { - bbt.beats++; - } - } else { - if (bbt.ticks >= (Meter::ticks_per_beat/2)) { - bbt.beats++; - } - } - if (bbt.beats > ceil(metric.meter().beats_per_bar()) ) { - bbt.beats = 1; - bbt.bars++; - } - bbt.ticks = 0; - break; - - } - - /* - cerr << "for " << frame << " round to " << bbt << " using " - << metric.start() - << endl; - */ - return metric.frame() + count_frames_between (metric.start(), bbt); -} - -TempoMap::BBTPointList * -TempoMap::get_points (nframes_t lower, nframes_t upper) const -{ - - Metrics::const_iterator i; - BBTPointList *points; - double current; - const MeterSection* meter; - const MeterSection* m; - const TempoSection* tempo; - const TempoSection* t; - uint32_t bar; - uint32_t beat; - double beats_per_bar; - double beat_frame; - double beat_frames; - double frames_per_bar; - double delta_bars; - double delta_beats; - double dummy; - nframes_t limit; - - meter = &first_meter (); - tempo = &first_tempo (); - - /* find the starting point */ - - for (i = metrics->begin(); i != metrics->end(); ++i) { - - if ((*i)->frame() > lower) { - break; - } - - if ((t = dynamic_cast<const TempoSection*>(*i)) != 0) { - tempo = t; - } else if ((m = dynamic_cast<const MeterSection*>(*i)) != 0) { - meter = m; - } - } - - /* We now have: - - meter -> the Meter for "lower" - tempo -> the Tempo for "lower" - i -> for first new metric after "lower", possibly metrics->end() - - Now start generating points. - */ - - beats_per_bar = meter->beats_per_bar (); - frames_per_bar = meter->frames_per_bar (*tempo, _frame_rate); - beat_frames = tempo->frames_per_beat (_frame_rate, *meter); - - if (meter->frame() > tempo->frame()) { - bar = meter->start().bars; - beat = meter->start().beats; - current = meter->frame(); - } else { - bar = tempo->start().bars; - beat = tempo->start().beats; - current = tempo->frame(); - } - - /* initialize current to point to the bar/beat just prior to the - lower frame bound passed in. assumes that current is initialized - above to be on a beat. - */ - - delta_bars = (lower-current) / frames_per_bar; - delta_beats = modf(delta_bars, &dummy) * beats_per_bar; - current += (floor(delta_bars) * frames_per_bar) + (floor(delta_beats) * beat_frames); - - // adjust bars and beats too - bar += (uint32_t) (floor(delta_bars)); - beat += (uint32_t) (floor(delta_beats)); - - points = new BBTPointList; - - do { - - if (i == metrics->end()) { - limit = upper; - // cerr << "== limit set to end of request @ " << limit << endl; - } else { - // cerr << "== limit set to next metric @ " << (*i)->frame() << endl; - limit = (*i)->frame(); - } - - limit = min (limit, upper); - - while (current < limit) { - - /* if we're at the start of a bar, add bar point */ - - if (beat == 1) { - if (current >= lower) { - // cerr << "Add Bar at " << bar << "|1" << " @ " << current << endl; - points->push_back (BBTPoint (*meter, *tempo,(nframes_t)rint(current), Bar, bar, 1)); - - } - } - - /* add some beats if we can */ - - beat_frame = current; - - while (beat <= ceil( beats_per_bar) && beat_frame < limit) { - if (beat_frame >= lower) { - // cerr << "Add Beat at " << bar << '|' << beat << " @ " << beat_frame << endl; - points->push_back (BBTPoint (*meter, *tempo, (nframes_t) rint(beat_frame), Beat, bar, beat)); - } - beat_frame += beat_frames; - current+= beat_frames; - - beat++; - } - - // cerr << "out of beats, @ end ? " << (i == metrics->end()) << " out of bpb ? " - // << (beat > ceil(beats_per_bar)) - // << endl; - - if (beat > ceil(beats_per_bar) || i != metrics->end()) { - - /* we walked an entire bar. its - important to move `current' forward - by the actual frames_per_bar, not move it to - an integral beat_frame, so that metrics with - non-integral beats-per-bar have - their bar positions set - correctly. consider a metric with - 9-1/2 beats-per-bar. the bar we - just filled had 10 beat marks, - but the bar end is 1/2 beat before - the last beat mark. - And it is also possible that a tempo - change occured in the middle of a bar, - so we subtract the possible extra fraction from the current - */ - - if (beat > ceil (beats_per_bar)) { - /* next bar goes where the numbers suggest */ - current -= beat_frames * (ceil(beats_per_bar)-beats_per_bar); - // cerr << "++ next bar from numbers\n"; - } else { - /* next bar goes where the next metric is */ - current = limit; - // cerr << "++ next bar at next metric\n"; - } - bar++; - beat = 1; - } - - } - - /* if we're done, then we're done */ - - if (current >= upper) { - break; - } - - /* i is an iterator that refers to the next metric (or none). - if there is a next metric, move to it, and continue. - */ - - if (i != metrics->end()) { - - if ((t = dynamic_cast<const TempoSection*>(*i)) != 0) { - tempo = t; - } else if ((m = dynamic_cast<const MeterSection*>(*i)) != 0) { - meter = m; - /* new MeterSection, beat always returns to 1 */ - beat = 1; - } - - current = (*i)->frame (); - // cerr << "loop around with current @ " << current << endl; - - beats_per_bar = meter->beats_per_bar (); - frames_per_bar = meter->frames_per_bar (*tempo, _frame_rate); - beat_frames = tempo->frames_per_beat (_frame_rate, *meter); - - ++i; - } - - } while (1); - - return points; -} - -const TempoSection& -TempoMap::tempo_section_at (nframes_t frame) -{ - Glib::RWLock::ReaderLock lm (lock); - Metrics::iterator i; - TempoSection* prev = 0; - - for (i = metrics->begin(); i != metrics->end(); ++i) { - TempoSection* t; - - if ((t = dynamic_cast<TempoSection*> (*i)) != 0) { - - if ((*i)->frame() > frame) { - break; - } - - prev = t; - } - } - - if (prev == 0) { - fatal << endmsg; - } - - return *prev; -} - -const Tempo& -TempoMap::tempo_at (nframes_t frame) -{ - Metric m (metric_at (frame)); - return m.tempo(); -} - - -const Meter& -TempoMap::meter_at (nframes_t frame) -{ - Metric m (metric_at (frame)); - return m.meter(); -} - -XMLNode& -TempoMap::get_state () -{ - Metrics::const_iterator i; - XMLNode *root = new XMLNode ("TempoMap"); - - { - Glib::RWLock::ReaderLock lm (lock); - for (i = metrics->begin(); i != metrics->end(); ++i) { - root->add_child_nocopy ((*i)->get_state()); - } - } - - return *root; -} - -int -TempoMap::set_state (const XMLNode& node) -{ - { - Glib::RWLock::WriterLock lm (lock); - - XMLNodeList nlist; - XMLNodeConstIterator niter; - Metrics old_metrics (*metrics); - - metrics->clear(); - - nlist = node.children(); - - for (niter = nlist.begin(); niter != nlist.end(); ++niter) { - XMLNode* child = *niter; - - if (child->name() == TempoSection::xml_state_node_name) { - - try { - metrics->push_back (new TempoSection (*child)); - } - - catch (failed_constructor& err){ - error << _("Tempo map: could not set new state, restoring old one.") << endmsg; - *metrics = old_metrics; - break; - } - - } else if (child->name() == MeterSection::xml_state_node_name) { - - try { - metrics->push_back (new MeterSection (*child)); - } - - catch (failed_constructor& err) { - error << _("Tempo map: could not set new state, restoring old one.") << endmsg; - *metrics = old_metrics; - break; - } - } - } - - if (niter == nlist.end()) { - - MetricSectionSorter cmp; - metrics->sort (cmp); - timestamp_metrics (true); - } - } - - StateChanged (Change (0)); - - return 0; -} - -void -TempoMap::dump (std::ostream& o) const -{ - const MeterSection* m; - const TempoSection* t; - - for (Metrics::const_iterator i = metrics->begin(); i != metrics->end(); ++i) { - - if ((t = dynamic_cast<const TempoSection*>(*i)) != 0) { - o << "Tempo @ " << *i << ' ' << t->beats_per_minute() << " BPM (denom = " << t->note_type() << ") at " << t->start() << " frame= " << t->frame() << " (move? " - << t->movable() << ')' << endl; - } else if ((m = dynamic_cast<const MeterSection*>(*i)) != 0) { - o << "Meter @ " << *i << ' ' << m->beats_per_bar() << '/' << m->note_divisor() << " at " << m->start() << " frame= " << m->frame() - << " (move? " << m->movable() << ')' << endl; - } - } -} - -int -TempoMap::n_tempos() const -{ - Glib::RWLock::ReaderLock lm (lock); - int cnt = 0; - - for (Metrics::const_iterator i = metrics->begin(); i != metrics->end(); ++i) { - if (dynamic_cast<const TempoSection*>(*i) != 0) { - cnt++; - } - } - - return cnt; -} - -int -TempoMap::n_meters() const -{ - Glib::RWLock::ReaderLock lm (lock); - int cnt = 0; - - for (Metrics::const_iterator i = metrics->begin(); i != metrics->end(); ++i) { - if (dynamic_cast<const MeterSection*>(*i) != 0) { - cnt++; - } - } - - return cnt; -} diff --git a/libs/ardour/track.cc b/libs/ardour/track.cc deleted file mode 100644 index 052105cc85..0000000000 --- a/libs/ardour/track.cc +++ /dev/null @@ -1,224 +0,0 @@ -/* - 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. -*/ -#include <pbd/error.h> -#include <sigc++/retype.h> -#include <sigc++/retype_return.h> -#include <sigc++/bind.h> - -#include <ardour/track.h> -#include <ardour/diskstream.h> -#include <ardour/session.h> -#include <ardour/io_processor.h> -#include <ardour/audioregion.h> -#include <ardour/audiosource.h> -#include <ardour/route_group_specialized.h> -#include <ardour/processor.h> -#include <ardour/audioplaylist.h> -#include <ardour/panner.h> -#include <ardour/utils.h> - -#include "i18n.h" - -using namespace std; -using namespace ARDOUR; -using namespace PBD; - -Track::Track (Session& sess, string name, Route::Flag flag, TrackMode mode, DataType default_type) - : Route (sess, name, 1, -1, -1, -1, flag, default_type) - , _rec_enable_control (new RecEnableControllable(*this)) -{ - _declickable = true; - _freeze_record.state = NoFreeze; - _saved_meter_point = _meter_point; - _mode = mode; -} - -Track::Track (Session& sess, const XMLNode& node, DataType default_type) - : Route (sess, node) - , _rec_enable_control (new RecEnableControllable(*this)) -{ - _freeze_record.state = NoFreeze; - _declickable = true; - _saved_meter_point = _meter_point; -} - -Track::~Track () -{ -} - -void -Track::set_meter_point (MeterPoint p, void *src) -{ - Route::set_meter_point (p, src); -} - -XMLNode& -Track::get_state () -{ - return state (true); -} - -XMLNode& -Track::get_template () -{ - return state (false); -} - -void -Track::toggle_monitor_input () -{ - for (PortSet::iterator i = _inputs.begin(); i != _inputs.end(); ++i) { - i->ensure_monitor_input(!i->monitoring_input()); - } -} - -ARDOUR::nframes_t -Track::update_total_latency () -{ - nframes_t old = _own_latency; - - if (_user_latency) { - _own_latency = _user_latency; - } else { - _own_latency = 0; - - for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { - if ((*i)->active ()) { - _own_latency += (*i)->signal_latency (); - } - } - } - - set_port_latency (_own_latency); - - if (old != _own_latency) { - signal_latency_changed (); /* EMIT SIGNAL */ - } - - return _own_latency; -} - -Track::FreezeRecord::~FreezeRecord () -{ - for (vector<FreezeRecordProcessorInfo*>::iterator i = processor_info.begin(); i != processor_info.end(); ++i) { - delete *i; - } -} - -Track::FreezeState -Track::freeze_state() const -{ - return _freeze_record.state; -} - -Track::RecEnableControllable::RecEnableControllable (Track& s) - : Controllable (X_("recenable")), track (s) -{ -} - -void -Track::RecEnableControllable::set_value (float val) -{ - bool bval = ((val >= 0.5f) ? true: false); - track.set_record_enable (bval, this); -} - -float -Track::RecEnableControllable::get_value (void) const -{ - if (track.record_enabled()) { return 1.0f; } - return 0.0f; -} - -bool -Track::record_enabled () const -{ - return _diskstream->record_enabled (); -} - -bool -Track::can_record() -{ - bool will_record = true; - for (PortSet::iterator i = _inputs.begin(); i != _inputs.end() && will_record; ++i) { - if (!i->connected()) - will_record = false; - } - - return will_record; -} - -void -Track::set_record_enable (bool yn, void *src) -{ - if (_freeze_record.state == Frozen) { - return; - } - - if (_mix_group && src != _mix_group && _mix_group->is_active()) { - _mix_group->apply (&Track::set_record_enable, yn, _mix_group); - return; - } - - /* keep track of the meter point as it was before we rec-enabled */ - if (!_diskstream->record_enabled()) { - _saved_meter_point = _meter_point; - } - - _diskstream->set_record_enabled (yn); - - if (_diskstream->record_enabled()) { - set_meter_point (MeterInput, this); - } else { - set_meter_point (_saved_meter_point, this); - } - - _rec_enable_control->Changed (); -} - - -bool -Track::set_name (const string& str) -{ - bool ret; - - if (record_enabled() && _session.actively_recording()) { - /* this messes things up if done while recording */ - return false; - } - - if (_diskstream->set_name (str)) { - return false; - } - - /* save state so that the statefile fully reflects any filename changes */ - - if ((ret = IO::set_name (str)) == 0) { - _session.save_state (""); - } - - return ret; -} - -void -Track::set_latency_delay (nframes_t longest_session_latency) -{ - Route::set_latency_delay (longest_session_latency); - _diskstream->set_roll_delay (_roll_delay); -} - diff --git a/libs/ardour/transient_detector.cc b/libs/ardour/transient_detector.cc deleted file mode 100644 index d3200d72e4..0000000000 --- a/libs/ardour/transient_detector.cc +++ /dev/null @@ -1,118 +0,0 @@ -#include <ardour/transient_detector.h> - -#include "i18n.h" - -using namespace Vamp; -using namespace ARDOUR; -using namespace std; - -/* need a static initializer function for this */ - -string TransientDetector::_op_id = X_("libardourvampplugins:percussiononsets:2"); - -TransientDetector::TransientDetector (float sr) - : AudioAnalyser (sr, X_("libardourvampplugins:percussiononsets")) -{ - /* update the op_id */ - - _op_id = X_("libardourvampplugins:percussiononsets"); - - // XXX this should load the above-named plugin and get the current version - - _op_id += ":2"; -} - -TransientDetector::~TransientDetector() -{ -} - -string -TransientDetector::operational_identifier() -{ - return _op_id; -} - -int -TransientDetector::run (const std::string& path, Readable* src, uint32_t channel, AnalysisFeatureList& results) -{ - current_results = &results; - int ret = analyse (path, src, channel); - - current_results = 0; - return ret; -} - -int -TransientDetector::use_features (Plugin::FeatureSet& features, ostream* out) -{ - const Plugin::FeatureList& fl (features[0]); - - for (Plugin::FeatureList::const_iterator f = fl.begin(); f != fl.end(); ++f) { - - if ((*f).hasTimestamp) { - - if (out) { - (*out) << (*f).timestamp.toString() << endl; - } - - current_results->push_back (RealTime::realTime2Frame ((*f).timestamp, (nframes_t) floor(sample_rate))); - } - } - - return 0; -} - -void -TransientDetector::set_threshold (float val) -{ - if (plugin) { - plugin->setParameter ("threshold", val); - } -} - -void -TransientDetector::set_sensitivity (float val) -{ - if (plugin) { - plugin->setParameter ("sensitivity", val); - } -} - -void -TransientDetector::cleanup_transients (AnalysisFeatureList& t, float sr, float gap_msecs) -{ - if (t.empty()) { - return; - } - - t.sort (); - - /* remove duplicates or other things that are too close */ - - AnalysisFeatureList::iterator i = t.begin(); - AnalysisFeatureList::iterator f, b; - const nframes64_t gap_frames = (nframes64_t) floor (gap_msecs * (sr / 1000.0)); - - while (i != t.end()) { - - // move front iterator to just past i, and back iterator the same place - - f = i; - ++f; - b = f; - - // move f until we find a new value that is far enough away - - while ((f != t.end()) && (((*f) - (*i)) < gap_frames)) { - ++f; - } - - i = f; - - // if f moved forward from b, we had duplicates/too-close points: get rid of them - - if (b != f) { - t.erase (b, f); - } - } -} diff --git a/libs/ardour/user_bundle.cc b/libs/ardour/user_bundle.cc deleted file mode 100644 index 471d823496..0000000000 --- a/libs/ardour/user_bundle.cc +++ /dev/null @@ -1,198 +0,0 @@ -#include <cassert> -#include <pbd/failed_constructor.h> -#include <pbd/compose.h> -#include <pbd/xml++.h> -#include "ardour/user_bundle.h" -#include "ardour/port_set.h" -#include "ardour/io.h" -#include "ardour/session.h" -#include "ardour/audioengine.h" -#include "i18n.h" - -ARDOUR::UserBundle::UserBundle (std::string const & n) - : Bundle (n) -{ - -} - -ARDOUR::UserBundle::UserBundle (XMLNode const & x, bool i) - : Bundle (i) -{ - if (set_state (x)) { - throw failed_constructor (); - } -} - -uint32_t -ARDOUR::UserBundle::nchannels () const -{ - Glib::Mutex::Lock lm (_ports_mutex); - return _ports.size (); -} - -const ARDOUR::PortList& -ARDOUR::UserBundle::channel_ports (uint32_t n) const -{ - assert (n < nchannels ()); - - Glib::Mutex::Lock lm (_ports_mutex); - return _ports[n]; -} - -void -ARDOUR::UserBundle::add_port_to_channel (uint32_t c, std::string const & p) -{ - assert (c < nchannels ()); - - PortsWillChange (c); - - { - Glib::Mutex::Lock lm (_ports_mutex); - _ports[c].push_back (p); - } - - PortsHaveChanged (c); -} - -void -ARDOUR::UserBundle::remove_port_from_channel (uint32_t c, std::string const & p) -{ - assert (c < nchannels ()); - - PortsWillChange (c); - - { - Glib::Mutex::Lock lm (_ports_mutex); - PortList::iterator i = std::find (_ports[c].begin(), _ports[c].end(), p); - if (i != _ports[c].end()) { - _ports[c].erase (i); - } - } - - PortsHaveChanged (c); -} - -bool -ARDOUR::UserBundle::port_attached_to_channel (uint32_t c, std::string const & p) const -{ - assert (c < nchannels ()); - - Glib::Mutex::Lock lm (_ports_mutex); - return std::find (_ports[c].begin(), _ports[c].end(), p) != _ports[c].end(); -} - -void -ARDOUR::UserBundle::add_channel () -{ - ConfigurationWillChange (); - - { - Glib::Mutex::Lock lm (_ports_mutex); - _ports.resize (_ports.size() + 1); - } - - ConfigurationHasChanged (); -} - -void -ARDOUR::UserBundle::set_channels (uint32_t n) -{ - ConfigurationWillChange (); - - { - Glib::Mutex::Lock lm (_ports_mutex); - _ports.resize (n); - } - - ConfigurationHasChanged (); -} - -void -ARDOUR::UserBundle::remove_channel (uint32_t r) -{ - assert (r < nchannels ()); - - ConfigurationWillChange (); - - { - Glib::Mutex::Lock lm (_ports_mutex); - _ports.erase (_ports.begin() + r, _ports.begin() + r + 1); - } - - ConfigurationHasChanged (); -} - -int -ARDOUR::UserBundle::set_state (XMLNode const & node) -{ - XMLProperty const * name; - - if ((name = node.property ("name")) == 0) { - PBD::error << _("Node for Bundle has no \"name\" property") << endmsg; - return -1; - } - - set_name (name->value ()); - - XMLNodeList const channels = node.children (); - - int n = 0; - for (XMLNodeConstIterator i = channels.begin(); i != channels.end(); ++i) { - - if ((*i)->name() != "Channel") { - PBD::error << string_compose (_("Unknown node \"%s\" in Bundle"), (*i)->name()) << endmsg; - return -1; - } - - add_channel (); - - XMLNodeList const ports = (*i)->children (); - - for (XMLNodeConstIterator j = ports.begin(); j != ports.end(); ++j) { - if ((*j)->name() != "Port") { - PBD::error << string_compose (_("Unknown node \"%s\" in Bundle"), (*j)->name()) << endmsg; - return -1; - } - - if ((name = (*j)->property ("name")) == 0) { - PBD::error << _("Node for Port has no \"name\" property") << endmsg; - return -1; - } - - add_port_to_channel (n, name->value ()); - } - - ++n; - } - - return 0; -} - -XMLNode& -ARDOUR::UserBundle::get_state () -{ - XMLNode *node; - - if (ports_are_inputs ()) { - node = new XMLNode ("InputBundle"); - } else { - node = new XMLNode ("OutputBundle"); - } - - node->add_property ("name", name ()); - - for (std::vector<PortList>::iterator i = _ports.begin(); i != _ports.end(); ++i) { - - XMLNode* c = new XMLNode ("Channel"); - - for (PortList::iterator j = i->begin(); j != i->end(); ++j) { - XMLNode* p = new XMLNode ("Port"); - p->add_property ("name", *j); - c->add_child_nocopy (*p); - } - - node->add_child_nocopy (*c); - } - - return *node; -} diff --git a/libs/ardour/utils.cc b/libs/ardour/utils.cc deleted file mode 100644 index f30f568f9d..0000000000 --- a/libs/ardour/utils.cc +++ /dev/null @@ -1,529 +0,0 @@ -/* - Copyright (C) 2000-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. - -*/ - -#define __STDC_FORMAT_MACROS 1 -#include <stdint.h> - -#include <cstdio> /* for sprintf */ -#include <cstring> -#include <cmath> -#include <cctype> -#include <string> -#include <cerrno> -#include <iostream> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <fcntl.h> -#include <unistd.h> - -#ifdef HAVE_WORDEXP -#include <wordexp.h> -#endif - -#include <pbd/error.h> -#include <pbd/stacktrace.h> -#include <pbd/xml++.h> -#include <pbd/basename.h> -#include <ardour/utils.h> - -#include "i18n.h" - -using namespace ARDOUR; -using namespace std; -using namespace PBD; -using Glib::ustring; - -ustring -legalize_for_path (ustring str) -{ - ustring::size_type pos; - ustring legal_chars = "abcdefghijklmnopqrtsuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_+=: "; - ustring legal; - - legal = str; - pos = 0; - - while ((pos = legal.find_first_not_of (legal_chars, pos)) != string::npos) { - legal.replace (pos, 1, "_"); - pos += 1; - } - - return legal; -} - -string bump_name_once(std::string name) -{ - string::size_type period; - string newname; - - if ((period = name.find_last_of ('.')) == string::npos) { - newname = name; - newname += ".1"; - } else { - int isnumber = 1; - const char *last_element = name.c_str() + period + 1; - for (size_t i = 0; i < strlen(last_element); i++) { - if (!isdigit(last_element[i])) { - isnumber = 0; - break; - } - } - - errno = 0; - long int version = strtol (name.c_str()+period+1, (char **)NULL, 10); - - if (isnumber == 0 || errno != 0) { - // last_element is not a number, or is too large - newname = name; - newname += ".1"; - } else { - char buf[32]; - - snprintf (buf, sizeof(buf), "%ld", version+1); - - newname = name.substr (0, period+1); - newname += buf; - } - } - - return newname; - -} - -ostream& -operator<< (ostream& o, const BBT_Time& bbt) -{ - o << bbt.bars << '|' << bbt.beats << '|' << bbt.ticks; - return o; -} - -XMLNode * -find_named_node (const XMLNode& node, string name) -{ - XMLNodeList nlist; - XMLNodeConstIterator niter; - XMLNode* child; - - nlist = node.children(); - - for (niter = nlist.begin(); niter != nlist.end(); ++niter) { - - child = *niter; - - if (child->name() == name) { - return child; - } - } - - return 0; -} - -int -cmp_nocase (const string& s, const string& s2) -{ - string::const_iterator p = s.begin(); - string::const_iterator p2 = s2.begin(); - - while (p != s.end() && p2 != s2.end()) { - if (toupper(*p) != toupper(*p2)) { - return (toupper(*p) < toupper(*p2)) ? -1 : 1; - } - ++p; - ++p2; - } - - return (s2.size() == s.size()) ? 0 : (s.size() < s2.size()) ? -1 : 1; -} - -int -touch_file (ustring path) -{ - int fd = open (path.c_str(), O_RDWR|O_CREAT, 0660); - if (fd >= 0) { - close (fd); - return 0; - } - return 1; -} - -ustring -region_name_from_path (ustring path, bool strip_channels, bool add_channel_suffix, uint32_t total, uint32_t this_one) -{ - path = PBD::basename_nosuffix (path); - - if (strip_channels) { - - /* remove any "?R", "?L" or "?[a-z]" channel identifier */ - - ustring::size_type len = path.length(); - - if (len > 3 && (path[len-2] == '%' || path[len-2] == '?' || path[len-2] == '.') && - (path[len-1] == 'R' || path[len-1] == 'L' || (islower (path[len-1])))) { - - path = path.substr (0, path.length() - 2); - } - } - - if (add_channel_suffix) { - - path += '%'; - - if (total > 2) { - path += (char) ('a' + this_one); - } else { - path += (char) (this_one == 0 ? 'L' : 'R'); - } - } - - return path; -} - -bool -path_is_paired (ustring path, ustring& pair_base) -{ - ustring::size_type pos; - - /* remove any leading path */ - - if ((pos = path.find_last_of ('/')) != string::npos) { - path = path.substr(pos+1); - } - - /* remove filename suffixes etc. */ - - if ((pos = path.find_last_of ('.')) != string::npos) { - path = path.substr (0, pos); - } - - ustring::size_type len = path.length(); - - /* look for possible channel identifier: "?R", "%R", ".L" etc. */ - - if (len > 3 && (path[len-2] == '%' || path[len-2] == '?' || path[len-2] == '.') && - (path[len-1] == 'R' || path[len-1] == 'L' || (islower (path[len-1])))) { - - pair_base = path.substr (0, len-2); - return true; - - } - - return false; -} - -ustring -path_expand (ustring path) -{ -#ifdef HAVE_WORDEXP - /* Handle tilde and environment variable expansion in session path */ - string ret = path; - - wordexp_t expansion; - switch (wordexp (path.c_str(), &expansion, WRDE_NOCMD|WRDE_UNDEF)) { - case 0: - break; - default: - error << string_compose (_("illegal or badly-formed string used for path (%1)"), path) << endmsg; - goto out; - } - - if (expansion.we_wordc > 1) { - error << string_compose (_("path (%1) is ambiguous"), path) << endmsg; - goto out; - } - - ret = expansion.we_wordv[0]; - out: - wordfree (&expansion); - return ret; - -#else - return path; -#endif -} - -#if defined(HAVE_COREAUDIO) || defined(HAVE_AUDIOUNITS) -string -CFStringRefToStdString(CFStringRef stringRef) -{ - CFIndex size = - CFStringGetMaximumSizeForEncoding(CFStringGetLength(stringRef) , - kCFStringEncodingUTF8); - char *buf = new char[size]; - - std::string result; - - if(CFStringGetCString(stringRef, buf, size, kCFStringEncodingUTF8)) { - result = buf; - } - delete [] buf; - return result; -} -#endif // HAVE_COREAUDIO - -void -compute_equal_power_fades (nframes_t nframes, float* in, float* out) -{ - double step; - - step = 1.0/nframes; - - in[0] = 0.0f; - - for (nframes_t i = 1; i < nframes - 1; ++i) { - in[i] = in[i-1] + step; - } - - in[nframes-1] = 1.0; - - const float pan_law_attenuation = -3.0f; - const float scale = 2.0f - 4.0f * powf (10.0f,pan_law_attenuation/20.0f); - - for (nframes_t n = 0; n < nframes; ++n) { - float inVal = in[n]; - float outVal = 1 - inVal; - out[n] = outVal * (scale * outVal + 1.0f - scale); - in[n] = inVal * (scale * inVal + 1.0f - scale); - } -} - -EditMode -string_to_edit_mode (string str) -{ - if (str == _("Splice Edit")) { - return Splice; - } else if (str == _("Slide Edit")) { - return Slide; - } else if (str == _("Lock Edit")) { - return Lock; - } - fatal << string_compose (_("programming error: unknown edit mode string \"%1\""), str) << endmsg; - /*NOTREACHED*/ - return Slide; -} - -const char* -edit_mode_to_string (EditMode mode) -{ - switch (mode) { - case Slide: - return _("Slide Edit"); - - case Lock: - return _("Lock Edit"); - - default: - case Splice: - return _("Splice Edit"); - } -} - -SlaveSource -string_to_slave_source (string str) -{ - if (str == _("Internal")) { - return None; - } - - if (str == _("MTC")) { - return MTC; - } - - if (str == _("JACK")) { - return JACK; - } - - fatal << string_compose (_("programming error: unknown slave source string \"%1\""), str) << endmsg; - /*NOTREACHED*/ - return None; -} - -const char* -slave_source_to_string (SlaveSource src) -{ - switch (src) { - case JACK: - return _("JACK"); - - case MTC: - return _("MTC"); - - default: - case None: - return _("Internal"); - - } -} - -/* I don't really like hard-coding these falloff rates here - * Probably should use a map of some kind that could be configured - * These rates are db/sec. -*/ - -#define METER_FALLOFF_OFF 0.0f -#define METER_FALLOFF_SLOWEST 6.6f // BBC standard -#define METER_FALLOFF_SLOW 8.6f // BBC standard -#define METER_FALLOFF_MEDIUM 20.0f -#define METER_FALLOFF_FAST 32.0f -#define METER_FALLOFF_FASTER 46.0f -#define METER_FALLOFF_FASTEST 70.0f - -float -meter_falloff_to_float (MeterFalloff falloff) -{ - switch (falloff) { - case MeterFalloffOff: - return METER_FALLOFF_OFF; - case MeterFalloffSlowest: - return METER_FALLOFF_SLOWEST; - case MeterFalloffSlow: - return METER_FALLOFF_SLOW; - case MeterFalloffMedium: - return METER_FALLOFF_MEDIUM; - case MeterFalloffFast: - return METER_FALLOFF_FAST; - case MeterFalloffFaster: - return METER_FALLOFF_FASTER; - case MeterFalloffFastest: - return METER_FALLOFF_FASTEST; - default: - return METER_FALLOFF_FAST; - } -} - -MeterFalloff -meter_falloff_from_float (float val) -{ - if (val == METER_FALLOFF_OFF) { - return MeterFalloffOff; - } - else if (val <= METER_FALLOFF_SLOWEST) { - return MeterFalloffSlowest; - } - else if (val <= METER_FALLOFF_SLOW) { - return MeterFalloffSlow; - } - else if (val <= METER_FALLOFF_MEDIUM) { - return MeterFalloffMedium; - } - else if (val <= METER_FALLOFF_FAST) { - return MeterFalloffFast; - } - else if (val <= METER_FALLOFF_FASTER) { - return MeterFalloffFaster; - } - else { - return MeterFalloffFastest; - } -} - -float -meter_hold_to_float (MeterHold hold) -{ - switch (hold) { - case MeterHoldOff: - return 0.0f; - case MeterHoldShort: - return 40.0f; - case MeterHoldMedium: - return 100.0f; - case MeterHoldLong: - default: - return 200.0f; - } -} - -AutoState -ARDOUR::string_to_auto_state (std::string str) -{ - if (str == X_("Off")) { - return Off; - } else if (str == X_("Play")) { - return Play; - } else if (str == X_("Write")) { - return Write; - } else if (str == X_("Touch")) { - return Touch; - } - - fatal << string_compose (_("programming error: %1 %2"), "illegal AutoState string: ", str) << endmsg; - /*NOTREACHED*/ - return Touch; -} - -string -ARDOUR::auto_state_to_string (AutoState as) -{ - /* to be used only for XML serialization, no i18n done */ - - switch (as) { - case Off: - return X_("Off"); - break; - case Play: - return X_("Play"); - break; - case Write: - return X_("Write"); - break; - case Touch: - return X_("Touch"); - } - - fatal << string_compose (_("programming error: %1 %2"), "illegal AutoState type: ", as) << endmsg; - /*NOTREACHED*/ - return ""; -} - -AutoStyle -ARDOUR::string_to_auto_style (std::string str) -{ - if (str == X_("Absolute")) { - return Absolute; - } else if (str == X_("Trim")) { - return Trim; - } - - fatal << string_compose (_("programming error: %1 %2"), "illegal AutoStyle string: ", str) << endmsg; - /*NOTREACHED*/ - return Trim; -} - -string -ARDOUR::auto_style_to_string (AutoStyle as) -{ - /* to be used only for XML serialization, no i18n done */ - - switch (as) { - case Absolute: - return X_("Absolute"); - break; - case Trim: - return X_("Trim"); - break; - } - - fatal << string_compose (_("programming error: %1 %2"), "illegal AutoStyle type: ", as) << endmsg; - /*NOTREACHED*/ - return ""; -} - -extern "C" { - void c_stacktrace() { stacktrace (cerr); } -} diff --git a/libs/ardour/vst_plugin.cc b/libs/ardour/vst_plugin.cc deleted file mode 100644 index 47b5cb4fba..0000000000 --- a/libs/ardour/vst_plugin.cc +++ /dev/null @@ -1,512 +0,0 @@ -/* - 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. - -*/ - -#include <algorithm> -#include <vector> -#include <string> -#include <ctype.h> - -#include <cstdlib> -#include <cstdio> // so libraptor doesn't complain -#include <cmath> -#include <dirent.h> -#include <string.h> // for memmove -#include <sys/stat.h> -#include <cerrno> - -#include <lrdf.h> -#include <fst.h> - -#include <pbd/compose.h> -#include <pbd/error.h> -#include <pbd/pathscanner.h> -#include <pbd/xml++.h> - -#include <vst/aeffectx.h> - -#include <ardour/session.h> -#include <ardour/audioengine.h> -#include <ardour/filesystem_paths.h> -#include <ardour/vst_plugin.h> -#include <ardour/buffer_set.h> - -#include <pbd/stl_delete.h> - -#include "i18n.h" -#include <locale.h> - -using namespace ARDOUR; -using namespace PBD; -using std::min; -using std::max; - -VSTPlugin::VSTPlugin (AudioEngine& e, Session& session, FSTHandle* h) - : Plugin (e, session) -{ - handle = h; - - if ((_fst = fst_instantiate (handle, Session::vst_callback, this)) == 0) { - throw failed_constructor(); - } - - _plugin = _fst->plugin; - _plugin->user = this; - - /* set rate and blocksize */ - - _plugin->dispatcher (_plugin, effSetSampleRate, 0, 0, NULL, - (float) session.frame_rate()); - _plugin->dispatcher (_plugin, effSetBlockSize, 0, - session.get_block_size(), NULL, 0.0f); - - /* set program to zero */ - - _plugin->dispatcher (_plugin, effSetProgram, 0, 0, NULL, 0.0f); - - Plugin::setup_controls (); -} - -VSTPlugin::VSTPlugin (const VSTPlugin &other) - : Plugin (other) -{ - handle = other.handle; - - if ((_fst = fst_instantiate (handle, Session::vst_callback, this)) == 0) { - throw failed_constructor(); - } - _plugin = _fst->plugin; - - Plugin::setup_controls (); -} - -VSTPlugin::~VSTPlugin () -{ - deactivate (); - GoingAway (); /* EMIT SIGNAL */ - fst_close (_fst); -} - -void -VSTPlugin::set_block_size (nframes_t nframes) -{ - deactivate (); - _plugin->dispatcher (_plugin, effSetBlockSize, 0, nframes, NULL, 0.0f); - activate (); -} - -float -VSTPlugin::default_value (uint32_t port) -{ - return 0; -} - -void -VSTPlugin::set_parameter (uint32_t which, float val) -{ - _plugin->setParameter (_plugin, which, val); - //ParameterChanged (which, val); /* EMIT SIGNAL */ -} - -float -VSTPlugin::get_parameter (uint32_t which) const -{ - return _plugin->getParameter (_plugin, which); - -} - -uint32_t -VSTPlugin::nth_parameter (uint32_t n, bool& ok) const -{ - ok = true; - return n; -} - -XMLNode& -VSTPlugin::get_state() -{ - XMLNode *root = new XMLNode (state_node_name()); - LocaleGuard lg (X_("POSIX")); - - if (_plugin->flags & effFlagsProgramChunks) { - - /* fetch the current chunk */ - - void* data; - long data_size; - - if ((data_size = _plugin->dispatcher (_plugin, effGetChunk, 0, 0, &data, false)) == 0) { - return *root; - } - - /* save it to a file */ - - string path; - struct stat sbuf; - - sys::path user_vst_directory(user_config_directory()); - - user_vst_directory /= "vst"; - - path = user_vst_directory.to_string(); - - if (stat (path.c_str(), &sbuf)) { - if (errno == ENOENT) { - if (g_mkdir_with_parents (path.c_str(), 0600)) { - error << string_compose (_("cannot create VST chunk directory: %1"), - strerror (errno)) - << endmsg; - return *root; - } - - } else { - - warning << string_compose (_("cannot check VST chunk directory: %1"), strerror (errno)) - << endmsg; - return *root; - } - - } else if (!S_ISDIR (sbuf.st_mode)) { - error << string_compose (_("%1 exists but is not a directory"), path) - << endmsg; - return *root; - } - - path += "something"; - - /* store information */ - - XMLNode* chunk_node = new XMLNode (X_("chunk")); - chunk_node->add_property ("path", path); - - root->add_child_nocopy (*chunk_node); - - } else { - - XMLNode* parameters = new XMLNode ("parameters"); - - for (long n = 0; n < _plugin->numParams; ++n) { - char index[64]; - char val[32]; - snprintf (index, sizeof (index), "param_%ld", n); - snprintf (val, sizeof (val), "%.12g", _plugin->getParameter (_plugin, n)); - parameters->add_property (index, val); - } - - root->add_child_nocopy (*parameters); - } - - return *root; -} - -int -VSTPlugin::set_state(const XMLNode& node) -{ - LocaleGuard lg (X_("POSIX")); - - if (node.name() != state_node_name()) { - error << _("Bad node sent to VSTPlugin::set_state") << endmsg; - return 0; - } - - XMLNode* child; - - if ((child = find_named_node (node, X_("chunks"))) != 0) { - - return 0; - - } else if ((child = find_named_node (node, X_("parameters"))) != 0) { - - XMLPropertyList::const_iterator i; - - for (i = child->properties().begin(); i != child->properties().end(); ++i) { - long param; - float val; - - sscanf ((*i)->name().c_str(), "param_%ld", ¶m); - sscanf ((*i)->value().c_str(), "%f", &val); - - _plugin->setParameter (_plugin, param, val); - } - - return 0; - } - - return -1; -} - -int -VSTPlugin::get_parameter_descriptor (uint32_t which, ParameterDescriptor& desc) const -{ - VstParameterProperties prop; - - desc.min_unbound = false; - desc.max_unbound = false; - - if (_plugin->dispatcher (_plugin, effGetParameterProperties, which, 0, &prop, 0)) { - - /* i have yet to find or hear of a VST plugin that uses this */ - - if (prop.flags & kVstParameterUsesIntegerMinMax) { - desc.lower = prop.minInteger; - desc.upper = prop.maxInteger; - } else { - desc.lower = 0; - desc.upper = 1.0; - } - - if (prop.flags & kVstParameterUsesIntStep) { - - desc.step = prop.stepInteger; - desc.smallstep = prop.stepInteger; - desc.largestep = prop.stepInteger; - - } else if (prop.flags & kVstParameterUsesFloatStep) { - - desc.step = prop.stepFloat; - desc.smallstep = prop.smallStepFloat; - desc.largestep = prop.largeStepFloat; - - } else { - - float range = desc.upper - desc.lower; - - desc.step = range / 100.0f; - desc.smallstep = desc.step / 2.0f; - desc.largestep = desc.step * 10.0f; - } - - desc.toggled = prop.flags & kVstParameterIsSwitch; - desc.logarithmic = false; - desc.sr_dependent = false; - desc.label = prop.label; - - } else { - - /* old style */ - - char label[64]; - label[0] = '\0'; - - _plugin->dispatcher (_plugin, effGetParamName, which, 0, label, 0); - - desc.label = label; - desc.integer_step = false; - desc.lower = 0.0f; - desc.upper = 1.0f; - desc.step = 0.01f; - desc.smallstep = 0.005f; - desc.largestep = 0.1f; - desc.toggled = false; - desc.logarithmic = false; - desc.sr_dependent = false; - } - - return 0; -} - -bool -VSTPlugin::load_preset (string name) -{ - if (_plugin->flags & effFlagsProgramChunks) { - error << _("no support for presets using chunks at this time") - << endmsg; - return false; - } - return Plugin::load_preset (name); -} - -bool -VSTPlugin::save_preset (string name) -{ - if (_plugin->flags & effFlagsProgramChunks) { - error << _("no support for presets using chunks at this time") - << endmsg; - return false; - } - return Plugin::save_preset (name, "vst"); -} - -string -VSTPlugin::describe_parameter (uint32_t param) -{ - char name[64]; - _plugin->dispatcher (_plugin, effGetParamName, param, 0, name, 0); - return name; -} - -nframes_t -VSTPlugin::signal_latency () const -{ - if (_user_latency) { - return _user_latency; - } - - return _plugin->initialDelay; -} - -set<uint32_t> -VSTPlugin::automatable () const -{ - set<uint32_t> ret; - - for (uint32_t i = 0; i < parameter_count(); ++i){ - ret.insert (ret.end(), i); - } - - return ret; -} - -int -VSTPlugin::connect_and_run (BufferSet& bufs, uint32_t& in_index, uint32_t& out_index, nframes_t nframes, nframes_t offset) -{ - float *ins[_plugin->numInputs]; - float *outs[_plugin->numOutputs]; - int32_t i; - - const uint32_t nbufs = bufs.count().n_audio(); - - for (i = 0; i < (int32_t) _plugin->numInputs; ++i) { - ins[i] = bufs.get_audio(min((uint32_t) in_index, nbufs - 1)).data() + offset; - in_index++; - } - - for (i = 0; i < (int32_t) _plugin->numOutputs; ++i) { - outs[i] = bufs.get_audio(min((uint32_t) out_index, nbufs - 1)).data() + offset; - - /* unbelievably, several VST plugins still rely on Cubase - behaviour and do not silence the buffer in processReplacing - when they have no output. - */ - - // memset (outs[i], 0, sizeof (Sample) * nframes); - out_index++; - } - - - /* we already know it can support processReplacing */ - - _plugin->processReplacing (_plugin, ins, outs, nframes); - - return 0; -} - -void -VSTPlugin::deactivate () -{ - _plugin->dispatcher (_plugin, effMainsChanged, 0, 0, NULL, 0.0f); -} - -void -VSTPlugin::activate () -{ - _plugin->dispatcher (_plugin, effMainsChanged, 0, 1, NULL, 0.0f); -} - -string -VSTPlugin::unique_id() const -{ - char buf[32]; - snprintf (buf, sizeof (buf), "%d", _plugin->uniqueID); - return string (buf); -} - - -const char * -VSTPlugin::name () const -{ - return handle->name; -} - -const char * -VSTPlugin::maker () const -{ - return "imadeit"; -} - -const char * -VSTPlugin::label () const -{ - return handle->name; -} - -uint32_t -VSTPlugin::parameter_count() const -{ - return _plugin->numParams; -} - -bool -VSTPlugin::has_editor () const -{ - return _plugin->flags & effFlagsHasEditor; -} - -void -VSTPlugin::print_parameter (uint32_t param, char *buf, uint32_t len) const -{ - char lab[9]; - char *first_nonws; - - _plugin->dispatcher (_plugin, effGetParamLabel, param, 0, lab, 0); - _plugin->dispatcher (_plugin, effGetParamDisplay, param, 0, buf, 0); - - if (buf[0] == '\0') { - return; - } - - first_nonws = buf; - while (*first_nonws && isspace (*first_nonws)) { - first_nonws++; - } - if (*first_nonws == '\0') { - return; - } - - memmove (buf, first_nonws, strlen (buf) - (first_nonws - buf) + 1); -} - -PluginPtr -VSTPluginInfo::load (Session& session) -{ - try { - PluginPtr plugin; - - if (Config->get_use_vst()) { - FSTHandle* handle; - - handle = fst_load(path.c_str()); - - if ( (int)handle == -1) { - error << string_compose(_("VST: cannot load module from \"%1\""), path) << endmsg; - } else { - plugin.reset (new VSTPlugin (session.engine(), session, handle)); - } - } else { - error << _("You asked ardour to not use any VST plugins") << endmsg; - return PluginPtr ((Plugin*) 0); - } - - plugin->set_info(PluginInfoPtr(new VSTPluginInfo(*this))); - return plugin; - } - - catch (failed_constructor &err) { - return PluginPtr ((Plugin*) 0); - } -} |