2010-08-09 13:28:56 +00:00
|
|
|
#ifdef DSP_CPP
|
|
|
|
|
|
|
|
void DSP::brr_decode(voice_t &v) {
|
|
|
|
//state.t_brr_byte = ram[v.brr_addr + v.brr_offset] cached from previous clock cycle
|
Update to v074r11 release.
byuu says:
Changelog:
- debugger compiles on all three profiles
- libsnes compiles on all three platforms (no API changes to libsnes)
- memory.cpp : namespace memory removed (wram -> cpu, apuram -> smp,
vram, oam, cgram -> ppu)
- sa1.cpp : namespace memory removed (SA-1 specific functions merged
inline to SA1::bus_read,write)
- GameBoy: added serial link support with interrupts and proper 8192hz
timing, but obviously it acts as if no other GB is connected to it
- GameBoy: added STAT OAM interrupt, and better STAT d1,d0 mode values
- UI: since Qt is dead, I've renamed the config files back to bsnes.cfg
and bsnes-geometry.cfg
- SA1: IRAM was not syncing to CPU on SA-1 side
- PPU/Accuracy and PPU/Performance needed Sprite oam renamed to Sprite
sprite; so that I could add uint8 oam[544]
- makes more sense anyway, OAM = object attribute memory, obj or
sprite are better names for Sprite rendering class
- more cleanup
2011-01-24 09:03:17 +00:00
|
|
|
int nybbles = (state.t_brr_byte << 8) + smp.apuram[(uint16)(v.brr_addr + v.brr_offset + 1)];
|
2010-08-09 13:28:56 +00:00
|
|
|
|
|
|
|
const int filter = (state.t_brr_header >> 2) & 3;
|
|
|
|
const int scale = (state.t_brr_header >> 4);
|
|
|
|
|
|
|
|
//decode four samples
|
|
|
|
for(unsigned i = 0; i < 4; i++) {
|
|
|
|
//bits 12-15 = current nybble; sign extend, then shift right to 4-bit precision
|
|
|
|
//result: s = 4-bit sign-extended sample value
|
|
|
|
int s = (int16)nybbles >> 12;
|
|
|
|
nybbles <<= 4; //slide nybble so that on next loop iteration, bits 12-15 = current nybble
|
|
|
|
|
|
|
|
if(scale <= 12) {
|
|
|
|
s <<= scale;
|
|
|
|
s >>= 1;
|
|
|
|
} else {
|
|
|
|
s &= ~0x7ff;
|
|
|
|
}
|
|
|
|
|
|
|
|
//apply IIR filter (2 is the most commonly used)
|
|
|
|
const int p1 = v.buffer[v.buf_pos - 1];
|
|
|
|
const int p2 = v.buffer[v.buf_pos - 2] >> 1;
|
|
|
|
|
|
|
|
switch(filter) {
|
|
|
|
case 0: break; //no filter
|
|
|
|
|
|
|
|
case 1: {
|
|
|
|
//s += p1 * 0.46875
|
|
|
|
s += p1 >> 1;
|
|
|
|
s += (-p1) >> 5;
|
|
|
|
} break;
|
|
|
|
|
|
|
|
case 2: {
|
|
|
|
//s += p1 * 0.953125 - p2 * 0.46875
|
|
|
|
s += p1;
|
|
|
|
s -= p2;
|
|
|
|
s += p2 >> 4;
|
|
|
|
s += (p1 * -3) >> 6;
|
|
|
|
} break;
|
|
|
|
|
|
|
|
case 3: {
|
|
|
|
//s += p1 * 0.8984375 - p2 * 0.40625
|
|
|
|
s += p1;
|
|
|
|
s -= p2;
|
|
|
|
s += (p1 * -13) >> 7;
|
|
|
|
s += (p2 * 3) >> 4;
|
|
|
|
} break;
|
|
|
|
}
|
|
|
|
|
|
|
|
//adjust and write sample
|
|
|
|
s = sclamp<16>(s);
|
|
|
|
s = (int16)(s << 1);
|
|
|
|
v.buffer.write(v.buf_pos++, s);
|
|
|
|
if(v.buf_pos >= brr_buf_size) v.buf_pos = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|