ALSA Sequencer System
(page 1)
Outline
(page 2)
Characteristics of ALSA
(page 3)
Structure of ALSA
(page 4)
ALSA Drivers
ex) SB AWE64 with sequencer
Card Driver
snd-card-sbawe - SB AWE 32/64
Mid-Level Drivers
snd-pcm - PCM
snd-hwdep - H/W-dep device
snd-timer - Timer
snd-opl3 - FM OPL3
snd-rawmidi - RawMIDI
snd-seq-device - Sequencer manager
Low-Level Drivers
snd-mpu401-uart - MPU401 driver
snd-emu8000 - Emu8000 driver
snd-sb16-dsp - SB16 DSP driver
snd-sb16-csp - SB16 CSP
snd-sb-common - SB8/16 common
snd-util-mem - Emu/Trident memory manager
snd - ALSA core
Sequencer Kernel Clients (loaded as plug-in)
snd-synth-opl3 - FM OPL3
snd-seq-midi - MIDI synth
snd-synth-emu8000 - Emu8000 WaveTable
Sequencer Support (loaded as plug-in)
snd-seq-virmidi - Virtual MIDI device
snd-seq-instr - Instrument abstract layer
snd-ainstr-fm - FM OPL3 instrument support
snd-synth-emux - Emu8000/10k1 wavetable support
snd-seq-midi-emul - MIDI emulation
snd-seq-midi-event - MIDI byte stream conversion
(page 5)
ALSA Library
(page 6)
OSS Compatibility
ALSA is (almost :-) full compatible with OSS
(page 7)
What's Sequencer?
The role of sequencer =
Problems of OSS sequencer
ALSA sequencer
(page 8)
Structure of ALSA Sequencer
![struct1.gif](http://www.alsa-project.org/~tiwai/lk2k/struct1.gif)
(page 9)
Sequencer as Dispatcher
![struct2.gif](http://www.alsa-project.org/~tiwai/lk2k/struct2.gif)
(page 10)
Sequencer as Dispatcher - 2
(page 11)
Sequencer as Scheduler
![struct3.gif](http://www.alsa-project.org/~tiwai/lk2k/struct3.gif)
(page 12)
Sequencer as Scheduler - 2
(page 13)
Multiple Queues
![qstruct.gif](http://www.alsa-project.org/~tiwai/lk2k/qstruct.gif)
(page 14)
Client
(page 15)
Special Clients
(page 16)
Other Kernel Clients
(page 17)
Port Capabilities
Access to the port is controlled via capability bits
SND_SEQ_PORT_CAP_XXX
(page 18)
Subscription
Subscription = connection between two ports
(page 19)
Subscription Examples
(page 20)
More about Subscription
(page 21)
Double Queue System
Concept
Implementation
![queueup.gif](http://www.alsa-project.org/~tiwai/lk2k/queueup.gif)
(page 22)
Event
A fixed size event packet:
snd_seq_event_t {
snd_seq_event_type type; /* event type */
unsigned char flags; /* event flags */
char tag; /* for removing */
unsigned char queue; /* schedule queue */
union {
snd_seq_tick_time_t tick; /* MIDI tick */
snd_seq_real_time_t time; /* real-time */
} time; /* schedule time */
snd_seq_addr_t source; /* source address */
snd_seq_addr_t dest; /* destination address */
union { /* event data: 12bytes */
snd_seq_ev_note note; /* note events */
snd_seq_ev_ctrl control; /* chanel control events */
snd_seq_ev_ext ext; /* external data */
....
} data;
};
(page 23)
Event Types
(page 24)
Variable Length Events - Case 1
![dispatchk1.gif](http://www.alsa-project.org/~tiwai/lk2k/dispatchk1.gif)
![dispatchk2.gif](http://www.alsa-project.org/~tiwai/lk2k/dispatchk2.gif)
![dispatchk3.gif](http://www.alsa-project.org/~tiwai/lk2k/dispatchk3.gif)
(page 25)
Variable Length Events - Case 2
![dispatchu1.gif](http://www.alsa-project.org/~tiwai/lk2k/dispatchu1.gif)
![dispatchu2.gif](http://www.alsa-project.org/~tiwai/lk2k/dispatchu2.gif)
![dispatchu3.gif](http://www.alsa-project.org/~tiwai/lk2k/dispatchu3.gif)
(page 26)
Variable Length Events - Case 3
![schedk1.gif](http://www.alsa-project.org/~tiwai/lk2k/schedk1.gif)
![schedk2.gif](http://www.alsa-project.org/~tiwai/lk2k/schedk2.gif)
![schedk3.gif](http://www.alsa-project.org/~tiwai/lk2k/schedk3.gif)
(page 27)
Variable Length Events - Case 4
![schedu1.gif](http://www.alsa-project.org/~tiwai/lk2k/schedu1.gif)
![schedu2.gif](http://www.alsa-project.org/~tiwai/lk2k/schedu2.gif)
![schedu3.gif](http://www.alsa-project.org/~tiwai/lk2k/schedu3.gif)
![schedu4.gif](http://www.alsa-project.org/~tiwai/lk2k/schedu4.gif)
(page 28)
More Efficiency..?
--> Use of mmap
(page 29)
Synchronization
Synchronization = running two (or more) queues
at the same position with the same tempo
(page 30)
Implementation of Sync
(page 31)
Implementation of Sync - 2
(page 32)
Sequencer API
(page 33)
Proc Interface
Files under /proc/asound/seq
(page 34)
OSS Emulation
![oss-seq.gif](http://www.alsa-project.org/~tiwai/lk2k/oss-seq.gif)
(page 35)
Latency Test
Echo-back events from a user-client to itself
Iteration = 10,000,000, CPU = celeron 400MHz, Kernel 2.2.16 low-latency
(page 36)
Playback with TiMidity++
pmidi -> sequencer -> aseqview -> output (timidity)
(page 37)
Combination with Jazz++
![jazz-system.gif](http://www.alsa-project.org/~tiwai/lk2k/jazz-system.gif)
(page 38)
Network Transparency
![seq-net.gif](http://www.alsa-project.org/~tiwai/lk2k/seq-net.gif)
(page 39)
Combination of Sync
![sync-ex.gif](http://www.alsa-project.org/~tiwai/lk2k/sync-ex.gif)
(page 40)
Remarkable Notes
(page 41)
Known Problems
(page 42)
Further Works to Do
(page 43)
Resources
(page 1)
Outline
- Introduction
-
- Characteristics
- Structure of ALSA
- ALSA Sequencer
-
- Structure
- Client/Port
- Subscription
- Event
- Synchronization
- Sequencer API
- OSS Emulation
- Examples
- Resources
(page 2)
Characteristics of ALSA
- ALSA =
- Advanced LinuxSoundArchitecture
- High quality sound system
- Support up to 8 cards
- Full-duplex, multi-channel PCM
- Flexible and extensible control/mixer
- Powerful sequencer
- Good OSS Compatibility
(page 3)
Structure of ALSA
![archtect.gif](http://www.alsa-project.org/~tiwai/lk2k/archtect.gif)
(page 4)
ALSA Drivers
- Fully GPL'ed
- Modularization
- Separation of low-level, mid-level and card drivers
- No duplication of codes
- Ease of development & maintenance
- .. but ..
ex) SB AWE64 with sequencer
Card Driver
snd-card-sbawe - SB AWE 32/64
Mid-Level Drivers
snd-pcm - PCM
snd-hwdep - H/W-dep device
snd-timer - Timer
snd-opl3 - FM OPL3
snd-rawmidi - RawMIDI
snd-seq-device - Sequencer manager
Low-Level Drivers
snd-mpu401-uart - MPU401 driver
snd-emu8000 - Emu8000 driver
snd-sb16-dsp - SB16 DSP driver
snd-sb16-csp - SB16 CSP
snd-sb-common - SB8/16 common
snd-util-mem - Emu/Trident memory manager
snd - ALSA core
Sequencer Kernel Clients (loaded as plug-in)
snd-synth-opl3 - FM OPL3
snd-seq-midi - MIDI synth
snd-synth-emu8000 - Emu8000 WaveTable
Sequencer Support (loaded as plug-in)
snd-seq-virmidi - Virtual MIDI device
snd-seq-instr - Instrument abstract layer
snd-ainstr-fm - FM OPL3 instrument support
snd-synth-emux - Emu8000/10k1 wavetable support
snd-seq-midi-emul - MIDI emulation
snd-seq-midi-event - MIDI byte stream conversion
(page 5)
ALSA Library
- Fully LGPL'ed
- Provides consistent APIs
- Abstract PCM Plug-in
- Support for different formats, channels and rates.
- No direct access to device files
- All applications access via ALSA-lib API.
(page 6)
OSS Compatibility
ALSA is (almost :-) full compatible with OSS
- PCM and Mixer
- Additional plug-in modules
- Auto-loading via kmod
- Raw MIDI
- Nothing special is necessary
- Sequencer
- Devices are mapped through ALSA sequencer
- Concurrent access is allowed
(page 7)
What's Sequencer?
The role of sequencer =
- Delivers events at the right time (sequence) to the right destination (device).
Problems of OSS sequencer
- Using a single FIFO for scheduling
- Exclusive access
- No good real-time control
- The destination is only a device
ALSA sequencer
- Multiple concurrent access
- Scheduled by priority queues
- Real-time event dispatching
(page 8)
Structure of ALSA Sequencer
![struct1.gif](http://www.alsa-project.org/~tiwai/lk2k/struct1.gif)
(page 9)
Sequencer as Dispatcher
![struct2.gif](http://www.alsa-project.org/~tiwai/lk2k/struct2.gif)
(page 10)
Sequencer as Dispatcher - 2
- Concurrent clients (up to 192)
-
- Multiplex access to the sequencer device
- Kernel clients
-
- Manage h/w devices
- Implemented as a kernel module
- Light-weight inter-client communications
- Use callbacks
- User clients
-
- Assigned at each open of the sequencer device
- write/read syscalls for client communications
- Data goes always across user/kernel boundary
- Broadcasting / multicasting
-
- Subscribers or all clients/ports
- Multiple ports (up to 253)
(page 11)
Sequencer as Scheduler
![struct3.gif](http://www.alsa-project.org/~tiwai/lk2k/struct3.gif)
(page 12)
Sequencer as Scheduler - 2
- Priority queues for scheduling
-
- Arbitrary order of schedule
- Events can be scheduled in advance
- Events may go through queues (real-time)
- Multiple event queues with own tempo
-
- Queues are controlled independently
- Double queue system
-
- Real-time queue - constant base time
- MIDI tick queue - variable base time
- Synchronization
-
- Sync-master (to other devices)
- Sync-slave (from another device)
(page 13)
Multiple Queues
![qstruct.gif](http://www.alsa-project.org/~tiwai/lk2k/qstruct.gif)
(page 14)
Client
![client.gif](http://www.alsa-project.org/~tiwai/lk2k/client.gif)
(page 15)
Special Clients
- Client #0 - System clients
-
- Port #0 - Timer port
- Write: Controls queues
- Read: Broadcasts queue changes (e.g. tempo, position, etc.)
- Port #1 - Announce port (read only)
- Read: Broadcasts client, port and subscription status changes
- Port #0 - Timer port
- Client #62 - Dummy (MIDI-thru) client
-
- Broadcasts all received events to subscribers
- Client #63 - OSS sequencer emulator
-
- Supports for the OSS sequencer access via /dev/sequencer
(page 16)
Other Kernel Clients
- External MIDI (r/w)
-
- A port assigned to the external MIDI device (MPU-401) on the corresponding soundcard.
- Virtual MIDI (r/w)
-
- A port assigned to the virtual MIDI device.
- The input/output events are converted from/to MIDI byte streams through the virtual MIDI device file.
- WaveTable (w only)
-
- WaveTable synthesizer ports.
- Supported on Emu8000 and Emu10k1.
- FM OPL-3 (w only)
-
- FM OPL-3 synthesizer ports.
- Supported on most soundcards.
(page 17)
Port Capabilities
Access to the port is controlled via capability bits
SND_SEQ_PORT_CAP_XXX
- READ- The port is readable (input device)
- WRITE- The port is writable (output device)
- DUPLEX- The port supports duplex
- READ_SUBS- Read subscription allowed
- WRITE_SUBS - Write subscription allowed
- NO_EXPORT- Prohibits arbitrary connections
(page 18)
Subscription
Subscription = connection between two ports
- Read subscription
-
- e.g. input from an external keyboard
- send events automatically to the associated ports
- Write subscription
-
- e.g. output to a MIDI device
- open the device explicitly
- Arbitrary connection
-
- e.g. connection from MIDI keyboard to WaveTable synth
- arbitrary routing between two ports (patchbay)
(page 19)
Subscription Examples
- Command line utility -
- aconnect
- External MIDI external input (port#0) --> Emu8000 wavetable (port#1)
- % aconnect External:0 Emu8000:1
- you may see the current connection in /proc/asound/seq/clients
- With GUI
(page 20)
More about Subscription
- Broadcast to subscribers
-
- A client can send events to all subscribers by using a special destination, SND_SEQ_ADDRESS_SUBSCRIBERS
- just like stdin/out
- Auto-update of time-stamp
-
- The time-stamp of the incoming event can be updated with the given queue.
- Exclusive connection
-
- The exclusive connection can be assured with a special flag.
- Synchronization Information
-
- The queue-synchronization is implemented on subscription.
(page 21)
Double Queue System
Concept
- Virtual-Time (MIDI tick)
- Musician's standard (bar, clock, tick)
- The time increase depends on tempo
- MIDI clock synchronization
- Real-Time (wall-clock time)
- Intuitive (sec / nanosec)
- The time increases constantly
- SMPTE / MTC synchronization
Implementation
![queueup.gif](http://www.alsa-project.org/~tiwai/lk2k/queueup.gif)
(page 22)
Event
A fixed size event packet:
snd_seq_event_t {
snd_seq_event_type type; /* event type */
unsigned char flags; /* event flags */
char tag; /* for removing */
unsigned char queue; /* schedule queue */
union {
snd_seq_tick_time_t tick; /* MIDI tick */
snd_seq_real_time_t time; /* real-time */
} time; /* schedule time */
snd_seq_addr_t source; /* source address */
snd_seq_addr_t dest; /* destination address */
union { /* event data: 12bytes */
snd_seq_ev_note note; /* note events */
snd_seq_ev_ctrl control; /* chanel control events */
snd_seq_ev_ext ext; /* external data */
....
} data;
};
- Schedule time union:
-
- MIDI tick - unsigned int tick; (4 bytes)
- Real-time - unsigned int sec, nsec; (8 bytes)
- Source / destination addresses:
-
- unsigned char client, port; (2 bytes)
- Data union:
-
- various data types in fixed size (12 bytes)
(page 23)
Event Types
- Fixed length -
- a single event cell
- MIDI events - note-on, off, MIDI controls
- Queue control events - start, stop, change tempo
- Sync signals
- Variable length -
- a header cell (size, pointer) + external data
- SYSEX messages
- User-space data -
- a header cell (size, pointer) only
- Instrument management
- Quoted events -
- a wrapper cell (pointer) + original event cell
- Error messages
- MIDI-thru
- IPC shared memory -
- a single cell containing the IPC key
(page 24)
Variable Length Events - Case 1
![dispatchk1.gif](http://www.alsa-project.org/~tiwai/lk2k/dispatchk1.gif)
![dispatchk2.gif](http://www.alsa-project.org/~tiwai/lk2k/dispatchk2.gif)
![dispatchk3.gif](http://www.alsa-project.org/~tiwai/lk2k/dispatchk3.gif)
(page 25)
Variable Length Events - Case 2
![dispatchu1.gif](http://www.alsa-project.org/~tiwai/lk2k/dispatchu1.gif)
![dispatchu2.gif](http://www.alsa-project.org/~tiwai/lk2k/dispatchu2.gif)
![dispatchu3.gif](http://www.alsa-project.org/~tiwai/lk2k/dispatchu3.gif)
(page 26)
Variable Length Events - Case 3
![schedk1.gif](http://www.alsa-project.org/~tiwai/lk2k/schedk1.gif)
![schedk2.gif](http://www.alsa-project.org/~tiwai/lk2k/schedk2.gif)
![schedk3.gif](http://www.alsa-project.org/~tiwai/lk2k/schedk3.gif)
(page 27)
Variable Length Events - Case 4
![schedu1.gif](http://www.alsa-project.org/~tiwai/lk2k/schedu1.gif)
![schedu2.gif](http://www.alsa-project.org/~tiwai/lk2k/schedu2.gif)
![schedu3.gif](http://www.alsa-project.org/~tiwai/lk2k/schedu3.gif)
![schedu4.gif](http://www.alsa-project.org/~tiwai/lk2k/schedu4.gif)
(page 28)
More Efficiency..?
- Waste of resources on user/kernel boundary
- Input/output buffers on user-space
--> Use of mmap
(page 29)
Synchronization
Synchronization = running two (or more) queues
at the same position with the same tempo
- Synchronization on the same system
- Sharing the same queue
- No extra coding!
- Sharing the same queue
- Synchronization between different systems
- Sync with signals
- via MIDI cable, network, etc.
- Sync with signals
- Two directions
- Sync Master
- Send (periodic) sync signals to other devices
- Sync Slave
- Receive sync signals and synchronize the queue
- Sync Master
(page 30)
Implementation of Sync
- Device <--> Queue Connection
- Use subscription mechanism
- Prepare a special port for each queue
- Multiple sync-mastering allowed
- Exclusive sync-slave
![sync.gif](http://www.alsa-project.org/~tiwai/lk2k/sync.gif)
(page 31)
Implementation of Sync - 2
- Using PLL
- Robustness (but not 100% accurate)
- Accuracy (tolerance, lock condition) configurable
- Capable with low resolution sources
- Sync of real-time queues
- Sync signal -> Modify increment in a timer interrupt
- The speed of associated tick queue is modified automatically!
- Sync signal -> Modify increment in a timer interrupt
- Sync of tick queues
- Sync signal -> Modify the queue tempo value
- The associated real-time queue is not affected.
- Sync signal -> Modify the queue tempo value
(page 32)
Sequencer API
- Create/delete a client
- int snd_seq_open(&handle);
- int snd_seq_close(handle);
- Create/delete a port
- int snd_seq_create_port(handle, port_info);
- int snd_seq_delete_port(handle, port_info);
- Subscription
- int snd_seq_subscribe_port(handle, subs_info);
- int snd_seq_unsubscribe_port(handle, subs_info);
- Create/delete a queue
- int snd_seq_alloc_queue(handle);
- int snd_seq_free_queue(handle, queue);
- Output/Input an event packet
- int snd_seq_event_output(handle, event)
- int snd_seq_event_input(handle, &event)
(page 33)
Proc Interface
Files under /proc/asound/seq
- clients
- List of cients, ports and subscriptions
- queues
- List of all allocated queues and sync connections
- timer
- List of current running timers
- oss
- List of OSS sequencer devices and running apps
(page 34)
OSS Emulation
![oss-seq.gif](http://www.alsa-project.org/~tiwai/lk2k/oss-seq.gif)
(page 35)
Latency Test
Echo-back events from a user-client to itself
Iteration = 10,000,000, CPU = celeron 400MHz, Kernel 2.2.16 low-latency
- Disk Write Test (1GB write)
-
- Normal: Max. 48.0 ms / Avg. 9.0 ms
- SCHED_FIFO: Max. 0.10 ms / Avg. 0.0059 ms
- Disk Read Test (1GB read)
-
- Normal: Max. 8.9 ms / Avg. 0.0073 ms
- SCHED_FIFO: Max. 0.096 ms / Avg. 0.0056 ms
- Disk Copy Test (1GB copy)
-
- Normal: Max. 8.8 ms / Avg. 0.0075 ms
- SCHED_FIFO: Max. 0.092 ms / Avg. 0.0059 ms
- Proc Test (top -d0.1)
-
- Normal: Max. 30.0 ms / Avg. 0.012 ms
- SCHED_FIFO: Max. 0.076 ms / Avg. 0.0075 ms
- X11 Test (x11perf -scroll500 -shmput500)
-
- Normal: Max. 21.0 ms / Avg. 0.0080 ms
- SCHED_FIFO: Max. 0.12 ms / Avg. 0.0074 ms
(page 36)
Playback with TiMidity++
pmidi -> sequencer -> aseqview -> output (timidity)
(page 37)
Combination with Jazz++
![jazz-system.gif](http://www.alsa-project.org/~tiwai/lk2k/jazz-system.gif)
(page 38)
Network Transparency
![seq-net.gif](http://www.alsa-project.org/~tiwai/lk2k/seq-net.gif)
(page 39)
Combination of Sync
![sync-ex.gif](http://www.alsa-project.org/~tiwai/lk2k/sync-ex.gif)
(page 40)
Remarkable Notes
- Real-time event-delivery
- Multiple clients / ports / queues
- Flexible routing
- Arbitrary Scheduling using priority queues
- Double time system (MIDI tick & real-time)
- Support of virtual MIDI devices
- Intelligent sync-master / slave
- Various sync formats: SMPTE/MTC/DTL, MIDI-clock
(page 41)
Known Problems
- Fairly big (and complicated) stuff on kernel
- -> Implement seq-scheduler on user-space
- Sequencer core plays only as a router
- How to get timer interrupt in real time?
- fasync on RTC
- Latency
- Always required setuid-root?
(page 42)
Further Works to Do
- Complete sync stuffs
- Support of multi-MIDI port h/w (e.g. MTPAV)
- Light-weight soft-synth client
- SMPTE decoder/encoder clients
- Complete WaveTable synths (on Trident, Yamaha, etc.)
- Support of SoundFont (and other) instrument layers
(page 43)
Resources
- ALSA project homepage
- ALSA CVS (v0.6)
- cvs.alsa-project.org
- Author's webpage (about ALSA)
- HTTP version of these slides
- Synchronization details