2015-09-14 5 views
0

Так что я чувствую, что Google устает пытаться помочь мне в этом.Передача указателя массива float через расширение/оболочку python - SndObj-library

Я пытался поэкспериментировать с библиотекой 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)

Хорошо, достаточно справедливо. Я проверяю (автоматически сгенерированную) документацию и некоторый пример кода в Интернете и обнаруживаю, что он также хочет целое число размер. Сказал и сделал (мне нравится, как они это делают, я думаю, это, по крайней мере, датированный код в примере).

В любом случае, новый аргумент; новая ошибка:

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

Я не испытывал вообще в C++, который я считаю, это библиотеки «родной» (простите мое отсутствие надлежащей терминологии) язык, но я уверен, что я взял что он хочет иметь float array/vector в качестве второго аргумента (первый из которых - self). Тем не менее, я с трудом справляюсь с этим. Разве это не то, что у меня уже есть float array/vector? Я также, среди прочего, пробовал использовать float вместо float32 в первой строке и float (32768) в четвертом случае безрезультатно.

Любая помощь, предложение или отзыв будут очень благодарны!

EDIT: Стала неуверены поплавка вектора/части массива и снова пошел к авто-документы:

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

Так что я бы сказал, что по крайней мере, C++ хочет флоат массив/вектор, хотя Конечно, я могу ошибаться в оболочке python.

UPDATE По просьбе PRUNE (в о том, что сообщение об ошибке не просит вектор поплавка, но говорят, что это ошибка), я попытался inputing различного числа (INT, int32 и т.д. .) вместо векторов. Однако, видя, что я все еще получаю то же сообщение об ошибке и сохраняю EDIT выше, я бы сказал, что на самом деле он должен быть флоат-вектором.

UPDATE2 После некоторых намеков из saulspatz я изменил заголовок вопроса и теги, чтобы лучше сформулировать свою проблему. Я сделал еще один поход по этому же пути, но я еще не извлек ничего полезного.

UDATE3 решаемые

ответ

0

Так что, наконец, удалось заставить его работать (с некоторой помощью очень дружелюбный автор обложек)!

Оказывается, в библиотеке песочницы есть класс floatArray, который используется для передачи массивов float в 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 
1

На самом деле, проблема противоположная: Pushin принимает массив целых чисел. Сообщение об ошибке жалуется что вы дали ему плавает. Попробуйте это вместо вашего вызова PushIn

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

, а затем подайте int_sine вместо синуса в PushIn.

+0

Благодарит Вас за быстрый ответ! Это действительно объяснило бы многое! Тем не менее, я все равно получаю то же сообщение об ошибке ... Я также проверил массив, для какого типа он содержался, чтобы убедиться, и неудивительно, что это _int32_. Я также пытался с _int_, но это не имело никакого значения. – JohanPI

1

У меня нет ответа на ваш вопрос, но у меня есть некоторая информация для вас, которая слишком длинная, чтобы вписаться в комментарий, и что я думаю, может оказаться полезным. Я посмотрел на источник того, что я считаю последней версией, 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* означает указатель на float; in_vector - это всего лишь идентификатор. Я прочитал сообщение об ошибке, чтобы означать, что функция получила float, когда ожидала, что указатель будет плавать. В программе на C++ вы можете передать указатель на float, передав имя массива float, хотя это не единственный способ сделать это.

Я ничего не знаю о том, как программируются расширения python, извините. Из того, что я вижу, obj.PushIn(sine,256) выглядит правильно, но это наивный взгляд.

Возможно, с этой информацией вы можете сформулировать другой вопрос (или найти другой тег), который привлечет внимание тех, кто знает о написании расширений python в C/C++.

Надеюсь, это поможет.

+0

Удивительная информация, большое спасибо! Я расскажу об этом. – JohanPI

+0

@JohanPL Вы очень желанны. Когда вы найдете ответ, пожалуйста, дайте мне знать. Вы раздражали мое любопытство. – saulspatz