public unsafe int DecodePCM(SoundSample sample, int sampleOffset44k, int sampleCount44k, float *dest) { lastFormat = WAVE_FORMAT_TAG.PCM; lastSample = sample; var shift = 22050 / sample.objectInfo.nSamplesPerSec; var sampleOffset = sampleOffset44k >> shift; var sampleCount = sampleCount44k >> shift; if (sample.nonCacheData == null) { Debug.Assert(false); failed = true; return(0); } // this should never happen ( note: I've seen that happen with the main thread down in idGameLocal::MapClear clearing entities - TTimo ) if (!sample.FetchFromCache(sampleOffset * sizeof(short), out var first, out var pos, out var size, false)) { failed = true; return(0); } var readSamples = size - pos < sampleCount * sizeof(short) ? (size - pos) / sizeof(short) : sampleCount; // duplicate samples for 44kHz output fixed(byte *_ = &first.v[first.o + pos]) Simd.UpSamplePCMTo44kHz(dest, (short *)_, readSamples, sample.objectInfo.nSamplesPerSec, sample.objectInfo.nChannels); return(readSamples << shift); }
public void Clear() { failed = false; lastFormat = WAVE_FORMAT_TAG.PCM; lastSample = null; lastSampleOffset = 0; lastDecodeTime = 0; }
public unsafe int DecodeOGG(SoundSample sample, int sampleOffset44k, int sampleCount44k, float *dest) { int readSamples, totalSamples; var shift = 22050 / sample.objectInfo.nSamplesPerSec; var sampleOffset = sampleOffset44k >> shift; var sampleCount = sampleCount44k >> shift; // open OGG file if not yet opened if (lastSample == null) { // make sure there is enough space for another decoder if (ISampleDecoder.decoderMemoryAllocator.FreeBlockMemory < ISampleDecoder.MIN_OGGVORBIS_MEMORY) { return(0); } if (sample.nonCacheData == null) { Debug.Assert(false); failed = true; return(0); } // this should never happen file.SetData(sample.nonCacheData, sample.objectMemSize); if (OggVorbis.ov_openFile(file, ogg) < 0) { failed = true; return(0); } lastFormat = WAVE_FORMAT_TAG.OGG; lastSample = sample; } // seek to the right offset if necessary if (sampleOffset != lastSampleOffset && ov_pcm_seek(ogg, sampleOffset / sample.objectInfo.nChannels) != 0) { failed = true; return(0); } lastSampleOffset = sampleOffset; // decode OGG samples totalSamples = sampleCount; readSamples = 0; do { float **samples; var ret = (int)ov_read_float(ogg, &samples, totalSamples / sample.objectInfo.nChannels, null); if (ret == 0) { failed = true; break; } if (ret < 0) { failed = true; return(0); } ret *= sample.objectInfo.nChannels; Simd.UpSampleOGGTo44kHz(dest + (readSamples << shift), samples, ret, sample.objectInfo.nSamplesPerSec, sample.objectInfo.nChannels); readSamples += ret; totalSamples -= ret; } while (totalSamples > 0); lastSampleOffset += readSamples; return(readSamples << shift); }