diff options
author | John Anderson <ardour@semiosix.com> | 2007-07-18 19:09:33 +0000 |
---|---|---|
committer | John Anderson <ardour@semiosix.com> | 2007-07-18 19:09:33 +0000 |
commit | bfb5ddedab95238a67964310f44290ba301471d0 (patch) | |
tree | 2558d86a7a351cc9b6e5d23e7398d167e4b79406 | |
parent | 5c8830f952d9db413b03a24088d4c91b3d7f5709 (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/TODO | 2 | ||||
-rw-r--r-- | libs/surfaces/mackie/controls.h | 6 | ||||
-rw-r--r-- | libs/surfaces/mackie/mackie_control_protocol.cc | 33 | ||||
-rw-r--r-- | libs/surfaces/mackie/mackie_control_protocol_poll.cc | 26 | ||||
-rw-r--r-- | libs/surfaces/mackie/mackie_midi_builder.cc | 37 | ||||
-rw-r--r-- | libs/surfaces/mackie/mackie_midi_builder.h | 7 | ||||
-rw-r--r-- | libs/surfaces/mackie/mackie_port.cc | 35 | ||||
-rw-r--r-- | libs/surfaces/mackie/mackie_port.h | 4 | ||||
-rw-r--r-- | libs/surfaces/mackie/midi_byte_array.cc | 10 | ||||
-rw-r--r-- | libs/surfaces/mackie/midi_byte_array.h | 3 | ||||
-rw-r--r-- | libs/surfaces/mackie/surface.cc | 1 | ||||
-rw-r--r-- | libs/surfaces/mackie/surface_port.cc | 7 |
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 } |