首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >应该将32位浮动音频示例转换为AudioWorkletProcessor中的16位PCM数据wav文件,还是应该在工作线程中这样做?

应该将32位浮动音频示例转换为AudioWorkletProcessor中的16位PCM数据wav文件,还是应该在工作线程中这样做?
EN

Stack Overflow用户
提问于 2022-09-29 06:26:24
回答 1查看 225关注 0票数 0

因此,我编写了一个小型的js库,它将从用户的麦克风/音频输入设备中记录音频样本,并将它们转换为wav文件。由于现代浏览器不支持这一点,所以我使用了WebAudio API来实现这一点。

Recording.js:

代码语言:javascript
复制
var blobArray = [];
var audioContext;

var Float32BitSampleArray = [];

var record = async function() {
    audioContext = new AudioContext(),
    microphone = await navigator.mediaDevices.getUserMedia( {
        audio: true
    } );

    var inputNode = audioContext.createMediaStreamSource( microphone );

    await audioContext.audioWorklet.addModule( 'wavprocessor.js' );

    var wavProcessingNode = new AudioWorkletNode( audioContext, 'wav-processor' );

    inputNode.connect( wavProcessingNode );

    wavProcessingNode.connect( audioContext.destination );

    wavProcessingNode.port.onmessage = (e) => {

        Float32BitSampleArray = Float32BitSampleArray.concat( e.data );
    }
}

function buildWav() {
    buildWavSpecification();
}

function appendData( index, view ) {
    for( var i = 0; i < Float32BitSampleArray.length; i++ ) {
        var s = Math.max( -1, Math.min( 1, Float32BitSampleArray[ i ] ) );
        s = s < 0 ? s * 0x8000 : s * 0x7FFF;

        view.setUint16( index + 2 * i, s, true );
    }
}

function buildWavSpecification() {
    var dataTypeSize = 16, // 16 bit PCM data
    totalDataSize = ( dataTypeSize / 8 ) * Float32BitSampleArray.length,
    sizeOfFileDescriptor = totalDataSize + 36,
    numberOfChannels = 1,
    sampleRate = 44100,
    bytesPerSample = numberOfChannels * dataTypeSize / 8,
    blockAlign = numberOfChannels * bytesPerSample,
    bitsPerSample = bytesPerSample * 8,
    byteRate = sampleRate * bytesPerSample,
    buffer = new ArrayBuffer( 44 + totalDataSize ),
    view = new DataView( buffer ),
    format = 1;

    function writeStringIntoBuffer( index, str ) {
        for( var i = 0; i < str.length; i++ ) {
            view.setUint8( index + i, str.charCodeAt( i ) );
        }
    }

    function write32BitInt( index, val ) {
        view.setUint32( index, val, true );
    }

    function write16BitInt( index, val ) {
        view.setUint16( index, val, true );
    }



    writeStringIntoBuffer( 0, 'RIFF' );
    write32BitInt( 4, sizeOfFileDescriptor );
    writeStringIntoBuffer( 8, 'WAVE' );
    writeStringIntoBuffer( 12, 'fmt ' );
    write32BitInt( 16, 16 );
    write16BitInt( 20, format );
    write16BitInt( 22, numberOfChannels );
    write32BitInt( 24, sampleRate );
    write32BitInt( 28, byteRate );
    write16BitInt( 32, blockAlign );
    write16BitInt( 34, bitsPerSample );
    writeStringIntoBuffer( 36, 'data' );
    write32BitInt( 40, totalDataSize );

    appendData( 44, view );

    var blob = new Blob([ view ], { type: 'audio/wav' });

    return blob;

}

var stop = function() {
    // stop the recording
    var blob = buildWav();

}

波形处理器AudioWorkletProcessor (wavprocessor.js):

代码语言:javascript
复制
class WavProcessor extends AudioWorkletProcessor {

    constructor() {
        super();
        this.buffer = [];
    }

    process( inputs, outputs, parameters ) {
        this.pushData( inputs[ 0 ][ 0 ] );


        this.port.postMessage( this.buffer );

        this.buffer = [];

        return true;
    }

    pushData( samples ) {       
        for( var i = 0; i < samples.length; i++ ) {
            this.buffer.push( samples[ i ] );
        }
    }

}

registerProcessor('wav-processor', WavProcessor );

现在这很好,但是我的问题是我是应该在AudioWorkletProcessor中构建wav文件,还是应该跨一个单独的工作线程来构建wav文件。现在,该文件正在浏览器的主线程中构建,在10秒内它将发送大约700 K的音频样本,因此Float32BitSampleArray内部有700 K的音频样本。我是从表演的角度来要求的。

用于构建wav文件的Stackoverflow文章:链接

Wav文件规范:链接1 链接2

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-09-29 21:08:59

我想说的是,这取决于你如何定义性能。

如果您想要尽快完成它,那么在音频线程上执行它可能是最快的方法。

但是它可能会干扰在同一线程上计划的任何其他音频处理,并可能导致可听到的故障。为了避免这种情况,最好在其他地方进行后处理(也就是将PCM数据转换为WAV文件)。由于在主线程上执行时,它可能会干扰任何用户交互,所以我认为在Web工作人员中这样做是个好主意。

在过去,我不得不开发一种类似的方法,并采用了第二种方法。结果可作为npm软件包使用。也许这对你有用。可扩展媒体记录器

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73891141

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档