2013-11-21 68 views
1

我是新來的編程,我搞亂了Web Audio API。現在,我有三個樣本(踢,拍,唧),當按下播放按鈕時,它們組成了一個簡單的鼓組節奏。如何使用網絡音頻API/JavaScript操作DOM?

我希望能夠在前端作爲一個音序器演示這種視覺效果,通過這個鼓手玩。例如,每次播放「kick.wav」示例時,我都想更改與其關聯的div的顏色。

我的問題是:

  1. 如何關聯每次踢,拍手或踩鑔用在html一個div玩過嗎?
  2. 如何添加此關聯來按順序播放按鈕?

HTML:

<body> 
    <div id="container"> 
    <canvas id="canvas"></canvas> 
    </div> 
    <button id="play">play</button> 

    <script src="javascript/tween.js"></script> 
    <script src="javascript/shared.js"></script> 
    <script src="javascript/seq.js"></script> 

</body> 

的Javascript:

function playSound(buffer, time) { 
    var source = context.createBufferSource(); 
    source.buffer = buffer; 
    source.connect(context.destination); 
    source.start(time); 
} 

function loadSounds(obj, soundMap, callback) { 
    // Array-ify 
    var names = []; 
    var paths = []; 
    for (var name in soundMap) { 
    var path = soundMap[name]; 
    names.push(name); 
    paths.push(path); 
    } 
    bufferLoader = new BufferLoader(context, paths, function(bufferList) { 
    for (var i = 0; i < bufferList.length; i++) { 
     var buffer = bufferList[i]; 
     var name = names[i]; 
     obj[name] = buffer; 
    } 
    if (callback) { 
     callback(); 
    } 
    }); 
    bufferLoader.load(); 
} 

function BufferLoader(context, urlList, callback) { 
    this.context = context; 
    this.urlList = urlList; 
    this.onload = callback; 
    this.bufferList = new Array(); 
    this.loadCount = 0; 
} 

BufferLoader.prototype.loadBuffer = function(url, index) { 
    // Load buffer asynchronously 
    var request = new XMLHttpRequest(); 
    request.open("GET", url, true); 
    request.responseType = "arraybuffer"; 

    var loader = this; 

    request.onload = function() { 
    // Asynchronously decode the audio file data in request.response 
    loader.context.decodeAudioData(
     request.response, 
     function(buffer) { 
     if (!buffer) { 
      alert('error decoding file data: ' + url); 
      return; 
     } 
     loader.bufferList[index] = buffer; 
     if (++loader.loadCount == loader.urlList.length) 
      loader.onload(loader.bufferList); 
     }, 
     function(error) { 
     console.error('decodeAudioData error', error); 
     } 
    ); 
    } 

    request.onerror = function() { 
    alert('BufferLoader: XHR error'); 
    } 

    request.send(); 
}; 

BufferLoader.prototype.load = function() { 
    for (var i = 0; i < this.urlList.length; ++i) 
    this.loadBuffer(this.urlList[i], i); 
}; 

var RhythmSample = function() { 
    loadSounds(this, { 
    kick: 'sounds/kick.wav', 
    claps: 'sounds/claps.wav', 
    hihat: 'sounds/hihat.wav' 
    }); 
}; 

RhythmSample.prototype.play = function() { 
    // We'll start playing the rhythm 100 milliseconds from "now" 
    var startTime = context.currentTime + 0.100; 
    var tempo = 120; // BPM (beats per minute) 
    var eighthNoteTime = (60/tempo)/2; 
    var allDivs = document.getElementsByName('colorchangingdivs[]'); 

    // Play 2 bars of the following: 
    for (var bar = 0; bar < 2; bar++) { 
    var time = startTime + bar * 8 * eighthNoteTime; 
    // Play the bass (kick) drum on beats 1, 5 
    playSound(this.kick, time); 

    playSound(this.kick, time + 4 * eighthNoteTime); 
    console.log("4") 
    // Play the snare drum on beats 3, 7 
    playSound(this.claps, time + 2 * eighthNoteTime); 
    playSound(this.claps, time + 6 * eighthNoteTime); 

    // Play the hi-hat every eighthh note. 
    for (var i = 0; i < 8; ++i) { 
     playSound(this.hihat, time + i * eighthNoteTime); 
    } 
    } 
}; 

var sample = new RhythmSample(); 

document.querySelector('#play').addEventListener('click', function() { 
    sample.play(); 
}); 

非常感謝!

+0

在您的playSound()函數內改變你想要的元素的顏色。 – Seano666

+0

我會如何補充?它會是一個回調函數嗎?我沒有任何線索。 –

+0

對不起,你將不得不做一些谷歌搜索找出時機,我不熟悉緩衝和音頻播放。 – Seano666

回答

1

將playSound()的另一個參數添加到與您想要着色的分辨率相匹配的分辨率。和播放聲音時,通過你所傳遞的ID選擇DIV邏輯來改變顏色。

function playSound(buffer, time, colorID) { 
    var source = context.createBufferSource(); 
    source.buffer = buffer; 
    source.connect(context.destination); 
    source.start(time); 
    document.getElementById(colorID).backgroundColor = blue; //or hex color/rgb value 
} 

然後你只需要添加,當你調用playSound正確的參數。

playSound(this.kick, time + 4 * eighthNoteTime,"your-kick-div-id"); 

如果你需要不同的聲音/ div的不同的顏色,那麼就在背景顏色設置添加一個if/elseif的語句。

+0

謝謝,這對大部分工作。如何將div顏色更改的時間關聯起來,以便在時間線上播放聲音時,div也會更改顏色。現在,播放按鈕立即更改所有關聯的div的顏色。 –

+0

對不起,你將不得不做一些谷歌搜索找出時機,我不熟悉緩衝和音頻播放。 – Seano666