19

I'm working on a web-based music sequencer/tracker, and I've noticed that in my sample playback routine, audio contexts seem to exist only for the duration of of a sample, and that the Web Audio API doesn't seem to adjust playback duration when I pitchshift a sample. For instance, if I shift a note down an octave, the routine only plays the first half of the sound before cutting off. More intense pitch downshifts result in even less of the sound playing, and while I'm not sure I can confirm this, I suspect that speeding up the audio results in relatively long periods of silence before the sound exits the buffer.

Here's my audio playback routine at the moment. So far, a lot more work has gone into making sure other functions send the right data to this than into extending the functionality of this routine.

function playSound(buffer, pitch, dspEffect, dspValue, volume) {

  var source = audioEngine.createBufferSource();  
  source.buffer = buffer;
  source.playbackRate.value = pitch; 

  // Volume adjustment is handled before other DSP effects are added.
  var volumeAdjustment = audioEngine.createGain();
  source.connect(volumeAdjustment);
  // Very basic error trapping in case of bad volume input.
  if(volume >= 0 && volume <= 1) { 
    volumeAdjustment.gain.value = volume; 
  } else { 
    volumeAdjustment.gain.value = 0.6; 
  }

  switch(dspEffect){
    case 'lowpass':
      var createLowPass = audioEngine.createBiquadFilter();
      volumeAdjustment.connect(createLowPass);
      createLowPass.connect(audioEngine.destination);
      createLowPass.type = 'lowpass';
      createLowPass.frequency.value = dspValue;
      break;
    // There are a couple of other optional DSP effects, 
    // but so far they all operate in about the same fashion.
  }
  source.start();
}

My intent is for samples to play back fully no matter how much pitch shifting is applied, and to limit the amount of pitch shifting allowed if necessary. I've found that appending several seconds of silence to a sound works around this issue, but it's cumbersome due to the large amount of sounds I would need to process, and I'd prefer a code-based solution.

EDIT: Of the browsers I can test this in, this only appears to be an issue in Google Chrome. Samples play back fully in Firefox, Internet Explorer does not yet support the Web Audio API, and I do not have ready access to Safari or Opera. This definitely changes the nature of the help I'm looking for.

thanksd
  • 54,176
  • 22
  • 157
  • 150
Jessica Kagan
  • 319
  • 1
  • 8
  • Do you have a hosted example of this occurring? It's certainly true that changing playbackrate should not change the sound playing to completion, but without seeing it in action I can't debug. – cwilso Jun 17 '15 at 19:52
  • This routine is part of a program called Tracker2D, which is available at http://gabekagan.github.io/Tracker2D/. I've recently found that the bug doesn't seem to happen in Firefox. I apparently missed it because I've mostly been developing in Chrome, and I will edit the original question to indicate this. – Jessica Kagan Jun 17 '15 at 20:07
  • I'd suggest you double check if this appears in the latest Chromium nightly and then file a bug in Chromium issue tracker https://code.google.com/p/chromium/issues/list – Mikko Ohtamaa Jun 17 '15 at 21:33
  • 4
    There were some issues in Chrome with the playback of source nodes with a playback rate less than 1. I think this was fixed in time for M44, but I'm not sure. – Raymond Toy Jun 17 '15 at 22:19

1 Answers1

1

I've found that appending several seconds of silence to a sound works around this issue, but it's cumbersome due to the large amount of sounds I would need to process, and I'd prefer a code-based solution.

You could upload a sound file that is just several seconds of silence and append it to the actual audio file. Here is an SO answer that shows how to do this...

Community
  • 1
  • 1
MoralCode
  • 1,954
  • 1
  • 20
  • 42