summaryrefslogtreecommitdiff
path: root/libs/surfaces/mackie
diff options
context:
space:
mode:
Diffstat (limited to 'libs/surfaces/mackie')
-rw-r--r--libs/surfaces/mackie/mackie_control_protocol.cc91
-rw-r--r--libs/surfaces/mackie/mackie_control_protocol.h11
-rw-r--r--libs/surfaces/mackie/mackie_control_protocol_poll.cc5
3 files changed, 100 insertions, 7 deletions
diff --git a/libs/surfaces/mackie/mackie_control_protocol.cc b/libs/surfaces/mackie/mackie_control_protocol.cc
index 502cea581f..f7886e078f 100644
--- a/libs/surfaces/mackie/mackie_control_protocol.cc
+++ b/libs/surfaces/mackie/mackie_control_protocol.cc
@@ -1030,9 +1030,9 @@ void MackieControlProtocol::update_automation( RouteSignal & rs )
}
}
-void MackieControlProtocol::poll_automation()
+void MackieControlProtocol::poll_automation ()
{
- if ( _active )
+ if ( _active && _automation_last.elapsed() >= 20 )
{
// do all currently mapped routes
for( RouteSignals::iterator it = route_signals.begin(); it != route_signals.end(); ++it )
@@ -1041,7 +1041,92 @@ void MackieControlProtocol::poll_automation()
}
// and the master strip
- if ( master_route_signal != 0 ) update_automation( *master_route_signal );
+ if ( master_route_signal != 0 )
+ {
+ update_automation( *master_route_signal );
+ }
+
+ update_timecode_display();
+
+ _automation_last.start();
+ }
+}
+
+string MackieControlProtocol::format_bbt_timecode( nframes_t now_frame )
+{
+ BBT_Time bbt_time;
+ session->bbt_time( now_frame, bbt_time );
+
+ // According to the Logic docs
+ // digits: 888/88/88/888
+ // BBT mode: Bars/Beats/Subdivisions/Ticks
+ ostringstream os;
+ os << setw(3) << setfill('0') << bbt_time.bars;
+ os << setw(2) << setfill('0') << bbt_time.beats;
+
+ // figure out subdivisions per beat
+ const Meter & meter = session->tempo_map().meter_at( now_frame );
+ int subdiv = 2;
+ if ( meter.note_divisor() == 8 && (meter.beats_per_bar() == 12.0 || meter.beats_per_bar() == 9.0 || meter.beats_per_bar() == 6.0) )
+ {
+ subdiv = 3;
+ }
+
+ uint32_t subdivisions = bbt_time.ticks / uint32_t( Meter::ticks_per_beat / subdiv );
+ uint32_t ticks = bbt_time.ticks % uint32_t( Meter::ticks_per_beat / subdiv );
+
+ os << setw(2) << setfill('0') << subdivisions + 1;
+ os << setw(3) << setfill('0') << ticks;
+
+ return os.str();
+}
+
+string MackieControlProtocol::format_smpte_timecode( nframes_t now_frame )
+{
+ SMPTE::Time smpte;
+ session->smpte_time( now_frame, smpte );
+
+ // According to the Logic docs
+ // digits: 888/88/88/888
+ // SMPTE mode: Hours/Minutes/Seconds/Frames
+ ostringstream os;
+ os << setw(3) << setfill('0') << smpte.hours;
+ os << setw(2) << setfill('0') << smpte.minutes;
+ os << setw(2) << setfill('0') << smpte.seconds;
+ os << setw(3) << setfill('0') << smpte.frames;
+
+ return os.str();
+}
+
+void MackieControlProtocol::update_timecode_display()
+{
+ if ( surface().has_timecode_display() )
+ {
+ // do assignment here so current_frame is fixed
+ nframes_t current_frame = session->transport_frame();
+ string timecode;
+
+ switch ( _timecode_type )
+ {
+ case ARDOUR::AnyTime::BBT:
+ timecode = format_bbt_timecode( current_frame );
+ break;
+ case ARDOUR::AnyTime::SMPTE:
+ timecode = format_smpte_timecode( current_frame );
+ break;
+ default:
+ ostringstream os;
+ os << "Unknown timecode: " << _timecode_type;
+ throw runtime_error( os.str() );
+ }
+
+ // only write the timecode string to the MCU if it's changed
+ // since last time. This is to reduce midi bandwidth used.
+ if ( timecode != _timecode_last )
+ {
+ surface().display_timecode( mcu_port(), builder, timecode, _timecode_last );
+ _timecode_last = timecode;
+ }
}
}
diff --git a/libs/surfaces/mackie/mackie_control_protocol.h b/libs/surfaces/mackie/mackie_control_protocol.h
index 0ff7fbd9d4..735a2c88bd 100644
--- a/libs/surfaces/mackie/mackie_control_protocol.h
+++ b/libs/surfaces/mackie/mackie_control_protocol.h
@@ -255,12 +255,19 @@ class MackieControlProtocol
void add_port( MIDI::Port &, int number );
- /// read automation data from the currently active routes and send to surface
- void poll_automation();
+ /**
+ Read session data and send to surface. Includes
+ automation from the currently active routes and
+ timecode displays.
+ */
+ void poll_automation ();
// called from poll_automation to figure out which automations need to be sent
void update_automation( Mackie::RouteSignal & );
+ // also called from poll_automation to update timecode display
+ void update_timecode_display();
+
/**
notification that the port is about to start it's init sequence.
We must make sure that before this exits, the port is being polled
diff --git a/libs/surfaces/mackie/mackie_control_protocol_poll.cc b/libs/surfaces/mackie/mackie_control_protocol_poll.cc
index cf72c35678..cd95551f70 100644
--- a/libs/surfaces/mackie/mackie_control_protocol_poll.cc
+++ b/libs/surfaces/mackie/mackie_control_protocol_poll.cc
@@ -33,8 +33,7 @@ bool MackieControlProtocol::probe()
void * MackieControlProtocol::monitor_work()
{
- // What does ThreadCreatedWithRequestSize do?
- PBD::ThreadCreated (pthread_self(), X_("Mackie"));
+ PBD::notify_gui_about_thread_creation (pthread_self(), X_("Mackie"));
pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, 0);
pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0);
@@ -105,6 +104,8 @@ void MackieControlProtocol::read_ports()
for ( int p = 0; p < nfds; ++p )
{
// this will cause handle_midi_any in the MackiePort to be triggered
+ // for alsa/raw ports
+ // alsa/sequencer ports trigger the midi parser off poll
if ( (pfd[p].revents & POLLIN) > 0 )
{
// avoid deadlocking?