2015-04-04 6 views
1

У меня проблема: Я пытаюсь реализовать музыкальное приложение с javascipt и т. Д. Я разобрал архитектуру модуля в Engine и пользовательском интерфейсе. Моя проблема заключается в модулях двигателя. В основном я есть главный модуль двигателяОстановить несколько экземпляров setTimeout

var NoteEngine = (function(){ 
    var that = {}, 
     matrices = [], 
     beatCount = 1, 
     globalBPM = 100, 

    init = function(count){ 
     window.AudioContext = window.AudioContext || window.webkitAudioContext; 
     context = new AudioContext(); 

     _registerListener(); 

     beatCount = count; 
     matrices = [ 
      new NoteMatrix("piano", (16 * beatCount), globalBPM), 
      new NoteMatrix("guitar", (16 * beatCount), globalBPM), 
      new NoteMatrix("bass", (16 * beatCount), globalBPM), 
      new NoteMatrix("bell", (16 * beatCount), globalBPM) 
     ]; 
    }, 

    _registerListener = function(){ 

    }; 

    that.init = init; 
    return that; 
})(); 

A Class, чтобы загрузить звуки и создавать все строки

function NoteMatrix(instrument, colCount, bpm){ 

    var rows = [], 
     matrixInstrument = instrument, 
     bufferLoader, 
     bufferList; 

    _loadBuffer(); 

    function _loadBuffer(){ 
     var notePaths = _createNoteFilePaths(); 

     bufferLoader = new BufferLoader(
      context, 
      notePaths, 
      _finishedLoading); 
     bufferLoader.load(); 
    } 

    function _createNoteFilePaths(){ 
     var basePath = "res/notes/" + matrixInstrument + "/", 
      scale = ['C6', 'A5', 'G5', 'E5', 'D5', 'C5', 'A4', 'G4', 'E4', 'D4', 'C4', 'A3', 'G3', 'E3', 'D3', 'C3'], 
      result = []; 
     for(var i = 0; i < 16; i++){ 
      result[i] = basePath + scale[i] + ".mp3"; 
     } 
     return result; 
    } 

    function _finishedLoading(buffer){ 
     $("body").trigger("MODULE_FINISHED"); 
     bufferList = buffer; 
     _createMatrix(); 
    } 

    function _createMatrix(){ 
     for(var i = 0; i < 16; i++){ 
      rows[i] = new NoteRow(matrixInstrument, colCount, bpm, i, (i*colCount), (((i+1)*colCount) - 1), bufferList[i]); 
     } 
    } 
} 

и другой подкласс, чтобы управлять одной строки для каждого прибора

function NoteRow(instrument, loopLength, bpm, row, minID, maxID, buffer){ 

    var noteBuffer = buffer,   // Notenklang in Bufferform 
     gainNode = null,    // Hauptknoten für Ausgabe (auch lautstärke) 
     volume,       // Gesamtlautstärke 
     notes = [],      // Enthält alle Notenzustände in der Schleife (taktübergreifend) 
     rowInstrument = instrument,  // Instrumentname in Stringform (für Abgleiche) 
     timeoutID = null,    // Zuständig für Wiederholung/Stop der Schleife 
     isPlaying = false,    // Status ob Schleife spielt oder nicht 
     current16thNote = 0,   // Aktuelle Position in der Schleife 
     rowBPM = bpm,     // Tempo der Schleife 
     scheduleDelay = 0,    // Verzögerung der Wiederholung der Planschleife (in ms) 
     scheduleAheadTime = 0.1,  // Abdeckung der Planschleife (in s) 
     nextNoteTime = 0.0;    // Startzeit der nächsten Note 

    _init(); 
    _registerListener(); 

    // Initialisiert die Notenreihe 
    function _init(){ 
     gainNode = context.createGain(); 
     volume = 2.5; 
     gainNode.gain.value = volume; 
     for(var i = 0; i < loopLength; i++){ 
      notes[i] = false; 
     } 
    } 

    // Registriert alle Listener für die Notenreihe 
    function _registerListener(){ 
     $("body").on("CELL_CLICKED", _toggleNote); 
     $("body").on("PLAY", _play); 
     $("body").on("STOP", _stop); 
     $("body").on("VOLUME_CHANGE", _changeVolume); 
     $("body").on("BPM_CHANGE", _changeBPM); 
     $("body").on("MUTE", _mute); 
     $("body").on("RESUME_SOUND", _resumeSound); 
     $("body").on("REFRESH_ALL", _refresh); 
    } 

    // Schaltet eine Note um 
    function _toggleNote(event, data){ 
     if(data.instrument == rowInstrument && (data.id >= minID && data.id <= maxID)){ 
      console.log(data); 
      notes[data.id - minID] = !notes[data.id - minID]; 
     } 
    } 

    function _play(){ 
     current16thNote = 0; 
     nextNoteTime = context.currentTime; 
     _startScheduler(); 
    } 

    function _stop(){ 
     clearTimeout(timeoutId); 
    } 

    function _handlePlayback(){ 
     isPlaying = !isPlaying; 

     if(isPlaying) { 
      current16thNote = 0; 
      nextNoteTime = context.currentTime; 
      _startScheduler(); 
     }else{ 
      clearTimeout(timeoutId); 
     } 
    } 

    // Schaltet die Notenreihe stumm 
    function _mute(){ 
     gainNode.gain.value = 0; 
    } 

    // Stellt die ursprüngliche Lautstärke der Notenreihe wieder her 
    function _resumeSound(){ 
     gainNode.gain.value = volume; 
    } 

    // Setzt die Notenreihe zurück 
    function _refresh(){ 
     for(var i = 0; i < notes.length; i++){ 
      notes[i] = false; 
     } 
    } 

    // Ändert die Lautstärke der Notenreihe 
    function _changeVolume(event, data){ 
     volume = data/20; 
     gainNode.gain.value = volume; 
    } 

    // Ändert das Tempo der Notenreihe 
    function _changeBPM(event, data){ 
     rowBPM = data; 
    } 

    // Startet die Playback Schleife, die immer wieder abprüft, 
    // ob im vorgelegten Zeitraum eine Note abgespielt werden soll 
    function _startScheduler(){ 
     while (nextNoteTime < context.currentTime + scheduleAheadTime) { 
      _scheduleNote(current16thNote, nextNoteTime); 
      _nextNote(); 
     } 
     timeoutId = setTimeout(_startScheduler, scheduleDelay); 
    } 

    // Spielt die Note und aktiviert die entsprechende Animation 
    function _scheduleNote(beatPosition, time){ 
     if(notes[beatPosition]){ 
      var voice = context.createBufferSource(); 
      voice.buffer = noteBuffer; 
      voice.connect(gainNode); 
      gainNode.connect(context.destination); 
      voice.start(time); 

      $("#" + (minID + beatPosition)).addClass("animation"); 
      setTimeout(function(){ 
       $("#" + (minID + beatPosition)).removeClass("animation"); 
      }, 100); 
     } 
    } 

    // Verschiebt die Position der Schleife nach vorne 
    // Abhängig vom Tempo legt es auch das Interval zur nächsten Note fest 
    function _nextNote(){ 
     var secondsPerBeat = 60.0/rowBPM; 
     nextNoteTime += 0.25 * secondsPerBeat; 

     current16thNote++; 
     if (current16thNote == loopLength) { 
      current16thNote = 0; 
     } 
    } 
} 

Моя проблема лежит в NoteRows. Поскольку вы можете видеть, что объект класса NoteRow управляет всей строкой из определенного инструмента с конкретной записью. Все работает отлично, но я не могу остановить игровой цикл с clearTimeout. Любой совет? (вероятно, без изменения всей архитектуры)

+1

Можем ли мы увидеть где-нибудь все животное? – Flint

+0

Я не думаю, что это имеет значение, потому что ui и движок не зависят друг от друга в этой проблеме. Существует более старая сборка (к сожалению, любая музыкальная функция) по адресу http://132.199.139.24/~krm22840/Note16/index.html – sixeco

+0

Позвольте мне уйти, мм? ; P – Igle

ответ

1

Добавить все ваши функции таймаута в массив.

Если вы хотите, чтобы остановить их, просто сделать это следующим образом:

function stopTrackedTimeouts() 

{ 
    for(var i=0; i<timeouts.length; i++) 
    { 
     clearTimeout(timeouts[i]); 
    } 
    timeouts = []; 
} 

Если вы не заботитесь о других тайм-аутов, работающих рядом с теми, вы начали, вы можете очистить все время ожидания, получив идентификатор последний таймаут, добавив нулевой тайм-аут.

function stopAllTimeouts() 
{ 
    var id = window.setTimeout(null,0); 
    while (id--) 
    { 
     window.clearTimeout(id); 
    } 
} 
+0

большое спасибо, что сработало красиво ^^ – sixeco

+0

Bitteschön;) Bitte zwecks der Punkte einem alten Medieninformatiker die Antwort noch als richtig akzeptieren;) – Igle

Смежные вопросы