New interpolating mixer routines
Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1909
This commit is contained in:
parent
27a331e73d
commit
7bbec56bed
6 changed files with 76 additions and 66 deletions
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -684,7 +684,6 @@ protected:
|
|||
double f1, f2;
|
||||
Bitu len,pos;
|
||||
char str[256];
|
||||
MIXER_Channel * chan;
|
||||
} dial;
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue