简体   繁体   English

通过python扩展/包装传递浮点数组指针– SndObj-library

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

So I'm feeling that Google is getting tired of trying to help me with this. 因此,我感到Google厌倦了尝试为此提供帮助。

I've been trying to experiment some with the SndObj library as of late, and more specifically the python wrapper of it. 我最近一直在尝试使用SndObj库进行一些实验,更具体地说是它的python包装器。

The library is kind enough to include a python example to play around with, the only issue being it to get it to work. 该库足够友好,可以包含一个可运行的python示例,唯一的问题是可以使其正常工作。 The last line below is giving me a world of hurt: 下面的最后一行给了我一个痛苦的世界:

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)

In the original code it was: 在原始代码中,它是:

obj.PushIn(sine)

That gave me the error 那给了我错误

TypeError: SndObj_PushIn() takes exactly 3 arguments (2 given) TypeError:SndObj_PushIn()恰好接受3个参数(给定2个)

Alright, fair enough. 好吧,很公平。 I check the (automatically generated) documentation and some example code around the web and find that it also wants an integer size . 我在网上检查了(自动生成的)文档和一些示例代码,发现它也想要一个整数size Said and done (I like how they have, what I'm guessing is at least, dated code in the example). 说完了(我喜欢它们的状态,我猜至少是示例中的过时代码)。

Anyway, new argument; 无论如何,新的论点; new error: 新错误:

TypeError: in method 'SndObj_PushIn', argument 2 of type 'float *' TypeError:在方法“ SndObj_PushIn”中,类型为“ float *”的参数2

I'm not experienced at all in c++, which I believe is the library's "native" (excuse my lack of proper terminology) language, but I'm pretty sure I've picked up that it wants a float array/vector as its second argument (the first being self ). 我一点都没有C ++的经验,我相信这是库的“本机”(请问我缺乏适当的术语)语言,但是我很确定自己已经选择使用float数组/向量作为它的语言。第二个参数(第一个是self )。 However, I am having a hard time accomplishing that. 但是,我很难做到这一点。 Isn't what I've got a float array/vector already? 我已经没有浮点数组/向量了吗? I've also, among other things, tried using float instead of float32 in the first line and float(32768) in the fourth to no avail. 除其他外,我还尝试在第一行中使用float而不是float32 ,在第四行中使用float(32768)却无济于事。

Any help, suggestion or tip would be much appreciated! 任何帮助,建议或技巧将不胜感激!

EDIT: Became unsure of the float vector/array part and went to the auto-docs again: 编辑:不确定浮点矢量/数组部分,然后再次进入自动文档:

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

So I'd say that at least the c++ wants a float array/vector, although I can of course still be wrong about the python wrapper. 因此,我想至少要说c ++想要一个float数组/向量,尽管我当然仍然对python包装器有误。

UPDATE As per Prune's request (saying that the error message isn't asking for a float vector, but saying that that's the error), I tried inputing different integer ( int , int32 , etc.) vectors instead. 更新根据Prune的要求(说错误消息不是要浮点向量,而是说那是错误),我尝试输入其他整数( intint32等)向量。 However, seeing that I still got the same error message and keeping the EDIT above in mind, I'd say that its actually supposed to be a float vector after all. 但是,看到我仍然收到相同的错误消息并牢记上面的EDIT,我想说它实际上应该是浮点向量。

UPDATE2 After some hints from saulspatz I've changed the question title and tags to better formulate my problem. UPDATE2从saulspatz得到一些提示后,我更改了问题标题和标签以更好地解决我的问题。 I did some further googling according to this as well, but am yet to dig out anything useful. 我也根据此进行了进一步的谷歌搜索,但是还没有发现任何有用的东西。

UDATE3 SOLVED 解决了 UDATE3

Actually, the problem is the opposite: PushIn takes an array of integers. 实际上,问题恰恰相反:PushIn接受一个整数数组。 The error message is complaining that you gave it floats. 错误消息抱怨您给它浮动。 Try this in place of your call to PushIn 尝试此操作来代替对PushIn的调用

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

and then feed int_sine instead of sine to PushIn. 然后将int_sine代替正弦输入给PushIn。

I don't really have an answer to your question, but I have some information for you that's too long to fit in a comment, and that I think may prove useful. 对于您的问题,我确实没有答案,但是我为您提供的信息太长,无法在评论中显示,我认为这可能有用。 I looked at the source of what I take to be the latest version, SndObj 2.6.7. 我查看了最新版本SndObj 2.6.7的来源。 In SndObj.h the definition of PushIn is 在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;
  }

so it's clear that size is the number of elements to push. 因此很明显, size是要推送的元素数。 (I presume this would be the number of elements in your array, and 256 is right.) The float* means a pointer to float; (我想这将是数组中元素的数量,而256是正确的。) float*表示一个指向float的指针。 in_vector is just an identifier. in_vector只是一个标识符。 I read the error message to mean that the function received a float when it was expecting a pointer to float. 我读到错误消息,表示该函数在期望指针浮动时收到了浮动。 In a C++ program, you might pass a pointer to float by passing the name of an array of floats, though this is not the only way to do it. 在C ++程序中,您可以通过传递浮点数数组的名称来传递指向浮点数的指针,尽管这不是唯一的方法。

I don't know anything about how python extensions are programmed, I'm sorry to say. 很抱歉,我对python扩展的编程方式一无所知。 From what I'm seeing, obj.PushIn(sine,256) looks right, but that's a naive view. 从我所看到的, obj.PushIn(sine,256)看起来是正确的,但这是一个幼稚的视图。

Perhaps with this information, you can formulate another question (or find another tag) that will attract the attention of someone who knows about writing python extensions in C/C++. 也许有了这些信息,您就可以提出另一个问题(或找到另一个标签),该问题将引起那些了解用C / C ++编写python扩展的人的注意。

I hope this helps. 我希望这有帮助。

So finally managed to get it working (with some assistance the very friendly wrapper author)! 因此,终于设法使其工作了(在非常友好的包装作者的帮助下)!

It turns out that there is a floatArray class in the sandbox-library which is used for passing float arrays to the c++-functions. 事实证明,沙盒库中有一个floatArray类,用于将float数组传递给c ++函数。 I'm guessing that they included that after the numpy-test.py was written which threw me for a loop. 我猜想他们写了numpy-test.py之后就把它们包括在内,这让我陷入了循环。

Functioning code: 功能代码:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM