p5.js-sound
p5.js-sound copied to clipboard
Chrome 70 will require user gestures required to enable web audio api
https://bugs.chromium.org/p/chromium/issues/detail?id=807017 (via Web Audio Weekly)
We'll need to update examples and documentation...I think the best bet is to encourage p5 developers to design prompts that guide users to start the web audio context
I am initializing the audio on a touchStarted event in Chrome on Android and still getting the error
The AudioContext was not allowed to start. It must be resume (or created) after a user gesture on the page. https://goo.gl/7K7WLu
(anonymous) @ p5.sound.js:211
(anonymous) @ p5.sound.js:292
(anonymous) @ p5.sound.js:73
(anonymous) @ p5.sound.js:74
p5.sound.js:4247 The AudioContext was not allowed to start. It must be resume (or created) after a user gesture on the page. https://goo.gl/7K7WLu
Tone.Context @ p5.sound.js:4247
(anonymous) @ p5.sound.js:4420
(anonymous) @ p5.sound.js:4425
(anonymous) @ p5.sound.js:73
(anonymous) @ p5.sound.js:74
My code is:
var mic
var vol = 0
function setup() {
createCanvas(windowWidth, windowHeight);
// Create an Audio input
}
function draw() {
background(200);
// Get the overall volume (between 0 and 1.0)
if(mic) {
background(255, 0, 0)
vol = mic.getLevel();
}
fill(127);
stroke(0);
// Draw an ellipse with height based on volume
var h = map(vol, 0, 0.5, height, 0);
ellipse(width/2, h - 25, 50, 50);
}
function touchStarted() {
mic = new p5.AudioIn();
// start the Audio Input.
// By default, it does not .connect() (to the computer speakers)
mic.start();
}
What's weird is that occasionally it DOES work, but only if I load the page from remote developer tools in Chrome.
Any suggestions for at least a temporary fix?
I also started seeing this error (new to Web Audio). Information here: https://developers.google.com/web/updates/2017/09/autoplay-policy-changes#webaudio getAudioContext() should do it, but I have worked out details as yet.
@shadoof is there a way to access the variable containing the audio context without changing the library? I am not very familiar with P5 sound.... I would like to try calling context.resume() as mentioned in that link.
I think that’s precisely what getAudioContext() does, but haven’t yet read the manual or done the work, so can’t provide a snippet. Doesn’t seem to be too hard. Good luck.
On May 3, 2018 at 1:22:08 PM, Olivia Jack ([email protected](mailto:[email protected])) wrote:
@shadoof(https://github.com/shadoof) is there a way to access the variable containing the audio context without changing the library? I am not very familiar with P5 sound.... I would like to try calling context.resume() as mentioned in that link.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub(https://github.com/processing/p5.js-sound/issues/249#issuecomment-386371294), or mute the thread(https://github.com/notifications/unsubscribe-auth/ABAMoPvGYLg45YWaAXSQnLrLqoW0Rp0iks5tuzzAgaJpZM4R4Bl4).
ok, this works for me in case it is helpful for anyone else:
var mic
var vol = 0
function setup() {
createCanvas(windowWidth, windowHeight);
// Create an Audio input
mic = new p5.AudioIn();
// start the Audio Input.
// By default, it does not .connect() (to the computer speakers)
mic.start();
}
function draw() {
background(200);
// Get the overall volume (between 0 and 1.0)
var vol = mic.getLevel();
fill(127);
stroke(0);
// Draw an ellipse with height based on volume
var h = map(vol, 0, 0.5, height, 0);
ellipse(width/2, h - 25, 50, 50);
}
function touchStarted() {
getAudioContext().resume()
}
nice work-around! I'd probably also add a condition to check if the AudioContext is running just in case there's some issue with resuming it on every touch:
function touchStarted() {
if (getAudioContext().state !== 'running') {
getAudioContext().resume();
}
}
I started adding a startAudioContext method in https://github.com/processing/p5.js-sound/pull/283
would love some feedback on this approach!
function mousePressed() { getAudioContext().resume() }
I had this issue after the new policy, and that line of code above fixed my guitar tuner app which uses p5 oscillators. I have a 'touring' mode, when activated (html checkbox) plays all the different frequencies in ascending order for a given guitar tuning, looping until the user hits the stop button. That's the only line I added. I didn't have to change anything else. Hope it helps.
The userStartAudio method will be in this release
https://github.com/processing/p5.js-sound/pull/322
An example:
function setup() {
var myDiv = createDiv('click to start audio');
myDiv.position(0, 0);
var mySynth = new p5.MonoSynth();
// This won't play until the context has started
mySynth.play('A6');
// Start the audio context on a click/touch event
userStartAudio().then(function() {
myDiv.remove();
});
}
This should have been fixed a long time ago, I'm sorry for trouble it's caused in the meantime. Feeling a bit overwhelmed about updating examples + documentation to help avoid future issues for anyone out there who is/has encountered this issue, and would love some help!
here's a PR / RFC to address this in a better way #402
sorry i'm kind of new but how do you fix this code The AudioContext was not allowed to start. It must be resumed (or created) after a user gesture on the page. audio.js:5
` function GameBoyAdvanceAudio() { window.AudioContext = window.AudioContext || window.webkitAudioContext; if (window.AudioContext) { var self = this; this.context = new AudioContext(); this.bufferSize = 0; this.bufferSize = 4096; this.maxSamples = this.bufferSize << 2; this.buffers = [new Float32Array(this.maxSamples), new Float32Array(this.maxSamples)]; this.sampleMask = this.maxSamples - 1; if (this.context.createScriptProcessor) { this.jsAudio = this.context.createScriptProcessor(this.bufferSize); } else { this.jsAudio = this.context.createJavaScriptNode(this.bufferSize); } this.jsAudio.onaudioprocess = function(e) { self.audioProcess(e) }; } else { this.context = null; }
this.masterEnable = true;
this.masterVolume = 1.0;
this.SOUND_MAX = 0x400;
this.FIFO_MAX = 0x200;
this.PSG_MAX = 0x080;
};
GameBoyAdvanceAudio.prototype.clear = function() { this.fifoA = []; this.fifoB = []; this.fifoASample = 0; this.fifoBSample = 0;
this.enabled = false;
if (this.context) {
try {
this.jsAudio.disconnect(this.context.destination);
} catch (e) {
}
}
this.enableChannel3 = false;
this.enableChannel4 = false;
this.enableChannelA = false;
this.enableChannelB = false;
this.enableRightChannelA = false;
this.enableLeftChannelA = false;
this.enableRightChannelB = false;
this.enableLeftChannelB = false;
this.playingChannel3 = false;
this.playingChannel4 = false;
this.volumeLeft = 0;
this.volumeRight = 0;
this.ratioChannelA = 1;
this.ratioChannelB = 1;
this.enabledLeft = 0;
this.enabledRight = 0;
this.dmaA = -1;
this.dmaB = -1;
this.soundTimerA = 0;
this.soundTimerB = 0;
this.soundRatio = 1;
this.soundBias = 0x200;
this.squareChannels = new Array();
for (var i = 0; i < 2; ++i) {
this.squareChannels[i] = {
enabled: false,
playing: false,
sample: 0,
duty: 0.5,
increment: 0,
step: 0,
initialVolume: 0,
volume: 0,
frequency: 0,
interval: 0,
sweepSteps: 0,
sweepIncrement: 0,
sweepInterval: 0,
doSweep: false,
raise: 0,
lower: 0,
nextStep: 0,
timed: false,
length: 0,
end: 0
}
}
this.waveData = new Uint8Array(32);
this.channel3Dimension = 0;
this.channel3Bank = 0;
this.channel3Volume = 0;
this.channel3Interval = 0;
this.channel3Next = 0;
this.channel3Length = 0;
this.channel3Timed = false;
this.channel3End = 0;
this.channel3Pointer =0;
this.channel3Sample = 0;
this.cpuFrequency = this.core.irq.FREQUENCY;
this.channel4 = {
sample: 0,
lfsr: 0,
width: 15,
interval: this.cpuFrequency / 524288,
increment: 0,
step: 0,
initialVolume: 0,
volume: 0,
nextStep: 0,
timed: false,
length: 0,
end: 0
};
this.nextEvent = 0;
this.nextSample = 0;
this.outputPointer = 0;
this.samplePointer = 0;
this.backup = 0;
this.totalSamples = 0;
this.sampleRate = 32768;
this.sampleInterval = this.cpuFrequency / this.sampleRate;
this.resampleRatio = 1;
if (this.context) {
this.resampleRatio = this.sampleRate / this.context.sampleRate;
}
this.writeSquareChannelFC(0, 0);
this.writeSquareChannelFC(1, 0);
this.writeChannel4FC(0);
};
GameBoyAdvanceAudio.prototype.freeze = function() { return { nextSample: this.nextSample }; };
GameBoyAdvanceAudio.prototype.defrost = function(frost) { this.nextSample = frost.nextSample; };
GameBoyAdvanceAudio.prototype.pause = function(paused) { if (this.context) { if (paused) { try { this.jsAudio.disconnect(this.context.destination); } catch (e) { // Sigh } } else if (this.enabled) { this.jsAudio.connect(this.context.destination); } } };
GameBoyAdvanceAudio.prototype.updateTimers = function() { var cycles = this.cpu.cycles; if (!this.enabled || (cycles < this.nextEvent && cycles < this.nextSample)) { return; }
if (cycles >= this.nextEvent) {
var channel = this.squareChannels[0];
this.nextEvent = Infinity;
if (channel.playing) {
this.updateSquareChannel(channel, cycles);
}
channel = this.squareChannels[1];
if (channel.playing) {
this.updateSquareChannel(channel, cycles);
}
if (this.enableChannel3 && this.playingChannel3) {
if (cycles >= this.channel3Next) {
if (this.channel3Write) {
var sample = this.waveData[this.channel3Pointer >> 1];
this.channel3Sample = (((sample >> ((this.channel3Pointer & 1) << 2)) & 0xF) - 0x8) / 8;
this.channel3Pointer = (this.channel3Pointer + 1);
if (this.channel3Dimension && this.channel3Pointer >= 64) {
this.channel3Pointer -= 64;
} else if (!this.channel3Bank && this.channel3Pointer >= 32) {
this.channel3Pointer -= 32;
} else if (this.channel3Pointer >= 64) {
this.channel3Pointer -= 32;
}
}
this.channel3Next += this.channel3Interval;
if (this.channel3Interval && this.nextEvent > this.channel3Next) {
this.nextEvent = this.channel3Next;
}
}
if (this.channel3Timed && cycles >= this.channel3End) {
this.playingChannel3 = false;
}
}
if (this.enableChannel4 && this.playingChannel4) {
if (this.channel4.timed && cycles >= this.channel4.end) {
this.playingChannel4 = false;
} else {
if (cycles >= this.channel4.next) {
this.channel4.lfsr >>= 1;
var sample = this.channel4.lfsr & 1;
this.channel4.lfsr |= (((this.channel4.lfsr >> 1) & 1) ^ sample) << (this.channel4.width - 1);
this.channel4.next += this.channel4.interval;
this.channel4.sample = (sample - 0.5) * 2 * this.channel4.volume;
}
this.updateEnvelope(this.channel4, cycles);
if (this.nextEvent > this.channel4.next) {
this.nextEvent = this.channel4.next;
}
if (this.channel4.timed && this.nextEvent > this.channel4.end) {
this.nextEvent = this.channel4.end;
}
}
}
}
if (cycles >= this.nextSample) {
this.sample();
this.nextSample += this.sampleInterval;
}
this.nextEvent = Math.ceil(this.nextEvent);
if ((this.nextEvent < cycles) || (this.nextSample < cycles)) {
// STM instructions may take a long time
this.updateTimers();
}
};
GameBoyAdvanceAudio.prototype.writeEnable = function(value) { this.enabled = !!value; this.nextEvent = this.cpu.cycles; this.nextSample = this.nextEvent; this.updateTimers(); this.core.irq.pollNextEvent(); if (this.context) { if (value) { this.jsAudio.connect(this.context.destination); } else { try { this.jsAudio.disconnect(this.context.destination); } catch (e) { } } } };
GameBoyAdvanceAudio.prototype.writeSoundControlLo = function(value) { this.masterVolumeLeft = value & 0x7; this.masterVolumeRight = (value >> 4) & 0x7; this.enabledLeft = (value >> 8) & 0xF; this.enabledRight = (value >> 12) & 0xF;
this.setSquareChannelEnabled(this.squareChannels[0], (this.enabledLeft | this.enabledRight) & 0x1);
this.setSquareChannelEnabled(this.squareChannels[1], (this.enabledLeft | this.enabledRight) & 0x2);
this.enableChannel3 = (this.enabledLeft | this.enabledRight) & 0x4;
this.setChannel4Enabled((this.enabledLeft | this.enabledRight) & 0x8);
this.updateTimers();
this.core.irq.pollNextEvent();
};
GameBoyAdvanceAudio.prototype.writeSoundControlHi = function(value) { switch (value & 0x0003) { case 0: this.soundRatio = 0.25; break; case 1: this.soundRatio = 0.50; break; case 2: this.soundRatio = 1; break; } this.ratioChannelA = (((value & 0x0004) >> 2) + 1) * 0.5; this.ratioChannelB = (((value & 0x0008) >> 3) + 1) * 0.5;
this.enableRightChannelA = value & 0x0100;
this.enableLeftChannelA = value & 0x0200;
this.enableChannelA = value & 0x0300;
this.soundTimerA = value & 0x0400;
if (value & 0x0800) {
this.fifoA = [];
}
this.enableRightChannelB = value & 0x1000;
this.enableLeftChannelB = value & 0x2000;
this.enableChannelB = value & 0x3000;
this.soundTimerB = value & 0x4000;
if (value & 0x8000) {
this.fifoB = [];
}
};
GameBoyAdvanceAudio.prototype.resetSquareChannel = function(channel) { if (channel.step) { channel.nextStep = this.cpu.cycles + channel.step; } if (channel.enabled && !channel.playing) { channel.raise = this.cpu.cycles; channel.lower = channel.raise + channel.duty * channel.interval; channel.end = this.cpu.cycles + channel.length; this.nextEvent = this.cpu.cycles; } channel.playing = channel.enabled; this.updateTimers(); this.core.irq.pollNextEvent(); };
GameBoyAdvanceAudio.prototype.setSquareChannelEnabled = function(channel, enable) { if (!(channel.enabled && channel.playing) && enable) { channel.enabled = !!enable; this.updateTimers(); this.core.irq.pollNextEvent(); } else { channel.enabled = !!enable; } };
GameBoyAdvanceAudio.prototype.writeSquareChannelSweep = function(channelId, value) { var channel = this.squareChannels[channelId]; channel.sweepSteps = value & 0x07; channel.sweepIncrement = (value & 0x08) ? -1 : 1; channel.sweepInterval = ((value >> 4) & 0x7) * this.cpuFrequency / 128; channel.doSweep = !!channel.sweepInterval; channel.nextSweep = this.cpu.cycles + channel.sweepInterval; this.resetSquareChannel(channel); };
GameBoyAdvanceAudio.prototype.writeSquareChannelDLE = function(channelId, value) { var channel = this.squareChannels[channelId]; var duty = (value >> 6) & 0x3; switch (duty) { case 0: channel.duty = 0.125; break; case 1: channel.duty = 0.25; break; case 2: channel.duty = 0.5; break; case 3: channel.duty = 0.75; break; } this.writeChannelLE(channel, value); this.resetSquareChannel(channel); };
GameBoyAdvanceAudio.prototype.writeSquareChannelFC = function(channelId, value) { var channel = this.squareChannels[channelId]; var frequency = value & 2047; channel.frequency = frequency; channel.interval = this.cpuFrequency * (2048 - frequency) / 131072; channel.timed = !!(value & 0x4000);
if (value & 0x8000) {
this.resetSquareChannel(channel);
channel.volume = channel.initialVolume;
}
};
GameBoyAdvanceAudio.prototype.updateSquareChannel = function(channel, cycles) { if (channel.timed && cycles >= channel.end) { channel.playing = false; return; }
if (channel.doSweep && cycles >= channel.nextSweep) {
channel.frequency += channel.sweepIncrement * (channel.frequency >> channel.sweepSteps);
if (channel.frequency < 0) {
channel.frequency = 0;
} else if (channel.frequency > 2047) {
channel.frequency = 2047;
channel.playing = false;
return;
}
channel.interval = this.cpuFrequency * (2048 - channel.frequency) / 131072;
channel.nextSweep += channel.sweepInterval;
}
if (cycles >= channel.raise) {
channel.sample = channel.volume;
channel.lower = channel.raise + channel.duty * channel.interval;
channel.raise += channel.interval;
} else if (cycles >= channel.lower) {
channel.sample = -channel.volume;
channel.lower += channel.interval;
}
this.updateEnvelope(channel, cycles);
if (this.nextEvent > channel.raise) {
this.nextEvent = channel.raise;
}
if (this.nextEvent > channel.lower) {
this.nextEvent = channel.lower;
}
if (channel.timed && this.nextEvent > channel.end) {
this.nextEvent = channel.end;
}
if (channel.doSweep && this.nextEvent > channel.nextSweep) {
this.nextEvent = channel.nextSweep;
}
};
GameBoyAdvanceAudio.prototype.writeChannel3Lo = function(value) { this.channel3Dimension = value & 0x20; this.channel3Bank = value & 0x40; var enable = value & 0x80; if (!this.channel3Write && enable) { this.channel3Write = enable; this.resetChannel3(); } else { this.channel3Write = enable; } };
GameBoyAdvanceAudio.prototype.writeChannel3Hi = function(value) { this.channel3Length = this.cpuFrequency * (0x100 - (value & 0xFF)) / 256; var volume = (value >> 13) & 0x7; switch (volume) { case 0: this.channel3Volume = 0; break; case 1: this.channel3Volume = 1; break; case 2: this.channel3Volume = 0.5; break; case 3: this.channel3Volume = 0.25; break; default: this.channel3Volume = 0.75; } };
GameBoyAdvanceAudio.prototype.writeChannel3X = function(value) { this.channel3Interval = this.cpuFrequency * (2048 - (value & 0x7FF)) / 2097152; this.channel3Timed = !!(value & 0x4000); if (this.channel3Write) { this.resetChannel3(); } };
GameBoyAdvanceAudio.prototype.resetChannel3 = function() { this.channel3Next = this.cpu.cycles; this.nextEvent = this.channel3Next; this.channel3End = this.cpu.cycles + this.channel3Length; this.playingChannel3 = this.channel3Write; this.updateTimers(); this.core.irq.pollNextEvent(); };
GameBoyAdvanceAudio.prototype.writeWaveData = function(offset, data, width) { if (!this.channel3Bank) { offset += 16; } if (width == 2) { this.waveData[offset] = data & 0xFF; data >>= 8; ++offset; } this.waveData[offset] = data & 0xFF; };
GameBoyAdvanceAudio.prototype.setChannel4Enabled = function(enable) { if (!this.enableChannel4 && enable) { this.channel4.next = this.cpu.cycles; this.channel4.end = this.cpu.cycles + this.channel4.length; this.enableChannel4 = true; this.playingChannel4 = true; this.nextEvent = this.cpu.cycles; this.updateEnvelope(this.channel4); this.updateTimers(); this.core.irq.pollNextEvent(); } else { this.enableChannel4 = enable; } }
GameBoyAdvanceAudio.prototype.writeChannel4LE = function(value) { this.writeChannelLE(this.channel4, value); this.resetChannel4(); };
GameBoyAdvanceAudio.prototype.writeChannel4FC = function(value) { this.channel4.timed = !!(value & 0x4000);
var r = value & 0x7;
if (!r) {
r = 0.5;
}
var s = (value >> 4) & 0xF;
var interval = this.cpuFrequency * (r * (2 << s)) / 524288;
if (interval != this.channel4.interval) {
this.channel4.interval = interval;
this.resetChannel4();
}
var width = (value & 0x8) ? 7 : 15;
if (width != this.channel4.width) {
this.channel4.width = width;
this.resetChannel4();
}
if (value & 0x8000) {
this.resetChannel4();
}
};
GameBoyAdvanceAudio.prototype.resetChannel4 = function() { if (this.channel4.width == 15) { this.channel4.lfsr = 0x4000; } else { this.channel4.lfsr = 0x40; } this.channel4.volume = this.channel4.initialVolume; if (this.channel4.step) { this.channel4.nextStep = this.cpu.cycles + this.channel4.step; } this.channel4.end = this.cpu.cycles + this.channel4.length; this.channel4.next = this.cpu.cycles; this.nextEvent = this.channel4.next;
this.playingChannel4 = this.enableChannel4;
this.updateTimers();
this.core.irq.pollNextEvent();
};
GameBoyAdvanceAudio.prototype.writeChannelLE = function(channel, value) { channel.length = this.cpuFrequency * ((0x40 - (value & 0x3F)) / 256);
if (value & 0x0800) {
channel.increment = 1 / 16;
} else {
channel.increment = -1 / 16;
}
channel.initialVolume = ((value >> 12) & 0xF) / 16;
channel.step = this.cpuFrequency * (((value >> 8) & 0x7) / 64);
};
GameBoyAdvanceAudio.prototype.updateEnvelope = function(channel, cycles) { if (channel.step) { if (cycles >= channel.nextStep) { channel.volume += channel.increment; if (channel.volume > 1) { channel.volume = 1; } else if (channel.volume < 0) { channel.volume = 0; } channel.nextStep += channel.step; }
if (this.nextEvent > channel.nextStep) {
this.nextEvent = channel.nextStep;
}
}
};
GameBoyAdvanceAudio.prototype.appendToFifoA = function(value) { var b; if (this.fifoA.length > 28) { this.fifoA = this.fifoA.slice(-28); } for (var i = 0; i < 4; ++i) { b = (value & 0xFF) << 24; value >>= 8; this.fifoA.push(b / 0x80000000); } };
GameBoyAdvanceAudio.prototype.appendToFifoB = function(value) { var b; if (this.fifoB.length > 28) { this.fifoB = this.fifoB.slice(-28); } for (var i = 0; i < 4; ++i) { b = (value & 0xFF) << 24; value >>= 8; this.fifoB.push(b / 0x80000000); } };
GameBoyAdvanceAudio.prototype.sampleFifoA = function() { if (this.fifoA.length <= 16) { var dma = this.core.irq.dma[this.dmaA]; dma.nextCount = 4; this.core.mmu.serviceDma(this.dmaA, dma); } this.fifoASample = this.fifoA.shift(); };
GameBoyAdvanceAudio.prototype.sampleFifoB = function() { if (this.fifoB.length <= 16) { var dma = this.core.irq.dma[this.dmaB]; dma.nextCount = 4; this.core.mmu.serviceDma(this.dmaB, dma); } this.fifoBSample = this.fifoB.shift(); };
GameBoyAdvanceAudio.prototype.scheduleFIFODma = function(number, info) { switch (info.dest) { case this.cpu.mmu.BASE_IO | this.cpu.irq.io.FIFO_A_LO: // FIXME: is this needed or a hack? info.dstControl = 2; this.dmaA = number; break; case this.cpu.mmu.BASE_IO | this.cpu.irq.io.FIFO_B_LO: info.dstControl = 2; this.dmaB = number; break; default: this.core.WARN('Tried to schedule FIFO DMA for non-FIFO destination'); break; } };
GameBoyAdvanceAudio.prototype.sample = function() { var sampleLeft = 0; var sampleRight = 0; var sample; var channel;
channel = this.squareChannels[0];
if (channel.playing) {
sample = channel.sample * this.soundRatio * this.PSG_MAX;
if (this.enabledLeft & 0x1) {
sampleLeft += sample;
}
if (this.enabledRight & 0x1) {
sampleRight += sample;
}
}
channel = this.squareChannels[1];
if (channel.playing) {
sample = channel.sample * this.soundRatio * this.PSG_MAX;
if (this.enabledLeft & 0x2) {
sampleLeft += sample;
}
if (this.enabledRight & 0x2) {
sampleRight += sample;
}
}
if (this.playingChannel3) {
sample = this.channel3Sample * this.soundRatio * this.channel3Volume * this.PSG_MAX;
if (this.enabledLeft & 0x4) {
sampleLeft += sample;
}
if (this.enabledRight & 0x4) {
sampleRight += sample;
}
}
if (this.playingChannel4) {
sample = this.channel4.sample * this.soundRatio * this.PSG_MAX;
if (this.enabledLeft & 0x8) {
sampleLeft += sample;
}
if (this.enabledRight & 0x8) {
sampleRight += sample;
}
}
if (this.enableChannelA) {
sample = this.fifoASample * this.FIFO_MAX * this.ratioChannelA;
if (this.enableLeftChannelA) {
sampleLeft += sample;
}
if (this.enableRightChannelA) {
sampleRight += sample;
}
}
if (this.enableChannelB) {
sample = this.fifoBSample * this.FIFO_MAX * this.ratioChannelB;
if (this.enableLeftChannelB) {
sampleLeft += sample;
}
if (this.enableRightChannelB) {
sampleRight += sample;
}
}
var samplePointer = this.samplePointer;
sampleLeft *= this.masterVolume / this.SOUND_MAX;
sampleLeft = Math.max(Math.min(sampleLeft, 1), -1);
sampleRight *= this.masterVolume / this.SOUND_MAX;
sampleRight = Math.max(Math.min(sampleRight, 1), -1);
if (this.buffers) {
this.buffers[0][samplePointer] = sampleLeft;
this.buffers[1][samplePointer] = sampleRight;
}
this.samplePointer = (samplePointer + 1) & this.sampleMask;
};
GameBoyAdvanceAudio.prototype.audioProcess = function(audioProcessingEvent) { var left = audioProcessingEvent.outputBuffer.getChannelData(0); var right = audioProcessingEvent.outputBuffer.getChannelData(1); if (this.masterEnable) { var i; var o = this.outputPointer; for (i = 0; i < this.bufferSize; ++i, o += this.resampleRatio) { if (o >= this.maxSamples) { o -= this.maxSamples; } if ((o | 0) == this.samplePointer) { ++this.backup; break; } left[i] = this.buffers[0][o | 0]; right[i] = this.buffers[1][o | 0]; } for (; i < this.bufferSize; ++i) { left[i] = 0; right[i] = 0; } this.outputPointer = o; ++this.totalSamples; } else { for (i = 0; i < this.bufferSize; ++i) { left[i] = 0; right[i] = 0; } } }; `
this.ac.onstatechange = function() {
console.log(this.ac.state);
if (this.ac.state !== 'running') {
this.ac.resume();
}
}
I worked out this issue what u need to do is go to site settings and allow sound their by default it works then
I worked out this issue what u need to do is go to site settings and allow sound their by default it works then
Building on @TireOnFire 's comment, I was able to allow sound autoplay for localhost:8080 in Chrome. This is just for development purposes, which is what I needed. I imagine this won't be a solution for everyone.
chrome://settings/content/sound