Major change to sequencer API.

The sequencer API is totally recoded with the style of "encapsulation"
in other api.
The structure becomes opaque and accessed only via functions.

Other changes:
- There is no longer group in client and port info.
- snd_seq_query_subs_t is renamed to snd_seq_query_subscribe_t.
- snd_seq_delete_port takes only the port id argument instead of
  port_info structure.
- snd_seq_input/output_buffer_size are renamed
  as snd_seq_get_input/output_buffer_size.
  Similarly snd_seq_resize_input/output_buffer are renamed as
  snd_seq_set_input/output_buffer_size.
- snd_seq_get_named_queue is renamed to snd_seq_query_named_queue.
- Sync codes are removed temporarily from API.
- Subscription conditions are accessed via the corresponding functions.
  convert_time is named now as time_update.
- snd_seq_get/set_queue_owner are removed.
  Use snd_seq_get/set_queue_info instead.
- Instrument put/get/remove structure is unified as snd_instr_header_t.
This commit is contained in:
Jaroslav Kysela 2001-07-04 13:54:13 +00:00
parent d23ff765ad
commit 88e5e45151
20 changed files with 4410 additions and 1691 deletions

View file

@ -7,7 +7,7 @@ header_files=header.h version.h global.h input.h output.h error.h \
conf.h pcm.h rawmidi.h timer.h \
hwdep.h hwdep_m4.h control.h \
mixer.h \
seq.h seqmid.h seq_midi_event.h \
seq_event.h seq.h seqmid.h seq_midi_event.h \
conv.h instr.h footer.h
noinst_HEADERS=$(header_files) search.h list.h aserver.h local.h

View file

@ -11,41 +11,144 @@
* \{
*/
/* FM instrument support */
/* instrument get/put */
#ifdef __cplusplus
extern "C" {
#endif
typedef struct _snd_instr_header snd_instr_header_t;
size_t snd_instr_header_sizeof(void);
#define snd_instr_header_alloca(ptr) \
do {\
assert(ptr);\
*ptr = (snd_instr_header_t *)alloca(snd_instr_header_sizeof());\
memset(*ptr, 0, snd_instr_header_sizeof());\
} while (0)
int snd_instr_header_malloc(snd_instr_header_t **ptr, size_t len);
void snd_instr_header_free(snd_instr_header_t *ptr);
void snd_instr_header_copy(snd_instr_header_t *dst, const snd_instr_header_t *src);
const snd_seq_instr_t *snd_instr_header_get_id(const snd_instr_header_t *info);
snd_seq_instr_cluster_t snd_instr_header_get_cluster(const snd_instr_header_t *info);
unsigned int snd_instr_header_get_cmd(const snd_instr_header_t *info);
size_t snd_instr_header_get_len(const snd_instr_header_t *info);
const char *snd_instr_header_get_name(const snd_instr_header_t *info);
int snd_instr_header_get_type(const snd_instr_header_t *info);
const char *snd_instr_header_get_format(const snd_instr_header_t *info);
const snd_seq_instr_t *snd_instr_header_get_alias(const snd_instr_header_t *info);
void *snd_instr_header_get_data(const snd_instr_header_t *info);
int snd_instr_header_get_follow_alias(const snd_instr_header_t *info);
void snd_instr_header_set_id(snd_instr_header_t *info, const snd_seq_instr_t *id);
void snd_instr_header_set_cluster(snd_instr_header_t *info, snd_seq_instr_cluster_t cluster);
void snd_instr_header_set_cmd(snd_instr_header_t *info, unsigned int cmd);
void snd_instr_header_set_len(snd_instr_header_t *info, size_t len);
void snd_instr_header_set_name(snd_instr_header_t *info, const char *name);
void snd_instr_header_set_type(snd_instr_header_t *info, int type);
void snd_instr_header_set_format(snd_instr_header_t *info, const char *format);
void snd_instr_header_set_alias(snd_instr_header_t *info, const snd_seq_instr_t *instr);
void snd_instr_header_set_follow_alias(snd_instr_header_t *info, int bool);
#ifdef __cplusplus
}
#endif
/**
* Instrument abstraction layer
* - based on events
*/
/** instrument types */
#define SND_SEQ_INSTR_ATYPE_DATA 0 /**< instrument data */
#define SND_SEQ_INSTR_ATYPE_ALIAS 1 /**< instrument alias */
/** instrument ASCII identifiers */
#define SND_SEQ_INSTR_ID_DLS1 "DLS1" /**< DLS1 */
#define SND_SEQ_INSTR_ID_DLS2 "DLS2" /**< DLS2 */
#define SND_SEQ_INSTR_ID_SIMPLE "Simple Wave" /**< Simple Wave */
#define SND_SEQ_INSTR_ID_SOUNDFONT "SoundFont" /**< SoundFont */
#define SND_SEQ_INSTR_ID_GUS_PATCH "GUS Patch" /**< Gravis Patch */
#define SND_SEQ_INSTR_ID_INTERWAVE "InterWave FFFF" /**< InterWave FFFF */
#define SND_SEQ_INSTR_ID_OPL2_3 "OPL2/3 FM" /**< OPL2/3 FM */
#define SND_SEQ_INSTR_ID_OPL4 "OPL4" /**< OPL4 */
/** instrument types */
#define SND_SEQ_INSTR_TYPE0_DLS1 (1<<0) /**< MIDI DLS v1 */
#define SND_SEQ_INSTR_TYPE0_DLS2 (1<<1) /**< MIDI DLS v2 */
#define SND_SEQ_INSTR_TYPE1_SIMPLE (1<<0) /**< Simple Wave */
#define SND_SEQ_INSTR_TYPE1_SOUNDFONT (1<<1) /**< EMU SoundFont */
#define SND_SEQ_INSTR_TYPE1_GUS_PATCH (1<<2) /**< Gravis UltraSound Patch */
#define SND_SEQ_INSTR_TYPE1_INTERWAVE (1<<3) /**< InterWave FFFF */
#define SND_SEQ_INSTR_TYPE2_OPL2_3 (1<<0) /**< Yamaha OPL2/3 FM */
#define SND_SEQ_INSTR_TYPE2_OPL4 (1<<1) /**< Yamaha OPL4 */
/** put commands */
#define SND_SEQ_INSTR_PUT_CMD_CREATE 0 /**< create a new layer */
#define SND_SEQ_INSTR_PUT_CMD_REPLACE 1 /**< replace the old layer with new one */
#define SND_SEQ_INSTR_PUT_CMD_MODIFY 2 /**< modify the existing layer */
#define SND_SEQ_INSTR_PUT_CMD_ADD 3 /**< add one to the existing layer */
#define SND_SEQ_INSTR_PUT_CMD_REMOVE 4 /**< remove the layer */
/** get commands */
#define SND_SEQ_INSTR_GET_CMD_FULL 0 /**< get the full data stream */
#define SND_SEQ_INSTR_GET_CMD_PARTIAL 1 /**< get the partial data stream */
/** free commands */
#define SND_SEQ_INSTR_FREE_CMD_ALL 0 /**< remove all matching instruments */
#define SND_SEQ_INSTR_FREE_CMD_PRIVATE 1 /**< remove only private instruments */
#define SND_SEQ_INSTR_FREE_CMD_CLUSTER 2 /**< remove only cluster instruments */
#define SND_SEQ_INSTR_FREE_CMD_SINGLE 3 /**< remove single instrument */
/**
* FM instrument support
*/
/** FM instrument data structure */
typedef void snd_instr_fm_t;
#ifdef __cplusplus
extern "C" {
#endif
int snd_instr_fm_convert_to_stream(snd_instr_fm_t *fm, const char *name, snd_seq_instr_put_t **put, size_t *size);
int snd_instr_fm_convert_from_stream(snd_seq_instr_get_t *data, size_t size, snd_instr_fm_t **fm);
int snd_instr_fm_convert_to_stream(snd_instr_fm_t *fm, const char *name, snd_instr_header_t **put, size_t *size);
int snd_instr_fm_convert_from_stream(snd_instr_header_t *data, size_t size, snd_instr_fm_t **fm);
int snd_instr_fm_free(snd_instr_fm_t *fm);
#ifdef __cplusplus
}
#endif
/* Simple Wave support */
/**
* Simple Wave support
*/
/** simple instrument data structure */
typedef void snd_instr_simple_t;
#ifdef __cplusplus
extern "C" {
#endif
int snd_instr_simple_convert_to_stream(snd_instr_simple_t *simple, const char *name, snd_seq_instr_put_t **put, size_t *size);
int snd_instr_simple_convert_from_stream(snd_seq_instr_get_t *data, size_t size, snd_instr_simple_t **simple);
int snd_instr_simple_convert_to_stream(snd_instr_simple_t *simple, const char *name, snd_instr_header_t **put, size_t *size);
int snd_instr_simple_convert_from_stream(snd_instr_header_t *data, size_t size, snd_instr_simple_t **simple);
int snd_instr_simple_free(snd_instr_simple_t *simple);
#ifdef __cplusplus
}
#endif
/* InterWave FFFF support */
/**
* InterWave FFFF support
*/
/** IW FFFF instrument data structure */
typedef void snd_instr_iwffff_t;
/** IW FFFF handler */
typedef struct _snd_iwffff_handle snd_iwffff_handle_t;
#ifdef __cplusplus
@ -57,8 +160,8 @@ int snd_instr_iwffff_open_rom(snd_iwffff_handle_t **handle, int card, int bank,
int snd_instr_iwffff_open_rom_file(snd_iwffff_handle_t **handle, const char *name, int bank, int file);
int snd_instr_iwffff_close(snd_iwffff_handle_t *handle);
int snd_instr_iwffff_load(snd_iwffff_handle_t *handle, int bank, int prg, snd_instr_iwffff_t **iwffff);
int snd_instr_iwffff_convert_to_stream(snd_instr_iwffff_t *iwffff, const char *name, snd_seq_instr_put_t **data, size_t *size);
int snd_instr_iwffff_convert_from_stream(snd_seq_instr_get_t *data, size_t size, snd_instr_iwffff_t **iwffff);
int snd_instr_iwffff_convert_to_stream(snd_instr_iwffff_t *iwffff, const char *name, snd_instr_header_t **data, size_t *size);
int snd_instr_iwffff_convert_from_stream(snd_instr_header_t *data, size_t size, snd_instr_iwffff_t **iwffff);
int snd_instr_iwffff_free(snd_instr_iwffff_t *iwffff);
#ifdef __cplusplus

View file

@ -46,6 +46,28 @@
#define _snd_hwdep_info sndrv_hwdep_info
#define _SND_SEQ_IN_LOCAL 1
#define _snd_seq_queue_tempo sndrv_seq_queue_tempo
#define _snd_seq_client_info sndrv_seq_client_info
#define _snd_seq_port_info sndrv_seq_port_info
#define _snd_seq_system_info sndrv_seq_system_info
#define _snd_seq_queue_info sndrv_seq_queue_info
#define _snd_seq_queue_status sndrv_seq_queue_status
#define _snd_seq_queue_timer sndrv_seq_queue_timer
#define _snd_seq_port_subscribe sndrv_seq_port_subscribe
#define _snd_seq_query_subscribe sndrv_seq_query_subs
#define _snd_seq_client_pool sndrv_seq_client_pool
#define _snd_seq_remove_events sndrv_seq_remove_events
#define _snd_instr_header sndrv_seq_instr_header
typedef struct sndrv_seq_addr snd_seq_addr_t;
#define snd_seq_tick_time_t sndrv_seq_tick_time_t
typedef struct sndrv_seq_real_time snd_seq_real_time_t;
typedef union sndrv_seq_timestamp snd_seq_timestamp_t;
typedef struct sndrv_seq_instr snd_seq_instr_t;
typedef struct sndrv_seq_event snd_seq_event_t;
#define snd_seq_instr_cluster_t sndrv_seq_instr_cluster_t
#include "asoundlib.h"
#include "list.h"

File diff suppressed because it is too large Load diff

432
include/seq_event.h Normal file
View file

@ -0,0 +1,432 @@
/**
* \defgroup Sequencer Sequencer Interface
* Sequencer Interface
* \{
*/
/** \} */
/**
* \defgroup SeqEvents Sequencer Event Definitions
* Sequencer Event Definitions
* \ingroup Sequencer
* \{
*/
/**
* Sequencer event data type
*/
typedef unsigned char snd_seq_event_type_t;
enum snd_seq_event_type {
/** 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 realtime 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,
/** Sync signal; event data type = #snd_seq_ev_queue_control_t */
SND_SEQ_EVENT_SYNC,
/** 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,
/** 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,
/** Sample select; event data type = #snd_seq_ev_sample_control_t */
SND_SEQ_EVENT_SAMPLE = 70,
/** Sample cluster select; event data type = #snd_seq_ev_sample_control_t */
SND_SEQ_EVENT_SAMPLE_CLUSTER,
/** voice start */
SND_SEQ_EVENT_SAMPLE_START,
/** voice stop */
SND_SEQ_EVENT_SAMPLE_STOP,
/** playback frequency */
SND_SEQ_EVENT_SAMPLE_FREQ,
/** volume and balance */
SND_SEQ_EVENT_SAMPLE_VOLUME,
/** sample loop */
SND_SEQ_EVENT_SAMPLE_LOOP,
/** sample position */
SND_SEQ_EVENT_SAMPLE_POSITION,
/** private (hardware dependent) event */
SND_SEQ_EVENT_SAMPLE_PRIVATE1,
/** 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,
/** begin of instrument management */
SND_SEQ_EVENT_INSTR_BEGIN = 100,
/** end of instrument management */
SND_SEQ_EVENT_INSTR_END,
/** query instrument interface info */
SND_SEQ_EVENT_INSTR_INFO,
/** result of instrument interface info */
SND_SEQ_EVENT_INSTR_INFO_RESULT,
/** query instrument format info */
SND_SEQ_EVENT_INSTR_FINFO,
/** result of instrument format info */
SND_SEQ_EVENT_INSTR_FINFO_RESULT,
/** reset instrument instrument memory */
SND_SEQ_EVENT_INSTR_RESET,
/** get instrument interface status */
SND_SEQ_EVENT_INSTR_STATUS,
/** result of instrument interface status */
SND_SEQ_EVENT_INSTR_STATUS_RESULT,
/** put an instrument to port */
SND_SEQ_EVENT_INSTR_PUT,
/** get an instrument from port */
SND_SEQ_EVENT_INSTR_GET,
/** result of instrument query */
SND_SEQ_EVENT_INSTR_GET_RESULT,
/** free instrument(s) */
SND_SEQ_EVENT_INSTR_FREE,
/** get instrument list */
SND_SEQ_EVENT_INSTR_LIST,
/** result of instrument list */
SND_SEQ_EVENT_INSTR_LIST_RESULT,
/** set cluster parameters */
SND_SEQ_EVENT_INSTR_CLUSTER,
/** get cluster parameters */
SND_SEQ_EVENT_INSTR_CLUSTER_GET,
/** result of cluster parameters */
SND_SEQ_EVENT_INSTR_CLUSTER_RESULT,
/** instrument change */
SND_SEQ_EVENT_INSTR_CHANGE,
/** 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
};
#ifndef _SND_SEQ_IN_LOCAL
/** Sequencer event address */
typedef struct snd_seq_addr {
unsigned char client; /**< Client id */
unsigned char port; /**< Port id */
} snd_seq_addr_t;
/** Connection (subscription) between ports */
typedef struct snd_seq_connect {
snd_seq_addr_t sender; /**< sender address */
snd_seq_addr_t dest; /**< destination address */
} snd_seq_connect_t;
/** Real-time data record */
typedef struct snd_seq_real_time {
unsigned int tv_sec; /**< seconds */
unsigned int tv_nsec; /**< nanoseconds */
} snd_seq_real_time_t;
/** (MIDI) Tick-time data record */
typedef unsigned int snd_seq_tick_time_t;
/** unioned time stamp */
typedef union snd_seq_timestamp {
snd_seq_tick_time_t tick; /**< tick-time */
struct snd_seq_real_time time; /**< real-time */
} snd_seq_timestamp_t;
/**
* Event mode flags
*
* NOTE: only 8 bits available!
*/
#define SND_SEQ_TIME_STAMP_TICK (0<<0) /**< timestamp in clock ticks */
#define SND_SEQ_TIME_STAMP_REAL (1<<0) /**< timestamp in real time */
#define SND_SEQ_TIME_STAMP_MASK (1<<0) /**< mask for timestamp bits */
#define SND_SEQ_TIME_MODE_ABS (0<<1) /**< absolute timestamp */
#define SND_SEQ_TIME_MODE_REL (1<<1) /**< relative to current time */
#define SND_SEQ_TIME_MODE_MASK (1<<1) /**< mask for time mode bits */
#define SND_SEQ_EVENT_LENGTH_FIXED (0<<2) /**< fixed event size */
#define SND_SEQ_EVENT_LENGTH_VARIABLE (1<<2) /**< variable event size */
#define SND_SEQ_EVENT_LENGTH_VARUSR (2<<2) /**< variable event size - user memory space */
#define SND_SEQ_EVENT_LENGTH_VARIPC (3<<2) /**< variable event size - IPC */
#define SND_SEQ_EVENT_LENGTH_MASK (3<<2) /**< mask for event length bits */
#define SND_SEQ_PRIORITY_NORMAL (0<<4) /**< normal priority */
#define SND_SEQ_PRIORITY_HIGH (1<<4) /**< event should be processed before others */
#define SND_SEQ_PRIORITY_MASK (1<<4) /**< mask for priority bits */
/** Note event */
typedef struct snd_seq_ev_note {
unsigned char channel; /**< channel number */
unsigned char note; /**< note */
unsigned char velocity; /**< velocity */
unsigned char off_velocity; /**< note-off velocity; only for #SND_SEQ_EVENT_NOTE */
unsigned int duration; /**< duration until note-off; only for #SND_SEQ_EVENT_NOTE */
} snd_seq_ev_note_t;
/** Controller event */
typedef struct snd_seq_ev_ctrl {
unsigned char channel; /**< channel number */
unsigned char unused[3]; /**< reserved */
unsigned int param; /**< control parameter */
signed int value; /**< control value */
} snd_seq_ev_ctrl_t;
/** generic set of bytes (12x8 bit) */
typedef struct snd_seq_ev_raw8 {
unsigned char d[12]; /**< 8 bit value */
} snd_seq_ev_raw8_t;
/** generic set of integers (3x32 bit) */
typedef struct snd_seq_ev_raw32 {
unsigned int d[3]; /**< 32 bit value */
} snd_seq_ev_raw32_t;
/** external stored data */
typedef struct snd_seq_ev_ext {
size_t len; /**< length of data */
void *ptr; /**< pointer to data (note: can be 64-bit) */
} snd_seq_ev_ext_t;
/** external stored data - IPC shared memory */
typedef struct snd_seq_ev_ipcshm {
size_t len; /**< length of data */
key_t ipc; /**< IPC key */
} snd_seq_ev_ipcshm_t;
/** Instrument cluster type */
typedef unsigned int snd_seq_instr_cluster_t;
/** Instrument type */
typedef struct snd_seq_instr {
snd_seq_instr_cluster_t cluster; /**< cluster id */
unsigned int std; /**< instrument standard id; the upper byte means a private instrument (owner - client id) */
unsigned short bank; /**< instrument bank id */
unsigned short prg; /**< instrument program id */
} snd_seq_instr_t;
/** sample number */
typedef struct snd_seq_ev_sample {
unsigned int std; /**< sample standard id */
unsigned short bank; /**< sample bank id */
unsigned short prg; /**< sample program id */
} snd_seq_ev_sample_t;
/** sample cluster */
typedef struct snd_seq_ev_cluster {
snd_seq_instr_cluster_t cluster; /**< cluster id */
} snd_seq_ev_cluster_t;
/** sample position */
typedef unsigned int snd_seq_position_t; /**< playback position (in samples) * 16 */
/** sample stop mode */
typedef enum snd_seq_stop_mode {
SND_SEQ_SAMPLE_STOP_IMMEDIATELY = 0, /**< terminate playing immediately */
SND_SEQ_SAMPLE_STOP_VENVELOPE = 1, /**< finish volume envelope */
SDN_SEQ_SAMPLE_STOP_LOOP = 2 /**< terminate loop and finish wave */
} snd_seq_stop_mode_t;
/** sample frequency */
typedef int snd_seq_frequency_t; /**< playback frequency in HZ * 16 */
/** sample volume control; if any value is set to -1 == do not change */
typedef struct snd_seq_ev_volume {
signed short volume; /**< range: 0-16383 */
signed short lr; /**< left-right balance; range: 0-16383 */
signed short fr; /**< front-rear balance; range: 0-16383 */
signed short du; /**< down-up balance; range: 0-16383 */
} snd_seq_ev_volume_t;
/** simple loop redefinition */
typedef struct snd_seq_ev_loop {
unsigned int start; /**< loop start (in samples) * 16 */
unsigned int end; /**< loop end (in samples) * 16 */
} snd_seq_ev_loop_t;
/** Sample control events */
typedef struct snd_seq_ev_sample_control {
unsigned char channel; /**< channel */
unsigned char unused[3]; /**< reserved */
union {
snd_seq_ev_sample_t sample;
snd_seq_ev_cluster_t cluster;
snd_seq_position_t position;
snd_seq_stop_mode_t stop_mode;
snd_seq_frequency_t frequency;
snd_seq_ev_volume_t volume;
snd_seq_ev_loop_t loop;
unsigned char raw8[8];
} param; /**< control parameters */
} snd_seq_ev_sample_control_t;
/** INSTR_BEGIN event */
typedef struct snd_seq_ev_instr_begin {
int timeout; /**< zero = forever, otherwise timeout in ms */
} snd_seq_ev_instr_begin_t;
/** Result events */
typedef struct snd_seq_result {
int event; /**< processed event type */
int result; /**< status */
} snd_seq_result_t;
/** queue timer control */
typedef struct snd_seq_ev_queue_control {
unsigned char queue; /**< affected queue */
unsigned char unused[3]; /**< reserved */
union {
signed int value; /**< affected value (e.g. tempo) */
snd_seq_timestamp_t time; /**< time */
unsigned int position; /**< sync position */
unsigned int d32[2]; /**< any data */
unsigned char d8[8]; /**< any data */
} param; /**< data value union */
} snd_seq_ev_queue_control_t;
/** Sequencer event */
typedef struct snd_seq_event {
snd_seq_event_type_t type; /**< event type */
unsigned char flags; /**< event flags */
unsigned char tag; /**< tag */
unsigned char queue; /**< schedule queue */
snd_seq_timestamp_t time; /**< schedule time */
snd_seq_addr_t source; /**< source address */
snd_seq_addr_t dest; /**< destination address */
union {
snd_seq_ev_note_t note;
snd_seq_ev_ctrl_t control;
snd_seq_ev_raw8_t raw8;
snd_seq_ev_raw32_t raw32;
snd_seq_ev_ext_t ext;
snd_seq_ev_ipcshm_t ipcshm;
snd_seq_ev_queue_control_t queue;
snd_seq_timestamp_t time;
snd_seq_addr_t addr;
snd_seq_connect_t connect;
snd_seq_result_t result;
snd_seq_ev_instr_begin_t instr_begin;
snd_seq_ev_sample_control_t sample;
} data; /**< event data... */
} snd_seq_event_t;
#endif /* _SND_SEQ_IN_LOCAL */
/** \} */

View file

@ -4,6 +4,10 @@
* *
****************************************************************************/
#ifdef __cplusplus
extern "C" {
#endif
/**
* \defgroup SeqMiddle Sequencer Middle Level Interface
* Sequencer Middle Level Interface
@ -11,72 +15,237 @@
* \{
*/
#ifdef __cplusplus
extern "C" {
#endif
/* initialize event record */
void snd_seq_ev_clear(snd_seq_event_t *ev);
/* set destination - following three macros are exclusive */
/* explicit destination */
void snd_seq_ev_set_dest(snd_seq_event_t *ev, int client, int port);
/* to subscribers */
void snd_seq_ev_set_subs(snd_seq_event_t *ev);
/* broadcast to all clients/ports */
void snd_seq_ev_set_broadcast(snd_seq_event_t *ev);
/* set source port */
void snd_seq_ev_set_source(snd_seq_event_t *ev, int port);
/* set scheduling - following three macros are exclusive */
/* direct event passing without enqueued */
void snd_seq_ev_set_direct(snd_seq_event_t *ev);
/* scheduled on tick-queue */
void snd_seq_ev_schedule_tick(snd_seq_event_t *ev, int q, int relative,
snd_seq_tick_time_t tick);
/* scheduled on real-time-queue */
void snd_seq_ev_schedule_real(snd_seq_event_t *ev, int q, int relative,
snd_seq_real_time_t *_time);
/* set event priority (optional) */
void snd_seq_ev_set_priority(snd_seq_event_t *ev, int high_prior);
/* set event data type - following three macros are exclusive */
/* fixed size event */
void snd_seq_ev_set_fixed(snd_seq_event_t *ev);
/* variable size event */
void snd_seq_ev_set_variable(snd_seq_event_t *ev, int len, void *ptr);
/* variable size event - user memory space */
void snd_seq_ev_set_varusr(snd_seq_event_t *ev, int len, void *ptr);
/* set queue control event data */
/* destination is overwritten to Timer port (0:0) */
int snd_seq_ev_set_queue_start(snd_seq_event_t *ev, int q);
int snd_seq_ev_set_queue_stop(snd_seq_event_t *ev, int q);
int snd_seq_ev_set_queue_continue(snd_seq_event_t *ev, int q);
int snd_seq_ev_set_queue_tempo(snd_seq_event_t *ev, int q, int tempo);
int snd_seq_ev_set_queue_control(snd_seq_event_t *ev, int type, int q, int value);
int snd_seq_ev_set_queue_pos_real(snd_seq_event_t *ev, int q, snd_seq_real_time_t *rtime);
int snd_seq_ev_set_queue_pos_tick(snd_seq_event_t *ev, int q, snd_seq_tick_time_t tick);
/*
* use/unuse a queue
/**
* \brief initialize event record
* \param ev event record pointer
*/
int snd_seq_use_queue(snd_seq_t *seq, int q, int use);
#define snd_seq_ev_clear(ev) \
memset(ev, 0, sizeof(snd_seq_event_t))
/* set and send a queue control event:
* to send at scheduled time, set the schedule in ev.
* if ev is NULL, event is sent immediately (to output queue).
* Note: to send actually to driver, you need to call snd_seq_flush_event()
* apropriately.
/**
* \brief set the explicit destination
* \param ev event record
* \param c destination client id
* \param p destination port id
*/
#define snd_seq_ev_set_dest(ev,c,p) \
((ev)->dest.client = (c), (ev)->dest.port = (p))
/**
* \brief set broadcasting to subscribers
* \param ev event record
*/
#define snd_seq_ev_set_subs(ev) \
((ev)->dest.client = SND_SEQ_ADDRESS_SUBSCRIBERS,\
(ev)->dest.port = SND_SEQ_ADDRESS_UNKNOWN)
/**
* \brief set broadcasting to all clients/ports
* \param ev event record
*/
#define snd_seq_ev_set_broadcast(ev) \
((ev)->dest.client = SND_SEQ_ADDRESS_BROADCAST,\
(ev)->dest.port = SND_SEQ_ADDRESS_BROADCAST)
/**
* \brief set the source port
* \param ev event record
* \param p source port id
*/
#define snd_seq_ev_set_source(ev,p) \
((ev)->source.port = (p))
/**
* \brief set direct passing mode (without queued)
* \param ev event instance
*/
#define snd_seq_ev_set_direct(ev) \
((ev)->queue = SNDRV_SEQ_QUEUE_DIRECT)
/**
* \brief set tick-scheduling mode on queue
* \param ev event instance
* \param q queue id to schedule
* \param relative relative time-stamp if non-zero
* \param ttick tick time-stap to be delivered
*/
#define snd_seq_ev_schedule_tick(ev, q, relative, ttick) \
((ev)->flags &= ~(SNDRV_SEQ_TIME_STAMP_MASK | SNDRV_SEQ_TIME_MODE_MASK),\
(ev)->flags |= SNDRV_SEQ_TIME_STAMP_TICK,\
(ev)->flags |= (relative) ? SNDRV_SEQ_TIME_MODE_REL : SNDRV_SEQ_TIME_MODE_ABS,\
(ev)->time.tick = (ttick),\
(ev)->queue = (q))
/**
* \brief set real-time-scheduling mode on queue
* \param ev event instance
* \param q queue id to schedule
* \param relative relative time-stamp if non-zero
* \param rtime time-stamp to be delivered
*/
#define snd_seq_ev_schedule_real(ev, q, relative, rtime) \
((ev)->flags &= ~( SNDRV_SEQ_TIME_STAMP_MASK | SNDRV_SEQ_TIME_MODE_MASK),\
(ev)->flags |= SNDRV_SEQ_TIME_STAMP_REAL,\
(ev)->flags |= (relative) ? SNDRV_SEQ_TIME_MODE_REL : SNDRV_SEQ_TIME_MODE_ABS,\
(ev)->time.time = *(rtime),\
(ev)->queue = (q))
/**
* \brief set event priority
* \param ev event instance
* \param high_prior 1 for high priority mode
*/
#define snd_seq_ev_set_priority(ev, high_prior) \
((ev)->flags &= ~SNDRV_SEQ_PRIORITY_MASK,\
(ev)->flags |= (high_prior) ? SNDRV_SEQ_PRIORITY_HIGH : SNDRV_SEQ_PRIORITY_NORMAL)
/**
* \brief set fixed data
* \param ev event instance
*
* Sets the event length mode as fixed size.
*/
#define snd_seq_ev_set_fixed(ev) \
((ev)->flags &= ~SNDRV_SEQ_EVENT_LENGTH_MASK,\
(ev)->flags |= SNDRV_SEQ_EVENT_LENGTH_FIXED)
/**
* \brief set variable data
* \param ev event instance
* \param datalen length of the external data
* \param dataptr pointer of the external data
*
* Sets the event length mode as variable length and stores the data.
*/
#define snd_seq_ev_set_variable(ev, datalen, dataptr) \
((ev)->flags &= ~SNDRV_SEQ_EVENT_LENGTH_MASK,\
(ev)->flags |= SNDRV_SEQ_EVENT_LENGTH_VARIABLE,\
(ev)->data.ext.len = (datalen),\
(ev)->data.ext.ptr = (dataptr))
/**
* \brief set varusr data
* \param ev event instance
* \param len length of the external data
* \param ptr pointer of the external data
*
* Sets the event length mode as variable user-space data and stores the data.
*/
#define snd_seq_ev_set_varusr(ev, datalen, dataptr) \
((ev)->flags &= ~SNDRV_SEQ_EVENT_LENGTH_MASK,\
(ev)->flags |= SNDRV_SEQ_EVENT_LENGTH_VARUSR,\
(ev)->data.ext.len = (datalen),\
(ev)->data.ext.ptr = (dataptr))
/**
* \brief set queue controls
* \param ev event record
* \param typ event type
* \param q queue id
* \param val control value
*/
#define snd_seq_ev_set_queue_control(ev, typ, q, 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))
/**
* \brief set the start queue event
* \param ev event record
* \param q queud id to start
*/
#define snd_seq_ev_set_queue_start(ev, q) \
snd_seq_ev_set_queue_control(ev, SND_SEQ_EVENT_START, q, 0)
/**
* \brief set the stop queue event
* \param ev event record
* \param q queud id to stop
*/
#define snd_seq_ev_set_queue_stop(ev, q) \
snd_seq_ev_set_queue_control(ev, SND_SEQ_EVENT_STOP, q, 0)
/**
* \brief set the stop queue event
* \param ev event record
* \param q queud id to continue
*/
#define snd_seq_ev_set_queue_continue(ev, q) \
snd_seq_ev_set_queue_control(ev, SND_SEQ_EVENT_CONTINUE, q, 0)
/**
* \brief set the stop queue event
* \param ev event record
* \param q queud id to change tempo
* \param val the new tempo value
*/
#define snd_seq_ev_set_queue_tempo(ev, q, val) \
snd_seq_ev_set_queue_control(ev, SND_SEQ_EVENT_TEMPO, q, val)
/**
* \brief set the real-time position of a queue
* \param ev event record
* \param q queud id to change tempo
* \param rtime the new real-time pointer
*/
#define snd_seq_ev_set_queue_pos_real(ev, q, 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))
/**
* \brief set the tick-time position of a queue
* \param ev event record
* \param q queud id to change tempo
* \param ttime the new tick-time
*/
#define snd_seq_ev_set_queue_pos_tick(ev, q, 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);
int snd_seq_start_queue(snd_seq_t *seq, int q, snd_seq_event_t *ev);
int snd_seq_stop_queue(snd_seq_t *seq, int q, snd_seq_event_t *ev);
int snd_seq_continue_queue(snd_seq_t *seq, int q, snd_seq_event_t *ev);
int snd_seq_change_queue_tempo(snd_seq_t *seq, int q, int tempo, snd_seq_event_t *ev);
int snd_seq_setpos_queue(snd_seq_t *seq, int q, snd_seq_timestamp_t *rtime, snd_seq_event_t *ev);
/**
* \brief start the specified queue
* \param seq sequencer handle
* \param q queue id to start
* \param ev optional event record (see #snd_seq_control_queue)
*/
#define snd_seq_start_queue(seq, q, ev) \
snd_seq_control_queue(seq, q, SND_SEQ_EVENT_START, 0, ev)
/**
* \brief stop the specified queue
* \param seq sequencer handle
* \param q queue id to stop
* \param ev optional event record (see #snd_seq_control_queue)
*/
#define snd_seq_stop_queue(seq, q, ev) \
snd_seq_control_queue(seq, q, SND_SEQ_EVENT_STOP, 0, ev)
/**
* \brief continue the specified queue
* \param seq sequencer handle
* \param q queue id to continue
* \param ev optional event record (see #snd_seq_control_queue)
*/
#define snd_seq_continue_queue(seq, q, ev) \
snd_seq_control_queue(seq, q, SND_SEQ_EVENT_CONTINUE, 0, ev)
/**
* \brief change the tempo of the specified queue
* \param seq sequencer handle
* \param q queue id
* \param tempo the new tempo value
* \param ev optional event record (see #snd_seq_control_queue)
*/
#define snd_seq_change_queue_tempo(seq, q, tempo, 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,
@ -96,12 +265,15 @@ int snd_seq_disconnect_to(snd_seq_t *seq, int my_port, int dest_client, int dest
* set client information
*/
int snd_seq_set_client_name(snd_seq_t *seq, const char *name);
int snd_seq_set_client_group(snd_seq_t *seq, const char *name);
int snd_seq_set_client_filter(snd_seq_t *seq, unsigned int filter);
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, int size);
int snd_seq_set_client_pool_output_room(snd_seq_t *seq, int size);
int snd_seq_set_client_pool_input(snd_seq_t *seq, int size);
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);
/*
* 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
@ -109,115 +281,129 @@ int snd_seq_set_client_pool_input(snd_seq_t *seq, int size);
int snd_seq_reset_pool_output(snd_seq_t *seq);
int snd_seq_reset_pool_input(snd_seq_t *seq);
/*
* equivalent macros
/**
* \brief set note event
* \param ev event record
* \param ch channel number
* \param key note key
* \param vel velocity
* \param dur duration (in tick or msec)
*/
#define snd_seq_ev_clear(ev) memset(ev, 0, sizeof(snd_seq_event_t))
#define snd_seq_ev_set_dest(ev,c,p) \
((ev)->dest.client = (c), (ev)->dest.port = (p))
#define snd_seq_ev_set_subs(ev) \
((ev)->dest.client = SND_SEQ_ADDRESS_SUBSCRIBERS,\
(ev)->dest.port = SND_SEQ_ADDRESS_UNKNOWN)
#define snd_seq_ev_set_broadcast(ev) \
((ev)->dest.client = SND_SEQ_ADDRESS_BROADCAST,\
(ev)->dest.port = SND_SEQ_ADDRESS_BROADCAST)
#define snd_seq_ev_set_source(ev,p) ((ev)->source.port = (p))
/*
* queue controls
*/
#define snd_seq_ev_set_queue_control(ev,t,q,val) \
((ev)->type = (t),\
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))
#define snd_seq_ev_set_queue_start(ev,q) \
snd_seq_ev_set_queue_control(ev,SND_SEQ_EVENT_START,q,0)
#define snd_seq_ev_set_queue_stop(ev,q) \
snd_seq_ev_set_queue_control(ev,SND_SEQ_EVENT_STOP,q,0)
#define snd_seq_ev_set_queue_continue(ev,q) \
snd_seq_ev_set_queue_control(ev,SND_SEQ_EVENT_CONTINUE,q,0)
#define snd_seq_ev_set_queue_tempo(ev,q,val) \
snd_seq_ev_set_queue_control(ev,SND_SEQ_EVENT_TEMPO,q,val)
#define snd_seq_ev_set_queue_pos_real(ev,q,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))
#define snd_seq_ev_set_queue_pos_tick(ev,q,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))
#define snd_seq_start_queue(seq,q,ev) \
snd_seq_control_queue(seq, q, SND_SEQ_EVENT_START, 0, ev)
#define snd_seq_stop_queue(seq,q,ev) \
snd_seq_control_queue(seq, q, SND_SEQ_EVENT_STOP, 0, ev)
#define snd_seq_continue_queue(seq,q,ev) \
snd_seq_control_queue(seq, q, SND_SEQ_EVENT_CONTINUE, 0, ev)
#define snd_seq_change_queue_tempo(seq,q,tempo,ev) \
snd_seq_control_queue(seq, q, SND_SEQ_EVENT_TEMPO, tempo, ev)
/*
* macros to set standard event data
*/
#define snd_seq_ev_set_note(ev,ch,key,vel,dur) \
#define snd_seq_ev_set_note(ev, ch, key, vel, 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.dulation = (dur))
#define snd_seq_ev_set_noteon(ev,ch,key,vel) \
(ev)->data.note.duration = (dur))
/**
* \brief set note-on event
* \param ev event record
* \param ch channel number
* \param key note key
* \param vel velocity
*/
#define snd_seq_ev_set_noteon(ev, ch, key, 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))
#define snd_seq_ev_set_noteoff(ev,ch,key,vel) \
/**
* \brief set note-off event
* \param ev event record
* \param ch channel number
* \param key note key
* \param vel velocity
*/
#define snd_seq_ev_set_noteoff(ev, ch, key, 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))
/**
* \brief set key-pressure event
* \param ev event record
* \param ch channel number
* \param key note key
* \param vel velocity
*/
#define snd_seq_ev_set_keypress(ev,ch,key,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))
/**
* \brief set MIDI controller event
* \param ev event record
* \param ch channel number
* \param cc controller number
* \param val control value
*/
#define snd_seq_ev_set_controller(ev,ch,cc,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))
/**
* \brief set program change event
* \param ev event record
* \param ch channel number
* \param val program number
*/
#define snd_seq_ev_set_pgmchange(ev,ch,val) \
((ev)->type = SND_SEQ_EVENT_PGMCHANGE,\
snd_seq_ev_set_fixed(ev),\
(ev)->data.control.channel = (ch),\
(ev)->data.control.value = (val))
/**
* \brief set pitchbend event
* \param ev event record
* \param ch channel number
* \param val pitch bend; zero centered from -8192 to 8191
*/
#define snd_seq_ev_set_pitchbend(ev,ch,val) \
((ev)->type = SND_SEQ_EVENT_PITCHBEND,\
snd_seq_ev_set_fixed(ev),\
(ev)->data.control.channel = (ch),\
(ev)->data.control.value = (val))
/**
* \brief set channel pressure event
* \param ev event record
* \param ch channel number
* \param val channel pressure value
*/
#define snd_seq_ev_set_chanpress(ev,ch,val) \
((ev)->type = SND_SEQ_EVENT_CHANPRESS,\
snd_seq_ev_set_fixed(ev),\
(ev)->data.control.channel = (ch),\
(ev)->data.control.value = (val))
/**
* \brief set sysex event
* \param ev event record
* \param datalen length of sysex data
* \param dataptr sysex data pointer
*
* the sysex data must contain the start byte 0xf0 and the end byte 0xf7.
*/
#define snd_seq_ev_set_sysex(ev,datalen,dataptr) \
((ev)->type = SND_SEQ_EVENT_SYSEX,\
snd_seq_ev_set_variable(ev, datalen, dataptr))
/* etc. etc... */
/** \} */
#ifdef __cplusplus
}
#endif
/** \} */