increasing volume when user comes closer

edited January 2014 in Library Questions

Hi,

I am working with the kinect and processing. I want to have a sound which volume increases as the user comes closer to the kinect. How can I do that?

Answers

  • Split your problem up into smaller pieces. Can you write a simple example program that detects how far away a person is? Can you write a separate example program that changes the volume based on a changing variable? When you have each piece working separately, then you can think about combining them.

  • Is there a code for the volume? I have a program to detect the distance that works. AllI have to know is what I have to write in order to control the volume. I've read that setGain and setVolume don't work in the new processing, so what else can I use in order to do that? I'm currently working with the minim library, but will it work with that?

  • In order to control volume using minim you can use this peice of code . (note: this isn't my code)

    /**
      * This sketch demonstrates how to use the <code>getVolume</code> and <code>setVolume</code> methods of a 
      * <code>Controller</code> object. The class used here is an <code>AudioOutput</code> but you can also 
      * get and set the volume of <code>AudioSample</code>, <code>AudioSnippet</code>, <code>AudioInput</code>, 
      * and <code>AudioPlayer</code> objects. <code>getVolume</code> and <code>setVolume</code> will get and set 
      * the volume of the <code>DataLine</code> that is being used for input or output, but only if that line has 
      * a volume control. A <code>DataLine</code> is a low-level JavaSound class that is used for sending audio to, 
      * or receiving audio from, the audio system. You will notice in this sketch that you will hear the volume 
      * changing (if it's available) but you will not see any difference in the waveform being drawn. The reason for this
      * is that what you see in the output's sample buffers is what it sends to the audio system. The system makes the 
      * volume change after receiving the samples.
      */
    
    import ddf.minim.*;
    import ddf.minim.signals.*;
    
    Minim minim;
    AudioOutput out;
    Oscillator  osc;
    WaveformRenderer waveform;
    
    void setup()
    {
      size(512, 200);
      minim = new Minim(this);
      out = minim.getLineOut();
    
      // see the example AudioOutput >> SawWaveSignal for more about this class
      osc = new SawWave(100, 0.2, out.sampleRate());
      // see the example Polyphonic >> addSignal for more about this
      out.addSignal(osc);
    
      waveform = new WaveformRenderer();
      // see the example Recordable >> addListener for more about this
      out.addListener(waveform); 
    
      textFont(createFont("Arial", 12));
    }
    
    void draw()
    {
      background(0);
      // see waveform.pde for more about this
      waveform.draw();
    
      if ( out.hasControl(Controller.VOLUME) )
      {
        // map the mouse position to the range of the volume
        float val = map(mouseX, 0, width, 1, 0);
        // if a volume control is not available, this will do nothing
        out.setVolume(val); 
        // if a volume control is not available this will report zero
        text("The current volume is " + out.getVolume() + ".", 5, 15);
      }
      else
      {
        text("There is no volume control for this output.", 5, 15);
      }
    }
    
    void stop()
    {
      // always close Minim audio classes when you are finished with them
      out.close();
      minim.stop();
    
      super.stop();
    }
    
  • I have this code now (see below). I have it working so that when the closest point, like a finger, goes to the right, the volume increases. How can I change this code so that when the user comes closer, the volume increases. I've tried several things but they won't work.

    //fullscreen
    import fullscreen.*;                  
    import japplemenubar.*;               
    FullScreen fs;
    
    PImage bg;                            //achtergrond afbeelding
    
    
    // kinect
    import SimpleOpenNI.*;
    SimpleOpenNI kinect;
    int closestValue;
    int closestX;
    int closestY;
    
    // geluid
    import ddf.minim.*;
    import ddf.minim.effects.*;
    Minim minim;
    AudioSnippet player;
    
    void setup(){
    size(640, 480);
    bg = loadImage("wallpaper.jpg");      // achtergrond afbeelding
    
    //fullscreen
    frameRate(30);                        
    fs = new FullScreen(this);            
    fs.enter();                           
    
    // kinect
    kinect = new SimpleOpenNI(this);
    kinect.enableDepth();
    
    // geluid
    minim = new Minim(this);
    player = minim.loadSnippet("wouter2.wav");
    player.play();
    
    }
    
    void draw() {
      background(bg);                    // achtergrond afbeelding
    
     // kinect
      closestValue = 8000; 
     kinect.update();
     // get the depth array from the kinect
     int[] depthValues = kinect.depthMap();
     // for each row in the depth image
     for(int y = 0; y < 480; y++){ 
     // look at each pixel in the row
     for(int x = 0; x < 640; x++){ 
     // pull out the corresponding value from the depth array
     int i = x + y * 640; 
     int currentDepthValue = depthValues[i];
     // if that pixel is the closest one we've seen so far
     if(currentDepthValue > 0 && currentDepthValue < closestValue){ 
     // save its value
     closestValue = currentDepthValue;
     // and save its position (both X and Y coordinates)
     closestX = x;
     closestY = y;
     }
     }
     }
    
    fill(255);
    ellipse(closestX, closestY, 25, 25);
     float vol = map(closestX, 0, width, -50,0);
     player.setGain(vol);
    
    }
    
  • edited January 2014

    Instead of giving it the X value of the closest point, give it the Z or depth value:

    int depth = ??? //No clue what the best value is, look in the Kinect library documentation or do some println()'s...
    float vol = map(closestValue, 0, depth, -50, 0);
    
  • I think the idea is good, but I'm kind of new to processing... How could I get this inside of my code?

    But I do think that would work, thank you @colouredmirrorball !

  • @colouredmirrorball , I have put the code inside of mine, but I don't really see a difference... what does the value of the int depth do? , what I mean is, what would be the best value?

    I really appreciate your help! :D Thanks a lot!

  • Your code posted above looks for the smallest value in the Array depthValues. These are integers, with a value between 0 (I guess, more or less touching the Kinect) and the largest value the Kinect can reach. I have no experience with the Kinect library as I don't have one so I don't know what this maximum value is. But as you have this line in the code: closestValue = 8000;, I suppose the maximum value is 8000. After going through all values in depthValues, you end up with a closestValue which is the Z position of the closest point to the Kinect. This is the actual value you need. Because giving in a number between 0 and 8000 in the volume control would be a very bad idea, you need to rescale it: float vol = map(closestValue, 0, depth, -50, 0); where depth is the furthest the Kinect can reach. The map() method takes the first argument (closestValue), which you assume is scaled between the two following arguments (i.e. between 0 and depth), and rescales it between the two last arguments (-50 and 0). So, if closestValue = 0 (near the Kinect), vol will get the value of -50, and if closestValue = depth (furthest away), it will have the value 0. (Are you sure these aren't reversed?)

    So, I think you need to replace line 70 with float vol = map(closestValue, 0, 8000, -50, 0);though it's possible you need to adjust those values...

    Succes!

  • If I use 'depth' in line 70 I get the right effect, only the effectis reversed (the sound increaes if the closest point goes further away from the kinect) But I will fix that! :D Thanks a lot for your help, I only have to loop the song now! :D thanks!

  • Just swap the values in map(): map(closestValue, 0, 8000, 0, -50);.

  • when I put the 8000 in map(); the sound stops in about half a second. when I use depth the sketch works,only in opposite direction, but I think that's maybe even better :)

  • Maybe -50 is too low? Try playing with that value until you get the desired result.

  • But once I use getVolume() in my project, it will say Volume is not supported. Is there anyone who can tell me how to get volume control availbale? Thanks~

Sign In or Register to comment.