iT邦幫忙

2022 iThome 鐵人賽

DAY 13
0
Modern Web

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

D13_Audio聲音操作(麥克風)

  • 分享至 

  • xImage
  •  

Audio聲音操作(麥克風)

今天來整理Audio的音源輸入的操作

使用 p5.sound library 之 p5.AudioIn 套件

p5.js的聲音的部份,採用 p5.sound 套件,包括各種與聲音有關的套件,
今天先來整理 p5.AudioIn 的功能及操作

要使用p5.sound套件,先在index.html中引入套件

<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.2/p5.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.2/addons/p5.sound.js"></script>
let can;
let mic;
function setup() {

	can = createCanvas(400, 400);
	can.id("can1");
	can.class("c1");
	can.position(10, 10);
	background(0);

	mic = new p5.AudioIn();
	mic.getSources((devices) => {
		//console.log(devices);
		let device_name = "外接麥克風";
		devices.forEach((dev) => {
			if (dev.label.indexOf(device_name) != -1 && dev.kind == 'audioinput') {
				console.log(dev.deviceId + ", " + dev.kind + ", " + dev.label);
				mic.setSource(0);
				mic.amp(1.0);
				//mic.start(); //-- 在此執行start(),stop()才會沒有作用
			}
		});
	});
	background(0);
}

let nt = [0, 0];
let pt = [0, 0];
function draw() {

	stroke(255);
	noFill();
	micLevel = mic.getLevel();

	pt[0] = pt[0] + 0.5;
	pt[1] = height / 2 - micLevel * height / 2;

	line(nt[0], nt[1], pt[0], pt[1]);

	nt[0] = pt[0];
	nt[1] = pt[1];

	if (pt[0] > width) {
		pt[0] = 0;
		pt[1] = height / 2 - micLevel * height / 2;
		nt[0] = pt[0];
		nt[1] = pt[1];
		background(0);

		console.log(getAudioContext()); //-- AudioContext
		console.log(mic.amplitude); //-- Amplitude
		console.log(mic.input); //-- GainNode
		console.log(mic.output); //-- GainNode
		console.log(mic.stream); //-- MediaStream
		console.log(mic.mediaStream); //-- MediaStreamAudioSourceNode
		console.log(mic.currentSource); //--  0
		console.log(mic.enabled); //-- true 
		// mic.stop(); //-- 由程式停止
	}

}

function keyPressed(e){
	console.log(e);
  if(e.key == 'a'){
    mic.start();  //-- 在此執行start(),stop()才會有作用
  } else if(e.key == 'q'){
	mic.stop(); //-- 停止音訊輸入
  }
}

執行結果畫面
執行結果畫面

使用 getSources() 取得音訊來源,與 MediaDevices.enumerateDevices() 的方法相同
查到的音訊來源清單結果為
音訊來源清單
音訊來源清單

使用 getLevel() 取得音量的大小,數值範圍 0.0 ~ 1.0
使用 amp(vol) 設定音訊來源的音量大小,數值範圍 0.0 ~ 1.0 (經測試,可以大於1.0)

整個程式碼執行的流程

  1. mic = new p5.AudioIn() 建立AudioIn元件
  2. mic.getSources((devices)=>{}) 取得音訊來源清單
  3. devices.forEach((dev)=>{}) 取得要使用的音訊來源ID編號
  4. mic.setSource(0); 設定要使用的音訊來源
  5. mic.amp(1.0); 設定音訊來源音量大小
  6. mic.start(); 手動開啟音訊來源,接收音訊訊號
  7. mic.getLevel(); 取得音訊音量大小

有關 mic.start(); 及 mic.stop(); 的操作
經測試,利用程式自動start(),執行stop()會沒有作用。
如果是使用者利用鍵盤滑鼠手動執行start()的話,手動或程式執行stop()會有作用。

p5.sound套件的功能很多,接下來分幾次內容來介紹。

使用 createCapture() (附帶補充)

使用 navigator.mediaDevices.enumerateDevices().then((devices))
來連結到 audio input, 像是連結到「外接麥克風」,
不過產生的DOM元件是 video的元件標籤。
p5.js使用 audio = createCapture(constraints, (stream)) 來建立audio input
產生的物件類別是 MediaElement

let can;
let audio;
function setup() {

	can = createCanvas(400, 400);
	can.id("can1");
	can.class("c1");
	can.position(10, 10);
	background(0);

	navigator.mediaDevices.enumerateDevices().then((devices) => {
		console.log(devices);

		let device_name = "外接麥克風";
		devices.forEach((dev) =>{
			if(dev.label.indexOf(device_name) != -1 && dev.kind=='audioinput'){
				console.log(dev.deviceId + ", " + dev.kind + ", " + dev.label);
				let constraints = {
					audio: {
						deviceId: dev.deviceId
					},
					video: false
				};
				audio = createCapture(constraints, (stream) => {
					console.log(stream.getAudioTracks());  //-- MediaStreamTrack
					audio.hide();
					console.log(audio);
					console.log(audio.elt);
				});
			} 
		});
	});
}

device.kind 為 audioinput
device.label 為 外接麥克風

產生的video的元件標籤

<video playsinline="" crossorigin="anonymous" width="0" height="0" style="display: none;"></video>

參考資料
p5.sound library
https://p5js.org/reference/#/libraries/p5.sound
p5.AudioIn
https://p5js.org/reference/#/p5.AudioIn


上一篇
D12_Audio聲音操作(聲音檔)
下一篇
D14_Audio音訊數值處理(振幅,頻域)
系列文
從新開始學習p5.js畫出一片天40
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言