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

📄 mixdrv.c

📁 这个是延伸mame的在wince平台下的游戏模拟器的代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * $Id: mixdrv.c 1.13 1996/09/08 21:14:54 chasan released $ *               1.14 1998/10/24 18:20:53 chasan released (Mixer API) * * Software-based waveform synthesizer emulator driver. * * Copyright (C) 1995-1999 Carlos Hasan * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */#define __FILTER__#ifdef __GNUC__#include <memory.h>#define cdecl#endif#include <string.h>#include <malloc.h>#include "audio.h"#include "drivers.h"/* * Voice control bit fields */#define VOICE_STOP              0x01#define VOICE_16BITS            0x02#define VOICE_LOOP              0x04#define VOICE_BIDILOOP          0x08#define VOICE_REVERSE           0x10/* * Voice pitch accurary and mixing buffer size */#define ACCURACY                12#define BUFFERSIZE              512/* * Waveform synthesizer voice structure */typedef struct {    LPVOID  lpData;    LONG    dwAccum;    LONG    dwFrequency;    LONG    dwLoopStart;    LONG    dwLoopEnd;    BYTE    nVolume;    BYTE    nPanning;    BYTE    bControl;    BYTE    bReserved;} VOICE, *LPVOICE;/* * Low level voice mixing routine prototype */typedef VOID (cdecl* LPFNMIXAUDIO)(LPLONG, UINT, LPVOICE);/* * Waveform synthesizer state structure */static struct {    VOICE   aVoices[AUDIO_MAX_VOICES];    UINT    nVoices;    UINT    wFormat;    UINT    nSampleRate;    LONG    dwTimerRate;    LONG    dwTimerAccum;    LPBYTE  lpMemory;    LPFNAUDIOTIMER lpfnAudioTimer;    LPFNMIXAUDIO lpfnMixAudioProc[2];} Synth;LPLONG lpVolumeTable;LPBYTE lpFilterTable;static VOID AIAPI UpdateVoices(LPBYTE lpData, UINT nCount);/* low level resamplation and quantization routines */#ifdef __ASM__VOID cdecl QuantAudioData08(LPVOID lpBuffer, LPLONG lpData, UINT nCount);VOID cdecl QuantAudioData16(LPVOID lpBuffer, LPLONG lpData, UINT nCount);VOID cdecl MixAudioData08M(LPLONG lpBuffer, UINT nCount, LPVOICE lpVoice);VOID cdecl MixAudioData08S(LPLONG lpBuffer, UINT nCount, LPVOICE lpVoice);VOID cdecl MixAudioData08MI(LPLONG lpBuffer, UINT nCount, LPVOICE lpVoice);VOID cdecl MixAudioData08SI(LPLONG lpBuffer, UINT nCount, LPVOICE lpVoice);VOID cdecl MixAudioData16M(LPLONG lpBuffer, UINT nCount, LPVOICE lpVoice);VOID cdecl MixAudioData16S(LPLONG lpBuffer, UINT nCount, LPVOICE lpVoice);VOID cdecl MixAudioData16MI(LPLONG lpBuffer, UINT nCount, LPVOICE lpVoice);VOID cdecl MixAudioData16SI(LPLONG lpBuffer, UINT nCount, LPVOICE lpVoice);static VOID QuantAudioData(LPVOID lpBuffer, LPLONG lpData, UINT nCount){    if (Synth.wFormat & AUDIO_FORMAT_16BITS)	QuantAudioData16(lpBuffer, lpData, nCount);    else	QuantAudioData08(lpBuffer, lpData, nCount);}#elsetypedef short SHORT;typedef SHORT* LPSHORT;static VOID QuantAudioData(LPVOID lpBuffer, LPLONG lpData, UINT nCount){    LPSHORT lpwBuffer;    LPBYTE lpbBuffer;    LONG dwSample;    if (Synth.wFormat & AUDIO_FORMAT_16BITS) {	lpwBuffer = (LPSHORT) lpBuffer;	while (nCount-- > 0) {	    dwSample = *lpData++;	    if (dwSample < -32768)		dwSample = -32768;	    else if (dwSample > +32767)		dwSample = +32767;	    *lpwBuffer++ = (SHORT) dwSample;	}    }    else {	lpbBuffer = (LPBYTE) lpBuffer;	while (nCount-- > 0) {	    dwSample = *lpData++;	    if (dwSample < -32768)		dwSample = -32768;	    else if (dwSample > +32767)		dwSample = +32767;	    *lpbBuffer++ = (BYTE) ((dwSample >> 8) + 128);	}    }}static VOID AIAPIMixAudioData08M(LPLONG lpBuffer, UINT nCount, LPVOICE lpVoice){    register UINT count;    register DWORD accum, delta;    register LPLONG table, buf;    register LPBYTE data;    accum = lpVoice->dwAccum;    delta = lpVoice->dwFrequency;    table = lpVolumeTable + ((UINT) lpVoice->nVolume << 8);    data = lpVoice->lpData;    buf = lpBuffer;    count = nCount;    do {	*buf++ += table[data[accum >> ACCURACY]];	accum += delta;    } while (--count != 0);    lpVoice->dwAccum = accum;}#define min(a, b) ((a) < (b) ? (a) : (b))static VOID AIAPIMixAudioData08S(LPLONG lpBuffer, UINT nCount, LPVOICE lpVoice){    register UINT a;    register DWORD accum, delta;    register LPLONG ltable, rtable, buf;    register LPBYTE data;    accum = lpVoice->dwAccum;    delta = lpVoice->dwFrequency;    a = ((UINT) lpVoice->nVolume * lpVoice->nPanning) >> 8;    rtable = lpVolumeTable + (a << 8);    ltable = lpVolumeTable + ((lpVoice->nVolume - a) << 8);    data = lpVoice->lpData;    buf = lpBuffer;    do {	a = data[accum >> ACCURACY];	buf[0] += ltable[a];	buf[1] += rtable[a];	accum += delta;	buf += 2;    } while (--nCount != 0);    lpVoice->dwAccum = accum;}static VOID AIAPIMixAudioData08MI(LPLONG lpBuffer, UINT nCount, LPVOICE lpVoice){    register INT a, frac;    register DWORD accum, delta;    register LPLONG table, buf;    register LPBYTE data, ftable;    /* adaptive oversampling interpolation comparison */    if (lpVoice->dwFrequency < -(1 << ACCURACY) ||	lpVoice->dwFrequency > +(1 << ACCURACY)) {	MixAudioData08M(lpBuffer, nCount, lpVoice);	return;    }    accum = lpVoice->dwAccum;    delta = lpVoice->dwFrequency;    table = lpVolumeTable + ((UINT) lpVoice->nVolume << 8);    data = lpVoice->lpData;    buf = lpBuffer;#ifdef __FILTER__    a = (BYTE) lpVoice->bReserved;    frac = ((long) delta < 0 ? -delta : +delta) >> (ACCURACY - 5);    ftable = lpFilterTable + (frac << 8);    do {	a = (BYTE)(a + ftable[data[accum >> ACCURACY]] - ftable[a]);	*buf++ += table[a];	accum += delta;    } while (--nCount != 0);    lpVoice->bReserved = (BYTE) a;#else    do {	register INT b;	a = (signed char) data[accum >> ACCURACY];	b = (signed char) data[(accum >> ACCURACY) + 1];	frac = (accum & ((1 << ACCURACY) - 1)) >> (ACCURACY - 5);	a = (BYTE)(a + ((frac * (b - a)) >> 5));	*buf++ += table[a];	accum += delta;    } while (--nCount != 0);#endif    lpVoice->dwAccum = accum;}static VOID AIAPIMixAudioData08SI(LPLONG lpBuffer, UINT nCount, LPVOICE lpVoice){    register INT a, frac;    register DWORD accum, delta;    register LPLONG buf, ltable, rtable;    register LPBYTE data, ftable;    /* adaptive oversampling interpolation comparison */    if (lpVoice->dwFrequency < -(1 << ACCURACY) ||	lpVoice->dwFrequency > +(1 << ACCURACY)) {	MixAudioData08S(lpBuffer, nCount, lpVoice);	return;    }    accum = lpVoice->dwAccum;    delta = lpVoice->dwFrequency;    a = ((UINT) lpVoice->nVolume * lpVoice->nPanning) >> 8;    rtable = lpVolumeTable + (a << 8);    ltable = lpVolumeTable + ((lpVoice->nVolume - a) << 8);    data = lpVoice->lpData;    buf = lpBuffer;#ifdef __FILTER__    a = (BYTE) lpVoice->bReserved;    frac = ((long) delta < 0 ? -delta : +delta) >> (ACCURACY - 5);    ftable = lpFilterTable + (frac << 8);    do {	a = (BYTE)(a + ftable[data[accum >> ACCURACY]] - ftable[a]);	buf[0] += ltable[a];	buf[1] += rtable[a];	accum += delta;	buf += 2;    } while (--nCount != 0);    lpVoice->bReserved = (BYTE) a;#else    do {	register INT b;	a = (signed char) data[accum >> ACCURACY];	b = (signed char) data[(accum >> ACCURACY) + 1];	frac = (accum & ((1 << ACCURACY) - 1)) >> (ACCURACY - 5);	a = (BYTE)(a + ((frac * (b - a)) >> 5));	buf[0] += ltable[a];	buf[1] += rtable[a];	accum += delta;	buf += 2;    } while (--nCount != 0);#endif    lpVoice->dwAccum = accum;}static VOID AIAPIMixAudioData16M(LPLONG lpBuffer, UINT nCount, LPVOICE lpVoice){    register UINT a, count;    register DWORD accum, delta;    register LPLONG table, buf;    register LPWORD data;    accum = lpVoice->dwAccum;    delta = lpVoice->dwFrequency;    table = lpVolumeTable + ((UINT) lpVoice->nVolume << 8);    data = lpVoice->lpData;    buf = lpBuffer;    count = nCount;    do {	a = data[accum >> ACCURACY];	*buf++ += table[a >> 8];	accum += delta;    } while (--count != 0);    lpVoice->dwAccum = accum;}static VOID AIAPIMixAudioData16S(LPLONG lpBuffer, UINT nCount, LPVOICE lpVoice){    register UINT a;    register DWORD accum, delta;    register LPLONG ltable, rtable, buf;    register LPWORD data;    accum = lpVoice->dwAccum;    delta = lpVoice->dwFrequency;    a = ((UINT) lpVoice->nVolume * lpVoice->nPanning) >> 8;    rtable = lpVolumeTable + (a << 8);    ltable = lpVolumeTable + ((lpVoice->nVolume - a) << 8);    data = lpVoice->lpData;    buf = lpBuffer;    do {	a = data[accum >> ACCURACY];	buf[0] += ltable[a >> 8];	buf[1] += rtable[a >> 8];	accum += delta;	buf += 2;    } while (--nCount != 0);    lpVoice->dwAccum = accum;}static VOID AIAPIMixAudioData16MI(LPLONG lpBuffer, UINT nCount, LPVOICE lpVoice){    register UINT frac, count;    register DWORD a, b, accum, delta;    register LPLONG table, buf;    register LPWORD data;    /* adaptive oversampling interpolation comparison */    if (lpVoice->dwFrequency < -(1 << ACCURACY) ||	lpVoice->dwFrequency > +(1 << ACCURACY)) {	MixAudioData16M(lpBuffer, nCount, lpVoice);	return;    }    accum = lpVoice->dwAccum;    delta = lpVoice->dwFrequency;    table = lpVolumeTable + ((UINT) lpVoice->nVolume << 8);    data = lpVoice->lpData;    buf = lpBuffer;    count = nCount;    do {	a = data[accum >> ACCURACY];	b = data[(accum >> ACCURACY) + 1];	frac = (accum & ((1 << ACCURACY) - 1)) >> (ACCURACY - 5);	a = (WORD)((SHORT)a + ((frac * ((SHORT)b - (SHORT)a)) >> 5));	*buf++ += table[a >> 8];	accum += delta;    } while (--count != 0);    lpVoice->dwAccum = accum;}static VOID AIAPIMixAudioData16SI(LPLONG lpBuffer, UINT nCount, LPVOICE lpVoice){    register UINT frac;    register DWORD a, b, accum, delta;    register LPLONG ltable, rtable, buf;    register LPWORD data;    /* adaptive oversampling interpolation comparison */    if (lpVoice->dwFrequency < -(1 << ACCURACY) ||	lpVoice->dwFrequency > +(1 << ACCURACY)) {	MixAudioData16S(lpBuffer, nCount, lpVoice);	return;    }    accum = lpVoice->dwAccum;    delta = lpVoice->dwFrequency;    a = ((UINT) lpVoice->nVolume * lpVoice->nPanning) >> 8;    rtable = lpVolumeTable + (a << 8);    ltable = lpVolumeTable + ((lpVoice->nVolume - a) << 8);    data = lpVoice->lpData;    buf = lpBuffer;    do {	a = data[accum >> ACCURACY];	b = data[(accum >> ACCURACY) + 1];	frac = (accum & ((1 << ACCURACY) - 1)) >> (ACCURACY - 5);	a = (WORD)((SHORT)a + ((frac * ((int)(SHORT)b - (int)(SHORT)a)) >> 5));	buf[0] += ltable[a >> 8];	buf[1] += rtable[a >> 8];	accum += delta;	buf += 2;    } while (--nCount != 0);    lpVoice->dwAccum = accum;}#endifstatic VOID MixAudioData(LPLONG lpBuffer, UINT nCount, LPVOICE lpVoice){    UINT nSize;    if (Synth.wFormat & AUDIO_FORMAT_STEREO)	nCount >>= 1;    while (nCount > 0 && !(lpVoice->bControl & VOICE_STOP)) {	/* check boundary conditions */	if (lpVoice->bControl & VOICE_REVERSE) {	    if (lpVoice->dwAccum < lpVoice->dwLoopStart) {		if (lpVoice->bControl & VOICE_BIDILOOP) {		    lpVoice->dwAccum = lpVoice->dwLoopStart +			(lpVoice->dwLoopStart - lpVoice->dwAccum);		    lpVoice->bControl ^= VOICE_REVERSE;		    continue;		}		else if (lpVoice->bControl & VOICE_LOOP) {		    lpVoice->dwAccum = lpVoice->dwLoopEnd -			(lpVoice->dwLoopStart - lpVoice->dwAccum);		    continue;		}		else {		    lpVoice->bControl |= VOICE_STOP;		    break;		}	    }	}	else {	    if (lpVoice->dwAccum > lpVoice->dwLoopEnd) {		if (lpVoice->bControl & VOICE_BIDILOOP) {		    lpVoice->dwAccum = lpVoice->dwLoopEnd -			(lpVoice->dwAccum - lpVoice->dwLoopEnd);		    lpVoice->bControl ^= VOICE_REVERSE;		    continue;		}		else if (lpVoice->bControl & VOICE_LOOP) {		    lpVoice->dwAccum = lpVoice->dwLoopStart +			(lpVoice->dwAccum - lpVoice->dwLoopEnd);		    continue;

⌨️ 快捷键说明

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