An open API service indexing awesome lists of open source software.

https://github.com/thi-ng/ws-ldn-12

ARM / STM32F7 DIY synth workshop
https://github.com/thi-ng/ws-ldn-12

arm audio baremetal dsp midi sequencer stm32f746g-discovery synth usb workshop

Last synced: about 1 month ago
JSON representation

ARM / STM32F7 DIY synth workshop

Awesome Lists containing this project

README

        

* thi.ng/ws-ldn-12
ARM / STM32F7 DIY synth workshop (STM32F746-DISCO)

[[./assets/ws-ldn-12-minigorille.jpg]]

Photo by Lysandre Follet

*[[https://soundcloud.com/forthcharlie/sets/stm32f4][Check out demo tracks on Soundcloud]]*

** Project setup

This repo contains 8 sub-projects, all described below and each
compilable as standalone application. The repo also includes various
support libraries of the thi.ng collection as Git submodules, located
in the [[./ext][/ext]] folder:

- [[http://thi.ng/ct-gui][ct-gui]] - tiny GUI library
- [[http://thi.ng/ct-head][ct-head]] - common headers, macros & utils
- [[http://thi.ng/synstack][ct-synstack]] - softsynth / DSP engine

#+BEGIN_SRC shell
# clone with submodules
git clone https://github.com/thi-ng/ws-ldn-12 --recursive
#+END_SRC

*** Other 3rd party dependecies

- [[http://www.st.com/web/en/catalog/tools/PF261909][STM32 CubeF7 SDK]]
- [[https://launchpad.net/gcc-arm-embedded][GCC ARM toolchain]]
- [[https://github.com/texane/stlink][ST-Link]]
- [[https://gnuarmeclipse.github.io/openocd/releases/][OpenOCD]] (optional, using dev version w/ STM32F746 support)
** Building

This repo uses a flexible =Makefile= to build all included
projects - *no IDE required!* The setup features:

- easily customizable device config & linker scripts
- no requirement to manually copy STM Cube SDK sources
- catalog file(s) to selectively exclude various SDK source files (see
[[./make/sources.txt][/make/sources.txt]], can be overridden per project)
- config flags to include USBH & FatFs middlewares
- support for multiple sub-projects (with & without shared sources)
- individual module (sub-project) configs (e.g. [[./make/modules/ex08.make][/make/modules/ex08.make]])
- separate build & target folders for each module

Currently only the STM32F746-DISCO board is supported, but additional
board configurations can be easily added (see [[./make/devices/][/make/devices/]] for
reference).

*IMPORTANT:* The =Makefile= requires the env var =STM_CUBE_HOME= to be
set to the root of your STM SDK directory, e.g.
=~/dev/arm/STM32Cube_FW_F7_V1.4.0=.

#+BEGIN_SRC shell
export STM_CUBE_HOME=~/dev/arm/STM32Cube_FW_F7_V1.4.0

make module=ex01 clean
make module=ex01 -j4

# flash device (0x800000 is ROM start address)
st-flash --reset write bin/ex01/app.bin 0x8000000

# combine for improved usability in terminal
make module=ex01 -j4 && st-flash --reset write bin/ex01/app.bin 0x8000000
#+END_SRC

** Examples
*** ex01 - blinky

[[./src/ex01/main.c][Source]]

Simple Hello World LED blink example & demo of using EXTI interrupt to
react to user button. Stops/starts blinking each time button is
pressed.

*** ex02 - LCD, touchscreen & GUI basics

[[./src/ex02/main.c][Source]]

Basic demonstration of working with BSP LCD & touchscreen modules, as
well as intro to working w/ external libraries (here
[[http://thi.ng/ct-gui][thi.ng/ct-gui]]).

Edit the source file to [[./src/ex02/main.c#L28][uncomment different demo modes]]:

- =demoWelcome()= - simple text rendering & random dots, non-interactive
- =demoScribble()= - 5 point multi-touch drawing
- =demoGUI()= - basic GUI usage example (dials control nothing)

*** ex03 - Timers

[[./src/ex03/main.c][Source]]

Basic timer setup & multi-tasking example. Timer runs @ 10kHz and
controls simple LED blinking task. Task can be suspended interactively
by pressing user button.

*** ex04 - Oscillators

[[./src/ex04/main.c][Source]]

Simple oscillator & frequency modulation experiment. The following
oscillator types are supported for both main osc & modulator:

| *ID* | *Type* |
|------+-------------------------------|
| 0 | Sine |
| 1 | Saw |
| 2 | Square |
| 3 | Triangle |
| 4 | Saw + Sin |
| 5 | Noise (uses [[http://xoroshiro.di.unimi.it/][Xorshift128]] PRNG) |

*Important:* The =mod_amp= field of the =Oscillator= struct is the
modulation amplitude, but since the modulator is acting in the
frequency domain, this amplitude too is in Hz.

*** ex05 - USB stick WAV file streaming playback

[[./src/ex05/main.c][Source]]

This example uses the STM USB Host library & FatFS to access a USB
memory stick connected to the board. Once USB handshake is complete,
the app will then attempt to read the file =sound.wav= located in the
root of the USB filesystem and start streaming to the headphone audio
output (looping playback).

*Important:*
- The WAV file MUST be in 44.1kHz, 16bit stereo format
- The example is currently configured to use the USB FS (fullspeed)
port (not HS (highspeed)). This can be changed via the
=ex05/usbh_conf.h= file.

*** ex06 - thi.ng/synstack basics

[[./src/ex06/main.c][Source]] | [[https://soundcloud.com/forthcharlie/stm32f7-synstack-ex06-ws-ldn-12][Soundcloud]]

First example using [[http://thi.ng/synstack][thi.ng/synstack]] to implement polyphonic synth with
fully configurable node based DSP graph (1 graph per voice). The graph
implemented is shown below.

We also define a musical scale to play a randomized, but always
harmonic sequence and show how to dynamically modify parameters of the
DSP node.

*Note*: The graph doesn't show global LFOs, which are used for various
modulation purposes (env mod, freq etc.).

#+BEGIN_SRC dot :file assets/ex06-dag.png :exports results
digraph g {
rankdir=LR;
node[color="black",style="filled",fontname="Inconsolata",fontcolor="white",fontsize=11];
edge[fontname="Inconsolata",fontsize=9];

env[label="AD(S)R"];
osc1[label="osc #1\n(spiral)"];
osc2[label="osc #2\n(saw-sin)"];
mul1[shape="circle",label="*"];
mul2[shape="circle",label="*"];
sum[shape="circle",label="+"];
filter[label="biquad LPF\n(randomized)"];
pan[label="stereo pan"];
delay[label="delay"];
env -> mul1;
env -> mul2;
osc1 -> mul1 -> sum;
osc2 -> mul2 -> sum;
sum -> filter -> pan -> delay;
}
#+END_SRC

#+RESULTS:
[[file:assets/ex06-dag.png]]

*** ex07 - thi.ng/synstack & custom SDRAM delay

[[./src/ex07/main.c][Source]] | [[https://soundcloud.com/forthcharlie/stm32f7-synstack-3-osc-fb-sdramdelay][Soundcloud]]

Similar setup to *ex06* above, however to enable much longer delay
times and not be limited by the <320KB of available on-chip RAM of the
STM32F746-DISCO board, this example uses the 8MB "external" SDRAM
(still on-board, just not in-chip), a [[./src/common/sdram_alloc.c][custom memory allocator]]
(targetting SDRAM) and shows how to easily extend Synstack with custom
DSP nodes - in this case a [[./src/synth_extras/osc_noise.c][noise oscillator]] and a [[./src/synth_extras/sdram_delay.c][new delay node]],
which stores its long delay line in SDRAM, but then has to work with
small, windowed sections in main RAM and mirror them back & forth.

We also updated the DSP node graph to add the new oscillator, foldback
distortion and replace the old delay with the new one...

#+BEGIN_SRC dot :file assets/ex07-dag.png :exports results
digraph g {
rankdir=LR;
node[color="black",style="filled",fontname="Inconsolata",fontcolor="white",fontsize=11];
edge[fontname="Inconsolata",fontsize=9];

env[label="AD(S)R"];
osc1[label="osc #1\n(spiral)"];
osc2[label="osc #2\n(saw-sin)"];
osc3[label="osc #3\n(noise)", color="red"];
mul1[shape="circle",label="*"];
mul2[shape="circle",label="*"];
mul3[shape="circle",label="*"];
sum[shape="circle",label="+"];
sum2[shape="circle",label="+"];
fb[label="foldback\ndistortion", color="red"];
filter[label="biquad LPF\n(randomized)"];
pan[label="stereo pan"];
delay[label="SDRAM delay", color="red"];
env -> mul1;
env -> mul2;
osc1 -> mul1 -> sum -> sum2;
osc2 -> mul2 -> sum;
osc3 -> mul3 -> sum2;
sum2 -> fb -> filter -> pan -> delay;
}
#+END_SRC

#+RESULTS:
[[file:assets/ex07-dag.png]]

*** ex08 - Synstack & MIDI

[[./src/ex08/main.c][Source]]

Based on *ex07* synth setup, but with USB MIDI support to turn synth
into actual instrument (4 voice polyphonic). Via the optional
=LOG_MIDI= flag (defined in [[./make/modules/ex08.make][ex08.make]]), received MIDI message can be
logged to the board's LCD screen.

*Note:* Currently the synth only accepts MIDI Note On messages and
ignores MIDI Note Off's, since all voices only use an ADR envelope,
without "sustain" phase. This will be added later...
** Resources

- http://asm.thi.ng/ - links to all required SDK & build tools,
references, learning resources...

** Contributors

| *Name* | *Role* | *Website* |
| [[mailto:[email protected]][Karsten Schmidt]] | initiator & principal developer | [[http://thi.ng][thi.ng]] |

** License

This project is open source and licensed under the [[http://www.apache.org/licenses/LICENSE-2.0][Apache Software License 2.0]].