通过 python extension/wrapper – SndObj-library 传递浮点数组指针

Passing a float array pointer through a python extension/wrapper – SndObj-library

所以我觉得 Google 已经厌倦了尝试帮助我解决这个问题。

最近我一直在尝试使用 SndObj 库进行一些实验,更具体地说是它的 python 包装器。

该库非常友好,包含一个 python 示例供您试用,唯一的问题是让它正常工作。下面的最后一行让我很受伤:

from sndobj import SndObj, SndRTIO, HarmTable, Oscili, SND_OUTPUT
from scipy import zeros, pi, sin, float32
import numpy

sine = numpy.array([256],float32)
for i in range(sine.size):
    sine[i] = 0.5 * sin((2 * pi * i) / sine.size)
    sine *= 32768

obj = SndObj()
obj.PushIn(sine,256)

在原始代码中是:

obj.PushIn(sine)

这给了我错误

TypeError: SndObj_PushIn() takes exactly 3 arguments (2 given)

好吧,很公平。我检查了(自动生成的)文档和网络上的一些示例代码,发现它也需要一个整数 size。说完了(我喜欢他们的做法,我猜至少是示例中的过时代码)。

总之,新论点;新错误:

TypeError: in method 'SndObj_PushIn', argument 2 of type 'float *'

我在 C++ 方面一点经验都没有,我认为这是库的 "native"(请原谅我缺乏正确的术语)语言,但我很确定我已经掌握了它想要的一个 float array/vector 作为它的第二个参数(第一个是 self)。但是,我很难做到这一点。我不是已经有一个浮动 array/vector 了吗?除其他外,我还尝试在第一行使用 float 而不是 float32float(32768)第四次无果

如有任何帮助、建议或提示,我们将不胜感激!

编辑: 不确定浮动 vector/array 部分并再次转到 auto-docs :

int SndObj::PushIn  (   float *     vector,
int     size 
)

所以我想说至少 c++ 需要一个浮点数 array/vector,尽管我当然对 python 包装器仍然是错误的。

更新 根据 Prune 的要求(说错误消息不是要求浮点向量,而是说那是错误),我尝试输入不同的整数 (int, int32, 等) 向量代替。但是,看到我仍然收到相同的错误消息并牢记上面的编辑,我会说它实际上应该是一个浮点向量。

更新2 在 saulspatz 的一些提示之后,我更改了问题标题和标签以更好地表述我的问题。我也根据这个做了一些进一步的谷歌搜索,但我还没有挖掘出任何有用的东西。

UDATE3 已解决

实际上,问题恰恰相反:PushIn 采用整数数组。错误信息是抱怨你给了它浮动。试试这个来代替你对 PushIn

的调用
int_sine = numpy.array([256],int32)
int_sine = [int(x) for x in sine]

然后将 int_sine 而不是正弦输入 PushIn。

我真的无法回答您的问题,但我为您提供了一些信息,这些信息太长而无法发表评论,但我认为这些信息可能会有用。我查看了最新版本 SndObj 2.6.7 的来源。在SndObj.h中PushIn的定义是

  int PushIn(float *in_vector, int size){
    for(int i = 0; i<size; i++){
      if(m_vecpos >= m_vecsize) m_vecpos = 0;
      m_output[m_vecpos++] = in_vector[i];
    }
    return m_vecpos;
  }

所以很明显,size就是要推送的元素个数。 (我假设这是你的数组中元素的数量,256 是正确的。)float* 表示指向浮点数的指针; in_vector 只是一个标识符。我读到的错误消息表示该函数在期望一个浮点指针时收到了一个浮点数。在 C++ 程序中,您可以通过传递浮点数数组的名称来传递指向浮点数的指针,但这不是唯一的方法。

我对 python 扩展程序的编程方式一无所知,抱歉。据我所见,obj.PushIn(sine,256) 看起来不错,但这是一个幼稚的观点。

也许有了这些信息,您可以提出另一个问题(或找到另一个标签),这将吸引知道在 C/C++ 中编写 python 扩展的人的注意。

希望对您有所帮助。

所以终于设法让它工作了(在非常友好的包装器作者的帮助下)!

事实证明沙箱库中有一个 floatArray class 用于将浮点数组传递给 c++ 函数。我猜他们在写了 numpy-test.py 之后包括了它,这让我陷入了循环。

运行代码:

from sndobj import SndObj, SndRTIO, SND_OUTPUT, floatArray
from scipy import pi, sin

# ---------------------------------------------------------------------------
# Test PushIn

# Create 1 frame of a sine wave in a numpy array
sine = floatArray(256)
for i in range(256):
     sine[i] = float(32768*0.5 * sin((2 * pi * i) / 256))

obj = SndObj()
obj.PushIn(sine,256)

outp = SndRTIO(1, SND_OUTPUT)
outp.SetOutput(1, obj)

# Repeatedly output the 1 frame of sine wave
duration = outp.GetSr() * 2  # 2 seconds
i = 0
vector_size = outp.GetVectorSize()
while i < duration:
    outp.Write()
    i += vector_size