1

i am coding a full air horn piano for me and my friends (kind of dumb i know) and i got to doing all the key binds and then i ran into this problem, the sounds wont stop when i release the key that was pressed to activate it.

here is what i have so far in the .js file(just one sound put in so far):

function startAnatural(){

var A = new Audio("A natural.mp3"); 
A.play();

}

function stopAnatural(){
var A = new Audio("A natural.mp3");

A.pause();
A.currentTime = 0;;

}

document.onkeydown = function(e){
    e = e || window.event;
    var key = e.which || e.keyCode;
    if(key===81){
        startAnatural();
    }
};

document.onkeyup = function(e){
    e = e || window.event;
    var key = e.which || e.keyCode;
    if(key===81){
        stopAnatural();
    }

};

2 Answers2

1

You're creating a new instance of the same sound and pausing it, whilst the original instance carries on playing.

Instead, both functions need to have a reference to the same Audio object.

Maybe a design like this would work better for you.

function createSound(file) {
  var sound = new Audio(file);

  return {
    start: function() {
      sound.play();
    },
    stop: function() {
      sound.pause();
      sound.currentTime = 0;
    }
  };
}

This function takes the name of a sound you want to load, then returns two other functions for starting and stopping it. Both functions will always refer to the same Audio instance.

var aNatural = createSound('A natural.mp3');

document.onkeydown = function() {
  // ...
  aNatural.start();
  // ...
}

document.onkeyup = function() {
  // ...
  aNatural.stop();
  // ...
}

If you want to organize all of your sounds, you'll want to store the sounds against the corresponding keycodes.

var notes = [
  { key: 81, sound: createSound('A natural.mp3') },
  { key: 82, sound: createSound('B natural.mp3') },
  { key: 83, sound: createSound('C natural.mp3') }
  // ...
];

Then you can create event listeners trigger each sound with the appropriate key code.

document.onkeydown = function() {
  var pressedKey = e.which;

  notes.forEach(function(note) {
    if(note.key === pressedKey) {
      note.sound.start();
    }
  });
}

// do the same for keyup
// ...
Dan Prince
  • 29,491
  • 13
  • 89
  • 120
0

To solve your code, just move the sound declaration outside the functions... but Dan is correct regarding multiple instances playing simultaneously.

var A = new Audio("A natural.mp3"); 

function startAnatural(){
    A.play();
}

function stopAnatural(){
  A.pause();
  A.currentTime = 0;
}

document.onkeydown = function(e){
    e = e || window.event;
    var key = e.which || e.keyCode;
    if(key===81){
        startAnatural();
    }
};

document.onkeyup = function(e){
    e = e || window.event;
    var key = e.which || e.keyCode;
    if(key===81){
        stopAnatural();
    }

};
mjwjon
  • 316
  • 1
  • 4