]> git.alsa-project.org Git - alsa-lib.git/commitdiff
Major change to sequencer API.
authorJaroslav Kysela <perex@perex.cz>
Wed, 4 Jul 2001 13:54:13 +0000 (13:54 +0000)
committerJaroslav Kysela <perex@perex.cz>
Wed, 4 Jul 2001 13:54:13 +0000 (13:54 +0000)
The sequencer API is totally recoded with the style of "encapsulation"
in other api.
The structure becomes opaque and accessed only via functions.

Other changes:
- There is no longer group in client and port info.
- snd_seq_query_subs_t is renamed to snd_seq_query_subscribe_t.
- snd_seq_delete_port takes only the port id argument instead of
  port_info structure.
- snd_seq_input/output_buffer_size are renamed
  as snd_seq_get_input/output_buffer_size.
  Similarly snd_seq_resize_input/output_buffer are renamed as
  snd_seq_set_input/output_buffer_size.
- snd_seq_get_named_queue is renamed to snd_seq_query_named_queue.
- Sync codes are removed temporarily from API.
- Subscription conditions are accessed via the corresponding functions.
  convert_time is named now as time_update.
- snd_seq_get/set_queue_owner are removed.
  Use snd_seq_get/set_queue_info instead.
- Instrument put/get/remove structure is unified as snd_instr_header_t.

20 files changed:
include/Makefile.am
include/instr.h
include/local.h
include/seq.h
include/seq_event.h [new file with mode: 0644]
include/seqmid.h
src/instr/fm.c
src/instr/iwffff.c
src/instr/simple.c
src/seq/Makefile.am
src/seq/seq.c
src/seq/seq_event.c [new file with mode: 0644]
src/seq/seq_hw.c
src/seq/seq_local.h
src/seq/seq_midi_event.c
src/seq/seqmid.c
test/playmidi1.c
test/seq-decoder.c
test/seq-sender.c
test/seq.c

index 72e0b1d6e2c1ad68c09bd27f6fb28af883ad5a02..14ba36fec08653f8d260fca46d0dc0a409da8ae8 100644 (file)
@@ -7,7 +7,7 @@ header_files=header.h version.h global.h input.h output.h error.h \
             conf.h pcm.h rawmidi.h timer.h \
             hwdep.h hwdep_m4.h control.h \
             mixer.h \
-            seq.h seqmid.h seq_midi_event.h \
+            seq_event.h seq.h seqmid.h seq_midi_event.h \
              conv.h instr.h footer.h
 
 noinst_HEADERS=$(header_files) search.h list.h aserver.h local.h
index bff722cd8ea2d8daad57cdac6e10961b2e54c0b1..cabd02fb9178231bae4e97a8943822b405dbcc47 100644 (file)
  *  \{
  */
 
-/* FM instrument support */
+/* instrument get/put */
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct _snd_instr_header snd_instr_header_t;
+
+size_t snd_instr_header_sizeof(void);
+#define snd_instr_header_alloca(ptr) \
+do {\
+       assert(ptr);\
+       *ptr = (snd_instr_header_t *)alloca(snd_instr_header_sizeof());\
+       memset(*ptr, 0, snd_instr_header_sizeof());\
+} while (0)
+int snd_instr_header_malloc(snd_instr_header_t **ptr, size_t len);
+void snd_instr_header_free(snd_instr_header_t *ptr);
+void snd_instr_header_copy(snd_instr_header_t *dst, const snd_instr_header_t *src);
+
+const snd_seq_instr_t *snd_instr_header_get_id(const snd_instr_header_t *info);
+snd_seq_instr_cluster_t snd_instr_header_get_cluster(const snd_instr_header_t *info);
+unsigned int snd_instr_header_get_cmd(const snd_instr_header_t *info);
+size_t snd_instr_header_get_len(const snd_instr_header_t *info);
+const char *snd_instr_header_get_name(const snd_instr_header_t *info);
+int snd_instr_header_get_type(const snd_instr_header_t *info);
+const char *snd_instr_header_get_format(const snd_instr_header_t *info);
+const snd_seq_instr_t *snd_instr_header_get_alias(const snd_instr_header_t *info);
+void *snd_instr_header_get_data(const snd_instr_header_t *info);
+int snd_instr_header_get_follow_alias(const snd_instr_header_t *info);
+
+void snd_instr_header_set_id(snd_instr_header_t *info, const snd_seq_instr_t *id);
+void snd_instr_header_set_cluster(snd_instr_header_t *info, snd_seq_instr_cluster_t cluster);
+void snd_instr_header_set_cmd(snd_instr_header_t *info, unsigned int cmd);
+void snd_instr_header_set_len(snd_instr_header_t *info, size_t len);
+void snd_instr_header_set_name(snd_instr_header_t *info, const char *name);
+void snd_instr_header_set_type(snd_instr_header_t *info, int type);
+void snd_instr_header_set_format(snd_instr_header_t *info, const char *format);
+void snd_instr_header_set_alias(snd_instr_header_t *info, const snd_seq_instr_t *instr);
+void snd_instr_header_set_follow_alias(snd_instr_header_t *info, int bool);
+
+#ifdef __cplusplus
+}
+#endif
+
+/**
+ *  Instrument abstraction layer
+ *     - based on events
+ */
+
+/** instrument types */
+#define SND_SEQ_INSTR_ATYPE_DATA       0       /**< instrument data */
+#define SND_SEQ_INSTR_ATYPE_ALIAS      1       /**< instrument alias */
+
+/** instrument ASCII identifiers */
+#define SND_SEQ_INSTR_ID_DLS1          "DLS1"          /**< DLS1 */
+#define SND_SEQ_INSTR_ID_DLS2          "DLS2"          /**< DLS2 */
+#define SND_SEQ_INSTR_ID_SIMPLE                "Simple Wave"   /**< Simple Wave */
+#define SND_SEQ_INSTR_ID_SOUNDFONT     "SoundFont"     /**< SoundFont */
+#define SND_SEQ_INSTR_ID_GUS_PATCH     "GUS Patch"     /**< Gravis Patch */
+#define SND_SEQ_INSTR_ID_INTERWAVE     "InterWave FFFF"        /**< InterWave FFFF */
+#define SND_SEQ_INSTR_ID_OPL2_3                "OPL2/3 FM"     /**< OPL2/3 FM */
+#define SND_SEQ_INSTR_ID_OPL4          "OPL4"          /**< OPL4 */
+
+/** instrument types */
+#define SND_SEQ_INSTR_TYPE0_DLS1       (1<<0)  /**< MIDI DLS v1 */
+#define SND_SEQ_INSTR_TYPE0_DLS2       (1<<1)  /**< MIDI DLS v2 */
+#define SND_SEQ_INSTR_TYPE1_SIMPLE     (1<<0)  /**< Simple Wave */
+#define SND_SEQ_INSTR_TYPE1_SOUNDFONT  (1<<1)  /**< EMU SoundFont */
+#define SND_SEQ_INSTR_TYPE1_GUS_PATCH  (1<<2)  /**< Gravis UltraSound Patch */
+#define SND_SEQ_INSTR_TYPE1_INTERWAVE  (1<<3)  /**< InterWave FFFF */
+#define SND_SEQ_INSTR_TYPE2_OPL2_3     (1<<0)  /**< Yamaha OPL2/3 FM */
+#define SND_SEQ_INSTR_TYPE2_OPL4       (1<<1)  /**< Yamaha OPL4 */
+
+/** put commands */
+#define SND_SEQ_INSTR_PUT_CMD_CREATE   0       /**< create a new layer */
+#define SND_SEQ_INSTR_PUT_CMD_REPLACE  1       /**< replace the old layer with new one */
+#define SND_SEQ_INSTR_PUT_CMD_MODIFY   2       /**< modify the existing layer */
+#define SND_SEQ_INSTR_PUT_CMD_ADD      3       /**< add one to the existing layer */
+#define SND_SEQ_INSTR_PUT_CMD_REMOVE   4       /**< remove the layer */
+
+/** get commands */
+#define SND_SEQ_INSTR_GET_CMD_FULL     0       /**< get the full data stream */
+#define SND_SEQ_INSTR_GET_CMD_PARTIAL  1       /**< get the partial data stream */
+
+/** free commands */
+#define SND_SEQ_INSTR_FREE_CMD_ALL             0       /**< remove all matching instruments */
+#define SND_SEQ_INSTR_FREE_CMD_PRIVATE         1       /**< remove only private instruments */
+#define SND_SEQ_INSTR_FREE_CMD_CLUSTER         2       /**< remove only cluster instruments */
+#define SND_SEQ_INSTR_FREE_CMD_SINGLE          3       /**< remove single instrument */
+
+
+/**
+ * FM instrument support
+ */
+
+/** FM instrument data structure */
 typedef void snd_instr_fm_t;
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-int snd_instr_fm_convert_to_stream(snd_instr_fm_t *fm, const char *name, snd_seq_instr_put_t **put, size_t *size);
-int snd_instr_fm_convert_from_stream(snd_seq_instr_get_t *data, size_t size, snd_instr_fm_t **fm);
+int snd_instr_fm_convert_to_stream(snd_instr_fm_t *fm, const char *name, snd_instr_header_t **put, size_t *size);
+int snd_instr_fm_convert_from_stream(snd_instr_header_t *data, size_t size, snd_instr_fm_t **fm);
 int snd_instr_fm_free(snd_instr_fm_t *fm);
 
 #ifdef __cplusplus
 }
 #endif
 
-/* Simple Wave support */
 
+/**
+ * Simple Wave support
+ */
+
+/** simple instrument data structure */
 typedef void snd_instr_simple_t;
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-int snd_instr_simple_convert_to_stream(snd_instr_simple_t *simple, const char *name, snd_seq_instr_put_t **put, size_t *size);
-int snd_instr_simple_convert_from_stream(snd_seq_instr_get_t *data, size_t size, snd_instr_simple_t **simple);
+int snd_instr_simple_convert_to_stream(snd_instr_simple_t *simple, const char *name, snd_instr_header_t **put, size_t *size);
+int snd_instr_simple_convert_from_stream(snd_instr_header_t *data, size_t size, snd_instr_simple_t **simple);
 int snd_instr_simple_free(snd_instr_simple_t *simple);
 
 #ifdef __cplusplus
 }
 #endif
 
-/* InterWave FFFF support */
 
+/**
+ * InterWave FFFF support
+ */
+
+/** IW FFFF instrument data structure */
 typedef void snd_instr_iwffff_t;
+/** IW FFFF handler */
 typedef struct _snd_iwffff_handle snd_iwffff_handle_t;
 
 #ifdef __cplusplus
@@ -57,8 +160,8 @@ int snd_instr_iwffff_open_rom(snd_iwffff_handle_t **handle, int card, int bank,
 int snd_instr_iwffff_open_rom_file(snd_iwffff_handle_t **handle, const char *name, int bank, int file);
 int snd_instr_iwffff_close(snd_iwffff_handle_t *handle);
 int snd_instr_iwffff_load(snd_iwffff_handle_t *handle, int bank, int prg, snd_instr_iwffff_t **iwffff);
-int snd_instr_iwffff_convert_to_stream(snd_instr_iwffff_t *iwffff, const char *name, snd_seq_instr_put_t **data, size_t *size);
-int snd_instr_iwffff_convert_from_stream(snd_seq_instr_get_t *data, size_t size, snd_instr_iwffff_t **iwffff);
+int snd_instr_iwffff_convert_to_stream(snd_instr_iwffff_t *iwffff, const char *name, snd_instr_header_t **data, size_t *size);
+int snd_instr_iwffff_convert_from_stream(snd_instr_header_t *data, size_t size, snd_instr_iwffff_t **iwffff);
 int snd_instr_iwffff_free(snd_instr_iwffff_t *iwffff);
 
 #ifdef __cplusplus
index 55b6181a1e1ca22c81e0a452db6b9ea4d2ba60c0..7e1a526d02a0dbe567a6b7874302cfe163f9faaa 100644 (file)
 
 #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"
 
index 844b4c0636450cba7961061fee5c10f2cc458f6f..e5f8e0f902b7f2f56734eba2fafac6e71635548a 100644 (file)
-/****************************************************************************
- *                                                                          *
- *                                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);
@@ -396,15 +453,211 @@ int snd_seq_drop_output(snd_seq_t *handle);
 int snd_seq_drop_output_buffer(snd_seq_t *handle);
 int snd_seq_drop_input(snd_seq_t *handle);
 int snd_seq_drop_input_buffer(snd_seq_t *handle);
+
+/** event removal conditionals */
+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
diff --git a/include/seq_event.h b/include/seq_event.h
new file mode 100644 (file)
index 0000000..b8a6fc1
--- /dev/null
@@ -0,0 +1,432 @@
+/**
+ *  \defgroup Sequencer Sequencer Interface
+ *  Sequencer Interface
+ *  \{
+ */
+
+/** \} */
+
+/**
+ *  \defgroup SeqEvents Sequencer Event Definitions
+ *  Sequencer Event Definitions
+ *  \ingroup Sequencer
+ *  \{
+ */
+
+/**
+ * Sequencer event data type
+ */
+typedef unsigned char snd_seq_event_type_t;
+
+enum snd_seq_event_type {
+       /** system status; event data type = #snd_seq_result_t */
+       SND_SEQ_EVENT_SYSTEM = 0,
+       /** returned result status; event data type = #snd_seq_result_t */
+       SND_SEQ_EVENT_RESULT,
+
+       /** note on and off with duration; event data type = #snd_seq_ev_note_t */
+       SND_SEQ_EVENT_NOTE = 5,
+       /** note on; event data type = #snd_seq_ev_note_t */
+       SND_SEQ_EVENT_NOTEON,
+       /** note off; event data type = #snd_seq_ev_note_t */
+       SND_SEQ_EVENT_NOTEOFF,
+       /** key pressure change (aftertouch); event data type = #snd_seq_ev_note_t */
+       SND_SEQ_EVENT_KEYPRESS,
+       
+       /** controller; event data type = #snd_seq_ev_ctrl_t */
+       SND_SEQ_EVENT_CONTROLLER = 10,
+       /** program change; event data type = #snd_seq_ev_ctrl_t */
+       SND_SEQ_EVENT_PGMCHANGE,
+       /** channel pressure; event data type = #snd_seq_ev_ctrl_t */
+       SND_SEQ_EVENT_CHANPRESS,
+       /** pitchwheel; event data type = #snd_seq_ev_ctrl_t; data is from -8192 to 8191) */
+       SND_SEQ_EVENT_PITCHBEND,
+       /** 14 bit controller value; event data type = #snd_seq_ev_ctrl_t */
+       SND_SEQ_EVENT_CONTROL14,
+       /** 14 bit NRPN;  event data type = #snd_seq_ev_ctrl_t */
+       SND_SEQ_EVENT_NONREGPARAM,
+       /** 14 bit RPN; event data type = #snd_seq_ev_ctrl_t */
+       SND_SEQ_EVENT_REGPARAM,
+
+       /** SPP with LSB and MSB values; event data type = #snd_seq_ev_ctrl_t */
+       SND_SEQ_EVENT_SONGPOS = 20,
+       /** Song Select with song ID number; event data type = #snd_seq_ev_ctrl_t */
+       SND_SEQ_EVENT_SONGSEL,
+       /** midi time code quarter frame; event data type = #snd_seq_ev_ctrl_t */
+       SND_SEQ_EVENT_QFRAME,
+       /** SMF Time Signature event; event data type = #snd_seq_ev_ctrl_t */
+       SND_SEQ_EVENT_TIMESIGN,
+       /** SMF Key Signature event; event data type = #snd_seq_ev_ctrl_t */
+       SND_SEQ_EVENT_KEYSIGN,
+               
+       /** MIDI Real Time Start message; event data type = #snd_seq_ev_queue_control_t */
+       SND_SEQ_EVENT_START = 30,
+       /** MIDI Real Time Continue message; event data type = #snd_seq_ev_queue_control_t */
+       SND_SEQ_EVENT_CONTINUE,
+       /** MIDI Real Time Stop message; event data type = #snd_seq_ev_queue_control_t */
+       SND_SEQ_EVENT_STOP,
+       /** Set tick queue position; event data type = #snd_seq_ev_queue_control_t */
+       SND_SEQ_EVENT_SETPOS_TICK,
+       /** Set realtime queue position; event data type = #snd_seq_ev_queue_control_t */
+       SND_SEQ_EVENT_SETPOS_TIME,
+       /** (SMF) Tempo event; event data type = #snd_seq_ev_queue_control_t */
+       SND_SEQ_EVENT_TEMPO,
+       /** MIDI Real Time Clock message; event data type = #snd_seq_ev_queue_control_t */
+       SND_SEQ_EVENT_CLOCK,
+       /** MIDI Real Time Tick message; event data type = #snd_seq_ev_queue_control_t */
+       SND_SEQ_EVENT_TICK,
+       /** Sync signal; event data type = #snd_seq_ev_queue_control_t */
+       SND_SEQ_EVENT_SYNC,
+       /** Sync position changed; event data type = #snd_seq_ev_queue_control_t */
+       SND_SEQ_EVENT_SYNC_POS,
+
+       /** Tune request; event data type = none */
+       SND_SEQ_EVENT_TUNE_REQUEST = 40,
+       /** Reset to power-on state; event data type = none */
+       SND_SEQ_EVENT_RESET,
+       /** Active sensing event; event data type = none */
+       SND_SEQ_EVENT_SENSING,
+
+       /** Echo-back event; event data type = any type */
+       SND_SEQ_EVENT_ECHO = 50,
+       /** OSS emulation raw event; event data type = any type */
+       SND_SEQ_EVENT_OSS,
+
+       /** New client has connected; event data type = #snd_seq_addr_t */
+       SND_SEQ_EVENT_CLIENT_START,
+       /** Client has left the system; event data type = #snd_seq_addr_t */
+       SND_SEQ_EVENT_CLIENT_EXIT,
+       /** Client status/info has changed; event data type = #snd_seq_addr_t */
+       SND_SEQ_EVENT_CLIENT_CHANGE,
+       /** New port was created; event data type = #snd_seq_addr_t */
+       SND_SEQ_EVENT_PORT_START,
+       /** Port was deleted from system; event data type = #snd_seq_addr_t */
+       SND_SEQ_EVENT_PORT_EXIT,
+       /** Port status/info has changed; event data type = #snd_seq_addr_t */
+       SND_SEQ_EVENT_PORT_CHANGE,
+
+       /** Ports connected; event data type = #snd_seq_connect_t */
+       SND_SEQ_EVENT_PORT_SUBSCRIBED,
+       /** Ports disconnected; event data type = #snd_seq_connect_t */
+       SND_SEQ_EVENT_PORT_UNSUBSCRIBED,
+
+       /** Sample select; event data type = #snd_seq_ev_sample_control_t */
+       SND_SEQ_EVENT_SAMPLE = 70,
+       /** Sample cluster select; event data type = #snd_seq_ev_sample_control_t */
+       SND_SEQ_EVENT_SAMPLE_CLUSTER,
+       /** voice start */
+       SND_SEQ_EVENT_SAMPLE_START,
+       /** voice stop */
+       SND_SEQ_EVENT_SAMPLE_STOP,
+       /** playback frequency */
+       SND_SEQ_EVENT_SAMPLE_FREQ,
+       /** volume and balance */
+       SND_SEQ_EVENT_SAMPLE_VOLUME,
+       /** sample loop */
+       SND_SEQ_EVENT_SAMPLE_LOOP,
+       /** sample position */
+       SND_SEQ_EVENT_SAMPLE_POSITION,
+       /** private (hardware dependent) event */
+       SND_SEQ_EVENT_SAMPLE_PRIVATE1,
+
+       /** user-defined event; event data type = any (fixed size) */
+       SND_SEQ_EVENT_USR0 = 90,
+       /** user-defined event; event data type = any (fixed size) */
+       SND_SEQ_EVENT_USR1,
+       /** user-defined event; event data type = any (fixed size) */
+       SND_SEQ_EVENT_USR2,
+       /** user-defined event; event data type = any (fixed size) */
+       SND_SEQ_EVENT_USR3,
+       /** user-defined event; event data type = any (fixed size) */
+       SND_SEQ_EVENT_USR4,
+       /** user-defined event; event data type = any (fixed size) */
+       SND_SEQ_EVENT_USR5,
+       /** user-defined event; event data type = any (fixed size) */
+       SND_SEQ_EVENT_USR6,
+       /** user-defined event; event data type = any (fixed size) */
+       SND_SEQ_EVENT_USR7,
+       /** user-defined event; event data type = any (fixed size) */
+       SND_SEQ_EVENT_USR8,
+       /** user-defined event; event data type = any (fixed size) */
+       SND_SEQ_EVENT_USR9,
+
+       /** begin of instrument management */
+       SND_SEQ_EVENT_INSTR_BEGIN = 100,
+       /** end of instrument management */
+       SND_SEQ_EVENT_INSTR_END,
+       /** query instrument interface info */
+       SND_SEQ_EVENT_INSTR_INFO,
+       /** result of instrument interface info */
+       SND_SEQ_EVENT_INSTR_INFO_RESULT,
+       /** query instrument format info */
+       SND_SEQ_EVENT_INSTR_FINFO,
+       /** result of instrument format info */
+       SND_SEQ_EVENT_INSTR_FINFO_RESULT,
+       /** reset instrument instrument memory */
+       SND_SEQ_EVENT_INSTR_RESET,
+       /** get instrument interface status */
+       SND_SEQ_EVENT_INSTR_STATUS,
+       /** result of instrument interface status */
+       SND_SEQ_EVENT_INSTR_STATUS_RESULT,
+       /** put an instrument to port */
+       SND_SEQ_EVENT_INSTR_PUT,
+       /** get an instrument from port */
+       SND_SEQ_EVENT_INSTR_GET,
+       /** result of instrument query */
+       SND_SEQ_EVENT_INSTR_GET_RESULT,
+       /** free instrument(s) */
+       SND_SEQ_EVENT_INSTR_FREE,
+       /** get instrument list */
+       SND_SEQ_EVENT_INSTR_LIST,
+       /** result of instrument list */
+       SND_SEQ_EVENT_INSTR_LIST_RESULT,
+       /** set cluster parameters */
+       SND_SEQ_EVENT_INSTR_CLUSTER,
+       /** get cluster parameters */
+       SND_SEQ_EVENT_INSTR_CLUSTER_GET,
+       /** result of cluster parameters */
+       SND_SEQ_EVENT_INSTR_CLUSTER_RESULT,
+       /** instrument change */
+       SND_SEQ_EVENT_INSTR_CHANGE,
+
+       /** system exclusive data (variable length);  event data type = #snd_seq_ev_ext_t */
+       SND_SEQ_EVENT_SYSEX = 130,
+       /** error event;  event data type = #snd_seq_ev_ext_t */
+       SND_SEQ_EVENT_BOUNCE,
+       /** reserved for user apps;  event data type = #snd_seq_ev_ext_t */
+       SND_SEQ_EVENT_USR_VAR0 = 135,
+       /** reserved for user apps; event data type = #snd_seq_ev_ext_t */
+       SND_SEQ_EVENT_USR_VAR1,
+       /** reserved for user apps; event data type = #snd_seq_ev_ext_t */
+       SND_SEQ_EVENT_USR_VAR2,
+       /** reserved for user apps; event data type = #snd_seq_ev_ext_t */
+       SND_SEQ_EVENT_USR_VAR3,
+       /** reserved for user apps; event data type = #snd_seq_ev_ext_t */
+       SND_SEQ_EVENT_USR_VAR4,
+
+       /** NOP; ignored in any case */
+       SND_SEQ_EVENT_NONE = 255
+};
+
+
+#ifndef _SND_SEQ_IN_LOCAL
+
+/** Sequencer event address */
+typedef struct snd_seq_addr {
+       unsigned char client;   /**< Client id */
+       unsigned char port;     /**< Port id */
+} snd_seq_addr_t;
+
+/** Connection (subscription) between ports */
+typedef struct snd_seq_connect {
+       snd_seq_addr_t sender;  /**< sender address */
+       snd_seq_addr_t dest;    /**< destination address */
+} snd_seq_connect_t;
+
+
+/** Real-time data record */
+typedef struct snd_seq_real_time {
+       unsigned int tv_sec;            /**< seconds */
+       unsigned int tv_nsec;           /**< nanoseconds */
+} snd_seq_real_time_t;
+
+/** (MIDI) Tick-time data record */
+typedef unsigned int snd_seq_tick_time_t;
+
+/** unioned time stamp */
+typedef union snd_seq_timestamp {
+       snd_seq_tick_time_t tick;       /**< tick-time */
+       struct snd_seq_real_time time;  /**< real-time */
+} snd_seq_timestamp_t;
+
+
+/**
+ * Event mode flags
+ *
+ * NOTE: only 8 bits available!
+ */
+#define SND_SEQ_TIME_STAMP_TICK                (0<<0)  /**< timestamp in clock ticks */
+#define SND_SEQ_TIME_STAMP_REAL                (1<<0)  /**< timestamp in real time */
+#define SND_SEQ_TIME_STAMP_MASK                (1<<0)  /**< mask for timestamp bits */
+
+#define SND_SEQ_TIME_MODE_ABS          (0<<1)  /**< absolute timestamp */
+#define SND_SEQ_TIME_MODE_REL          (1<<1)  /**< relative to current time */
+#define SND_SEQ_TIME_MODE_MASK         (1<<1)  /**< mask for time mode bits */
+
+#define SND_SEQ_EVENT_LENGTH_FIXED     (0<<2)  /**< fixed event size */
+#define SND_SEQ_EVENT_LENGTH_VARIABLE  (1<<2)  /**< variable event size */
+#define SND_SEQ_EVENT_LENGTH_VARUSR    (2<<2)  /**< variable event size - user memory space */
+#define SND_SEQ_EVENT_LENGTH_VARIPC    (3<<2)  /**< variable event size - IPC */
+#define SND_SEQ_EVENT_LENGTH_MASK      (3<<2)  /**< mask for event length bits */
+
+#define SND_SEQ_PRIORITY_NORMAL                (0<<4)  /**< normal priority */
+#define SND_SEQ_PRIORITY_HIGH          (1<<4)  /**< event should be processed before others */
+#define SND_SEQ_PRIORITY_MASK          (1<<4)  /**< mask for priority bits */
+
+
+/** Note event */
+typedef struct snd_seq_ev_note {
+       unsigned char channel;          /**< channel number */
+       unsigned char note;             /**< note */
+       unsigned char velocity;         /**< velocity */
+       unsigned char off_velocity;     /**< note-off velocity; only for #SND_SEQ_EVENT_NOTE */
+       unsigned int duration;          /**< duration until note-off; only for #SND_SEQ_EVENT_NOTE */
+} snd_seq_ev_note_t;
+
+/** Controller event */
+typedef struct snd_seq_ev_ctrl {
+       unsigned char channel;          /**< channel number */
+       unsigned char unused[3];        /**< reserved */
+       unsigned int param;             /**< control parameter */
+       signed int value;               /**< control value */
+} snd_seq_ev_ctrl_t;
+
+/** generic set of bytes (12x8 bit) */
+typedef struct snd_seq_ev_raw8 {
+       unsigned char d[12];            /**< 8 bit value */
+} snd_seq_ev_raw8_t;
+
+/** generic set of integers (3x32 bit) */
+typedef struct snd_seq_ev_raw32 {
+       unsigned int d[3];              /**< 32 bit value */
+} snd_seq_ev_raw32_t;
+
+/** external stored data */
+typedef struct snd_seq_ev_ext {
+       size_t len;                     /**< length of data */
+       void *ptr;                      /**< pointer to data (note: can be 64-bit) */
+} snd_seq_ev_ext_t;
+
+/** external stored data - IPC shared memory */
+typedef struct snd_seq_ev_ipcshm {
+       size_t len;                     /**< length of data */
+       key_t ipc;                      /**< IPC key */
+} snd_seq_ev_ipcshm_t;
+
+/** Instrument cluster type */
+typedef unsigned int snd_seq_instr_cluster_t;
+
+/** Instrument type */
+typedef struct snd_seq_instr {
+       snd_seq_instr_cluster_t cluster;        /**< cluster id */
+       unsigned int std;       /**< instrument standard id; the upper byte means a private instrument (owner - client id) */
+       unsigned short bank;    /**< instrument bank id */
+       unsigned short prg;     /**< instrument program id */
+} snd_seq_instr_t;
+
+/** sample number */
+typedef struct snd_seq_ev_sample {
+       unsigned int std;       /**< sample standard id */
+       unsigned short bank;    /**< sample bank id */
+       unsigned short prg;     /**< sample program id */
+} snd_seq_ev_sample_t;
+
+/** sample cluster */
+typedef struct snd_seq_ev_cluster {
+       snd_seq_instr_cluster_t cluster;        /**< cluster id */
+} snd_seq_ev_cluster_t;
+
+/** sample position */
+typedef unsigned int snd_seq_position_t; /**< playback position (in samples) * 16 */
+
+/** sample stop mode */
+typedef enum snd_seq_stop_mode {
+       SND_SEQ_SAMPLE_STOP_IMMEDIATELY = 0,    /**< terminate playing immediately */
+       SND_SEQ_SAMPLE_STOP_VENVELOPE = 1,      /**< finish volume envelope */
+       SDN_SEQ_SAMPLE_STOP_LOOP = 2            /**< terminate loop and finish wave */
+} snd_seq_stop_mode_t;
+
+/** sample frequency */
+typedef int snd_seq_frequency_t; /**< playback frequency in HZ * 16 */
+
+/** sample volume control; if any value is set to -1 == do not change */
+typedef struct snd_seq_ev_volume {
+       signed short volume;    /**< range: 0-16383 */
+       signed short lr;        /**< left-right balance; range: 0-16383 */
+       signed short fr;        /**< front-rear balance; range: 0-16383 */
+       signed short du;        /**< down-up balance; range: 0-16383 */
+} snd_seq_ev_volume_t;
+
+/** simple loop redefinition */
+typedef struct snd_seq_ev_loop {
+       unsigned int start;     /**< loop start (in samples) * 16 */
+       unsigned int end;       /**< loop end (in samples) * 16 */
+} snd_seq_ev_loop_t;
+
+/** Sample control events */
+typedef struct snd_seq_ev_sample_control {
+       unsigned char channel;          /**< channel */
+       unsigned char unused[3];        /**< reserved */
+       union {
+               snd_seq_ev_sample_t sample;
+               snd_seq_ev_cluster_t cluster;
+               snd_seq_position_t position;
+               snd_seq_stop_mode_t stop_mode;
+               snd_seq_frequency_t frequency;
+               snd_seq_ev_volume_t volume;
+               snd_seq_ev_loop_t loop;
+               unsigned char raw8[8];
+       } param;                /**< control parameters */
+} snd_seq_ev_sample_control_t;
+
+
+
+/** INSTR_BEGIN event */
+typedef struct snd_seq_ev_instr_begin {
+       int timeout;            /**< zero = forever, otherwise timeout in ms */
+} snd_seq_ev_instr_begin_t;
+
+/** Result events */
+typedef struct snd_seq_result {
+       int event;              /**< processed event type */
+       int result;             /**< status */
+} snd_seq_result_t;
+
+
+/** queue timer control */
+typedef struct snd_seq_ev_queue_control {
+       unsigned char queue;                    /**< affected queue */
+       unsigned char unused[3];                /**< reserved */
+       union {
+               signed int value;               /**< affected value (e.g. tempo) */
+               snd_seq_timestamp_t time;       /**< time */
+               unsigned int position;          /**< sync position */
+               unsigned int d32[2];            /**< any data */
+               unsigned char d8[8];            /**< any data */
+       } param;                                /**< data value union */
+} snd_seq_ev_queue_control_t;
+
+
+/** Sequencer event */
+typedef struct snd_seq_event {
+       snd_seq_event_type_t type;      /**< event type */
+       unsigned char flags;            /**< event flags */
+       unsigned char tag;              /**< tag */
+       
+       unsigned char queue;            /**< schedule queue */
+       snd_seq_timestamp_t time;       /**< schedule time */
+
+       snd_seq_addr_t source;          /**< source address */
+       snd_seq_addr_t dest;            /**< destination address */
+
+       union {
+               snd_seq_ev_note_t note;
+               snd_seq_ev_ctrl_t control;
+               snd_seq_ev_raw8_t raw8;
+               snd_seq_ev_raw32_t raw32;
+               snd_seq_ev_ext_t ext;
+               snd_seq_ev_ipcshm_t ipcshm;
+               snd_seq_ev_queue_control_t queue;
+               snd_seq_timestamp_t time;
+               snd_seq_addr_t addr;
+               snd_seq_connect_t connect;
+               snd_seq_result_t result;
+               snd_seq_ev_instr_begin_t instr_begin;
+               snd_seq_ev_sample_control_t sample;
+       } data;                         /**< event data... */
+} snd_seq_event_t;
+
+#endif /* _SND_SEQ_IN_LOCAL */
+
+
+/** \} */
index 63dc11c50085cb18e1a9135a5b47e5edc508fbed..8951807c6fe78b6b63f479978964446ff8700f81 100644 (file)
@@ -4,6 +4,10 @@
  *                                                                          *
  ****************************************************************************/
 
+#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
 
-/** \} */
-
index bdc409b8965ca56be10864490beb6cf72503eb9a..6d31a702134de6af56e3b1b9da6552495a9101b5 100644 (file)
@@ -27,7 +27,7 @@
 #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;
@@ -37,11 +37,10 @@ int snd_instr_fm_free(snd_instr_simple_t *fm)
 
 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;
@@ -51,18 +50,15 @@ int snd_instr_fm_convert_to_stream(snd_instr_fm_t *fm,
        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]);
@@ -93,7 +89,7 @@ int snd_instr_fm_convert_to_stream(snd_instr_fm_t *fm,
        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)
 {
index 770b2b291dec4d06f9ba1c9fbb8671f65d861499..df1fd17250752e7a9e6ea93386b583e811827068 100644 (file)
@@ -740,11 +740,10 @@ static int copy_env_to_stream(iwffff_xenv_t *xenv, iwffff_env_t *env, __u32 styp
 
 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;
@@ -759,19 +758,16 @@ int snd_instr_iwffff_conv_to_stream(snd_instr_iwffff_t *iwffff,
        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);
@@ -827,11 +823,11 @@ int snd_instr_iwffff_conv_to_stream(snd_instr_iwffff_t *iwffff,
        }
        /* 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)
 {
index 776ead19de854fbadfa6cc489dde2b8443887068..3200210a78d7297be1b0ed490f9043e949a66fbd 100644 (file)
@@ -50,11 +50,10 @@ static long simple_size(simple_instrument_t *instr)
 
 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;
@@ -66,18 +65,15 @@ int snd_instr_simple_convert_to_stream(snd_instr_simple_t *simple,
        *__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]);
@@ -101,7 +97,7 @@ int snd_instr_simple_convert_to_stream(snd_instr_simple_t *simple,
        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)
 {
index 0b65749fa9604b3764415e2e300d40e65bba991c..003b0a6fd5e0880f73b64d7967792194d88db5e8 100644 (file)
@@ -1,6 +1,6 @@
 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
index 3933dc9c1a03a0b7d876cfd44a7c8c03fcccbbc0..a2676ad682a7072641efad663fe20b2f8aa089c1 100644 (file)
@@ -4,10 +4,6 @@
  * \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
@@ -167,27 +170,24 @@ static int snd_seq_open_noupdate(snd_seq_t **seqp, snd_config_t *root,
  * 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)
@@ -202,12 +202,12 @@ int snd_seq_open(snd_seq_t **seqp, const char *name,
 
 /**
  * \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.
  */
@@ -256,7 +256,7 @@ int snd_seq_poll_descriptors_count(snd_seq_t *seq, short events)
 }
 
 /**
- * \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
@@ -286,7 +286,7 @@ int snd_seq_poll_descriptors(snd_seq_t *seq, struct pollfd *pfds, unsigned int s
 }
 
 /**
- * \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
@@ -294,7 +294,7 @@ int snd_seq_poll_descriptors(snd_seq_t *seq, struct pollfd *pfds, unsigned int s
  * 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)
 {
@@ -311,7 +311,7 @@ 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
  *
@@ -327,7 +327,7 @@ int snd_seq_client_id(snd_seq_t *seq)
 }
 
 /**
- * \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
  *
@@ -335,7 +335,7 @@ int snd_seq_client_id(snd_seq_t *seq)
  * 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)
@@ -344,14 +344,14 @@ int snd_seq_output_buffer_size(snd_seq_t *seq)
 }
 
 /**
- * \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)
@@ -360,14 +360,14 @@ int snd_seq_input_buffer_size(snd_seq_t *seq)
 }
 
 /**
- * \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));
@@ -385,14 +385,14 @@ int snd_seq_resize_output_buffer(snd_seq_t *seq, size_t size)
 }
 
 /**
- * \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));
@@ -410,637 +410,1989 @@ int snd_seq_resize_input_buffer(snd_seq_t *seq, size_t size)
        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);
+}
 
 /*----------------------------------------------------------------*/
 
@@ -1072,7 +2424,7 @@ ssize_t snd_seq_event_length(snd_seq_event_t *ev)
 {
        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;
 }
@@ -1129,7 +2481,7 @@ int snd_seq_event_output_buffer(snd_seq_t *seq, snd_seq_event_t *ev)
                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;
        }
@@ -1275,7 +2627,7 @@ static int snd_seq_event_retrieve_buffer(snd_seq_t *seq, snd_seq_event_t **retp)
        *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) {
@@ -1404,53 +2756,251 @@ int snd_seq_drop_input_buffer(snd_seq_t *seq)
 }
 
 /**
- * \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)
@@ -1461,54 +3011,53 @@ static inline int snd_seq_compare_real_time(snd_seq_real_time_t *a,
 }
 
 /* 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;
        }
@@ -1519,28 +3068,27 @@ static int remove_match(snd_seq_remove_events_t *info,
 /**
  * \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 {
@@ -1575,78 +3123,174 @@ int snd_seq_remove_events(snd_seq_t *seq, snd_seq_remove_events_t *rmp)
  */
 
 /**
- * \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);
 }
 
 /*----------------------------------------------------------------*/
@@ -1683,3 +3327,264 @@ int snd_seq_get_bit(int nr, void *array)
        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;
+}
diff --git a/src/seq/seq_event.c b/src/seq/seq_event.c
new file mode 100644 (file)
index 0000000..d50f442
--- /dev/null
@@ -0,0 +1,55 @@
+/**
+ * \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),
+};
+
index 1fab56ab0a4be8a6ac2851a902b025884d4196ba..b5af002ca943499fe42191f644a4bab2e5a48b0d 100644 (file)
@@ -174,7 +174,7 @@ static int snd_seq_hw_unsubscribe_port(snd_seq_t *seq, snd_seq_port_subscribe_t
        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) {
@@ -214,26 +214,6 @@ static int snd_seq_hw_set_queue_tempo(snd_seq_t *seq, snd_seq_queue_tempo_t * te
        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;
@@ -409,8 +389,6 @@ snd_seq_ops_t snd_seq_hw_ops = {
        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,
index 165ec8568b3fca0adfd79031e329a1f1224d1a9a..5eed15e0707bde40f7dc973bf8c51fdc0c8173a1 100644 (file)
@@ -32,6 +32,9 @@
 #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);
@@ -45,12 +48,10 @@ typedef struct {
        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);
index dbdcd910ad964a898152c7192382db0f3f8edd08..5740fe115d2c6fd6e0826f5fedf7b6b53cc95e55 100644 (file)
@@ -72,31 +72,31 @@ static struct status_event_list_t {
        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);
@@ -105,9 +105,9 @@ static struct extra_event_list_t {
        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]))
@@ -201,7 +201,7 @@ long snd_midi_event_encode(snd_midi_event_t *dev, unsigned char *buf, long count
        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);
@@ -230,8 +230,8 @@ int snd_midi_event_encode_byte(snd_midi_event_t *dev, int c, snd_seq_event_t *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;
        }
 
@@ -258,16 +258,16 @@ int snd_midi_event_encode_byte(snd_midi_event_t *dev, int c, snd_seq_event_t *ev
        }
        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)
@@ -333,7 +333,7 @@ long snd_midi_event_decode(snd_midi_event_t *dev, unsigned char *buf, long count
        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++) {
@@ -358,9 +358,9 @@ long snd_midi_event_decode(snd_midi_event_t *dev, unsigned char *buf, long count
                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);
index d9a8c463fe4bf811dd88ec20bf12bf5ec8b5ddc2..a1a6d0d871856e4a3ac4178c7004df91a1cc7f27 100644 (file)
 #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
@@ -141,8 +37,11 @@ int snd_seq_use_queue(snd_seq_t *seq, int q, int use)
  * \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)
 {
@@ -156,38 +55,16 @@ int snd_seq_control_queue(snd_seq_t *seq, int q, int type, int value, snd_seq_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)
@@ -199,35 +76,38 @@ int snd_seq_create_simple_port(snd_seq_t *seq, const char *name,
        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)
 {
@@ -245,6 +125,13 @@ int snd_seq_connect_from(snd_seq_t *seq, int myport, int src_client, int src_por
 
 /**
  * \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)
 {
@@ -261,7 +148,14 @@ int snd_seq_connect_to(snd_seq_t *seq, int myport, int dest_client, int dest_por
 }
 
 /**
- * \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)
 {
@@ -278,7 +172,14 @@ int snd_seq_disconnect_from(snd_seq_t *seq, int myport, int src_client, int src_
 }
 
 /**
- * \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)
 {
@@ -297,8 +198,12 @@ int snd_seq_disconnect_to(snd_seq_t *seq, int myport, int dest_client, int dest_
 /*
  * 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)
 {
@@ -312,35 +217,10 @@ 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)
 {
@@ -349,15 +229,18 @@ 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;
@@ -370,8 +253,11 @@ int snd_seq_set_client_pool_output(snd_seq_t *seq, int size)
 
 /**
  * \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;
@@ -384,8 +270,11 @@ int snd_seq_set_client_pool_output_room(snd_seq_t *seq, int size)
 
 /**
  * \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;
@@ -398,27 +287,74 @@ int snd_seq_set_client_pool_input(snd_seq_t *seq, int size)
 
 /**
  * \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;
+}
+
index a7b20467b7c2ae3fb7c25da25d040032932ad4fd..7fc7baa772bba7a80e23ffd8f02eefbd3660fc45 100644 (file)
@@ -114,13 +114,11 @@ static void write_ev(snd_seq_event_t *ev)
                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);
                }
        }
@@ -147,7 +145,7 @@ static void mytext(int type, int leng, char *msg)
 
 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);
@@ -159,15 +157,16 @@ static void do_header(int format, int ntracks, int 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);
@@ -176,7 +175,7 @@ static void do_header(int format, int ntracks, int division)
                } 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... */
@@ -364,13 +363,11 @@ static snd_seq_event_t *wait_for_event(void)
                /* 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);
                        }
                }
@@ -525,13 +522,13 @@ int main(int argc, char *argv[])
        /* 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);
@@ -557,7 +554,7 @@ int main(int argc, char *argv[])
        
        /* 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);
                }
@@ -580,7 +577,7 @@ int main(int argc, char *argv[])
        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);
index 87e610fe97d7a2cfd7c5347d99452dbba4f09c22..09cc1100253acfc0f2ffd13fc2294947823881dd 100644 (file)
  */
 
 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)
@@ -267,15 +104,15 @@ 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,
@@ -285,114 +122,120 @@ int decode_event(snd_seq_event_t * ev)
               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;
@@ -411,11 +254,12 @@ void event_decoder_start_timer(snd_seq_t *handle, int queue, int client, int por
 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));
@@ -427,33 +271,37 @@ void event_decoder(snd_seq_t *handle, int argc, char *argv[])
                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;
        }
@@ -462,27 +310,29 @@ void event_decoder(snd_seq_t *handle, int argc, char *argv[])
                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)
index 546f0a91d5e41100f2a0396a7368bc8545a315c7..b18d36c34a240b06379fb8a4868428f46a0d4095 100644 (file)
@@ -1,57 +1,65 @@
 
-#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(&params);
+       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
@@ -89,23 +97,15 @@ void event_sender_start_timer(snd_seq_t *handle, int client, int queue, snd_pcm_
 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;
@@ -119,8 +119,7 @@ void send_event(snd_seq_t *handle, int queue, int client, int port,
        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;
@@ -141,10 +140,11 @@ void send_event(snd_seq_t *handle, int queue, int client, int port,
 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;
 
@@ -164,20 +164,22 @@ void event_sender(snd_seq_t *handle, int argc, char *argv[])
        }
        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];
@@ -191,26 +193,25 @@ void event_sender(snd_seq_t *handle, int argc, char *argv[])
                        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);
@@ -220,43 +221,46 @@ void event_sender(snd_seq_t *handle, int argc, char *argv[])
        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);
index 9c2faa3c548bc92552976ae88bda7980288e8a2d..f18a6fa43a219e9300aed9cb9321584f03a11fb1 100644 (file)
 #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);
        }
@@ -38,78 +37,88 @@ void set_name(snd_seq_t *handle)
 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));
@@ -117,9 +126,9 @@ void show_client_info(snd_seq_t *handle, int client)
                }
                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));
        }
 }
 
@@ -190,7 +199,7 @@ int main(int argc, char *argv[])
                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);
        }