1
0
Fork 0

New interpolating mixer routines

Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1909
This commit is contained in:
Sjoerd van der Berg 2004-08-23 08:11:58 +00:00
parent 27a331e73d
commit 7bbec56bed
6 changed files with 76 additions and 66 deletions

View file

@ -86,7 +86,7 @@ namespace THEOPL3 {
static struct {
bool active;
OPL_Mode mode;
MIXER_Channel * chan;
MixerChannel * chan;
Bit32u last_used;
Bit16s mixbuf[2][128];
struct {
@ -103,30 +103,30 @@ static struct {
} raw;
} opl;
static void OPL_CallBack(Bit8u *stream, Bit32u len) {
static void OPL_CallBack(Bitu len) {
/* Check for size to update and check for 1 ms updates to the opl registers */
/* Calculate teh machine ms we are at now */
/* update 1 ms of data */
Bitu i;
switch(opl.mode) {
case OPL_opl2:
OPL2::YM3812UpdateOne(0,(OPL2::INT16 *)stream,len);
OPL2::YM3812UpdateOne(0,(OPL2::INT16 *)MixTemp,len);
opl.chan->AddSamples_m16(len,(Bit16s*)MixTemp);
break;
case OPL_opl3:
THEOPL3::YMF262UpdateOne(0,(OPL2::INT16 *)stream,len);
THEOPL3::YMF262UpdateOne(0,(OPL2::INT16 *)MixTemp,len);
opl.chan->AddSamples_s16(len,(Bit16s*)MixTemp);
break;
case OPL_dualopl2:
OPL2::YM3812UpdateOne(0,(OPL2::INT16 *)opl.mixbuf[0],len);
OPL2::YM3812UpdateOne(1,(OPL2::INT16 *)opl.mixbuf[1],len);
for (i=0;i<len;i++) {
((Bit16u *)stream)[i*2+0]=opl.mixbuf[0][i];
((Bit16u *)stream)[i*2+1]=opl.mixbuf[1][i];
((Bit16s*)MixTemp)[i*2+0]=opl.mixbuf[0][i];
((Bit16s*)MixTemp)[i*2+1]=opl.mixbuf[1][i];
}
opl.chan->AddSamples_s16(len,(Bit16s*)MixTemp);
break;
}
if ((PIC_Ticks-opl.last_used)>5000) {
MIXER_Enable(opl.chan,false);
opl.chan->Enable(false);
opl.active=false;
}
}
@ -149,7 +149,7 @@ void OPL_Write(Bitu port,Bitu val,Bitu iolen) {
opl.last_used=PIC_Ticks;
if (!opl.active) {
opl.active=true;
MIXER_Enable(opl.chan,true);
opl.chan->Enable(true);
}
port&=3;
if (port&1) {
@ -324,8 +324,6 @@ void OPL_Init(Section* sec,Bitu base,OPL_Mode oplmode,Bitu rate) {
opl.mode=oplmode;
memset(&opl.raw,0,sizeof(opl.raw));
opl.chan=MIXER_AddChannel(OPL_CallBack,rate,"FM");
MIXER_SetMode(opl.chan,(opl.mode>OPL_opl2) ? MIXER_16STEREO : MIXER_16MONO);
MIXER_Enable(opl.chan,false);
MAPPER_AddHandler(OPL_SaveRawEvent,MK_f7,MMOD1|MMOD2,"caprawopl","Cap OPL");
sec->AddDestroyFunction(&OPL_Stop);
};

View file

@ -22,9 +22,6 @@
#include "mixer.h"
#include "pic.h"
#include "setup.h"
#include "programs.h"
#define DISNEY_BASE 0x0378
@ -35,11 +32,15 @@ static struct {
Bit8u status;
Bit8u control;
Bit8u buffer[DISNEY_SIZE];
Bitu used;
MIXER_Channel * chan;
Bitu used;Bitu last_used;
MixerChannel * chan;
} disney;
static void disney_write(Bitu port,Bitu val,Bitu iolen) {
if (!disney.last_used) {
disney.chan->Enable(true);
}
disney.last_used=PIC_Ticks;
switch (port-DISNEY_BASE) {
case 0: /* Data Port */
disney.data=val;
@ -80,18 +81,21 @@ static Bitu disney_read(Bitu port,Bitu iolen) {
}
static void DISNEY_CallBack(Bit8u * stream,Bit32u len) {
static void DISNEY_CallBack(Bitu len) {
if (!len) return;
if (disney.used>len) {
memcpy(stream,disney.buffer,len);
disney.chan->AddSamples_m8(len,disney.buffer);
memmove(disney.buffer,&disney.buffer[len],disney.used-len);
disney.used-=len;
return;
} else {
memcpy(stream,disney.buffer,disney.used);
memset(stream+disney.used,0x80,len-disney.used);
disney.chan->AddSamples_m8(disney.used,disney.buffer);
disney.chan->AddSilence();
disney.used=0;
}
if (disney.last_used+5000<PIC_Ticks) {
disney.last_used=0;
disney.chan->Enable(false);
}
}
@ -104,11 +108,10 @@ void DISNEY_Init(Section* sec) {
IO_RegisterReadHandler(DISNEY_BASE,disney_read,IO_MB,3);
disney.chan=MIXER_AddChannel(&DISNEY_CallBack,7000,"DISNEY");
MIXER_SetMode(disney.chan,MIXER_8MONO);
MIXER_Enable(disney.chan,true);
disney.status=0x84;
disney.control=0;
disney.used=0;
disney.last_used=0;
}

View file

@ -131,7 +131,7 @@ static int amplitude_lookup[16] = {
/* global parameters */
static double sample_rate;
static SAA1099 saa1099[2];
static MIXER_Channel * cms_chan;
static MixerChannel * cms_chan;
static Bit16s cms_buffer[2][2][CMS_BUFFER_SIZE];
static Bit16s * cms_buf_point[4] = {
cms_buffer[0][0],cms_buffer[0][1],cms_buffer[1][0],cms_buffer[1][1] };
@ -364,7 +364,7 @@ static void saa1099_write_port_w( int chip, int offset, int data )
static void write_cms(Bitu port,Bitu val,Bitu iolen) {
if (last_command + 100 < PIC_Ticks) MIXER_Enable(cms_chan,true);
if (last_command + 1000 < PIC_Ticks) cms_chan->Enable(true);
last_command = PIC_Ticks;
switch (port) {
case 0x0220:
@ -390,32 +390,33 @@ static void write_cms(Bitu port,Bitu val,Bitu iolen) {
}
break;
}
if (last_command > PIC_Ticks+1000) MIXER_Enable(cms_chan,true);
}
static void CMS_CallBack(Bit8u * stream,Bit32u len) {
static void CMS_CallBack(Bitu len) {
if (len > CMS_BUFFER_SIZE) return;
saa1099_update(0, &cms_buf_point[0], (int)len);
saa1099_update(1, &cms_buf_point[2], (int)len);
Bit16s * stream=(Bit16s *) MixTemp;
/* Mix chip outputs */
for (Bitu l=0;l<len;l++) {
register Bits left, right;
left = cms_buffer[0][LEFT][l] + cms_buffer[1][LEFT][l];
right = cms_buffer[0][RIGHT][l] + cms_buffer[1][RIGHT][l];
if (left>MAX_AUDIO) *(Bit16s *)stream=MAX_AUDIO;
else if (left<MIN_AUDIO) *(Bit16s *)stream=MIN_AUDIO;
else *(Bit16s *)stream=(Bit16s)left;
stream+=2;
if (left>MAX_AUDIO) *stream=MAX_AUDIO;
else if (left<MIN_AUDIO) *stream=MIN_AUDIO;
else *stream=(Bit16s)left;
stream++;
if (right>MAX_AUDIO) *(Bit16s *)stream=MAX_AUDIO;
else if (right<MIN_AUDIO) *(Bit16s *)stream=MIN_AUDIO;
else *(Bit16s *)stream=(Bit16s)right;
stream+=2;
if (right>MAX_AUDIO) *stream=MAX_AUDIO;
else if (right<MIN_AUDIO) *stream=MIN_AUDIO;
else *stream=(Bit16s)right;
stream++;
}
if (last_command + 5000 < PIC_Ticks) MIXER_Enable(cms_chan,false);
cms_chan->AddSamples_s16(len,(Bit16s *)MixTemp);
if (last_command + 10000 < PIC_Ticks) cms_chan->Enable(false);
}
@ -428,8 +429,6 @@ static void write_cms(Bitu port,Bitu val,Bitu iolen) {
/* Register the Mixer CallBack */
cms_chan=MIXER_AddChannel(CMS_CallBack,rate,"CMS");
MIXER_SetMode(cms_chan,MIXER_16STEREO);
MIXER_Enable(cms_chan,true);
last_command=PIC_Ticks;
for (int s=0;s<2;s++) {

View file

@ -45,7 +45,7 @@
#define LOG_GUS
Bit8u adlib_commandreg;
static MIXER_Channel * gus_chan;
static MixerChannel * gus_chan;
static Bit8u irqtable[8] = { 0, 2, 5, 3, 7, 11, 12, 15 };
static Bit8u dmatable[8] = { 0, 1, 3, 5, 6, 7, 0, 0 };
static Bit8u GUSRam[1024*1024]; // 1024K of GUS Ram
@ -558,7 +558,7 @@ static void ExecuteGlobRegister(void) {
if(myGUS.ActiveChannels < 14) myGUS.ActiveChannels = 14;
if(myGUS.ActiveChannels > 32) myGUS.ActiveChannels = 32;
myGUS.ActiveMask=0xffffffffU >> (32-myGUS.ActiveChannels);
MIXER_Enable(gus_chan,true);
gus_chan->Enable(true);
myGUS.basefreq = (Bit32u)((float)1000000/(1.619695497*(float)(myGUS.ActiveChannels)));
LOG_GUS("GUS set to %d channels", myGUS.ActiveChannels);
for (i=0;i<myGUS.ActiveChannels;i++) guschan[i]->UpdateWaveRamp();
@ -752,15 +752,15 @@ static void GUS_DMA_Callback(DmaChannel * chan,DMAEvent event) {
chan->Register_Callback(0);
}
static void GUS_CallBack(Bit8u * stream,Bit32u len) {
Bit32s buffer[4096];
memset(&buffer[0],0,len*8);
static void GUS_CallBack(Bitu len) {
memset(&MixTemp,0,len*8);
Bitu i;
Bit16s * buf16 = (Bit16s *)MixTemp;
Bit32s * buf32 = (Bit32s *)MixTemp;
for(i=0;i<myGUS.ActiveChannels;i++)
guschan[i]->generateSamples(&buffer[0],len);
Bit16s * bufptr = (Bit16s *)stream;
guschan[i]->generateSamples(buf32,len);
for(i=0;i<len*2;i++) {
Bit32s sample=((buffer[i] >> 13)*AutoAmp)>>9;
Bit32s sample=((buf32[i] >> 13)*AutoAmp)>>9;
if (sample>32767) {
sample=32767;
AutoAmp--;
@ -768,8 +768,9 @@ static void GUS_CallBack(Bit8u * stream,Bit32u len) {
sample=-32768;
AutoAmp--;
}
bufptr[i] = (Bit16s)(sample);
buf16[i] = (Bit16s)(sample);
}
gus_chan->AddSamples_s16(len,buf16);
CheckVoiceIrq();
}
@ -848,8 +849,6 @@ void GUS_Init(Section* sec) {
}
// Register the Mixer CallBack
gus_chan=MIXER_AddChannel(GUS_CallBack,GUS_RATE,"GUS");
MIXER_SetMode(gus_chan,MIXER_16STEREO);
MIXER_Enable(gus_chan,false);
myGUS.gRegData=0x1;
GUSReset();
myGUS.gRegData=0x0;

View file

@ -684,7 +684,6 @@ protected:
double f1, f2;
Bitu len,pos;
char str[256];
MIXER_Channel * chan;
} dial;
};

View file

@ -28,6 +28,7 @@
#include "setup.h"
#include "pic.h"
#define DAC_CLOCK 3570000
#define MAX_OUTPUT 0x7fff
#define STEP 0x10000
@ -70,20 +71,22 @@ struct SN76496
static struct SN76496 sn;
static struct {
MIXER_Channel * chan;
MixerChannel * chan;
bool enabled;
Bitu last_write;
struct {
bool playing;
Bitu rate;
} dac;
} tandy;
static void SN76496Write(Bitu port,Bitu data,Bitu iolen)
{
static void SN76496Write(Bitu port,Bitu data,Bitu iolen) {
struct SN76496 *R = &sn;
tandy.last_write=PIC_Ticks;
if (!tandy.enabled) {
MIXER_Enable(tandy.chan,true);
tandy.chan->Enable(true);
tandy.enabled=true;
}
@ -155,15 +158,15 @@ static void SN76496Write(Bitu port,Bitu data,Bitu iolen)
}
}
static void SN76496Update(Bit8u * stream,Bit32u length)
static void SN76496Update(Bitu length)
{
if ((tandy.last_write+1000)<PIC_Ticks) {
if ((tandy.last_write+5000)<PIC_Ticks) {
tandy.enabled=false;
MIXER_Enable(tandy.chan,false);
tandy.chan->Enable(false);
}
int i;
struct SN76496 *R = &sn;
Bit16s * buffer=(Bit16s *)stream;
Bit16s * buffer=(Bit16s *)MixTemp;
/* If the volume is 0, increase the counter */
for (i = 0;i < 4;i++)
@ -177,7 +180,8 @@ static void SN76496Update(Bit8u * stream,Bit32u length)
}
}
while (length > 0)
Bitu count=length;
while (count)
{
int vol[4];
unsigned int out;
@ -246,8 +250,9 @@ static void SN76496Update(Bit8u * stream,Bit32u length)
*(buffer++) = out / STEP;
length--;
count--;
}
tandy.chan->AddSamples_m16(length,(Bit16s *)MixTemp);
}
@ -267,6 +272,12 @@ static void SN76496_set_clock(int clock)
}
static void TandyDACWrite(Bitu port,Bitu data,Bitu iolen) {
LOG_MSG("Write tandy dac %X val %X",port,data);
}
static void SN76496_set_gain(int gain)
{
@ -298,17 +309,18 @@ static void SN76496_set_gain(int gain)
void TANDYSOUND_Init(Section* sec) {
if (machine!=MCH_TANDY) return;
Section_prop * section=static_cast<Section_prop *>(sec);
if(!section->Get_bool("tandy")) return;
IO_RegisterWriteHandler(0xc0,SN76496Write,IO_MB);
IO_RegisterWriteHandler(0xc0,SN76496Write,IO_MB,2);
IO_RegisterWriteHandler(0xc4,TandyDACWrite,IO_MB,4);
Bit32u sample_rate = section->Get_int("tandyrate");
tandy.chan=MIXER_AddChannel(&SN76496Update,sample_rate,"TANDY");
MIXER_Enable(tandy.chan,false);
tandy.enabled=false;
MIXER_SetMode(tandy.chan,MIXER_16MONO);
Bitu i;
struct SN76496 *R = &sn;