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

📄 midi.c

📁 Wine-20031016
💻 C
📖 第 1 页 / 共 3 页
字号:
        if (wDevID >= MODM_NumDevs) return MMSYSERR_BADDEVICEID;    if (!MidiOutDev[wDevID].bEnabled) return MIDIERR_NODEVICE;    if (midiSeq == NULL) {	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");	lpNewData = HeapAlloc(GetProcessHeap, 0, lpMidiHdr->dwBufferLength + 2);    }    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 start of System Exclusive */	    len_add = 1;	    lpData[0] = 0xF0;	    memcpy(lpNewData, lpData, lpMidiHdr->dwBufferLength);	    WARN("Adding missing 0xF0 marker at the beginning of "		 "system exclusive byte stream\n");	}	if (lpData[lpMidiHdr->dwBufferLength-1] != 0xF7) {	    /* Send end of System Exclusive */	    memcpy(lpData + len_add, lpData, lpMidiHdr->dwBufferLength);            lpNewData[lpMidiHdr->dwBufferLength + len_add - 1] = 0xF0;	    len_add++;	    WARN("Adding missing 0xF7 marker at the end of "		 "system exclusive byte stream\n");	}	snd_seq_ev_clear(&event);	snd_seq_ev_set_direct(&event);	snd_seq_ev_set_source(&event, port_out);	snd_seq_ev_set_dest(&event, MidiOutDev[wDevID].addr.client, MidiOutDev[wDevID].addr.port);	TRACE("client = %d port = %d\n", MidiOutDev[wDevID].addr.client, MidiOutDev[wDevID].addr.port);	snd_seq_ev_set_sysex(&event, lpMidiHdr->dwBufferLength + len_add, lpNewData ? lpNewData : lpData);	snd_seq_event_output_direct(midiSeq, &event);	if (lpNewData)		HeapFree(GetProcessHeap(), 0, lpData);	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 (midiSeq == NULL) {	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 (midiSeq == NULL) {	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_CMD_CONTROL | chn);	/* remove sustain on all channels */	modData(wDevID, (MIDI_CTL_SUSTAIN << 8) | MIDI_CMD_CONTROL | chn);    }    /* FIXME: the LongData buffers must also be returned to the app */    return MMSYSERR_NOERROR;}#endif /* defined(HAVE_ALSA) && ((SND_LIB_MAJOR == 0 && SND_LIB_MINOR >= 9) || SND_LIB_MAJOR >= 1) *//*======================================================================* *                  	    MIDI entry points 				* *======================================================================*//************************************************************************** * ALSA_MidiInit				[internal] * * Initializes the MIDI devices information variables */LONG ALSA_MidiInit(void){#if defined(HAVE_ALSA) && ((SND_LIB_MAJOR == 0 && SND_LIB_MINOR >= 9) || SND_LIB_MAJOR >= 1)    static	BOOL	bInitDone = FALSE;    snd_seq_client_info_t *cinfo;    snd_seq_port_info_t *pinfo;    int count;    if (bInitDone)	return TRUE;    TRACE("Initializing the MIDI variables.\n");    bInitDone = TRUE;    /* try to open device */    if (midiOpenSeq(0) == -1) {	return TRUE;    }#if 0 /* Debug purpose */    snd_lib_error_set_handler(error_handler);#endif        snd_seq_client_info_alloca(&cinfo);    snd_seq_port_info_alloca(&pinfo);    snd_seq_client_info_set_client(cinfo, -1);    while(snd_seq_query_next_client(midiSeq, cinfo) >= 0) {        snd_seq_port_info_set_client(pinfo, snd_seq_client_info_get_client(cinfo));	snd_seq_port_info_set_port(pinfo, -1);	count = 0;	while (snd_seq_query_next_port(midiSeq, pinfo) >= 0) {            int cap = snd_seq_port_info_get_capability(pinfo);	    int type = snd_seq_port_info_get_type(pinfo);	    if (cap & SND_SEQ_PORT_CAP_WRITE) {                TRACE("OUT (%d:%s:%s:%d:%s:%x)\n",snd_seq_client_info_get_client(cinfo),				                snd_seq_client_info_get_name(cinfo),						snd_seq_client_info_get_type(cinfo) == SND_SEQ_USER_CLIENT ? "user" : "kernel",						snd_seq_port_info_get_port(pinfo),						snd_seq_port_info_get_name(pinfo),						type);				if (MODM_NumDevs >= MAX_MIDIOUTDRV)		    continue;		if (!type)	            continue;		memcpy(&MidiOutDev[MODM_NumDevs].addr, snd_seq_port_info_get_addr(pinfo), sizeof(snd_seq_addr_t));				/* Manufac ID. We do not have access to this with soundcard.h		 * Does not seem to be a problem, because in mmsystem.h only		 * Microsoft's ID is listed.		 */		MidiOutDev[MODM_NumDevs].caps.wMid = 0x00FF;		MidiOutDev[MODM_NumDevs].caps.wPid = 0x0001; 	/* FIXME Product ID  */		/* Product Version. We simply say "1" */		MidiOutDev[MODM_NumDevs].caps.vDriverVersion = 0x001;		MidiOutDev[MODM_NumDevs].caps.wChannelMask   = 0xFFFF;		/* FIXME Do we have this information?		 * Assuming the soundcards can handle		 * MIDICAPS_VOLUME and MIDICAPS_LRVOLUME but		 * not MIDICAPS_CACHE.		 */		MidiOutDev[MODM_NumDevs].caps.dwSupport      = MIDICAPS_VOLUME|MIDICAPS_LRVOLUME;                strcpy(MidiOutDev[MODM_NumDevs].caps.szPname, snd_seq_client_info_get_name(cinfo));                MidiOutDev[MODM_NumDevs].caps.wTechnology = MIDI_AlsaToWindowsDeviceType(type);                MidiOutDev[MODM_NumDevs].caps.wVoices     = 16;                /* FIXME Is it possible to know the maximum                 * number of simultaneous notes of a soundcard ?                 * I believe we don't have this information, but                 * it's probably equal or more than wVoices                 */                MidiOutDev[MODM_NumDevs].caps.wNotes = 16;                MidiOutDev[MODM_NumDevs].bEnabled    = TRUE;	        TRACE("MidiOut[%d]\tname='%s' techn=%d voices=%d notes=%d chnMsk=%04x support=%ld\n"	      	      "\tALSA info: midi dev-type=%lx, capa=%lx\n",	      	      MODM_NumDevs, MidiOutDev[MODM_NumDevs].caps.szPname, MidiOutDev[MODM_NumDevs].caps.wTechnology,	      	      MidiOutDev[MODM_NumDevs].caps.wVoices, MidiOutDev[MODM_NumDevs].caps.wNotes,	              MidiOutDev[MODM_NumDevs].caps.wChannelMask, MidiOutDev[MODM_NumDevs].caps.dwSupport,	              (long)type, (long)0);				MODM_NumDevs++;            }	    if (cap & SND_SEQ_PORT_CAP_READ) {                TRACE("IN  (%d:%s:%s:%d:%s:%x)\n",snd_seq_client_info_get_client(cinfo),				                snd_seq_client_info_get_name(cinfo),						snd_seq_client_info_get_type(cinfo) == SND_SEQ_USER_CLIENT ? "user" : "kernel",						snd_seq_port_info_get_port(pinfo),						snd_seq_port_info_get_name(pinfo),						type);				if (MIDM_NumDevs >= MAX_MIDIINDRV)		    continue;		if (!type)		    continue;		memcpy(&MidiInDev[MIDM_NumDevs].addr, snd_seq_port_info_get_addr(pinfo), sizeof(snd_seq_addr_t));				/* Manufac ID. We do not have access to this with soundcard.h		 * Does not seem to be a problem, because in mmsystem.h only		 * Microsoft's ID is listed.		 */		MidiInDev[MIDM_NumDevs].caps.wMid = 0x00FF;		MidiInDev[MIDM_NumDevs].caps.wPid = 0x0001; 	/* FIXME Product ID  */		/* Product Version. We simply say "1" */		MidiInDev[MIDM_NumDevs].caps.vDriverVersion = 0x001;		/* FIXME Do we have this information?		 * Assuming the soundcards can handle		 * MIDICAPS_VOLUME and MIDICAPS_LRVOLUME but		 * not MIDICAPS_CACHE.		 */		MidiInDev[MIDM_NumDevs].caps.dwSupport      = MIDICAPS_VOLUME|MIDICAPS_LRVOLUME;                strcpy(MidiInDev[MIDM_NumDevs].caps.szPname, snd_seq_client_info_get_name(cinfo));                MidiInDev[MIDM_NumDevs].state = 0;                TRACE("MidiIn [%d]\tname='%s' support=%ld\n"	      	      "\tALSA info: midi dev-type=%lx, capa=%lx\n",	              MIDM_NumDevs, MidiInDev[MIDM_NumDevs].caps.szPname, MidiInDev[MIDM_NumDevs].caps.dwSupport,	              (long)type, (long)0);		MIDM_NumDevs++;	    }	}    }    /* close file and exit */    midiCloseSeq();    TRACE("End\n");#endif    return TRUE;}/************************************************************************** * 			midMessage (WINEOSS.4) */DWORD WINAPI ALSA_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) {#if defined(HAVE_ALSA) && ((SND_LIB_MAJOR == 0 && SND_LIB_MINOR >= 9) || SND_LIB_MAJOR >= 1)    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 ALSA_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) {#if defined(HAVE_ALSA) && ((SND_LIB_MAJOR == 0 && SND_LIB_MINOR >= 9) || SND_LIB_MAJOR >= 1)    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 + -