OggVorbis_File ogg; // OggVorbis file public unsafe virtual void Decode(SoundSample sample, int sampleOffset44k, int sampleCount44k, float *dest) { if (sample.objectInfo.wFormatTag != lastFormat || sample != lastSample) { ClearDecoder(); } lastDecodeTime = soundSystemLocal.CurrentSoundTime; if (failed) { UnsafeX.InitBlock(dest, 0, sampleCount44k * sizeof(float)); return; } // samples can be decoded both from the sound thread and the main thread for shakes ISystem.EnterCriticalSection(CRITICAL_SECTION.SECTION_ONE); var readSamples44k = sample.objectInfo.wFormatTag switch { WAVE_FORMAT_TAG.PCM => DecodePCM(sample, sampleOffset44k, sampleCount44k, dest), WAVE_FORMAT_TAG.OGG => DecodeOGG(sample, sampleOffset44k, sampleCount44k, dest), _ => 0, }; ISystem.LeaveCriticalSection(CRITICAL_SECTION.SECTION_ONE); if (readSamples44k < sampleCount44k) { UnsafeX.InitBlock(dest + readSamples44k, 0, (sampleCount44k - readSamples44k) * sizeof(float)); } }
// Will always return 44kHz samples for the given range, even if it deeply looped or out of the range of the unlooped samples. Handles looping between multiple different // samples and leadins public unsafe void GatherChannelSamples(int sampleOffset44k, int sampleCount44k, float *dest) { int len; //Sys_DebugPrintf( "msec:%i sample:%i : %i : %i\n", Sys_Milliseconds(), soundSystemLocal.GetCurrent44kHzTime(), sampleOffset44k, sampleCount44k ); //!@# var destF = dest; { var dest_p = destF; // negative offset times will just zero fill if (sampleOffset44k < 0) { len = -sampleOffset44k; if (len > sampleCount44k) { len = sampleCount44k; } UnsafeX.InitBlock(dest_p, 0, len * sizeof(float)); dest_p += len; sampleCount44k -= len; sampleOffset44k += len; } // grab part of the leadin sample var leadin = leadinSample; if (leadin == null || sampleOffset44k < 0 || sampleCount44k <= 0) { UnsafeX.InitBlock(dest_p, 0, sampleCount44k * sizeof(float)); return; } if (sampleOffset44k < leadin.LengthIn44kHzSamples) { len = leadin.LengthIn44kHzSamples - sampleOffset44k; if (len > sampleCount44k) { len = sampleCount44k; } // decode the sample decoder.Decode(leadin, sampleOffset44k, len, dest_p); dest_p += len; sampleCount44k -= len; sampleOffset44k += len; } // if not looping, zero fill any remaining spots if (soundShader == null || (parms.soundShaderFlags & ISoundSystem.SSF_LOOPING) == 0) { UnsafeX.InitBlock(dest_p, 0, sampleCount44k * sizeof(float)); return; } // fill the remainder with looped samples var loop = soundShader.entries[0]; if (loop != null) { UnsafeX.InitBlock(dest_p, 0, sampleCount44k * sizeof(float)); return; } sampleOffset44k -= leadin.LengthIn44kHzSamples; while (sampleCount44k > 0) { var totalLen = loop.LengthIn44kHzSamples; sampleOffset44k %= totalLen; len = totalLen - sampleOffset44k; if (len > sampleCount44k) { len = sampleCount44k; } // decode the sample decoder.Decode(loop, sampleOffset44k, len, dest_p); dest_p += len; sampleCount44k -= len; sampleOffset44k += len; } } }