From 7bbec56bedaab155142b3c35a0ca1502bf3ee2d6 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 23 Aug 2004 08:11:58 +0000 Subject: [PATCH] New interpolating mixer routines Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1909 --- src/hardware/adlib.cpp | 24 ++++++++++------------ src/hardware/disney.cpp | 27 +++++++++++++----------- src/hardware/gameblaster.cpp | 29 +++++++++++++------------- src/hardware/gus.cpp | 21 +++++++++---------- src/hardware/softmodem.cpp | 1 - src/hardware/tandy_sound.cpp | 40 +++++++++++++++++++++++------------- 6 files changed, 76 insertions(+), 66 deletions(-) diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index ef0e74ba..10a9d690 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -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;iAddSamples_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); }; diff --git a/src/hardware/disney.cpp b/src/hardware/disney.cpp index 70fb4453..36d36efb 100644 --- a/src/hardware/disney.cpp +++ b/src/hardware/disney.cpp @@ -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+5000Enable(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; } diff --git a/src/hardware/gameblaster.cpp b/src/hardware/gameblaster.cpp index 567be28e..5ef52c79 100644 --- a/src/hardware/gameblaster.cpp +++ b/src/hardware/gameblaster.cpp @@ -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;lMAX_AUDIO) *(Bit16s *)stream=MAX_AUDIO; - else if (leftMAX_AUDIO) *stream=MAX_AUDIO; + else if (leftMAX_AUDIO) *(Bit16s *)stream=MAX_AUDIO; - else if (rightMAX_AUDIO) *stream=MAX_AUDIO; + else if (rightAddSamples_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++) { diff --git a/src/hardware/gus.cpp b/src/hardware/gus.cpp index 2a325158..40ff9785 100644 --- a/src/hardware/gus.cpp +++ b/src/hardware/gus.cpp @@ -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;iUpdateWaveRamp(); @@ -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;igenerateSamples(&buffer[0],len); - Bit16s * bufptr = (Bit16s *)stream; + guschan[i]->generateSamples(buf32,len); for(i=0;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; diff --git a/src/hardware/softmodem.cpp b/src/hardware/softmodem.cpp index 2fcbe055..0db28141 100644 --- a/src/hardware/softmodem.cpp +++ b/src/hardware/softmodem.cpp @@ -684,7 +684,6 @@ protected: double f1, f2; Bitu len,pos; char str[256]; - MIXER_Channel * chan; } dial; }; diff --git a/src/hardware/tandy_sound.cpp b/src/hardware/tandy_sound.cpp index bad2feca..4ba44264 100644 --- a/src/hardware/tandy_sound.cpp +++ b/src/hardware/tandy_sound.cpp @@ -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)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(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;