Beispiel #1
0
        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();
                }
        }
Beispiel #2
0
        protected override unsafe void ExtractAndFillData()
        {
            if (byteBuffer != null)
            {
                int maxSize      = 100 * 1000;
                int bufferLen    = byteBuffer.Length;
                int remainingLen = bufferLen - byteBufferCurrentPosition;

                int     countByteTransfered = remainingLen > maxSize ? maxSize : remainingLen;
                short[] sdata = new short[(int)Math.Ceiling((decimal)(countByteTransfered / 2))];
                Buffer.BlockCopy(byteBuffer, byteBufferCurrentPosition, sdata, 0, countByteTransfered);
                byteBufferCurrentPosition += countByteTransfered;

                bool endingPacket = byteBufferCurrentPosition == bufferLen;

                var bufferType = AudioLayer.BufferType.None;
                if (endingPacket)
                {
                    bufferType = looped ? AudioLayer.BufferType.EndOfLoop : AudioLayer.BufferType.EndOfStream;
                }
                else if (begin)
                {
                    bufferType = AudioLayer.BufferType.BeginOfStream;
                    begin      = false;
                }

                FillBuffer(sdata, countByteTransfered, bufferType);
            }
            else if (currentPacketIndex > endPacketIndex)
            {
                // Go back to beginning if necessary
                if (soundInstance.Position.TotalSeconds == 0.0)
                {
                    if (looped) //prepare again to play from begin
                    {
                        PrepareInternal();
                    }
                    else // stops the sound
                    {
                        StopInternal(false);
                    }
                }
            }
            else
            {
                const int passes         = SamplesPerBuffer / SamplesPerFrame;
                var       offset         = 0;
                var       bufferPtr      = (short *)utilityBuffer.Pointer;
                var       startingPacket = startingPacketIndex == currentPacketIndex;
                var       endingPacket   = false;
                for (var i = 0; i < passes; i++)
                {
                    endingPacket = endPacketIndex == currentPacketIndex;

                    //read one packet, size first, then data
                    var len = reader.ReadInt16();
                    compressedSoundStream.Read(compressedBuffer, 0, len);
                    currentPacketIndex++;

                    var writePtr = bufferPtr + offset;
                    if (decoder.Decode(compressedBuffer, len, writePtr) != SamplesPerFrame)
                    {
                        throw new Exception("Celt decoder returned a wrong decoding buffer size.");
                    }

                    offset += SamplesPerFrame * channels;

                    if (endingPacket || compressedSoundStream.Position == compressedSoundStream.Length)
                    {
                        break;
                    }
                }

                // Send buffer to hardware
                var finalPtr  = new IntPtr(bufferPtr + (startingPacket ? startPktSampleIndex : 0));
                var finalSize = (offset - (startingPacket ? startPktSampleIndex : 0) - (endingPacket ? endPktSampleIndex : 0)) * sizeof(short);

                var bufferType = AudioLayer.BufferType.None;
                if (endingPacket)
                {
                    bufferType = looped ? AudioLayer.BufferType.EndOfLoop : AudioLayer.BufferType.EndOfStream;
                }
                else if (begin)
                {
                    bufferType = AudioLayer.BufferType.BeginOfStream;
                    begin      = false;
                }
                FillBuffer(finalPtr, finalSize, bufferType);
            }
        }