예제 #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="OpusSource"/> class.
        /// </summary>
        /// <param name="stream">The stream.</param>
        /// <param name="sampleRate">The sample rate.</param>
        /// <param name="channels">The channels.</param>
        public OpusSource(Stream stream, int sampleRate, int channels)
        {
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            if (!stream.CanRead)
            {
                throw new ArgumentException("Stream is not readable.", nameof(stream));
            }

            _stream = stream;

            WaveFormat = new WaveFormat(sampleRate, BitsPerSample, channels);

            var decoder = new OpusDecoder(WaveFormat.SampleRate, WaveFormat.Channels);

            _opusReadStream = new OpusOggReadStream(decoder, stream);

            _cts.Token.Register(() =>
            {
                decoder.ResetState();
            });
        }
예제 #2
0
        /// <summary>
        /// Seeks the stream for a valid packet at the specified granule position.
        /// </summary>
        /// <param name="granulePosition">The granule position.</param>
        private void SeekToGranulePosition(long granulePosition)
        {
            if (!CanSeek)
            {
                throw new InvalidOperationException("Stream is not seekable.");
            }

            if (granulePosition < 0 || granulePosition > GranuleCount)
            {
                throw new ArgumentOutOfRangeException(nameof(granulePosition));
            }

            // Find a packet based on offset and return 1 in the callback if the packet is valid
            var foundPacket = _packetProvider.FindPacket(granulePosition, GetPacketLength);

            // Check of the found packet is valid
            if (foundPacket == null || foundPacket.IsEndOfStream)
            {
                _endOfStream    = true;
                _nextDataPacket = null;
                return;
            }

            // Just seek to this found packet and get the previous packet (preRoll = 1)
            _packetProvider.SeekToPacket(foundPacket, 1);

            // Update the PageGranulePosition to the position from this next packet which will be retrieved by the next QueueNextPacket call
            PageGranulePosition = _packetProvider.PeekNextPacket().PageGranulePosition;

            // Reset the state from the decoder to start processing a fresh stream
            _decoder.ResetState();
        }
 public void togglePlayingTCP()
 {
     if (sdsock != null)
     {
         sdsock.Dispose();
         sdsock = null;
         if (concentusOpusDecoder != null)
         {
             concentusOpusDecoder.ResetState();
             concentusOpusDecoder = null;
         }
         m_Player.Close();
     }
     else
     {
         sdsock = new SoundDataSocket(NetworkTypes.Client);
         sdsock.ConnectedCallback         += Socket_ConnectedCallback;
         sdsock.DisconnectedCallback      += Socket_DisconnectedCallback;
         sdsock.ConnectionFailedCallback  += Socket_ConnectionFailedCallback;
         sdsock.DataRecievedCallback      += Socket_DataRecievedCallback;
         sdsock.StartDataRecievedCallback += Socket_StartDataRecievedCallback;
         sdsock.EndDataRecievedCallback   += Socket_EndDataRecievedCallback;
         sdsock.Connect(System.Net.IPAddress.Parse(GlobalConfiguration.ServerAddress), config.SoundServerPort);
     }
 }
예제 #4
0
        private ResultCode DecodeInterleavedInternal(BinaryReader input, out short[] outPcmData, long outputSize, out uint outConsumed, out int outSamples)
        {
            outPcmData  = null;
            outConsumed = 0;
            outSamples  = 0;

            long streamSize = input.BaseStream.Length;

            if (streamSize < Marshal.SizeOf <OpusPacketHeader>())
            {
                return(ResultCode.OpusInvalidInput);
            }

            OpusPacketHeader header = OpusPacketHeader.FromStream(input);

            uint totalSize = header.length + (uint)Marshal.SizeOf <OpusPacketHeader>();

            if (totalSize > streamSize)
            {
                return(ResultCode.OpusInvalidInput);
            }

            byte[] opusData = input.ReadBytes((int)header.length);

            ResultCode result = GetPacketNumSamples(out int numSamples, opusData);

            if (result == ResultCode.Success)
            {
                if ((uint)numSamples * (uint)_channelsCount * sizeof(short) > outputSize)
                {
                    return(ResultCode.OpusInvalidInput);
                }

                outPcmData = new short[numSamples * _channelsCount];

                if (_reset)
                {
                    _reset = false;

                    _decoder.ResetState();
                }

                try
                {
                    outSamples  = _decoder.Decode(opusData, 0, opusData.Length, outPcmData, 0, outPcmData.Length / _channelsCount);
                    outConsumed = totalSize;
                }
                catch (OpusException)
                {
                    // TODO: as OpusException doesn't provide us the exact error code, this is kind of inaccurate in some cases...
                    return(ResultCode.OpusInvalidInput);
                }
            }

            return(ResultCode.Success);
        }
예제 #5
0
        public async Task Stop()
        {
            if (playing)
            {
                playing = false;

                BasePlayer.Stop();

                if (provideThread != null)
                {
                    provideThread.Abort();
                    await Task.Run(() => provideThread.Join());

                    provideThread = null;
                }

                decoder.ResetState();
            }
        }
예제 #6
0
        public Sound LoadSound(string filepath)
        {
            //Read ogg packets
            FileStream stream = new FileStream(filepath, FileMode.Open);

            byte[][] packets = GetAudioPackets(stream);

            List <byte> pcmBytes = new List <byte>();

            //Decode packets from opus to pcm
            for (int i = 0; i < packets.Length; i++)
            {
                try
                {
                    var     packet    = packets[i];
                    int     frameSize = OpusPacketInfo.GetNumSamplesPerFrame(packet, 0, SAMPLE_RATE); //Get frame size from opus packet
                    short[] rawBuffer = new short[frameSize * 2];                                     //2 channels
                    var     buffer    = decoder.Decode(packet, 0, packet.Length, rawBuffer, 0, frameSize, false);

                    //Convert shorts to bytes
                    byte[] result = new byte[rawBuffer.Length * 2];
                    for (int j = 0; j < rawBuffer.Length; j++)
                    {
                        byte[] val = BitConverter.GetBytes(rawBuffer[j]);
                        Array.Copy(val, 0, result, j * 2, 2);
                    }

                    pcmBytes.AddRange(result);
                }
                catch (Concentus.OpusException e)
                {
                    //Skip this frame
                    //Note: the first 2 frames will hit this exception (they're probably just metadata frames, but i'm too lazy to check)
                }
            }

            decoder.ResetState();
            return(Sound.FromS16LE(pcmBytes.ToArray()));
        }
예제 #7
0
        public async Task Stop(bool isSoft)
        {
            if (playing)
            {
                playing = false;

                if (!isSoft)
                {
                    BasePlayer.Playing = false;
                }

                if (provideThread != null)
                {
                    BaseStream.Dispose();
                    provideThread.Abort();
                    await Task.Run(() => provideThread.Join());

                    provideThread = null;
                }

                decoder.ResetState();
            }
        }
예제 #8
0
파일: Decoder.cs 프로젝트: Xpl0itR/Ryujinx
 public void ResetState()
 {
     _decoder.ResetState();
 }