0

对于这个问题,我进行了研究,但我不确定我是否一直在寻找合适的术语?也许有人可以帮助...

我正在使用 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];
    }
}

[编辑] 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

不起作用的是它没有创建对象的单个实例和/或每个实例的属性根据频率不断变化,这不是我想要实现的行为;我想要的是将每个对象创建在某个高度并保持这种状态,然后在它旁边创建一个新对象,依此类推,就像每秒左右一样。

有意义吗?我仍在试图弄清楚如何提出正确的问题。谢谢,布里

4

1 回答 1

0

好的,据我了解您需要这样做,也许这会有所帮助:

尝试将指针存储在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);

从这里删除 draw 方法并bldg在每一帧上绘制 every 。将此添加到您的绘图方法中:

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

将与绘图不直接相关的所有内容移动到 testApp 的更新方法中会是一个更好的做法。例如,将您的创作和填充矢量内容移动到更新方法。

于 2011-08-15T13:29:27.923 回答