示例#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);
                    }

                    // Ignore invalid data at beginning (due to encoder delay) & end of stream (due to packet size)
                    var samplesToSkip = decoder.GetDecoderSampleDelay();
                    AudioLayer.BufferFill(PreloadedBuffer, memory.Pointer + samplesToSkip * Channels * sizeof(short), Samples * Channels * sizeof(short), SampleRate, Channels == 1);
                    memory.Dispose();
                }
        }
示例#2
0
        protected override void PrepareInternal()
        {
            base.PrepareInternal();

            begin = true;
            if (byteBuffer != null)
            {
                return;
            }

            compressedSoundStream.Position = 0;
            currentPacketIndex             = 0;
            startPktSampleIndex            = 0;
            endPktSampleIndex = 0;
            endPacketIndex    = numberOfPackets;

            PlayRange range;

            lock (rangeLock)
            {
                range = playRange;
            }

            // Reset decoder state
            decoder.ResetDecoder();

            // Ignore invalid data at beginning (due to encoder delay) & end of stream (due to packet size)
            var samplesToSkip = decoder.GetDecoderSampleDelay();

            var frameSize = SamplesPerFrame * channels;
            //ok we need to handle this case properly, this means that the user wants to use a different then full audio stream range...
            var sampleStart = (channels * samplesToSkip) + (int)Math.Floor(sampleRate * (double)channels * range.Start.TotalSeconds);

            startPktSampleIndex = sampleStart % (frameSize);

            var sampleStop = (channels * samplesToSkip)
                             + (range.Length != TimeSpan.Zero
                    ? (int)Math.Floor(sampleRate * (double)channels * range.End.TotalSeconds)
                    : (channels * samples));

            endPktSampleIndex = frameSize - sampleStop % frameSize;

            var skipCounter = startingPacketIndex = sampleStart / frameSize;

            endPacketIndex = sampleStop / frameSize;

            // skip to the starting packet
            if (startingPacketIndex < numberOfPackets && endPacketIndex < numberOfPackets && startingPacketIndex < endPacketIndex)
            {
                //valid offsets.. process it
                while (skipCounter-- > 0)
                {
                    //skip data to reach starting packet
                    var len = reader.ReadInt16();
                    compressedSoundStream.Position = compressedSoundStream.Position + len;
                    currentPacketIndex++;
                }
            }
        }
示例#3
0
        protected override void PrepareInternal()
        {
            base.PrepareInternal();

            begin = true;
            if (byteBuffer != null)
            {
                return;
            }

            compressedSoundStream.Position = 0;
            currentPacketIndex             = 0;
            startPktSampleIndex            = 0;
            endPktSampleIndex = 0;
            endPacketIndex    = numberOfPackets;

            PlayRange range;

            lock (rangeLock)
            {
                range = playRange;
            }

            // Reset decoder state
            decoder.ResetDecoder();

            // Ignore invalid data at beginning (due to encoder delay) & end of stream (due to packet size)
            var samplesToSkip = decoder.GetDecoderSampleDelay();

            // Compute boundaries
            var sampleBegin = (channels * samplesToSkip);
            var sampleEnd   = sampleBegin + (channels * samples);

            var frameSize = SamplesPerFrame * channels;
            //ok we need to handle this case properly, this means that the user wants to use a different then full audio stream range...
            var sampleStart = sampleBegin + (int)Math.Floor(sampleRate * (double)channels * range.Start.TotalSeconds);

            // Make sure start is at least one sample before the end to avoid edge cases where startingPacketIndex == numberOfPackets
            sampleStart = Math.Min(Math.Max(sampleStart, sampleBegin), sampleEnd - 1 * channels);

            var sampleStop = sampleBegin
                             + (range.Length != TimeSpan.Zero
                    ? (int)Math.Floor(sampleRate * (double)channels * range.End.TotalSeconds)
                    : (channels * samples));

            // Make sure stop is at least one sample after start
            sampleStop = Math.Min(Math.Max(sampleStop, sampleStart + 1 * channels), sampleEnd);

            // Compute start/end packet
            startingPacketIndex = sampleStart / frameSize;
            endPacketIndex      = (sampleStop - 1) / frameSize; // -1 to make sure we stay in last packet if using all of it

            // How much data to use in start/end packet
            startPktSampleIndex = sampleStart % (frameSize);
            endPktSampleIndex   = frameSize - sampleStop % frameSize;

            // skip to the starting packet
            if (startingPacketIndex < numberOfPackets && endPacketIndex < numberOfPackets && startingPacketIndex <= endPacketIndex) // this shouldn't happen anymore with the min/max clamps
            {
                //valid offsets.. process it
                var skipCounter = startingPacketIndex;
                while (skipCounter-- > 0)
                {
                    //skip data to reach starting packet
                    var len = reader.ReadInt16();
                    compressedSoundStream.Position = compressedSoundStream.Position + len;
                    currentPacketIndex++;
                }
            }
        }