2014-02-25 1 views
0

여러 사운드 소스를 동시에로드/재생하기 위해 일부 웹 오디오를 설정하려고합니다. 사운드가 현재로드되고 있고 버튼 입력을 통해 재생이 시작됩니다.웹 오디오, 다중 사운드, 별도의 게인 노드 및 글로벌 저역 필터 설정?

내 문제는 모든 소리가 하나의 BiquadFilter (이 경우에는 0; // LOWPASS 필터)를 통해 실행되기를 원합니다. 필자는 필터가 올바르게 부착 된 코드를 만들었지 만 주파수를 제어 할 수있는 입력을 얻을 수 없다는 것을 알고 있습니다. 뭔가 잘 커뮤니케이션하지 못하고 완전히 잃어 버렸습니다.

또한 동일한 주제에 대해 각 개별 사운드가 자체 이득 노드 (볼륨 컨트롤)를 통해 실행되기를 원합니다.이 경우 다시 범위 입력을 통해 변경됩니다. 기본적으로 6 개의 오디오 파일이 있으며, 자신의 gainNode를 통해 실행 한 다음 목적지 (예 : 스피커) 앞에있는 LOWPASS 필터를 통과하기 위해 함께 모이게됩니다.

희망에 따라 개별 pannerNodes를 실행하려고하지만 현재는 프로젝트를 모두 포기할 가능성이 있습니다. 다음은

내 코드입니다 (내가 전에 말했듯이, 버튼은 모든 소리를하지만, 트리거되지만 필터는 큰 문제이다) :

HTML :

<body> 

<div id="startbtn"> 
<p><input type="button" onClick="tracks.toggle();">PLAY!</p> 
</div> <!-- startbtn div --> 

<div id="frequency"> 
<p><input type="range" id="freq1" min="0" max="1" step="0.01" value="1"  onchange="sound.changeFrequency(this);" style="width:180px; background-color:#FFF;"> Frequency</p> 
</p> 
</div> 

<script> 
var tracks = new SongTracks(); 
var sound = new playSound(); 
</script> 
</body> 

JAVASCRIPT :

var context = new webkitAudioContext(); 
var myAudioAnalyser; 

    function init() { 
      if('webkitAudioContext' in window) { 
       myAudioContext = new webkitAudioContext(); 
       // an analyser is used for the spectrum 
       myAudioAnalyser = myAudioContext.createAnalyser(); 
       myAudioAnalyser.smoothingTimeConstant = 0.85; 
       myAudioAnalyser.connect(myAudioContext.destination); 

       fetchSounds(); 
       }; 
      }; 


// shim layer with setTimeout fallback 
window.requestAnimFrame = (function(){ 
return window.requestAnimationFrame  || 
window.webkitRequestAnimationFrame || 
window.mozRequestAnimationFrame || 
window.oRequestAnimationFrame  || 
window.msRequestAnimationFrame  || 
function(callback){ 
window.setTimeout(callback, 1000/60); 
}; 
})(); 


function playSound(buffer, time) { 
    var source = context.createBufferSource(); 
    source.buffer = buffer; 

var filter = context.createBiquadFilter(); ///////////////// HERE 
filter.type = filter.LOWPASS; 
filter.frequency.value = 5000; 

source.connect(filter); 
filter.connect(context.destination); 
source.start(time); 

this.filter = filter; 

}; 

function loadSounds(obj, soundMap, callback) { 

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 SongTracks = function() { 
    loadSounds(this, { 
    vocals: 'tracks/vocals.mp3', 
    guitar: 'tracks/guitar.mp3', 
    piano: 'tracks/piano.mp3' 
    }); 
}; 

var filter; 

SongTracks.prototype.play = function() { 
    playSound(this.vocals, 0); 
    playSound(this.guitar, 0); 
    playSound(this.piano, 0); 
///////////////////////////////////////////////////////////// OR HERE 
var source1 = context.createBufferSource(); 
source1.buffer = this.buffer 
source1 = bufferList[0]; 


var filter = context.createBiquadFilter(); 
filter.type = filter.LOWPASS; 
filter.frequency.value = 5000; 

source1.connect(filter); 
filter.connect(context.destination); 

this.filter = filter; 
///////////////////////////////////////////////////////////////////// TO HERE? 
}; 

    SongTracks.prototype.stop = function() { 
    this.source.stop(0); 
}; 

SongTracks.prototype.toggle = function() { 
    this.isPlaying ? this.stop() : this.play(); 
    this.isPlaying = !this.isPlaying; 
}; 

/* SongTracks.prototype.changeFrequency = function(element) { 
var minValue = 40; 
var maxValue = context.sampleRate/2; 

var numberOfOctaves = Math.log(maxValue/minValue)/Math.LN2; 
var multiplier = Math.pow(2, numberOfOctaves * (element.value - 1.0)); 
this.filter.frequency.value = maxValue * multiplier; 
}; */ 

playSound.prototype.changeFrequency = function(element) { 
var minValue = 40; 
var maxValue = context.sampleRate/2; 

var numberOfOctaves = Math.log(maxValue/minValue)/Math.LN2; 
var multiplier = Math.pow(2, numberOfOctaves * (element.value - 1.0)); 
this.filter.frequency.value = maxValue * multiplier; 
}; 


</script> 

내 메모 등을 통해 알 수 있듯이 매우 혼란스럽고 친절한 벽돌 벽에 부딪혔다. 오디오 파일을 차별화하는 코드를 보았습니다.

var source1 = context.createBufferSource(); 
    var source2 = context.createBufferSource(); 
    var source3 = context.createBufferSource(); 
    var source4 = context.createBufferSource(); 

    source1.buffer = bufferList[0]; 
    source2.buffer = bufferList[1]; 
    source3.buffer = bufferList[2]; 
    source4.buffer = bufferList[3]; 

하지만 잘 모르겠지만 행운을 빕니다.

답변

1

노드를 playSound에 전달하고 FilterNode를 전달하면됩니다.

playSound 내부에 BiquadFilter를 만드는 데 잘못된 위치가 있습니다. N 개의 사운드가 재생 될 때마다 재생 사운드가 하나씩 생성되므로 결국 하나만 필요합니다. 제외

HTML이 같은 파일 : :

<input type="range" id="freq1" min="0" max="1" step="0.01" value="1" onchange="changeFilterFrequency(this);" style="width:180px; background-color:#FFF;"> Frequency</p> 

JS :

당신은 같은 것을 원하는

function playSound(buffer, outputNode, time) { 
    var source = context.createBufferSource(); 
    source.buffer = buffer; 

    source.connect(outputNode); 
    source.start(time); 
} 

var globalFilter = null; // one global filter 

SongTracks.prototype.play = function() { 
    var globalFilter = context.createBiquadFilter(); 
    globalFilter.type = globalFilter.LOWPASS; 
    globalFilter.frequency.value = 5000; 
    globalFilter.connect(context.destination); 

    playSound(this.vocals, globalFilter, 0); 
    playSound(this.guitar, globalFilter, 0); 
    playSound(this.piano, globalFilter, 0); 
}; 

function changeFilterFrequency(element) { 
    var minValue = 40; 
    var maxValue = context.sampleRate/2; 

    var numberOfOctaves = Math.log(maxValue/minValue)/Math.LN2; 
    var multiplier = Math.pow(2, numberOfOctaves * (element.value - 1.0)); 
    globalFilter.frequency.value = maxValue * multiplier; 
} 
+0

당신은 아주 똑똑한 사람이야,하지만이 고정되지 않은 내 문제는 완전히. Chrome에서 미리보고 요소를 검사 할 때 "null의 속성 '빈도'(line : globalFilter.frequency.value = maxValue * multiplier;)를 읽을 수 없습니까? – ryananthonyyy

+0

의'SongTracks.prototype.play' 파일에서 첫 줄에서'var' 키워드를 제거하십시오. 글로벌 변수에 값을 할당하는 대신 globalFilter라는 로컬 변수가 생성됩니다. –

+0

무슨 뜻인지 잘 모르시겠습니까? var라는 단어를 삭제했지만 이제는이 오류 메시지가 나타납니다. "정의되지 않은 속성 값 '을 설정할 수 없습니다 (줄 : globalFilter.Frequency.value = maxValue * multiplier;).이 웹 오디오는 너무 혼란 스럽습니다. – ryananthonyyy

관련 문제