Howdy, Stranger!

We are about to switch to a new forum software. Until then we have removed the registration on this forum.

  • Play just a selection from a sound sample?

    I'm able to create and play long sound samples with code like this: wave = minim.createSample( samples, format, buffersize ); wave.trigger(); But the array samples is huge, and sometimes I want to play only a small part of it. Is there a way to specify a range within samples when I call createSample, or do I have to create a new separate smaller sample each time, and trigger the smaller sample?

  • USB microphone and minim

    I've been struggling for ages to get a mini USB microphone setup. Starting to feel it might not be compatible...

    I need a robust solution that uses the USB mic every boot of the pi as it is headless and goes straight into running my sketch using minim to detect beats.

    Any reccomnedations of mics that work, the tiny cheap USB type, would be great. Also any advice of setup and ideally auto levelling the input would be great.

    I'm using this to beat match audio and the levels vary wildly from my flat to a club... The more plug and forget the better!

    Cheers :)

  • How to add a trigger to an oscilloscope program?

    Doing something like this requires to know about the nature of your data, and exactly how you envision your trigger to work. Here I have implemented the concept based on leading edge crossing. White line is based line. Blue line is the current threshold definition. The data from minim is in a range of -1..+1. When displaying, I multiply this data by a normalization factor which I defined as height/2. I set my threshold to 0.4 based on observations from the printInfo() function in my code below. Green line shows the data points.

    The concept is this. If the wave crosses the threshold, capture this crossing point. Set this crossing point as the center of the display (across the sketch width) which means all the data is shifted either to the left or to the right. Because the display width is 512 and the data buffer is 512, if the data is shifted with respect to the leading edge crossing, then it is natural that either the left end or right end will have no data... these data bins were set to zero (Notice this is because I copy the original data to a temporal array before I reset those containers to zero).

    I removed the hsb color definition, added an inversion on the y axis, and instead of calling background(), I am using a fill with alpha to slowly erased my sketch content. So this creates an effect of memory on the display where you can see that previous waves are attenuated and removed after few iterations, and not immediately in the case you call background() function.

    As in an oscilloscope, I work with the time-amplitude domain. However, the examples of the minim is based on a buffer that provides amplitude only, no time information. Then What I do is that I take the index of the array and I set them to be my time. The amplitude from minim is used as my amplitude data, so I get two internal arrays: time and amplitude which store the data to display.

    Kf

    //REFERENCE: https://forum.processing.org/two/discussion/28074/how-to-add-a-trigger-to-an-oscilloscope-program#latest // //Title: Oscilloscope trigger based on the leading edge. //Author: Kfrajer, July 15, 2018

    import ddf.minim.*;
    
    Minim minim;
    AudioInput in;
    color white;
    
    WavePacket wp;
    
    void setup()
    {
      size(512, 200, P2D);
      white = color(255);
    
      minim = new Minim(this);
      minim.debugOn();
    
      in = minim.getLineIn(Minim.STEREO, 512);
    
      wp=new WavePacket(in.bufferSize());
    
      background(0);
    }
    
    void draw()
    {
      //clone wafeform
      wp.loadData(in);
      wp.printInfo();
      wp.searchHThresholdCrossing();
      wp.shiftWaveBasedOnHThreshold();
    
      //This next enables drawing only of those signals above the threshold
      //Remove or comment out if you want to see all the signals
      if (!wp.thresholdFound()) {
        return;
      }
    
      fill(0, 60);
      rect(0, 0, width, height);
      translate(0, height/2);
      scale(1, -1);
      wp.drawBaseLine();
      wp.display();
      wp.drawThresold(); 
    }
    
    
    void stop()
    {
      in.close();
      minim.stop();
      super.stop();
    }
    
    class WavePacket {
    
      final float NORMFACTOR=height/2;
    
      int len;
      FloatList time;
      FloatList amp;
    
      float highThreshold;
      float idxTimeFirstCrossing;
    
      WavePacket(int n) {
        len=n;
        time=new FloatList(len);
        amp=new FloatList(len);
    
        highThreshold=0.4;  //Chosen based on initial observations from printInfo()
    
        println("Size set to ", len);
      }
    
      void loadData(AudioInput in) {    
    
        for (int i = 0; i < in.bufferSize(); i++) {
          time.set(i, i);
          amp.set(i, in.left.get(i));
        }
      }
    
      //It finds index when the curve crosses the threshold for the first time
      void searchHThresholdCrossing() {
    
        idxTimeFirstCrossing = -1;  //Resets
    
        for (int i = 0; i < in.bufferSize(); i++) {
          if (amp.get(i)>=highThreshold) {
            idxTimeFirstCrossing=i;
            return;
          }
        }
      }
    
      boolean thresholdFound() {
        return idxTimeFirstCrossing>=0;
      }
    
      void shiftWaveBasedOnHThreshold() {
    
        int middlePoint=(len/2);
        //If wave did not cross threshold, then define delta time correction as zero
        int deltaTime = thresholdFound() ? int(middlePoint-idxTimeFirstCrossing) : 0;
    
        FloatList tempX=new FloatList();
        FloatList tempY=new FloatList();
    
        //Create temporal containers with shifted tinme data 
        for (int i = 0; i < in.bufferSize(); i++) {
          tempX.set(i, time.get(i)+deltaTime);
          tempY.set(i, amp.get(i));
        }
    
    
        //Zero original containers
        for (int i = 0; i < in.bufferSize() - 1; i++) {
          time.set(i, 0);
          amp.set(i, 0);
        }
    
        //Search for first index
        int idx=0;
        for (; idx < in.bufferSize(); idx++) {
    
          if (tempX.get(idx)<0)
            continue;
    
          break;
        }
    
        //println("Threshold:", highThreshold, "idxTimeFirstCrossing", idxTimeFirstCrossing, "idx:", idx);
    
        //Populate arrays with shifted data using temporal holders
        for (int j=idx; j<len; j++) {
    
          //println(idx);
          //println(int(tempX.get(j)), tempY.get(j));
    
          time.set(int(tempX.get(j)), tempX.get(j));
          amp.set(int(tempX.get(j)), tempY.get(j));
        }
      }
    
      void display() {
        // draw the waveforms
        stroke(0, 250, 10);  //Green
        strokeWeight(2);
        for (int i = 0; i < in.bufferSize(); i++) {
    
          point(i, amp.get(i)*NORMFACTOR);
        }
      }
    
      void drawThresold() {
        stroke(0, 0, 200);  //Blue
        strokeWeight(1);
    
        int step=2;
        for (int k=0; k<len-step*2; k+=step*2)
          line(k, highThreshold*NORMFACTOR, k+step, highThreshold*NORMFACTOR);
      }
    
      void drawBaseLine() {
        stroke(250);  //White
        strokeWeight(1);
        line(0, 0, width, 0);
      }
    
    
      void printInfo() {
        println("Report range: ", amp.min(), amp.max());
        println("Report Norm Factor", NORMFACTOR);
      }
    }
    
  • How to add a trigger to an oscilloscope program?

    I'm working on a very bare bones oscilloscope program using the minim library:

    import ddf.minim.*;
    
    Minim minim;
    AudioInput in;
    color white;
    
    void setup()
    {
      size(512, 100, P2D);
      white = color(255);
      colorMode(HSB,100);
      minim = new Minim(this);
      minim.debugOn();
    
      in = minim.getLineIn(Minim.STEREO, 512);
      background(0);
    }
    
    void draw()
    {
      background(0);
      // draw the waveforms
      for(int i = 0; i < in.bufferSize() - 1; i++)
      {
        stroke((1+in.left.get(i))*50,100,100);
        line(i, 50 + in.left.get(i)*50, i, 50 + in.left.get(i+1)*50);
      }
    }
    
    
    void stop()
    {
      in.close();
      minim.stop();
      super.stop();
    }
    

    My question is, how do I make the waveform trigger/stabilize like an actual oscilloscope? I'm trying to figure that out so I can make the waveform stay at a certain spot so it doesn't jump around. Basically keep the waveform stable at all times.

    Thanks for your help.

  • How to switch from one text to another according to time with the Geomerative library?!

    Dear Chrisir, In fact my problem is linked to the attarctor in my main sketch. I switch from a phrase to the other and the attractor for the lines works too but no the attractor linked to the words !? Don't find why... I tried to debug, but don't succeed. Here is the code: Thanks for your help... best, L

    import generativedesign.*;
    import geomerative.*;
    import ddf.minim.analysis.*;
    import ddf.minim.*;
    // List of a list of points. 1rst the numbre of phrases: 4,  the 2nd indicate the number of points
    RPoint[][] myPoints = new RPoint[5][0];
    RFont font;
    PFont f;
    Attractor attractor;
    
    // Variables for lines
    Attractor_Lines attractor_Lines;
    int xCount=401;
    int yCount=401;
    float gridSizeX=1800;
    float gridSizeY=1000;
    Node [] myNodes;
    float xPos, yPos;
    
    String [][] phraseSets = new String [4][0];
    String [] FR1 = {
      "On me dit de te haïr et je m'y efforce", 
      "Je t'imagine cruel, violent, implacable", 
      "Mais à te voir je n'ai bientôt plus de force", 
      "Et de te blesser je suis bien incapable", 
    };
    String [] FR2 = {
      "Tous mes camarades combattent avec rage", 
      "Et pleurent la nuit au souvenir des supplices", 
      "Infligés à leurs frères qui sont du même âge", 
      "et rêvent comme eux de toucher une peau lisse"
    };
    String [] FR3 =
      {"Et de pouvoir enfin caresser des obus", 
      "Autres que ceux produits par le pouvoir obtus", 
      "Je rêve de quitter ces boyaux infernaux"
    };
    String [] FR4 = {
      "De laisser ces furieux des deux bords du Rhin", 
      "Et de pouvoir embrasser ta chute de rein", 
      "Et porter notre amour sur les fonts baptismaux"
    };
    
    //TEXT
    final color textColor = color(245);
    int fontSize;
    
    //SOUND
    Minim minim;
    AudioPlayer[] sounds;
    FFT fft;
    float bandHeight;
    float soundDuration ;
    float soundDuration1 ;
    String []fileNamesFR= {"FR_01", "FR_02", "FR_03", "FR_04", "FR_05", "FR_06", "FR_07", "FR_08", "FR_09", "FR_10", "FR_11", "FR_12", "FR_13", "FR_14"};
    SoundManager sm;
    
    // TIME
    int startTime;
    int initTime;
    int lineSpacing;
    int index;
    int state;
    float duration;
    float dur1;
    float dur2;
    //----------------SETUP---------------------------------------------------------------------------------------
    
    void setup() {
      size(1920, 1080, JAVA2D);
      //add phrases to list
      phraseSets[0]=FR1;
      phraseSets[1]=FR2;
      phraseSets[2]=FR3;
      phraseSets[3]=FR4;
    
      smooth();
      RG.init(this);
      font = new RFont("FreeSans.ttf", 86, CENTER);
      stroke(textColor);
      strokeWeight(0.05);
      //INIT
      drawPhrases(phraseSets[0]);
    
      // LINES initiate attractor + attractors specs
      myNodes = new Node [xCount*yCount];
      initGrid();
      attractor_Lines = new Attractor_Lines(0, 0);
      attractor_Lines.strength=-160;
      attractor_Lines.ramp = 0.85;
    
      //SOUND
      minim = new Minim(this);
      sounds = new AudioPlayer[fileNamesFR.length];
      for (int idx=0; idx<sounds.length; idx++) {
        sounds[idx] = minim.loadFile(fileNamesFR[idx]+".wav", 2048);
        fft = new FFT(sounds[idx].bufferSize(), sounds[idx].sampleRate());
      }
      soundDuration = 2000;
      sm=new SoundManager(this);
      //}
      // TIME
      startTime=millis();
      initTime=millis();
      index=0;
      lineSpacing =150;
    }
    
    //----------------DRAW---------------------------------------------------------------------------------------------
    
    void draw() {
      background(255);
      state =0;
    
      //SOUNDS ANALYZIS
      for (int idx=0; idx < sounds.length; idx++) {
        fft.forward(sounds[idx].mix);
        for (int i =0; i< fft.specSize(); i++) {
          float bandDB = 10*log(fft.getBand(i)/fft.timeSize());
          bandDB = constrain(bandDB, -1000, 1000);
          bandHeight = map(bandDB*4, 0, -220, 0, height);
          stroke(0);
          //line(i, height, i, bandHeight-fft.getBand(i)*8);
        }
      }
    
    
      // LINES
      if (millis()-startTime > 0) {
        for (int i = 0; i<myNodes.length; i=i+10) {
          pushMatrix();
          translate(myNodes[i].x, myNodes[i].y);
          stroke(0, 100);
          strokeWeight(0.01);
          float noiseXRange = attractor_Lines.x/100.0;
          float noiseYRange = attractor_Lines.y/1000.0;
          float noiseX = map(myNodes[i].x, 0, xCount, 0, noiseXRange/5);
          float noiseY = map(myNodes[i].y, 0, yCount, 0, noiseYRange/5);
          float noiseValue = noise(noiseX, noiseY);
          float angle = noiseValue*TWO_PI;
          rotate(angle);
          line(0, 0, 10, 10);
          popMatrix();
        }
      }
    
      // TEXTS
      // draw on the center of the screen
      translate(width/2, height/2);
      // draw phrases vertically centered by moving the top up by half the line spaces
      translate(0, -1.0*lineSpacing*(phraseSets[index].length-1)/2.0);
      // loop through lines
      for (int i=0; i< myPoints.length; i++) {
        // draw a line
        for (int j=0; j< myPoints[i].length-1; j++) {
          pushMatrix(); 
          translate(myPoints[i][j].x, myPoints[i][j].y);
          noFill();
          stroke(0, 200);
          strokeWeight(0.25);
          float angle = TWO_PI*10;
          rotate(j/angle);
          bezier(-2*(noise(10)), 10, 25*(noise(10)), -5, 2*noise(5), -15, 10, -3);
          //bezier(-10*(noise(20))+mouseX/15, 30+mouseY/10, -10*(noise(10))+mouseX/15, 20+mouseY/15, -20*noise(20)+mouseX/15, -20+mouseY/5, 10+mouseX/15, -10+mouseY/15);
          popMatrix();
        }
        // move to the next line
        translate(0, lineSpacing);
      }
      //check Timer and redraw phrases if time has passed
    
      changePhraseTimerN(dur1, phraseSets);
      sm.update();
      // changePhraseTimer(duration*4, phraseSets);
    }
    
    //----------------INITIALIZE----------------------------------------------------------------------------------------------------------------------------------------
    void drawPhrases(String [] phrases) {
      myPoints = new RPoint[phrases.length][0];
      for (int j=0; j<phrases.length; j++) {
        RGroup myGroup = font.toGroup(phrases[j]);
        myGroup = myGroup.toPolygonGroup();
        myPoints[j] = myGroup.getPoints();
      }
    }
    
    //----------------TIMER----------------------------------------------------------------------------------------------------------------------------------------
    
    /*void changePhraseTimer( float duration, String [][] phraseSets) {
      duration = sounds[0].length()-150;
      if (millis()-startTime > duration*4) {
        index =(index+1) % phraseSets.length; 
        drawPhrases(phraseSets[index]);
        //startTime = millis();
      }
    }*/
    
    void changePhraseTimerN(float dur1, String [][] phraseSets) {
      dur1 = 11200.;
      dur2=7000;
      if (millis()-startTime < dur1) {
        state=0;
      } else if (millis()-startTime < dur1*2-200.) {
        state=1;
      } else if (millis()-startTime < dur1*3-4500.) {
        state=2;
      } else if (millis()-startTime < dur1*4-9500.) {
        state=3;
      } else {
        state=0;
        startTime = millis();
      }
    
      switch(state) {
    
      case 0:
        drawPhrases(phraseSets[0]);
        //println(0);
        index=0;
        break;
      case 1:
        //drawPhrases(phraseSets[1]); 
        index = (index+1) % phraseSets.length;
        println(index);
        startTime = millis();
        drawPhrases(phraseSets[index]);
        // println(1);
        break;
      case 2:
        drawPhrases(phraseSets[2]);
        // println(2);
        break;
      case 3:
        drawPhrases(phraseSets[3]);
        // println(3);
        break;
      }
    }
    
    
    //----------------TEXT ATTRACTOR INIT----------------------------------------------------------------------------------------------------------------------------------------
    void initAttractor(int i) {
      if (i>=4 && i<8) {
        i-=4;
      } else if (i>=8 && i<11) {
        i-=8;
      } else if (i>=11 && i<14) { 
        i-=11;
      } else if (i>14) {
        i=0;
      }
    
      float x = 0;
      float y =-50; 
      // println(i);
      attractor = new Attractor(x, y, myPoints[i]);
    }
    //----------------LINES ATTRACTOR INIT----------------------------------------------------------------------------------------------------------------------------------------
    void updateAttractorLines(float x, float y) {
      attractor_Lines.x=x;
      attractor_Lines.y=y;
    }
    //----------------LINES GRID INIT----------------------------------------------------------------------------------------------------------------------------------------
    void initGrid() {
      int i =0;
      for (int x=0; x<xCount; x++) {
        for (int y=0; y<yCount; y++) {
    
          xPos = x*(gridSizeX /(xCount-1)) + (width-gridSizeX)/2;
          yPos = y*(gridSizeY /(yCount-1)) + (height-gridSizeY)/2;
          myNodes[i] = new Node(xPos, yPos);
          myNodes[i]. setBoundary(0, 0, width, height);
          myNodes[i].setDamping(0.9);
          i++;
        }
      }
    }
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    class Attractor {
    
      float force_radious = 100;
      float maxForce = 15;
      RPoint position;
      RPoint[] points;
    
      Attractor(float x, float y, RPoint[] p) {
        points = p;
        position = new RPoint(x, y);
      }
    
      void attract() {
    
        for (int i =0; i < points.length; i++) {
    
          float d= points[i].dist(position);
         // println ("d : "+d);
          if (d < force_radious) {   
            RPoint desired = new RPoint(points[i]);
            //points[i]= new RPoint(points[i]);
            //println( "avant x : "+ points[i].x +" y: "+points[i].y);
            desired.sub(position);
            desired.normalize();
            desired.scale(map(d, 0, force_radious, maxForce, 0));
            points[i].add(desired);
             //println( "après x : "+ points[i].x +" y: "+points[i].y);
          }
        }
      }
      void display () {
        stroke(0);
       strokeWeight(2);
      // ellipse (position.x, position.y-750, 30, 30);
      }
      void moveTo(float x, float y){
        position.x=x;
        position.y=y;
    
      }
    }
    
    class Attractor_Lines {
      float x=0, y=0;
      float radius =110;
      float strength= 0.55;
      float ramp=0.05;
      float theX;
      float theY;
    
      Attractor_Lines( float theX, float theY) {
        x= theX;
        y = theY;
      }
    
      void attract_Lines (Node theNode) {
    
        float dx = x-theNode.x;
        float dy = y-theNode.y;
        float d= mag(dx, dy);
        if ( d > 0 && d < radius) {
    
          float s = pow(d/radius, 1/ramp);
          float f = s*9*strength*50 * (1/(s+1)+((s-3)/4))/d;
          theNode.velocity.x += dx*f;
          theNode.velocity.y += dy*f;
        }
      }
    }
    
    ////////////////////////////////////////////////////////////////
    
    import ddf.minim.analysis.*;
    import ddf.minim.*;
    
    class SoundManager {
      //SOUND
      Minim minim;
      AudioPlayer[] sounds;
      FFT fft;
      float bandHeight;
      int currentSound;
      String []fileNamesFR1= {"FR_01", "FR_02", "FR_03", "FR_04", "FR_05", "FR_06", "FR_07", "FR_08", "FR_09", "FR_10", "FR_11", "FR_12", "FR_13", "FR_14"};
      float []linesYPositions ={300., 450., 600., 750., 300., 450., 600., 750., 450., 600., 750., 450., 600., 750.};
    
      SoundManager(PApplet app) {
    
        minim = new Minim(app);
        currentSound =-1;
        sounds = new AudioPlayer[fileNamesFR1.length];
        for (int idx=0; idx<sounds.length; idx++) {
          sounds[idx] = minim.loadFile(fileNamesFR1[idx]+".wav", 2048);
          fft = new FFT(sounds[idx].bufferSize(), sounds[idx].sampleRate());
    
        }
      }
    
      void update() {
    
        // SOUND
        if (currentSound ==-1) { 
          startPlaying();
    
        } else if (!sounds[currentSound].isPlaying()) {
          playNext();
        } else { 
    
          fft.forward(sounds[currentSound].mix);
          for (int i =0; i< fft.specSize(); i++) {
            float bandDB = 10*log(fft.getBand(i)/fft.timeSize());
            bandDB = constrain(bandDB, -1000, 1000);
            bandHeight = map(bandDB*4, 0, -220, 0, height);
          }
    
          attractor.moveTo(map(sounds[currentSound].position(), 0, sounds[currentSound].length(), 0, width-100)-width/2, bandHeight/10-300);
          attractor.attract();
    
          updateAttractorLines( attractor_Lines.x = map(sounds[currentSound].position(), 0, sounds[currentSound].length(), 0, width-(100)/2), linesYPositions[currentSound]);
    
          for (int j = 0; j<myNodes.length; j++) {
            attractor_Lines.attract_Lines(myNodes[j]);
            myNodes[j].update();
          }
        }
      }
    
    
      void startPlaying() {
        currentSound=0;
        playCurrentSound();
      }
    
      void playNext() {
    
        currentSound++;
        if (currentSound > sounds.length-1) {
          currentSound=0;
          drawPhrases(phraseSets[0]);
        } 
    
        // fonction restartAnimation
        //drawPhrases(phraseSets[0]);
       playCurrentSound();
    
      } 
    
      void playCurrentSound() {
        sounds[currentSound].rewind();
        sounds[currentSound].play();
        initAttractor(currentSound);
      }
    }
    
  • How do I record the audio input to a new audio render using minim

    Ok, so implementing @koogs changes are not enough, as you get back to the business of empty recorded files. However, that gave me an idea (Thxs @koogs) which I tested and sort of works. I mean, it only works for mp3 files but not for wav files. However, I tried a second idea, and it might work for you although it doesn't seem to have much control over audio when it is being played. That is what I labeled second solution using sampler objects. It works for both mp3 and wav files (tested).

    INSTRUCTIONS: In the code, define your file to play. When you run the sketch, press r to begin recording, r again to stop recording. Don't forget to press s to save the file to an audio file which will be located in the data folder.

    Kf


    FIRST solution: Only mp3

    //REFERENCE: https:// forum.processing.org/one/topic/how-can-i-detect-sound-with-my-mic-in-my-computer.html
    //REFERENCE: https:// forum.processing.org/two/discussion/21842/is-it-possible-to-perform-fft-with-fileplayer-object-minim
    
    /**
     * This sketch demonstrates how to use an <code>AudioRecorder</code> to record audio to disk. 
     * Press 'r' to toggle recording on and off and the press 's' to save to disk. 
     * The recorded file will be placed in the sketch folder of the sketch.
     * <p>
     * For more information about Minim and additional features, 
     * visit <a href="http://code.compartmental.net/minim/" target="_blank" rel="nofollow">http://code.compartmental.net/minim/</a>;
     */
    
    import ddf.minim.*;
    import ddf.minim.ugens.*;
    import ddf.minim.analysis.*;
    
    Minim         minim;
    FilePlayer player;
    AudioOutput out;
    AudioRecorder recorder;
    
    void setup()
    {
      size(512, 200, P3D);
      textFont(createFont("Arial", 12));
    
      minim = new Minim(this);  
      player = new FilePlayer(minim.loadFileStream("energeticDJ.mp3"));
      // IT DOESN'T WORK FOR WAV files  ====> player = new FilePlayer(minim.loadFileStream("fair1939.wav"));
      out = minim.getLineOut();
      TickRate rateControl = new TickRate(1.f);
      player.patch(rateControl).patch(out);
      recorder = minim.createRecorder(out, dataPath("myrecording.wav"),true);
    
      player.loop(0);
    
    }
    
    void draw()
    {
      background(0); 
      stroke(255);
    
      // draw a line to show where in the song playback is currently located
      float posx = map(player.position(), 0, player.length(), 0, width);
      stroke(0, 200, 0);
      line(posx, 0, posx, height);
    
    
    
      if ( recorder.isRecording() )
      {
        text("Currently recording...", 5, 15);
      } else
      {
        text("Not recording.", 5, 15);
      }
    }
    
    void keyReleased()
    {
      if ( key == 'r' ) 
      {
        // to indicate that you want to start or stop capturing audio data, you must call
        // beginRecord() and endRecord() on the AudioRecorder object. You can start and stop
        // as many times as you like, the audio data will be appended to the end of the buffer 
        // (in the case of buffered recording) or to the end of the file (in the case of streamed recording). 
        if ( recorder.isRecording() ) 
        {
          recorder.endRecord();
        } else
        {
          recorder.beginRecord();
        }
      }
      if ( key == 's' )
      {
        // we've filled the file out buffer, 
        // now write it to the file we specified in createRecorder
        // in the case of buffered recording, if the buffer is large, 
        // this will appear to freeze the sketch for sometime
        // in the case of streamed recording, 
        // it will not freeze as the data is already in the file and all that is being done
        // is closing the file.
        // the method returns the recorded audio as an AudioRecording, 
        // see the example  AudioRecorder >> RecordAndPlayback for more about that
        recorder.save();
        println("Done saving.");
      }
    }
    

    SECOND solution: Works for both wav and mp3

    //REFERENCE: https:// forum.processing.org/one/topic/how-can-i-detect-sound-with-my-mic-in-my-computer.html
    //REFERENCE: https:// forum.processing.org/two/discussion/21842/is-it-possible-to-perform-fft-with-fileplayer-object-minim
    //REFERENCE: https:// forum.processing.org/two/discussion/21953/why-can-i-only-load-four-audio-files-in-minum
    /**
     * This sketch demonstrates how to use an <code>AudioRecorder</code> to record audio to disk. 
     * Press 'r' to toggle recording on and off and the press 's' to save to disk. 
     * The recorded file will be placed in the sketch folder of the sketch.
     * <p>
     * For more information about Minim and additional features, 
     * visit <a href="http://code.compartmental.net/minim/" target="_blank" rel="nofollow">http://code.compartmental.net/minim/</a>;
     */
    
    import ddf.minim.*;
    import ddf.minim.ugens.*;
    import ddf.minim.analysis.*;
    
    Minim         minim;
    AudioRecorder recorder;
    AudioOutput out;
    Sampler  note;
    
    void setup()
    {
      size(512, 200, P3D);
      textFont(createFont("Arial", 12));
    
      minim = new Minim(this);  
      out = minim.getLineOut();
      note = new Sampler( "energeticDJ.mp3", 4, minim );
      //note = new Sampler( "fair1939.wav", 4, minim );
      note.patch( out );
    
      recorder = minim.createRecorder(out, dataPath("myrecording.wav"), true);
    
      note.trigger();
    }
    
    void draw()
    {
      background(0); 
      stroke(255);
    
      if ( recorder.isRecording() )
      {
        text("Currently recording...", 5, 15);
      } else
      {
        text("Not recording.", 5, 15);
      }
    }
    
    void keyReleased()
    {
      if ( key == 'r' ) 
      {
        // to indicate that you want to start or stop capturing audio data, you must call
        // beginRecord() and endRecord() on the AudioRecorder object. You can start and stop
        // as many times as you like, the audio data will be appended to the end of the buffer 
        // (in the case of buffered recording) or to the end of the file (in the case of streamed recording). 
        if ( recorder.isRecording() ) 
        {
          recorder.endRecord();
        } else
        {
          recorder.beginRecord();
        }
      }
      if ( key == 's' )
      {
        // we've filled the file out buffer, 
        // now write it to the file we specified in createRecorder
        // in the case of buffered recording, if the buffer is large, 
        // this will appear to freeze the sketch for sometime
        // in the case of streamed recording, 
        // it will not freeze as the data is already in the file and all that is being done
        // is closing the file.
        // the method returns the recorded audio as an AudioRecording, 
        // see the example  AudioRecorder >> RecordAndPlayback for more about that
        recorder.save();
        println("Done saving.");
      }
    }
    

    Keyword: kf_keyword minim sound recording from wav mp3 files

  • sharing work and request for help to bring it to the OpenProcessing platform

    this code takes in input a wav(for now just wav file!!) file, but unlike minim works in deferred time, so you can save every frame without having the problem of a non-constant frameRate, so we will not have problems synchronizing with the audio later.

    the code generates points approximating the waveform of the buffer read in the for loop. the points are connected by lines, and the rangeMax parameter is used to define the maximum distance for which a line joins two points. the other modifiable parameters are: start - this parameter determines from which sample to start reading the audio buffer. end - this parameter determines which sample to stop reading the audio buffer. buffer - the size of the buffer read at each cycle

    Note fps are determined by the buffer size because a second of audio is equivalent to 44100 samples, so the calculation to know the fps is: 44100 / buffer. so if the buffer is 1024 the corresponding fps will be: 44100/1024 = 43.06640625 to a larger buffer will correspond more points read every cycle, therefore less fps. to synchronize everything so you will need to import the photos into a program like Adobe Premiere or similar and re-map the photo display time according to the size of end less start. so if we have saved 30 seconds of audio we will have to remap the total number of frames generated in this time. or if you prefere you can generate 24 fps settings buffer=44100/24

    on my pc it work perfectly, but if i try it here: https://www.openprocessing.org/sketch/556158 it doesn't work and give me this error: $this_1.str is not a function

    can someone help me please? thank you very much!

    here the code:

    Wav wav;
    ArrayList<PVector> pos;
    int start=0, end=200;
    int rangeMax=300, sampleStart=44100*start, sampleFinal=44100*end, buffer=1024;
    float max, min, sample_Max;
    color back=0, line=50, ball=color(0, 0, 255);
    float[] r;
    void setup() {
      size(1920, 1080, P2D);
      wav = new Wav();
      wav.read("ikeda_01.wav");
      r=wav.getSampleArray();
      float max=max(r);
      float min=min(r);
      sample_Max=max(abs(min), abs(max));
      println(sample_Max);
      pos=new ArrayList<PVector>();
      frameRate(1000);
      println(buffer);
    }
    
    
    void draw() {
      //println(frameCount);
      while (pos.size()>0) { 
        for (int i=0; i<pos.size(); i+=1) {
          pos.remove(i);
        }
      }
    
      if (abs(r[sampleStart])<sample_Max/3) {
        back=color(0);
        line=color(255, 50);
        ball=color(10, 100, 255);
        //println(frameCount, "ciao");
      } else {
        back=color(255);
        line=color(0);
        ball=color(255, 0, 0);
      }
      background(back);
      stroke(ball);
      strokeWeight(12);
      for (int i=sampleStart; i<(sampleStart+buffer); i+=3) {
        int si=(int)map(i, sampleStart, (sampleStart+buffer), 0, width);
        float val=height/2+(r[i]/sample_Max)*(height/2);
        point(si, val);
        PVector momPos=new PVector(si, val);
        pos.add(momPos);
      }
    
      sampleStart+=buffer;
      stroke(line);
      strokeWeight(1);
      for (int i=0; i<pos.size(); i+=1) {
        for (int y=1; y<pos.size(); y+=1) {
          if (pos.get(i).dist(pos.get(y))<rangeMax) {
            line(pos.get(i).x, pos.get(i).y, pos.get(y).x, pos.get(y).y);
          }
        }
      }
      if (sampleStart>=sampleFinal) {
        println(sampleStart);
        exit();
      }
    
      if (frameCount<10) saveFrame("E:/MediaWork/ProcesampleStarting/Sketch/pointline_audio_offline/frame/" + "asterion000"+str(frameCount)+".png");
      if (frameCount>=10 && frameCount<100) saveFrame("E:/MediaWork/ProcesampleStarting/Sketch/pointline_audio_offline/frame/" + "asterion00"+str(frameCount)+".png");
      if (frameCount>=100 && frameCount<1000) saveFrame("E:/MediaWork/ProcesampleStarting/Sketch/pointline_audio_offline/frame/" + "asterion0"+str(frameCount)+".png");
      if (frameCount>=1000 && frameCount<10000) saveFrame("E:/MediaWork/ProcesampleStarting/Sketch/pointline_audio_offline/frame/" + "asterion"+str(frameCount)+".png");
      println("save image n:", frameCount);
      //if (frameCount==120) exit();
    }
    
    /*
    Method of Class:
    
     void read(String fileName)
     void write(float[] r_, String fileName) 
     void write(float[] r_, float[] l_, String fileName)
     void write(float[] r_, int numbit_, int samplingrate_, String fileName)
     void write(float[] r_, float[] l_, int numbit_, int samplingrate_, String fileName) 
     int getSampleLength()
     float getSampleValueLeft(int n) 
     float getSampleValueRight(int n) 
     float getSampleValue(int n)
     float getSampleArray()
     float getSampleArrayLeft()
     float getSampleArrayRight()
     int getBit()
     int getSamplingRate()
    
     */
    
    class Wav {
      int sampleLength, stereomono, numbit;
      int b1, b2, b3, b4, x=0;
      int samplingrate;
      int Dim_file_dati;
      float [] r, l;
      int c1, c2, j;
      byte[] b;
      String str=str(hour())+"_"+str(minute())+"_"+str(second());
    
      Wav() {
      }
    
      void read(String fileName) {
        b=loadBytes(fileName);
        stereomono=b[22];
    
        b1=(b[24]+ 256) % 256;
        b2=(b[25]+ 256) % 256;
        b3=(b[26]+ 256) % 256;
        b4=(b[27]+ 256) % 256;
        samplingrate = b4*16777216+b3*65536+b2*256+b1;
    
        b1=(b[34] + 256) % 256;
        b2=(b[35] + 256) % 256;
        numbit=b2*256+b1;
    
        b1=(b[40]+ 256) % 256;
        b2=(b[41]+ 256) % 256;
        b3=(b[42]+ 256) % 256;
        b4=(b[43]+ 256) % 256;
        Dim_file_dati=b4*16777216+b3*65536+b2*256+b1;
    
        sampleLength=Dim_file_dati/(stereomono*(numbit/8));
    
        r = new float [sampleLength];
        l = new float [sampleLength];
    
        btf();
      }
    
      void btf() { 
        if (stereomono==1 && numbit==16) {
          j=44;
          for (int i=0; i<sampleLength; i++)
          {
            c1=(b[j]+256) % 256;
            j++;
            c2=(b[j]+256) % 256;
            j++;
    
            r[i]= int(c2*256+c1);
            if (r[i] > 32768) r[i]=r[i]-65536;
          }
        }
        if (stereomono==2 && numbit==16) {
          j=44;
          for (int i=0; i<sampleLength; i++) {
            c1=(b[j]+256) % 256;
            j++;
            c2=(b[j]+256) % 256;
            j++;
            r[i]= int(c2*256+c1);
            if (r[i] > 32768) r[i]=r[i]-65536;
    
            c1=(b[j]+256) % 256;
            j++;
            c2=(b[j]+256) % 256;
            j++;
            l[i]= int(c2*256+c1);
            if (l[i] > 32768) l[i]=l[i]-65536;
          }
        }
      }
    
      int getBit() {
        return numbit;
      }
      int getSamplingRate() {
        return samplingrate;
      }
      int getSampleLength() {
        return sampleLength;
      }
    
      float getSampleValue(int n) {
        return r[n];
      }
      float[] getSampleArray() {
        return r;
      }
    
      float getSampleValueLeft(int n) {
        return l[n];
      }
      float getSampleValueRight(int n) {
        return r[n];
      }
      float[] getSampleArrayLeft() {
        return l;
      }
      float[] getSampleArrayRight() {
        return r;
      }
      void write(float[] r) {
        write(r, str);
      }
    
      void write(float[] r, float[] l) {
        write(r, l, str);
      }
    
      void write(float[] r, String fileName) {
        write(r, 16, 44100, fileName);
      }
    
      void write(float[] r, float[] l, String fileName) {
        write(r, l, 16, 44100, fileName);
      }
    
      void write(float[] r, int numbit, int samplingrate, String fileName) {
        str=fileName;
        sampleLength=r.length;
        this.numbit=numbit;
        stereomono=1;
        this.samplingrate=samplingrate;
        this.r =r;
        normaLize(100);
        header();
      }
    
      void write(float[] r, float[] l, int numbit, int samplingrate, String fileName) {
        str=fileName;
        sampleLength=r.length;
        this.numbit=numbit;
        stereomono=2;
        this.samplingrate=samplingrate;
        this.r =r;
        this.l=l;
        normaLize(100);
        header();
      }
    
      void normaLize(float gain) {
        float maxSampleValueFinal=0;
        float maxSample=max(r);
        float minSample=min(r);
        float maxSampleValue=max(abs(minSample), abs(maxSample));
        if (stereomono==2) {
          maxSample=max(r);
          minSample=min(r);
          maxSampleValueFinal=max(abs(minSample), abs(maxSample));
        }
        gain=gain*32767/100;
        for (int i=0; i<sampleLength; i++)
        {
          r[i]=gain*r[i]/maxSampleValue;
          if (stereomono==2) l[i]=gain*l[i]/maxSampleValueFinal;
        }
      }
    
      void header() {
        int aux=sampleLength;
        int DimFile, dimFileData, sr = samplingrate;
        byte Stereomono = byte(stereomono), Numbit = byte(numbit);
        dimFileData = aux * Stereomono * (Numbit / 8);
        DimFile = dimFileData + 44;
        byte[] f=new byte[DimFile];
        f[0]='R';
        f[1]='I';
        f[2]='F';
        f[3]='F';
        byte f1, f2, f3, f4;
        f1=byte((DimFile-8)/16777216);
        f2=byte(((DimFile-8)- f1 * 16777216) / 65536);
        f3= byte(((DimFile-8) - f1 * 16777216 - f2 * 65536) / 256);
        f4 = byte((DimFile-8) % 256);
        f[4]=f4;
        f[5]=f3;
        f[6]=f2;
        f[7]=f1;
        f[8]='W';
        f[9]='A';
        f[10]='V';
        f[11]='E';
        f[12]='f';
        f[13]='m';
        f[14]='t';
        f[15]=' ';
        f[16]=16;
        f[17]=0;
        f[18]=0;
        f[19]=0;
        f[20]=1;
        f[21]=0;
        f[22]=Stereomono;
        f[23]=0;
        f1=byte(sr/16777216);
        f2=byte((sr - f1 * 16777216) / 65536);
        f3= byte((sr - f1 * 16777216 - f2 * 65536) / 256);
        f4 = byte(sr % 256);
        f[24]=byte(68);
        f[25]=byte(172);
        f[26]=byte(0);
        f[27]=byte(0);
        int byte_per_secondo= sr * Stereomono * Numbit / 8;
        f1=byte(byte_per_secondo/16777216);
        f2=byte((byte_per_secondo- f1 * 16777216) / 65536);
        f3= byte((byte_per_secondo - f1 * 16777216 - f2 * 65536) / 256);
        f4 = byte(byte_per_secondo % 256);
        f[28]=f4; 
        f[29]=f3; 
        f[30]=f2; 
        f[31]=f1; 
        int byte_da_leggere_in_ogni_istante = Stereomono * Numbit / 8;
        f[32]=byte(byte_da_leggere_in_ogni_istante);
        f[33]=0;
        f[34]=Numbit;
        f[35]=0;
        f[36]='d';
        f[37]='a';
        f[38]='t';
        f[39]='a';
        f1=byte(dimFileData/16777216);
        f2=byte((dimFileData- f1 * 16777216) / 65536);
        f3= byte((dimFileData - f1 * 16777216 - f2 * 65536) / 256);
        f4 = byte(dimFileData % 256);
        f[40]=f4;
        f[41]=f3;
        f[42]=f2;
        f[43]=f1;
        byte[] out=new byte[stereomono*2*sampleLength+44];
        int d1, d2;
        for (int j=0; j<44; j++) {
          out[j]=f[j];
        }
    
        for (int i=0; i<sampleLength; i++) {
    
          r[i]=r[i]+65536; // Questa somma si fa per evitare gli errori causati dai numeri negativi.
          d1=byte(r[i]/256);
          d2= byte(int(r[i]) % 256);
          out[j]=byte(d2);
          j++;
          out[j]=byte(d1);
          j++;
    
          if (stereomono==2) {
            l[i]=l[i]+65536; // Questa somma si fa per evitare gli errori causati dai numeri negativi.
            d1=byte(l[i]/256);
            d2= byte(int(l[i]) % 256);
            out[j]=byte(d2);
            j++;
            out[j]=byte(d1);
            j++;
          }
        }
        saveBytes(str+".wav", out);
        println(str);
      }
    }
    
  • How do I record the audio input to a new audio render using minim

    Tested with both wav and mp3. Data should be placed in data folder.

    Kf

    //REFERENCE:  https:// forum.processing.org/one/topic/how-can-i-detect-sound-with-my-mic-in-my-computer.html
    
    
    /**
      * This sketch demonstrates how to use an <code>AudioRecorder</code> to record audio to disk. 
      * Press 'r' to toggle recording on and off and the press 's' to save to disk. 
      * The recorded file will be placed in the sketch folder of the sketch.
      * <p>
      * For more information about Minim and additional features, 
      * visit http://code.compartmental.net/minim/
      */
    
    import ddf.minim.*;
    import ddf.minim.ugens.*;
    
    Minim         minim;
    AudioPlayer player;
    AudioInput in;
    AudioRecorder recorder;
    
    void setup()
    {
      size(512, 200, P3D);
    
      minim = new Minim(this);  
      //player = minim.loadFile("energeticDJ.mp3");
      player = minim.loadFile("fair1939.wav");
    
      delay(800);   //Needed (?)
      player.play();
      in = minim.getLineIn(Minim.STEREO, 512);
    
      recorder = minim.createRecorder(in, dataPath("myrecording.wav"));
    
    
      textFont(createFont("Arial", 12));
    }
    
    void draw()
    {
      background(0); 
      stroke(255);
    
      for(int i = 0; i < player.bufferSize() - 1; i++)
      {
        float x1 = map( i, 0, player.bufferSize(), 0, width );
        float x2 = map( i+1, 0, player.bufferSize(), 0, width );
        line( x1, 50 + player.left.get(i)*50, x2, 50 + player.left.get(i+1)*50 );
        line( x1, 150 + player.right.get(i)*50, x2, 150 + player.right.get(i+1)*50 );
      }
    
      // draw a line to show where in the song playback is currently located
      float posx = map(player.position(), 0, player.length(), 0, width);
      stroke(0,200,0);
      line(posx, 0, posx, height);
    
    
    
      if ( recorder.isRecording() )
      {
        text("Currently recording...", 5, 15);
      }
      else
      {
        text("Not recording.", 5, 15);
      }
    }
    
    void keyReleased()
    {
      if ( key == 'r' ) 
      {
        // to indicate that you want to start or stop capturing audio data, you must call
        // beginRecord() and endRecord() on the AudioRecorder object. You can start and stop
        // as many times as you like, the audio data will be appended to the end of the buffer 
        // (in the case of buffered recording) or to the end of the file (in the case of streamed recording). 
        if ( recorder.isRecording() ) 
        {
          recorder.endRecord();
        }
        else 
        {
          recorder.beginRecord();
        }
      }
      if ( key == 's' )
      {
        // we've filled the file out buffer, 
        // now write it to the file we specified in createRecorder
        // in the case of buffered recording, if the buffer is large, 
        // this will appear to freeze the sketch for sometime
        // in the case of streamed recording, 
        // it will not freeze as the data is already in the file and all that is being done
        // is closing the file.
        // the method returns the recorded audio as an AudioRecording, 
        // see the example  AudioRecorder >> RecordAndPlayback for more about that
        recorder.save();
        println("Done saving.");
      }
    }
    
  • How do I record the audio input to a new audio render using minim

    So, i´ve been tryng to make the minim recorder to record the audio from the Audioplayer object when is played without any succes.

    Something like the combination of this 2 examples :

    http://code.compartmental.net/minim/audioplayer_method_play.html http://code.compartmental.net/minim/minim_method_createrecorder.html

    I´ve found similar threats but with no anwer to it :

    https://forum.processing.org/one/topic/minim-how-to-record-minim-s-output.html

    The audio plays just well but the recorder comes out empty. If I try the "createrecorder" example it works on recording the sounds created by minim, but I need it to record the sound getting them from the audio player. This is my greates attemp :

    import ddf.minim.*;
    import ddf.minim.ugens.*;
    
    Minim         minim;
    AudioOutput   out;
    AudioRecorder recorder;
    AudioPlayer sonido;
    void setup()
    {
      size(512, 200, P3D);
    
      minim = new Minim(this);
    
      out = minim.getLineOut();
      sonido = minim.loadFile("fijo2.wav");
      sonido.loop();
    
      recorder = minim.createRecorder(out, "myrecording.wav");  
      textFont(createFont("Arial", 12));
    }
    
    void draw()
    {
      background(0); 
      stroke(255);
    }
    
    void keyReleased()
    {
      if ( key == 'r' ) 
      {
        if ( recorder.isRecording() ) 
        {
          recorder.endRecord();
        }
        else 
        {
          recorder.beginRecord();
        }
      }
      if ( key == 's' )
      {
        recorder.save();
        println("Done saving.");
      }
    }
    
  • How ro record audio?

    Im tryng the same thing without any success.

    this would be the combination of > kfrajer but is coming out empty anyway.``

    `import ddf.minim.*;
    
    import ddf.minim.ugens.*;
    
    Minim         minim;
    AudioOutput   out;
    AudioRecorder recorder;
    AudioPlayer sonido;
    void setup()
    {
      size(512, 200, P3D);
    
      minim = new Minim(this);
    
      out = minim.getLineOut();
      sonido = minim.loadFile("fijo2.wav");
      sonido.loop();
    
      recorder = minim.createRecorder(out, "myrecording.wav");  
      textFont(createFont("Arial", 12));
    }
    
    void draw()
    {
      background(0); 
      stroke(255);
    }
    
    void keyReleased()
    {
      if ( key == 'r' ) 
      {
        if ( recorder.isRecording() ) 
        {
          recorder.endRecord();
        }
        else 
        {
          recorder.beginRecord();
        }
      }
      if ( key == 's' )
      {
        recorder.save();
        println("Done saving.");
      }
    }`
    
  • Sound Library

    edit post, highlight code , press ctrl-o to format.

    minim is more mature than the sound library, try that.

  • [minim] Saving audioSample to .wav

    I recorded with audioRecorder, then converted it to audioSample to access it's arrays and mess around with the sounds (playing it back with .trigger() ) But I'm now stumped on how to actually save this audioSample to a .wav (the audioRecorder has to be able to record all the while in parallel with whatever the method for saving is as well..)

    Hopefully someone has a method that could work for this? Diving deeper in to the library but no glimpse of how to achieve this yet :(

  • How to understand what is slowing down the code on many iterations?

    I was able to learn (with the strategical use of "println") that the code is slowing down when this loop is running:

     for ( int i = 0; i< 20; i++) {
          aliens.add(new Worker(width/2, height/2, elites.get(j).net));
          j++;
          if (j >= elites.size()) {
            j = 0;
          }
        }
    

    So somehow adding a new "Worker" is slow. Here is what the constructor looks like:

      public Worker(float _x, float _y, NeuralNetwork _net) {
    
    
        directionsPI = new float [] {0,QUARTER_PI, PI/2, PI/2 + QUARTER_PI, PI, PI + QUARTER_PI, PI + PI/2, PI*2 - QUARTER_PI, PI};
        directionalValues = new float [directionsPI.length];
        for ( int i = 0; i < directionalValues.length; i++){
          directionalValues [i] = 0;
        }
    
        _layers = new int[] {16, 30, 16, directionalValues.length};
        net = new NeuralNetwork ( _layers, _net);
        type = "Worker";
        diameter = worker_size;
        pos = new PVector (_x, _y);
        speed = worker_speed;
        cor = workerColor;
        hearing_distance = 100;
        controls = new String[] {"Evolve Fighter"};
        out = minim.getLineOut();
        // create a sine wave Oscil, set to 440 Hz, at 0.5 amplitude
        wave = new Oscil( 200, 0.5f, Waves.SINE );
        fftLinA = new FFT (out.bufferSize(), out.sampleRate());
        fftLinA.linAverages(30);
        this.registerObserver(tutorial);
        collidable = true;
        selectable = true;
        soundInterval = 10;
        fitness = 0;
    
         float ran = random(1);
            if ( ran > mutation_chance){
              net.Mutate();
            }
    
      }
    

    As you can see that it contains a constructor for the other class which is NeuralNetwork which is the constructor that creates a copy of an existing net which is one of the arguments for the Worker. It also runs a "Mutate()" command which makes random changes to the neural network.

  • Creating a Piano (need help with keyReleased)

    Or use a minim Sampler and no rewinding -- that is specifically what it is for.

    When choosing the number of voices think about how many additional times you could press the piano key while previous vibrato from that note hangs in the air.

  • record past 15 seconds of microphone with Minim

    I asked the original question and I finally resorted to using Python to do all the audio stuff I recorded audio using a python audio library, saved audio "frames" in a cyclical buffer (called deque in python/c++) and then saved the audio to a file when I needed too.

    Minim was a nightmare to work with and the documentation abysmal.

  • Creating a Piano (need help with keyReleased)

    I am creating a music machine and when I press the 'a' key the function begins to hold the note. When I release the 'a' key, the sound file stops, as i want it to.

    But when I go to press the 'a' key again, no sound comes out at all. I feel like the key1.pause(); function stops it correctly but wont load the same sound file when pressing the 'a' key again.

    When I use the key1.rewind(); under the keyReleased function, it plays the sound upon releasing the key 'a' in a rewind manner.

    This is my final project for Programming for Visual Artists and really could use some assistance please!

                import ddf.minim.analysis.*;
                import ddf.minim.*;
    
                Minim minim;
    
                AudioPlayer key1;
    
                void setup() {
    
                size(1440, 770);
    
                minim = new Minim(this);
                key1 = minim.loadFile("key1.mp3", 512);
                }
    
                void draw() {
                }
    
                void keyPressed() {
                  if (key=='a')
                    key1.play();
                }
                void keyReleased() {
                  key1.pause();
    
                }
    
  • TIS/TSM ERROR & crash while looping()

    (using minim is an aside here... it's the P3D causing the TIS/TSM error)

  • TIS/TSM ERROR & crash while looping()

    @koogs - thanks for the link! i will try something other than P3D... minim always works for me, but i just tried running a basic sketch and this happened :)] Screen Shot 2018-05-02 at 21.00.52