We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
Page Index Toggle Pages: 1
Sonia <--> Ess (Read 3745 times)
Sonia <--> Ess
Jun 17th, 2005, 3:55am
 
I'm having quite a bit of fun with both Sonia and Ess, but I do  bemoan the fact Ess has no live import support (as far as I understand). I'm currently trying to grab samples from the line-in port with Sonia, but I want to use Ess' methods for subsequent processing. My logic (or lack thereof) is as follows:

1. record sample using sonia's LiveInput.startRec(sample)
2. copy the live input data to a temp buffer using sonia's sample.read(buffer[])
3. access ess' buffer with channel.loadSamples()
4. write the temp buffer to ess' channel buffer using channel.setFrame() in a for loop.
5. updating ess' buffer using channel.updateSamples()
6. play/process channel using channel.play(), etc.

I'm having nothing but troubles with this methodology. First of all, the sample data from sonia is a float array, and the channel data is a byte array. I tried type conversion, and the sketch runs, but all i get is an array full of 0's. If i try a straight arraycopy(), I get an array out of bounds error.

Is this at all possible? if so, am I on the right track? I'll post code if it's worth it.

Thanks...
Re: Sonia <--> Ess
Reply #1 - Jun 17th, 2005, 2:29pm
 
i think that may work - although i don't know why you're not being able to do the conversion. better yet i hope that ess and sonia will unite into one super-lib one of these days (or at least consolidate some functions)

in the meantime, which features are you missing in sonia?

amit
Re: Sonia <--> Ess
Reply #2 - Jun 17th, 2005, 2:54pm
 
Thanks for the validation! I'll take a closer look at the type conversion...if I do get this working, I'm afraid all the array copying will be a performance liability. I guess I'll see...As for Sonia's features, I'd like to see more in the way of effects, e.g., Ess' fade, reverb, filters, etc.

Thanks...

~pN~
Re: Sonia <--> Ess
Reply #3 - Jun 17th, 2005, 3:59pm
 
Ok, got the type conversion working. Ess now plays the grabbed data. However, my fears about performance have been confirmed. There's a definite pause in the sketch when the data is transferred. Is there any way to do this in the background, say using threads? I know of the ability to use threads in Java, but have never done so. Is it even possible in Processing?

~pN~
Re: Sonia <--> Ess
Reply #4 - Jun 20th, 2005, 6:18am
 
Hey there pinkNoise, do you want to post your code? I am super busy right now but I might be able to tell you what's possible in terms of optimization.

I've been sitting on an update that deals with one latency issue for like a month now, I just haven't had time to finish testing it (sometime next week I hope).
Re: Sonia <--> Ess
Reply #5 - Jun 20th, 2005, 6:45pm
 
Krister,

Here's the code. Thanks for taking a look! ~pN~


//THIS PROGRAM USES SONIA TO CAPTURE LIVE SOUND INPUT AND//
//COPIES THE SAMPLE TO AN ESS CHANNEL OBJECT FOR PLAYBACK//

import krister.Ess.*;
import pitaru.sonia_v2_9.*;

Sample mySample;
Channel myChannel;
float[] tempBuffer;

int numBands = 512;
int rate = 60;
int currentChannel = 0;
int sampleLength = 5;
int sampleRate = 44100;
int numFrames = sampleRate*sampleLength;

void setup(){

 size(200,200);
 framerate(rate);
 background(0);
 noLoop();
 //START SONIA AND LIVE INPUT, CREATE EMPTY SAMPLE OBJECT//
 Sonia.start(this);
 LiveInput.start(numBands);
 mySample = new Sample(numFrames);
 //START ESS, CREATE A TEMP BUFFER AND AN EMPTY CHANNEL OBJECT//
 Ess.start(this);
 tempBuffer = new float[numFrames];
 myChannel = new Channel(numFrames);
}

void draw(){

  LiveInput.startRec(mySample); //START RECORDING LIVE INPUT//
  delay(1000*sampleLength);     //WAIT TILL SAMPLE FRAMES ARE FULL//
                                //THERE MUST BE A BETTER WAY!//
  mySample.read(tempBuffer);    //COPIES SAMPLE DATA TO FLOAT ARRAY//
  myChannel.loadSamples();      //ACCESS ESS CHANNEL DATA ARRAY//
 
  //THE FOLLOWING WRITES THE FLOAT ARRAY TO THE ESS DATA ARRAY//
  //OF TYPE INT. THE FLOAT ARRAY HAS VALUES BETWEEN 1 AND -1,//
  //SO SCALE DATA AND CAST TO INT. MUST BE A BETTER WAY TO DO THIS//
 
  for(int i=0; i<tempBuffer.length; i++){
      myChannel.setFrame(myChannel.samples,i,int(tempBuffer[i]*pow(10,5)));
  }
 
  myChannel.updateSamples(); //PUSH DATA INTO THE CHANNEL OBJECT//
  myChannel.play(); //PLAY THE CHANNEL//
}

//CLEAN UP SONIA AND ESS//

public void stop(){
   Sonia.stop();
   Ess.stopAll();
   Ess.stop();
   super.stop();
}
Re: Sonia <--> Ess
Reply #6 - Jun 21st, 2005, 5:19pm
 
pitaru,

is there a way to handle the end recordings or the recommencement of recordings with events? would this increase too much latency?

something like having to implement functions like:
Code:

void sampleFullEvent(Sample mySample){
mySample.read(tempBuffer); // to have a copy of the buffer and process it
}


for the case of a startRecLoop() after the execution of the sampleFullEvent(Sample s) the LiveInput would go back to the first frame of the sample and keep recording.

this could avoid things like (although there are maybe other ways to avoid this with the current version of sonia):
Quote:
   LiveInput.startRec(mySample); //START RECORDING LIVE INPUT//
  delay(1000*sampleLength);     //WAIT TILL SAMPLE FRAMES ARE FULL//
       //THERE MUST BE A BETTER WAY!//
  mySample.read(tempBuffer);    //COPIES SAMPLE DATA TO FLOAT ARRAY//


i have no idea at all yet of sound programming, so it might be nonsense. sorry, if its the case.
Re: Sonia <--> Ess
Reply #7 - Jun 21st, 2005, 9:02pm
 
I was wondering the same thing. Started experimenting with Sample.getCurrentFrame() in a conditional loop to check whether or not the buffer was full and then start playing instead of using delay(), but I was having problems. Think it might be the behavior of LiveInput.startRec() when it appears in a loop. For instance,

void draw{
 LiveInput.startRec(mySample);
 mySample.play();
}

This works fine for playback, but my guess is that the sample buffer never gets filled completely, as the current frame pointer is set to zero when startRec is called. At least I think this is the case. Can someone confirm this?

In the meantime, a little test:

void setup(){
 size(100,100);
 background(0);
 framerate(1);
 int numFrames = 44100;
 Sonia.start(this);
 LiveInput.start(numBands);
 mySample = new Sample(numFrames);
}

void draw(){
 LiveInput.startRec(mySample);
 println(mySample.getCurrentFrame());
 mySample.play();
}

When it's run at framerate(1), the output is a series of numbers very close to the number of samples @ 44100. Something like 44033, 42369, etc.  A test at framerate(100) results in much lower numbers, around 500 or less. If I remove the mySample.play() statement from the loop, only zeros are returned. This I did not expect.

Pitaru, perhaps you can shed some light on what's going on behind the scenes of LiveInput.startRec()?

Thanks,

~pN~

Re: Sonia <--> Ess
Reply #8 - Jun 29th, 2005, 6:10am
 
Hey, still haven't had time to look at the code, will give it a shot this weekend! K
Page Index Toggle Pages: 1