Dynamically playing multiple sounds using javascript - javascript

var actions = function(){return {whichPattern:"pattern1"}};
var audio = new Audio();
var _play = function(){
var l = pattern[actions().whichPattern].instrument.length,
times_played =0;
var p = setInterval(function(){
var x = pattern[actions().whichPattern][times_played];
for(var i=0; i<x.length;i++){
var toBePlayed = pattern[actions().whichPattern][times_played][i],
url= "All Drums sounds/"+toBePlayed+".wav";
audio.src = url;
audio.play();
console.log(audio);
times_played++;
}
}, pattern_config[actions().whichPattern].delay);
if(times_played === l){
clearInterval(p);
};
var pp=document.getElementById("play_pause");
pp.style.background="url('graphics/pause.png') no-repeat";
pp.style.backgroundSize ="30px 28px"
audio.source='All Drums sounds/'+pattern['pattern1'][1][0]+'.wav';
audio.play();
};
var pattern_config = {
pattern1:{
WP_slotsCounter:0,
instrument:["Kick_02", "F_T_03", "Rude_cymbal_02"],
delay:10
},
};
var pattern={
pattern1: [], // [['asas', 'sf', 'asd'], ['svv','dgh','sdgh']]
}
The above code is very simple. The first function return an object ...
well the main motive of mine is like :
assuming that pattern.pattern1 = [['asas', 'sf', 'asd'], ['svv','dgh','sdgh']] so i what that the all the strings in the pattern['pattern1'][0] should play at same instant and then with a delay of patter_config[actions().whichPattern].delay that sound files with that names of pattern['pattern1'][1] should play together.
so to achieve this i made the above function _play()
well the problem is that it is not playing the music files and not giving any errors too so that i can identify where is that problem.

pattern["pattern1"] is an array of strings and does not have any 'instrument' property
maybe you were trying to use pattern_config["pattern1"]
var actions = function () {
return {
whichPattern: "pattern1"
}
};
var audio = new Audio();
var _play = function () {
var l = pattern_config[actions().whichPattern].instrument.length,
times_played = 0;
var p = setInterval(function () {
var x = pattern_config[actions().whichPattern][times_played];
for (var i = 0; i < x.length; i++) {
var toBePlayed = pattern_config[actions().whichPattern][times_played][i],
url = "All Drums sounds/" + toBePlayed + ".wav";
audio.src = url;
audio.play();
console.log(audio);
times_played++;
}
}, pattern_config[actions().whichPattern].delay);
if (times_played === l) {
clearInterval(p);
};
var pp = document.getElementById("play_pause");
pp.style.background = "url('graphics/pause.png') no-repeat";
pp.style.backgroundSize = "30px 28px"
audio.source = 'All Drums sounds/' + pattern['pattern1'][1][0] + '.wav';
audio.play();
};
var pattern_config = {
pattern1: {
WP_slotsCounter: 0,
instrument: ["Kick_02", "F_T_03", "Rude_cymbal_02"],
delay: 10
},
};
var pattern = {
pattern1: [['asas', 'sf', 'asd'], ['svv','dgh','sdgh']],
}

Related

addEventListener code is not working after i added click too

var numofDrumButton = document.querySelectorAll(".drum").length;
for (var i = 0 ; i<numofDrumButton; i++){
document.querySelector(".drum")[i].addEventListener("click", function() {
var audio = new Audio("sounds/tom-1.mp3");
audio.play();
});
}
Change your code to this:
var drumButton = document.querySelectorAll(".drum");
for (var i = 0; i < drumButton.length; i++){
drumButton[i].addEventListener("click", function() {
var audio = new Audio("sounds/tom-1.mp3");
audio.play();
});
}
You have to use the same variable in the for loop :)

why will lines 56 and 67 not work? (.votess +=1;)

var imgs = ['bmw.jpg', 'bugatti.jpg', 'classic.jpg', 'concept.jpg', 'corvette.jpg', 'dino.jpg', 'lambo.jpg', 'mcclaren.jpg', 'p1.jpg', 'porsche.jpg', 'rally.jpg', 'audi.jpg'];
// var imgs_count = {'bmw.jpg': 0, 'bugatti.jpg': 0, 'classic.jpg': 0, 'concept.jpg': 0, 'corvette.jpg': 0, 'dino.jpg': 0, 'lambo.jpg': 0, 'mcclaren.jpg': 0, 'p1.jpg': 0, 'porsche.jpg': 0,'rally.jpg': 0, 'audi.jpg':0}
// for (var i in imgs_count) {
// imgs_count[i]
// }
var allCars = [];
var votes;
function Car(file) {
this.file = file;
this.votes = 0;
allCars.push(this);
}
var bmw = new Car('bmw.jpg');
var bugatti = new Car('bugatti.jpg');
var classic = new Car('classic.jpg');
var concept = new Car('concept.jpg');
var corvette = new Car('corvette.jpg');
var dino = new Car('dino.jpg');
var lambo = new Car('lambo.jpg');
var mcclaren = new Car('mcclaren.jpg');
var p1 = new Car('p1.jpg');
var porsche =new Car('porsche.jpg');
var rally = new Car('rally.jpg');
var audi = new Car('audi.jpg');
var idx1 = 0;
var idx2 = 0;
var path = 'cars/';
var done = false;
function getRandomImage() {
idx1 = Math.floor(Math.random()*imgs.length);
var img1 = imgs[idx1];
idx2 = idx1;
while (idx2 == idx1) {
idx2 = Math.floor(Math.random()*imgs.length);
}
img2 = imgs[idx2];
document.getElementById('choice1').setAttribute('src', path + img1);
document.getElementById('choice2').setAttribute('src', path + img2);
}
function setOnClicks(id) {
document.getElementById(id).addEventListener('click', function(event) {
var choice = event.target.id;
if (choice === 'choice1') {
console.log(allCars);
var img = document.getElementById(id).getAttribute('src');
var allCars = img.slice(5,img.length);
this.allCars[idx1].votes += 1;
console.log(idx1);
console.log(this.allCars[idx1].votes)
if ( allCars[idx1].votes=3) {
done = true;
}
}
if (choice === 'choice2') {
var img = document.getElementById(id).getAttribute('src');
var allCars = img.slice(5,img.length);
console.log(idx2);
console.log(this.allCars[idx2].votes);
this.allCars[idx2].votes += 1;
if (allCars[idx2].votes == 3) {
done = true;
}
}
if (!done)
getRandomImage();
});
}
getRandomImage();
setOnClicks('choice1');
setOnClicks('choice2')l
You're overwriting your global allCars with a local var declaration of the same name:
var allCars = img.slice(5,img.length);
you are creating a local variable allCars under click event, while this.allCars is point to the allCars variable under window object
var allCars = img.slice(5,img.length); // this is a local variable
this.allCars[idx1].votes += 1; // this is same as window.allCars
console.log(idx1);

Javascript play Audio after other without audio-collapse

I am trying to play one audio after another using Javascript. I get the audio file name from a vector (int) and from some strings I have created.
This is my code but I can't make it works.
var audio = new Audio();
function playAll(){
var folder_name = "synthex/";
var file_name = ".sentence";
var audio_file = ".wav";
for(i=0;i<18;++i)
{
var dir_file = folder_name + voicesClicks[i];
dir_file = dir_file + file_name;
if(voicesClicks[i] == null){
continue;
}
//var value = voicesClicks[i];
dir_file = dir_file + i;
dir_file = dir_file + audio_file;
console.log(dir_file);
audio.src = dir_file;
audio.play();
}
}
One major problem that I find with your code is, audio's src keep changing in each iteration, so even if the audio.src value is a vaild wav file, you code would end up playing the last one...
I had a similar requirement, I did...
function playAll() {
// CHANGE this list to as per your requirement.
var urls = ['http://upload.wikimedia.org/wikipedia/en/f/f9/Beatles_eleanor_rigby.ogg',
'http://upload.wikimedia.org/wikipedia/commons/5/5b/Ludwig_van_Beethoven_-_Symphonie_5_c-moll_-_1._Allegro_con_brio.ogg'
];
var idx = 0;
var aud = new Audio();
aud.src = urls[idx];
aud.addEventListener('ended', function() { // for automatically starting the next.
idx++;
if (idx === urls.length) idx = 0;
aud.src = urls[idx];
aud.play();
});
aud.play();
}
document.addEventListener("DOMContentLoaded", playAll); // you can change this to button.onclick handler.
Edit: you can change the urls to ...
var urls = [];
for(i=0;i<18;++i){
if(!voicesClicks[i]){
continue;
}
urls.push(folder_name + voicesClicks[i] + file_name + i + audio_file);
}
console.log(JSON.stringify(urls)); // for debug

Low Latency Audio Playback?

Is it possible to achieve low latency audio playback using HTML5? I'm currently using AudioContext API. However, I am getting latency of about 4 seconds. Which is way to much for my use case.
if (!window.audioContextInstance) {
window.audioContextInstance = new webkitAudioContext();
}
var context = window.audioContextInstance;
context.sampleRate = 48000;
var buffers = [];
var src = new Float32Array();
var srcIdx = 0;
var bufferSize = 2048;
var sourceNode = context.createScriptProcessor(bufferSize, 1, 2);
sourceNode.onaudioprocess = function(evt) {
var c0 = evt.outputBuffer.getChannelData(0);
var c1 = evt.outputBuffer.getChannelData(1);
var sample = 0;
while(sample < bufferSize) {
if (srcIdx >= src.length) {
if (!buffers.length) {
console.log("Warning: Audio Buffer Underflow")
return;
}
src = buffers.shift();
srcIdx = 0;
}
while(sample < bufferSize && srcIdx < src.length) {
c0[sample] = src[srcIdx++];
c1[sample] = src[srcIdx++];
sample++;
}
}
};
scope.$on('frame', function (event, frame) {
while (buffers.length > 1) {
buffers.shift();
}
buffers.push(new Float32Array(frame.data));
if (buffers.length > 0) {
sourceNode.connect(context.destination);
}
});
}
You may be interested in riffwave.js which appears to have much lower than 4s latency.

Html5/javascript/easeljs game project.Lots of code.I need a way out

I am working on a card game with HTML5 canvas and javascript with create.js library. The problem i have is that, I have an onclick function that deletes the clicked card from player's hand(removes the object from the array with splice and then redraws the canvas/redraws on canvas the new array of player's cards without the deleted one). When i do this for first time it does well.But if I click again on the card that it should be for example at index 1 in the array(after the splice method) it doesn't work.
Look at this code:
Here is my code for class Card:
function Card(suit,rank,imageFrontUrl,imageBackUrl)
{
this.imageFront = new createjs.Bitmap(imageFrontUrl);
this.imageBack = new createjs.Bitmap(imageBackUrl);
this.suit = suit;
this.rank = rank;
}
function Deck(){
this.cards = new Array();
this.makeDeck = function()
{
this.cards[0]= new Card("clubs",1,"images/114.png","images/155.png");
this.cards[1]= new Card("clubs",2,"images/115.png","images/155.png");
this.cards[2]= new Card("clubs",3,"images/116.png","images/155.png");
this.cards[3]= new Card("clubs",4,"images/117.png","images/155.png");
this.cards[4]= new Card("clubs",5,"images/118.png","images/155.png");
this.cards[5]= new Card("clubs",6,"images/119.png","images/155.png");
...
}
this.shuffleDeck = function()
{
var j,k;
for (j = 0; j < this.cards.length; j++) {
k = Math.floor(Math.random() * this.cards.length);
temp = this.cards[j];
this.cards[j] = this.cards[k];
this.cards[k] = temp;
}
}
this.dealCardsPlayer = function()
{
var playerDeck = new Array();
for(var i = 0; i<6;i++)
{
var x = this.cards.pop();
playerDeck.push(x);
}
return playerDeck;
}
}
Here is my code for class Player:
function Player()
{
this.playerTurn = false;
this.id = this;
this.name = this;
this.score = this;
this.playerHand = new Array();
this.playerTakenCards = new Array();
this.playerPickCard = function(n)
{
var card = this.playerHand(n);
return card;
}
this.tempArray = this;}
Here is my init function:
function init(){
var canvas = document.getElementById("tutorialCanvas");
var stage = new createjs.Stage(canvas);
var deck = new Deck();
var player1 = new Player();
deck.makeDeck();
deck.shuffleDeck();
player1.playerHand = deck.dealCardsPlayer();
function drawPlayerCards(){
var rotation=280;
for(var i =0;i<player1.playerHand.length;i++)
{
player1.playerHand[i].imageFront.x=330;
player1.playerHand[i].imageFront.y=750;
player1.playerHand[i].imageFront.regX = 0;
player1.playerHand[i].imageFront.regY = 96;
player1.playerHand[i].imageFront.rotation = rotation;
rotation = player1.playerHand[i].imageFront.rotation+20;
stage.addChild(player1.playerHand[i].imageFront);
}
}
createjs.Ticker.addEventListener("tick", stage);}
And here is the function i have problem with:
player1.playerHand[1].imageFront.addEventListener('click',function(event)
{
stage.removeAllChildren();
player1.playerHand.splice(1,1);
drawTableDeck();
drawPlayerCards();
}
After some researching I realized that the function works just for the first bitmap player1.playerHand[1].imageFront . If i change the array with the first onclick event and after that player1.playerHand[1].imageFront is some other image/bitmap, it doesn't work for it. Please help!
Why are you "hardcoding" the index of a card in your hand?
player1.playerHand.forEach(function(card) {
card.imageFront.addEventListener("click", function() {
var index = player1.playerHand.indexOf(card);
if (index != -1) {
stage.removeAllChildren();
player1.playerHand.splice(index, 1);
drawPlayerCards();
}
});
});
Some other notes:
It's a convention to use [] instead of new Array()
We normally put the opening brace { on the same line
Your Player constructor has an error: this.playerHand[n] instead of this.playerHand(n)

Categories