|
Author |
Topic: LiveOutputEvent - manual sample looping (Read 530 times) |
|
js
|
LiveOutputEvent - manual sample looping
« on: May 13th, 2004, 9:15am » |
|
Hello. I'm looking into how to use LiveOutputEvent in Sonia for playing back samples more flexibly instead of using Sample objects, but there's something that doesn't work properly. In this case, I have a mono 16-bit 44.1kHz sample ("adv2_mono.aiff") that I want to loop, using a variable, loopPos, which is the number of the current frame. For some reason, the sample skips, jumps and restarts very often. Can somebody help me, please? int streamSize = 8192; Sample mySample; float[] sampleData; int sampleFrames; int loopPos; void setup(){ // setup sample size(200,200); Sonia.start(this,44100); mySample = new Sample("adv2_mono.aif"); sampleFrames = mySample.getNumFrames(); sampleData = new float[sampleFrames]; mySample.read(sampleData); loopPos = 0; LiveOutput.start(streamSize,streamSize*2); LiveOutput.startStream(); } void loop(){ } void liveOutputEvent(){ for(int i=0;i<LiveOutput.data.length;i++) { LiveOutput.data[i] = sampleData[loopPos]; loopPos++; // end reached, start again from beginning of sample (loop) if (loopPos == sampleFrames) loopPos = 0; } } public void stop(){ Sonia.stop(); super.stop(); }
|
|
|
|
pitaru
|
Re: LiveOutputEvent - manual sample looping
« Reply #1 on: May 13th, 2004, 3:12pm » |
|
Hmm.. your code seems to work fine with an aiff sample i tried. I notice that you are hardcoding the stream size with - int streamSize = 8192; Are you sure this is the size of your sample. To be sure, you could add this in the setup .. streamSize = sampleFrames; Also, which system and Processing/Sonia version are you using? amit
|
|
|
|
js
|
Re: LiveOutputEvent - manual sample looping
« Reply #2 on: May 13th, 2004, 5:56pm » |
|
I'm using Processing V68 and Sonia V2.6_c9. No, the streamSize is just arbitrarily set (2^13), and my sample is something like 18032 frames, but I want to be able to handle samples of any length, independantly of the streamSize. I thought that the global loopPos variable could be used for this, since the feeding of a sample to the stream might take several calls to liveOutputEvent, but somehow it doesn't. Thanks for a very nice library!
|
|
|
|
pitaru
|
Re: LiveOutputEvent - manual sample looping
« Reply #3 on: May 13th, 2004, 9:57pm » |
|
Ahh... i smell a bug somewhere. I need to take a look. btw - there's a newer version of Sonia available, but it has the same problem. this will be fixed in the next version! sorry! amit
|
|
|
|
pitaru
|
Re: LiveOutputEvent - manual sample looping
« Reply #4 on: May 15th, 2004, 12:11am » |
|
OK, can you please try out this file with your program? http://pitaru.com/sonia/download/beta/sonia_v2_8_beta.jar Simply replace this file with the current sonia_v2_7.jar file in the code folder. if it works, i'l package it into the next sonia version. amit
|
|
|
|
js
|
Re: LiveOutputEvent - manual sample looping
« Reply #5 on: May 18th, 2004, 9:20am » |
|
Thanks Amit! The looping works a bit better now, but there are still pops in the beginning of the loop. However, I tried several different options for liveOutputEvent(), and strangely enough, this very similar piece of code works: void liveOutputEvent(){ for(int i=0;i<LiveOutput.data.length;i++) { LiveOutput.data[i] = sampleData[loopPos]; // end reached, start again from beginning of sample (loop) if (loopPos++ == sampleFrames) loopPos = 0; } } What's making it more confusing is that the reference manual for processing describes "++" in the wrong way. Usually (or, at least in C++) the operation is done at the end of the whole command, so that if (loopPos++ == sampleFrames) { } would first compare loopPos to sampleFrames, and increase its value by 1 afterwards. This can be demonstrated by just running the example for the "++" command (it doesn't work as described). Anyway, this doesn't explain why this latter piece of code works better. Any suggestions? /johan
|
|
|
|
pitaru
|
Re: LiveOutputEvent - manual sample looping
« Reply #6 on: May 18th, 2004, 2:59pm » |
|
Johan, i'm not sure why loopPos++ works better for you. On my machine i get the predictable missing-frame pop sound. Which system are you working with. > but there are still pops in the beginning of the loop Do you mean at the beginning of the LiveOutput loop, or at the beginning of the Sample's loop? I've tried your code with a simple sine-wave sample (http://pitaru.com/sonia/download/beta/sine.wav) and it sounds squeaky clean. It's important that the sample itself loops cleanly. Here's my code: int streamSize; Sample mySample; short[] sampleData; float[] fsampleData; int sampleFrames; int loopPos; void setup(){ // setup sample size(200,200); Sonia.start(this,11050); mySample = new Sample("sine.aiff"); sampleFrames = mySample.getNumFrames(); streamSize = 256; sampleData = new short[sampleFrames]; fsampleData = new float[sampleFrames]; mySample.read(sampleData); mySample.read(fsampleData); loopPos = 0; LiveOutput.start(streamSize, streamSize*2); LiveOutput.startStream(); } void loop(){ } void liveOutputEvent(){ for(int i=0;i<=streamSize;i++) { float amp = 0.5; LiveOutput.data[i] = fsampleData[loopPos] * amp; loopPos++; // end reached, start again from beginning of sample (loop) if (loopPos == sampleFrames){ loopPos = 0; } } } public void stop(){ Sonia.stop(); super.stop(); } amit
|
« Last Edit: May 18th, 2004, 3:00pm by pitaru » |
|
|
|
|
js
|
Re: LiveOutputEvent - manual sample looping
« Reply #7 on: May 19th, 2004, 9:16am » |
|
Thanks for the code. I tried it, and it works perfect with an increased streamSize of 1024. This is probably due to that I'm working on an old IBM ThinkPad 600 series with a staggering 64Mb of RAM + Win200. This whole thing is very strange, though. A summary: If I use my old code from the first post, it seems as if I get clicks in the beginning of each LiveOutput loop. I edited the sample so that it runs perfectly smooth, but it makes no difference. Also, the pops seem to coincide with reading from the harddrive while the program is running. Could it be a virtual memory error? But on the other hand, if I change the code so that it reads past the sample, like this: void liveOutputEvent(){ for(int i=0;i<LiveOutput.data.length;i++) { LiveOutput.data[i] = sampleData[loopPos]; // end reached, start again from beginning of sample (loop) if (loopPos++ == sampleFrames) loopPos = 0; } } it works fine, but not if I do this: void liveOutputEvent(){ for(int i=0;i<LiveOutput.data.length;i++) { LiveOutput.data[i] = sampleData[loopPos]; loopPos++; // end reached, start again from beginning of sample (loop) if (loopPos == (sampleFrames+1)) loopPos = 0; } } To add to the confusion, reading past the sample only works with my samples, not with "sine.wav". I'll try experimenting more tonight - it could be a problem with my soundfile-editor. Thanks for all your kind help this far! /johan
|
|
|
|
mattgilbert
|
Re: LiveOutputEvent - manual sample looping
« Reply #8 on: May 21st, 2004, 3:59am » |
|
I had just run into a similar problem, and the sonia 2.8 beta solved it! Thanks to both of you for finding and dealing with this problem, and thanks especially to pitaru for sonia! matt
|
|
|
|
pitaru
|
e: LiveOutputEvent - manual sample looping
« Reply #9 on: May 21st, 2004, 7:48pm » |
|
my pleasure matt. there's a new beta here: http://pitaru.com/sonia/download/beta/sonia_v2_8_beta_2.jar This version should further optimize performance with LiveOutput. It also fixes the functionality of mySample.getSpectrum(fftbins, sampleFrame) -- for non real-time fft analysis of sample data. I'll soon document the various new features. amit
|
|
|
|
|