从“ ISampleSource”读取样本后如何播放样本数组

时间:2018-06-22 19:48:00

标签: c# cscore

因此,我有一段代码可以将ISampleSource读入float[][],第一个数组层用于通道数,第二个数组层用于通道内的样本数据。我将获取这些数据并尝试对其进行信号处理,但是出于调试目的,我可能希望操纵示例数组,然后进行回放,以便“听到”代码在做什么。是否有一种简单的方法来获取ISampleSource.Read返回的数据并将其重新粘贴到 new ISampleSource中,以便随后将其转换为IWaveSource并使用WasapiOut玩过吗?

这是我到目前为止尝试制作的类,您将float[][]传递给了WaveFormat并基本上将所有数据传递给了它,以便从中获得一个数据..但实际上并没有这样做任何东西。没有错误,没有播放..只是什么都不做。我在做什么错了?

private class SampleSource : ISampleSource
{
    public long Position { get; set; }
    public WaveFormat WaveFormat { get; private set; }
    public bool CanSeek => true;
    public long Length  => _data.Length;

    private float[] _data;
    private long readPoint = 0;

    public SampleSource(float[][] samples, int sampleRate, int bits, int channels)
    {
        WaveFormat = new WaveFormat(sampleRate, bits, channels);
        if (samples.Length <= 0) return;

        _data = new float[samples[0].Length * samples.Length];
        int cchannels = samples.Length;
        int sampleLength = samples[0].Length;

        for (var i = 0; i < sampleLength; i += cchannels)
            for (var n = 0; n < cchannels; n++)
                _data[i + n] = samples[n][i / cchannels];
    }

    public int Read(float[] buffer, int offset, int count)
    {
        if (_data.Length < Position + count)
            count = (int) (_data.Length - Position);

        float[] outFloats = new float[count];
        for (var i = 0; i < count; i++)
            outFloats[i] = _data[i + Position + offset];

        buffer = outFloats;
        Position += count;
        return count;
    }

    public void Dispose() =>_data = null;
}

1 个答案:

答案 0 :(得分:0)

我不需要尝试将buffer设置为新数组(这没有任何意义),而是需要直接写入buffer数组元素,以便可以在函数调用之外使用它们。我不太喜欢这种方式,也许是要解决一个我看不到的问题,但是很明显,这就是我正在使用的库的方式。

private class SampleSource : ISampleSource
{
    public long Position { get; set; }
    public WaveFormat WaveFormat { get; private set; }
    public bool CanSeek => true;
    public long Length  => _data.Length;

    private float[] _data;
    private long readPoint = 0;

    public SampleSource(float[][] samples, int sampleRate, int bits, int channels)
    {
        WaveFormat = new WaveFormat(sampleRate, bits, channels);
        if (samples.Length <= 0) return;

        _data = new float[samples[0].Length * samples.Length];
        int cchannels = samples.Length;
        int sampleLength = samples[0].Length;

        for (var i = 0; i < sampleLength; i += cchannels)
            for (var n = 0; n < cchannels; n++)
                _data[i + n] = samples[n][i / cchannels];
    }

    public int Read(float[] buffer, int offset, int count)
    {
        /*THIS IS THE CHANGED FUNCTION*/
        if (_data.Length < Position + count)
            count = (int) (_data.Length - Position);

        for (var i = 0; i < count; i++)
            buffer[i] = _data[i + Position + offset];

        Position += count;
        return count;
    }

    public void Dispose() =>_data = null;
}