Добавление в вектор объектов с атрибутами, определяемыми постоянно меняющимися значениями - PullRequest
0 голосов
/ 13 августа 2011

По этому вопросу я провел исследование, но не уверен, что искал правильные термины?Может быть, кто-то может помочь ...

Я пишу приложение в openframeworks, которое по сути является визуализатором звука.Я пытаюсь сделать так, чтобы программа создала и нарисовала прямоугольник в определенной точке, высота которой определяется частотой аудиовхода в момент создания прямоугольника.Затем я хочу, чтобы программа нарисовала рядом другой прямоугольник, высота которого определяется частотой в тот момент, и так далее, и так далее.(Я также планирую перемещать это влево каждый раз, чтобы он создавал очень длинную цепочку прямоугольников).Прямоугольники будут похожи на здания (нарисуйте городской пейзаж), поэтому я создал их класс с очень простыми атрибутами: положение, высота и т. Д., И основная работа (поправьте меня, если я ошибаюсь)будет в основной части приложения.Проблемы, с которыми я столкнулся, заключаются в рисовании объекта, а затем в том, что его высота соответствует частоте.Кроме того, я не хочу, чтобы высота прямоугольника изменялась после его создания, поэтому у меня возникают проблемы с правильным выполнением.Сейчас мне удалось создать только один большой прямоугольник, который мерцает вверх и вниз при вводе звука.Я не совсем уверен, как мне следует добавлять в вектор объект с правильными атрибутами каждую секунду и чтобы этот экземпляр свойства объекта оставался статичным.Я не уверен, правильно ли я задаю правильные вопросы, но, возможно, кто-то может помочь?

Вот верхний уровень кода приложения:

#include "testApp.h"

//--------------------------------------------------------------
void testApp::setup(){

    ofSetFrameRate(60);
    ofBackground(0,30,60);

    //sound stream setup and such
    ofSoundStreamSetup(0,2,this, 44100, BUFFER_SIZE, 4);
    left = new float[BUFFER_SIZE];
    right = new float[BUFFER_SIZE];

    FFTanalyzer.setup(44100, BUFFER_SIZE/2, 1);
    FFTanalyzer.peakHoldTime = 15; // hold longer
    FFTanalyzer.peakDecayRate = 0.95f; // decay slower
    FFTanalyzer.linearEQIntercept = 0.9f; // reduced gain at lowest frequency
    FFTanalyzer.linearEQSlope = 0.01f; // increasing gain at higher frequencies
    numOctaves=1;


    //control panel setup
    panel.setup("control", 770, 0, 300, 150);
    panel.addPanel("fft settings", 1, false);
    panel.setWhichPanel("fft settings");
    panel.addSlider("Number of Sub Octaves","NUM_OCT",  1, 1,12, false);

    //set up buildings
    for (int i = 0; i <  bldgs.size() ; i+= 20){

    }

}

//--------------------------------------------------------------
void testApp::update(){
    panel.update();
    if(numOctaves != panel.getValueI("NUM_OCT")){
        numOctaves = panel.getValueI("NUM_OCT");
        panel.setValueI("NUM_OCT", numOctaves,0);
        FFTanalyzer.setup(44100, BUFFER_SIZE/2, numOctaves);
    }



}

//--------------------------------------------------------------
void testApp::draw(){

    panel.draw();
    static int index=0;
    float avg_power = 0.0f;

    /* do the FFT   */
    myfft.powerSpectrum(0,(int)BUFFER_SIZE/2, left,BUFFER_SIZE,&magnitude[0],&phase[0],&power[0],&avg_power);


    for (int i = 0; i < (int)(BUFFER_SIZE/2); i++){
        freq[i] = magnitude[i];
    }
    FFTanalyzer.calculate(freq);
    float binDrawWidth = (ofGetWidth()-20)/FFTanalyzer.nAverages;



//float bldgHeighTemp;
for (int i = 0; i <  1000 ; i+=30){
    for (int f = 0; f < (int)(BUFFER_SIZE/2); f++){
        bldg temp;

        freqs[i] = freq[f]*-6;
        temp.bldgPosX = i;
        temp.bldgPosY = ofGetHeight()/2;
        temp.bldgWidth = 30;
        temp.bldgHeight = freqs[i];
        temp.draw();

        bldgs.push_back(temp);
    }
}






}

//--------------------------------------------------------------
void testApp::keyPressed(int key){

}

//--------------------------------------------------------------
void testApp::keyReleased(int key){

}

//--------------------------------------------------------------
void testApp::mouseMoved(int x, int y ){

}

//--------------------------------------------------------------
void testApp::mouseDragged(int x, int y, int button){
    panel.mouseDragged(x,y,button);
}

//--------------------------------------------------------------
void testApp::mousePressed(int x, int y, int button){
    panel.mousePressed(x,y,button);
}

//--------------------------------------------------------------
void testApp::mouseReleased(int x, int y, int button){
    panel.mouseReleased();
}

//--------------------------------------------------------------
void testApp::windowResized(int w, int h){

}
//--------------------------------------------------------------
void testApp::audioReceived     (float * input, int bufferSize, int nChannels){
    // samples are "interleaved"
    for (int i = 0; i < bufferSize; i++){
        left[i] = input[i*2];
        right[i] = input[i*2+1];
    }
}

[edit] testapp.h

#ifndef _TEST_APP
#define _TEST_APP


#include "ofMain.h"
#include "fft.h"
#include "FFTOctaveAnalyzer.h"
#include "ofxControlPanel.h"
#include "bldg.h"

#define BUFFER_SIZE 512

class testApp : public ofBaseApp{

    public:
        void setup();
        void update();
        void draw();

        void keyPressed  (int key);
        void keyReleased(int key);
        void mouseMoved(int x, int y );
        void mouseDragged(int x, int y, int button);
        void mousePressed(int x, int y, int button);
        void mouseReleased(int x, int y, int button);
        void windowResized(int w, int h);

        void audioReceived  (float * input, int bufferSize, int nChannels);

        ofxControlPanel  panel;
        int numOctaves;


        FFTOctaveAnalyzer FFTanalyzer;

        float * left;
        float * right;
        int     bufferCounter;
        fft     myfft;

        float magnitude[BUFFER_SIZE];
        float phase[BUFFER_SIZE];
        float power[BUFFER_SIZE];
        float freq[BUFFER_SIZE/2];

        vector <float> freqs;
        vector <bldg> bldgs;
};

#endif

что не работает, так это то, что он не создает отдельные экземпляры объекта и / или атрибуты каждого экземпляра постоянно меняются в зависимости от частоты, а это не то поведение, которое я пытаюсьдостижения;я хочу, чтобы каждый объект создавался на определенной высоте и оставался таким же образом, затем рядом с ним создавались новые, и т. д., и т. п., каждую секунду или около того.

Имеет ли смысл?Я все еще пытаюсь понять, как задавать правильные вопросы.Спасибо, Бри

1 Ответ

0 голосов
/ 15 августа 2011

Хорошо, насколько я понимаю вашу проблему, вам нужно сделать это, может быть, это поможет:

Попробуйте сохранить указатели в вашем bldgs векторе

vector<bldg*> bldgs;

и добавьте в него новые объекты с помощью

    bldg* temp;

    freqs[i] = freq[f]*-6;
    temp->bldgPosX = i;
    temp->bldgPosY = ofGetHeight()/2;
    temp->bldgWidth = 30;
    temp->bldgHeight = freqs[i];

    bldgs.push_back(temp);

уберите метод рисования отсюда и рисуйте каждый bldg в каждом кадре. добавьте это к вашему методу рисования:

for(int i = 0; i < bldgs.size(); i++)
{
    bldgs[i]->draw();
}

Лучше было бы переместить все, что не имеет непосредственного отношения к рисованию, для добавления в метод обновления вашего testApp. так, например, перенесите ваше создание и заливку векторного материала в метод обновления.

...