public byte[] Encode(SpeechCodecs codec) { //Get the codec var codecInstance = _codecs.GetCodec(codec); //How many bytes can we fit into the larget frame? var maxBytes = codecInstance.PermittedEncodingFrameSizes.Max() * sizeof(ushort); bool stopped = false; //If we have an unencoded item stored here it's because a previous iteration pulled from the queue and discovered it could not process this packet (different target) if (_unencodedItem.HasValue && TryAddToEncodingBuffer(_unencodedItem.Value, out stopped)) { _unencodedItem = null; } //Accumulate as many bytes as we can stuff into a single frame while (_pcmBuffer.Count < maxBytes && !stopped) { TargettedSpeech item; if (!_unencodedBuffer.TryTake(out item, TimeSpan.FromMilliseconds(1))) { break; } //Add this packet to the encoding buffer, or stop accumulating bytes if (!TryAddToEncodingBuffer(item, out stopped)) { _unencodedItem = item; break; } } //Nothing to encode, early exit if (_pcmBuffer.Count == 0) { return(null); } if (stopped) { //User has stopped talking, pad buffer up to next buffer size with silence var frameBytes = codecInstance.PermittedEncodingFrameSizes.Select(f => f * sizeof(ushort)).Where(f => f >= _pcmBuffer.Count).Min(); byte[] b = new byte[frameBytes]; int read = _pcmBuffer.Read(new ArraySegment <byte>(b)); return(codecInstance.Encode(new ArraySegment <byte>(b, 0, read))); } else { //We have a load of bytes of PCM data, let's encode them var frameBytes = codecInstance.PermittedEncodingFrameSizes.Select(f => f * sizeof(ushort)).Where(f => f <= _pcmBuffer.Count).Max(); byte[] b = new byte[frameBytes]; int read = _pcmBuffer.Read(new ArraySegment <byte>(b)); return(codecInstance.Encode(new ArraySegment <byte>(b, 0, read))); } }
protected internal IVoiceCodec GetCodec(SpeechCodecs codec) { if (!_owner.Connection.VoiceSupportEnabled) { throw new InvalidOperationException("Voice Support is disabled with this connection"); } return(_codecs.GetCodec(codec)); }
/// <summary> /// Get a voice decoder for the specified user/codec combination /// </summary> /// <param name="session"></param> /// <param name="codec"></param> /// <returns></returns> public virtual IVoiceCodec GetCodec(uint session, SpeechCodecs codec) { User user; if (!UserDictionary.TryGetValue(session, out user)) { return(null); } return(user.GetCodec(codec)); }
public byte[] Encode(SpeechCodecs codec) { //Get the codec var codecInstance = _codecs.GetCodec(codec); //How many bytes can we fit into the larget frame? var maxBytes = codecInstance.PermittedEncodingFrameSizes.Max() * sizeof(ushort); bool stopped = false; //If we have an unencoded item stored here it's because a previous iteration pulled from the queue and discovered it could not process this packet (different target) if (_unencodedItem.HasValue && TryAddToEncodingBuffer(_unencodedItem.Value, out stopped)) _unencodedItem = null; //Accumulate as many bytes as we can stuff into a single frame while (_pcmBuffer.Count < maxBytes && !stopped) { TargettedSpeech item; if (!_unencodedBuffer.TryTake(out item, TimeSpan.FromMilliseconds(1))) break; //Add this packet to the encoding buffer, or stop accumulating bytes if (!TryAddToEncodingBuffer(item, out stopped)) { _unencodedItem = item; break; } } //Nothing to encode, early exit if (_pcmBuffer.Count == 0) return null; if (stopped) { //User has stopped talking, pad buffer up to next buffer size with silence var frameBytes = codecInstance.PermittedEncodingFrameSizes.Select(f => f * sizeof(ushort)).Where(f => f >= _pcmBuffer.Count).Min(); byte[] b = new byte[frameBytes]; int read = _pcmBuffer.Read(new ArraySegment<byte>(b)); return codecInstance.Encode(new ArraySegment<byte>(b, 0, read)); } else { //We have a load of bytes of PCM data, let's encode them var frameBytes = codecInstance.PermittedEncodingFrameSizes.Select(f => f * sizeof(ushort)).Where(f => f <= _pcmBuffer.Count).Max(); byte[] b = new byte[frameBytes]; int read = _pcmBuffer.Read(new ArraySegment<byte>(b)); return codecInstance.Encode(new ArraySegment<byte>(b, 0, read)); } }
protected internal IVoiceCodec GetCodec(SpeechCodecs codec) { switch (codec) { case SpeechCodecs.CeltAlpha: return _alpha.Value; case SpeechCodecs.Speex: return _speex.Value; case SpeechCodecs.CeltBeta: return _beta.Value; case SpeechCodecs.Opus: return _opus.Value; default: throw new ArgumentOutOfRangeException("codec"); } }
protected internal IVoiceCodec GetCodec(SpeechCodecs codec) { switch (codec) { case SpeechCodecs.CeltAlpha: return(_alpha.Value); case SpeechCodecs.Speex: return(_speex.Value); case SpeechCodecs.CeltBeta: return(_beta.Value); case SpeechCodecs.Opus: return(_opus.Value); default: throw new ArgumentOutOfRangeException("codec"); } }
/// <summary> /// Get a voice decoder for the specified user/codec combination /// </summary> /// <param name="session"></param> /// <param name="codec"></param> /// <returns></returns> public virtual IVoiceCodec GetCodec(uint session, SpeechCodecs codec) { User user; if (!UserDictionary.TryGetValue(session, out user)) return null; return user.GetCodec(codec); }
protected internal IVoiceCodec GetCodec(SpeechCodecs codec) { return(_codecs.GetCodec(codec)); }