Merged with trunk revision 610

git-svn-id: svn://localhost/ardour2/branches/midi@611 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
David Robillard 2006-06-15 22:31:13 +00:00
parent b5db1f624d
commit e13e84677a
31 changed files with 545 additions and 1980 deletions

View file

@ -1,3 +1,3 @@
Last merged with trunk revision: Last merged with trunk revision:
600 610

View file

@ -35,7 +35,7 @@
#include <ardour/session.h> #include <ardour/session.h>
#include <ardour/control_protocol_manager.h> #include <ardour/control_protocol_manager.h>
#include "control_protocol.h" #include <control_protocol/control_protocol.h>
#include "i18n.h" #include "i18n.h"

View file

@ -48,7 +48,7 @@
#include <ardour/tempo.h> #include <ardour/tempo.h>
#include <ardour/utils.h> #include <ardour/utils.h>
#include "control_protocol.h" #include <control_protocol/control_protocol.h>
#include "ardour_ui.h" #include "ardour_ui.h"
#include "editor.h" #include "editor.h"

View file

@ -334,8 +334,12 @@ GainMeter::update_meters ()
if (peak > max_peak) { if (peak > max_peak) {
max_peak = peak; max_peak = peak;
/* set peak display */ /* set peak display */
if (max_peak <= -200.0f) {
peak_display_label.set_text (_("-inf"));
} else {
snprintf (buf, sizeof(buf), "%.1f", max_peak); snprintf (buf, sizeof(buf), "%.1f", max_peak);
peak_display_label.set_text (buf); peak_display_label.set_text (buf);
}
if (max_peak >= 0.0f) { if (max_peak >= 0.0f) {
peak_display.set_name ("MixerStripPeakDisplayPeak"); peak_display.set_name ("MixerStripPeakDisplayPeak");

View file

@ -302,6 +302,11 @@ NewSessionDialog::NewSessionDialog()
if (!path.empty()) { if (!path.empty()) {
m_template->set_current_folder (path + X_("templates/")); 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")); m_template->set_title(_("select template"));
Gtk::FileFilter* session_filter = manage (new (Gtk::FileFilter)); Gtk::FileFilter* session_filter = manage (new (Gtk::FileFilter));
session_filter->add_pattern(X_("*.ardour")); session_filter->add_pattern(X_("*.ardour"));

View file

@ -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__ */

View file

@ -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__ */

View file

@ -32,7 +32,7 @@
#include <ardour/types.h> #include <ardour/types.h>
#include "basic_ui.h" #include <control_protocol/basic_ui.h>
namespace ARDOUR { namespace ARDOUR {
class Session; class Session;

View file

@ -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__ */

View file

@ -592,7 +592,6 @@ class Session : public sigc::trackable, public Stateful
int set_smpte_type (float fps, bool drop_frames); int set_smpte_type (float fps, bool drop_frames);
void bbt_time (jack_nframes_t when, BBT_Time&); 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 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 sample_to_smpte( jack_nframes_t sample, SMPTE::Time& smpte, bool use_offset, bool use_subframes ) const;
void smpte_time (SMPTE::Time &); void smpte_time (SMPTE::Time &);
@ -1352,7 +1351,7 @@ class Session : public sigc::trackable, public Stateful
jack_nframes_t last_smpte_when; jack_nframes_t last_smpte_when;
SMPTE::Time last_smpte; 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_full_time_code(jack_nframes_t nframes);
int send_midi_time_code_for_cycle(jack_nframes_t nframes); int send_midi_time_code_for_cycle(jack_nframes_t nframes);

View file

@ -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__ */

View file

@ -29,6 +29,7 @@
#include <inttypes.h> #include <inttypes.h>
#include <jack/types.h> #include <jack/types.h>
#include <control_protocol/smpte.h>
#include <map> #include <map>
#if __GNUC__ < 3 #if __GNUC__ < 3
@ -99,33 +100,6 @@ namespace ARDOUR {
Destructive 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 { struct BBT_Time {
uint32_t bars; uint32_t bars;
uint32_t beats; uint32_t beats;
@ -164,7 +138,7 @@ namespace ARDOUR {
Type type; Type type;
SMPTE_Time smpte; SMPTE::Time smpte;
BBT_Time bbt; BBT_Time bbt;
union { union {

View file

@ -4,7 +4,7 @@
#include <pbd/error.h> #include <pbd/error.h>
#include <pbd/pathscanner.h> #include <pbd/pathscanner.h>
#include "control_protocol.h" #include <control_protocol/control_protocol.h>
#include <ardour/session.h> #include <ardour/session.h>
#include <ardour/control_protocol_manager.h> #include <ardour/control_protocol_manager.h>

File diff suppressed because it is too large Load diff

View file

@ -2493,7 +2493,7 @@ IO::meter ()
} else { } else {
// do falloff // do falloff
new_peak = _visible_peak_power[n] - _session.meter_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);
} }
} }
} }

View file

@ -1,8 +1,8 @@
#include <ardour/session.h> #include <ardour/session.h>
#include <ardour/control_protocol.h> #include <control_protocol/control_protocol.h>
#include <ardour/generic_midi_control_protocol.h> #include <generic_midi/generic_midi_control_protocol.h>
#include <ardour/tranzport_control_protocol.h> #include <transport/tranzport_control_protocol.h>
using namespace ARDOUR; using namespace ARDOUR;

View file

@ -39,7 +39,7 @@
#include <ardour/session.h> #include <ardour/session.h>
#include <ardour/audio_track.h> #include <ardour/audio_track.h>
#include <ardour/audio_diskstream.h> #include <ardour/audio_diskstream.h>
#include <ardour/control_protocol.h> #include <control_protocol/control_protocol.h>
#include "i18n.h" #include "i18n.h"

View file

@ -354,11 +354,12 @@ FastMeter::vertical_expose (GdkEventExpose* ev)
// draw peak bar // draw peak bar
if (hold_state && intersection.width > 0) { if (hold_state && intersection.width > 0) {
gint y = pixheight - (gint) floor (pixheight * current_peak); 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, get_window()->draw_pixbuf (get_style()->get_fg_gc(get_state()), pixbuf,
intersection.x, y, intersection.x, y,
intersection.x, y, intersection.x, y,
intersection.width, 3, intersection.width, h,
Gdk::RGB_DITHER_NONE, 0, 0); Gdk::RGB_DITHER_NONE, 0, 0);
} }

View file

@ -23,6 +23,7 @@ cp.Append(POTFILE = domain + '.pot')
cp_files=Split(""" cp_files=Split("""
basic_ui.cc basic_ui.cc
control_protocol.cc control_protocol.cc
smpte.cc
""") """)
cp.Append(CCFLAGS="-D_REENTRANT -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE") 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'], env.Alias('tarball', env.Distribute (env['DISTTREE'],
[ 'SConscript' ] + [ 'SConscript' ] +
cp_files + cp_files +
glob.glob('po/*.po') + glob.glob('*.h'))) glob.glob('po/*.po') + glob.glob('*.h') + glob.glob('control_protocol/*.h')))

View file

@ -24,7 +24,8 @@
#include <ardour/session.h> #include <ardour/session.h>
#include <ardour/location.h> #include <ardour/location.h>
#include "basic_ui.h" #include <control_protocol/basic_ui.h>
#include "i18n.h" #include "i18n.h"
using namespace ARDOUR; using namespace ARDOUR;
@ -263,19 +264,19 @@ BasicUI::smpte_frames_per_hour ()
} }
void 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)); session->smpte_time (where, *((SMPTE::Time *) &smpte));
} }
void 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); session->smpte_to_sample (*((SMPTE::Time*)&smpte), sample, use_offset, use_subframes);
} }
void 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); session->sample_to_smpte (sample, *((SMPTE::Time*)&smpte), use_offset, use_subframes);
} }

View file

@ -23,7 +23,7 @@
#include <ardour/route.h> #include <ardour/route.h>
#include <ardour/audio_track.h> #include <ardour/audio_track.h>
#include "control_protocol.h" #include <control_protocol/control_protocol.h>
using namespace ARDOUR; using namespace ARDOUR;
using namespace std; using namespace std;

View file

@ -25,6 +25,7 @@
#include <string> #include <string>
#include <jack/types.h> #include <jack/types.h>
#include <control_protocol/smpte.h>
namespace ARDOUR { namespace ARDOUR {
class Session; class Session;
@ -72,27 +73,9 @@ class BasicUI {
jack_nframes_t smpte_frames_per_hour (); jack_nframes_t smpte_frames_per_hour ();
struct SMPTE_t { void smpte_time (jack_nframes_t where, SMPTE::Time&);
bool negative; void smpte_to_sample (SMPTE::Time& smpte, jack_nframes_t& sample, bool use_offset, bool use_subframes) const;
uint32_t hours; void sample_to_smpte (jack_nframes_t sample, SMPTE::Time& smpte, bool use_offset, bool use_subframes) const;
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: protected:
BasicUI (); BasicUI ();

View file

@ -27,7 +27,7 @@
#include <list> #include <list>
#include <sigc++/sigc++.h> #include <sigc++/sigc++.h>
#include "basic_ui.h" #include <control_protocol/basic_ui.h>
namespace ARDOUR { namespace ARDOUR {

View file

@ -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__

View file

@ -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

View file

@ -1,7 +1,7 @@
#ifndef ardour_generic_midi_control_protocol_h #ifndef ardour_generic_midi_control_protocol_h
#define 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 { namespace MIDI {
class Port; class Port;

View file

@ -1,5 +1,4 @@
#include "control_protocol.h" #include <control_protocol/control_protocol.h>
#include "generic_midi_control_protocol.h" #include "generic_midi_control_protocol.h"
using namespace ARDOUR; using namespace ARDOUR;

View file

@ -1,5 +1,4 @@
#include "control_protocol.h" #include <control_protocol/control_protocol.h>
#include "tranzport_control_protocol.h" #include "tranzport_control_protocol.h"
using namespace ARDOUR; using namespace ARDOUR;

View file

@ -324,7 +324,7 @@ TranzportControlProtocol::show_transport_time ()
if (where != last_where) { if (where != last_where) {
char buf[5]; char buf[5];
SMPTE_Time smpte; SMPTE::Time smpte;
session->smpte_time (where, smpte); session->smpte_time (where, smpte);
@ -395,10 +395,7 @@ TranzportControlProtocol::open_core (struct usb_device* dev)
} }
if (usb_set_configuration (udev, 1) < 0) { if (usb_set_configuration (udev, 1) < 0) {
error << _("Tranzport: cannot configure USB interface") << endmsg; cerr << _("Tranzport: cannot configure USB interface") << endmsg;
usb_close (udev);
udev = 0;
return -1;
} }
return 0; return 0;

View file

@ -11,7 +11,7 @@
#include <ardour/types.h> #include <ardour/types.h>
#include "control_protocol.h" #include <control_protocol/control_protocol.h>
class TranzportControlProtocol : public ARDOUR::ControlProtocol class TranzportControlProtocol : public ARDOUR::ControlProtocol
{ {

View file

@ -13,5 +13,5 @@ for template in template_files:
Default(template_build) 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)) env.Alias('tarball', env.Distribute (env['DISTTREE'], [ 'SConscript' ] + template_build))