通过 python 扩展/包装器传递浮点数组指针 – SndObj-library
Posted
技术标签:
【中文标题】通过 python 扩展/包装器传递浮点数组指针 – SndObj-library【英文标题】:Passing a float array pointer through a python extension/wrapper – SndObj-library 【发布时间】:2015-09-14 17:28:44 【问题描述】:所以我觉得 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() 只需要 3 个参数(给定 2 个)
好吧,够公平的。我检查了(自动生成的)文档和网络上的一些示例代码,发现它也需要一个整数 size。言归正传(我喜欢他们的做法,我猜至少是示例中过时的代码)。
无论如何,新的论点;新错误:
TypeError:在方法“SndObj_PushIn”中,类型为“float *”的参数 2
我完全没有使用 c++ 的经验,我相信它是库的“原生”(请原谅我缺乏正确的术语)语言,但我很确定我已经知道它需要一个浮点数组/ vector 作为它的第二个参数(第一个是 self)。但是,我很难做到这一点。我不是已经有一个浮点数组/向量了吗?除其他外,我还尝试在第一行使用 float 而不是 float32 并在第四行使用 float(32768) 到否有用。
任何帮助、建议或提示将不胜感激!
编辑: 不确定浮点向量/数组部分并再次查看自动文档:
int SndObj::PushIn ( float * vector,
int size
)
所以我会说至少 c++ 需要一个浮点数组/向量,尽管我当然仍然对 python 包装器有误。
更新 根据 Prune 的要求(说错误消息不是要求浮点向量,而是说这是错误),我尝试输入不同的整数(int,int32等)向量代替。但是,看到我仍然收到相同的错误消息并牢记上面的 EDIT,我想说它实际上应该是一个浮点向量。
更新2 在 saulspatz 的一些提示之后,我更改了问题的标题和标签,以更好地表述我的问题。我也根据这个做了一些进一步的谷歌搜索,但还没有挖掘出任何有用的东西。
UDATE3 已解决
【问题讨论】:
【参考方案1】:实际上,问题恰恰相反:PushIn 接受一个整数数组。错误消息是抱怨你给它浮动。试试这个来代替你对 PushIn 的调用
int_sine = numpy.array([256],int32)
int_sine = [int(x) for x in sine]
然后将 int_sine 而不是正弦输入 PushIn。
【讨论】:
感谢您的快速答复!这确实可以解释很多!但是我仍然收到完全相同的错误消息...我还检查了数组中包含的类型,以确保它是int32。我也尝试了 int,但没有任何区别。【参考方案2】:我对你的问题没有真正的答案,但我有一些信息太长,无法在评论中显示,我认为这些信息可能会很有用。我查看了我认为是最新版本 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 扩展的人的注意力。
我希望这会有所帮助。
【讨论】:
很棒的信息,非常感谢!我会对此进行一些研究。 @JohanPL 不客气。当你找到答案时,请告诉我。你激起了我的好奇心。【参考方案3】:所以终于设法让它工作了(在非常友好的包装作者的帮助下)!
事实证明,沙盒库中有一个 floatArray 类,用于将浮点数组传递给 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
【讨论】:
以上是关于通过 python 扩展/包装器传递浮点数组指针 – SndObj-library的主要内容,如果未能解决你的问题,请参考以下文章
使用 CFFI 从 Python 传递指向 C 函数的指针的最佳方法