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

📄 mixdrv.c

📁 这个是延伸mame的在wince平台下的游戏模拟器的代码
💻 C
📖 第 1 页 / 共 2 页
字号:
		}		else {		    lpVoice->bControl |= VOICE_STOP;		    break;		}	    }	}	/* check for overflow and clip if necessary */	nSize = nCount;	if (lpVoice->bControl & VOICE_REVERSE) {	    if (nSize * lpVoice->dwFrequency >		lpVoice->dwAccum - lpVoice->dwLoopStart)		nSize = (lpVoice->dwAccum - lpVoice->dwLoopStart +			 lpVoice->dwFrequency) / lpVoice->dwFrequency;	}	else {	    if (nSize * lpVoice->dwFrequency >		lpVoice->dwLoopEnd - lpVoice->dwAccum)		nSize = (lpVoice->dwLoopEnd - lpVoice->dwAccum +			 lpVoice->dwFrequency) / lpVoice->dwFrequency;	}	if (lpVoice->bControl & VOICE_REVERSE)	    lpVoice->dwFrequency = -lpVoice->dwFrequency;	/* mixes chunk of data in a burst mode */	if (lpVoice->bControl & VOICE_16BITS) {	    Synth.lpfnMixAudioProc[1] (lpBuffer, nSize, lpVoice);	}	else {	    Synth.lpfnMixAudioProc[0] (lpBuffer, nSize, lpVoice);	}	if (lpVoice->bControl & VOICE_REVERSE)	    lpVoice->dwFrequency = -lpVoice->dwFrequency;	/* update mixing buffer address and counter */	lpBuffer += nSize;	if (Synth.wFormat & AUDIO_FORMAT_STEREO)	    lpBuffer += nSize;	nCount -= nSize;    }}static VOID MixAudioVoices(LPLONG lpBuffer, UINT nCount){    UINT nVoice, nSize;    while (nCount > 0) {	nSize = nCount;	if (Synth.lpfnAudioTimer != NULL) {	    nSize = (Synth.dwTimerRate - Synth.dwTimerAccum + 64L) & ~63L;	    if (nSize > nCount)		nSize = nCount;	    if ((Synth.dwTimerAccum += nSize) >= Synth.dwTimerRate) {		Synth.dwTimerAccum -= Synth.dwTimerRate;		Synth.lpfnAudioTimer();	    }	}	for (nVoice = 0; nVoice < Synth.nVoices; nVoice++) {	    MixAudioData(lpBuffer, nSize, &Synth.aVoices[nVoice]);	}	lpBuffer += nSize;	nCount -= nSize;    }}/* * High level waveform synthesizer interface */static UINT AIAPI GetAudioCaps(LPAUDIOCAPS lpCaps){    memset(lpCaps, 0, sizeof(AUDIOCAPS));    return AUDIO_ERROR_NOTSUPPORTED;}static UINT AIAPI PingAudio(VOID){    return AUDIO_ERROR_NOTSUPPORTED;}static UINT AIAPI OpenAudio(LPAUDIOINFO lpInfo){    memset(&Synth, 0, sizeof(Synth));    Synth.wFormat = lpInfo->wFormat;    Synth.nSampleRate = lpInfo->nSampleRate;    if (Synth.wFormat & AUDIO_FORMAT_FILTER) {	Synth.lpfnMixAudioProc[0] = (Synth.wFormat & AUDIO_FORMAT_STEREO) ?	    MixAudioData08SI : MixAudioData08MI;	Synth.lpfnMixAudioProc[1] = (Synth.wFormat & AUDIO_FORMAT_STEREO) ?	    MixAudioData16SI : MixAudioData16MI;    }    else {	Synth.lpfnMixAudioProc[0] = (Synth.wFormat & AUDIO_FORMAT_STEREO) ?	    MixAudioData08S : MixAudioData08M;	Synth.lpfnMixAudioProc[1] = (Synth.wFormat & AUDIO_FORMAT_STEREO) ?	    MixAudioData16S : MixAudioData16M;    }    /* allocate volume (0-64) and filter (0-31) table */    Synth.lpMemory = malloc(sizeof(LONG) * 65 * 256 +			    sizeof(BYTE) * 32 * 256 + 1023);    if (Synth.lpMemory != NULL) {	lpVolumeTable = (LPLONG) (((DWORD) Synth.lpMemory + 1023) & ~1023);	lpFilterTable = (LPBYTE) (lpVolumeTable + 65 * 256);	ASetAudioMixerValue(AUDIO_MIXER_MASTER_VOLUME, 96);	ASetAudioCallback(UpdateVoices);	return AUDIO_ERROR_NONE;    }    return AUDIO_ERROR_NOMEMORY;}static UINT AIAPI CloseAudio(VOID){    if (Synth.lpMemory != NULL)	free(Synth.lpMemory);    memset(&Synth, 0, sizeof(Synth));    return AUDIO_ERROR_NONE;}static UINT AIAPI SetAudioMixerValue(UINT nChannel, UINT nMixerValue){    LPBYTE lpFilter;    LPLONG lpVolume;    UINT nVolume, nSample;    LONG dwAccum, dwDelta;    if (Synth.lpMemory == NULL)	return AUDIO_ERROR_NOTSUPPORTED;    /* master volume must be less than 256 units */    if (nChannel != AUDIO_MIXER_MASTER_VOLUME || nMixerValue > 256)	return AUDIO_ERROR_INVALPARAM;    /* half dynamic range for mono output */    if (!(Synth.wFormat & AUDIO_FORMAT_STEREO))	nMixerValue >>= 1;    /* build volume table (0-64) */    lpVolume = lpVolumeTable;    dwDelta = 0;    for (nVolume = 0; nVolume <= 64; nVolume++, dwDelta += nMixerValue) {	dwAccum = 0;	for (nSample = 0; nSample < 128; nSample++, dwAccum += dwDelta)	    *lpVolume++ = dwAccum >> 4;	dwAccum = -dwAccum;	for (nSample = 0; nSample < 128; nSample++, dwAccum += dwDelta)	    *lpVolume++ = dwAccum >> 4;    }#ifdef __FILTER__    /* build lowpass filter table (0-31) */    lpFilter = lpFilterTable;    for (nVolume = 0; nVolume < 32; nVolume++) {	dwAccum = 0;	for (nSample = 0; nSample < 128; nSample++, dwAccum += nVolume)	    *lpFilter++ = dwAccum >> 5;	dwAccum = -dwAccum;	for (nSample = 0; nSample < 128; nSample++, dwAccum += nVolume)	    *lpFilter++ = dwAccum >> 5;    }#endif    return AUDIO_ERROR_NONE;}static UINT AIAPI OpenVoices(UINT nVoices){    UINT nVoice;    /*     * Initialize waveform synthesizer structure for playback     */    if (nVoices >= 1 && nVoices <= AUDIO_MAX_VOICES) {	Synth.nVoices = nVoices;	for (nVoice = 0; nVoice < Synth.nVoices; nVoice++)	    Synth.aVoices[nVoice].bControl = VOICE_STOP;	return AUDIO_ERROR_NONE;    }    return AUDIO_ERROR_INVALPARAM;}static UINT AIAPI CloseVoices(VOID){    UINT nVoice;    memset(Synth.aVoices, 0, sizeof(Synth.aVoices));    for (nVoice = 0; nVoice < AUDIO_MAX_VOICES; nVoice++)	Synth.aVoices[nVoice].bControl = VOICE_STOP;    return AUDIO_ERROR_NONE;}static UINT AIAPI UpdateAudio(VOID){    return AUDIO_ERROR_NONE;}static LONG AIAPI GetAudioDataAvail(VOID){    return 0;}static UINT AIAPI CreateAudioData(LPAUDIOWAVE lpWave){    if (lpWave != NULL) {	lpWave->dwHandle = (DWORD) lpWave->lpData;	return AUDIO_ERROR_NONE;    }    return AUDIO_ERROR_INVALHANDLE;}static UINT AIAPI DestroyAudioData(LPAUDIOWAVE lpWave){    if (lpWave != NULL && lpWave->dwHandle != 0) {	return AUDIO_ERROR_NONE;    }    return AUDIO_ERROR_INVALHANDLE;}static UINT AIAPI WriteAudioData(LPAUDIOWAVE lpWave, DWORD dwOffset, UINT nCount){    if (lpWave != NULL && lpWave->dwHandle != 0) {	/* anticlick removal work around */	if (lpWave->wFormat & AUDIO_FORMAT_LOOP) {	    *(LPSTR)(lpWave->dwHandle + lpWave->dwLoopEnd) =		*(LPSTR)(lpWave->dwHandle + lpWave->dwLoopStart);	}	else if (dwOffset + nCount >= lpWave->dwLength) {	    *(LPDWORD) (lpWave->dwHandle + lpWave->dwLength) = 0;	}	return AUDIO_ERROR_NONE;    }    return AUDIO_ERROR_INVALHANDLE;}static UINT AIAPI PrimeVoice(UINT nVoice, LPAUDIOWAVE lpWave){    LPVOICE lpVoice;    if (nVoice < Synth.nVoices && lpWave != NULL && lpWave->dwHandle != 0) {	lpVoice = &Synth.aVoices[nVoice];	lpVoice->lpData = (LPVOID) lpWave->dwHandle;	lpVoice->bControl = VOICE_STOP;	lpVoice->dwAccum = 0;	if (lpWave->wFormat & (AUDIO_FORMAT_LOOP | AUDIO_FORMAT_BIDILOOP)) {	    lpVoice->dwLoopStart = lpWave->dwLoopStart;	    lpVoice->dwLoopEnd = lpWave->dwLoopEnd;	    lpVoice->bControl |= VOICE_LOOP;	    if (lpWave->wFormat & AUDIO_FORMAT_BIDILOOP)		lpVoice->bControl |= VOICE_BIDILOOP;	}	else {	    lpVoice->dwLoopStart = lpWave->dwLength;	    lpVoice->dwLoopEnd = lpWave->dwLength;	}	if (lpWave->wFormat & AUDIO_FORMAT_16BITS) {	    lpVoice->dwLoopStart >>= 1;	    lpVoice->dwLoopEnd >>= 1;	    lpVoice->bControl |= VOICE_16BITS;	}	lpVoice->dwAccum <<= ACCURACY;	lpVoice->dwLoopStart <<= ACCURACY;	lpVoice->dwLoopEnd <<= ACCURACY;	return AUDIO_ERROR_NONE;    }    return AUDIO_ERROR_INVALHANDLE;}static UINT AIAPI StartVoice(UINT nVoice){    if (nVoice < Synth.nVoices) {	Synth.aVoices[nVoice].bControl &= ~VOICE_STOP;	return AUDIO_ERROR_NONE;    }    return AUDIO_ERROR_INVALHANDLE;}static UINT AIAPI StopVoice(UINT nVoice){    if (nVoice < Synth.nVoices) {	Synth.aVoices[nVoice].bControl |= VOICE_STOP;	return AUDIO_ERROR_NONE;    }    return AUDIO_ERROR_INVALHANDLE;}static UINT AIAPI SetVoicePosition(UINT nVoice, LONG dwPosition){    if (nVoice < Synth.nVoices) {	dwPosition <<= ACCURACY;	if (dwPosition >= 0 && dwPosition < Synth.aVoices[nVoice].dwLoopEnd) {	    Synth.aVoices[nVoice].dwAccum = dwPosition;	    return AUDIO_ERROR_NONE;	}	return AUDIO_ERROR_INVALPARAM;    }    return AUDIO_ERROR_INVALHANDLE;}static UINT AIAPI SetVoiceFrequency(UINT nVoice, LONG dwFrequency){    if (nVoice < Synth.nVoices) {	if (dwFrequency >= AUDIO_MIN_FREQUENCY &&	    dwFrequency <= AUDIO_MAX_FREQUENCY) {	    Synth.aVoices[nVoice].dwFrequency = ((dwFrequency << ACCURACY) +						 (Synth.nSampleRate >> 1)) / Synth.nSampleRate;	    return AUDIO_ERROR_NONE;	}	return AUDIO_ERROR_INVALPARAM;    }    return AUDIO_ERROR_INVALHANDLE;}static UINT AIAPI SetVoiceVolume(UINT nVoice, UINT nVolume){    if (nVoice < Synth.nVoices) {	if (nVolume <= AUDIO_MAX_VOLUME) {	    Synth.aVoices[nVoice].nVolume = nVolume >> 1;	    return AUDIO_ERROR_NONE;	}	return AUDIO_ERROR_INVALPARAM;    }    return AUDIO_ERROR_INVALHANDLE;}static UINT AIAPI SetVoicePanning(UINT nVoice, UINT nPanning){    if (nVoice < Synth.nVoices) {	if (nPanning <= AUDIO_MAX_PANNING) {	    Synth.aVoices[nVoice].nPanning = nPanning;	    return AUDIO_ERROR_NONE;	}	return AUDIO_ERROR_INVALPARAM;    }    return AUDIO_ERROR_INVALHANDLE;}static UINT AIAPI GetVoicePosition(UINT nVoice, LPLONG lpdwPosition){    if (nVoice < Synth.nVoices) {	if (lpdwPosition != NULL) {	    *lpdwPosition = Synth.aVoices[nVoice].dwAccum >> ACCURACY;	    return AUDIO_ERROR_NONE;	}	return AUDIO_ERROR_INVALPARAM;    }    return AUDIO_ERROR_INVALHANDLE;}static UINT AIAPI GetVoiceFrequency(UINT nVoice, LPLONG lpdwFrequency){    if (nVoice < Synth.nVoices) {	if (lpdwFrequency != NULL) {	    *lpdwFrequency = (Synth.aVoices[nVoice].dwFrequency *			      Synth.nSampleRate) >> ACCURACY;	    return AUDIO_ERROR_NONE;	}	return AUDIO_ERROR_INVALPARAM;    }    return AUDIO_ERROR_INVALHANDLE;}static UINT AIAPI GetVoiceVolume(UINT nVoice, LPUINT lpnVolume){    if (nVoice < Synth.nVoices) {	if (lpnVolume != NULL) {	    *lpnVolume = Synth.aVoices[nVoice].nVolume << 1;	    return AUDIO_ERROR_NONE;	}	return AUDIO_ERROR_INVALPARAM;    }    return AUDIO_ERROR_INVALHANDLE;}static UINT AIAPI GetVoicePanning(UINT nVoice, LPUINT lpnPanning){    if (nVoice < Synth.nVoices) {	if (lpnPanning != NULL) {	    *lpnPanning = Synth.aVoices[nVoice].nPanning;	    return AUDIO_ERROR_NONE;	}	return AUDIO_ERROR_INVALPARAM;    }    return AUDIO_ERROR_INVALHANDLE;}static UINT AIAPI GetVoiceStatus(UINT nVoice, LPBOOL lpnStatus){    if (nVoice < Synth.nVoices) {	if (lpnStatus != NULL) {	    *lpnStatus = (Synth.aVoices[nVoice].bControl & VOICE_STOP) != 0;	    return AUDIO_ERROR_NONE;	}	return AUDIO_ERROR_INVALPARAM;    }    return AUDIO_ERROR_INVALHANDLE;}static UINT AIAPI SetAudioTimerProc(LPFNAUDIOTIMER lpfnAudioTimer){    Synth.lpfnAudioTimer = lpfnAudioTimer;    return AUDIO_ERROR_NONE;}static UINT AIAPI SetAudioTimerRate(UINT nBPM){    if (nBPM >= 0x20 && nBPM <= 0xFF) {	Synth.dwTimerRate = Synth.nSampleRate;	if (Synth.wFormat & AUDIO_FORMAT_STEREO)	    Synth.dwTimerRate <<= 1;	Synth.dwTimerRate = (5 * Synth.dwTimerRate) / (2 * nBPM);	return AUDIO_ERROR_NONE;    }    return AUDIO_ERROR_INVALPARAM;}static VOID AIAPI UpdateVoices(LPBYTE lpData, UINT nCount){    static LONG aBuffer[BUFFERSIZE];    UINT nSamples;    if (Synth.wFormat & AUDIO_FORMAT_16BITS)	nCount >>= 1;    while (nCount > 0) {	if ((nSamples = nCount) > BUFFERSIZE)	    nSamples = BUFFERSIZE;	memset(aBuffer, 0, nSamples << 2);	MixAudioVoices(aBuffer, nSamples);	QuantAudioData(lpData, aBuffer, nSamples);	lpData += nSamples << ((Synth.wFormat & AUDIO_FORMAT_16BITS) != 0);	nCount -= nSamples;    }}/* * Waveform synthesizer public interface */AUDIOSYNTHDRIVER EmuSynthDriver ={    GetAudioCaps, PingAudio, OpenAudio, CloseAudio,    UpdateAudio, OpenVoices, CloseVoices,    SetAudioTimerProc, SetAudioTimerRate, SetAudioMixerValue,    GetAudioDataAvail, CreateAudioData, DestroyAudioData,    WriteAudioData, PrimeVoice, StartVoice, StopVoice,    SetVoicePosition, SetVoiceFrequency, SetVoiceVolume,    SetVoicePanning, GetVoicePosition, GetVoiceFrequency,    GetVoiceVolume, GetVoicePanning, GetVoiceStatus};

⌨️ 快捷键说明

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