使用 asioOut 从 naudio GetAsInterleavedSamples 获取多个音频样本

Getting multiple audio samples from naudio GetAsInterleavedSamples using asioOut

提问人:Timothy Ayodele 提问时间:10/3/2023 更新时间:10/4/2023 访问量:20

问:

查看此链接后: 从 NAudio asioOut 编写多个 wav 文件,我希望能够将单独的波形样本放入不同的文件中,但它不起作用。我只得到零字节文件。我不知道自 2012 年发布解决方案以来是否对 naudio 库进行了更新。 请问我对下面的代码进行哪些调整,以将各种波形样本放入不同的文件中。目前,我收到多个零字节文件,没有任何错误

我的代码如下:

    private WaveFileWriter[] writer = null;
    private AsioOut asioOut;
    private string[] fileName = null;
    private int recordChannelCount;

    private void Start()
    {
        // allow change device
        if (asioOut != null &&
            (asioOut.DriverName != comboBoxAsioDevice.Text ||
            asioOut.ChannelOffset != GetUserSpecifiedChannelOffset()))
        {
            asioOut.AudioAvailable -= OnAsioOutAudioAvailable;
            asioOut.Dispose();
            asioOut = null;
        }

        recordChannelCount = GetUserSpecifiedChannelCount();

        // create device if necessary
        if (asioOut == null)
        {
            asioOut = new AsioOut(comboBoxAsioDevice.Text);
            asioOut.InputChannelOffset = GetUserSpecifiedChannelOffset();
            asioOut.InitRecordAndPlayback(null, recordChannelCount, 44100);
            asioOut.AudioAvailable += OnAsioOutAudioAvailable;
        }

        filename = new string[recordChannelCount];
        writer = new WaveFileWriter[recordChannelCount];

        for (int i = 0; i < recordChannelCount; i++)
        {
            filename[i] = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), $"Record{i+1}"  + ".wav");
            writer[i] = new WaveFileWriter(fileName[i], new WaveFormat(44100, recordChannelCount));
        }
        
        asioOut.Play();
        timer1.Enabled = true;
        SetButtonStates();
    }

    void OnAsioOutAudioAvailable(object sender, AsioAudioAvailableEventArgs e)
    {
      #pragma warning disable 618
        float[] samples = new float[2 * 44100 * GetUserSpecifiedChannelCount()];
        samples = e.GetAsInterleavedSamples();
      #pragma warning restore 618
        
        int offset = 0;
        for (int i = 0; i < writer. Length; i++)
        {
            //writer[i].WriteSamples(samples, 0, samples.Length); //works but writes same thing
            writer[i].WriteSamples(samples, offset, 1); //Not working
            offset += 1;
        }
    }

谢谢

C# Naudio ASIO

评论


答:

0赞 Timothy Ayodele 10/4/2023 #1

因此,显然您可以对 getasinterleavedsamples 进行交错处理。该过程称为交错数组,即将数组存储在数组中。因此,下面的函数将有助于将各个样本放入其自己的浮点数组中:

    public static void DeInterleave(float[] interleavedData, int channels, out float[][] deinterleavedData)
    {
        int samplesPerChannel = interleavedData.Length / channels;
        deinterleavedData = new float[channels][];

        for (int channel = 0; channel < channels; channel++)
        {
            deinterleavedData[channel] = new float[samplesPerChannel];

            for (int sample = 0; sample < samplesPerChannel; sample++)
            {
                int interleavedIndex = sample * channels + channel;
                deinterleavedData[channel][sample] = interleavedData[interleavedIndex];
            }
        }
    }

您可以使用以下代码获取每个单独的样本浮点数:

float[][] deinterleavedData;
DeInterleave(samples, channels, out deinterleavedData);

然后遍历 deinterleavedData 以获取示例。 我希望它能帮助到一些人。