cwilso / metronome Goto Github PK
View Code? Open in Web Editor NEWWeb Audio metronome example to show scheduling.
Home Page: https://cwilso.github.io/metronome/
License: MIT License
Web Audio metronome example to show scheduling.
Home Page: https://cwilso.github.io/metronome/
License: MIT License
I've just read your article https://web.dev/audio-scheduling/ and it seems like you said that the combination of
setTimeout/Interval with AudioContext make the Rock-Solid Timing
.
But in the example it is a bit more complex than the article.
Is this released under an FOSS license and if so can you include it in the repo or README?
Hi Chris,
I use this approach for metronome timing in Tone.js. One great thing about using a WebWorker like you do is that it runs in a background tab. But, I was just running this on Chrome Canary (55.0.2856.0) and I noticed this is no longer the case. It seems to get throttled just like events scheduled from requestAnimationFrame.
Background scheduling of Web Audio is a wonderful thing and it'd be a shame to lose it in Chrome (still works the same in Safari and FF though). I'm wondering if you have any thoughts or work arounds for this.
Thanks!
After starting the metronome, the first note is always clipped and generates a click.
It is easier to tell when the metronome is set to quarter notes or slowed to a low tempo.
Hi mate,
I managed to make your metronome work on an Ionic mobile app, but i need to change the audio file to some other 4 options of audio.
I'm reading your code but im not finding the best way to do that.
Can you give me a hint?
Thanks and great work!
Great job. Thanks for that.
Well I think I got an isse here. If you turns on the microphone to record something on the same page, the metronome stops working. Any idea of what is going on?
I am not good at music or coding at all, so I am sorry if my question is too stupid.
Some comments in metronome.js (https://github.com/cwilso/metronome/blob/master/js/metronome.js) about pitch confuse me -
Line 58 - if (beatNumber % 16 === 0) // beat 0 == low pitch <- should this actually a high pitch note?
osc.frequency.value = 880.0;
Line 62 else // other 16th notes = high pitch <- should these actually low pitch notes?
osc.frequency.value = 220.0;
If the tab with the metronome app is made inactive the AudioContext is 'suspended' / 'interrupted' and has to be manually re-started with audioContext.resume();
in the play()
function once the tab is made active again. (see https://developer.mozilla.org/en-US/docs/Web/API/BaseAudioContext/state)
This works on Chrome, but not in Safari. AudioContext is apparently re-started and running in Safari, but the audio clock is frozen leaving the application dead. The only workround I have found is to detect the 'suspended' or 'interrupted' state and then close the AudioContext and make a new one (plus any associated nodes like gain).
This then works in both Safari and Chrome. (see https://github.com/nmcgann/metronome for this fix and various other added features)
There is an issue with the live app in Firefox. When you change the BPM slider the number isn't updated.
The problem appears to be that you include a non HTTPS script in a HTTPS page. The javascript console reported an error and referred to an explanation.
The script is accessible via HTTPS so the fix is trivial.
I suggest you change the line
<script src="http://cwilso.github.io/AudioContext-MonkeyPatch/AudioContextMonkeyPatch.js"></script>
to
<script src="//cwilso.github.io/AudioContext-MonkeyPatch/AudioContextMonkeyPatch.js"></script>
That way it will work with both HTTP and HTTPS pages.
Time to redeploy with Oscillator.start() instead of Oscillator.noteOn() :)
I see a difference in time between the visual and the auditory, I can not say why. But where I notice the most is with Google Chrome on Android. Would you know how to correct it? Thank you. I'm sorry for my English.
Hi,
I was wondering if someone can help me along. I'm playing with metronome, hoping I can use it to (manually) align it with a media track (audio or video).
I can play both and play with the tempo in the metronome, but have a hard time figuring how to align them.
Let's say the beat (120bmp) starts at 4.5 seconds in my media track. how do I 'offset' the metronome to align it's beat and also 'start' at 4.5 seconds?
Any advice?
I suspect this is related to using requestAnimationFrame
.
I am aware that requestAnimationFrame
is preferable to using setTimeout
or setInterval
, but I'm curious what you would recommend for making a web audio app where you want playback to continue even if you switch to another tab in the browser.
It seems more suited to games (as its name implies) where if you leave the tab there is no need to redraw the page cause you can't see it anymore. Maybe we need a requestAudioFrame
?
I also am not sure if this is something specific to my computer and how Chrome optimizes repainting or if it is a more general issue.
Thanks.
I am very new to JS. I was wondering if there was any way to insert a line of code into a
Hello I use MIDI.js in my App to play sequence of notes.
I have array of notes and array of delay, and I iterate though it using for loop.
var notes = [67, 78, 67 ,67,90, 56,..,...,....]
var delay = [.........]
for(var i=0; l < notes.length; i++)
{
MIDI.noteOn(channel, notes[i], velocity, delay[i]);
}
When array of notes is long [ 300+ ] then result is not good and browser struggles to play such long sequence.
Is it possible to schedule partial number of notes [ 25 notes ] at any given time and when it is close to finish that sequence then schedule next 25 notes so that load on browser can be controlled to get good result ?
For reference, here is the code of midi.noteOn
function of MIDI.js which uses setTimeout
function to play notes.
midi.noteOn = function(channelId, noteId, velocity, delay) {
delay = delay || 0;
/// check whether the note exists
var channel = root.channels[channelId];
var instrument = channel.instrument;
var bufferId = instrument + '' + noteId;
var buffer = audioBuffers[bufferId];
if (!buffer) {
// console.log(MIDI.GM.byId[instrument].id, instrument, channelId);
return;
}
/// convert relative delay to absolute delay
if (delay < ctx.currentTime) {
delay += ctx.currentTime;
}
/// create audio buffer
if (useStreamingBuffer) {
var source = ctx.createMediaElementSource(buffer);
} else { // XMLHTTP buffer
var source = ctx.createBufferSource();
source.buffer = buffer;
}
/// add effects to buffer
if (effects) {
var chain = source;
for (var key in effects) {
chain.connect(effects[key].input);
chain = effects[key];
}
}
/// add gain + pitchShift
var gain = (velocity / 127) * (masterVolume / 127) * 2 - 1;
source.connect(ctx.destination);
source.detune.value = detuneCents;
source.playbackRate.value = 1; // pitch shift
source.gainNode = ctx.createGain(); // gain
source.gainNode.connect(ctx.destination);
source.gainNode.gain.value = Math.min(1.0, Math.max(-1.0, gain));
source.connect(source.gainNode);
if (useStreamingBuffer) {
if (delay) {
return setTimeout(function() {
buffer.currentTime = 0;
buffer.play()
}, delay * 1000);
} else {
buffer.currentTime = 0;
buffer.play()
}
} else {
source.start(delay || 0);
}
///
sources[channelId + '' + noteId] = source;
///
return source;
};
When I try the demo in iOS on Safari, nothing happens. There's nothing in the error console either. It's ok on desktop Safari.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.