⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 midi.c

📁 Wine-20031016
💻 C
📖 第 1 页 / 共 4 页
字号:
				if (voice[i].channel == chn) {				    SEQ_BENDER_RANGE(wDevID, i, channel[chn].benderRange);				}			    }			}			break;		    case 0x7F7F:			channel[chn].benderRange = 2;			for (i = 0; i < MidiOutDev[wDevID].caps.wVoices; i++) {			    if (voice[i].channel == chn) {				SEQ_BENDER_RANGE(wDevID, i, channel[chn].benderRange);			    }			}			break;		    default:			TRACE("Data entry: regPmt=0x%02x%02x, nrgPmt=0x%02x%02x with %x\n",			      channel[chn].regPmtMSB, channel[chn].regPmtLSB,			      channel[chn].nrgPmtMSB, channel[chn].nrgPmtLSB,			      d2);			break;		    }		    break;		case 0x78: /* all sounds off */		    /* FIXME: I don't know if I have to take care of the channel		     * for this control ?		     */		    for (i = 0; i < MidiOutDev[wDevID].caps.wVoices; i++) {			if (voice[i].status != sVS_UNUSED && voice[i].channel == chn) {			    voice[i].status = sVS_UNUSED;			    SEQ_STOP_NOTE(wDevID, i, voice[i].note, 64);			}		    }		    break;		case 0x7B: /* all notes off */		    /* FIXME: I don't know if I have to take care of the channel		     * for this control ?		     */		    for (i = 0; i < MidiOutDev[wDevID].caps.wVoices; i++) {			if (voice[i].status == sVS_PLAYING && voice[i].channel == chn) {			    voice[i].status = sVS_UNUSED;			    SEQ_STOP_NOTE(wDevID, i, voice[i].note, 64);			}		    }		    break;		default:		    TRACE("Dropping MIDI control event 0x%02x(%02x) on channel %d\n",			  d1, d2, chn);		    break;		}		break;	    case MIDI_PGM_CHANGE:		channel[chn].program = d1;		break;	    case MIDI_CHN_PRESSURE:		for (i = 0; i < MidiOutDev[wDevID].caps.wVoices; i++) {		    if (voice[i].status != sVS_UNUSED && voice[i].channel == chn) {			SEQ_KEY_PRESSURE(wDevID, i, voice[i].note, d1);		    }		}		break;	    case MIDI_PITCH_BEND:		channel[chn].bender = (d2 << 7) + d1;		for (i = 0; i < MidiOutDev[wDevID].caps.wVoices; i++) {		    if (voice[i].channel == chn) {			SEQ_BENDER(wDevID, i, channel[chn].bender);		    }		}		break;	    case MIDI_SYSTEM_PREFIX:		switch (evt & 0x0F) {		case 0x0F: 	/* Reset */		    modFMReset(wDevID);		    break;		default:		    WARN("Unsupported (yet) system event %02x\n", evt & 0x0F);		}		break;	    default:		WARN("Internal error, shouldn't happen (event=%08x)\n", evt & 0xF0);		return MMSYSERR_NOTENABLED;	    }	}	break;    case MOD_MIDIPORT:	{	    int	dev = wDevID - MODM_NumFMSynthDevs;	    if (dev < 0) {		WARN("Internal error on devID (%u) !\n", wDevID);		return MIDIERR_NODEVICE;	    }	    switch (evt & 0xF0) {	    case MIDI_NOTEOFF:	    case MIDI_NOTEON:	    case MIDI_KEY_PRESSURE:	    case MIDI_CTL_CHANGE:	    case MIDI_PITCH_BEND:		SEQ_MIDIOUT(dev, evt);		SEQ_MIDIOUT(dev, d1);		SEQ_MIDIOUT(dev, d2);		break;	    case MIDI_PGM_CHANGE:	    case MIDI_CHN_PRESSURE:		SEQ_MIDIOUT(dev, evt);		SEQ_MIDIOUT(dev, d1);		break;	    case MIDI_SYSTEM_PREFIX:		switch (evt & 0x0F) {		case 0x00:	/* System Exclusive, don't do it on modData,				 * should require modLongData*/		case 0x01:	/* Undefined */		case 0x04:	/* Undefined. */		case 0x05:	/* Undefined. */		case 0x07:	/* End of Exclusive. */		case 0x09:	/* Undefined. */		case 0x0D:	/* Undefined. */		    break;		case 0x06:	/* Tune Request */		case 0x08:	/* Timing Clock. */		case 0x0A:	/* Start. */		case 0x0B:	/* Continue */		case 0x0C:	/* Stop */		case 0x0E: 	/* Active Sensing. */		    SEQ_MIDIOUT(dev, evt);		    break;		case 0x0F: 	/* Reset */				/* SEQ_MIDIOUT(dev, evt);				   this other way may be better */		    SEQ_MIDIOUT(dev, MIDI_SYSTEM_PREFIX);		    SEQ_MIDIOUT(dev, 0x7e);		    SEQ_MIDIOUT(dev, 0x7f);		    SEQ_MIDIOUT(dev, 0x09);		    SEQ_MIDIOUT(dev, 0x01);		    SEQ_MIDIOUT(dev, 0xf7);		    break;		case 0x03:	/* Song Select. */		    SEQ_MIDIOUT(dev, evt);		    SEQ_MIDIOUT(dev, d1);		case 0x02:	/* Song Position Pointer. */		    SEQ_MIDIOUT(dev, evt);		    SEQ_MIDIOUT(dev, d1);		    SEQ_MIDIOUT(dev, d2);		}		break;	    }	}	break;    default:	WARN("Technology not supported (yet) %d !\n",	     MidiOutDev[wDevID].caps.wTechnology);	return MMSYSERR_NOTENABLED;    }    SEQ_DUMPBUF();    return MMSYSERR_NOERROR;}/************************************************************************** *		modLongData					[internal] */static DWORD modLongData(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize){    int		count;    LPBYTE	lpData;    TRACE("(%04X, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);    /* Note: MS doc does not say much about the dwBytesRecorded member of the MIDIHDR structure     * but it seems to be used only for midi input.     * Taking a look at the WAVEHDR structure (which is quite similar) confirms this assumption.     */        if (wDevID >= MODM_NumDevs) return MMSYSERR_BADDEVICEID;    if (!MidiOutDev[wDevID].bEnabled) return MIDIERR_NODEVICE;    if (midiSeqFD == -1) {	WARN("can't play !\n");	return MIDIERR_NODEVICE;    }    lpData = lpMidiHdr->lpData;    if (lpData == NULL)	return MIDIERR_UNPREPARED;    if (!(lpMidiHdr->dwFlags & MHDR_PREPARED))	return MIDIERR_UNPREPARED;    if (lpMidiHdr->dwFlags & MHDR_INQUEUE)	return MIDIERR_STILLPLAYING;    lpMidiHdr->dwFlags &= ~MHDR_DONE;    lpMidiHdr->dwFlags |= MHDR_INQUEUE;    /* FIXME: MS doc is not 100% clear. Will lpData only contain system exclusive     * data, or can it also contain raw MIDI data, to be split up and sent to     * modShortData() ?     * If the latest is true, then the following WARNing will fire up     */    if (lpData[0] != 0xF0 || lpData[lpMidiHdr->dwBufferLength - 1] != 0xF7) {	WARN("Alledged system exclusive buffer is not correct\n\tPlease report with MIDI file\n");    }    TRACE("dwBufferLength=%lu !\n", lpMidiHdr->dwBufferLength);    TRACE("                 %02X %02X %02X ... %02X %02X %02X\n",	  lpData[0], lpData[1], lpData[2], lpData[lpMidiHdr->dwBufferLength-3],	  lpData[lpMidiHdr->dwBufferLength-2], lpData[lpMidiHdr->dwBufferLength-1]);    switch (MidiOutDev[wDevID].caps.wTechnology) {    case MOD_FMSYNTH:	/* FIXME: I don't think there is much to do here */	break;    case MOD_MIDIPORT:	if (lpData[0] != 0xF0) {	    /* Send end of System Exclusive */	    SEQ_MIDIOUT(wDevID - MODM_NumFMSynthDevs, 0xF0);	    WARN("Adding missing 0xF0 marker at the beginning of "		 "system exclusive byte stream\n");	}	for (count = 0; count < lpMidiHdr->dwBufferLength; count++) {	    SEQ_MIDIOUT(wDevID - MODM_NumFMSynthDevs, lpData[count]);	}	if (lpData[count - 1] != 0xF7) {	    /* Send end of System Exclusive */	    SEQ_MIDIOUT(wDevID - MODM_NumFMSynthDevs, 0xF7);	    WARN("Adding missing 0xF7 marker at the end of "		 "system exclusive byte stream\n");	}	SEQ_DUMPBUF();	break;    default:	WARN("Technology not supported (yet) %d !\n",	     MidiOutDev[wDevID].caps.wTechnology);	return MMSYSERR_NOTENABLED;    }    lpMidiHdr->dwFlags &= ~MHDR_INQUEUE;    lpMidiHdr->dwFlags |= MHDR_DONE;    if (MIDI_NotifyClient(wDevID, MOM_DONE, (DWORD)lpMidiHdr, 0L) != MMSYSERR_NOERROR) {	WARN("can't notify client !\n");	return MMSYSERR_INVALPARAM;    }    return MMSYSERR_NOERROR;}/************************************************************************** * 			modPrepare				[internal] */static DWORD modPrepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize){    TRACE("(%04X, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);    if (midiSeqFD == -1) {	WARN("can't prepare !\n");	return MMSYSERR_NOTENABLED;    }    /* MS doc says that dwFlags must be set to zero, but (kinda funny) MS mciseq drivers     * asks to prepare MIDIHDR which dwFlags != 0.     * So at least check for the inqueue flag     */    if (dwSize < sizeof(MIDIHDR) || lpMidiHdr == 0 ||	lpMidiHdr->lpData == 0 || (lpMidiHdr->dwFlags & MHDR_INQUEUE) != 0 ||	lpMidiHdr->dwBufferLength >= 0x10000ul) {	WARN("%p %p %08lx %d/%ld\n", lpMidiHdr, lpMidiHdr->lpData,	           lpMidiHdr->dwFlags, sizeof(MIDIHDR), dwSize);	return MMSYSERR_INVALPARAM;    }    lpMidiHdr->lpNext = 0;    lpMidiHdr->dwFlags |= MHDR_PREPARED;    lpMidiHdr->dwFlags &= ~MHDR_DONE;    return MMSYSERR_NOERROR;}/************************************************************************** * 				modUnprepare			[internal] */static DWORD modUnprepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize){    TRACE("(%04X, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);    if (midiSeqFD == -1) {	WARN("can't unprepare !\n");	return MMSYSERR_NOTENABLED;    }    if (dwSize < sizeof(MIDIHDR) || lpMidiHdr == 0)	return MMSYSERR_INVALPARAM;    if (lpMidiHdr->dwFlags & MHDR_INQUEUE)	return MIDIERR_STILLPLAYING;    lpMidiHdr->dwFlags &= ~MHDR_PREPARED;    return MMSYSERR_NOERROR;}/************************************************************************** * 			modReset				[internal] */static DWORD modReset(WORD wDevID){    unsigned chn;    TRACE("(%04X);\n", wDevID);    if (wDevID >= MODM_NumDevs) return MMSYSERR_BADDEVICEID;    if (!MidiOutDev[wDevID].bEnabled) return MIDIERR_NODEVICE;    /* stop all notes */    /* FIXME: check if 0x78B0 is channel dependent or not. I coded it so that     * it's channel dependent...     */    for (chn = 0; chn < 16; chn++) {	/* turn off every note */	modData(wDevID, 0x7800 | MIDI_CTL_CHANGE | chn);	/* remove sustain on all channels */	modData(wDevID, (CTL_SUSTAIN << 8) | MIDI_CTL_CHANGE | chn);    }    /* FIXME: the LongData buffers must also be returned to the app */    return MMSYSERR_NOERROR;}#endif /* HAVE_OSS_MIDI *//*======================================================================* *                  	    MIDI entry points 				* *======================================================================*//************************************************************************** * 			midMessage (WINEOSS.4) */DWORD WINAPI OSS_midMessage(UINT wDevID, UINT wMsg, DWORD dwUser,			    DWORD dwParam1, DWORD dwParam2){    TRACE("(%04X, %04X, %08lX, %08lX, %08lX);\n",	  wDevID, wMsg, dwUser, dwParam1, dwParam2);    switch (wMsg) {#ifdef HAVE_OSS_MIDI    case DRVM_INIT:    case DRVM_ENABLE:    case DRVM_DISABLE:	/* FIXME: Pretend this is supported */	return 0;    case MIDM_OPEN:	return midOpen(wDevID, (LPMIDIOPENDESC)dwParam1, dwParam2);    case MIDM_CLOSE:	return midClose(wDevID);    case MIDM_ADDBUFFER:	return midAddBuffer(wDevID, (LPMIDIHDR)dwParam1, dwParam2);    case MIDM_PREPARE:	return midPrepare(wDevID, (LPMIDIHDR)dwParam1, dwParam2);    case MIDM_UNPREPARE:	return midUnprepare(wDevID, (LPMIDIHDR)dwParam1, dwParam2);    case MIDM_GETDEVCAPS:	return midGetDevCaps(wDevID, (LPMIDIINCAPSA)dwParam1,dwParam2);    case MIDM_GETNUMDEVS:	return MIDM_NumDevs;    case MIDM_RESET:	return midReset(wDevID);    case MIDM_START:	return midStart(wDevID);    case MIDM_STOP:	return midStop(wDevID);#endif    default:	TRACE("Unsupported message\n");    }    return MMSYSERR_NOTSUPPORTED;}/************************************************************************** * 				modMessage (WINEOSS.5) */DWORD WINAPI OSS_modMessage(UINT wDevID, UINT wMsg, DWORD dwUser,			    DWORD dwParam1, DWORD dwParam2){    TRACE("(%04X, %04X, %08lX, %08lX, %08lX);\n",	  wDevID, wMsg, dwUser, dwParam1, dwParam2);    switch (wMsg) {#ifdef HAVE_OSS_MIDI    case DRVM_INIT:    case DRVM_EXIT:    case DRVM_ENABLE:    case DRVM_DISABLE:	/* FIXME: Pretend this is supported */	return 0;    case MODM_OPEN:	return modOpen(wDevID, (LPMIDIOPENDESC)dwParam1, dwParam2);    case MODM_CLOSE:	return modClose(wDevID);    case MODM_DATA:	return modData(wDevID, dwParam1);    case MODM_LONGDATA:	return modLongData(wDevID, (LPMIDIHDR)dwParam1, dwParam2);    case MODM_PREPARE:	return modPrepare(wDevID, (LPMIDIHDR)dwParam1, dwParam2);    case MODM_UNPREPARE:	return modUnprepare(wDevID, (LPMIDIHDR)dwParam1, dwParam2);    case MODM_GETDEVCAPS:	return modGetDevCaps(wDevID, (LPMIDIOUTCAPSA)dwParam1, dwParam2);    case MODM_GETNUMDEVS:	return MODM_NumDevs;    case MODM_GETVOLUME:	return 0;    case MODM_SETVOLUME:	return 0;    case MODM_RESET:	return modReset(wDevID);#endif    default:	TRACE("Unsupported message\n");    }    return MMSYSERR_NOTSUPPORTED;}/*-----------------------------------------------------------------------*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -