对于这个问题,我做过研究,但我不确定我一直在寻找合适的术语?也许有人可以帮忙...
我正在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
不起作用的是它不是创建对象的单个实例和/或每个实例的属性根据频率不断变化,这不是我想要实现的行为;我想要的是每个对象在某个高度创建并保持这种状态,然后在它旁边创建一个新的对象,依此类推,就像每一秒左右一样。
有道理吗?我仍在试图弄清楚如何提出正确的问题。 谢谢, 布里
答案 0 :(得分: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);
从此处删除绘制方法,并在每个帧上绘制每个bldg
。将此添加到您的绘制方法:
for(int i = 0; i < bldgs.size(); i++)
{
bldgs[i]->draw();
}
将与draw直接相关的所有内容移到testApp的update方法中会更好。例如,移动你的创建并将向量内容填充到更新方法。