diff options
Diffstat (limited to 'src/SPU.cpp')
-rw-r--r-- | src/SPU.cpp | 64 |
1 files changed, 50 insertions, 14 deletions
diff --git a/src/SPU.cpp b/src/SPU.cpp index b25b8d0..b36becf 100644 --- a/src/SPU.cpp +++ b/src/SPU.cpp @@ -26,7 +26,6 @@ // * capture addition modes, overflow bugs // * channel hold // * 'length less than 4' glitch -int brap = 0; namespace SPU { @@ -63,10 +62,10 @@ const s16 PSGTable[8][8] = const u32 kSamplesPerRun = 1; -const u32 OutputBufferSize = 2*2*1024; +const u32 OutputBufferSize = 2*1024; s16 OutputBuffer[2 * OutputBufferSize]; -u32 OutputReadOffset; -u32 OutputWriteOffset; +volatile u32 OutputReadOffset; +volatile u32 OutputWriteOffset; u16 Cnt; @@ -99,9 +98,7 @@ void DeInit() void Reset() { - memset(OutputBuffer, 0, 2*OutputBufferSize*2); - OutputReadOffset = 0; - OutputWriteOffset = 0;//OutputBufferSize; + InitOutput(); Cnt = 0; MasterVolume = 0; @@ -579,7 +576,7 @@ void CaptureUnit::Run(s32 sample) } } -int zog = 0, zig = 0; + void Mix(u32 samples) { s32 channelbuf[32]; @@ -629,7 +626,7 @@ void Mix(u32 samples) else if (val > 0x7FFF) val = 0x7FFF; Capture[0]->Run(val); - if (!((Capture[0]->Cnt & (1<<7)))) break; + if (!(Capture[0]->Cnt & (1<<7))) break; } } @@ -644,7 +641,7 @@ void Mix(u32 samples) else if (val > 0x7FFF) val = 0x7FFF; Capture[1]->Run(val); - if (!((Capture[1]->Cnt & (1<<7)))) break; + if (!(Capture[1]->Cnt & (1<<7))) break; } } @@ -735,22 +732,61 @@ void Mix(u32 samples) OutputWriteOffset += 2; OutputWriteOffset &= ((2*OutputBufferSize)-1); if (OutputWriteOffset == OutputReadOffset) printf("!! SOUND FIFO OVERFLOW %d\n", OutputWriteOffset>>1); - zog++; zig++; brap++; } NDS::ScheduleEvent(NDS::Event_SPU, true, 1024*kSamplesPerRun, Mix, kSamplesPerRun); } +void DrainOutput() +{ + OutputReadOffset = 0; + OutputWriteOffset = 0; +} + +void InitOutput() +{ + memset(OutputBuffer, 0, 2*OutputBufferSize*2); + OutputReadOffset = 0; + OutputWriteOffset = OutputBufferSize; +} + int GetOutputSize() { - return zog; // derp + int ret; + if (OutputWriteOffset >= OutputReadOffset) + ret = OutputWriteOffset - OutputReadOffset; + else + ret = (OutputBufferSize*2) - OutputReadOffset + OutputWriteOffset; + + ret >>= 1; + return ret; +} + +void Sync(bool wait) +{ + // sync to audio output in case the core is running too fast + // * wait=true: wait until enough audio data has been played + // * wait=false: merely skip some audio data to avoid a FIFO overflow + + const int halflimit = (OutputBufferSize / 2); + + if (wait) + { + // TODO: less CPU-intensive wait? + while (GetOutputSize() > halflimit); + } + else if (GetOutputSize() > halflimit) + { + int readpos = OutputWriteOffset - (halflimit*2); + if (readpos < 0) readpos += (OutputBufferSize*2); + + OutputReadOffset = readpos; + } } int ReadOutput(s16* data, int samples) { - printf("ReadOutput(%d): wrote=%d level=%d ReadOffset=%d WriteOffset=%d\n", samples, zog, zig, OutputReadOffset>>1, OutputWriteOffset>>1); - zog = 0; zig -= (zig<samples ? zig : samples); if (OutputReadOffset == OutputWriteOffset) return 0; |