Merged with trunk revision 610
authorDavid Robillard <d@drobilla.net>
Thu, 15 Jun 2006 22:31:13 +0000 (22:31 +0000)
committerDavid Robillard <d@drobilla.net>
Thu, 15 Jun 2006 22:31:13 +0000 (22:31 +0000)
git-svn-id: svn://localhost/ardour2/branches/midi@611 d708f5d6-7413-0410-9779-e7cbd77b26cf

33 files changed:
LAST_MERGE
gtk2_ardour/ardour_ui_ed.cc
gtk2_ardour/editor.cc
gtk2_ardour/gain_meter.cc
gtk2_ardour/new_session_dialog.cc
libs/ardour/ardour/constsource.h [deleted file]
libs/ardour/ardour/filesource.h [deleted file]
libs/ardour/ardour/osc.h
libs/ardour/ardour/seqsource.h [deleted file]
libs/ardour/ardour/session.h
libs/ardour/ardour/silentsource.h [deleted file]
libs/ardour/ardour/types.h
libs/ardour/control_protocol_manager.cc
libs/ardour/filesource.cc [deleted file]
libs/ardour/io.cc
libs/ardour/session_control.cc
libs/ardour/session_feedback.cc
libs/gtkmm2ext/fastmeter.cc
libs/surfaces/control_protocol/SConscript
libs/surfaces/control_protocol/basic_ui.cc
libs/surfaces/control_protocol/basic_ui.h [deleted file]
libs/surfaces/control_protocol/control_protocol.cc
libs/surfaces/control_protocol/control_protocol.h [deleted file]
libs/surfaces/control_protocol/control_protocol/basic_ui.h [new file with mode: 0644]
libs/surfaces/control_protocol/control_protocol/control_protocol.h [new file with mode: 0644]
libs/surfaces/control_protocol/control_protocol/smpte.h [new file with mode: 0644]
libs/surfaces/control_protocol/smpte.cc [new file with mode: 0644]
libs/surfaces/generic_midi/generic_midi_control_protocol.h
libs/surfaces/generic_midi/interface.cc
libs/surfaces/tranzport/interface.cc
libs/surfaces/tranzport/tranzport_control_protocol.cc
libs/surfaces/tranzport/tranzport_control_protocol.h
templates/SConscript

index e8327edbfb3386f14fe520e8430d31614582319b..065d65bce77081b4bbe894a520f8c72a9774e9ce 100644 (file)
@@ -1,3 +1,3 @@
 Last merged with trunk revision:
 
-600
+610
index 3ca435a24d82e8682e28fcb69f61f4a8987b7091..8714eec9a98afa6d8d11df3076efc143e377b90c 100644 (file)
@@ -35,7 +35,7 @@
 #include <ardour/session.h>
 #include <ardour/control_protocol_manager.h>
 
-#include "control_protocol.h"
+#include <control_protocol/control_protocol.h>
 
 #include "i18n.h"
 
index 1d78c2fce0edbc9d78adc169c3ccf10b1819d55a..16a8e5d92228e8b7aa0a1fe757894a06d8348316 100644 (file)
@@ -48,7 +48,7 @@
 #include <ardour/tempo.h>
 #include <ardour/utils.h>
 
-#include "control_protocol.h"
+#include <control_protocol/control_protocol.h>
 
 #include "ardour_ui.h"
 #include "editor.h"
index 9d0228dba68023337e63f0676a33f2d52576e146..60b485460097221d2d86f4c6b128284ae92348ae 100644 (file)
@@ -326,23 +326,27 @@ GainMeter::update_meters ()
        char buf[32];
        
        for (n = 0, i = meters.begin(); i != meters.end(); ++i, ++n) {
-                if ((*i).packed) {
-                        peak = _io.peak_input_power (n);
+               if ((*i).packed) {
+                       peak = _io.peak_input_power (n);
 
                        (*i).meter->set (log_meter (peak), peak);
-                       
-                        if (peak > max_peak) {
-                                max_peak = peak;
-                                /* set peak display */
-                                snprintf (buf, sizeof(buf), "%.1f", max_peak);
-                                peak_display_label.set_text (buf);
-
-                                if (max_peak >= 0.0f) {
-                                        peak_display.set_name ("MixerStripPeakDisplayPeak");
-                                }
-                        }
-                }
-        }
+                                               
+                       if (peak > max_peak) {
+               max_peak = peak;
+                /* set peak display */
+                               if (max_peak <= -200.0f) {
+                                       peak_display_label.set_text (_("-inf"));
+                               } else {
+                                       snprintf (buf, sizeof(buf), "%.1f", max_peak);
+                                       peak_display_label.set_text (buf);
+                               }
+
+                               if (max_peak >= 0.0f) {
+                                       peak_display.set_name ("MixerStripPeakDisplayPeak");
+                               }
+                       }
+               }
+       }
 }
 
 void
index 88944aacb7172b55b93d0d56b565e96a18545895..d1059cebe08f76b204cccf62f0b84cced5fa0f5d 100644 (file)
@@ -302,6 +302,11 @@ NewSessionDialog::NewSessionDialog()
        if (!path.empty()) {
                m_template->set_current_folder (path + X_("templates/"));
        }
+
+       const std::string sys_templates_dir = ARDOUR::get_system_data_path() + X_("templates");
+       if (Glib::file_test(sys_templates_dir, Glib::FILE_TEST_IS_DIR))
+               m_template->add_shortcut_folder(sys_templates_dir);
+       
        m_template->set_title(_("select template"));
        Gtk::FileFilter* session_filter = manage (new (Gtk::FileFilter));
        session_filter->add_pattern(X_("*.ardour"));
diff --git a/libs/ardour/ardour/constsource.h b/libs/ardour/ardour/constsource.h
deleted file mode 100644 (file)
index d000afb..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
-    Copyright (C) 2000 Paul Davis 
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-    $Id$
-*/
-
-#ifndef __playlist_const_buffer_h__ 
-#define __playlist_const_buffer_h__
-
-#include <string>
-#include <cstdlib>
-
-#include "edl.h"
-
-namespace EDL {
-
-class ConstSource : public Source {
-  public:
-       ConstSource (const gchar *id) {
-               _type = Source::Const;
-               value = strtod (id, 0);
-               strncpy (idstr, id, 15);
-               idstr[15] = '\0';
-       }
-       
-       const gchar * const id() { return idstr; }
-
-       uint32_t length() { return ~0U; }
-
-       uint32_t read (Source::Data *dst, uint32_t start, uint32_t cnt) {
-               uint32_t n = cnt;
-               while (n--) *dst++ = value;
-               return cnt;
-       }
-       void peak (guint8 *max, guint8 *min, uint32_t start, uint32_t cnt) {
-               *max = *min = (guint8) value;
-       }
-
-  private:
-       Source::Data value;
-       gchar idstr[16];
-};
-
-}; /* namespace EDL */
-
-#endif /* __playlist_const_buffer_h__ */
diff --git a/libs/ardour/ardour/filesource.h b/libs/ardour/ardour/filesource.h
deleted file mode 100644 (file)
index 28a01f0..0000000
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
-    Copyright (C) 2000 Paul Davis 
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-    $Id$
-*/
-
-#ifndef __playlist_file_buffer_h__ 
-#define __playlist_file_buffer_h__
-
-// darwin supports 64 by default and doesn't provide wrapper functions.
-#if defined (__APPLE__)
-typedef off_t off64_t;
-#define open64 open
-#define close64 close
-#define lseek64 lseek
-#define pread64 pread
-#define pwrite64 pwrite
-#endif
-
-#include <vector>
-#include <string>
-
-#include <ardour/source.h>
-
-struct tm;
-
-using std::string;
-
-namespace ARDOUR {
-
-class FileSource : public Source {
-  public:
-       FileSource (string path, jack_nframes_t rate, bool repair_first = false, SampleFormat samp_format=FormatFloat);
-       FileSource (const XMLNode&, jack_nframes_t rate);
-       ~FileSource ();
-
-       int set_name (std::string str, bool destructive);
-
-       void set_allow_remove_if_empty (bool yn);
-
-       jack_nframes_t length() const { return _length; }
-       jack_nframes_t read (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const;
-       jack_nframes_t write (Sample *src, jack_nframes_t cnt, char * workbuf);
-       void           mark_for_remove();
-       string         peak_path(string audio_path);
-       string         path() const { return _path; }
-       float sample_rate () const;
-
-       virtual int            seek (jack_nframes_t frame) {return 0; }
-       virtual jack_nframes_t last_capture_start_frame() const { return 0; }
-       virtual void           mark_capture_start (jack_nframes_t) {}
-       virtual void           mark_capture_end () {}
-       virtual void           clear_capture_marks() {}
-
-       int update_header (jack_nframes_t when, struct tm&, time_t);
-
-       int move_to_trash (const string trash_dir_name);
-
-       static bool is_empty (string path);
-       void mark_streaming_write_completed ();
-
-       void   mark_take (string);
-       string take_id() const { return _take_id; }
-
-       static void set_bwf_country_code (string x);
-       static void set_bwf_organization_code (string x);
-       static void set_bwf_serial_number (int);
-       
-       static void set_search_path (string);
-
-  protected:
-       int            fd;
-       string        _path;
-       bool           remove_at_unref;
-       bool           is_bwf;
-       off64_t        data_offset;
-       string        _take_id;
-       SampleFormat  _sample_format;
-       int           _sample_size;
-       bool           allow_remove_if_empty;
-
-       static char bwf_country_code[3];
-       static char bwf_organization_code[4];
-       static char bwf_serial_number[13];
-
-       struct GenericChunk {
-           char    id[4];
-           int32_t  size; 
-       };
-
-       struct WAVEChunk : public GenericChunk {
-           char    text[4];      /* wave pseudo-chunk id "WAVE" */
-       };
-
-       struct FMTChunk : public GenericChunk {
-           int16_t   formatTag;           /* format tag; currently pcm   */
-           int16_t   nChannels;           /* number of channels         */
-           uint32_t  nSamplesPerSec;      /* sample rate in hz          */
-           int32_t   nAvgBytesPerSec;     /* average bytes per second   */
-           int16_t   nBlockAlign;         /* number of bytes per sample */
-           int16_t   nBitsPerSample;      /* number of bits in a sample */
-       };
-
-       struct BroadcastChunk : public GenericChunk {
-           char   description[256];
-           char   originator[32];
-           char   originator_reference[32];
-           char   origination_date[10];
-           char   origination_time[8];
-           int32_t time_reference_low;
-           int32_t time_reference_high;
-           int16_t version;               /* 1.0 because we have umid and 190 bytes of "reserved" */
-           char   umid[64];
-           char   reserved[190];
-           /* we don't treat coding history as part of the struct */
-       };
-
-       struct ChunkInfo {
-           std::string name;
-           uint32_t    size;
-           off64_t     offset;
-           
-           ChunkInfo (string s, uint32_t sz, off64_t o) 
-                   : name (s), size (sz), offset (o) {}
-       };
-
-       vector<ChunkInfo> chunk_info;
-       
-       struct {
-           WAVEChunk               wave;
-           FMTChunk                format;
-           GenericChunk            data;
-           BroadcastChunk          bext;
-           vector<string>          coding_history;
-           bool                    bigendian;
-       } header;
-
-       int init (string, bool must_exist, jack_nframes_t);
-       jack_nframes_t read_unlocked (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const;
-
-       ssize_t file_write (Sample *src, jack_nframes_t framepos, jack_nframes_t cnt, char * workbuf) {
-               switch (_sample_format) {
-               case FormatInt24: return write_pcm_24(src, framepos, cnt, workbuf);
-               default: return write_float(src, framepos, cnt, workbuf);
-               };
-       }
-       
-       ssize_t file_read  (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const  {
-               switch (_sample_format) {
-               case FormatInt24: return read_pcm_24(dst, start, cnt, workbuf);
-               default: return read_float(dst, start, cnt, workbuf);
-               };
-       }
-       
-       ssize_t write_float(Sample *src, jack_nframes_t framepos, jack_nframes_t cnt, char * workbuf);
-       ssize_t read_float (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const;
-        ssize_t write_pcm_24(Sample *src, jack_nframes_t framepos, jack_nframes_t cnt, char * workbuf);
-       ssize_t read_pcm_24 (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const;
-       
-       int discover_chunks (bool silent);
-       ChunkInfo* lookup_chunk (string name);
-
-       int write_header ();
-       int read_header (bool silent);
-
-       int check_header (jack_nframes_t rate, bool silent);
-       int fill_header (jack_nframes_t rate);
-       
-       int read_broadcast_data (ChunkInfo&);
-       void compute_header_size ();
-       
-       static const int32_t wave_header_size = sizeof (WAVEChunk) + sizeof (FMTChunk) + sizeof (GenericChunk);
-       static const int32_t bwf_header_size = wave_header_size + sizeof (BroadcastChunk);
-
-       static string search_path;
-
-       int repair (string, jack_nframes_t);
-
-       void swap_endian (GenericChunk & chunk) const;
-       void swap_endian (FMTChunk & chunk) const;
-       void swap_endian (BroadcastChunk & chunk) const;
-       void swap_endian (Sample *buf, jack_nframes_t cnt) const;
-};
-
-}
-
-#endif /* __playlist_file_buffer_h__ */
index 69ec76eac6ca80b4044a583c3d56a626bce356e0..0a34f44a41bfa35a273b4a25c3031e694ce0a5a9 100644 (file)
@@ -32,7 +32,7 @@
 
 #include <ardour/types.h>
 
-#include "basic_ui.h"
+#include <control_protocol/basic_ui.h>
 
 namespace ARDOUR {
        class Session;
diff --git a/libs/ardour/ardour/seqsource.h b/libs/ardour/ardour/seqsource.h
deleted file mode 100644 (file)
index 7e38d27..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
-    Copyright (C) 2000 Paul Davis 
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-    $Id$
-*/
-
-#ifndef __playlist_seqsource_h__ 
-#define __playlist_seqsource_h__
-
-#include <string>
-
-#include "edl.h"
-
-namespace EDL {
-
-class PlaylistSource : public Source {
-  public:
-       PlaylistSource (Playlist&);
-       ~PlaylistSource ();
-
-       const gchar * const id() { return playlist.name().c_str(); }
-       uint32_t length() { return playlist.length(); }
-       uint32_t read (Source::Data *dst, uint32_t start, uint32_t cnt) {
-               return playlist.read (dst, start, cnt, false);
-       }
-       uint32_t write (Source::Data *src, uint32_t where, uint32_t cnt) {
-               return playlist.write (src, where, cnt);
-       }
-
-//     int read_peaks (peak_data_t *, uint32_t npeaks, uint32_t start, uint32_t cnt);
-//     int build_peak (uint32_t first_frame, uint32_t cnt);
-
-  protected:
-
-  private:
-       Playlist& playlist;
-};
-
-}; /* namespace EDL */
-
-#endif /* __playlist_seqsource_h__ */
index 0554d13e68950e5546f997c7ae94f161bf55b96b..a193536d744d4555ad4bd466c80eac53a287335d 100644 (file)
@@ -592,7 +592,6 @@ class Session : public sigc::trackable, public Stateful
        int  set_smpte_type (float fps, bool drop_frames);
 
        void bbt_time (jack_nframes_t when, BBT_Time&);
-
        void smpte_to_sample( SMPTE::Time& smpte, jack_nframes_t& sample, bool use_offset, bool use_subframes ) const;
        void sample_to_smpte( jack_nframes_t sample, SMPTE::Time& smpte, bool use_offset, bool use_subframes ) const;
        void smpte_time (SMPTE::Time &);
@@ -1352,7 +1351,7 @@ class Session : public sigc::trackable, public Stateful
        jack_nframes_t last_smpte_when;
        SMPTE::Time    last_smpte;
        
-       bool _send_smpte_update; ///< Send a full MTC timecode this cycle
+       bool _send_smpte_update; ///< Flag to send a full frame (SMPTE) MTC message this cycle
 
        int send_full_time_code(jack_nframes_t nframes);
        int send_midi_time_code_for_cycle(jack_nframes_t nframes);
diff --git a/libs/ardour/ardour/silentsource.h b/libs/ardour/ardour/silentsource.h
deleted file mode 100644 (file)
index 0079e5f..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
-    Copyright (C) 2000 Paul Davis 
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-    $Id$
-*/
-
-#ifndef __playlist_const_buffer_h__ 
-#define __playlist_const_buffer_h__
-
-#include <string>
-#include <cstdlib>
-
-#include "source.h"
-
-namespace ARDOUR {
-
-class SilentSource : public Source {
-  public:
-       SilentSource () {
-               _name = "Silent Source";
-       }
-       
-       static bool is_silent_source (const string& name) {
-               return name == "Silent Source";
-       }
-       
-       jack_nframes_t length() { return ~0U; }
-
-       jack_nframes_t read (Source::Data *dst, jack_nframes_t start, jack_nframes_t cnt) {
-               jack_nframes_t n = cnt;
-               while (n--) *dst++ = 0;
-               return cnt;
-       }
-
-       void peak (guint8 *max, guint8 *min, jack_nframes_t start, jack_nframes_t cnt) {
-               *max = *min = 0;
-       }
-};
-
-}
-
-#endif /* __playlist_const_buffer_h__ */
index cdf71b8cc63d406ed9b9208ccaf6724d9dfd6325..a0a209b569248ee87a6a40cb65b0c7e22944216d 100644 (file)
@@ -29,6 +29,7 @@
 
 #include <inttypes.h>
 #include <jack/types.h>
+#include <control_protocol/smpte.h>
 #include <map>
 
 #if __GNUC__ < 3
@@ -98,34 +99,7 @@ namespace ARDOUR {
                Normal,
                Destructive
        };
-
-       enum smpte_wrap_t {
-               smpte_wrap_none = 0,
-               smpte_wrap_frames,
-               smpte_wrap_seconds,
-               smpte_wrap_minutes,
-               smpte_wrap_hours
-       };
-
-       struct SMPTE_Time {
-               bool negative;
-               uint32_t hours;
-               uint32_t minutes;
-               uint32_t seconds;
-               uint32_t frames;
-               uint32_t subframes; // mostly not used
-
-               SMPTE_Time() {
-                       negative = false;
-                       hours = 0;
-                       minutes = 0;
-                       seconds = 0;
-                       frames = 0;
-                       subframes = 0;
-               }
-               
-       };
-
+       
        struct BBT_Time {
            uint32_t bars;
            uint32_t beats;
@@ -164,7 +138,7 @@ namespace ARDOUR {
 
            Type type;
 
-           SMPTE_Time     smpte;
+           SMPTE::Time    smpte;
            BBT_Time       bbt;
 
            union { 
index 57a89cc2d9643cb495d41972571171f322c791c7..16437cf8ce225c6b7b55a4891f7877fa2cb2760f 100644 (file)
@@ -4,7 +4,7 @@
 #include <pbd/error.h>
 #include <pbd/pathscanner.h>
 
-#include "control_protocol.h"
+#include <control_protocol/control_protocol.h>
 
 #include <ardour/session.h>
 #include <ardour/control_protocol_manager.h>
diff --git a/libs/ardour/filesource.cc b/libs/ardour/filesource.cc
deleted file mode 100644 (file)
index 0e0ef0b..0000000
+++ /dev/null
@@ -1,1512 +0,0 @@
-/*
-    Copyright (C) 2000 Paul Davis 
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-    $Id$
-*/
-
-#include <algorithm>
-
-/* This is is very hacky way to get pread and pwrite declarations.
-   First, include <features.h> so that we can avoid its #undef __USE_UNIX98.
-   Then define __USE_UNIX98, include <unistd.h>, 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 <features.h>
-#endif
-
-#if __GNUC__ >= 3
-// #define _XOPEN_SOURCE 500
-#include <unistd.h>
-#else
-#define __USE_UNIX98
-#include <unistd.h>
-#undef  __USE_UNIX98
-#endif
-
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <climits>
-#include <cerrno>
-#include <sys/types.h>
-#include <pwd.h>
-#include <time.h>
-#include <sys/utsname.h>
-#include <vector>
-#include <cstdio> /* for rename(2) */
-
-#include <glibmm.h>
-
-#include <pbd/stl_delete.h>
-
-#include <glibmm/thread.h>
-#include <pbd/pathscanner.h>
-
-#include <ardour/ardour.h>
-#include <ardour/version.h>
-#include <ardour/audiofilesource.h>
-#include <ardour/session.h>
-#include <ardour/cycle_timer.h>
-#include <ardour/pcm_utils.h>
-
-#include "i18n.h"
-
-using namespace ARDOUR;
-
-string prepare_string(string& regex);
-
-char   FileSource::bwf_country_code[3] = "us";
-char   FileSource::bwf_organization_code[4] = "las";
-char   FileSource::bwf_serial_number[13] = "000000000000";
-string FileSource::search_path;
-
-#undef WE_ARE_BIGENDIAN
-#ifdef __BIG_ENDIAN__
-#define WE_ARE_BIGENDIAN true
-#else
-#define WE_ARE_BIGENDIAN false
-#endif
-
-#define Swap_32(value)         \
-       (((((uint32_t)value)<<24) & 0xFF000000) | \
-        ((((uint32_t)value)<< 8) & 0x00FF0000) | \
-        ((((uint32_t)value)>> 8) & 0x0000FF00) | \
-        ((((uint32_t)value)>>24) & 0x000000FF))
-
-#define Swap_16(value)         \
-       (((((uint16_t)value)>> 8) & 0x000000FF) | \
-        ((((uint16_t)value)<< 8) & 0x0000FF00))
-
-
-void
-FileSource::set_search_path (string p)
-{
-       search_path = p;
-}
-
-FileSource::FileSource (string pathstr, jack_nframes_t rate, bool repair_first, SampleFormat samp_format)
-{
-       /* constructor used when the file cannot already exist or might be damaged */
-       _sample_format = samp_format;
-       if (samp_format == FormatInt24) {
-               _sample_size = 3;
-       } else {
-               _sample_size = sizeof(float);
-       }
-       
-       if (repair_first && repair (pathstr, rate)) {
-               throw failed_constructor ();
-       }
-       
-       if (init (pathstr, false, rate)) {
-               throw failed_constructor ();
-       }
-
-       SourceCreated (this); /* EMIT SIGNAL */
-}
-
-FileSource::FileSource (const XMLNode& node, jack_nframes_t rate) 
-       : Source (node)
-{
-       _sample_format = FormatFloat;
-       _sample_size = sizeof(float);
-
-       if (set_state (node)) {
-               throw failed_constructor();
-       }
-
-       /* constructor used when the file must already exist */
-
-       if (init (_name, true, rate)) {
-               throw failed_constructor ();
-       }
-
-       SourceCreated (this); /* EMIT SIGNAL */
-}
-
-int
-FileSource::init (string pathstr, bool must_exist, jack_nframes_t rate)
-{
-       bool new_file = false;
-       int ret = -1;
-       PathScanner scanner;
-
-       /* all native files end in .wav. this lets us discard
-          SndFileSource paths, which have ":N" at the end to
-          indicate which channel to read from, as well as any
-          other kind of non-native file. obviously, there
-          are more subtle checks later on.
-       */
-
-       if (pathstr.length() < 4 || pathstr.rfind (".wav") != pathstr.length() - 4) {
-               return ret;
-       }
-
-       is_bwf = false;
-       _length = 0;
-       fd = -1;
-       remove_at_unref = false;
-       next_peak_clear_should_notify = false;
-       allow_remove_if_empty = true;
-
-       if (pathstr[0] != '/') {
-
-               /* find pathstr in search path */
-               
-               if (search_path.length() == 0) {
-                       error << _("FileSource: search path not set") << endmsg;
-                       goto out;
-               }
-
-               /* force exact match on the filename component by prefixing the regexp.
-                  otherwise, "Drums-2.wav" matches "Comp_Drums-2.wav".
-               */
-
-               string regexp = "^";
-               regexp += prepare_string(pathstr);
-               regexp += '$';
-
-               vector<string*>* result = scanner (search_path, regexp, false, true, -1);
-               
-               if (result == 0 || result->size() == 0) {
-                       error << string_compose (_("FileSource: \"%1\" not found when searching %2 using %3"), 
-                                         pathstr, search_path, regexp) << endmsg;
-                       goto out;
-               }
-               
-               if (result->size() > 1) {
-                       string msg = string_compose (_("FileSource: \"%1\" is ambigous when searching %2\n\t"), pathstr, search_path);
-                       vector<string*>::iterator x = result->begin();
-
-                       while (true) {
-                               msg += *(*x);
-                               ++x;
-
-                               if (x == result->end()) {
-                                       break;
-                               }
-
-                               msg += "\n\t";
-                       }
-                       
-                       error << msg << endmsg;
-                       goto out;
-               }
-               
-               _name = pathstr;
-               _path = *(result->front());
-
-               vector_delete (result);
-               delete result;
-
-       } else {
-
-               /* old style sessions include full paths */
-
-               _path = pathstr;
-               _name = pathstr.substr (pathstr.find_last_of ('/') + 1);
-
-       }
-
-       if (access (_path.c_str(), F_OK) != 0) {
-               if (must_exist) {
-                       error << string_compose(_("Filesource: cannot find required file (%1): %2"), _path, strerror (errno)) << endmsg;
-                       goto out;
-                       
-               }
-
-               if (errno == ENOENT) {
-                       new_file = true;
-               } else {
-                       error << string_compose(_("Filesource: cannot check for existing file (%1): %2"), _path, strerror (errno)) << endmsg;
-                       goto out;
-               }
-       }
-
-       if ((fd = open64 (_path.c_str(), O_RDWR|O_CREAT, 0644)) < 0) {
-               error << string_compose(_("FileSource: could not open \"%1\": (%2)"), _path, strerror (errno)) << endmsg;
-               goto out;
-       }
-       
-       /* if there was no timestamp available via XML,
-          then get it from the filesystem.
-       */
-
-       if (_timestamp == 0) {
-               struct stat statbuf;
-               
-               fstat (fd, &statbuf);
-               _timestamp = statbuf.st_mtime;
-       }
-
-       if (lseek (fd, 0, SEEK_END) == 0) {
-               new_file = true;
-       }
-
-       /* check that its a RIFF/WAVE format file */
-       
-       if (new_file) {
-
-               switch (Config->get_native_file_header_format()) {
-               case BWF:
-                       is_bwf = true;
-                       break;
-               default:
-                       is_bwf = false;
-                       break;
-               }
-
-               if (fill_header (rate)) {
-                       error << string_compose (_("FileSource: cannot write header in %1"), _path) << endmsg;
-                       goto out;
-               }
-
-               struct tm* now;
-               time_t     xnow;
-               
-               time (&xnow);
-               now = localtime (&xnow);
-
-               update_header (0, *now, xnow);
-               
-       } else {
-
-               if (discover_chunks (must_exist)) {
-                       error << string_compose (_("FileSource: cannot locate chunks in %1"), _path) << endmsg;
-                       goto out;
-               }
-               
-               if (read_header (must_exist)) {
-                       error << string_compose (_("FileSource: cannot read header in %1"), _path) << endmsg;
-                       goto out;
-               }
-
-               if (check_header (rate, must_exist)) {
-                       error << string_compose (_("FileSource: cannot check header in %1"), _path) << endmsg;
-                       goto out;
-               }
-
-               compute_header_size ();
-       }
-       
-       if ((ret = initialize_peakfile (new_file, _path))) {
-               error << string_compose (_("FileSource: cannot initialize peakfile for %1 as %2"), _path, peakpath) << endmsg;
-       }
-
-  out:
-       if (ret) {
-
-               if (fd >= 0) {
-                       close (fd);
-               }
-
-               if (new_file) {
-                       unlink (_path.c_str());
-               }
-       }
-
-       return ret;
-
-}
-
-FileSource::~FileSource ()
-{
-       GoingAway (this); /* EMIT SIGNAL */
-       
-       if (fd >= 0) {
-
-               if (remove_at_unref || (is_empty (_path) && allow_remove_if_empty)) {
-                       unlink (_path.c_str());
-                       unlink (peakpath.c_str());
-               }
-
-               close (fd);
-       } 
-}
-
-void
-FileSource::set_allow_remove_if_empty (bool yn)
-{
-       allow_remove_if_empty = yn;
-}
-
-int
-FileSource::set_name (string newname, bool destructive)
-{
-       Glib::Mutex::Lock lm (_lock);
-       string oldpath = _path;
-       string newpath = Session::change_audio_path_by_name (oldpath, _name, newname, destructive);
-
-       if (newpath.empty()) {
-               error << string_compose (_("programming error: %1"), "cannot generate a changed audio path") << endmsg;
-               return -1;
-       }
-
-       if (rename (oldpath.c_str(), newpath.c_str()) != 0) {
-               error << string_compose (_("cannot rename audio file for %1 to %2"), _name, newpath) << endmsg;
-               return -1;
-       }
-
-       _name = Glib::path_get_basename (newpath);
-       _path = newpath;
-
-       return rename_peakfile (peak_path (_path));
-}
-
-string
-FileSource::peak_path (string audio_path)
-{
-       return Session::peak_path_from_audio_path (audio_path);
-}
-
-int
-FileSource::discover_chunks (bool silent)
-{
-       WAVEChunk rw;
-       off64_t end;
-       off64_t offset;
-       char null_terminated_id[5];
-       bool doswap = false;
-       
-       if ((end = lseek (fd, 0, SEEK_END)) < 0) {
-               error << _("FileSource: cannot seek to end of file") << endmsg;
-               return -1;
-       }
-
-       if (::pread64 (fd, &rw, sizeof (rw), 0) != sizeof (rw)) {
-               error << _("FileSource: cannot read RIFF/WAVE chunk from file") << endmsg;
-               return -1;
-       }
-
-       if (memcmp (rw.id, "RIFF", 4) == 0 && memcmp (rw.text, "WAVE", 4) == 0) {
-               header.bigendian = false;
-       }
-       else if (memcmp(rw.id, "RIFX", 4) == 0 && memcmp (rw.text, "WAVE", 4) == 0) {
-               header.bigendian = true;
-       }
-       else {
-               if (!silent) {
-                       error << string_compose (_("FileSource %1: not a RIFF/WAVE file"), _path) << endmsg;
-               }
-               return -1;
-       }
-
-       null_terminated_id[4] = '\0';
-
-       /* OK, its a RIFF/WAVE file. Find each chunk */
-
-       doswap = header.bigendian != WE_ARE_BIGENDIAN;
-       
-       if (doswap) {
-               swap_endian(rw);
-       }
-
-       
-       
-       memcpy (null_terminated_id, rw.id, 4);
-       chunk_info.push_back (ChunkInfo (null_terminated_id, rw.size, 0));
-
-       offset = sizeof (rw);
-
-       while (offset < end) {
-
-               GenericChunk this_chunk;
-               
-               if (::pread64 (fd, &this_chunk, sizeof (this_chunk), offset) != sizeof (this_chunk)) {
-                       error << _("FileSource: can't read a chunk") << endmsg;
-                       return -1;
-               }
-
-               if (doswap) {
-                       swap_endian(this_chunk);
-               }
-
-               memcpy (null_terminated_id, this_chunk.id, 4);
-
-               /* do sanity check and possible correction to legacy ardour RIFF wavs
-                  created on big endian platforms. after swapping, the size field will not be
-                  in range for the fmt chunk
-               */
-               if ((memcmp(null_terminated_id, "fmt ", 4) == 0 || memcmp(null_terminated_id, "bext", 4) == 0)
-                    && !header.bigendian && (this_chunk.size > 700 || this_chunk.size < 0))
-               {
-                       warning << _("filesource: correcting mis-written RIFF file to become a RIFX: ") << name() << endmsg;
-                       
-                       memcpy (&rw.id, "RIFX", 4);
-                       ::pwrite64 (fd, &rw.id, 4, 0);
-                       header.bigendian = true;
-                       // fix wave chunk already read
-                       swap_endian(rw);
-                       
-                       doswap = header.bigendian != WE_ARE_BIGENDIAN;
-
-                       // now reset offset and continue the loop
-                       // to reread all the chunks
-                       chunk_info.clear();
-                       memcpy (null_terminated_id, rw.id, 4);
-                       chunk_info.push_back (ChunkInfo (null_terminated_id, rw.size, 0));
-                       offset = sizeof (rw);
-                       continue;
-               }
-                               
-
-               if (end != 44)
-                       if ((memcmp(null_terminated_id, "data", 4) == 0))
-                               if ((this_chunk.size == 0) || (this_chunk.size > (end - offset)))
-                                       this_chunk.size = end - offset;
-               
-               chunk_info.push_back (ChunkInfo (null_terminated_id, this_chunk.size, offset));
-
-               /* skip to the next chunk */
-
-               offset += sizeof(GenericChunk) + this_chunk.size;
-       }
-
-       return 0;
-}
-
-void
-FileSource::swap_endian (GenericChunk & chunk) const
-{
-       chunk.size = Swap_32(chunk.size);
-}
-
-void
-FileSource::swap_endian (FMTChunk & chunk) const
-{
-       chunk.size = Swap_32(chunk.size);
-
-       chunk.formatTag = Swap_16(chunk.formatTag);
-       chunk.nChannels = Swap_16(chunk.nChannels);
-       chunk.nSamplesPerSec = Swap_32(chunk.nSamplesPerSec);
-       chunk.nAvgBytesPerSec = Swap_32(chunk.nAvgBytesPerSec);
-       chunk.nBlockAlign = Swap_16(chunk.nBlockAlign);
-       chunk.nBitsPerSample = Swap_16(chunk.nBitsPerSample);
-}
-
-void
-FileSource::swap_endian (BroadcastChunk & chunk) const
-{
-       chunk.size = Swap_32(chunk.size);
-
-       chunk.time_reference_low = Swap_32(chunk.time_reference_low);
-       chunk.time_reference_high = Swap_32(chunk.time_reference_high);
-       chunk.version = Swap_16(chunk.version);
-}
-
-void FileSource::swap_endian (Sample *buf, jack_nframes_t cnt) const
-{
-       for (jack_nframes_t n=0; n < cnt; ++n) {
-               uint32_t * tmp = (uint32_t *) &buf[n];
-               *tmp = Swap_32(*tmp);
-       }
-}
-
-
-FileSource::ChunkInfo*
-FileSource::lookup_chunk (string what)
-{
-       for (vector<ChunkInfo>::iterator i = chunk_info.begin(); i != chunk_info.end(); ++i) {
-               if ((*i).name == what) {
-                       return &*i;
-               }
-       }
-       return 0;
-}
-
-int
-FileSource::fill_header (jack_nframes_t rate)
-{
-       /* RIFF/WAVE */
-
-       if (WE_ARE_BIGENDIAN) {
-               memcpy (header.wave.id, "RIFX", 4);
-               header.bigendian = true;
-       }
-       else {
-               memcpy (header.wave.id, "RIFF", 4);
-               header.bigendian = false;
-       }
-       header.wave.size = 0; /* file size */
-       memcpy (header.wave.text, "WAVE", 4);
-
-       /* BROADCAST WAVE EXTENSION */
-       
-       if (is_bwf) {
-
-               /* fill the entire BWF header with nulls */
-
-               memset (&header.bext, 0, sizeof (header.bext));
-
-               memcpy (header.bext.id, "bext", 4);
-
-               snprintf (header.bext.description, sizeof (header.bext.description), "%s", "ambiguity is clearer than precision.");
-
-               struct passwd *pwinfo;
-               struct utsname utsinfo;
-
-               if ((pwinfo = getpwuid (getuid())) == 0) {
-                       error << string_compose(_("FileSource: cannot get user information for BWF header (%1)"), strerror(errno)) << endmsg;
-                       return -1;
-               }
-               if (uname (&utsinfo)) {
-                       error << string_compose(_("FileSource: cannot get host information for BWF header (%1)"), strerror(errno)) << endmsg;
-                       return -1;
-               }
-
-               snprintf (header.bext.originator, sizeof (header.bext.originator), "ardour:%s:%s:%s:%s:%s)", 
-                         pwinfo->pw_gecos,
-                         utsinfo.nodename,
-                         utsinfo.sysname,
-                         utsinfo.release,
-                         utsinfo.version);
-
-               header.bext.version = 1;  
-               
-               /* XXX do something about this field */
-
-               snprintf (header.bext.umid, sizeof (header.bext.umid), "%s", "fnord");
-
-               /* add some coding history */
-
-               char buf[64];
-
-               /* encode: PCM,rate,mono,24bit,ardour-version
-                  
-                  Note that because we use JACK, there is no way to tell
-                  what the original bit depth of the signal was.
-                */
-               
-               snprintf (buf, sizeof(buf), "F=%u,A=PCM,M=mono,W=24,T=ardour-%d.%d.%d", 
-                         rate,
-                         libardour_major_version,
-                         libardour_minor_version,
-                         libardour_micro_version);
-
-               header.coding_history.push_back (buf);
-
-               /* initial size reflects coding history + "\r\n" */
-
-               header.bext.size = sizeof (BroadcastChunk) - sizeof (GenericChunk) + strlen (buf) + 2;
-       }
-       
-       memcpy (header.format.id, "fmt ", 4);
-       header.format.size = sizeof (FMTChunk) - sizeof (GenericChunk);
-
-       if (_sample_format == FormatInt24) {
-               header.format.formatTag = 1; // PCM
-               header.format.nBlockAlign = 3;
-               header.format.nBitsPerSample = 24;
-       }
-       else {
-               header.format.formatTag = 3; /* little-endian IEEE float format */
-               header.format.nBlockAlign = 4;
-               header.format.nBitsPerSample = 32;
-       }
-       header.format.nChannels = 1; /* mono */
-       header.format.nSamplesPerSec = rate;
-       header.format.nAvgBytesPerSec = rate * _sample_size;
-       
-       /* DATA */
-
-       memcpy (header.data.id, "data", 4);
-       header.data.size = 0;
-       
-       return 0;
-}
-
-void
-FileSource::compute_header_size ()
-{
-       off64_t end_of_file;
-       int32_t coding_history_size = 0;
-               
-       end_of_file = lseek (fd, 0, SEEK_END);
-
-       if (is_bwf) {
-               
-               /* include the coding history */
-               
-               for (vector<string>::iterator i = header.coding_history.begin(); i != header.coding_history.end(); ++i) {
-                       coding_history_size += (*i).length() + 2; // include "\r\n";
-               }
-               
-               header.bext.size = sizeof (BroadcastChunk) - sizeof (GenericChunk) + coding_history_size;
-               data_offset = bwf_header_size + coding_history_size;
-               
-       } else {
-               data_offset = wave_header_size;
-       }
-
-       if (end_of_file == 0) {
-
-               /* newfile condition */
-               
-               if (is_bwf) {
-                       /* include "WAVE" then all the chunk sizes (bext, fmt, data) */ 
-                       header.wave.size = 4 + sizeof (BroadcastChunk) + coding_history_size + sizeof (FMTChunk) + sizeof (GenericChunk);
-               } else {
-                       /* include "WAVE" then all the chunk sizes (fmt, data) */
-                       header.wave.size = 4 + sizeof (FMTChunk) + sizeof (GenericChunk);
-               }
-
-               header.data.size = 0;
-
-       } else {
-
-               header.wave.size = end_of_file - 8; /* size of initial RIFF+size pseudo-chunk */
-               header.data.size = end_of_file - data_offset;
-       }
-}
-
-int
-FileSource::update_header (jack_nframes_t when, struct tm& now, time_t tnow)
-{
-       Glib::Mutex::Lock lm (_lock);
-
-       if (is_bwf) {
-               /* random code is 9 digits */
-
-               int random_code = random() % 999999999;
-
-               snprintf (header.bext.originator_reference, sizeof (header.bext.originator_reference), "%2s%3s%12s%02d%02d%02d%9d",
-                         bwf_country_code,
-                         bwf_organization_code,
-                         bwf_serial_number,
-                         now.tm_hour,
-                         now.tm_min,
-                         now.tm_sec,
-                         random_code);
-                         
-               snprintf (header.bext.origination_date, sizeof (header.bext.origination_date), "%4d-%02d-%02d",
-                         1900 + now.tm_year,
-                         now.tm_mon,
-                         now.tm_mday);
-
-               snprintf (header.bext.origination_time, sizeof (header.bext.origination_time), "%02d-%02d-%02d",
-                         now.tm_hour,
-                         now.tm_min,
-                         now.tm_sec);
-
-               header.bext.time_reference_high = 0;
-               header.bext.time_reference_low = when;
-       }
-
-       compute_header_size ();
-
-       if (write_header()) {
-               error << string_compose(_("FileSource[%1]: cannot update data size: %2"), _path, strerror (errno)) << endmsg;
-               return -1;
-       }
-
-       stamp (tnow);
-
-       return 0;
-}
-
-int
-FileSource::read_header (bool silent)
-{
-       /* we already have the chunk info, so just load up whatever we have */
-
-       ChunkInfo* info;
-       
-       if (header.bigendian == false && (info = lookup_chunk ("RIFF")) == 0) {
-               error << _("FileSource: can't find RIFF chunk info") << endmsg;
-               return -1;
-       }
-       else if (header.bigendian == true && (info = lookup_chunk ("RIFX")) == 0) {
-               error << _("FileSource: can't find RIFX chunk info") << endmsg;
-               return -1;
-       }
-       
-       
-       /* just fill this chunk/header ourselves, disk i/o is stupid */
-
-       if (header.bigendian) {
-               memcpy (header.wave.id, "RIFX", 4);
-       }
-       else {
-               memcpy (header.wave.id, "RIFF", 4);
-       }
-       header.wave.size = 0;
-       memcpy (header.wave.text, "WAVE", 4);
-
-       if ((info = lookup_chunk ("bext")) != 0) {
-
-               is_bwf = true;
-               
-               if (::pread64 (fd, &header.bext, sizeof (header.bext), info->offset) != sizeof (header.bext)) {
-                       error << _("FileSource: can't read RIFF chunk") << endmsg;
-                       return -1;
-               }
-
-               if (read_broadcast_data (*info)) {
-                       return -1;
-               }
-       }
-
-       if ((info = lookup_chunk ("fmt ")) == 0) {
-               error << _("FileSource: can't find format chunk info") << endmsg;
-               return -1;
-       }
-
-       if (::pread64 (fd, &header.format, sizeof (header.format), info->offset) != sizeof (header.format)) {
-               error << _("FileSource: can't read format chunk") << endmsg;
-               return -1;
-       }
-
-       if (header.bigendian != WE_ARE_BIGENDIAN) {
-               swap_endian (header.format);
-       }
-       
-       if ((info = lookup_chunk ("data")) == 0) {
-               error << _("FileSource: can't find data chunk info") << endmsg;
-               return -1;
-       }
-
-       if (::pread64 (fd, &header.data, sizeof (header.data), info->offset) != sizeof (header.data)) {
-               error << _("FileSource: can't read data chunk") << endmsg;
-               return -1;
-       }
-
-       if (header.bigendian != WE_ARE_BIGENDIAN) {
-               swap_endian (header.data);
-       }
-
-       return 0;
-}
-
-int
-FileSource::read_broadcast_data (ChunkInfo& info)
-{
-       int32_t coding_history_size;
-
-       if (::pread64 (fd, (char *) &header.bext, sizeof (header.bext), info.offset + sizeof (GenericChunk)) != sizeof (header.bext)) {
-               error << string_compose(_("FileSource: cannot read Broadcast Wave data from existing audio file \"%1\" (%2)"),
-                                _path, strerror (errno)) << endmsg;
-               return -1;
-       }
-
-       if (header.bigendian != WE_ARE_BIGENDIAN) {
-               swap_endian (header.bext);
-       }
-       
-       if (info.size > sizeof (header.bext)) {
-
-               coding_history_size = info.size - (sizeof (header.bext) - sizeof (GenericChunk));
-               
-               char data[coding_history_size];
-               
-               if (::pread64 (fd, data, coding_history_size, info.offset + sizeof (BroadcastChunk)) != coding_history_size) {
-                       error << string_compose(_("FileSource: cannot read Broadcast Wave coding history from audio file \"%1\" (%2)"),
-                                        _path, strerror (errno)) << endmsg;
-                       return -1;
-               }
-               
-               /* elements of the coding history are divided by \r\n */
-               
-               char *p = data;
-               char *end = data + coding_history_size;
-               string tmp;
-
-               while (p < end) {
-                       if (*p == '\r' && (p+1) != end && *(p+1) == '\n') {
-                               if (tmp.length()) {
-                                       header.coding_history.push_back (tmp);
-                                       tmp = "";
-                               }
-                               p += 2;
-                       } else {
-                               tmp += *p;
-                               p++;
-                       }
-               }
-       }
-
-       return 0;
-}
-
-int
-FileSource::check_header (jack_nframes_t rate, bool silent)
-{
-       if (header.format.formatTag == 1 && header.format.nBitsPerSample == 24) {
-               // 24 bit PCM
-               _sample_format = FormatInt24;
-               _sample_size = 3;
-       } else if (header.format.formatTag == 3) {
-               /* IEEE float */                
-               _sample_format = FormatFloat;
-               _sample_size = 4;
-       }
-       else {
-               if (!silent) {
-                       error << string_compose(_("FileSource \"%1\" does not use valid sample format.\n"   
-                                          "This is probably a programming error."), _path) << endmsg;
-               }
-               return -1;
-       }
-       
-       /* compute the apparent length of the data */
-
-       data_offset = 0;
-
-       for (vector<ChunkInfo>::iterator i = chunk_info.begin(); i != chunk_info.end();) {
-               vector<ChunkInfo>::iterator n;
-
-               n = i;
-               ++n;
-
-               if ((*i).name == "data") {
-
-                       data_offset = (*i).offset + sizeof (GenericChunk);
-
-                       if (n == chunk_info.end()) {
-                               off64_t end_of_file;
-                               end_of_file = lseek (fd, 0, SEEK_END);
-
-                               _length = end_of_file - data_offset;
-
-                       } else {
-                               _length = (*n).offset - data_offset;
-                       }
-
-                       _length /= sizeof (Sample);
-
-                       break;
-               }
-               
-               i = n;
-       }
-
-       if (data_offset == 0) {
-               error << string_compose(_("FileSource \"%1\" has no \"data\" chunk"), _path) << endmsg;
-               return -1;
-       }
-
-       if (_length * sizeof (Sample) != (jack_nframes_t) header.data.size) {
-               warning << string_compose(_("%1: data length in header (%2) differs from implicit size in file (%3)"),
-                                  _path, header.data.size, _length * sizeof (Sample)) << endmsg;
-       }
-
-//     if ((jack_nframes_t) header.format.nSamplesPerSec != rate) {
-//             warning << string_compose(_("\"%1\" has a sample rate of %2 instead of %3 as used by this session"),
-//                                _path, header.format.nSamplesPerSec, rate) << endmsg;
-//     }
-
-       return 0;
-}
-
-float
-FileSource::sample_rate () const
-{
-       return header.format.nSamplesPerSec;
-}
-
-int
-FileSource::write_header()
-{
-       off64_t pos;
-
-       /* write RIFF/WAVE boilerplate */
-
-       pos = 0;
-
-       WAVEChunk wchunk = header.wave;
-       if (header.bigendian != WE_ARE_BIGENDIAN) {
-               swap_endian(wchunk);
-       }
-       
-       if (::pwrite64 (fd, (char *) &wchunk, sizeof (wchunk), pos) != sizeof (wchunk)) {
-               error << string_compose(_("FileSource: cannot write WAVE chunk: %1"), strerror (errno)) << endmsg;
-               return -1;
-       }
-       
-       pos += sizeof (header.wave);
-       
-       if (is_bwf) {
-
-               /* write broadcast chunk data without copy history */
-
-               BroadcastChunk bchunk = header.bext;
-               if (header.bigendian != WE_ARE_BIGENDIAN) {
-                       swap_endian (bchunk);
-               }
-               
-               if (::pwrite64 (fd, (char *) &bchunk, sizeof (bchunk), pos) != sizeof (bchunk)) {
-                       return -1;
-               }
-
-               pos += sizeof (header.bext);
-
-               /* write copy history */
-
-               for (vector<string>::iterator i = header.coding_history.begin(); i != header.coding_history.end(); ++i) {
-                       string x;
-                       
-                       x = *i;
-                       x += "\r\n";
-                       
-                       if (::pwrite64 (fd, x.c_str(), x.length(), pos) != (int32_t) x.length()) {
-                               return -1;
-                       }
-                       
-                       pos += x.length();
-               }
-       }
-
-        /* write fmt and data chunks */
-       FMTChunk fchunk = header.format;
-       if (header.bigendian != WE_ARE_BIGENDIAN) {
-               swap_endian (fchunk);
-       }
-       
-       if (::pwrite64 (fd, (char *) &fchunk, sizeof (fchunk), pos) != sizeof (fchunk)) {
-               error << string_compose(_("FileSource: cannot write format chunk: %1"), strerror (errno)) << endmsg;
-               return -1;
-       }
-
-       pos += sizeof (header.format);
-
-       GenericChunk dchunk = header.data;
-       if (header.bigendian != WE_ARE_BIGENDIAN) {
-               swap_endian (dchunk);
-       }
-       if (::pwrite64 (fd, (char *) &dchunk, sizeof (dchunk), pos) != sizeof (dchunk)) {
-               error << string_compose(_("FileSource: cannot data chunk: %1"), strerror (errno)) << endmsg;
-               return -1;
-       }
-
-       return 0;
-}
-
-void
-FileSource::mark_for_remove ()
-{
-       remove_at_unref = true;
-}
-
-jack_nframes_t
-FileSource::read (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const
-{
-       Glib::Mutex::Lock lm (_lock);
-       return read_unlocked (dst, start, cnt, workbuf);
-}
-
-jack_nframes_t
-FileSource::read_unlocked (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const
-{
-       jack_nframes_t file_cnt;
-
-       if (start > _length) {
-
-               /* read starts beyond end of data, just memset to zero */
-               
-               file_cnt = 0;
-
-       } else if (start + cnt > _length) {
-               
-               /* read ends beyond end of data, read some, memset the rest */
-               
-               file_cnt = _length - start;
-
-       } else {
-               
-               /* read is entirely within data */
-
-               file_cnt = cnt;
-       }
-
-       if (file_cnt) {
-               if (file_read(dst, start, file_cnt, workbuf) != (ssize_t) file_cnt) {
-                       return 0;
-               }
-       }
-
-       if (file_cnt != cnt) {
-               jack_nframes_t delta = cnt - file_cnt;
-               memset (dst+file_cnt, 0, sizeof (Sample) * delta);
-       }
-       
-       return cnt;
-}
-
-jack_nframes_t
-FileSource::write (Sample *data, jack_nframes_t cnt, char * workbuf)
-{
-       {
-               Glib::Mutex::Lock lm (_lock);
-               
-               jack_nframes_t oldlen;
-               int32_t frame_pos = _length;
-               
-               if (file_write(data, frame_pos, cnt, workbuf) != (ssize_t) cnt) {
-                       return 0;
-               }
-
-               oldlen = _length;
-               _length += 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 (*this);
-       }
-
-       return cnt;
-}
-
-ssize_t
-FileSource::write_float(Sample *data, jack_nframes_t framepos, jack_nframes_t cnt, char * workbuf)
-{
-       int32_t byte_cnt = cnt * _sample_size;
-       int32_t byte_pos = data_offset + (framepos * _sample_size);
-       ssize_t retval;
-       
-       if ((retval = ::pwrite64 (fd, (char *) data, byte_cnt, byte_pos)) != (ssize_t) byte_cnt) {
-               error << string_compose(_("FileSource: \"%1\" bad write (%2)"), _path, strerror (errno)) << endmsg;
-               if (retval > 0) {
-                       return retval / _sample_size;
-               }
-               else {
-                       return retval;
-               }
-       }
-
-       _write_data_count = byte_cnt;
-       
-       return cnt;
-}
-
-ssize_t
-FileSource::read_float (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const
-{
-       ssize_t nread;
-       ssize_t byte_cnt = (ssize_t) cnt * sizeof (Sample);
-       int readfd;
-
-       /* open, read, close */
-
-       if ((readfd = open64 (_path.c_str(), O_RDONLY)) < 0) {
-               error << string_compose(_("FileSource: could not open \"%1\": (%2)"), _path, strerror (errno)) << endmsg;
-               return 0;
-       }
-       
-       nread = ::pread64 (readfd, (char *) dst, byte_cnt, data_offset + (start * _sample_size));
-       close (readfd);
-
-       if (nread != byte_cnt) {
-
-               cerr << "FileSource: \""
-                    << _path
-                    << "\" bad read at frame "
-                    << start
-                    << ", of "
-                    << cnt
-                    << " (bytes="
-                    << byte_cnt
-                    << ") frames [length = " << _length 
-                    << " eor = " << start + cnt << "] ("
-                    << strerror (errno)
-                    << ") (read "
-                    << nread / sizeof (Sample)
-                    << " (bytes=" <<nread
-                    << ")) pos was"
-                    << data_offset
-                    << '+'
-                    << start << '*' << sizeof(Sample)
-                    << " = " << data_offset + (start * sizeof(Sample))
-                    << endl;
-               
-               if (nread > 0) {
-                       return nread / _sample_size;
-               } else {
-                       return nread;
-               }
-       }
-
-       if (header.bigendian != WE_ARE_BIGENDIAN) {
-               swap_endian(dst, cnt);
-       }
-       
-       _read_data_count = byte_cnt;
-
-       return cnt;
-}
-
-ssize_t
-FileSource::write_pcm_24(Sample *data, jack_nframes_t framepos, jack_nframes_t cnt, char * workbuf)
-{
-       int32_t byte_cnt = cnt * _sample_size;
-       int32_t byte_pos = data_offset + (framepos * _sample_size);
-       ssize_t retval;
-       
-       // convert to int24
-       if (header.bigendian) {
-               pcm_f2bet_clip_array (data, workbuf, cnt);
-       } else {
-               pcm_f2let_clip_array (data, workbuf, cnt);
-       }
-       
-       if ((retval = ::pwrite64 (fd, (char *) workbuf, byte_cnt, byte_pos)) != (ssize_t) byte_cnt) {
-               error << string_compose(_("FileSource: \"%1\" bad write (%2)"), _path, strerror (errno)) << endmsg;
-               if (retval > 0) {
-                       return retval / _sample_size;
-               }
-               else {
-                       return retval;
-               }
-       }
-
-       return (ssize_t) cnt;
-}
-
-ssize_t
-FileSource::read_pcm_24 (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const
-{
-       ssize_t nread;
-       ssize_t byte_cnt = (ssize_t) cnt * _sample_size;
-       int readfd;
-
-       /* open, read, close */
-
-       if ((readfd = open64 (_path.c_str(), O_RDONLY)) < 0) {
-               error << string_compose(_("FileSource: could not open \"%1\": (%2)"), _path, strerror (errno)) << endmsg;
-               return 0;
-       }
-
-       nread = ::pread64 (readfd, (char *) workbuf, byte_cnt, data_offset + (start * _sample_size));
-       close (readfd);
-
-       if (nread != byte_cnt) {
-
-               cerr << "May be OK - FileSource: \""
-                    << _path
-                    << "\" bad 24bit read at frame "
-                    << start
-                    << ", of "
-                    << cnt
-                    << " (bytes="
-                    << byte_cnt
-                    << ") frames [length = " << _length 
-                    << " eor = " << start + cnt << "] ("
-                    << strerror (errno)
-                    << ") (read "
-                    << nread / sizeof (Sample)
-                    << " (bytes=" <<nread
-                    << ")) pos was"
-                    << data_offset
-                    << '+'
-                    << start << '*' << sizeof(Sample)
-                    << " = " << data_offset + (start * sizeof(Sample))
-                    << endl;
-
-               if (nread > 0) {
-                       return nread / _sample_size;
-               }
-               else {
-                       return nread;
-               }
-       }
-
-       // convert from 24bit->float
-       
-       if (header.bigendian) {
-               pcm_bet2f_array (workbuf, cnt, dst);
-       } else {
-               pcm_let2f_array (workbuf, cnt, dst);
-       }
-       
-       _read_data_count = byte_cnt;
-
-       return (ssize_t) cnt;
-}
-
-
-bool
-FileSource::is_empty (string path)
-{
-       struct stat statbuf;
-
-       stat (path.c_str(), &statbuf);
-       
-       /* its a bit of a problem if an audio file happens
-          to be a regular WAVE file with just enough data
-          to match the size of an empty BWF. hmmm. not very
-          likely however - that represents a duration of
-          less than 1msec at typical sample rates.  
-       */
-
-       /* NOTE: 698 bytes is the size of a BWF header structure *plus* our minimal coding history */
-
-       return (statbuf.st_size == 0 || statbuf.st_size == wave_header_size || statbuf.st_size == 698);
-}
-
-void
-FileSource::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;
-                PeaksReady (); /* EMIT SIGNAL */
-       }
-}
-
-void
-FileSource::mark_take (string id)
-{
-       _take_id = id;
-}
-
-int
-FileSource::move_to_trash (const string trash_dir_name)
-{
-       string newpath;
-
-       /* don't move the file across filesystems, just
-          stick it in the `trash_dir_name' directory
-          on whichever filesystem it was already on.
-       */
-
-        // XXX Portability
-
-       newpath = Glib::path_get_dirname (_path);
-       newpath = Glib::path_get_dirname (newpath);
-
-       newpath += '/';
-       newpath += trash_dir_name;
-       newpath += '/';
-       newpath += Glib::path_get_basename (_path);
-
-       if (access (newpath.c_str(), F_OK) == 0) {
-
-               /* the new path already exists, try versioning */
-               
-               char buf[PATH_MAX+1];
-               int version = 1;
-               string newpath_v;
-
-               snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
-               newpath_v = buf;
-
-               while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
-                       snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
-                       newpath_v = buf;
-               }
-               
-               if (version == 999) {
-                       error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
-                                         newpath)
-                             << endmsg;
-               } else {
-                       newpath = newpath_v;
-               }
-
-       } else {
-
-               /* it doesn't exist, or we can't read it or something */
-
-       }
-
-       if (::rename (_path.c_str(), newpath.c_str()) != 0) {
-               error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
-                                 _path, newpath, strerror (errno))
-                     << endmsg;
-               return -1;
-       }
-
-       if (::unlink (peakpath.c_str()) != 0) {
-               error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
-                                 peakpath, _path, strerror (errno))
-                     << endmsg;
-               /* try to back out */
-               rename (newpath.c_str(), _path.c_str());
-               return -1;
-       }
-           
-       _path = newpath;
-       peakpath = "";
-       remove_at_unref = false;
-       
-       return 0;
-}
-
-string
-prepare_string(string& str)
-{
-       string prepared;
-       
-       for (uint32_t i = 0; i < str.size(); ++i){
-               char c = str[i];
-               if (isdigit(c) || isalpha(c)){
-                       prepared += c;
-               } else {
-                       prepared += '\\';
-                       prepared += c;
-               }
-       }
-
-       return prepared;
-}
-
-int
-FileSource::repair (string path, jack_nframes_t rate)
-{
-       FILE* in;
-       char buf[700];
-       char* ptr;
-       struct stat statbuf;
-       size_t i;
-       int ret = -1;
-       bool bigend = false;
-       bool doswap = false;
-       
-       if (stat (path.c_str(), &statbuf)) {
-               return -1;
-       }
-
-       if (statbuf.st_size <= (off_t) sizeof (buf)) {
-               /* nothing was ever written to the file, so there is nothing
-                  really to do.
-               */
-               return 0;
-       }
-
-       if ((in = fopen (path.c_str(), "r+")) == NULL) {
-               return -1;
-       }
-
-       if (fread (buf, sizeof (buf), 1, in) != 1) {
-               goto out;
-       }
-       
-       if ((memcmp (&buf[0], "RIFF", 4) && memcmp (&buf[0], "RIFX", 4)) || memcmp (&buf[8], "WAVE", 4)) {
-               /* no header. too dangerous to proceed */
-               goto out;
-       } 
-
-       if (memcmp (&buf[0], "RIFX", 4)==0) {
-               bigend = true;
-       }
-
-       doswap = bigend != WE_ARE_BIGENDIAN;
-       
-       /* reset the size of the RIFF chunk header */
-
-       if (doswap) {
-               *((int32_t *)&buf[4]) = Swap_32((int32_t)(statbuf.st_size - 8));
-       }
-       else {
-               *((int32_t *)&buf[4]) = statbuf.st_size - 8;
-       }
-
-       /* find data chunk and reset the size */
-
-       ptr = buf;
-
-       for (i = 0; i < sizeof (buf); ) {
-
-               if (memcmp (ptr, "fmt ", 4) == 0) {
-                       
-                       FMTChunk fmt;
-
-                       memcpy (&fmt, ptr, sizeof (fmt));
-                       if (doswap) {
-                               swap_endian(fmt);
-                       }
-                       
-                       fmt.nSamplesPerSec = rate;
-                       fmt.nAvgBytesPerSec = rate * 4;
-                       
-                       /* put it back */
-                       if (doswap) {
-                               swap_endian(fmt);
-                       }
-
-                       memcpy (ptr, &fmt, sizeof (fmt));
-                       ptr += sizeof (fmt);
-                       i += sizeof (fmt);
-
-               } else if (memcmp (ptr, "data", 4) == 0) {
-                       GenericChunk dchunk;
-                       memcpy(&dchunk, ptr, sizeof(dchunk));
-
-                       if(doswap) {
-                               swap_endian(dchunk);
-                       }
-
-                       dchunk.size = statbuf.st_size - i - 8;
-
-                       if (doswap) {
-                               swap_endian(dchunk);
-                       }
-                       memcpy (ptr, &dchunk, sizeof (dchunk));
-                       break;
-
-               } else {
-                       ++ptr;
-                       ++i;
-               }
-       }
-
-       /* now flush it back to disk */
-       
-       rewind (in);
-
-       if (fwrite (buf, sizeof (buf), 1, in) != 1) {
-               goto out;
-       }
-
-       ret = 0;
-       fflush (in);
-
-  out:
-       fclose (in);
-       return ret;
-}
-
index fa30463bd465cac887d38b23cb1266b4016e5fd1..9f4c3cd9e300d5be0435862d3320a6ea16b9b2dd 100644 (file)
@@ -2493,7 +2493,7 @@ IO::meter ()
                } else {
                        // do falloff
                        new_peak = _visible_peak_power[n] - _session.meter_falloff();
-                       _visible_peak_power[n] = max (new_peak, -200.0f);
+                       _visible_peak_power[n] = max (new_peak, -INFINITY);
                }
        }
 }
index 8e0a3e99a17d0c78d6a3b2884da3224b8e85c4bd..afecc146b7823160a6cf01e4feeec31b7882b679 100644 (file)
@@ -1,8 +1,8 @@
 
 #include <ardour/session.h>
-#include <ardour/control_protocol.h>
-#include <ardour/generic_midi_control_protocol.h>
-#include <ardour/tranzport_control_protocol.h>
+#include <control_protocol/control_protocol.h>
+#include <generic_midi/generic_midi_control_protocol.h>
+#include <transport/tranzport_control_protocol.h>
 
 using namespace ARDOUR;
 
index b409686ce75b3081edc21d82fa5e7e13bdfbe8e9..6fab01ec9dd243c06cd7ffc32d9ae11f1cc3a4df 100644 (file)
@@ -39,7 +39,7 @@
 #include <ardour/session.h>
 #include <ardour/audio_track.h>
 #include <ardour/audio_diskstream.h>
-#include <ardour/control_protocol.h>
+#include <control_protocol/control_protocol.h>
 
 #include "i18n.h"
 
index f0ee0ddea18159d513ca0b0f9fdab1d412ecac0a..3c489e08ffbcbb6f3500555b6103afbe4cc28d36 100644 (file)
@@ -354,11 +354,12 @@ FastMeter::vertical_expose (GdkEventExpose* ev)
        // draw peak bar 
        if (hold_state && intersection.width > 0) {
                gint y = pixheight - (gint) floor (pixheight * current_peak);
+               int h = min(3, pixheight - y);
 
                get_window()->draw_pixbuf (get_style()->get_fg_gc(get_state()), pixbuf,
                                           intersection.x, y,
                                           intersection.x, y,
-                                          intersection.width, 3,
+                                          intersection.width, h,
                                           Gdk::RGB_DITHER_NONE, 0, 0);
        }
 
index 38ff95d9f0da8c4f93d2d64359d48f9e1f5c3c82..f8a7d574f56622c573b0f57e3fa566890d746414 100644 (file)
@@ -23,6 +23,7 @@ cp.Append(POTFILE = domain + '.pot')
 cp_files=Split("""
 basic_ui.cc
 control_protocol.cc
+smpte.cc
 """)
 
 cp.Append(CCFLAGS="-D_REENTRANT -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE")
@@ -53,4 +54,4 @@ env.Alias('install', env.Install(os.path.join(install_prefix, 'lib/ardour2'), li
 env.Alias('tarball', env.Distribute (env['DISTTREE'],
                                     [ 'SConscript' ] +
                                     cp_files + 
-                                    glob.glob('po/*.po') + glob.glob('*.h')))
+                                    glob.glob('po/*.po') + glob.glob('*.h') + glob.glob('control_protocol/*.h')))
index 27133ba94cbd12d5d1939e7fb2e62a3b215f1213..3dc93cc64ad980070886d6215a613b25a5288260 100644 (file)
@@ -24,7 +24,8 @@
 #include <ardour/session.h>
 #include <ardour/location.h>
 
-#include "basic_ui.h"
+#include <control_protocol/basic_ui.h>
+
 #include "i18n.h"
 
 using namespace ARDOUR;
@@ -263,19 +264,19 @@ BasicUI::smpte_frames_per_hour ()
 }
 
 void
-BasicUI::smpte_time (jack_nframes_t where, SMPTE_t& smpte)
+BasicUI::smpte_time (jack_nframes_t where, SMPTE::Time& smpte)
 {
        session->smpte_time (where, *((SMPTE::Time *) &smpte));
 }
 
 void 
-BasicUI::smpte_to_sample (SMPTE_t& smpte, jack_nframes_t& sample, bool use_offset, bool use_subframes) const
+BasicUI::smpte_to_sample (SMPTE::Time& smpte, jack_nframes_t& sample, bool use_offset, bool use_subframes) const
 {
        session->smpte_to_sample (*((SMPTE::Time*)&smpte), sample, use_offset, use_subframes);
 }
 
 void 
-BasicUI::sample_to_smpte (jack_nframes_t sample, SMPTE_t& smpte, bool use_offset, bool use_subframes) const
+BasicUI::sample_to_smpte (jack_nframes_t sample, SMPTE::Time& smpte, bool use_offset, bool use_subframes) const
 {
        session->sample_to_smpte (sample, *((SMPTE::Time*)&smpte), use_offset, use_subframes);
 }
diff --git a/libs/surfaces/control_protocol/basic_ui.h b/libs/surfaces/control_protocol/basic_ui.h
deleted file mode 100644 (file)
index 81f2727..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
-    Copyright (C) 2006 Paul Davis 
-
-    This program is free software; you can redistribute it
-    and/or modify it under the terms of the GNU Lesser
-    General Public License as published by the Free Software
-    Foundation; either version 2 of the License, or (at your
-    option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the 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_basic_ui_h__
-#define __ardour_basic_ui_h__
-
-#include <string>
-
-#include <jack/types.h>
-
-namespace ARDOUR {
-       class Session;
-}
-
-class BasicUI {
-  public:
-       BasicUI (ARDOUR::Session&);
-       virtual ~BasicUI ();
-       
-       void add_marker ();
-
-       void register_thread (std::string name);
-
-       /* transport control */
-
-       void loop_toggle ();
-       void goto_start ();
-       void goto_end ();
-       void rewind ();
-       void ffwd ();
-       void transport_stop ();
-       void transport_play (bool jump_back = true);
-       void set_transport_speed (float speed);
-       float get_transport_speed ();
-
-       jack_nframes_t transport_frame ();
-       void locate (jack_nframes_t frame, bool play = false);
-       bool locating ();
-       bool locked ();
-
-       void save_state ();
-       void prev_marker ();
-       void next_marker ();
-       void undo ();
-       void redo ();
-       void toggle_punch_in ();
-       void toggle_punch_out ();
-
-       void set_record_enable (bool yn);
-       bool get_record_enabled ();
-
-       void rec_enable_toggle ();
-       void toggle_all_rec_enables ();
-
-       jack_nframes_t smpte_frames_per_hour ();
-
-       struct SMPTE_t {
-               bool negative;
-               uint32_t hours;
-               uint32_t minutes;
-               uint32_t seconds;
-               uint32_t frames;
-               uint32_t subframes; // mostly not used
-
-               SMPTE_t () {
-                       negative = false;
-                       hours = 0;
-                       minutes = 0;
-                       seconds = 0;
-                       frames = 0;
-                       subframes = 0;
-               }
-       };
-
-       void smpte_time (jack_nframes_t where, SMPTE_t&);
-       void smpte_to_sample (SMPTE_t& smpte, jack_nframes_t& sample, bool use_offset, bool use_subframes) const;
-       void sample_to_smpte (jack_nframes_t sample, SMPTE_t& smpte, bool use_offset, bool use_subframes) const;
-
-  protected:
-       BasicUI ();
-       ARDOUR::Session* session;
-};
-
-#endif /* __ardour_basic_ui_h__ */
index 6407c643857e856cf805e773f89b3c640494ebe4..10295bc698d522d970d045db1b5d3c8c170bc11f 100644 (file)
@@ -23,7 +23,7 @@
 #include <ardour/route.h>
 #include <ardour/audio_track.h>
 
-#include "control_protocol.h"
+#include <control_protocol/control_protocol.h>
 
 using namespace ARDOUR;
 using namespace std;
diff --git a/libs/surfaces/control_protocol/control_protocol.h b/libs/surfaces/control_protocol/control_protocol.h
deleted file mode 100644 (file)
index 720188c..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
-    Copyright (C) 2006 Paul Davis 
-
-    This program is free software; you can redistribute it
-    and/or modify it under the terms of the GNU Lesser
-    General Public License as published by the Free Software
-    Foundation; either version 2 of the License, or (at your
-    option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the 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_control_protocols_h
-#define ardour_control_protocols_h
-
-#include <string>
-#include <vector>
-#include <list>
-#include <sigc++/sigc++.h>
-
-#include "basic_ui.h"
-
-namespace ARDOUR {
-
-class Route;
-class Session;
-
-class ControlProtocol : public sigc::trackable, public BasicUI {
-  public:
-       ControlProtocol (Session&, std::string name);
-       virtual ~ControlProtocol();
-
-       std::string name() const { return _name; }
-
-       virtual int set_active (bool yn) = 0;
-       bool get_active() const { return _active; }
-
-       sigc::signal<void> ActiveChanged;
-
-       /* signals that a control protocol can emit and other (presumably graphical)
-          user interfaces can respond to
-       */
-
-       static sigc::signal<void> ZoomToSession;
-       static sigc::signal<void> ZoomIn;
-       static sigc::signal<void> ZoomOut;
-       static sigc::signal<void> Enter;
-       static sigc::signal<void,float> ScrollTimeline;
-
-       /* the model here is as follows:
-
-          we imagine most control surfaces being able to control
-          from 1 to N tracks at a time, with a session that may
-          contain 1 to M tracks, where M may be smaller, larger or
-          equal to N. 
-
-          the control surface has a fixed set of physical controllers
-          which can potentially be mapped onto different tracks/busses
-          via some mechanism.
-
-          therefore, the control protocol object maintains
-          a table that reflects the current mapping between
-          the controls and route object.
-       */
-
-       void set_route_table_size (uint32_t size);
-       void set_route_table (uint32_t table_index, ARDOUR::Route*);
-       bool set_route_table (uint32_t table_index, uint32_t remote_control_id);
-
-       void route_set_rec_enable (uint32_t table_index, bool yn);
-       bool route_get_rec_enable (uint32_t table_index);
-
-       float route_get_gain (uint32_t table_index);
-       void route_set_gain (uint32_t table_index, float);
-       float route_get_effective_gain (uint32_t table_index);
-
-       float route_get_peak_input_power (uint32_t table_index, uint32_t which_input);
-
-       bool route_get_muted (uint32_t table_index);
-       void route_set_muted (uint32_t table_index, bool);
-
-       bool route_get_soloed (uint32_t table_index);
-       void route_set_soloed (uint32_t table_index, bool);
-
-       std::string route_get_name (uint32_t table_index);
-
-  protected:
-       std::vector<ARDOUR::Route*> route_table;
-       std::string _name;
-       bool _active;
-
-       void next_track (uint32_t initial_id);
-       void prev_track (uint32_t initial_id);
-};
-
-extern "C" {
-       struct ControlProtocolDescriptor {
-           const char* name;      /* descriptive */
-           const char* id;        /* unique and version-specific */
-           void*       ptr;       /* protocol can store a value here */
-           void*       module;    /* not for public access */
-           int         mandatory; /* if non-zero, always load and do not make optional */
-           bool             (*probe)(ControlProtocolDescriptor*);
-           ControlProtocol* (*initialize)(ControlProtocolDescriptor*,Session*);
-           void             (*destroy)(ControlProtocolDescriptor*,ControlProtocol*);
-           
-       };
-}
-
-}
-
-#endif // ardour_control_protocols_h
diff --git a/libs/surfaces/control_protocol/control_protocol/basic_ui.h b/libs/surfaces/control_protocol/control_protocol/basic_ui.h
new file mode 100644 (file)
index 0000000..23b274c
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+    Copyright (C) 2006 Paul Davis 
+
+    This program is free software; you can redistribute it
+    and/or modify it under the terms of the GNU Lesser
+    General Public License as published by the Free Software
+    Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the 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_basic_ui_h__
+#define __ardour_basic_ui_h__
+
+#include <string>
+
+#include <jack/types.h>
+#include <control_protocol/smpte.h>
+
+namespace ARDOUR {
+       class Session;
+}
+
+class BasicUI {
+  public:
+       BasicUI (ARDOUR::Session&);
+       virtual ~BasicUI ();
+       
+       void add_marker ();
+
+       void register_thread (std::string name);
+
+       /* transport control */
+
+       void loop_toggle ();
+       void goto_start ();
+       void goto_end ();
+       void rewind ();
+       void ffwd ();
+       void transport_stop ();
+       void transport_play (bool jump_back = true);
+       void set_transport_speed (float speed);
+       float get_transport_speed ();
+
+       jack_nframes_t transport_frame ();
+       void locate (jack_nframes_t frame, bool play = false);
+       bool locating ();
+       bool locked ();
+
+       void save_state ();
+       void prev_marker ();
+       void next_marker ();
+       void undo ();
+       void redo ();
+       void toggle_punch_in ();
+       void toggle_punch_out ();
+
+       void set_record_enable (bool yn);
+       bool get_record_enabled ();
+
+       void rec_enable_toggle ();
+       void toggle_all_rec_enables ();
+
+       jack_nframes_t smpte_frames_per_hour ();
+
+       void smpte_time (jack_nframes_t where, SMPTE::Time&);
+       void smpte_to_sample (SMPTE::Time& smpte, jack_nframes_t& sample, bool use_offset, bool use_subframes) const;
+       void sample_to_smpte (jack_nframes_t sample, SMPTE::Time& smpte, bool use_offset, bool use_subframes) const;
+
+  protected:
+       BasicUI ();
+       ARDOUR::Session* session;
+};
+
+#endif /* __ardour_basic_ui_h__ */
diff --git a/libs/surfaces/control_protocol/control_protocol/control_protocol.h b/libs/surfaces/control_protocol/control_protocol/control_protocol.h
new file mode 100644 (file)
index 0000000..69135f2
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+    Copyright (C) 2006 Paul Davis 
+
+    This program is free software; you can redistribute it
+    and/or modify it under the terms of the GNU Lesser
+    General Public License as published by the Free Software
+    Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the 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_control_protocols_h
+#define ardour_control_protocols_h
+
+#include <string>
+#include <vector>
+#include <list>
+#include <sigc++/sigc++.h>
+
+#include <control_protocol/basic_ui.h>
+
+namespace ARDOUR {
+
+class Route;
+class Session;
+
+class ControlProtocol : public sigc::trackable, public BasicUI {
+  public:
+       ControlProtocol (Session&, std::string name);
+       virtual ~ControlProtocol();
+
+       std::string name() const { return _name; }
+
+       virtual int set_active (bool yn) = 0;
+       bool get_active() const { return _active; }
+
+       sigc::signal<void> ActiveChanged;
+
+       /* signals that a control protocol can emit and other (presumably graphical)
+          user interfaces can respond to
+       */
+
+       static sigc::signal<void> ZoomToSession;
+       static sigc::signal<void> ZoomIn;
+       static sigc::signal<void> ZoomOut;
+       static sigc::signal<void> Enter;
+       static sigc::signal<void,float> ScrollTimeline;
+
+       /* the model here is as follows:
+
+          we imagine most control surfaces being able to control
+          from 1 to N tracks at a time, with a session that may
+          contain 1 to M tracks, where M may be smaller, larger or
+          equal to N. 
+
+          the control surface has a fixed set of physical controllers
+          which can potentially be mapped onto different tracks/busses
+          via some mechanism.
+
+          therefore, the control protocol object maintains
+          a table that reflects the current mapping between
+          the controls and route object.
+       */
+
+       void set_route_table_size (uint32_t size);
+       void set_route_table (uint32_t table_index, ARDOUR::Route*);
+       bool set_route_table (uint32_t table_index, uint32_t remote_control_id);
+
+       void route_set_rec_enable (uint32_t table_index, bool yn);
+       bool route_get_rec_enable (uint32_t table_index);
+
+       float route_get_gain (uint32_t table_index);
+       void route_set_gain (uint32_t table_index, float);
+       float route_get_effective_gain (uint32_t table_index);
+
+       float route_get_peak_input_power (uint32_t table_index, uint32_t which_input);
+
+       bool route_get_muted (uint32_t table_index);
+       void route_set_muted (uint32_t table_index, bool);
+
+       bool route_get_soloed (uint32_t table_index);
+       void route_set_soloed (uint32_t table_index, bool);
+
+       std::string route_get_name (uint32_t table_index);
+
+  protected:
+       std::vector<ARDOUR::Route*> route_table;
+       std::string _name;
+       bool _active;
+
+       void next_track (uint32_t initial_id);
+       void prev_track (uint32_t initial_id);
+};
+
+extern "C" {
+       struct ControlProtocolDescriptor {
+           const char* name;      /* descriptive */
+           const char* id;        /* unique and version-specific */
+           void*       ptr;       /* protocol can store a value here */
+           void*       module;    /* not for public access */
+           int         mandatory; /* if non-zero, always load and do not make optional */
+           bool             (*probe)(ControlProtocolDescriptor*);
+           ControlProtocol* (*initialize)(ControlProtocolDescriptor*,Session*);
+           void             (*destroy)(ControlProtocolDescriptor*,ControlProtocol*);
+           
+       };
+}
+
+}
+
+#endif // ardour_control_protocols_h
diff --git a/libs/surfaces/control_protocol/control_protocol/smpte.h b/libs/surfaces/control_protocol/control_protocol/smpte.h
new file mode 100644 (file)
index 0000000..09c1c96
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+       Copyright (C) 2006 Paul Davis
+       
+       This program is free software; you can redistribute it and/or modify it
+       under the terms of the GNU Lesser General Public License as published
+       by the Free Software Foundation; either version 2 of the License, or
+       (at your option) any later version.
+       
+       This program is distributed in the hope that it will be useful, but WITHOUT
+       ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+       FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+       for more details.
+       
+       You should have received a copy of the GNU General Public License along
+       with this program; if not, write to the Free Software Foundation, Inc.,
+       675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __ardour_smpte_h__
+#define __ardour_smpte_h__
+
+#include <inttypes.h>
+
+namespace SMPTE {
+
+enum Wrap {
+       NONE = 0,
+       FRAMES,
+       SECONDS,
+       MINUTES,
+       HOURS
+};
+
+/** SMPTE frame rate (in frames per second).
+ *
+ * This should be eliminated in favour of a float to support arbitrary rates.
+ */
+enum FPS {
+    MTC_24_FPS = 0,
+    MTC_25_FPS = 1,
+    MTC_30_FPS_DROP = 2,
+    MTC_30_FPS = 3
+};
+
+struct Time {
+       bool       negative;
+       uint32_t   hours;
+       uint32_t   minutes;
+       uint32_t   seconds;
+       uint32_t   frames;       ///< SMPTE frames (not audio samples)
+       uint32_t   subframes;    ///< Typically unused
+       FPS        rate;         ///< Frame rate of this Time
+       static FPS default_rate; ///< Rate to use for default constructor
+
+       Time(FPS a_rate = default_rate) {
+               negative = false;
+               hours = 0;
+               minutes = 0;
+               seconds = 0;
+               frames = 0;
+               subframes = 0;
+               rate = a_rate;
+       }
+};
+
+Wrap increment( Time& smpte );
+Wrap decrement( Time& smpte );
+Wrap increment_subframes( Time& smpte );
+Wrap decrement_subframes( Time& smpte );
+Wrap increment_seconds( Time& smpte );
+Wrap increment_minutes( Time& smpte );
+Wrap increment_hours( Time& smpte );
+void frames_floor( Time& smpte );
+void seconds_floor( Time& smpte );
+void minutes_floor( Time& smpte );
+void hours_floor( Time& smpte );
+
+} // namespace SMPTE
+
+#endif  // __ardour_smpte_h__
diff --git a/libs/surfaces/control_protocol/smpte.cc b/libs/surfaces/control_protocol/smpte.cc
new file mode 100644 (file)
index 0000000..55d0660
--- /dev/null
@@ -0,0 +1,406 @@
+/*
+       Copyright (C) 2006 Paul Davis
+       
+       This program is free software; you can redistribute it and/or modify it
+       under the terms of the GNU Lesser General Public License as published
+       by the Free Software Foundation; either version 2 of the License, or
+       (at your option) any later version.
+       
+       This program is distributed in the hope that it will be useful, but WITHOUT
+       ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+       FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+       for more details.
+       
+       You should have received a copy of the GNU General Public License along
+       with this program; if not, write to the Free Software Foundation, Inc.,
+       675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#define SMPTE_IS_AROUND_ZERO( sm ) (!(sm).frames && !(sm).seconds && !(sm).minutes && !(sm).hours)
+#define SMPTE_IS_ZERO( sm ) (!(sm).frames && !(sm).seconds && !(sm).minutes && !(sm).hours && !(sm.subframes))
+
+#include <control_protocol/smpte.h>
+
+namespace SMPTE {
+
+FPS Time::default_rate = MTC_30_FPS;
+
+
+/** Increment @a smpte by exactly one frame (keep subframes value).
+ * Realtime safe.
+ * @return true if seconds wrap.
+ */
+Wrap
+increment( Time& smpte )
+{
+       Wrap wrap = NONE;
+
+       if (smpte.negative) {
+               if (SMPTE_IS_AROUND_ZERO(smpte) && smpte.subframes) {
+                       // We have a zero transition involving only subframes
+                       smpte.subframes = 80 - smpte.subframes;
+                       smpte.negative = false;
+                       return SECONDS;
+               }
+    
+               smpte.negative = false;
+               wrap = decrement( smpte );
+               if (!SMPTE_IS_ZERO( smpte )) {
+                       smpte.negative = true;
+               }
+               return wrap;
+       }
+  
+       switch (smpte.rate) {
+       case MTC_24_FPS:
+               if (smpte.frames == 23) {
+                       smpte.frames = 0;
+                       wrap = SECONDS;
+               }
+               break;
+       case MTC_25_FPS:
+               if (smpte.frames == 24) {
+                       smpte.frames = 0;
+                       wrap = SECONDS;
+               }
+               break;
+       case MTC_30_FPS_DROP:
+               if (smpte.frames == 29) {
+                       if ( ((smpte.minutes + 1) % 10) && (smpte.seconds == 59) ) {
+                               smpte.frames = 2;
+                       }
+                       else {
+                               smpte.frames = 0;
+                       }
+                       wrap = SECONDS;
+               }
+               break;
+       case MTC_30_FPS:
+               if (smpte.frames == 29) {
+                       smpte.frames = 0;
+                       wrap = SECONDS;
+               }
+               break;
+       }
+  
+       if (wrap == SECONDS) {
+               if (smpte.seconds == 59) {
+                       smpte.seconds = 0;
+                       wrap = MINUTES;
+                       if (smpte.minutes == 59) {
+                               smpte.minutes = 0;
+                               wrap = HOURS;
+                               smpte.hours++;
+                       } else {
+                               smpte.minutes++;
+                       }
+               } else {
+                       smpte.seconds++;
+               }
+       } else {
+               smpte.frames++;
+       }
+  
+       return wrap;
+}
+
+
+/** Decrement @a smpte by exactly one frame (keep subframes value)
+ * Realtime safe.
+ * @return true if seconds wrap. */
+Wrap
+decrement( Time& smpte )
+{
+       Wrap wrap = NONE;
+  
+  
+       if (smpte.negative || SMPTE_IS_ZERO(smpte)) {
+               smpte.negative = false;
+               wrap = increment( smpte );
+               smpte.negative = true;
+               return wrap;
+       } else if (SMPTE_IS_AROUND_ZERO(smpte) && smpte.subframes) {
+               // We have a zero transition involving only subframes
+               smpte.subframes = 80 - smpte.subframes;
+               smpte.negative = true;
+               return SECONDS;
+       }
+  
+       switch (smpte.rate) {
+       case MTC_24_FPS:
+               if (smpte.frames == 0) {
+                       smpte.frames = 23;
+                       wrap = SECONDS;
+               }
+               break;
+       case MTC_25_FPS:
+               if (smpte.frames == 0) {
+                       smpte.frames = 24;
+                       wrap = SECONDS;
+               }
+               break;
+       case MTC_30_FPS_DROP:
+               if ((smpte.minutes % 10) && (smpte.seconds == 0)) {
+                       if (smpte.frames <= 2) {
+                               smpte.frames = 29;
+                               wrap = SECONDS;
+                       }
+               } else if (smpte.frames == 0) {
+                       smpte.frames = 29;
+                       wrap = SECONDS;
+               }
+               break;
+       case MTC_30_FPS:
+               if (smpte.frames == 0) {
+                       smpte.frames = 29;
+                       wrap = SECONDS;
+               }
+               break;
+       }
+  
+       if (wrap == SECONDS) {
+               if (smpte.seconds == 0) {
+                       smpte.seconds = 59;
+                       wrap = MINUTES;
+                       if (smpte.minutes == 0) {
+                               smpte.minutes = 59;
+                               wrap = HOURS;
+                               smpte.hours--;
+                       }
+                       else {
+                               smpte.minutes--;
+                       }
+               } else {
+                       smpte.seconds--;
+               }
+       } else {
+               smpte.frames--;
+       }
+  
+       if (SMPTE_IS_ZERO( smpte )) {
+               smpte.negative = false;
+       }
+  
+       return wrap;
+}
+
+
+/** Go to lowest absolute subframe value in this frame (set to 0 :-) ) */
+void
+frames_floor( Time& smpte )
+{
+       smpte.subframes = 0;
+       if (SMPTE_IS_ZERO(smpte)) {
+               smpte.negative = false;
+       }
+}
+
+
+/** Increment @a smpte by one subframe */
+Wrap
+increment_subframes( Time& smpte )
+{
+       Wrap wrap = NONE;
+  
+       if (smpte.negative) {
+               smpte.negative = false;
+               wrap = decrement_subframes( smpte );
+               if (!SMPTE_IS_ZERO(smpte)) {
+                       smpte.negative = true;
+               }
+               return wrap;
+       }
+  
+       smpte.subframes++;
+       if (smpte.subframes >= 80) {
+               smpte.subframes = 0;
+               increment( smpte );
+               return FRAMES;
+       }
+       return NONE;
+}
+
+
+/** Decrement @a smpte by one subframe */
+Wrap
+decrement_subframes( Time& smpte )
+{
+       Wrap wrap = NONE;
+  
+       if (smpte.negative) {
+               smpte.negative = false;
+               wrap = increment_subframes( smpte );
+               smpte.negative = true;
+               return wrap;
+       }
+  
+       if (smpte.subframes <= 0) {
+               smpte.subframes = 0;
+               if (SMPTE_IS_ZERO(smpte)) {
+                       smpte.negative = true;
+                       smpte.subframes = 1;
+                       return FRAMES;
+               } else {
+                       decrement( smpte );
+                       smpte.subframes = 79;
+                       return FRAMES;
+               }
+       } else {
+               smpte.subframes--;
+               if (SMPTE_IS_ZERO(smpte)) {
+                       smpte.negative = false;
+               }
+               return NONE;
+       }
+}
+
+
+/** Go to next whole second (frames == 0 or frames == 2) */
+Wrap
+increment_seconds( Time& smpte )
+{
+       Wrap wrap = NONE;
+  
+       // Clear subframes
+       frames_floor( smpte );
+  
+       if (smpte.negative) {
+               // Wrap second if on second boundary
+               wrap = increment(smpte);
+               // Go to lowest absolute frame value
+               seconds_floor( smpte );
+               if (SMPTE_IS_ZERO(smpte)) {
+                       smpte.negative = false;
+               }
+       } else {
+               // Go to highest possible frame in this second
+               switch (smpte.rate) {
+               case MTC_24_FPS:
+                       smpte.frames = 23;
+                       break;
+               case MTC_25_FPS:
+                       smpte.frames = 24;
+                       break;
+               case MTC_30_FPS_DROP:
+               case MTC_30_FPS:
+                       smpte.frames = 29;
+                       break;
+               }
+    
+               // Increment by one frame
+               wrap = increment( smpte );
+       }
+  
+       return wrap;
+}
+
+
+/** Go to lowest (absolute) frame value in this second
+ * Doesn't care about positive/negative */
+void
+seconds_floor( Time& smpte )
+{
+       // Clear subframes
+       frames_floor( smpte );
+  
+       // Go to lowest possible frame in this second
+       switch (smpte.rate) {
+       case MTC_24_FPS:
+       case MTC_25_FPS:
+       case MTC_30_FPS:
+               smpte.frames = 0;
+               break;
+       case MTC_30_FPS_DROP:
+               if ((smpte.minutes % 10) && (smpte.seconds == 0)) {
+                       smpte.frames = 2;
+               } else {
+                       smpte.frames = 0;
+               }
+               break;
+       }
+  
+       if (SMPTE_IS_ZERO(smpte)) {
+               smpte.negative = false;
+       }
+}
+
+
+/** Go to next whole minute (seconds == 0, frames == 0 or frames == 2) */
+Wrap
+increment_minutes( Time& smpte )
+{
+       Wrap wrap = NONE;
+  
+       // Clear subframes
+       frames_floor( smpte );
+  
+       if (smpte.negative) {
+               // Wrap if on minute boundary
+               wrap = increment_seconds( smpte );
+               // Go to lowest possible value in this minute
+               minutes_floor( smpte );
+       } else {
+               // Go to highest possible second
+               smpte.seconds = 59;
+               // Wrap minute by incrementing second
+               wrap = increment_seconds( smpte );
+       }
+  
+       return wrap;
+}
+
+
+/** Go to lowest absolute value in this minute */
+void
+minutes_floor( Time& smpte )
+{
+       // Go to lowest possible second
+       smpte.seconds = 0;
+       // Go to lowest possible frame
+       seconds_floor( smpte );
+
+       if (SMPTE_IS_ZERO(smpte)) {
+               smpte.negative = false;
+       }
+}
+
+
+/** Go to next whole hour (minute = 0, second = 0, frame = 0) */
+Wrap
+increment_hours( Time& smpte )
+{
+       Wrap wrap = NONE;
+  
+       // Clear subframes
+       frames_floor(smpte);
+  
+       if (smpte.negative) {
+               // Wrap if on hour boundary
+               wrap = increment_minutes( smpte );
+               // Go to lowest possible value in this hour
+               hours_floor( smpte );
+       } else {
+               smpte.minutes = 59;
+               wrap = increment_minutes( smpte );
+       }
+  
+       return wrap;
+}
+
+
+/** Go to lowest absolute value in this hour */
+void
+hours_floor( Time& smpte )
+{
+       smpte.minutes = 0;
+       smpte.seconds = 0;
+       smpte.frames = 0;
+       smpte.subframes = 0;
+  
+       if (SMPTE_IS_ZERO(smpte)) {
+               smpte.negative = false;
+       }
+}
+
+
+} // namespace SMPTE
index 77a4dca805dd83ea40e3ec31ee5e6732587bb4b2..70cbd181c83210b4520bcb08f85241a26fc1926a 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef ardour_generic_midi_control_protocol_h
 #define ardour_generic_midi_control_protocol_h
 
-#include "control_protocol.h"
+#include <control_protocol/control_protocol.h>
 
 namespace MIDI {
        class Port;
index 625ac65273f25204383ced4a37ab89b985773d54..c6c59c658992ec49e5f793074ed968ba184dddb6 100644 (file)
@@ -1,5 +1,4 @@
-#include "control_protocol.h"
-
+#include <control_protocol/control_protocol.h>
 #include "generic_midi_control_protocol.h"
 
 using namespace ARDOUR;
index 20f38dce08666b0835e087af6713ea6fdc993039..29a0fde043d62f5fd7e922f962186f16d878297f 100644 (file)
@@ -1,5 +1,4 @@
-#include "control_protocol.h"
-
+#include <control_protocol/control_protocol.h>
 #include "tranzport_control_protocol.h"
 
 using namespace ARDOUR;
index 4fad413d2418c895d4dec98ce5a531533f50c76c..619f65678a21f03341ed0de9c992fa6ada2a40a6 100644 (file)
@@ -324,7 +324,7 @@ TranzportControlProtocol::show_transport_time ()
        if (where != last_where) {
 
                char buf[5];
-               SMPTE_Time smpte;
+               SMPTE::Time smpte;
 
                session->smpte_time (where, smpte);
                
@@ -395,10 +395,7 @@ TranzportControlProtocol::open_core (struct usb_device* dev)
        }
 
        if (usb_set_configuration (udev, 1) < 0) {
-               error << _("Tranzport: cannot configure USB interface") << endmsg;
-               usb_close (udev);
-               udev = 0;
-               return -1;
+               cerr << _("Tranzport: cannot configure USB interface") << endmsg;
        }
 
        return 0;
index 44045f683484df88a3bb867a9445a59b6d99e808..546cc2f2af3189ff5bbc85b59ee9a94fc79bc201 100644 (file)
@@ -11,7 +11,7 @@
 
 #include <ardour/types.h>
 
-#include "control_protocol.h"
+#include <control_protocol/control_protocol.h>
 
 class TranzportControlProtocol : public ARDOUR::ControlProtocol
 {
index b5410ad7a5caa637b9d307731f0680ef9dacc6e7..7fa556530b1e083a53a84211d33ed5ef484bf117 100644 (file)
@@ -13,5 +13,5 @@ for template in template_files:
 
 Default(template_build)
 
-env.Alias('install', env.Install(os.path.join(install_prefix, 'share/ardour/templates'), template_build))
+env.Alias('install', env.Install(os.path.join(install_prefix, 'share/ardour2/templates'), template_build))
 env.Alias('tarball', env.Distribute (env['DISTTREE'], [ 'SConscript' ] + template_build))