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
* \{
*/
-/* 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
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
#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"
-/****************************************************************************
- * *
- * seq.h *
- * Sequencer *
- * *
- ****************************************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
/**
- * \defgroup Sequencer Sequencer Interface
- * Sequencer Interface
+ * \defgroup SeqGlobal Sequencer System
+ * Global System Interface
+ * \ingroup Sequencer
* \{
*/
-typedef sndrv_seq_tick_time_t snd_seq_tick_time_t;
-typedef sndrv_seq_position_t snd_seq_position_t;
-typedef sndrv_seq_frequency_t snd_seq_frequency_t;
-typedef sndrv_seq_instr_cluster_t snd_seq_instr_cluster_t;
-typedef struct sndrv_seq_port_info snd_seq_port_info_t;
-typedef struct sndrv_seq_port_subscribe snd_seq_port_subscribe_t;
-typedef struct sndrv_seq_event snd_seq_event_t;
-typedef struct sndrv_seq_addr snd_seq_addr_t;
-typedef struct sndrv_seq_ev_volume snd_seq_ev_volume_t;
-typedef struct sndrv_seq_ev_loop snd_seq_ev_loop_t;
-typedef struct sndrv_seq_remove_events snd_seq_remove_events_t;
-typedef struct sndrv_seq_query_subs snd_seq_query_subs_t;
-typedef struct sndrv_seq_real_time snd_seq_real_time_t;
-typedef struct sndrv_seq_system_info snd_seq_system_info_t;
-typedef struct sndrv_seq_client_info snd_seq_client_info_t;
-typedef struct sndrv_seq_queue_info snd_seq_queue_info_t;
-typedef struct sndrv_seq_queue_status snd_seq_queue_status_t;
-typedef struct sndrv_seq_queue_tempo snd_seq_queue_tempo_t;
-typedef struct sndrv_seq_queue_owner snd_seq_queue_owner_t;
-typedef struct sndrv_seq_queue_timer snd_seq_queue_timer_t;
-typedef struct sndrv_seq_queue_client snd_seq_queue_client_t;
-typedef struct sndrv_seq_client_pool snd_seq_client_pool_t;
-typedef struct sndrv_seq_instr snd_seq_instr_t;
-typedef struct sndrv_seq_instr_data snd_seq_instr_data_t;
-typedef struct sndrv_seq_instr_free snd_seq_instr_free_t;
-typedef struct sndrv_seq_instr_put snd_seq_instr_put_t;
-typedef struct sndrv_seq_instr_get snd_seq_instr_get_t;
-typedef union sndrv_seq_timestamp snd_seq_timestamp_t;
-
-typedef enum sndrv_seq_client_type snd_seq_client_type_t;
-typedef enum sndrv_seq_stop_mode snd_seq_stop_mode_t;
-
-#define snd_seq_event_bounce_ext_data sndrv_seq_event_bounce_ext_data
-#define snd_seq_ev_is_result_type sndrv_seq_ev_is_result_type
-#define snd_seq_ev_is_channel_type sndrv_seq_ev_is_channel_type
-#define snd_seq_ev_is_note_type sndrv_seq_ev_is_note_type
-#define snd_seq_ev_is_control_type sndrv_seq_ev_is_control_type
-#define snd_seq_ev_is_queue_type sndrv_seq_ev_is_queue_type
-#define snd_seq_ev_is_message_type sndrv_seq_ev_is_message_type
-#define snd_seq_ev_is_sample_type sndrv_seq_ev_is_sample_type
-#define snd_seq_ev_is_user_type sndrv_seq_ev_is_user_type
-#define snd_seq_ev_is_fixed_type sndrv_seq_ev_is_fixed_type
-#define snd_seq_ev_is_instr_type sndrv_seq_ev_is_instr_type
-#define snd_seq_ev_is_variable_type sndrv_seq_ev_is_variable_type
-#define snd_seq_ev_is_varipc_type sndrv_seq_ev_is_varipc_type
-#define snd_seq_ev_is_reserved sndrv_seq_ev_is_reserved
-#define snd_seq_ev_is_direct sndrv_seq_ev_is_direct
-#define snd_seq_ev_is_prior sndrv_seq_ev_is_prior
-#define snd_seq_ev_length_type sndrv_seq_ev_length_type
-#define snd_seq_ev_is_fixed sndrv_seq_ev_is_fixed
-#define snd_seq_ev_is_variable sndrv_seq_ev_is_variable
-#define snd_seq_ev_is_varusr sndrv_seq_ev_is_varusr
-#define snd_seq_ev_is_varipc sndrv_seq_ev_is_varipc
-#define snd_seq_ev_timestamp_type sndrv_seq_ev_timestamp_type
-#define snd_seq_ev_is_tick sndrv_seq_ev_is_tick
-#define snd_seq_ev_is_real sndrv_seq_ev_is_real
-#define snd_seq_ev_timemode_type sndrv_seq_ev_timemode_type
-#define snd_seq_ev_is_abstime sndrv_seq_ev_is_abstime
-#define snd_seq_ev_is_reltime sndrv_seq_ev_is_reltime
-#define snd_seq_queue_sync_port sndrv_seq_queue_sync_port
-#define snd_seq_queue_owner sndrv_seq_queue_owner
-
-#ifdef SNDRV_SEQ_SYNC_SUPPORT
-#define SND_SEQ_SYNC_SUPPORT SNDRV_SEQ_SYNC_SUPPORT
-#endif
+/** Sequencer handle */
+typedef struct _snd_seq snd_seq_t;
+
+/** \internal */
+#define SND_ALLOCA(type,ptr) \
+do {\
+ assert(ptr);\
+ *ptr = (type##_t *)alloca(type##_sizeof());\
+ memset(*ptr, 0, type##_sizeof());\
+} while (0)
-#define SND_SEQ_EVENT_SYSTEM SNDRV_SEQ_EVENT_SYSTEM
-#define SND_SEQ_EVENT_RESULT SNDRV_SEQ_EVENT_RESULT
-#define SND_SEQ_EVENT_NOTE SNDRV_SEQ_EVENT_NOTE
-#define SND_SEQ_EVENT_NOTEON SNDRV_SEQ_EVENT_NOTEON
-#define SND_SEQ_EVENT_NOTEOFF SNDRV_SEQ_EVENT_NOTEOFF
-#define SND_SEQ_EVENT_KEYPRESS SNDRV_SEQ_EVENT_KEYPRESS
-#define SND_SEQ_EVENT_CONTROLLER SNDRV_SEQ_EVENT_CONTROLLER
-#define SND_SEQ_EVENT_PGMCHANGE SNDRV_SEQ_EVENT_PGMCHANGE
-#define SND_SEQ_EVENT_CHANPRESS SNDRV_SEQ_EVENT_CHANPRESS
-#define SND_SEQ_EVENT_PITCHBEND SNDRV_SEQ_EVENT_PITCHBEND
-#define SND_SEQ_EVENT_CONTROL14 SNDRV_SEQ_EVENT_CONTROL14
-#define SND_SEQ_EVENT_NONREGPARAM SNDRV_SEQ_EVENT_NONREGPARAM
-#define SND_SEQ_EVENT_REGPARAM SNDRV_SEQ_EVENT_REGPARAM
-#define SND_SEQ_EVENT_SONGPOS SNDRV_SEQ_EVENT_SONGPOS
-#define SND_SEQ_EVENT_SONGSEL SNDRV_SEQ_EVENT_SONGSEL
-#define SND_SEQ_EVENT_QFRAME SNDRV_SEQ_EVENT_QFRAME
-#define SND_SEQ_EVENT_TIMESIGN SNDRV_SEQ_EVENT_TIMESIGN
-#define SND_SEQ_EVENT_KEYSIGN SNDRV_SEQ_EVENT_KEYSIGN
-#define SND_SEQ_EVENT_START SNDRV_SEQ_EVENT_START
-#define SND_SEQ_EVENT_CONTINUE SNDRV_SEQ_EVENT_CONTINUE
-#define SND_SEQ_EVENT_STOP SNDRV_SEQ_EVENT_STOP
-#define SND_SEQ_EVENT_SETPOS_TICK SNDRV_SEQ_EVENT_SETPOS_TICK
-#define SND_SEQ_EVENT_SETPOS_TIME SNDRV_SEQ_EVENT_SETPOS_TIME
-#define SND_SEQ_EVENT_TEMPO SNDRV_SEQ_EVENT_TEMPO
-#define SND_SEQ_EVENT_CLOCK SNDRV_SEQ_EVENT_CLOCK
-#define SND_SEQ_EVENT_TICK SNDRV_SEQ_EVENT_TICK
-#define SND_SEQ_EVENT_SYNC SNDRV_SEQ_EVENT_SYNC
-#define SND_SEQ_EVENT_SYNC_POS SNDRV_SEQ_EVENT_SYNC_POS
-#define SND_SEQ_EVENT_TUNE_REQUEST SNDRV_SEQ_EVENT_TUNE_REQUEST
-#define SND_SEQ_EVENT_RESET SNDRV_SEQ_EVENT_RESET
-#define SND_SEQ_EVENT_SENSING SNDRV_SEQ_EVENT_SENSING
-#define SND_SEQ_EVENT_ECHO SNDRV_SEQ_EVENT_ECHO
-#define SND_SEQ_EVENT_OSS SNDRV_SEQ_EVENT_OSS
-#define SND_SEQ_EVENT_CLIENT_START SNDRV_SEQ_EVENT_CLIENT_START
-#define SND_SEQ_EVENT_CLIENT_EXIT SNDRV_SEQ_EVENT_CLIENT_EXIT
-#define SND_SEQ_EVENT_CLIENT_CHANGE SNDRV_SEQ_EVENT_CLIENT_CHANGE
-#define SND_SEQ_EVENT_PORT_START SNDRV_SEQ_EVENT_PORT_START
-#define SND_SEQ_EVENT_PORT_EXIT SNDRV_SEQ_EVENT_PORT_EXIT
-#define SND_SEQ_EVENT_PORT_CHANGE SNDRV_SEQ_EVENT_PORT_CHANGE
-#define SND_SEQ_EVENT_PORT_SUBSCRIBED SNDRV_SEQ_EVENT_PORT_SUBSCRIBED
-#define SND_SEQ_EVENT_PORT_USED SNDRV_SEQ_EVENT_PORT_USED
-#define SND_SEQ_EVENT_PORT_UNSUBSCRIBED SNDRV_SEQ_EVENT_PORT_UNSUBSCRIBED
-#define SND_SEQ_EVENT_PORT_UNUSED SNDRV_SEQ_EVENT_PORT_UNUSED
-#define SND_SEQ_EVENT_SAMPLE SNDRV_SEQ_EVENT_SAMPLE
-#define SND_SEQ_EVENT_SAMPLE_CLUSTER SNDRV_SEQ_EVENT_SAMPLE_CLUSTER
-#define SND_SEQ_EVENT_SAMPLE_START SNDRV_SEQ_EVENT_SAMPLE_START
-#define SND_SEQ_EVENT_SAMPLE_STOP SNDRV_SEQ_EVENT_SAMPLE_STOP
-#define SND_SEQ_EVENT_SAMPLE_FREQ SNDRV_SEQ_EVENT_SAMPLE_FREQ
-#define SND_SEQ_EVENT_SAMPLE_VOLUME SNDRV_SEQ_EVENT_SAMPLE_VOLUME
-#define SND_SEQ_EVENT_SAMPLE_LOOP SNDRV_SEQ_EVENT_SAMPLE_LOOP
-#define SND_SEQ_EVENT_SAMPLE_POSITION SNDRV_SEQ_EVENT_SAMPLE_POSITION
-#define SND_SEQ_EVENT_SAMPLE_PRIVATE1 SNDRV_SEQ_EVENT_SAMPLE_PRIVATE1
-#define SND_SEQ_EVENT_USR0 SNDRV_SEQ_EVENT_USR0
-#define SND_SEQ_EVENT_USR1 SNDRV_SEQ_EVENT_USR1
-#define SND_SEQ_EVENT_USR2 SNDRV_SEQ_EVENT_USR2
-#define SND_SEQ_EVENT_USR3 SNDRV_SEQ_EVENT_USR3
-#define SND_SEQ_EVENT_USR4 SNDRV_SEQ_EVENT_USR4
-#define SND_SEQ_EVENT_USR5 SNDRV_SEQ_EVENT_USR5
-#define SND_SEQ_EVENT_USR6 SNDRV_SEQ_EVENT_USR6
-#define SND_SEQ_EVENT_USR7 SNDRV_SEQ_EVENT_USR7
-#define SND_SEQ_EVENT_USR8 SNDRV_SEQ_EVENT_USR8
-#define SND_SEQ_EVENT_USR9 SNDRV_SEQ_EVENT_USR9
-#define SND_SEQ_EVENT_INSTR_BEGIN SNDRV_SEQ_EVENT_INSTR_BEGIN
-#define SND_SEQ_EVENT_INSTR_END SNDRV_SEQ_EVENT_INSTR_END
-#define SND_SEQ_EVENT_INSTR_INFO SNDRV_SEQ_EVENT_INSTR_INFO
-#define SND_SEQ_EVENT_INSTR_INFO_RESULT SNDRV_SEQ_EVENT_INSTR_INFO_RESULT
-#define SND_SEQ_EVENT_INSTR_FINFO SNDRV_SEQ_EVENT_INSTR_FINFO
-#define SND_SEQ_EVENT_INSTR_FINFO_RESULT SNDRV_SEQ_EVENT_INSTR_FINFO_RESULT
-#define SND_SEQ_EVENT_INSTR_RESET SNDRV_SEQ_EVENT_INSTR_RESET
-#define SND_SEQ_EVENT_INSTR_STATUS SNDRV_SEQ_EVENT_INSTR_STATUS
-#define SND_SEQ_EVENT_INSTR_STATUS_RESULT SNDRV_SEQ_EVENT_INSTR_STATUS_RESULT
-#define SND_SEQ_EVENT_INSTR_PUT SNDRV_SEQ_EVENT_INSTR_PUT
-#define SND_SEQ_EVENT_INSTR_GET SNDRV_SEQ_EVENT_INSTR_GET
-#define SND_SEQ_EVENT_INSTR_GET_RESULT SNDRV_SEQ_EVENT_INSTR_GET_RESULT
-#define SND_SEQ_EVENT_INSTR_FREE SNDRV_SEQ_EVENT_INSTR_FREE
-#define SND_SEQ_EVENT_INSTR_LIST SNDRV_SEQ_EVENT_INSTR_LIST
-#define SND_SEQ_EVENT_INSTR_LIST_RESULT SNDRV_SEQ_EVENT_INSTR_LIST_RESULT
-#define SND_SEQ_EVENT_INSTR_CLUSTER SNDRV_SEQ_EVENT_INSTR_CLUSTER
-#define SND_SEQ_EVENT_INSTR_CLUSTER_GET SNDRV_SEQ_EVENT_INSTR_CLUSTER_GET
-#define SND_SEQ_EVENT_INSTR_CLUSTER_RESULT SNDRV_SEQ_EVENT_INSTR_CLUSTER_RESULT
-#define SND_SEQ_EVENT_INSTR_CHANGE SNDRV_SEQ_EVENT_INSTR_CHANGE
-#define SND_SEQ_EVENT_LENGTH_VARIABLE SNDRV_SEQ_EVENT_LENGTH_VARIABLE
-#define SND_SEQ_EVENT_SYSEX SNDRV_SEQ_EVENT_SYSEX
-#define SND_SEQ_EVENT_BOUNCE SNDRV_SEQ_EVENT_BOUNCE
-#define SND_SEQ_EVENT_USR_VAR0 SNDRV_SEQ_EVENT_USR_VAR0
-#define SND_SEQ_EVENT_USR_VAR1 SNDRV_SEQ_EVENT_USR_VAR1
-#define SND_SEQ_EVENT_USR_VAR2 SNDRV_SEQ_EVENT_USR_VAR2
-#define SND_SEQ_EVENT_USR_VAR3 SNDRV_SEQ_EVENT_USR_VAR3
-#define SND_SEQ_EVENT_USR_VAR4 SNDRV_SEQ_EVENT_USR_VAR4
-#define SND_SEQ_EVENT_LENGTH_VARIPC SNDRV_SEQ_EVENT_LENGTH_VARIPC
-#define SND_SEQ_EVENT_IPCSHM SNDRV_SEQ_EVENT_IPCSHM
-#define SND_SEQ_EVENT_USR_VARIPC0 SNDRV_SEQ_EVENT_USR_VARIPC0
-#define SND_SEQ_EVENT_USR_VARIPC1 SNDRV_SEQ_EVENT_USR_VARIPC1
-#define SND_SEQ_EVENT_USR_VARIPC2 SNDRV_SEQ_EVENT_USR_VARIPC2
-#define SND_SEQ_EVENT_USR_VARIPC3 SNDRV_SEQ_EVENT_USR_VARIPC3
-#define SND_SEQ_EVENT_USR_VARIPC4 SNDRV_SEQ_EVENT_USR_VARIPC4
-#define SND_SEQ_EVENT_KERNEL_ERROR SNDRV_SEQ_EVENT_KERNEL_ERROR
-#define SND_SEQ_EVENT_KERNEL_QUOTE SNDRV_SEQ_EVENT_KERNEL_QUOTE
-#define SND_SEQ_EVENT_NONE SNDRV_SEQ_EVENT_NONE
-#define SND_SEQ_ADDRESS_UNKNOWN SNDRV_SEQ_ADDRESS_UNKNOWN
-#define SND_SEQ_ADDRESS_SUBSCRIBERS SNDRV_SEQ_ADDRESS_SUBSCRIBERS
-#define SND_SEQ_ADDRESS_BROADCAST SNDRV_SEQ_ADDRESS_BROADCAST
-#define SND_SEQ_QUEUE_DIRECT SNDRV_SEQ_QUEUE_DIRECT
-#define SND_SEQ_TIME_STAMP_TICK SNDRV_SEQ_TIME_STAMP_TICK
-#define SND_SEQ_TIME_STAMP_REAL SNDRV_SEQ_TIME_STAMP_REAL
-#define SND_SEQ_TIME_STAMP_MASK SNDRV_SEQ_TIME_STAMP_MASK
-#define SND_SEQ_TIME_MODE_ABS SNDRV_SEQ_TIME_MODE_ABS
-#define SND_SEQ_TIME_MODE_REL SNDRV_SEQ_TIME_MODE_REL
-#define SND_SEQ_TIME_MODE_MASK SNDRV_SEQ_TIME_MODE_MASK
-#define SND_SEQ_EVENT_LENGTH_FIXED SNDRV_SEQ_EVENT_LENGTH_FIXED
-#define SND_SEQ_EVENT_LENGTH_VARIABLE SNDRV_SEQ_EVENT_LENGTH_VARIABLE
-#define SND_SEQ_EVENT_LENGTH_VARUSR SNDRV_SEQ_EVENT_LENGTH_VARUSR
-#define SND_SEQ_EVENT_LENGTH_VARIPC SNDRV_SEQ_EVENT_LENGTH_VARIPC
-#define SND_SEQ_EVENT_LENGTH_MASK SNDRV_SEQ_EVENT_LENGTH_MASK
-#define SND_SEQ_PRIORITY_NORMAL SNDRV_SEQ_PRIORITY_NORMAL
-#define SND_SEQ_PRIORITY_HIGH SNDRV_SEQ_PRIORITY_HIGH
-#define SND_SEQ_PRIORITY_MASK SNDRV_SEQ_PRIORITY_MASK
-#define SND_SEQ_EVENT_NOTE SNDRV_SEQ_EVENT_NOTE
-#define SND_SEQ_EVENT_NOTE SNDRV_SEQ_EVENT_NOTE
-#define SND_SEQ_QUEUE_DIRECT SNDRV_SEQ_QUEUE_DIRECT
-#define SND_SEQ_PRIORITY_MASK SNDRV_SEQ_PRIORITY_MASK
-#define SND_SEQ_EVENT_LENGTH_MASK SNDRV_SEQ_EVENT_LENGTH_MASK
-#define SND_SEQ_EVENT_LENGTH_FIXED SNDRV_SEQ_EVENT_LENGTH_FIXED
-#define SND_SEQ_EVENT_LENGTH_VARIABLE SNDRV_SEQ_EVENT_LENGTH_VARIABLE
-#define SND_SEQ_EVENT_LENGTH_VARUSR SNDRV_SEQ_EVENT_LENGTH_VARUSR
-#define SND_SEQ_EVENT_LENGTH_VARIPC SNDRV_SEQ_EVENT_LENGTH_VARIPC
-#define SND_SEQ_TIME_STAMP_MASK SNDRV_SEQ_TIME_STAMP_MASK
-#define SND_SEQ_TIME_STAMP_TICK SNDRV_SEQ_TIME_STAMP_TICK
-#define SND_SEQ_TIME_STAMP_REAL SNDRV_SEQ_TIME_STAMP_REAL
-#define SND_SEQ_TIME_MODE_MASK SNDRV_SEQ_TIME_MODE_MASK
-#define SND_SEQ_TIME_MODE_ABS SNDRV_SEQ_TIME_MODE_ABS
-#define SND_SEQ_TIME_MODE_REL SNDRV_SEQ_TIME_MODE_REL
-#define SND_SEQ_CLIENT_SYSTEM SNDRV_SEQ_CLIENT_SYSTEM
-#define SND_SEQ_CLIENT_DUMMY SNDRV_SEQ_CLIENT_DUMMY
-#define SND_SEQ_CLIENT_OSS SNDRV_SEQ_CLIENT_OSS
-#define SND_SEQ_FILTER_BROADCAST SNDRV_SEQ_FILTER_BROADCAST
-#define SND_SEQ_FILTER_MULTICAST SNDRV_SEQ_FILTER_MULTICAST
-#define SND_SEQ_FILTER_BOUNCE SNDRV_SEQ_FILTER_BOUNCE
-#define SND_SEQ_FILTER_USE_EVENT SNDRV_SEQ_FILTER_USE_EVENT
-#define SND_SEQ_REMOVE_DEST SNDRV_SEQ_REMOVE_DEST
-#define SND_SEQ_REMOVE_DEST_CHANNEL SNDRV_SEQ_REMOVE_DEST_CHANNEL
-#define SND_SEQ_REMOVE_TIME_BEFORE SNDRV_SEQ_REMOVE_TIME_BEFORE
-#define SND_SEQ_REMOVE_TIME_AFTER SNDRV_SEQ_REMOVE_TIME_AFTER
-#define SND_SEQ_REMOVE_EVENT_TYPE SNDRV_SEQ_REMOVE_EVENT_TYPE
-#define SND_SEQ_REMOVE_IGNORE_OFF SNDRV_SEQ_REMOVE_IGNORE_OFF
-#define SND_SEQ_REMOVE_TAG_MATCH SNDRV_SEQ_REMOVE_TAG_MATCH
-#define SND_SEQ_PORT_SYSTEM_TIMER SNDRV_SEQ_PORT_SYSTEM_TIMER
-#define SND_SEQ_PORT_SYSTEM_ANNOUNCE SNDRV_SEQ_PORT_SYSTEM_ANNOUNCE
-#define SND_SEQ_PORT_CAP_READ SNDRV_SEQ_PORT_CAP_READ
-#define SND_SEQ_PORT_CAP_WRITE SNDRV_SEQ_PORT_CAP_WRITE
-#define SND_SEQ_PORT_CAP_SYNC_READ SNDRV_SEQ_PORT_CAP_SYNC_READ
-#define SND_SEQ_PORT_CAP_SYNC_WRITE SNDRV_SEQ_PORT_CAP_SYNC_WRITE
-#define SND_SEQ_PORT_CAP_DUPLEX SNDRV_SEQ_PORT_CAP_DUPLEX
-#define SND_SEQ_PORT_CAP_SUBS_READ SNDRV_SEQ_PORT_CAP_SUBS_READ
-#define SND_SEQ_PORT_CAP_SUBS_WRITE SNDRV_SEQ_PORT_CAP_SUBS_WRITE
-#define SND_SEQ_PORT_CAP_NO_EXPORT SNDRV_SEQ_PORT_CAP_NO_EXPORT
-#define SND_SEQ_PORT_TYPE_SPECIFIC SNDRV_SEQ_PORT_TYPE_SPECIFIC
-#define SND_SEQ_PORT_TYPE_MIDI_GENERIC SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC
-#define SND_SEQ_PORT_TYPE_MIDI_GM SNDRV_SEQ_PORT_TYPE_MIDI_GM
-#define SND_SEQ_PORT_TYPE_MIDI_GS SNDRV_SEQ_PORT_TYPE_MIDI_GS
-#define SND_SEQ_PORT_TYPE_MIDI_XG SNDRV_SEQ_PORT_TYPE_MIDI_XG
-#define SND_SEQ_PORT_TYPE_MIDI_MT32 SNDRV_SEQ_PORT_TYPE_MIDI_MT32
-#define SND_SEQ_PORT_TYPE_SYNTH SNDRV_SEQ_PORT_TYPE_SYNTH
-#define SND_SEQ_PORT_TYPE_DIRECT_SAMPLE SNDRV_SEQ_PORT_TYPE_DIRECT_SAMPLE
-#define SND_SEQ_PORT_TYPE_SAMPLE SNDRV_SEQ_PORT_TYPE_SAMPLE
-#define SND_SEQ_PORT_TYPE_APPLICATION SNDRV_SEQ_PORT_TYPE_APPLICATION
-#define SND_SEQ_GROUP_SYSTEM SNDRV_SEQ_GROUP_SYSTEM
-#define SND_SEQ_GROUP_DEVICE SNDRV_SEQ_GROUP_DEVICE
-#define SND_SEQ_GROUP_APPLICATION SNDRV_SEQ_GROUP_APPLICATION
-#define SND_SEQ_PORT_FLG_GIVEN_PORT SNDRV_SEQ_PORT_FLG_GIVEN_PORT
-#define SND_SEQ_QUEUE_FLG_SYNC SNDRV_SEQ_QUEUE_FLG_SYNC
-#define SND_SEQ_QUEUE_FLG_SYNC_LOST SNDRV_SEQ_QUEUE_FLG_SYNC_LOST
-#define SND_SEQ_SYNC_TICK SNDRV_SEQ_SYNC_TICK
-#define SND_SEQ_SYNC_TIME SNDRV_SEQ_SYNC_TIME
-#define SND_SEQ_SYNC_MODE SNDRV_SEQ_SYNC_MODE
-#define SND_SEQ_SYNC_FMT_PRIVATE_CLOCK SNDRV_SEQ_SYNC_FMT_PRIVATE_CLOCK
-#define SND_SEQ_SYNC_FMT_PRIVATE_TIME SNDRV_SEQ_SYNC_FMT_PRIVATE_TIME
-#define SND_SEQ_SYNC_FMT_MIDI_CLOCK SNDRV_SEQ_SYNC_FMT_MIDI_CLOCK
-#define SND_SEQ_SYNC_FMT_MTC SNDRV_SEQ_SYNC_FMT_MTC
-#define SND_SEQ_SYNC_FMT_DTL SNDRV_SEQ_SYNC_FMT_DTL
-#define SND_SEQ_SYNC_FMT_SMPTE SNDRV_SEQ_SYNC_FMT_SMPTE
-#define SND_SEQ_SYNC_FMT_MIDI_TICK SNDRV_SEQ_SYNC_FMT_MIDI_TICK
-#define SND_SEQ_SYNC_FPS_24 SNDRV_SEQ_SYNC_FPS_24
-#define SND_SEQ_SYNC_FPS_25 SNDRV_SEQ_SYNC_FPS_25
-#define SND_SEQ_SYNC_FPS_30_DP SNDRV_SEQ_SYNC_FPS_30_DP
-#define SND_SEQ_SYNC_FPS_30_NDP SNDRV_SEQ_SYNC_FPS_30_NDP
-#define SND_SEQ_TIMER_ALSA SNDRV_SEQ_TIMER_ALSA
-#define SND_SEQ_TIMER_MIDI_CLOCK SNDRV_SEQ_TIMER_MIDI_CLOCK
-#define SND_SEQ_TIMER_MIDI_TICK SNDRV_SEQ_TIMER_MIDI_TICK
-#define SND_SEQ_QUERY_SUBS_READ SNDRV_SEQ_QUERY_SUBS_READ
-#define SND_SEQ_QUERY_SUBS_WRITE SNDRV_SEQ_QUERY_SUBS_WRITE
-#define SND_SEQ_INSTR_ATYPE_DATA SNDRV_SEQ_INSTR_ATYPE_DATA
-#define SND_SEQ_INSTR_ATYPE_ALIAS SNDRV_SEQ_INSTR_ATYPE_ALIAS
-#define SND_SEQ_INSTR_ID_DLS1 SNDRV_SEQ_INSTR_ID_DLS1
-#define SND_SEQ_INSTR_ID_DLS2 SNDRV_SEQ_INSTR_ID_DLS2
-#define SND_SEQ_INSTR_ID_SIMPLE SNDRV_SEQ_INSTR_ID_SIMPLE
-#define SND_SEQ_INSTR_ID_SOUNDFONT SNDRV_SEQ_INSTR_ID_SOUNDFONT
-#define SND_SEQ_INSTR_ID_GUS_PATCH SNDRV_SEQ_INSTR_ID_GUS_PATCH
-#define SND_SEQ_INSTR_ID_INTERWAVE SNDRV_SEQ_INSTR_ID_INTERWAVE
-#define SND_SEQ_INSTR_ID_OPL2_3 SNDRV_SEQ_INSTR_ID_OPL2_3
-#define SND_SEQ_INSTR_ID_OPL4 SNDRV_SEQ_INSTR_ID_OPL4
-#define SND_SEQ_INSTR_TYPE0_DLS1 SNDRV_SEQ_INSTR_TYPE0_DLS1
-#define SND_SEQ_INSTR_TYPE0_DLS2 SNDRV_SEQ_INSTR_TYPE0_DLS2
-#define SND_SEQ_INSTR_TYPE1_SIMPLE SNDRV_SEQ_INSTR_TYPE1_SIMPLE
-#define SND_SEQ_INSTR_TYPE1_SOUNDFONT SNDRV_SEQ_INSTR_TYPE1_SOUNDFONT
-#define SND_SEQ_INSTR_TYPE1_GUS_PATCH SNDRV_SEQ_INSTR_TYPE1_GUS_PATCH
-#define SND_SEQ_INSTR_TYPE1_INTERWAVE SNDRV_SEQ_INSTR_TYPE1_INTERWAVE
-#define SND_SEQ_INSTR_TYPE2_OPL2_3 SNDRV_SEQ_INSTR_TYPE2_OPL2_3
-#define SND_SEQ_INSTR_TYPE2_OPL4 SNDRV_SEQ_INSTR_TYPE2_OPL4
-#define SND_SEQ_INSTR_PUT_CMD_CREATE SNDRV_SEQ_INSTR_PUT_CMD_CREATE
-#define SND_SEQ_INSTR_PUT_CMD_REPLACE SNDRV_SEQ_INSTR_PUT_CMD_REPLACE
-#define SND_SEQ_INSTR_PUT_CMD_MODIFY SNDRV_SEQ_INSTR_PUT_CMD_MODIFY
-#define SND_SEQ_INSTR_PUT_CMD_ADD SNDRV_SEQ_INSTR_PUT_CMD_ADD
-#define SND_SEQ_INSTR_PUT_CMD_REMOVE SNDRV_SEQ_INSTR_PUT_CMD_REMOVE
-#define SND_SEQ_INSTR_GET_CMD_FULL SNDRV_SEQ_INSTR_GET_CMD_FULL
-#define SND_SEQ_INSTR_GET_CMD_PARTIAL SNDRV_SEQ_INSTR_GET_CMD_PARTIAL
-#define SND_SEQ_INSTR_QUERY_FOLLOW_ALIAS SNDRV_SEQ_INSTR_QUERY_FOLLOW_ALIAS
-#define SND_SEQ_INSTR_FREE_CMD_ALL SNDRV_SEQ_INSTR_FREE_CMD_ALL
-#define SND_SEQ_INSTR_FREE_CMD_PRIVATE SNDRV_SEQ_INSTR_FREE_CMD_PRIVATE
-#define SND_SEQ_INSTR_FREE_CMD_CLUSTER SNDRV_SEQ_INSTR_FREE_CMD_CLUSTER
-#define SND_SEQ_INSTR_FREE_CMD_SINGLE SNDRV_SEQ_INSTR_FREE_CMD_SINGLE
-
-
-#define SND_SEQ_OPEN_OUTPUT 1
-#define SND_SEQ_OPEN_INPUT 2
-#define SND_SEQ_OPEN_DUPLEX (SND_SEQ_OPEN_OUTPUT|SND_SEQ_OPEN_INPUT)
-
-#define SND_SEQ_NONBLOCK 1
+/**
+ * sequencer opening stream types
+ */
+#define SND_SEQ_OPEN_OUTPUT 1 /**< open for output (write) */
+#define SND_SEQ_OPEN_INPUT 2 /**< open for input (read) */
+#define SND_SEQ_OPEN_DUPLEX (SND_SEQ_OPEN_OUTPUT|SND_SEQ_OPEN_INPUT) /**< open for both input and output (read/write) */
+
+/**
+ * sequencer opening mode
+ */
+#define SND_SEQ_NONBLOCK 1 /**< non-blocking mode */
typedef enum _snd_seq_type {
- SND_SEQ_TYPE_HW,
- SND_SEQ_TYPE_SHM,
- SND_SEQ_TYPE_INET,
+ SND_SEQ_TYPE_HW, /**< hardware */
+ SND_SEQ_TYPE_SHM, /**< shared memory (NYI) */
+ SND_SEQ_TYPE_INET, /**< network (NYI) */
} snd_seq_type_t;
-/* Sequencer handle */
-typedef struct _snd_seq snd_seq_t;
+/** special client (port) ids */
+#define SND_SEQ_ADDRESS_UNKNOWN 253 /**< unknown source */
+#define SND_SEQ_ADDRESS_SUBSCRIBERS 254 /**< send event to all subscribed ports */
+#define SND_SEQ_ADDRESS_BROADCAST 255 /**< send event to all queues/clients/ports/channels */
-#ifdef __cplusplus
-extern "C" {
-#endif
+/** known client numbers */
+#define SND_SEQ_CLIENT_SYSTEM 0 /**< system client */
+#define SND_SEQ_CLIENT_DUMMY 62 /**< dummy ports */
+#define SND_SEQ_CLIENT_OSS 63 /**< oss sequencer emulator */
+/*
+ */
int snd_seq_open(snd_seq_t **handle, const char *name, int streams, int mode);
+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, struct pollfd *pfds, unsigned int space, short events);
int snd_seq_nonblock(snd_seq_t *handle, int nonblock);
int snd_seq_client_id(snd_seq_t *handle);
-int snd_seq_output_buffer_size(snd_seq_t *handle);
-int snd_seq_input_buffer_size(snd_seq_t *handle);
-int snd_seq_resize_output_buffer(snd_seq_t *handle, size_t size);
-int snd_seq_resize_input_buffer(snd_seq_t *handle, size_t size);
+
+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 */
+typedef struct _snd_seq_system_info snd_seq_system_info_t;
+
+size_t snd_seq_system_info_sizeof(void);
+/** allocate a system_info container in heap */
+#define snd_seq_system_info_alloca(ptr) \
+ SND_ALLOCA(snd_seq_system_info, ptr)
+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(snd_seq_t *handle, snd_seq_system_info_t *info);
+
+/** \} */
+
+
+/**
+ * \defgroup SeqClient Sequencer Client Interface
+ * Sequencer Client Interface
+ * \ingroup Sequencer
+ * \{
+ */
+
+/** client information container */
+typedef struct _snd_seq_client_info snd_seq_client_info_t;
+
+/** client types */
+typedef enum snd_seq_client_type {
+ SND_SEQ_USER_CLIENT = 1, /**< user client */
+ SND_SEQ_KERNEL_CLIENT = 2 /**< kernel client */
+} snd_seq_client_type_t;
+
+size_t snd_seq_client_info_sizeof(void);
+/** allocate a client_info container in heap */
+#define snd_seq_client_info_alloca(ptr) \
+ SND_ALLOCA(snd_seq_client_info, ptr)
+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);
+const unsigned char *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 bool);
+void snd_seq_client_info_set_error_bounce(snd_seq_client_info_t *info, int bool);
+void snd_seq_client_info_set_event_filter(snd_seq_client_info_t *info, unsigned char *filter);
+
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 */
+typedef struct _snd_seq_client_pool snd_seq_client_pool_t;
+
+size_t snd_seq_client_pool_sizeof(void);
+/** allocate a client_pool container in heap */
+#define snd_seq_client_pool_alloca(ptr) \
+ SND_ALLOCA(snd_seq_client_pool, ptr)
+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);
+
+
+/** \} */
+
+
+/**
+ * \defgroup SeqPort Sequencer Port Interface
+ * Sequencer Port Interface
+ * \ingroup Sequencer
+ * \{
+ */
+
+/** port information container */
+typedef struct _snd_seq_port_info snd_seq_port_info_t;
+
+/** known port numbers */
+#define SND_SEQ_PORT_SYSTEM_TIMER 0 /**< system timer port */
+#define SND_SEQ_PORT_SYSTEM_ANNOUNCE 1 /**< sysem announce port */
+
+/** port capabilities (32 bits) */
+#define SND_SEQ_PORT_CAP_READ (1<<0) /**< readable from this port */
+#define SND_SEQ_PORT_CAP_WRITE (1<<1) /**< writable to this port */
+
+#define SND_SEQ_PORT_CAP_SYNC_READ (1<<2) /**< allow read subscriptions */
+#define SND_SEQ_PORT_CAP_SYNC_WRITE (1<<3) /**< allow write subscriptions */
+
+#define SND_SEQ_PORT_CAP_DUPLEX (1<<4) /**< allow read/write duplex */
+
+#define SND_SEQ_PORT_CAP_SUBS_READ (1<<5) /**< allow read subscription */
+#define SND_SEQ_PORT_CAP_SUBS_WRITE (1<<6) /**< allow write subscription */
+#define SND_SEQ_PORT_CAP_NO_EXPORT (1<<7) /**< routing not allowed */
+
+/** port type */
+#define SND_SEQ_PORT_TYPE_SPECIFIC (1<<0) /**< hardware specific */
+#define SND_SEQ_PORT_TYPE_MIDI_GENERIC (1<<1) /**< generic MIDI device */
+#define SND_SEQ_PORT_TYPE_MIDI_GM (1<<2) /**< General MIDI compatible device */
+#define SND_SEQ_PORT_TYPE_MIDI_GS (1<<3) /**< GS compatible device */
+#define SND_SEQ_PORT_TYPE_MIDI_XG (1<<4) /**< XG compatible device */
+#define SND_SEQ_PORT_TYPE_MIDI_MT32 (1<<5) /**< MT-32 compatible device */
+#define SND_SEQ_PORT_TYPE_SYNTH (1<<10) /**< Synth device */
+#define SND_SEQ_PORT_TYPE_DIRECT_SAMPLE (1<<11) /**< Sampling device (support sample download) */
+#define SND_SEQ_PORT_TYPE_SAMPLE (1<<12) /**< Sampling device (sample can be downloaded at any time) */
+#define SND_SEQ_PORT_TYPE_APPLICATION (1<<20) /**< application (sequencer/editor) */
+
+
+size_t snd_seq_port_info_sizeof(void);
+/** allocate a port_info container in heap */
+#define snd_seq_port_info_alloca(ptr) \
+ SND_ALLOCA(snd_seq_port_info, ptr)
+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);
+unsigned int snd_seq_port_info_get_capability(const snd_seq_port_info_t *info);
+unsigned int 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);
+
+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, unsigned int capability);
+void snd_seq_port_info_set_type(snd_seq_port_info_t *info, unsigned int 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 bool);
+
int snd_seq_create_port(snd_seq_t *handle, snd_seq_port_info_t *info);
-int snd_seq_delete_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);
+
+/** \} */
+
+
+/**
+ * \defgroup SeqSubscribe Sequencer Port Subscription
+ * Sequencer Port Subscription
+ * \ingroup Sequencer
+ * \{
+ */
+
+/** port subscription container */
+typedef struct _snd_seq_port_subscribe snd_seq_port_subscribe_t;
+
+size_t snd_seq_port_subscribe_sizeof(void);
+/** allocate a port_subscribe container in heap */
+#define snd_seq_port_subscribe_alloca(ptr) \
+ SND_ALLOCA(snd_seq_port_subscribe, ptr)
+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 bool);
+void snd_seq_port_subscribe_set_time_update(snd_seq_port_subscribe_t *info, int bool);
+void snd_seq_port_subscribe_set_time_real(snd_seq_port_subscribe_t *info, int bool);
+
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);
-int snd_seq_query_port_subscribers(snd_seq_t *seq, snd_seq_query_subs_t * subs);
-int snd_seq_get_queue_status(snd_seq_t *handle, int q, snd_seq_queue_status_t *status);
-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);
-int snd_seq_get_queue_owner(snd_seq_t *handle, int q, snd_seq_queue_owner_t *owner);
-int snd_seq_set_queue_owner(snd_seq_t *handle, int q, snd_seq_queue_owner_t *owner);
-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);
-int snd_seq_get_queue_client(snd_seq_t *handle, int q, snd_seq_queue_client_t *queue);
-int snd_seq_set_queue_client(snd_seq_t *handle, int q, snd_seq_queue_client_t *queue);
+
+/*
+ */
+
+/** subscription query container */
+typedef struct _snd_seq_query_subscribe snd_seq_query_subscribe_t;
+
+/** type of query subscription */
+typedef enum {
+ SND_SEQ_QUERY_SUBS_READ, /**< query read subscriptions */
+ SND_SEQ_QUERY_SUBS_WRITE /**< query write subscriptions */
+} snd_seq_query_subs_type_t;
+
+size_t snd_seq_query_subscribe_sizeof(void);
+/** allocate a query_subscribe container in heap */
+#define snd_seq_query_subscribe_alloca(ptr) \
+ SND_ALLOCA(snd_seq_query_subscribe, ptr)
+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);
+
+/** \} */
+
+
+/**
+ * \defgroup SeqQueue Sequencer Queue Interface
+ * Sequencer Queue Interface
+ * \ingroup Sequencer
+ * \{
+ */
+
+/** queue information container */
+typedef struct _snd_seq_queue_info snd_seq_queue_info_t;
+/** queue status container */
+typedef struct _snd_seq_queue_status snd_seq_queue_status_t;
+/** queue tempo container */
+typedef struct _snd_seq_queue_tempo snd_seq_queue_tempo_t;
+/** queue timer information container */
+typedef struct _snd_seq_queue_timer snd_seq_queue_timer_t;
+
+/** special queue ids */
+#define SND_SEQ_QUEUE_DIRECT 253 /**< direct dispatch */
+
+size_t snd_seq_queue_info_sizeof(void);
+/** allocate a queue_info container in heap */
+#define snd_seq_queue_info_alloca(ptr) \
+ SND_ALLOCA(snd_seq_queue_info, ptr)
+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);
+unsigned int 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, unsigned int 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);
-#ifdef SND_SEQ_SYNC_SUPPORT
-int snd_seq_alloc_sync_queue(snd_seq_t *seq, const char *name);
-#endif
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_get_named_queue(snd_seq_t *seq, const char *name);
-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);
-int snd_seq_query_next_client(snd_seq_t *handle, snd_seq_client_info_t * info);
-int snd_seq_query_next_port(snd_seq_t *handle, snd_seq_port_info_t * info);
-#ifdef SND_SEQ_SYNC_SUPPORT
-typedef struct sndrv_seq_queue_sync snd_seq_queue_sync_t;
-int snd_seq_add_sync_master(snd_seq_t *seq, int queue, snd_seq_addr_t *dest, snd_seq_queue_sync_t *info);
-int snd_seq_remove_sync_master(snd_seq_t *seq, int queue, snd_seq_addr_t *dest);
-int snd_seq_add_sync_std_master(snd_seq_t *seq, int queue, snd_seq_addr_t *dest, int format, int time_format, unsigned char *opt_info);
-#define snd_seq_add_sync_master_clock(seq,q,dest) snd_seq_add_sync_std_master(seq, q, dest, SND_SEQ_SYNC_FMT_MIDI_CLOCK, 0, 0)
-#define snd_seq_add_sync_master_mtc(seq,q,dest,tfmt) snd_seq_add_sync_std_master(seq, q, dest, SND_SEQ_SYNC_FMT_MTC, tfmt, 0)
-
-int snd_seq_set_sync_slave(snd_seq_t *seq, int queue, snd_seq_addr_t *src, snd_seq_queue_sync_t *info);
-int snd_seq_reset_sync_slave(snd_seq_t *seq, int queue, snd_seq_addr_t *src);
-#endif
+int snd_seq_query_named_queue(snd_seq_t *seq, const char *name);
-const char *snd_seq_name(snd_seq_t *seq);
-snd_seq_type_t snd_seq_type(snd_seq_t *seq);
+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(void);
+/** allocate a queue_status container in heap */
+#define snd_seq_queue_status_alloca(ptr) \
+ SND_ALLOCA(snd_seq_queue_status, ptr)
+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);
+unsigned int 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(void);
+/** allocate a queue_tempo container in heap */
+#define snd_seq_queue_tempo_alloca(ptr) \
+ SND_ALLOCA(snd_seq_queue_tempo, ptr)
+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);
+unsigned int 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);
+void snd_seq_queue_tempo_set_tempo(snd_seq_queue_tempo_t *info, unsigned int tempo);
+void snd_seq_queue_tempo_set_ppq(snd_seq_queue_tempo_t *info, int ppq);
+
+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);
+
+/*
+ */
+size_t snd_seq_queue_timer_sizeof(void);
+/** allocate a queue_timer container in heap */
+#define snd_seq_queue_timer_alloca(ptr) \
+ SND_ALLOCA(snd_seq_queue_timer, ptr)
+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);
+int 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);
+unsigned int 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, int 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, unsigned int 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);
+
+/** \} */
+
+/**
+ * \defgroup SeqEvent Sequencer Event API
+ * Sequencer Event API
+ * \ingroup Sequencer
+ * \{
+ */
-/* event routines */
snd_seq_event_t *snd_seq_create_event(void);
int snd_seq_free_event(snd_seq_event_t *ev);
ssize_t snd_seq_event_length(snd_seq_event_t *ev);
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 */
+typedef struct _snd_seq_remove_events snd_seq_remove_events_t;
+
+/** Remove conditional flags */
+#define SND_SEQ_REMOVE_INPUT (1<<0) /**< Flush input queues */
+#define SND_SEQ_REMOVE_OUTPUT (1<<1) /**< Flush output queues */
+#define SND_SEQ_REMOVE_DEST (1<<2) /**< Restrict by destination q:client:port */
+#define SND_SEQ_REMOVE_DEST_CHANNEL (1<<3) /**< Restrict by channel */
+#define SND_SEQ_REMOVE_TIME_BEFORE (1<<4) /**< Restrict to before time */
+#define SND_SEQ_REMOVE_TIME_AFTER (1<<5) /**< Restrict to time or after */
+#define SND_SEQ_REMOVE_TIME_TICK (1<<6) /**< Time is in ticks */
+#define SND_SEQ_REMOVE_EVENT_TYPE (1<<7) /**< Restrict to event type */
+#define SND_SEQ_REMOVE_IGNORE_OFF (1<<8) /**< Do not flush off events */
+#define SND_SEQ_REMOVE_TAG_MATCH (1<<9) /**< Restrict to events with given tag */
+
+size_t snd_seq_remove_events_sizeof(void);
+/** allocate a remove_events container in heap */
+#define snd_seq_remove_events_alloca(ptr) \
+ SND_ALLOCA(snd_seq_remove_events, ptr)
+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);
+
+unsigned int 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, unsigned int 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);
-/* misc */
+
+/** \} */
+
+/**
+ * \defgroup SeqMisc Sequencer Miscellaneous
+ * Sequencer Mescellaneous
+ * \ingroup Sequencer
+ * \{
+ */
+
void snd_seq_set_bit(int nr, void *array);
int snd_seq_change_bit(int nr, void *array);
int snd_seq_get_bit(int nr, void *array);
-#ifdef __cplusplus
-}
-#endif
+/** \} */
+
+
+/**
+ * \defgroup SeqEvType Sequencer Event Type Checks
+ * Sequencer Event Type Checks
+ * \ingroup Sequencer
+ * \{
+ */
+
+/* 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,
+ SND_SEQ_EVFLG_IPC
+};
+
+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.
+ */
+extern const unsigned int snd_seq_event_types[];
+
+#define _SND_SEQ_TYPE(x) (1<<(x)) /* 24bit */
+#define _SND_SEQ_TYPE_OPT(x) ((x)<<24) /* 8bit */
+
+#define snd_seq_type_check(ev,x) (snd_seq_event_types[(ev)->type] & _SND_SEQ_TYPE(x))
+
+/** event type check: result events */
+#define snd_seq_ev_is_result_type(ev) \
+ snd_seq_type_check(ev, SND_SEQ_EVFLG_RESULT)
+/** event type check: note events */
+#define snd_seq_ev_is_note_type(ev) \
+ snd_seq_type_check(ev, SND_SEQ_EVFLG_NOTE)
+/** event type check: control events */
+#define snd_seq_ev_is_control_type(ev) \
+ snd_seq_type_check(ev, SND_SEQ_EVFLG_CONTROL)
+/** event type check: channel specific events */
+#define snd_seq_ev_is_channel_type(ev) \
+ (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 */
+#define snd_seq_ev_is_queue_type(ev) \
+ snd_seq_type_check(ev, SND_SEQ_EVFLG_QUEUE)
+/** event type check: system status messages */
+#define snd_seq_ev_is_message_type(ev) \
+ snd_seq_type_check(ev, SND_SEQ_EVFLG_MESSAGE)
+/** event type check: system status messages */
+#define snd_seq_ev_is_subscribe_type(ev) \
+ snd_seq_type_check(ev, SND_SEQ_EVFLG_CONNECTION)
+/** event type check: sample messages */
+#define snd_seq_ev_is_sample_type(ev) \
+ snd_seq_type_check(ev, SND_SEQ_EVFLG_SAMPLE)
+/** event type check: user-defined messages */
+#define snd_seq_ev_is_user_type(ev) \
+ snd_seq_type_check(ev, SND_SEQ_EVFLG_USERS)
+/** event type check: instrument layer events */
+#define snd_seq_ev_is_instr_type(ev) \
+ snd_seq_type_check(ev, SND_SEQ_EVFLG_INSTR)
+/** event type check: fixed length events */
+#define snd_seq_ev_is_fixed_type(ev) \
+ snd_seq_type_check(ev, SND_SEQ_EVFLG_FIXED)
+/** event type check: variable length events */
+#define snd_seq_ev_is_variable_type(ev) \
+ snd_seq_type_check(ev, SND_SEQ_EVFLG_VARIABLE)
+/** event type check: user pointer events */
+#define snd_seq_ev_is_varusr_type(ev) \
+ snd_seq_type_check(ev, SND_SEQ_EVFLG_VARUSR)
+/** event type check: ipc events */
+#define snd_seq_ev_is_varipc_type(ev) \
+ snd_seq_type_check(ev, SND_SEQ_EVFLG_IPC)
+/** event type check: reserved for kernel */
+#define snd_seq_ev_is_reserved(ev) \
+ (! snd_seq_event_types[(ev)->type])
+
+/**
+ * macros to check event flags
+ */
+/** prior events */
+#define snd_seq_ev_is_prior(ev) \
+ (((ev)->flags & SND_SEQ_PRIORITY_MASK) == SND_SEQ_PRIORITY_HIGH)
+
+/** get the data length type */
+#define snd_seq_ev_length_type(ev) \
+ ((ev)->flags & SND_SEQ_EVENT_LENGTH_MASK)
+/** fixed length events */
+#define snd_seq_ev_is_fixed(ev) \
+ (snd_seq_ev_length_type(ev) == SND_SEQ_EVENT_LENGTH_FIXED)
+/** variable length events */
+#define snd_seq_ev_is_variable(ev) \
+ (snd_seq_ev_length_type(ev) == SND_SEQ_EVENT_LENGTH_VARIABLE)
+/** variable length on user-space */
+#define snd_seq_ev_is_varusr(ev) \
+ (snd_seq_ev_length_type(ev) == SND_SEQ_EVENT_LENGTH_VARUSR)
+/** variable length on IPC shm */
+#define snd_seq_ev_is_varipc(ev) \
+ (snd_seq_ev_length_type(ev) == SND_SEQ_EVENT_LENGTH_VARIPC)
+
+/** time-stamp type */
+#define snd_seq_ev_timestamp_type(ev) \
+ ((ev)->flags & SND_SEQ_TIME_STAMP_MASK)
+/** event is in tick time */
+#define snd_seq_ev_is_tick(ev) \
+ (snd_seq_ev_timestamp_type(ev) == SND_SEQ_TIME_STAMP_TICK)
+/** event is in real-time */
+#define snd_seq_ev_is_real(ev) \
+ (snd_seq_ev_timestamp_type(ev) == SND_SEQ_TIME_STAMP_REAL)
+
+/** time-mode type */
+#define snd_seq_ev_timemode_type(ev) \
+ ((ev)->flags & SND_SEQ_TIME_MODE_MASK)
+/** scheduled in absolute time */
+#define snd_seq_ev_is_abstime(ev) \
+ (snd_seq_ev_timemode_type(ev) == SND_SEQ_TIME_MODE_ABS)
+/** scheduled in relative time */
+#define snd_seq_ev_is_reltime(ev) \
+ (snd_seq_ev_timemode_type(ev) == SND_SEQ_TIME_MODE_REL)
+
+/** direct dispatched events */
+#define snd_seq_ev_is_direct(ev) \
+ ((ev)->queue == SND_SEQ_QUEUE_DIRECT)
/** \} */
+#ifdef __cplusplus
+}
+#endif
--- /dev/null
+/**
+ * \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 */
+
+
+/** \} */
* *
****************************************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/**
* \defgroup SeqMiddle Sequencer Middle Level Interface
* Sequencer Middle Level Interface
* \{
*/
-#ifdef __cplusplus
-extern "C" {
-#endif
+/**
+ * \brief initialize event record
+ * \param ev event record pointer
+ */
+#define snd_seq_ev_clear(ev) \
+ memset(ev, 0, sizeof(snd_seq_event_t))
-/* 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);
+/**
+ * \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))
-/*
- * use/unuse a queue
+/**
+ * \brief set broadcasting to subscribers
+ * \param ev event record
*/
-int snd_seq_use_queue(snd_seq_t *seq, int q, int use);
+#define snd_seq_ev_set_subs(ev) \
+ ((ev)->dest.client = SND_SEQ_ADDRESS_SUBSCRIBERS,\
+ (ev)->dest.port = SND_SEQ_ADDRESS_UNKNOWN)
-/* 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 broadcasting to all clients/ports
+ * \param ev event record
*/
-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);
+#define snd_seq_ev_set_broadcast(ev) \
+ ((ev)->dest.client = SND_SEQ_ADDRESS_BROADCAST,\
+ (ev)->dest.port = SND_SEQ_ADDRESS_BROADCAST)
-/* create a port - simple version - return the port number */
-int snd_seq_create_simple_port(snd_seq_t *seq, const char *name,
- unsigned int caps, unsigned int type);
-/* delete the port */
-int snd_seq_delete_simple_port(snd_seq_t *seq, int port);
+/**
+ * \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))
-/* 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);
+/**
+ * \brief set direct passing mode (without queued)
+ * \param ev event instance
+ */
+#define snd_seq_ev_set_direct(ev) \
+ ((ev)->queue = SNDRV_SEQ_QUEUE_DIRECT)
-/*
- * set client information
+/**
+ * \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
*/
-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);
+#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))
-/*
- * reset client input/output pool
+/**
+ * \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
*/
-int snd_seq_reset_pool_output(snd_seq_t *seq);
-int snd_seq_reset_pool_input(snd_seq_t *seq);
+#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))
-/*
- * equivalent macros
+/**
+ * \brief set event priority
+ * \param ev event instance
+ * \param high_prior 1 for high priority mode
*/
-#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))
+#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)
-/*
- * queue controls
+/**
+ * \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,t,q,val) \
- ((ev)->type = (t),\
+#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))
-#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) \
+
+/**
+ * \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))
-#define snd_seq_ev_set_queue_pos_tick(ev,q,ttime) \
+
+/**
+ * \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))
-#define snd_seq_start_queue(seq,q,ev) \
+/* 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);
+
+/**
+ * \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)
-#define snd_seq_stop_queue(seq,q,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)
-#define snd_seq_continue_queue(seq,q,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)
-#define snd_seq_change_queue_tempo(seq,q,tempo,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,
+ unsigned int caps, unsigned int 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);
+
/*
- * macros to set standard event data
+ * set client information
*/
-#define snd_seq_ev_set_note(ev,ch,key,vel,dur) \
+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);
+
+/*
+ * 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);
+
+/**
+ * \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_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
-/** \} */
-
#include <asm/byteorder.h>
#include <sound/ainstr_fm.h>
-int snd_instr_fm_free(snd_instr_simple_t *fm)
+int snd_instr_fm_free(snd_instr_fm_t *fm)
{
if (fm == NULL)
return 0;
int snd_instr_fm_convert_to_stream(snd_instr_fm_t *fm,
const char *name,
- snd_seq_instr_put_t **__data,
+ snd_instr_header_t **__data,
size_t *__size)
{
- snd_seq_instr_put_t *put;
- snd_seq_instr_data_t *data;
+ snd_instr_header_t *put;
fm_instrument_t *instr;
fm_xinstrument_t *xinstr;
int idx;
instr = (fm_instrument_t *)fm;
*__data = NULL;
*__size = 0;
- put = (snd_seq_instr_put_t *)malloc(sizeof(*put) + sizeof(fm_xinstrument_t));
- if (put == NULL)
+ if (snd_instr_header_malloc(&put, sizeof(fm_xinstrument_t)) < 0)
return -ENOMEM;
/* build header */
- memset(put, 0, sizeof(*put));
- data = &put->data;
if (name)
- strncpy(data->name, name, sizeof(data->name)-1);
- data->type = SND_SEQ_INSTR_ATYPE_DATA;
- strcpy(data->data.format, SND_SEQ_INSTR_ID_OPL2_3);
+ snd_instr_header_set_name(put, name);
+ snd_instr_header_set_type(put, SND_SEQ_INSTR_ATYPE_DATA);
+ snd_instr_header_set_format(put, SND_SEQ_INSTR_ID_OPL2_3);
/* build data section */
- xinstr = (fm_xinstrument_t *)(data + 1);
+ xinstr = (fm_xinstrument_t *)snd_instr_header_get_data(put);
xinstr->stype = FM_STRU_INSTR;
xinstr->share_id[0] = __cpu_to_le32(instr->share_id[0]);
xinstr->share_id[1] = __cpu_to_le32(instr->share_id[1]);
return 0;
}
-int snd_instr_fm_convert_from_stream(snd_seq_instr_get_t *__data ATTRIBUTE_UNUSED,
+int snd_instr_fm_convert_from_stream(snd_instr_header_t *__data ATTRIBUTE_UNUSED,
size_t size ATTRIBUTE_UNUSED,
snd_instr_fm_t **simple ATTRIBUTE_UNUSED)
{
int snd_instr_iwffff_conv_to_stream(snd_instr_iwffff_t *iwffff,
const char *name,
- snd_seq_instr_put_t **__data,
+ snd_instr_header_t **__data,
long *__size)
{
- snd_seq_instr_put_t *put;
- snd_seq_instr_data_t *data;
+ snd_instr_header_t *put;
int size;
char *ptr;
iwffff_instrument_t *instr;
instr = (iwffff_instrument_t *)iwffff;
*__data = NULL;
*__size = 0;
- size = sizeof(*data) + iwffff_size(iwffff);
- put = (snd_seq_instr_put_t *)malloc(sizeof(*put) + size);
- if (put == NULL)
+ size = iwffff_size(iwffff);
+ if (snd_instr_header_malloc(&put, size) < 0)
return -ENOMEM;
/* build header */
- memset(put, 0, sizeof(*put));
- data = &put->data;
if (name)
- strncpy(data->name, name, sizeof(data->name)-1);
- data->type = SND_SEQ_INSTR_ATYPE_DATA;
- strcpy(data->data.format, SND_SEQ_INSTR_ID_INTERWAVE);
+ snd_instr_header_set_name(put, name);
+ snd_instr_header_set_type(put, SND_SEQ_INSTR_ATYPE_DATA);
+ snd_instr_header_set_format(put, SND_SEQ_INSTR_ID_INTERWAVE);
/* build data section */
- xinstr = (iwffff_xinstrument_t *)(data + 1);
+ xinstr = (iwffff_xinstrument_t *)snd_instr_header_get_data(put);
xinstr->stype = IWFFFF_STRU_INSTR;
xinstr->exclusion = __cpu_to_le16(instr->exclusion);
xinstr->layer_type = __cpu_to_le16(instr->layer_type);
}
/* write result */
*__data = put;
- *__size = size;
+ *__size = sizeof(*put) + size;
return 0;
}
-int snd_instr_iwffff_convert_from_stream(snd_seq_instr_get_t *data ATTRIBUTE_UNUSED,
+int snd_instr_iwffff_convert_from_stream(snd_instr_header_t *data ATTRIBUTE_UNUSED,
size_t size ATTRIBUTE_UNUSED,
snd_instr_iwffff_t **iwffff ATTRIBUTE_UNUSED)
{
int snd_instr_simple_convert_to_stream(snd_instr_simple_t *simple,
const char *name,
- snd_seq_instr_put_t **__data,
+ snd_instr_header_t **__data,
size_t *__size)
{
- snd_seq_instr_put_t *put;
- snd_seq_instr_data_t *data;
+ snd_instr_header_t *put;
int size;
char *ptr;
simple_instrument_t *instr;
*__data = NULL;
*__size = 0;
size = simple_size(simple);
- put = (snd_seq_instr_put_t *)malloc(sizeof(*put) + sizeof(simple_xinstrument_t) + size);
- if (put == NULL)
+ if (snd_instr_header_malloc(&put, sizeof(simple_xinstrument_t) + size) < 0)
return -ENOMEM;
/* build header */
- memset(put, 0, sizeof(*put));
- data = &put->data;
if (name)
- strncpy(data->name, name, sizeof(data->name)-1);
- data->type = SND_SEQ_INSTR_ATYPE_DATA;
- strcpy(data->data.format, SND_SEQ_INSTR_ID_SIMPLE);
+ snd_instr_header_set_name(put, name);
+ snd_instr_header_set_type(put, SND_SEQ_INSTR_ATYPE_DATA);
+ snd_instr_header_set_format(put, SND_SEQ_INSTR_ID_SIMPLE);
/* build data section */
- xinstr = (simple_xinstrument_t *)(data + 1);
+ xinstr = (simple_xinstrument_t *)snd_instr_header_get_data(put);
xinstr->stype = SIMPLE_STRU_INSTR;
xinstr->share_id[0] = __cpu_to_le32(instr->share_id[0]);
xinstr->share_id[1] = __cpu_to_le32(instr->share_id[1]);
return 0;
}
-int snd_instr_simple_convert_from_stream(snd_seq_instr_get_t *__data ATTRIBUTE_UNUSED,
+int snd_instr_simple_convert_from_stream(snd_instr_header_t *__data ATTRIBUTE_UNUSED,
size_t size ATTRIBUTE_UNUSED,
snd_instr_simple_t **simple ATTRIBUTE_UNUSED)
{
EXTRA_LTLIBRARIES=libseq.la
-libseq_la_SOURCES = seq_hw.c seq.c seqmid.c seq_midi_event.c
+libseq_la_SOURCES = seq_hw.c seq.c seq_event.c seqmid.c seq_midi_event.c
noinst_HEADERS = seq_local.h
all: libseq.la
* \author Abramo Bagnara <abramo@alsa-project.org>
* \author Takashi Iwai <tiwai@suse.de>
* \date 2000-2001
- *
- * THE SEQUENCER INTERFACE WILL BE CHANGED IN NEAR FUTURE.
- * This interface is still not compliant to alsa 1.0 encapsulation.
- *
*/
/*
#include <dlfcn.h>
#include "seq_local.h"
+/****************************************************************************
+ * *
+ * seq.h *
+ * Sequencer *
+ * *
+ ****************************************************************************/
+
/**
* \brief get identifier of sequencer handle
* \param seq sequencer handle
* kept and passed to most of the other sequencer functions.
* \param name The sequencer's "name". This is \em not a name you make
* up for your own purposes; it has special significance to the ALSA
- * library. So far only \c "hw" type is supported.
- * Just pass \c "hw" for this.
+ * library. Usually you need to pass \c "default" here.
* \param streams The read/write mode of the sequencer. Can be one of
* three values:
- * - \c SND_SEQ_OPEN_OUTPUT - open the sequencer for output only
- * - \c SND_SEQ_OPEN_INPUT - open the sequencer for input only
- * - \c SND_SEQ_OPEN_DUPLEX - open the sequencer for output and input
- * I suppose that you'd always want to use \c SND_SEQ_OPEN_DUPLEX here;
- * I can't think of a reason for using either of the other two.
+ * - #SND_SEQ_OPEN_OUTPUT - open the sequencer for output only
+ * - #SND_SEQ_OPEN_INPUT - open the sequencer for input only
+ * - #SND_SEQ_OPEN_DUPLEX - open the sequencer for output and input
* \note Internally, these are translated to \c O_WRONLY, \c O_RDONLY and
* \O_RDWR respectively and used as the second argument to the C library
* open() call.
- * \param mode Optional modifier. Can be either 0, or \c
- * SND_SEQ_NONBLOCK, which will make read/write operations
- * non-blocking. This can also be set later using snd_seq_nonblock().
+ * \param mode Optional modifier. Can be either 0, or
+ * #SND_SEQ_NONBLOCK, which will make read/write operations
+ * non-blocking. This can also be set later using #snd_seq_nonblock().
* \return 0 on success otherwise a negative error code
*
* Creates a new handle and opens a connection to the kernel
* sequencer interface.
* After a client is created successfully, an event
- * with \c SND_SEQ_EVENT_CLIENT_START is broadcasted to announce port.
+ * with #SND_SEQ_EVENT_CLIENT_START is broadcasted to announce port.
*/
int snd_seq_open(snd_seq_t **seqp, const char *name,
int streams, int mode)
/**
* \brief Close the sequencer
- * \param handle Handle returned from snd_seq_open()
+ * \param handle Handle returned from #snd_seq_open()
* \return 0 on success otherwise a negative error code
*
* Closes the sequencer client and releases its resources.
* After a client is closed, an event with
- * \c SND_SEQ_EVENT_CLIENT_EXIT is broadcasted to announce port.
+ * #SND_SEQ_EVENT_CLIENT_EXIT is broadcasted to announce port.
* The connection between other clients are disconnected.
* Call this just before exiting your program.
*/
}
/**
- * \brief get poll descriptors
+ * \brief Get poll descriptors
* \param seq sequencer handle
* \param pfds array of poll descriptors
* \param space space in the poll descriptor array
}
/**
- * \brief set nonblock mode
+ * \brief Set nonblock mode
* \param seq sequencer handle
* \param nonblock 0 = block, 1 = nonblock mode
* \return 0 on success otherwise a negative error code
* Change the blocking mode of the given client.
* In block mode, the client falls into sleep when it fills the
* output memory pool with full events. The client will be woken up
- *after a certain amount of free space becomes available.
+ * after a certain amount of free space becomes available.
*/
int snd_seq_nonblock(snd_seq_t *seq, int nonblock)
{
}
/**
- * \brief get the client id
+ * \brief Get the client id
* \param seq sequencer handle
* \return the client id
*
}
/**
- * \brief return the size of output buffer
+ * \brief Return the size of output buffer
* \param seq sequencer handle
* \return the size of output buffer in bytes
*
* This buffer is used to store decoded byte-stream of output events
* before transferring to sequencer.
*/
-int snd_seq_output_buffer_size(snd_seq_t *seq)
+size_t snd_seq_get_output_buffer_size(snd_seq_t *seq)
{
assert(seq);
if (!seq->obuf)
}
/**
- * \brief return the size of input buffer
+ * \brief Return the size of input buffer
* \param seq sequencer handle
* \return the size of input buffer in bytes
*
* Obtains the size of input buffer.
* This buffer is used to read byte-stream of input events from sequencer.
*/
-int snd_seq_input_buffer_size(snd_seq_t *seq)
+size_t snd_seq_get_input_buffer_size(snd_seq_t *seq)
{
assert(seq);
if (!seq->ibuf)
}
/**
- * \brief change the size of output buffer
+ * \brief Change the size of output buffer
* \param seq sequencer handle
* \param size the size of output buffer to be changed in bytes
* \return 0 on success otherwise a negative error code
*
* Changes the size of output buffer.
*/
-int snd_seq_resize_output_buffer(snd_seq_t *seq, size_t size)
+int snd_seq_set_output_buffer_size(snd_seq_t *seq, size_t size)
{
assert(seq && seq->obuf);
assert(size >= sizeof(snd_seq_event_t));
}
/**
- * \brief resize the input buffer
+ * \brief Resize the input buffer
* \param seq sequencer handle
* \param size the size of input buffer to be changed in bytes
* \return 0 on success otherwise a negative error code
*
* Changes the size of input buffer.
*/
-int snd_seq_resize_input_buffer(snd_seq_t *seq, size_t size)
+int snd_seq_set_input_buffer_size(snd_seq_t *seq, size_t size)
{
assert(seq && seq->ibuf);
assert(size >= sizeof(snd_seq_event_t));
return 0;
}
+
/**
- * \brief obtain the sequencer system information
- * \param seq sequencer handle
- * \param info the pointer to be stored
- * \return 0 on success otherwise a negative error code
- *
- * Stores the global system information of ALSA sequencer system.
- * The returned data contains
- * the maximum available numbers of queues, clients, ports and channels.
+ * \brief Get size of #snd_seq_system_info_t
+ * \return size in bytes
*/
-int snd_seq_system_info(snd_seq_t *seq, snd_seq_system_info_t * info)
+size_t snd_seq_system_info_sizeof()
{
- assert(seq && info);
- return seq->ops->system_info(seq, info);
+ return sizeof(snd_seq_system_info_t);
}
/**
- * \brief obtain the information of the given client
- * \param seq sequencer handle
- * \param client client id
- * \param info the pointer to be stored
- * \return 0 on success otherwise a negative error code
- *
- * Obtains the information of the client with a client id specified by
- * info argument.
- * The obtained information is written on info parameter.
+ * \brief Allocate an empty #snd_seq_system_info_t using standard malloc
+ * \param ptr returned pointer
+ * \return 0 on success otherwise negative error code
*/
-int snd_seq_get_any_client_info(snd_seq_t *seq, int client, snd_seq_client_info_t * info)
+int snd_seq_system_info_malloc(snd_seq_system_info_t **ptr)
{
- assert(seq && info && client >= 0);
- memset(info, 0, sizeof(snd_seq_client_info_t));
- info->client = client;
- return seq->ops->get_client_info(seq, info);
+ assert(ptr);
+ *ptr = calloc(1, sizeof(snd_seq_system_info_t));
+ if (!*ptr)
+ return -ENOMEM;
+ return 0;
}
/**
- * \brief obtain the current client information
- * \param seq sequencer handle
- * \param info the pointer to be stored
- * \return 0 on success otherwise a negative error code
- *
- * Obtains the information of the current client stored on info.
- * client and type fields are ignored.
+ * \brief Frees a previously allocated #snd_seq_system_info_t
+ * \param pointer to object to free
*/
-int snd_seq_get_client_info(snd_seq_t *seq, snd_seq_client_info_t * info)
+void snd_seq_system_info_free(snd_seq_system_info_t *obj)
{
- return snd_seq_get_any_client_info(seq, seq->client, info);
+ free(obj);
}
/**
- * \brief set the current client information
- * \param seq sequencer handle
- * \param info the client info data to set
- * \return 0 on success otherwise a negative error code
- *
- * Obtains the information of the current client stored on info.
- * client and type fields are ignored.
+ * \brief Copy one #snd_seq_system_info_t to another
+ * \param dst pointer to destination
+ * \param src pointer to source
*/
-int snd_seq_set_client_info(snd_seq_t *seq, snd_seq_client_info_t * info)
+void snd_seq_system_info_copy(snd_seq_system_info_t *dst, const snd_seq_system_info_t *src)
{
- assert(seq && info);
- info->client = seq->client;
- info->type = USER_CLIENT;
- return seq->ops->set_client_info(seq, info);
+ assert(dst && src);
+ *dst = *src;
}
-/*----------------------------------------------------------------*/
/**
- * \brief create a sequencer port on the current client
- * \param seq sequencer handle
- * \param port port information for the new port
- * \return 0 on success otherwise a negative error code
- *
- * Creates a sequencer port on the current client.
- * The attributes of created port is specified in info argument.
- *
- * The client field in info argument is overwritten with the current client id.
- * Behavior of port creation depends on a flag defined in
- * flags field. The flags field is a bit mask containing
- * miscellaneous conditions.
- * If \c SND_SEQ_PORT_FLG_GIVEN_PORT is included in flags field,
- * the port number in port field in info argument
- * is used as the id of created port.
- * Otherwise, the first empty port id is searched and used.
- * The obtained id index of the created port is stored on
- * port field in return.
- *
- * The capability and cap_group are bit-masks to specify the access
- * capability of the port from other clients and from the same group,
- * respectively. The capability bit flags are defined as follows:
- * - \c SND_SEQ_PORT_CAP_READ Readable from this port
- * - \c SND_SEQ_PORT_CAP_WRITE Writable to this port.
- * - \c SND_SEQ_PORT_CAP_SYNC_READ For synchronization (not implemented)
- * - \c SND_SEQ_PORT_CAP_SYNC_WRITE For synchronization (not implemented)
- * - \c SND_SEQ_PORT_CAP_DUPLEX Read/write duplex access is supported
- * - \c SND_SEQ_PORT_SUBS_READ Read subscription is allowed
- * - \c SND_SEQ_PORT_SUBS_WRITE Write subscription is allowed
- * - \c SND_SEQ_PORT_SUBS_NO_EXPORT Subscription management from 3rd client is disallowed
- *
- * The type field is used to specify the type of the port.
- * It is a bitmask defined as follows:
- * - \c SND_SEQ_PORT_TYPE_SPECIFIC Hardware specific port
- * - \c SND_SEQ_PORT_TYPE_MIDI_GENERIC Generic MIDI device
- * - \c SND_SEQ_PORT_TYPE_MIDI_GM General MIDI compatible device
- * - \c SND_SEQ_PORT_TYPE_MIDI_GS GS compatible device
- * - \c SND_SEQ_PORT_TYPE_MIDI_XG XG compatible device
- * - \c SND_SEQ_PORT_TYPE_MIDI_MT32 MT-32 compatible device
- * - \c SND_SEQ_PORT_TYPE_SYNTH Synth device
- * - \c SND_SEQ_PORT_TYPE_DIRECT_SAMPLE Sampling device (supporting download)
- * - \c SND_SEQ_PORT_TYPE_SAMPLE Sampling device (sample can be downloaded at any time)
- * - \c SND_SEQ_PORT_TYPE_APPLICATION Application (suquencer/editor)
- *
- * The midi_channels, midi_voices and synth_voices fields are number of channels and
- * voices of this port. These values could be zero as default.
- * The read_use, write_use and kernel fields are at creation.
- * They should be zero-cleared.
+ * \brief Get maximum number of queues
+ * \param info #snd_seq_system_info_t container
+ * \return maximum number of queues
*/
-int snd_seq_create_port(snd_seq_t *seq, snd_seq_port_info_t * port)
+int snd_seq_system_info_get_queues(const snd_seq_system_info_t *info)
{
- assert(seq && port);
- port->client = seq->client;
- return seq->ops->create_port(seq, port);
+ assert(info);
+ return info->queues;
}
/**
- * \brief delete a sequencer port on the current client
- * \param seq sequencer handle
- * \param port port to be deleted
- * \return 0 on success otherwise a negative error code
- *
- * Deletes the existing sequencer port on the current client.
- * The port id must be specified in port field in info argument.
- * The client field is ignored.
+ * \brief Get maximum number of clients
+ * \param info #snd_seq_system_info_t container
+ * \return maximum number of clients
*/
-int snd_seq_delete_port(snd_seq_t *seq, snd_seq_port_info_t * port)
+int snd_seq_system_info_get_clients(const snd_seq_system_info_t *info)
{
- assert(seq && port);
- port->client = seq->client;
- return seq->ops->delete_port(seq, port);
+ assert(info);
+ return info->clients;
}
/**
- * \brief obatin the information of a port on an arbitrary client
- * \param seq sequencer handle
- * \param client client id to get
- * \param port port id to get
- * \param info pointer information returns
- * \return 0 on success otherwise a negative error code
+ * \brief Get maximum number of ports
+ * \param info #snd_seq_system_info_t container
+ * \return maximum number of ports
*/
-int snd_seq_get_any_port_info(snd_seq_t *seq, int client, int port, snd_seq_port_info_t * info)
+int snd_seq_system_info_get_ports(const snd_seq_system_info_t *info)
{
- assert(seq && info && client >= 0 && port >= 0);
- memset(info, 0, sizeof(snd_seq_port_info_t));
- info->client = client;
- info->port = port;
- return seq->ops->get_port_info(seq, info);
+ assert(info);
+ return info->ports;
}
/**
- * \brief obatin the information of a port on the current client
- * \param seq sequencer handle
- * \param port port id to get
- * \param info pointer information returns
- * \return 0 on success otherwise a negative error code
+ * \brief Get maximum number of channels
+ * \param info #snd_seq_system_info_t container
+ * \return maximum number of channels
*/
-int snd_seq_get_port_info(snd_seq_t *seq, int port, snd_seq_port_info_t * info)
+int snd_seq_system_info_get_channels(const snd_seq_system_info_t *info)
{
- return snd_seq_get_any_port_info(seq, seq->client, port, info);
+ assert(info);
+ return info->channels;
}
+
/**
- * \brief set the information of a port on the current client
+ * \brief obtain the sequencer system information
* \param seq sequencer handle
- * \param port port to be set
- * \param info port information to be set
+ * \param info the pointer to be stored
* \return 0 on success otherwise a negative error code
+ *
+ * Stores the global system information of ALSA sequencer system.
+ * The returned data contains
+ * the maximum available numbers of queues, clients, ports and channels.
*/
-int snd_seq_set_port_info(snd_seq_t *seq, int port, snd_seq_port_info_t * info)
+int snd_seq_system_info(snd_seq_t *seq, snd_seq_system_info_t * info)
{
- assert(seq && info && port >= 0);
- info->port = port;
- return seq->ops->set_port_info(seq, info);
+ assert(seq && info);
+ return seq->ops->system_info(seq, info);
}
-/*----------------------------------------------------------------*/
-/*
- * subscription
- */
+/*----------------------------------------------------------------*/
/**
- * \brief obtain subscription information
- * \param seq sequencer handle
- * \param sub pointer to return the subscription information
- * \return 0 on success otherwise a negative error code
+ * \brief get size of #snd_seq_client_info_t
+ * \return size in bytes
*/
-int snd_seq_get_port_subscription(snd_seq_t *seq, snd_seq_port_subscribe_t * sub)
+size_t snd_seq_client_info_sizeof()
{
- assert(seq && sub);
- return seq->ops->get_port_subscription(seq, sub);
+ return sizeof(snd_seq_client_info_t);
}
/**
- * \brief subscribe a port connection
- * \param seq sequencer handle
- * \param sub subscription information
- * \return 0 on success otherwise a negative error code
- *
- * Subscribes a connection between two ports.
- * The subscription information is stored in sub argument.
+ * \brief allocate an empty #snd_seq_client_info_t using standard malloc
+ * \param ptr returned pointer
+ * \return 0 on success otherwise negative error code
*/
-int snd_seq_subscribe_port(snd_seq_t *seq, snd_seq_port_subscribe_t * sub)
+int snd_seq_client_info_malloc(snd_seq_client_info_t **ptr)
{
- assert(seq && sub);
- return seq->ops->subscribe_port(seq, sub);
+ assert(ptr);
+ *ptr = calloc(1, sizeof(snd_seq_client_info_t));
+ if (!*ptr)
+ return -ENOMEM;
+ return 0;
}
/**
- * \brief unsubscribe a connection between ports
- * \param seq sequencer handle
- * \param sub subscription information to disconnect
- * \return 0 on success otherwise a negative error code
- *
- * Unsubscribes a connection between two ports,
- * described in sender and dest fields in sub argument.
+ * \brief frees a previously allocated #snd_seq_client_info_t
+ * \param pointer to object to free
*/
-int snd_seq_unsubscribe_port(snd_seq_t *seq, snd_seq_port_subscribe_t * sub)
+void snd_seq_client_info_free(snd_seq_client_info_t *obj)
{
- assert(seq && sub);
- return seq->ops->unsubscribe_port(seq, sub);
+ free(obj);
}
/**
- * \brief query port subscriber list
- * \param seq sequencer handle
- * \param subs subscription to query
- * \return 0 on success otherwise a negative error code
- *
- * Queries the subscribers accessing to a port.
- * The query information is specified in subs argument.
- *
+ * \brief copy one #snd_seq_client_info_t to another
+ * \param dst pointer to destination
+ * \param src pointer to source
*/
-int snd_seq_query_port_subscribers(snd_seq_t *seq, snd_seq_query_subs_t * subs)
+void snd_seq_client_info_copy(snd_seq_client_info_t *dst, const snd_seq_client_info_t *src)
{
- assert(seq && subs);
- return seq->ops->query_port_subscribers(seq, subs);
+ assert(dst && src);
+ *dst = *src;
}
-/*----------------------------------------------------------------*/
-/*
- * queue handlers
+/**
+ * \brief Get client id of a client_info container
+ * \param info client_info container
+ * \return client id
*/
+int snd_seq_client_info_get_client(const snd_seq_client_info_t *info)
+{
+ assert(info);
+ return info->client;
+}
/**
- * \brief obtain the running state of the queue
- * \param seq sequencer handle
- * \param q queue id to query
- * \param status pointer to store the current status
- * \return 0 on success otherwise a negative error code
+ * \brief Get client type of a client_info container
+ * \param info client_info container
+ * \return client type
*
- * Obtains the running state of the specified queue q.
+ * The client type is either #SEQ_CLIENT_TYPE_KERNEL or #SEQ_CLIENT_TYPE_USER
+ * for kernel or user client respectively.
*/
-int snd_seq_get_queue_status(snd_seq_t *seq, int q, snd_seq_queue_status_t * status)
+snd_seq_client_type_t snd_seq_client_info_get_type(const snd_seq_client_info_t *info)
{
- assert(seq && status);
- memset(status, 0, sizeof(snd_seq_queue_status_t));
- status->queue = q;
- return seq->ops->get_queue_status(seq, status);
+ assert(info);
+ return info->type;
}
/**
- * \brief obtain the current tempo of the queue
- * \param seq sequencer handle
- * \param q queue id to be queried
- * \param tempo pointer to store the current tempo
- * \return 0 on success otherwise a negative error code
+ * \brief Get the name of a client_info container
+ * \param info client_info container
+ * \return name string
*/
-int snd_seq_get_queue_tempo(snd_seq_t *seq, int q, snd_seq_queue_tempo_t * tempo)
+const char *snd_seq_client_info_get_name(snd_seq_client_info_t *info)
{
- assert(seq && tempo);
- memset(tempo, 0, sizeof(snd_seq_queue_tempo_t));
- tempo->queue = q;
- return seq->ops->get_queue_tempo(seq, tempo);
+ assert(info);
+ return info->name;
}
/**
- * \brief set the tempo of the queue
- * \param seq sequencer handle
- * \param q queue id to change the tempo
- * \param tempo tempo information
- * \return 0 on success otherwise a negative error code
+ * \brief Get the broadcast filter usage of a client_info container
+ * \param info client_info container
+ * \return 1 if broadcast is accepted
*/
-int snd_seq_set_queue_tempo(snd_seq_t *seq, int q, snd_seq_queue_tempo_t * tempo)
+int snd_seq_client_info_get_broadcast_filter(const snd_seq_client_info_t *info)
{
- assert(seq && tempo);
- tempo->queue = q;
- return seq->ops->set_queue_tempo(seq, tempo);
+ assert(info);
+ return (info->filter & SNDRV_SEQ_FILTER_BROADCAST) ? 1 : 0;
}
/**
- * \brief obtain the owner information of the queue
- * \param seq sequencer handle
- * \param q queue id to query
- * \param owner pointer to store the owner information
- * \return 0 on success otherwise a negative error code
+ * \brief Get the error-bounce usage of a client_info container
+ * \param info client_info container
+ * \return 1 if error-bounce is enabled
*/
-int snd_seq_get_queue_owner(snd_seq_t *seq, int q, snd_seq_queue_owner_t * owner)
+int snd_seq_client_info_get_error_bounce(const snd_seq_client_info_t *info)
{
- assert(seq && owner);
- memset(owner, 0, sizeof(snd_seq_queue_owner_t));
- owner->queue = q;
- return seq->ops->get_queue_owner(seq, owner);
+ assert(info);
+ return (info->filter & SNDRV_SEQ_FILTER_BOUNCE) ? 1 : 0;
}
/**
- * \biref set the owner information of the queue
- * \param seq sequencer handle
- * \param q queue id to change the ownership
- * \param owner owner information
- * \return 0 on success otherwise a negative error code
+ * \brief Get the event filter bitmap of a client_info container
+ * \param info client_info container
+ * \return NULL if no event filter, or pointer to event filter bitmap
*/
-int snd_seq_set_queue_owner(snd_seq_t *seq, int q, snd_seq_queue_owner_t * owner)
+const unsigned char *snd_seq_client_info_get_event_filter(const snd_seq_client_info_t *info)
{
- assert(seq && owner);
- owner->queue = q;
- return seq->ops->set_queue_owner(seq, owner);
+ assert(info);
+ if (info->filter & SNDRV_SEQ_FILTER_USE_EVENT)
+ return info->event_filter;
+ else
+ return NULL;
}
/**
- * \brief obtain the queue timer information
- * \param seq sequencer handle
- * \param q queue id to query
- * \param timer pointer to store the timer information
- * \return 0 on success otherwise a negative error code
+ * \brief Get the number of opened ports of a client_info container
+ * \param info client_info container
+ * \return number of opened ports
*/
-int snd_seq_get_queue_timer(snd_seq_t *seq, int q, snd_seq_queue_timer_t * timer)
+int snd_seq_client_info_get_num_ports(const snd_seq_client_info_t *info)
{
- assert(seq && timer);
- memset(timer, 0, sizeof(snd_seq_queue_timer_t));
- timer->queue = q;
- return seq->ops->get_queue_timer(seq, timer);
+ assert(info);
+ return info->num_ports;
}
/**
- * \brief set the queue timer information
- * \param seq sequencer handle
- * \param q queue id to change the timer
- * \param timer timer information
- * \return 0 on success otherwise a negative error code
+ * \brief Get the number of lost events of a client_info container
+ * \param info client_info container
+ * \return number of lost events
*/
-int snd_seq_set_queue_timer(snd_seq_t *seq, int q, snd_seq_queue_timer_t * timer)
+int snd_seq_client_info_get_event_lost(const snd_seq_client_info_t *info)
{
- assert(seq && timer);
- timer->queue = q;
- return seq->ops->set_queue_timer(seq, timer);
+ assert(info);
+ return info->event_lost;
}
/**
- * \brief obtain queue access information
- * \param seq sequencer handle
- * \param q queue id to query
- * \param info pointer to store the queue access information
- * \return 0 on success otherwise a negative error code
+ * \brief Set the client id of a client_info container
+ * \param info client_info container
+ * \param client client id
*/
-int snd_seq_get_queue_client(snd_seq_t *seq, int q, snd_seq_queue_client_t * info)
+void snd_seq_client_info_set_client(snd_seq_client_info_t *info, int client)
{
- assert(seq && info);
- memset(info, 0, sizeof(snd_seq_queue_client_t));
- info->queue = q;
- info->client = seq->client;
- return seq->ops->get_queue_client(seq, info);
+ assert(info);
+ info->client = client;
}
/**
- * \brief set queue access information
- * \param seq sequencer handle
- * \param q queue id to change access information
- * \param info access information
- * \return 0 on success otherwise a negative error code
+ * \brief Set the name of a client_info container
+ * \param info client_info container
+ * \param name name string
*/
-int snd_seq_set_queue_client(snd_seq_t *seq, int q, snd_seq_queue_client_t * info)
+void snd_seq_client_info_set_name(snd_seq_client_info_t *info, const char *name)
{
- assert(seq && info);
- info->queue = q;
- info->client = seq->client;
- return seq->ops->set_queue_client(seq, info);
+ assert(info && name);
+ strncpy(info->name, name, sizeof(info->name));
}
/**
- * \brief create a queue
- * \param seq sequencer handle
- * \param info queue information to initialize
- * \return the queue id (zero or positive) on success otherwise a negative error code
+ * \brief Set the broadcast filter usage of a client_info container
+ * \param info client_info container
+ * \param bool non-zero if broadcast is accepted
*/
-int snd_seq_create_queue(snd_seq_t *seq, snd_seq_queue_info_t *info)
+void snd_seq_client_info_set_broadcast_filter(snd_seq_client_info_t *info, int bool)
{
- int err;
- assert(seq && info);
- info->owner = seq->client;
- err = seq->ops->create_queue(seq, info);
- if (err < 0)
- return err;
- return info->queue;
+ assert(info);
+ if (bool)
+ info->filter |= SNDRV_SEQ_FILTER_BROADCAST;
+ else
+ info->filter &= ~SNDRV_SEQ_FILTER_BROADCAST;
}
/**
- * \brief allocate a queue with the speicified name
- * \param seq sequencer handle
- * \param name the name of the new queue
- * \return the queue id (zero or positive) on success otherwise a negative error code
- */
-int snd_seq_alloc_named_queue(snd_seq_t *seq, const char *name)
+ * \brief Set the error-bounce usage of a client_info container
+ * \param info client_info container
+ * \param bool non-zero if error is bounced
+ */
+void snd_seq_client_info_set_error_bounce(snd_seq_client_info_t *info, int bool)
{
- snd_seq_queue_info_t info;
- memset(&info, 0, sizeof(info));
- info.locked = 1;
- if (name)
- strncpy(info.name, name, sizeof(info.name) - 1);
- return snd_seq_create_queue(seq, &info);
+ assert(info);
+ if (bool)
+ info->filter |= SNDRV_SEQ_FILTER_BOUNCE;
+ else
+ info->filter &= ~SNDRV_SEQ_FILTER_BOUNCE;
}
/**
- * \brief allocate a queue
- * \param seq sequencer handle
- * \return the queue id (zero or positive) on success otherwise a negative error code
- */
-int snd_seq_alloc_queue(snd_seq_t *seq)
+ * \brief Set the event filter bitmap of a client_info container
+ * \param info client_info container
+ * \param filter event filter bitmap
+ */
+void snd_seq_client_info_set_event_filter(snd_seq_client_info_t *info, unsigned char *filter)
{
- return snd_seq_alloc_named_queue(seq, NULL);
+ assert(info);
+ if (! filter)
+ info->filter &= ~SNDRV_SEQ_FILTER_USE_EVENT;
+ else {
+ info->filter |= SNDRV_SEQ_FILTER_USE_EVENT;
+ memcpy(info->event_filter, filter, sizeof(info->event_filter));
+ }
}
-#ifdef SND_SEQ_SYNC_SUPPORT
+
/**
- * \brief allocate a synchronizable queue
+ * \brief obtain the information of the given client
+ * \param seq sequencer handle
+ * \param client client id
+ * \param info the pointer to be stored
+ * \return 0 on success otherwise a negative error code
+ *
+ * Obtains the information of the client with a client id specified by
+ * info argument.
+ * The obtained information is written on info parameter.
+ */
+int snd_seq_get_any_client_info(snd_seq_t *seq, int client, snd_seq_client_info_t *info)
+{
+ assert(seq && info && client >= 0);
+ memset(info, 0, sizeof(snd_seq_client_info_t));
+ info->client = client;
+ return seq->ops->get_client_info(seq, info);
+}
+
+/**
+ * \brief obtain the current client information
+ * \param seq sequencer handle
+ * \param info the pointer to be stored
+ * \return 0 on success otherwise a negative error code
+ *
+ * Obtains the information of the current client stored on info.
+ * client and type fields are ignored.
+ */
+int snd_seq_get_client_info(snd_seq_t *seq, snd_seq_client_info_t *info)
+{
+ return snd_seq_get_any_client_info(seq, seq->client, info);
+}
+
+/**
+ * \brief set the current client information
+ * \param seq sequencer handle
+ * \param info the client info data to set
+ * \return 0 on success otherwise a negative error code
+ *
+ * Obtains the information of the current client stored on info.
+ * client and type fields are ignored.
+ */
+int snd_seq_set_client_info(snd_seq_t *seq, snd_seq_client_info_t *info)
+{
+ assert(seq && info);
+ info->client = seq->client;
+ info->type = USER_CLIENT;
+ return seq->ops->set_client_info(seq, info);
+}
+
+/**
+ * \brief query the next matching client
+ * \param seq sequencer handle
+ * \param info query pattern and result
+ *
+ * Queries the next matching client with the given condition in
+ * info argument.
+ * The search begins at the client with an id one greater than
+ * client field in info.
+ * If name field in info is not empty, the client name is compared.
+ * If a matching client is found, its attributes are stored o
+ * info and returns zero.
+ * Otherwise returns a negative error code.
+ */
+int snd_seq_query_next_client(snd_seq_t *seq, snd_seq_client_info_t *info)
+{
+ assert(seq && info);
+ return seq->ops->query_next_client(seq, info);
+}
+
+
+/*----------------------------------------------------------------*/
+
+
+/*
+ * Port
+ */
+
+/**
+ * \brief get size of #snd_seq_port_info_t
+ * \return size in bytes
+ */
+size_t snd_seq_port_info_sizeof()
+{
+ return sizeof(snd_seq_port_info_t);
+}
+
+/**
+ * \brief allocate an empty #snd_seq_port_info_t using standard malloc
+ * \param ptr returned pointer
+ * \return 0 on success otherwise negative error code
+ */
+int snd_seq_port_info_malloc(snd_seq_port_info_t **ptr)
+{
+ assert(ptr);
+ *ptr = calloc(1, sizeof(snd_seq_port_info_t));
+ if (!*ptr)
+ return -ENOMEM;
+ return 0;
+}
+
+/**
+ * \brief frees a previously allocated #snd_seq_port_info_t
+ * \param pointer to object to free
+ */
+void snd_seq_port_info_free(snd_seq_port_info_t *obj)
+{
+ free(obj);
+}
+
+/**
+ * \brief copy one #snd_seq_port_info_t to another
+ * \param dst pointer to destination
+ * \param src pointer to source
+ */
+void snd_seq_port_info_copy(snd_seq_port_info_t *dst, const snd_seq_port_info_t *src)
+{
+ assert(dst && src);
+ *dst = *src;
+}
+
+
+/**
+ * \brief Get client id of a port_info container
+ * \param info port_info container
+ * \return client id
+ */
+int snd_seq_port_info_get_client(const snd_seq_port_info_t *info)
+{
+ assert(info);
+ return info->addr.client;
+}
+
+/**
+ * \brief Get port id of a port_info container
+ * \param info port_info container
+ * \return port id
+ */
+int snd_seq_port_info_get_port(const snd_seq_port_info_t *info)
+{
+ assert(info);
+ return info->addr.port;
+}
+
+/**
+ * \brief Get client/port address of a port_info container
+ * \param info port_info container
+ * \return client/port address pointer
+ */
+const snd_seq_addr_t *snd_seq_port_info_get_addr(const snd_seq_port_info_t *info)
+{
+ assert(info);
+ return &info->addr;
+}
+
+/**
+ * \brief Get the name of a port_info container
+ * \param info port_info container
+ * \return name string
+ */
+const char *snd_seq_port_info_get_name(const snd_seq_port_info_t *info)
+{
+ assert(info);
+ return info->name;
+}
+
+/**
+ * \brief Get the capability bits of a port_info container
+ * \param info port_info container
+ * \return capability bits
+ */
+unsigned int snd_seq_port_info_get_capability(const snd_seq_port_info_t *info)
+{
+ assert(info);
+ return info->capability;
+}
+
+/**
+ * \brief Get the type bits of a port_info container
+ * \param info port_info container
+ * \return port type bits
+ */
+unsigned int snd_seq_port_info_get_type(const snd_seq_port_info_t *info)
+{
+ assert(info);
+ return info->type;
+}
+
+/**
+ * \brief Get the number of read subscriptions of a port_info container
+ * \param info port_info container
+ * \return number of read subscriptions
+ */
+int snd_seq_port_info_get_read_use(const snd_seq_port_info_t *info)
+{
+ assert(info);
+ return info->read_use;
+}
+
+/**
+ * \brief Get the number of write subscriptions of a port_info container
+ * \param info port_info container
+ * \return number of write subscriptions
+ */
+int snd_seq_port_info_get_write_use(const snd_seq_port_info_t *info)
+{
+ assert(info);
+ return info->write_use;
+}
+
+/**
+ * \brief Get the midi channels of a port_info container
+ * \param info port_info container
+ * \return number of midi channels (default 0)
+ */
+int snd_seq_port_info_get_midi_channels(const snd_seq_port_info_t *info)
+{
+ assert(info);
+ return info->midi_channels;
+}
+
+/**
+ * \brief Get the midi voices of a port_info container
+ * \param info port_info container
+ * \return number of midi voices (default 0)
+ */
+int snd_seq_port_info_get_midi_voices(const snd_seq_port_info_t *info)
+{
+ assert(info);
+ return info->midi_voices;
+}
+
+/**
+ * \brief Get the synth voices of a port_info container
+ * \param info port_info container
+ * \return number of synth voices (default 0)
+ */
+int snd_seq_port_info_get_synth_voices(const snd_seq_port_info_t *info)
+{
+ assert(info);
+ return info->synth_voices;
+}
+
+/**
+ * \brief Get the port-specified mode of a port_info container
+ * \param info port_info container
+ * \return 1 if port id is specified at creation
+ */
+int snd_seq_port_info_get_port_specified(const snd_seq_port_info_t *info)
+{
+ assert(info);
+ return (info->flags & SNDRV_SEQ_PORT_FLG_GIVEN_PORT) ? 1 : 0;
+}
+
+/**
+ * \brief Set the client id of a port_info container
+ * \param info port_info container
+ * \param client client id
+ */
+void snd_seq_port_info_set_client(snd_seq_port_info_t *info, int client)
+{
+ assert(info);
+ info->addr.client = client;
+}
+
+/**
+ * \brief Set the port id of a port_info container
+ * \param info port_info container
+ * \param port port id
+ */
+void snd_seq_port_info_set_port(snd_seq_port_info_t *info, int port)
+{
+ assert(info);
+ info->addr.port = port;
+}
+
+/**
+ * \brief Set the client/port address of a port_info container
+ * \param info port_info container
+ * \param addr client/port address
+ */
+void snd_seq_port_info_set_addr(snd_seq_port_info_t *info, const snd_seq_addr_t *addr)
+{
+ assert(info);
+ info->addr = *addr;
+}
+
+/**
+ * \brief Set the name of a port_info container
+ * \param info port_info container
+ * \param name name string
+ */
+void snd_seq_port_info_set_name(snd_seq_port_info_t *info, const char *name)
+{
+ assert(info && name);
+ strncpy(info->name, name, sizeof(info->name));
+}
+
+/**
+ * \brief set the capability bits of a port_info container
+ * \param info port_info container
+ * \param capability capability bits
+ */
+void snd_seq_port_info_set_capability(snd_seq_port_info_t *info, unsigned int capability)
+{
+ assert(info);
+ info->capability = capability;
+}
+
+/**
+ * \brief Get the type bits of a port_info container
+ * \param info port_info container
+ * \return port type bits
+ */
+void snd_seq_port_info_set_type(snd_seq_port_info_t *info, unsigned int type)
+{
+ assert(info);
+ info->type = type;
+}
+
+/**
+ * \brief set the midi channels of a port_info container
+ * \param info port_info container
+ * \param channels midi channels (default 0)
+ */
+void snd_seq_port_info_set_midi_channels(snd_seq_port_info_t *info, int channels)
+{
+ assert(info);
+ info->midi_channels = channels;
+}
+
+/**
+ * \brief set the midi voices of a port_info container
+ * \param info port_info container
+ * \param voices midi voices (default 0)
+ */
+void snd_seq_port_info_set_midi_voices(snd_seq_port_info_t *info, int voices)
+{
+ assert(info);
+ info->midi_voices = voices;
+}
+
+/**
+ * \brief set the synth voices of a port_info container
+ * \param info port_info container
+ * \param voices synth voices (default 0)
+ */
+void snd_seq_port_info_set_synth_voices(snd_seq_port_info_t *info, int voices)
+{
+ assert(info);
+ info->synth_voices = voices;
+}
+
+/**
+ * \brief Set the port-specifiied mode of a port_info container
+ * \param info port_info container
+ * \param bool non-zero if specifying the port id at creation
+ */
+void snd_seq_port_info_set_port_specified(snd_seq_port_info_t *info, int bool)
+{
+ assert(info);
+ if (bool)
+ info->flags |= SNDRV_SEQ_PORT_FLG_GIVEN_PORT;
+ else
+ info->flags &= ~SNDRV_SEQ_PORT_FLG_GIVEN_PORT;
+}
+
+
+/**
+ * \brief create a sequencer port on the current client
+ * \param seq sequencer handle
+ * \param port port information for the new port
+ * \return 0 on success otherwise a negative error code
+ *
+ * Creates a sequencer port on the current client.
+ * The attributes of created port is specified in \a info argument.
+ *
+ * The client field in \a info argument is overwritten with the current client id.
+ * The port id to be created can be specified via #snd_seq_port_info_set_port_specified.
+ * You can get the created port id by reading the port pointer via #snd_seq_port_info_get_port.
+ *
+ * Each port has the capability bit-masks to specify the access capability
+ * of the port from other clients.
+ * The capability bit flags are defined as follows:
+ * - #SND_SEQ_PORT_CAP_READ Readable from this port
+ * - #SND_SEQ_PORT_CAP_WRITE Writable to this port.
+ * - #SND_SEQ_PORT_CAP_SYNC_READ For synchronization (not implemented)
+ * - #SND_SEQ_PORT_CAP_SYNC_WRITE For synchronization (not implemented)
+ * - #SND_SEQ_PORT_CAP_DUPLEX Read/write duplex access is supported
+ * - #SND_SEQ_PORT_CAP_SUBS_READ Read subscription is allowed
+ * - #SND_SEQ_PORT_CAP_SUBS_WRITE Write subscription is allowed
+ * - #SND_SEQ_PORT_CAP_SUBS_NO_EXPORT Subscription management from 3rd client is disallowed
+ *
+ * Each port has also the type bitmasks defined as follows:
+ * - #SND_SEQ_PORT_TYPE_SPECIFIC Hardware specific port
+ * - #SND_SEQ_PORT_TYPE_MIDI_GENERIC Generic MIDI device
+ * - #SND_SEQ_PORT_TYPE_MIDI_GM General MIDI compatible device
+ * - #SND_SEQ_PORT_TYPE_MIDI_GS GS compatible device
+ * - #SND_SEQ_PORT_TYPE_MIDI_XG XG compatible device
+ * - #SND_SEQ_PORT_TYPE_MIDI_MT32 MT-32 compatible device
+ * - #SND_SEQ_PORT_TYPE_SYNTH Synth device
+ * - #SND_SEQ_PORT_TYPE_DIRECT_SAMPLE Sampling device (supporting download)
+ * - #SND_SEQ_PORT_TYPE_SAMPLE Sampling device (sample can be downloaded at any time)
+ * - #SND_SEQ_PORT_TYPE_APPLICATION Application (suquencer/editor)
+ *
+ * A port may contain speicific midi channels, midi voices and synth voices.
+ * These values could be zero as default.
+ */
+int snd_seq_create_port(snd_seq_t *seq, snd_seq_port_info_t * port)
+{
+ assert(seq && port);
+ port->addr.client = seq->client;
+ return seq->ops->create_port(seq, port);
+}
+
+/**
+ * \brief delete a sequencer port on the current client
+ * \param seq sequencer handle
+ * \param port port to be deleted
+ * \return 0 on success otherwise a negative error code
+ *
+ * Deletes the existing sequencer port on the current client.
+ */
+int snd_seq_delete_port(snd_seq_t *seq, int port)
+{
+ snd_seq_port_info_t pinfo;
+ assert(seq);
+ memset(&pinfo, 0, sizeof(pinfo));
+ pinfo.addr.client = seq->client;
+ pinfo.addr.port = port;
+ return seq->ops->delete_port(seq, &pinfo);
+}
+
+/**
+ * \brief obatin the information of a port on an arbitrary client
+ * \param seq sequencer handle
+ * \param client client id to get
+ * \param port port id to get
+ * \param info pointer information returns
+ * \return 0 on success otherwise a negative error code
+ */
+int snd_seq_get_any_port_info(snd_seq_t *seq, int client, int port, snd_seq_port_info_t * info)
+{
+ assert(seq && info && client >= 0 && port >= 0);
+ memset(info, 0, sizeof(snd_seq_port_info_t));
+ info->addr.client = client;
+ info->addr.port = port;
+ return seq->ops->get_port_info(seq, info);
+}
+
+/**
+ * \brief obatin the information of a port on the current client
+ * \param seq sequencer handle
+ * \param port port id to get
+ * \param info pointer information returns
+ * \return 0 on success otherwise a negative error code
+ */
+int snd_seq_get_port_info(snd_seq_t *seq, int port, snd_seq_port_info_t * info)
+{
+ return snd_seq_get_any_port_info(seq, seq->client, port, info);
+}
+
+/**
+ * \brief set the information of a port on the current client
+ * \param seq sequencer handle
+ * \param port port to be set
+ * \param info port information to be set
+ * \return 0 on success otherwise a negative error code
+ */
+int snd_seq_set_port_info(snd_seq_t *seq, int port, snd_seq_port_info_t * info)
+{
+ assert(seq && info && port >= 0);
+ info->addr.client = seq->client;
+ info->addr.port = port;
+ return seq->ops->set_port_info(seq, info);
+}
+
+/**
+ * \brief query the next matching port
+ * \param seq sequencer handle
+ * \param info query pattern and result
+
+ * Queries the next matching port on the client specified in
+ * \a info argument.
+ * The search begins at the next port specified in
+ * port field of \a info argument.
+ * For finding the first port at a certain client, give -1.
+ *
+ * If a matching port is found, its attributes are stored on
+ * \a info and function returns zero.
+ * Otherwise, a negative error code is returned.
+ */
+int snd_seq_query_next_port(snd_seq_t *seq, snd_seq_port_info_t *info)
+{
+ assert(seq && info);
+ return seq->ops->query_next_port(seq, info);
+}
+
+
+/*----------------------------------------------------------------*/
+
+/*
+ * subscription
+ */
+
+
+/**
+ * \brief get size of #snd_seq_port_subscribe_t
+ * \return size in bytes
+ */
+size_t snd_seq_port_subscribe_sizeof()
+{
+ return sizeof(snd_seq_port_subscribe_t);
+}
+
+/**
+ * \brief allocate an empty #snd_seq_port_subscribe_t using standard malloc
+ * \param ptr returned pointer
+ * \return 0 on success otherwise negative error code
+ */
+int snd_seq_port_subscribe_malloc(snd_seq_port_subscribe_t **ptr)
+{
+ assert(ptr);
+ *ptr = calloc(1, sizeof(snd_seq_port_subscribe_t));
+ if (!*ptr)
+ return -ENOMEM;
+ return 0;
+}
+
+/**
+ * \brief frees a previously allocated #snd_seq_port_subscribe_t
+ * \param pointer to object to free
+ */
+void snd_seq_port_subscribe_free(snd_seq_port_subscribe_t *obj)
+{
+ free(obj);
+}
+
+/**
+ * \brief copy one #snd_seq_port_subscribe_t to another
+ * \param dst pointer to destination
+ * \param src pointer to source
+ */
+void snd_seq_port_subscribe_copy(snd_seq_port_subscribe_t *dst, const snd_seq_port_subscribe_t *src)
+{
+ assert(dst && src);
+ *dst = *src;
+}
+
+
+/**
+ * \brief Get sender address of a port_subscribe container
+ * \param info port_subscribe container
+ * \param addr sender address
+ */
+const snd_seq_addr_t *snd_seq_port_subscribe_get_sender(const snd_seq_port_subscribe_t *info)
+{
+ assert(info);
+ return &info->sender;
+}
+
+/**
+ * \brief Get destination address of a port_subscribe container
+ * \param info port_subscribe container
+ * \param addr destination address
+ */
+const snd_seq_addr_t *snd_seq_port_subscribe_get_dest(const snd_seq_port_subscribe_t *info)
+{
+ assert(info);
+ return &info->dest;
+}
+
+/**
+ * \brief Get the queue id of a port_subscribe container
+ * \param info port_subscribe container
+ * \return queue id
+ */
+int snd_seq_port_subscribe_get_queue(const snd_seq_port_subscribe_t *info)
+{
+ assert(info);
+ return info->queue;
+}
+
+/**
+ * \brief Get the exclusive mode of a port_subscribe container
+ * \param info port_subscribe container
+ * \return 1 if exclusive mode
+ */
+int snd_seq_port_subscribe_get_exclusive(const snd_seq_port_subscribe_t *info)
+{
+ assert(info);
+ return (info->flags & SNDRV_SEQ_PORT_SUBS_EXCLUSIVE) ? 1 : 0;
+}
+
+/**
+ * \brief Get the time-update mode of a port_subscribe container
+ * \param info port_subscribe container
+ * \return 1 if update timestamp
+ */
+int snd_seq_port_subscribe_get_time_update(const snd_seq_port_subscribe_t *info)
+{
+ assert(info);
+ return (info->flags & SNDRV_SEQ_PORT_SUBS_TIMESTAMP) ? 1 : 0;
+}
+
+/**
+ * \brief Get the real-time update mode of a port_subscribe container
+ * \param info port_subscribe container
+ * \return 1 if real-time update mode
+ */
+int snd_seq_port_subscribe_get_time_real(const snd_seq_port_subscribe_t *info)
+{
+ assert(info);
+ return (info->flags & SNDRV_SEQ_PORT_SUBS_TIME_REAL) ? 1 : 0;
+}
+
+/**
+ * \brief Set sender address of a port_subscribe container
+ * \param info port_subscribe container
+ * \param addr sender address
+ */
+void snd_seq_port_subscribe_set_sender(snd_seq_port_subscribe_t *info, const snd_seq_addr_t *addr)
+{
+ assert(info);
+ memcpy(&info->sender, addr, sizeof(*addr));
+}
+
+/**
+ * \brief Set destination address of a port_subscribe container
+ * \param info port_subscribe container
+ * \param addr destination address
+ */
+void snd_seq_port_subscribe_set_dest(snd_seq_port_subscribe_t *info, const snd_seq_addr_t *addr)
+{
+ assert(info);
+ memcpy(&info->dest, addr, sizeof(*addr));
+}
+
+/**
+ * \brief Set the queue id of a port_subscribe container
+ * \param info port_subscribe container
+ * \param q queue id
+ */
+void snd_seq_port_subscribe_set_queue(snd_seq_port_subscribe_t *info, int q)
+{
+ assert(info);
+ info->queue = q;
+}
+
+/**
+ * \brief Set the exclusive mode of a port_subscribe container
+ * \param info port_subscribe container
+ * \param bool non-zero to enable
+ */
+void snd_seq_port_subscribe_set_exclusive(snd_seq_port_subscribe_t *info, int bool)
+{
+ assert(info);
+ if (bool)
+ info->flags |= SNDRV_SEQ_PORT_SUBS_EXCLUSIVE;
+ else
+ info->flags &= ~SNDRV_SEQ_PORT_SUBS_EXCLUSIVE;
+}
+
+/**
+ * \brief Set the time-update mode of a port_subscribe container
+ * \param info port_subscribe container
+ * \param bool non-zero to enable
+ */
+void snd_seq_port_subscribe_set_time_update(snd_seq_port_subscribe_t *info, int bool)
+{
+ assert(info);
+ if (bool)
+ info->flags |= SNDRV_SEQ_PORT_SUBS_TIMESTAMP;
+ else
+ info->flags &= ~SNDRV_SEQ_PORT_SUBS_TIMESTAMP;
+}
+
+/**
+ * \brief Set the real-time mode of a port_subscribe container
+ * \param info port_subscribe container
+ * \param bool non-zero to enable
+ */
+void snd_seq_port_subscribe_set_time_real(snd_seq_port_subscribe_t *info, int bool)
+{
+ assert(info);
+ if (bool)
+ info->flags |= SNDRV_SEQ_PORT_SUBS_TIME_REAL;
+ else
+ info->flags &= ~SNDRV_SEQ_PORT_SUBS_TIME_REAL;
+}
+
+
+/**
+ * \brief obtain subscription information
+ * \param seq sequencer handle
+ * \param sub pointer to return the subscription information
+ * \return 0 on success otherwise a negative error code
+ */
+int snd_seq_get_port_subscription(snd_seq_t *seq, snd_seq_port_subscribe_t * sub)
+{
+ assert(seq && sub);
+ return seq->ops->get_port_subscription(seq, sub);
+}
+
+/**
+ * \brief subscribe a port connection
+ * \param seq sequencer handle
+ * \param sub subscription information
+ * \return 0 on success otherwise a negative error code
+ *
+ * Subscribes a connection between two ports.
+ * The subscription information is stored in sub argument.
+ */
+int snd_seq_subscribe_port(snd_seq_t *seq, snd_seq_port_subscribe_t * sub)
+{
+ assert(seq && sub);
+ return seq->ops->subscribe_port(seq, sub);
+}
+
+/**
+ * \brief unsubscribe a connection between ports
+ * \param seq sequencer handle
+ * \param sub subscription information to disconnect
+ * \return 0 on success otherwise a negative error code
+ *
+ * Unsubscribes a connection between two ports,
+ * described in sender and dest fields in sub argument.
+ */
+int snd_seq_unsubscribe_port(snd_seq_t *seq, snd_seq_port_subscribe_t * sub)
+{
+ assert(seq && sub);
+ return seq->ops->unsubscribe_port(seq, sub);
+}
+
+
+/**
+ * \brief get size of #snd_seq_query_subscribe_t
+ * \return size in bytes
+ */
+size_t snd_seq_query_subscribe_sizeof()
+{
+ return sizeof(snd_seq_query_subscribe_t);
+}
+
+/**
+ * \brief allocate an empty #snd_seq_query_subscribe_t using standard malloc
+ * \param ptr returned pointer
+ * \return 0 on success otherwise negative error code
+ */
+int snd_seq_query_subscribe_malloc(snd_seq_query_subscribe_t **ptr)
+{
+ assert(ptr);
+ *ptr = calloc(1, sizeof(snd_seq_query_subscribe_t));
+ if (!*ptr)
+ return -ENOMEM;
+ return 0;
+}
+
+/**
+ * \brief frees a previously allocated #snd_seq_query_subscribe_t
+ * \param pointer to object to free
+ */
+void snd_seq_query_subscribe_free(snd_seq_query_subscribe_t *obj)
+{
+ free(obj);
+}
+
+/**
+ * \brief copy one #snd_seq_query_subscribe_t to another
+ * \param dst pointer to destination
+ * \param src pointer to source
+ */
+void snd_seq_query_subscribe_copy(snd_seq_query_subscribe_t *dst, const snd_seq_query_subscribe_t *src)
+{
+ assert(dst && src);
+ *dst = *src;
+}
+
+
+/**
+ * \brief Get the client id of a query_subscribe container
+ * \param info query_subscribe container
+ * \return client id
+ */
+int snd_seq_query_subscribe_get_client(const snd_seq_query_subscribe_t *info)
+{
+ assert(info);
+ return info->root.client;
+}
+
+/**
+ * \brief Get the port id of a query_subscribe container
+ * \param info query_subscribe container
+ * \return port id
+ */
+int snd_seq_query_subscribe_get_port(const snd_seq_query_subscribe_t *info)
+{
+ assert(info);
+ return info->root.port;
+}
+
+/**
+ * \brief Get the client/port address of a query_subscribe container
+ * \param info query_subscribe container
+ * \return client/port address pointer
+ */
+const snd_seq_addr_t *snd_seq_query_subscribe_get_root(const snd_seq_query_subscribe_t *info)
+{
+ assert(info);
+ return &info->root;
+}
+
+/**
+ * \brief Get the query type of a query_subscribe container
+ * \param info query_subscribe container
+ * \return query type
+ */
+snd_seq_query_subs_type_t snd_seq_query_subscribe_get_type(const snd_seq_query_subscribe_t *info)
+{
+ assert(info);
+ return info->type;
+}
+
+/**
+ * \brief Get the index of subscriber of a query_subscribe container
+ * \param info query_subscribe container
+ * \return subscriber's index
+ */
+int snd_seq_query_subscribe_get_index(const snd_seq_query_subscribe_t *info)
+{
+ assert(info);
+ return info->index;
+}
+
+/**
+ * \brief Get the number of subscriptiosn of a query_subscribe container
+ * \param info query_subscribe container
+ * \return number of subscriptions
+ */
+int snd_seq_query_subscribe_get_num_subs(const snd_seq_query_subscribe_t *info)
+{
+ assert(info);
+ return info->num_subs;
+}
+
+/**
+ * \brief Get the address of subscriber of a query_subscribe container
+ * \param info query_subscribe container
+ * \return subscriber's address pointer
+ */
+const snd_seq_addr_t *snd_seq_query_subscribe_get_addr(const snd_seq_query_subscribe_t *info)
+{
+ assert(info);
+ return &info->addr;
+}
+
+/**
+ * \brief Get the queue id of subscriber of a query_subscribe container
+ * \param info query_subscribe container
+ * \return subscriber's queue id
+ */
+int snd_seq_query_subscribe_get_queue(const snd_seq_query_subscribe_t *info)
+{
+ assert(info);
+ return info->queue;
+}
+
+/**
+ * \brief Get the exclusive mode of a query_subscribe container
+ * \param info query_subscribe container
+ * \return 1 if exclusive mode
+ */
+int snd_seq_query_subscribe_get_exclusive(const snd_seq_query_subscribe_t *info)
+{
+ assert(info);
+ return (info->flags & SNDRV_SEQ_PORT_SUBS_EXCLUSIVE) ? 1 : 0;
+}
+
+/**
+ * \brief Get the time-update mode of a query_subscribe container
+ * \param info query_subscribe container
+ * \return 1 if update timestamp
+ */
+int snd_seq_query_subscribe_get_time_update(const snd_seq_query_subscribe_t *info)
+{
+ assert(info);
+ return (info->flags & SNDRV_SEQ_PORT_SUBS_TIMESTAMP) ? 1 : 0;
+}
+
+/**
+ * \brief Get the real-time update mode of a query_subscribe container
+ * \param info query_subscribe container
+ * \return 1 if real-time update mode
+ */
+int snd_seq_query_subscribe_get_time_real(const snd_seq_query_subscribe_t *info)
+{
+ assert(info);
+ return (info->flags & SNDRV_SEQ_PORT_SUBS_TIMESTAMP) ? 1 : 0;
+}
+
+/**
+ * \brief Set the client id of a query_subscribe container
+ * \param info query_subscribe container
+ * \param client client id
+ */
+void snd_seq_query_subscribe_set_client(snd_seq_query_subscribe_t *info, int client)
+{
+ assert(info);
+ info->root.client = client;
+}
+
+/**
+ * \brief Set the port id of a query_subscribe container
+ * \param info query_subscribe container
+ * \param port port id
+ */
+void snd_seq_query_subscribe_set_port(snd_seq_query_subscribe_t *info, int port)
+{
+ assert(info);
+ info->root.port = port;
+}
+
+/**
+ * \brief Set the client/port address of a query_subscribe container
+ * \param info query_subscribe container
+ * \param addr client/port address pointer
+ */
+void snd_seq_query_subscribe_set_root(snd_seq_query_subscribe_t *info, const snd_seq_addr_t *addr)
+{
+ assert(info);
+ info->root = *addr;
+}
+
+/**
+ * \brief Set the query type of a query_subscribe container
+ * \param info query_subscribe container
+ * \param type query type
+ */
+void snd_seq_query_subscribe_set_type(snd_seq_query_subscribe_t *info, snd_seq_query_subs_type_t type)
+{
+ assert(info);
+ info->type = type;
+}
+
+/**
+ * \brief Set the subscriber's index to be queried
+ * \param info query_subscribe container
+ * \param index index to be queried
+ */
+void snd_seq_query_subscribe_set_index(snd_seq_query_subscribe_t *info, int index)
+{
+ assert(info);
+ info->index = index;
+}
+
+
+/**
+ * \brief query port subscriber list
+ * \param seq sequencer handle
+ * \param subs subscription to query
+ * \return 0 on success otherwise a negative error code
+ *
+ * Queries the subscribers accessing to a port.
+ * The query information is specified in subs argument.
+ *
+ */
+int snd_seq_query_port_subscribers(snd_seq_t *seq, snd_seq_query_subscribe_t * subs)
+{
+ assert(seq && subs);
+ return seq->ops->query_port_subscribers(seq, subs);
+}
+
+/*----------------------------------------------------------------*/
+
+/*
+ * queue handlers
+ */
+
+/**
+ * \brief get size of #snd_seq_queue_info_t
+ * \return size in bytes
+ */
+size_t snd_seq_queue_info_sizeof()
+{
+ return sizeof(snd_seq_queue_info_t);
+}
+
+/**
+ * \brief allocate an empty #snd_seq_queue_info_t using standard malloc
+ * \param ptr returned pointer
+ * \return 0 on success otherwise negative error code
+ */
+int snd_seq_queue_info_malloc(snd_seq_queue_info_t **ptr)
+{
+ assert(ptr);
+ *ptr = calloc(1, sizeof(snd_seq_queue_info_t));
+ if (!*ptr)
+ return -ENOMEM;
+ return 0;
+}
+
+/**
+ * \brief frees a previously allocated #snd_seq_queue_info_t
+ * \param pointer to object to free
+ */
+void snd_seq_queue_info_free(snd_seq_queue_info_t *obj)
+{
+ free(obj);
+}
+
+/**
+ * \brief copy one #snd_seq_queue_info_t to another
+ * \param dst pointer to destination
+ * \param src pointer to source
+ */
+void snd_seq_queue_info_copy(snd_seq_queue_info_t *dst, const snd_seq_queue_info_t *src)
+{
+ assert(dst && src);
+ *dst = *src;
+}
+
+
+/**
+ * \brief Get the queue id of a queue_info container
+ * \param info queue_info container
+ * \return queue id
+ */
+int snd_seq_queue_info_get_queue(const snd_seq_queue_info_t *info)
+{
+ assert(info);
+ return info->queue;
+}
+
+/**
+ * \brief Get the name of a queue_info container
+ * \param info queue_info container
+ * \return name string
+ */
+const char *snd_seq_queue_info_get_name(const snd_seq_queue_info_t *info)
+{
+ assert(info);
+ return info->name;
+}
+
+/**
+ * \brief Get the owner client id of a queue_info container
+ * \param info queue_info container
+ * \return owner client id
+ */
+int snd_seq_queue_info_get_owner(const snd_seq_queue_info_t *info)
+{
+ assert(info);
+ return info->owner;
+}
+
+/**
+ * \brief Get the lock status of a queue_info container
+ * \param info queue_info container
+ * \return lock status --- non-zero = locked
+ */
+int snd_seq_queue_info_get_locked(const snd_seq_queue_info_t *info)
+{
+ assert(info);
+ return info->locked;
+}
+
+/**
+ * \brief Get the conditional bit flags of a queue_info container
+ * \param info queue_info container
+ * \return conditional bit flags
+ */
+unsigned int snd_seq_queue_info_get_flags(const snd_seq_queue_info_t *info)
+{
+ assert(info);
+ return info->flags;
+}
+
+/**
+ * \brief Set the name of a queue_info container
+ * \param info queue_info container
+ * \param name name string
+ */
+void snd_seq_queue_info_set_name(snd_seq_queue_info_t *info, const char *name)
+{
+ assert(info && name);
+ strncpy(info->name, name, sizeof(info->name));
+}
+
+/**
+ * \brief Set the owner client id of a queue_info container
+ * \param info queue_info container
+ * \param owner client id
+ */
+void snd_seq_queue_info_set_owner(snd_seq_queue_info_t *info, int owner)
+{
+ assert(info);
+ info->owner = owner;
+}
+
+/**
+ * \brief Set the lock status of a queue_info container
+ * \param info queue_info container
+ * \param locked lock status
+ */
+void snd_seq_queue_info_set_locked(snd_seq_queue_info_t *info, int locked)
+{
+ assert(info);
+ info->locked = locked;
+}
+
+/**
+ * \brief Set the conditional bit flags of a queue_info container
+ * \param info queue_info container
+ * \param flags contidional bit flags
+ */
+void snd_seq_queue_info_set_flags(snd_seq_queue_info_t *info, unsigned int flags)
+{
+ assert(info);
+ info->flags = flags;
+}
+
+
+/**
+ * \brief create a queue
+ * \param seq sequencer handle
+ * \param info queue information to initialize
+ * \return the queue id (zero or positive) on success otherwise a negative error code
+ */
+int snd_seq_create_queue(snd_seq_t *seq, snd_seq_queue_info_t *info)
+{
+ int err;
+ assert(seq && info);
+ info->owner = seq->client;
+ err = seq->ops->create_queue(seq, info);
+ if (err < 0)
+ return err;
+ return info->queue;
+}
+
+/**
+ * \brief allocate a queue with the speicified name
* \param seq sequencer handle
* \param name the name of the new queue
* \return the queue id (zero or positive) on success otherwise a negative error code
+ */
+int snd_seq_alloc_named_queue(snd_seq_t *seq, const char *name)
+{
+ snd_seq_queue_info_t info;
+ memset(&info, 0, sizeof(info));
+ info.locked = 1;
+ if (name)
+ strncpy(info.name, name, sizeof(info.name) - 1);
+ return snd_seq_create_queue(seq, &info);
+}
+
+/**
+ * \brief allocate a queue
+ * \param seq sequencer handle
+ * \return the queue id (zero or positive) on success otherwise a negative error code
+ */
+int snd_seq_alloc_queue(snd_seq_t *seq)
+{
+ return snd_seq_alloc_named_queue(seq, NULL);
+}
+
+/**
+ * \breif delete the specified queue
+ * \param seq sequencer handle
+ * \param q queue id to delete
+ * \return 0 on success otherwise a negative error code
+ */
+int snd_seq_free_queue(snd_seq_t *seq, int q)
+{
+ snd_seq_queue_info_t info;
+ assert(seq);
+ memset(&info, 0, sizeof(info));
+ info.queue = q;
+ return seq->ops->delete_queue(seq, &info);
+}
+
+/**
+ * \brief obtain queue attributes
+ * \param seq sequencer handle
+ * \param q queue id to query
+ * \param info information returned
+ * \return 0 on success otherwise a negative error code
+ */
+int snd_seq_get_queue_info(snd_seq_t *seq, int q, snd_seq_queue_info_t *info)
+{
+ assert(seq && info);
+ info->queue = q;
+ return seq->ops->get_queue_info(seq, info);
+}
+
+/**
+ * \brief change the queue attributes
+ * \param seq sequencer handle
+ * \param q queue id to change
+ * \param info information changed
+ * \return 0 on success otherwise a negative error code
+ */
+int snd_seq_set_queue_info(snd_seq_t *seq, int q, snd_seq_queue_info_t *info)
+{
+ assert(seq && info);
+ info->queue = q;
+ return seq->ops->set_queue_info(seq, info);
+}
+
+/**
+ * \brief query the matching queue with the specified name
+ * \param seq sequencer handle
+ * \param name the name string to query
+ * \return the queue id if found or negative error code
+ *
+ * Searches the matching queue with the specified name string.
+ */
+int snd_seq_query_named_queue(snd_seq_t *seq, const char *name)
+{
+ int err;
+ snd_seq_queue_info_t info;
+ assert(seq && name);
+ strncpy(info.name, name, sizeof(info.name));
+ err = seq->ops->get_named_queue(seq, &info);
+ if (err < 0)
+ return err;
+ return info.queue;
+}
+
+/**
+ * \brief Get the queue usage flag to the client
+ * \param seq sequencer handle
+ * \param q queue id
+ * \param client client id
+ * \return 1 = client is allowed to access the queue, 0 = not allowed,
+ * otherwise a negative error code
+ */
+int snd_seq_get_queue_usage(snd_seq_t *seq, int q)
+{
+ struct sndrv_seq_queue_client info;
+ int err;
+ assert(seq);
+ memset(&info, 0, sizeof(info));
+ info.queue = q;
+ info.client = seq->client;
+ if ((err = seq->ops->get_queue_client(seq, &info)) < 0)
+ return err;
+ return info.used;
+}
+
+/*
+ * \brief Set the queue usage flag to the client
+ * \param seq sequencer handle
+ * \param q queue id
+ * \param client client id
+ * \param used non-zero if the client is allowed
+ * \return 0 on success otherwise a negative error code
+ */
+int snd_seq_set_queue_usage(snd_seq_t *seq, int q, int used)
+{
+ struct sndrv_seq_queue_client info;
+ assert(seq);
+ memset(&info, 0, sizeof(info));
+ info.queue = q;
+ info.client = seq->client;
+ info.used = used ? 1 : 0;
+ return seq->ops->set_queue_client(seq, &info);
+}
+
+
+/**
+ * \brief get size of #snd_seq_queue_status_t
+ * \return size in bytes
+ */
+size_t snd_seq_queue_status_sizeof()
+{
+ return sizeof(snd_seq_queue_status_t);
+}
+
+/**
+ * \brief allocate an empty #snd_seq_queue_status_t using standard malloc
+ * \param ptr returned pointer
+ * \return 0 on success otherwise negative error code
+ */
+int snd_seq_queue_status_malloc(snd_seq_queue_status_t **ptr)
+{
+ assert(ptr);
+ *ptr = calloc(1, sizeof(snd_seq_queue_status_t));
+ if (!*ptr)
+ return -ENOMEM;
+ return 0;
+}
+
+/**
+ * \brief frees a previously allocated #snd_seq_queue_status_t
+ * \param pointer to object to free
+ */
+void snd_seq_queue_status_free(snd_seq_queue_status_t *obj)
+{
+ free(obj);
+}
+
+/**
+ * \brief copy one #snd_seq_queue_status_t to another
+ * \param dst pointer to destination
+ * \param src pointer to source
+ */
+void snd_seq_queue_status_copy(snd_seq_queue_status_t *dst, const snd_seq_queue_status_t *src)
+{
+ assert(dst && src);
+ *dst = *src;
+}
+
+
+/**
+ * \brief Get the queue id of a queue_status container
+ * \param info queue_status container
+ * \return queue id
+ */
+int snd_seq_queue_status_get_queue(const snd_seq_queue_status_t *info)
+{
+ assert(info);
+ return info->queue;
+}
+
+/**
+ * \brief Get the number of events of a queue_status container
+ * \param info queue_status container
+ * \return number of events
+ */
+int snd_seq_queue_status_get_events(const snd_seq_queue_status_t *info)
+{
+ assert(info);
+ return info->events;
+}
+
+/**
+ * \brief Get the tick time of a queue_status container
+ * \param info queue_status container
+ * \return tick time
+ */
+snd_seq_tick_time_t snd_seq_queue_status_get_tick_time(const snd_seq_queue_status_t *info)
+{
+ assert(info);
+ return info->tick;
+}
+
+/**
+ * \brief Get the real time of a queue_status container
+ * \param info queue_status container
+ * \param time real time
+ */
+const snd_seq_real_time_t *snd_seq_queue_status_get_real_time(const snd_seq_queue_status_t *info)
+{
+ assert(info);
+ return &info->time;
+}
+
+/**
+ * \brief Get the running status bits of a queue_status container
+ * \param info queue_status container
+ * \return running status bits
+ */
+unsigned int snd_seq_queue_status_get_status(const snd_seq_queue_status_t *info)
+{
+ assert(info);
+ return info->running;
+}
+
+
+/**
+ * \brief obtain the running state of the queue
+ * \param seq sequencer handle
+ * \param q queue id to query
+ * \param status pointer to store the current status
+ * \return 0 on success otherwise a negative error code
+ *
+ * Obtains the running state of the specified queue q.
+ */
+int snd_seq_get_queue_status(snd_seq_t *seq, int q, snd_seq_queue_status_t * status)
+{
+ assert(seq && status);
+ memset(status, 0, sizeof(snd_seq_queue_status_t));
+ status->queue = q;
+ return seq->ops->get_queue_status(seq, status);
+}
+
+
+/**
+ * \brief get size of #snd_seq_queue_tempo_t
+ * \return size in bytes
+ */
+size_t snd_seq_queue_tempo_sizeof()
+{
+ return sizeof(snd_seq_queue_tempo_t);
+}
+
+/**
+ * \brief allocate an empty #snd_seq_queue_tempo_t using standard malloc
+ * \param ptr returned pointer
+ * \return 0 on success otherwise negative error code
+ */
+int snd_seq_queue_tempo_malloc(snd_seq_queue_tempo_t **ptr)
+{
+ assert(ptr);
+ *ptr = calloc(1, sizeof(snd_seq_queue_tempo_t));
+ if (!*ptr)
+ return -ENOMEM;
+ return 0;
+}
+
+/**
+ * \brief frees a previously allocated #snd_seq_queue_tempo_t
+ * \param pointer to object to free
*/
-int snd_seq_alloc_sync_queue(snd_seq_t *seq, const char *name)
+void snd_seq_queue_tempo_free(snd_seq_queue_tempo_t *obj)
{
- snd_seq_queue_info_t info;
- memset(&info, 0, sizeof(info));
- info.locked = 1;
- if (name)
- strncpy(info.name, name, sizeof(info.name) - 1);
- info.flags = SND_SEQ_QUEUE_FLG_SYNC;
- return snd_seq_create_queue(seq, &info);
+ free(obj);
}
-#endif
/**
- * \breif delete the specified queue
- * \param seq sequencer handle
- * \param q queue id to delete
- * \return 0 on success otherwise a negative error code
+ * \brief copy one #snd_seq_queue_tempo_t to another
+ * \param dst pointer to destination
+ * \param src pointer to source
*/
-int snd_seq_free_queue(snd_seq_t *seq, int q)
+void snd_seq_queue_tempo_copy(snd_seq_queue_tempo_t *dst, const snd_seq_queue_tempo_t *src)
{
- snd_seq_queue_info_t info;
- assert(seq);
- memset(&info, 0, sizeof(info));
- info.queue = q;
- return seq->ops->delete_queue(seq, &info);
+ assert(dst && src);
+ *dst = *src;
}
+
/**
- * \brief obtain queue attributes
- * \param seq sequencer handle
- * \param q queue id to query
- * \param info information returned
- * \return 0 on success otherwise a negative error code
+ * \brief Get the queue id of a queue_status container
+ * \param info queue_status container
+ * \return queue id
*/
-int snd_seq_get_queue_info(snd_seq_t *seq, int q, snd_seq_queue_info_t *info)
+int snd_seq_queue_tempo_get_queue(const snd_seq_queue_tempo_t *info)
{
- assert(seq && info);
- info->queue = q;
- return seq->ops->get_queue_info(seq, info);
+ assert(info);
+ return info->queue;
}
/**
- * \brief change the queue attributes
+ * \brief Get the tempo of a queue_status container
+ * \param info queue_status container
+ * \return tempo value
+ */
+unsigned int snd_seq_queue_tempo_get_tempo(const snd_seq_queue_tempo_t *info)
+{
+ assert(info);
+ return info->tempo;
+}
+
+/**
+ * \brief Get the ppq of a queue_status container
+ * \param info queue_status container
+ * \return ppq value
+ */
+int snd_seq_queue_tempo_get_ppq(const snd_seq_queue_tempo_t *info)
+{
+ assert(info);
+ return info->ppq;
+}
+
+/**
+ * \brief Set the tempo of a queue_status container
+ * \param info queue_status container
+ * \param tempo tempo value
+ */
+void snd_seq_queue_tempo_set_tempo(snd_seq_queue_tempo_t *info, unsigned int tempo)
+{
+ assert(info);
+ info->tempo = tempo;
+}
+
+/**
+ * \brief Set the ppq of a queue_status container
+ * \param info queue_status container
+ * \param ppq ppq value
+ */
+void snd_seq_queue_tempo_set_ppq(snd_seq_queue_tempo_t *info, int ppq)
+{
+ assert(info);
+ info->ppq = ppq;
+}
+
+
+/**
+ * \brief obtain the current tempo of the queue
* \param seq sequencer handle
- * \param q queue id to change
- * \param info information changed
+ * \param q queue id to be queried
+ * \param tempo pointer to store the current tempo
* \return 0 on success otherwise a negative error code
*/
-int snd_seq_set_queue_info(snd_seq_t *seq, int q, snd_seq_queue_info_t *info)
+int snd_seq_get_queue_tempo(snd_seq_t *seq, int q, snd_seq_queue_tempo_t * tempo)
{
- assert(seq && info);
- info->queue = q;
- return seq->ops->set_queue_info(seq, info);
+ assert(seq && tempo);
+ memset(tempo, 0, sizeof(snd_seq_queue_tempo_t));
+ tempo->queue = q;
+ return seq->ops->get_queue_tempo(seq, tempo);
}
/**
- * \brief query the queue with the specified name
+ * \brief set the tempo of the queue
* \param seq sequencer handle
- * \param name name to query
- * \return the queue id if found or a negative error code
+ * \param q queue id to change the tempo
+ * \param tempo tempo information
+ * \return 0 on success otherwise a negative error code
*/
-int snd_seq_get_named_queue(snd_seq_t *seq, const char *name)
+int snd_seq_set_queue_tempo(snd_seq_t *seq, int q, snd_seq_queue_tempo_t * tempo)
{
- int err;
- snd_seq_queue_info_t info;
- assert(seq && name);
- strncpy(info.name, name, sizeof(info.name));
- err = seq->ops->get_named_queue(seq, &info);
- if (err < 0)
- return err;
- return info.queue;
+ assert(seq && tempo);
+ tempo->queue = q;
+ return seq->ops->set_queue_tempo(seq, tempo);
}
+
/*----------------------------------------------------------------*/
-#ifdef SND_SEQ_SYNC_SUPPORT
-/*
- * sync stuff
+/**
+ * \brief get size of #snd_seq_queue_timer_t
+ * \return size in bytes
*/
+size_t snd_seq_queue_timer_sizeof()
+{
+ return sizeof(snd_seq_queue_timer_t);
+}
/**
- * \brief add sync master
- * \param seq sequencer handle
- * \param queue queue id to change
- * \param dest destination of the sync slave
- * \param info sync information
+ * \brief allocate an empty #snd_seq_queue_timer_t using standard malloc
+ * \param ptr returned pointer
+ * \return 0 on success otherwise negative error code
*/
-int snd_seq_add_sync_master(snd_seq_t *seq,
- int queue,
- snd_seq_addr_t *dest,
- snd_seq_queue_sync_t *info)
+int snd_seq_queue_timer_malloc(snd_seq_queue_timer_t **ptr)
{
- snd_seq_port_subscribe_t subs;
+ assert(ptr);
+ *ptr = calloc(1, sizeof(snd_seq_queue_timer_t));
+ if (!*ptr)
+ return -ENOMEM;
+ return 0;
+}
- memset(&subs, 0, sizeof(subs));
- subs.convert_time = 1;
- if (info->format & SND_SEQ_SYNC_TIME)
- subs.realtime = 1;
- subs.sync = 1;
- subs.sender.client = SND_SEQ_CLIENT_SYSTEM;
- subs.sender.port = snd_seq_queue_sync_port(queue);
- subs.dest = *dest;
- subs.queue = queue;
- subs.opt.sync_info = *info;
- return snd_seq_subscribe_port(seq, &subs);
+/**
+ * \brief frees a previously allocated #snd_seq_queue_timer_t
+ * \param pointer to object to free
+ */
+void snd_seq_queue_timer_free(snd_seq_queue_timer_t *obj)
+{
+ free(obj);
}
/**
- * \brief add a standard sync master
- * \param seq sequencer handle
- * \param queue queue id
- * \param dest destination of the sync slave
- * \param format sync format
- * \param time_format time format
- * \param optinfo optional information
+ * \brief copy one #snd_seq_queue_timer_t to another
+ * \param dst pointer to destination
+ * \param src pointer to source
*/
-int snd_seq_add_sync_std_master(snd_seq_t *seq,
- int queue,
- snd_seq_addr_t *dest,
- int format, int time_format,
- unsigned char *optinfo)
+void snd_seq_queue_timer_copy(snd_seq_queue_timer_t *dst, const snd_seq_queue_timer_t *src)
{
- snd_seq_queue_sync_t sync_info;
+ assert(dst && src);
+ *dst = *src;
+}
- memset(&sync_info, 0, sizeof(sync_info));
- sync_info.format = format;
- sync_info.time_format = time_format;
- if (optinfo)
- memcpy(sync_info.info, optinfo, sizeof(sync_info.info));
- return snd_seq_add_sync_master(seq, queue, dest, &sync_info);
+/**
+ * \brief Get the queue id of a queue_timer container
+ * \param info queue_timer container
+ * \return queue id
+ */
+int snd_seq_queue_timer_get_queue(const snd_seq_queue_timer_t *info)
+{
+ assert(info);
+ return info->queue;
}
/**
- * \brief remove the specified sync master
+ * \brief Get the timer type of a queue_timer container
+ * \param info queue_timer container
+ * \return timer type
*/
-int snd_seq_remove_sync_master(snd_seq_t *seq, int queue, snd_seq_addr_t *dest)
+int snd_seq_queue_timer_get_type(const snd_seq_queue_timer_t *info)
{
- snd_seq_port_subscribe_t subs;
-
- memset(&subs, 0, sizeof(subs));
- subs.sync = 1;
- subs.sender.client = SND_SEQ_CLIENT_SYSTEM;
- subs.sender.port = snd_seq_queue_sync_port(queue);
- subs.dest = *dest;
- subs.queue = queue;
- return snd_seq_unsubscribe_port(seq, &subs);
+ assert(info);
+ return info->type;
}
-
/**
- * \brief set the sync slave mode
+ * \brief Get the timer id of a queue_timer container
+ * \param info queue_timer container
+ * \return timer id pointer
*/
-int snd_seq_set_sync_slave(snd_seq_t *seq,
- int queue,
- snd_seq_addr_t *src,
- snd_seq_queue_sync_t *info)
+const snd_timer_id_t *snd_seq_queue_timer_get_id(const snd_seq_queue_timer_t *info)
{
- snd_seq_port_subscribe_t subs;
+ assert(info);
+ return &info->u.alsa.id;
+}
- memset(&subs, 0, sizeof(subs));
- subs.convert_time = 1;
- if (info->format & SND_SEQ_SYNC_TIME)
- subs.realtime = 1;
- subs.sync = 1;
- subs.sender = *src;
- subs.dest.client = SND_SEQ_CLIENT_SYSTEM;
- subs.dest.port = snd_seq_queue_sync_port(queue);
- subs.queue = queue;
- subs.opt.sync_info = *info;
- return snd_seq_subscribe_port(seq, &subs);
+/**
+ * \brief Get the timer resolution of a queue_timer container
+ * \param info queue_timer container
+ * \return timer resolution
+ */
+unsigned int snd_seq_queue_timer_get_resolution(const snd_seq_queue_timer_t *info)
+{
+ assert(info);
+ return info->u.alsa.resolution;
}
/**
- * \brief reset the sync slave mode
+ * \brief Set the timer type of a queue_timer container
+ * \param info queue_timer container
+ * \param type timer type
+ */
+void snd_seq_queue_timer_set_type(snd_seq_queue_timer_t *info, int type)
+{
+ assert(info);
+ info->type = type;
+}
+
+/**
+ * \brief Set the timer id of a queue_timer container
+ * \param info queue_timer container
+ * \param id timer id pointer
*/
-int snd_seq_reset_sync_slave(snd_seq_t *seq, int queue, snd_seq_addr_t *src)
+void snd_seq_queue_timer_set_id(snd_seq_queue_timer_t *info, const snd_timer_id_t *id)
{
- snd_seq_port_subscribe_t subs;
+ assert(info && id);
+ info->u.alsa.id = *id;
+}
- memset(&subs, 0, sizeof(subs));
- subs.sync = 1;
- subs.sender = *src;
- subs.dest.client = SND_SEQ_CLIENT_SYSTEM;
- subs.dest.port = snd_seq_queue_sync_port(queue);
- subs.queue = queue;
- return snd_seq_unsubscribe_port(seq, &subs);
+/**
+ * \brief Set the timer resolution of a queue_timer container
+ * \param info queue_timer container
+ * \param resolution timer resolution
+ */
+void snd_seq_queue_timer_set_resolution(snd_seq_queue_timer_t *info, unsigned int resolution)
+{
+ assert(info);
+ info->u.alsa.resolution = resolution;
}
-#endif
+/**
+ * \brief obtain the queue timer information
+ * \param seq sequencer handle
+ * \param q queue id to query
+ * \param timer pointer to store the timer information
+ * \return 0 on success otherwise a negative error code
+ */
+int snd_seq_get_queue_timer(snd_seq_t *seq, int q, snd_seq_queue_timer_t * timer)
+{
+ assert(seq && timer);
+ memset(timer, 0, sizeof(snd_seq_queue_timer_t));
+ timer->queue = q;
+ return seq->ops->get_queue_timer(seq, timer);
+}
+
+/**
+ * \brief set the queue timer information
+ * \param seq sequencer handle
+ * \param q queue id to change the timer
+ * \param timer timer information
+ * \return 0 on success otherwise a negative error code
+ */
+int snd_seq_set_queue_timer(snd_seq_t *seq, int q, snd_seq_queue_timer_t * timer)
+{
+ assert(seq && timer);
+ timer->queue = q;
+ return seq->ops->set_queue_timer(seq, timer);
+}
/*----------------------------------------------------------------*/
{
ssize_t len = sizeof(snd_seq_event_t);
assert(ev);
- if (snd_seq_ev_is_variable(ev))
+ if (sndrv_seq_ev_is_variable(ev))
len += ev->data.ext.len;
return len;
}
return -EAGAIN;
memcpy(seq->obuf + seq->obufused, ev, sizeof(snd_seq_event_t));
seq->obufused += sizeof(snd_seq_event_t);
- if (snd_seq_ev_is_variable(ev)) {
+ if (sndrv_seq_ev_is_variable(ev)) {
memcpy(seq->obuf + seq->obufused, ev->data.ext.ptr, ev->data.ext.len);
seq->obufused += ev->data.ext.len;
}
*retp = ev = &seq->ibuf[seq->ibufptr];
seq->ibufptr++;
seq->ibuflen--;
- if (! snd_seq_ev_is_variable(ev))
+ if (! sndrv_seq_ev_is_variable(ev))
return 1;
ncells = (ev->data.ext.len + sizeof(snd_seq_event_t) - 1) / sizeof(snd_seq_event_t);
if (seq->ibuflen < ncells) {
}
/**
- * \brief remove all events on output buffer
- * \param seq sequencer handle
- *
- * Removes all events on both user-space output buffer and
- * output memory pool on kernel.
+ * \brief remove all events on output buffer
+ * \param seq sequencer handle
+ *
+ * Removes all events on both user-space output buffer and
+ * output memory pool on kernel.
+ */
+int snd_seq_drop_output(snd_seq_t *seq)
+{
+ snd_seq_remove_events_t rminfo;
+ assert(seq);
+ seq->obufused = 0; /* drain output buffer */
+
+ memset(&rminfo, 0, sizeof(rminfo));
+ rminfo.remove_mode = SNDRV_SEQ_REMOVE_OUTPUT;
+
+ return snd_seq_remove_events(seq, &rminfo);
+}
+
+/**
+ * \brief clear input buffer and and remove events in sequencer queue
+ * \param seq sequencer handle
+ */
+int snd_seq_drop_input(snd_seq_t *seq)
+{
+ snd_seq_remove_events_t rminfo;
+ assert(seq);
+
+ seq->ibufptr = 0; /* drain input buffer */
+ seq->ibuflen = 0;
+
+ memset(&rminfo, 0, sizeof(rminfo));
+ rminfo.remove_mode = SNDRV_SEQ_REMOVE_INPUT;
+
+ return snd_seq_remove_events(seq, &rminfo);
+}
+
+
+/**
+ * \brief get size of #snd_seq_remove_events_t
+ * \return size in bytes
+ */
+size_t snd_seq_remove_events_sizeof()
+{
+ return sizeof(snd_seq_remove_events_t);
+}
+
+/**
+ * \brief allocate an empty #snd_seq_remove_events_t using standard malloc
+ * \param ptr returned pointer
+ * \return 0 on success otherwise negative error code
+ */
+int snd_seq_remove_events_malloc(snd_seq_remove_events_t **ptr)
+{
+ assert(ptr);
+ *ptr = calloc(1, sizeof(snd_seq_remove_events_t));
+ if (!*ptr)
+ return -ENOMEM;
+ return 0;
+}
+
+/**
+ * \brief frees a previously allocated #snd_seq_remove_events_t
+ * \param pointer to object to free
+ */
+void snd_seq_remove_events_free(snd_seq_remove_events_t *obj)
+{
+ free(obj);
+}
+
+/**
+ * \brief copy one #snd_seq_remove_events_t to another
+ * \param dst pointer to destination
+ * \param src pointer to source
+ */
+void snd_seq_remove_events_copy(snd_seq_remove_events_t *dst, const snd_seq_remove_events_t *src)
+{
+ assert(dst && src);
+ *dst = *src;
+}
+
+
+/**
+ * \brief Get the removal condition bits
+ * \param info remove_events container
+ * \return removal condition bits
+ */
+unsigned int snd_seq_remove_events_get_condition(const snd_seq_remove_events_t *info)
+{
+ assert(info);
+ return info->remove_mode;
+}
+
+/**
+ * \brief Get the queue as removal condition
+ * \param info remove_events container
+ * \return queue id
+ */
+int snd_seq_remove_events_get_queue(const snd_seq_remove_events_t *info)
+{
+ assert(info);
+ return info->queue;
+}
+
+/**
+ * \brief Get the event timestamp as removal condition
+ * \param info remove_events container
+ * \return time stamp
+ */
+const snd_seq_timestamp_t *snd_seq_remove_events_get_time(const snd_seq_remove_events_t *info)
+{
+ assert(info);
+ return &info->time;
+}
+
+/**
+ * \brief Get the event destination address as removal condition
+ * \param info remove_events container
+ * \return destination address
+ */
+const snd_seq_addr_t *snd_seq_remove_events_get_dest(const snd_seq_remove_events_t *info)
+{
+ assert(info);
+ return &info->dest;
+}
+
+/**
+ * \brief Get the event channel as removal condition
+ * \param info remove_events container
+ * \return channel number
+ */
+int snd_seq_remove_events_get_channel(const snd_seq_remove_events_t *info)
+{
+ assert(info);
+ return info->channel;
+}
+
+/**
+ * \brief Get the event type as removal condition
+ * \param info remove_events container
+ * \return event type
+ */
+int snd_seq_remove_events_get_event_type(const snd_seq_remove_events_t *info)
+{
+ assert(info);
+ return info->type;
+}
+
+/**
+ * \brief Get the event tag id as removal condition
+ * \param info remove_events container
+ * \return tag id
+ */
+int snd_seq_remove_events_get_tag(const snd_seq_remove_events_t *info)
+{
+ assert(info);
+ return info->tag;
+}
+
+/**
+ * \brief Set the removal condition bits
+ * \param info remove_events container
+ * \param flags removal condition bits
+ */
+void snd_seq_remove_events_set_condition(snd_seq_remove_events_t *info, unsigned int flags)
+{
+ assert(info);
+ info->remove_mode = flags;
+}
+
+/**
+ * \brief Set the queue as removal condition
+ * \param info remove_events container
+ * \param queue queue id
+ */
+void snd_seq_remove_events_set_queue(snd_seq_remove_events_t *info, int queue)
+{
+ assert(info);
+ info->queue = queue;
+}
+
+/**
+ * \brief Set the timestamp as removal condition
+ * \param info remove_events container
+ * \param time timestamp pointer
+ */
+void snd_seq_remove_events_set_time(snd_seq_remove_events_t *info, const snd_seq_timestamp_t *time)
+{
+ assert(info);
+ info->time = *time;
+}
+
+/**
+ * \brief Set the destination address as removal condition
+ * \param info remove_events container
+ * \param addr destination address
+ */
+void snd_seq_remove_events_set_dest(snd_seq_remove_events_t *info, const snd_seq_addr_t *addr)
+{
+ assert(info);
+ info->dest = *addr;
+}
+
+/**
+ * \brief Set the channel as removal condition
+ * \param info remove_events container
+ * \param channel channel number
*/
-int snd_seq_drop_output(snd_seq_t *seq)
+void snd_seq_remove_events_set_channel(snd_seq_remove_events_t *info, int channel)
{
- snd_seq_remove_events_t rminfo;
- assert(seq);
- seq->obufused = 0; /* drain output buffer */
-
- memset(&rminfo, 0, sizeof(rminfo));
- rminfo.output = 1;
-
- return snd_seq_remove_events(seq, &rminfo);
+ assert(info);
+ info->channel = channel;
}
/**
- * \brief clear input buffer and and remove events in sequencer queue
- * \param seq sequencer handle
+ * \brief Set the event type as removal condition
+ * \param info remove_events container
+ * \param type event type
*/
-int snd_seq_drop_input(snd_seq_t *seq)
+void snd_seq_remove_events_set_event_type(snd_seq_remove_events_t *info, int type)
{
- snd_seq_remove_events_t rminfo;
- assert(seq);
-
- seq->ibufptr = 0; /* drain input buffer */
- seq->ibuflen = 0;
-
- memset(&rminfo, 0, sizeof(rminfo));
- rminfo.input = 1;
+ assert(info);
+ info->type = type;
+}
- return snd_seq_remove_events(seq, &rminfo);
+/**
+ * \brief Set the event tag as removal condition
+ * \param info remove_events container
+ * \param tag tag id
+ */
+void snd_seq_remove_events_set_tag(snd_seq_remove_events_t *info, int tag)
+{
+ assert(info);
+ info->tag = tag;
}
+
/* compare timestamp between events */
/* return 1 if a >= b; otherwise return 0 */
-static inline int snd_seq_compare_tick_time(snd_seq_tick_time_t *a,
- snd_seq_tick_time_t *b)
+static inline int snd_seq_compare_tick_time(sndrv_seq_tick_time_t *a, sndrv_seq_tick_time_t *b)
{
/* compare ticks */
return (*a >= *b);
}
-static inline int snd_seq_compare_real_time(snd_seq_real_time_t *a,
- snd_seq_real_time_t *b)
+static inline int snd_seq_compare_real_time(struct sndrv_seq_real_time *a, struct sndrv_seq_real_time *b)
{
/* compare real time */
if (a->tv_sec > b->tv_sec)
}
/* Routine to match events to be removed */
-static int remove_match(snd_seq_remove_events_t *info,
- snd_seq_event_t *ev)
+static int remove_match(snd_seq_remove_events_t *info, snd_seq_event_t *ev)
{
int res;
- if (info->remove_mode & SND_SEQ_REMOVE_DEST) {
+ if (info->remove_mode & SNDRV_SEQ_REMOVE_DEST) {
if (ev->dest.client != info->dest.client ||
ev->dest.port != info->dest.port)
return 0;
}
- if (info->remove_mode & SND_SEQ_REMOVE_DEST_CHANNEL) {
- if (! snd_seq_ev_is_channel_type(ev))
+ if (info->remove_mode & SNDRV_SEQ_REMOVE_DEST_CHANNEL) {
+ if (! sndrv_seq_ev_is_channel_type(ev))
return 0;
/* data.note.channel and data.control.channel are identical */
if (ev->data.note.channel != info->channel)
return 0;
}
- if (info->remove_mode & SND_SEQ_REMOVE_TIME_AFTER) {
- if (info->tick)
+ if (info->remove_mode & SNDRV_SEQ_REMOVE_TIME_AFTER) {
+ if (info->remove_mode & SNDRV_SEQ_REMOVE_TIME_TICK)
res = snd_seq_compare_tick_time(&ev->time.tick, &info->time.tick);
else
res = snd_seq_compare_real_time(&ev->time.time, &info->time.time);
if (!res)
return 0;
}
- if (info->remove_mode & SND_SEQ_REMOVE_TIME_BEFORE) {
- if (info->tick)
+ if (info->remove_mode & SNDRV_SEQ_REMOVE_TIME_BEFORE) {
+ if (info->remove_mode & SNDRV_SEQ_REMOVE_TIME_TICK)
res = snd_seq_compare_tick_time(&ev->time.tick, &info->time.tick);
else
res = snd_seq_compare_real_time(&ev->time.time, &info->time.time);
if (res)
return 0;
}
- if (info->remove_mode & SND_SEQ_REMOVE_EVENT_TYPE) {
+ if (info->remove_mode & SNDRV_SEQ_REMOVE_EVENT_TYPE) {
if (ev->type != info->type)
return 0;
}
- if (info->remove_mode & SND_SEQ_REMOVE_IGNORE_OFF) {
+ if (info->remove_mode & SNDRV_SEQ_REMOVE_IGNORE_OFF) {
/* Do not remove off events */
switch (ev->type) {
- case SND_SEQ_EVENT_NOTEOFF:
- /* case SND_SEQ_EVENT_SAMPLE_STOP: */
+ case SNDRV_SEQ_EVENT_NOTEOFF:
+ /* case SNDRV_SEQ_EVENT_SAMPLE_STOP: */
return 0;
default:
break;
}
}
- if (info->remove_mode & SND_SEQ_REMOVE_TAG_MATCH) {
+ if (info->remove_mode & SNDRV_SEQ_REMOVE_TAG_MATCH) {
if (info->tag != ev->tag)
return 0;
}
/**
* \brief remove events on input/output buffers
* \param seq sequencer handle
+ * \param rmp remove event container
*
* Removes matching events with the given condition from input/output buffers.
* The removal condition is specified in rmp argument.
*/
int snd_seq_remove_events(snd_seq_t *seq, snd_seq_remove_events_t *rmp)
{
- if (rmp->input) {
+ if (rmp->remove_mode & SNDRV_SEQ_REMOVE_INPUT) {
/*
* First deal with any events that are still buffered
* in the library.
*/
- if (rmp->remove_mode == 0)
- snd_seq_drop_input_buffer(seq);
- /* other modes are not supported yet */
+ snd_seq_drop_input_buffer(seq);
}
- if (rmp->output) {
+ if (rmp->remove_mode & SNDRV_SEQ_REMOVE_OUTPUT) {
/*
* First deal with any events that are still buffered
* in the library.
*/
- if (rmp->remove_mode == 0) {
+ if (rmp->remove_mode & ~(SNDRV_SEQ_REMOVE_INPUT|SNDRV_SEQ_REMOVE_OUTPUT)) {
/* The simple case - remove all */
snd_seq_drop_output_buffer(seq);
} else {
*/
/**
- * \brief obtain the pool information of the current client
- * \param seq sequencer handle
- * \param info information to be stored
+ * \brief get size of #snd_seq_client_pool_t
+ * \return size in bytes
*/
-int snd_seq_get_client_pool(snd_seq_t *seq, snd_seq_client_pool_t *info)
+size_t snd_seq_client_pool_sizeof()
{
- assert(seq && info);
- info->client = seq->client;
- return seq->ops->get_client_pool(seq, info);
+ return sizeof(snd_seq_client_pool_t);
}
/**
- * \brief set the pool information
- * \param seq sequencer handle
- * \param info information to update
- *
- * Sets the pool information of the current client.
- * The client field in info is replaced automatically with the current id.
+ * \brief allocate an empty #snd_seq_client_pool_t using standard malloc
+ * \param ptr returned pointer
+ * \return 0 on success otherwise negative error code
*/
-int snd_seq_set_client_pool(snd_seq_t *seq, snd_seq_client_pool_t *info)
+int snd_seq_client_pool_malloc(snd_seq_client_pool_t **ptr)
{
- assert(seq && info);
- info->client = seq->client;
- return seq->ops->set_client_pool(seq, info);
+ assert(ptr);
+ *ptr = calloc(1, sizeof(snd_seq_client_pool_t));
+ if (!*ptr)
+ return -ENOMEM;
+ return 0;
}
-/*----------------------------------------------------------------*/
+/**
+ * \brief frees a previously allocated #snd_seq_client_pool_t
+ * \param pointer to object to free
+ */
+void snd_seq_client_pool_free(snd_seq_client_pool_t *obj)
+{
+ free(obj);
+}
-/*
- * query functions
+/**
+ * \brief copy one #snd_seq_client_pool_t to another
+ * \param dst pointer to destination
+ * \param src pointer to source
+ */
+void snd_seq_client_pool_copy(snd_seq_client_pool_t *dst, const snd_seq_client_pool_t *src)
+{
+ assert(dst && src);
+ *dst = *src;
+}
+
+
+/**
+ * \brief Get the client id of a queue_info container
+ * \param info client_pool container
+ * \return client id
*/
+int snd_seq_client_pool_get_client(const snd_seq_client_pool_t *info)
+{
+ assert(info);
+ return info->client;
+}
/**
- * \brief query the next matching client
+ * \brief Get the output pool size of a queue_info container
+ * \param info client_pool container
+ * \return output pool size
+ */
+size_t snd_seq_client_pool_get_output_pool(const snd_seq_client_pool_t *info)
+{
+ assert(info);
+ return info->output_pool;
+}
+
+/**
+ * \brief Get the input pool size of a queue_info container
+ * \param info client_pool container
+ * \return input pool size
+ */
+size_t snd_seq_client_pool_get_input_pool(const snd_seq_client_pool_t *info)
+{
+ assert(info);
+ return info->input_pool;
+}
+
+/**
+ * \brief Get the output room size of a queue_info container
+ * \param info client_pool container
+ * \return output room size
+ */
+size_t snd_seq_client_pool_get_output_room(const snd_seq_client_pool_t *info)
+{
+ assert(info);
+ return info->output_room;
+}
+
+/**
+ * \brief Get the available size on output pool of a queue_info container
+ * \param info client_pool container
+ * \return available output size
+ */
+size_t snd_seq_client_pool_get_output_free(const snd_seq_client_pool_t *info)
+{
+ assert(info);
+ return info->output_free;
+}
+
+/**
+ * \brief Get the available size on input pool of a queue_info container
+ * \param info client_pool container
+ * \return available input size
+ */
+size_t snd_seq_client_pool_get_input_free(const snd_seq_client_pool_t *info)
+{
+ assert(info);
+ return info->input_free;
+}
+
+/**
+ * \brief Set the output pool size of a queue_info container
+ * \param info client_pool container
+ * \param size output pool size
+ */
+void snd_seq_client_pool_set_output_pool(snd_seq_client_pool_t *info, size_t size)
+{
+ assert(info);
+ info->output_pool = size;
+}
+
+/**
+ * \brief Set the input pool size of a queue_info container
+ * \param info client_pool container
+ * \param size input pool size
+ */
+void snd_seq_client_pool_set_input_pool(snd_seq_client_pool_t *info, size_t size)
+{
+ assert(info);
+ info->input_pool = size;
+}
+
+/**
+ * \brief Set the output room size of a queue_info container
+ * \param info client_pool container
+ * \param size output room size
+ */
+void snd_seq_client_pool_set_output_room(snd_seq_client_pool_t *info, size_t size)
+{
+ assert(info);
+ info->output_room = size;
+}
+
+
+/**
+ * \brief obtain the pool information of the current client
* \param seq sequencer handle
- * \param info query pattern and result
- *
- * Queries the next matching client with the given condition in
- * info argument.
- * The search begins at the client with an id one greater than
- * client field in info.
- * If name field in info is not empty, the client name is compared.
- * If a matching client is found, its attributes are stored o
- * info and returns zero.
- * Otherwise returns a negative error code.
+ * \param info information to be stored
*/
-int snd_seq_query_next_client(snd_seq_t *seq, snd_seq_client_info_t *info)
+int snd_seq_get_client_pool(snd_seq_t *seq, snd_seq_client_pool_t *info)
{
assert(seq && info);
- return seq->ops->query_next_client(seq, info);
+ info->client = seq->client;
+ return seq->ops->get_client_pool(seq, info);
}
/**
- * \brief query the next matching port
+ * \brief set the pool information
* \param seq sequencer handle
- * \param info query pattern and result
-
- * Queries the next matching port from the port
- * on the client given in info argument.
- * The search begins at the next port specified in
- * port field of info.
- * For finding the first port at a certain client, give -1 to
- * port field.
- * If name field is not empty, the name is checked.
- * If a matching port is found, its attributes are stored on
- * info and function returns zero.
- * Otherwise, a negative error code is returned.
+ * \param info information to update
+ *
+ * Sets the pool information of the current client.
+ * The client field in \a info is replaced automatically with the current id.
*/
-int snd_seq_query_next_port(snd_seq_t *seq, snd_seq_port_info_t *info)
+int snd_seq_set_client_pool(snd_seq_t *seq, snd_seq_client_pool_t *info)
{
assert(seq && info);
- return seq->ops->query_next_port(seq, info);
+ info->client = seq->client;
+ return seq->ops->set_client_pool(seq, info);
}
/*----------------------------------------------------------------*/
return ((((unsigned int *)array)[nr >> 5]) & (1UL << (nr & 31))) ? 1 : 0;
}
+
+/**
+ * instrument layer
+ */
+
+/**
+ * \brief get size of #snd_instr_header_t
+ * \return size in bytes
+ */
+size_t snd_instr_header_sizeof(void)
+{
+ return sizeof(snd_instr_header_t);
+}
+
+/**
+ * \brief allocate an empty #snd_instr_header_t using standard malloc
+ * \param ptr returned pointer
+ * \param len additional data length
+ * \return 0 on success otherwise negative error code
+ */
+int snd_instr_header_malloc(snd_instr_header_t **ptr, size_t len)
+{
+ assert(ptr);
+ *ptr = calloc(1, sizeof(snd_instr_header_t) + len);
+ if (!*ptr)
+ return -ENOMEM;
+ (*ptr)->len = len;
+ return 0;
+}
+
+/**
+ * \brief frees a previously allocated #snd_instr_header_t
+ * \param pointer to object to free
+ */
+void snd_instr_header_free(snd_instr_header_t *obj)
+{
+ free(obj);
+}
+
+/**
+ * \brief copy one #snd_instr_header_t to another
+ * \param dst pointer to destination
+ * \param src pointer to source
+ */
+void snd_instr_header_copy(snd_instr_header_t *dst, const snd_instr_header_t *src)
+{
+ assert(dst && src);
+ *dst = *src;
+}
+
+/**
+ * \brief Get the instrument id of an instr_header container
+ * \param info instr_header container
+ * \return instrument id pointer
+ */
+const snd_seq_instr_t *snd_instr_header_get_id(const snd_instr_header_t *info)
+{
+ assert(info);
+ return &info->id.instr;
+}
+
+/**
+ * \brief Get the cluster id of an instr_header container
+ * \param info instr_header container
+ * \return cluster id
+ */
+snd_seq_instr_cluster_t snd_instr_header_get_cluster(const snd_instr_header_t *info)
+{
+ assert(info);
+ return info->id.cluster;
+}
+
+/**
+ * \brief Get the command of an instr_header container
+ * \param info instr_header container
+ * \return command type
+ */
+unsigned int snd_instr_header_get_cmd(const snd_instr_header_t *info)
+{
+ assert(info);
+ return info->cmd;
+}
+
+/**
+ * \brief Get the length of extra data of an instr_header container
+ * \param info instr_header container
+ * \return the length in bytes
+ */
+size_t snd_instr_header_get_len(const snd_instr_header_t *info)
+{
+ assert(info);
+ return info->len;
+}
+
+/**
+ * \brief Get the data name of an instr_header container
+ * \param info instr_header container
+ * \return the name string
+ */
+const char *snd_instr_header_get_name(const snd_instr_header_t *info)
+{
+ assert(info);
+ return info->data.name;
+}
+
+/**
+ * \brief Get the data type of an instr_header container
+ * \param info instr_header container
+ * \return the data type
+ */
+int snd_instr_header_get_type(const snd_instr_header_t *info)
+{
+ assert(info);
+ return info->data.type;
+}
+
+/**
+ * \brief Get the data format of an instr_header container
+ * \param info instr_header container
+ * \return the data format string
+ */
+const char *snd_instr_header_get_format(const snd_instr_header_t *info)
+{
+ assert(info);
+ return info->data.data.format;
+}
+
+/**
+ * \brief Get the data alias of an instr_header container
+ * \param info instr_header container
+ * \return the data alias id
+ */
+const snd_seq_instr_t *snd_instr_header_get_alias(const snd_instr_header_t *info)
+{
+ assert(info);
+ return &info->data.data.alias;
+}
+
+/**
+ * \brief Get the extra data pointer of an instr_header container
+ * \param info instr_header container
+ * \return the extra data pointer
+ */
+void *snd_instr_header_get_data(const snd_instr_header_t *info)
+{
+ assert(info);
+ return (void*)((char*)info + sizeof(*info));
+}
+
+/**
+ * \brief Get the flag to follow alias of an instr_header container
+ * \param info instr_header container
+ * \return 1 if follow alias
+ */
+int snd_instr_header_get_follow_alias(const snd_instr_header_t *info)
+{
+ assert(info);
+ return (info->flags & SNDRV_SEQ_INSTR_QUERY_FOLLOW_ALIAS) ? 1 : 0;
+}
+
+/**
+ * \brief Set the instrument id of an instr_header container
+ * \param info instr_header container
+ * \param id instrumen id pointer
+ */
+void snd_instr_header_set_id(snd_instr_header_t *info, const snd_seq_instr_t *id)
+{
+ assert(info && id);
+ info->id.instr = *id;
+}
+
+/**
+ * \brief Set the cluster id of an instr_header container
+ * \param info instr_header container
+ * \param cluster cluster id
+ */
+void snd_instr_header_set_cluster(snd_instr_header_t *info, snd_seq_instr_cluster_t cluster)
+{
+ assert(info);
+ info->id.cluster = cluster;
+}
+
+/**
+ * \brief Set the command of an instr_header container
+ * \param info instr_header container
+ * \param cmd command type
+ */
+void snd_instr_header_set_cmd(snd_instr_header_t *info, unsigned int cmd)
+{
+ assert(info);
+ info->cmd = cmd;
+}
+
+/**
+ * \brief Set the length of extra data of an instr_header container
+ * \param info instr_header container
+ * \param len size of extra data in bytes
+ */
+void snd_instr_header_set_len(snd_instr_header_t *info, size_t len)
+{
+ assert(info);
+ info->len = len;
+}
+
+/**
+ * \brief Set the data name of an instr_header container
+ * \param info instr_header container
+ * \param name the name string
+ */
+void snd_instr_header_set_name(snd_instr_header_t *info, const char *name)
+{
+ assert(info && name);
+ strncpy(info->data.name, name, sizeof(info->data.name));
+}
+
+/**
+ * \brief Set the data type of an instr_header container
+ * \param info instr_header container
+ * \param type the data type
+ */
+void snd_instr_header_set_type(snd_instr_header_t *info, int type)
+{
+ assert(info);
+ info->data.type = type;
+}
+
+/**
+ * \brief Set the data format of an instr_header container
+ * \param info instr_header container
+ * \param format the data format string
+ */
+void snd_instr_header_set_format(snd_instr_header_t *info, const char *format)
+{
+ assert(info && format);
+ strncpy(info->data.data.format, format, sizeof(info->data.data.format));
+}
+
+/**
+ * \brief Set the data alias id of an instr_header container
+ * \param info instr_header container
+ * \param instr alias instrument id
+ */
+void snd_instr_header_set_alias(snd_instr_header_t *info, const snd_seq_instr_t *instr)
+{
+ assert(info && instr);
+ info->data.data.alias = *instr;
+}
+
+/**
+ * \brief Set the flag to follow alias of an instr_header container
+ * \param info instr_header container
+ * \param bool 1 if follow alias
+ */
+void snd_instr_header_set_follow_alias(snd_instr_header_t *info, int bool)
+{
+ assert(info);
+ if (bool)
+ info->flags |= SNDRV_SEQ_INSTR_QUERY_FOLLOW_ALIAS;
+ else
+ info->flags &= ~SNDRV_SEQ_INSTR_QUERY_FOLLOW_ALIAS;
+}
--- /dev/null
+/**
+ * \file seq/seq_event.c
+ * \author Takashi Iwai <tiwai@suse.de>
+ * \date 2001
+ */
+
+#include "../../include/asoundlib.h"
+
+#define FIXED_EV(x) (_SND_SEQ_TYPE(SND_SEQ_EVFLG_FIXED) | _SND_SEQ_TYPE(x))
+
+const unsigned int snd_seq_event_types[256] = {
+ [SND_SEQ_EVENT_SYSTEM ... SND_SEQ_EVENT_RESULT]
+ = FIXED_EV(SND_SEQ_EVFLG_RESULT),
+ [SND_SEQ_EVENT_NOTE]
+ = FIXED_EV(SND_SEQ_EVFLG_NOTE) | _SND_SEQ_TYPE_OPT(SND_SEQ_EVFLG_NOTE_TWOARG),
+ [SND_SEQ_EVENT_NOTEON ... SND_SEQ_EVENT_KEYPRESS]
+ = FIXED_EV(SND_SEQ_EVFLG_NOTE),
+ [SND_SEQ_EVENT_CONTROLLER ... SND_SEQ_EVENT_REGPARAM]
+ = FIXED_EV(SND_SEQ_EVFLG_CONTROL),
+ [SND_SEQ_EVENT_START ... SND_SEQ_EVENT_STOP]
+ = FIXED_EV(SND_SEQ_EVFLG_QUEUE),
+ [SND_SEQ_EVENT_SETPOS_TICK]
+ = FIXED_EV(SND_SEQ_EVFLG_QUEUE) | _SND_SEQ_TYPE_OPT(SND_SEQ_EVFLG_QUEUE_TICK),
+ [SND_SEQ_EVENT_SETPOS_TIME]
+ = FIXED_EV(SND_SEQ_EVFLG_QUEUE) | _SND_SEQ_TYPE_OPT(SND_SEQ_EVFLG_QUEUE_TIME),
+ [SND_SEQ_EVENT_TEMPO ... SND_SEQ_EVENT_SYNC_POS]
+ = FIXED_EV(SND_SEQ_EVFLG_QUEUE) | _SND_SEQ_TYPE_OPT(SND_SEQ_EVFLG_QUEUE_VALUE),
+ [SND_SEQ_EVENT_TUNE_REQUEST ... SND_SEQ_EVENT_SENSING]
+ = FIXED_EV(SND_SEQ_EVFLG_NONE),
+ [SND_SEQ_EVENT_ECHO ... SND_SEQ_EVENT_OSS]
+ = FIXED_EV(SND_SEQ_EVFLG_RAW) | FIXED_EV(SND_SEQ_EVFLG_SYSTEM),
+ [SND_SEQ_EVENT_CLIENT_START ... SND_SEQ_EVENT_PORT_CHANGE]
+ = FIXED_EV(SND_SEQ_EVFLG_MESSAGE),
+ [SND_SEQ_EVENT_PORT_SUBSCRIBED ... SND_SEQ_EVENT_PORT_UNSUBSCRIBED]
+ = FIXED_EV(SND_SEQ_EVFLG_CONNECTION),
+ [SND_SEQ_EVENT_SAMPLE ... SND_SEQ_EVENT_SAMPLE_PRIVATE1]
+ = FIXED_EV(SND_SEQ_EVFLG_SAMPLE),
+ [SND_SEQ_EVENT_USR0 ... SND_SEQ_EVENT_USR9]
+ = FIXED_EV(SND_SEQ_EVFLG_RAW) | FIXED_EV(SND_SEQ_EVFLG_USERS),
+ [SND_SEQ_EVENT_INSTR_BEGIN ... SND_SEQ_EVENT_INSTR_CHANGE]
+ = _SND_SEQ_TYPE(SND_SEQ_EVFLG_INSTR) | _SND_SEQ_TYPE(SND_SEQ_EVFLG_VARUSR),
+ [SND_SEQ_EVENT_SYSEX ... SND_SEQ_EVENT_BOUNCE]
+ = _SND_SEQ_TYPE(SND_SEQ_EVFLG_VARIABLE),
+ [SND_SEQ_EVENT_USR_VAR0 ... SND_SEQ_EVENT_USR_VAR4]
+ = _SND_SEQ_TYPE(SND_SEQ_EVFLG_VARIABLE) | _SND_SEQ_TYPE(SND_SEQ_EVFLG_USERS),
+#if 0 // NYI
+ [SND_SEQ_EVENT_IPCSHM]
+ = _SND_SEQ_TYPE(SND_SEQ_EVFLG_IPC),
+ [SND_SEQ_EVENT_USR_VARIPC0 ... SND_SEQ_EVENT_USR_VARIPC4]
+ = _SND_SEQ_TYPE(SND_SEQ_EVFLG_IPC) | _SND_SEQ_TYPE(SND_SEQ_EVFLG_USERS),
+#endif
+ [SND_SEQ_EVENT_NONE]
+ = FIXED_EV(SND_SEQ_EVFLG_NONE),
+};
+
return 0;
}
-static int snd_seq_hw_query_port_subscribers(snd_seq_t *seq, snd_seq_query_subs_t * subs)
+static int snd_seq_hw_query_port_subscribers(snd_seq_t *seq, snd_seq_query_subscribe_t * subs)
{
snd_seq_hw_t *hw = seq->private_data;
if (ioctl(hw->fd, SNDRV_SEQ_IOCTL_QUERY_SUBS, subs) < 0) {
return 0;
}
-static int snd_seq_hw_get_queue_owner(snd_seq_t *seq, snd_seq_queue_owner_t * owner)
-{
- snd_seq_hw_t *hw = seq->private_data;
- if (ioctl(hw->fd, SNDRV_SEQ_IOCTL_GET_QUEUE_OWNER, owner) < 0) {
- SYSERR("SNDRV_SEQ_IOCTL_GET_QUEUE_OWNER failed");
- return -errno;
- }
- return 0;
-}
-
-static int snd_seq_hw_set_queue_owner(snd_seq_t *seq, snd_seq_queue_owner_t * owner)
-{
- snd_seq_hw_t *hw = seq->private_data;
- if (ioctl(hw->fd, SNDRV_SEQ_IOCTL_SET_QUEUE_OWNER, owner) < 0) {
- SYSERR("SNDRV_SEQ_IOCTL_SET_QUEUE_OWNER failed");
- return -errno;
- }
- return 0;
-}
-
static int snd_seq_hw_get_queue_timer(snd_seq_t *seq, snd_seq_queue_timer_t * timer)
{
snd_seq_hw_t *hw = seq->private_data;
get_queue_status: snd_seq_hw_get_queue_status,
get_queue_tempo: snd_seq_hw_get_queue_tempo,
set_queue_tempo: snd_seq_hw_set_queue_tempo,
- get_queue_owner: snd_seq_hw_get_queue_owner,
- set_queue_owner: snd_seq_hw_set_queue_owner,
get_queue_timer: snd_seq_hw_get_queue_timer,
set_queue_timer: snd_seq_hw_set_queue_timer,
get_queue_client: snd_seq_hw_get_queue_client,
#define SND_SEQ_IBUF_SIZE 500 /* in event_size aligned */
#define DEFAULT_TMPBUF_SIZE 20
+typedef struct sndrv_seq_queue_client snd_seq_queue_client_t;
+
+
typedef struct {
int (*close)(snd_seq_t *seq);
int (*nonblock)(snd_seq_t *seq, int nonblock);
int (*get_port_subscription)(snd_seq_t *seq, snd_seq_port_subscribe_t * sub);
int (*subscribe_port)(snd_seq_t *seq, snd_seq_port_subscribe_t * sub);
int (*unsubscribe_port)(snd_seq_t *seq, snd_seq_port_subscribe_t * sub);
- int (*query_port_subscribers)(snd_seq_t *seq, snd_seq_query_subs_t * subs);
+ int (*query_port_subscribers)(snd_seq_t *seq, snd_seq_query_subscribe_t * subs);
int (*get_queue_status)(snd_seq_t *seq, snd_seq_queue_status_t * status);
int (*get_queue_tempo)(snd_seq_t *seq, snd_seq_queue_tempo_t * tempo);
int (*set_queue_tempo)(snd_seq_t *seq, snd_seq_queue_tempo_t * tempo);
- int (*get_queue_owner)(snd_seq_t *seq, snd_seq_queue_owner_t * owner);
- int (*set_queue_owner)(snd_seq_t *seq, snd_seq_queue_owner_t * owner);
int (*get_queue_timer)(snd_seq_t *seq, snd_seq_queue_timer_t * timer);
int (*set_queue_timer)(snd_seq_t *seq, snd_seq_queue_timer_t * timer);
int (*get_queue_client)(snd_seq_t *seq, snd_seq_queue_client_t * client);
event_decode_t decode;
} status_event[] = {
/* 0x80 - 0xf0 */
- {SND_SEQ_EVENT_NOTEOFF, 2, note_event, note_decode},
- {SND_SEQ_EVENT_NOTEON, 2, note_event, note_decode},
- {SND_SEQ_EVENT_KEYPRESS, 2, note_event, note_decode},
- {SND_SEQ_EVENT_CONTROLLER, 2, two_param_ctrl_event, two_param_decode},
- {SND_SEQ_EVENT_PGMCHANGE, 1, one_param_ctrl_event, one_param_decode},
- {SND_SEQ_EVENT_CHANPRESS, 1, one_param_ctrl_event, one_param_decode},
- {SND_SEQ_EVENT_PITCHBEND, 2, pitchbend_ctrl_event, pitchbend_decode},
- {SND_SEQ_EVENT_NONE, 0, NULL, NULL}, /* 0xf0 */
+ {SNDRV_SEQ_EVENT_NOTEOFF, 2, note_event, note_decode},
+ {SNDRV_SEQ_EVENT_NOTEON, 2, note_event, note_decode},
+ {SNDRV_SEQ_EVENT_KEYPRESS, 2, note_event, note_decode},
+ {SNDRV_SEQ_EVENT_CONTROLLER, 2, two_param_ctrl_event, two_param_decode},
+ {SNDRV_SEQ_EVENT_PGMCHANGE, 1, one_param_ctrl_event, one_param_decode},
+ {SNDRV_SEQ_EVENT_CHANPRESS, 1, one_param_ctrl_event, one_param_decode},
+ {SNDRV_SEQ_EVENT_PITCHBEND, 2, pitchbend_ctrl_event, pitchbend_decode},
+ {SNDRV_SEQ_EVENT_NONE, 0, NULL, NULL}, /* 0xf0 */
/* 0xf0 - 0xff */
- {SND_SEQ_EVENT_SYSEX, 1, NULL, NULL}, /* sysex: 0xf0 */
- {SND_SEQ_EVENT_QFRAME, 1, one_param_event, one_param_decode}, /* 0xf1 */
- {SND_SEQ_EVENT_SONGPOS, 2, songpos_event, songpos_decode}, /* 0xf2 */
- {SND_SEQ_EVENT_SONGSEL, 1, one_param_event, one_param_decode}, /* 0xf3 */
- {SND_SEQ_EVENT_NONE, 0, NULL, NULL}, /* 0xf4 */
- {SND_SEQ_EVENT_NONE, 0, NULL, NULL}, /* 0xf5 */
- {SND_SEQ_EVENT_TUNE_REQUEST, 0, NULL, NULL}, /* 0xf6 */
- {SND_SEQ_EVENT_NONE, 0, NULL, NULL}, /* 0xf7 */
- {SND_SEQ_EVENT_CLOCK, 0, NULL, NULL}, /* 0xf8 */
- {SND_SEQ_EVENT_NONE, 0, NULL, NULL}, /* 0xf9 */
- {SND_SEQ_EVENT_START, 0, NULL, NULL}, /* 0xfa */
- {SND_SEQ_EVENT_CONTINUE, 0, NULL, NULL}, /* 0xfb */
- {SND_SEQ_EVENT_STOP, 0, NULL, NULL}, /* 0xfc */
- {SND_SEQ_EVENT_NONE, 0, NULL, NULL}, /* 0xfd */
- {SND_SEQ_EVENT_SENSING, 0, NULL, NULL}, /* 0xfe */
- {SND_SEQ_EVENT_RESET, 0, NULL, NULL}, /* 0xff */
+ {SNDRV_SEQ_EVENT_SYSEX, 1, NULL, NULL}, /* sysex: 0xf0 */
+ {SNDRV_SEQ_EVENT_QFRAME, 1, one_param_event, one_param_decode}, /* 0xf1 */
+ {SNDRV_SEQ_EVENT_SONGPOS, 2, songpos_event, songpos_decode}, /* 0xf2 */
+ {SNDRV_SEQ_EVENT_SONGSEL, 1, one_param_event, one_param_decode}, /* 0xf3 */
+ {SNDRV_SEQ_EVENT_NONE, 0, NULL, NULL}, /* 0xf4 */
+ {SNDRV_SEQ_EVENT_NONE, 0, NULL, NULL}, /* 0xf5 */
+ {SNDRV_SEQ_EVENT_TUNE_REQUEST, 0, NULL, NULL}, /* 0xf6 */
+ {SNDRV_SEQ_EVENT_NONE, 0, NULL, NULL}, /* 0xf7 */
+ {SNDRV_SEQ_EVENT_CLOCK, 0, NULL, NULL}, /* 0xf8 */
+ {SNDRV_SEQ_EVENT_NONE, 0, NULL, NULL}, /* 0xf9 */
+ {SNDRV_SEQ_EVENT_START, 0, NULL, NULL}, /* 0xfa */
+ {SNDRV_SEQ_EVENT_CONTINUE, 0, NULL, NULL}, /* 0xfb */
+ {SNDRV_SEQ_EVENT_STOP, 0, NULL, NULL}, /* 0xfc */
+ {SNDRV_SEQ_EVENT_NONE, 0, NULL, NULL}, /* 0xfd */
+ {SNDRV_SEQ_EVENT_SENSING, 0, NULL, NULL}, /* 0xfe */
+ {SNDRV_SEQ_EVENT_RESET, 0, NULL, NULL}, /* 0xff */
};
static int extra_decode_ctrl14(snd_midi_event_t *dev, unsigned char *buf, int len, snd_seq_event_t *ev);
int event;
int (*decode)(snd_midi_event_t *dev, unsigned char *buf, int len, snd_seq_event_t *ev);
} extra_event[] = {
- {SND_SEQ_EVENT_CONTROL14, extra_decode_ctrl14},
- /*{SND_SEQ_EVENT_NONREGPARAM, extra_decode_nrpn},*/
- /*{SND_SEQ_EVENT_REGPARAM, extra_decode_rpn},*/
+ {SNDRV_SEQ_EVENT_CONTROL14, extra_decode_ctrl14},
+ /*{SNDRV_SEQ_EVENT_NONREGPARAM, extra_decode_nrpn},*/
+ /*{SNDRV_SEQ_EVENT_REGPARAM, extra_decode_rpn},*/
};
#define numberof(ary) (sizeof(ary)/sizeof(ary[0]))
long result = 0;
int rc;
- ev->type = SND_SEQ_EVENT_NONE;
+ ev->type = SNDRV_SEQ_EVENT_NONE;
while (count-- > 0) {
rc = snd_midi_event_encode_byte(dev, *buf++, ev);
if (c >= MIDI_CMD_COMMON_CLOCK) {
/* real-time event */
ev->type = status_event[ST_SPECIAL + c - 0xf0].event;
- ev->flags &= ~SND_SEQ_EVENT_LENGTH_MASK;
- ev->flags |= SND_SEQ_EVENT_LENGTH_FIXED;
+ ev->flags &= ~SNDRV_SEQ_EVENT_LENGTH_MASK;
+ ev->flags |= SNDRV_SEQ_EVENT_LENGTH_FIXED;
return 1;
}
}
if (dev->qlen == 0) {
ev->type = status_event[dev->type].event;
- ev->flags &= ~SND_SEQ_EVENT_LENGTH_MASK;
- ev->flags |= SND_SEQ_EVENT_LENGTH_FIXED;
+ ev->flags &= ~SNDRV_SEQ_EVENT_LENGTH_MASK;
+ ev->flags |= SNDRV_SEQ_EVENT_LENGTH_FIXED;
if (status_event[dev->type].encode) /* set data values */
status_event[dev->type].encode(dev, ev);
rc = 1;
} else if (dev->type == ST_SYSEX) {
if (c == MIDI_CMD_COMMON_SYSEX_END ||
dev->read >= dev->bufsize) {
- ev->flags &= ~SND_SEQ_EVENT_LENGTH_MASK;
- ev->flags |= SND_SEQ_EVENT_LENGTH_VARIABLE;
+ ev->flags &= ~SNDRV_SEQ_EVENT_LENGTH_MASK;
+ ev->flags |= SNDRV_SEQ_EVENT_LENGTH_VARIABLE;
ev->data.ext.len = dev->read;
ev->data.ext.ptr = dev->buf;
if (c != MIDI_CMD_COMMON_SYSEX_END)
long qlen;
unsigned int type;
- if (ev->type == SND_SEQ_EVENT_NONE)
+ if (ev->type == SNDRV_SEQ_EVENT_NONE)
return -ENOENT;
for (type = 0; type < numberof(status_event); type++) {
qlen = ev->data.ext.len;
if (count < qlen)
return -ENOMEM;
- switch (ev->flags & SND_SEQ_EVENT_LENGTH_MASK) {
- case SND_SEQ_EVENT_LENGTH_FIXED:
- case SND_SEQ_EVENT_LENGTH_VARIPC:
+ switch (ev->flags & SNDRV_SEQ_EVENT_LENGTH_MASK) {
+ case SNDRV_SEQ_EVENT_LENGTH_FIXED:
+ case SNDRV_SEQ_EVENT_LENGTH_VARIPC:
return -EINVAL; /* invalid event */
}
memcpy(dev->buf, ev->data.ext.ptr, qlen);
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
+#include <ctype.h>
#include <sys/ioctl.h>
#include "seq_local.h"
-/**
- * \brief set direct passing mode (without queued)
- * \param ev event instance
- */
-void snd_seq_ev_set_direct(snd_seq_event_t *ev)
-{
- ev->queue = SND_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 tick tick time-stap to be delivered
- */
-void snd_seq_ev_schedule_tick(snd_seq_event_t *ev, int q, int relative,
- snd_seq_tick_time_t tick)
-{
- 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 = tick;
- 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 _time time-stamp to be delivered
- */
-void snd_seq_ev_schedule_real(snd_seq_event_t *ev, int q, int relative,
- snd_seq_real_time_t *_time)
-{
- 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 = *_time;
- ev->queue = q;
-}
-
-/**
- * \brief set event priority
- * \param ev event instance
- * \param high_prior 1 for high priority mode
- */
-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;
-}
-
-/**
- * \brief set fixed data
- *
- * Sets the event length mode as fixed size.
- */
-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;
-}
-
-/**
- * \brief set variable data
- *
- * Sets the event length mode as variable length and stores the data.
- */
-void snd_seq_ev_set_variable(snd_seq_event_t *ev, int len, void *ptr)
-{
- ev->flags &= ~SND_SEQ_EVENT_LENGTH_MASK;
- ev->flags |= SND_SEQ_EVENT_LENGTH_VARIABLE;
- ev->data.ext.len = len;
- ev->data.ext.ptr = ptr;
-}
-
-/**
- * \brief set varusr data
- *
- * Sets the event length mode as variable user-space data and stores the data.
- */
-void snd_seq_ev_set_varusr(snd_seq_event_t *ev, int len, void *ptr)
-{
- ev->flags &= ~SND_SEQ_EVENT_LENGTH_MASK;
- ev->flags |= SND_SEQ_EVENT_LENGTH_VARUSR;
- ev->data.ext.len = len;
- ev->data.ext.ptr = ptr;
-}
-
-
-/**
- * \brief use or unuse a queue
- */
-int snd_seq_use_queue(snd_seq_t *seq, int q, int use)
-{
- snd_seq_queue_client_t info;
-
- memset(&info, 0, sizeof(info));
- info.used = use;
- return snd_seq_set_queue_client(seq, q, &info);
-}
-
-
/**
* \brief queue controls - start/stop/continue
* \param seq sequencer handle
* \param value event value
* \param ev event instance
*
- * if ev is NULL, send events immediately.
- * otherwise, duplicate the given event data.
+ * This function sets up general queue control event and sends it.
+ * To send at scheduled time, set the schedule in \a ev.
+ * If \a ev is NULL, the event is composed locally and sent immediately
+ * to the specified queue. In any cases, you need to call #snd_seq_drain_event
+ * apropriately to feed the event.
*/
int snd_seq_control_queue(snd_seq_t *seq, int q, int type, int value, snd_seq_event_t *ev)
{
return snd_seq_event_output(seq, ev);
}
-/**
- * \brief reset queue position
- *
- * new values of both real-time and tick values must be given.
- */
-int snd_seq_setpos_queue(snd_seq_t *seq, int q, snd_seq_timestamp_t *rtime, snd_seq_event_t *ev)
-{
- snd_seq_event_t tmpev;
- int result;
-
- if (ev == NULL) {
- snd_seq_ev_clear(&tmpev);
- ev = &tmpev;
- snd_seq_ev_set_direct(ev);
- }
- /* stop the timer */
- result = snd_seq_stop_queue(seq, q, ev);
- /* reset queue position */
- snd_seq_ev_set_queue_pos_real(ev, q, &rtime->time);
- result = snd_seq_event_output(seq, ev);
- snd_seq_ev_set_queue_pos_tick(ev, q, rtime->tick);
- result = snd_seq_event_output(seq, ev);
- /* continue the timer */
- result = snd_seq_continue_queue(seq, q, ev);
-
- return result;
-}
/**
* \brief create a port - simple version
+ * \param seq sequencer handle
+ * \param name the name of the port
+ * \param caps capability bits
+ * \param type type bits
+ * \return the created port number or negative error code
*
- * return the port number
+ * Creates a port with the given capability and type bits.
*/
int snd_seq_create_simple_port(snd_seq_t *seq, const char *name,
unsigned int caps, unsigned int type)
if (name)
strncpy(pinfo.name, name, sizeof(pinfo.name) - 1);
pinfo.capability = caps;
- pinfo.cap_group = caps;
pinfo.type = type;
pinfo.midi_channels = 16;
pinfo.midi_voices = 64; /* XXX */
pinfo.synth_voices = 0; /* XXX */
- pinfo.kernel = NULL;
result = snd_seq_create_port(seq, &pinfo);
if (result < 0)
return result;
else
- return pinfo.port;
+ return pinfo.addr.port;
}
/**
* \brief delete the port
+ * \param seq sequencer handle
+ * \param port port id
+ * \return 0 on success or negavie error code
*/
int snd_seq_delete_simple_port(snd_seq_t *seq, int port)
{
- snd_seq_port_info_t pinfo;
-
- memset(&pinfo, 0, sizeof(pinfo));
- pinfo.port = port;
-
- return snd_seq_delete_port(seq, &pinfo);
+ return snd_seq_delete_port(seq, port);
}
/**
- * \brief sipmle subscription (w/o exclusive & time conversion)
+ * \brief simple subscription (w/o exclusive & time conversion)
+ * \param myport the port id as receiver
+ * \param src_client sender client id
+ * \param src_port sender port id
+ * \return 0 on success or negative error code
+ *
+ * Connect from the given sender client:port to the given destination port in the
+ * current client.
*/
int snd_seq_connect_from(snd_seq_t *seq, int myport, int src_client, int src_port)
{
/**
* \brief sipmle subscription (w/o exclusive & time conversion)
+ * \param myport the port id as sender
+ * \param dest_client destination client id
+ * \param dest_port destination port id
+ * \return 0 on success or negative error code
+ *
+ * Connect from the given receiver port in the current client
+ * to the given destination client:port.
*/
int snd_seq_connect_to(snd_seq_t *seq, int myport, int dest_client, int dest_port)
{
}
/**
- * \brief sipmle disconnection (w/o exclusive & time conversion)
+ * \brief simple disconnection
+ * \param myport the port id as receiver
+ * \param src_client sender client id
+ * \param src_port sender port id
+ * \return 0 on success or negative error code
+ *
+ * Remove connection from the given sender client:port
+ * to the given destination port in the current client.
*/
int snd_seq_disconnect_from(snd_seq_t *seq, int myport, int src_client, int src_port)
{
}
/**
- * \brief sipmle disconnection (w/o exclusive & time conversion)
+ * \brief simple disconnection
+ * \param myport the port id as sender
+ * \param dest_client destination client id
+ * \param dest_port destination port id
+ * \return 0 on success or negative error code
+ *
+ * Remove connection from the given sender client:port
+ * to the given destination port in the current client.
*/
int snd_seq_disconnect_to(snd_seq_t *seq, int myport, int dest_client, int dest_port)
{
/*
* set client information
*/
+
/**
* \brief set client name
+ * \param seq sequencer handle
+ * \param name name string
+ * \return 0 on success or negative error code
*/
int snd_seq_set_client_name(snd_seq_t *seq, const char *name)
{
}
/**
- * \brief set client group
- */
-int snd_seq_set_client_group(snd_seq_t *seq, const char *name)
-{
- snd_seq_client_info_t info;
- int err;
-
- if ((err = snd_seq_get_client_info(seq, &info)) < 0)
- return err;
- strncpy(info.group, name, sizeof(info.group) - 1);
- return snd_seq_set_client_info(seq, &info);
-}
-
-/**
- * \brief set client filter
- */
-int snd_seq_set_client_filter(snd_seq_t *seq, unsigned int filter)
-{
- snd_seq_client_info_t info;
- int err;
-
- if ((err = snd_seq_get_client_info(seq, &info)) < 0)
- return err;
- info.filter = filter;
- return snd_seq_set_client_info(seq, &info);
-}
-
-/**
- * \brief set client event filter
+ * \brief add client event filter
+ * \param seq sequencer handle
+ * \param event_type event type to be added
+ * \return 0 on success or negative error code
*/
int snd_seq_set_client_event_filter(snd_seq_t *seq, int event_type)
{
if ((err = snd_seq_get_client_info(seq, &info)) < 0)
return err;
- info.filter |= SND_SEQ_FILTER_USE_EVENT;
+ info.filter |= SNDRV_SEQ_FILTER_USE_EVENT;
snd_seq_set_bit(event_type, info.event_filter);
return snd_seq_set_client_info(seq, &info);
}
/**
* \brief change the output pool size of the given client
+ * \param seq sequencer handle
+ * \param size output pool size
+ * \return 0 on success or negative error code
*/
-int snd_seq_set_client_pool_output(snd_seq_t *seq, int size)
+int snd_seq_set_client_pool_output(snd_seq_t *seq, size_t size)
{
snd_seq_client_pool_t info;
int err;
/**
* \brief change the output room size of the given client
+ * \param seq sequencer handle
+ * \param size output room size
+ * \return 0 on success or negative error code
*/
-int snd_seq_set_client_pool_output_room(snd_seq_t *seq, int size)
+int snd_seq_set_client_pool_output_room(snd_seq_t *seq, size_t size)
{
snd_seq_client_pool_t info;
int err;
/**
* \brief change the input pool size of the given client
+ * \param seq sequencer handle
+ * \param size input pool size
+ * \return 0 on success or negative error code
*/
-int snd_seq_set_client_pool_input(snd_seq_t *seq, int size)
+int snd_seq_set_client_pool_input(snd_seq_t *seq, size_t size)
{
snd_seq_client_pool_t info;
int err;
/**
* \brief reset client output pool
+ * \param seq sequencer handle
+ * \return 0 on success or negative error code
*/
int snd_seq_reset_pool_output(snd_seq_t *seq)
{
- snd_seq_remove_events_t rmp;
+ struct sndrv_seq_remove_events rmp;
memset(&rmp, 0, sizeof(rmp));
- rmp.output = 1;
- rmp.remove_mode = 0; /* remove all */
+ rmp.remove_mode = SNDRV_SEQ_REMOVE_OUTPUT; /* remove all outputs */
return snd_seq_remove_events(seq, &rmp);
}
/**
* \brief reset client input pool
+ * \param seq sequencer handle
+ * \return 0 on success or negative error code
*/
int snd_seq_reset_pool_input(snd_seq_t *seq)
{
snd_seq_remove_events_t rmp;
memset(&rmp, 0, sizeof(rmp));
- rmp.input = 1;
- rmp.remove_mode = 0; /* remove all */
+ rmp.remove_mode = SNDRV_SEQ_REMOVE_INPUT; /* remove all inputs */
return snd_seq_remove_events(seq, &rmp);
}
+/**
+ * \brief parse the given string and get the sequencer address
+ * \param seq sequencer handle
+ * \param addr the address pointer to be returned
+ * \param arg the string to be parsed
+ * \return 0 on success or negative error code
+ */
+int snd_seq_parse_address(snd_seq_t *seq, snd_seq_addr_t *addr, const char *arg)
+{
+ char *p;
+ int client, port;
+
+ assert(seq && addr && arg);
+
+ if ((p = strpbrk(arg, ":.")) == NULL)
+ return -EINVAL;
+ if ((port = atoi(p + 1)) < 0)
+ return -EINVAL;
+ addr->port = port;
+ if (isdigit(*arg)) {
+ client = atoi(arg);
+ if (client < 0)
+ return -EINVAL;
+ addr->client = client;
+ } else {
+ /* convert from the name */
+ snd_seq_client_info_t cinfo;
+ int len;
+
+ *p = 0;
+ len = (int)(p - arg); /* length of client name */
+ if (len <= 0)
+ return -EINVAL;
+ cinfo.client = -1;
+ while (snd_seq_query_next_client(seq, &cinfo) >= 0) {
+ if (! strncmp(cinfo.name, arg, len)) {
+ addr->client = cinfo.client;
+ return 0;
+ }
+ }
+ return -ENOENT; /* not found */
+ }
+ return 0;
+}
+
return;
}
while ((rc = snd_seq_event_output(seq_handle, ev)) < 0) {
- int seqfd;
- fd_set fds;
- seqfd = snd_seq_poll_descriptor(seq_handle);
- FD_ZERO(&fds);
- FD_SET(seqfd, &fds);
- if ((rc = select(seqfd + 1, NULL, &fds, NULL, NULL)) < 0) {
- printf("select error = %i (%s)\n", rc, snd_strerror(rc));
+ int npfds = snd_seq_poll_descriptors_count(seq_handle, POLLOUT);
+ struct pollfd *pfds = alloca(sizeof(*pfds) * npfds);
+ snd_seq_poll_descriptors(seq_handle, pfds, npfds, POLLOUT);
+ if ((rc = poll(pfds, npfds, -1)) < 0) {
+ printf("poll error = %i (%s)\n", rc, snd_strerror(errno));
exit(1);
}
}
static void do_header(int format, int ntracks, int division)
{
- snd_seq_queue_tempo_t tempo;
+ snd_seq_queue_tempo_t *tempo;
if (verbose >= VERB_INFO)
printf("smf format %d, %d tracks, %d ppq\n", format, ntracks, division);
exit(1);
}
/* set ppq */
+ snd_seq_queue_tempo_alloca(&tempo);
/* ppq must be set before starting timer */
- if (snd_seq_get_queue_tempo(seq_handle, dest_queue, &tempo) < 0) {
+ if (snd_seq_get_queue_tempo(seq_handle, dest_queue, tempo) < 0) {
perror("get_queue_tempo");
exit(1);
}
- if (tempo.ppq != ppq) {
- slave_ppq = tempo.ppq;
- tempo.ppq = ppq;
- if (snd_seq_set_queue_tempo(seq_handle, dest_queue, &tempo) < 0) {
+ if (snd_seq_queue_tempo_get_ppq(tempo) != ppq) {
+ slave_ppq = snd_seq_queue_tempo_get_ppq(tempo);
+ snd_seq_queue_tempo_set_ppq(tempo, ppq);
+ if (snd_seq_set_queue_tempo(seq_handle, dest_queue, tempo) < 0) {
perror("set_queue_tempo");
if (!slave)
exit(1);
} else
slave_ppq = ppq;
if (verbose >= VERB_INFO)
- printf("ALSA Timer updated, PPQ = %d\n", tempo.ppq);
+ printf("ALSA Timer updated, PPQ = %d\n", snd_seq_queue_tempo_get_ppq(tempo));
}
/* start playing... */
/* read event - using select syscall */
while ((left = snd_seq_event_input(seq_handle, &input_event)) >= 0 &&
input_event == NULL) {
- int seqfd;
- fd_set fds;
- seqfd = snd_seq_poll_descriptor(seq_handle);
- FD_ZERO(&fds);
- FD_SET(seqfd, &fds);
- if ((left = select(seqfd + 1, &fds, NULL, NULL, NULL)) < 0) {
- printf("select error = %i (%s)\n", left, snd_strerror(left));
+ int npfds = snd_seq_poll_descriptors_count(seq_handle, POLLIN);
+ struct pollfd *pfds = alloca(sizeof(*pfds) * npfds);
+ snd_seq_poll_descriptors(seq_handle, pfds, npfds, POLLIN);
+ if ((left = poll(pfds, npfds, -1)) < 0) {
+ printf("poll error = %i (%s)\n", errno, snd_strerror(errno));
exit(1);
}
}
/* open sequencer device */
/* Here we open the device read/write mode. */
/* Because we write SND_SEQ_EVENT_ECHO to myself to sync. */
- tmp = snd_seq_open(&seq_handle, SND_SEQ_OPEN);
+ tmp = snd_seq_open(&seq_handle, "hw", SND_SEQ_OPEN_DUPLEX, 0);
if (tmp < 0) {
perror("open /dev/snd/seq");
exit(1);
}
- tmp = snd_seq_block_mode(seq_handle, use_blocking_mode);
+ tmp = snd_seq_nonblock(seq_handle, !use_blocking_mode);
if (tmp < 0) {
perror("block_mode");
exit(1);
/* setup queue */
if (dest_queue >= 0) {
- if (snd_seq_use_queue(seq_handle, dest_queue, 1) < 0) {
+ if (snd_seq_set_queue_usage(seq_handle, dest_queue, 1) < 0) {
perror("use queue");
exit(1);
}
if (slave) {
tmp = snd_seq_connect_from(seq_handle, my_port,
SND_SEQ_CLIENT_SYSTEM,
- snd_seq_queue_sync_port(dest_queue));
+ dest_queue + 16 /*snd_seq_queue_sync_port(dest_queue)*/);
if (tmp < 0) {
perror("subscribe");
exit(1);
*/
static char *event_names[256] = {
- /* 0 */ "System",
- /* 1 */ "Result",
- /* 2 */ "Reserved 2",
- /* 3 */ "Reserved 3",
- /* 4 */ "Reserved 4",
- /* 5 */ "Note",
- /* 6 */ "Note On",
- /* 7 */ "Note Off",
- /* 8 */ "Key Pressure",
- /* 9 */ "Reserved 9",
- /* 10 */ "Controller",
- /* 11 */ "Program Change",
- /* 12 */ "Channel Pressure",
- /* 13 */ "Pitchbend",
- /* 14 */ "Control14",
- /* 15 */ "Nonregparam",
- /* 16 */ "Regparam",
- /* 17 */ "Reserved 17",
- /* 18 */ "Reserved 18",
- /* 19 */ "Reserved 19",
- /* 20 */ "Song Position",
- /* 21 */ "Song Select",
- /* 22 */ "Qframe",
- /* 23 */ "SMF Time Signature",
- /* 24 */ "SMF Key Signature",
- /* 25 */ "Reserved 25",
- /* 26 */ "Reserved 26",
- /* 27 */ "Reserved 27",
- /* 28 */ "Reserved 28",
- /* 29 */ "Reserved 29",
- /* 30 */ "Start",
- /* 31 */ "Continue",
- /* 32 */ "Stop",
- /* 33 */ "Set Position Tick",
- /* 34 */ "Set Position Time",
- /* 35 */ "Tempo",
- /* 36 */ "Clock",
- /* 37 */ "Tick",
- /* 38 */ "Reserved 38",
- /* 39 */ "Reserved 39",
- /* 40 */ "Tune Request",
- /* 41 */ "Reset",
- /* 42 */ "Active Sensing",
- /* 43 */ "Reserved 43",
- /* 44 */ "Reserved 44",
- /* 45 */ "Reserved 45",
- /* 46 */ "Reserved 46",
- /* 47 */ "Reserved 47",
- /* 48 */ "Reserved 48",
- /* 49 */ "Reserved 49",
- /* 50 */ "Echo",
- /* 51 */ "OSS",
- /* 52 */ "Reserved 52",
- /* 53 */ "Reserved 53",
- /* 54 */ "Reserved 54",
- /* 55 */ "Reserved 55",
- /* 56 */ "Reserved 56",
- /* 57 */ "Reserved 57",
- /* 58 */ "Reserved 58",
- /* 59 */ "Reserved 59",
- /* 60 */ "Client Start",
- /* 61 */ "Client Exit",
- /* 62 */ "Client Change",
- /* 63 */ "Port Start",
- /* 64 */ "Port Exit",
- /* 65 */ "Port Change",
- /* 66 */ "Port Subscribed",
- /* 67 */ "Port Used",
- /* 68 */ "Port Unsubscribed",
- /* 69 */ "Port Unused",
- /* 70 */ "Sample",
- /* 71 */ "Sample Cluster",
- /* 72 */ "Sample Start",
- /* 73 */ "Sample Stop",
- /* 74 */ "Sample Freq",
- /* 75 */ "Sample Volume",
- /* 76 */ "Sample Loop",
- /* 77 */ "Sample Position",
- /* 78 */ "Sample Private1",
- /* 79 */ "Reserved 79",
- /* 80 */ "Reserved 80",
- /* 81 */ "Reserved 81",
- /* 82 */ "Reserved 82",
- /* 83 */ "Reserved 83",
- /* 84 */ "Reserved 84",
- /* 85 */ "Reserved 85",
- /* 86 */ "Reserved 86",
- /* 87 */ "Reserved 87",
- /* 88 */ "Reserved 88",
- /* 89 */ "Reserved 89",
- /* 90 */ "User 0",
- /* 91 */ "User 1",
- /* 92 */ "User 2",
- /* 93 */ "User 3",
- /* 94 */ "User 4",
- /* 95 */ "User 5",
- /* 96 */ "User 6",
- /* 97 */ "User 7",
- /* 98 */ "User 8",
- /* 99 */ "User 9",
- /* 100 */ "Instr Begin",
- /* 101 */ "Instr End",
- /* 102 */ "Instr Info",
- /* 103 */ "Instr Info Result",
- /* 104 */ "Instr Finfo",
- /* 105 */ "Instr Finfo Result",
- /* 106 */ "Instr Reset",
- /* 107 */ "Instr Status",
- /* 108 */ "Instr Status Result",
- /* 109 */ "Instr Put",
- /* 110 */ "Instr Get",
- /* 111 */ "Instr Get Result",
- /* 112 */ "Instr Free",
- /* 113 */ "Instr List",
- /* 114 */ "Instr List Result",
- /* 115 */ "Instr Cluster",
- /* 116 */ "Instr Cluster Get",
- /* 117 */ "Instr Cluster Result",
- /* 118 */ "Instr Change",
- /* 119 */ "Reserved 119",
- /* 120 */ "Reserved 120",
- /* 121 */ "Reserved 121",
- /* 122 */ "Reserved 122",
- /* 123 */ "Reserved 123",
- /* 124 */ "Reserved 124",
- /* 125 */ "Reserved 125",
- /* 126 */ "Reserved 126",
- /* 127 */ "Reserved 127",
- /* 128 */ "Reserved 128",
- /* 129 */ "Reserved 129",
- /* 130 */ "Sysex",
- /* 131 */ "Bounce",
- /* 132 */ "Reserved 132",
- /* 133 */ "Reserved 133",
- /* 134 */ "Reserved 134",
- /* 135 */ "User Var0",
- /* 136 */ "User Var1",
- /* 137 */ "User Var2",
- /* 138 */ "User Var3",
- /* 139 */ "User Var4",
- /* 140 */ "IPC Shm",
- /* 141 */ "Reserved 141",
- /* 142 */ "Reserved 142",
- /* 143 */ "Reserved 143",
- /* 144 */ "Reserved 144",
- /* 145 */ "User IPC0",
- /* 146 */ "User IPC1",
- /* 147 */ "User IPC2",
- /* 148 */ "User IPC3",
- /* 149 */ "User IPC4",
- /* 150 */ "Reserved 150",
- /* 151 */ "Reserved 151",
- /* 152 */ "Reserved 152",
- /* 153 */ "Reserved 153",
- /* 154 */ "Reserved 154",
- /* 155 */ "Reserved 155",
- /* 156 */ "Reserved 156",
- /* 157 */ "Reserved 157",
- /* 158 */ "Reserved 158",
- /* 159 */ "Reserved 159",
- /* 160 */ "Reserved 160",
- /* 161 */ "Reserved 161",
- /* 162 */ "Reserved 162",
- /* 163 */ "Reserved 163",
- /* 164 */ "Reserved 164",
- /* 165 */ "Reserved 165",
- /* 166 */ "Reserved 166",
- /* 167 */ "Reserved 167",
- /* 168 */ "Reserved 168",
- /* 169 */ "Reserved 169",
- /* 170 */ "Reserved 170",
- /* 171 */ "Reserved 171",
- /* 172 */ "Reserved 172",
- /* 173 */ "Reserved 173",
- /* 174 */ "Reserved 174",
- /* 175 */ "Reserved 175",
- /* 176 */ "Reserved 176",
- /* 177 */ "Reserved 177",
- /* 178 */ "Reserved 178",
- /* 179 */ "Reserved 179",
- /* 180 */ "Reserved 180",
- /* 181 */ "Reserved 181",
- /* 182 */ "Reserved 182",
- /* 183 */ "Reserved 183",
- /* 184 */ "Reserved 184",
- /* 185 */ "Reserved 185",
- /* 186 */ "Reserved 186",
- /* 187 */ "Reserved 187",
- /* 188 */ "Reserved 188",
- /* 189 */ "Reserved 189",
- /* 190 */ "Reserved 190",
- /* 191 */ "Reserved 191",
- /* 192 */ "Reserved 192",
- /* 193 */ "Reserved 193",
- /* 194 */ "Reserved 194",
- /* 195 */ "Reserved 195",
- /* 196 */ "Reserved 196",
- /* 197 */ "Reserved 197",
- /* 198 */ "Reserved 198",
- /* 199 */ "Reserved 199",
- /* 200 */ "Reserved 200",
- /* 201 */ "Reserved 201",
- /* 202 */ "Reserved 202",
- /* 203 */ "Reserved 203",
- /* 204 */ "Reserved 204",
- /* 205 */ "Reserved 205",
- /* 206 */ "Reserved 206",
- /* 207 */ "Reserved 207",
- /* 208 */ "Reserved 208",
- /* 209 */ "Reserved 209",
- /* 210 */ "Reserved 210",
- /* 211 */ "Reserved 211",
- /* 212 */ "Reserved 212",
- /* 213 */ "Reserved 213",
- /* 214 */ "Reserved 214",
- /* 215 */ "Reserved 215",
- /* 216 */ "Reserved 216",
- /* 217 */ "Reserved 217",
- /* 218 */ "Reserved 218",
- /* 219 */ "Reserved 219",
- /* 220 */ "Reserved 220",
- /* 221 */ "Reserved 221",
- /* 222 */ "Reserved 222",
- /* 223 */ "Reserved 223",
- /* 224 */ "Reserved 224",
- /* 225 */ "Reserved 225",
- /* 226 */ "Reserved 226",
- /* 227 */ "Reserved 227",
- /* 228 */ "Reserved 228",
- /* 229 */ "Reserved 229",
- /* 230 */ "Reserved 230",
- /* 231 */ "Reserved 231",
- /* 232 */ "Reserved 232",
- /* 233 */ "Reserved 233",
- /* 234 */ "Reserved 234",
- /* 235 */ "Reserved 235",
- /* 236 */ "Reserved 236",
- /* 237 */ "Reserved 237",
- /* 238 */ "Reserved 238",
- /* 239 */ "Reserved 239",
- /* 240 */ "Reserved 240",
- /* 241 */ "Reserved 241",
- /* 242 */ "Reserved 242",
- /* 243 */ "Reserved 243",
- /* 244 */ "Reserved 244",
- /* 245 */ "Reserved 245",
- /* 246 */ "Reserved 246",
- /* 247 */ "Reserved 247",
- /* 248 */ "Reserved 248",
- /* 249 */ "Reserved 249",
- /* 250 */ "Reserved 250",
- /* 251 */ "Reserved 251",
- /* 252 */ "Reserved 252",
- /* 253 */ "Reserved 253",
- /* 254 */ "Reserved 254",
- /* 255 */ "None"
+ [SND_SEQ_EVENT_SYSTEM]= "System",
+ [SND_SEQ_EVENT_RESULT]= "Result",
+ [SND_SEQ_EVENT_NOTE]= "Note",
+ [SND_SEQ_EVENT_NOTEON]= "Note On",
+ [SND_SEQ_EVENT_NOTEOFF]= "Note Off",
+ [SND_SEQ_EVENT_KEYPRESS]= "Key Pressure",
+ [SND_SEQ_EVENT_CONTROLLER]= "Controller",
+ [SND_SEQ_EVENT_PGMCHANGE]= "Program Change",
+ [SND_SEQ_EVENT_CHANPRESS]= "Channel Pressure",
+ [SND_SEQ_EVENT_PITCHBEND]= "Pitchbend",
+ [SND_SEQ_EVENT_CONTROL14]= "Control14",
+ [SND_SEQ_EVENT_NONREGPARAM]= "Nonregparam",
+ [SND_SEQ_EVENT_REGPARAM]= "Regparam",
+ [SND_SEQ_EVENT_SONGPOS]= "Song Position",
+ [SND_SEQ_EVENT_SONGSEL]= "Song Select",
+ [SND_SEQ_EVENT_QFRAME]= "Qframe",
+ [SND_SEQ_EVENT_TIMESIGN]= "SMF Time Signature",
+ [SND_SEQ_EVENT_KEYSIGN]= "SMF Key Signature",
+ [SND_SEQ_EVENT_START]= "Start",
+ [SND_SEQ_EVENT_CONTINUE]= "Continue",
+ [SND_SEQ_EVENT_STOP]= "Stop",
+ [SND_SEQ_EVENT_SETPOS_TICK]= "Set Position Tick",
+ [SND_SEQ_EVENT_SETPOS_TIME]= "Set Position Time",
+ [SND_SEQ_EVENT_TEMPO]= "Tempo",
+ [SND_SEQ_EVENT_CLOCK]= "Clock",
+ [SND_SEQ_EVENT_TICK]= "Tick",
+ [SND_SEQ_EVENT_SYNC]= "Sync",
+ [SND_SEQ_EVENT_SYNC_POS]= "Sync Position",
+ [SND_SEQ_EVENT_TUNE_REQUEST]= "Tune Request",
+ [SND_SEQ_EVENT_RESET]= "Reset",
+ [SND_SEQ_EVENT_SENSING]= "Active Sensing",
+ [SND_SEQ_EVENT_ECHO]= "Echo",
+ [SND_SEQ_EVENT_OSS]= "OSS",
+ [SND_SEQ_EVENT_CLIENT_START]= "Client Start",
+ [SND_SEQ_EVENT_CLIENT_EXIT]= "Client Exit",
+ [SND_SEQ_EVENT_CLIENT_CHANGE]= "Client Change",
+ [SND_SEQ_EVENT_PORT_START]= "Port Start",
+ [SND_SEQ_EVENT_PORT_EXIT]= "Port Exit",
+ [SND_SEQ_EVENT_PORT_CHANGE]= "Port Change",
+ [SND_SEQ_EVENT_PORT_SUBSCRIBED]= "Port Subscribed",
+ [SND_SEQ_EVENT_PORT_UNSUBSCRIBED]= "Port Unsubscribed",
+ [SND_SEQ_EVENT_SAMPLE]= "Sample",
+ [SND_SEQ_EVENT_SAMPLE_CLUSTER]= "Sample Cluster",
+ [SND_SEQ_EVENT_SAMPLE_START]= "Sample Start",
+ [SND_SEQ_EVENT_SAMPLE_STOP]= "Sample Stop",
+ [SND_SEQ_EVENT_SAMPLE_FREQ]= "Sample Freq",
+ [SND_SEQ_EVENT_SAMPLE_VOLUME]= "Sample Volume",
+ [SND_SEQ_EVENT_SAMPLE_LOOP]= "Sample Loop",
+ [SND_SEQ_EVENT_SAMPLE_POSITION]= "Sample Position",
+ [SND_SEQ_EVENT_SAMPLE_PRIVATE1]= "Sample Private1",
+ [SND_SEQ_EVENT_USR0]= "User 0",
+ [SND_SEQ_EVENT_USR1]= "User 1",
+ [SND_SEQ_EVENT_USR2]= "User 2",
+ [SND_SEQ_EVENT_USR3]= "User 3",
+ [SND_SEQ_EVENT_USR4]= "User 4",
+ [SND_SEQ_EVENT_USR5]= "User 5",
+ [SND_SEQ_EVENT_USR6]= "User 6",
+ [SND_SEQ_EVENT_USR7]= "User 7",
+ [SND_SEQ_EVENT_USR8]= "User 8",
+ [SND_SEQ_EVENT_USR9]= "User 9",
+ [SND_SEQ_EVENT_INSTR_BEGIN]= "Instr Begin",
+ [SND_SEQ_EVENT_INSTR_END]= "Instr End",
+ [SND_SEQ_EVENT_INSTR_INFO]= "Instr Info",
+ [SND_SEQ_EVENT_INSTR_INFO_RESULT]= "Instr Info Result",
+ [SND_SEQ_EVENT_INSTR_FINFO]= "Instr Font Info",
+ [SND_SEQ_EVENT_INSTR_FINFO_RESULT]= "Instr Font Info Result",
+ [SND_SEQ_EVENT_INSTR_RESET]= "Instr Reset",
+ [SND_SEQ_EVENT_INSTR_STATUS]= "Instr Status",
+ [SND_SEQ_EVENT_INSTR_STATUS_RESULT]= "Instr Status Result",
+ [SND_SEQ_EVENT_INSTR_PUT]= "Instr Put",
+ [SND_SEQ_EVENT_INSTR_GET]= "Instr Get",
+ [SND_SEQ_EVENT_INSTR_GET_RESULT]= "Instr Get Result",
+ [SND_SEQ_EVENT_INSTR_FREE]= "Instr Free",
+ [SND_SEQ_EVENT_INSTR_LIST]= "Instr List",
+ [SND_SEQ_EVENT_INSTR_LIST_RESULT]= "Instr List Result",
+ [SND_SEQ_EVENT_INSTR_CLUSTER]= "Instr Cluster",
+ [SND_SEQ_EVENT_INSTR_CLUSTER_GET]= "Instr Cluster Get",
+ [SND_SEQ_EVENT_INSTR_CLUSTER_RESULT]= "Instr Cluster Result",
+ [SND_SEQ_EVENT_INSTR_CHANGE]= "Instr Change",
+ [SND_SEQ_EVENT_SYSEX]= "Sysex",
+ [SND_SEQ_EVENT_BOUNCE]= "Bounce",
+ [SND_SEQ_EVENT_USR_VAR0]= "User Var0",
+ [SND_SEQ_EVENT_USR_VAR1]= "User Var1",
+ [SND_SEQ_EVENT_USR_VAR2]= "User Var2",
+ [SND_SEQ_EVENT_USR_VAR3]= "User Var3",
+ [SND_SEQ_EVENT_USR_VAR4]= "User Var4",
+ [SND_SEQ_EVENT_IPCSHM]= "IPC Shm",
+ [SND_SEQ_EVENT_USR_VARIPC0]= "User IPC0",
+ [SND_SEQ_EVENT_USR_VARIPC1]= "User IPC1",
+ [SND_SEQ_EVENT_USR_VARIPC2]= "User IPC2",
+ [SND_SEQ_EVENT_USR_VARIPC3]= "User IPC3",
+ [SND_SEQ_EVENT_USR_VARIPC4]= "User IPC4",
+ [SND_SEQ_EVENT_NONE]= "None",
};
int decode_event(snd_seq_event_t * ev)
printf("EVENT>>> Type = %d, flags = 0x%x", ev->type, ev->flags);
switch (ev->flags & SND_SEQ_TIME_STAMP_MASK) {
- case SND_SEQ_TIME_STAMP_TICK:
- printf(", time = %d ticks",
- ev->time.tick);
- break;
- case SND_SEQ_TIME_STAMP_REAL:
- printf(", time = %d.%09d",
- (int)ev->time.time.tv_sec,
- (int)ev->time.time.tv_nsec);
- break;
+ case SND_SEQ_TIME_STAMP_TICK:
+ printf(", time = %d ticks",
+ ev->time.tick);
+ break;
+ case SND_SEQ_TIME_STAMP_REAL:
+ printf(", time = %d.%09d",
+ (int)ev->time.time.tv_sec,
+ (int)ev->time.time.tv_nsec);
+ break;
}
printf("\n%sSource = %d.%d, dest = %d.%d, queue = %d\n",
space,
ev->dest.port,
ev->queue);
- printf("%sEvent = %s", space, event_names[ev->type]);
+ if (event_names[ev->type])
+ printf("%sEvent = %s", space, event_names[ev->type]);
+ else
+ printf("%sEvent = Reserved %d\n", space, ev->type);
/* decode actual event data... */
switch (ev->type) {
- case SND_SEQ_EVENT_NOTE:
- printf("; ch=%d, note=%d, velocity=%d, off_velocity=%d, duration=%d\n",
- ev->data.note.channel,
- ev->data.note.note,
- ev->data.note.velocity,
- ev->data.note.off_velocity,
- ev->data.note.duration);
- break;
+ case SND_SEQ_EVENT_NOTE:
+ printf("; ch=%d, note=%d, velocity=%d, off_velocity=%d, duration=%d\n",
+ ev->data.note.channel,
+ ev->data.note.note,
+ ev->data.note.velocity,
+ ev->data.note.off_velocity,
+ ev->data.note.duration);
+ break;
- case SND_SEQ_EVENT_NOTEON:
- case SND_SEQ_EVENT_NOTEOFF:
- case SND_SEQ_EVENT_KEYPRESS:
- printf("; ch=%d, note=%d, velocity=%d\n",
- ev->data.note.channel,
- ev->data.note.note,
- ev->data.note.velocity);
- break;
+ case SND_SEQ_EVENT_NOTEON:
+ case SND_SEQ_EVENT_NOTEOFF:
+ case SND_SEQ_EVENT_KEYPRESS:
+ printf("; ch=%d, note=%d, velocity=%d\n",
+ ev->data.note.channel,
+ ev->data.note.note,
+ ev->data.note.velocity);
+ break;
- case SND_SEQ_EVENT_CONTROLLER:
- printf("; ch=%d, param=%i, value=%i\n",
- ev->data.control.channel,
- ev->data.control.param,
- ev->data.control.value);
- break;
+ case SND_SEQ_EVENT_CONTROLLER:
+ printf("; ch=%d, param=%i, value=%i\n",
+ ev->data.control.channel,
+ ev->data.control.param,
+ ev->data.control.value);
+ break;
- case SND_SEQ_EVENT_PGMCHANGE:
- printf("; ch=%d, program=%i\n",
- ev->data.control.channel,
- ev->data.control.value);
- break;
+ case SND_SEQ_EVENT_PGMCHANGE:
+ printf("; ch=%d, program=%i\n",
+ ev->data.control.channel,
+ ev->data.control.value);
+ break;
- case SND_SEQ_EVENT_CHANPRESS:
- case SND_SEQ_EVENT_PITCHBEND:
- printf("; ch=%d, value=%i\n",
- ev->data.control.channel,
- ev->data.control.value);
- break;
+ case SND_SEQ_EVENT_CHANPRESS:
+ case SND_SEQ_EVENT_PITCHBEND:
+ printf("; ch=%d, value=%i\n",
+ ev->data.control.channel,
+ ev->data.control.value);
+ break;
- case SND_SEQ_EVENT_SYSEX:
- {
- unsigned char *sysex = (unsigned char *) ev + sizeof(snd_seq_event_t);
- int c;
-
- printf("; len=%d [", ev->data.ext.len);
-
- for (c = 0; c < ev->data.ext.len; c++) {
- printf("%02x%s", sysex[c], c < ev->data.ext.len - 1 ? ":" : "");
- }
- printf("]\n");
- }
- break;
+ case SND_SEQ_EVENT_SYSEX:
+ {
+ unsigned char *sysex = (unsigned char *) ev + sizeof(snd_seq_event_t);
+ unsigned int c;
- case SND_SEQ_EVENT_QFRAME:
- printf("; frame=0x%02x\n", ev->data.control.value);
- break;
+ printf("; len=%d [", ev->data.ext.len);
- case SND_SEQ_EVENT_CLOCK:
- case SND_SEQ_EVENT_START:
- case SND_SEQ_EVENT_CONTINUE:
- case SND_SEQ_EVENT_STOP:
- printf("; queue = %i\n", ev->data.queue.queue);
- break;
+ for (c = 0; c < ev->data.ext.len; c++) {
+ printf("%02x%s", sysex[c], c < ev->data.ext.len - 1 ? ":" : "");
+ }
+ printf("]\n");
+ }
+ break;
+
+ case SND_SEQ_EVENT_QFRAME:
+ printf("; frame=0x%02x\n", ev->data.control.value);
+ break;
+
+ case SND_SEQ_EVENT_CLOCK:
+ case SND_SEQ_EVENT_START:
+ case SND_SEQ_EVENT_CONTINUE:
+ case SND_SEQ_EVENT_STOP:
+ printf("; queue = %i\n", ev->data.queue.queue);
+ break;
- case SND_SEQ_EVENT_SENSING:
- printf("\n");
- break;
+ case SND_SEQ_EVENT_SENSING:
+ printf("\n");
+ break;
- case SND_SEQ_EVENT_ECHO:
- {
- int i;
+ case SND_SEQ_EVENT_ECHO:
+ {
+ int i;
- printf("; ");
- for (i = 0; i < 8; i++) {
- printf("%02i%s", ev->data.raw8.d[i], i < 7 ? ":" : "\n");
- }
- }
- break;
+ printf("; ");
+ for (i = 0; i < 8; i++) {
+ printf("%02i%s", ev->data.raw8.d[i], i < 7 ? ":" : "\n");
+ }
+ }
+ break;
- case SND_SEQ_EVENT_CLIENT_START:
- case SND_SEQ_EVENT_CLIENT_EXIT:
- case SND_SEQ_EVENT_CLIENT_CHANGE:
- printf("; client=%i\n", ev->data.addr.client);
- break;
+ case SND_SEQ_EVENT_CLIENT_START:
+ case SND_SEQ_EVENT_CLIENT_EXIT:
+ case SND_SEQ_EVENT_CLIENT_CHANGE:
+ printf("; client=%i\n", ev->data.addr.client);
+ break;
- case SND_SEQ_EVENT_PORT_START:
- case SND_SEQ_EVENT_PORT_EXIT:
- case SND_SEQ_EVENT_PORT_CHANGE:
- case SND_SEQ_EVENT_PORT_SUBSCRIBED:
- case SND_SEQ_EVENT_PORT_USED:
- case SND_SEQ_EVENT_PORT_UNSUBSCRIBED:
- case SND_SEQ_EVENT_PORT_UNUSED:
- printf("; client=%i, port = %i\n", ev->data.addr.client, ev->data.addr.port);
- break;
+ case SND_SEQ_EVENT_PORT_START:
+ case SND_SEQ_EVENT_PORT_EXIT:
+ case SND_SEQ_EVENT_PORT_CHANGE:
+ printf("; client=%i, port = %i\n", ev->data.addr.client, ev->data.addr.port);
+ break;
+
+ case SND_SEQ_EVENT_PORT_SUBSCRIBED:
+ case SND_SEQ_EVENT_PORT_UNSUBSCRIBED:
+ printf("; %i:%i -> %i:%i\n",
+ ev->data.connect.sender.client, ev->data.connect.sender.port,
+ ev->data.connect.dest.client, ev->data.connect.dest.port);
+ break;
- default:
- printf("; not implemented\n");
+ default:
+ printf("; not implemented\n");
}
switch (ev->flags & SND_SEQ_EVENT_LENGTH_MASK) {
- case SND_SEQ_EVENT_LENGTH_FIXED:
- return sizeof(snd_seq_event_t);
+ case SND_SEQ_EVENT_LENGTH_FIXED:
+ return sizeof(snd_seq_event_t);
- case SND_SEQ_EVENT_LENGTH_VARIABLE:
- return sizeof(snd_seq_event_t) + ev->data.ext.len;
+ case SND_SEQ_EVENT_LENGTH_VARIABLE:
+ return sizeof(snd_seq_event_t) + ev->data.ext.len;
}
return 0;
void event_decoder(snd_seq_t *handle, int argc, char *argv[])
{
snd_seq_event_t *ev;
- snd_seq_port_info_t port;
- snd_seq_port_subscribe_t sub;
- fd_set in;
- int client, queue, max, err, v1, v2;
+ snd_seq_port_info_t *pinfo;
+ snd_seq_port_subscribe_t *sub;
+ snd_seq_addr_t addr;
+ int client, port, queue, max, err, v1, v2;
char *ptr;
+ struct pollfd *pfds;
if ((client = snd_seq_client_id(handle))<0) {
fprintf(stderr, "Cannot determine client number: %s\n", snd_strerror(client));
return;
}
printf("Queue ID = %i\n", queue);
- if ((err = snd_seq_block_mode(handle, 0))<0)
+ if ((err = snd_seq_nonblock(handle, 1))<0)
fprintf(stderr, "Cannot set nonblock mode: %s\n", snd_strerror(err));
- bzero(&port, sizeof(port));
- strcpy(port.name, "Input");
- port.capability = SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_READ;
- port.capability |= SND_SEQ_PORT_CAP_SUBS_WRITE;
- if ((err = snd_seq_create_port(handle, &port)) < 0) {
+ snd_seq_port_info_alloca(&pinfo);
+ snd_seq_port_info_set_name(pinfo, "Input");
+ snd_seq_port_info_set_capability(pinfo, SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_WRITE);
+ if ((err = snd_seq_create_port(handle, pinfo)) < 0) {
fprintf(stderr, "Cannot create input port: %s\n", snd_strerror(err));
return;
}
- event_decoder_start_timer(handle, queue, client, port.port);
+ port = snd_seq_port_info_get_port(pinfo);
+ event_decoder_start_timer(handle, queue, client, port);
- bzero(&sub, sizeof(sub));
- sub.sender.client = SND_SEQ_CLIENT_SYSTEM;
- sub.sender.port = SND_SEQ_PORT_SYSTEM_ANNOUNCE;
- sub.dest.client = client;
- sub.dest.port = port.port;
- sub.queue = queue;
- sub.exclusive = 0;
- sub.convert_time = 1;
- sub.realtime = 1;
- if ((err = snd_seq_subscribe_port(handle, &sub))<0) {
+ snd_seq_port_subscribe_alloca(&sub);
+ addr.client = SND_SEQ_CLIENT_SYSTEM;
+ addr.port = SND_SEQ_PORT_SYSTEM_ANNOUNCE;
+ snd_seq_port_subscribe_set_sender(sub, &addr);
+ addr.client = client;
+ addr.port = port;
+ snd_seq_port_subscribe_set_dest(sub, &addr);
+ snd_seq_port_subscribe_set_queue(sub, queue);
+ snd_seq_port_subscribe_set_time_update(sub, 1);
+ snd_seq_port_subscribe_set_time_real(sub, 1);
+ if ((err = snd_seq_subscribe_port(handle, sub))<0) {
fprintf(stderr, "Cannot subscribe announce port: %s\n", snd_strerror(err));
return;
}
- sub.sender.port = SND_SEQ_PORT_SYSTEM_TIMER;
- if ((err = snd_seq_subscribe_port(handle, &sub))<0) {
+
+ addr.client = SND_SEQ_CLIENT_SYSTEM;
+ addr.port = SND_SEQ_PORT_SYSTEM_TIMER;
+ snd_seq_port_subscribe_set_sender(sub, &addr);
+ if ((err = snd_seq_subscribe_port(handle, sub))<0) {
fprintf(stderr, "Cannot subscribe timer port: %s\n", snd_strerror(err));
return;
}
ptr = argv[max];
if (!ptr)
continue;
- sub.realtime = 0;
+ snd_seq_port_subscribe_set_time_real(sub, 0);
if (tolower(*ptr) == 'r') {
- sub.realtime = 1;
+ snd_seq_port_subscribe_set_time_real(sub, 1);
ptr++;
}
if (sscanf(ptr, "%i.%i", &v1, &v2) != 2) {
fprintf(stderr, "Wrong argument '%s'...\n", argv[max]);
return;
}
- sub.sender.client = v1;
- sub.sender.port = v2;
- if ((err = snd_seq_subscribe_port(handle, &sub))<0) {
+ addr.client = v1;
+ addr.port = v2;
+ snd_seq_port_subscribe_set_sender(sub, &addr);
+ if ((err = snd_seq_subscribe_port(handle, sub))<0) {
fprintf(stderr, "Cannot subscribe port %i from client %i: %s\n", v2, v1, snd_strerror(err));
return;
}
}
+ max = snd_seq_poll_descriptors_count(handle, POLLIN);
+ pfds = alloca(sizeof(*pfds) * max);
while (1) {
- FD_ZERO(&in);
- FD_SET(max = snd_seq_poll_descriptor(handle), &in);
- if (select(max + 1, &in, NULL, NULL, NULL) < 0)
+ snd_seq_poll_descriptors(handle, pfds, max, POLLIN);
+ if (poll(pfds, max, -1) < 0)
break;
do {
if ((err = snd_seq_event_input(handle, &ev))<0)
-#ifdef USE_PCM
+#ifdef USE_PCM // XXX not yet
/*
* PCM timer layer
*/
int pcard = 0;
int pdevice = 0;
-int pfragment_size = 4096;
+int period_size = 1024;
-void set_format(snd_pcm_t *phandle)
+void set_hwparams(snd_pcm_t *phandle)
{
int err;
- snd_pcm_format_t format;
+ snd_pcm_hw_params_t *params;
- bzero(&format, sizeof(format));
- format.sfmt = SND_PCM_FORMAT_S16_LE;
- format.channels = 2;
- format.rate = 44100;
- if ((err = snd_pcm_playback_format(phandle, &format)) < 0) {
- fprintf(stderr, "Playback format error: %s\n", snd_strerror(err));
+ err = snd_output_stdio_attach(&log, stderr, 0);
+ if (err < 0) {
+ fprintf(stderr, "cannot attach output stdio\n");
exit(0);
}
-}
-void set_fragment(snd_pcm_t *phandle)
-{
- int err;
- snd_pcm_playback_params_t pparams;
-
- bzero(&pparams, sizeof(pparams));
- pparams.fragment_size = pfragment_size;
- pparams.fragments_max = -1; /* maximum */
- pparams.fragments_room = 1;
- if ((err = snd_pcm_playback_params(phandle, &pparams)) < 0) {
- fprintf(stderr, "Fragment setup error: %s\n", snd_strerror(err));
+ snd_pcm_hw_params_alloca(¶ms);
+ err = snd_pcm_hw_params_any(phandle, params);
+ if (err < 0) {
+ fprintf(stderr, "Broken configuration for this PCM: no configurations available\n");
exit(0);
}
-}
-
-void show_playback_status(snd_pcm_t *phandle)
-{
- int err;
- snd_pcm_playback_status_t pstatus;
- if ((err = snd_pcm_playback_status(phandle, &pstatus)) < 0) {
- fprintf(stderr, "Playback status error: %s\n", snd_strerror(err));
+ err = snd_pcm_hw_params_set_access(phandle, params,
+ SND_PCM_ACCESS_RW_INTERLEAVED);
+ if (err < 0) {
+ fprintf(stderr, "Access type not available\n");
+ exit(0);
+ }
+ err = snd_pcm_hw_params_set_format(phandle, params, SND_PCM_FORMAT_S16_LE);
+ if (err < 0) {
+ fprintf(stderr, "cannot set format\n");
exit(0);
}
- printf("Playback status\n");
- printf(" Real rate : %u\n", pstatus.rate);
- printf(" Fragments : %i\n", pstatus.fragments);
- printf(" Fragment size : %i\n", pstatus.fragment_size);
+ err = snd_pcm_hw_params_set_channels(phandle, params, 2);
+ if (err < 0) {
+ fprintf(stderr, "cannot set channels 2\n");
+ exit(0);
+ }
+ err = snd_pcm_hw_params_set_rate_near(phandle, params, 44100, 0);
+ if (err < 0) {
+ fprintf(stderr, "cannot set rate\n");
+ exit(0);
+ }
+ err = snd_pcm_hw_params_set_period_size_near(phandle, params, period_size);
+ if (err < 0) {
+ fprintf(stderr, "cannot set period size\n");
+ exit(0);
+ }
+ err = snd_pcm_hw_params(phandle, params);
+ if (err < 0) {
+ fprintf(stderr, "Unable to install hw params:\n");
+ exit(0);
+ }
+ snd_pcm_hw_params_dump(params, log);
}
+
#endif
/*
* Simple event sender
void event_sender_filter(snd_seq_t *handle)
{
int err;
- snd_seq_client_info_t info;
- if ((err = snd_seq_get_client_info(handle, &info)) < 0) {
- fprintf(stderr, "Unable to get client info: %s\n", snd_strerror(err));
- return;
- }
- info.filter = SND_SEQ_FILTER_USE_EVENT;
- memset(&info.event_filter, 0, sizeof(info.event_filter));
- snd_seq_set_bit(SND_SEQ_EVENT_ECHO, info.event_filter);
- if ((err = snd_seq_set_client_info(handle, &info)) < 0) {
+ if ((err = snd_seq_set_client_event_filter(handle, SND_SEQ_EVENT_ECHO)) < 0) {
fprintf(stderr, "Unable to set client info: %s\n", snd_strerror(err));
return;
}
}
void send_event(snd_seq_t *handle, int queue, int client, int port,
- snd_seq_port_subscribe_t *sub, int *time)
+ snd_seq_addr_t *dest, int *time)
{
int err;
snd_seq_event_t ev;
ev.type = SND_SEQ_EVENT_ECHO;
if ((err = snd_seq_event_output(handle, &ev))<0)
fprintf(stderr, "Event output error: %s\n", snd_strerror(err));
- ev.dest.client = sub->dest.client;
- ev.dest.port = sub->dest.port;
+ ev.dest = *dest;
ev.type = SND_SEQ_EVENT_PGMCHANGE;
ev.data.control.channel = 0;
ev.data.control.value = 16;
void event_sender(snd_seq_t *handle, int argc, char *argv[])
{
snd_seq_event_t *ev;
- snd_seq_port_info_t port;
- snd_seq_port_subscribe_t sub;
- fd_set out, in;
- int client, queue, max, err, v1, v2, time = 0, pcm_flag = 0;
+ snd_seq_port_info_t *pinfo;
+ snd_seq_port_subscribe_t *sub;
+ snd_seq_addr_t addr;
+ struct pollfd *pfds;
+ int client, port, queue, max, err, v1, v2, time = 0, pcm_flag = 0;
char *ptr;
snd_pcm_t *phandle = NULL;
}
printf("Queue ID = %i\n", queue);
event_sender_filter(handle);
- if ((err = snd_seq_block_mode(handle, 0))<0)
+ if ((err = snd_seq_nonblock(handle, 1))<0)
fprintf(stderr, "Cannot set nonblock mode: %s\n", snd_strerror(err));
- bzero(&port, sizeof(port));
- port.capability = SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_READ;
- strcpy(port.name, "Output");
- if ((err = snd_seq_create_port(handle, &port)) < 0) {
+
+ snd_seq_port_info_alloca(&pinfo);
+ snd_seq_port_info_set_capability(pinfo, SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_READ);
+ snd_seq_port_info_set_name(pinfo, "Output");
+ if ((err = snd_seq_create_port(handle, pinfo)) < 0) {
fprintf(stderr, "Cannot create output port: %s\n", snd_strerror(err));
return;
}
+ port = snd_seq_port_info_get_port(pinfo);
- bzero(&sub, sizeof(sub));
- sub.sender.client = client;
- sub.sender.port = port.port;
- sub.exclusive = 0;
+ snd_seq_port_subscribe_alloca(&sub);
+ addr.client = client;
+ addr.port = port;
+ snd_seq_port_subscribe_set_sender(sub, &addr);
for (max = 0; max < argc; max++) {
ptr = argv[max];
fprintf(stderr, "Wrong argument '%s'...\n", argv[max]);
return;
}
- sub.dest.client = v1;
- sub.dest.port = v2;
- if ((err = snd_seq_subscribe_port(handle, &sub))<0) {
+ addr.client = v1;
+ addr.port = v2;
+ snd_seq_port_subscribe_set_dest(sub, &addr);
+ if ((err = snd_seq_subscribe_port(handle, sub))<0) {
fprintf(stderr, "Cannot subscribe port %i from client %i: %s\n", v2, v1, snd_strerror(err));
return;
}
}
- printf("Destination client = %i, port = %i\n", sub.dest.client, sub.dest.port);
+ printf("Destination client = %i, port = %i\n", addr.client, addr.port);
#ifdef USE_PCM
if (pcm_flag) {
- if ((err = snd_pcm_open(&phandle, pcard, pdevice, SND_PCM_OPEN_PLAYBACK)) < 0) {
+ if ((err = snd_pcm_open(&phandle, "default", SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
fprintf(stderr, "Playback open error: %s\n", snd_strerror(err));
exit(0);
}
- set_format(phandle);
- set_fragment(phandle);
- show_playback_status(phandle);
- pbuf = calloc(1, pfragment_size);
+ set_hwparams(phandle);
+ pbuf = calloc(1, period_size * 4);
if (pbuf == NULL) {
fprintf(stderr, "No enough memory...\n");
exit(0);
event_sender_start_timer(handle, client, queue, phandle);
/* send the first event */
- send_event(handle, queue, client, port.port, &sub, &time);
-
+ send_event(handle, queue, client, port, &addr, &time);
+#ifdef USE_PCM
+ if (phandle)
+ max += snd_pcm_poll_descriptors_count(phandle);
+#endif
+ pfds = alloca(sizeof(*pfds) * max);
while (1) {
- FD_ZERO(&out);
- FD_ZERO(&in);
- max = snd_seq_poll_descriptor(handle);
- FD_SET(snd_seq_poll_descriptor(handle), &in);
- if (snd_seq_event_output_pending(handle)) {
- FD_SET(snd_seq_poll_descriptor(handle), &out);
- }
+ int nseqs = snd_seq_poll_descriptors_count(handle, POLLOUT|POLLIN);
+ if (snd_seq_event_output_pending(handle))
+ snd_seq_poll_descriptors(handle, pfds, nseqs, POLLOUT|POLLIN);
+ else
+ snd_seq_poll_descriptors(handle, pfds, nseqs, POLLIN);
+ max = nseqs;
#ifdef USE_PCM
if (phandle) {
- if (snd_pcm_poll_descriptor(phandle) > max)
- max = snd_pcm_poll_descriptor(phandle);
- FD_SET(snd_pcm_poll_descriptor(phandle), &out);
+ int pmax = snd_pcm_poll_descriptors_count(phandle);
+ snd_seq_poll_descriptors(phandle, pfds + max, pmax);
+ max += pmax;
}
#endif
- if (select(max + 1, &in, &out, NULL, NULL) < 0)
+ if (poll(pfds, max, -1) < 0)
break;
#ifdef USE_PCM
- if (phandle && FD_ISSET(snd_pcm_poll_descriptor(phandle), &out)) {
- if (snd_pcm_writei(phandle, pbuf, pfragment_size) != pfragment_size) {
+ if (phandle && (pfds[nseqs].revents & POLLOUT)) {
+ if (snd_pcm_writei(phandle, pbuf, period_size) != period_size) {
fprintf(stderr, "Playback write error!!\n");
exit(0);
}
}
#endif
- if (FD_ISSET(snd_seq_poll_descriptor(handle), &out))
+ if (pfds[0].revents & POLLOUT)
snd_seq_drain_output(handle);
- if (FD_ISSET(snd_seq_poll_descriptor(handle), &in)) {
+ if (pfds[0].revents & POLLIN) {
do {
if ((err = snd_seq_event_input(handle, &ev))<0)
break;
if (!ev)
continue;
if (ev->type == SND_SEQ_EVENT_ECHO)
- send_event(handle, queue, client, port.port, &sub, &time);
+ send_event(handle, queue, client, port, &addr, &time);
decode_event(ev);
snd_seq_free_event(ev);
} while (err > 0);
#define HELPID_VERBOSE 1002
#define HELPID_VERSION 1003
-snd_seq_system_info_t sysinfo;
+int max_clients;
+int max_ports;
+int max_queues;
int debug = 0;
int verbose = 0;
void set_name(snd_seq_t *handle)
{
int err;
- snd_seq_client_info_t info;
+ char name[64];
- bzero(&info, sizeof(info));
- info.client = snd_seq_client_id(handle);
- info.type = USER_CLIENT;
- snprintf(info.name, sizeof(info.name), "SeqUtil - %i", getpid());
- if ((err = snd_seq_set_client_info(handle, &info)) < 0) {
+ sprintf(name, "SeqUtil - %i", getpid());
+ if ((err = snd_seq_set_client_name(handle, name)) < 0) {
fprintf(stderr, "Set client info error: %s\n", snd_strerror(err));
exit(0);
}
void system_info(snd_seq_t *handle)
{
int err;
+ snd_seq_system_info_t *sysinfo;
- if ((err = snd_seq_system_info(handle, &sysinfo))<0) {
+ snd_seq_system_info_alloca(&sysinfo);
+ if ((err = snd_seq_system_info(handle, sysinfo))<0) {
fprintf(stderr, "System info error: %s\n", snd_strerror(err));
exit(0);
}
+ max_clients = snd_seq_system_info_get_clients(sysinfo);
+ max_ports = snd_seq_system_info_get_ports(sysinfo);
+ max_queues = snd_seq_system_info_get_ports(sysinfo);
}
void show_system_info(snd_seq_t *handle)
{
printf("System info\n");
- printf(" Max queues : %i\n", sysinfo.queues);
- printf(" Max clients : %i\n", sysinfo.clients);
- printf(" Max ports : %i\n", sysinfo.ports);
+ printf(" Max queues : %i\n", max_queues);
+ printf(" Max clients : %i\n", max_clients);
+ printf(" Max ports : %i\n", max_ports);
}
void show_queue_status(snd_seq_t *handle, int queue)
{
int err, idx, min, max;
- snd_seq_queue_status_t status;
-
+ snd_seq_queue_status_t *status;
+
+ snd_seq_queue_status_alloca(&status);
min = queue < 0 ? 0 : queue;
- max = queue < 0 ? sysinfo.queues : queue + 1;
+ max = queue < 0 ? max_queues : queue + 1;
for (idx = min; idx < max; idx++) {
- if ((err = snd_seq_get_queue_status(handle, idx, &status))<0) {
+ if ((err = snd_seq_get_queue_status(handle, idx, status))<0) {
if (err == -ENOENT)
continue;
fprintf(stderr, "Client %i info error: %s\n", idx, snd_strerror(err));
exit(0);
}
- printf("Queue %i info\n", status.queue);
- printf(" Tick : %u\n", status.tick);
- printf(" Realtime : %li.%li\n", status.time.tv_sec, status.time.tv_nsec);
- printf(" Flags : 0x%x\n", status.flags);
+ printf("Queue %i info\n", snd_seq_queue_status_get_queue(status));
+ printf(" Tick : %u\n", snd_seq_queue_status_get_tick_time(status));
+ printf(" Realtime : %i.%i\n",
+ snd_seq_queue_status_get_real_time(status)->tv_sec,
+ snd_seq_queue_status_get_real_time(status)->tv_nsec);
+ printf(" Flags : 0x%x\n", snd_seq_queue_status_get_status(status));
}
}
void show_port_info(snd_seq_t *handle, int client, int port)
{
int err, idx, min, max;
- snd_seq_port_info_t info;
+ snd_seq_port_info_t *info;
+ snd_seq_port_info_alloca(&info);
min = port < 0 ? 0 : port;
- max = port < 0 ? sysinfo.ports : port + 1;
+ max = port < 0 ? max_ports : port + 1;
for (idx = min; idx < max; idx++) {
- if ((err = snd_seq_get_any_port_info(handle, client, idx, &info))<0) {
+ if ((err = snd_seq_get_any_port_info(handle, client, idx, info))<0) {
if (err == -ENOENT)
continue;
fprintf(stderr, "Port %i/%i info error: %s\n", client, idx, snd_strerror(err));
exit(0);
}
printf(" Port %i info\n", idx);
- printf(" Client : %i\n", info.client);
- printf(" Port : %i\n", info.port);
- printf(" Name : %s\n", info.name);
- printf(" Capability : 0x%x\n", info.capability);
- printf(" Type : 0x%x\n", info.type);
- printf(" Midi channels : %i\n", info.midi_channels);
- printf(" Synth voices : %i\n", info.synth_voices);
- printf(" Output subs : %i\n", info.write_use);
- printf(" Input subs : %i\n", info.read_use);
+ printf(" Client : %i\n", snd_seq_port_info_get_client(info));
+ printf(" Port : %i\n", snd_seq_port_info_get_port(info));
+ printf(" Name : %s\n", snd_seq_port_info_get_name(info));
+ printf(" Capability : 0x%x\n", snd_seq_port_info_get_capability(info));
+ printf(" Type : 0x%x\n", snd_seq_port_info_get_type(info));
+ //printf(" Midi channels : %i\n", info.midi_channels);
+ //printf(" Synth voices : %i\n", info.synth_voices);
+ printf(" Output subs : %i\n", snd_seq_port_info_get_write_use(info));
+ printf(" Input subs : %i\n", snd_seq_port_info_get_read_use(info));
}
}
void show_client_info(snd_seq_t *handle, int client)
{
int err, idx, min, max;
- snd_seq_client_info_t info;
+ snd_seq_client_info_t *info;
+ snd_seq_client_info_alloca(&info);
min = client < 0 ? 0 : client;
- max = client < 0 ? sysinfo.clients : client + 1;
+ max = client < 0 ? max_clients : client + 1;
for (idx = min; idx < max; idx++) {
- if ((err = snd_seq_get_any_client_info(handle, idx, &info))<0) {
+ if ((err = snd_seq_get_any_client_info(handle, idx, info))<0) {
if (err == -ENOENT)
continue;
fprintf(stderr, "Client %i info error: %s\n", idx, snd_strerror(err));
}
printf("Client %i info\n", idx);
if (verbose)
- printf(" Client : %i\n", info.client);
- printf(" Type : %s\n", info.type == KERNEL_CLIENT ? "kernel" : "user");
- printf(" Name : %s\n", info.name);
+ printf(" Client : %i\n", snd_seq_client_info_get_client(info));
+ printf(" Type : %s\n", snd_seq_client_info_get_type(info) == SND_SEQ_KERNEL_CLIENT ? "kernel" : "user");
+ printf(" Name : %s\n", snd_seq_client_info_get_name(info));
}
}
fprintf(stderr, "seq: Specify command...\n");
return 0;
}
- if ((err = snd_seq_open(&handle, SND_SEQ_OPEN))<0) {
+ if ((err = snd_seq_open(&handle, "hw", SND_SEQ_OPEN_DUPLEX, 0))<0) {
fprintf(stderr, "Open error: %s\n", snd_strerror(err));
exit(0);
}