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

@@ -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));
}
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);
}

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