コード例 #1
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);
        }
コード例 #2
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);
        }