首页 > 解决方案 > 努力播放 Float 32 数组(Web 音频 API)

问题描述

我正在构建一个简单的循环器,以帮助我了解 Web Audio API,但努力获取缓冲源来播放录制的音频。

代码已尽可能简化,但注释仍然是 70 多行,省略了 CSS 和 HTML,因此对此深表歉意。可以在 JSFiddle 上找到包含 CSS 和 HTML 的版本:

https://jsfiddle.net/b5w9j4yk/10/

任何帮助将非常感激。谢谢 :)

// Aim of the code is to record the input from the mike to a float32 array. then  prass that to a buffer which is linked to a buffer source, so the audio can be played back.  

// Grab DOM Elements
const playButton = document.getElementById('play');
const recordButton = document.getElementById('record');

// If allowed access to microphone run this code
const promise = navigator.mediaDevices.getUserMedia({audio: true, video: false})
    .then((stream) => {
        recordButton.addEventListener('click', () => {
                // when the record button is pressed clear enstanciate the record buffer
            if (!recordArmed) {
                recordArmed = true;
                recordButton.classList.add('on');
                console.log('recording armed')
                recordBuffer = new Float32Array(audioCtx.sampleRate * 10);
            }
            else {
                recordArmed = false;
                recordButton.classList.remove('on');
                
                // After the recording has stopped pass the recordBuffer the source's buffer
                myArrayBuffer.copyToChannel(recordBuffer, 0);
                
                //Looks like the buffer has been passed
                console.log(myArrayBuffer.getChannelData(0));
            }
        });
                
        // this should stat the playback of the source intended to be used adter the audio has been recorded, I can't get it to work in this given context
        playButton.addEventListener('click', () => {
                playButton.classList.add('on');
                source.start();   
        });
        
        //Transport variables
        let recordArmed = false;
        let playing = false;
       
        // this buffer will later be assigned a Float 32 Array / I'd like to keep this intimediate buffer so the audio can be sliced and minipulated with ease later 
        let recordBuffer;
       
        // Declear Context, input source and a block processor to pass the input sorce to the recordBuffer
        const audioCtx = new AudioContext();
        const audioIn = audioCtx.createMediaStreamSource(stream);
        const processor = audioCtx.createScriptProcessor(512, 1, 1);
        
        // Create a source and corrisponding buffer for playback and then assign link
        const myArrayBuffer = audioCtx.createBuffer(1, audioCtx.sampleRate * 10, audioCtx.sampleRate);
        const source = audioCtx.createBufferSource();
        source.buffer = myArrayBuffer;

        // Audio Routing
        audioIn.connect(processor);
        source.connect(audioCtx.destination); 

        // When recording is armed pass the samples of the block one at a time to the record buffer
        processor.onaudioprocess = ((audioProcessingEvent) => {
            let inputBuffer = audioProcessingEvent.inputBuffer;
            let i  = 0;
            
            if (recordArmed) {
                for (let channel = 0; channel < inputBuffer.numberOfChannels; channel++) {
                    let inputData = inputBuffer.getChannelData(channel);
                    let avg = 0;
                    inputData.forEach(sample => {
                        recordBuffer.set([sample], i);
                        i++;
                    });
                } 
            }
            else {
                i = 0;
    
            }
        });
})

标签: javascriptapiwebaudio

解决方案


推荐阅读