Moved SMPTE type/functions into SMPTE namespace;

LGPL'd SMPTE code and moved in to libardour_cp;
Juggled control_protocol dir layout to be the same as other libs;


git-svn-id: svn://localhost/ardour2/trunk@610 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
David Robillard
2006-06-15 21:54:26 +00:00
parent 4ef0bd2310
commit 6313751f75
27 changed files with 558 additions and 495 deletions

View 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"

View File

@@ -457,7 +457,7 @@ void
AudioClock::set_smpte (jack_nframes_t when, bool force)
{
char buf[32];
SMPTE_Time smpte;
SMPTE::Time smpte;
if (is_duration) {
session->smpte_duration (when, smpte);
@@ -1281,7 +1281,7 @@ AudioClock::smpte_frame_from_display () const
return 0;
}
SMPTE_Time smpte;
SMPTE::Time smpte;
jack_nframes_t sample;
smpte.hours = atoi (hours_label.get_text());
@@ -1302,10 +1302,10 @@ AudioClock::smpte_frame_from_display () const
#define SMPTE_SAMPLE_TEST_7
// Testcode for smpte<->sample conversions (P.S.)
SMPTE_Time smpte1;
SMPTE::Time smpte1;
jack_nframes_t sample1;
jack_nframes_t oldsample = 0;
SMPTE_Time smpte2;
SMPTE::Time smpte2;
jack_nframes_t sample_increment;
sample_increment = (long)rint(session->frame_rate() / session->smpte_frames_per_second);

View 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"

View File

@@ -3458,7 +3458,7 @@ void
Editor::show_verbose_time_cursor (jack_nframes_t frame, double offset, double xpos, double ypos)
{
char buf[128];
SMPTE_Time smpte;
SMPTE::Time smpte;
BBT_Time bbt;
float secs;
@@ -3502,7 +3502,7 @@ void
Editor::show_verbose_duration_cursor (jack_nframes_t start, jack_nframes_t end, double offset, double xpos, double ypos)
{
char buf[128];
SMPTE_Time smpte;
SMPTE::Time smpte;
BBT_Time sbbt;
BBT_Time ebbt;
float secs;

View File

@@ -798,7 +798,7 @@ Editor::metric_get_smpte (GtkCustomRulerMark **marks, gdouble lower, gdouble upp
jack_nframes_t pos;
jack_nframes_t spacer;
jack_nframes_t fr;
SMPTE_Time smpte;
SMPTE::Time smpte;
gchar buf[16];
gint nmarks = 0;
gint n;
@@ -927,13 +927,13 @@ Editor::metric_get_smpte (GtkCustomRulerMark **marks, gdouble lower, gdouble upp
(*marks)[n].position = pos;
// Increment subframes by one
session->smpte_increment_subframes( smpte );
SMPTE::increment_subframes( smpte );
}
} else if (show_seconds) {
// Find smpte time of this sample (pos)
session->sample_to_smpte(pos, smpte, true /* use_offset */, false /* use_subframes */ );
// Go to next whole second down
session->smpte_seconds_floor( smpte );
SMPTE::seconds_floor( smpte );
for (n = 0; n < nmarks; n++) {
session->smpte_to_sample(smpte, pos, true /* use_offset */, false /* use_subframes */ );
@@ -953,13 +953,13 @@ Editor::metric_get_smpte (GtkCustomRulerMark **marks, gdouble lower, gdouble upp
}
(*marks)[n].label = g_strdup (buf);
session->smpte_increment_seconds( smpte );
SMPTE::increment_seconds( smpte );
}
} else if (show_minutes) {
// Find smpte time of this sample (pos)
session->sample_to_smpte(pos, smpte, true /* use_offset */, false /* use_subframes */ );
// Go to next whole minute down
session->smpte_minutes_floor( smpte );
SMPTE::minutes_floor( smpte );
for (n = 0; n < nmarks; n++) {
session->smpte_to_sample(smpte, pos, true /* use_offset */, false /* use_subframes */ );
@@ -977,13 +977,13 @@ Editor::metric_get_smpte (GtkCustomRulerMark **marks, gdouble lower, gdouble upp
}
(*marks)[n].label = g_strdup (buf);
(*marks)[n].position = pos;
session->smpte_increment_minutes( smpte );
SMPTE::increment_minutes( smpte );
}
} else if (show_hours) {
// Find smpte time of this sample (pos)
session->sample_to_smpte(pos, smpte, true /* use_offset */, false /* use_subframes */ );
// Go to next whole hour down
session->smpte_hours_floor( smpte );
SMPTE::hours_floor( smpte );
for (n = 0; n < nmarks; n++) {
session->smpte_to_sample(smpte, pos, true /* use_offset */, false /* use_subframes */ );
@@ -998,13 +998,13 @@ Editor::metric_get_smpte (GtkCustomRulerMark **marks, gdouble lower, gdouble upp
(*marks)[n].label = g_strdup (buf);
(*marks)[n].position = pos;
session->smpte_increment_hours( smpte );
SMPTE::increment_hours( smpte );
}
} else { // show_frames
// Find smpte time of this sample (pos)
session->sample_to_smpte(pos, smpte, true /* use_offset */, false /* use_subframes */ );
// Go to next whole frame down
session->smpte_frames_floor( smpte );
SMPTE::frames_floor( smpte );
for (n = 0; n < nmarks; n++) {
session->smpte_to_sample(smpte, pos, true /* use_offset */, false /* use_subframes */ );
@@ -1019,7 +1019,7 @@ Editor::metric_get_smpte (GtkCustomRulerMark **marks, gdouble lower, gdouble upp
}
(*marks)[n].label = g_strdup (buf);
session->smpte_increment( smpte );
SMPTE::increment( smpte );
}
}

View File

@@ -201,8 +201,8 @@ ardour.Merge ([
libraries['pbd3'],
libraries['soundtouch'],
libraries['midi++2'],
libraries['glib2'],
libraries['glibmm2']
libraries['glib2'],
libraries['glibmm2']
])
if ardour['LIBLO']:

View File

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

View File

@@ -590,25 +590,13 @@ 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 &);
void smpte_time (jack_nframes_t when, SMPTE::Time&);
void smpte_time_subframes (jack_nframes_t when, SMPTE::Time&);
ARDOUR::smpte_wrap_t smpte_increment( SMPTE_Time& smpte ) const;
ARDOUR::smpte_wrap_t smpte_decrement( SMPTE_Time& smpte ) const;
ARDOUR::smpte_wrap_t smpte_increment_subframes( SMPTE_Time& smpte ) const;
ARDOUR::smpte_wrap_t smpte_decrement_subframes( SMPTE_Time& smpte ) const;
ARDOUR::smpte_wrap_t smpte_increment_seconds( SMPTE_Time& smpte ) const;
ARDOUR::smpte_wrap_t smpte_increment_minutes( SMPTE_Time& smpte ) const;
ARDOUR::smpte_wrap_t smpte_increment_hours( SMPTE_Time& smpte ) const;
void smpte_frames_floor( SMPTE_Time& smpte ) const;
void smpte_seconds_floor( SMPTE_Time& smpte ) const;
void smpte_minutes_floor( SMPTE_Time& smpte ) const;
void smpte_hours_floor( SMPTE_Time& smpte ) 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 smpte_time (SMPTE_Time &);
void smpte_time (jack_nframes_t when, SMPTE_Time&);
void smpte_time_subframes (jack_nframes_t when, SMPTE_Time&);
void smpte_duration (jack_nframes_t, SMPTE_Time&) const;
void smpte_duration (jack_nframes_t, SMPTE::Time&) const;
void smpte_duration_string (char *, jack_nframes_t) const;
void set_smpte_offset (jack_nframes_t);
@@ -1346,7 +1334,7 @@ class Session : public sigc::trackable, public Stateful
MIDI::byte mtc_smpte_bits; /* encoding of SMTPE type for MTC */
MIDI::byte midi_msg[16];
jack_nframes_t outbound_mtc_smpte_frame;
SMPTE_Time transmitting_smpte_time;
SMPTE::Time transmitting_smpte_time;
int next_quarter_frame_to_send;
double _frames_per_smpte_frame; /* has to be floating point because of drop frame */
@@ -1362,7 +1350,7 @@ class Session : public sigc::trackable, public Stateful
bool last_smpte_valid;
jack_nframes_t last_smpte_when;
SMPTE_Time last_smpte;
SMPTE::Time last_smpte;
int send_full_time_code ();
int send_midi_time_code ();

View 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 {

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

View File

@@ -87,7 +87,7 @@ void
MTC_Slave::update_mtc_time (const byte *msg, bool was_full)
{
jack_nframes_t now = session.engine().frame_time();
SMPTE_Time smpte;
SMPTE::Time smpte;
smpte.hours = msg[3];
smpte.minutes = msg[2];

View 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;

View 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"

View File

@@ -724,7 +724,7 @@ Session::mmc_locate (MIDI::MachineControl &mmc, const MIDI::byte* mmc_tc)
}
jack_nframes_t target_frame;
SMPTE_Time smpte;
SMPTE::Time smpte;
smpte.hours = mmc_tc[0] & 0xf;
smpte.minutes = mmc_tc[1];
@@ -858,7 +858,7 @@ Session::send_full_time_code ()
{
MIDI::byte msg[10];
SMPTE_Time smpte;
SMPTE::Time smpte;
if (_mtc_port == 0 || !send_mtc) {
return 0;
@@ -884,7 +884,7 @@ Session::send_full_time_code ()
outbound_mtc_smpte_frame = _transport_frame;
if (((mtc_smpte_bits >> 5) != MIDI::MTC_25_FPS) && (transmitting_smpte_time.frames % 2)) {
// start MTC quarter frame transmission on an even frame
smpte_increment( transmitting_smpte_time );
SMPTE::increment( transmitting_smpte_time );
outbound_mtc_smpte_frame += (jack_nframes_t) _frames_per_smpte_frame;
}
}
@@ -985,8 +985,8 @@ Session::send_midi_time_code ()
// Wrap quarter frame counter
next_quarter_frame_to_send = 0;
// Increment smpte time twice
smpte_increment( transmitting_smpte_time );
smpte_increment( transmitting_smpte_time );
SMPTE::increment( transmitting_smpte_time );
SMPTE::increment( transmitting_smpte_time );
// Re-calculate timing of first quarter frame
smpte_to_sample( transmitting_smpte_time, outbound_mtc_smpte_frame, true /* use_offset */, false );
// Compensate for audio latency
@@ -1024,7 +1024,7 @@ Session::deliver_mmc (MIDI::MachineControl::Command cmd, jack_nframes_t where)
{
using namespace MIDI;
int nbytes = 4;
SMPTE_Time smpte;
SMPTE::Time smpte;
if (_mmc_port == 0 || !send_mmc) {
return;

View File

@@ -109,377 +109,9 @@ Session::set_smpte_offset_negative (bool neg)
SMPTEOffsetChanged (); /* EMIT SIGNAL */
}
#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))
// Increment by exactly one frame (keep subframes value)
// Return true if seconds wrap
smpte_wrap_t
Session::smpte_increment( SMPTE_Time& smpte ) const
{
smpte_wrap_t wrap = smpte_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 smpte_wrap_seconds;
}
smpte.negative = false;
wrap = smpte_decrement( smpte );
if (!SMPTE_IS_ZERO( smpte )) {
smpte.negative = true;
}
return wrap;
}
switch (mtc_smpte_bits >> 5) {
case MIDI::MTC_24_FPS:
if (smpte.frames == 23) {
smpte.frames = 0;
wrap = smpte_wrap_seconds;
}
break;
case MIDI::MTC_25_FPS:
if (smpte.frames == 24) {
smpte.frames = 0;
wrap = smpte_wrap_seconds;
}
break;
case MIDI::MTC_30_FPS_DROP:
if (smpte.frames == 29) {
if ( ((smpte.minutes + 1) % 10) && (smpte.seconds == 59) ) {
smpte.frames = 2;
}
else {
smpte.frames = 0;
}
wrap = smpte_wrap_seconds;
}
break;
case MIDI::MTC_30_FPS:
if (smpte.frames == 29) {
smpte.frames = 0;
wrap = smpte_wrap_seconds;
}
break;
}
if (wrap == smpte_wrap_seconds) {
if (smpte.seconds == 59) {
smpte.seconds = 0;
wrap = smpte_wrap_minutes;
if (smpte.minutes == 59) {
smpte.minutes = 0;
wrap = smpte_wrap_hours;
smpte.hours++;
} else {
smpte.minutes++;
}
} else {
smpte.seconds++;
}
} else {
smpte.frames++;
}
return wrap;
}
// Decrement by exactly one frame (keep subframes value)
smpte_wrap_t
Session::smpte_decrement( SMPTE_Time& smpte ) const
{
smpte_wrap_t wrap = smpte_wrap_none;
if (smpte.negative || SMPTE_IS_ZERO(smpte)) {
smpte.negative = false;
wrap = smpte_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 smpte_wrap_seconds;
}
switch (mtc_smpte_bits >> 5) {
case MIDI::MTC_24_FPS:
if (smpte.frames == 0) {
smpte.frames = 23;
wrap = smpte_wrap_seconds;
}
break;
case MIDI::MTC_25_FPS:
if (smpte.frames == 0) {
smpte.frames = 24;
wrap = smpte_wrap_seconds;
}
break;
case MIDI::MTC_30_FPS_DROP:
if ((smpte.minutes % 10) && (smpte.seconds == 0)) {
if (smpte.frames <= 2) {
smpte.frames = 29;
wrap = smpte_wrap_seconds;
}
} else if (smpte.frames == 0) {
smpte.frames = 29;
wrap = smpte_wrap_seconds;
}
break;
case MIDI::MTC_30_FPS:
if (smpte.frames == 0) {
smpte.frames = 29;
wrap = smpte_wrap_seconds;
}
break;
}
if (wrap == smpte_wrap_seconds) {
if (smpte.seconds == 0) {
smpte.seconds = 59;
wrap = smpte_wrap_minutes;
if (smpte.minutes == 0) {
smpte.minutes = 59;
wrap = smpte_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
Session::smpte_frames_floor( SMPTE_Time& smpte ) const
{
smpte.subframes = 0;
if (SMPTE_IS_ZERO(smpte)) {
smpte.negative = false;
}
}
// Increment by one subframe
smpte_wrap_t
Session::smpte_increment_subframes( SMPTE_Time& smpte ) const
{
smpte_wrap_t wrap = smpte_wrap_none;
if (smpte.negative) {
smpte.negative = false;
wrap = smpte_decrement_subframes( smpte );
if (!SMPTE_IS_ZERO(smpte)) {
smpte.negative = true;
}
return wrap;
}
smpte.subframes++;
if (smpte.subframes >= 80) {
smpte.subframes = 0;
smpte_increment( smpte );
return smpte_wrap_frames;
}
return smpte_wrap_none;
}
// Decrement by one subframe
smpte_wrap_t
Session::smpte_decrement_subframes( SMPTE_Time& smpte ) const
{
smpte_wrap_t wrap = smpte_wrap_none;
if (smpte.negative) {
smpte.negative = false;
wrap = smpte_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 smpte_wrap_frames;
} else {
smpte_decrement( smpte );
smpte.subframes = 79;
return smpte_wrap_frames;
}
} else {
smpte.subframes--;
if (SMPTE_IS_ZERO(smpte)) {
smpte.negative = false;
}
return smpte_wrap_none;
}
}
// Go to next whole second (frames == 0 or frames == 2)
smpte_wrap_t
Session::smpte_increment_seconds( SMPTE_Time& smpte ) const
{
smpte_wrap_t wrap = smpte_wrap_none;
// Clear subframes
smpte_frames_floor( smpte );
if (smpte.negative) {
// Wrap second if on second boundary
wrap = smpte_increment(smpte);
// Go to lowest absolute frame value
smpte_seconds_floor( smpte );
if (SMPTE_IS_ZERO(smpte)) {
smpte.negative = false;
}
} else {
// Go to highest possible frame in this second
switch (mtc_smpte_bits >> 5) {
case MIDI::MTC_24_FPS:
smpte.frames = 23;
break;
case MIDI::MTC_25_FPS:
smpte.frames = 24;
break;
case MIDI::MTC_30_FPS_DROP:
case MIDI::MTC_30_FPS:
smpte.frames = 29;
break;
}
// Increment by one frame
wrap = smpte_increment( smpte );
}
return wrap;
}
// Go to lowest (absolute) frame value in this second
// Doesn't care about positive/negative
void
Session::smpte_seconds_floor( SMPTE_Time& smpte ) const
{
// Clear subframes
smpte_frames_floor( smpte );
// Go to lowest possible frame in this second
switch (mtc_smpte_bits >> 5) {
case MIDI::MTC_24_FPS:
case MIDI::MTC_25_FPS:
case MIDI::MTC_30_FPS:
smpte.frames = 0;
break;
case MIDI::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)
smpte_wrap_t
Session::smpte_increment_minutes( SMPTE_Time& smpte ) const
{
smpte_wrap_t wrap = smpte_wrap_none;
// Clear subframes
smpte_frames_floor( smpte );
if (smpte.negative) {
// Wrap if on minute boundary
wrap = smpte_increment_seconds( smpte );
// Go to lowest possible value in this minute
smpte_minutes_floor( smpte );
} else {
// Go to highest possible second
smpte.seconds = 59;
// Wrap minute by incrementing second
wrap = smpte_increment_seconds( smpte );
}
return wrap;
}
// Go to lowest absolute value in this minute
void
Session::smpte_minutes_floor( SMPTE_Time& smpte ) const
{
// Go to lowest possible second
smpte.seconds = 0;
// Go to lowest possible frame
smpte_seconds_floor( smpte );
if (SMPTE_IS_ZERO(smpte)) {
smpte.negative = false;
}
}
// Go to next whole hour (minute = 0, second = 0, frame = 0)
smpte_wrap_t
Session::smpte_increment_hours( SMPTE_Time& smpte ) const
{
smpte_wrap_t wrap = smpte_wrap_none;
// Clear subframes
smpte_frames_floor(smpte);
if (smpte.negative) {
// Wrap if on hour boundary
wrap = smpte_increment_minutes( smpte );
// Go to lowest possible value in this hour
smpte_hours_floor( smpte );
} else {
smpte.minutes = 59;
wrap = smpte_increment_minutes( smpte );
}
return wrap;
}
// Go to lowest absolute value in this hour
void
Session::smpte_hours_floor( SMPTE_Time& smpte ) const
{
smpte.minutes = 0;
smpte.seconds = 0;
smpte.frames = 0;
smpte.subframes = 0;
if (SMPTE_IS_ZERO(smpte)) {
smpte.negative = false;
}
}
void
Session::smpte_to_sample( SMPTE_Time& smpte, jack_nframes_t& sample, bool use_offset, bool use_subframes ) const
Session::smpte_to_sample( SMPTE::Time& smpte, jack_nframes_t& sample, bool use_offset, bool use_subframes ) const
{
if (smpte_drop_frames) {
// The drop frame format was created to better approximate the 30000/1001 = 29.97002997002997....
@@ -562,7 +194,7 @@ Session::smpte_to_sample( SMPTE_Time& smpte, jack_nframes_t& sample, bool use_of
void
Session::sample_to_smpte( jack_nframes_t sample, SMPTE_Time& smpte, bool use_offset, bool use_subframes ) const
Session::sample_to_smpte( jack_nframes_t sample, SMPTE::Time& smpte, bool use_offset, bool use_subframes ) const
{
jack_nframes_t offset_sample;
@@ -656,7 +288,7 @@ Session::sample_to_smpte( jack_nframes_t sample, SMPTE_Time& smpte, bool use_off
}
void
Session::smpte_time (jack_nframes_t when, SMPTE_Time& smpte)
Session::smpte_time (jack_nframes_t when, SMPTE::Time& smpte)
{
if (last_smpte_valid && when == last_smpte_when) {
smpte = last_smpte;
@@ -671,7 +303,7 @@ Session::smpte_time (jack_nframes_t when, SMPTE_Time& smpte)
}
void
Session::smpte_time_subframes (jack_nframes_t when, SMPTE_Time& smpte)
Session::smpte_time_subframes (jack_nframes_t when, SMPTE::Time& smpte)
{
if (last_smpte_valid && when == last_smpte_when) {
smpte = last_smpte;
@@ -686,7 +318,7 @@ Session::smpte_time_subframes (jack_nframes_t when, SMPTE_Time& smpte)
}
void
Session::smpte_duration (jack_nframes_t when, SMPTE_Time& smpte) const
Session::smpte_duration (jack_nframes_t when, SMPTE::Time& smpte) const
{
sample_to_smpte( when, smpte, false /* use_offset */, true /* use_subframes */ );
}
@@ -694,14 +326,14 @@ Session::smpte_duration (jack_nframes_t when, SMPTE_Time& smpte) const
void
Session::smpte_duration_string (char* buf, jack_nframes_t when) const
{
SMPTE_Time smpte;
SMPTE::Time smpte;
smpte_duration (when, smpte);
snprintf (buf, sizeof (buf), "%02" PRIu32 ":%02" PRIu32 ":%02" PRIu32 ":%02" PRIu32, smpte.hours, smpte.minutes, smpte.seconds, smpte.frames);
}
void
Session::smpte_time (SMPTE_Time &t)
Session::smpte_time (SMPTE::Time &t)
{
smpte_time (_transport_frame, t);

View 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')))

View 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));
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);
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);
session->sample_to_smpte (sample, *((SMPTE::Time*)&smpte), use_offset, use_subframes);
}

View 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;

View File

@@ -25,6 +25,7 @@
#include <string>
#include <jack/types.h>
#include <control_protocol/smpte.h>
namespace ARDOUR {
class Session;
@@ -72,27 +73,9 @@ class BasicUI {
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;
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 ();

View File

@@ -27,7 +27,7 @@
#include <list>
#include <sigc++/sigc++.h>
#include "basic_ui.h"
#include <control_protocol/basic_ui.h>
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
#define ardour_generic_midi_control_protocol_h
#include "control_protocol.h"
#include <control_protocol/control_protocol.h>
namespace MIDI {
class Port;

View File

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

View File

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

View 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);

View File

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