consistent interface to resources and services regardless of the audio hardware
configuration. The Java Sound API : Packages. Two main packages – targeted ...
An Introduction to MIDI Programming with
The Java Sound API : Overview
Provides low level services for digital audio and midi processing. Is essentially an abstraction layer over the lower level native services offered by the operating system. Is hardware agnostic and relies on the operating system to provide access to hardware resources. The Java Sound packages were designed to provide application programmers with a consistent interface to resources and services regardless of the audio hardware configuration.
The Java Sound API : Packages
Two main packages – targeted by application programmers y javax.sound.sampled – provides services for
capturing, mixing, and playback of digital audio streams. y javax.sound.midi – provides services to support MIDI synthesis, sequencing, and event capture/playback.
The Java Sound API : Packages
Two extension packages – for use by system programmers to extend the Java Sound API y javax.sound.sampled.spi y javax.sound.midi.spi
Devices, Transmitters, and Receivers
Devices, Transmitters, and Receivers
MIDI Devices must be a transmitter, a receiver, or both a transmitter and a receiver. A transmitter is capable of generating MIDI messages. A receiver is capable of capturing MIDI messages.
A Controller is a MIDI device which generates MIDI messages (Transmitter). A Synthesizer (Software or Hardware) is a MIDI device which captures MIDI messages (Receiver). A Sequencer is a MIDI device which generates and captures MIDI messages (Transmitter and Receiver).
Devices, Transmitters, and Receivers
Transmitters generate MIDI messages and stream them to connected receivers.
MIDI Streaming vs. Sequencing
Streaming – Real Time Processing
Sequencing – Relative Time Processing
y Messages
y Events
y Message Type
y Message Type
y Channel Number
y Channel Number
y Associated Data
y Associated Data y Relative Time
MIDI Streaming
Can be thought of as “Live” MIDI MIDI Messages contain no timing information and are processed immediately as they arrive. Examples:
MIDI Sequencing
Can be thought of as “Scheduled” MIDI. MIDI Events contain MIDI Messages and associated timing values. Examples:
y A MIDI controller generates MIDI messages which are
y Playback - A MIDI file stores a series of MIDI Events
streamed to capture devices (like sequencers) during recording or sound generators (like synthesizers) during performance. y A MIDI sequencer generates MIDI messages which are streamed to devices which generate sound (like synthesizers) during playback.
which a sequencer can use to generate MIDI messages to send to sound generating devices at the appropriate time. y Capture - A MIDI sequencer captures MIDI messages from a MIDI controller and adds a time stamp to the message data for storage and subsequent playback.
MIDI Data Flow
Sequences and Tracks
A sequence can be thought of as an entire “song,” whereas a track can be thought of as a single part of the song like “the guitar part” or the “drum part.” A sequence can, but does not necessarily have to, contain multiple tracks.
Sequences and Tracks
Sequence – stored in a MIDI File or managed by a MIDI Sequencer.
A Sequence can be thought of as a MIDI schedule.
Track – represents a MIDI Event schedule for a single instrument/performer/voice.
Sequences and Tracks
A Sequence is a collection of Tracks
A Track is a collection of MIDI Events
A MIDI Event is a MIDI Message combined with timing information.
MidiDevice Interface
MidiDevice Interface
open(), close(), isOpen()
getDeviceInfo()
getReceiver(), getReceivers(), getMaxReceivers()
getTransmitter(), getTransmitters(), getMaxTransmitters()
getMicrosecondPosition()
Interface implemented by software representations of MIDI devices.
Can represent both software devices and hardware devices.
Implementations provide all functionality required by a MIDI port (input or output).
MidiDevice.Info Class
A data access class whose sole responsibility is to provide information describing a MidiDevice instance.
Clients of a MidiDevice may obtain an instance of this class to query for information about the MidiDevice by calling the MidiDevice’s getDeviceInfo() method.
MidiDevice.Info Class
getName()
getVendor()
getVersion()
getDescription()
Transmitter Interface
Instances of a MidiDevice’s Transmitter implementation can be obtained by calling the MidiDevice’s getTransmitter() method. Be sure to call the Transmitter instance’s close() method when the Transmitter is no longer needed.
Transmitter Interface
Interface implemented by software objects that transmit MIDI messages on behalf of a MidiDevice implementation.
Examples: Sequencers and MIDI Input Ports provide Transmitters to clients.
Transmitter Interface
setReceiver(), getReceiver()
close()
Receiver Interface
Receiver Interface
Interface implemented by software objects that receive MIDI messages on behalf of a MidiDevice implementation.
Instances of a MidiDevice’s Receiver implementation can be obtained by calling the MidiDevice’s getReceiver() method.
Examples: Synthesizers and MIDI Output Ports provide Receivers to clients.
Be sure to call the Receiver instance’s close() method when the Receiver is no longer needed.
Receiver Interface
send()
close()
MidiMessage Class
Base class for all MIDI Message implementations.
Provides access to the message’s status byte, data bytes, and total message length.
Subclasses include ShortMessage, MetaMessage, and SysExMessage classes.
MidiMessage Class
getStatus()
getLength()
getMessage()
ShortMessage Class
getCommand()
getChannel()
getData1(), getData2()
ShortMessage Class
Implements data access and transport for short messages (2 data bytes) which are usually associated with MIDI channels.
Examples: Note On and Note Off messages
ShortMessage Class
Status code byte values are provided by static fields on the ShortMessage class.
Examples: y ShortMessage.NOTE_ON y ShortMessage.NOTE_OFF
getDataLength()
setMessage()
y ShortMessage.PITCH_BEND
SysexMessage Class
Implements data access and transport for MIDI system exclusive messages.
getData()
setMessage()
MIDI system exclusive messages are largely vendor specific and are variable in size.
MetaMessage Class
SysexMessage Class
Implements data access and transport for MIDI meta messages. MetaMessages are used in MIDI files and Sequences and are not used during live communication. Contain data useful for sequencers like tempo changes, time signatures, etc.
MetaMessage Class
getType()
getData()
setMessage()
Sequence Interface
Sequencer Interface
Extends the MidiDevice Interface
getSequence(), setSequence()
Implemented by classes which represent MIDI Sequencers.
getTickLength()
getTickPosition(), setTickPosition()
start(), stop()
Sequencer Interface
Sequencer Interface
startRecording(), stopRecording()
addControllerEventListener()
isRunning(), isRecording()
addMetaEventListener()
getTrackSolo(), setTrackSolo()
getTrackMute(), setTrackMute()
Sequence Class
Implements data access and manipulation for a MIDI Sequence. Is essentially a collection of Track objects and provides the ability to add, access, and remove Tracks.
Track Class
Implements an ordered collection of MidiEvent objects. Represents the MIDI message schedule for a single instrument or voice for a Sequence. Tracks can only be created by calling a Sequence’s createTrack() method.
Sequence Class
createTrack(), deleteTrack()
getTracks()
getTickLength()
Track Class
add(), remove()
get()
size()
ticks()
MidiEvent Class
Implements data access and transport for a MIDI Event.
getTick(), setTick()
getMessage()
Is, quite simply, a container for a MidiMessage object and an associated tick value.
Event Listener Interfaces
MidiEvent Class
ControllerEventListener Interface
Synthesizer Interface
Extends the MidiDevice Interface
Implemented by software objects that represent MIDI Synthesizers.
Implementations of this interface are the only objects in the Midi package that produce audio.
y controlChange()
MetaEventListener Interface y meta()
Synthesizer Interface
getChannels()
getAvailableInstruments()
getMaxPolyphony()
getLatency()
getVoiceStatus()
Instrument Class
getName()
getPatch()
Instrument Class
Implements the sound synthesis algorithms for a specific instrument provided by a Soundbank.
To use an instance of an Instrument object with a Synthesizer, that Instrument and its Soundbank must be loaded into the Synthesizer.
Patch Class
Implementation of an Instrument’s sound patch.
Represents the “location” at which an instrument’s data is loaded into a synthesizer.
Provides the bank and program numbers to a MidiChannel so the channel can use the instrument.
Patch Class
getBank()
getProgram()
MidiChannel Interface
MidiChannel Interface
Interface for implementations of a MIDI Channel provided by a Synthesizer.
Instances can be retrieved by calling a Synthesizer instance’s getChannels() method.
Synthesizers usually provide 16 MidiChannel instances to clients.
MidiChannel Interface
noteOn(), noteOff()
getSolo(), setSolo()
allNotesOff()
getMute(), setMute()
controlChange(), getController()
getProgram(), programChange()
getPitchBend(), setPitchBend()
MidiSystem Class
Provides access to the system’s MIDI resources (installed hardware and software based MIDI devices, soundbanks, etc.) Like most subsystems in the Java Libraries, the MIDI subsystem is implemented as a Singleton by exposing only static methods.
MidiSystem Class
getMidiFileTypes()
write()
MidiSystem Class
getMidiDeviceInfo()
getMidiDevice()
getReceiver(), getTransmitter(), getSynthesizer(), getSequencer()
getSequence()
References
JavaSound API Programmer’s Guide y http://download.oracle.com/javase/1.5.0/docs/gui
de/sound/programmer_guide/index.html
Java SE 6 API y http://download.oracle.com/javase/6/docs/api/java
x/sound/midi/package-summary.html
Java Sound API – Soundbanks y http://www.oracle.com/technetwork/java/soundba
nks-135798.html