8

Nspeex を使用して録音したオーディオをエンコードし、それをインターネット経由で転送して、反対側でデコードしようとしています。これはすべて Windows Phone 7/8 で行っています。エンコードとデコードには、次のコードを使用しています。しかし、デコード中に結果が正しく返されず、もう一度再生できます。WP7/8で録音されたオーディオで実行されるエンコードおよびデコードコードを誰かに提供してもらえますか:

private static Microphone mic = Microphone.Default;

        private static byte[] EncodeSpeech(byte[] buf, int len)
        {
            BandMode mode = GetBandMode(mic.SampleRate);
            SpeexEncoder encoder = new SpeexEncoder(mode);

            // set encoding quality to lowest (which will generate the smallest size in the fastest time)
            encoder.Quality = 1;
            int inDataSize = len / 2;

            // convert to short array
            short[] data = new short[inDataSize];
            int sampleIndex = 0;
            for (int index = 0; index < len; index += 2, sampleIndex++)
            {
                data[sampleIndex] = BitConverter.ToInt16(buf, index);
            }

            // note: the number of samples per frame must be a multiple of encoder.FrameSize
            inDataSize = inDataSize - inDataSize % encoder.FrameSize;
            var encodedData = new byte[len];
            int encodedBytes = encoder.Encode(data, 0, inDataSize, encodedData, 0, len);
            if (encodedBytes != 0)
            {
                // each chunk is laid out as follows:
                // | 4-byte total chunk size | 4-byte encoded buffer size | <encoded-bytes> |
                byte[] inDataSizeBuf = BitConverter.GetBytes(inDataSize);
                byte[] sizeBuf = BitConverter.GetBytes(encodedBytes + inDataSizeBuf.Length);
                byte[] returnBuf = new byte[encodedBytes + sizeBuf.Length + inDataSizeBuf.Length];
                sizeBuf.CopyTo(returnBuf, 0);
                inDataSizeBuf.CopyTo(returnBuf, sizeBuf.Length);
                Array.Copy(encodedData, 0, returnBuf, sizeBuf.Length + inDataSizeBuf.Length, encodedBytes);
                return returnBuf;
            }
            else
                return buf;
        }


        private byte[] DecodeSpeech(byte[] buf)
        {
            BandMode mode = GetBandMode(mic.SampleRate);
            SpeexDecoder decoder = new SpeexDecoder(mode);

            byte[] inDataSizeBuf = new byte[4];
            byte[] sizeBuf = new byte[4];
            byte[] encodedBuf = new byte[buf.Length - 8];
            Array.Copy(buf, 0, sizeBuf, 0, 4);
            Array.Copy(buf, 4, inDataSizeBuf, 0, 4);
            Array.Copy(buf, 8, encodedBuf, 0, buf.Length - 8);

            int inDataSize = BitConverter.ToInt32(inDataSizeBuf, 0);
            int size = BitConverter.ToInt32(sizeBuf, 0);
            short[] decodedBuf = new short[inDataSize];
            int decodedSize = decoder.Decode(encodedBuf, 0, encodedBuf.Length, decodedBuf, 0, false);

            byte[] returnBuf = new byte[inDataSize * 2];
            for (int index = 0; index < decodedBuf.Length; index++)
            {
                byte[] temp = BitConverter.GetBytes(decodedBuf[index]);
                Array.Copy(temp, 0, returnBuf, index * 2, 2);
            }

            return returnBuf;
        }


        private static BandMode GetBandMode(int sampleRate)
        {

            if (sampleRate <= 8000)

                return BandMode.Narrow;

            if (sampleRate <= 16000)

                return BandMode.Wide;

            return BandMode.UltraWide;

        }
4

1 に答える 1

0

あなたの問題は、オーディオをエンコードするたびに新しい SpeexEncoder を新しく作成していることだと思います。それをクラスのメンバーにして再利用してみてください。

Nspeexのコードを見て、狭帯域をSpeexEncoder使用していることに気付きました。NbEncoderそのクラスでは、エンコードを実行するために以前のオーディオ データの履歴を保持しているように見えます。これは、エンコーダーの異なるインスタンスの出力が一緒にならないことを意味するはずです。

private static Microphone mic = Microphone.Default;
private static SpeexEncoder encoder = CreateEncoder();

    private static SpeexEncoder CreateEncoder()
    {
        BandMode mode = GetBandMode(mic.SampleRate);
        SpeexEncoder encoder = new SpeexEncoder(mode);

        // set encoding quality to lowest (which will generate the smallest size in the fastest time)
        encoder.Quality = 1;
        return encoder;
    }

    private static byte[] EncodeSpeech(byte[] buf, int len)
    {
        int inDataSize = len / 2;

        ...
于 2013-03-06T21:03:20.973 に答える