I'm writing a program that talks with Wekinator, but I'm having a problem with sending the feature names over OSC that I'm fairly certain is a problem with chuck. At the bottom of the code (see bottom of email) is the relevant method, sendOscFeatureNames(). When I run wekinator and get to the training screen, I run this code. The instant it sends the feature names to Wekinator (i.e., the instant it is run), an exception gets raised: " Exception in thread "Thread-4" java.lang.ArrayIndexOutOfBoundsException: 1536 at com.illposed.osc.utility.OSCByteArrayToJavaConverter.lengthOfCurrentS tring(Unknown Source) at com.illposed.osc.utility.OSCByteArrayToJavaConverter.readString(Unkno wn Source) at com.illposed.osc.utility.OSCByteArrayToJavaConverter.readArgument(Unk nown Source) at com.illposed.osc.utility.OSCByteArrayToJavaConverter.convertMessage(U nknown Source) at com.illposed.osc.utility.OSCByteArrayToJavaConverter.convert(Unknown Source) at com.illposed.osc.OSCPortIn.run(Unknown Source) at java.lang.Thread.run(Unknown Source) " This exception is not thrown when I replace numDataPoints[i] with a constant (like 5). Here is the entire .ck file. You can use it just like you would any OSC feature extractor with Wekinator. //Extracts the following for different numDataPoints //0 - centroidAvg //1 - centroidStdDev //2 - centroidMin //3 - centroidMax //4 - rmsAvg //5 - rmsStdDev //6 - rmsMin //7 - rmsMax //8 - fft bin with highest fval (highest over all windows) //... //whenever an amplitude > threshold is detected from input, computed over //numDataPoints 128-sample ffts that overlap by 64-samples // "127.0.0.1" => string hostname; OscSend xmit; xmit.setHost( hostname, 6448 ); OscSend xmit2; xmit2.setHost( hostname, 6448 ); //Custom objects adc => FFT f =^ RMS rms => blackhole; f =^ Centroid centroid => blackhole; f =^ Flux flux => blackhole; f =^ RollOff rolloff => blackhole; UAnaBlob b; //for storing the results from each window float rmsArr[50]; float cent[50]; float highestFFTBin[50]; //bin with highest fft fval float highestFFTVal[50]; //the actual value of the bin //Set up bin stuff 128 => int FFT_SIZE; FFT_SIZE => f.size; Windowing.hamming(64) => f.window; 1::second / 1::samp => float SR; SR/FFT_SIZE => float bin_width; //constants .5 => float threshold; 0 => int peakDetected; //flag if peak has been detected now => time lastPeakTime; 100::samp => dur peakWindow; 10::samp => dur peakPollRate; [1,5,10,15,20,25,30,35,40,45,50] @=> int numDataPoints[]; //list of numDataPoints values to try 1 => float rmsMultiplier; //so it isn't out of wek's range (this actually doesn't matter, leave it at 1) 0 => int currentlyAnalyzing; //flag if currently analyzing i.e. don't detect peak //Run the peak detector in parallel to set the peakDetected flag spork ~peakDetector(); spork ~sendOscFeatureNames(); //Extract features and send via osc when peak detected. while (true) { if (peakDetected) { <<<"Peak detected! Analyzing">>>; analyzeAndSend(); } .1::second => now; } //When peak detected, compute min, max, avg, and std. dev for centroid and rms //and send fun void analyzeAndSend() { 1 => currentlyAnalyzing; xmit.startMsg( "/oscCustomFeatures", "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); //Get all float and rms values for the maximum numDataPoints getRmsCentroidAndFFT(); for (0 => int i; i < 11; i++) { analyzeNumDataPoints(numDataPoints[i]) @=> float result[]; for (0 => int j; j < 9; j++) { result[j] => xmit.addFloat; } } <<<"done">>>; 0 => currentlyAnalyzing; } //populates rms, cent, and fft arrays fun void getRmsCentroidAndFFT() { 50 => int maxDataPoints; 128::samp => now; rms.upchuck(); for (0 => int i; i < maxDataPoints; 1 +=> i) { rms.fval(0) => rmsArr[i]; centroid.upchuck(); centroid.fval(0) => cent[i]; 0 => float highestBinMagnitude; 0 => int highestBin; f.upchuck(); //find highest bin for (1 => int j; j < FFT_SIZE; j++) { if (f.fval(j) > highestBinMagnitude) { f.fval(j) => highestBinMagnitude; j => highestBin; } } highestBin => highestFFTBin[i]; highestBinMagnitude => highestFFTVal[i]; } } //Analyze data using the specified number of data points, return the float array corresponding to //the osc message format described at top //requires that the arrays have been populated fun float[] analyzeNumDataPoints(int numDataPoints) { float centroidTotal; float centroidMin; float centroidMax; float centroidStdDev; float rmsTotal; float rmsMin; float rmsMax; float rmsStdDev; float highestBin; float highestBinMagnitude; new float[numDataPoints] @=> float centroidData[]; new float[numDataPoints] @=> float rmsData[]; //get 1st centroid and rms rmsArr[0] +=> rmsTotal; rmsArr[0] => rmsMin => rmsMax => rmsData[0]; cent[0] +=> centroidTotal; cent[0] => centroidMin => centroidMax => centroidData[0]; //do rest for (1 => int i; i < numDataPoints; i++) { rmsArr[i] +=> rmsTotal; Math.max( rmsArr[i], rmsMax ) => rmsMax; Math.min( rmsArr[i], rmsMin ) => rmsMin; rmsArr[i] => rmsData[i]; cent[i] +=> centroidTotal; Math.max( cent[i], centroidMax ) => centroidMax; Math.min( cent[i], centroidMin ) => centroidMin; cent[i] => centroidData[i]; //compute current highestBin if (highestFFTVal[i] > highestBinMagnitude) { highestFFTVal[i] => highestBinMagnitude; highestFFTBin[i] => highestBin; } } //calculate rmsTotal / numDataPoints => float rmsAvg; centroidTotal / numDataPoints => float centroidAvg; //get std dev float rmsDevSquaredTotal; float centroidDevSquaredTotal; for (0 => int i; i < numDataPoints; i++) { (rmsData[i] - rmsAvg)*(rmsData[i] - rmsAvg) +=> rmsDevSquaredTotal; (centroidData[i] - centroidAvg)*(centroidData[i] - centroidAvg) +=> centroidDevSquaredTotal; } Math.sqrt(rmsDevSquaredTotal / numDataPoints) => rmsStdDev; Math.sqrt(centroidDevSquaredTotal / numDataPoints) => centroidStdDev; float result[9]; centroidAvg => result[0]; centroidStdDev => result[1]; centroidMin => result[2]; centroidMax => result[3]; rmsAvg * rmsMultiplier => result[4]; rmsStdDev * rmsMultiplier => result[5]; rmsMin * rmsMultiplier => result[6]; rmsMax * rmsMultiplier => result[7]; highestBin => result[8]; return result; } //Pretty inefficient but does the trick //Looks for a peak in the last peakWindow fun void peakDetector() { while (true){ if (adc.last() > threshold || adc.last() < -1 * threshold) { 1 => peakDetected; // analyze now => lastPeakTime; } else if (now > lastPeakTime + peakWindow) { 0 => peakDetected; } peakPollRate => now; //This is silly; would be better do do a low-pass filter envelope and look for peaks there. But don't worry about it right now. } } //run in parallel to send osc feature names fun void sendOscFeatureNames() { while (true) { xmit2.startMsg( "/oscCustomFeaturesNames sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss"); for (0 => int i; i < 11; i++) { numDataPoints[i] => int n; xmit2.addString(n + "centroidAvg"); xmit2.addString(n + "centroidStdDev"); xmit2.addString(n + "centroidMin"); xmit2.addString(n + "centroidMax"); xmit2.addString(n + "rmsAvg"); xmit2.addString(n + "rmsStdDev"); xmit2.addString(n + "rmsMin"); xmit2.addString(n + "rmsMax"); xmit2.addString(n + "highestFFT"); } .1::second => now; } }
participants (1)
-
Kyle Hipke