Ejemplo n.º 1
0
        /// <summary>
        /// Encodes an array of 16-bit samples in a roughly equivalent set of 8-bit samples and downsamples them from 16Khz to 8Khz
        /// </summary>
        /// <param name="rawFrame">A byte-array of the 16-bit 16-Khz source samples</param>
        /// <param name="start">The starting index of the source samples IN BYTES</param>
        /// <param name="length">The length IN BYTES of the samples</param>
        /// <param name="encodedFrame">The byte array in which to place the encoded 8-bit samples</param>
        /// <param name="isSilent">Whether the frame is silent or not</param>
        /// <returns>The length IN BYTES of the encoded data</returns>
        public int Encode(byte[] rawFrame, int start, int length, byte[] encodedFrame, bool isSilent)
        {
            if (isSilent)
            {
                return(0);
            }
            int encodedPos = 0;

            for (int i = start; i < start + length; i += _byteStep)
            {
                short rawSample = G711.ToShort(rawFrame[i], rawFrame[++i]);
                encodedFrame[encodedPos++] = G711.LinearToULawFast(rawSample);
            }
            return(encodedPos);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Encodes an array of 16-bit samples in a roughly equivalent set of 8-bit samples and downsamples from 16Khz to 8Khz
        /// </summary>
        /// <param name="rawFrame">A short-array of the 16-bit source samples</param>
        /// <param name="start">The starting index of the source samples IN SHORTS</param>
        /// <param name="length">The length IN SHORTS of the samples</param>
        /// <param name="encodedFrame">The short array in which to place the packed and encoded 8-bit samples</param>
        /// <param name="isSilent">Whether the array contains silence</param>
        /// <returns>The length IN SHORTS of the encoded data</returns>
        public int Encode(short[] rawFrame, int start, int length, short[] encodedFrame, bool isSilent)
        {
            if (isSilent)
            {
                return(0);
            }
            int encodedPos = 0;

            for (int i = start; i < start + length; i += _shortStep)
            {
                byte b1 = G711.LinearToULawFast(rawFrame[i]);
                i += _shortStep;
                byte b2 = G711.LinearToULawFast(rawFrame[i]);
                encodedFrame[encodedPos++] = G711.ToShort(b1, b2);
            }
            return(encodedPos);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Decodes an 8Khz array of 8-bit encoded values into an equivalent set of 16-bit samples
        /// </summary>
        /// <param name="encodedFrame">A short array with the encoded values</param>
        /// <param name="inputStart">The starting position IN SHORTS of the samples</param>
        /// <param name="inputLength">The length of the samples IN SHORTS</param>
        /// <param name="decodedFrame">The output frame</param>
        /// <param name="outputStart">The starting position IN SHORTS in the output buffer where the decoded data should be written</param>
        /// <param name="isSilent">Whether the samples contain silence</param>
        /// <returns>The length of the decoded samples IN SHORTS</returns>
        public int Decode(short[] encodedFrame, int inputStart, int inputLength, short[] decodedFrame, int outputStart, bool isSilent)
        {
            if (isSilent)
            {
                Array.Clear(decodedFrame, outputStart, _outputAudioFormat.SamplesPerFrame);
                return(_outputAudioFormat.SamplesPerFrame);
            }

            // Decode
            int decodedPos = outputStart;

            if (_outputAudioFormat.SamplesPerSecond == 16000)
            {
                for (int i = inputStart; i < inputStart + inputLength; i++)
                {
                    byte b1;
                    byte b2;
                    G711.FromShort(encodedFrame[i], out b1, out b2);
                    decodedFrame[decodedPos] = G711.ULawToLinearFast(b1);
                    decodedPos += 2;
                    decodedFrame[decodedPos] = G711.ULawToLinearFast(b2);
                    decodedPos += 2;
                }

                // Upsample using linear interpolation. Not the best quality, but cheap on CPU.
                for (int i = 1; i < decodedPos - 1; i += 2)
                {
                    decodedFrame[i] = (short)((decodedFrame[i - 1] + decodedFrame[i + 1]) / 2);
                }
                decodedFrame[decodedPos - 1] = decodedFrame[decodedPos - 2];                 // Cheat on the last sample
            }
            else
            {
                for (int i = inputStart; i < inputStart + inputLength; i++)
                {
                    byte b1;
                    byte b2;
                    G711.FromShort(encodedFrame[i], out b1, out b2);
                    decodedFrame[decodedPos++] = G711.ULawToLinearFast(b1);
                    decodedFrame[decodedPos++] = G711.ULawToLinearFast(b2);
                }
            }
            return(decodedPos - outputStart);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Decodes an 8Khz array of 8-bit encoded values into an equivalent set of 16-bit samples (and upsamples them to 16Khz if necessary).
        /// </summary>
        /// <param name="encodedFrame">A byte array with the encoded values</param>
        /// <param name="inputStart">The starting position IN BYTES of the samples</param>
        /// <param name="inputLength">The length of the samples IN BYTES</param>
        /// <param name="decodedFrame">The output frame</param>
        /// <param name="outputStart">The starting position IN BYTES of the output buffer where the decoded data should be written.</param>
        /// <param name="isSilent">Whether the samples contain silence</param>
        /// <returns>The length of the decoded samples IN BYTES</returns>
        public int Decode(byte[] encodedFrame, int inputStart, int inputLength, byte[] decodedFrame, int outputStart, bool isSilent)
        {
            if (isSilent)
            {
                Array.Clear(decodedFrame, outputStart, _outputAudioFormat.BytesPerFrame);
                return(_outputAudioFormat.BytesPerFrame);
            }

            int end        = inputStart + inputLength;
            int decodedPos = outputStart;

            if (_outputAudioFormat.SamplesPerSecond == 16000)
            {
                // Decode
                for (int i = inputStart; i < end; i++)
                {
                    short decodedSample = G711.ULawToLinearFast(encodedFrame[i]);
                    G711.FromShort(decodedSample, out decodedFrame[decodedPos++], out decodedFrame[decodedPos++]);
                    decodedPos += 2;
                }

                // Upsample
                short next = 0;
                for (int i = 2; i < decodedPos - 2; i += 4)
                {
                    short previous = G711.ToShort(decodedFrame[i - 2], decodedFrame[i - 1]);
                    next = G711.ToShort(decodedFrame[i + 2], decodedFrame[i + 3]);
                    G711.FromShort((short)((previous + next) / 2), out decodedFrame[i], out decodedFrame[i + 1]);
                }
                G711.FromShort(next, out decodedFrame[decodedPos - 2], out decodedFrame[decodedPos - 1]); // Cheat on the last sample
            }
            else                                                                                          // if outputAudioFormat.SamplesPerSecond = 8000
            {
                // Decode
                for (int i = inputStart; i < end; i++)
                {
                    short decodedSample = G711.ULawToLinearFast(encodedFrame[i]);
                    G711.FromShort(decodedSample, out decodedFrame[decodedPos++], out decodedFrame[decodedPos++]);
                }
            }
            return(decodedPos - outputStart);
        }