📄 soundcard.h
字号:
* the event: * * 0x8X = system level events, * 0x9X = device/port specific events, event[1] = device/port, * The last 4 bits give the subtype: * 0x02 = Channel event (event[3] = chn). * 0x01 = note event (event[4] = note). * (0x01 is not used alone but always with bit 0x02). * event[2] = MIDI message code (0x80=note off etc.) * */#define EV_SEQ_LOCAL 0x80#define EV_TIMING 0x81#define EV_CHN_COMMON 0x92#define EV_CHN_VOICE 0x93#define EV_SYSEX 0x94/* * Event types 200 to 220 are reserved for application use. * These numbers will not be used by the driver. *//* * Events for event type EV_CHN_VOICE */#define MIDI_NOTEOFF 0x80#define MIDI_NOTEON 0x90#define MIDI_KEY_PRESSURE 0xA0/* * Events for event type EV_CHN_COMMON */#define MIDI_CTL_CHANGE 0xB0#define MIDI_PGM_CHANGE 0xC0#define MIDI_CHN_PRESSURE 0xD0#define MIDI_PITCH_BEND 0xE0#define MIDI_SYSTEM_PREFIX 0xF0/* * Timer event types */#define TMR_WAIT_REL 1 /* Time relative to the prev time */#define TMR_WAIT_ABS 2 /* Absolute time since TMR_START */#define TMR_STOP 3#define TMR_START 4#define TMR_CONTINUE 5#define TMR_TEMPO 6#define TMR_ECHO 8#define TMR_CLOCK 9 /* MIDI clock */#define TMR_SPP 10 /* Song position pointer */#define TMR_TIMESIG 11 /* Time signature *//* * Local event types */#define LOCL_STARTAUDIO 1#define LOCL_STARTAUDIO2 2#define LOCL_STARTAUDIO3 3#define LOCL_STARTAUDIO4 4#if (!defined(__KERNEL__) && !defined(KERNEL) && !defined(INKERNEL) && !defined(_KERNEL)) || defined(USE_SEQ_MACROS) /* * Some convenience macros to simplify programming of the * /dev/sequencer interface * * These macros define the API which should be used when possible. */#define SEQ_DECLAREBUF() SEQ_USE_EXTBUF()void seqbuf_dump(void); /* This function must be provided by programs */EXTERNC int OSS_init(int seqfd, int buflen);EXTERNC void OSS_seqbuf_dump(int fd, unsigned char *buf, int buflen);EXTERNC void OSS_seq_advbuf(int len, int fd, unsigned char *buf, int buflen);EXTERNC void OSS_seq_needbuf(int len, int fd, unsigned char *buf, int buflen);EXTERNC void OSS_patch_caching(int dev, int chn, int patch, int fd, unsigned char *buf, int buflen);EXTERNC void OSS_drum_caching(int dev, int chn, int patch, int fd, unsigned char *buf, int buflen);EXTERNC void OSS_write_patch(int fd, unsigned char *buf, int len);EXTERNC int OSS_write_patch2(int fd, unsigned char *buf, int len);#define SEQ_PM_DEFINES int __foo_bar___#ifdef OSSLIB# define SEQ_USE_EXTBUF() \ EXTERNC unsigned char *_seqbuf; \ EXTERNC int _seqbuflen;EXTERNC int _seqbufptr# define SEQ_DEFINEBUF(len) SEQ_USE_EXTBUF();static int _requested_seqbuflen=len# define _SEQ_ADVBUF(len) OSS_seq_advbuf(len, seqfd, _seqbuf, _seqbuflen)# define _SEQ_NEEDBUF(len) OSS_seq_needbuf(len, seqfd, _seqbuf, _seqbuflen)# define SEQ_DUMPBUF() OSS_seqbuf_dump(seqfd, _seqbuf, _seqbuflen)# define SEQ_LOAD_GMINSTR(dev, instr) \ OSS_patch_caching(dev, -1, instr, seqfd, _seqbuf, _seqbuflen)# define SEQ_LOAD_GMDRUM(dev, drum) \ OSS_drum_caching(dev, -1, drum, seqfd, _seqbuf, _seqbuflen)#else /* !OSSLIB */# define SEQ_LOAD_GMINSTR(dev, instr)# define SEQ_LOAD_GMDRUM(dev, drum)# define SEQ_USE_EXTBUF() \ EXTERNC unsigned char _seqbuf[]; \ EXTERNC int _seqbuflen;EXTERNC int _seqbufptr#ifndef USE_SIMPLE_MACROS/* Sample seqbuf_dump() implementation: * * SEQ_DEFINEBUF (2048); -- Defines a buffer for 2048 bytes * * int seqfd; -- The file descriptor for /dev/sequencer. * * void * seqbuf_dump () * { * if (_seqbufptr) * if (write (seqfd, _seqbuf, _seqbufptr) == -1) * { * perror ("write /dev/sequencer"); * exit (-1); * } * _seqbufptr = 0; * } */#define SEQ_DEFINEBUF(len) unsigned char _seqbuf[len]; int _seqbuflen = len;int _seqbufptr = 0#define _SEQ_NEEDBUF(len) if ((_seqbufptr+(len)) > _seqbuflen) seqbuf_dump()#define _SEQ_ADVBUF(len) _seqbufptr += len#define SEQ_DUMPBUF seqbuf_dump#else/* * This variation of the sequencer macros is used just to format one event * using fixed buffer. * * The program using the macro library must define the following macros before * using this library. * * #define _seqbuf name of the buffer (unsigned char[]) * #define _SEQ_ADVBUF(len) If the applic needs to know the exact * size of the event, this macro can be used. * Otherwise this must be defined as empty. * #define _seqbufptr Define the name of index variable or 0 if * not required. */#define _SEQ_NEEDBUF(len) /* empty */#endif#endif /* !OSSLIB */#define SEQ_VOLUME_MODE(dev, mode) {_SEQ_NEEDBUF(8);\ _seqbuf[_seqbufptr] = SEQ_EXTENDED;\ _seqbuf[_seqbufptr+1] = SEQ_VOLMODE;\ _seqbuf[_seqbufptr+2] = (dev);\ _seqbuf[_seqbufptr+3] = (mode);\ _seqbuf[_seqbufptr+4] = 0;\ _seqbuf[_seqbufptr+5] = 0;\ _seqbuf[_seqbufptr+6] = 0;\ _seqbuf[_seqbufptr+7] = 0;\ _SEQ_ADVBUF(8);}/* * Midi voice messages */#define _CHN_VOICE(dev, event, chn, note, parm) \ {_SEQ_NEEDBUF(8);\ _seqbuf[_seqbufptr] = EV_CHN_VOICE;\ _seqbuf[_seqbufptr+1] = (dev);\ _seqbuf[_seqbufptr+2] = (event);\ _seqbuf[_seqbufptr+3] = (chn);\ _seqbuf[_seqbufptr+4] = (note);\ _seqbuf[_seqbufptr+5] = (parm);\ _seqbuf[_seqbufptr+6] = (0);\ _seqbuf[_seqbufptr+7] = 0;\ _SEQ_ADVBUF(8);}#define SEQ_START_NOTE(dev, chn, note, vol) \ _CHN_VOICE(dev, MIDI_NOTEON, chn, note, vol)#define SEQ_STOP_NOTE(dev, chn, note, vol) \ _CHN_VOICE(dev, MIDI_NOTEOFF, chn, note, vol)#define SEQ_KEY_PRESSURE(dev, chn, note, pressure) \ _CHN_VOICE(dev, MIDI_KEY_PRESSURE, chn, note, pressure)/* * Midi channel messages */#define _CHN_COMMON(dev, event, chn, p1, p2, w14) \ {_SEQ_NEEDBUF(8);\ _seqbuf[_seqbufptr] = EV_CHN_COMMON;\ _seqbuf[_seqbufptr+1] = (dev);\ _seqbuf[_seqbufptr+2] = (event);\ _seqbuf[_seqbufptr+3] = (chn);\ _seqbuf[_seqbufptr+4] = (p1);\ _seqbuf[_seqbufptr+5] = (p2);\ *(short *)&_seqbuf[_seqbufptr+6] = (w14);\ _SEQ_ADVBUF(8);}/* * SEQ_SYSEX permits sending of sysex messages. (It may look that it permits * sending any MIDI bytes but it's absolutely not possible. Trying to do * so _will_ cause problems with MPU401 intelligent mode). * * Sysex messages are sent in blocks of 1 to 6 bytes. Longer messages must be * sent by calling SEQ_SYSEX() several times (there must be no other events * between them). First sysex fragment must have 0xf0 in the first byte * and the last byte (buf[len-1] of the last fragment must be 0xf7. No byte * between these sysex start and end markers cannot be larger than 0x7f. Also * lengths of each fragments (except the last one) must be 6. * * Breaking the above rules may work with some MIDI ports but is likely to * cause fatal problems with some other devices (such as MPU401). */#define SEQ_SYSEX(dev, buf, len) \ {int ii, ll=(len); \ unsigned char *bufp=buf;\ if (ll>6)ll=6;\ _SEQ_NEEDBUF(8);\ _seqbuf[_seqbufptr] = EV_SYSEX;\ _seqbuf[_seqbufptr+1] = (dev);\ for(ii=0;ii<ll;ii++)\ _seqbuf[_seqbufptr+ii+2] = bufp[ii];\ for(ii=ll;ii<6;ii++)\ _seqbuf[_seqbufptr+ii+2] = 0xff;\ _SEQ_ADVBUF(8);}#define SEQ_CHN_PRESSURE(dev, chn, pressure) \ _CHN_COMMON(dev, MIDI_CHN_PRESSURE, chn, pressure, 0, 0)#define SEQ_SET_PATCH SEQ_PGM_CHANGE#ifdef OSSLIB# define SEQ_PGM_CHANGE(dev, chn, patch) \ {OSS_patch_caching(dev, chn, patch, seqfd, _seqbuf, _seqbuflen); \ _CHN_COMMON(dev, MIDI_PGM_CHANGE, chn, patch, 0, 0);}#else# define SEQ_PGM_CHANGE(dev, chn, patch) \ _CHN_COMMON(dev, MIDI_PGM_CHANGE, chn, patch, 0, 0)#endif#define SEQ_CONTROL(dev, chn, controller, value) \ _CHN_COMMON(dev, MIDI_CTL_CHANGE, chn, controller, 0, value)#define SEQ_BENDER(dev, chn, value) \ _CHN_COMMON(dev, MIDI_PITCH_BEND, chn, 0, 0, value)#define SEQ_V2_X_CONTROL(dev, voice, controller, value) {_SEQ_NEEDBUF(8);\ _seqbuf[_seqbufptr] = SEQ_EXTENDED;\ _seqbuf[_seqbufptr+1] = SEQ_CONTROLLER;\ _seqbuf[_seqbufptr+2] = (dev);\ _seqbuf[_seqbufptr+3] = (voice);\ _seqbuf[_seqbufptr+4] = (controller);\ _seqbuf[_seqbufptr+5] = ((value)&0xff);\ _seqbuf[_seqbufptr+6] = ((value>>8)&0xff);\ _seqbuf[_seqbufptr+7] = 0;\ _SEQ_ADVBUF(8);}/* * The following 5 macros are incorrectly implemented and obsolete. * Use SEQ_BENDER and SEQ_CONTROL (with proper controller) instead. */#define SEQ_PITCHBEND(dev, voice, value) SEQ_V2_X_CONTROL(dev, voice, CTRL_PITCH_BENDER, value)#define SEQ_BENDER_RANGE(dev, voice, value) SEQ_V2_X_CONTROL(dev, voice, CTRL_PITCH_BENDER_RANGE, value)#define SEQ_EXPRESSION(dev, voice, value) SEQ_CONTROL(dev, voice, CTL_EXPRESSION, value*128)#define SEQ_MAIN_VOLUME(dev, voice, value) SEQ_CONTROL(dev, voice, CTL_MAIN_VOLUME, (value*16383)/100)#define SEQ_PANNING(dev, voice, pos) SEQ_CONTROL(dev, voice, CTL_PAN, (pos+128) / 2)#if 0#define SEQ_PANNING(dev, voice, pos) {_SEQ_NEEDBUF(8);\ _seqbuf[_seqbufptr] = SEQ_EXTENDED;\ _seqbuf[_seqbufptr+1] = SEQ_BALANCE;\ _seqbuf[_seqbufptr+2] = (dev);\ _seqbuf[_seqbufptr+3] = (voice);\ (char)_seqbuf[_seqbufptr+4] = (pos);\ _seqbuf[_seqbufptr+5] = 0;\ _seqbuf[_seqbufptr+6] = 0;\ _seqbuf[_seqbufptr+7] = 1;\ _SEQ_ADVBUF(8);}#endif/* * Timing and syncronization macros */#define _TIMER_EVENT(ev, parm) {_SEQ_NEEDBUF(8);\ _seqbuf[_seqbufptr+0] = EV_TIMING; \ _seqbuf[_seqbufptr+1] = (ev); \ _seqbuf[_seqbufptr+2] = 0;\ _seqbuf[_seqbufptr+3] = 0;\ *(unsigned int *)&_seqbuf[_seqbufptr+4] = (parm); \ _SEQ_ADVBUF(8);}#define SEQ_START_TIMER() _TIMER_EVENT(TMR_START, 0)#define SEQ_STOP_TIMER() _TIMER_EVENT(TMR_STOP, 0)#define SEQ_CONTINUE_TIMER() _TIMER_EVENT(TMR_CONTINUE, 0)#define SEQ_WAIT_TIME(ticks) _TIMER_EVENT(TMR_WAIT_ABS, ticks)#define SEQ_DELTA_TIME(ticks) _TIMER_EVENT(TMR_WAIT_REL, ticks)#define SEQ_ECHO_BACK(key) _TIMER_EVENT(TMR_ECHO, key)#define SEQ_SET_TEMPO(value) _TIMER_EVENT(TMR_TEMPO, value)#define SEQ_SONGPOS(pos) _TIMER_EVENT(TMR_SPP, pos)#define SEQ_TIME_SIGNATURE(sig) _TIMER_EVENT(TMR_TIMESIG, sig)/* * Local control events */#define _LOCAL_EVENT(ev, parm) {_SEQ_NEEDBUF(8);\ _seqbuf[_seqbufptr+0] = EV_SEQ_LOCAL; \ _seqbuf[_seqbufptr+1] = (ev); \ _seqbuf[_seqbufptr+2] = 0;\ _seqbuf[_seqbufptr+3] = 0;\ *(unsigned int *)&_seqbuf[_seqbufptr+4] = (parm); \ _SEQ_ADVBUF(8);}#define SEQ_PLAYAUDIO(devmask) _LOCAL_EVENT(LOCL_STARTAUDIO, devmask)#define SEQ_PLAYAUDIO2(devmask) _LOCAL_EVENT(LOCL_STARTAUDIO2, devmask)#define SEQ_PLAYAUDIO3(devmask) _LOCAL_EVENT(LOCL_STARTAUDIO3, devmask)#define SEQ_PLAYAUDIO4(devmask) _LOCAL_EVENT(LOCL_STARTAUDIO4, devmask)/* * Events for the level 1 interface only */#define SEQ_MIDIOUT(device, byte) {_SEQ_NEEDBUF(4);\ _seqbuf[_seqbufptr] = SEQ_MIDIPUTC;\ _seqbuf[_seqbufptr+1] = (byte);\ _seqbuf[_seqbufptr+2] = (device);\ _seqbuf[_seqbufptr+3] = 0;\ _SEQ_ADVBUF(4);}/* * Patch loading. */#ifdef OSSLIB# define SEQ_WRPATCH(patchx, len) \ OSS_write_patch(seqfd, (char*)(patchx), len)# define SEQ_WRPATCH2(patchx, len) \ OSS_write_patch2(seqfd, (char*)(patchx), len)#else# define SEQ_WRPATCH(patchx, len) \ {if (_seqbufptr) SEQ_DUMPBUF();\ if (write(seqfd, (char*)(patchx), len)==-1) \ perror("Write patch: /dev/sequencer");}# define SEQ_WRPATCH2(patchx, len) \ (SEQ_DUMPBUF(), write(seqfd, (char*)(patchx), len))#endif#endif#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -