Skip to content

Instantly share code, notes, and snippets.

@pbackus
Created May 29, 2023 19:28
Show Gist options
  • Save pbackus/5eadddb1de8a8c5b24f5016a365c5942 to your computer and use it in GitHub Desktop.
Save pbackus/5eadddb1de8a8c5b24f5016a365c5942 to your computer and use it in GitHub Desktop.
ALSA sequencer bindings for D
/**
Bindings for the ALSA sequencer API.
See http://alsa-project.org/ for documentation.
License: GNU Lesser General Public License version 2.1
Authors: Jaroslav Kysela <perex@perex.cz>, Abramo Bagnara
<abramo@alsa-project.org>, and Takashi Iwai <tiwai@suse.de>.
D bindings by Paul Backus <snarwin@gmail.com>.
*/
module alsaseq;
import core.stdc.config: c_long;
import core.stdc.string: memset;
import core.sys.posix.poll;
import core.sys.posix.sys.types: ssize_t;
extern(C):
nothrow:
@nogc:
// From conf.h
struct _snd_config;
alias _snd_config snd_config_t;
// From timer.h
struct _snd_timer_id;
alias _snd_timer_id snd_timer_id_t;
// seq_event.h
// Sequencer Event Definitions
/**
* Sequencer event data type
*/
alias ubyte snd_seq_event_type_t;
/** Sequencer event type */
enum : snd_seq_event_type_t {
/** system status; event data type = [snd_seq_result_t] */
SND_SEQ_EVENT_SYSTEM = 0,
/** returned result status; event data type = [snd_seq_result_t] */
SND_SEQ_EVENT_RESULT,
/** note on and off with duration; event data type = [snd_seq_ev_note_t] */
SND_SEQ_EVENT_NOTE = 5,
/** note on; event data type = [snd_seq_ev_note_t] */
SND_SEQ_EVENT_NOTEON,
/** note off; event data type = [snd_seq_ev_note_t] */
SND_SEQ_EVENT_NOTEOFF,
/** key pressure change (aftertouch); event data type = [snd_seq_ev_note_t] */
SND_SEQ_EVENT_KEYPRESS,
/** controller; event data type = [snd_seq_ev_ctrl_t] */
SND_SEQ_EVENT_CONTROLLER = 10,
/** program change; event data type = [snd_seq_ev_ctrl_t] */
SND_SEQ_EVENT_PGMCHANGE,
/** channel pressure; event data type = [snd_seq_ev_ctrl_t] */
SND_SEQ_EVENT_CHANPRESS,
/** pitchwheel; event data type = [snd_seq_ev_ctrl_t] data is from -8192 to 8191) */
SND_SEQ_EVENT_PITCHBEND,
/** 14 bit controller value; event data type = [snd_seq_ev_ctrl_t] */
SND_SEQ_EVENT_CONTROL14,
/** 14 bit NRPN; event data type = [snd_seq_ev_ctrl_t] */
SND_SEQ_EVENT_NONREGPARAM,
/** 14 bit RPN; event data type = [snd_seq_ev_ctrl_t] */
SND_SEQ_EVENT_REGPARAM,
/** SPP with LSB and MSB values; event data type = [snd_seq_ev_ctrl_t] */
SND_SEQ_EVENT_SONGPOS = 20,
/** Song Select with song ID number; event data type = [snd_seq_ev_ctrl_t] */
SND_SEQ_EVENT_SONGSEL,
/** midi time code quarter frame; event data type = [snd_seq_ev_ctrl_t] */
SND_SEQ_EVENT_QFRAME,
/** SMF Time Signature event; event data type = [snd_seq_ev_ctrl_t] */
SND_SEQ_EVENT_TIMESIGN,
/** SMF Key Signature event; event data type = [snd_seq_ev_ctrl_t] */
SND_SEQ_EVENT_KEYSIGN,
/** MIDI Real Time Start message; event data type = [snd_seq_ev_queue_control_t] */
SND_SEQ_EVENT_START = 30,
/** MIDI Real Time Continue message; event data type = [snd_seq_ev_queue_control_t] */
SND_SEQ_EVENT_CONTINUE,
/** MIDI Real Time Stop message; event data type = [snd_seq_ev_queue_control_t] */
SND_SEQ_EVENT_STOP,
/** Set tick queue position; event data type = [snd_seq_ev_queue_control_t] */
SND_SEQ_EVENT_SETPOS_TICK,
/** Set real-time queue position; event data type = [snd_seq_ev_queue_control_t] */
SND_SEQ_EVENT_SETPOS_TIME,
/** (SMF) Tempo event; event data type = [snd_seq_ev_queue_control_t] */
SND_SEQ_EVENT_TEMPO,
/** MIDI Real Time Clock message; event data type = [snd_seq_ev_queue_control_t] */
SND_SEQ_EVENT_CLOCK,
/** MIDI Real Time Tick message; event data type = [snd_seq_ev_queue_control_t] */
SND_SEQ_EVENT_TICK,
/** Queue timer skew; event data type = [snd_seq_ev_queue_control_t] */
SND_SEQ_EVENT_QUEUE_SKEW,
/** Sync position changed; event data type = [snd_seq_ev_queue_control_t] */
SND_SEQ_EVENT_SYNC_POS,
/** Tune request; event data type = none */
SND_SEQ_EVENT_TUNE_REQUEST = 40,
/** Reset to power-on state; event data type = none */
SND_SEQ_EVENT_RESET,
/** Active sensing event; event data type = none */
SND_SEQ_EVENT_SENSING,
/** Echo-back event; event data type = any type */
SND_SEQ_EVENT_ECHO = 50,
/** OSS emulation raw event; event data type = any type */
SND_SEQ_EVENT_OSS,
/** New client has connected; event data type = [snd_seq_addr_t] */
SND_SEQ_EVENT_CLIENT_START = 60,
/** Client has left the system; event data type = [snd_seq_addr_t] */
SND_SEQ_EVENT_CLIENT_EXIT,
/** Client status/info has changed; event data type = [snd_seq_addr_t] */
SND_SEQ_EVENT_CLIENT_CHANGE,
/** New port was created; event data type = [snd_seq_addr_t] */
SND_SEQ_EVENT_PORT_START,
/** Port was deleted from system; event data type = [snd_seq_addr_t] */
SND_SEQ_EVENT_PORT_EXIT,
/** Port status/info has changed; event data type = [snd_seq_addr_t] */
SND_SEQ_EVENT_PORT_CHANGE,
/** Ports connected; event data type = [snd_seq_connect_t] */
SND_SEQ_EVENT_PORT_SUBSCRIBED,
/** Ports disconnected; event data type = [snd_seq_connect_t] */
SND_SEQ_EVENT_PORT_UNSUBSCRIBED,
/** user-defined event; event data type = any (fixed size) */
SND_SEQ_EVENT_USR0 = 90,
/** user-defined event; event data type = any (fixed size) */
SND_SEQ_EVENT_USR1,
/** user-defined event; event data type = any (fixed size) */
SND_SEQ_EVENT_USR2,
/** user-defined event; event data type = any (fixed size) */
SND_SEQ_EVENT_USR3,
/** user-defined event; event data type = any (fixed size) */
SND_SEQ_EVENT_USR4,
/** user-defined event; event data type = any (fixed size) */
SND_SEQ_EVENT_USR5,
/** user-defined event; event data type = any (fixed size) */
SND_SEQ_EVENT_USR6,
/** user-defined event; event data type = any (fixed size) */
SND_SEQ_EVENT_USR7,
/** user-defined event; event data type = any (fixed size) */
SND_SEQ_EVENT_USR8,
/** user-defined event; event data type = any (fixed size) */
SND_SEQ_EVENT_USR9,
/** system exclusive data (variable length); event data type = [snd_seq_ev_ext_t] */
SND_SEQ_EVENT_SYSEX = 130,
/** error event; event data type = [snd_seq_ev_ext_t] */
SND_SEQ_EVENT_BOUNCE,
/** reserved for user apps; event data type = [snd_seq_ev_ext_t] */
SND_SEQ_EVENT_USR_VAR0 = 135,
/** reserved for user apps; event data type = [snd_seq_ev_ext_t] */
SND_SEQ_EVENT_USR_VAR1,
/** reserved for user apps; event data type = [snd_seq_ev_ext_t] */
SND_SEQ_EVENT_USR_VAR2,
/** reserved for user apps; event data type = [snd_seq_ev_ext_t] */
SND_SEQ_EVENT_USR_VAR3,
/** reserved for user apps; event data type = [snd_seq_ev_ext_t] */
SND_SEQ_EVENT_USR_VAR4,
/** NOP; ignored in any case */
SND_SEQ_EVENT_NONE = 255
}
/** Sequencer event address */
struct snd_seq_addr {
ubyte client; /** Client id */
ubyte port; /** Port id */
}
alias snd_seq_addr snd_seq_addr_t;
/** Connection (subscription) between ports */
struct snd_seq_connect {
snd_seq_addr_t sender; /** sender address */
snd_seq_addr_t dest; /** destination address */
}
alias snd_seq_connect snd_seq_connect_t;
/** Real-time data record */
struct snd_seq_real_time {
uint tv_sec; /** seconds */
uint tv_nsec; /** nanoseconds */
}
alias snd_seq_real_time snd_seq_real_time_t;
/** (MIDI) Tick-time data record */
alias uint snd_seq_tick_time_t;
/** unioned time stamp */
union snd_seq_timestamp {
snd_seq_tick_time_t tick; /** tick-time */
snd_seq_real_time_t time; /** real-time */
}
alias snd_seq_timestamp snd_seq_timestamp_t;
/**
* Event mode flags
*
* NOTE: only 8 bits available!
*/
enum SND_SEQ_TIME_STAMP_TICK = (0<<0); /** timestamp in clock ticks */
enum SND_SEQ_TIME_STAMP_REAL = (1<<0); /** timestamp in real time */
enum SND_SEQ_TIME_STAMP_MASK = (1<<0); /** mask for timestamp bits */
enum SND_SEQ_TIME_MODE_ABS = (0<<1); /** absolute timestamp */
enum SND_SEQ_TIME_MODE_REL = (1<<1); /** relative to current time */
enum SND_SEQ_TIME_MODE_MASK = (1<<1); /** mask for time mode bits */
enum SND_SEQ_EVENT_LENGTH_FIXED = (0<<2); /** fixed event size */
enum SND_SEQ_EVENT_LENGTH_VARIABLE = (1<<2); /** variable event size */
enum SND_SEQ_EVENT_LENGTH_VARUSR = (2<<2); /** variable event size - user memory space */
enum SND_SEQ_EVENT_LENGTH_MASK = (3<<2); /** mask for event length bits */
enum SND_SEQ_PRIORITY_NORMAL = (0<<4); /** normal priority */
enum SND_SEQ_PRIORITY_HIGH = (1<<4); /** event should be processed before others */
enum SND_SEQ_PRIORITY_MASK = (1<<4); /** mask for priority bits */
/** Note event */
struct snd_seq_ev_note {
ubyte channel; /** channel number */
ubyte note; /** note */
ubyte velocity; /** velocity */
ubyte off_velocity; /** note-off velocity; only for [SND_SEQ_EVENT_NOTE] */
uint duration; /** duration until note-off; only for [SND_SEQ_EVENT_NOTE] */
}
alias snd_seq_ev_note snd_seq_ev_note_t;
/** Controller event */
struct snd_seq_ev_ctrl {
ubyte channel; /** channel number */
ubyte[3] unused; /** reserved */
uint param; /** control parameter */
int value; /** control value */
}
alias snd_seq_ev_ctrl snd_seq_ev_ctrl_t;
/** generic set of bytes (12x8 bit) */
struct snd_seq_ev_raw8 {
ubyte[12] d; /** 8 bit value */
}
alias snd_seq_ev_raw8 snd_seq_ev_raw8_t;
/** generic set of integers (3x32 bit) */
struct snd_seq_ev_raw32 {
uint[3] d; /** 32 bit value */
}
alias snd_seq_ev_raw32 snd_seq_ev_raw32_t;
/** external stored data */
struct snd_seq_ev_ext {
align(1):
uint len; /** length of data */
void *ptr; /** pointer to data (note: can be 64-bit) */
};
/** external stored data */
alias snd_seq_ev_ext snd_seq_ev_ext_t;
/** Result events */
struct snd_seq_result {
int event; /** processed event type */
int result; /** status */
}
alias snd_seq_result snd_seq_result_t;
/** Queue skew values */
struct snd_seq_queue_skew {
uint value; /** skew value */
uint base; /** skew base */
}
alias snd_seq_queue_skew snd_seq_queue_skew_t;
/** queue timer control */
struct snd_seq_ev_queue_control {
ubyte queue; /** affected queue */
ubyte[3] unused; /** reserved */
private union param_t {
int value; /** affected value (e.g. tempo) */
snd_seq_timestamp_t time; /** time */
uint position; /** sync position */
snd_seq_queue_skew_t skew; /** queue skew */
uint[2] d32; /** any data */
ubyte[8] d8; /** any data */
}
param_t param; /** data value union */
}
alias snd_seq_ev_queue_control snd_seq_ev_queue_control_t;
/** Sequencer event */
struct snd_seq_event {
snd_seq_event_type_t type; /** event type */
ubyte flags; /** event flags */
ubyte tag; /** tag */
ubyte queue; /** schedule queue */
snd_seq_timestamp_t time; /** schedule time */
snd_seq_addr_t source; /** source address */
snd_seq_addr_t dest; /** destination address */
private union data_t {
snd_seq_ev_note_t note; /** note information */
snd_seq_ev_ctrl_t control; /** MIDI control information */
snd_seq_ev_raw8_t raw8; /** raw8 data */
snd_seq_ev_raw32_t raw32; /** raw32 data */
snd_seq_ev_ext_t ext; /** external data */
snd_seq_ev_queue_control_t queue; /** queue control */
snd_seq_timestamp_t time; /** timestamp */
snd_seq_addr_t addr; /** address */
snd_seq_connect_t connect; /** connect information */
snd_seq_result_t result; /** operation result code */
}
data_t data; /** event data... */
}
alias snd_seq_event snd_seq_event_t;
// seq.h
// MIDI Sequencer Interface
/** Sequencer handle */
struct _snd_seq;
alias _snd_seq snd_seq_t;
/**
* sequencer opening stream types
*/
enum SND_SEQ_OPEN_OUTPUT = 1; /** open for output (write) */
enum SND_SEQ_OPEN_INPUT = 2; /** open for input (read) */
enum SND_SEQ_OPEN_DUPLEX = (SND_SEQ_OPEN_OUTPUT|SND_SEQ_OPEN_INPUT); /** open for both input and output (read/write) */
/**
* sequencer opening mode
*/
enum SND_SEQ_NONBLOCK = 0x0001; /** non-blocking mode (flag to open mode) */
/** sequencer handle type */
alias snd_seq_type_t = int;
enum : snd_seq_type_t {
SND_SEQ_TYPE_HW, /** hardware */
SND_SEQ_TYPE_SHM, /** shared memory (NYI) */
SND_SEQ_TYPE_INET /** network (NYI) */
}
/** special client (port) ids */
enum SND_SEQ_ADDRESS_UNKNOWN = 253; /** unknown source */
enum SND_SEQ_ADDRESS_SUBSCRIBERS = 254; /** send event to all subscribed ports */
enum SND_SEQ_ADDRESS_BROADCAST = 255; /** send event to all queues/clients/ports/channels */
/** known client numbers */
enum SND_SEQ_CLIENT_SYSTEM = 0; /** system client */
int snd_seq_open(snd_seq_t **handle, const(char) *name, int streams, int mode);
int snd_seq_open_lconf(snd_seq_t **handle, const(char) *name, int streams, int mode, snd_config_t *lconf);
const(char) *snd_seq_name(snd_seq_t *seq);
snd_seq_type_t snd_seq_type(snd_seq_t *seq);
int snd_seq_close(snd_seq_t *handle);
int snd_seq_poll_descriptors_count(snd_seq_t *handle, short events);
int snd_seq_poll_descriptors(snd_seq_t *handle, pollfd *pfds, uint space, short events);
int snd_seq_poll_descriptors_revents(snd_seq_t *seq, pollfd *pfds, uint nfds, ushort *revents);
int snd_seq_nonblock(snd_seq_t *handle, int nonblock);
int snd_seq_client_id(snd_seq_t *handle);
size_t snd_seq_get_output_buffer_size(snd_seq_t *handle);
size_t snd_seq_get_input_buffer_size(snd_seq_t *handle);
int snd_seq_set_output_buffer_size(snd_seq_t *handle, size_t size);
int snd_seq_set_input_buffer_size(snd_seq_t *handle, size_t size);
/** system information container */
struct _snd_seq_system_info;
alias _snd_seq_system_info snd_seq_system_info_t;
size_t snd_seq_system_info_sizeof();
// snd_seq_system_info_alloca: not implemented
int snd_seq_system_info_malloc(snd_seq_system_info_t **ptr);
void snd_seq_system_info_free(snd_seq_system_info_t *ptr);
void snd_seq_system_info_copy(snd_seq_system_info_t *dst, const(snd_seq_system_info_t) *src);
int snd_seq_system_info_get_queues(const(snd_seq_system_info_t) *info);
int snd_seq_system_info_get_clients(const(snd_seq_system_info_t) *info);
int snd_seq_system_info_get_ports(const(snd_seq_system_info_t) *info);
int snd_seq_system_info_get_channels(const(snd_seq_system_info_t) *info);
int snd_seq_system_info_get_cur_clients(const(snd_seq_system_info_t) *info);
int snd_seq_system_info_get_cur_queues(const(snd_seq_system_info_t) *info);
int snd_seq_system_info(snd_seq_t *handle, snd_seq_system_info_t *info);
// Sequencer Client Interface
/** client information container */
struct _snd_seq_client_info;
alias _snd_seq_client_info snd_seq_client_info_t;
/** client types */
alias snd_seq_client_type_t = int;
enum : snd_seq_client_type_t {
SND_SEQ_USER_CLIENT = 1, /** user client */
SND_SEQ_KERNEL_CLIENT = 2 /** kernel client */
}
size_t snd_seq_client_info_sizeof();
// snd_seq_client_info_alloca: not implemented
int snd_seq_client_info_malloc(snd_seq_client_info_t **ptr);
void snd_seq_client_info_free(snd_seq_client_info_t *ptr);
void snd_seq_client_info_copy(snd_seq_client_info_t *dst, const(snd_seq_client_info_t) *src);
int snd_seq_client_info_get_client(const(snd_seq_client_info_t) *info);
snd_seq_client_type_t snd_seq_client_info_get_type(const(snd_seq_client_info_t) *info);
const(char) *snd_seq_client_info_get_name(snd_seq_client_info_t *info);
int snd_seq_client_info_get_broadcast_filter(const(snd_seq_client_info_t) *info);
int snd_seq_client_info_get_error_bounce(const(snd_seq_client_info_t) *info);
int snd_seq_client_info_get_card(const(snd_seq_client_info_t) *info);
int snd_seq_client_info_get_pid(const(snd_seq_client_info_t) *info);
const(ubyte) *snd_seq_client_info_get_event_filter(const(snd_seq_client_info_t) *info);
int snd_seq_client_info_get_num_ports(const(snd_seq_client_info_t) *info);
int snd_seq_client_info_get_event_lost(const(snd_seq_client_info_t) *info);
void snd_seq_client_info_set_client(snd_seq_client_info_t *info, int client);
void snd_seq_client_info_set_name(snd_seq_client_info_t *info, const(char) *name);
void snd_seq_client_info_set_broadcast_filter(snd_seq_client_info_t *info, int val);
void snd_seq_client_info_set_error_bounce(snd_seq_client_info_t *info, int val);
void snd_seq_client_info_set_event_filter(snd_seq_client_info_t *info, ubyte *filter);
void snd_seq_client_info_event_filter_clear(snd_seq_client_info_t *info);
void snd_seq_client_info_event_filter_add(snd_seq_client_info_t *info, int event_type);
void snd_seq_client_info_event_filter_del(snd_seq_client_info_t *info, int event_type);
int snd_seq_client_info_event_filter_check(snd_seq_client_info_t *info, int event_type);
int snd_seq_get_client_info(snd_seq_t *handle, snd_seq_client_info_t *info);
int snd_seq_get_any_client_info(snd_seq_t *handle, int client, snd_seq_client_info_t *info);
int snd_seq_set_client_info(snd_seq_t *handle, snd_seq_client_info_t *info);
int snd_seq_query_next_client(snd_seq_t *handle, snd_seq_client_info_t *info);
/** client pool information container */
struct _snd_seq_client_pool;
alias _snd_seq_client_pool snd_seq_client_pool_t;
size_t snd_seq_client_pool_sizeof();
// snd_seq_client_pool_alloca: not implemented
int snd_seq_client_pool_malloc(snd_seq_client_pool_t **ptr);
void snd_seq_client_pool_free(snd_seq_client_pool_t *ptr);
void snd_seq_client_pool_copy(snd_seq_client_pool_t *dst, const(snd_seq_client_pool_t) *src);
int snd_seq_client_pool_get_client(const(snd_seq_client_pool_t) *info);
size_t snd_seq_client_pool_get_output_pool(const(snd_seq_client_pool_t) *info);
size_t snd_seq_client_pool_get_input_pool(const(snd_seq_client_pool_t) *info);
size_t snd_seq_client_pool_get_output_room(const(snd_seq_client_pool_t) *info);
size_t snd_seq_client_pool_get_output_free(const(snd_seq_client_pool_t) *info);
size_t snd_seq_client_pool_get_input_free(const(snd_seq_client_pool_t) *info);
void snd_seq_client_pool_set_output_pool(snd_seq_client_pool_t *info, size_t size);
void snd_seq_client_pool_set_input_pool(snd_seq_client_pool_t *info, size_t size);
void snd_seq_client_pool_set_output_room(snd_seq_client_pool_t *info, size_t size);
int snd_seq_get_client_pool(snd_seq_t *handle, snd_seq_client_pool_t *info);
int snd_seq_set_client_pool(snd_seq_t *handle, snd_seq_client_pool_t *info);
// Sequencer Port Interface
/** port information container */
struct _snd_seq_port_info;
alias _snd_seq_port_info snd_seq_port_info_t;
/** known port numbers */
enum SND_SEQ_PORT_SYSTEM_TIMER = 0; /** system timer port */;
enum SND_SEQ_PORT_SYSTEM_ANNOUNCE = 1; /** system announce port */;
/** port capabilities (32 bits) */
enum SND_SEQ_PORT_CAP_READ = (1<<0); /** readable from this port */;
enum SND_SEQ_PORT_CAP_WRITE = (1<<1); /** writable to this port */;
enum SND_SEQ_PORT_CAP_SYNC_READ = (1<<2); /** allow read subscriptions */;
enum SND_SEQ_PORT_CAP_SYNC_WRITE = (1<<3); /** allow write subscriptions */;
enum SND_SEQ_PORT_CAP_DUPLEX = (1<<4); /** allow read/write duplex */;
enum SND_SEQ_PORT_CAP_SUBS_READ = (1<<5); /** allow read subscription */;
enum SND_SEQ_PORT_CAP_SUBS_WRITE = (1<<6); /** allow write subscription */;
enum SND_SEQ_PORT_CAP_NO_EXPORT = (1<<7); /** routing not allowed */;
/* port type */
/** Messages sent from/to this port have device-specific semantics. */
enum SND_SEQ_PORT_TYPE_SPECIFIC = (1<<0);
/** This port understands MIDI messages. */
enum SND_SEQ_PORT_TYPE_MIDI_GENERIC = (1<<1);
/** This port is compatible with the General MIDI specification. */
enum SND_SEQ_PORT_TYPE_MIDI_GM = (1<<2);
/** This port is compatible with the Roland GS standard. */
enum SND_SEQ_PORT_TYPE_MIDI_GS = (1<<3);
/** This port is compatible with the Yamaha XG specification. */
enum SND_SEQ_PORT_TYPE_MIDI_XG = (1<<4);
/** This port is compatible with the Roland MT-32. */
enum SND_SEQ_PORT_TYPE_MIDI_MT32 = (1<<5);
/** This port is compatible with the General MIDI 2 specification. */
enum SND_SEQ_PORT_TYPE_MIDI_GM2 = (1<<6);
/** This port understands SND_SEQ_EVENT_SAMPLE_xxx messages
(these are not MIDI messages). */
enum SND_SEQ_PORT_TYPE_SYNTH = (1<<10);
/** Instruments can be downloaded to this port
(with SND_SEQ_EVENT_INSTR_xxx messages sent directly). */
enum SND_SEQ_PORT_TYPE_DIRECT_SAMPLE = (1<<11);
/** Instruments can be downloaded to this port
(with SND_SEQ_EVENT_INSTR_xxx messages sent directly or through a queue). */
enum SND_SEQ_PORT_TYPE_SAMPLE = (1<<12);
/** This port is implemented in hardware. */
enum SND_SEQ_PORT_TYPE_HARDWARE = (1<<16);
/** This port is implemented in software. */
enum SND_SEQ_PORT_TYPE_SOFTWARE = (1<<17);
/** Messages sent to this port will generate sounds. */
enum SND_SEQ_PORT_TYPE_SYNTHESIZER = (1<<18);
/** This port may connect to other devices
(whose characteristics are not known). */
enum SND_SEQ_PORT_TYPE_PORT = (1<<19);
/** This port belongs to an application, such as a sequencer or editor. */
enum SND_SEQ_PORT_TYPE_APPLICATION = (1<<20);
size_t snd_seq_port_info_sizeof();
// snd_seq_port_info_alloca: not implemented
int snd_seq_port_info_malloc(snd_seq_port_info_t **ptr);
void snd_seq_port_info_free(snd_seq_port_info_t *ptr);
void snd_seq_port_info_copy(snd_seq_port_info_t *dst, const(snd_seq_port_info_t) *src);
int snd_seq_port_info_get_client(const(snd_seq_port_info_t) *info);
int snd_seq_port_info_get_port(const(snd_seq_port_info_t) *info);
const(snd_seq_addr_t) *snd_seq_port_info_get_addr(const(snd_seq_port_info_t) *info);
const(char) *snd_seq_port_info_get_name(const(snd_seq_port_info_t) *info);
uint snd_seq_port_info_get_capability(const(snd_seq_port_info_t) *info);
uint snd_seq_port_info_get_type(const(snd_seq_port_info_t) *info);
int snd_seq_port_info_get_midi_channels(const(snd_seq_port_info_t) *info);
int snd_seq_port_info_get_midi_voices(const(snd_seq_port_info_t) *info);
int snd_seq_port_info_get_synth_voices(const(snd_seq_port_info_t) *info);
int snd_seq_port_info_get_read_use(const(snd_seq_port_info_t) *info);
int snd_seq_port_info_get_write_use(const(snd_seq_port_info_t) *info);
int snd_seq_port_info_get_port_specified(const(snd_seq_port_info_t) *info);
int snd_seq_port_info_get_timestamping(const(snd_seq_port_info_t) *info);
int snd_seq_port_info_get_timestamp_real(const(snd_seq_port_info_t) *info);
int snd_seq_port_info_get_timestamp_queue(const(snd_seq_port_info_t) *info);
void snd_seq_port_info_set_client(snd_seq_port_info_t *info, int client);
void snd_seq_port_info_set_port(snd_seq_port_info_t *info, int port);
void snd_seq_port_info_set_addr(snd_seq_port_info_t *info, const(snd_seq_addr_t) *addr);
void snd_seq_port_info_set_name(snd_seq_port_info_t *info, const(char) *name);
void snd_seq_port_info_set_capability(snd_seq_port_info_t *info, uint capability);
void snd_seq_port_info_set_type(snd_seq_port_info_t *info, uint type);
void snd_seq_port_info_set_midi_channels(snd_seq_port_info_t *info, int channels);
void snd_seq_port_info_set_midi_voices(snd_seq_port_info_t *info, int voices);
void snd_seq_port_info_set_synth_voices(snd_seq_port_info_t *info, int voices);
void snd_seq_port_info_set_port_specified(snd_seq_port_info_t *info, int val);
void snd_seq_port_info_set_timestamping(snd_seq_port_info_t *info, int enable);
void snd_seq_port_info_set_timestamp_real(snd_seq_port_info_t *info, int realtime);
void snd_seq_port_info_set_timestamp_queue(snd_seq_port_info_t *info, int queue);
int snd_seq_create_port(snd_seq_t *handle, snd_seq_port_info_t *info);
int snd_seq_delete_port(snd_seq_t *handle, int port);
int snd_seq_get_port_info(snd_seq_t *handle, int port, snd_seq_port_info_t *info);
int snd_seq_get_any_port_info(snd_seq_t *handle, int client, int port, snd_seq_port_info_t *info);
int snd_seq_set_port_info(snd_seq_t *handle, int port, snd_seq_port_info_t *info);
int snd_seq_query_next_port(snd_seq_t *handle, snd_seq_port_info_t *info);
// Sequencer Port Subscription
/** port subscription container */
struct _snd_seq_port_subscribe;
alias _snd_seq_port_subscribe snd_seq_port_subscribe_t;
size_t snd_seq_port_subscribe_sizeof();
// snd_seq_port_subscribe_alloca: not implemented
int snd_seq_port_subscribe_malloc(snd_seq_port_subscribe_t **ptr);
void snd_seq_port_subscribe_free(snd_seq_port_subscribe_t *ptr);
void snd_seq_port_subscribe_copy(snd_seq_port_subscribe_t *dst, const(snd_seq_port_subscribe_t) *src);
const(snd_seq_addr_t) *snd_seq_port_subscribe_get_sender(const(snd_seq_port_subscribe_t) *info);
const(snd_seq_addr_t) *snd_seq_port_subscribe_get_dest(const(snd_seq_port_subscribe_t) *info);
int snd_seq_port_subscribe_get_queue(const(snd_seq_port_subscribe_t) *info);
int snd_seq_port_subscribe_get_exclusive(const(snd_seq_port_subscribe_t) *info);
int snd_seq_port_subscribe_get_time_update(const(snd_seq_port_subscribe_t) *info);
int snd_seq_port_subscribe_get_time_real(const(snd_seq_port_subscribe_t) *info);
void snd_seq_port_subscribe_set_sender(snd_seq_port_subscribe_t *info, const(snd_seq_addr_t) *addr);
void snd_seq_port_subscribe_set_dest(snd_seq_port_subscribe_t *info, const(snd_seq_addr_t) *addr);
void snd_seq_port_subscribe_set_queue(snd_seq_port_subscribe_t *info, int q);
void snd_seq_port_subscribe_set_exclusive(snd_seq_port_subscribe_t *info, int val);
void snd_seq_port_subscribe_set_time_update(snd_seq_port_subscribe_t *info, int val);
void snd_seq_port_subscribe_set_time_real(snd_seq_port_subscribe_t *info, int val);
int snd_seq_get_port_subscription(snd_seq_t *handle, snd_seq_port_subscribe_t *sub);
int snd_seq_subscribe_port(snd_seq_t *handle, snd_seq_port_subscribe_t *sub);
int snd_seq_unsubscribe_port(snd_seq_t *handle, snd_seq_port_subscribe_t *sub);
/** subscription query container */
struct _snd_seq_query_subscribe;
alias _snd_seq_query_subscribe snd_seq_query_subscribe_t;
/** type of query subscription */
alias snd_seq_query_subs_type_t = int;
enum : snd_seq_query_subs_type_t {
SND_SEQ_QUERY_SUBS_READ, /** query read subscriptions */
SND_SEQ_QUERY_SUBS_WRITE /** query write subscriptions */
}
size_t snd_seq_query_subscribe_sizeof();
// snd_seq_query_subscribe_alloca: not implemented
int snd_seq_query_subscribe_malloc(snd_seq_query_subscribe_t **ptr);
void snd_seq_query_subscribe_free(snd_seq_query_subscribe_t *ptr);
void snd_seq_query_subscribe_copy(snd_seq_query_subscribe_t *dst, const(snd_seq_query_subscribe_t) *src);
int snd_seq_query_subscribe_get_client(const(snd_seq_query_subscribe_t) *info);
int snd_seq_query_subscribe_get_port(const(snd_seq_query_subscribe_t) *info);
const(snd_seq_addr_t) *snd_seq_query_subscribe_get_root(const(snd_seq_query_subscribe_t) *info);
snd_seq_query_subs_type_t snd_seq_query_subscribe_get_type(const(snd_seq_query_subscribe_t) *info);
int snd_seq_query_subscribe_get_index(const(snd_seq_query_subscribe_t) *info);
int snd_seq_query_subscribe_get_num_subs(const(snd_seq_query_subscribe_t) *info);
const(snd_seq_addr_t) *snd_seq_query_subscribe_get_addr(const(snd_seq_query_subscribe_t) *info);
int snd_seq_query_subscribe_get_queue(const(snd_seq_query_subscribe_t) *info);
int snd_seq_query_subscribe_get_exclusive(const(snd_seq_query_subscribe_t) *info);
int snd_seq_query_subscribe_get_time_update(const(snd_seq_query_subscribe_t) *info);
int snd_seq_query_subscribe_get_time_real(const(snd_seq_query_subscribe_t) *info);
void snd_seq_query_subscribe_set_client(snd_seq_query_subscribe_t *info, int client);
void snd_seq_query_subscribe_set_port(snd_seq_query_subscribe_t *info, int port);
void snd_seq_query_subscribe_set_root(snd_seq_query_subscribe_t *info, const(snd_seq_addr_t) *addr);
void snd_seq_query_subscribe_set_type(snd_seq_query_subscribe_t *info, snd_seq_query_subs_type_t type);
void snd_seq_query_subscribe_set_index(snd_seq_query_subscribe_t *info, int _index);
int snd_seq_query_port_subscribers(snd_seq_t *seq, snd_seq_query_subscribe_t * subs);
// Sequencer Queue Interface
/** queue information container */
struct _snd_seq_queue_info;
alias _snd_seq_queue_info snd_seq_queue_info_t;
/** queue status container */
struct _snd_seq_queue_status;
alias _snd_seq_queue_status snd_seq_queue_status_t;
/** queue tempo container */
struct _snd_seq_queue_tempo;
alias _snd_seq_queue_tempo snd_seq_queue_tempo_t;
/** queue timer information container */
struct _snd_seq_queue_timer;
alias _snd_seq_queue_timer snd_seq_queue_timer_t;
/** special queue ids */
enum SND_SEQ_QUEUE_DIRECT = 253; /** direct dispatch */
size_t snd_seq_queue_info_sizeof();
// snd_seq_queue_info_alloca: not implemented
int snd_seq_queue_info_malloc(snd_seq_queue_info_t **ptr);
void snd_seq_queue_info_free(snd_seq_queue_info_t *ptr);
void snd_seq_queue_info_copy(snd_seq_queue_info_t *dst, const(snd_seq_queue_info_t) *src);
int snd_seq_queue_info_get_queue(const(snd_seq_queue_info_t) *info);
const(char) *snd_seq_queue_info_get_name(const(snd_seq_queue_info_t) *info);
int snd_seq_queue_info_get_owner(const(snd_seq_queue_info_t) *info);
int snd_seq_queue_info_get_locked(const(snd_seq_queue_info_t) *info);
uint snd_seq_queue_info_get_flags(const(snd_seq_queue_info_t) *info);
void snd_seq_queue_info_set_name(snd_seq_queue_info_t *info, const(char) *name);
void snd_seq_queue_info_set_owner(snd_seq_queue_info_t *info, int owner);
void snd_seq_queue_info_set_locked(snd_seq_queue_info_t *info, int locked);
void snd_seq_queue_info_set_flags(snd_seq_queue_info_t *info, uint flags);
int snd_seq_create_queue(snd_seq_t *seq, snd_seq_queue_info_t *info);
int snd_seq_alloc_named_queue(snd_seq_t *seq, const(char) *name);
int snd_seq_alloc_queue(snd_seq_t *handle);
int snd_seq_free_queue(snd_seq_t *handle, int q);
int snd_seq_get_queue_info(snd_seq_t *seq, int q, snd_seq_queue_info_t *info);
int snd_seq_set_queue_info(snd_seq_t *seq, int q, snd_seq_queue_info_t *info);
int snd_seq_query_named_queue(snd_seq_t *seq, const(char) *name);
int snd_seq_get_queue_usage(snd_seq_t *handle, int q);
int snd_seq_set_queue_usage(snd_seq_t *handle, int q, int used);
size_t snd_seq_queue_status_sizeof();
// snd_seq_queue_status_alloca: not implemented
int snd_seq_queue_status_malloc(snd_seq_queue_status_t **ptr);
void snd_seq_queue_status_free(snd_seq_queue_status_t *ptr);
void snd_seq_queue_status_copy(snd_seq_queue_status_t *dst, const(snd_seq_queue_status_t) *src);
int snd_seq_queue_status_get_queue(const(snd_seq_queue_status_t) *info);
int snd_seq_queue_status_get_events(const(snd_seq_queue_status_t) *info);
snd_seq_tick_time_t snd_seq_queue_status_get_tick_time(const(snd_seq_queue_status_t) *info);
const(snd_seq_real_time_t) *snd_seq_queue_status_get_real_time(const(snd_seq_queue_status_t) *info);
uint snd_seq_queue_status_get_status(const(snd_seq_queue_status_t) *info);
int snd_seq_get_queue_status(snd_seq_t *handle, int q, snd_seq_queue_status_t *status);
size_t snd_seq_queue_tempo_sizeof();
// snd_seq_queue_tempo_alloca: not implemented
int snd_seq_queue_tempo_malloc(snd_seq_queue_tempo_t **ptr);
void snd_seq_queue_tempo_free(snd_seq_queue_tempo_t *ptr);
void snd_seq_queue_tempo_copy(snd_seq_queue_tempo_t *dst, const(snd_seq_queue_tempo_t) *src);
int snd_seq_queue_tempo_get_queue(const(snd_seq_queue_tempo_t) *info);
uint snd_seq_queue_tempo_get_tempo(const(snd_seq_queue_tempo_t) *info);
int snd_seq_queue_tempo_get_ppq(const(snd_seq_queue_tempo_t) *info);
uint snd_seq_queue_tempo_get_skew(const(snd_seq_queue_tempo_t) *info);
uint snd_seq_queue_tempo_get_skew_base(const(snd_seq_queue_tempo_t) *info);
void snd_seq_queue_tempo_set_tempo(snd_seq_queue_tempo_t *info, uint tempo);
void snd_seq_queue_tempo_set_ppq(snd_seq_queue_tempo_t *info, int ppq);
void snd_seq_queue_tempo_set_skew(snd_seq_queue_tempo_t *info, uint skew);
void snd_seq_queue_tempo_set_skew_base(snd_seq_queue_tempo_t *info, uint base);
int snd_seq_get_queue_tempo(snd_seq_t *handle, int q, snd_seq_queue_tempo_t *tempo);
int snd_seq_set_queue_tempo(snd_seq_t *handle, int q, snd_seq_queue_tempo_t *tempo);
/** sequencer timer sources */
alias snd_seq_queue_timer_type_t = int;
enum : snd_seq_queue_timer_type_t {
SND_SEQ_TIMER_ALSA = 0, /* ALSA timer */
SND_SEQ_TIMER_MIDI_CLOCK = 1, /* Midi Clock (CLOCK event) */
SND_SEQ_TIMER_MIDI_TICK = 2 /* Midi Timer Tick (TICK event */
}
size_t snd_seq_queue_timer_sizeof();
// snd_seq_queue_timer_alloca: not implemented
int snd_seq_queue_timer_malloc(snd_seq_queue_timer_t **ptr);
void snd_seq_queue_timer_free(snd_seq_queue_timer_t *ptr);
void snd_seq_queue_timer_copy(snd_seq_queue_timer_t *dst, const(snd_seq_queue_timer_t) *src);
int snd_seq_queue_timer_get_queue(const(snd_seq_queue_timer_t) *info);
snd_seq_queue_timer_type_t snd_seq_queue_timer_get_type(const(snd_seq_queue_timer_t) *info);
const(snd_timer_id_t) *snd_seq_queue_timer_get_id(const(snd_seq_queue_timer_t) *info);
uint snd_seq_queue_timer_get_resolution(const(snd_seq_queue_timer_t) *info);
void snd_seq_queue_timer_set_type(snd_seq_queue_timer_t *info, snd_seq_queue_timer_type_t type);
void snd_seq_queue_timer_set_id(snd_seq_queue_timer_t *info, const(snd_timer_id_t) *id);
void snd_seq_queue_timer_set_resolution(snd_seq_queue_timer_t *info, uint resolution);
int snd_seq_get_queue_timer(snd_seq_t *handle, int q, snd_seq_queue_timer_t *timer);
int snd_seq_set_queue_timer(snd_seq_t *handle, int q, snd_seq_queue_timer_t *timer);
// Sequencer Event API
int snd_seq_free_event(snd_seq_event_t *ev);
ssize_t snd_seq_event_length(snd_seq_event_t *ev);
int snd_seq_event_output(snd_seq_t *handle, snd_seq_event_t *ev);
int snd_seq_event_output_buffer(snd_seq_t *handle, snd_seq_event_t *ev);
int snd_seq_event_output_direct(snd_seq_t *handle, snd_seq_event_t *ev);
int snd_seq_event_input(snd_seq_t *handle, snd_seq_event_t **ev);
int snd_seq_event_input_pending(snd_seq_t *seq, int fetch_sequencer);
int snd_seq_drain_output(snd_seq_t *handle);
int snd_seq_event_output_pending(snd_seq_t *seq);
int snd_seq_extract_output(snd_seq_t *handle, snd_seq_event_t **ev);
int snd_seq_drop_output(snd_seq_t *handle);
int snd_seq_drop_output_buffer(snd_seq_t *handle);
int snd_seq_drop_input(snd_seq_t *handle);
int snd_seq_drop_input_buffer(snd_seq_t *handle);
/** event removal conditionals */
struct _snd_seq_remove_events;
alias _snd_seq_remove_events snd_seq_remove_events_t;
/** Remove conditional flags */
enum SND_SEQ_REMOVE_INPUT = (1<<0); /** Flush input queues */
enum SND_SEQ_REMOVE_OUTPUT = (1<<1); /** Flush output queues */
enum SND_SEQ_REMOVE_DEST = (1<<2); /** Restrict by destination q:client:port */
enum SND_SEQ_REMOVE_DEST_CHANNEL = (1<<3); /** Restrict by channel */
enum SND_SEQ_REMOVE_TIME_BEFORE = (1<<4); /**Restrict to before time */
enum SND_SEQ_REMOVE_TIME_AFTER = (1<<5); /** Restrict to time or after */
enum SND_SEQ_REMOVE_TIME_TICK = (1<<6); /** Time is in ticks */
enum SND_SEQ_REMOVE_EVENT_TYPE = (1<<7); /** Restrict to event type */
enum SND_SEQ_REMOVE_IGNORE_OFF = (1<<8); /** Do not flush off events */
enum SND_SEQ_REMOVE_TAG_MATCH = (1<<9); /** Restrict to events with given tag */
size_t snd_seq_remove_events_sizeof();
// snd_seq_remove_events_alloca: not implemented
int snd_seq_remove_events_malloc(snd_seq_remove_events_t **ptr);
void snd_seq_remove_events_free(snd_seq_remove_events_t *ptr);
void snd_seq_remove_events_copy(snd_seq_remove_events_t *dst, const(snd_seq_remove_events_t) *src);
uint snd_seq_remove_events_get_condition(const(snd_seq_remove_events_t) *info);
int snd_seq_remove_events_get_queue(const(snd_seq_remove_events_t) *info);
const(snd_seq_timestamp_t) *snd_seq_remove_events_get_time(const(snd_seq_remove_events_t) *info);
const(snd_seq_addr_t) *snd_seq_remove_events_get_dest(const(snd_seq_remove_events_t) *info);
int snd_seq_remove_events_get_channel(const(snd_seq_remove_events_t) *info);
int snd_seq_remove_events_get_event_type(const(snd_seq_remove_events_t) *info);
int snd_seq_remove_events_get_tag(const(snd_seq_remove_events_t) *info);
void snd_seq_remove_events_set_condition(snd_seq_remove_events_t *info, uint flags);
void snd_seq_remove_events_set_queue(snd_seq_remove_events_t *info, int queue);
void snd_seq_remove_events_set_time(snd_seq_remove_events_t *info, const(snd_seq_timestamp_t) *time);
void snd_seq_remove_events_set_dest(snd_seq_remove_events_t *info, const(snd_seq_addr_t) *addr);
void snd_seq_remove_events_set_channel(snd_seq_remove_events_t *info, int channel);
void snd_seq_remove_events_set_event_type(snd_seq_remove_events_t *info, int type);
void snd_seq_remove_events_set_tag(snd_seq_remove_events_t *info, int tag);
int snd_seq_remove_events(snd_seq_t *handle, snd_seq_remove_events_t *info);
// Sequencer Miscellaneous
void snd_seq_set_bit(int nr, void *array);
void snd_seq_unset_bit(int nr, void *array);
int snd_seq_change_bit(int nr, void *array);
int snd_seq_get_bit(int nr, void *array);
// Sequencer Event Type Checks
/* event type macros */
enum {
SND_SEQ_EVFLG_RESULT,
SND_SEQ_EVFLG_NOTE,
SND_SEQ_EVFLG_CONTROL,
SND_SEQ_EVFLG_QUEUE,
SND_SEQ_EVFLG_SYSTEM,
SND_SEQ_EVFLG_MESSAGE,
SND_SEQ_EVFLG_CONNECTION,
SND_SEQ_EVFLG_SAMPLE,
SND_SEQ_EVFLG_USERS,
SND_SEQ_EVFLG_INSTR,
SND_SEQ_EVFLG_QUOTE,
SND_SEQ_EVFLG_NONE,
SND_SEQ_EVFLG_RAW,
SND_SEQ_EVFLG_FIXED,
SND_SEQ_EVFLG_VARIABLE,
SND_SEQ_EVFLG_VARUSR
};
enum {
SND_SEQ_EVFLG_NOTE_ONEARG,
SND_SEQ_EVFLG_NOTE_TWOARG
};
enum {
SND_SEQ_EVFLG_QUEUE_NOARG,
SND_SEQ_EVFLG_QUEUE_TICK,
SND_SEQ_EVFLG_QUEUE_TIME,
SND_SEQ_EVFLG_QUEUE_VALUE
};
/**
* Exported event type table
*
* This table is referred by snd_seq_ev_is_xxx.
*/
/* In the C header, the array below has unspecified length. However, if we omit
* the length here, D will assume it is a D-style dynamic array, and generate the
* wrong code to access it, leading to undefined behavior at runtime.
*
* The solution is to specify a "dummy" length that's guaranteed to be at
* least as large as the actual array's length. Since we know that this array
* is intended to be indexed using the `type` member of the `snd_seq_event`
* struct, we choose the minimum length such that every possible value of that
* member results in an in-bounds access.
*/
extern __gshared const(uint)[snd_seq_event_type_t.max + 1] snd_seq_event_types;
pure int _SND_SEQ_TYPE(int x) { return (1<<(x)); } /** master type - 24bit */
pure int _SND_SEQ_TYPE_OPT(int x) { return ((x)<<24); } /** optional type - 8bit */
/** check the event type */
int snd_seq_type_check(snd_seq_event_t* ev, int x)
{
return snd_seq_event_types[ev.type] & _SND_SEQ_TYPE(x);
}
/** event type check: result events */
int snd_seq_ev_is_result_type(snd_seq_event_t* ev)
{
return snd_seq_type_check(ev, SND_SEQ_EVFLG_RESULT);
}
/** event type check: note events */
int snd_seq_ev_is_note_type(snd_seq_event_t* ev)
{
return snd_seq_type_check(ev, SND_SEQ_EVFLG_NOTE);
}
/** event type check: control events */
int snd_seq_ev_is_control_type(snd_seq_event_t* ev)
{
return snd_seq_type_check(ev, SND_SEQ_EVFLG_CONTROL);
}
/** event type check: channel specific events */
int snd_seq_ev_is_channel_type(snd_seq_event_t* ev)
{
return (snd_seq_event_types[ev.type]
& (_SND_SEQ_TYPE(SND_SEQ_EVFLG_NOTE)
| _SND_SEQ_TYPE(SND_SEQ_EVFLG_CONTROL)));
}
/** event type check: queue control events */
int snd_seq_ev_is_queue_type(snd_seq_event_t* ev)
{
return snd_seq_type_check(ev, SND_SEQ_EVFLG_QUEUE);
}
/** event type check: system status messages */
int snd_seq_ev_is_message_type(snd_seq_event_t* ev)
{
return snd_seq_type_check(ev, SND_SEQ_EVFLG_MESSAGE);
}
/** event type check: system status messages */
int snd_seq_ev_is_subscribe_type(snd_seq_event_t* ev)
{
return snd_seq_type_check(ev, SND_SEQ_EVFLG_CONNECTION);
}
/** event type check: sample messages */
int snd_seq_ev_is_sample_type(snd_seq_event_t* ev)
{
return snd_seq_type_check(ev, SND_SEQ_EVFLG_SAMPLE);
}
/** event type check: user-defined messages */
int snd_seq_ev_is_user_type(snd_seq_event_t* ev)
{
return snd_seq_type_check(ev, SND_SEQ_EVFLG_USERS);
}
/** event type check: instrument layer events */
int snd_seq_ev_is_instr_type(snd_seq_event_t* ev)
{
return snd_seq_type_check(ev, SND_SEQ_EVFLG_INSTR);
}
/** event type check: fixed length events */
int snd_seq_ev_is_fixed_type(snd_seq_event_t* ev)
{
return snd_seq_type_check(ev, SND_SEQ_EVFLG_FIXED);
}
/** event type check: variable length events */
int snd_seq_ev_is_variable_type(snd_seq_event_t* ev)
{
return snd_seq_type_check(ev, SND_SEQ_EVFLG_VARIABLE);
}
/** event type check: user pointer events */
int snd_seq_ev_is_varusr_type(snd_seq_event_t* ev)
{
return snd_seq_type_check(ev, SND_SEQ_EVFLG_VARUSR);
}
/** event type check: reserved for kernel */
int snd_seq_ev_is_reserved(snd_seq_event_t* ev)
{
return (! snd_seq_event_types[ev.type]);
}
// seqmid.h
// Sequencer Middle Level Interface
/**
* initialize event record
*
* Clears the given event record pointer to the default status.
*
* Params:
* ev = event record pointer
*/
pure void snd_seq_ev_clear(snd_seq_event_t* ev)
{
memset(ev, 0, snd_seq_event_t.sizeof);
}
/**
* set the tag for given event
*
* Sets the tag to the given event record.
*
* Params:
* ev = event record
* t = event tag
*/
pure void snd_seq_ev_set_tag(snd_seq_event_t* ev, ubyte t)
{
ev.tag = t;
}
/**
* set the explicit destination
*
* Sets the client and port id numbers to the given event record.
*
* Params:
* ev = event record
* c = destination client id
* p = destination port id
*
* See_Also: snd_seq_ev_set_subs()
*/
pure void snd_seq_ev_set_dest(snd_seq_event_t* ev, ubyte c, ubyte p)
{
ev.dest.client = c; ev.dest.port = p;
}
/**
* set broadcasting to subscribers
*
* Sets the destination as the subscribers.
*
* Params:
* ev = event record
*
* See_Also: snd_seq_ev_set_dest()
*/
pure void snd_seq_ev_set_subs(snd_seq_event_t* ev)
{
ev.dest.client = SND_SEQ_ADDRESS_SUBSCRIBERS;
ev.dest.port = SND_SEQ_ADDRESS_UNKNOWN;
}
/**
* set broadcasting to all clients/ports
*
* Sets the destination as the broadcasting.
*
* Params:
* ev = event record
*
* See_Also: snd_seq_ev_set_dest
*/
pure void snd_seq_ev_set_broadcast(snd_seq_event_t* ev)
{
ev.dest.client = SND_SEQ_ADDRESS_BROADCAST;
ev.dest.port = SND_SEQ_ADDRESS_BROADCAST;
}
/**
* set the source port
*
* Sets the source port id number
*
* Params:
* ev = event record
* p = source port id
*/
pure void snd_seq_ev_set_source(snd_seq_event_t* ev, ubyte p)
{
ev.source.port = p;
}
/**
* set direct passing mode (without queued)
*
* Sets the event to the direct passing mode to be delivered
* immediately without queueing.
*
* Params:
* ev = event instance
*
* See_Also: snd_seq_ev_schedule_tick(), snd_seq_ev_schedule_real()
*/
pure void snd_seq_ev_set_direct(snd_seq_event_t* ev)
{
ev.queue = SND_SEQ_QUEUE_DIRECT;
}
/**
* set tick-scheduling mode on queue
*
* Sets the scheduling of the event in the MIDI tick mode.
*
* Params:
* ev = event instance
* q = queue id to schedule
* relative = relative time-stamp if non-zero
* ttick = tick time-stamp to be delivered
*
* See_Also: snd_seq_ev_schedule_real(), snd_seq_ev_set_direct()
*/
pure void snd_seq_ev_schedule_tick(snd_seq_event_t* ev, ubyte q, int relative,
snd_seq_tick_time_t ttick)
{
ev.flags &= ~(SND_SEQ_TIME_STAMP_MASK | SND_SEQ_TIME_MODE_MASK);
ev.flags |= SND_SEQ_TIME_STAMP_TICK;
ev.flags |= relative ? SND_SEQ_TIME_MODE_REL : SND_SEQ_TIME_MODE_ABS;
ev.time.tick = ttick;
ev.queue = q;
}
/**
* set real-time-scheduling mode on queue
*
* Sets the scheduling of the event in the realtime mode.
*
* Params:
* ev = event instance
* q = queue id to schedule
* relative = relative time-stamp if non-zero
* rtime = time-stamp to be delivered
*
* See_Also: snd_seq_eve_schedule_tick(), snd_seq_ev_set_direct()
*/
pure void snd_seq_ev_schedule_real(snd_seq_event_t* ev, ubyte q, int relative,
snd_seq_real_time_t* rtime)
{
ev.flags &= ~(SND_SEQ_TIME_STAMP_MASK | SND_SEQ_TIME_MODE_MASK);
ev.flags |= SND_SEQ_TIME_STAMP_REAL;
ev.flags |= relative ? SND_SEQ_TIME_MODE_REL : SND_SEQ_TIME_MODE_ABS;
ev.time.time = *rtime;
ev.queue = q;
}
/**
* set event priority
*
* Params:
* ev = event instance
* high_prior = 1 for high priority mode
*/
pure void snd_seq_ev_set_priority(snd_seq_event_t* ev, int high_prior)
{
ev.flags &= ~SND_SEQ_PRIORITY_MASK;
ev.flags |= high_prior ? SND_SEQ_PRIORITY_HIGH : SND_SEQ_PRIORITY_NORMAL;
}
/**
* set fixed data
*
* Sets the event length mode as fixed size.
*
* Params:
* ev = event instance
*
* See_Also: snd_seq_ev_set_variable(), snd_seq_ev_set_varusr()
*/
pure void snd_seq_ev_set_fixed(snd_seq_event_t* ev)
{
ev.flags &= ~SND_SEQ_EVENT_LENGTH_MASK;
ev.flags |= SND_SEQ_EVENT_LENGTH_FIXED;
}
/**
* set variable data
*
* Sets the event length mode as variable length and stores the data.
*
* Params:
* ev = event instance
* datalen = length of the external data
* dataprt = pointer of the external data
*
* See_Also: snd_seq_ev_set_fixed(), snd_seq_ev_set_varusr()
*/
pure void snd_seq_ev_set_variable(snd_seq_event_t* ev, uint datalen, void* dataptr)
{
ev.flags &= ~SND_SEQ_EVENT_LENGTH_MASK;
ev.flags |= SND_SEQ_EVENT_LENGTH_VARIABLE;
ev.data.ext.len = datalen;
ev.data.ext.ptr = dataptr;
}
/**
* set varusr data
*
* Sets the event length mode as variable user-space data and stores the data.
*
* Params:
* ev = event instance
* datalen = length of the external data
* dataptr = pointer of the external data
*
* See_Also: snd_seq_ev_set_fixed(), snd_seq_ev_set_variable()
*/
pure void snd_seq_ev_set_varusr(snd_seq_event_t* ev, uint datalen, void* dataptr)
{
ev.flags &= ~SND_SEQ_EVENT_LENGTH_MASK;
ev.flags |= SND_SEQ_EVENT_LENGTH_VARUSR;
ev.data.ext.len = datalen;
ev.data.ext.ptr = dataptr;
}
/**
* set queue controls
*
* Params:
* ev = event record
* typ = event type
* q = queue id
* val = control value
*/
pure void snd_seq_ev_set_queue_control(snd_seq_event_t* ev, snd_seq_event_type_t typ,
ubyte q, int val)
{
ev.type = typ;
snd_seq_ev_set_dest(ev, SND_SEQ_CLIENT_SYSTEM, SND_SEQ_PORT_SYSTEM_TIMER);
ev.data.queue.queue = q;
ev.data.queue.param.value = val;
}
/**
* set the start queue event
*
* Params:
* ev = event record
* q = queue id to start
*
* See_Also: snd_seq_ev_set_queue_stop(), snd_seq_ev_set_queue_continue()
*/
pure void snd_seq_ev_set_queue_start(snd_seq_event_t* ev, ubyte q)
{
snd_seq_ev_set_queue_control(ev, SND_SEQ_EVENT_START, q, 0);
}
/**
* set the stop queue event
*
* Params:
* ev = event record
* q = queue id to stop
*
* See_Also: snd_seq_ev_set_queue_start(), snd_seq_ev_set_queue_continue()
*/
pure void snd_seq_ev_set_queue_stop(snd_seq_event_t* ev, ubyte q)
{
snd_seq_ev_set_queue_control(ev, SND_SEQ_EVENT_STOP, q, 0);
}
/**
* set the continue queue event
*
* Params:
* ev = event record
* q = queue id to continue
*
* See_Also: snd_seq_ev_set_queue_start(), snd_seq_ev_set_queue_stop()
*/
pure void snd_seq_ev_set_queue_continue(snd_seq_event_t* ev, ubyte q)
{
snd_seq_ev_set_queue_control(ev, SND_SEQ_EVENT_CONTINUE, q, 0);
}
/**
* set the tempo queue event
*
* Params:
* ev = event record
* q = queue id to change tempo
* val = new tempo value
*/
pure void snd_seq_ev_set_queue_tempo(snd_seq_event_t* ev, ubyte q, int val)
{
snd_seq_ev_set_queue_control(ev, SND_SEQ_EVENT_TEMPO, q, val);
}
/**
* set the real-time position of a queue
*
* Params:
* ev = event record
* q = queue id to change position
* rtime = the new real-time pointer
*/
pure void snd_seq_ev_set_queue_pos_real(snd_seq_event_t* ev, ubyte q,
snd_seq_real_time_t* rtime)
{
ev.type = SND_SEQ_EVENT_SETPOS_TIME;
snd_seq_ev_set_dest(ev, SND_SEQ_CLIENT_SYSTEM, SND_SEQ_PORT_SYSTEM_TIMER);
ev.data.queue.queue = q;
ev.data.queue.param.time.time = *rtime;
}
/**
* set the tick-time position of a queue
*
* Param:
* ev = event record
* q = queue id to change position
* ttime = the new tick-time
*/
pure void snd_seq_ev_set_queue_pos_tick(snd_seq_event_t* ev, ubyte q,
snd_seq_tick_time_t ttime)
{
ev.type = SND_SEQ_EVENT_SETPOS_TICK;
snd_seq_ev_set_dest(ev, SND_SEQ_CLIENT_SYSTEM, SND_SEQ_PORT_SYSTEM_TIMER);
ev.data.queue.queue = q;
ev.data.queue.param.time.tick = ttime;
}
/* set and send a queue control event */
int snd_seq_control_queue(snd_seq_t *seq, int q, int type, int value, snd_seq_event_t *ev);
/**
* start the specified queue
*
* Params:
* seq = sequencer handle
* q = queue id to start
* ev = optional event record (see [snd_seq_control_queue])
*/
void snd_seq_start_queue(snd_seq_t* seq, int q, snd_seq_event_t* ev)
{
snd_seq_control_queue(seq, q, SND_SEQ_EVENT_START, 0, ev);
}
/**
* stop the specified queue
*
* Params:
* seq = sequencer handle
* q = queue id to stop
* ev = optional event record (see [snd_seq_control_queue])
*/
void snd_seq_stop_queue(snd_seq_t* seq, int q, snd_seq_event_t* ev)
{
snd_seq_control_queue(seq, q, SND_SEQ_EVENT_STOP, 0, ev);
}
/**
* continue the specified queue
*
* Params:
* seq = sequencer handle
* q = queue id to continue
* ev = optional event record (see [snd_seq_control_queue])
*/
void snd_seq_continue_queue(snd_seq_t* seq, int q, snd_seq_event_t* ev)
{
snd_seq_control_queue(seq, q, SND_SEQ_EVENT_CONTINUE, 0, ev);
}
/**
* change the tempo of the specified queue
*
* Params:
* seq = sequencer handle
* q = queue id to continue
* tempo = the new tempo value
* ev = optional event record (see [snd_seq_control_queue])
*/
void snd_seq_change_queue_tempo(snd_seq_t* seq, int q, int tempo, snd_seq_event_t* ev)
{
snd_seq_control_queue(seq, q, SND_SEQ_EVENT_TEMPO, tempo, ev);
}
/* create a port - simple version - return the port number */
int snd_seq_create_simple_port(snd_seq_t *seq, const(char) *name,
uint caps, uint type);
/* delete the port */
int snd_seq_delete_simple_port(snd_seq_t *seq, int port);
/* simple subscription between this port and another port
(w/o exclusive & time conversion)
*/
int snd_seq_connect_from(snd_seq_t *seq, int my_port, int src_client, int src_port);
int snd_seq_connect_to(snd_seq_t *seq, int my_port, int dest_client, int dest_port);
int snd_seq_disconnect_from(snd_seq_t *seq, int my_port, int src_client, int src_port);
int snd_seq_disconnect_to(snd_seq_t *seq, int my_port, int dest_client, int dest_port);
/*
* set client information
*/
int snd_seq_set_client_name(snd_seq_t *seq, const(char) *name);
int snd_seq_set_client_event_filter(snd_seq_t *seq, int event_type);
int snd_seq_set_client_pool_output(snd_seq_t *seq, size_t size);
int snd_seq_set_client_pool_output_room(snd_seq_t *seq, size_t size);
int snd_seq_set_client_pool_input(snd_seq_t *seq, size_t size);
/* sync output queue */
int snd_seq_sync_output_queue(snd_seq_t *seq);
/*
* parse the given string and get the sequencer address
*/
int snd_seq_parse_address(snd_seq_t *seq, snd_seq_addr_t *addr, const(char) *str);
/*
* reset client input/output pool
*/
int snd_seq_reset_pool_output(snd_seq_t *seq);
int snd_seq_reset_pool_input(snd_seq_t *seq);
/**
* set note event
*
* Params:
* ev = event record
* ch = channel number
* key = note key
* vel = veloticy
* dur = duration (in tick or msec)
*/
pure void snd_seq_ev_set_note(snd_seq_event_t* ev, ubyte ch, ubyte key, ubyte vel,
uint dur)
{
ev.type = SND_SEQ_EVENT_NOTE;
snd_seq_ev_set_fixed(ev);
ev.data.note.channel = ch;
ev.data.note.note = key;
ev.data.note.velocity = vel;
ev.data.note.duration = dur;
}
/**
* set note-on event
*
* Params:
* ev = event record
* ch = channel number
* key = note key
* vel = velocity
*/
pure void snd_seq_ev_set_noteon(snd_seq_event_t* ev, ubyte ch, ubyte key, ubyte vel)
{
ev.type = SND_SEQ_EVENT_NOTEON;
snd_seq_ev_set_fixed(ev);
ev.data.note.channel = ch;
ev.data.note.note = key;
ev.data.note.velocity = vel;
}
/**
* set note-off event
*
* Params:
* ev = event record
* ch = channel number
* key = note key
* vel = velocity
*/
pure void snd_seq_ev_set_noteoff(snd_seq_event_t* ev, ubyte ch, ubyte key, ubyte vel)
{
ev.type = SND_SEQ_EVENT_NOTEOFF;
snd_seq_ev_set_fixed(ev);
ev.data.note.channel = ch;
ev.data.note.note = key;
ev.data.note.velocity = vel;
}
/**
* set key-pressure event
*
* Params:
* ev = event record
* ch = channel number
* key = note key
* vel = velocity
*/
pure void snd_seq_ev_set_keypress(snd_seq_event_t* ev, ubyte ch, ubyte key, ubyte vel)
{
ev.type = SND_SEQ_EVENT_KEYPRESS;
snd_seq_ev_set_fixed(ev);
ev.data.note.channel = ch;
ev.data.note.note = key;
ev.data.note.velocity = vel;
}
/**
* set MIDI controller event
*
* Params:
* ev = event record
* ch = channel number
* cc = controller number
* val = control value
*/
pure void snd_seq_ev_set_controller(snd_seq_event_t* ev, ubyte ch, uint cc, int val)
{
ev.type = SND_SEQ_EVENT_CONTROLLER;
snd_seq_ev_set_fixed(ev);
ev.data.control.channel = ch;
ev.data.control.param = cc;
ev.data.control.value = val;
}
/**
* set program change event
*
* Params:
* ev = event record
* ch = channel number
* val = program number
*/
pure void snd_seq_ev_set_pgmchange(snd_seq_event_t* ev, ubyte ch, int val)
{
ev.type = SND_SEQ_EVENT_PGMCHANGE;
snd_seq_ev_set_fixed(ev);
ev.data.control.channel = ch;
ev.data.control.value = val;
}
/**
* set pitch-bend event
*
* Params:
* ev = event record
* ch = channel number
* val = pitch bend; zero centered from -8192 to 8191
*/
pure void snd_seq_ev_set_pitchbend(snd_seq_event_t* ev, ubyte ch, int val)
{
ev.type = SND_SEQ_EVENT_PITCHBEND;
snd_seq_ev_set_fixed(ev);
ev.data.control.channel = ch;
ev.data.control.value = val;
}
/**
* set channel pressure event
*
* Params
* ev = event record
* ch = channel number
* val = channel pressure value
*/
pure void snd_seq_ev_set_chanpress(snd_seq_event_t* ev, ubyte ch, int val)
{
ev.type = SND_SEQ_EVENT_CHANPRESS;
snd_seq_ev_set_fixed(ev);
ev.data.control.channel = ch;
ev.data.control.value = val;
}
/**
* set sysex event
*
* The sysex data must contain the start byte 0xf0 and the end byte 0xf7
*
* Params:
* ev = event record
* datalen = length of sysex data
* dataptr = sysex data ptr
*/
pure void snd_seq_ev_set_sysex(snd_seq_event_t* ev, uint datalen, void* dataptr)
{
ev.type = SND_SEQ_EVENT_SYSEX;
snd_seq_ev_set_variable(ev, datalen, dataptr);
}
// seq_midi_event.h
// Sequencer event <-> MIDI byte stream coder
/** container for sequencer midi event parsers */
struct snd_midi_event;
alias snd_midi_event snd_midi_event_t;
int snd_midi_event_new(size_t bufsize, snd_midi_event_t **rdev);
int snd_midi_event_resize_buffer(snd_midi_event_t *dev, size_t bufsize);
void snd_midi_event_free(snd_midi_event_t *dev);
void snd_midi_event_init(snd_midi_event_t *dev);
void snd_midi_event_reset_encode(snd_midi_event_t *dev);
void snd_midi_event_reset_decode(snd_midi_event_t *dev);
void snd_midi_event_no_status(snd_midi_event_t *dev, int on);
/* encode from byte stream - return number of written bytes if success */
c_long snd_midi_event_encode(snd_midi_event_t *dev, const(ubyte) *buf, c_long count, snd_seq_event_t *ev);
int snd_midi_event_encode_byte(snd_midi_event_t *dev, int c, snd_seq_event_t *ev);
/* decode from event to bytes - return number of written bytes if success */
c_long snd_midi_event_decode(snd_midi_event_t *dev, ubyte *buf, c_long count, const(snd_seq_event_t) *ev);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment