С++ oop beginner - вернуть выходную сумму каждого созданного объекта в векторе за один вызов функции

у меня простой класс

#ifndef _VOICE
#define _VOICE
#include "maximilian.h"

class voice{
public:
    voice(int waveType);
    void setNote(double pitch,double amplitude);
    void triggerNote();
    void releaseNote();
    double getOutput();
    bool getState();
private:
    maxiOsc op;
    convert mtof;
    double amp;
    double freq;
    double out;
    int type;
    bool state;
};

#endif // _VOICE

#include "voice.h"

voice::voice(int waveType){
    type=waveType;
    state=false;
    out=0;
}

void voice::setNote(double pitch,double amplitude){
    freq=pitch;
    amp=amplitude;
}

void voice::triggerNote(){
    if(type==1)
        out=op.sinewave(mtof.mtof(freq))*amp;
    if(type==2)
        out=op.triangle(mtof.mtof(freq))*amp;
    if(type==3)
        out=op.saw(mtof.mtof(freq))*amp;
    if(type==4)
        out=op.square(mtof.mtof(freq))*amp;
    state=true;
}

void voice::releaseNote(){
    out=0;
    state=false;
}

bool voice::getState(){
    return state;
}

double voice::getOutput(){
    return out;
}

Затем я сохраняю эти голоса в векторе

Я хочу найти более эффективный способ доступа к выходной сумме всех объектов в векторе

это выглядит примерно так:

double PreMaster;
        PreMaster=voices[0].getOutput()+voices[1].getOutput()+voices[2].getOutput()+voices[3].getOutput()....(n-object)...;

(в моей программе это идет до 34)

(for) не работает, так как мне нужно одновременно выводить значение в каждом объекте...

внутри класса должен быть способ иметь глобальную функцию, которая будет возвращать выходную сумму каждого созданного объекта в пределах одного вызова функции...

Я новичок в oop, поэтому, пожалуйста, извините меня, если решение кажется очевидным. И заранее спасибо, если вы можете указать мне в полезном направлении.

РЕДАКТИРОВАТЬ:

У меня есть обратный вызов, который вызывается с частотой дискретизации (44100 Гц).

У меня есть вектор голосового объекта (они выводят простые формы волны синтезатора), чтобы сформировать звучащий аккорд, мне нужно суммировать вывод каждого голоса «одновременно».

Затем я передаю сумму на свою звуковую карту для каждого семпла с частотой дискретизации.

void testApp::audioOut (float * output, int bufferSize, int nChannels){

     for (int i = 0; i < bufferSize; i++){

         for(int j=0;j<voices.size();j++){
            if(keys[j]==true){
                voices[j].triggerNote();
            }
            else if(keys[j]==false)
                voices[j].releaseNote();
         }

        PreMaster=voices[0].getOutput()+voices[1].getOutput()+voices[2].getOutput()+voices[3].getOutput()
                          +voices[4].getOutput()+voices[5].getOutput()+voices[6].getOutput()+voices[7].getOutput()
                          +voices[8].getOutput()+voices[9].getOutput()+voices[10].getOutput()+voices[11].getOutput()
                          +voices[12].getOutput()+voices[13].getOutput()+voices[14].getOutput()+voices[15].getOutput()
                          +voices[16].getOutput()+voices[17].getOutput()+voices[18].getOutput()+voices[19].getOutput()
                          +voices[20].getOutput()+voices[21].getOutput()+voices[22].getOutput()+voices[23].getOutput()
                          +voices[24].getOutput()+voices[25].getOutput()+voices[26].getOutput()+voices[27].getOutput()
                          +voices[28].getOutput()+voices[29].getOutput()+voices[30].getOutput()+voices[31].getOutput()
                          +voices[32].getOutput()+voices[33].getOutput();

        MasterOut.stereo(PreMaster, outputs, 0.5);

        lAudioOut[i] = output[i*nChannels    ] = outputs[0]; /* You may end up with lots of outputs. add them here */
        rAudioOut[i] = output[i*nChannels + 1] = outputs[1];
        }
}

надеюсь, это немного прояснит...

Да, я забыл о +=, поэтому я протестировал его, и моя программа остановила вывод звуков. Когда я делаю это своим уродливым методом, он работает...


person user1650117    schedule 05.09.2012    source источник
comment
Взгляните на это: stackoverflow.com/questions/228783/   -  person chris    schedule 06.09.2012
comment
'for не работает, потому что...' Я не понимаю этот комментарий, что не так с double PreMaster = 0.0; for (int i = 0; i < 34; ++i) PreMaster += voices[i].getOutput();? Вы говорите, что это не работает, потому что вам «нужно выводить значение одновременно», объясните, пожалуйста, что вы имеете в виду.   -  person john    schedule 06.09.2012
comment
возможный дубликат функции шаблона с макросом - накапливать на векторе   -  person Bo Persson    schedule 06.09.2012
comment
@BoPersson Я думаю, что это отличается от возможного дубликата, потому что требуется вызов функции для каждого элемента контейнера. Я не мог придумать хороший способ сделать это с помощью std::accumulate (но я очень устал).   -  person juanchopanza    schedule 06.09.2012
comment
Вы можете указать функцию или функтор в качестве последнего параметра для std::accumulate. Это не обязательно должно делать только x + y, но может делать x + y.get_soemthing().   -  person Bo Persson    schedule 06.09.2012
comment
@BoPersson, но разве начальное значение не должно относиться к типу содержащихся элементов?   -  person juanchopanza    schedule 06.09.2012
comment
Не совсем. Это отдельный параметр шаблона, также задающий тип результата. Вход представляет собой пару итераторов. Их value_type должен (каким-то образом) соответствовать результату и оператору, но это довольно гибко.   -  person Bo Persson    schedule 06.09.2012
comment
@BoPersson Спасибо, конечно, ты прав. Я действительно спал. Я вернулся к решению, используя accumulate вместо for_each.   -  person juanchopanza    schedule 06.09.2012


Ответы (2)


Вы можете выполнить простой цикл, поскольку нет причин полагать, что for не работает, учитывая ваш пример кода:

double sum = 0;
for (const auto& v : voices) {
  sum += v.getOutput();
}

Другой вариант — использовать std::accumulate и подходящий функтор:

// function to sum voice's getOutput() to get running total
double addOutput(double sum, const voice& v) { return sum + voice.getOutput(); }
....
double sum = std::accumulate(voices.begin(), voices.end(), 0.0, addOutput);
person juanchopanza    schedule 05.09.2012

Пример:

int sum = 0;
for(std::vector<voice>::iterator i = voices.begin(); i != voices.end(); i++)
    sum += i->getOutput();
person perreal    schedule 05.09.2012