internal void LoadSoundInMemory() { if (PreloadedBuffer.Ptr != IntPtr.Zero) { return; } using (var soundStream = FileProvider.OpenStream(CompressedDataUrl, VirtualFileMode.Open, VirtualFileAccess.Read, VirtualFileShare.Read, StreamFlags.Seekable)) using (var decoder = new Celt(SampleRate, CompressedSoundSource.SamplesPerFrame, Channels, true)) { var reader = new BinarySerializationReader(soundStream); var samplesPerPacket = CompressedSoundSource.SamplesPerFrame * Channels; PreloadedBuffer = AudioLayer.BufferCreate(samplesPerPacket * NumberOfPackets * sizeof(short)); var memory = new UnmanagedArray <short>(samplesPerPacket * NumberOfPackets); var offset = 0; var outputBuffer = new short[samplesPerPacket]; for (var i = 0; i < NumberOfPackets; i++) { var len = reader.ReadInt16(); var compressedBuffer = reader.ReadBytes(len); var samplesDecoded = decoder.Decode(compressedBuffer, len, outputBuffer); memory.Write(outputBuffer, offset, 0, samplesDecoded * Channels); offset += samplesDecoded * Channels * sizeof(short); } AudioLayer.BufferFill(PreloadedBuffer, memory.Pointer, memory.Length * sizeof(short), SampleRate, Channels == 1); memory.Dispose(); } }
/// <summary> /// Sub classes can implement their own streaming sources. /// </summary> /// <param name="soundInstance">the sound instance associated.</param> /// <param name="numberOfBuffers">the size of the streaming ring-buffer.</param> /// <param name="maxBufferSizeBytes">the maximum size of each buffer.</param> protected DynamicSoundSource(SoundInstance soundInstance, int numberOfBuffers, int maxBufferSizeBytes) { nativeBufferSizeBytes = maxBufferSizeBytes; prebufferedTarget = (int)Math.Ceiling(numberOfBuffers / (double)3); SoundInstance = soundInstance; for (var i = 0; i < numberOfBuffers; i++) { var buffer = AudioLayer.BufferCreate(nativeBufferSizeBytes); deviceBuffers.Add(buffer); freeBuffers.Enqueue(deviceBuffers[i]); } if (readFromDiskWorker == null) { readFromDiskWorker = Task.Factory.StartNew(Worker, TaskCreationOptions.LongRunning); } }
/// <summary> /// Initializes a new instance of the <see cref="DynamicSoundSource"/> class. /// Sub classes can implement their own streaming sources. /// </summary> /// <param name="soundInstance">the sound instance associated.</param> /// <param name="numberOfBuffers">the size of the streaming ring-buffer.</param> /// <param name="maxBufferSizeBytes">the maximum size of each buffer.</param> protected DynamicSoundSource(SoundInstance soundInstance, int numberOfBuffers, int maxBufferSizeBytes) { nativeBufferSizeBytes = maxBufferSizeBytes; prebufferedTarget = (int)Math.Ceiling(numberOfBuffers / 3.0); this.soundInstance = soundInstance; for (var i = 0; i < numberOfBuffers; i++) { var buffer = AudioLayer.BufferCreate(nativeBufferSizeBytes); deviceBuffers.Add(buffer); freeBuffers.Enqueue(deviceBuffers[i]); } if (readFromDiskWorker == null) { readFromDiskWorker = new Thread(new ThreadStart(Worker)); readFromDiskWorker.Priority = ThreadPriority.BelowNormal; readFromDiskWorker.IsBackground = true; readFromDiskWorker.Start(); } }