mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-08 15:54:57 +01:00
Removed excessive debug printing, added missing files for SMPTE namespace and Jack libmidi++ ports
git-svn-id: svn://localhost/ardour2/branches/midi@577 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
5905d4f7b6
commit
2f4392f043
6 changed files with 681 additions and 8 deletions
76
libs/ardour/ardour/smpte.h
Normal file
76
libs/ardour/ardour/smpte.h
Normal file
|
|
@ -0,0 +1,76 @@
|
||||||
|
/* Copyright (C) 2006 Paul Davis
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by the
|
||||||
|
Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __ardour_smpte_h__
|
||||||
|
#define __ardour_smpte_h__
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
namespace SMPTE {
|
||||||
|
|
||||||
|
enum Wrap {
|
||||||
|
NONE = 0,
|
||||||
|
FRAMES,
|
||||||
|
SECONDS,
|
||||||
|
MINUTES,
|
||||||
|
HOURS
|
||||||
|
};
|
||||||
|
|
||||||
|
// FIXME: make this a float
|
||||||
|
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__
|
||||||
|
|
@ -22,6 +22,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
|
#include <cassert>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ using namespace std;
|
||||||
void
|
void
|
||||||
Session::process (jack_nframes_t nframes)
|
Session::process (jack_nframes_t nframes)
|
||||||
{
|
{
|
||||||
cerr << "CYCLE START " << _transport_frame << "-------------------" << endl;
|
//cerr << "CYCLE START " << _transport_frame << "-------------------" << endl;
|
||||||
|
|
||||||
MIDI::Manager::instance()->cycle_start(nframes);
|
MIDI::Manager::instance()->cycle_start(nframes);
|
||||||
|
|
||||||
|
|
@ -69,7 +69,7 @@ Session::process (jack_nframes_t nframes)
|
||||||
|
|
||||||
MIDI::Manager::instance()->cycle_end();
|
MIDI::Manager::instance()->cycle_end();
|
||||||
|
|
||||||
cerr << "CYCLE END " << _transport_frame << "-----------------------" << endl;
|
//cerr << "CYCLE END " << _transport_frame << "-----------------------" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -87,8 +87,6 @@ Session::no_roll (jack_nframes_t nframes, jack_nframes_t offset)
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
bool declick = get_transport_declick_required();
|
bool declick = get_transport_declick_required();
|
||||||
|
|
||||||
cerr << "[DR] no_roll\n";
|
|
||||||
|
|
||||||
if (_click_io) {
|
if (_click_io) {
|
||||||
_click_io->silence (nframes, offset);
|
_click_io->silence (nframes, offset);
|
||||||
}
|
}
|
||||||
|
|
@ -261,8 +259,6 @@ Session::process_with_events (jack_nframes_t nframes)
|
||||||
long frames_moved;
|
long frames_moved;
|
||||||
bool session_needs_butler = false;
|
bool session_needs_butler = false;
|
||||||
|
|
||||||
cerr << "[DR] with events" << endl;
|
|
||||||
|
|
||||||
if (auditioner) {
|
if (auditioner) {
|
||||||
auditioner->silence (nframes, 0);
|
auditioner->silence (nframes, 0);
|
||||||
}
|
}
|
||||||
|
|
@ -741,8 +737,6 @@ Session::follow_slave (jack_nframes_t nframes, jack_nframes_t offset)
|
||||||
void
|
void
|
||||||
Session::process_without_events (jack_nframes_t nframes)
|
Session::process_without_events (jack_nframes_t nframes)
|
||||||
{
|
{
|
||||||
cerr << "[DR] without events" << endl;
|
|
||||||
|
|
||||||
bool session_needs_butler = false;
|
bool session_needs_butler = false;
|
||||||
jack_nframes_t stop_limit;
|
jack_nframes_t stop_limit;
|
||||||
long frames_moved;
|
long frames_moved;
|
||||||
|
|
|
||||||
406
libs/ardour/smpte.cc
Normal file
406
libs/ardour/smpte.cc
Normal 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 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.,
|
||||||
|
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 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 <ardour/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;
|
||||||
|
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
|
||||||
128
libs/midi++2/jack_midiport.cc
Normal file
128
libs/midi++2/jack_midiport.cc
Normal file
|
|
@ -0,0 +1,128 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2006 Paul Davis
|
||||||
|
Written by Dave Robillard
|
||||||
|
|
||||||
|
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: alsa_sequencer_midiport.cc 244 2006-01-06 04:59:17Z essej $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <cerrno>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
#include <midi++/types.h>
|
||||||
|
#include <midi++/jack.h>
|
||||||
|
#include <midi++/port_request.h>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace MIDI;
|
||||||
|
|
||||||
|
JACK_MidiPort::JACK_MidiPort(PortRequest & req, jack_client_t* jack_client)
|
||||||
|
: Port(req)
|
||||||
|
, _jack_client(jack_client)
|
||||||
|
, _jack_input_port(NULL)
|
||||||
|
, _jack_output_port(NULL)
|
||||||
|
, _last_read_index(0)
|
||||||
|
{
|
||||||
|
int err = create_ports(req);
|
||||||
|
|
||||||
|
if (!err) {
|
||||||
|
req.status = PortRequest::OK;
|
||||||
|
_ok = true;
|
||||||
|
} else {
|
||||||
|
req.status = PortRequest::Unknown;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
JACK_MidiPort::~JACK_MidiPort()
|
||||||
|
{
|
||||||
|
// FIXME: remove port
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
JACK_MidiPort::cycle_start (nframes_t nframes)
|
||||||
|
{
|
||||||
|
Port::cycle_start(nframes);
|
||||||
|
assert(_nframes_this_cycle == nframes);
|
||||||
|
_last_read_index = 0;
|
||||||
|
jack_midi_clear_buffer(jack_port_get_buffer(_jack_output_port, nframes), nframes);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
JACK_MidiPort::write(byte * msg, size_t msglen, timestamp_t timestamp)
|
||||||
|
{
|
||||||
|
assert(_currently_in_cycle);
|
||||||
|
assert(timestamp < _nframes_this_cycle);
|
||||||
|
assert(_jack_output_port);
|
||||||
|
|
||||||
|
// FIXME: return value correct?
|
||||||
|
return jack_midi_event_write (
|
||||||
|
jack_port_get_buffer(_jack_output_port, _nframes_this_cycle),
|
||||||
|
timestamp, msg, msglen, _nframes_this_cycle);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
JACK_MidiPort::read(byte * buf, size_t max, timestamp_t timestamp)
|
||||||
|
{
|
||||||
|
assert(_currently_in_cycle);
|
||||||
|
assert(timestamp < _nframes_this_cycle);
|
||||||
|
assert(_jack_input_port);
|
||||||
|
|
||||||
|
jack_midi_event_t ev;
|
||||||
|
|
||||||
|
int err = jack_midi_event_get (&ev,
|
||||||
|
jack_port_get_buffer(_jack_input_port, _nframes_this_cycle),
|
||||||
|
_last_read_index++, _nframes_this_cycle);
|
||||||
|
|
||||||
|
if (!err) {
|
||||||
|
memcpy(buf, ev.buffer, ev.size);
|
||||||
|
return ev.size;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
JACK_MidiPort::create_ports(PortRequest & req)
|
||||||
|
{
|
||||||
|
assert(!_jack_input_port);
|
||||||
|
assert(!_jack_output_port);
|
||||||
|
|
||||||
|
jack_nframes_t nframes = jack_get_buffer_size(_jack_client);
|
||||||
|
|
||||||
|
bool ret = true;
|
||||||
|
|
||||||
|
if (req.mode == O_RDWR || req.mode == O_WRONLY) {
|
||||||
|
_jack_output_port = jack_port_register(_jack_client,
|
||||||
|
string(req.tagname).append("_out").c_str(),
|
||||||
|
JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0);
|
||||||
|
jack_midi_reset_new_port(
|
||||||
|
jack_port_get_buffer(_jack_output_port, nframes), nframes);
|
||||||
|
ret = ret && (_jack_output_port != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (req.mode == O_RDWR || req.mode == O_RDONLY) {
|
||||||
|
_jack_input_port = jack_port_register(_jack_client,
|
||||||
|
string(req.tagname).append("_in").c_str(),
|
||||||
|
JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0);
|
||||||
|
jack_midi_reset_new_port(
|
||||||
|
jack_port_get_buffer(_jack_input_port, nframes), nframes);
|
||||||
|
ret = ret && (_jack_input_port != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret ? 0 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
68
libs/midi++2/midi++/jack.h
Normal file
68
libs/midi++2/midi++/jack.h
Normal file
|
|
@ -0,0 +1,68 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2006 Paul Davis
|
||||||
|
Written by Dave Robillard
|
||||||
|
|
||||||
|
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: jack.h 4 2005-05-13 20:47:18Z taybin $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __jack_midiport_h__
|
||||||
|
#define __jack_midiport_h__
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <jack/jack.h>
|
||||||
|
#include <jack/midiport.h>
|
||||||
|
#include <midi++/port.h>
|
||||||
|
|
||||||
|
namespace MIDI
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
class JACK_MidiPort : public Port
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
JACK_MidiPort (PortRequest &req, jack_client_t* jack_client);
|
||||||
|
virtual ~JACK_MidiPort ();
|
||||||
|
|
||||||
|
/* No select(2)/poll(2)-based I/O */
|
||||||
|
virtual int selectable() const { return -1; }
|
||||||
|
|
||||||
|
virtual void cycle_start(nframes_t nframes);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/* Direct I/O */
|
||||||
|
int write(byte *msg, size_t msglen, timestamp_t timestamp);
|
||||||
|
int read(byte *buf, size_t max, timestamp_t timestamp);
|
||||||
|
|
||||||
|
private:
|
||||||
|
int create_ports(PortRequest &req);
|
||||||
|
|
||||||
|
jack_client_t* _jack_client;
|
||||||
|
jack_port_t* _jack_input_port;
|
||||||
|
jack_port_t* _jack_output_port;
|
||||||
|
nframes_t _last_read_index;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} /* namespace MIDI */
|
||||||
|
|
||||||
|
#endif // __jack_midiport_h__
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue