| 189 | } |
| 190 | |
| 191 | static __forceinline void DecodeSamples(uint coreidx, uint voiceidx) |
| 192 | { |
| 193 | V_Core& thiscore(Cores[coreidx]); |
| 194 | V_Voice& vc(thiscore.Voices[voiceidx]); |
| 195 | |
| 196 | // Update the block header on every audio frame |
| 197 | UpdateBlockHeader(thiscore, voiceidx); |
| 198 | |
| 199 | // When a voice is started at 0 pitch, NAX quickly advances to SSA + 5 |
| 200 | // So that would mean the decode buffer holds around 12 samples |
| 201 | if (((int)(vc.DecPosWrite - vc.DecPosRead)) > 12) { |
| 202 | // Sufficient data buffered |
| 203 | return; |
| 204 | } |
| 205 | |
| 206 | if (vc.ADSR.Phase > V_ADSR::PHASE_STOPPED) |
| 207 | { |
| 208 | GetNextDataBuffered(thiscore, voiceidx); |
| 209 | } |
| 210 | |
| 211 | vc.DecPosWrite += 4; |
| 212 | |
| 213 | IncrementNextA(thiscore, voiceidx); |
| 214 | if ((vc.NextA & 7) == 0) |
| 215 | { |
| 216 | if (vc.LoopFlags & XAFLAG_LOOP_END) |
| 217 | { |
| 218 | thiscore.Regs.ENDX |= (1 << voiceidx); |
| 219 | vc.NextA = vc.LoopStartA; |
| 220 | if (!(vc.LoopFlags & XAFLAG_LOOP)) |
| 221 | { |
| 222 | vc.Stop(); |
| 223 | |
| 224 | if (IsDevBuild) |
| 225 | { |
| 226 | if (SPU2::MsgVoiceOff()) |
| 227 | SPU2::ConLog("* SPU2: Voice Off by EndPoint: %d \n", voiceidx); |
| 228 | } |
| 229 | } |
| 230 | } |
| 231 | |
| 232 | IncrementNextA(thiscore, voiceidx); |
| 233 | vc.SBuffer = nullptr; |
| 234 | } |
| 235 | } |
| 236 | |
| 237 | static void __forceinline UpdatePitch(uint coreidx, uint voiceidx) |
| 238 | { |
no test coverage detected