Home | History | Annotate | Download | only in midi
      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