void SPU_struct::KeyOn(int channel) { channel_struct &thischan = channels[channel]; thischan.status = CHANSTAT_PLAY; thischan.totlength = thischan.length + thischan.loopstart; adjust_channel_timer(&thischan); //LOG("Channel %d key on: vol = %d, datashift = %d, hold = %d, pan = %d, waveduty = %d, repeat = %d, format = %d, source address = %07X," // "timer = %04X, loop start = %04X, length = %06X, MMU.ARM7_REG[0x501] = %02X\n", channel, chan->vol, chan->datashift, chan->hold, // chan->pan, chan->waveduty, chan->repeat, chan->format, chan->addr, chan->timer, chan->loopstart, chan->length, T1ReadByte(MMU.ARM7_REG, 0x501)); switch(thischan.format) { case 0: // 8-bit thischan.buf8 = (s8*)&MMU.MMU_MEM[1][(thischan.addr>>20)&0xFF][(thischan.addr & MMU.MMU_MASK[1][(thischan.addr >> 20) & 0xFF])]; // thischan.loopstart = thischan.loopstart << 2; // thischan.length = (thischan.length << 2) + thischan.loopstart; thischan.sampcnt = -3; break; case 1: // 16-bit thischan.buf16 = (s16 *)&MMU.MMU_MEM[1][(thischan.addr>>20)&0xFF][(thischan.addr & MMU.MMU_MASK[1][(thischan.addr >> 20) & 0xFF])]; // thischan.loopstart = thischan.loopstart << 1; // thischan.length = (thischan.length << 1) + thischan.loopstart; thischan.sampcnt = -3; break; case 2: // ADPCM { thischan.buf8 = (s8*)&MMU.MMU_MEM[1][(thischan.addr>>20)&0xFF][(thischan.addr & MMU.MMU_MASK[1][(thischan.addr >> 20) & 0xFF])]; thischan.pcm16b = (s16)((thischan.buf8[1] << 8) | thischan.buf8[0]); thischan.pcm16b_last = thischan.pcm16b; thischan.index = thischan.buf8[2] & 0x7F; thischan.lastsampcnt = 7; thischan.sampcnt = -3; thischan.loop_index = K_ADPCM_LOOPING_RECOVERY_INDEX; // thischan.loopstart = thischan.loopstart << 3; // thischan.length = (thischan.length << 3) + thischan.loopstart; break; } case 3: // PSG { thischan.sampcnt = -1; thischan.x = 0x7FFF; break; } default: break; } thischan.double_totlength_shifted = (double)(thischan.totlength << format_shift[thischan.format]); if(thischan.format != 3) { if(thischan.double_totlength_shifted == 0) { printf("INFO: Stopping channel %d due to zero length\n",channel); thischan.status = CHANSTAT_STOPPED; } } }
void SPU_struct::KeyOn(int channel) { channel_struct &thischan = channels[channel]; thischan.init_resampler(); resampler_clear(thischan.resampler); resampler_set_quality(thischan.resampler, thischan.format == 3 ? RESAMPLER_QUALITY_BLEP : spuInterpolationMode(state)); adjust_channel_timer(&thischan); // LOG("Channel %d key on: vol = %d, datashift = %d, hold = %d, pan = %d, waveduty = %d, repeat = %d, format = %d, source address = %07X, timer = %04X, loop start = %04X, length = %06X, cpu->state->MMUARM7_REG[0x501] = %02X\n", channel, chan->vol, chan->datashift, chan->hold, chan->pan, chan->waveduty, chan->repeat, chan->format, chan->addr, chan->timer, chan->loopstart, chan->length, T1ReadByte(MMU->ARM7_REG, 0x501)); switch(thischan.format) { case 0: // 8-bit thischan.buf8 = (s8*)&state->MMU->MMU_MEM[1][(thischan.addr>>20)&0xFF][(thischan.addr & state->MMU->MMU_MASK[1][(thischan.addr >> 20) & 0xFF])]; // thischan.loopstart = thischan.loopstart << 2; // thischan.length = (thischan.length << 2) + thischan.loopstart; thischan.sampcnt = 0; break; case 1: // 16-bit thischan.buf16 = (s16 *)&state->MMU->MMU_MEM[1][(thischan.addr>>20)&0xFF][(thischan.addr & state->MMU->MMU_MASK[1][(thischan.addr >> 20) & 0xFF])]; // thischan.loopstart = thischan.loopstart << 1; // thischan.length = (thischan.length << 1) + thischan.loopstart; thischan.sampcnt = 0; break; case 2: // ADPCM { thischan.buf8 = (s8*)&state->MMU->MMU_MEM[1][(thischan.addr>>20)&0xFF][(thischan.addr & state->MMU->MMU_MASK[1][(thischan.addr >> 20) & 0xFF])]; thischan.pcm16b = (s16)((thischan.buf8[1] << 8) | thischan.buf8[0]); thischan.pcm16b_last = thischan.pcm16b; thischan.index = thischan.buf8[2] & 0x7F; thischan.lastsampcnt = 7; thischan.sampcnt = 8; thischan.loop_index = K_ADPCM_LOOPING_RECOVERY_INDEX; // thischan.loopstart = thischan.loopstart << 3; // thischan.length = (thischan.length << 3) + thischan.loopstart; break; } case 3: // PSG { thischan.x = 0x7FFF; break; } default: break; } if(thischan.format != 3) { if(thischan.double_totlength_shifted == 0) { printf("INFO: Stopping channel %d due to zero length\n",channel); thischan.status = CHANSTAT_STOPPED; } } thischan.double_totlength_shifted = (double)(thischan.totlength << format_shift[thischan.format]); }