When triggering a sound file there is a delay or latency, can this be reduced?

edited October 2016 in Library Questions

Heres a simple example that demonstrates the 70mS delay between triggering a sound file and it actually creating the sound.

This was tested with processing 3 on a windows platform. A microphone signal showing the sound is compared with the serial data signal indicating the command to play.

Am I doing something wrong? Can the delay be reduced?

Thanks for any help.

cheers, Andy

// A quick demo to show the delay between .play() and the sound being generated
// 
// every second, a serial character is sent - to trigger the oscilloscope on channel 1.
// then a sound file is played (edited .wav so there is no quiet start in the file)
// a microphone detects the sound which is displayed on the oscilloscope channel 2.
// the delay averages 70ms (varying between 65mS to 85mS)
//
// What is causing the delay and can it be reduced?



import processing.serial.*;
import processing.sound.*;
Serial myPort1;  // The serial port 
SoundFile Sound1;
int now, last;


void setup() 
{
  // List all the available serial ports
  printArray(Serial.list());
  // specify a specific port (to keep it simple)

  try {
        myPort1 = new Serial(this, Serial.list()[2], 57600);
        myPort1.clear();
      } catch (RuntimeException e) 
      {   
      }

  if (null != myPort1) print("Attached port1 to [2], ", Serial.list()[2], "\n");
  else print("port1 not connected\n");

  // open the .wav sound file which is a drum sound with no quiet time before the sample.
  Sound1 = new SoundFile(this, "click.wav");

  // set up timing to trigger sound every second
  last = millis();
}


void draw() 
{
  int now = millis();
  // if 1000mS elapsed since last sound, trigger again
  if ( (now - last) >= 1000 )
  {
    last = now;  // record time of click
    DoClick();
  }
}


// make the sound
void DoClick()
{
  // trigger the sound before sending oscilloscope trigger
   Sound1.play();
  // send serial character as a simple timing trigger.
  // done after sound so we cant blame the serial port for the delay.
  if (null != myPort1)
  { 
    myPort1.write(0x22);
  }
}

sound_latency

Tagged:

Answers

  • draw is only called every 60th of a second, by default, so there's a potential 60th of a second delay. change this using frameRate().

    jeremy posted some code this morning that used a busy wait to get the timing of frames more exact. here: https://forum.processing.org/two/discussion/comment/76482/#Comment_76482

    there might still be a delay in the play though because it has to do something.

    btw methods and members start with a lower case letter by default.

  • edited October 2016

    Thanks koogs,

    that is very useful to know and I'll try to get used to the lower case for methods and members :-)

    draw running 60 times a second or 16mS period will have some effect on the test start time but once doClick() is called, there should not be 70mS delay between statements within the function - right? 70mS is a very long time (1/14th second) to re-trigger a pre-loaded wav file.

    The play occurs 70mS after the write to serial port, opposite to call order.

    sound1.play();   // t + 70mS
    myPort1.write(0x22);   // t + 0mS
    

    Thanks for help.

  • you've no idea what play is doing behind the scenes though. i'm guessing it's not simple.

    actually, source is here:

    https://github.com/processing/processing-sound/blob/master/src/processing/sound/SoundFile.java#L114

    and doesn't do much other than call the underlying (third party) methcla library

    interestingly it is passing the filename to the library. is it reloading it from disk?

  • (it could just be using the filename as a label to a buffer that is already loaded.)

    methcla library is also in github but there's no reference to soundFilePlayMulti() within it.

Sign In or Register to comment.