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.
IndexProgramming Questions & HelpSyntax Questions › Add data to Array/String
Page Index Toggle Pages: 1
Add data to Array/String (Read 2444 times)
Add data to Array/String
Mar 30th, 2010, 2:51am
 
Hi,

I'm writing a program which can record sounds and play them by hitting the keys "0-9". Recording and playing works fine.

Now I want to play those sounds in a specific order by hitting the keys, and processing shall save what key I hit at what time (in ms). I want to save this data in a string or array to be able to play it again without hitting all those buttons again.

Example:
Hitting key "2" at the time "2530" ms saves "2 2530" or whatever to an array or string.
Later I want to use the saved data to play the sound which appears by hitting key "2" at "2530" ms automatically.

The problem is, I haven't got a clue about saving data like this. I'm totally new to arrays/strings and stuff like this. The Reference didn't help me much.

Could anyone post an example how it could work?

Thx a lot!!
Re: Add data to Array/String
Reply #1 - Mar 30th, 2010, 4:26am
 
alright.
this is a pretty dirty draft of a ways you should go...

i created a class that saves the key you press and the the frame, i used frames instead of millis as they are easier to check later, you can still convert it to millis with some work if you want to.

anyway, recording starts when the sketch is started. then everytime a key is pressed, the key and the frame is added to an arraylist. when done with recording. you can press space to start the play.
it then plays what you just recorded.
pretty simple. but need some more work...

Code:
ArrayList keys;
PFont myfont;
boolean play = false;
int playStart;
void setup() {
size(600,400,P2D);
smooth();
background(0);
keys = new ArrayList();
myfont = createFont("Arial",60);
textFont(myfont);

}

void draw() {
fill(0,10);
rect(0,0,width,height);

if(play){
for (int i = 0; i < keys.size()-1; i++) {
Tone tone = (Tone) keys.get(i);
if(frameCount-playStart==tone.frames) tone.printKey();
}
}
}

void keyPressed(){
keys.add(new Tone(frameCount,key));
println("Pressed key "+ key + " at "+ frameCount);
fill(255,0,0);
text(key, width/2,height/2);
if(key==' '){
play = true;
playStart = frameCount;
}

}


class Tone {
char keys;
int frames;
Tone(int _frames,char _keys){
keys = _keys;
frames = _frames;
}

void printKey(){
fill(255);
text(keys, width/2,height/2);
}
}


Re: Add data to Array/String
Reply #2 - Mar 30th, 2010, 4:31am
 
Two classical ways (at least):
- Beginner's solution: have two arrays, one of keys, one of times, and grow the arrays simultaneously on each note.
Works, is relatively simple, but not satisfying for an experimented programmer, as there is no strong coupling between the two arrays.
- Alternative: use a simple class (here, used as data structure) to store the key-time pair, and store the instances in an array list, more suited to growing data.
Advantage: at the cost of the usage of a "scary" "advanced" concept (class), there is better coupling of the data, and it is more efficient.
Moreover, it can grow, eg. you can easily add duration of the note. You can even add a method to play the note. Etc.

Example with class (untested):
Code:
class Note
{
 char key;
 long time;
}
ArrayList notes = new ArrayList();
// With Java 1.5 syntax: ArrayList<Note> notes = new ArrayList<Note>();

void keyPressed()
{
 Note note = new Note();
 note.key = key; // Filter out wrong keys!
 note.time = millis();
 notes.add(note);
}

void playBack()
{
 for (int i = 0; i < notes.size(); i++)
 {
   Note note = (Note) notes.get(i); // Cast not necessary with Java 1.5 syntax
   playNote(note);
 }
}

Actually, my code for playBack isn't good, it should use draw() I think. Something like:
Code:
int currentNodeIdx;
Note currentNote;
long startOfPlay;
boolean bPlaying;
void playBack()
{
 startOfPlay = millis();
 currentNoteIdx = 0;
 currentNote = notes.get(0);
 bPlaying = true;
}

void draw()
{
 if (bPlaying && millis() - startOfPlay > currentNote.time)
 {
   if (currentNodeIdx >= notes.size()
   {
endPlayBack(); // Set bPlaying to false
   }
   // Next note
   currentNote = notes.get(currentNoteIdx++);
   playNote(note);
 }
}
Re: Add data to Array/String
Reply #3 - Mar 30th, 2010, 5:01am
 
i always like comparing PhiLhos and mine solution of a problem when we both work on it at the same time without knowing.
Re: Add data to Array/String
Reply #4 - Mar 30th, 2010, 8:21am
 
Thank you, both of you.
I especially took a look at Cedric's solution and it makes totally sense.
But when it comes to my program, I don't really know where to put in the reference to my audio samples.
Is there another possibility to record the order of my sounds?
Perhaps with LineOut or something? (I tried this before but it didn't work).
Thanks again for your commitment, but I guess I'm just too less experienced in processing, and I don't have a book or something at the moment.


Code:

import ddf.minim.*;
import ddf.minim.signals.*;

Minim minim;
AudioInput in;
AudioRecorder recorder1;
AudioRecorder recorder2;
AudioSample sound1;
AudioSample sound2;

int pad = 0;

void setup() {
background(0);
size(600, 400);

// Get Line In
minim = new Minim(this);
in = minim.getLineIn(Minim.STEREO, 2048);
recorder1 = minim.createRecorder(in, "sound1.wav", true);
recorder2 = minim.createRecorder(in, "sound2.wav", true);

// Pad colours
noStroke();
fill(255, 85, 0);
rect(0, 0, 200, 200);
fill(255, 128, 66);
rect(200, 0, 200, 200);
fill(254, 170, 128);
rect(400, 0, 200, 200);
fill(255, 150, 0);
rect(0, 200, 200, 200);
fill(254, 180, 73);
rect(200, 200, 200, 200);
fill(254, 203, 128);
rect(400, 200, 200, 200);
}

void draw() {
float ms = millis() % 10000;

// Which pad?
if (mouseX > 0 && mouseX < 200 && mouseY > 0 && mouseY < 200) {
pad = 1;
}
if (mouseX > 200 && mouseX < 400 && mouseY > 0 && mouseY < 200) {
pad = 2;
}
}

// Recording
void keyReleased() {
// Checken, if cursor is over Pad1
if (pad == 1) {
if (key == 'r') {
// Start/stop recording
if (recorder1.isRecording()) {
recorder1.endRecord();
}
else {
recorder1.beginRecord();
}
}
// Save recording
if (key == 's') {
recorder1.save();
println("Pad1 has a sound.");
}
}
// Play Pad1
if ( key == '1' ) {
sound1 = minim.loadSample("sound1.wav", 2048);
sound1.trigger();
}

if (pad == 2) {
if (key == 'r') {
if (recorder2.isRecording()) {
recorder2.endRecord();
}
else {
recorder2.beginRecord();
}
}
if (key == 's') {
recorder2.save();
println("Pad2 has sound.");
}
}
if ( key == '2' ) {
sound2 = minim.loadSample("sound2.wav", 2048);
sound2.trigger();
}

}

// Stop tone with quitting program
void stop()
{
in.close();
minim.stop();
super.stop();
}

Page Index Toggle Pages: 1