0

だから私は Float 32 ビットをステレオの 16 ビットに変換しています。そして、私自身も完全には理解していないので、悲しいことにほとんどコピペです。

しかし、品質または速度のいずれかで改善できるのだろうか?それらのいずれかがひどいなどというわけではありません。

    void SendWaloop(object sender, NAudio.Wave.WaveInEventArgs e)
    {

        byte[] newArray16Bit = new byte[e.BytesRecorded / 2];
        short two;
        float value;
        for (int i = 0, j = 0; i < e.BytesRecorded; i += 4, j += 2)
        {
            value = (BitConverter.ToSingle(e.Buffer, i));
            two = (short)(value * short.MaxValue);

            newArray16Bit[j] = (byte)(two & 0xFF);
            newArray16Bit[j + 1] = (byte)((two >> 8) & 0xFF);
        }
        if (connect == true && MuteMic.Checked == false)
        {
            udpSend.Send(newArray16Bit, newArray16Bit.Length, otherPartyIP.Address.ToString(), 1500);
        }

    }

まあ、バッファを 32 ビットから 16 ビットに変換し、UDP で送信しますが、何も変ではありません。

私にとってこれは非常に複雑に見えますが、私が理解していることから、4バイトごとに削除するか、そのようなものです。

編集:

        unsafe
        {
            byte[] newArray16Bit = new byte[e.BytesRecorded / 2];
            fixed (byte* sourcePtr = e.Buffer)
            fixed (byte* targetPtr = newArray16Bit)
            {
                float* sourceTyped = (float*)sourcePtr;
                short* targetTyped = (short*)targetPtr;

                int count = e.BytesRecorded / 4;
                for (int i = 0; i < count; i++)
                {
                    targetTyped[i] = (short)(sourceTyped[i] * short.MaxValue);
                }
            }

            if (connect == true && MuteMic.Checked == false)
            {
                udpSend.Send(newArray16Bit, newArray16Bit.Length, otherPartyIP.Address.ToString(), 1500);
            }
        }
    }
4

1 に答える 1

2

テストが必要ですが、おそらくいくつか試してみますunsafe

fixed(byte* sourcePtr = e.Buffer)
fixed(byte* targetPtr = newArray16Bit)
{
    float* sourceTyped = (float*)sourcePtr;
    short* targetTyped = (short*)targetPtr;

    int count = e.BytesRecorded / 4;
    for(int i = 0 ; i < count ; i++)
    {
        targetTyped[i] = (short)(sourceTyped[i] * short.MaxValue);
    }
}

同じように動作することを示すには:

using System;
static class Program
{
    static void Main()
    {
        byte[] raw1 = new byte[64 * 1024];
        new Random(12345).NextBytes(raw1); // 64k of random data
        var raw2 = (byte[])raw1.Clone(); // just to rule out corruption
        var result1 = OriginalImplFromTopPost(raw1, raw1.Length - 20);
        var result2 = MyImpl(raw2, raw2.Length - 20);

        bool areSame = Convert.ToBase64String(result1) == Convert.ToBase64String(result2);
        Console.WriteLine(areSame); // True
    }

    public static unsafe byte[] MyImpl(byte[] source, int byteCount)
    {
        byte[] newArray16Bit = new byte[byteCount / 2];
        fixed (byte* sourcePtr = source)
        fixed (byte* targetPtr = newArray16Bit)
        {
            float* sourceTyped = (float*)sourcePtr;
            short* targetTyped = (short*)targetPtr;

            int count = byteCount / 4;
            for (int i = 0; i < count; i++)
            {
                targetTyped[i] = (short)(sourceTyped[i] * short.MaxValue);
            }
        }
        return newArray16Bit;
    }

    public static byte[] OriginalImplFromTopPost(byte[] source, int byteCount)
    {
        byte[] newArray16Bit = new byte[byteCount / 2];
        short two;
        float value;
        for (int i = 0, j = 0; i < byteCount; i += 4, j += 2)
        {
            value = (BitConverter.ToSingle(source, i));
            two = (short)(value * short.MaxValue);

            newArray16Bit[j] = (byte)(two & 0xFF);
            newArray16Bit[j + 1] = (byte)((two >> 8) & 0xFF);
        }
        return newArray16Bit;
    }
}
于 2013-08-15T12:28:29.747 に答える