public BigArray <float> DecodeFrame(VoicePacketWrapper data) { int frameSize = frameSizes[data.Frequency * 1000]; codecWrapper codec = encoders[data.Frequency * 1000]; short[] decodedFrame16Bit = TempArray <short> .Obtain(frameSize * 4); int decoded = codec.decoder.Decode(data.RawData, 0, data.RawData.Length, decodedFrame16Bit, 0, false); if (tempOutputArray.Length != decoded) { tempOutputArray.Resize(decoded); } for (int i = 0; i < decoded; i++) { float val = (float)decodedFrame16Bit[i]; val /= short.MaxValue; tempOutputArray[i] = val; } TempArray <short> .Release(decodedFrame16Bit); return(tempOutputArray); }
protected override void OnAudioDataEncoded(VoicePacketWrapper encodedFrame) { if (Random.Range(0f, 1f) <= PacketLoss) { return; } ReceiveAudioData(encodedFrame); }
public SpeexCodec(bool VBR) { encoders = new Dictionary <int, codecWrapper>() { { 8000, new codecWrapper(NSpeex.BandMode.Narrow, VBR) }, { 16000, new codecWrapper(NSpeex.BandMode.Wide, VBR) }, { 32000, new codecWrapper(NSpeex.BandMode.UltraWide, VBR) }, }; chunkBuffer = new ChunkBuffer(); tempOutputArray = new BigArray <float>(1024, 0); tempPacketWrapper = new VoicePacketWrapper(0, 16, new byte[0]); }
public VoicePacketWrapper?GetNextEncodedFrame(int frequency) { int frameSize = frameSizes[frequency]; codecWrapper codec = encoders[frequency]; float[] chunk = TempArray <float> .Obtain(frameSize); bool chunkAvailable = chunkBuffer.RetrieveChunk(chunk); if (!chunkAvailable) { TempArray <float> .Release(chunk); return(null); } tempPacketWrapper = new VoicePacketWrapper(); tempPacketWrapper.Frequency = (byte)(frequency / 1000); short[] audio16bit = TempArray <short> .Obtain(frameSize); for (int i = 0; i < frameSize; i++) { float val = chunk[i] * short.MaxValue; audio16bit[i] = (short)val; } TempArray <float> .Release(chunk); byte[] buffer = TempArray <byte> .Obtain(audio16bit.Length * 2); int encoded = codec.encoder.Encode(audio16bit, 0, frameSize, buffer, 0, buffer.Length); TempArray <short> .Release(audio16bit); tempPacketWrapper.RawData = new byte[encoded]; System.Buffer.BlockCopy(buffer, 0, tempPacketWrapper.RawData, 0, encoded); TempArray <byte> .Release(buffer); return(tempPacketWrapper); }
/// <summary> /// Decode and play back received audio data /// </summary> protected virtual void ReceiveAudioData(VoicePacketWrapper encodedFrame) { if (!IsLocal || DebugAudio) { //Debug.Log("encoded index" + encodedFrame.Index + " next expected" + nextExpectedIndex); // discard old samples if (encodedFrame.Index < nextExpectedIndex) { return; } // voice controller is muted - don't bother decoding or buffering audio data if (Mute) { nextExpectedIndex = encodedFrame.Index + 1; return; } speaker.SetSampleRate(encodedFrame.Frequency * 1000); // some frames were lost, generate filler data for them // unless the speaker isn't playing any sound, in which case filler data will only delay the stream further // OR unless nextExpectedIndex is zero, implying that we haven't received any frames yet if (nextExpectedIndex != 0 && encodedFrame.Index != nextExpectedIndex && speaker.PlayingSound) { int numMissingFrames = (int)(encodedFrame.Index - nextExpectedIndex); for (int i = 0; i < numMissingFrames; i++) { BigArray <float> filler = codec.GenerateMissingFrame(encodedFrame.Frequency); speaker.BufferAudio(filler); } } BigArray <float> decoded = codec.DecodeFrame(encodedFrame); speaker.BufferAudio(decoded); nextExpectedIndex = encodedFrame.Index + 1; } }
/// <summary> /// Called when new audio is available from the microphone /// </summary> protected virtual void OnMicrophoneDataReady(BigArray <float> newData, int frequency) { if (!IsLocal) { return; } codec.OnAudioAvailable(newData); VoicePacketWrapper?enc = codec.GetNextEncodedFrame(frequency); while (enc.HasValue) { // assign index VoicePacketWrapper packet = enc.Value; packet.Index = nextFrameIndex++; enc = packet; OnAudioDataEncoded(enc.Value); enc = codec.GetNextEncodedFrame(frequency); } }
/// <summary> /// Called when a frame of audio is encoded and ready to send /// </summary> protected virtual void OnAudioDataEncoded(VoicePacketWrapper encodedFrame) { // TODO: send audio over network }
void vc(byte[] headers, byte[] rawData) { VoicePacketWrapper packet = new VoicePacketWrapper(headers, rawData); ReceiveAudioData(packet); }
protected override void OnAudioDataEncoded(VoicePacketWrapper encodedFrame) { byte[] headers = encodedFrame.ObtainHeaders(); GetComponent <NetworkView>().RPC("vc", RPCMode.All, headers, encodedFrame.RawData); encodedFrame.ReleaseHeaders(); }