0

So I'm feeling that Google is getting tired of trying to help me with this.

I've been trying to experiment some with the SndObj library as of late, and more specifically the python wrapper of it.

The library is kind enough to include a python example to play around with, the only issue being it to get it to work. 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)

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. 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 *'

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). 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.

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.

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. 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.

UPDATE2 After some hints from saulspatz I've changed the question title and tags to better formulate my problem. I did some further googling according to this as well, but am yet to dig out anything useful.

UDATE3 SOLVED

JohanPI
  • 161
  • 9

3 Answers3

1

Actually, the problem is the opposite: PushIn takes an array of integers. The error message is complaining that you gave it floats. Try this in place of your call to 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.

Prune
  • 76,765
  • 14
  • 60
  • 81
  • Thank you for your speedy answer! This would indeed explain a whole lot! However I still receive the exact same error message... I also checked the array for what type it contained just to make sure, and it unsurprisingly was _int32_. I also tried with _int_ but it didn't make a difference. – JohanPI Sep 14 '15 at 18:20
1

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. In SndObj.h the definition of PushIn is

  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. (I presume this would be the number of elements in your array, and 256 is right.) The float* means a pointer to float; in_vector is just an identifier. 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.

I don't know anything about how python extensions are programmed, I'm sorry to say. From what I'm seeing, obj.PushIn(sine,256) looks right, but that's a naive view.

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++.

I hope this helps.

saulspatz
  • 5,011
  • 5
  • 36
  • 47
1

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. I'm guessing that they included that after the numpy-test.py was written which threw me for a loop.

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
JohanPI
  • 161
  • 9