Midis (MIDI service) is a system service for processing MIDI(https://en.wikipedia.org/wiki/MIDI) events. It can communicate information about device connection/disconnection to several client applications, and pass file descriptors to these clients to send and receive MIDI messages to and from hardware, respectively.
Client - A userspace process that establishes an IPC connection with midis. Once the connection is established, it can listen for device connection / disconnection messages sent from midis, and can also request for file descriptors to listen to different MIDI H/W devices and write to them.
Device - Representation of a MIDI h/w device in midis. It is considered analogous to the ALSA sequencer concept of a “client”. A device consists of multiple subdevices (referred to in ALSA sequencer parlance as “ports”).
The general structure of the classes is best illustrated by a few diagrams:
DeviceTracker | | | ----------------------------------------- | | | | | | | | | SeqHandler Device1 ... DeviceN
This class handles the management of MIDI h/w devices connected to a system. Its functionality includes:
This class handles all the interactions with the ALSA Seq interface. It performs many functions:
Device | | | ---------------------------------------------- | | | | | | InPorts OutPorts SubDeviceClientFdHolders
This object is used to represent an input port of a subdevice, on which we receive data from a MIDI H/W device.
When we want to start listening for data from a MIDI H/W subdevice, we call the InPort::Create() function which creates an InPort object, and calls InPort::Subscribe(). InPort::Subscribe() calls a SeqHandler function to register with ALSA Seq to receive MIDI events from that subdevice.
This object is used to represent the output port of a sudevice, on which we sent data from a client to the MIDI H/W device.
When we want to enable the writing of data to a MIDI H/W subdevice, we call the OutPort::Subscribe() function, which is a callback to a SeqHandler function to register with ALSA seq to open a handle to the subdevice which we can write to. When we receive data from a client, the OutPort invokes a SeqHandler callback to send the data to the relevant ALSA device handle.
This class represents a connection between a client and a particular subdevice of a H/W device. When a Client object receives a request to obtain/listen to a subdevice, the Device object creates a socket pair. It sends one end to the client to send/receive data on, and it creates a SubDeviceClientFdHolder object using the other end. This object performs the following:
TODO(pmalani)
The data flow to and from H/W devices and clients is best illustrated with the help of flow diagrams.
H/W device | | \|/ SeqHandler -------------------> DeviceTracker | | \|/ Device | | \|/ write to all client FDs registered for that subdevice. --------> Client (SubDeviceClientFDHolder)
Client (writes data to FD) | | \|/ Device (WriteClientDataToDevice) | | \|/ OutPort --------------> SeqHandler (SendMidiData) | | \|/ H/W device