zoukankan      html  css  js  c++  java
  • JavaScript web端录音测试噪声

    流程:

    1. 使用scriptprocessor记录前端音频流,转换成Float32Array
    2. 将Float32Array转换成16bit PCM
    3. 计算公式:引用:如何计算音频dB级别?

    代码:

      function floatTo16BitPCM(output: DataView, offset: number, input: Float32Array) {
        for (let i = 0; i < input.length; i++, offset += 2) {
          let s = Math.max(-1, Math.min(1, input[i]));
          output.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7fff, true);
        }
      }
    
      function onMediaSuccess(stream): Promise<Float32Array[]> {
        return new Promise(resolve => {
          const context = new AudioContext();
          const audioInput = context.createMediaStreamSource(stream);
          var inputData = [];
          const recorder = context.createScriptProcessor(4096, 1, 1);
          recorder.onaudioprocess = function(e) {
            var data = e.inputBuffer.getChannelData(0);
            inputData.push(new Float32Array(data));
          };
          audioInput.connect(recorder);
          recorder.connect(context.destination);
          setTimeout(() => {//噪声录音至少需要1s,数据才可用
            resolve(inputData);
            recorder.disconnect();
            audioInput.disconnect();
            if (stream) {
              stream.getAudioTracks().forEach(function(track) {
                track.stop();
              });
              stream = null;
            }
          }, 1000);
        });
      }
    
      //数据合并
      function compress(inputData: Float32Array[]) {
        let size = 0;
        for (let i = 0; i < inputData.length; i++) {
          size += inputData[i].length;
        }
        var data = new Float32Array(size);
        var offset = 0;
        for (var i = 0; i < inputData.length; i++) {
          data.set(inputData[i], offset);
          offset += inputData[i].length;
        }
        return data;
      }
      
      //record button click
      const onRecord = () => {
        navigator.mediaDevices.getUserMedia(mediaConstraints).then(async function computeNoise(stream) {
          const inputData = await onMediaSuccess(stream);
          const samples = compress(inputData);
          const db = getDB(samples);
          Recording(db);//正式录音
        });
      };
    
      //计算DB
      const getDB = (samples: Float32Array): number => {
        const bitDepth = 16;
        const bytesPerSample = bitDepth / 8;
        const offset = 0;
        let buffer = new ArrayBuffer(samples.length * bytesPerSample);
        let view = new DataView(buffer);
        floatTo16BitPCM(view, offset, samples);
    
        const int16Audio = new Int16Array(buffer);
    
        let avgEnergy = 0;
        int16Audio.forEach(fragment => {
          avgEnergy += fragment * fragment;
        });
    
        avgEnergy = Math.sqrt(avgEnergy / int16Audio.length);
        const db = 20 * Math.log10(avgEnergy / 32767);
        return Number(db.toFixed(3));
      };
    

    参考:js实现pcm数据编码

  • 相关阅读:
    一sqlite分页 语句,
    array调用排序,返回的数组要 重新赋值,
    sublime text3快速编辑选中多行
    sublime text3实现多行快速编辑Ctrl+E或者Tab
    sublime使用Markdown Preview标记语言
    解决sublime package control 出现There are no packages available for installation
    sublime text 3安装html-css-js prettify后使用时报错An unhandled OS error was encountered
    sublime格式化插件---HTML-CSS-JS Prettify美化代码
    node=day5
    封装异步API
  • 原文地址:https://www.cnblogs.com/xym4869/p/13638008.html
Copyright © 2011-2022 走看看