Javascript 如何使用Web audio API移动/调制音频缓冲频率

Javascript 如何使用Web audio API移动/调制音频缓冲频率,javascript,html,audio,web-audio-api,Javascript,Html,Audio,Web Audio Api,我正在试验Web Audio API,我的目标是创建一个数字吉他,其中每根弦都有一个实际吉他的初始声源,打开弦,然后我想动态生成所有其他fret位置的声音。在对这个主题进行了一些研究之后(这对我来说是一个全新的话题),听起来这可能是通过改变源声音样本的频率来实现的 问题是我见过很多改变合成正弦波的算法,但没有任何改变音频样本频率的算法。以下是我的代码示例,以更好地了解我是如何实现这一点的: // Guitar chord buffer var chordBuffer = null; /

我正在试验Web Audio API,我的目标是创建一个数字吉他,其中每根弦都有一个实际吉他的初始声源,打开弦,然后我想动态生成所有其他fret位置的声音。在对这个主题进行了一些研究之后(这对我来说是一个全新的话题),听起来这可能是通过改变源声音样本的频率来实现的

问题是我见过很多改变合成正弦波的算法,但没有任何改变音频样本频率的算法。以下是我的代码示例,以更好地了解我是如何实现这一点的:

// Guitar chord buffer    
var chordBuffer = null;

// Create audio context
var context = new webkitAudioContext();

// Load sound sample
var request = new XMLHttpRequest();
request.open('GET', 'chord.mp3', true);
request.responseType = 'arraybuffer';
request.onload = loadChord;
request.send();

// Handle guitar string "pluck"
$('.string').mouseenter(function(e){
    e.preventDefault();

    var source = context.createBufferSource();
    source.buffer = chordBuffer;

    // Create javaScriptNode so we can get at raw audio buffer
    var jsnode = context.createJavaScriptNode(1024, 1, 1);
    jsnode.onaudioprocess = changeFrequency;

    // Connect nodes and play
    source.connect(jsnode);
    jsnode.connect(context.destination);
    source.noteOn(0);
});

function loadChord() {
    context.decodeAudioData(
        request.response,
        function(pBuffer) { chordBuffer = pBuffer; },
        function(pError) { console.error(pError); }
    );
}

function changeFrequency(e) {
    var ib = e.inputBuffer.getChannelData(0);
    var ob = e.outputBuffer.getChannelData(0);
    var n = ib.length;

    for (var i = 0; i < n; ++i) {
        // Code needed...
    }
}
//吉他和弦缓冲区
var chordBuffer=null;
//创建音频上下文
var context=新的webkitAudioContext();
//加载声音样本
var request=new XMLHttpRequest();
request.open('GET','chord.mp3',true);
request.responseType='arraybuffer';
request.onload=loadChord;
request.send();
//处理吉他弦“弹拨”
$('.string').mouseenter(函数(e){
e、 预防默认值();
var source=context.createBufferSource();
source.buffer=chordBuffer;
//创建javaScriptNode,以便获取原始音频缓冲区
var jsnode=context.createJavaScriptNode(1024,1,1);
jsnode.onaudioprocess=变更频率;
//连接节点并播放
connect(jsnode);
jsnode.connect(context.destination);
来源:注释(0);
});
函数loadChord(){
上下文解码音频数据(
请求.答复,
函数(pBuffer){chordBuffer=pBuffer;},
函数(pError){console.error(pError);}
);
}
功能转换频率(e){
var ib=e.inputBuffer.getChannelData(0);
var ob=e.outputBuffer.getChannelData(0);
var n=ib.长度;
对于(变量i=0;i
你就知道了-我可以把声音放得很好,但是在changeFrequency函数中创建代码时,我有点不知所措,该函数会改变和弦采样频率,因此听起来像是弦上的另一个摩擦位置。如果您对本代码有任何帮助,或对我正在尝试做的事情是否可行发表意见,我们将不胜感激


谢谢

您可以通过设置
playbackRate
获得所需的行为,但正如Brad所说,您必须使用多重采样。还可以看到这个问题:。

播放速率会改变声音的音调,但也会改变其播放时间


如果你只想改变音高,也许你可以使用音高移位器。检查我的javascript基音移位器实现及其在JavascriptNode中的使用,您正在制作一个采样器。您将需要比单个字符串更多的样本。如果你想要好的声音,你至少需要每八度两个样本。即便如此,吉他也是一种非常复杂的乐器,仅凭样品就可以重现。