Сохранение значений в буфере в методе функции класса

Я программирую плагин VST DSP на С++.

Я создаю серию полосовых фильтров в «банке фильтров». Я реализовал класс фильтра в своем заголовке (включая функцию) и правильно построил конструктор/деструктор в .cpp.

Я могу передавать значения методу и также возвращать их. Однако проблемы лежат в области хранения данных в буферах в функции. Кажется, что каждый раз, когда вызывается метод функции, значения, хранящиеся в буфере, сбрасываются (или, наоборот, изначально не сохраняются правильно). Следовательно, то, что передается обратно, не является «полным».

Любые советы очень ценятся!

н.б. Этот пост был обновлен новым кодом:

Вот классы:

class aFilterL

{

класс друзей Beat_to_Midi;

общедоступный: aFilterL(); ~фильтрL();

float fOut1_l;
float filterOut1_l;
float Out_1_l;
float Out_2_l;
float* buffer_Out_1_l;
float* buffer_Out_2_l;

виртуальный float aFilterMethodL (с плавающей запятой a0, с плавающей запятой a1, с плавающей запятой a2, с плавающей запятой b1, с плавающей запятой b2, с плавающей запятой inputL, с плавающей запятой prevInput1L, с плавающей запятой prevInput2L) {

Out_1_l = buffer_Out_1_l[0];
Out_2_l = buffer_Out_2_l[0];

filterOut1_l = (a0 * inputL) + (a1 * prevInput1L) + (a2 * prevInput2L) - (b1 * Out_1_l) - (b2 * Out_2_l) + 1.0E-25;

fOut1_l = filterOut1_l;
buffer_Out_2_l[0] = buffer_Out_1_l[0];
buffer_Out_1_l[0] = fOut1_l;  
return fOut1_l;

}

};

класс aFilterR {

класс друзей Beat_to_Midi;

общедоступный: aFilterR(); ~фильтрR();

float fOut1_r;
float filterOut1_r;
float Out_1_r;
float Out_2_r;
float* buffer_Out_1_r;
float* buffer_Out_2_r;

виртуальный float aFilterMethodR (float a0, float a1, float a2, float b1, float b2, float inputR, float prevInput1R, float prevInput2R) {

Out_1_r = buffer_Out_1_r[0];
Out_2_r = buffer_Out_2_r[0];

filterOut1_r = (a0 * inputR) + (a1 * prevInput1R) + (a2 * prevInput2R) - (b1 * Out_1_r) - (b2 * Out_2_r) + 1.0E-25;

fOut1_r = filterOut1_r;
buffer_Out_2_r[0] = buffer_Out_1_r[0];
buffer_Out_1_r[0] = fOut1_r;
return fOut1_r;

} };

Затем он создается/удаляется в cpp следующим образом:

aFilterL::aFilterL()

{ fOut1_l = 0.f; filterOut1_l = 0.f;

Out_1_l = 0.f;
Out_2_l = 0.f;

buffer_Out_1_l = new float [1];
buffer_Out_2_l = new float [1];

buffer_Out_1_l[0] = 0.f;
buffer_Out_2_l[0] = 0.f;

}

aFilterL::~aFilterL() {

if (buffer_Out_1_l)
    delete[] buffer_Out_1_l;
if (buffer_Out_2_l)
    delete[] buffer_Out_2_l;

}

aFilterR::aFilterR() { fOut1_r = 0.f;

filterOut1_r = 0.f;

Out_1_r = 0.f;
Out_2_r = 0.f;

buffer_Out_1_r = new float [1];
buffer_Out_2_r = new float [1];

buffer_Out_1_r[0] = 0.f;
buffer_Out_2_r[0] = 0.f;

}

aFilterR::~aFilterR() {

if (buffer_Out_1_r)
    delete[] buffer_Out_1_r;
if (buffer_Out_2_r)
    delete [] buffer_Out_2_r;

}

Наконец, это реализовано в функции processReplacing следующим образом:

void myPlugin::processReplacing (входы с плавающей запятой, выходные данные с плавающей запятой, VstInt32 sampleFrames) {

float* in1  =  inputs[0]; 
float* in2  =  inputs[1]; 
float* out1 = outputs[0]; 
float* out2 = outputs[1]; 

    aFilterL *my_aFilter1L = new aFilterL;
aFilterR *my_aFilter1R = new aFilterR;

в то время как (--sampleFrames >= 0) {

// Фильтрация входных данных

In

class aFilterL
l = буфер_In
class aFilterL
l[0];

In

class aFilterL
r = буфер_In
class aFilterL
r[0];

In

float fOut1_l;
float filterOut1_l;
float Out_1_l;
float Out_2_l;
float* buffer_Out_1_l;
float* buffer_Out_2_l;
l = буфер_In
float fOut1_l;
float filterOut1_l;
float Out_1_l;
float Out_2_l;
float* buffer_Out_1_l;
float* buffer_Out_2_l;
l[0];

In

float fOut1_l;
float filterOut1_l;
float Out_1_l;
float Out_2_l;
float* buffer_Out_1_l;
float* buffer_Out_2_l;
r = буфер_In
float fOut1_l;
float filterOut1_l;
float Out_1_l;
float Out_2_l;
float* buffer_Out_1_l;
float* buffer_Out_2_l;
r[0];

// Фильтр в управлении

буфер_In

float fOut1_l;
float filterOut1_l;
float Out_1_l;
float Out_2_l;
float* buffer_Out_1_l;
float* buffer_Out_2_l;
l[0] = буфер_In
class aFilterL
l[0];

буфер_In

float fOut1_l;
float filterOut1_l;
float Out_1_l;
float Out_2_l;
float* buffer_Out_1_l;
float* buffer_Out_2_l;
r[0] = буфер_In
class aFilterL
r[0];

buffer_In

class aFilterL
l[0] = *in1;

buffer_In

class aFilterL
r[0] = *in2;

// отправляем в функцию для обработки

returnL = my_aFilter1L->aFilterMethodL(0.000171f, 0.0f, -0.000171f, -1.999911f, 0.999943f, *in1, In

class aFilterL
l, In
float fOut1_l;
float filterOut1_l;
float Out_1_l;
float Out_2_l;
float* buffer_Out_1_l;
float* buffer_Out_2_l;
l);

returnR = my_aFilter1R->aFilterMethodR(0.000171f, 0.0f, -0.000171f, -1.999911f, 0.999943f, *in2, In

class aFilterL
r, In
float fOut1_l;
float filterOut1_l;
float Out_1_l;
float Out_2_l;
float* buffer_Out_1_l;
float* buffer_Out_2_l;
r);

// Отправляем выходные данные фильтра на выход

*out1 = возвращеноL;

*out2 = возвращеноR;

*in1++;

*in2++;

*выход1++;

*выход2++; }}


person Forge_13    schedule 02.02.2011    source источник
comment
деструктор должен быть виртуальным, если у вас есть виртуальные методы и ваши указатели не инициализированы... к счастью, возврат пропускает назначение, которое будет иметь неопределенное поведение.   -  person AJG85    schedule 02.02.2011


Ответы (2)


Знаете ли вы, что return немедленно выходит из функции? Таким образом, код после этого, который хранит значения в ваших буферах, никогда не выполняется.

Вместо этого вы должны поместить обратный вызов в конец функции.

Некоторые другие примечания:

  • Мне непонятно, зачем вам нужны указатели на буферы, если вы используете только первый элемент.
  • У вас есть повторяющийся код в функциях -L и -R. Вместо этого используйте два экземпляра класса «моно», чтобы хранить данные только для одного канала для каждого класса.
  • Вам (почти) никогда не нужно использовать this->. Просто оставьте это.
person Frederik Slijkerman    schedule 02.02.2011
comment
Это происходит как в aFilterMethodR, так и в aFilterMethodL - person ; 02.02.2011
comment
ах да. Я не понял этого. Я изменил это сейчас, и это изменило способ работы программы и то, что она выводит на слух. Однако выполнение некоторой оперативной отладки по-прежнему показывает значения 0,0, хранящиеся в буферах. что, в свою очередь, означает, что фильтр все еще не работает - person Forge_13; 02.02.2011
comment
1. мне это тоже кажется немного странным, но vst sdk довольно требователен к тому, как он обрабатывает данные буфера, эти значения инициализируются в конструкторе как buffer_Out_1_r = new float [1]; buffer_Out_1_r[0] = 0.f; 2. Теперь я создал 2 класса, aFilterL и aFilterR для ясности 3. Я удалили this-› и текущая функциональность такая же. Благодарность - person Forge_13; 02.02.2011
comment
Похоже, вам придется заняться отладкой самостоятельно! :-) - person Frederik Slijkerman; 02.02.2011
comment
О, я. Я все еще учусь, поэтому время от времени мой уровень становится немного выше моего. Я надеюсь, что моя и текущая функциональность такая же. выражение благодарности не показалось неблагодарным. спасибо было всеобъемлющим за ваш совет :) - person Forge_13; 02.02.2011

После создания моего нового вопроса о вложенных классах, найденного здесь, решение было нашел.

Классы фильтров объявлены в классе myPlugin.

Отсюда конструкторы и деструкторы строятся как:

myPlugin::aFilterL::aFilterL()
myPlugin::aFilterL::~aFilterL()

в конструкторе myPlugin создаются новые экземпляры:

aFilterL *my_aFilter1L = new aFilterL();

и последняя часть головоломки — убедиться, что они добавлены в качестве экземпляра к эффекту myPlugin:

aFilterL my_aFilter1L;
aFilterR my_aFilter1R;

Доступ к my_aFilter1L и т. д. теперь можно получить через processReplacing, и, похоже, он работает правильно.

Большое спасибо всем за вашу помощь в этом вопросе.

person Forge_13    schedule 03.02.2011