This repository has been archived on 2025-04-28. You can view files and clone it, but cannot push or open issues or pull requests.
computers-sound-music-portf.../code/project
2024-12-11 07:23:25 -08:00
..
.cargo rust file 2024-12-11 05:59:40 -08:00
src project; add rust 2024-12-11 05:59:20 -08:00
bsides.jpg project readme updates 2024-12-11 00:32:47 -08:00
buzzer.jpg project readme updates 2024-12-11 00:32:47 -08:00
Cargo.toml project; add rust 2024-12-11 05:59:20 -08:00
defcon.jpg project readme updates 2024-12-11 00:32:47 -08:00
Embed.toml project; add rust 2024-12-11 05:59:20 -08:00
fm-tuner.jpg project readme updates 2024-12-11 00:32:47 -08:00
main.py project; comments, formatting py 2024-12-11 06:24:14 -08:00
README.md more project readme changes 2024-12-11 07:23:25 -08:00
tone-demo.mkv more project readme changes 2024-12-11 07:23:25 -08:00

micro-tuner

An instrument tuner assistant, built to be run on the Microbit V2. Portable and Practical!

Background

Selecting a project for this course was itself small challenge and lead to a slightly later start then I would have otherwise planned.

Alternatives

Since I thought a lot about it, I may as well mention what the alternatives may have been

  • Reverse engineering, or augmenting the firmware of my DEFCON30 badge
  • Adding sound output capabilities to my recent BSides badge, possibly with my piezoelectric buzzer (discussed briefy in the notebook)
  • An undetermined project, perhaps reverse engineering or adding to a small FM receiver board I have, but know little about (Chip MEGA328P)
  • Sound oriented project involving other small devices I own like arduinos, raspberry pi's, and my newly aquired adafruit featherboard RP2040. Notably, the new Pi 5 no longer has a 3.5mm audio port, and it would be interesting to try to build a DAC in code with GPIO output, to not need an external USB DAC.
  • Understanding/Experimenting with sound tricks like Dolby Pro Logic
  • Buying an SDR and exploring the various ways sounds is encoded and transmitted in practical radio applications. Learning the law, and getting an amateur radio license

I hope to work on many of these some day soon, but feel free to share these with any future students looking for ideas

Decision

I chose to create an instrument tuner device with my microbit-v2 from the previous embedded rust course. Compared to the other ideas, this project is both tangible and flexible. It can be broken into different levels of goals and there are different layers of abstraction I can choose from with this approach.

Goals

Primary Goals (MVP)

  • The microbit shall be able to play any reference note (tone mode). The reference note will be displayed on the LED matrix, and the touch button shall play the note when touched. The A and B buttons will allow the choosing of different reference notes.
  • In an alternative mode (listen mode), the microbit shall be able to identify the note heard by the microphone. Likewise, this note should also be displayed
  • Portable / can run on a battery (this should just work)

Stretch Goals

  • In the listen mode, if the note heard is close to a reference note, some feedback should be given (up or down arrow, etc.)
    • Building on the above point to set a "target" note and provide appropriate feedback
  • Avoid to some extent, sound abstraction the microbit package provides and build/interpret my own frequencies

Fun ideas (Stretch ++)

  • Interfacing with the dragontail and breadboard to do some cool stuff:
    • Using the analog dial resistor to assist with chaning notes
    • Using an external LED for more interesting feedback
    • Printing some data to an external display
    • Interfacing some pins to a USB adapter -> MIDI adapter -> My MIDI keyboard, to instantly choose a reference note
  • Parallel implemention in rust, and comparing the performance

Source Code Overview

Although I already have experience interfacing with the various capabilities of this device with rust, I initially decided to go with python for this project. I want to compare the experience of both, and also have the ability to take advantage of more abstractions if I choose to. However, after making significant progress building tone mode in micropy, I came to find that micropy (and the microbit package) do not generally allow API access to the raw data samples of the microphone pins. They only seem to expose 256 values of sound intensity. This makes rust appear much more feasible for listen mode, and the scope of this project has changed to now implement only tone mode in python, and listen mode in rust.

It should also be possible to flash a python application with some compiled rust, using a package like PyO3. If I have time, I will look into that.

Python

main.py

This application (tone mode) works relatively well. Ultimetly, I decided to rely on microbits music.play() function which takes a note name as a parameter. In this regard much of the sound theory efforts are abstracted away, and there was more focus on the music and computers. The application works as follow

  • On start, note A4 / Midi key 69 is selected.
  • Pressing A selects the next note down; Pressing B selects the next note up
  • The selected note and octave will wrap around on both ends (0 and 128)
  • The root note (letter portion) is always rendered using all pixels except the last column
  • If a flat note is selected, the bottom pixel of the last column is dimly lit.
  • The current octave is expressed in a little-endian binary fashion with 4 pixels, top-down in the last column (not to conflict with the flat flag)
  • Pressing A and B together was intended to switch to and from listen mode (not implemented as explained above)

Rust

src/main.rs

Much of the code for this feature has beeen written, but some critical pieces remain. Some repositories were consulted, including

  • mb2-template: Configurations and common packages
  • microbit-spectrum: This seems to be one of the only code examples of grabbing raw audio samples with the microbit microphone in rust

Building/ Running - Python

It seems that many python microbit developers use a highly abstracted web-based IDE. I attempted to avoid that. These methods are tested only on my local debian-based linux machine, so your results may vary

Dependencies

pip install microbit-3
pip install uflash

IDE support

The microbit package does not seem to include the necessary stubs/tooltips for graceful IDE development. I found the micro:bit Python VS Code extension helpful. Follow its instructions

Flashing

uflash main.py # Optional paramter for device port like /dev/ttyACM0 if not found automatically

Serial (for console output)

screen /dev/ttyACM0 115200 # You may have a different port

Building/ Running - Rust

Dependencies

rustup target add thumbv7em-none-eabihf
rustup component add llvm-tools
cargo install cargo-binutils
cargo install probe-run
cargo install cargo-embed

Flashing

cargo embed --release

Testing

More time should be allocated to write tests, as well as perform user acceptence testing

Demo

Tone Mode

tone-demo.mkv

Listen Mode

Not Yet Ready

Author: David Westgate