How to change the volume of audio whilst playing

edited January 2016 in Arduino

So I have a code which goes through Processing into Arduino. It controls an LED and makes it pulsate like a heartbeat. What I want to achieve is the WhiteNoise increasing and decreasing in volume at the same time as the brightness of the LED gets brighter and dimmer.

Here is the code:

import processing.serial.*;
import cc.arduino.*;
Arduino arduino;  
import processing.sound.*;
WhiteNoise noise;

int ledPin = 9;

void setup()
{
  //println(Arduino.list());
  arduino = new Arduino(this, "/dev/cu.usbmodem1411", 57600);
  arduino.pinMode(ledPin, Arduino.OUTPUT);

  size(640, 360);
  background(255);

  // Create the noise generator
  noise = new WhiteNoise(this);
  noise.play();
  noise.amp(0.5);
}      


void draw()

{  // fade in from min to max in increments of 5 points:
  for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) { 
    // sets the value (range from 0 to 255):
    arduino.analogWrite(ledPin, fadeValue);         
    // wait for 20 milliseconds to see the dimming effect    
    delay(20);                            
  } 

  delay(1000);
  arduino.analogWrite(ledPin, 0);
  delay (80);
  arduino.analogWrite(ledPin, 255);  
  delay (100);
  arduino.analogWrite(ledPin, 0);
  delay (80);
  arduino.analogWrite(ledPin, 255);  

  // fade out from not-quite-max to min in increments of 5 points:
  for(int fadeValue = 200 ; fadeValue >= 0; fadeValue -=random(2,20)) { 
    // sets the value (range from 0 to 200):
    arduino.analogWrite(ledPin, fadeValue);         
    // wait for 30 milliseconds to see the dimming effect    
    delay(30);                            
  } 
}

So at the moment, all that happens is that the LED performs as I want it to perform, but the WhiteNoise just plays solidly.

I think I could achieve the dip and rise in volume using the timing of the delays. However, so far, I have not been able to achieve volume changing at all.

Any help appreciated. Thank you.

Answers

  • I understand that I can change the sound before playback with amp() but I want to achieve volume changes over time (whilst the light is changing brightness) so I assume that I would have to write some code changing the volume under 'void draw() {' rather than 'void setup() {'.

    Forgot to mention that I am fairly new to Processing and Arduino.

  • err.... where do you change the amp of the WhiteNoise ?

    you wrote

    the LED performs as I want it to perform

    does the LED goes brighter and then dim again and on and on?

  • after line 30 AND 47 (well one time it's 255 and one time 200 nvm) insert

    float ampValue = map(fadeValue, 
        0, 255, 
        0.0, 1.0); 
    noise.amp(ampValue);
    
  • since amp says: Changes the amplitude/volume of the player. Allowed values are between 0.0 and 1.0.

    we need our amp values to be between 0.0 and 1.0.

    map() is a clever way to calculate this based on fadeValue and its range

    see reference on map() please

    https://www.processing.org/reference/

  • it is possible that the sound does not change the amp in that architecture

    then ask again

    I'm off now

  • edited January 2016

    Well it's sort of there, i've edited the code a bit and this is what i've got now

    import processing.serial.*;
    import cc.arduino.*;
    Arduino arduino;
    
    import processing.sound.*;
    WhiteNoise noise;
    
    int ledPin = 9;
    
    void setup()
    {
      //println(Arduino.list());
      arduino = new Arduino(this, "/dev/cu.usbmodem1411", 57600);
      arduino.pinMode(ledPin, Arduino.OUTPUT);
    
      size(640, 360);
      background(255);
    
      // Create the noise generator
      noise = new WhiteNoise(this);
      noise.play();
      noise.amp(0.5);
    
    }      
    
    
    void draw()
    
    {  // fade in from min to max in increments of 5 points:
      for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) { 
        // sets the value (range from 0 to 255):
        arduino.analogWrite(ledPin, fadeValue); 
    
        float ampValue = map(fadeValue, 255, 0, 0.0, 1.0); 
        noise.amp(ampValue);
    
        // wait for 20 milliseconds to see the dimming effect    
        delay(20);                            
      } 
    
      delay(1000);
      arduino.analogWrite(ledPin, 0);
      noise.amp(0);
      delay (80);
      arduino.analogWrite(ledPin, 255);  
      noise.amp(0.5);
      delay (100);
      arduino.analogWrite(ledPin, 0);
      noise.amp(0);
      delay (80);
      arduino.analogWrite(ledPin, 255); 
      noise.amp(0.5);
    
      // fade out from not-quite-max to min in increments of 5 points:
      for(int fadeValue = 200 ; fadeValue >= 0; fadeValue -=random(2,20)) { 
        // sets the value (range from 0 to 200);
        arduino.analogWrite(ledPin, fadeValue);         
        // wait for 30 milliseconds to see the dimming effect    
        delay(30);                            
      } 
    }
    

    What happens is the light and the white noise flash together. After this sequence, the LED gets bright then dims to no light whatsoever. Then the flashes come back and it loops. (Which is what I want to happen). However, the white noise seems to get a bit louder as the light gets brighter, then as it reaches its peak, it sounds like another WhiteNoise plays over the top as it goes lower again.

    It's hard to describe without videoing it or something.

  • Ah, it was just doing that because the noise.amp went as high as 1.0.

    Another question I wanted to ask is, why won't processing allow me to write: delay(random(1000,4000));

    I want a delay to start at a random time but Processing is saying "The function "delay()" expects parameters like: "delay(int)"". How would I achieve this?

  • edited January 2016

    The fact you're relying on delay() indicates you don't understand the purpose of Processing's draw() callback: https://Processing.org/reference/draw_.html

    When we need any animation to happen during some amount of time, we modify variables little by little for each draw().

    Placing everything inside some loop, especially when accompanied by delay(), is the wrong approach!

  • Answer ✓

    "The function "delay()" expects parameters like: "delay(int)""

    but random() returns a float. you can cast between the two

    delay((int)random(1000,4000));
    
  • @gotoloop: I think in this case it's ok to use a for-loop within draw() as he does since both, the LED and the sound, are updated throughout and not only at the end of draw() as it is with graphics.

  • edited January 2016

    @Chrisir, you're right.
    As long as he doesn't attempt to display anything to the canvas it won't make any diff. 8-|
    Just be aware that the WhiteNoise instance is run by another Thread.
    And while delay() is in effect, WhiteNoise is gonna keep its last amp().

Sign In or Register to comment.