iT邦幫忙

2022 iThome 鐵人賽

0
Modern Web

從新開始學習p5.js畫出一片天系列 第 37

D37_手機麥克風音訊波形資料及錄音的操作

  • 分享至 

  • xImage
  •  

手機麥克風音訊波形資料及錄音的操作

今天來整理利用p5.sound.js在音訊波形資料的操作
一般來說,音訊除了音量大小的數值之外,就是波形的資料,分別為
頻譜波形 spectrum 及振幅波形 waveform
在前一篇介紹讀取麥克風音量大小數值時,發現在iOS的手機,此功能會失效
也就是 mic.getLevel() 會讀不到資料,
因此,改用 FFT 的 waveform的功能,也就是將 波形振幅取正值再加以平均,就可以獲得音量大小數值了。

另外麥克風的啟動,需要透過手動點擊螢幕來打開麥克風的收音。

像是 getAudioContext().suspend();
還有

let isUserStarted = false;
function touchStarted() {
  if (!isUserStarted) {
    userStartAudio().then(() => {
      mic.start();
    });
  }
  isUserStarted = true;
}

以下是完整的程式
HTML

<!DOCTYPE html>
<html lang="en">

<head>
	<meta charset="utf-8" />
	<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
	<!-- keep the line below for OpenProcessing compatibility -->
	<!-- <script src="https://openprocessing.org/openprocessing_sketch.js"></script> -->
	<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.5.0/p5.js"></script>
	<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.5.0/addons/p5.sound.js"></script>
	<script src="mySketch2.js"></script>
	<link rel="stylesheet" type="text/css" href="style.css">
</head>

<body></body>
</html>

CSS

html,
body {
	margin: 0;
	padding: 0;
}

JS

let mic, fft;
let isUserStarted = false;
let amplitude;
let size1 = 0;

let recorder;
let soundFile;
let n = 0;
function setup() {

    getAudioContext().suspend();  //--- 關閉預設Audio的功能
    createCanvas(710, 400);
    noFill();

    // 建立 AudioIn 物件
    mic = new p5.AudioIn();
    mic.getSources(gotSources); 
    // mic.start();

    //--  建立 FFT 物件
    fft = new p5.FFT();
    fft.setInput(mic);

    //amplitude = new p5.Amplitude();
    textSize(24);
    
    recorder = new p5.SoundRecorder();  //--- 建立錄音物件
    recorder.setInput(mic);   //--  設定錄音音源來源
    soundFile = new p5.SoundFile();  //--  建立錄音檔案物件

}

function gotSources(devices) {  //--- 取得音源裝置清單---
    //console.log(devices);
    let device_name = "外接麥克風";
    devices.forEach( (dev, index) => {
      console.log(dev.label);
      if(dev.kind == 'audioinput'){
          mic.setSource(0);  //--- 設定音源裝置來源---
      } 
    });
  }


function draw() {
    background(0);
    let spectrum = fft.analyze();  //--- 取得音源 spectrum 音訊資料---
    let waveform1 = fft.waveform();  //--- 取得音源 waveform 音訊資料---
    
    //-- spectrum ------
    beginShape();
    for (i = 0; i < spectrum.length; i++) {
        vertex(i, map(spectrum[i], 0, 255, height, 0));
    }
    endShape();
    
    //-- waveform ------
    let level = 0;
    beginShape();
    for (i = 0; i < waveform1.length; i++) {
        let x = map(i, 0, waveform1.length, 0, width);
        let y = map( waveform1[i], -1, 1, 0, height);
        vertex(x,y);
        level += abs(waveform1[i]);
    }
    endShape();
    let level1 = level/waveform1.length;  //--- 計算平均值
    
    if(n==1){
        let size0 = map(level1, 0, 1, 0, 2000);
        fill(255);
        text(nfc(size0, 2), 50, 50);
        
        size1 = size1 + (size0-size1)*0.1;
        noFill();
        stroke(255);
        ellipse(width/2-100, height/2, size1, size1);
    }
}


function touchStarted() {
    if (!isUserStarted) {
        userStartAudio().then(() => {
            print('mic started!');
            mic.start();   //--- 開啟麥克風
            n = 1;
            console.log(n);
        });
        isUserStarted = true;
    }
}

function keyPressed(e) {
	console.log(e);
    if(e.key == '1'){
        recorder.record(soundFile);  //--- 開啟錄音
        console.log(recorder);
        console.log(soundFile);

    } else if(e.key == '2'){
        recorder.stop();  //--- 停止錄音

    } else if(e.key == '3'){

      soundFile.play();  //--- 播放儲存錄音檔
      save(soundFile, 'mySound.wav');  //--- 儲存錄音檔
    }
}

執行結果
https://ithelp.ithome.com.tw/upload/images/20221109/20152098BV0x7R2eGM.png

參考資料
マイク入力と録音 p5.sound.js サウンド
https://himco.jp/2020/01/11/5:マイク入力-p5-sound-js-サウンド/
測試網址
https://www.moc2718.com/web1109/index.html
Web Audio API
https://webaudio.github.io/web-audio-api/


上一篇
D36_音樂檔及麥克風同時讀取音訊資料的操作
下一篇
D38_FileUpload 檔案上傳及縮圖處理的操作
系列文
從新開始學習p5.js畫出一片天40
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言