首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >CSCore:从纯数据回放浮点数组

CSCore:从纯数据回放浮点数组
EN

Stack Overflow用户
提问于 2015-12-25 17:41:43
回答 1查看 1K关注 0票数 1

我正在用C#编写一个程序,它使用libpd库与纯数据通信(更多信息:http://libpd.cc/)

我的纯数据补丁仅仅是创建了一个正弦波。

我编写了一些测试代码,以查看是否从纯数据修补程序中获得任何数据。LibPD.Process方法将示例写入外部缓冲区数组,并且内容是-1到1之间的连续值:

代码语言:javascript
复制
// Initialise Pd with 0 input and 2 output channels and a samplerate of 44100. Project dependent.
int pdOpen = -1;
pdOpen = LibPD.OpenAudio(0, 2, 44100);

if (pdOpen != 0)
{
    Console.WriteLine("Error opening audio... exiting");
    return;
}

string patchFile = @"..\..\..\test.pd";
int patch = LibPD.OpenPatch(patchFile);
LibPD.ComputeAudio(true);

//Read from Process Function...
// The size of each buffer must be the product of the number of channels, the number of ticks, 
// and the number of samples per tick. (The number of samples per tick is the value 
// returned by libpd_blocksize(), i.e., 64.)

int ret;
float[] outbuffer = new float[2 * 1 * LibPD.BlockSize]; // Size = 128

for (int i = 0; i < 10; i++)
{
    ret = LibPD.Process(1, new float[0], outbuffer);
    Thread.Sleep(1000);
}

LibPD.ClosePatch(patch);
LibPD.Release();

因此,我确信我正在从我的补丁中获得处理过的数据。

现在,我想使用CSCore回放这个浮点数组。我在文档中找到了ISampleSource接口,我认为这是完成这一任务的正确方法。我在接口实现的读取方法中尝试了这样的方法:

代码语言:javascript
复制
...

public PureDataSource()
{
    _WaveFormat = new WaveFormat(44100, 16, 2);

    int pdOpen = -1;
    pdOpen = LibPD.OpenAudio(0, 2, 44100);

    if (pdOpen != 0)
    {
        Console.WriteLine("Error opening audio... exiting");
        return;
    }

    string patch = @"..\..\..\test.pd";
    _Patch = LibPD.OpenPatch(patch);
    LibPD.ComputeAudio(true);
}

...

public int Read(float[] buffer, int offset, int count)
{
    LibPD.Process(1, new float[0], buffer);

    return count;
}

但这不管用-我只听到刺耳的声音(猜怎么着)。我知道这与Read方法的缓冲区大小有关,但是我可以在哪里配置它呢?LibPd的处理功能如下所示:

代码语言:javascript
复制
The size of each buffer must be the product of the number of channels, the      number of ticks, 
and the number of samples per tick. (The number of samples per tick is the value 
returned by libpd_blocksize(), i.e., 64.)

在我的例子中,是:两个通道(输出通道),一个滴答,每个滴答的样本数是64 -> 128。

编辑:我编写了一个PureDataSource类,它使用上面的信息实现了ISampleSource接口:

代码语言:javascript
复制
class Program
{
    static void Main(string[] args)
    {
        PureDataSource pdSource = new PureDataSource();
        WasapiOut soundOut = new WasapiOut();

        soundOut.Initialize(pdSource.ToWaveSource());

        soundOut.Play();
        Thread.Sleep(5000);
        soundOut.Stop();
    }
}

class PureDataSource : ISampleSource
{
    public long Length
    {
        get
        {
            return 0;
        }
    }

    public long Position
    {
        get
        {
            return 0;
        }

        set
        {
            throw new NotImplementedException();
        }
    }
    private WaveFormat _WaveFormat;
    public WaveFormat WaveFormat
    {
        get
        {
            return _WaveFormat;
        }
    }

    private int _Patch;
    public int Patch
    {
        get { return _Patch; }
        //set { _Patch = value; }
    }

    public PureDataSource()
    {
        _WaveFormat = new WaveFormat(44100, 16, 2);

        // Initialise Pd with 2 ins and outs and a samplerate of 44100. Project dependent.
        int pdOpen = -1;
        pdOpen = LibPD.OpenAudio(0, 2, 44100);

        if (pdOpen != 0)
        {
            Console.WriteLine("Error opening audio... exiting");
            return;
        }

        string patch = @"..\..\..\test.pd";
        _Patch = LibPD.OpenPatch(patch);
        LibPD.ComputeAudio(true);
    }

    public void Dispose()
    {
        LibPD.ClosePatch(_Patch);
        LibPD.Release();
    }

    public int Read(float[] buffer, int offset, int count)
    {
        int ticks = 1;

        int pdBufferPos = 0;
        float[] pdBuffer = new float[2 * ticks * LibPD.BlockSize];
        LibPD.Process(ticks, new float[0], pdBuffer);

        for (int i = offset; i < count; i++)
        { 
            if (pdBufferPos >= pdBuffer.Length)
            {
                pdBufferPos = 0;
                LibPD.Process(ticks, new float[0], pdBuffer);
            }

            buffer[i] = pdBuffer[pdBufferPos];
            pdBufferPos++;
        }            

        return count;
    }
}

Read方法用LibPD.Process提供的输出填充整个缓冲区(这是一个每次大小为128个的浮点数数组)。

我现在可以听到正弦波,但是有很大的劈啪声--似乎没有连续地处理样品。有什么办法解决这个问题吗?

EN

回答 1

Stack Overflow用户

发布于 2016-01-03 22:28:03

但这不管用-我只听到刺耳的声音(猜怎么着)。我知道这与Read方法的缓冲区大小有关,但是我可以在哪里配置它呢?

你不能“配置”它。如果WasapiOut请求一定数量的数据,那么它就掌握在您手中,您需要返回多少数据。从指定的buffer开始,用所需的数据填充offset。返回提供的样本数。这就是你“配置”它的方式。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34465033

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档