コード例 #1
0
        //byte[] LastBuffer;
        //bool LastBufferSet;
        //byte[] EchoBuff;

        private bool EncodeAudio(RecordBuffer buffer)
        {
            // done in a seperate function to avoid buffer from being re-assigned while delegate is being processed

            short maxVolume = 0;

            for (int i = 0; i < BufferSize / 2; i++)
            {
                short val = BitConverter.ToInt16(buffer.Data, i * 2);
                if (val > maxVolume)
                {
                    maxVolume = val;
                }
            }

            // pre-process
            Speex.speex_preprocess_run(PreProcessor, buffer.Data);

            // echo cancel
            //if (EchoBuff == null) EchoBuff = new byte[BufferSize];
            //Speex.speex_echo_capture(EchoState, buffer.Data, EchoBuff);
            //EchoBuff.CopyTo(buffer.Data, 0);

            // encode
            Speex.speex_bits_reset(ref EncodeBits);

            int success = Speex.speex_encode_int(SpeexEncoder, buffer.DataPtr, ref EncodeBits);

            if (success == 0) // dtx returns 0 if no data
            {
                return(false);
            }

            int written = Speex.speex_bits_write(ref EncodeBits, EncodedBytes, EncodedBytes.Length);

            // filler is 10b high quality, 6b low quality, dont write filler only good audio
            if (written > 10)
            {
                //buffer.Data.CopyTo(LastBuffer, 0);
                //LastBufferSet = true;

                byte[] safeBuffer = Utilities.ExtractBytes(EncodedBytes, 0, written);

                // pass frame size because recorder could be null by the time event gets there
                Voices.Core.RunInCoreAsync(() => Voices.Recorder_AudioData(safeBuffer, maxVolume, FrameSize));

                return(true);
            }

            return(false);
        }
コード例 #2
0
        public void ProcessBuffers()
        {
            try
            {
                while (FilledBuffers < BufferCount)
                {
                    byte[] data = null;
                    lock (AudioQueue) // either gets called from core, or system thread
                    {
                        if (AudioQueue.Count == 0)
                        {
                            return;
                        }

                        data = AudioQueue.Dequeue();
                    }

                    // keep a log of received audio that user can back track through
                    lock (History)
                    {
                        History.Enqueue(data);

                        while (History.Count > HistoryLength)
                        {
                            History.Dequeue();
                        }
                    }

                    // decode
                    Speex.speex_bits_reset(ref DecodeBits);

                    Speex.speex_bits_read_from(ref DecodeBits, data, data.Length);

                    byte[] mono    = new byte[FrameSize * 2];
                    int    success = Speex.speex_decode_int(SpeexDecoder, ref DecodeBits, mono);

                    if (success != 0)
                    {
                        continue;
                    }

                    // cancel echo
                    //if (Voices.Recorder != null && FrameSize == Voices.Recorder.FrameSize)
                    //   Speex.speex_echo_playback(Voices.Recorder.EchoState, mono);

                    // get volume
                    short maxVolume = 0;
                    for (int i = 0; i < mono.Length / 2; i++)
                    {
                        short val = BitConverter.ToInt16(mono, i * 2);
                        if (val > maxVolume)
                        {
                            maxVolume = val;
                        }
                    }

                    if (maxVolume > User.VolumeIn)
                    {
                        User.VolumeIn = maxVolume;
                    }


                    // find out where audio should come out from, if at all
                    // return down here so that even if user not listening, window shows volume bar
                    AudioDirection direction = User.GetDirection();

                    if (direction == AudioDirection.None)
                    {
                        continue;
                    }


                    // shifting to one side
                    PlayBuffer buffer = Buffers[NextBuffer];

                    for (int i = 0; i < mono.Length / 2; i++)
                    {
                        switch (direction)
                        {
                        case AudioDirection.Both:
                            Buffer.BlockCopy(mono, i * 2, buffer.Data, i * 4, 2);     // left
                            Buffer.BlockCopy(mono, i * 2, buffer.Data, i * 4 + 2, 2); // right
                            break;

                        case AudioDirection.Left:
                            Buffer.BlockCopy(mono, i * 2, buffer.Data, i * 4, 2);     // left
                            break;

                        case AudioDirection.Right:
                            Buffer.BlockCopy(mono, i * 2, buffer.Data, i * 4 + 2, 2);     // right
                            break;
                        }
                    }


                    WinMM.ErrorCheck(WinMM.waveOutWrite(WaveHandle, ref buffer.Header, Marshal.SizeOf(buffer.Header)));

                    FilledBuffers++;

                    NextBuffer++;
                    if (NextBuffer >= BufferCount)
                    {
                        NextBuffer = 0;
                    }
                }
            }
            catch (Exception ex)
            {
                Voices.Core.RunInCoreAsync(() =>
                {
                    Dispose();
                    Voices.Core.Network.UpdateLog("Voice", "Error filling buffers: " + ex.Message);
                });
            }
        }