summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Anderson <ardour@semiosix.com>2007-07-18 19:09:33 +0000
committerJohn Anderson <ardour@semiosix.com>2007-07-18 19:09:33 +0000
commitbfb5ddedab95238a67964310f44290ba301471d0 (patch)
tree2558d86a7a351cc9b6e5d23e7398d167e4b79406
parent5c8830f952d9db413b03a24088d4c91b3d7f5709 (diff)
Beginnings of writing to the LCD strip display. Some other tweaks and output thing, mostly related to alsa/sequencer weirdness.
git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@2144 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r--libs/surfaces/mackie/TODO2
-rw-r--r--libs/surfaces/mackie/controls.h6
-rw-r--r--libs/surfaces/mackie/mackie_control_protocol.cc33
-rw-r--r--libs/surfaces/mackie/mackie_control_protocol_poll.cc26
-rw-r--r--libs/surfaces/mackie/mackie_midi_builder.cc37
-rw-r--r--libs/surfaces/mackie/mackie_midi_builder.h7
-rw-r--r--libs/surfaces/mackie/mackie_port.cc35
-rw-r--r--libs/surfaces/mackie/mackie_port.h4
-rw-r--r--libs/surfaces/mackie/midi_byte_array.cc10
-rw-r--r--libs/surfaces/mackie/midi_byte_array.h3
-rw-r--r--libs/surfaces/mackie/surface.cc1
-rw-r--r--libs/surfaces/mackie/surface_port.cc7
12 files changed, 157 insertions, 14 deletions
diff --git a/libs/surfaces/mackie/TODO b/libs/surfaces/mackie/TODO
index a9cb1b9878..f552c4a74c 100644
--- a/libs/surfaces/mackie/TODO
+++ b/libs/surfaces/mackie/TODO
@@ -1,3 +1,5 @@
+* alsa/sequencer ports unstable
+* crash when mmc port set to mcu
* how long can UI signal callbacks take to execute? What happens if they block?
where ENSURE_CORRECT_THREAD is a macro that is modelled on ENSURE_GUI_THREAD
if the handler is not called in the "correct thread", it will use a pseudo-RT-safe-enough technique to get the correct thread to recall "handler" later on, and return.
diff --git a/libs/surfaces/mackie/controls.h b/libs/surfaces/mackie/controls.h
index 129fe070c6..ed9e8b79fb 100644
--- a/libs/surfaces/mackie/controls.h
+++ b/libs/surfaces/mackie/controls.h
@@ -83,6 +83,9 @@ class Fader;
class Strip : public Group
{
public:
+ /**
+ \param is the index of the strip. 0-based.
+ */
Strip( const std::string & name, int index );
virtual bool is_strip() const
@@ -92,10 +95,11 @@ public:
virtual void add( Control & control );
- /// This is the index of the strip
+ /// This is the index of the strip. zero-based.
int index() const { return _index; }
/// This is for Surface only
+ /// index is zero-based
void index( int rhs ) { _index = rhs; }
Button & solo();
diff --git a/libs/surfaces/mackie/mackie_control_protocol.cc b/libs/surfaces/mackie/mackie_control_protocol.cc
index dac287a758..4a9121bb71 100644
--- a/libs/surfaces/mackie/mackie_control_protocol.cc
+++ b/libs/surfaces/mackie/mackie_control_protocol.cc
@@ -38,6 +38,7 @@
#include <pbd/pthread_utils.h>
#include <pbd/error.h>
#include <pbd/memento_command.h>
+#include <pbd/convert.h>
#include <ardour/route.h>
#include <ardour/session.h>
@@ -366,7 +367,7 @@ void MackieControlProtocol::zero_all()
}
}
-int MackieControlProtocol::set_active (bool yn)
+int MackieControlProtocol::set_active( bool yn )
{
if ( yn != _active )
{
@@ -563,6 +564,10 @@ void MackieControlProtocol::connect_session_signals()
void MackieControlProtocol::add_port( MIDI::Port & midi_port, int number )
{
+#ifdef DEBUG
+ cout << "add port " << midi_port.name() << ", " << midi_port.device() << endl;
+#endif
+
MackiePort * sport = new MackiePort( *this, midi_port, number );
_ports.push_back( sport );
@@ -998,7 +1003,30 @@ void MackieControlProtocol::notify_name_changed( void *, RouteSignal * route_sig
{
try
{
- // TODO implement MackieControlProtocol::notify_name_changed
+ Strip & strip = route_signal->strip();
+ if ( !strip.is_master() )
+ {
+ string line1;
+ string line2;
+ string fullname = route_signal->route().name();
+
+ if ( fullname.length() <= 6 )
+ {
+ line1 = fullname;
+ }
+ else
+ {
+ line1 = PBD::short_version( fullname, 6 );
+ line2 = fullname.substr( fullname.length() - 6, 6 );
+ }
+
+ route_signal->port().write_sysex(
+ builder.strip_display( strip.index(), 0, line1 )
+ );
+ route_signal->port().write_sysex(
+ builder.strip_display( strip.index(), 1, line2 )
+ );
+ }
}
catch( exception & e )
{
@@ -1012,7 +1040,6 @@ void MackieControlProtocol::notify_panner_changed( RouteSignal * route_signal )
{
Pot & pot = route_signal->strip().vpot();
const Panner & panner = route_signal->route().panner();
- cout << "panner from ardour" << panner.size() << " " << boolalpha << panner.linked() << endl;
if ( panner.size() == 1 || ( panner.size() == 2 && panner.linked() ) )
{
float pos;
diff --git a/libs/surfaces/mackie/mackie_control_protocol_poll.cc b/libs/surfaces/mackie/mackie_control_protocol_poll.cc
index 951fb75a50..6ae2da071e 100644
--- a/libs/surfaces/mackie/mackie_control_protocol_poll.cc
+++ b/libs/surfaces/mackie/mackie_control_protocol_poll.cc
@@ -29,7 +29,15 @@ const char * MackieControlProtocol::default_port_name = "mcu";
bool MackieControlProtocol::probe()
{
- return MIDI::Manager::instance()->port( default_port_name ) != 0;
+ if ( MIDI::Manager::instance()->port( default_port_name ) == 0 )
+ {
+ error << "No port called mcu. Add it to ardour.rc." << endmsg;
+ return false;
+ }
+ else
+ {
+ return true;
+ }
}
void * MackieControlProtocol::monitor_work()
@@ -47,6 +55,8 @@ void * MackieControlProtocol::monitor_work()
{
if ( poll_ports() )
{
+ cout << "--------------------------------------" << endl;
+ cout << "MackieControlProtocol::read_ports _ports: " << _ports.size() << ", nfds: " << nfds << endl;
try { read_ports(); }
catch ( exception & e ) {
cout << "MackieControlProtocol::poll_ports caught exception: " << e.what() << endl;
@@ -82,14 +92,14 @@ void MackieControlProtocol::update_ports()
{
// create new pollfd structures
if ( pfd != 0 ) delete[] pfd;
- // TODO This might be a memory leak. How does thread cancellation cleanup work?
pfd = new pollfd[_ports.size()];
nfds = 0;
-
for( MackiePorts::iterator it = _ports.begin(); it != _ports.end(); ++it )
{
+ // add the port any handler
+ (*it)->connect_any();
#ifdef DEBUG
- cout << "adding port " << (*it)->port().name() << " to pollfd" << endl;
+ cout << "adding pollfd for port " << (*it)->port().name() << " to pollfd" << endl;
#endif
pfd[nfds].fd = (*it)->port().selectable();
pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
@@ -108,6 +118,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?
@@ -129,12 +141,14 @@ bool MackieControlProtocol::poll_ports()
if ( nfds < 1 )
{
lock.release();
- //cout << "poll_ports no ports" << endl;
+#ifdef DEBUG
+ cout << "poll_ports no ports" << endl;
+#endif
usleep( no_ports_sleep * 1000 );
return false;
}
- int retval = poll( pfd, nfds, timeout );
+ int retval = ::poll( pfd, nfds, timeout );
if ( retval < 0 )
{
// gdb at work, perhaps
diff --git a/libs/surfaces/mackie/mackie_midi_builder.cc b/libs/surfaces/mackie/mackie_midi_builder.cc
index 3d07ff94bf..a02126d059 100644
--- a/libs/surfaces/mackie/mackie_midi_builder.cc
+++ b/libs/surfaces/mackie/mackie_midi_builder.cc
@@ -171,3 +171,40 @@ MidiByteArray MackieMidiBuilder::two_char_display( unsigned int value, const std
os << setfill('0') << setw(2) << value % 100;
return two_char_display( os.str() );
}
+
+MidiByteArray MackieMidiBuilder::strip_display( unsigned int strip_index, unsigned int line_number, const std::string & line )
+{
+ if ( line_number > 1 )
+ {
+ throw runtime_error( "line_number must be 0 or 1" );
+ }
+
+ if ( strip_index > 7 )
+ {
+ throw runtime_error( "strip_index must be between 0 and 7" );
+ }
+
+ cout << "MackieMidiBuilder::strip_display index: " << strip_index << ", line " << line_number << ": " << line << endl;
+
+ MidiByteArray retval;
+ // code for display
+ retval << 0x12;
+ // offset (0 to 0x37 first line, 0x38 to 0x6f for second line )
+ retval << ( strip_index * 7 + ( line_number * 0x38 ) );
+ retval << line;
+ if ( strip_index != 7 )
+ {
+ retval << ' ';
+ }
+
+ cout << "MackieMidiBuilder::strip_display midi: " << retval << endl;
+ return retval;
+}
+
+MidiByteArray MackieMidiBuilder::all_strips_display( std::vector<std::string> & lines1, std::vector<std::string> & lines2 )
+{
+ MidiByteArray retval;
+ retval << 0x12 << 0;
+ retval << "Not working yet";
+ return retval;
+}
diff --git a/libs/surfaces/mackie/mackie_midi_builder.h b/libs/surfaces/mackie/mackie_midi_builder.h
index c71c718041..d039fb43d1 100644
--- a/libs/surfaces/mackie/mackie_midi_builder.h
+++ b/libs/surfaces/mackie/mackie_midi_builder.h
@@ -73,6 +73,13 @@ public:
MidiByteArray two_char_display( const std::string & msg, const std::string & dots = " " );
MidiByteArray two_char_display( unsigned int value, const std::string & dots = " " );
+ /// for displaying a particular strip name
+ /// index is zero-based
+ MidiByteArray strip_display( unsigned int strip_index, unsigned int line_number, const std::string & line );
+
+ /// for generating all strip names
+ MidiByteArray all_strips_display( std::vector<std::string> & lines1, std::vector<std::string> & lines2 );
+
protected:
static MIDI::byte calculate_pot_value( midi_pot_mode mode, const ControlState & );
};
diff --git a/libs/surfaces/mackie/mackie_port.cc b/libs/surfaces/mackie/mackie_port.cc
index 9bcee638fb..26c3612a86 100644
--- a/libs/surfaces/mackie/mackie_port.cc
+++ b/libs/surfaces/mackie/mackie_port.cc
@@ -296,13 +296,38 @@ void MackiePort::finalise_init( bool yn )
active_event();
// start handling messages from controls
- _any = port().input()->any.connect( ( mem_fun (*this, &MackiePort::handle_midi_any) ) );
+ connect_any();
}
_initialising = false;
init_cond.signal();
init_mutex.unlock();
}
+void MackiePort::connect_any()
+{
+/*
+ Doesn't work because there isn't and == operator for slots
+ MIDI::Signal::slot_list_type slots = port().input()->any.slots();
+
+ if ( find( slots.begin(), slots.end(), mem_fun( *this, &MackiePort::handle_midi_any ) ) == slots.end() )
+*/
+ // but this will break if midi tracing is turned on
+ if ( port().input()->any.empty() )
+ {
+#ifdef DEBUG
+ cout << "connect input parser " << port().input() << " to handle_midi_any" << endl;
+#endif
+ _any = port().input()->any.connect( mem_fun( *this, &MackiePort::handle_midi_any ) );
+#ifdef DEBUG
+ cout << "input parser any connections: " << port().input()->any.size() << endl;
+#endif
+ }
+ else
+ {
+ cout << "MackiePort::connect_any already connected" << endl;
+ }
+}
+
bool MackiePort::wait_for_init()
{
Glib::Mutex::Lock lock( init_mutex );
@@ -346,6 +371,9 @@ void MackiePort::handle_midi_sysex (MIDI::Parser & parser, MIDI::byte * raw_byte
void MackiePort::handle_midi_any (MIDI::Parser & parser, MIDI::byte * raw_bytes, size_t count )
{
MidiByteArray bytes( count, raw_bytes );
+#ifdef DEBUG
+ cout << "MackiePort::handle_midi_any " << bytes << endl;
+#endif
try
{
// ignore sysex messages
@@ -394,6 +422,9 @@ void MackiePort::handle_midi_any (MIDI::Parser & parser, MIDI::byte * raw_bytes,
}
catch( MackieControlException & e )
{
- //cout << bytes << ' ' << e.what() << endl;
+ cout << bytes << ' ' << e.what() << endl;
}
+#ifdef DEBUG
+ cout << "finished MackiePort::handle_midi_any " << bytes << endl;
+#endif
}
diff --git a/libs/surfaces/mackie/mackie_port.h b/libs/surfaces/mackie/mackie_port.h
index 2ad5cf6154..0a705e65f3 100644
--- a/libs/surfaces/mackie/mackie_port.h
+++ b/libs/surfaces/mackie/mackie_port.h
@@ -71,6 +71,10 @@ public:
emulation_t emulation() const { return _emulation; }
+ /// Connect the any signal from the parser to handle_midi_any
+ /// unless it's already connected
+ void connect_any();
+
protected:
/**
The initialisation sequence is fairly complex. First a lock is acquired
diff --git a/libs/surfaces/mackie/midi_byte_array.cc b/libs/surfaces/mackie/midi_byte_array.cc
index 192af6a1ce..1c27c82be1 100644
--- a/libs/surfaces/mackie/midi_byte_array.cc
+++ b/libs/surfaces/mackie/midi_byte_array.cc
@@ -24,6 +24,7 @@
#include <algorithm>
#include <cstdarg>
#include <iomanip>
+#include <stdexcept>
using namespace std;
@@ -96,3 +97,12 @@ ostream & operator << ( ostream & os, const MidiByteArray & mba )
os << "]";
return os;
}
+
+MidiByteArray & operator << ( MidiByteArray & mba, const std::string & st )
+{
+ for ( string::const_iterator it = st.begin(); it != st.end(); ++it )
+ {
+ mba << *it;
+ }
+ return mba;
+}
diff --git a/libs/surfaces/mackie/midi_byte_array.h b/libs/surfaces/mackie/midi_byte_array.h
index e77ece1b88..7176367189 100644
--- a/libs/surfaces/mackie/midi_byte_array.h
+++ b/libs/surfaces/mackie/midi_byte_array.h
@@ -67,6 +67,9 @@ public:
/// append the given byte to the end of the array
MidiByteArray & operator << ( MidiByteArray & mba, const MIDI::byte & b );
+/// append the given string to the end of the array
+MidiByteArray & operator << ( MidiByteArray & mba, const std::string & );
+
/// append the given array to the end of this array
MidiByteArray & operator << ( MidiByteArray & mba, const MidiByteArray & barr );
diff --git a/libs/surfaces/mackie/surface.cc b/libs/surfaces/mackie/surface.cc
index bcf6071f15..7c77e86285 100644
--- a/libs/surfaces/mackie/surface.cc
+++ b/libs/surfaces/mackie/surface.cc
@@ -123,4 +123,3 @@ void Strip::add( Control & control )
throw MackieControlException( os.str() );
}
}
-
diff --git a/libs/surfaces/mackie/surface_port.cc b/libs/surfaces/mackie/surface_port.cc
index e74ae93841..cba4c2c494 100644
--- a/libs/surfaces/mackie/surface_port.cc
+++ b/libs/surfaces/mackie/surface_port.cc
@@ -67,6 +67,7 @@ MidiByteArray SurfacePort::read()
if ( !active() ) return retval;
// return nothing read if the lock isn't acquired
+#if 0
Glib::RecMutex::Lock lock( _rwlock, Glib::TRY_LOCK );
if ( !lock.locked() )
@@ -77,6 +78,7 @@ MidiByteArray SurfacePort::read()
// check active again - destructor sequence
if ( !active() ) return retval;
+#endif
// read port and copy to return value
int nread = port().read( buf, sizeof (buf) );
@@ -85,6 +87,9 @@ MidiByteArray SurfacePort::read()
retval.copy( nread, buf );
if ((size_t) nread == sizeof (buf))
{
+#ifdef DEBUG
+ cout << "SurfacePort::read recursive" << endl;
+#endif
retval << read();
}
}
@@ -136,7 +141,7 @@ void SurfacePort::write( const MidiByteArray & mba )
}
}
#ifdef DEBUG
- if ( mba[0] == 0xf0 ) cout << "SurfacePort::write " << count << endl;
+ cout << "SurfacePort::wrote " << count << endl;
#endif
}