Передача указателя массива с плавающей точкой через расширение / оболочку Python — 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)

Это дало мне ошибку

Ошибка типа: SndObj_PushIn () принимает ровно 3 аргумента (2 дано)

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

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

Ошибка типа: в методе ‘SndObj_PushIn’, аргумент 2 типа ‘float *’

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

Любая помощь, предложение или совет будет высоко ценится!

РЕДАКТИРОВАТЬ:
Стал неуверенным в части вектора / массива с плавающей точкой и снова отправился в автодокументы:

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

Поэтому я бы сказал, что, по крайней мере, C ++ хочет массив / вектор с плавающей точкой, хотя я, конечно, могу ошибаться насчет оболочки Python.

ОБНОВИТЬ
В соответствии с запросом Чернослива (говоря, что сообщение об ошибке не запрашивает вектор с плавающей точкой, но говорит, что это ошибка), я попытался ввести другое целое число (ИНТ,int32, и т.д.) векторы вместо. Однако, увидев, что я все еще получаю то же сообщение об ошибке и имея в виду вышеупомянутый РЕДАКТИРОВАТЬ, я бы сказал, что это на самом деле должен быть вектор с плавающей точкой в ​​конце концов.

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

UDATE3
РЕШИТЬ

0

Решение

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

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

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

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

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

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

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

1

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

Оказывается, в библиотеке-песочнице есть класс 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
0
По вопросам рекламы [email protected]