Синхронизация звука с прокруткой счетовJavascript

Форум по Javascript
Ответить
Anonymous
 Синхронизация звука с прокруткой счетов

Сообщение Anonymous »

Я настраиваю веб -страницу, которая будет использоваться барабанщиками для практики шаблонов. функциональный) < /li>
< /ol>
Проблема заключается в синхронизации прокрутки баллов до метронома. На данный момент я использую чисто эмпирические значения, потому что, когда я пытался вычислить расстояния и использовал Settimeout, чтобы прокрутить счет, который я не смог получить удовлетворительный результат. Exemple. < /li>
Вертикальная планка в середине холста является эталонной точкой. Когда примечание достигает этой панели, будет воспроизведен звук, чтобы пользователь мог услышать, какой ударный элемент должен быть воспроизведен и как (Snare Max Vol или Min Vol в этом примере). < /Li>
< /ol>
Сценарий выполняет работу, но является довольно приблизительным. Чтобы сценарий был использован, должна быть очень хорошая синхронизация между метрономом и примечаниями, достигающими справочной панели. class = "lang-html prettyprint-override">




DrumChallenge.com

#div_patterns {
display: inline-block;
margin: 20px;
}
#div_tempo {
display: inline-block;
margin: 20px;
}
#drumscore {
position: relative;
width: 100%;
height: 200px;
}
#drumscore canvas {
position: absolute;
top: 0px;
left: 0px;
}
canvas {
border: 1px solid black;
width: 100%;
height: 200px;
}






Tempo :


Delai :


Timer :


Lancer challenge









document.addEventListener('DOMContentLoaded', () => {
const audioContext = new (window.AudioContext || window.webkitAudioContext)();
const metronome = new Metronome(audioContext);

var Current_Audio = false;
var Challenge_Launched = false;
var Current_Animation = false;
var Timer_Challenge = false;
var Timer_General = false;
var Tempo = 60;
var Delai;
var Distance_Between_Notes = 30;
var General_Timer = 0;
var NextNoteTime = 0;
//
//
//
const LaunchButton = document.getElementById('launch');
LaunchButton.addEventListener('click', function(){
if (Challenge_Launched == false){
CreerChallenge();
Challenge_Launched = true;

const bpm = parseInt(InputTempo.value, 10);
metronome.setTempo(bpm);
metronome.start();

Timer_General = setInterval(SetGeneralTimer, 1000);
NextNoteTime = performance.now();
//drawNotes();
requestAnimationFrame(drawNotes);
} else {
Challenge_Launched = false;
clearTimeout(Timer_Challenge);
clearInterval(Timer_General);
metronome.stop();
//cancelAnimationFrame(Current_Animation);
}
});
//
//
//
function SetTempo(){
Tempo = InputTempo.value;
Delai = (60000 / Tempo).toFixed(2);
document.getElementById('value_tempo').innerHTML = Tempo;
document.getElementById('value_delai').innerHTML = Delai + 'ms';
metronome.setTempo(Tempo);
/*if (Challenge_Launched){
clearTimeout(Timer_Challenge);
//Timer_Challenge = setTimeout(drawNotes, Delai);
}*/
}
//
//
//
const InputTempo = document.getElementById('value_tempo');
InputTempo.addEventListener('blur', function(){
SetTempo()
});
SetTempo()
//
//
//
const drumscore = document.getElementById('drumscore');
//
// Canvas et contexte de la partition
//
const score = document.getElementById('score');
const scorectx = score.getContext('2d');
scorectx.canvas.width = drumscore.offsetWidth;
scorectx.canvas.height = drumscore.offsetHeight;
//
// Canvas et contexte des notes
//
const canvas = document.getElementById('scoreCanvas');
const ctx = canvas.getContext('2d');
ctx.canvas.width = drumscore.offsetWidth;
ctx.canvas.height = drumscore.offsetHeight;
//
// Lignes de la partition
//
const ScoreLines = [60,80,100,120,140];
//
//
//
const Elements = [
{Name: 'Snare', Line: ScoreLines[2]}
];
//
// Patterns
//
const Patterns = [
{
Name: 'Rll',
Element: 'Snare',
Notes: ['R', 'l', 'l'],
Checkbox: false,
Label: false,
Checked: false,
},
{
Name: 'rrL',
Element: 'Snare',
Notes: ['r', 'r', 'L'],
Checkbox: false,
Label: false,
Checked: false,
}
];
//
// Affichage patterns
//
const DivPatterns = document.getElementById('div_patterns');
Patterns.forEach(pattern => {
pattern.Checkbox = document.createElement('input');
pattern.Checkbox.type = "checkbox";

pattern.Label = document.createElement('label')
pattern.Label.htmlFor = pattern.Name;
pattern.Label.appendChild(document.createTextNode(pattern.Name));

DivPatterns.appendChild(pattern.Checkbox);
DivPatterns.appendChild(pattern.Label);
});
//
// Sounds
//
const Sounds = [
{
Element: 'Snare',
Type: 'Normal',
URL: '',
Audio: new Audio('snare_normal.wav')
},
{
Element: 'Snare',
Type: 'Ghost',
Audio: new Audio('snare_ghost.wav')
}

];
//
// Notes à afficher
//

const measures = 20;
const noteWidth = 10;
const noteHeight = 10;
const scrollSpeed = 3;
//
// Main Droite ou Gauche
//
const isAccented = str => str === str.toUpperCase();
const isRightHand = str => str.toUpperCase() === 'R';

//
// Créer le challenge
//
var notes = [];
var current_pattern;
//
// Dessiner la partition
//
function CreerChallenge() {
notes = [];
for (var i=0 ; i {

//ctx.fillRect(note.x, note.y, note.w, note.w);
ctx.beginPath();
ctx.ellipse(note.x, note.y, note.w, note.h, Math.PI, 0, 2 * Math.PI);
ctx.fill();

if (note.x > canvas.width / 2 - 5 && note.x requestAnimationFrame(drawNotes), 1);
}
}

function SetGeneralTimer(){
const startTime = performance.now()
General_Timer++;
document.getElementById('value_timer').innerHTML = General_Timer
const endTime = performance.now()
//console.log(`Started ` + startTime + ' | ' + (endTime - startTime) + ' | ' + General_Timer)
}

drawScore();
});




< /code>
и класс Metronome: < /p>
class Metronome {
constructor(context) {
this.context = context;
this.isPlaying = false;
this.current16thNote = 0;
this.tempo = 60;
this.lookahead = 25.0;
this.scheduleAheadTime = 0.1;
this.nextNoteTime = 0.0;
this.timerID = null;
}

nextNote() {
const secondsPerBeat = 60.0 / this.tempo;
this.nextNoteTime += 0.25 * secondsPerBeat;
this.current16thNote++;
if (this.current16thNote === 16) {
this.current16thNote = 0;
}
}

scheduleNote(beatNumber, time) {
const osc = this.context.createOscillator();
const envelope = this.context.createGain();
osc.frequency.value = (beatNumber % 4 === 0) ? 1000 : 800;
envelope.gain.value = 1;
envelope.gain.exponentialRampToValueAtTime(0.001, time + 0.2);
osc.connect(envelope);
envelope.connect(this.context.destination);
osc.start(time);
osc.stop(time + 0.2);
}

scheduler() {
console.log(this.nextNoteTime);
console.log(this.context.currentTime);
console.log(this.scheduleAheadTime);
while (this.nextNoteTime < this.context.currentTime + this.scheduleAheadTime) {
this.scheduleNote(this.current16thNote, this.nextNoteTime);
this.nextNote();
}
this.timerID = setTimeout(this.scheduler.bind(this), this.lookahead);
}

start() {
if (!this.isPlaying) {
this.isPlaying = true;
this.current16thNote = 0;
this.nextNoteTime = this.context.currentTime;
this.scheduler();
}
}

stop() {
this.isPlaying = false;
clearTimeout(this.timerID);
}

setTempo(newTempo) {
this.tempo = newTempo;
}
}


Подробнее здесь: https://stackoverflow.com/questions/795 ... -scrolling
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Javascript»