|
Sound Playback Using Auto Init DMA Mode Example 6 |
Mission : The ultimate way to achieve flawless playback! Let's make some very minor
changes to our SB16 class to be able to utilize this mode!
Download the Expansion Pack!
Introvoid SetupAutoInitDSP(); void Auto8Mono(); void Old8Mono(); void Auto8Stereo(); void Auto16Mono(); void Auto16Stereo(); void FillHalfBuffer(); void MemMove(unsigned char*, unsigned char*,unsigned int); char SideToFill; |
void SB16::SetupDMA()
{...
if(TransferMode==1)
{dma.SetControlByteMask(DemandMode,AddressIncrement,SingleCycle,WriteTransfer);
//Put into 8-bit SingleCycle mode
}
else
{dma.SetControlByteMask(DemandMode,AddressIncrement,AutoInit,WriteTransfer);
//Put into 8-bit AutoInit mode
TransferLength=HALFBUFFSIZE;
}
...
} |
void SB16::SetupDSP()
{ if(TransferMode==1)
{SetupSingleCycleDSP();
}
else
{ SetupAutoInitDSP();
}
} |
void SB16::SetupAutoInitDSP()
{if(ModeBits==8)
{ if(!ModeStereoMono)
{ Auto8Mono(); //8 bit Mono
}
else
{ Auto8Stereo(); //8 bit Stereo
}
}
else
{ if(!ModeStereoMono)
{ Auto16Mono(); //16 bit Mono
}
else
{ Auto16Stereo();//16 bit Stereo
}
}
} |
void SB16::Auto8Mono()
{ if(DSPVersionNum <4.0)
{Old8Mono();
}
SendFrequency();
WriteDSP(0xC6);
WriteDSP(0x00);
SendLength();
}
void SB16::Old8Mono()
{ WriteDSP(DSP_TIME_CONSTANT);
WriteDSP(HiByte(OldTimeConstant()));//use only high byte
WriteDSP(0x48);
SendLength();
WriteDSP(0x1C);
}
void SB16::Auto8Stereo()
{ SendFrequency();
WriteDSP(0xC6);
WriteDSP(0x20);
SendLength();
}
void SB16::Auto16Mono()
{ SendFrequency();
WriteDSP(0xB6);
WriteDSP(0x00);
SendLength();
}
void SB16::Auto16Stereo()
{ SendFrequency();
WriteDSP(0xB6);
WriteDSP(0x20);
SendLength();
} |
void SB16::ServiceISR()
{disable();
if(TransferMode==1) //SS
{ ServiceSC();
}
else //AI
{ ServiceAI();
}
enable();
outp(0x20,0x20); //eoi command to PIC
} |
void SB16::ServiceAI()
{ if(ModeBits == 8)
{ inp(DSPStatus);
}
else
{ outp(MixerAddr,0x82);
short temp=0;
temp=inp(MixerData);
if(temp & 2)
{ inp(DSPIntAck);
}
}
FillHalfBuffer();
} |
void SB16::FillHalfBuffer()
{ unsigned char *d=(unsigned char*)dma.MK_FP(dma.phys>>4,0);
unsigned char *s = Sounds[0].Sound;
SideToFill^=1;
if(SideToFill)
{d+=HALFBUFFSIZE;
}
if(!Done)
{s+=place;
if(SoundSize < HALFBUFFSIZE)
{MemMove(d,s,SoundSize);
memset((unsigned char *)d+amount,128,HALFBUFFSIZE-SoundSize);
WriteDSP(DSP_HALT_8_AUTO_INIT);
}
else
{MemMove(d,s,HALFBUFFSIZE);
SoundSize-=HALFBUFFSIZE;
place+=HALFBUFFSIZE;
}
}
} |
void SB16::MemMove(unsigned char* dest,unsigned char*source,unsigned int length)
{length/=4;// or length>>=2
asm("rep
movsl"
: : "D" (dest), "S" (source), "c" (length) : "%esi","%edi","%ecx");
} |