1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef MEDIA_MIDI_MIDI_MANAGER_H_ 6 #define MEDIA_MIDI_MIDI_MANAGER_H_ 7 8 #include <set> 9 10 #include "base/basictypes.h" 11 #include "base/memory/scoped_ptr.h" 12 #include "base/message_loop/message_loop_proxy.h" 13 #include "base/synchronization/lock.h" 14 #include "media/base/media_export.h" 15 #include "media/midi/midi_port_info.h" 16 17 namespace base { 18 class Thread; 19 } 20 21 namespace media { 22 23 // A MIDIManagerClient registers with the MIDIManager to receive MIDI data. 24 // See MIDIManager::RequestAccess() and MIDIManager::ReleaseAccess() 25 // for details. 26 class MEDIA_EXPORT MIDIManagerClient { 27 public: 28 virtual ~MIDIManagerClient() {} 29 30 // ReceiveMIDIData() is called when MIDI data has been received from the 31 // MIDI system. 32 // |port_index| represents the specific input port from input_ports(). 33 // |data| represents a series of bytes encoding one or more MIDI messages. 34 // |length| is the number of bytes in |data|. 35 // |timestamp| is the time the data was received, in seconds. 36 virtual void ReceiveMIDIData(int port_index, 37 const uint8* data, 38 size_t length, 39 double timestamp) = 0; 40 41 // AccumulateMIDIBytesSent() is called to acknowledge when bytes have 42 // successfully been sent to the hardware. 43 // This happens as a result of the client having previously called 44 // MIDIManager::DispatchSendMIDIData(). 45 virtual void AccumulateMIDIBytesSent(size_t n) = 0; 46 }; 47 48 // Manages access to all MIDI hardware. 49 class MEDIA_EXPORT MIDIManager { 50 public: 51 static MIDIManager* Create(); 52 53 MIDIManager(); 54 virtual ~MIDIManager(); 55 56 // A client calls StartSession() to receive and send MIDI data. 57 // If the session is ready to start, the MIDI system is lazily initialized 58 // and the client is registered to receive MIDI data. 59 // Returns |true| if the session succeeds to start. 60 bool StartSession(MIDIManagerClient* client); 61 62 // A client calls ReleaseSession() to stop receiving MIDI data. 63 void EndSession(MIDIManagerClient* client); 64 65 // DispatchSendMIDIData() schedules one or more messages to be sent 66 // at the given time on a dedicated thread. 67 // |port_index| represents the specific output port from output_ports(). 68 // |data| represents a series of bytes encoding one or more MIDI messages. 69 // |length| is the number of bytes in |data|. 70 // |timestamp| is the time to send the data, in seconds. A value of 0 71 // means send "now" or as soon as possible. 72 void DispatchSendMIDIData(MIDIManagerClient* client, 73 int port_index, 74 const uint8* data, 75 size_t length, 76 double timestamp); 77 78 // input_ports() is a list of MIDI ports for receiving MIDI data. 79 // Each individual port in this list can be identified by its 80 // integer index into this list. 81 const MIDIPortInfoList& input_ports() { return input_ports_; } 82 83 // output_ports() is a list of MIDI ports for sending MIDI data. 84 // Each individual port in this list can be identified by its 85 // integer index into this list. 86 const MIDIPortInfoList& output_ports() { return output_ports_; } 87 88 protected: 89 // Initializes the MIDI system, returning |true| on success. 90 virtual bool Initialize() = 0; 91 92 // Implements the platform-specific details of sending MIDI data. 93 virtual void SendMIDIData(MIDIManagerClient* client, 94 int port_index, 95 const uint8* data, 96 size_t length, 97 double timestamp) = 0; 98 99 void AddInputPort(const MIDIPortInfo& info); 100 void AddOutputPort(const MIDIPortInfo& info); 101 102 // Dispatches to all clients. 103 void ReceiveMIDIData( 104 int port_index, 105 const uint8* data, 106 size_t length, 107 double timestamp); 108 109 bool initialized_; 110 111 // Keeps track of all clients who wish to receive MIDI data. 112 typedef std::set<MIDIManagerClient*> ClientList; 113 ClientList clients_; 114 115 // Protects access to our clients. 116 base::Lock clients_lock_; 117 118 MIDIPortInfoList input_ports_; 119 MIDIPortInfoList output_ports_; 120 121 // |send_thread_| is used to send MIDI data by calling the platform-specific 122 // API. 123 scoped_ptr<base::Thread> send_thread_; 124 scoped_refptr<base::MessageLoopProxy> send_message_loop_; 125 126 DISALLOW_COPY_AND_ASSIGN(MIDIManager); 127 }; 128 129 } // namespace media 130 131 #endif // MEDIA_MIDI_MIDI_MANAGER_H_ 132