Batch processing sound files (i.e. not realtime).

Hi all,

OS X Lion 10.7.2, Xcode 4. Libraries ofxMaximillian.

I’m writing a program that gets the MFCCs of a .wav file, using maximillian to do the FFT work for me and then dumping all the values to a .txt file to use later with a clustering algorithm. It all works in realtime, perfectly. I do my audio processing in the audioRequested buffer and the file streaming in the update function. However, in the grand scheme of things, I don’t want this part of the program that I’m writing to work in realtime - I’d really like to select a file (or some files), then just dump off all the MFCCs as fast as I can to a txt file, so that I can use them in the next part of the program. I’ve been scratching my head about how to do this now for a while, thats why I thought i’d post here and see if anyone could shed some light.

I’ve tried doing all sorts, such as sticking the two parts together in the setup function, which yielded no results at all, the same goes with the update function. I’m starting to think that its because ofxMaxi requires information from the audioRequested method to get going - it is meant for realtime stuff. I hope theres a way around this, because I like openFrameworks, it will be very handy further down the road in this project and I like maximillian. I’m hoping that I don’t have to move away from using oF, or rewrite a part of ofxmaxi to do what i need to do, or write my own timing thread or something like that. Can’t see the wood through the trees currently.

Heres my code so far for this part, its fairly simple:

  
#pragma once  
  
#include "ofMain.h"  
#include "ofxMaxim.h"  
#include <sys/time.h>  
#include <iostream>  
#include <fstream>  
#include <sstream>  
#include "maxiMFCC.h"  
  
class testApp : public ofBaseApp{  
	  
public:  
	~testApp();/* deconsructor is very useful */  
	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 audioRequested 	(float * input, int bufferSize, int nChannels); /* output method */  
	void audioReceived 	(float * input, int bufferSize, int nChannels); /* input method */  
	  
	float 	* lAudioOut; /* outputs */  
	float   * rAudioOut;  
	  
	float * lAudioIn; /* inputs */  
	float * rAudioIn;  
	  
	int		initialBufferSize; /* buffer size */   
	int		sampleRate;  
	int i;  
	  
	/* stick you maximilian stuff below */  
	  
	double wave,sample,outputs[2], ifftVal;  
	maxiMix mymix;  
    int random_integer;  
      
    Boolean isStream;  
    ofstream myfile;  
    stringstream ss;  
      
	ofxMaxiFFTOctaveAnalyzer oct;  
	int nAverages;  
	float *ifftOutput;  
	int ifftSize;  
	  
	ofxMaxiIFFT ifft;  
	ofxMaxiFFT mfft;  
	int fftSize;  
	int bins, dataSize;  
	  
	float callTime;  
	timeval callTS, callEndTS;  
	  
	maxiMFCC mfcc;  
	double *mfccs;  
	  
	maxiSample samp;  
	  
	  
	  
};  
  

  
#include "testApp.h"  
#include "maximilian.h"  
  
  
  
  
//-------------------------------------------------------------  
testApp::~testApp() {  
	  
}  
  
  
//--------------------------------------------------------------  
void testApp::setup(){  
	  
	ofEnableAlphaBlending();  
	ofSetupScreen();  
	ofBackground(0, 0, 0);  
	ofSetFrameRate(60);  
	  
	sampleRate 			= 44100;  
	initialBufferSize	= 512;	      
      
	lAudioOut			= new float[initialBufferSize];  
	rAudioOut			= new float[initialBufferSize];  
	lAudioIn			= new float[initialBufferSize];  
	rAudioIn			= new float[initialBufferSize];  
	  
	memset(lAudioOut, 0, initialBufferSize * sizeof(float));  
	memset(rAudioOut, 0, initialBufferSize * sizeof(float));  
	  
	memset(lAudioIn, 0, initialBufferSize * sizeof(float));  
	memset(rAudioIn, 0, initialBufferSize * sizeof(float));  
	  
    samp.load(".../MFCC/bin/data/sound2.wav");  
      
	samp.getLength();  
	  
	fftSize = 1024;  
	mfft.setup(fftSize, 512, 256);  
	ifft.setup(fftSize, 512, 256);  
      
    srand((unsigned)time(0));   
    random_integer = rand();   
      
    ss << ".../MFCC/bin/data/" << random_integer << ".txt";  
	  
    isStream = false;  
      
      
	nAverages = 12;  
	oct.setup(sampleRate, fftSize/2, nAverages);  
	  
	mfccs = (double*) malloc(sizeof(double) * 13);  
	mfcc.setup(512, 42, 13, 20, 20000, sampleRate);  
	  
	ofxMaxiSettings::setup(sampleRate, 2, initialBufferSize);  
	ofSoundStreamSetup(2,2, this, sampleRate, initialBufferSize, 4);/* Call this last ! */  
	  
	ofSetVerticalSync(true);  
      
	  
}  
  
//--------------------------------------------------------------  
void testApp::update(){  
      
      
    myfile.open(".../bin/data/somethingsomethin.txt");  
      
    if(myfile.is_open()){  
  
                for(i=0; i < 14; i++){  
                    myfile << i << " " << mfccs[i] << ";" << " " ;  
                    cout << i << " " << mfccs[i]  << ";" << " " ;  
                      
                }  
        myfile.close();  
          
    }  
      
  
      
}  
  
//--------------------------------------------------------------  
void testApp::draw(){  
      
}  
  
//--------------------------------------------------------------  
void testApp::audioRequested 	(float * output, int bufferSize, int nChannels){  
	//	static double tm;  
for (int i = 0; i < bufferSize; i++){  
    
    wave = samp.play();  
      
	if (mfft.process(wave)) {  
			mfft.magsToDB();  
			oct.calculate(mfft.magnitudesDB);  
			mfcc.mfcc(mfft.magnitudes, mfccs);  
		}  
         
		mymix.stereo(wave, outputs, 0.5);  
          
		lAudioOut[i] = output[i*nChannels    ] = outputs[0];   
		rAudioOut[i] = output[i*nChannels + 1] = outputs[1];  
	}  
	  
	  
	  
}  
  
//--------------------------------------------------------------  
void testApp::audioReceived 	(float * input, int bufferSize, int nChannels){	  
      
      
	for (int i = 0; i < bufferSize; i++){  
          
	}  
	  
}  
  
//--------------------------------------------------------------  
void testApp::keyPressed(int key){  
      
    if (key == 'o'){  
		isStream = !isStream;  
          
	}  
      
	  
}  

Theres a fair amount of stuff in the .h thats not used. Pay no mind, it’s just there because I will be using it further down the development road.

i’ve had to use libsndfile to load sounds for offline processing.

https://github.com/scratchml/ofxXwax/blob/master/example-AudioToScratchML/src/ofApp.cpp

http://ofdsp.blogspot.com/2011/07/installing-libsndfile-with-xcode.html

So I have been trying to dabble a bit with ofxxwax. However, it needs the libsndfile libraries, and for the life of me I cannot get them installed properly. I am no wizard with the terminal but can follow instructions, and from what I understand (also from the qt creator error console) I need to install the x64 64 version? According to the instructions of libsndfile that would be these commands:

./configure CC=“gcc -arch x86_64”
./configure CXX=“g++ -arch x86_64”
./configure CPP=“gcc -E” CXXCPP=“g++ -E”

which I can all run without errors. However, I still get a ‘ld: symbol(s) not found for architecture x86_64’ error in QT.

The link that Kyle is giving refers to how it ‘used to work’ but those commands are not working at least for me in terminal anymore.

Anybody had more success in using libsndfile with openframeworks?