PCM DAC: wave interpolation
This commit is contained in:
parent
d7a3cc3049
commit
00108a04f5
|
@ -42,12 +42,65 @@ void DivPlatformPCMDAC::acquire(short** buf, size_t len) {
|
||||||
while (chan[0].audSub>=0x10000) {
|
while (chan[0].audSub>=0x10000) {
|
||||||
chan[0].audSub-=0x10000;
|
chan[0].audSub-=0x10000;
|
||||||
chan[0].audPos+=((!chan[0].useWave) && chan[0].audDir)?-1:1;
|
chan[0].audPos+=((!chan[0].useWave) && chan[0].audDir)?-1:1;
|
||||||
}
|
|
||||||
if (chan[0].audPos>=(int)chan[0].audLen) {
|
if (chan[0].audPos>=(int)chan[0].audLen) {
|
||||||
chan[0].audPos%=chan[0].audLen;
|
chan[0].audPos%=chan[0].audLen;
|
||||||
chan[0].audDir=false;
|
chan[0].audDir=false;
|
||||||
}
|
}
|
||||||
output=(chan[0].ws.output[chan[0].audPos]-0x80)<<8;
|
chan[0].audDat[0]=chan[0].audDat[1];
|
||||||
|
chan[0].audDat[1]=chan[0].audDat[2];
|
||||||
|
chan[0].audDat[2]=chan[0].audDat[3];
|
||||||
|
chan[0].audDat[3]=chan[0].audDat[4];
|
||||||
|
chan[0].audDat[4]=chan[0].audDat[5];
|
||||||
|
chan[0].audDat[5]=chan[0].audDat[6];
|
||||||
|
chan[0].audDat[6]=chan[0].audDat[7];
|
||||||
|
chan[0].audDat[7]=(chan[0].ws.output[chan[0].audPos]-0x80)<<8;
|
||||||
|
}
|
||||||
|
|
||||||
|
const short s0=chan[0].audDat[0];
|
||||||
|
const short s1=chan[0].audDat[1];
|
||||||
|
const short s2=chan[0].audDat[2];
|
||||||
|
const short s3=chan[0].audDat[3];
|
||||||
|
const short s4=chan[0].audDat[4];
|
||||||
|
const short s5=chan[0].audDat[5];
|
||||||
|
const short s6=chan[0].audDat[6];
|
||||||
|
const short s7=chan[0].audDat[7];
|
||||||
|
|
||||||
|
switch (interp) {
|
||||||
|
case 1: // linear
|
||||||
|
output=s6+((s7-s6)*(chan[0].audSub&0xffff)>>16);
|
||||||
|
break;
|
||||||
|
case 2: { // cubic
|
||||||
|
float* cubicTable=DivFilterTables::getCubicTable();
|
||||||
|
float* t=&cubicTable[((chan[0].audSub&0xffff)>>6)<<2];
|
||||||
|
float result=(float)s4*t[0]+(float)s5*t[1]+(float)s6*t[2]+(float)s7*t[3];
|
||||||
|
if (result<-32768) result=-32768;
|
||||||
|
if (result>32767) result=32767;
|
||||||
|
output=result;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 3: { // sinc
|
||||||
|
float* sincTable=DivFilterTables::getSincTable8();
|
||||||
|
float* t1=&sincTable[(8191-((chan[0].audSub&0xffff)>>3))<<2];
|
||||||
|
float* t2=&sincTable[((chan[0].audSub&0xffff)>>3)<<2];
|
||||||
|
float result=(
|
||||||
|
s0*t2[3]+
|
||||||
|
s1*t2[2]+
|
||||||
|
s2*t2[1]+
|
||||||
|
s3*t2[0]+
|
||||||
|
s4*t1[0]+
|
||||||
|
s5*t1[1]+
|
||||||
|
s6*t1[2]+
|
||||||
|
s7*t1[3]
|
||||||
|
);
|
||||||
|
if (result<-32768) result=-32768;
|
||||||
|
if (result>32767) result=32767;
|
||||||
|
output=result;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: // none
|
||||||
|
output=s7;
|
||||||
|
break;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
DivSample* s=parent->getSample(chan[0].sample);
|
DivSample* s=parent->getSample(chan[0].sample);
|
||||||
if (s->samples>0) {
|
if (s->samples>0) {
|
||||||
|
|
Loading…
Reference in New Issue