Skip to content

Commit

Permalink
WIP record audio
Browse files Browse the repository at this point in the history
  • Loading branch information
microbit-grace committed Mar 22, 2024
1 parent 292addc commit b73637d
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 4 deletions.
42 changes: 41 additions & 1 deletion src/board/audio/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ interface AudioOptions {
speechAudioCallback: () => void;
}

export class Audio {
export class BoardAudio {
private frequency: number = 440;
// You can mute the sim before it's running so we can't immediately write to the muteNode.
private muted: boolean = false;
Expand Down Expand Up @@ -66,6 +66,46 @@ export class Audio {
);
}

async record() {
let mediaRecorder: MediaRecorder | undefined;
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
try {
const stream = await navigator.mediaDevices.getUserMedia({ video: false, audio: true });
mediaRecorder = new MediaRecorder(stream);
mediaRecorder.start();

setTimeout(() => {
if (mediaRecorder) {
mediaRecorder.stop();
}
}, 5000)

const chunks:Blob[] = []
mediaRecorder.ondataavailable = (e: BlobEvent) => {
chunks.push(e.data);
}

mediaRecorder.onstop = async () => {
if (chunks.length > 0) {
const recordingType = 'audio/wav; codecs=MS_PCM'
const blob = new Blob(chunks, { type: recordingType });
const audioURL = window.URL.createObjectURL(blob);
const recording = new Audio(audioURL);
await recording.play()
}
}

} catch (error) {
console.log("An error occurred, could not get microphone access");
if (mediaRecorder) {
mediaRecorder.stop();
}
}
} else {
console.log("getUserMedia not supported on your browser!");
}
}

async createAudioContextFromUserInteraction(): Promise<void> {
this.context =
this.context ??
Expand Down
14 changes: 11 additions & 3 deletions src/board/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import svgText from "../microbit-drawing.svg";
import { Accelerometer } from "./accelerometer";
import { Audio } from "./audio";
import { BoardAudio } from "./audio";
import { Button } from "./buttons";
import { Compass } from "./compass";
import {
Expand Down Expand Up @@ -92,7 +92,7 @@ export class Board {
display: Display;
buttons: Button[];
pins: Pin[];
audio: Audio;
audio: BoardAudio;
temperature: RangeSensor;
microphone: Microphone;
accelerometer: Accelerometer;
Expand Down Expand Up @@ -202,7 +202,7 @@ export class Board {
this.pins[MICROBIT_HAL_PIN_P19] = new StubPin("pin19");
this.pins[MICROBIT_HAL_PIN_P20] = new StubPin("pin20");

this.audio = new Audio();
this.audio = new BoardAudio();
this.temperature = new RangeSensor("temperature", -5, 50, 21, "°C");
this.accelerometer = new Accelerometer(onChange);
this.compass = new Compass();
Expand Down Expand Up @@ -513,6 +513,10 @@ export class Board {
return this.runningPromise;
}

async record(): Promise<void> {
await this.audio.record()
}

/**
* An external reset.
*/
Expand Down Expand Up @@ -782,6 +786,10 @@ export const createMessageListener = (board: Board) => (e: MessageEvent) => {
board.stop();
break;
}
case "record": {
board.record();
break;
}
case "reset": {
board.reset();
break;
Expand Down
10 changes: 10 additions & 0 deletions src/demo.html
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ <h1>MicroPython-micro:bit simulator example embedding</h1>
<div class="actions">
<button id="stop">Stop</button>
<button id="reset">Reset</button>
<button id="record">Record</button>
<button id="mute">Mute</button>
<button id="unmute">Unmute</button>
</div>
Expand Down Expand Up @@ -241,6 +242,15 @@ <h1>MicroPython-micro:bit simulator example embedding</h1>
);
});

document.querySelector("#record").addEventListener("click", async () => {
simulator.postMessage(
{
kind: "record",
},
"*"
);
});

document.querySelector("#reset").addEventListener("click", async () => {
simulator.postMessage(
{
Expand Down

0 comments on commit b73637d

Please sign in to comment.