ALSA Sequencer System

ALSA Sequencer System

(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



(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 ..
you'll see so many modules!


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


(page 9)


Sequencer as Dispatcher

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


(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



(page 14)


Client
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
  • 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
  • patchbay.gif



(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


(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
dispatchk2.gif
dispatchk3.gif



(page 25)


Variable Length Events - Case 2
dispatchu1.gif
dispatchu2.gif
dispatchu3.gif



(page 26)


Variable Length Events - Case 3
schedk1.gif
schedk2.gif
schedk3.gif


(page 27)


Variable Length Events - Case 4
schedu1.gif
schedu2.gif
schedu3.gif
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!

  • Synchronization between different systems
    • Sync with signals
      • via MIDI cable, network, etc.

  • Two directions
    • Sync Master
      • Send (periodic) sync signals to other devices
    • Sync Slave
      • Receive sync signals and synchronize the queue


(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



(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 of tick queues
    • Sync signal -> Modify the queue tempo value
      • The associated real-time queue is not affected.



(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



(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


(page 38)


Network Transparency

seq-net.gif


(page 39)


Combination of Sync

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 CVS (v0.6)
    • cvs.alsa-project.org



(page 44)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值