Quantcast
Channel: Library Questions - Processing 2.x and 3.x Forum
Viewing all articles
Browse latest Browse all 2896

Stitch together audio samples from microphone to get continuous signal?

$
0
0

I want to capture real-time audio continuously without interruption, so I can take samples of arbitrary length from that capture, but without waiting for that capture-length of time. My goal is to be able to analyze the signal such that the higher frequency results appear immediately, while allowing some lag for the lower frequency components. The code below shows my attempt to do this using an array to paste together the input samples as they appear, using arrayCopy() to move older samples to the right, eventually falling off. I had expected that each new sample would start where the previous sample had ended, but this appears not to be the case. The sketch shows this as a discontinuity in waveform at the junctions shown in the middle (most easily seen with a sine wave input, varying the frequency). I've checked the timing various ways, and the problem is not with math or drawing speed. An additional waveform discontinuity seen only in the most recent sample at about 10-20% from the left suggests that new samples actually do not start at the end of the old sample.
As you can see I've tried using a "listener" and putting the capture and array processing in a separate thread from draw, as well as checking my assumptions about which end of the capture buffer is most recent. I'm sure there must be some solution to this. GetInputStream looks like a possibility, but I couldn't find any examples showing how to use it. Or am I better off going to Processing 3? Many Thanks for suggestions!!!

import ddf.minim.analysis.*;
import ddf.minim.*;

Minim       minim;
AudioInput in1;
ListenUp listenUp;

int bufSize = 1024, bufMult = 16;

float points[] = new float[bufSize];
float bigSrc[] = new float[bufMult*bufSize];
float bigDest[] = new float[bufMult*bufSize];

class ListenUp implements AudioListener
{
  private float[] left;
  private float[] right;

  ListenUp()
  {
    left = null;
    right = null;
  }

  synchronized void samples(float[] samp)
  {
    left = samp;
  }

  synchronized void samples(float[] sampL, float[] sampR)
  {
    left = sampL;
    right = sampR;
  }
}

void setup()
{
 // frameRate(30);
  size(bufSize/2, 400);
  minim = new Minim(this);
  listenUp = new ListenUp();

  in1 = minim.getLineIn(Minim.MONO, bufSize);

  background(0);

  for (int i=0; i<bufMult*bufSize; i++)
  {
     bigSrc[i]=0;
     bigDest[i]=0;
  }
  in1.addListener(listenUp);
}


void stuff()
{
   if ( listenUp.left != null )
    {
      points = listenUp.left; //read "listened" input buffer front to back
    //  for(int i = 0; i<bufSize; i++) {points[bufSize-1-i]=listenUp.left[i];} //read "listened input buffer back to front

//    arrayCopy(bigSrc, bufSize, bigDest, 0, (bufMult-1)*bufSize); //to put most recent input at back of array
//    arrayCopy(points, 0, bigDest, (bufMult-1)*bufSize, bufSize); // ''

    arrayCopy(bigSrc, 0, bigDest, bufSize, (bufMult-1)*bufSize);  //to put most recent input at front of array
    arrayCopy(points, 0, bigDest, 0, bufSize);                    //''

    arrayCopy(bigDest, bigSrc);
  }
}

void draw()
{
  background(0);
  stroke(255);

  thread("stuff"); //to see if capturing input as separate thread helps - no difference

  for (int j=0; j<bufMult/2; j++) //presenting result as adjacent buffers to show discontinuity in capture
  {
    for(int i = 0; i<bufSize*2; i+=4) //take every 4th point - to fit on screen and to decrease draw time
    {
      float dH = bigDest[i+j*bufSize]*100;
      line( i/4, height*(j+1)/10-dH, i/4+1, height*(j+1)/10 - dH );
    }
  }
}

Viewing all articles
Browse latest Browse all 2896

Trending Articles