hi, just checked out OF tonight for the first time. Love the design and the idea.
However, I noticed that the sound support didn’t allow for reading in individual real-time buffer data from soundfiles (for oscilloscopes, etc) so I extended the OF sound class by including the following code in ofSoundPlayer.h and ofSoundPlayer.cpp:
in ofSoundPlayer.h:
class ofSoundPlayer{
public:
// ....
float * getWaveData(int nValues, int chan); // returns buffer of right or left channel as array of floats
private:
float waveDataValues[8192]; // added a private member for wave data
};
and then in ofSoundPlayer.cpp:
float * ofSoundPlayer::getWaveData(int nValues, int chan){
if (getIsPlaying() == true){
// set to 0
for (int i = 0; i < 8192; i++){
waveDataValues[i] = 0;
}
// check what the user wants vs. what we can do:
if (nValues > 8192){
printf("error in ofSoundPlayer::getWaveData, the maximum number of values is 8192 - you asked for %i\nwe will return 8192\n", nValues);
nValues = 8192;
} else if (nValues <= 0){
printf("error in ofSoundPlayer::getWaveData, you've asked for %i values, minimum is 1\n", nValues);
return waveDataValues;
}
// if chan > 1 then it is multichannel, we'll keep to stereo for now
if (chan > 1)
{
printf("error in ofSoundPlayer::getWaveData, the maximum number of channels is 2\n");
return waveDataValues;
}
// then he request is for right channel, but check to see if sound is stereo
else if (chan == 1)
{
int numChannels;
FMOD_Sound_GetFormat(sound, NULL, NULL, &numChannels, NULL);
if (numChannels != 2)
{
printf("error in ofSoundPlayer::getWaveData, the sound is not stereo, so returning mono channel");
chan = 0;
}
}
// now get the waveData information
FMOD_Channel_GetWaveData(channel, waveDataValues, nValues, chan);
return waveDataValues;
}
}
Here is a simple example of how to use it (and a test showing it works):
main.cpp:
#include "ofMain.h"
#include "demo.h"
//========================================================================
int main( ){
ofSetupOpenGL(640,480, OF_WINDOW);
ofRunApp(new demoApp());
}
demo.h:
#ifndef _DEMO_APP
#define _DEMO_APP
#include "ofMain.h"
#include "ofAddons.h"
class demoApp : public ofSimpleApp{
public:
void setup();
void update();
void draw();
void keyPressed (int key);
ofSoundPlayer demoSound;
bool isPlaying;
float * demoBuffer;
int bufferSize;
};
#endif
demo.cpp:
#include "demo.h"
//--------------------------------------------------------------
void demoApp::setup(){
isPlaying = false; // i wait on hitting "p" to play
//demoSound.loadSound("sounds/something.mp3");
demoSound.loadSound("sounds/artemis_drums.mp3");
bufferSize = 512; // some buffer size of your choosing
demoBuffer = new float[bufferSize];
// zero the buffers out
for (int i = 0; i < bufferSize; i++){
demoBuffer[i] = 0;
}
}
//--------------------------------------------------------------
void demoApp::update(){
ofBackground(80,80,20);
if (isPlaying)
{
// get the buffer data
float * newBuffer = demoSound.getWaveData(bufferSize, 0);
for (int i = 0;i < bufferSize; i++){
demoBuffer[i] = newBuffer[i];
}
}
}
//--------------------------------------------------------------
void demoApp::draw(){
int y = ofGetHeight(); // draw inside entire window, whatever size you want for demo
int x = 0;
int w = ofGetWidth();
int h = y;
float width = (float)(ofGetWidth()) / bufferSize;
// draw a line connecting the values in the buffer across the screen
for (int i = 0;i < bufferSize - 1; i++){
ofLine(x + i*width, y - h/2 - demoBuffer[i]*h,x + (i+1)*width, y - h/2 - demoBuffer[i+1]*h);
}
}
//--------------------------------------------------------------
void demoApp::keyPressed (int key){
if (key == 'p'){
if(isPlaying == false) {
demoSound.play();
isPlaying = true;
} else {
demoSound.stop();
isPlaying = false;
}
}
}
Does anybody think this would be a good addition to the sound support for the future? I guess maybe it’s just a straightforward wrapper around the FMOD function, but I feel like I don’t want to touch the OF source code as much as possible… if anything just so I don’t have to rewrite/reimplement code on future updates!
-Aaron
[/code]