2017-02-17 50 views
0

我目前在React中構建一個應用程序來學習語言。該應用程序是一款遊戲,在遊戲中,我使用Howler.js播放很多聲音。咆哮很棒,因爲它可以讓我輕鬆創作聲音,而且非常重要的是,我可以調整聲音的音高,我可以用一個樣本製作旋律。更好的Javascript性能

我開始運行到時我在不同的音高事情有很多不同的聲音的問題是性能。隨着代碼我已設置循環播放我的聲音對象是相當沉重,我想知道是否有一種方法來優化它(我絕不是一個JavaScript專家,所以我不會感到驚訝,如果有一個更精簡方式來執行聲音對象)。反正這是我的聲音以下對象給你一個想法:

var testTrack = [{ 
     rowId:1, 
     rowExtras:"notExpanded", 
     rowSample: 
      { 
       sampleId:"1", 
       notes:[ 
        { 
         keyNumber:0, 
         noteDelay:0, 
         notePitch:1 
        },{ 
         keyNumber:2, 
         noteDelay:460, 
         notePitch:1 
        },{ 
         keyNumber:4, 
         noteDelay:920, 
         notePitch:1 
        },{ 
         keyNumber:6, 
         noteDelay:1380, 
         notePitch:1 
        },{ 
         keyNumber:8, 
         noteDelay:1840, 
         notePitch:1 
        },{ 
         keyNumber:10, 
         noteDelay:2300, 
         notePitch:1 
        },{ 
         keyNumber:12, 
         noteDelay:2760, 
         notePitch:1 
        },{ 
         keyNumber:14, 
         noteDelay:3220, 
         notePitch:1 
        }        
       ], 
       sampleName:"Heavy Kick", 
       sampleSource:"../../samplesWav/sample1.wav" 
      } 

     },{ ...there are 12 more objects in the array with different samples in them 

這是我在使用循環和玩Howler.js聲音的代碼。請注意,上述對象的生活在我的應用程序狀態this.state.trackObject下:

playTrack(){ 

    var audioArray = this.state.trackObject; 

    for(var i=0; i <= audioArray.length - 1; i++) { 

     var rowObject = this.state.trackObject[i] 

     var notesLength = rowObject.rowSample.notes.length 

     for(var j=0; j <= notesLength - 1; j++) { 
      var notes = rowObject.rowSample.notes[j].noteDelay; 
      var id = rowObject.rowSample.sampleId; 
      var src = rowObject.rowSample.sampleSource; 
      var pitch = rowObject.rowSample.notes[j].notePitch; 

      playSample(id,notes,src,pitch)     
     } 

    } 

    function playSample(id,notes,src,pitch){ 

     if(id != "null"){ 
     setTimeout(function(){ 

     //this is where howler is used 
     var sound = new Howl({ 
       src: [src], 
       rate:pitch 
     }) 

     sound.play();     

     }, notes); 
     } 
    } 


} 

我嘗試做盡可能多的事情,我可以在「陣營」的方式,但我還在學習,以便不確定是否有更好的方式來整合Play功能和我的Apps狀態以獲得更好的瀏覽器性能。

我已經想過使用音頻精靈(這實際上是建立在吼工作得很好)。我試過用這個here。我實際上有一個安裝問題,coudln't讓它運行,但即使我設法解決這個問題,那麼我不認爲我可以添加聲音與從howler API應用到精靈的音高彎曲?

謝謝,我歡迎對性能/解決方案的人可能有什麼建議!

+1

一個微優化你可以做,不會對性能產生任何顯着的影響,但可以與可維護性有助於將移動src'的'分配和'id'了'j'循環的地方'notesLength'被創建。它們只會在'i'改變時纔會改變,所以每次'j'循環都不需要重讀/重寫它們。另外,如果你改變使用'let'而不是'var'將它們移動到合適的範圍,也可能會阻止一些GC減速,因爲使用'let'你將會不斷創建和銷燬變量,因爲'let'是塊範圍。 –

+0

僅供參考,當前版本的audiosprite已損壞,請嘗試使用以前的版本。另外,你應該沒有問題用howler操縱單個精靈。 –

+0

謝謝詹姆斯,有沒有一種方法可以推薦改變音頻的音調,但以一種轉換聲音的方式?即使音高更高/更低但保持樣本長度相同?此外,我已經嘗試了一種新方法來解決我的性能問題:https://jsfiddle.net/xs5Lu4db/不確定是否可以推薦比這更精簡的方法?這是最好的我可以拿出.. –

回答

1

我不知道你的遊戲是如何工作的,但也許你並不需要遍歷整個陣列上。如果您將聲音存儲在散列中,並通過某個唯一標識符(可能是聲音名稱?)訪問它們,則這應該會顯着提高性能。

因此,而不是代替聲明testTrack作爲像這樣的陣列的...

var testTrack = [{ 
    rowId:1, 
    rowExtras:"notExpanded", 
    rowSample: { // Code removed for brevity } 
},{ 
    rowId:2, 
    rowExtras:"notExpanded", 
    rowSample: { // Code removed for brevity } 
}]; 

聲明它像這樣...

var testTrack = { 
    "track1": { 
    rowId:1, 
    rowExtras: "notExpanded", 
    rowSample: { } 
    }, 
    "track2": { 
    rowId:2, 
    rowExtras:"notExpanded", 
    rowSample: { } 
    } 
}; 

然後訪問使用下面的方法之一的元件,其中「track1」將是聲音名稱...

var myTrack = testTrack.track1; 
var myTrack = testTrack['track1']; 

不確定這是否合理你的遊戲的上下文,但這至少可以幫助你重複整個循環。

+0

感謝您的提示,這將阻止我循環「外」forloop,但我仍然必須循環音符數組,除非有繞過這個方向嗎? –

+0

爲什麼你需要在遊戲的上下文中迭代notes數組?迭代音符實際上意味着什麼?是否有任何東西阻止你使用散列而不是內部數組? – grizzthedj

+0

Basicaly筆記是基於用戶輸入(其音樂遊戲)的動態。因此,當用戶點擊一系列按鈕時,根據按鈕,它會分配一定的聲音以及該聲音的不同音符(再次,音符取決於用戶點擊了哪個按鈕,並且分配給該音符的變量將具有唯一性延遲和可選的音調(或速率)變化,這就是爲什麼我需要一種方式來循環播放聲音 - 因爲它們是基於用戶輸入的動態。不確定是否有方法可以在用戶之前存儲每個聲音的功能點擊播放可以在播放時保存性能? –