Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DO NOT MERGE] Sim changes for forthcoming beta MicroPython release #113

Draft
wants to merge 36 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
699a2d7
Work towards building on the audio-recording branch
microbit-matt-hillsdon Mar 20, 2024
202c7fd
The simulator compiles (with my local mpy change)
microbit-matt-hillsdon Mar 21, 2024
41ff6b0
Add pin touches sample
microbit-grace Mar 21, 2024
292addc
Update pin_touches sample to include logo
microbit-grace Mar 21, 2024
b73637d
WIP record audio
microbit-grace Mar 22, 2024
1b9465a
Initial steps towards microphone HAL
microbit-matt-hillsdon Mar 22, 2024
9cc4b2b
Microphone: get as far as reading samples
microbit-matt-hillsdon Mar 22, 2024
c971228
WIP convertToUnit8Array
microbit-grace Mar 25, 2024
3c4a79c
Update to latest from audio-recording branch
microbit-matt-hillsdon Mar 27, 2024
7aaa800
Remove unused HAL method
microbit-matt-hillsdon Mar 27, 2024
c562955
Reinstate clear on display for non-HAL use (reset)
microbit-matt-hillsdon Mar 27, 2024
88e2baf
Safari 13 compatible speech option
microbit-matt-hillsdon Mar 27, 2024
41e7ce3
Merge branch 'beta-updates' of https://github.com/microbit-foundation…
microbit-grace Mar 27, 2024
2916e18
WIP
microbit-matt-hillsdon Mar 27, 2024
62a338e
WIP playing recorded audio
microbit-matt-hillsdon Mar 27, 2024
8eb6fa7
Update
microbit-matt-hillsdon Apr 2, 2024
26a4ee4
Roughly works
microbit-matt-hillsdon Apr 2, 2024
2cda4d2
Sample program
microbit-matt-hillsdon Apr 2, 2024
d232569
Fix set rate in record.py
microbit-grace Apr 2, 2024
19b095b
Remove debug
microbit-matt-hillsdon Apr 2, 2024
90292b6
Merge branch 'beta-updates' of https://github.com/microbit-foundation…
microbit-grace Apr 3, 2024
3c30c59
Give older Safari a chance
microbit-matt-hillsdon Apr 3, 2024
4f1baa3
Tweak Safari workaround
microbit-matt-hillsdon Apr 3, 2024
ef44717
Fix PR feedback
microbit-matt-hillsdon Apr 3, 2024
5907c05
Tweak sample to allow on-the-fly rate change
microbit-matt-hillsdon Apr 3, 2024
4ed8c93
Remove browser tab mic indicator
microbit-grace Apr 11, 2024
aea7937
Activate sim mic light when recording
microbit-grace Apr 11, 2024
8798367
Update simulator micropython lib
microbit-grace May 3, 2024
4da3f33
Add microphone.set_sensitivity example and js hal
microbit-grace May 3, 2024
6042086
Update to latest
microbit-matt-hillsdon May 23, 2024
06b4549
Tweak AUDIO_OUTPUT_BUFFER_SIZE and document
microbit-matt-hillsdon May 23, 2024
b887f22
Audio fixes
microbit-matt-hillsdon May 24, 2024
34e45b3
Update MicroPython to fix silent frames issue
microbit-matt-hillsdon May 28, 2024
7d84c58
Update MicroPython
microbit-matt-hillsdon Aug 19, 2024
677585f
Update MicroPython
microbit-matt-hillsdon Aug 21, 2024
ab07528
Resample via a libsamplerate (#117)
microbit-matt-hillsdon Aug 28, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Initial steps towards microphone HAL
Audio format needs some investigation - MediaRecorder might not be the
right approach.
  • Loading branch information
microbit-matt-hillsdon committed Mar 22, 2024
commit 1b9465a2d61cde5dda8a1b13204fa2ad94807f9e
40 changes: 0 additions & 40 deletions src/board/audio/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,46 +66,6 @@ export class BoardAudio {
);
}

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
8 changes: 0 additions & 8 deletions src/board/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -513,10 +513,6 @@ export class Board {
return this.runningPromise;
}

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

/**
* An external reset.
*/
Expand Down Expand Up @@ -786,10 +782,6 @@ export const createMessageListener = (board: Board) => (e: MessageEvent) => {
board.stop();
break;
}
case "record": {
board.record();
break;
}
case "reset": {
board.reset();
break;
Expand Down
51 changes: 51 additions & 0 deletions src/board/microphone.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export class Microphone {
150
);
private soundLevelCallback: SoundLevelCallback | undefined;
private _isRecording: boolean = false;

constructor(
private element: SVGElement,
Expand Down Expand Up @@ -66,4 +67,54 @@ export class Microphone {
boardStopped() {
this.microphoneOff();
}

isRecording() {
return this._isRecording;
}

stopRecording() {
// TODO
}

async startRecording(onChunk: (chunk: ArrayBuffer) => void) {
if (!navigator?.mediaDevices?.getUserMedia) {
return;
}
if (this.isRecording()) {
this.stopRecording();
// Wait for it if needed
}
this._isRecording = true;

// This might not be the right recording approach as we want 8 bit PCM for AudioFrame
// and we're getting a fancy codec.
let mediaRecorder: MediaRecorder | undefined;
try {
const stream = await navigator.mediaDevices.getUserMedia({
video: false,
audio: true,
});
mediaRecorder = new MediaRecorder(stream);
mediaRecorder.start();

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

mediaRecorder.ondataavailable = async (e: BlobEvent) => {
const buffer = await e.data.arrayBuffer();
onChunk(buffer);
};
mediaRecorder.onstop = async () => {
this._isRecording = false;
};
} catch (error) {
if (mediaRecorder) {
mediaRecorder.stop();
}
this._isRecording = false;
}
}
}
10 changes: 0 additions & 10 deletions src/demo.html
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,6 @@ <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 @@ -242,15 +241,6 @@ <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
3 changes: 3 additions & 0 deletions src/jshal.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ bool mp_js_hal_audio_is_expression_active(void);
void mp_js_hal_microphone_init(void);
void mp_js_hal_microphone_set_threshold(int kind, int value);
int mp_js_hal_microphone_get_level(void);
void mp_js_hal_microphone_start_recording(uint8_t *buf, size_t max_len, size_t *cur_len, int rate);
bool mp_js_hal_microphone_is_recording(void);
void mp_js_hal_microphone_stop_recording(void);

void mp_js_radio_enable(uint8_t group, uint8_t max_payload, uint8_t queue);
void mp_js_radio_disable(void);
Expand Down
19 changes: 19 additions & 0 deletions src/jshal.js
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,25 @@ mergeInto(LibraryManager.library, {
);
},

mp_js_hal_microphone_start_recording: function (
/** @type {number} */ buf,
/** @type {number} */ max_len,
/** @type {number} */ cur_len,
/** @type {number} */ rate
) {
Module.board.microphone.startRecording(function (
chunk
) /** @type {ArrayBuffer} */
{
console.log("Chunk", chunk);
});
},
mp_js_hal_microphone_is_recording: function () {
return Module.board.microphone.isRecording();
},
mp_js_hal_microphone_stop_recording: function () {
Module.board.microphone.stopRecording();
},
mp_js_hal_microphone_get_level: function () {
return Module.board.microphone.soundLevel.value;
},
Expand Down
4 changes: 3 additions & 1 deletion src/microbithal_js.c
Original file line number Diff line number Diff line change
Expand Up @@ -514,11 +514,13 @@ int microbit_hal_microphone_get_level(void) {
}

void microbit_hal_microphone_start_recording(uint8_t *buf, size_t max_len, size_t *cur_len, int rate) {
mp_js_hal_microphone_start_recording(buf, max_len, cur_len, rate);
}

bool microbit_hal_microphone_is_recording(void) {
return false;
return mp_js_hal_microphone_is_recording();
}

void microbit_hal_microphone_stop_recording(void) {
mp_js_hal_microphone_stop_recording();
}
Loading