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 & HelpSound,  Music Libraries › My own sample bytes to an output - how! (Solved)
Page Index Toggle Pages: 1
My own sample bytes to an output - how!? (Solved) (Read 1176 times)
My own sample bytes to an output - how!? (Solved)
Nov 27th, 2009, 6:06am
 
Hi everyone.

Please excuse if this has been solved or answered earlier, but i am way too fresh at this as plain reading of examples would lead me to a clue.

I have read various examples using Ess and Minim, but somehow none of them made this certain thing i want to do.

I have loaded a sample (44khz, 16 bit wav) and i have all the values (words, 16bit) at hand in an array. I can display portions of the wave to the screen and i can scroll my pointer through the wave file.

Now - how do i manage to copy my sample16bit[] array into an audio buffer, with the effect, that at a given lenght (1024 words) this buffer will loop and playback the audio i have given into it?

I have examined minim´s "createSample" example, but - instead of using a free "container" (array) where values are generated into, it uses a sine function.

If only i could read values from a table or array and manually copy them into some whatever audio-playback buffer.

Can anybody help me?

best regards,
cB
Re: My own sample bytes to an output - how!?
Reply #1 - Nov 27th, 2009, 7:37am
 
I have finally made it, i believe, looking at the soundScrawl applet by Matt Gilbert. mattgilbert.net/article/37/sound-scrawl

At the moment i am still experiencing a weird hiss potential, sort of a bit depht distortion, but - i am such a noob that parts of my code are not entirely transparent to me, yet :-D

If anybody wants, i can post the code, but be warned, it is from the mind of an old-school spaghetti coder.

best,
cB
Re: My own sample bytes to an output - how!?
Reply #2 - Nov 27th, 2009, 3:09pm
 
Sound issue also solved. It was all in the numbers (buffer received very unhealthy values).

IMPORTANT - if you believe you must complain because it is *badly coded* well - this piece of code reflects my first 12 hours in processing so - please be gentle.

second important note:
due to the manual byte order reading and stuff, this only works for 16 bit intel byte order 44.1khz mono data (wav or raw). and yes, i do absolutely ignore the wav header. i had worse stuff to care about.

Code:
// 514audiodesign in November 2009
// This is to :
// 1. read a sample
// 2. display the waveform on screen
// 3. make the values from the sample available for manipulation
// 4. give the values back to a playback-buffer
// 5. have the possibility to manipulate and save back samples
// This is just a lesson for me to learn this stuff.

import pitaru.sonia_v2_9.*;

//tweakable values
int sampmaxlen = 5000000; //max sample length 5 mb
int screenwidth = 1200; //display x size
int screenheight = 500; //display y size
int buffsize = 8192;    //playback buffer size (will loop)

int samplepointer;
int samplesize;
float amplivalue;
float interim;
float u;
float z;
boolean copybuff = false;
boolean copynow = true;

//create sample array in wordsize of the max sample length
//(normally half size of the bytelenght of the sample lenght)
//(but i didn´t know how to read the sample lenght upon initialisation)
int[] sample16bit = new int[sampmaxlen];

float[] data = new float[buffsize];



void setup(){
 //sonia
 int streamSize = buffsize;
 Sonia.start(this, 44100);
 LiveOutput.start(streamSize,streamSize*2); // Start LiveOutput with a buffer.
 LiveOutput.startStream(); // Start the liveOutput stream, and activate the liveOutputEvent(){}

 //screen
 size(screenwidth,screenheight);
 smooth();

 //onscreen control values text display  
 PFont font;
 font = loadFont("ErbarLT-BoldCondensed-12.vlw");
 textFont(font);

 //load sample
   byte b[] = loadBytes("anymono16bitpcmsample.wav");
// byte b[] = loadBytes("anymono16bitinelfile.raw");
 samplesize = (b.length/2);

 
 //convert 8 to 16 bit and copy in array
 for (int i=0; i<b.length;i=i+2){
   int lobyte = (b[i]);  //read low byte 0-255
   int hibyte = (b[i+1]); //read high byte 256-65535)
  sample16bit[i/2]=((hibyte*256)+lobyte);     //byte1 * 256 + byte2 = word = 8->16 bit
 }

   //initially clear audio buffer (just to make sure)
   for(int i = 0; i < buffsize; i++){
LiveOutput.data[i] = 0;
   }

//end setup
}



void draw(){
 
 background(100);   //refresh
 noFill();    //faster gfx

 //pointer startposition to read the amount of (screenwidth) values relatively to x position
 samplepointer=int ((samplesize/screenwidth) * mouseX);

 // catch underflow
 while (samplepointer < 1) {
 samplepointer=1;
 }

 //catch overflow
 while (samplepointer > (samplesize-screenwidth)) {
 samplepointer = (samplesize-screenwidth);
 }
 
 //graphical part  
 //read values from sample to display onscreen with the length of (screenwidth)
 for (int i = 0; i < screenwidth; i = i + 1) {
   z = float (sample16bit[samplepointer+i]);  //read values at pointerposition+i,
   u = z + 32768; // unorthodox messing
   z = u/(screenheight/3.85);  // around with the values so
   amplivalue = z ;     // they show up in the right place on the screen


   ellipse (i,amplivalue,1,1); //draw a fat dot representing the amplitude value
 }

 //draw amplitude centerline
 line (0,screenheight/2,screenwidth,screenheight/2);


 //On-screen control values
 text (("Samplesize:"+samplesize*2),screenwidth/3,screenheight-2);
 text (("Samplepointer:"+samplepointer*2),screenwidth/2,screenheight-2);
 text (("Amplivalue:"+sample16bit[samplepointer]),screenwidth/1.5,screenheight-2);
 text (("Realamplivalue:"+amplivalue),screenwidth/1.1,screenheight-2);

 //Copy data of the currently displayed position to buffer if mouse is pressed
 if(copybuff){
   for(int i=1; i<buffsize; i++){
z = sample16bit[(samplepointer+i)]; // transparent calculations
u = z / 10000;    // to reach a float range
data[i] = u / 3.5; // of -1 to 1
   }
 }

//end draw
}

//mouse stuff
void mousePressed(){
 copybuff = true;
 }

void mouseReleased(){
 copybuff = false;
 }


//Playback event
// This event is automatically called when the system requests new data for the stream.
void liveOutputEvent(){

   for(int i = 0; i < buffsize; i++){
   LiveOutput.data[i] = data[i];
   }

//end playback event
}



//sonia shutdown
public void stop(){    
  Sonia.stop();    
  super.stop();  
}



best regards,
cB
Page Index Toggle Pages: 1