【问题标题】:How to play back a array of samples after reading them from an 'ISampleSource'从“ISampleSource”读取样本后如何播放样本数组
【发布时间】:2018-12-02 07:56:59
【问题描述】:

所以,我有一段代码将ISampleSource 读入float[][],第一个数组层用于通道数,第二个用于通道内的样本数据。我将获取这些数据并尝试对其应用信号处理,但是出于调试目的,我可能想要操作样本数组然后回放它,以便我可以“听到”代码在做什么。有没有一种简单的方法来获取ISampleSource.Read 返回的数据并将其粘贴回 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;
}

【问题讨论】:

  • 这听起来可能很愚蠢,但这很常见,您是否打开了音量或插入了音频播放器?
  • 是的,为了理智,我一直在玩一个非玩弄的“原始”ISampleSource,它可以正常播放,然后我将同一个文件加载到不同的ISampleSource,做我的过程提取通道数据,然后将其放入我创建的此类中。我在输出中得到的只是一条消息,表示线程在我调用play 时立即终止。
  • 没有抛出异常吗??
  • 不,没有错误,没有任何迹象。
  • 您是否在调试模式下启动了您的程序?有什么线程终止的信息吗?

标签: c# cscore


【解决方案1】:

与其尝试将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;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-31
    • 2017-07-12
    • 1970-01-01
    相关资源
    最近更新 更多