From 45d3ec1437cf661533bc7750c623865def4424df Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Wed, 11 Apr 2007 13:07:51 +0000 Subject: merged with 1697 revision of trunk (which is post-rc1 but pre-rc2 git-svn-id: svn://localhost/ardour2/branches/2.1-staging@1698 d708f5d6-7413-0410-9779-e7cbd77b26cf --- libs/ardour/SConscript | 18 +- libs/ardour/ardour/ardour.h | 1 - libs/ardour/ardour/audio_diskstream.h | 71 +- libs/ardour/ardour/audio_track.h | 1 - libs/ardour/ardour/audioengine.h | 1 - libs/ardour/ardour/audiofilesource.h | 57 +- libs/ardour/ardour/audiofilter.h | 1 - libs/ardour/ardour/audioplaylist.h | 1 - libs/ardour/ardour/audioregion.h | 5 +- libs/ardour/ardour/audiosource.h | 80 +- libs/ardour/ardour/auditioner.h | 1 - libs/ardour/ardour/automation_event.h | 1 - libs/ardour/ardour/click.h | 1 - libs/ardour/ardour/configuration.h | 1 - libs/ardour/ardour/configuration_variable.h | 5 +- libs/ardour/ardour/configuration_vars.h | 7 +- libs/ardour/ardour/connection.h | 1 - libs/ardour/ardour/coreaudiosource.h | 2 +- libs/ardour/ardour/crossfade.h | 1 - libs/ardour/ardour/crossfade_compare.h | 1 - libs/ardour/ardour/curve.h | 1 - libs/ardour/ardour/cycle_timer.h | 1 - libs/ardour/ardour/cycles.h | 1 - libs/ardour/ardour/dB.h | 1 - libs/ardour/ardour/destructive_filesource.h | 76 -- libs/ardour/ardour/diskstream.h | 8 +- libs/ardour/ardour/export.h | 6 +- libs/ardour/ardour/gain.h | 1 - libs/ardour/ardour/gdither.h | 1 - libs/ardour/ardour/gdither_types.h | 1 - libs/ardour/ardour/gdither_types_internal.h | 1 - libs/ardour/ardour/insert.h | 1 - libs/ardour/ardour/io.h | 4 +- libs/ardour/ardour/ladspa_plugin.h | 1 - libs/ardour/ardour/location.h | 9 +- libs/ardour/ardour/logcurve.h | 1 - libs/ardour/ardour/mix.h | 19 +- libs/ardour/ardour/named_selection.h | 1 - libs/ardour/ardour/osc.h | 1 - libs/ardour/ardour/panner.h | 1 - libs/ardour/ardour/pcm_utils.h | 1 - libs/ardour/ardour/playlist.h | 8 +- libs/ardour/ardour/playlist_templates.h | 1 - libs/ardour/ardour/plugin.h | 1 - libs/ardour/ardour/plugin_manager.h | 1 - libs/ardour/ardour/port.h | 1 - libs/ardour/ardour/profile.h | 31 + libs/ardour/ardour/redirect.h | 1 - libs/ardour/ardour/region.h | 1 - libs/ardour/ardour/reverse.h | 1 - libs/ardour/ardour/route.h | 22 +- libs/ardour/ardour/route_group.h | 1 - libs/ardour/ardour/send.h | 1 - libs/ardour/ardour/session.h | 34 +- libs/ardour/ardour/session_connection.h | 1 - libs/ardour/ardour/session_playlist.h | 1 - libs/ardour/ardour/session_route.h | 1 - libs/ardour/ardour/session_selection.h | 1 - libs/ardour/ardour/silentfilesource.h | 66 ++ libs/ardour/ardour/slave.h | 2 +- libs/ardour/ardour/sndfilesource.h | 9 +- libs/ardour/ardour/soundseq.h | 1 - libs/ardour/ardour/source.h | 5 +- libs/ardour/ardour/source_factory.h | 1 + libs/ardour/ardour/tempo.h | 1 - libs/ardour/ardour/types.h | 8 +- libs/ardour/ardour/utils.h | 1 - libs/ardour/ardour/vst_plugin.h | 1 - libs/ardour/audio_diskstream.cc | 637 +++++----- libs/ardour/audio_playlist.cc | 3 +- libs/ardour/audio_track.cc | 16 +- libs/ardour/audioengine.cc | 9 +- libs/ardour/audiofilesource.cc | 227 ++-- libs/ardour/audiofilter.cc | 2 +- libs/ardour/audioregion.cc | 72 +- libs/ardour/audiosource.cc | 575 ++++----- libs/ardour/auditioner.cc | 13 +- libs/ardour/automation_event.cc | 1 - libs/ardour/configuration.cc | 19 +- libs/ardour/connection.cc | 1 - libs/ardour/control_protocol_manager.cc | 13 +- libs/ardour/coreaudiosource.cc | 13 +- libs/ardour/crossfade.cc | 1 - libs/ardour/curve.cc | 1 - libs/ardour/cycle_timer.cc | 1 - libs/ardour/default_click.cc | 1 - libs/ardour/destructive_filesource.cc | 424 ------- libs/ardour/diskstream.cc | 10 +- libs/ardour/enums.cc | 6 + libs/ardour/gain.cc | 1 - libs/ardour/gdither.cc | 1 - libs/ardour/globals.cc | 13 +- libs/ardour/import.cc | 269 +++-- libs/ardour/insert.cc | 5 +- libs/ardour/io.cc | 8 +- libs/ardour/jack_slave.cc | 1 - libs/ardour/ladspa_plugin.cc | 13 +- libs/ardour/location.cc | 21 +- libs/ardour/macosx/English.lproj/InfoPlist.strings | Bin 0 -> 142 bytes libs/ardour/macosx/Info.plist | 26 + .../ardour/macosx/ardour.xcodeproj/project.pbxproj | 1214 ++++++++++++++++++++ libs/ardour/macosx/ardour_Prefix.pch | 4 + libs/ardour/macosx/version.cc | 3 + libs/ardour/macosx/version.h | 17 + libs/ardour/mix.cc | 28 +- libs/ardour/mtc_slave.cc | 38 +- libs/ardour/named_selection.cc | 1 - libs/ardour/osc.cc | 18 +- libs/ardour/panner.cc | 20 +- libs/ardour/pcm_utils.cc | 1 - libs/ardour/playlist.cc | 56 +- libs/ardour/playlist_factory.cc | 1 - libs/ardour/plugin.cc | 1 - libs/ardour/plugin_manager.cc | 1 - libs/ardour/port.cc | 1 - libs/ardour/redirect.cc | 1 - libs/ardour/region.cc | 7 +- libs/ardour/region_factory.cc | 1 - libs/ardour/reverse.cc | 33 +- libs/ardour/route.cc | 92 +- libs/ardour/route_group.cc | 1 - libs/ardour/send.cc | 1 - libs/ardour/session.cc | 175 ++- libs/ardour/session_butler.cc | 13 +- libs/ardour/session_click.cc | 1 - libs/ardour/session_command.cc | 5 +- libs/ardour/session_control.cc | 30 - libs/ardour/session_events.cc | 1 - libs/ardour/session_export.cc | 58 +- libs/ardour/session_feedback.cc | 1 - libs/ardour/session_midi.cc | 57 +- libs/ardour/session_process.cc | 32 +- libs/ardour/session_state.cc | 206 +++- libs/ardour/session_time.cc | 2 +- libs/ardour/session_timefx.cc | 46 +- libs/ardour/session_transport.cc | 19 +- libs/ardour/session_vst.cc | 1 - libs/ardour/silentfilesource.cc | 39 + libs/ardour/sndfilesource.cc | 76 +- libs/ardour/source.cc | 22 +- libs/ardour/source_factory.cc | 29 +- libs/ardour/sse_functions_xmm.cc | 116 ++ libs/ardour/tempo.cc | 1 - libs/ardour/utils.cc | 1 - libs/ardour/vst_plugin.cc | 6 +- 145 files changed, 3465 insertions(+), 2012 deletions(-) delete mode 100644 libs/ardour/ardour/destructive_filesource.h create mode 100644 libs/ardour/ardour/profile.h create mode 100644 libs/ardour/ardour/silentfilesource.h delete mode 100644 libs/ardour/destructive_filesource.cc create mode 100644 libs/ardour/macosx/English.lproj/InfoPlist.strings create mode 100644 libs/ardour/macosx/Info.plist create mode 100644 libs/ardour/macosx/ardour.xcodeproj/project.pbxproj create mode 100644 libs/ardour/macosx/ardour_Prefix.pch create mode 100644 libs/ardour/macosx/version.cc create mode 100644 libs/ardour/macosx/version.h delete mode 100644 libs/ardour/session_control.cc create mode 100644 libs/ardour/silentfilesource.cc create mode 100644 libs/ardour/sse_functions_xmm.cc (limited to 'libs/ardour') diff --git a/libs/ardour/SConscript b/libs/ardour/SConscript index bc3b16d067..4eb50bdc54 100644 --- a/libs/ardour/SConscript +++ b/libs/ardour/SConscript @@ -88,6 +88,7 @@ session_state.cc session_time.cc session_timefx.cc session_transport.cc +silentfilesource.cc sndfile_helpers.cc sndfilesource.cc source.cc @@ -283,16 +284,29 @@ env['BUILDERS']['SharedAsmObject'] = Builder (action = '$CXX -c -fPIC $SOURCE -o 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 + extra_sources + arch_specific_objects) +libardour = ardour.SharedLibrary('ardour', ardour_files + always_sse_objects + extra_sources + arch_specific_objects) Default(libardour) @@ -305,6 +319,6 @@ env.Alias('install', env.Install(os.path.join(install_prefix, env['LIBDIR'], 'ar env.Alias('version', ardour.VersionBuild(['version.cc', 'ardour/version.h'], [])) env.Alias('tarball', env.Distribute (env['DISTTREE'], - [ 'SConscript', 'i18n.h', 'gettext.h', 'sse_functions.s', 'sse_functions_64bit.s' ] + + [ 'SConscript', 'i18n.h', 'gettext.h', 'sse_functions_xmm.cc', 'sse_functions.s', 'sse_functions_64bit.s' ] + ardour_files + osc_files + vst_files + coreaudio_files + audiounit_files + glob.glob('po/*.po') + glob.glob('ardour/*.h'))) diff --git a/libs/ardour/ardour/ardour.h b/libs/ardour/ardour/ardour.h index 4a7182ad7a..09c6bd8856 100644 --- a/libs/ardour/ardour/ardour.h +++ b/libs/ardour/ardour/ardour.h @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #ifndef __ardour_ardour_h__ diff --git a/libs/ardour/ardour/audio_diskstream.h b/libs/ardour/ardour/audio_diskstream.h index 1da8903a41..4846a20cbd 100644 --- a/libs/ardour/ardour/audio_diskstream.h +++ b/libs/ardour/ardour/audio_diskstream.h @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -65,24 +66,28 @@ class AudioDiskstream : public Diskstream float capture_buffer_load() const; string input_source (uint32_t n=0) const { - if (n < channels.size()) { - return channels[n].source ? channels[n].source->name() : ""; + boost::shared_ptr c = channels.reader(); + if (n < c->size()) { + return (*c)[n]->source ? (*c)[n]->source->name() : ""; } else { return ""; } } Port *input_source_port (uint32_t n=0) const { - if (n < channels.size()) return channels[n].source; return 0; + boost::shared_ptr c = channels.reader(); + if (n < c->size()) return (*c)[n]->source; return 0; } void set_record_enabled (bool yn); int set_destructive (bool yn); bool can_become_destructive (bool& requires_bounce) const; - float peak_power(uint32_t n=0) { - float x = channels[n].peak_power; - channels[n].peak_power = 0.0f; + float peak_power(uint32_t n = 0) { + boost::shared_ptr c = channels.reader(); + ChannelInfo* chaninfo = (*c)[n]; + float x = chaninfo->peak_power; + chaninfo->peak_power = 0.0f; if (x > 0.0f) { return 20.0f * fast_log10(x); } else { @@ -96,27 +101,29 @@ class AudioDiskstream : public Diskstream int use_new_playlist (); int use_copy_playlist (); - Sample *playback_buffer (uint32_t n=0) { - if (n < channels.size()) - return channels[n].current_playback_buffer; + Sample *playback_buffer (uint32_t n = 0) { + boost::shared_ptr c = channels.reader(); + if (n < c->size()) + return (*c)[n]->current_playback_buffer; return 0; } - Sample *capture_buffer (uint32_t n=0) { - if (n < channels.size()) - return channels[n].current_capture_buffer; + Sample *capture_buffer (uint32_t n = 0) { + boost::shared_ptr c = channels.reader(); + if (n < c->size()) + return (*c)[n]->current_capture_buffer; return 0; } boost::shared_ptr write_source (uint32_t n=0) { - if (n < channels.size()) - return channels[n].write_source; + boost::shared_ptr c = channels.reader(); + if (n < c->size()) + return (*c)[n]->write_source; return boost::shared_ptr(); } - int add_channel (); - int remove_channel (); - + int add_channel (uint32_t how_many); + int remove_channel (uint32_t how_many); /* stateful */ @@ -174,12 +181,9 @@ class AudioDiskstream : public Diskstream struct ChannelInfo { - ChannelInfo (); + ChannelInfo (nframes_t buffer_size, nframes_t speed_buffer_size, nframes_t wrap_buffer_size); ~ChannelInfo (); - void init (nframes_t buffer_size, nframes_t speed_buffer_size, nframes_t wrap_buffer_size); - void release (); - Sample *playback_wrap_buffer; Sample *capture_wrap_buffer; Sample *speed_buffer; @@ -208,17 +212,19 @@ class AudioDiskstream : public Diskstream nframes_t curr_capture_cnt; }; + typedef std::vector ChannelList; + /* The two central butler operations */ int do_flush (Session::RunContext context, bool force = false); int do_refill () { return _do_refill(_mixdown_buffer, _gain_buffer); } - int do_refill_with_alloc(); + int 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); + nframes_t& start, nframes_t cnt, + ChannelInfo* channel_info, int channel, bool reversed); - void finish_capture (bool rec_monitors_input); + void finish_capture (bool rec_monitors_input, boost::shared_ptr); void transport_stopped (struct tm&, time_t, bool abort); void init (Diskstream::Flag); @@ -251,14 +257,17 @@ class AudioDiskstream : public Diskstream static Sample* _mixdown_buffer; static gain_t* _gain_buffer; - // Uh, /really/ private? (there should probably be less friends of Diskstream) - int _do_refill (Sample *mixdown_buffer, float *gain_buffer); - - std::vector > capturing_sources; - typedef vector ChannelList; - ChannelList channels; + SerializedRCUManager channels; + + /* really */ + private: + int _do_refill (Sample *mixdown_buffer, float *gain_buffer); + + int add_channel_to (boost::shared_ptr, uint32_t how_many); + int remove_channel_from (boost::shared_ptr, uint32_t how_many); + }; } // namespace ARDOUR diff --git a/libs/ardour/ardour/audio_track.h b/libs/ardour/ardour/audio_track.h index f35bdd44be..0405c30301 100644 --- a/libs/ardour/ardour/audio_track.h +++ b/libs/ardour/ardour/audio_track.h @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #ifndef __ardour_audio_track_h__ diff --git a/libs/ardour/ardour/audioengine.h b/libs/ardour/ardour/audioengine.h index 71639b3dc3..0b423a7e28 100644 --- a/libs/ardour/ardour/audioengine.h +++ b/libs/ardour/ardour/audioengine.h @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #ifndef __ardour_audioengine_h__ diff --git a/libs/ardour/ardour/audiofilesource.h b/libs/ardour/ardour/audiofilesource.h index f91f78f6d9..dce06c1ca0 100644 --- a/libs/ardour/ardour/audiofilesource.h +++ b/libs/ardour/ardour/audiofilesource.h @@ -20,12 +20,19 @@ #ifndef __ardour_audiofilesource_h__ #define __ardour_audiofilesource_h__ +#include + #include #include namespace ARDOUR { +class non_existent_source : public std::exception { + public: + virtual const char *what() const throw() { return "audio file does not exist"; } +}; + struct SoundFileInfo { float samplerate; uint16_t channels; @@ -49,17 +56,19 @@ class AudioFileSource : public AudioSource { virtual ~AudioFileSource (); - int set_name (string newname, bool destructive); + int set_name (Glib::ustring newname, bool destructive); + + Glib::ustring path() const { return _path; } + Glib::ustring peak_path (Glib::ustring audio_path); + Glib::ustring old_peak_path (Glib::ustring audio_path); - string path() const { return _path; } - string peak_path (string audio_path); - string old_peak_path (string audio_path); + uint16_t channel() const { return _channel; } - static void set_peak_dir (string dir) { peak_dir = dir; } + static void set_peak_dir (Glib::ustring dir) { peak_dir = dir; } - static bool get_soundfile_info (string path, SoundFileInfo& _info, string& error); + static bool get_soundfile_info (Glib::ustring path, SoundFileInfo& _info, std::string& error); - static bool safe_file_extension (string path); + static bool safe_file_extension (Glib::ustring path); void set_allow_remove_if_empty (bool yn); void mark_for_remove(); @@ -72,23 +81,24 @@ class AudioFileSource : public AudioSource { 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 string trash_dir_name); + int move_to_trash (const Glib::ustring& trash_dir_name); - static bool is_empty (Session&, string path); + static bool is_empty (Session&, Glib::ustring path); void mark_streaming_write_completed (); - void mark_take (string); - string take_id() const { return _take_id; } + 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 (string); + static void set_search_path (Glib::ustring string); static void set_header_position_offset (nframes_t offset ); int setup_peakfile (); @@ -100,6 +110,7 @@ class AudioFileSource : public AudioSource { 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; } @@ -116,31 +127,31 @@ class AudioFileSource : public AudioSource { /* constructor to be called for existing external-to-session files */ - AudioFileSource (Session&, std::string path, Flag flags); + AudioFileSource (Session&, Glib::ustring path, Flag flags); /* constructor to be called for new in-session files */ - AudioFileSource (Session&, std::string path, Flag flags, + 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&); + AudioFileSource (Session&, const XMLNode&, bool must_exit = true); - int init (string idstr, bool must_exist); + int init (Glib::ustring idstr, bool must_exist); - string _path; + Glib::ustring _path; Flag _flags; - string _take_id; + Glib::ustring _take_id; int64_t timeline_position; bool file_is_new; - uint16_t channel; + uint16_t _channel; bool _is_embedded; - static bool determine_embeddedness(string path); + static bool determine_embeddedness(Glib::ustring path); - static string peak_dir; - static string search_path; + static Glib::ustring peak_dir; + static Glib::ustring search_path; static char bwf_country_code[3]; static char bwf_organization_code[4]; @@ -151,7 +162,7 @@ class AudioFileSource : public AudioSource { virtual void set_timeline_position (int64_t pos); virtual void set_header_timeline_position () = 0; - bool find (std::string path, bool must_exist, bool& is_new); + bool find (Glib::ustring& path, bool must_exist, bool& is_new, uint16_t& chan); bool removable() const; bool writable() const { return _flags & Writable; } }; diff --git a/libs/ardour/ardour/audiofilter.h b/libs/ardour/ardour/audiofilter.h index c8762dbf69..6b60544942 100644 --- a/libs/ardour/ardour/audiofilter.h +++ b/libs/ardour/ardour/audiofilter.h @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #ifndef __ardour_audiofilter_h__ diff --git a/libs/ardour/ardour/audioplaylist.h b/libs/ardour/ardour/audioplaylist.h index 586bf6ccc6..38084a1f7a 100644 --- a/libs/ardour/ardour/audioplaylist.h +++ b/libs/ardour/ardour/audioplaylist.h @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #ifndef __ardour_audio_playlist_h__ diff --git a/libs/ardour/ardour/audioregion.h b/libs/ardour/ardour/audioregion.h index ef5f5dc6e7..a450d90008 100644 --- a/libs/ardour/ardour/audioregion.h +++ b/libs/ardour/ardour/audioregion.h @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #ifndef __ardour_audio_region_h__ @@ -66,7 +65,7 @@ class AudioRegion : public Region void normalize_to (float target_in_dB = 0.0f); - uint32_t n_channels() { return sources.size(); } + uint32_t n_channels() const { return sources.size(); } vector master_source_names(); bool envelope_active () const { return _flags & Region::EnvelopeActive; } @@ -96,6 +95,8 @@ class AudioRegion : public Region 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, diff --git a/libs/ardour/ardour/audiosource.h b/libs/ardour/ardour/audiosource.h index 251f19f2e5..b1062c43a9 100644 --- a/libs/ardour/ardour/audiosource.h +++ b/libs/ardour/ardour/audiosource.h @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id: audio_source.h 486 2006-04-27 09:04:24Z pauld $ */ #ifndef __ardour_audio_source_h__ @@ -23,7 +22,6 @@ #include #include -#include #include #include @@ -31,6 +29,7 @@ #include #include +#include #include @@ -41,7 +40,7 @@ using std::list; using std::vector; -using std::string; +using Glib::ustring; namespace ARDOUR { @@ -50,7 +49,7 @@ const nframes_t frames_per_peak = 256; class AudioSource : public Source, public boost::enable_shared_from_this { public: - AudioSource (Session&, string name); + AudioSource (Session&, ustring name); AudioSource (Session&, const XMLNode&); virtual ~AudioSource (); @@ -77,8 +76,10 @@ const nframes_t frames_per_peak = 256; virtual void mark_for_remove() = 0; virtual void mark_streaming_write_completed () {} - void set_captured_for (string str) { _captured_for = str; } - string captured_for() const { return _captured_for; } + virtual bool can_truncate_peaks() const { return true; } + + void set_captured_for (ustring str) { _captured_for = str; } + 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; } @@ -93,10 +94,7 @@ const nframes_t frames_per_peak = 256; XMLNode& get_state (); int set_state (const XMLNode&); - static int start_peak_thread (); - static void stop_peak_thread (); - - int rename_peakfile (std::string newpath); + int rename_peakfile (ustring newpath); void touch_peakfile (); static void set_build_missing_peakfiles (bool yn) { @@ -109,6 +107,9 @@ const nframes_t frames_per_peak = 256; virtual int setup_peakfile () { return 0; } + int prepare_for_peakfile_writes (); + void done_with_peakfile_writes (); + protected: static bool _build_missing_peakfiles; static bool _build_peakfiles; @@ -116,63 +117,34 @@ const nframes_t frames_per_peak = 256; bool _peaks_built; mutable Glib::Mutex _lock; nframes_t _length; - bool next_peak_clear_should_notify; - string peakpath; - string _captured_for; + ustring peakpath; + 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, string path); - void build_peaks_from_scratch (); - - int do_build_peak (nframes_t, nframes_t); + int initialize_peakfile (bool newfile, ustring path); + int build_peaks_from_scratch (); + int compute_and_write_peaks (Sample* buf, nframes_t first_frame, nframes_t cnt, bool force); void truncate_peakfile(); - mutable off_t _peak_byte_max; // modified in do_build_peaks() + 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 string peak_path(string audio_path) = 0; - virtual string old_peak_path(string audio_path) = 0; + virtual ustring peak_path(ustring audio_path) = 0; + virtual ustring old_peak_path(ustring audio_path) = 0; void update_length (nframes_t pos, nframes_t cnt); - static pthread_t peak_thread; - static bool have_peak_thread; - static void* peak_thread_work(void*); - - static int peak_request_pipe[2]; - - struct PeakRequest { - enum Type { - Build, - Quit - }; - }; - - static vector > pending_peak_sources; - static Glib::Mutex* pending_peak_sources_lock; - - static void queue_for_peaks (boost::shared_ptr, bool notify=true); - static void clear_queue_for_peaks (); - - struct PeakBuildRecord { - nframes_t frame; - nframes_t cnt; - - PeakBuildRecord (nframes_t f, nframes_t c) - : frame (f), cnt (c) {} - PeakBuildRecord (const PeakBuildRecord& other) { - frame = other.frame; - cnt = other.cnt; - } - }; - - list pending_peak_builds; - private: - bool file_changed (string path); + int peakfile; + nframes_t peak_leftover_cnt; + nframes_t peak_leftover_size; + Sample* peak_leftovers; + nframes_t peak_leftover_frame; + + bool file_changed (ustring path); }; } diff --git a/libs/ardour/ardour/auditioner.h b/libs/ardour/ardour/auditioner.h index e6091cfba0..06d521ea21 100644 --- a/libs/ardour/ardour/auditioner.h +++ b/libs/ardour/ardour/auditioner.h @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #ifndef __ardour_auditioner_h__ diff --git a/libs/ardour/ardour/automation_event.h b/libs/ardour/ardour/automation_event.h index a2cfb23e61..007bad7259 100644 --- a/libs/ardour/ardour/automation_event.h +++ b/libs/ardour/ardour/automation_event.h @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #ifndef __ardour_automation_event_h__ diff --git a/libs/ardour/ardour/click.h b/libs/ardour/ardour/click.h index 71214978a5..60499b98da 100644 --- a/libs/ardour/ardour/click.h +++ b/libs/ardour/ardour/click.h @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #ifndef __ardour_click_h__ diff --git a/libs/ardour/ardour/configuration.h b/libs/ardour/ardour/configuration.h index bb49b2dce4..31cb74ab33 100644 --- a/libs/ardour/ardour/configuration.h +++ b/libs/ardour/ardour/configuration.h @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #ifndef __ardour_configuration_h__ diff --git a/libs/ardour/ardour/configuration_variable.h b/libs/ardour/ardour/configuration_variable.h index 8710369a64..81e282ff64 100644 --- a/libs/ardour/ardour/configuration_variable.h +++ b/libs/ardour/ardour/configuration_variable.h @@ -27,10 +27,13 @@ class ConfigVariableBase { 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 (); @@ -61,7 +64,7 @@ class ConfigVariable : public ConfigVariableBase void add_to_node (XMLNode& node) { std::stringstream ss; ss << value; - cerr << "Config variable " << _name << " stored as " << ss.str() << endl; + show_stored_value (ss.str()); XMLNode* child = new XMLNode ("Option"); child->add_property ("name", _name); child->add_property ("value", ss.str()); diff --git a/libs/ardour/ardour/configuration_vars.h b/libs/ardour/ardour/configuration_vars.h index 703352b305..4f0bae1208 100644 --- a/libs/ardour/ardour/configuration_vars.h +++ b/libs/ardour/ardour/configuration_vars.h @@ -17,12 +17,14 @@ CONFIG_VARIABLE (bool, send_mtc, "send-mtc", false) CONFIG_VARIABLE (bool, send_mmc, "send-mmc", false) CONFIG_VARIABLE (bool, mmc_control, "mmc-control", false) CONFIG_VARIABLE (bool, midi_feedback, "midi-feedback", false) -CONFIG_VARIABLE (bool, midi_control, "midi-control", false) +CONFIG_VARIABLE (uint8_t, mmc_device_id, "mmc-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 */ @@ -35,7 +37,7 @@ CONFIG_VARIABLE (HeaderFormat, native_file_header_format, "native-file-header-f /* OSC */ CONFIG_VARIABLE (uint32_t, osc_port, "osc-port", 3819) -CONFIG_VARIABLE (bool, use_osc, "use-osc", true) +CONFIG_VARIABLE (bool, use_osc, "use-osc", false) /* crossfades */ @@ -62,6 +64,7 @@ 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) /* click */ diff --git a/libs/ardour/ardour/connection.h b/libs/ardour/ardour/connection.h index da4d4e2684..d2f1cb4294 100644 --- a/libs/ardour/ardour/connection.h +++ b/libs/ardour/ardour/connection.h @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #ifndef __ardour_connection_h__ diff --git a/libs/ardour/ardour/coreaudiosource.h b/libs/ardour/ardour/coreaudiosource.h index 63c50d7cfb..ad21188531 100644 --- a/libs/ardour/ardour/coreaudiosource.h +++ b/libs/ardour/ardour/coreaudiosource.h @@ -52,7 +52,7 @@ class CoreAudioSource : public AudioFileSource { mutable nframes_t tmpbufsize; mutable Glib::Mutex _tmpbuf_lock; - void init (string str); + void init (); }; }; /* namespace ARDOUR */ diff --git a/libs/ardour/ardour/crossfade.h b/libs/ardour/ardour/crossfade.h index 3eafed818c..7346e645fb 100644 --- a/libs/ardour/ardour/crossfade.h +++ b/libs/ardour/ardour/crossfade.h @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #ifndef __ardour_overlap_h__ diff --git a/libs/ardour/ardour/crossfade_compare.h b/libs/ardour/ardour/crossfade_compare.h index 2ecf79c04c..b92806a6bb 100644 --- a/libs/ardour/ardour/crossfade_compare.h +++ b/libs/ardour/ardour/crossfade_compare.h @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #ifndef __ardour_crossfade_compare_h__ diff --git a/libs/ardour/ardour/curve.h b/libs/ardour/ardour/curve.h index df984b74e0..dd63439f08 100644 --- a/libs/ardour/ardour/curve.h +++ b/libs/ardour/ardour/curve.h @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #ifndef __ardour_curve_h__ diff --git a/libs/ardour/ardour/cycle_timer.h b/libs/ardour/ardour/cycle_timer.h index b9cbbbf0a8..4e1a50e602 100644 --- a/libs/ardour/ardour/cycle_timer.h +++ b/libs/ardour/ardour/cycle_timer.h @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #ifndef __ardour_cycle_timer_h__ diff --git a/libs/ardour/ardour/cycles.h b/libs/ardour/ardour/cycles.h index a6f34d59be..f1422880b8 100644 --- a/libs/ardour/ardour/cycles.h +++ b/libs/ardour/ardour/cycles.h @@ -16,7 +16,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #ifndef __ardour_cycles_h__ diff --git a/libs/ardour/ardour/dB.h b/libs/ardour/ardour/dB.h index 703de6fb1a..b67e581067 100644 --- a/libs/ardour/ardour/dB.h +++ b/libs/ardour/ardour/dB.h @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #ifndef __ardour_dB_h__ diff --git a/libs/ardour/ardour/destructive_filesource.h b/libs/ardour/ardour/destructive_filesource.h deleted file mode 100644 index 2e6f5d0e57..0000000000 --- a/libs/ardour/ardour/destructive_filesource.h +++ /dev/null @@ -1,76 +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$ -*/ - -#ifndef __ardour_destructive_file_source_h__ -#define __ardour_destructive_file_source_h__ - -#include - -#include - -struct tm; - -namespace ARDOUR { - -class DestructiveFileSource : public SndFileSource { - public: - DestructiveFileSource (Session&, std::string path, SampleFormat samp_format, HeaderFormat hdr_format, nframes_t rate, - Flag flags = AudioFileSource::Flag (AudioFileSource::Writable)); - - DestructiveFileSource (Session&, std::string path, Flag flags); - - DestructiveFileSource (Session&, const XMLNode&); - ~DestructiveFileSource (); - - nframes_t last_capture_start_frame() const; - void mark_capture_start (nframes_t); - void mark_capture_end (); - void clear_capture_marks(); - - XMLNode& get_state (); - - static void setup_standard_crossfades (nframes_t sample_rate); - - int read_peaks (PeakData *peaks, nframes_t npeaks, nframes_t start, nframes_t cnt, double samples_per_unit) const; - - protected: - nframes_t write_unlocked (Sample *src, nframes_t cnt); - - virtual void handle_header_position_change (); - - private: - 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 - Sample* xfade_buf; - - void init (); - nframes_t crossfade (Sample* data, nframes_t cnt, int dir); - void set_timeline_position (int64_t); -}; - -} - -#endif /* __ardour_destructive_file_source_h__ */ diff --git a/libs/ardour/ardour/diskstream.h b/libs/ardour/ardour/diskstream.h index c56c411a82..79fec98d6e 100644 --- a/libs/ardour/ardour/diskstream.h +++ b/libs/ardour/ardour/diskstream.h @@ -15,7 +15,6 @@ 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_diskstream_h__ @@ -54,7 +53,7 @@ class Session; class Playlist; class IO; - class Diskstream : public PBD::StatefulDestructible +class Diskstream : public PBD::StatefulDestructible { public: enum Flag { @@ -200,7 +199,6 @@ class IO; /** For non-butler contexts (allocates temporary working buffers) */ virtual int do_refill_with_alloc() = 0; - /* XXX fix this redundancy ... */ @@ -208,7 +206,6 @@ class IO; virtual void playlist_modified (); virtual void playlist_deleted (boost::weak_ptr); - virtual void finish_capture (bool rec_monitors_input) = 0; virtual void transport_stopped (struct tm&, time_t, bool abort) = 0; struct CaptureInfo { @@ -237,7 +234,7 @@ class IO; virtual void use_destructive_playlist () = 0; static nframes_t disk_io_chunk_frames; - vector capture_info; + std::vector capture_info; Glib::Mutex capture_info_lock; uint32_t i_am_the_modifier; @@ -285,6 +282,7 @@ class IO; 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; diff --git a/libs/ardour/ardour/export.h b/libs/ardour/ardour/export.h index f66acec893..66e5b1b7d5 100644 --- a/libs/ardour/ardour/export.h +++ b/libs/ardour/ardour/export.h @@ -76,9 +76,9 @@ namespace ARDOUR /* shared between UI thread and audio thread */ - float progress; /* audio thread sets this */ - bool stop; /* UI sets this */ - bool running; /* audio thread sets to false when export is done */ + 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; diff --git a/libs/ardour/ardour/gain.h b/libs/ardour/ardour/gain.h index 3613ea1a5a..5832f71101 100644 --- a/libs/ardour/ardour/gain.h +++ b/libs/ardour/ardour/gain.h @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #ifndef __ardour_gain_h__ diff --git a/libs/ardour/ardour/gdither.h b/libs/ardour/ardour/gdither.h index 51343b13c4..67efcc3583 100644 --- a/libs/ardour/ardour/gdither.h +++ b/libs/ardour/ardour/gdither.h @@ -15,7 +15,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id$ */ #ifndef GDITHER_H diff --git a/libs/ardour/ardour/gdither_types.h b/libs/ardour/ardour/gdither_types.h index 46feb55fbc..bcc0097d7f 100644 --- a/libs/ardour/ardour/gdither_types.h +++ b/libs/ardour/ardour/gdither_types.h @@ -15,7 +15,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id$ */ #ifndef GDITHER_TYPES_H diff --git a/libs/ardour/ardour/gdither_types_internal.h b/libs/ardour/ardour/gdither_types_internal.h index 55d5792833..e73a256310 100644 --- a/libs/ardour/ardour/gdither_types_internal.h +++ b/libs/ardour/ardour/gdither_types_internal.h @@ -15,7 +15,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id$ */ #ifndef GDITHER_TYPES_H diff --git a/libs/ardour/ardour/insert.h b/libs/ardour/ardour/insert.h index 99b4e4b373..9d063ca54b 100644 --- a/libs/ardour/ardour/insert.h +++ b/libs/ardour/ardour/insert.h @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #ifndef __ardour_insert_h__ diff --git a/libs/ardour/ardour/io.h b/libs/ardour/ardour/io.h index 3dc2c84b4f..ab918345b1 100644 --- a/libs/ardour/ardour/io.h +++ b/libs/ardour/ardour/io.h @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #ifndef __ardour_io_h__ @@ -109,7 +108,8 @@ class IO : public PBD::StatefulDestructible virtual gain_t effective_gain () const; Panner& panner() { return *_panner; } - + const Panner& panner() const { return *_panner; } + int ensure_io (uint32_t, uint32_t, bool clear, void *src); int use_input_connection (Connection&, void *src); diff --git a/libs/ardour/ardour/ladspa_plugin.h b/libs/ardour/ardour/ladspa_plugin.h index aeac7f05c6..63f8f600d3 100644 --- a/libs/ardour/ardour/ladspa_plugin.h +++ b/libs/ardour/ardour/ladspa_plugin.h @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #ifndef __ardour_ladspa_plugin_h__ diff --git a/libs/ardour/ardour/location.h b/libs/ardour/ardour/location.h index 57e13de5af..6625b7dbf5 100644 --- a/libs/ardour/ardour/location.h +++ b/libs/ardour/ardour/location.h @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #ifndef __ardour_location_h__ @@ -159,11 +158,11 @@ class Locations : public PBD::StatefulDestructible int set_current (Location *, bool want_lock = true); Location *current () const { return current_location; } - Location *first_location_before (nframes_t); - Location *first_location_after (nframes_t); + 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); - nframes_t first_mark_after (nframes_t); + nframes_t first_mark_before (nframes_t, bool include_special_ranges = false); + nframes_t first_mark_after (nframes_t, bool include_special_ranges = false); sigc::signal current_changed; sigc::signal changed; diff --git a/libs/ardour/ardour/logcurve.h b/libs/ardour/ardour/logcurve.h index ac60a10fd7..dd58263313 100644 --- a/libs/ardour/ardour/logcurve.h +++ b/libs/ardour/ardour/logcurve.h @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #ifndef __ardour_logcurve_h__ diff --git a/libs/ardour/ardour/mix.h b/libs/ardour/ardour/mix.h index 653b61cb95..5555f5437e 100644 --- a/libs/ardour/ardour/mix.h +++ b/libs/ardour/ardour/mix.h @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #ifndef __ardour_mix_h__ #define __ardour_mix_h__ @@ -28,7 +27,7 @@ extern "C" { /* SSE functions */ - float x86_sse_compute_peak (ARDOUR::Sample *buf, nframes_t nsamples, float current); + float x86_sse_compute_peak (ARDOUR::Sample *buf, nframes_t nsamples, float current); void x86_sse_apply_gain_to_buffer (ARDOUR::Sample *buf, nframes_t nframes, float gain); @@ -37,9 +36,11 @@ extern "C" { void x86_sse_mix_buffers_no_gain (ARDOUR::Sample *dst, ARDOUR::Sample *src, nframes_t nframes); } +void x86_sse_find_peaks (ARDOUR::Sample *buf, nframes_t nsamples, float *min, float *max); + /* debug wrappers for SSE functions */ -float debug_compute_peak (ARDOUR::Sample *buf, nframes_t nsamples, float current); +float debug_compute_peak (ARDOUR::Sample *buf, nframes_t nsamples, float current); void debug_apply_gain_to_buffer (ARDOUR::Sample *buf, nframes_t nframes, float gain); @@ -53,6 +54,8 @@ void debug_mix_buffers_no_gain (ARDOUR::Sample *dst, ARDOUR::Sample *src, nfra float veclib_compute_peak (ARDOUR::Sample *buf, nframes_t nsamples, float current); +void veclib_find_peaks (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, ARDOUR::Sample *src, nframes_t nframes, float gain); @@ -63,12 +66,14 @@ void veclib_mix_buffers_no_gain (ARDOUR::Sample *dst, ARDOUR::Sample *src /* non-optimized functions */ -float compute_peak (ARDOUR::Sample *buf, nframes_t nsamples, float current); +float compute_peak (ARDOUR::Sample *buf, nframes_t nsamples, float current); + +void find_peaks (ARDOUR::Sample *buf, nframes_t nsamples, float *min, float *max); -void apply_gain_to_buffer (ARDOUR::Sample *buf, nframes_t nframes, float gain); +void apply_gain_to_buffer (ARDOUR::Sample *buf, nframes_t nframes, float gain); -void mix_buffers_with_gain (ARDOUR::Sample *dst, ARDOUR::Sample *src, nframes_t nframes, float gain); +void mix_buffers_with_gain (ARDOUR::Sample *dst, ARDOUR::Sample *src, nframes_t nframes, float gain); -void mix_buffers_no_gain (ARDOUR::Sample *dst, ARDOUR::Sample *src, nframes_t nframes); +void mix_buffers_no_gain (ARDOUR::Sample *dst, 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 index fd5777ccf6..7636099e1f 100644 --- a/libs/ardour/ardour/named_selection.h +++ b/libs/ardour/ardour/named_selection.h @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #ifndef __ardour_named_selection_h__ diff --git a/libs/ardour/ardour/osc.h b/libs/ardour/ardour/osc.h index 0a34f44a41..ca2f4488dd 100644 --- a/libs/ardour/ardour/osc.h +++ b/libs/ardour/ardour/osc.h @@ -15,7 +15,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - * $Id$ */ #ifndef ardour_osc_h diff --git a/libs/ardour/ardour/panner.h b/libs/ardour/ardour/panner.h index 32d512c253..a4a1d5d3b9 100644 --- a/libs/ardour/ardour/panner.h +++ b/libs/ardour/ardour/panner.h @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #ifndef __ardour_panner_h__ diff --git a/libs/ardour/ardour/pcm_utils.h b/libs/ardour/ardour/pcm_utils.h index 6866e53251..5e6436cc94 100644 --- a/libs/ardour/ardour/pcm_utils.h +++ b/libs/ardour/ardour/pcm_utils.h @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #ifndef __ardour_pcm_utils_h__ diff --git a/libs/ardour/ardour/playlist.h b/libs/ardour/ardour/playlist.h index 50282f3331..5f33719ae7 100644 --- a/libs/ardour/ardour/playlist.h +++ b/libs/ardour/ardour/playlist.h @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #ifndef __ardour_playlist_h__ @@ -139,6 +138,12 @@ class Playlist : public PBD::StatefulDestructible, public boost::enable_shared_f virtual bool destroy_region (boost::shared_ptr) = 0; + /* special case function used by UI selection objects, which have playlists that actually own the regions + within them. + */ + + void drop_regions (); + protected: friend class Session; @@ -177,6 +182,7 @@ class Playlist : public PBD::StatefulDestructible, public boost::enable_shared_f bool save_on_thaw; string last_save_reason; uint32_t in_set_state; + bool first_set_state; bool _hidden; bool _splicing; bool _nudging; diff --git a/libs/ardour/ardour/playlist_templates.h b/libs/ardour/ardour/playlist_templates.h index 603e0bef37..bf072a71c1 100644 --- a/libs/ardour/ardour/playlist_templates.h +++ b/libs/ardour/ardour/playlist_templates.h @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #ifndef __ardour_playlist_templates_h__ diff --git a/libs/ardour/ardour/plugin.h b/libs/ardour/ardour/plugin.h index 1521dd929d..c7708e3690 100644 --- a/libs/ardour/ardour/plugin.h +++ b/libs/ardour/ardour/plugin.h @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #ifndef __ardour_plugin_h__ diff --git a/libs/ardour/ardour/plugin_manager.h b/libs/ardour/ardour/plugin_manager.h index 8e6c0bd1c7..b4d2e5e99d 100644 --- a/libs/ardour/ardour/plugin_manager.h +++ b/libs/ardour/ardour/plugin_manager.h @@ -7,7 +7,6 @@ #include #include -#include namespace ARDOUR { diff --git a/libs/ardour/ardour/port.h b/libs/ardour/ardour/port.h index b6a8e6fd36..44e9dc00a8 100644 --- a/libs/ardour/ardour/port.h +++ b/libs/ardour/ardour/port.h @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #ifndef __ardour_port_h__ diff --git a/libs/ardour/ardour/profile.h b/libs/ardour/ardour/profile.h new file mode 100644 index 0000000000..2ee47d39ea --- /dev/null +++ b/libs/ardour/ardour/profile.h @@ -0,0 +1,31 @@ +#ifndef __ardour_profile_h__ +#define __ardour_profile_h__ + +#include +#include + +namespace ARDOUR { + +class RuntimeProfile { + public: + enum Element { + SmallScreen, + LastElement + }; + + RuntimeProfile() { bits.resize (LastElement); } + ~RuntimeProfile() {} + + void set_small_screen() { bits[SmallScreen] = true; } + bool get_small_screen() const { return bits[SmallScreen]; } + + private: + boost::dynamic_bitset bits; + +}; + +extern RuntimeProfile* Profile; + +}; // namespace ARDOUR + +#endif /* __ardour_profile_h__ */ diff --git a/libs/ardour/ardour/redirect.h b/libs/ardour/ardour/redirect.h index 83b389d72a..6dcc105370 100644 --- a/libs/ardour/ardour/redirect.h +++ b/libs/ardour/ardour/redirect.h @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #ifndef __ardour_redirect_h__ diff --git a/libs/ardour/ardour/region.h b/libs/ardour/ardour/region.h index f0262777f3..8ab99fa151 100644 --- a/libs/ardour/ardour/region.h +++ b/libs/ardour/ardour/region.h @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #ifndef __ardour_region_h__ diff --git a/libs/ardour/ardour/reverse.h b/libs/ardour/ardour/reverse.h index c60df990f2..3296c77c62 100644 --- a/libs/ardour/ardour/reverse.h +++ b/libs/ardour/ardour/reverse.h @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #ifndef __ardour_reverse_h__ diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h index 869d7eb239..442c006e9b 100644 --- a/libs/ardour/ardour/route.h +++ b/libs/ardour/ardour/route.h @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #ifndef __ardour_route_h__ @@ -78,8 +77,8 @@ class Route : public IO std::string comment() { return _comment; } void set_comment (std::string str, void *src); - long order_key(std::string name) const; - void set_order_key (std::string name, long n); + long order_key (const char* name) const; + void set_order_key (const char* name, long n); bool hidden() const { return _flags & Hidden; } bool master() const { return _flags & MasterOut; } @@ -121,6 +120,7 @@ class Route : public IO 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); @@ -169,9 +169,9 @@ class Route : public IO int copy_redirects (const Route&, Placement, uint32_t* err_streams = 0); int sort_redirects (uint32_t* err_streams = 0); - void clear_redirects (void *src); + void clear_redirects (Placement, void *src); void all_redirects_flip(); - void all_redirects_active (bool state); + void all_redirects_active (Placement, bool state); virtual nframes_t update_total_latency(); nframes_t signal_latency() const { return _own_latency; } @@ -256,7 +256,6 @@ class Route : public IO bool _muted : 1; bool _soloed : 1; - bool _solo_muted : 1; bool _solo_safe : 1; bool _phase_invert : 1; bool _recordable : 1; @@ -321,7 +320,16 @@ class Route : public IO void init (); static uint32_t order_key_cnt; - typedef std::map OrderKeys; + + struct ltstr + { + bool operator()(const char* s1, const char* s2) const + { + return strcmp(s1, s2) < 0; + } + }; + + typedef std::map OrderKeys; OrderKeys order_keys; void input_change_handler (IOChange, void *src); diff --git a/libs/ardour/ardour/route_group.h b/libs/ardour/ardour/route_group.h index d87d3fa3a4..55448df45b 100644 --- a/libs/ardour/ardour/route_group.h +++ b/libs/ardour/ardour/route_group.h @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #ifndef __ardour_route_group_h__ diff --git a/libs/ardour/ardour/send.h b/libs/ardour/ardour/send.h index 38c3d2a20a..7f88f0624f 100644 --- a/libs/ardour/ardour/send.h +++ b/libs/ardour/ardour/send.h @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #ifndef __ardour_send_h__ diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index 92687c7dc0..a14daa4485 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #ifndef __ardour_session_h__ @@ -165,7 +164,7 @@ class Session : public PBD::StatefulDestructible SlaveSource slave; }; - boost::shared_ptr region; + boost::shared_ptr region; list audio_range; list music_range; @@ -237,6 +236,7 @@ class Session : public PBD::StatefulDestructible string name() const { return _name; } string snap_name() const { return _current_snapshot_name; } string raid_path () const; + string export_dir () const; void set_snap_name (); @@ -333,7 +333,7 @@ class Session : public PBD::StatefulDestructible /* Record status signals */ - sigc::signal RecordStateChanged; + sigc::signal RecordStateChanged; /* Transport mechanism signals */ @@ -358,6 +358,7 @@ class Session : public PBD::StatefulDestructible 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); @@ -410,6 +411,8 @@ class Session : public PBD::StatefulDestructible 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); static int rename_template (string old_name, string new_name); @@ -475,6 +478,8 @@ class Session : public PBD::StatefulDestructible void resort_routes (); void resort_routes_using (boost::shared_ptr); + void set_remote_control_ids(); + AudioEngine &engine() { return _engine; }; int32_t max_level; @@ -573,13 +578,14 @@ class Session : public PBD::StatefulDestructible int start_audio_export (ARDOUR::AudioExportSpecification&); int stop_audio_export (ARDOUR::AudioExportSpecification&); - + void finalize_audio_export (); + void add_source (boost::shared_ptr); void remove_source (boost::weak_ptr); struct cleanup_report { vector paths; - int32_t space; + int64_t space; }; int cleanup_sources (cleanup_report&); @@ -606,6 +612,7 @@ class Session : public PBD::StatefulDestructible boost::shared_ptr create_audio_source_for_session (ARDOUR::AudioDiskstream&, uint32_t which_channel, bool destructive); boost::shared_ptr source_by_id (const PBD::ID&); + boost::shared_ptr source_by_path_and_channel (const Glib::ustring&, uint16_t); /* playlist management */ @@ -663,6 +670,7 @@ class Session : public PBD::StatefulDestructible void set_all_mute (bool); sigc::signal SoloActive; + sigc::signal SoloChanged; void record_disenable_all (); void record_enable_all (); @@ -720,6 +728,8 @@ class Session : public PBD::StatefulDestructible void deliver_midi (MIDI::Port*, MIDI::byte*, int32_t size); + void set_mmc_device_id (uint32_t id); + /* Scrubbing */ void start_scrub (nframes_t where); @@ -900,12 +910,14 @@ class Session : public PBD::StatefulDestructible void* ptr, float opt); - typedef float (*compute_peak_t) (Sample *, nframes_t, float); + 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 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; @@ -975,6 +987,7 @@ class Session : public PBD::StatefulDestructible 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; @@ -1263,8 +1276,7 @@ class Session : public PBD::StatefulDestructible 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_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 *); @@ -1561,7 +1573,9 @@ class Session : public PBD::StatefulDestructible static const char* dead_sound_dir_name; static const char* interchange_dir_name; static const char* peak_dir_name; - + static const char* export_dir_name; + + string old_sound_dir (bool with_path = true) const; string discover_best_sound_dir (bool destructive = false); int ensure_sound_dir (string, string&); void refresh_disk_space (); diff --git a/libs/ardour/ardour/session_connection.h b/libs/ardour/ardour/session_connection.h index addc896b0b..d5e32c7904 100644 --- a/libs/ardour/ardour/session_connection.h +++ b/libs/ardour/ardour/session_connection.h @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #ifndef __ardour_session_connection_h__ diff --git a/libs/ardour/ardour/session_playlist.h b/libs/ardour/ardour/session_playlist.h index 20cf4d8f2e..baeb74916d 100644 --- a/libs/ardour/ardour/session_playlist.h +++ b/libs/ardour/ardour/session_playlist.h @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #ifndef __ardour_session_playlist_h__ diff --git a/libs/ardour/ardour/session_route.h b/libs/ardour/ardour/session_route.h index feacc14775..0c70bf407d 100644 --- a/libs/ardour/ardour/session_route.h +++ b/libs/ardour/ardour/session_route.h @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #ifndef __ardour_session_route_h__ diff --git a/libs/ardour/ardour/session_selection.h b/libs/ardour/ardour/session_selection.h index a110c2c3da..4169a3a511 100644 --- a/libs/ardour/ardour/session_selection.h +++ b/libs/ardour/ardour/session_selection.h @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #ifndef __ardour_session_named_selection_h__ diff --git a/libs/ardour/ardour/silentfilesource.h b/libs/ardour/ardour/silentfilesource.h new file mode 100644 index 0000000000..92ef076a9b --- /dev/null +++ b/libs/ardour/ardour/silentfilesource.h @@ -0,0 +1,66 @@ +/* + 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 + +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); + + int read_peaks (PeakData *peaks, nframes_t npeaks, nframes_t start, nframes_t cnt, double samples_per_unit) const { + memset (peaks, 0, sizeof (PeakData) * npeaks); + return 0; + } + + bool destructive() 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 () {} + +}; + +} // namespace ARDOUR + +#endif /* __ardour_audiofilesource_h__ */ + diff --git a/libs/ardour/ardour/slave.h b/libs/ardour/ardour/slave.h index d4a7e2f22a..170facb1de 100644 --- a/libs/ardour/ardour/slave.h +++ b/libs/ardour/ardour/slave.h @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #ifndef __ardour_slave_h__ @@ -70,6 +69,7 @@ class MTC_Slave : public Slave, public sigc::trackable { Session& session; MIDI::Port* port; std::vector connections; + bool can_notify_on_unknown_rate; struct SafeTime { diff --git a/libs/ardour/ardour/sndfilesource.h b/libs/ardour/ardour/sndfilesource.h index a5000a4b63..916e9da49e 100644 --- a/libs/ardour/ardour/sndfilesource.h +++ b/libs/ardour/ardour/sndfilesource.h @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #ifndef __sndfile_source_h__ @@ -31,11 +30,11 @@ class SndFileSource : public AudioFileSource { public: /* constructor to be called for existing external-to-session files */ - SndFileSource (Session&, std::string path, int chn, Flag flags); + SndFileSource (Session&, Glib::ustring path, int chn, Flag flags); /* constructor to be called for new in-session files */ - SndFileSource (Session&, std::string path, SampleFormat samp_format, HeaderFormat hdr_format, nframes_t rate, + 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 */ @@ -57,10 +56,12 @@ class SndFileSource : public AudioFileSource { 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 (string path, SoundFileInfo& _info, string& error_msg); + static int get_soundfile_info (const Glib::ustring& path, SoundFileInfo& _info, string& error_msg); protected: void set_header_timeline_position (); diff --git a/libs/ardour/ardour/soundseq.h b/libs/ardour/ardour/soundseq.h index 4a318e9750..c7157428ee 100644 --- a/libs/ardour/ardour/soundseq.h +++ b/libs/ardour/ardour/soundseq.h @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #ifndef __soundseq_h__ diff --git a/libs/ardour/ardour/source.h b/libs/ardour/ardour/source.h index 91b856894d..7ffa616a40 100644 --- a/libs/ardour/ardour/source.h +++ b/libs/ardour/ardour/source.h @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #ifndef __ardour_source_h__ @@ -64,7 +63,9 @@ class Source : public PBD::StatefulDestructible string _name; time_t _timestamp; - std::set > _playlists; + Glib::Mutex playlist_lock; + typedef std::map, uint32_t > PlaylistMap; + PlaylistMap _playlists; private: uint32_t _in_use; diff --git a/libs/ardour/ardour/source_factory.h b/libs/ardour/ardour/source_factory.h index 207015a253..cc3863904a 100644 --- a/libs/ardour/ardour/source_factory.h +++ b/libs/ardour/ardour/source_factory.h @@ -20,6 +20,7 @@ class SourceFactory { static sigc::signal > SourceCreated; static boost::shared_ptr create (Session&, const XMLNode& node); + static boost::shared_ptr createSilent (Session&, const XMLNode& node, nframes_t nframes, float sample_rate); // MIDI sources will have to be hacked in here somehow static boost::shared_ptr createReadable (Session&, std::string path, int chn, AudioFileSource::Flag flags, bool announce = true); diff --git a/libs/ardour/ardour/tempo.h b/libs/ardour/ardour/tempo.h index f8751b5d2b..5e3e93e48b 100644 --- a/libs/ardour/ardour/tempo.h +++ b/libs/ardour/ardour/tempo.h @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #ifndef __ardour_tempo_h__ diff --git a/libs/ardour/ardour/types.h b/libs/ardour/ardour/types.h index 4fe8a54f71..05956336b6 100644 --- a/libs/ardour/ardour/types.h +++ b/libs/ardour/ardour/types.h @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #ifndef __ardour_types_h__ @@ -267,6 +266,12 @@ namespace ARDOUR { ExternalMonitoring, }; + enum RemoteModel { + UserOrdered, + MixerOrdered, + EditorOrdered, + }; + enum CrossfadeModel { FullCrossfade, ShortCrossfade @@ -349,6 +354,7 @@ 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); diff --git a/libs/ardour/ardour/utils.h b/libs/ardour/ardour/utils.h index de97a5c150..20badf5ea1 100644 --- a/libs/ardour/ardour/utils.h +++ b/libs/ardour/ardour/utils.h @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #ifndef __ardour_utils_h__ diff --git a/libs/ardour/ardour/vst_plugin.h b/libs/ardour/ardour/vst_plugin.h index e4c887ebc2..fb03a75bb8 100644 --- a/libs/ardour/ardour/vst_plugin.h +++ b/libs/ardour/ardour/vst_plugin.h @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #ifndef __ardour_vst_plugin_h__ diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc index 44d5c19ab1..48085d4922 100644 --- a/libs/ardour/audio_diskstream.cc +++ b/libs/ardour/audio_diskstream.cc @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -43,7 +44,6 @@ #include #include #include -#include #include #include #include @@ -66,6 +66,7 @@ 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 */ @@ -80,6 +81,7 @@ AudioDiskstream::AudioDiskstream (Session &sess, const string &name, Diskstream: AudioDiskstream::AudioDiskstream (Session& sess, const XMLNode& node) : Diskstream(sess, node) , deprecated_io_node(NULL) + , channels (new ChannelList) { in_set_state = true; init (Recordable); @@ -109,7 +111,7 @@ AudioDiskstream::init (Diskstream::Flag f) set_block_size (_session.get_block_size()); allocate_temporary_buffers (); - add_channel (); + add_channel (1); assert(_n_channels == 1); } @@ -118,16 +120,17 @@ AudioDiskstream::~AudioDiskstream () notify_callbacks (); { - /* don't be holding this lock as we exit the destructor, glib will wince - visibly since the mutex gets destroyed before we release it. - */ - - Glib::Mutex::Lock lm (state_lock); - for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) { - (*chan).release (); + RCUWriter writer (channels); + boost::shared_ptr c = writer.get_copy(); + + for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) { + delete *chan; } - channels.clear(); + + c->clear(); } + + channels.flush (); } void @@ -153,37 +156,26 @@ AudioDiskstream::free_working_buffers() void AudioDiskstream::non_realtime_input_change () { - { + { Glib::Mutex::Lock lm (state_lock); if (input_change_pending == NoChange) { return; } - if (input_change_pending & ConfigurationChanged) { - + { + RCUWriter writer (channels); + boost::shared_ptr c = writer.get_copy(); + + _n_channels = c->size(); + if (_io->n_inputs() > _n_channels) { - - // we need to add new channel infos - - int diff = _io->n_inputs() - channels.size(); - - for (int i = 0; i < diff; ++i) { - add_channel (); - } - - } else if (_io->n_inputs() < _n_channels) { - - // we need to get rid of channels - - int diff = channels.size() - _io->n_inputs(); - - for (int i = 0; i < diff; ++i) { - remove_channel (); - } + add_channel_to (c, _io->n_inputs() - _n_channels); + } else if (_io->n_inputs() < _n_channels) { + remove_channel_from (c, _n_channels - _io->n_inputs()); } - } - + } + get_input_sources (); set_capture_offset (); @@ -193,10 +185,12 @@ AudioDiskstream::non_realtime_input_change () } else { set_align_style_from_io (); } - + input_change_pending = NoChange; - } + /* implicit unlock */ + } + /* reset capture files */ reset_write_sources (false); @@ -213,23 +207,26 @@ AudioDiskstream::non_realtime_input_change () void AudioDiskstream::get_input_sources () { + boost::shared_ptr c = channels.reader(); + + uint32_t n; + ChannelList::iterator chan; uint32_t ni = _io->n_inputs(); - - for (uint32_t n = 0; n < ni; ++n) { + + for (n = 0, chan = c->begin(); chan != c->end() && n < ni; ++chan, ++n) { const char **connections = _io->input(n)->get_connections (); - ChannelInfo& chan = channels[n]; if (connections == 0 || connections[0] == 0) { - if (chan.source) { + if ((*chan)->source) { // _source->disable_metering (); } - chan.source = 0; + (*chan)->source = 0; } else { - chan.source = _session.engine().get_port_by_name (connections[0]); + (*chan)->source = _session.engine().get_port_by_name (connections[0]); } if (connections) { @@ -322,9 +319,10 @@ void AudioDiskstream::setup_destructive_playlist () { SourceList srcs; - - for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) { - srcs.push_back ((*chan).write_source); + boost::shared_ptr c = channels.reader(); + + for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) { + srcs.push_back ((*chan)->write_source); } /* a single full-sized region */ @@ -361,15 +359,16 @@ AudioDiskstream::use_destructive_playlist () uint32_t n; ChannelList::iterator chan; + boost::shared_ptr c = channels.reader(); - for (n = 0, chan = channels.begin(); chan != channels.end(); ++chan, ++n) { - (*chan).write_source = boost::dynamic_pointer_cast(region->source (n)); - assert((*chan).write_source); - (*chan).write_source->set_allow_remove_if_empty (false); + for (n = 0, chan = c->begin(); chan != c->end(); ++chan, ++n) { + (*chan)->write_source = boost::dynamic_pointer_cast(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); + (*chan)->write_source->set_destructive (true); } /* the source list will never be reset for a destructive track */ @@ -465,15 +464,16 @@ AudioDiskstream::check_record_status (nframes_t transport_frame, nframes_t nfram } if (_flags & Recordable) { - for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) { + boost::shared_ptr c = channels.reader(); + for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) { RingBufferNPT::rw_vector transvec; - (*chan).capture_transition_buf->get_write_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); + (*chan)->capture_transition_buf->increment_write_ptr(1); } else { // bad! @@ -503,7 +503,8 @@ int AudioDiskstream::process (nframes_t transport_frame, nframes_t nframes, nframes_t offset, bool can_record, bool rec_monitors_input) { uint32_t n; - ChannelList::iterator c; + boost::shared_ptr c = channels.reader(); + ChannelList::iterator chan; int ret = -1; nframes_t rec_offset = 0; nframes_t rec_nframes = 0; @@ -523,6 +524,8 @@ AudioDiskstream::process (nframes_t transport_frame, nframes_t nframes, nframes_ return 0; } + commit_should_unlock = false; + check_record_status (transport_frame, nframes, can_record); nominally_recording = (can_record && re); @@ -540,13 +543,13 @@ AudioDiskstream::process (nframes_t transport_frame, nframes_t nframes, nframes_ // If we can't take the state lock return. if (!state_lock.trylock()) { return 1; - } - + } + commit_should_unlock = true; adjust_capture_position = 0; - for (c = channels.begin(); c != channels.end(); ++c) { - (*c).current_capture_buffer = 0; - (*c).current_playback_buffer = 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())) { @@ -607,25 +610,25 @@ AudioDiskstream::process (nframes_t transport_frame, nframes_t nframes, nframes_ if (nominally_recording || rec_nframes) { - for (n = 0, c = channels.begin(); c != channels.end(); ++c, ++n) { + for (n = 0, chan = c->begin(); chan != c->end(); ++chan, ++n) { - ChannelInfo& chan (*c); - - chan.capture_buf->get_write_vector (&chan.capture_vector); + ChannelInfo* chaninfo (*chan); + + chaninfo->capture_buf->get_write_vector (&chaninfo->capture_vector); - if (rec_nframes <= chan.capture_vector.len[0]) { + if (rec_nframes <= chaninfo->capture_vector.len[0]) { - chan.current_capture_buffer = chan.capture_vector.buf[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 */ - memcpy (chan.current_capture_buffer, _io->input(n)->get_buffer (rec_nframes) + offset + rec_offset, sizeof (Sample) * rec_nframes); + memcpy (chaninfo->current_capture_buffer, _io->input(n)->get_buffer (rec_nframes) + offset + rec_offset, sizeof (Sample) * rec_nframes); } else { - nframes_t total = chan.capture_vector.len[0] + chan.capture_vector.len[1]; + nframes_t total = chaninfo->capture_vector.len[0] + chaninfo->capture_vector.len[1]; if (rec_nframes > total) { DiskOverrun (); @@ -633,21 +636,21 @@ AudioDiskstream::process (nframes_t transport_frame, nframes_t nframes, nframes_ } Sample* buf = _io->input (n)->get_buffer (nframes) + offset; - nframes_t first = chan.capture_vector.len[0]; + nframes_t first = chaninfo->capture_vector.len[0]; - memcpy (chan.capture_wrap_buffer, buf, sizeof (Sample) * first); - memcpy (chan.capture_vector.buf[0], buf, sizeof (Sample) * first); - memcpy (chan.capture_wrap_buffer+first, buf + first, sizeof (Sample) * (rec_nframes - first)); - memcpy (chan.capture_vector.buf[1], buf + first, sizeof (Sample) * (rec_nframes - first)); + 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)); - chan.current_capture_buffer = chan.capture_wrap_buffer; + chaninfo->current_capture_buffer = chaninfo->capture_wrap_buffer; } } } else { if (was_recording) { - finish_capture (rec_monitors_input); + finish_capture (rec_monitors_input, c); } } @@ -658,8 +661,8 @@ AudioDiskstream::process (nframes_t transport_frame, nframes_t nframes, nframes_ if (rec_nframes == nframes && rec_offset == 0) { - for (c = channels.begin(); c != channels.end(); ++c) { - (*c).current_playback_buffer = (*c).current_capture_buffer; + for (chan = c->begin(); chan != c->end(); ++chan) { + (*chan)->current_playback_buffer = (*chan)->current_capture_buffer; } playback_distance = nframes; @@ -681,8 +684,8 @@ AudioDiskstream::process (nframes_t transport_frame, nframes_t nframes, nframes_ /* can't do actual capture yet - waiting for latency effects to finish before we start*/ - for (c = channels.begin(); c != channels.end(); ++c) { - (*c).current_playback_buffer = (*c).current_capture_buffer; + for (chan = c->begin(); chan != c->end(); ++chan) { + (*chan)->current_playback_buffer = (*chan)->current_capture_buffer; } playback_distance = nframes; @@ -706,22 +709,22 @@ AudioDiskstream::process (nframes_t transport_frame, nframes_t nframes, nframes_ necessary_samples = nframes; } - for (c = channels.begin(); c != channels.end(); ++c) { - (*c).playback_buf->get_read_vector (&(*c).playback_vector); + for (chan = c->begin(); chan != c->end(); ++chan) { + (*chan)->playback_buf->get_read_vector (&(*chan)->playback_vector); } n = 0; - for (c = channels.begin(); c != channels.end(); ++c, ++n) { - - ChannelInfo& chan (*c); + for (chan = c->begin(); chan != c->end(); ++chan, ++n) { + + ChannelInfo* chaninfo (*chan); - if (necessary_samples <= chan.playback_vector.len[0]) { + if (necessary_samples <= chaninfo->playback_vector.len[0]) { - chan.current_playback_buffer = chan.playback_vector.buf[0]; + chaninfo->current_playback_buffer = chaninfo->playback_vector.buf[0]; } else { - nframes_t total = chan.playback_vector.len[0] + chan.playback_vector.len[1]; + nframes_t total = chaninfo->playback_vector.len[0] + chaninfo->playback_vector.len[1]; if (necessary_samples > total) { DiskUnderrun (); @@ -729,12 +732,12 @@ AudioDiskstream::process (nframes_t transport_frame, nframes_t nframes, nframes_ } else { - memcpy ((char *) chan.playback_wrap_buffer, chan.playback_vector.buf[0], - chan.playback_vector.len[0] * sizeof (Sample)); - memcpy (chan.playback_wrap_buffer + chan.playback_vector.len[0], chan.playback_vector.buf[1], - (necessary_samples - chan.playback_vector.len[0]) * sizeof (Sample)); + 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)); - chan.current_playback_buffer = chan.playback_wrap_buffer; + chaninfo->current_playback_buffer = chaninfo->playback_wrap_buffer; } } } @@ -747,10 +750,10 @@ AudioDiskstream::process (nframes_t transport_frame, nframes_t nframes, nframes_ // Linearly interpolate into the alt buffer // using 40.24 fixp maths (swh) - for (c = channels.begin(); c != channels.end(); ++c) { + for (chan = c->begin(); chan != c->end(); ++chan) { float fr; - ChannelInfo& chan (*c); + ChannelInfo* chaninfo (*chan); i = 0; phase = last_phase; @@ -758,13 +761,13 @@ AudioDiskstream::process (nframes_t transport_frame, nframes_t nframes, nframes_ for (nframes_t outsample = 0; outsample < nframes; ++outsample) { i = phase >> 24; fr = (phase & 0xFFFFFF) / 16777216.0f; - chan.speed_buffer[outsample] = - chan.current_playback_buffer[i] * (1.0f - fr) + - chan.current_playback_buffer[i+1] * fr; + chaninfo->speed_buffer[outsample] = + chaninfo->current_playback_buffer[i] * (1.0f - fr) + + chaninfo->current_playback_buffer[i+1] * fr; phase += phi; } - chan.current_playback_buffer = chan.speed_buffer; + chaninfo->current_playback_buffer = chaninfo->speed_buffer; } playback_distance = i + 1; @@ -787,6 +790,7 @@ AudioDiskstream::process (nframes_t transport_frame, nframes_t nframes, nframes_ be called. unlock the state lock. */ + commit_should_unlock = false; state_lock.unlock(); } @@ -804,12 +808,13 @@ AudioDiskstream::commit (nframes_t nframes) playback_sample += playback_distance; } - for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) { + boost::shared_ptr c = channels.reader(); + for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) { - (*chan).playback_buf->increment_read_ptr (playback_distance); + (*chan)->playback_buf->increment_read_ptr (playback_distance); if (adjust_capture_position) { - (*chan).capture_buf->increment_write_ptr (adjust_capture_position); + (*chan)->capture_buf->increment_write_ptr (adjust_capture_position); } } @@ -819,13 +824,15 @@ AudioDiskstream::commit (nframes_t nframes) } if (_slaved) { - need_butler = channels[0].playback_buf->write_space() >= channels[0].playback_buf->bufsize() / 2; + need_butler = c->front()->playback_buf->write_space() >= c->front()->playback_buf->bufsize() / 2; } else { - need_butler = channels[0].playback_buf->write_space() >= disk_io_chunk_frames - || channels[0].capture_buf->read_space() >= disk_io_chunk_frames; + need_butler = c->front()->playback_buf->write_space() >= disk_io_chunk_frames + || c->front()->capture_buf->read_space() >= disk_io_chunk_frames; } - state_lock.unlock(); + if (commit_should_unlock) { + state_lock.unlock(); + } _processed = false; @@ -840,12 +847,13 @@ AudioDiskstream::set_pending_overwrite (bool yn) pending_overwrite = yn; overwrite_frame = playback_sample; - overwrite_offset = channels.front().playback_buf->get_read_ptr(); + overwrite_offset = channels.reader()->front()->playback_buf->get_read_ptr(); } int AudioDiskstream::overwrite_existing_buffers () { + boost::shared_ptr c = channels.reader(); Sample* mixdown_buffer; float* gain_buffer; int ret = -1; @@ -854,7 +862,7 @@ AudioDiskstream::overwrite_existing_buffers () overwrite_queued = false; /* assume all are the same size */ - nframes_t size = channels[0].playback_buf->bufsize(); + nframes_t size = c->front()->playback_buf->bufsize(); mixdown_buffer = new Sample[size]; gain_buffer = new float[size]; @@ -865,7 +873,7 @@ AudioDiskstream::overwrite_existing_buffers () uint32_t n=0; nframes_t start; - for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan, ++n) { + for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan, ++n) { start = overwrite_frame; nframes_t cnt = size; @@ -883,7 +891,7 @@ AudioDiskstream::overwrite_existing_buffers () 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)) { + 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; @@ -893,7 +901,7 @@ AudioDiskstream::overwrite_existing_buffers () cnt -= to_read; - if (read ((*chan).playback_buf->buffer(), mixdown_buffer, gain_buffer, + 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; @@ -914,25 +922,27 @@ AudioDiskstream::overwrite_existing_buffers () int AudioDiskstream::seek (nframes_t frame, bool complete_refill) { - Glib::Mutex::Lock lm (state_lock); uint32_t n; int ret; ChannelList::iterator chan; + boost::shared_ptr c = channels.reader(); - for (n = 0, chan = channels.begin(); chan != channels.end(); ++chan, ++n) { - (*chan).playback_buf->reset (); - (*chan).capture_buf->reset (); + 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 { @@ -946,9 +956,10 @@ int AudioDiskstream::can_internal_playback_seek (nframes_t distance) { ChannelList::iterator chan; + boost::shared_ptr c = channels.reader(); - for (chan = channels.begin(); chan != channels.end(); ++chan) { - if ((*chan).playback_buf->read_space() < distance) { + for (chan = c->begin(); chan != c->end(); ++chan) { + if ((*chan)->playback_buf->read_space() < distance) { return false; } } @@ -959,9 +970,10 @@ int AudioDiskstream::internal_playback_seek (nframes_t distance) { ChannelList::iterator chan; + boost::shared_ptr c = channels.reader(); - for (chan = channels.begin(); chan != channels.end(); ++chan) { - (*chan).playback_buf->increment_read_ptr (distance); + for (chan = c->begin(); chan != c->end(); ++chan) { + (*chan)->playback_buf->increment_read_ptr (distance); } first_recordable_frame += distance; @@ -972,7 +984,7 @@ AudioDiskstream::internal_playback_seek (nframes_t distance) int AudioDiskstream::read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer, nframes_t& start, nframes_t cnt, - ChannelInfo& channel_info, int channel, bool reversed) + ChannelInfo* channel_info, int channel, bool reversed) { nframes_t this_read = 0; bool reloop = false; @@ -982,7 +994,10 @@ AudioDiskstream::read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer, 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 @@ -1006,11 +1021,16 @@ AudioDiskstream::read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer, 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)) { @@ -1038,9 +1058,6 @@ AudioDiskstream::read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer, if (reversed) { - /* don't adjust start, since caller has already done that - */ - swap_by_ptr (buf, buf + this_read - 1); } else { @@ -1062,7 +1079,7 @@ AudioDiskstream::read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer, } int -AudioDiskstream::do_refill_with_alloc() +AudioDiskstream::do_refill_with_alloc () { Sample* mix_buf = new Sample[disk_io_chunk_frames]; float* gain_buf = new float[disk_io_chunk_frames]; @@ -1086,17 +1103,27 @@ AudioDiskstream::_do_refill (Sample* mixdown_buffer, float* gain_buffer) nframes_t zero_fill; uint32_t chan_n; ChannelList::iterator i; + boost::shared_ptr c = channels.reader(); nframes_t ts; + if (c->empty()) { + return 0; + } + assert(mixdown_buffer); assert(gain_buffer); - channels.front().playback_buf->get_write_vector (&vector); + 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. @@ -1122,10 +1149,12 @@ AudioDiskstream::_do_refill (Sample* mixdown_buffer, float* gain_buffer) work with. */ - if (_slaved && total_space < (channels.front().playback_buf->bufsize() / 2)) { + 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) { @@ -1134,15 +1163,15 @@ AudioDiskstream::_do_refill (Sample* mixdown_buffer, float* gain_buffer) /* at start: nothing to do but fill with silence */ - for (chan_n = 0, i = channels.begin(); i != channels.end(); ++i, ++chan_n) { + for (chan_n = 0, i = c->begin(); i != c->end(); ++i, ++chan_n) { - ChannelInfo& chan (*i); - chan.playback_buf->get_write_vector (&vector); + 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]); + chan->playback_buf->increment_write_ptr (vector.len[0] + vector.len[1]); } return 0; } @@ -1159,11 +1188,6 @@ AudioDiskstream::_do_refill (Sample* mixdown_buffer, float* gain_buffer) } else { - /* move read position backwards because we are going - to reverse the data. - */ - - file_frame -= total_space; zero_fill = 0; } @@ -1173,15 +1197,15 @@ AudioDiskstream::_do_refill (Sample* mixdown_buffer, float* gain_buffer) /* at end: nothing to do but fill with silence */ - for (chan_n = 0, i = channels.begin(); i != channels.end(); ++i, ++chan_n) { + for (chan_n = 0, i = c->begin(); i != c->end(); ++i, ++chan_n) { - ChannelInfo& chan (*i); - chan.playback_buf->get_write_vector (&vector); + 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]); + chan->playback_buf->increment_write_ptr (vector.len[0] + vector.len[1]); } return 0; } @@ -1200,30 +1224,45 @@ AudioDiskstream::_do_refill (Sample* mixdown_buffer, float* gain_buffer) nframes_t file_frame_tmp = 0; - for (chan_n = 0, i = channels.begin(); i != channels.end(); ++i, ++chan_n) { + for (chan_n = 0, i = c->begin(); i != c->end(); ++i, ++chan_n) { - ChannelInfo& chan (*i); + ChannelInfo* chan (*i); Sample* buf1; Sample* buf2; nframes_t len1, len2; - chan.playback_buf->get_write_vector (&vector); + 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; - if (reversed) { - buf1 = vector.buf[1]; - len1 = vector.len[1]; - buf2 = vector.buf[0]; - len2 = vector.len[0]; - } else { - buf1 = vector.buf[0]; - len1 = vector.len[0]; - buf2 = vector.buf[1]; - len2 = vector.len[1]; - } - + 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); @@ -1234,8 +1273,8 @@ AudioDiskstream::_do_refill (Sample* mixdown_buffer, float* gain_buffer) ret = -1; goto out; } - - chan.playback_buf->increment_write_ptr (to_read); + + chan->playback_buf->increment_write_ptr (to_read); ts -= to_read; } @@ -1243,7 +1282,6 @@ AudioDiskstream::_do_refill (Sample* mixdown_buffer, float* gain_buffer) 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. */ @@ -1253,7 +1291,7 @@ AudioDiskstream::_do_refill (Sample* mixdown_buffer, float* gain_buffer) goto out; } - chan.playback_buf->increment_write_ptr (to_read); + chan->playback_buf->increment_write_ptr (to_read); } if (zero_fill) { @@ -1290,13 +1328,18 @@ AudioDiskstream::do_flush (Session::RunContext context, bool force_flush) _write_data_count = 0; - for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) { + transvec.buf[0] = 0; + transvec.buf[1] = 0; + vector.buf[0] = 0; + vector.buf[1] = 0; + + boost::shared_ptr c = channels.reader(); + for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) { - (*chan).capture_buf->get_read_vector (&vector); + (*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; } @@ -1322,7 +1365,7 @@ AudioDiskstream::do_flush (Session::RunContext context, bool force_flush) // important that we get this after the capture buf if (destructive()) { - (*chan).capture_transition_buf->get_read_vector(&transvec); + (*chan)->capture_transition_buf->get_read_vector(&transvec); size_t transcount = transvec.len[0] + transvec.len[1]; bool have_start = false; size_t ti; @@ -1333,8 +1376,8 @@ AudioDiskstream::do_flush (Session::RunContext context, bool force_flush) 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; + (*chan)->write_source->mark_capture_start (captrans.capture_val); + (*chan)->curr_capture_cnt = 0; have_start = true; } @@ -1342,17 +1385,17 @@ AudioDiskstream::do_flush (Session::RunContext context, bool force_flush) // capture end, the capture_val represents total frames in capture - if (captrans.capture_val <= (*chan).curr_capture_cnt + to_write) { + 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); + 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 (); + (*chan)->write_source->mark_capture_end (); // increment past this transition, but go no further ++ti; @@ -1367,17 +1410,17 @@ AudioDiskstream::do_flush (Session::RunContext context, bool force_flush) } if (ti > 0) { - (*chan).capture_transition_buf->increment_read_ptr(ti); + (*chan)->capture_transition_buf->increment_read_ptr(ti); } } - if ((!(*chan).write_source) || (*chan).write_source->write (vector.buf[0], to_write) != to_write) { + 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; + (*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()) { @@ -1385,18 +1428,18 @@ AudioDiskstream::do_flush (Session::RunContext context, bool force_flush) 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) { + + 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(); + _write_data_count += (*chan)->write_source->write_data_count(); - (*chan).capture_buf->increment_read_ptr (to_write); - (*chan).curr_capture_cnt += to_write; + (*chan)->capture_buf->increment_read_ptr (to_write); + (*chan)->curr_capture_cnt += to_write; } } @@ -1416,10 +1459,11 @@ AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_ca SourceList::iterator src; ChannelList::iterator chan; vector::iterator ci; + boost::shared_ptr c = channels.reader(); uint32_t n = 0; bool mark_write_completed = false; - finish_capture (true); + finish_capture (true, c); /* butler is already stopped, but there may be work to do to flush remaining data to disk. @@ -1451,13 +1495,13 @@ AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_ca goto outout; } - for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) { + for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) { - if ((*chan).write_source) { + if ((*chan)->write_source) { - (*chan).write_source->mark_for_remove (); - (*chan).write_source->drop_references (); - (*chan).write_source.reset (); + (*chan)->write_source->mark_for_remove (); + (*chan)->write_source->drop_references (); + (*chan)->write_source.reset (); } /* new source set up in "out" below */ @@ -1472,15 +1516,15 @@ AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_ca /* figure out the name for this take */ - for (n = 0, chan = channels.begin(); chan != channels.end(); ++chan, ++n) { + for (n = 0, chan = c->begin(); chan != c->end(); ++chan, ++n) { - boost::shared_ptr s = (*chan).write_source; + boost::shared_ptr 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 (); } } @@ -1499,7 +1543,7 @@ AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_ca } else { string whole_file_region_name; - whole_file_region_name = region_name_from_path (channels[0].write_source->name(), true); + 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 @@ -1508,7 +1552,7 @@ AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_ca */ try { - boost::shared_ptr rx (RegionFactory::create (srcs, channels[0].write_source->last_capture_start_frame(), total_capture, + boost::shared_ptr 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))); @@ -1529,7 +1573,7 @@ AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_ca XMLNode &before = _playlist->get_state(); _playlist->freeze (); - for (buffer_position = channels[0].write_source->last_capture_start_frame(), ci = capture_info.begin(); ci != capture_info.end(); ++ci) { + for (buffer_position = c->front()->write_source->last_capture_start_frame(), ci = capture_info.begin(); ci != capture_info.end(); ++ci) { string region_name; @@ -1579,7 +1623,7 @@ AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_ca } void -AudioDiskstream::finish_capture (bool rec_monitors_input) +AudioDiskstream::finish_capture (bool rec_monitors_input, boost::shared_ptr c) { was_recording = false; @@ -1588,16 +1632,16 @@ AudioDiskstream::finish_capture (bool rec_monitors_input) } if (recordable() && destructive()) { - for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) { + for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) { RingBufferNPT::rw_vector transvec; - (*chan).capture_transition_buf->get_write_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); + (*chan)->capture_transition_buf->increment_write_ptr(1); } else { // bad! @@ -1640,7 +1684,7 @@ AudioDiskstream::set_record_enabled (bool yn) return; } - if (yn && channels[0].source == 0) { + if (yn && channels.reader()->front()->source == 0) { /* pick up connections not initiated *from* the IO object we're associated with. @@ -1665,20 +1709,24 @@ AudioDiskstream::set_record_enabled (bool yn) void AudioDiskstream::engage_record_enable () { - bool rolling = _session.transport_speed() != 0.0f; + bool rolling = _session.transport_speed() != 0.0f; + boost::shared_ptr c = channels.reader(); g_atomic_int_set (&_record_enabled, 1); capturing_sources.clear (); + if (Config->get_monitoring_model() == HardwareMonitoring) { - for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) { - if ((*chan).source) { - (*chan).source->ensure_monitor_input (!(Config->get_auto_input() && rolling)); + + 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); + capturing_sources.push_back ((*chan)->write_source); } + } else { - for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) { - capturing_sources.push_back ((*chan).write_source); + for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) { + capturing_sources.push_back ((*chan)->write_source); } } @@ -1689,17 +1737,17 @@ void AudioDiskstream::disengage_record_enable () { g_atomic_int_set (&_record_enabled, 0); - if (Config->get_monitoring_model() == HardwareMonitoring) { - for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) { - if ((*chan).source) { - (*chan).source->ensure_monitor_input (false); + boost::shared_ptr c = channels.reader(); + for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) { + if (Config->get_monitoring_model() == HardwareMonitoring) { + if ((*chan)->source) { + (*chan)->source->ensure_monitor_input (false); } } } capturing_sources.clear (); RecordEnableChanged (); /* EMIT SIGNAL */ } - XMLNode& AudioDiskstream::get_state () @@ -1707,10 +1755,11 @@ AudioDiskstream::get_state () XMLNode* node = new XMLNode ("AudioDiskstream"); char buf[64] = ""; LocaleGuard lg (X_("POSIX")); + boost::shared_ptr c = channels.reader(); node->add_property ("flags", enum_2_string (_flags)); - snprintf (buf, sizeof(buf), "%zd", channels.size()); + snprintf (buf, sizeof(buf), "%zd", c->size()); node->add_property ("channels", buf); node->add_property ("playlist", _playlist->name()); @@ -1805,27 +1854,15 @@ AudioDiskstream::set_state (const XMLNode& node) // create necessary extra channels // we are always constructed with one and we always need one + _n_channels = channels.reader()->size(); + if (nchans > _n_channels) { - // we need to add new channel infos - //LockMonitor lm (state_lock, __LINE__, __FILE__); - - int diff = nchans - channels.size(); - - for (int i=0; i < diff; ++i) { - add_channel (); - } + add_channel (nchans - _n_channels); } else if (nchans < _n_channels) { - // we need to get rid of channels - //LockMonitor lm (state_lock, __LINE__, __FILE__); - - int diff = channels.size() - nchans; - - for (int i = 0; i < diff; ++i) { - remove_channel (); - } + remove_channel (_n_channels - nchans); } if ((prop = node.property ("playlist")) == 0) { @@ -1861,8 +1898,6 @@ AudioDiskstream::set_state (const XMLNode& node) } } - _n_channels = channels.size(); - in_set_state = false; /* make sure this is clear before we do anything else */ @@ -1881,37 +1916,40 @@ AudioDiskstream::set_state (const XMLNode& node) int AudioDiskstream::use_new_write_source (uint32_t n) { + boost::shared_ptr c = channels.reader(); + if (!recordable()) { return 1; } - if (n >= channels.size()) { + if (n >= c->size()) { error << string_compose (_("AudioDiskstream: channel %1 out of range"), n) << endmsg; return -1; } - ChannelInfo &chan = channels[n]; + ChannelInfo* chan = (*c)[n]; - if (chan.write_source) { - chan.write_source->set_allow_remove_if_empty (true); - chan.write_source.reset (); + 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) { + 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 (); + 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()); + chan->write_source->set_allow_remove_if_empty (!destructive()); return 0; } @@ -1920,6 +1958,7 @@ void AudioDiskstream::reset_write_sources (bool mark_write_complete, bool force) { ChannelList::iterator chan; + boost::shared_ptr c = channels.reader(); uint32_t n; if (!recordable()) { @@ -1928,20 +1967,20 @@ AudioDiskstream::reset_write_sources (bool mark_write_complete, bool force) capturing_sources.clear (); - for (chan = channels.begin(), n = 0; chan != channels.end(); ++chan, ++n) { + 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 (); + 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); + capturing_sources.push_back ((*chan)->write_source); } } else { - if ((*chan).write_source == 0) { + if ((*chan)->write_source == 0) { use_new_write_source (n); } } @@ -1963,11 +2002,12 @@ int AudioDiskstream::rename_write_sources () { ChannelList::iterator chan; + boost::shared_ptr c = channels.reader(); uint32_t n; - for (chan = channels.begin(), n = 0; chan != channels.end(); ++chan, ++n) { - if ((*chan).write_source != 0) { - (*chan).write_source->set_name (_name, destructive()); + for (chan = c->begin(), n = 0; chan != c->end(); ++chan, ++n) { + if ((*chan)->write_source != 0) { + (*chan)->write_source->set_name (_name, destructive()); /* XXX what to do if one of them fails ? */ } } @@ -1980,10 +2020,11 @@ 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 c = channels.reader(); - for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) { - if ((*chan).speed_buffer) delete [] (*chan).speed_buffer; - (*chan).speed_buffer = new Sample[speed_buffer_size]; + 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 (); @@ -2002,11 +2043,13 @@ AudioDiskstream::allocate_temporary_buffers () if (required_wrap_size > wrap_buffer_size) { - for (ChannelList::iterator chan = channels.begin(); chan != channels.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]; + boost::shared_ptr 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; @@ -2016,10 +2059,12 @@ AudioDiskstream::allocate_temporary_buffers () void AudioDiskstream::monitor_input (bool yn) { - for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) { + boost::shared_ptr c = channels.reader(); + + for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) { - if ((*chan).source) { - (*chan).source->ensure_monitor_input (yn); + if ((*chan)->source) { + (*chan)->source->ensure_monitor_input (yn); } } } @@ -2035,8 +2080,10 @@ AudioDiskstream::set_align_style_from_io () get_input_sources (); - for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) { - if ((*chan).source && (*chan).source->flags() & JackPortIsPhysical) { + boost::shared_ptr c = channels.reader(); + + for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) { + if ((*chan)->source && (*chan)->source->flags() & JackPortIsPhysical) { have_physical = true; break; } @@ -2050,55 +2097,64 @@ AudioDiskstream::set_align_style_from_io () } int -AudioDiskstream::add_channel () +AudioDiskstream::add_channel_to (boost::shared_ptr c, uint32_t how_many) { - /* XXX need to take lock??? */ + while (how_many--) { + c->push_back (new ChannelInfo(_session.diskstream_buffer_size(), speed_buffer_size, wrap_buffer_size)); + } - /* this copies the ChannelInfo, which currently has no buffers. kind - of pointless really, but we want the channels list to contain - actual objects, not pointers to objects. mostly for convenience, - which isn't much in evidence. - */ + _n_channels = c->size(); - channels.push_back (ChannelInfo()); + return 0; +} - /* now allocate the buffers */ +int +AudioDiskstream::add_channel (uint32_t how_many) +{ + RCUWriter writer (channels); + boost::shared_ptr c = writer.get_copy(); - channels.back().init (_session.diskstream_buffer_size(), - speed_buffer_size, - wrap_buffer_size); + return add_channel_to (c, how_many); +} - _n_channels = channels.size(); +int +AudioDiskstream::remove_channel_from (boost::shared_ptr c, uint32_t how_many) +{ + while (--how_many && !c->empty()) { + delete c->back(); + c->pop_back(); + } + + _n_channels = c->size(); return 0; } int -AudioDiskstream::remove_channel () +AudioDiskstream::remove_channel (uint32_t how_many) { - if (channels.size() > 1) { - /* XXX need to take lock??? */ - channels.back().release (); - channels.pop_back(); - _n_channels = channels.size(); - return 0; - } - - return -1; + RCUWriter writer (channels); + boost::shared_ptr c = writer.get_copy(); + + return remove_channel_from (c, how_many); } float AudioDiskstream::playback_buffer_load () const { - return (float) ((double) channels.front().playback_buf->read_space()/ - (double) channels.front().playback_buf->bufsize()); + boost::shared_ptr c = channels.reader(); + + return (float) ((double) c->front()->playback_buf->read_space()/ + (double) c->front()->playback_buf->bufsize()); } float AudioDiskstream::capture_buffer_load () const { - return (float) ((double) channels.front().capture_buf->write_space()/ - (double) channels.front().capture_buf->bufsize()); + boost::shared_ptr c = channels.reader(); + + return (float) ((double) c->front()->capture_buf->write_space()/ + (double) c->front()->capture_buf->bufsize()); } int @@ -2260,24 +2316,14 @@ AudioDiskstream::can_become_destructive (bool& requires_bounce) const return true; } -AudioDiskstream::ChannelInfo::ChannelInfo () +AudioDiskstream::ChannelInfo::ChannelInfo (nframes_t bufsize, nframes_t speed_size, nframes_t wrap_size) { - playback_wrap_buffer = 0; - capture_wrap_buffer = 0; - speed_buffer = 0; peak_power = 0.0f; source = 0; current_capture_buffer = 0; current_playback_buffer = 0; curr_capture_cnt = 0; - playback_buf = 0; - capture_buf = 0; - capture_transition_buf = 0; -} -void -AudioDiskstream::ChannelInfo::init (nframes_t bufsize, nframes_t speed_size, nframes_t wrap_size) -{ speed_buffer = new Sample[speed_size]; playback_wrap_buffer = new Sample[wrap_size]; capture_wrap_buffer = new Sample[wrap_size]; @@ -2298,11 +2344,6 @@ AudioDiskstream::ChannelInfo::init (nframes_t bufsize, nframes_t speed_size, nfr } AudioDiskstream::ChannelInfo::~ChannelInfo () -{ -} - -void -AudioDiskstream::ChannelInfo::release () { if (write_source) { write_source.reset (); diff --git a/libs/ardour/audio_playlist.cc b/libs/ardour/audio_playlist.cc index eefbeb7889..501482c840 100644 --- a/libs/ardour/audio_playlist.cc +++ b/libs/ardour/audio_playlist.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include @@ -383,7 +382,7 @@ AudioPlaylist::check_dependents (boost::shared_ptr r, bool norefresh) OverlapType c = top->coverage (bottom->position(), bottom->last_frame()); - + try { switch (c) { case OverlapNone: diff --git a/libs/ardour/audio_track.cc b/libs/ardour/audio_track.cc index e7b1368fa4..7c25a8c899 100644 --- a/libs/ardour/audio_track.cc +++ b/libs/ardour/audio_track.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include @@ -61,6 +60,7 @@ AudioTrack::AudioTrack (Session& sess, string name, Route::Flag flag, TrackMode } boost::shared_ptr ds (new AudioDiskstream (_session, name, dflags)); + _session.add_diskstream (ds); set_diskstream (boost::dynamic_pointer_cast (ds), this); @@ -276,14 +276,7 @@ AudioTrack::_set_state (const XMLNode& node, bool call_base) for (niter = nlist.begin(); niter != nlist.end(); ++niter){ child = *niter; - 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); - } - - } else if (child->name() == X_("recenable")) { + if (child->name() == X_("recenable")) { _rec_enable_control.set_state (*child); _session.add_controllable (&_rec_enable_control); } @@ -329,11 +322,6 @@ AudioTrack::state(bool full_state) align_node->add_property (X_("style"), enum_2_string (as)); root.add_child_nocopy (*align_node); - 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); - root.add_child_nocopy (*remote_control_node); - root.add_property (X_("mode"), enum_2_string (_mode)); /* we don't return diskstream state because we don't diff --git a/libs/ardour/audioengine.cc b/libs/ardour/audioengine.cc index 35a47c927b..51251e1cba 100644 --- a/libs/ardour/audioengine.cc +++ b/libs/ardour/audioengine.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include @@ -226,9 +225,9 @@ AudioEngine::jack_sync_callback (jack_transport_state_t state, jack_position_t* { if (_jack && session) { return session->jack_sync_callback (state, pos); - } else { - return true; } + + return true; } int @@ -965,10 +964,6 @@ AudioEngine::freewheel (bool onoff) _freewheel_thread_registered = false; } - if (!onoff) { - stacktrace (cout); - } - return jack_set_freewheel (_jack, onoff); } else { diff --git a/libs/ardour/audiofilesource.cc b/libs/ardour/audiofilesource.cc index b74f6b370f..b9aa977e0a 100644 --- a/libs/ardour/audiofilesource.cc +++ b/libs/ardour/audiofilesource.cc @@ -29,11 +29,13 @@ #include #include #include +#include #include #include #include +#include #include #include @@ -53,9 +55,10 @@ using namespace ARDOUR; using namespace PBD; +using namespace Glib; -string AudioFileSource::peak_dir = ""; -string AudioFileSource::search_path; +ustring AudioFileSource::peak_dir = ""; +ustring AudioFileSource::search_path; sigc::signal AudioFileSource::HeaderPositionOffsetChanged; uint64_t AudioFileSource::header_position_offset = 0; @@ -63,9 +66,9 @@ uint64_t AudioFileSource::header_position_offset = 0; /* XXX maybe this too */ char AudioFileSource::bwf_serial_number[13] = "000000000000"; -AudioFileSource::AudioFileSource (Session& s, string path, Flag flags) +AudioFileSource::AudioFileSource (Session& s, ustring path, Flag flags) : AudioSource (s, path), _flags (flags), - channel (0) + _channel (0) { /* constructor used for existing external to session files. file must exist already */ _is_embedded = AudioFileSource::determine_embeddedness (path); @@ -76,9 +79,9 @@ AudioFileSource::AudioFileSource (Session& s, string path, Flag flags) } -AudioFileSource::AudioFileSource (Session& s, std::string path, Flag flags, SampleFormat samp_format, HeaderFormat hdr_format) +AudioFileSource::AudioFileSource (Session& s, ustring path, Flag flags, SampleFormat samp_format, HeaderFormat hdr_format) : AudioSource (s, path), _flags (flags), - channel (0) + _channel (0) { /* constructor used for new internal-to-session files. file cannot exist */ _is_embedded = false; @@ -88,17 +91,19 @@ AudioFileSource::AudioFileSource (Session& s, std::string path, Flag flags, Samp } } -AudioFileSource::AudioFileSource (Session& s, const XMLNode& node) +AudioFileSource::AudioFileSource (Session& s, const XMLNode& node, bool must_exist) : AudioSource (s, node), _flags (Flag (Writable|CanRename)) - /* channel is set in set_state() */ + /* _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 (_name, true)) { + if (init (foo, must_exist)) { throw failed_constructor (); } } @@ -112,7 +117,7 @@ AudioFileSource::~AudioFileSource () } bool -AudioFileSource::determine_embeddedness (std::string path) +AudioFileSource::determine_embeddedness (ustring path) { return (path.find("/") == 0); } @@ -124,18 +129,17 @@ AudioFileSource::removable () const } int -AudioFileSource::init (string pathstr, bool must_exist) +AudioFileSource::init (ustring pathstr, bool must_exist) { bool is_new = false; _length = 0; timeline_position = 0; - next_peak_clear_should_notify = false; _peaks_built = false; file_is_new = false; - if (!find (pathstr, must_exist, is_new)) { - return -1; + if (!find (pathstr, must_exist, is_new, _channel)) { + throw non_existent_source (); } if (is_new && must_exist) { @@ -146,40 +150,40 @@ AudioFileSource::init (string pathstr, bool must_exist) } -string -AudioFileSource::peak_path (string audio_path) +ustring +AudioFileSource::peak_path (ustring audio_path) { return _session.peak_path_from_audio_path (audio_path); } -string -AudioFileSource::old_peak_path (string audio_path) +ustring +AudioFileSource::old_peak_path (ustring audio_path) { /* XXX hardly bombproof! fix me */ struct stat stat_file; struct stat stat_mount; - string mp = mountpoint (audio_path); + 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); + 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); + snprintf (buf, sizeof (buf), "%ld-%ld-%d.peak", stat_mount.st_ino, stat_file.st_ino, _channel); #endif - string res = peak_dir; + ustring res = peak_dir; res += buf; return res; } bool -AudioFileSource::get_soundfile_info (string path, SoundFileInfo& _info, string& error_msg) +AudioFileSource::get_soundfile_info (ustring path, SoundFileInfo& _info, string& error_msg) { #ifdef HAVE_COREAUDIO if (CoreAudioSource::get_soundfile_info (path, _info, error_msg) == 0) { @@ -200,7 +204,7 @@ AudioFileSource::get_state () XMLNode& root (AudioSource::get_state()); char buf[32]; root.add_property (X_("flags"), enum_2_string (_flags)); - snprintf (buf, sizeof (buf), "%d", channel); + snprintf (buf, sizeof (buf), "%u", _channel); root.add_property (X_("channel"), buf); return root; } @@ -222,9 +226,9 @@ AudioFileSource::set_state (const XMLNode& node) } if ((prop = node.property (X_("channel"))) != 0) { - channel = atoi (prop->value()); + _channel = atoi (prop->value()); } else { - channel = 0; + _channel = 0; } if ((prop = node.property (X_("name"))) != 0) { @@ -244,7 +248,10 @@ AudioFileSource::set_state (const XMLNode& node) void AudioFileSource::mark_for_remove () { - if (!writable()) { + // 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; } @@ -260,16 +267,13 @@ AudioFileSource::mark_streaming_write_completed () Glib::Mutex::Lock lm (_lock); - next_peak_clear_should_notify = true; - - if (_peaks_built || pending_peak_builds.empty()) { - _peaks_built = true; + if (_peaks_built) { PeaksReady (); /* EMIT SIGNAL */ } } void -AudioFileSource::mark_take (string id) +AudioFileSource::mark_take (ustring id) { if (writable()) { _take_id = id; @@ -277,14 +281,14 @@ AudioFileSource::mark_take (string id) } int -AudioFileSource::move_to_trash (const string trash_dir_name) +AudioFileSource::move_to_trash (const ustring& trash_dir_name) { if (is_embedded()) { cerr << "tried to move an embedded region to trash" << endl; return -1; } - string newpath; + ustring newpath; if (!writable()) { return -1; @@ -311,7 +315,7 @@ AudioFileSource::move_to_trash (const string trash_dir_name) char buf[PATH_MAX+1]; int version = 1; - string newpath_v; + ustring newpath_v; snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version); newpath_v = buf; @@ -362,29 +366,21 @@ AudioFileSource::move_to_trash (const string trash_dir_name) } bool -AudioFileSource::find (string pathstr, bool must_exist, bool& isnew) +AudioFileSource::find (ustring& pathstr, bool must_exist, bool& isnew, uint16_t& chan) { - string::size_type pos; + ustring::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 dirs; + vector dirs; int cnt; - string fullpath; - string keeppath; + ustring fullpath; + ustring keeppath; if (search_path.length() == 0) { error << _("FileSource: search path not set") << endmsg; @@ -395,18 +391,66 @@ AudioFileSource::find (string pathstr, bool must_exist, bool& isnew) cnt = 0; - for (vector::iterator i = dirs.begin(); i != dirs.end(); ++i) { + for (vector::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 (access (fullpath.c_str(), R_OK) == 0) { - keeppath = fullpath; - ++cnt; - } + 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) { @@ -423,7 +467,7 @@ AudioFileSource::find (string pathstr, bool must_exist, bool& isnew) isnew = true; } } - + _name = pathstr; _path = keeppath; ret = true; @@ -431,18 +475,31 @@ AudioFileSource::find (string pathstr, bool must_exist, bool& isnew) } 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 (access (_path.c_str(), R_OK) != 0) { - /* file does not exist or we cannot read it */ + 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; @@ -463,6 +520,7 @@ AudioFileSource::find (string pathstr, bool must_exist, bool& isnew) /* already exists */ ret = true; + } } @@ -471,7 +529,7 @@ AudioFileSource::find (string pathstr, bool must_exist, bool& isnew) } void -AudioFileSource::set_search_path (string p) +AudioFileSource::set_search_path (ustring p) { search_path = p; } @@ -504,11 +562,11 @@ AudioFileSource::set_allow_remove_if_empty (bool yn) } int -AudioFileSource::set_name (string newname, bool destructive) +AudioFileSource::set_name (ustring newname, bool destructive) { Glib::Mutex::Lock lm (_lock); - string oldpath = _path; - string newpath = Session::change_audio_path_by_name (oldpath, _name, newname, destructive); + 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; @@ -533,7 +591,7 @@ AudioFileSource::set_name (string newname, bool destructive) } bool -AudioFileSource::is_empty (Session& s, string path) +AudioFileSource::is_empty (Session& s, ustring path) { bool ret = false; boost::shared_ptr afs = boost::dynamic_pointer_cast (SourceFactory::createReadable (s, path, 0, NoPeakFile, false)); @@ -556,30 +614,39 @@ AudioFileSource::setup_peakfile () } bool -AudioFileSource::safe_file_extension(string file) +AudioFileSource::safe_file_extension(ustring file) { - return !(file.rfind(".wav") == string::npos && - file.rfind(".aiff")== string::npos && - file.rfind(".aif") == string::npos && - file.rfind(".snd") == string::npos && - file.rfind(".au") == string::npos && - file.rfind(".raw") == string::npos && - file.rfind(".sf") == string::npos && - file.rfind(".cdr") == string::npos && - file.rfind(".smp") == string::npos && - file.rfind(".maud")== string::npos && - file.rfind(".vwe") == string::npos && - file.rfind(".paf") == string::npos && + return !(file.rfind(".wav") == ustring::npos && + file.rfind(".aiff")== ustring::npos && + file.rfind(".aif") == ustring::npos && + file.rfind(".snd") == ustring::npos && + file.rfind(".au") == ustring::npos && + file.rfind(".raw") == ustring::npos && + file.rfind(".sf") == ustring::npos && + file.rfind(".cdr") == ustring::npos && + file.rfind(".smp") == ustring::npos && + file.rfind(".maud")== ustring::npos && + file.rfind(".vwe") == ustring::npos && + file.rfind(".paf") == ustring::npos && +#ifdef HAVE_FLAC + file.rfind(".flac")== ustring::npos && +#endif // HAVE_FLAC #ifdef HAVE_COREAUDIO - file.rfind(".mp3") == string::npos && - file.rfind(".aac") == string::npos && - file.rfind(".mp4") == string::npos && + file.rfind(".mp3") == ustring::npos && + file.rfind(".aac") == ustring::npos && + file.rfind(".mp4") == ustring::npos && #endif // HAVE_COREAUDIO - file.rfind(".voc") == string::npos); + file.rfind(".voc") == ustring::npos); } void AudioFileSource::mark_immutable () { - _flags = Flag (_flags & ~(Writable|Removable|RemovableIfEmpty|RemoveAtDestroy|CanRename)); + /* destructive sources stay writable, and their other flags don't + change. + */ + + if (!(_flags & Destructive)) { + _flags = Flag (_flags & ~(Writable|Removable|RemovableIfEmpty|RemoveAtDestroy|CanRename)); + } } diff --git a/libs/ardour/audiofilter.cc b/libs/ardour/audiofilter.cc index a7117cf9dc..d10010fbf0 100644 --- a/libs/ardour/audiofilter.cc +++ b/libs/ardour/audiofilter.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include @@ -79,6 +78,7 @@ AudioFilter::finish (boost::shared_ptr region, SourceList& nsrcs) boost::shared_ptr afs = boost::dynamic_pointer_cast(*si); if (afs) { afs->update_header (region->position(), *now, xnow); + afs->mark_immutable (); } } diff --git a/libs/ardour/audioregion.cc b/libs/ardour/audioregion.cc index bc66f0d6b0..1d3032c1e0 100644 --- a/libs/ardour/audioregion.cc +++ b/libs/ardour/audioregion.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include @@ -41,7 +40,6 @@ #include #include #include -#include #include #include "i18n.h" @@ -454,12 +452,12 @@ AudioRegion::_read_at (const SourceList& srcs, Sample *buf, Sample *mixdown_buff nframes_t buf_offset; nframes_t to_read; - /* precondition: caller has verified that we cover the desired section */ - - if (chan_n >= sources.size()) { + if (muted()) { return 0; /* read nothing */ } - + + /* precondition: caller has verified that we cover the desired section */ + if (position < _position) { internal_offset = 0; buf_offset = _position - position; @@ -484,17 +482,29 @@ AudioRegion::_read_at (const SourceList& srcs, Sample *buf, Sample *mixdown_buff mixdown_buffer += buf_offset; } - if (muted()) { - return 0; /* read nothing */ - } - _read_data_count = 0; - if (srcs[chan_n]->read (mixdown_buffer, _start + internal_offset, to_read) != to_read) { - return 0; /* "read nothing" */ - } + if (chan_n < n_channels()) { + + if (srcs[chan_n]->read (mixdown_buffer, _start + internal_offset, to_read) != to_read) { + + return 0; /* "read nothing" */ + } + + _read_data_count += srcs[chan_n]->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); - _read_data_count += srcs[chan_n]->read_data_count(); + /* no fades required */ + + goto merge; + } /* fade in */ @@ -505,7 +515,7 @@ AudioRegion::_read_at (const SourceList& srcs, Sample *buf, Sample *mixdown_buff /* see if this read is within the fade in */ if (internal_offset < fade_in_length) { - + nframes_t limit; limit = min (to_read, fade_in_length - internal_offset); @@ -579,13 +589,15 @@ AudioRegion::_read_at (const SourceList& srcs, Sample *buf, Sample *mixdown_buff 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]; } @@ -948,6 +960,18 @@ AudioRegion::set_fade_out_active (bool yn) 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 () { @@ -1059,7 +1083,6 @@ AudioRegion::separate_by_channel (Session& session, vector r = RegionFactory::create (srcs, _start, _length, new_name, _layer, f); boost::shared_ptr ar = boost::dynamic_pointer_cast (r); - cerr << "new region name is " << ar->name() << endl; v.push_back (ar); @@ -1313,14 +1336,16 @@ void AudioRegion::suspend_fade_in () { if (++_fade_in_disabled == 1) { - set_fade_in_active (false); + if (fade_in_is_default()) { + set_fade_in_active (false); + } } } void AudioRegion::resume_fade_in () { - if (_fade_in_disabled && --_fade_in_disabled == 0) { + if (--_fade_in_disabled == 0 && _fade_in_disabled) { set_fade_in_active (true); } } @@ -1329,14 +1354,16 @@ void AudioRegion::suspend_fade_out () { if (++_fade_out_disabled == 1) { - set_fade_out_active (false); + if (fade_out_is_default()) { + set_fade_out_active (false); + } } } void AudioRegion::resume_fade_out () { - if (_fade_out_disabled && --_fade_out_disabled == 0) { + if (--_fade_out_disabled == 0 &&_fade_out_disabled) { set_fade_out_active (true); } } @@ -1369,6 +1396,7 @@ void AudioRegion::set_playlist (boost::weak_ptr wpl) { boost::shared_ptr old_playlist = (_playlist.lock()); + boost::shared_ptr pl (wpl.lock()); if (old_playlist == pl) { @@ -1391,7 +1419,7 @@ AudioRegion::set_playlist (boost::weak_ptr wpl) } else { if (old_playlist) { for (SourceList::const_iterator i = sources.begin(); i != sources.end(); ++i) { - (*i)->remove_playlist (_playlist); + (*i)->remove_playlist (old_playlist); } } } diff --git a/libs/ardour/audiosource.cc b/libs/ardour/audiosource.cc index d94a34e1f0..0043df7d2e 100644 --- a/libs/ardour/audiosource.cc +++ b/libs/ardour/audiosource.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id: source.cc 404 2006-03-17 17:39:21Z pauld $ */ #include @@ -36,6 +35,7 @@ #include #include +#include #include "i18n.h" @@ -43,41 +43,33 @@ using namespace std; using namespace ARDOUR; using namespace PBD; -pthread_t AudioSource::peak_thread; -bool AudioSource::have_peak_thread = false; -vector > AudioSource::pending_peak_sources; -Glib::Mutex* AudioSource::pending_peak_sources_lock = 0; -int AudioSource::peak_request_pipe[2]; - bool AudioSource::_build_missing_peakfiles = false; bool AudioSource::_build_peakfiles = false; -AudioSource::AudioSource (Session& s, string name) +AudioSource::AudioSource (Session& s, ustring name) : Source (s, name) { - if (pending_peak_sources_lock == 0) { - pending_peak_sources_lock = new Glib::Mutex; - } - _peaks_built = false; _peak_byte_max = 0; - next_peak_clear_should_notify = true; + 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) { - if (pending_peak_sources_lock == 0) { - pending_peak_sources_lock = new Glib::Mutex; - } - _peaks_built = false; _peak_byte_max = 0; - next_peak_clear_should_notify = true; + 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(); @@ -86,6 +78,19 @@ AudioSource::AudioSource (Session& s, const XMLNode& node) 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& @@ -118,171 +123,6 @@ AudioSource::set_state (const XMLNode& node) PEAK FILE STUFF ***********************************************************************/ -void* -AudioSource::peak_thread_work (void* arg) -{ - PBD::ThreadCreated (pthread_self(), X_("Peak")); - struct pollfd pfd[1]; - - if (pending_peak_sources_lock == 0) { - pending_peak_sources_lock = new Glib::Mutex; - } - - Glib::Mutex::Lock lm (*pending_peak_sources_lock); - - while (true) { - - pfd[0].fd = peak_request_pipe[0]; - pfd[0].events = POLLIN|POLLERR|POLLHUP; - - pending_peak_sources_lock->unlock (); - - if (poll (pfd, 1, -1) < 0) { - - if (errno == EINTR) { - pending_peak_sources_lock->lock (); - continue; - } - - error << string_compose (_("poll on peak request pipe failed (%1)"), - strerror (errno)) - << endmsg; - break; - } - - if (pfd[0].revents & ~POLLIN) { - error << _("Error on peak thread request pipe") << endmsg; - break; - } - - if (pfd[0].revents & POLLIN) { - - char req; - - /* empty the pipe of all current requests */ - - while (1) { - size_t nread = ::read (peak_request_pipe[0], &req, sizeof (req)); - - if (nread == 1) { - switch ((PeakRequest::Type) req) { - - case PeakRequest::Build: - break; - - case PeakRequest::Quit: - pthread_exit_pbd (0); - /*NOTREACHED*/ - break; - - default: - break; - } - - } else if (nread == 0) { - break; - } else if (errno == EAGAIN) { - break; - } else { - fatal << _("Error reading from peak request pipe") << endmsg; - /*NOTREACHED*/ - } - } - } - - pending_peak_sources_lock->lock (); - - while (!pending_peak_sources.empty()) { - - boost::shared_ptr s = pending_peak_sources.front(); - pending_peak_sources.erase (pending_peak_sources.begin()); - - pending_peak_sources_lock->unlock (); - s->build_peaks(); - pending_peak_sources_lock->lock (); - } - } - - pthread_exit_pbd (0); - /*NOTREACHED*/ - return 0; -} - -int -AudioSource::start_peak_thread () -{ - if (!_build_peakfiles) { - return 0; - } - - if (pipe (peak_request_pipe)) { - error << string_compose(_("Cannot create transport request signal pipe (%1)"), strerror (errno)) << endmsg; - return -1; - } - - if (fcntl (peak_request_pipe[0], F_SETFL, O_NONBLOCK)) { - error << string_compose(_("UI: cannot set O_NONBLOCK on peak request pipe (%1)"), strerror (errno)) << endmsg; - return -1; - } - - if (fcntl (peak_request_pipe[1], F_SETFL, O_NONBLOCK)) { - error << string_compose(_("UI: cannot set O_NONBLOCK on peak request pipe (%1)"), strerror (errno)) << endmsg; - return -1; - } - - if (pthread_create_and_store ("peak file builder", &peak_thread, 0, peak_thread_work, 0)) { - error << _("AudioSource: could not create peak thread") << endmsg; - return -1; - } - - have_peak_thread = true; - return 0; -} - -void -AudioSource::stop_peak_thread () -{ - if (!have_peak_thread) { - return; - } - - void* status; - - char c = (char) PeakRequest::Quit; - ::write (peak_request_pipe[1], &c, 1); - pthread_join (peak_thread, &status); -} - -void -AudioSource::queue_for_peaks (boost::shared_ptr source, bool notify) -{ - if (have_peak_thread) { - - Glib::Mutex::Lock lm (*pending_peak_sources_lock); - - source->next_peak_clear_should_notify = notify; - - if (find (pending_peak_sources.begin(), - pending_peak_sources.end(), - source) == pending_peak_sources.end()) { - pending_peak_sources.push_back (source); - } - - char c = (char) PeakRequest::Build; - ::write (peak_request_pipe[1], &c, 1); - } -} - -void AudioSource::clear_queue_for_peaks () -{ - /* this is done to cancel a group of running peak builds */ - if (have_peak_thread) { - Glib::Mutex::Lock lm (*pending_peak_sources_lock); - pending_peak_sources.clear (); - } -} - - bool AudioSource::peaks_ready (sigc::slot the_slot, sigc::connection& conn) const { @@ -318,11 +158,11 @@ AudioSource::touch_peakfile () } int -AudioSource::rename_peakfile (string newpath) +AudioSource::rename_peakfile (ustring newpath) { /* caller must hold _lock */ - string oldpath = peakpath; + ustring oldpath = peakpath; if (access (oldpath.c_str(), F_OK) == 0) { if (rename (oldpath.c_str(), newpath.c_str()) != 0) { @@ -337,7 +177,7 @@ AudioSource::rename_peakfile (string newpath) } int -AudioSource::initialize_peakfile (bool newfile, string audio_path) +AudioSource::initialize_peakfile (bool newfile, ustring audio_path) { struct stat statbuf; @@ -348,7 +188,7 @@ AudioSource::initialize_peakfile (bool newfile, string audio_path) */ if (!newfile && access (peakpath.c_str(), R_OK) != 0) { - string str = old_peak_path (audio_path); + ustring str = old_peak_path (audio_path); if (access (str.c_str(), R_OK) == 0) { peakpath = str; } @@ -431,7 +271,7 @@ AudioSource::read_peaks (PeakData *peaks, nframes_t npeaks, nframes_t start, nfr int ret = -1; PeakData* staging = 0; Sample* raw_staging = 0; - int peakfile = -1; + int _peakfile = -1; expected_peaks = (cnt / (double) frames_per_peak); scale = npeaks/expected_peaks; @@ -492,7 +332,7 @@ AudioSource::read_peaks (PeakData *peaks, nframes_t npeaks, nframes_t start, nfr /* open, read, close */ - if ((peakfile = ::open (peakpath.c_str(), O_RDONLY, 0664)) < 0) { + if ((_peakfile = ::open (peakpath.c_str(), O_RDONLY, 0664)) < 0) { error << string_compose(_("AudioSource: cannot open peakpath \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg; return -1; } @@ -501,8 +341,8 @@ AudioSource::read_peaks (PeakData *peaks, nframes_t npeaks, nframes_t start, nfr cerr << "DIRECT PEAKS\n"; #endif - nread = ::pread (peakfile, peaks, sizeof (PeakData)* npeaks, first_peak_byte); - close (peakfile); + nread = ::pread (_peakfile, peaks, sizeof (PeakData)* npeaks, first_peak_byte); + close (_peakfile); if (nread != sizeof (PeakData) * npeaks) { cerr << "AudioSource[" @@ -566,7 +406,7 @@ AudioSource::read_peaks (PeakData *peaks, nframes_t npeaks, nframes_t start, nfr /* open ... close during out: handling */ - if ((peakfile = ::open (peakpath.c_str(), O_RDONLY, 0664)) < 0) { + if ((_peakfile = ::open (peakpath.c_str(), O_RDONLY, 0664)) < 0) { error << string_compose(_("AudioSource: cannot open peakpath \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg; return 0; } @@ -583,10 +423,10 @@ AudioSource::read_peaks (PeakData *peaks, nframes_t npeaks, nframes_t start, nfr cerr << "read " << sizeof (PeakData) * to_read << " from peakfile @ " << start_byte << endl; #endif - if ((nread = ::pread (peakfile, staging, sizeof (PeakData) * to_read, start_byte)) + if ((nread = ::pread (_peakfile, staging, sizeof (PeakData) * to_read, start_byte)) != sizeof (PeakData) * to_read) { - off_t fend = lseek (peakfile, 0, SEEK_END); + off_t fend = lseek (_peakfile, 0, SEEK_END); cerr << "AudioSource[" << _name @@ -672,13 +512,21 @@ AudioSource::read_peaks (PeakData *peaks, nframes_t npeaks, nframes_t start, nfr 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") - , _name, to_read, current_frame) + 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; } @@ -708,8 +556,8 @@ AudioSource::read_peaks (PeakData *peaks, nframes_t npeaks, nframes_t start, nfr } out: - if (peakfile >= 0) { - close (peakfile); + if (_peakfile >= 0) { + close (_peakfile); } if (staging) { @@ -730,196 +578,277 @@ AudioSource::read_peaks (PeakData *peaks, nframes_t npeaks, nframes_t start, nfr #undef DEBUG_PEAK_BUILD int -AudioSource::build_peaks () +AudioSource::build_peaks_from_scratch () { - vector built; - int status = -1; - bool pr_signal = false; - list copy; + nframes_t current_frame; + nframes_t cnt; + Sample buf[frames_per_peak]; + nframes_t frames_read; + nframes_t frames_to_read; + int ret = -1; { - Glib::Mutex::Lock lm (_lock); - copy = pending_peak_builds; - pending_peak_builds.clear (); - } - -#ifdef DEBUG_PEAK_BUILD - cerr << "build peaks with " << copy.size() << " requests pending\n"; -#endif + /* hold lock while building peaks */ - for (list::iterator i = copy.begin(); i != copy.end(); ++i) { + Glib::Mutex::Lock lp (_lock); - if ((status = do_build_peak ((*i)->frame, (*i)->cnt)) != 0) { - unlink (peakpath.c_str()); - break; + if (prepare_for_peakfile_writes ()) { + goto out; } - built.push_back (new PeakBuildRecord (*(*i))); - delete *i; - } + + current_frame = 0; + cnt = _length; + _peaks_built = false; + + while (cnt) { + + frames_to_read = min (frames_per_peak, cnt); - { - Glib::Mutex::Lock lm (_lock); + 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 (); + goto out; + } - if (status == 0) { - _peaks_built = true; - - if (next_peak_clear_should_notify) { - next_peak_clear_should_notify = false; - pr_signal = true; + if (compute_and_write_peaks (buf, current_frame, frames_read, true)) { + break; } + + current_frame += frames_read; + cnt -= frames_read; } + + if (cnt == 0) { + /* success */ + truncate_peakfile(); + _peaks_built = true; + } + + done_with_peakfile_writes (); } - if (status == 0) { - for (vector::iterator i = built.begin(); i != built.end(); ++i) { - PeakRangeReady ((*i)->frame, (*i)->cnt); /* EMIT SIGNAL */ - delete *i; - } + /* lock no longer held, safe to signal */ - if (pr_signal) { - truncate_peakfile(); - PeaksReady (); /* EMIT SIGNAL */ - } + if (_peaks_built) { + PeaksReady (); /* EMIT SIGNAL */ + ret = 0; + } + + out: + if (ret) { + unlink (peakpath.c_str()); } - return status; + return ret; } int -AudioSource::do_build_peak (nframes_t first_frame, nframes_t cnt) +AudioSource::prepare_for_peakfile_writes () { + if ((peakfile = ::open (peakpath.c_str(), O_RDWR|O_CREAT, 0664)) < 0) { + error << string_compose(_("AudioSource: cannot open peakpath \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg; + return -1; + } + return 0; +} + +void +AudioSource::done_with_peakfile_writes () +{ + if (peak_leftover_cnt) { + compute_and_write_peaks (0, 0, 0, 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) +{ + Sample* buf2 = 0; + nframes_t to_do; + uint32_t peaks_computed; + PeakData* peakbuf = 0; + int ret = -1; nframes_t current_frame; - Sample buf[frames_per_peak]; - Sample xmin, xmax; - uint32_t peaki; - PeakData* peakbuf; - nframes_t frames_read; - nframes_t frames_to_read; + nframes_t frames_done; + const size_t blocksize = (128 * 1024); off_t first_peak_byte; - int peakfile = -1; - int ret = -1; - off_t target_length; - off_t endpos; -#ifdef DEBUG_PEAK_BUILD - cerr << pthread_self() << ": " << _name << ": building peaks for " << first_frame << " to " << first_frame + cnt - 1 << endl; -#endif + if (peakfile < 0) { + prepare_for_peakfile_writes (); + } - first_peak_byte = (first_frame / frames_per_peak) * sizeof (PeakData); + restart: + if (peak_leftover_cnt) { -#ifdef DEBUG_PEAK_BUILD - cerr << "seeking to " << first_peak_byte << " before writing new peak data\n"; -#endif + if (first_frame != peak_leftover_frame + peak_leftover_cnt) { - current_frame = first_frame; - peakbuf = new PeakData[(cnt/frames_per_peak)+1]; - peaki = 0; + /* 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]; + Session::find_peaks (peak_leftovers + 1, peak_leftover_cnt - 1, &x.min, &x.max); - if ((peakfile = ::open (peakpath.c_str(), O_RDWR|O_CREAT, 0664)) < 0) { - error << string_compose(_("AudioSource: cannot open peakpath \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg; - return -1; - } - - while (cnt) { + off_t byte = (peak_leftover_frame / frames_per_peak) * sizeof (PeakData); - frames_to_read = min (frames_per_peak, cnt); + 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; + } - /* lock for every read */ + _peak_byte_max = max (_peak_byte_max, (off_t) (byte + sizeof(PeakData))); - if ((frames_read = read (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; - goto out; + PeakRangeReady (peak_leftover_frame, peak_leftover_cnt); /* EMIT SIGNAL */ + PeaksReady (); /* EMIT SIGNAL */ + + /* left overs are done */ + + peak_leftover_cnt = 0; + goto restart; } - xmin = buf[0]; - xmax = buf[0]; + /* 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 */ - for (nframes_t n = 1; n < frames_read; ++n) { - xmax = max (xmax, buf[n]); - xmin = min (xmin, buf[n]); + to_do = cnt + peak_leftover_cnt; + buf2 = new Sample[to_do]; -// if (current_frame < frames_read) { -// cerr << "sample = " << buf[n] << " max = " << xmax << " min = " << xmin << " max of 2 = " << max (xmax, buf[n]) << endl; -// } - } + /* 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; - peakbuf[peaki].max = xmax; - peakbuf[peaki].min = xmin; - peaki++; + /* make sure that when we write into the peakfile, we startup where we left off */ - current_frame += frames_read; - cnt -= frames_read; + first_frame = peak_leftover_frame; + + } else { + to_do = cnt; } -#define BLOCKSIZE (128 * 1024) + peakbuf = new PeakData[(to_do/frames_per_peak)+1]; + peaks_computed = 0; + current_frame = first_frame; + frames_done = 0; - /* 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. - */ - endpos = lseek (peakfile, 0, SEEK_END); + while (to_do) { + + /* if some frames were passed in (i.e. we're not flushing leftovers) + and there are less than frames_per_peak to do, save them till + next time + */ + + if (force && (to_do < frames_per_peak)) { + /* 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 (frames_per_peak, to_do); + + peakbuf[peaks_computed].max = buf[0]; + peakbuf[peaks_computed].min = buf[0]; + + Session::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; + } - target_length = BLOCKSIZE * ((first_peak_byte + BLOCKSIZE + 1) / BLOCKSIZE); + first_peak_byte = (first_frame / frames_per_peak) * sizeof (PeakData); - if (endpos < target_length) { - // XXX - we really shouldn't be doing this for destructive source peaks - ftruncate (peakfile, target_length); - //cerr << "do build TRUNC: " << peakpath << " " << target_length << endl; + if (can_truncate_peaks()) { - /* error doesn't actually matter though, so continue on without testing */ + /* 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) * peaki, first_peak_byte) != (ssize_t) (sizeof (PeakData) * peaki)) { + 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)*peaki)); + _peak_byte_max = max (_peak_byte_max, (off_t) (first_peak_byte + sizeof(PeakData)*peaks_computed)); + + if (frames_done) { + PeakRangeReady (first_frame, frames_done); /* EMIT SIGNAL */ + PeaksReady (); /* EMIT SIGNAL */ + } ret = 0; out: delete [] peakbuf; - if (peakfile >= 0) { - close (peakfile); + if (buf2) { + delete [] buf2; } return ret; } -void -AudioSource::build_peaks_from_scratch () -{ - Glib::Mutex::Lock lp (_lock); - - next_peak_clear_should_notify = true; - pending_peak_builds.push_back (new PeakBuildRecord (0, _length)); - queue_for_peaks (shared_from_this(), true); -} - void AudioSource::truncate_peakfile () { - int peakfile = -1; + 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 */ - if ((peakfile = ::open (peakpath.c_str(), O_RDWR)) >= 0) { - off_t end = lseek (peakfile, 0, SEEK_END); - - if (end > _peak_byte_max) { - ftruncate(peakfile, _peak_byte_max); - //cerr << "truncated " << peakpath << " to " << _peak_byte_max << " bytes" << endl; - } - else { - //cerr << "NOT truncated " << peakpath << " to " << _peak_byte_max << " end " << end << endl; - } - close (peakfile); + off_t end = lseek (peakfile, 0, SEEK_END); + + if (end > _peak_byte_max) { + ftruncate (peakfile, _peak_byte_max); } } bool -AudioSource::file_changed (string path) +AudioSource::file_changed (ustring path) { struct stat stat_file; struct stat stat_peak; diff --git a/libs/ardour/auditioner.cc b/libs/ardour/auditioner.cc index 84f6f13f1d..e6f4e12e3d 100644 --- a/libs/ardour/auditioner.cc +++ b/libs/ardour/auditioner.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include @@ -65,7 +64,7 @@ Auditioner::Auditioner (Session& s) } if (right.length()) { - audio_diskstream()->add_channel(); + audio_diskstream()->add_channel (1); add_output_port (right, this, DataType::AUDIO); } @@ -139,12 +138,10 @@ Auditioner::audition_region (boost::shared_ptr region) _diskstream->playlist()->clear (); _diskstream->playlist()->add_region (the_region, 0, 1); - while (_diskstream->n_channels() < the_region->n_channels()) { - audio_diskstream()->add_channel (); - } - - while (_diskstream->n_channels() > the_region->n_channels()) { - audio_diskstream()->remove_channel (); + if (_diskstream->n_channels() < the_region->n_channels()) { + audio_diskstream()->add_channel (the_region->n_channels() - _diskstream->n_channels()); + } else if (_diskstream->n_channels() > the_region->n_channels()) { + audio_diskstream()->remove_channel (_diskstream->n_channels() - the_region->n_channels()); } /* force a panner reset now that we have all channels */ diff --git a/libs/ardour/automation_event.cc b/libs/ardour/automation_event.cc index af6fffdeb9..341fa82091 100644 --- a/libs/ardour/automation_event.cc +++ b/libs/ardour/automation_event.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include diff --git a/libs/ardour/configuration.cc b/libs/ardour/configuration.cc index a0f2b5e036..c8d71c5155 100644 --- a/libs/ardour/configuration.cc +++ b/libs/ardour/configuration.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include @@ -27,7 +26,6 @@ #include #include #include -#include #include #include "i18n.h" @@ -318,6 +316,22 @@ Configuration::map_parameters (sigc::slot theSlot) #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 () { @@ -330,3 +344,4 @@ 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/connection.cc b/libs/ardour/connection.cc index fbfd02d509..13b7dc4ddb 100644 --- a/libs/ardour/connection.cc +++ b/libs/ardour/connection.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include diff --git a/libs/ardour/control_protocol_manager.cc b/libs/ardour/control_protocol_manager.cc index 72f56794d7..899790dddc 100644 --- a/libs/ardour/control_protocol_manager.cc +++ b/libs/ardour/control_protocol_manager.cc @@ -43,7 +43,6 @@ ControlProtocolManager::~ControlProtocolManager() } control_protocol_info.clear(); - } void @@ -75,12 +74,11 @@ ControlProtocolManager::drop_session () delete *p; } control_protocols.clear (); - + for (list::iterator p = control_protocol_info.begin(); p != control_protocol_info.end(); ++p) { - delete *p; + // otherwise the ControlProtocol instances are not recreated in set_session + (*p)->requested = true; } - - control_protocol_info.clear(); } } @@ -106,10 +104,6 @@ ControlProtocolManager::instantiate (ControlProtocolInfo& cpi) Glib::Mutex::Lock lm (protocols_lock); control_protocols.push_back (cpi.protocol); - if (cpi.state) { - cpi.protocol->set_state (*cpi.state); - } - return cpi.protocol; } @@ -297,7 +291,6 @@ ControlProtocolManager::set_state (const XMLNode& node) 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 { diff --git a/libs/ardour/coreaudiosource.cc b/libs/ardour/coreaudiosource.cc index 572fd9ef81..703225e502 100644 --- a/libs/ardour/coreaudiosource.cc +++ b/libs/ardour/coreaudiosource.cc @@ -38,9 +38,10 @@ CoreAudioSource::CoreAudioSource (Session& s, const XMLNode& node) } CoreAudioSource::CoreAudioSource (Session& s, const string& path, int chn, Flag flags) - : AudioFileSource(s, path, flags), + /* files created this way are never writable or removable */ + : AudioFileSource (s, path, Flag (flags & ~(Writable|Removable|RemovableIfEmpty|RemoveAtDestroy))) { - channel = chn; + _channel = chn; init (); } @@ -60,8 +61,8 @@ CoreAudioSource::init () n_channels = file_asbd.NumberChannels(); cerr << "number of channels: " << n_channels << endl; - 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; + 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(); } @@ -132,14 +133,14 @@ CoreAudioSource::read_unlocked (Sample *dst, nframes_t start, nframes_t cnt) con abl.mBuffers[0].mDataByteSize = tmpbufsize * sizeof(Sample); abl.mBuffers[0].mData = tmpbuf; - cerr << "channel: " << channel << endl; + cerr << "channel: " << _channel << endl; try { af.Read (real_cnt, &abl); } catch (CAXException& cax) { error << string_compose("CoreAudioSource: %1 (%2)", cax.mOperation, _name); } - float *ptr = tmpbuf + channel; + float *ptr = tmpbuf + _channel; real_cnt /= n_channels; /* stride through the interleaved data */ diff --git a/libs/ardour/crossfade.cc b/libs/ardour/crossfade.cc index 57821ca440..eae6c7cc52 100644 --- a/libs/ardour/crossfade.cc +++ b/libs/ardour/crossfade.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include diff --git a/libs/ardour/curve.cc b/libs/ardour/curve.cc index 8465094775..5a1dc108f8 100644 --- a/libs/ardour/curve.cc +++ b/libs/ardour/curve.cc @@ -18,7 +18,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include diff --git a/libs/ardour/cycle_timer.cc b/libs/ardour/cycle_timer.cc index 3031d5a7ec..143cb841ec 100644 --- a/libs/ardour/cycle_timer.cc +++ b/libs/ardour/cycle_timer.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include diff --git a/libs/ardour/default_click.cc b/libs/ardour/default_click.cc index b4067a2051..5bdbeb2ac5 100644 --- a/libs/ardour/default_click.cc +++ b/libs/ardour/default_click.cc @@ -16,7 +16,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include diff --git a/libs/ardour/destructive_filesource.cc b/libs/ardour/destructive_filesource.cc deleted file mode 100644 index 5eada195cd..0000000000 --- a/libs/ardour/destructive_filesource.cc +++ /dev/null @@ -1,424 +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$ -*/ - -/* This is is very hacky way to get pread and pwrite declarations. - First, include so that we can avoid its #undef __USE_UNIX98. - Then define __USE_UNIX98, include , and then undef it - again. If #define _XOPEN_SOURCE actually worked, I'd use that, but - despite claims in the header that it does, it doesn't. - - features.h isn't available on osx and it compiles fine without it. -*/ - -#ifdef HAVE_FEATURES_H -#include -#endif - -#if __GNUC__ >= 3 -// #define _XOPEN_SOURCE 500 -#include -#else -#define __USE_UNIX98 -#include -#undef __USE_UNIX98 -#endif - -// darwin supports 64 by default and doesn't provide wrapper functions. -#if defined (__APPLE__) -typedef off_t off64_t; -#define open64 open -#define close64 close -#define lseek64 lseek -#define pread64 pread -#define pwrite64 pwrite -#endif - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "i18n.h" - -using namespace std; -using namespace ARDOUR; -using namespace PBD; - -gain_t* DestructiveFileSource::out_coefficient = 0; -gain_t* DestructiveFileSource::in_coefficient = 0; -nframes_t DestructiveFileSource::xfade_frames = 64; - -DestructiveFileSource::DestructiveFileSource (Session& s, string path, SampleFormat samp_format, HeaderFormat hdr_format, nframes_t rate, Flag flags) - : SndFileSource (s, path, samp_format, hdr_format, rate, flags) -{ - init (); -} - - -DestructiveFileSource::DestructiveFileSource (Session& s, string path, Flag flags) - : SndFileSource (s, path, flags) -{ - init (); -} - -DestructiveFileSource::DestructiveFileSource (Session& s, const XMLNode& node) - : SndFileSource (s, node) -{ - init (); -} - -void -DestructiveFileSource::init () -{ - xfade_buf = new Sample[xfade_frames]; - - _capture_start = false; - _capture_end = false; - file_pos = 0; - - timeline_position = header_position_offset; - AudioFileSource::HeaderPositionOffsetChanged.connect (mem_fun (*this, &DestructiveFileSource::handle_header_position_change)); -} - -DestructiveFileSource::~DestructiveFileSource() -{ - delete xfade_buf; -} - -void -DestructiveFileSource::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 -DestructiveFileSource::mark_capture_start (nframes_t pos) -{ - if (pos < timeline_position) { - _capture_start = false; - } else { - _capture_start = true; - capture_start_frame = pos; - } -} - -void -DestructiveFileSource::mark_capture_end() -{ - _capture_end = true; -} - -void -DestructiveFileSource::clear_capture_marks () -{ - _capture_start = false; - _capture_end = false; -} - -nframes_t -DestructiveFileSource::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(_("DestructiveFileSource: \"%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(_("DestructiveFileSource: \"%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) { - - 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]); - } - } - - if (xfade) { - if (write_float (xfade_buf, fade_position, xfade) != xfade) { - error << string_compose(_("DestructiveFileSource: \"%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(_("DestructiveFileSource: \"%1\" bad write (%2)"), _path, strerror (errno)) << endmsg; - return 0; - } - } - - return cnt; -} - -nframes_t -DestructiveFileSource::write_unlocked (Sample* data, nframes_t cnt) -{ - nframes_t old_file_pos; - - if (!writable()) { - 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); - file_pos += cnt; - - if (_build_peakfiles) { - PeakBuildRecord *pbr = 0; - - if (pending_peak_builds.size()) { - pbr = pending_peak_builds.back(); - } - - if (pbr && pbr->frame + pbr->cnt == old_file_pos) { - - /* the last PBR extended to the start of the current write, - so just extend it again. - */ - - pbr->cnt += cnt; - } else { - pending_peak_builds.push_back (new PeakBuildRecord (old_file_pos, cnt)); - } - - _peaks_built = false; - } - - if (_build_peakfiles) { - queue_for_peaks (shared_from_this ()); - } - - return cnt; -} - -nframes_t -DestructiveFileSource::last_capture_start_frame () const -{ - return capture_start_frame; -} - -XMLNode& -DestructiveFileSource::get_state () -{ - XMLNode& node = AudioFileSource::get_state (); - node.add_property (X_("destructive"), "true"); - return node; -} - -void -DestructiveFileSource::handle_header_position_change () -{ - 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 -DestructiveFileSource::set_timeline_position (int64_t pos) -{ - //destructive track timeline postion does not change except at instantion or when header_position_offset (session start) changes -} - -int -DestructiveFileSource::read_peaks (PeakData *peaks, nframes_t npeaks, nframes_t start, nframes_t cnt, double samples_per_unit) const -{ - // cerr << _name << " read peaks at " << start << " for " << cnt << " tpos = " << timeline_position << endl; - return AudioFileSource::read_peaks (peaks, npeaks, start, cnt, samples_per_unit); -} - diff --git a/libs/ardour/diskstream.cc b/libs/ardour/diskstream.cc index 420dd20fcb..c9c11cc92d 100644 --- a/libs/ardour/diskstream.cc +++ b/libs/ardour/diskstream.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id: diskstream.cc 567 2006-06-07 14:54:12Z trutkin $ */ #include @@ -45,7 +44,6 @@ #include #include #include -#include #include #include #include @@ -116,6 +114,7 @@ Diskstream::init (Flag f) playback_distance = 0; _read_data_count = 0; _write_data_count = 0; + commit_should_unlock = false; pending_overwrite = false; overwrite_frame = 0; @@ -127,9 +126,6 @@ Diskstream::init (Flag f) Diskstream::~Diskstream () { - // Taken by derived class destrctors.. should assure locked here somehow? - //Glib::Mutex::Lock lm (state_lock); - if (_playlist) _playlist->release (); } @@ -219,7 +215,9 @@ Diskstream::prepare () void Diskstream::recover () { - state_lock.unlock(); + if (commit_should_unlock) { + state_lock.unlock(); + } _processed = false; } diff --git a/libs/ardour/enums.cc b/libs/ardour/enums.cc index 0460df43d8..4220adf7eb 100644 --- a/libs/ardour/enums.cc +++ b/libs/ardour/enums.cc @@ -31,6 +31,7 @@ setup_enum_writer () RegionPoint _RegionPoint; Placement _Placement; MonitorModel _MonitorModel; + RemoteModel _RemoteModel; CrossfadeModel _CrossfadeModel; LayerModel _LayerModel; SoloModel _SoloModel; @@ -142,6 +143,11 @@ setup_enum_writer () REGISTER_ENUM (ExternalMonitoring); REGISTER (_MonitorModel); + REGISTER_ENUM (UserOrdered); + REGISTER_ENUM (MixerOrdered); + REGISTER_ENUM (EditorOrdered); + REGISTER (_RemoteModel); + REGISTER_ENUM (FullCrossfade); REGISTER_ENUM (ShortCrossfade); REGISTER (_CrossfadeModel); diff --git a/libs/ardour/gain.cc b/libs/ardour/gain.cc index 0b77bea279..369df7348c 100644 --- a/libs/ardour/gain.cc +++ b/libs/ardour/gain.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include diff --git a/libs/ardour/gdither.cc b/libs/ardour/gdither.cc index ec6bfaa2ea..7242f857c8 100644 --- a/libs/ardour/gdither.cc +++ b/libs/ardour/gdither.cc @@ -15,7 +15,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id$ */ #include diff --git a/libs/ardour/globals.cc b/libs/ardour/globals.cc index d0ee94dca7..2d22f4eb11 100644 --- a/libs/ardour/globals.cc +++ b/libs/ardour/globals.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id: globals.cc 935 2006-09-29 21:39:39Z paul $ */ #include // Needed so that libraptor (included in lrdf) won't complain @@ -43,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -62,6 +62,7 @@ #include "i18n.h" ARDOUR::Configuration* ARDOUR::Config = 0; +ARDOUR::RuntimeProfile* ARDOUR::Profile = 0; ARDOUR::AudioLibrary* ARDOUR::Library = 0; #ifdef HAVE_LIBLO @@ -234,6 +235,7 @@ setup_hardware_optimization (bool try_optimization) // SSE SET Session::compute_peak = x86_sse_compute_peak; + Session::find_peaks = x86_sse_find_peaks; Session::apply_gain_to_buffer = x86_sse_apply_gain_to_buffer; Session::mix_buffers_with_gain = x86_sse_mix_buffers_with_gain; Session::mix_buffers_no_gain = x86_sse_mix_buffers_no_gain; @@ -250,6 +252,7 @@ setup_hardware_optimization (bool try_optimization) if (sysVersion >= 0x00001040) { // Tiger at least Session::compute_peak = veclib_compute_peak; + Session::find_peaks = veclib_find_peaks; Session::apply_gain_to_buffer = veclib_apply_gain_to_buffer; Session::mix_buffers_with_gain = veclib_mix_buffers_with_gain; Session::mix_buffers_no_gain = veclib_mix_buffers_no_gain; @@ -263,7 +266,8 @@ setup_hardware_optimization (bool try_optimization) if (generic_mix_functions) { - Session::compute_peak = compute_peak; + Session::compute_peak = compute_peak; + Session::find_peaks = find_peaks; Session::apply_gain_to_buffer = apply_gain_to_buffer; Session::mix_buffers_with_gain = mix_buffers_with_gain; Session::mix_buffers_no_gain = mix_buffers_no_gain; @@ -279,8 +283,6 @@ ARDOUR::init (bool use_vst, bool try_optimization) (void) bindtextdomain(PACKAGE, LOCALEDIR); - PBD::ID::init (); - setup_enum_writer (); lrdf_init(); @@ -294,6 +296,8 @@ ARDOUR::init (bool use_vst, bool try_optimization) Config->set_use_vst (use_vst); + Profile = new RuntimeProfile; + if (setup_midi ()) { return -1; } @@ -616,6 +620,7 @@ std::istream& operator>>(std::istream& o, HeaderFormat& var) { return int_to_typ std::istream& operator>>(std::istream& o, SampleFormat& var) { return int_to_type (o, var); } std::istream& operator>>(std::istream& o, AutoConnectOption& var) { return int_to_type (o, var); } std::istream& operator>>(std::istream& o, MonitorModel& var) { return int_to_type (o, var); } +std::istream& operator>>(std::istream& o, RemoteModel& var) { return int_to_type (o, var); } std::istream& operator>>(std::istream& o, EditMode& var) { return int_to_type (o, var); } std::istream& operator>>(std::istream& o, SoloModel& var) { return int_to_type (o, var); } std::istream& operator>>(std::istream& o, LayerModel& var) { return int_to_type (o, var); } diff --git a/libs/ardour/import.cc b/libs/ardour/import.cc index e6be0f4fc2..712b9a35e4 100644 --- a/libs/ardour/import.cc +++ b/libs/ardour/import.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include @@ -51,6 +50,63 @@ using namespace PBD; #define BLOCKSIZE 4096U +class ImportableSource { + public: + ImportableSource (SNDFILE* sf, SF_INFO* info) : in (sf), sf_info (info) {} + virtual ~ImportableSource() {} + + virtual nframes_t read (Sample* buffer, nframes_t nframes) { + nframes_t per_channel = nframes / sf_info->channels; + per_channel = sf_readf_float (in, buffer, per_channel); + return per_channel * sf_info->channels; + } + + virtual float ratio() const { return 1.0f; } + +protected: + SNDFILE* in; + SF_INFO* sf_info; +}; + +class ResampledImportableSource : public ImportableSource { + public: + ResampledImportableSource (SNDFILE* sf, SF_INFO* info, nframes_t rate) : ImportableSource (sf, info) { + int err; + + sf_seek (in, 0, SEEK_SET) ; + + /* Initialize the sample rate converter. */ + + if ((src_state = src_new (SRC_SINC_BEST_QUALITY, sf_info->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) / sf_info->samplerate ; + + } + + ~ResampledImportableSource () { + src_state = src_delete (src_state) ; + } + + nframes_t read (Sample* buffer, nframes_t nframes); + + float ratio() const { return src_data.src_ratio; } + + private: + float input[BLOCKSIZE]; + SRC_STATE* src_state; + SRC_DATA src_data; +}; + int Session::import_audiofile (import_status& status) { @@ -61,7 +117,6 @@ Session::import_audiofile (import_status& status) float *data = 0; Sample **channel_data = 0; long nfiles = 0; - long n; string basepath; string sounds_dir; nframes_t so_far; @@ -69,42 +124,32 @@ Session::import_audiofile (import_status& status) int ret = -1; vector new_paths; struct tm* now; - string tmp_convert_file; - + ImportableSource* importable = 0; + const nframes_t nframes = BLOCKSIZE; + status.new_regions.clear (); if ((in = sf_open (status.paths.front().c_str(), SFM_READ, &info)) == 0) { error << string_compose(_("Import: cannot open input sound file \"%1\""), status.paths.front()) << endmsg; + status.done = 1; + status.cancel = 1; return -1; + } + + if ((nframes_t) info.samplerate != frame_rate()) { + importable = new ResampledImportableSource (in, &info, frame_rate()); } else { - if ((uint32_t) info.samplerate != frame_rate()) { - sf_close(in); - status.doing_what = _("resampling audio"); - // resample to session frame_rate - if (sample_rate_convert(status, status.paths.front(), tmp_convert_file)) { - if ((in = sf_open (tmp_convert_file.c_str(), SFM_READ, &info)) == 0) { - error << string_compose(_("Import: cannot open converted sound file \"%1\""), tmp_convert_file) << endmsg; - return -1; - } - } else if (!status.cancel){ - // error - error << string_compose(_("Import: error while resampling sound file \"%1\""), status.paths.front()) << endmsg; - return -1; - } else { - // canceled - goto out; - } - } + importable = new ImportableSource (in, &info); } - for (n = 0; n < info.channels; ++n) { + for (int n = 0; n < info.channels; ++n) { newfiles.push_back (boost::shared_ptr()); } sounds_dir = discover_best_sound_dir (); basepath = PBD::basename_nosuffix (status.paths.front()); - for (n = 0; n < info.channels; ++n) { + for (int n = 0; n < info.channels; ++n) { bool goodfile = false; @@ -116,12 +161,12 @@ Session::import_audiofile (import_status& status) snprintf (buf, sizeof(buf), "%s/%s-R.wav", sounds_dir.c_str(), basepath.c_str()); } } else if (info.channels > 1) { - snprintf (buf, sizeof(buf), "%s/%s-c%lu.wav", sounds_dir.c_str(), basepath.c_str(), n+1); + snprintf (buf, sizeof(buf), "%s/%s-c%d.wav", sounds_dir.c_str(), basepath.c_str(), n+1); } else { snprintf (buf, sizeof(buf), "%s/%s.wav", sounds_dir.c_str(), basepath.c_str()); } - if (::access (buf, F_OK) == 0) { + if (Glib::file_test (buf, 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 @@ -150,12 +195,11 @@ Session::import_audiofile (import_status& status) nfiles++; } - - data = new float[BLOCKSIZE * info.channels]; + data = new float[nframes * info.channels]; channel_data = new Sample * [ info.channels ]; - for (n = 0; n < info.channels; ++n) { - channel_data[n] = new Sample[BLOCKSIZE]; + for (int n = 0; n < info.channels; ++n) { + channel_data[n] = new Sample[nframes]; } so_far = 0; @@ -165,18 +209,21 @@ Session::import_audiofile (import_status& status) while (!status.cancel) { - long nread; + nframes_t nread, nfread; long x; long chn; - - if ((nread = sf_readf_float (in, data, BLOCKSIZE)) == 0) { + + if ((nread = importable->read (data, nframes)) == 0) { break; } + nfread = nread / info.channels; /* de-interleave */ for (chn = 0; chn < info.channels; ++chn) { - for (x = chn, n = 0; n < nread; x += info.channels, ++n) { + + nframes_t n; + for (x = chn, n = 0; n < nfread; x += info.channels, ++n) { channel_data[chn][n] = (Sample) data[x]; } } @@ -184,11 +231,15 @@ Session::import_audiofile (import_status& status) /* flush to disk */ for (chn = 0; chn < info.channels; ++chn) { - newfiles[chn]->write (channel_data[chn], nread); + newfiles[chn]->write (channel_data[chn], nfread); } so_far += nread; - status.progress = so_far / (float) (info.frames * info.channels); + status.progress = so_far / (importable->ratio () * info.frames * info.channels); + } + + if (status.cancel) { + goto out; } if (status.multichan) { @@ -203,13 +254,10 @@ Session::import_audiofile (import_status& status) time (&xnow); now = localtime (&xnow); - if (status.cancel) { - goto out; - } - if (status.multichan) { /* all sources are used in a single multichannel region */ - for (n = 0; n < nfiles && !status.cancel; ++n) { + + for (int n = 0; n < nfiles && !status.cancel; ++n) { /* flush the final length to the header */ newfiles[n]->update_header(0, *now, xnow); sources.push_back(newfiles[n]); @@ -226,7 +274,7 @@ Session::import_audiofile (import_status& status) status.new_regions.push_back (r); } else { - for (n = 0; n < nfiles && !status.cancel; ++n) { + for (int n = 0; n < nfiles && !status.cancel; ++n) { /* flush the final length to the header */ @@ -261,7 +309,7 @@ Session::import_audiofile (import_status& status) } if (channel_data) { - for (n = 0; n < info.channels; ++n) { + for (int n = 0; n < info.channels; ++n) { delete [] channel_data[n]; } delete [] channel_data; @@ -276,116 +324,59 @@ Session::import_audiofile (import_status& status) } } - if (tmp_convert_file.length()) { - unlink(tmp_convert_file.c_str()); + if (importable) { + delete importable; } - - sf_close (in); + + sf_close (in); status.done = true; + return ret; } -string -Session::build_tmp_convert_name(string infile) +nframes_t +ResampledImportableSource::read (Sample* output, nframes_t nframes) { - string tmp_name(_path + "/." + Glib::path_get_basename (infile.c_str()) + "XXXXXX"); - char* tmp = new char[tmp_name.length() + 1]; - tmp_name.copy(tmp, string::npos); - tmp[tmp_name.length()] = 0; - mkstemp(tmp); - string outfile = tmp; - delete [] tmp; - - return outfile; -} + int err; -bool -Session::sample_rate_convert (import_status& status, string infile, string& outfile) -{ - float input [BLOCKSIZE] ; - float output [BLOCKSIZE] ; - - SF_INFO sf_info; - SRC_STATE* src_state ; - SRC_DATA src_data ; - int err ; - sf_count_t output_count = 0 ; - sf_count_t input_count = 0; - - SNDFILE* in = sf_open(infile.c_str(), SFM_READ, &sf_info); - if (!in) { - error << string_compose(_("Import/SRC: could not open input file: %1"), outfile) << endmsg; - return false; - } - sf_count_t total_input_frames = sf_info.frames; + /* If the input buffer is empty, refill it. */ - outfile = build_tmp_convert_name(infile); - SNDFILE* out = sf_open(outfile.c_str(), SFM_RDWR, &sf_info); - if (!out) { - error << string_compose(_("Import/SRC: could not open output file: %1"), outfile) << endmsg; - return false; - } - - sf_seek (in, 0, SEEK_SET) ; - sf_seek (out, 0, SEEK_SET) ; - - /* Initialize the sample rate converter. */ - if ((src_state = src_new (SRC_SINC_BEST_QUALITY, sf_info.channels, &err)) == 0) { - error << string_compose(_("Import: src_new() failed : %1"), src_strerror (err)) << endmsg ; - return false ; - } + if (src_data.input_frames == 0) { - 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 = (1.0 * frame_rate()) / sf_info.samplerate ; - - src_data.data_out = output ; - src_data.output_frames = BLOCKSIZE / sf_info.channels ; - - while (!status.cancel) { - /* If the input buffer is empty, refill it. */ - if (src_data.input_frames == 0) { - src_data.input_frames = sf_readf_float (in, input, BLOCKSIZE / sf_info.channels) ; - src_data.data_in = input ; - - /* The last read will not be a full buffer, so snd_of_input. */ - if (src_data.input_frames < (int)BLOCKSIZE / sf_info.channels) { - src_data.end_of_input = SF_TRUE ; - } - } + src_data.input_frames = ImportableSource::read (input, BLOCKSIZE); - if ((err = src_process (src_state, &src_data))) { - error << string_compose(_("Import: %1"), src_strerror (err)) << endmsg ; - return false ; - } + /* The last read will not be a full buffer, so set end_of_input. */ - /* Terminate if at end */ - if (src_data.end_of_input && src_data.output_frames_gen == 0) { - break ; - } + if ((nframes_t) src_data.input_frames < BLOCKSIZE) { + src_data.end_of_input = SF_TRUE ; + } - /* Write output. */ - sf_writef_float (out, output, src_data.output_frames_gen) ; - output_count += src_data.output_frames_gen ; - input_count += src_data.input_frames_used; + src_data.input_frames /= sf_info->channels; + src_data.data_in = input ; + } + + src_data.data_out = output; - src_data.data_in += src_data.input_frames_used * sf_info.channels ; - src_data.input_frames -= src_data.input_frames_used ; - - status.progress = (float) input_count / total_input_frames; + if (!src_data.end_of_input) { + src_data.output_frames = nframes / sf_info->channels ; + } else { + src_data.output_frames = src_data.input_frames; } - src_state = src_delete (src_state) ; - sf_close(in); - sf_close(out); - - if (status.cancel) { - return false; - } else { - return true ; + 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 * sf_info->channels ; + src_data.input_frames -= src_data.input_frames_used ; + + return src_data.output_frames_gen * sf_info->channels; } + diff --git a/libs/ardour/insert.cc b/libs/ardour/insert.cc index 8231cbbbe6..11d41cfab4 100644 --- a/libs/ardour/insert.cc +++ b/libs/ardour/insert.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include @@ -485,9 +484,11 @@ PluginInsert::protect_automation () switch (al.automation_state()) { case Write: - case Touch: al.set_automation_state (Off); break; + case Touch: + al.set_automation_state (Play); + break; default: break; } diff --git a/libs/ardour/io.cc b/libs/ardour/io.cc index 9442583379..f899b71d1e 100644 --- a/libs/ardour/io.cc +++ b/libs/ardour/io.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include @@ -29,6 +28,7 @@ #include #include +#include #include #include @@ -2101,6 +2101,12 @@ IO::set_name (string name, void* src) return 0; } + /* 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 (vector::iterator i = _inputs.begin(); i != _inputs.end(); ++i) { string current_name = (*i)->short_name(); current_name.replace (current_name.find (_name), _name.length(), name); diff --git a/libs/ardour/jack_slave.cc b/libs/ardour/jack_slave.cc index 2e03b2f45d..a06e295a09 100644 --- a/libs/ardour/jack_slave.cc +++ b/libs/ardour/jack_slave.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include diff --git a/libs/ardour/ladspa_plugin.cc b/libs/ardour/ladspa_plugin.cc index c96e14e30a..6d55423e37 100644 --- a/libs/ardour/ladspa_plugin.cc +++ b/libs/ardour/ladspa_plugin.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include @@ -165,6 +164,7 @@ LadspaPlugin::default_value (uint32_t port) float ret = 0.0f; bool bounds_given = false; bool sr_scaling = false; + bool earlier_hint = false; /* defaults - case 1 */ @@ -173,6 +173,7 @@ LadspaPlugin::default_value (uint32_t port) ret = prh[port].LowerBound; bounds_given = true; sr_scaling = true; + earlier_hint = true; } /* FIXME: add support for logarithmic defaults */ @@ -181,33 +182,41 @@ LadspaPlugin::default_value (uint32_t port) 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 */ @@ -260,7 +269,7 @@ LadspaPlugin::default_value (uint32_t port) /* defaults - case 5 */ - if (LADSPA_IS_HINT_SAMPLE_RATE(prh[port].HintDescriptor)) { + if (LADSPA_IS_HINT_SAMPLE_RATE(prh[port].HintDescriptor) && !earlier_hint) { if (bounds_given) { if (sr_scaling) { ret *= sample_rate; diff --git a/libs/ardour/location.cc b/libs/ardour/location.cc index bec87e5dd6..3d04c66824 100644 --- a/libs/ardour/location.cc +++ b/libs/ardour/location.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include @@ -662,7 +661,7 @@ struct LocationStartLaterComparison }; Location * -Locations::first_location_before (nframes_t frame) +Locations::first_location_before (nframes_t frame, bool include_special_ranges) { LocationList locs; @@ -677,6 +676,9 @@ Locations::first_location_before (nframes_t frame) /* 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); } @@ -686,7 +688,7 @@ Locations::first_location_before (nframes_t frame) } Location * -Locations::first_location_after (nframes_t frame) +Locations::first_location_after (nframes_t frame, bool include_special_ranges) { LocationList locs; @@ -701,6 +703,9 @@ Locations::first_location_after (nframes_t frame) /* 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); } @@ -710,7 +715,7 @@ Locations::first_location_after (nframes_t frame) } nframes_t -Locations::first_mark_before (nframes_t frame) +Locations::first_mark_before (nframes_t frame, bool include_special_ranges) { LocationList locs; @@ -725,6 +730,9 @@ Locations::first_mark_before (nframes_t frame) /* 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 */ @@ -747,7 +755,7 @@ Locations::first_mark_before (nframes_t frame) } nframes_t -Locations::first_mark_after (nframes_t frame) +Locations::first_mark_after (nframes_t frame, bool include_special_ranges) { LocationList locs; @@ -762,6 +770,9 @@ Locations::first_mark_after (nframes_t frame) /* 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 */ diff --git a/libs/ardour/macosx/English.lproj/InfoPlist.strings b/libs/ardour/macosx/English.lproj/InfoPlist.strings new file mode 100644 index 0000000000..0c0cacad8b Binary files /dev/null and b/libs/ardour/macosx/English.lproj/InfoPlist.strings differ diff --git a/libs/ardour/macosx/Info.plist b/libs/ardour/macosx/Info.plist new file mode 100644 index 0000000000..931491039f --- /dev/null +++ b/libs/ardour/macosx/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + ardour + CFBundleIconFile + + CFBundleIdentifier + com.apple.carbonframeworktemplate + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + FMWK + CFBundleSignature + ???? + CFBundleVersion + 1.0 + CFBundleShortVersionString + 1.01 + CSResourcesFileMapped + + + diff --git a/libs/ardour/macosx/ardour.xcodeproj/project.pbxproj b/libs/ardour/macosx/ardour.xcodeproj/project.pbxproj new file mode 100644 index 0000000000..4026b65f59 --- /dev/null +++ b/libs/ardour/macosx/ardour.xcodeproj/project.pbxproj @@ -0,0 +1,1214 @@ +// !$*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 = ""; }; + 32BAE0B70371A74B00C91783 /* ardour_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ardour_Prefix.pch; sourceTree = ""; }; + 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 = ""; }; + 696149E60B97CEF500ECBDF0 /* gmodule */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = gmodule; path = /Library/Frameworks/GLib.framework/Versions/2.12.3/Libraries/gmodule; sourceTree = ""; }; + 696149E70B97CEF500ECBDF0 /* gobject */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = gobject; path = /Library/Frameworks/GLib.framework/Versions/2.12.3/Libraries/gobject; sourceTree = ""; }; + 696149E80B97CEF500ECBDF0 /* gthread */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = gthread; path = /Library/Frameworks/GLib.framework/Versions/2.12.3/Libraries/gthread; sourceTree = ""; }; + 6964FEC80B8E7A7900799BAE /* version.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = version.h; sourceTree = ""; }; + 6964FEC90B8E7A7900799BAE /* version.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = version.cc; sourceTree = ""; }; + 696C8FAF0B8D526000D66CAF /* ardour.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ardour.h; sourceTree = ""; }; + 696C8FB00B8D526000D66CAF /* audio_diskstream.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = audio_diskstream.h; sourceTree = ""; }; + 696C8FB10B8D526000D66CAF /* audio_library.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = audio_library.h; sourceTree = ""; }; + 696C8FB20B8D526000D66CAF /* audio_track.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = audio_track.h; sourceTree = ""; }; + 696C8FB40B8D526000D66CAF /* audioengine.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = audioengine.h; sourceTree = ""; }; + 696C8FB50B8D526000D66CAF /* audiofilesource.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = audiofilesource.h; sourceTree = ""; }; + 696C8FB60B8D526000D66CAF /* audiofilter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = audiofilter.h; sourceTree = ""; }; + 696C8FB70B8D526000D66CAF /* audioplaylist.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = audioplaylist.h; sourceTree = ""; }; + 696C8FB80B8D526000D66CAF /* audioregion.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = audioregion.h; sourceTree = ""; }; + 696C8FB90B8D526000D66CAF /* audiosource.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = audiosource.h; sourceTree = ""; }; + 696C8FBA0B8D526000D66CAF /* auditioner.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = auditioner.h; sourceTree = ""; }; + 696C8FBB0B8D526000D66CAF /* automation_event.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = automation_event.h; sourceTree = ""; }; + 696C8FBC0B8D526000D66CAF /* buffer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = buffer.h; sourceTree = ""; }; + 696C8FBD0B8D526000D66CAF /* click.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = click.h; sourceTree = ""; }; + 696C8FBE0B8D526000D66CAF /* configuration.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = configuration.h; sourceTree = ""; }; + 696C8FBF0B8D526000D66CAF /* configuration_variable.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = configuration_variable.h; sourceTree = ""; }; + 696C8FC00B8D526000D66CAF /* configuration_vars.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = configuration_vars.h; sourceTree = ""; }; + 696C8FC10B8D526000D66CAF /* connection.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = connection.h; sourceTree = ""; }; + 696C8FC20B8D526000D66CAF /* control_protocol_manager.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = control_protocol_manager.h; sourceTree = ""; }; + 696C8FC40B8D526000D66CAF /* crossfade.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = crossfade.h; sourceTree = ""; }; + 696C8FC50B8D526000D66CAF /* crossfade_compare.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = crossfade_compare.h; sourceTree = ""; }; + 696C8FC60B8D526000D66CAF /* curve.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = curve.h; sourceTree = ""; }; + 696C8FC70B8D526000D66CAF /* cycle_timer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = cycle_timer.h; sourceTree = ""; }; + 696C8FC80B8D526000D66CAF /* cycles.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = cycles.h; sourceTree = ""; }; + 696C8FC90B8D526000D66CAF /* data_type.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = data_type.h; sourceTree = ""; }; + 696C8FCA0B8D526000D66CAF /* dB.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = dB.h; sourceTree = ""; }; + 696C8FCC0B8D526000D66CAF /* diskstream.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = diskstream.h; sourceTree = ""; }; + 696C8FCD0B8D526000D66CAF /* export.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = export.h; sourceTree = ""; }; + 696C8FCE0B8D526000D66CAF /* gain.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = gain.h; sourceTree = ""; }; + 696C8FCF0B8D526000D66CAF /* gdither.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = gdither.h; sourceTree = ""; }; + 696C8FD00B8D526000D66CAF /* gdither_types.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = gdither_types.h; sourceTree = ""; }; + 696C8FD10B8D526000D66CAF /* gdither_types_internal.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = gdither_types_internal.h; sourceTree = ""; }; + 696C8FD20B8D526000D66CAF /* insert.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = insert.h; sourceTree = ""; }; + 696C8FD30B8D526000D66CAF /* io.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = io.h; sourceTree = ""; }; + 696C8FD40B8D526000D66CAF /* ladspa.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ladspa.h; sourceTree = ""; }; + 696C8FD50B8D526000D66CAF /* ladspa_plugin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ladspa_plugin.h; sourceTree = ""; }; + 696C8FD60B8D526000D66CAF /* location.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = location.h; sourceTree = ""; }; + 696C8FD70B8D526000D66CAF /* logcurve.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = logcurve.h; sourceTree = ""; }; + 696C8FD80B8D526000D66CAF /* mix.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = mix.h; sourceTree = ""; }; + 696C8FD90B8D526000D66CAF /* named_selection.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = named_selection.h; sourceTree = ""; }; + 696C8FDA0B8D526000D66CAF /* noise.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = noise.h; sourceTree = ""; }; + 696C8FDB0B8D526000D66CAF /* osc.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = osc.h; sourceTree = ""; }; + 696C8FDC0B8D526000D66CAF /* panner.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = panner.h; sourceTree = ""; }; + 696C8FDD0B8D526000D66CAF /* pcm_utils.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = pcm_utils.h; sourceTree = ""; }; + 696C8FDE0B8D526000D66CAF /* peak.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = peak.h; sourceTree = ""; }; + 696C8FDF0B8D526000D66CAF /* playlist.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = playlist.h; sourceTree = ""; }; + 696C8FE00B8D526000D66CAF /* playlist_factory.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = playlist_factory.h; sourceTree = ""; }; + 696C8FE10B8D526000D66CAF /* playlist_templates.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = playlist_templates.h; sourceTree = ""; }; + 696C8FE20B8D526000D66CAF /* plugin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = plugin.h; sourceTree = ""; }; + 696C8FE30B8D526000D66CAF /* plugin_manager.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = plugin_manager.h; sourceTree = ""; }; + 696C8FE40B8D526000D66CAF /* port.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = port.h; sourceTree = ""; }; + 696C8FE50B8D526000D66CAF /* recent_sessions.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = recent_sessions.h; sourceTree = ""; }; + 696C8FE60B8D526000D66CAF /* redirect.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = redirect.h; sourceTree = ""; }; + 696C8FE70B8D526000D66CAF /* region.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = region.h; sourceTree = ""; }; + 696C8FE80B8D526000D66CAF /* region_factory.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = region_factory.h; sourceTree = ""; }; + 696C8FE90B8D526000D66CAF /* reverse.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = reverse.h; sourceTree = ""; }; + 696C8FEA0B8D526000D66CAF /* route.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = route.h; sourceTree = ""; }; + 696C8FEB0B8D526000D66CAF /* route_group.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = route_group.h; sourceTree = ""; }; + 696C8FEC0B8D526000D66CAF /* route_group_specialized.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = route_group_specialized.h; sourceTree = ""; }; + 696C8FED0B8D526000D66CAF /* send.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = send.h; sourceTree = ""; }; + 696C8FEE0B8D526000D66CAF /* session.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = session.h; sourceTree = ""; }; + 696C8FEF0B8D526000D66CAF /* session_connection.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = session_connection.h; sourceTree = ""; }; + 696C8FF00B8D526000D66CAF /* session_playlist.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = session_playlist.h; sourceTree = ""; }; + 696C8FF10B8D526000D66CAF /* session_region.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = session_region.h; sourceTree = ""; }; + 696C8FF20B8D526000D66CAF /* session_route.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = session_route.h; sourceTree = ""; }; + 696C8FF30B8D526000D66CAF /* session_selection.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = session_selection.h; sourceTree = ""; }; + 696C8FF40B8D526000D66CAF /* silentfilesource.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = silentfilesource.h; sourceTree = ""; }; + 696C8FF50B8D526000D66CAF /* slave.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = slave.h; sourceTree = ""; }; + 696C8FF60B8D526000D66CAF /* sndfile_helpers.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = sndfile_helpers.h; sourceTree = ""; }; + 696C8FF70B8D526000D66CAF /* sndfilesource.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = sndfilesource.h; sourceTree = ""; }; + 696C8FF80B8D526000D66CAF /* soundseq.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = soundseq.h; sourceTree = ""; }; + 696C8FF90B8D526000D66CAF /* source.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = source.h; sourceTree = ""; }; + 696C8FFA0B8D526000D66CAF /* source_factory.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = source_factory.h; sourceTree = ""; }; + 696C8FFB0B8D526000D66CAF /* spline.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = spline.h; sourceTree = ""; }; + 696C8FFC0B8D526000D66CAF /* tempo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = tempo.h; sourceTree = ""; }; + 696C8FFD0B8D526000D66CAF /* timestamps.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = timestamps.h; sourceTree = ""; }; + 696C8FFE0B8D526000D66CAF /* track.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = track.h; sourceTree = ""; }; + 696C8FFF0B8D526000D66CAF /* types.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = types.h; sourceTree = ""; }; + 696C90000B8D526000D66CAF /* utils.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = utils.h; sourceTree = ""; }; + 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 = ""; }; + 696C90F80B8D52F300D66CAF /* Jack.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Jack.framework; path = /Library/Frameworks/Jack.framework; sourceTree = ""; }; + 696C90F90B8D52F300D66CAF /* lo.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = lo.framework; path = /Library/Frameworks/lo.framework; sourceTree = ""; }; + 696C90FA0B8D52F300D66CAF /* LRdf.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = LRdf.framework; path = /Library/Frameworks/LRdf.framework; sourceTree = ""; }; + 696C90FB0B8D52F300D66CAF /* Raptor.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Raptor.framework; path = /Library/Frameworks/Raptor.framework; sourceTree = ""; }; + 696C90FC0B8D52F300D66CAF /* SampleRate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SampleRate.framework; path = /Library/Frameworks/SampleRate.framework; sourceTree = ""; }; + 696C90FD0B8D52F300D66CAF /* sigc.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = sigc.framework; path = /Library/Frameworks/sigc.framework; sourceTree = ""; }; + 696C90FE0B8D52F300D66CAF /* Sndfile-ardour.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = "Sndfile-ardour.framework"; path = "/Library/Frameworks/Sndfile-ardour.framework"; sourceTree = ""; }; + 696C90FF0B8D52F300D66CAF /* soundtouch.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = soundtouch.framework; path = /Library/Frameworks/soundtouch.framework; sourceTree = ""; }; + 697D98080B8DCD8C0006A892 /* libxml2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libxml2.dylib; path = /usr/lib/libxml2.dylib; sourceTree = ""; }; + 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 = ""; }; + 69B1B54F0B8E80AD007E41C1 /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = /System/Library/Frameworks/CoreAudio.framework; sourceTree = ""; }; + 69DBC41A0BA794A500C19E65 /* Accelerate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = /Developer/SDKs/MacOSX10.4u.sdk/System/Library/Frameworks/Accelerate.framework; sourceTree = ""; }; + 69DBC42A0BA7992800C19E65 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /Developer/SDKs/MacOSX10.4u.sdk/System/Library/Frameworks/Carbon.framework; sourceTree = ""; }; + 69F7CE520B8DCB3300D76871 /* basic_ui.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = basic_ui.cc; sourceTree = ""; }; + 69F7CE540B8DCB3300D76871 /* basic_ui.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = basic_ui.h; sourceTree = ""; }; + 69F7CE550B8DCB3300D76871 /* control_protocol.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = control_protocol.h; sourceTree = ""; }; + 69F7CE560B8DCB3300D76871 /* smpte.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = smpte.h; sourceTree = ""; }; + 69F7CE570B8DCB3300D76871 /* control_protocol.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = control_protocol.cc; sourceTree = ""; }; + 69F7CE590B8DCB3300D76871 /* smpte.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = smpte.cc; sourceTree = ""; }; + 8D07F2C70486CC7A007CD1D0 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; + 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 = ""; + }; + 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 = ""; + }; + 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 = ""; + }; + 089C1665FE841158C02AAC07 /* Resources */ = { + isa = PBXGroup; + children = ( + 8D07F2C70486CC7A007CD1D0 /* Info.plist */, + 089C1666FE841158C02AAC07 /* InfoPlist.strings */, + ); + name = Resources; + sourceTree = ""; + }; + 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 = ""; + }; + 691B3B780B8D5508009155B5 /* Products */ = { + isa = PBXGroup; + children = ( + 691B3B7C0B8D5508009155B5 /* pbd.framework */, + ); + name = Products; + sourceTree = ""; + }; + 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 = ""; + }; + 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 = ""; + }; +/* 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 = ""; + }; +/* 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 new file mode 100644 index 0000000000..b03e5d3d98 --- /dev/null +++ b/libs/ardour/macosx/ardour_Prefix.pch @@ -0,0 +1,4 @@ +// +// 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 new file mode 100644 index 0000000000..9da3d2c359 --- /dev/null +++ b/libs/ardour/macosx/version.cc @@ -0,0 +1,3 @@ +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 new file mode 100644 index 0000000000..9c575ee077 --- /dev/null +++ b/libs/ardour/macosx/version.h @@ -0,0 +1,17 @@ +/* + * 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/mix.cc b/libs/ardour/mix.cc index 6b7755e498..2d31c8ccc8 100644 --- a/libs/ardour/mix.cc +++ b/libs/ardour/mix.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include @@ -25,7 +24,6 @@ #include #if defined (ARCH_X86) && defined (BUILD_SSE_OPTIMIZATIONS) - // Debug wrappers float @@ -91,6 +89,25 @@ compute_peak (ARDOUR::Sample *buf, nframes_t nsamples, float current) return current; } +void +find_peaks (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 apply_gain_to_buffer (ARDOUR::Sample *buf, nframes_t nframes, float gain) { @@ -125,6 +142,13 @@ veclib_compute_peak (ARDOUR::Sample *buf, nframes_t nsamples, float current) return f_max(current, tmpmax); } +void +veclib_find_peaks (ARDOUR::Sample *buf, nframes_t nframes, float *min, float *max) +{ + vDSP_maxv (buf, 1, max, nframes); + vDSP_minv (buf, 1, min, nframes); +} + void veclib_apply_gain_to_buffer (ARDOUR::Sample *buf, nframes_t nframes, float gain) { diff --git a/libs/ardour/mtc_slave.cc b/libs/ardour/mtc_slave.cc index 0caa86196a..a86a3e9014 100644 --- a/libs/ardour/mtc_slave.cc +++ b/libs/ardour/mtc_slave.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include @@ -42,6 +41,8 @@ using namespace PBD; MTC_Slave::MTC_Slave (Session& s, MIDI::Port& p) : session (s) { + can_notify_on_unknown_rate = true; + rebind (p); reset (); } @@ -94,8 +95,39 @@ MTC_Slave::update_mtc_time (const byte *msg, bool was_full) smpte.minutes = msg[2]; smpte.seconds = msg[1]; smpte.frames = msg[0]; - - session.smpte_to_sample( smpte, mtc_frame, true, false ); + + 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) { diff --git a/libs/ardour/named_selection.cc b/libs/ardour/named_selection.cc index b5a71f6403..fbb4b748df 100644 --- a/libs/ardour/named_selection.cc +++ b/libs/ardour/named_selection.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include diff --git a/libs/ardour/osc.cc b/libs/ardour/osc.cc index 933fba8740..d999386005 100644 --- a/libs/ardour/osc.cc +++ b/libs/ardour/osc.cc @@ -15,7 +15,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - * $Id$ */ #include @@ -59,6 +58,11 @@ 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); @@ -109,16 +113,22 @@ OSC::start () 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()); } - // stop server thread - terminate_osc_thread(); - return 0; } diff --git a/libs/ardour/panner.cc b/libs/ardour/panner.cc index 09974a9529..563d4e90d4 100644 --- a/libs/ardour/panner.cc +++ b/libs/ardour/panner.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include @@ -654,10 +653,7 @@ Multi2dPanner::distribute (Sample* src, Sample** obufs, gain_t gain_coeff, nfram } pan = left * gain_coeff; - - for (; n < nframes; ++n) { - dst[n] += src[n] * pan; - } + Session::mix_buffers_with_gain(dst+n,src+n,nframes-n,pan); } else { @@ -667,20 +663,10 @@ Multi2dPanner::distribute (Sample* src, Sample** obufs, gain_t gain_coeff, nfram if ((pan *= gain_coeff) != 1.0f) { if (pan != 0.0f) { - - for (nframes_t n = 0; n < nframes; ++n) { - dst[n] += src[n] * pan; - } - + Session::mix_buffers_with_gain(dst,src,nframes,pan); } - - } else { - - for (nframes_t n = 0; n < nframes; ++n) { - dst[n] += src[n]; - } - + Session::mix_buffers_no_gain(dst,src,nframes); } #endif #ifdef CAN_INTERP diff --git a/libs/ardour/pcm_utils.cc b/libs/ardour/pcm_utils.cc index dd18fe8690..08d8a63d6e 100644 --- a/libs/ardour/pcm_utils.cc +++ b/libs/ardour/pcm_utils.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include diff --git a/libs/ardour/playlist.cc b/libs/ardour/playlist.cc index 19ff3894e8..807bcd23ca 100644 --- a/libs/ardour/playlist.cc +++ b/libs/ardour/playlist.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include @@ -75,6 +74,7 @@ Playlist::Playlist (Session& sess, string nom, bool hide) : _session (sess) { init (hide); + first_set_state = false; _name = nom; } @@ -109,6 +109,7 @@ Playlist::Playlist (boost::shared_ptr other, string namestr, boo _edit_mode = other->_edit_mode; in_set_state = 0; + first_set_state = false; in_flush = false; in_partition = false; subcnt = 0; @@ -181,6 +182,7 @@ Playlist::Playlist (boost::shared_ptr other, nframes_t start, nf } in_set_state--; + first_set_state = false; /* this constructor does NOT notify others (session) */ } @@ -221,6 +223,7 @@ Playlist::init (bool hide) g_atomic_int_set (&ignore_state_changes, 0); pending_modified = false; pending_length = false; + first_set_state = true; _refcnt = 0; _hidden = hide; _splicing = false; @@ -509,10 +512,10 @@ Playlist::add_region_internal (boost::shared_ptr region, nframes_t posit old_length = _get_maximum_extent(); } - if (!in_set_state) { + if (!first_set_state) { boost::shared_ptr foo (shared_from_this()); region->set_playlist (boost::weak_ptr(foo)); - } + } region->set_position (position, this); @@ -575,6 +578,11 @@ Playlist::remove_region_internal (boost::shared_ptrregion) old_length = _get_maximum_extent(); } + if (!in_set_state) { + /* unset playlist */ + region->set_playlist (boost::weak_ptr()); + } + for (i = regions.begin(); i != regions.end(); ++i) { if (*i == region) { @@ -1175,6 +1183,14 @@ Playlist::region_changed (Change what_changed, boost::shared_ptr region) return save; } +void +Playlist::drop_regions () +{ + RegionLock rl (this); + regions.clear (); + all_regions.clear (); +} + void Playlist::clear (bool with_signals) { @@ -1406,7 +1422,7 @@ Playlist::set_state (const XMLNode& node) } in_set_state--; - + first_set_state = false; return 0; } @@ -1504,17 +1520,33 @@ Playlist::bump_name_once (string name) string newname; if ((period = name.find_last_of ('.')) == string::npos) { - newname = name; + newname = name; newname += ".1"; } else { - char buf[32]; - int version; - - sscanf (name.substr (period+1).c_str(), "%d", &version); - snprintf (buf, sizeof(buf), "%d", version+1); + 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; + newname = name.substr (0, period+1); + newname += buf; + } } return newname; diff --git a/libs/ardour/playlist_factory.cc b/libs/ardour/playlist_factory.cc index 636b09213d..9cbdba0c79 100644 --- a/libs/ardour/playlist_factory.cc +++ b/libs/ardour/playlist_factory.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include diff --git a/libs/ardour/plugin.cc b/libs/ardour/plugin.cc index 3b471014eb..b1fb43fc8f 100644 --- a/libs/ardour/plugin.cc +++ b/libs/ardour/plugin.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include diff --git a/libs/ardour/plugin_manager.cc b/libs/ardour/plugin_manager.cc index 2a18de7d9d..5fa04c41f1 100644 --- a/libs/ardour/plugin_manager.cc +++ b/libs/ardour/plugin_manager.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include diff --git a/libs/ardour/port.cc b/libs/ardour/port.cc index 6f3a8f858a..4b0399702a 100644 --- a/libs/ardour/port.cc +++ b/libs/ardour/port.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include "ardour/port.h" diff --git a/libs/ardour/redirect.cc b/libs/ardour/redirect.cc index a5f6031f30..045faf6ebf 100644 --- a/libs/ardour/redirect.cc +++ b/libs/ardour/redirect.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include diff --git a/libs/ardour/region.cc b/libs/ardour/region.cc index 3e10df9dba..2b11bcc3df 100644 --- a/libs/ardour/region.cc +++ b/libs/ardour/region.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include @@ -738,7 +737,7 @@ Region::state (bool full_state) { XMLNode *node = new XMLNode ("Region"); char buf[64]; - char* fe; + char* fe = NULL; _id.print (buf, sizeof (buf)); node->add_property ("id", buf); @@ -760,6 +759,10 @@ Region::state (bool full_state) case EditChangesID: fe = X_("id"); break; + default: /* should be unreachable but makes g++ happy */ + cerr << "Odd region property found\n"; + fe = X_("nothing"); + break; } node->add_property ("first_edit", fe); diff --git a/libs/ardour/region_factory.cc b/libs/ardour/region_factory.cc index 5bcbdb8b80..631c27b42f 100644 --- a/libs/ardour/region_factory.cc +++ b/libs/ardour/region_factory.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id: playlist_factory.cc 629 2006-06-21 23:01:03Z paul $ */ #include diff --git a/libs/ardour/reverse.cc b/libs/ardour/reverse.cc index eb68a09049..fc58e161aa 100644 --- a/libs/ardour/reverse.cc +++ b/libs/ardour/reverse.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include @@ -47,10 +46,9 @@ Reverse::run (boost::shared_ptr region) { SourceList nsrcs; SourceList::iterator si; - const nframes_t blocksize = 256 * 1048; - Sample buf[blocksize]; + nframes_t blocksize = 256 * 1024; + Sample* buf = 0; nframes_t fpos; - nframes_t fend; nframes_t fstart; nframes_t to_read; int ret = -1; @@ -61,20 +59,19 @@ Reverse::run (boost::shared_ptr region) goto out; } - fend = region->start() + region->length(); fstart = region->start(); - if (blocksize < fend) { - fpos =max(fstart, fend - blocksize); - } else { - fpos = fstart; + if (blocksize > region->length()) { + blocksize = region->length(); } - to_read = min (region->length(), blocksize); + fpos = max (fstart, (fstart + region->length() - blocksize)); + buf = new Sample[blocksize]; + to_read = blocksize; /* now read it backwards */ - while (1) { + while (to_read) { uint32_t n; @@ -85,7 +82,7 @@ Reverse::run (boost::shared_ptr region) if (region->source (n)->read (buf, fpos, to_read) != to_read) { goto out; } - + /* swap memory order */ for (nframes_t i = 0; i < to_read/2; ++i) { @@ -99,13 +96,11 @@ Reverse::run (boost::shared_ptr region) } } - if (fpos == fstart) { - break; - } else if (fpos > fstart + to_read) { + if (fpos > fstart + blocksize) { fpos -= to_read; - to_read = min (fstart - fpos, blocksize); + to_read = blocksize; } else { - to_read = fpos-fstart; + to_read = fpos - fstart; fpos = fstart; } }; @@ -114,6 +109,10 @@ Reverse::run (boost::shared_ptr region) out: + if (buf) { + delete [] buf; + } + if (ret) { for (si = nsrcs.begin(); si != nsrcs.end(); ++si) { (*si)->mark_for_remove (); diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index d3097dd776..091ff549ad 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include @@ -79,7 +78,7 @@ Route::init () _soloed = false; _solo_safe = false; _phase_invert = false; - order_keys[N_("signal")] = order_key_cnt++; + order_keys[strdup (N_("signal"))] = order_key_cnt++; _active = true; _silent = false; _meter_point = MeterPostFader; @@ -113,7 +112,12 @@ Route::init () Route::~Route () { - clear_redirects (this); + clear_redirects (PreFader, this); + clear_redirects (PostFader, this); + + for (OrderKeys::iterator i = order_keys.begin(); i != order_keys.end(); ++i) { + free ((void*)(i->first)); + } if (_control_outs) { delete _control_outs; @@ -136,21 +140,23 @@ Route::remote_control_id() const } long -Route::order_key (string name) const +Route::order_key (const char* name) const { OrderKeys::const_iterator i; - if ((i = order_keys.find (name)) == order_keys.end()) { - return -1; + for (i = order_keys.begin(); i != order_keys.end(); ++i) { + if (!strcmp (name, i->first)) { + return i->second; + } } - return (*i).second; + return -1; } void -Route::set_order_key (string name, long n) +Route::set_order_key (const char* name, long n) { - order_keys[name] = n; + order_keys[strdup(name)] = n; _session.set_dirty (); } @@ -919,10 +925,13 @@ Route::add_redirects (const RedirectList& others, void *src, uint32_t* err_strea return 0; } +/** Remove redirects with a given placement. + * @param p Placement of redirects to remove. + */ void -Route::clear_redirects (void *src) +Route::clear_redirects (Placement p, void *src) { - uint32_t old_rmo = redirect_max_outs; + const uint32_t old_rmo = redirect_max_outs; if (!_session.engine().connected()) { return; @@ -930,13 +939,22 @@ Route::clear_redirects (void *src) { Glib::RWLock::WriterLock lm (redirect_lock); - RedirectList::iterator i; - for (i = _redirects.begin(); i != _redirects.end(); ++i) { - (*i)->drop_references (); + RedirectList new_list; + + for (RedirectList::iterator i = _redirects.begin(); i != _redirects.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); + } } - _redirects.clear (); + + _redirects = new_list; } + /* FIXME: can't see how this test can ever fire */ if (redirect_max_outs != old_rmo) { reset_panner (); } @@ -1147,9 +1165,16 @@ Route::_reset_plugin_counts (uint32_t* err_streams) } else { s->expect_inputs ((*prev)->output_streams()); } - } - redirect_max_outs = max ((*r)->output_streams (), redirect_max_outs); + } else { + + /* don't pay any attention to send output configuration, since it doesn't + affect the route. + */ + + redirect_max_outs = max ((*r)->output_streams (), redirect_max_outs); + + } } /* we're done */ @@ -1297,8 +1322,12 @@ Route::all_redirects_flip () } } +/** Set all redirects with a given placement to a given active state. + * @param p Placement of redirects to change. + * @param state New active state for those redirects. + */ void -Route::all_redirects_active (bool state) +Route::all_redirects_active (Placement p, bool state) { Glib::RWLock::ReaderLock lm (redirect_lock); @@ -1307,7 +1336,9 @@ Route::all_redirects_active (bool state) } for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) { - (*i)->set_active (state, this); + if ((*i)->placement() == p) { + (*i)->set_active (state, this); + } } } @@ -1389,7 +1420,7 @@ Route::state(bool full_state) OrderKeys::iterator x = order_keys.begin(); while (x != order_keys.end()) { - order_string += (*x).first; + order_string += string ((*x).first); order_string += '='; snprintf (buf, sizeof(buf), "%ld", (*x).second); order_string += buf; @@ -1408,6 +1439,11 @@ Route::state(bool 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)); @@ -1604,7 +1640,7 @@ Route::_set_state (const XMLNode& node, bool call_base) error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining) << endmsg; } else { - set_order_key (remaining.substr (0, equal), n); + set_order_key (remaining.substr (0, equal).c_str(), n); } } @@ -1701,6 +1737,13 @@ Route::_set_state (const XMLNode& node, bool call_base) _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) { @@ -2284,8 +2327,9 @@ Route::protect_automation () { switch (gain_automation_state()) { case Write: - case Touch: set_gain_automation_state (Off); + case Touch: + set_gain_automation_state (Play); break; default: break; @@ -2293,9 +2337,11 @@ Route::protect_automation () switch (panner().automation_state ()) { case Write: - case Touch: panner().set_automation_state (Off); break; + case Touch: + panner().set_automation_state (Play); + break; default: break; } diff --git a/libs/ardour/route_group.cc b/libs/ardour/route_group.cc index c2aa59ed8b..13b90474cc 100644 --- a/libs/ardour/route_group.cc +++ b/libs/ardour/route_group.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #define __STDC_FORMAT_MACROS diff --git a/libs/ardour/send.cc b/libs/ardour/send.cc index 7888f89d41..faafa3295e 100644 --- a/libs/ardour/send.cc +++ b/libs/ardour/send.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 9b09f45ee8..8f61fc9ac1 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include @@ -50,7 +49,6 @@ #include #include #include -#include #include #include #include @@ -80,6 +78,12 @@ 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 + const char* Session::_template_suffix = X_(".template"); const char* Session::_statefile_suffix = X_(".ardour"); const char* Session::_pending_suffix = X_(".pending"); @@ -88,8 +92,10 @@ const char* Session::sound_dir_name = X_("audiofiles"); const char* Session::peak_dir_name = X_("peaks"); const char* Session::dead_sound_dir_name = X_("dead_sounds"); const char* Session::interchange_dir_name = X_("interchange"); +const char* Session::export_dir_name = X_("export"); -Session::compute_peak_t Session::compute_peak = 0; +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; @@ -270,6 +276,10 @@ Session::Session (AudioEngine &eng, { 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(); @@ -328,6 +338,10 @@ Session::Session (AudioEngine &eng, { 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(); @@ -1388,7 +1402,7 @@ Session::set_block_size (nframes_t nframes) uint32_t np; current_block_size = nframes; - + for (np = 0, i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i, ++np) { free (*i); } @@ -1409,7 +1423,7 @@ Session::set_block_size (nframes_t nframes) #ifdef NO_POSIX_MEMALIGN buf = (Sample *) malloc(current_block_size * sizeof(Sample)); #else - posix_memalign((void **)&buf,16,current_block_size * 4); + posix_memalign((void **)&buf,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample)); #endif *i = buf; @@ -1684,16 +1698,19 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod } else { nphysical_out = 0; } + + shared_ptr track; try { - shared_ptr track (new AudioTrack (*this, track_name, Route::Flag (0), mode)); + track = boost::shared_ptr((new AudioTrack (*this, track_name, Route::Flag (0), mode))); if (track->ensure_io (input_channels, 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() && x < nphysical_in; ++x) { @@ -1753,14 +1770,43 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod catch (failed_constructor &err) { error << _("Session: could not create new audio track.") << endmsg; - // XXX should we delete the tracks already created? - ret.clear (); - return ret; + + 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 writer (diskstreams); + boost::shared_ptr 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 writer (diskstreams); + boost::shared_ptr ds = writer.get_copy(); + ds->remove (track->audio_diskstream()); + } + } + + goto failed; + } + --how_many; } + failed: if (!new_routes.empty()) { add_routes (new_routes, false); save_state (_current_snapshot_name); @@ -1769,6 +1815,27 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod return ret; } +void +Session::set_remote_control_ids () +{ + RemoteModel m = Config->get_remote_model(); + + shared_ptr 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) { @@ -1786,7 +1853,7 @@ Session::new_audio_route (int input_channels, int output_channels, uint32_t how_ for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { if (dynamic_cast((*i).get()) == 0) { - if (!(*i)->hidden()) { + if (!(*i)->hidden() && (*i)->name() != _("master")) { bus_id++; } } @@ -1803,15 +1870,13 @@ Session::new_audio_route (int input_channels, int output_channels, uint32_t how_ while (how_many) { do { - ++bus_id; - snprintf (bus_name, sizeof(bus_name), "Bus %" PRIu32, bus_id); if (route_by_name (bus_name) == 0) { break; } - } while (bus_id < (UINT_MAX-1)); + } while (++bus_id < (UINT_MAX-1)); try { shared_ptr bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO)); @@ -1820,6 +1885,7 @@ Session::new_audio_route (int input_channels, int output_channels, uint32_t how_ 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(); ++x) { @@ -1871,13 +1937,19 @@ Session::new_audio_route (int input_channels, int output_channels, uint32_t how_ catch (failed_constructor &err) { error << _("Session: could not create new audio route.") << endmsg; - ret.clear (); - return ret; + 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, false); save_state (_current_snapshot_name); @@ -1928,21 +2000,23 @@ void Session::add_diskstream (boost::shared_ptr dstream) { /* need to do this in case we're rolling at the time, to prevent false underruns */ - dstream->do_refill_with_alloc(); + dstream->do_refill_with_alloc (); - { + dstream->set_block_size (current_block_size); + + { RCUWriter writer (diskstreams); boost::shared_ptr ds = writer.get_copy(); ds->push_back (dstream); - } - - dstream->set_block_size (current_block_size); + /* 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 @@ -2125,9 +2199,11 @@ Session::route_solo_changed (void* src, boost::weak_ptr wpr) modify_solo_mute (is_track, same_thing_soloed); if (signal) { - SoloActive (currently_soloing); + SoloActive (currently_soloing); /* EMIT SIGNAL */ } + SoloChanged (); /* EMIT SIGNAL */ + set_dirty(); } @@ -2763,6 +2839,24 @@ Session::source_by_id (const PBD::ID& id) return source; } + +boost::shared_ptr +Session::source_by_path_and_channel (const Glib::ustring& path, uint16_t chn) +{ + Glib::Mutex::Lock lm (audio_source_lock); + + for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) { + cerr << "comparing " << path << " with " << i->second->name() << endl; + boost::shared_ptr afs = boost::dynamic_pointer_cast(i->second); + + if (afs && afs->path() == path && chn == afs->channel()) { + return afs; + } + + } + return boost::shared_ptr(); +} + string Session::peak_path_from_audio_path (string audio_path) const { @@ -3278,7 +3372,7 @@ void Session::graph_reordered () { /* don't do this stuff if we are setting up connections - from a set_state() call. + from a set_state() call or creating new tracks. */ if (_state_of_the_state & InitialConnecting) { @@ -3405,11 +3499,11 @@ Session::available_capture_duration () switch (Config->get_native_file_data_format()) { case FormatFloat: - sample_bytes_on_disk = 4; + sample_bytes_on_disk = 4.0; break; case FormatInt24: - sample_bytes_on_disk = 3; + sample_bytes_on_disk = 3.0; break; default: @@ -3493,7 +3587,7 @@ Session::ensure_passthru_buffers (uint32_t howmany) #ifdef NO_POSIX_MEMALIGN p = (Sample *) malloc(current_block_size * sizeof(Sample)); #else - posix_memalign((void **)&p,16,current_block_size * 4); + posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample)); #endif _passthru_buffers.push_back (p); @@ -3502,7 +3596,7 @@ Session::ensure_passthru_buffers (uint32_t howmany) #ifdef NO_POSIX_MEMALIGN p = (Sample *) malloc(current_block_size * sizeof(Sample)); #else - posix_memalign((void **)&p,16,current_block_size * 4); + posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * 4); #endif memset (p, 0, sizeof (Sample) * current_block_size); _silent_buffers.push_back (p); @@ -3512,7 +3606,7 @@ Session::ensure_passthru_buffers (uint32_t howmany) #ifdef NO_POSIX_MEMALIGN p = (Sample *) malloc(current_block_size * sizeof(Sample)); #else - posix_memalign((void **)&p,16,current_block_size * 4); + posix_memalign((void **)&p,CPU_CACHE_ALIGN,current_block_size * sizeof(Sample)); #endif memset (p, 0, sizeof (Sample) * current_block_size); _send_buffers.push_back (p); @@ -3530,7 +3624,6 @@ Session::next_insert_id () for (boost::dynamic_bitset::size_type n = 0; n < insert_bitset.size(); ++n) { if (!insert_bitset[n]) { insert_bitset[n] = true; - cerr << "Returning " << n << " as insert ID\n"; return n; } @@ -3551,7 +3644,6 @@ Session::next_send_id () for (boost::dynamic_bitset::size_type n = 0; n < send_bitset.size(); ++n) { if (!send_bitset[n]) { send_bitset[n] = true; - cerr << "Returning " << n << " as send ID\n"; return n; } @@ -3792,11 +3884,15 @@ Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t le #ifdef NO_POSIX_MEMALIGN b = (Sample *) malloc(chunk_size * sizeof(Sample)); #else - posix_memalign((void **)&b,16,chunk_size * 4); + posix_memalign((void **)&b,4096,chunk_size * sizeof(Sample)); #endif buffers.push_back (b); } + for (vector >::iterator src=srcs.begin(); src != srcs.end(); ++src) { + (*src)->prepare_for_peakfile_writes (); + } + while (to_do && !itt.cancel) { this_chunk = min (to_do, chunk_size); @@ -3835,18 +3931,10 @@ Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t le if (afs) { afs->update_header (position, *xnow, now); + afs->flush_header (); } } - /* build peakfile for new source */ - - for (vector >::iterator src=srcs.begin(); src != srcs.end(); ++src) { - boost::shared_ptr afs = boost::dynamic_pointer_cast(*src); - if (afs) { - afs->build_peaks (); - } - } - /* construct a region to represent the bounced material */ boost::shared_ptr aregion = RegionFactory::create (srcs, 0, srcs.front()->length(), @@ -3866,6 +3954,11 @@ Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t le (*src)->drop_references (); } + + } else { + for (vector >::iterator src = srcs.begin(); src != srcs.end(); ++src) { + (*src)->done_with_peakfile_writes (); + } } for (vector::iterator i = buffers.begin(); i != buffers.end(); ++i) { diff --git a/libs/ardour/session_butler.cc b/libs/ardour/session_butler.cc index bb02eede91..afb284b0f4 100644 --- a/libs/ardour/session_butler.cc +++ b/libs/ardour/session_butler.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include @@ -104,10 +103,12 @@ Session::start_butler_thread () void Session::terminate_butler_thread () { - void* status; - char c = ButlerRequest::Quit; - ::write (butler_request_pipe[1], &c, 1); - pthread_join (butler_thread, &status); + if (butler_thread) { + void* status; + char c = ButlerRequest::Quit; + ::write (butler_request_pipe[1], &c, 1); + pthread_join (butler_thread, &status); + } } void @@ -247,7 +248,7 @@ Session::butler_thread_work () gettimeofday (&begin, 0); boost::shared_ptr dsl = diskstreams.reader (); - + for (i = dsl->begin(); !transport_work_requested() && butler_should_run && i != dsl->end(); ++i) { boost::shared_ptr ds = *i; diff --git a/libs/ardour/session_click.cc b/libs/ardour/session_click.cc index 38cc27be0b..f2064ab731 100644 --- a/libs/ardour/session_click.cc +++ b/libs/ardour/session_click.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include diff --git a/libs/ardour/session_command.cc b/libs/ardour/session_command.cc index 1ecf4fce8d..ef2196ed13 100644 --- a/libs/ardour/session_command.cc +++ b/libs/ardour/session_command.cc @@ -392,7 +392,7 @@ Session::GlobalMeteringStateCommand::get_state() if (r) { child->add_property (X_("id"), r->id().to_s()); - const char* meterstr; + const char* meterstr = 0; switch (x->second) { case MeterInput: @@ -404,6 +404,8 @@ Session::GlobalMeteringStateCommand::get_state() 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); @@ -430,6 +432,7 @@ Session::GlobalMeteringStateCommand::get_state() case MeterPostFader: meterstr = X_("post"); break; + default: meterstr = ""; } child->add_property (X_("meter"), meterstr); diff --git a/libs/ardour/session_control.cc b/libs/ardour/session_control.cc deleted file mode 100644 index afecc146b7..0000000000 --- a/libs/ardour/session_control.cc +++ /dev/null @@ -1,30 +0,0 @@ - -#include -#include -#include -#include - -using namespace ARDOUR; - -void -Session::initialize_control () -{ - GenericMidiControlProtocol* midi_protocol = new GenericMidiControlProtocol (*this); - - if (midi_protocol->init() == 0) { - control_protocols.push_back (midi_protocol); - } - - if (Config->get_use_tranzport()) { - cerr << "Creating new tranzport control" << endl; - - TranzportControlProtocol* tranzport_protocol = new TranzportControlProtocol (*this); - - cerr << "Initializing new tranzport control" << endl; - - if (tranzport_protocol->init() == 0) { - control_protocols.push_back (tranzport_protocol); - } - } -} - diff --git a/libs/ardour/session_events.cc b/libs/ardour/session_events.cc index 4a2800dcb1..e93a7a5f17 100644 --- a/libs/ardour/session_events.cc +++ b/libs/ardour/session_events.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include diff --git a/libs/ardour/session_export.cc b/libs/ardour/session_export.cc index 8286934358..87bf5a5b03 100644 --- a/libs/ardour/session_export.cc +++ b/libs/ardour/session_export.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ /* see gdither.cc for why we have to do this */ @@ -268,7 +267,7 @@ AudioExportSpecification::process (nframes_t nframes) char errbuf[256]; nframes_t to_write = 0; int cnt = 0; - + do { /* now do sample rate conversion */ @@ -428,8 +427,6 @@ AudioExportSpecification::process (nframes_t nframes) int Session::start_audio_export (AudioExportSpecification& spec) { - int ret; - if (spec.prepare (current_block_size, frame_rate())) { return -1; } @@ -437,40 +434,21 @@ Session::start_audio_export (AudioExportSpecification& spec) 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)); - if ((ret = _engine.freewheel (true)) == 0) { - spec.running = true; - spec.do_freewheel = false; - } - - return ret; + return _engine.freewheel (true); } int Session::stop_audio_export (AudioExportSpecification& spec) { - /* 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 */ + /* don't stop freewheeling but do stop paying attention to it for now */ - if (post_export_slave != None) { - Config->set_slave_source (post_export_slave); - } else { - locate (post_export_position, false, false, false); - } - - spec.clear (); - _exporting = false; - - spec.running = false; + spec.freewheel_connection.disconnect (); + spec.clear (); /* resets running/stop etc */ return 0; } @@ -640,3 +618,25 @@ Session::process_export (nframes_t nframes, AudioExportSpecification* spec) 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 index 1fd8389e11..2bb9886f50 100644 --- a/libs/ardour/session_feedback.cc +++ b/libs/ardour/session_feedback.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include diff --git a/libs/ardour/session_midi.cc b/libs/ardour/session_midi.cc index 8a553fb12d..f58098d9d1 100644 --- a/libs/ardour/session_midi.cc +++ b/libs/ardour/session_midi.cc @@ -16,7 +16,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include @@ -126,9 +125,20 @@ Session::set_mtc_port (string port_tag) return 0; } +void +Session::set_mmc_device_id (uint32_t device_id) +{ + if (mmc) { + mmc->set_device_id (device_id); + } +} + int Session::set_mmc_port (string port_tag) { + MIDI::byte old_device_id = 0; + bool reset_id = false; + if (port_tag.length() == 0) { if (_mmc_port == 0) { return 0; @@ -146,6 +156,8 @@ Session::set_mmc_port (string port_tag) _mmc_port = port; if (mmc) { + old_device_id = mmc->device_id(); + reset_id = true; delete mmc; } @@ -153,6 +165,9 @@ Session::set_mmc_port (string port_tag) MMC_CommandSignature, MMC_ResponseSignature); + if (reset_id) { + mmc->set_device_id (old_device_id); + } mmc->Play.connect (mem_fun (*this, &Session::mmc_deferred_play)); @@ -181,6 +196,7 @@ Session::set_mmc_port (string port_tag) 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)); @@ -382,24 +398,6 @@ Session::setup_midi_control () mtc_msg[10] = 0xf1; mtc_msg[12] = 0xf1; mtc_msg[14] = 0xf1; - - if (_mmc_port != 0) { - - Config->set_send_mmc (session_send_mmc); - - } else { - - mmc = 0; - session_send_mmc = false; - } - - if (_mtc_port != 0) { - - Config->set_send_mtc (session_send_mtc); - - } else { - session_send_mtc = false; - } } int @@ -543,7 +541,6 @@ Session::mmc_pause (MIDI::MachineControl &mmc) static bool step_queued = false; void - Session::mmc_step (MIDI::MachineControl &mmc, int steps) { if (!Config->get_mmc_control()) { @@ -1099,15 +1096,17 @@ Session::start_midi_thread () void Session::terminate_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); + 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 diff --git a/libs/ardour/session_process.cc b/libs/ardour/session_process.cc index 06ba4e304e..055cbcf82d 100644 --- a/libs/ardour/session_process.cc +++ b/libs/ardour/session_process.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include @@ -211,6 +210,9 @@ Session::commit_diskstreams (nframes_t nframes, bool &needs_butler) } /* 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) { @@ -285,7 +287,7 @@ Session::process_with_events (nframes_t nframes) return; } - end_frame = _transport_frame + nframes; + end_frame = _transport_frame + (nframes_t)abs(floor(nframes * _transport_speed)); { Event* this_event; @@ -331,20 +333,15 @@ Session::process_with_events (nframes_t nframes) while (nframes) { - if (this_event == 0 || this_event->action_frame > end_frame || this_event->action_frame < _transport_frame) { + this_nframes = nframes; /* real (jack) time relative */ + frames_moved = (long) floor (_transport_speed * nframes); /* transport relative */ - this_nframes = nframes; - - } else { - - /* compute nframes to next event */ - - if (this_event->action_frame < end_frame) { - this_nframes = nframes - (end_frame - this_event->action_frame); - } else { - this_nframes = nframes; - } - } + /* 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) { @@ -363,8 +360,6 @@ Session::process_with_events (nframes_t nframes) nframes -= this_nframes; offset += this_nframes; - frames_moved = (nframes_t) floor (_transport_speed * this_nframes); - if (frames_moved < 0) { decrement_transport_position (-frames_moved); } else { @@ -396,8 +391,7 @@ Session::process_with_events (nframes_t nframes) } /* this is necessary to handle the case of seamless looping */ - /* not sure if it will work in conjuction with varispeed */ - end_frame = _transport_frame + nframes; + end_frame = _transport_frame + (nframes_t) floor (nframes * _transport_speed); } diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index 42aac479a1..119d2c858d 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include @@ -64,7 +63,8 @@ #include #include #include -#include +#include +#include #include #include #include @@ -131,6 +131,7 @@ Session::first_stage_init (string fullpath, string snapshot_name) 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; @@ -183,6 +184,8 @@ Session::first_stage_init (string fullpath, string snapshot_name) 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(); @@ -465,11 +468,16 @@ Session::create (bool& new_session, string* mix_template, nframes_t initial_leng return -1; } - dir = sound_dir (); + /* if this is is an existing session with an old "sounds" directory, just use it. see Session::sound_dir() for more details */ - 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; + if (!Glib::file_test (old_sound_dir(), Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_DIR)) { + + dir = sound_dir (); + + 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 = dead_sound_dir (); @@ -486,6 +494,13 @@ Session::create (bool& new_session, string* mix_template, nframes_t initial_leng return -1; } + dir = export_dir (); + + if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) { + error << string_compose(_("Session: cannot create session export dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg; + return -1; + } + /* check new_session so we don't overwrite an existing one */ @@ -578,6 +593,48 @@ Session::remove_pending_capture_state () unlink (xml_path.c_str()); } +/** 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_path = _path + old_name + _statefile_suffix; + const string new_xml_path = _path + new_name + _statefile_suffix; + + if (rename (old_xml_path.c_str(), new_xml_path.c_str()) != 0) { + error << string_compose(_("could not rename snapshot %1 to %2"), old_name, new_name) << 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; + } + + const string xml_path = _path + snapshot_name + _statefile_suffix; + + /* make a backup copy of the state file */ + const string bak_path = xml_path + ".bak"; + if (g_file_test (xml_path.c_str(), G_FILE_TEST_EXISTS)) { + copy_file (xml_path, bak_path); + } + + /* and delete it */ + unlink (xml_path.c_str()); +} + int Session::save_state (string snapshot_name, bool pending) { @@ -603,10 +660,12 @@ Session::save_state (string snapshot_name, bool pending) if (!pending) { + /* proper save: use _statefile_suffix (.ardour in English) */ xml_path = _path; xml_path += snapshot_name; xml_path += _statefile_suffix; + /* make a backup copy of the old file */ bak_path = xml_path; bak_path += ".bak"; @@ -616,6 +675,7 @@ Session::save_state (string snapshot_name, bool pending) } else { + /* pending save: use _pending_suffix (.pending in English) */ xml_path = _path; xml_path += snapshot_name; xml_path += _pending_suffix; @@ -1391,6 +1451,19 @@ Session::XMLRegionFactory (const XMLNode& node, bool full) try { boost::shared_ptr region (boost::dynamic_pointer_cast (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 sfp = boost::dynamic_pointer_cast (*sx); + if (sfp) { + sfp->set_length (region->length()); + } + } + } + + return region; } @@ -1430,11 +1503,16 @@ Session::path_from_region_name (string name, string identifier) } else { snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 ".wav", dir.c_str(), name.c_str(), n); } - if (access (buf, F_OK) != 0) { + + if (!g_file_test (buf, G_FILE_TEST_EXISTS)) { return buf; } } + 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 ""; } @@ -1452,10 +1530,16 @@ Session::load_sources (const XMLNode& node) for (niter = nlist.begin(); niter != nlist.end(); ++niter) { - if ((source = XMLSourceFactory (**niter)) == 0) { - error << _("Session: cannot create Source from XML description.") << endmsg; + 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; @@ -1471,7 +1555,7 @@ Session::XMLSourceFactory (const XMLNode& node) try { return SourceFactory::create (*this, node); } - + catch (failed_constructor& err) { error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg; return boost::shared_ptr(); @@ -1820,36 +1904,34 @@ Session::dead_sound_dir () const { string res = _path; res += dead_sound_dir_name; - res += '/'; + return res; } string -Session::sound_dir (bool with_path) const +Session::old_sound_dir (bool with_path) const { - /* support old session structure */ + string res; - struct stat statbuf; - string old_nopath; - string old_withpath; + if (with_path) { + res = _path; + } - old_nopath += old_sound_dir_name; - old_nopath += '/'; - - old_withpath = _path; - old_withpath += old_sound_dir_name; + res += old_sound_dir_name; - if (stat (old_withpath.c_str(), &statbuf) == 0) { - if (with_path) - return old_withpath; - - return old_nopath; - } + return res; +} +string +Session::sound_dir (bool with_path) const +{ string res; + string full; if (with_path) { res = _path; + } else { + full = _path; } res += interchange_dir_name; @@ -1858,6 +1940,38 @@ Session::sound_dir (bool with_path) const res += '/'; res += sound_dir_name; + if (with_path) { + full = res; + } else { + full += res; + } + + /* if this already exists, don't check for the old session sound directory */ + + if (Glib::file_test (full, Glib::FILE_TEST_IS_DIR|Glib::FILE_TEST_EXISTS)) { + return res; + } + + /* possibly support old session structure */ + + string old_nopath; + string old_withpath; + + old_nopath += old_sound_dir_name; + old_nopath += '/'; + + old_withpath = _path; + old_withpath += old_sound_dir_name; + + if (Glib::file_test (old_withpath.c_str(), Glib::FILE_TEST_IS_DIR|Glib::FILE_TEST_EXISTS)) { + if (with_path) + return old_withpath; + + return old_nopath; + } + + /* ok, old "sounds" directory isn't there, return the new path */ + return res; } @@ -1887,6 +2001,15 @@ Session::template_dir () return path; } +string +Session::export_dir () const +{ + string res = _path; + res += export_dir_name; + res += '/'; + return res; +} + string Session::suffixed_search_path (string suffix, bool data) { @@ -2566,6 +2689,9 @@ Session::cleanup_sources (Session::cleanup_report& rep) } } + char tmppath1[PATH_MAX+1]; + char tmppath2[PATH_MAX+1]; + for (vector::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) { used = false; @@ -2573,7 +2699,10 @@ Session::cleanup_sources (Session::cleanup_report& rep) for (set::iterator i = all_sources.begin(); i != all_sources.end(); ++i) { - if (spath == *i) { + realpath(spath.c_str(), tmppath1); + realpath((*i).c_str(), tmppath2); + + if (strcmp(tmppath1, tmppath2) == 0) { used = true; break; } @@ -2601,7 +2730,7 @@ Session::cleanup_sources (Session::cleanup_report& rep) on whichever filesystem it was already on. */ - if (_path.find ("/sounds/")) { + if ((*x).find ("/sounds/") != string::npos) { /* old school, go up 1 level */ @@ -2796,6 +2925,12 @@ Session::set_deletion_in_progress () void Session::add_controllable (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); } @@ -3029,6 +3164,12 @@ Session::config_changed (const char* parameter_name) poke_midi_thread (); + } else if (PARAM_IS ("mmc-device-id")) { + + if (mmc) { + mmc->set_device_id (Config->get_mmc_device_id()); + } + } else if (PARAM_IS ("midi-control")) { poke_midi_thread (); @@ -3087,6 +3228,8 @@ Session::config_changed (const char* parameter_name) /* mark us ready to send */ next_quarter_frame_to_send = 0; } + } else { + session_send_mtc = false; } } else if (PARAM_IS ("send-mmc")) { @@ -3097,6 +3240,9 @@ Session::config_changed (const char* parameter_name) if (_mmc_port != 0) { session_send_mmc = Config->get_send_mmc(); + } else { + mmc = 0; + session_send_mmc = false; } } else if (PARAM_IS ("midi-feedback")) { @@ -3131,6 +3277,8 @@ Session::config_changed (const char* parameter_name) } else if (PARAM_IS ("slave-source")) { set_slave_source (Config->get_slave_source()); + } else if (PARAM_IS ("remote-model")) { + set_remote_control_ids (); } set_dirty (); diff --git a/libs/ardour/session_time.cc b/libs/ardour/session_time.cc index e7bd0a3696..9ae3492ea7 100644 --- a/libs/ardour/session_time.cc +++ b/libs/ardour/session_time.cc @@ -16,7 +16,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include @@ -26,6 +25,7 @@ #include #include +#include #include #include diff --git a/libs/ardour/session_timefx.cc b/libs/ardour/session_timefx.cc index d7274388aa..37b0aa1d48 100644 --- a/libs/ardour/session_timefx.cc +++ b/libs/ardour/session_timefx.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include @@ -50,6 +49,9 @@ Session::tempoize_region (TimeStretchRequest& tsr) float percentage; nframes_t total_frames; nframes_t done; + int c; + char buf[64]; + string::size_type len; /* the soundtouch code wants a *tempo* change percentage, which is of opposite sign to the length change. @@ -73,8 +75,18 @@ Session::tempoize_region (TimeStretchRequest& tsr) done = 0; for (uint32_t i = 0; i < tsr.region->n_channels(); ++i) { - string path = path_from_region_name (PBD::basename_nosuffix (names[i]), ident); + string rstr; + string::size_type existing_ident; + + if ((existing_ident = names[i].find (ident)) != string::npos) { + rstr = names[i].substr (0, existing_ident); + } else { + rstr = names[i]; + } + + string path = path_from_region_name (PBD::basename_nosuffix (rstr), ident); + if (path.length() == 0) { error << string_compose (_("tempoize: error creating name for new audio file based on %1"), tsr.region->name()) << endmsg; @@ -88,6 +100,7 @@ Session::tempoize_region (TimeStretchRequest& tsr) error << string_compose (_("tempoize: error creating new audio file %1 (%2)"), path, strerror (errno)) << endmsg; goto out; } + } try { @@ -158,7 +171,34 @@ Session::tempoize_region (TimeStretchRequest& tsr) } } - region_name = tsr.region->name() + X_(".t"); + len = tsr.region->name().length(); + + while (--len) { + if (!isdigit (tsr.region->name()[len])) { + break; + } + } + + if (len == 0) { + + region_name = tsr.region->name() + ".t000"; + + } else { + + if (tsr.region->name()[len] == 't') { + c = atoi (tsr.region->name().substr(len+1)); + + snprintf (buf, sizeof (buf), "t%03d", ++c); + region_name = tsr.region->name().substr (0, len) + buf; + + } else { + + /* not sure what this is, just tack the suffix on to it */ + + region_name = tsr.region->name() + ".t000"; + } + + } r = (boost::dynamic_pointer_cast (RegionFactory::create (sources, 0, sources.front()->length(), region_name, 0, AudioRegion::Flag (AudioRegion::DefaultFlags | AudioRegion::WholeFile)))); diff --git a/libs/ardour/session_transport.cc b/libs/ardour/session_transport.cc index 59a6bce785..e4811ca18d 100644 --- a/libs/ardour/session_transport.cc +++ b/libs/ardour/session_transport.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include @@ -176,7 +175,7 @@ Session::realtime_stop (bool abort) waiting_for_sync_offset = true; } - transport_sub_state = (Config->get_auto_return() ? AutoReturning : 0); + transport_sub_state = ((Config->get_slave_source() == None && Config->get_auto_return()) ? AutoReturning : 0); } void @@ -372,13 +371,13 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished) update_latency_compensation (true, abort); } - if (Config->get_auto_return() || (post_transport_work & PostTransportLocate) || synced_to_jack()) { + if ((Config->get_slave_source() == None && Config->get_auto_return()) || (post_transport_work & PostTransportLocate) || synced_to_jack()) { if (pending_locate_flush) { flush_all_redirects (); } - - if ((Config->get_auto_return() || synced_to_jack()) && !(post_transport_work & PostTransportLocate)) { + + if (((Config->get_slave_source() == None && Config->get_auto_return()) || synced_to_jack()) && !(post_transport_work & PostTransportLocate)) { _transport_frame = last_stop_frame; @@ -640,7 +639,7 @@ Session::locate (nframes_t target_frame, bool with_roll, bool with_flush, bool w } } - if (transport_rolling() && !Config->get_auto_play() && !with_roll && !(synced_to_jack() && play_loop)) { + if (transport_rolling() && (!auto_play_legal || !Config->get_auto_play()) && !with_roll && !(synced_to_jack() && play_loop)) { realtime_stop (false); } @@ -925,7 +924,7 @@ Session::post_transport () if (post_transport_work & PostTransportLocate) { - if ((Config->get_auto_play() && !_exporting) || (post_transport_work & PostTransportRoll)) { + if (((Config->get_slave_source() == None && (auto_play_legal && Config->get_auto_play())) && !_exporting) || (post_transport_work & PostTransportRoll)) { start_transport (); } else { @@ -1250,3 +1249,9 @@ Session::update_latency_compensation_proxy (void* ignored) { update_latency_compensation (false, false); } + +void +Session::allow_auto_play (bool yn) +{ + auto_play_legal = yn; +} diff --git a/libs/ardour/session_vst.cc b/libs/ardour/session_vst.cc index 70bf1a8042..16233feba2 100644 --- a/libs/ardour/session_vst.cc +++ b/libs/ardour/session_vst.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include diff --git a/libs/ardour/silentfilesource.cc b/libs/ardour/silentfilesource.cc new file mode 100644 index 0000000000..b34944e342 --- /dev/null +++ b/libs/ardour/silentfilesource.cc @@ -0,0 +1,39 @@ +/* + 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 + +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/sndfilesource.cc b/libs/ardour/sndfilesource.cc index 629b3e4158..24647030ab 100644 --- a/libs/ardour/sndfilesource.cc +++ b/libs/ardour/sndfilesource.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include @@ -36,6 +35,7 @@ using namespace std; using namespace ARDOUR; using namespace PBD; +using Glib::ustring; gain_t* SndFileSource::out_coefficient = 0; gain_t* SndFileSource::in_coefficient = 0; @@ -55,11 +55,11 @@ SndFileSource::SndFileSource (Session& s, const XMLNode& node) } } -SndFileSource::SndFileSource (Session& s, string path, int chn, Flag flags) +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; + _channel = chn; init (); @@ -68,7 +68,7 @@ SndFileSource::SndFileSource (Session& s, string path, int chn, Flag flags) } } -SndFileSource::SndFileSource (Session& s, string path, SampleFormat sfmt, HeaderFormat hf, nframes_t rate, Flag flags) +SndFileSource::SndFileSource (Session& s, ustring path, SampleFormat sfmt, HeaderFormat hf, nframes_t rate, Flag flags) : AudioFileSource (s, path, flags, sfmt, hf) { int fmt = 0; @@ -178,7 +178,7 @@ SndFileSource::SndFileSource (Session& s, string path, SampleFormat sfmt, Header void SndFileSource::init () { - string file; + ustring file; // lets try to keep the object initalizations here at the top xfade_buf = 0; @@ -222,8 +222,8 @@ SndFileSource::open () return -1; } - if (channel >= _info.channels) { - error << string_compose(_("SndFileSource: file only contains %1 channels; %2 is invalid as a channel number"), _info.channels, channel) << endmsg; + if (_channel >= _info.channels) { + error << string_compose(_("SndFileSource: file only contains %1 channels; %2 is invalid as a channel number"), _info.channels, _channel) << endmsg; sf_close (sf); sf = 0; return -1; @@ -347,7 +347,7 @@ SndFileSource::read_unlocked (Sample *dst, nframes_t start, nframes_t cnt) const } nread = sf_read_float (sf, interleave_buf, real_cnt); - ptr = interleave_buf + channel; + ptr = interleave_buf + _channel; nread /= _info.channels; /* stride through the interleaved data */ @@ -388,7 +388,7 @@ SndFileSource::nondestructive_write_unlocked (Sample *data, nframes_t cnt) nframes_t oldlen; int32_t frame_pos = _length; - + if (write_float (data, frame_pos, cnt) != cnt) { return 0; } @@ -397,28 +397,7 @@ SndFileSource::nondestructive_write_unlocked (Sample *data, nframes_t cnt) update_length (oldlen, cnt); if (_build_peakfiles) { - PeakBuildRecord *pbr = 0; - - if (pending_peak_builds.size()) { - pbr = pending_peak_builds.back(); - } - - if (pbr && pbr->frame + pbr->cnt == oldlen) { - - /* the last PBR extended to the start of the current write, - so just extend it again. - */ - pbr->cnt += cnt; - } else { - pending_peak_builds.push_back (new PeakBuildRecord (oldlen, cnt)); - } - - _peaks_built = false; - } - - - if (_build_peakfiles) { - queue_for_peaks (shared_from_this (), false); + compute_and_write_peaks (data, frame_pos, cnt, false); } _write_data_count = cnt; @@ -508,32 +487,12 @@ SndFileSource::destructive_write_unlocked (Sample* data, nframes_t cnt) old_file_pos = file_pos; update_length (file_pos, cnt); - file_pos += cnt; if (_build_peakfiles) { - PeakBuildRecord *pbr = 0; - - if (pending_peak_builds.size()) { - pbr = pending_peak_builds.back(); - } - - if (pbr && pbr->frame + pbr->cnt == old_file_pos) { - - /* the last PBR extended to the start of the current write, - so just extend it again. - */ - - pbr->cnt += cnt; - } else { - pending_peak_builds.push_back (new PeakBuildRecord (old_file_pos, cnt)); - } - - _peaks_built = false; + compute_and_write_peaks (data, file_pos, cnt, false); } - if (_build_peakfiles) { - queue_for_peaks (shared_from_this (), true); - } + file_pos += cnt; return cnt; } @@ -628,9 +587,6 @@ SndFileSource::set_header_timeline_position () delete _broadcast_info; _broadcast_info = 0; } - - - } nframes_t @@ -886,7 +842,7 @@ SndFileSource::set_timeline_position (int64_t pos) } int -SndFileSource::get_soundfile_info (string path, SoundFileInfo& info, string& error_msg) +SndFileSource::get_soundfile_info (const ustring& path, SoundFileInfo& info, string& error_msg) { SNDFILE *sf; SF_INFO sf_info; @@ -938,3 +894,9 @@ SndFileSource::get_timecode_info (SNDFILE* sf, SF_BROADCAST_INFO* binfo, bool& e 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 index 39a83cb6de..7f680e7100 100644 --- a/libs/ardour/source.cc +++ b/libs/ardour/source.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include @@ -112,7 +111,17 @@ Source::set_state (const XMLNode& node) void Source::add_playlist (boost::shared_ptr pl) { - _playlists.insert (pl); + std::pair res; + std::pair, 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 (pl))); } @@ -125,10 +134,15 @@ Source::remove_playlist (boost::weak_ptr wpl) return; } - std::set >::iterator x; + PlaylistMap::iterator x; + Glib::Mutex::Lock lm (playlist_lock); if ((x = _playlists.find (pl)) != _playlists.end()) { - _playlists.erase (x); + if (x->second > 1) { + x->second--; + } else { + _playlists.erase (x); + } } } diff --git a/libs/ardour/source_factory.cc b/libs/ardour/source_factory.cc index 2cbd7624be..6ecd79844d 100644 --- a/libs/ardour/source_factory.cc +++ b/libs/ardour/source_factory.cc @@ -22,7 +22,7 @@ #include #include -#include +#include #include #ifdef HAVE_COREAUDIO @@ -51,6 +51,14 @@ SourceFactory::setup_peakfile (boost::shared_ptr s) return 0; } +boost::shared_ptr +SourceFactory::createSilent (Session& s, const XMLNode& node, nframes_t nframes, float sr) +{ + boost::shared_ptr ret (new SilentFileSource (s, node, nframes, sr)); + SourceCreated (ret); + return ret; +} + #ifdef HAVE_COREAUDIO boost::shared_ptr SourceFactory::create (Session& s, const XMLNode& node) @@ -63,9 +71,12 @@ SourceFactory::create (Session& s, const XMLNode& node) SourceCreated (ret); return ret; } - - - catch (failed_constructor& err) { + + + catch (failed_constructor& err) { + + /* this is allowed to throw */ + boost::shared_ptr ret (new SndFileSource (s, node)); if (setup_peakfile (ret)) { return boost::shared_ptr(); @@ -82,14 +93,15 @@ SourceFactory::create (Session& s, const XMLNode& node) boost::shared_ptr SourceFactory::create (Session& s, const XMLNode& node) { - boost::shared_ptr ret (new SndFileSource (s, node)); + /* this is allowed to throw */ + boost::shared_ptr ret (new SndFileSource (s, node)); + if (setup_peakfile (ret)) { return boost::shared_ptr(); } - + SourceCreated (ret); - return ret; } @@ -113,6 +125,9 @@ SourceFactory::createReadable (Session& s, string path, int chn, AudioFileSource } catch (failed_constructor& err) { + + /* this is allowed to throw */ + boost::shared_ptr ret (new SndFileSource (s, path, chn, flags)); if (setup_peakfile (ret)) { return boost::shared_ptr(); diff --git a/libs/ardour/sse_functions_xmm.cc b/libs/ardour/sse_functions_xmm.cc new file mode 100644 index 0000000000..5554462132 --- /dev/null +++ b/libs/ardour/sse_functions_xmm.cc @@ -0,0 +1,116 @@ +/* + 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 +#include + +void +x86_sse_find_peaks(float *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/tempo.cc b/libs/ardour/tempo.cc index e86c30dd4d..cd59e93054 100644 --- a/libs/ardour/tempo.cc +++ b/libs/ardour/tempo.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include diff --git a/libs/ardour/utils.cc b/libs/ardour/utils.cc index a02016201a..6b5ea2cef6 100644 --- a/libs/ardour/utils.cc +++ b/libs/ardour/utils.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include /* for sprintf */ diff --git a/libs/ardour/vst_plugin.cc b/libs/ardour/vst_plugin.cc index 5d7a303fc6..afba6b5cfb 100644 --- a/libs/ardour/vst_plugin.cc +++ b/libs/ardour/vst_plugin.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include @@ -173,9 +172,8 @@ VSTPlugin::get_state() } else { - error << string_compose (_("cannot check VST chunk directory: %1"), - strerror (errno)) - << endmsg; + warning << string_compose (_("cannot check VST chunk directory: %1"), strerror (errno)) + << endmsg; return *root; } -- cgit v1.2.3