mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	
		
			
				
	
	
		
			102 lines
		
	
	
	
		
			3.2 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			102 lines
		
	
	
	
		
			3.2 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
/** \page page_midi MIDI Support
 | 
						|
 | 
						|
This document explains how MIDI is implemented.
 | 
						|
 | 
						|
# Use cases
 | 
						|
 | 
						|
### MIDI devices are made available as processing nodes/ports
 | 
						|
 | 
						|
Applications need to be able to see a port for each stream of a
 | 
						|
MIDI device.
 | 
						|
 | 
						|
### MIDI devices can be plugged and unplugged
 | 
						|
 | 
						|
When devices are plugged and unplugged the associated nodes/ports
 | 
						|
need to be created and removed.
 | 
						|
 | 
						|
### Applications can connect to MIDI devices
 | 
						|
 | 
						|
Applications can create ports that can connect to the MIDI ports
 | 
						|
so that data can be provided to or consumed from them.
 | 
						|
 | 
						|
### Some MIDI devices are sinks or sources for midi data
 | 
						|
 | 
						|
It should be possible to create a MIDI sink or source that routes the
 | 
						|
midi events to specific midi ports.
 | 
						|
 | 
						|
One example of such a sink would be in front of a software midi
 | 
						|
renderer.
 | 
						|
 | 
						|
An example of a MIDI source would be after a virtual keyboard or
 | 
						|
as a mix from many midi input devices.
 | 
						|
 | 
						|
### Applications should autoconnect to MIDI sinks or sources
 | 
						|
 | 
						|
An application should be able to be connected to a MIDI sink when
 | 
						|
it wants to play midi data.
 | 
						|
 | 
						|
An application should be able to connect to a MIDI source when it
 | 
						|
wants to capture midi data.
 | 
						|
 | 
						|
# Design
 | 
						|
 | 
						|
## SPA
 | 
						|
 | 
						|
MIDI devices/streams are implemented with an \ref spa_node with generic
 | 
						|
control input and output Ports. These ports have a media type of
 | 
						|
`"application/control"` and the data transported over these ports
 | 
						|
are of type \ref spa_pod_sequence with the \ref spa_pod_control type set to
 | 
						|
\ref SPA_CONTROL_Midi.
 | 
						|
 | 
						|
This means that every midi event is timestamped with the sample
 | 
						|
offset against the current graph clock cycle to get sample accurate
 | 
						|
midi events that can be aligned with the corresponding sample data.
 | 
						|
 | 
						|
Since the MIDI events are embedded in the generic control stream,
 | 
						|
they can be interleaved with other control message types, such as
 | 
						|
property updates or OSC messages.
 | 
						|
 | 
						|
## The PipeWire daemon
 | 
						|
 | 
						|
Nothing special is implemented for MIDI. Negotiation of formats
 | 
						|
happens between `"application/control"` media types and buffers are
 | 
						|
negotiated in the same way as any generic format.
 | 
						|
 | 
						|
## The session manager
 | 
						|
 | 
						|
The session manager needs to create the MIDI nodes/ports for the available
 | 
						|
devices.
 | 
						|
 | 
						|
This can either be done as a single node with ports per device/stream
 | 
						|
or as separate nodes created by a MIDI device monitor.
 | 
						|
 | 
						|
The session manager needs to be aware of the various MIDI sinks and sources
 | 
						|
in order to route MIDI streams to them from applications that want this.
 | 
						|
 | 
						|
 | 
						|
# Implementation
 | 
						|
 | 
						|
## pipewire-media-session
 | 
						|
 | 
						|
PipeWire media session uses the \ref SPA_NAME_API_ALSA_SEQ_BRIDGE plugin for
 | 
						|
the midi features. This creates a single SPA Node with ports per
 | 
						|
MIDI client/stream.
 | 
						|
 | 
						|
The media session will check the permissions on `/dev/snd/seq` before
 | 
						|
attempting to create this node. It will also use inotify to wait
 | 
						|
until the sequencer device node is accessible.
 | 
						|
 | 
						|
## JACK
 | 
						|
 | 
						|
JACK assumes all `"application/control"` ports are midi ports.
 | 
						|
 | 
						|
The control messages are converted to the JACK event format by
 | 
						|
filtering out the \ref SPA_CONTROL_Midi types. On output ports, the JACK
 | 
						|
event stream is converted to control messages in a similar way.
 | 
						|
 | 
						|
There is a 1 to 1 mapping between the JACK events and control
 | 
						|
messages so there is no information loss or need for complicated
 | 
						|
conversions.
 | 
						|
 | 
						|
 | 
						|
*/
 |