* gpatinfo.c: This program demonstrates the patch management
* interface of the GUS driver.
* NOTE! The patch manager interface is highly device dependent,
* currently incompletely implemented prototype and
* will change before final implementation.
#include <sys/ultrasound.h>
#define patch_access(cmd, rec) \
if (ioctl(seqfd, SNDCTL_PMGR_IFACE, &rec)==-1)\
perror("/dev/sequencer(SNDCTL_PMGR_IFACE/" #cmd ")");\
* The function seqbuf_dump() must always be provided
if (write (seqfd
, _seqbuf
, _seqbufptr
) == -1)
perror ("write /dev/sequencer");
main (int argc
, char *argv
[])
struct patch_info
*patch
;
struct patmgr_info mgr
, mgr2
, mgr3
;
if ((seqfd
= open ("/dev/sequencer", O_WRONLY
, 0)) == -1)
perror ("/dev/sequencer");
if (ioctl (seqfd
, SNDCTL_SEQ_NRSYNTHS
, &n
) == -1)
perror ("/dev/sequencer");
* First locate the GUS device
if (ioctl (seqfd
, SNDCTL_SYNTH_INFO
, &info
) == -1)
perror ("/dev/sequencer");
if (info
.synth_type
== SYNTH_TYPE_SAMPLE
&& info
.synth_subtype
== SAMPLE_TYPE_GUS
)
fprintf (stderr
, "Error: Gravis Ultrasound not detected\n");
printf("Gravis UltraSound device = %d\n", gus_dev
);
* Get type of the Patch Manager interface of the GUS device
patch_access(PM_GET_DEVTYPE
, mgr
);
printf("Patch manager type: %d\n", mgr
.parm1
);
if (mgr
.parm1
!= PMTYPE_WAVE
)
fprintf(stderr
, "Hups, this program seems to be obsolete\n");
* The GUS driver supports up to 256 different midi program numbers but
* this limit can be changed before compiling the driver. The following
* call returns the value compiled to the driver.
patch_access(PM_GET_PGMMAP
, mgr
);
printf("Device supports %d midi programs.\n", mgr
.parm1
);
* Each program can be undefined or it may have one or more patches.
* A patch consists of header and the waveform data. If there is more
* than one patch in a program, the right one is selected by checking the
* note number when the program is played.
* The following call reads an array indexed by program number. Each
* element defines the number of patches defined for the corresponding
printf("Loaded programs:\n");
for (i
=0;i
<mgr
.parm1
;i
++)
printf("%03d: %2d patches\n", i
, mgr
.data
.data8
[i
]);
* Next get the magic keys of the patches associated with this program.
* This key can be used to access the patc data.
patch_access(PM_GET_PGM_PATCHES
, mgr2
);
for (j
= 0;j
<mgr2
.parm1
;j
++)
printf("\tPatch %d: %3d ", j
, mgr2
.data
.data32
[j
]);
* The last step is to read the patch header (without wave data).
* The header is returned in the mgr3.data. The field parm1 returns
* address of the wave data in tge GUS DRAM. Parm2 returns
* size of the struct patch_info in the kernel.
* There is also the PM_SET_PATCH call which allows modification of the
* header data. The only limitation is that the sample len cannot be
mgr3
.parm1
= mgr2
.data
.data32
[j
];
patch_access(PM_GET_PATCH
, mgr3
);
patch
= (struct patch_info
*)&mgr3
.data
; /* Pointer to the patch hdr */
printf("DRAM ptr = %7d, sample len =%6d bytes.\n",
if (ioctl(seqfd
, SNDCTL_SYNTH_MEMAVL
, &i
)==-1) exit(-1);
printf("%d bytes of DRAM available for wave data\n", i
);