Last modified 2016-09-18 19:14:20 PDT

elec-rec

Pictures

elec_rec_3
elec_rec_front
elec_rec_end

Source

elec-rec firmware: https://github.com/vsergeev/elec-rec

elec-rec schematic: https://github.com/vsergeev/elec-rec/raw/master/hardware/elec-rec.sch

elec-rec board layout: https://github.com/vsergeev/elec-rec/raw/master/hardware/elec-rec.brd

Concept

The Electronic Recorder (elec-rec) is an open hardware, open source electronic wind instrument. At a first glance, the elec-rec is comprised of a breath input provided by an electret microphone, push button inputs to control sound pitch, a microcontroller to process the inputs and synthesize audio, a 3.5mm jack for audio output, and a USB port for configuration. It supports battery power, meaning it can be used as a standalone instrument. I call it the elec-rec because its interface basically emulates a recorder’s interface; in fact, the seven push buttons used to select pitch are spaced identically to recorder pitch holes.

The motivation behind the elec-rec was to create an electronic musical instrument with a flute or recorder-like interface, but with the reconfigurability and processing potential of electronic hardware to support features like multiple instruments and polyphony. A side goal was to make the device inexpensive, just like a multitude of other wind instruments such as recorders, ocarinas, tin whistles, and pan flutes. Many of these can be had for as little as ten dollars, take a lifetime to master, and in the hands of a professional produce music that prove the instrument is much more than the sum value of its parts. The elec-rec currently costs about $50 in parts in low quantities, plus the cost of fabricating the PCB. The elec-rec is open source, in all aspects: hardware, firmware, and software.

The elec-rec hardware platform is very general, and might be better thought of as a generic sampled-data system with an analog input (microphone), digital inputs (buttons), processing stage, and analog output (mono audio). The particular firmware I’ve written yields a simple reconfigurable tonal wind instrument with several features, but the platform is general enough to support a vocoder, noise instrument, etc. with simply a change of firmware.

Hardware and Schematic

                          elec rec hardware block diagram

       +----------------+  +---------------+  +--------------+  +-------------+
       | Digital Input  |  | Digital Input |  | Analog Input |  |Accelerometer|
       | 7 Front Buttons|  | 4 Back Buttons|  | Wheel Pot    |  | (Unmounted) |
       +------------+---+  +---+-----------+  +----------+---+  +---+---------+
                    |          |                         |          |
                    |          +--------+   +------------+          |
                    +---------------+   |   |   +-------------------+
                                    |   |   |   |
                                    v   v   v   v
+------------+   +-----------+   +----------------+   +--------+   +----------------+   +--------+
|            |   |AC Coupling|   |                |   |        |   |LPF             |   | 3.5mm  |
| Microphone +-->|Gain       +-->|  LPC1313 MCU   +-->| 16 bit +-->|Volume Wheel Pot+-->| Stereo |
|   Input    |   |LPF        |   | ARM Cortex M3  |   |  DAC   |   |Buffer          |   | Output |
|            |   +-----------+   |                |   |        |   |AC Coupling     |   +--------+
+------------+                   +--+-------------+   +--------+   +----------------+
                                    |       ^   ^
                        +-----------+       |   |
                        |                 +-+   +------+
                        |                 |            |
                        v                 v            v
                   +--------+      +------------+  +--------+   +--------+
                   |4 Status|      |Non volatile|  |UART/USB+-->|USB Port|
                   |  LEDs  |      |   Memory   |  | Bridge |   | Mini-B |
                   +--------+      +------------+  +--------+   +--------+

vsergeev
(to be generated with ditaa)
elec_rec_sch

Brief Description of Major Stages

The input stage is responsible for amplifying and filtering the microphone input before it is sampled at the microcontroller’s ADC input. The digital stage consists of a microcontroller for inputs processing and sound synthesis, non-volatile memory for sound waveform storage, and a UART/USB bridge for communication with a host computer for flashing and waveform uploading. The output stage consists of a DAC to produce the analog waveform, a smoothing filter, a potentiometer attenuator for volume control, and outputs to a standard 3.5mm stereo jack.

For the analog stages, I used Microchip MCP6024 op-amps. They are a bit pricey, but are rail-to-rail input and output and have some other great specs: 10MHz GBW, 7V/uS slew, 500uV offset.

Analog Input Stage:

Digital / Processing Stage:

Analog Output Stage:

Buttons and Other Inputs:

Power:

Miscellaneous:

Parts List

Name Digi-Key PN Price Part Reference Brief Description
ICs        
LPC1313 568-4914-ND $3.50 U1 ARM Cortex M3 MCU by NXP
LD1086 497-3446-1-ND $1.73 x 2 VREG1,VREG2 3.3V Linear Voltage Regulator
AD5061 AD5061BRJZ-2REEL7CT-ND $6.78 U6 16-bit DAC (4us settle)
ADR366 ADR366AUJZ-R2CT-ND $2.08 U5 3.3V Voltage Reference for DAC
AT25DF041A AT25DF041A-SSH-B-ND $1.08 U2 4-MBit 70MHz Atmel DataFlash
FT232RL 768-1007-1-ND $4.50 U3 USB to UART bridge
LMV344 296-20925-1-ND $0.95 U4 Filtering op-amps (Quad, 1MHz GBW, 1V/uS)
LMV342 LMV342MA-ND $1.12 U7 Filtering op-amps (Dual, 1MHz GBW, 1V/uS)
Ports and Jacks        
USB mini-B Port H2959CT-ND $1.18 J2 USB mini-B socket
Audio Jack CP1-3523N-ND $1.02 J1 3.5mm Stereo female jack (3 conductors / 3 contacts, no switch)
Buttons and Switches        
SW Front EEG1869CT-ND $0.52 x 7 SW_F1,SW_F2,SW_F3,
SW_F4,SW_F5,SW_F6,
SW_F7
7 front push buttons
SW Back 401-1757-1-ND $0.72 x 5 SW_B1,SW_B2,SW_B3,
SW_B4,SW_RESET
4 back push buttons and reset button
SW Power 563-1090-ND $0.68 SW_PWR Power slide switch
Wheel Pots 3352T-203LF-ND $1.58 x 2 WPOT1,WPOT2 2 Wheel pots (one volume, one analog input)
Passives        
12MHz Crystal 535-10218-1-ND $0.41 Q1 12MHz Crystal
Passives Misc. $6.10   Passives
Misc.        
Lite-On Green LED 160-1423-1-ND $0.44 x 4 LED1,LED2,LED3,LED4 4 Status LEDs (Green)
Lite-On Amber LED 160-1419-1-ND $0.44 x 2 LED5,LED6 2 FT232RL TX/RX LEDs (Orange)
Lite-On Red LED 160-1176-1-ND $0.40 LED_PWR Power LED (Red)
BSH112 568-1768-1-ND $0.32 x 4 T1,T2,T3,T4 FETs for driving LEDs
Microphone 102-1732-ND $2.28 MIC Electret Microphone (100Hz-20KHz)
ADXL325B ADXL325BCPZ-RL7CT-ND $4.82   XYZ +-5g Accelerometer
Total   $51.47    

Firmware

As I’ve mentioned above, some of the choices made in the firmware were design decisions to yield a simple reconfigurable tonal instrument, but are completely arbitrary as far as the hardware platform is concerned. In other words, this firmware is just one approach to processing the inputs and generating the outputs on the elec-rec hardware.

The elec-rec firmware was written in C, and uses the CMSIS abstraction layer. Check out my guide and thoughts on CMSIS here: Getting Started with Cortex M3, CMSIS, and GNU Tools

In instrument mode, the heart of the elec-rec firmware is an interrupt-driven (by the Cortex M3 SysTick timer) periodic sample, process, and write handler that runs at 36KHz. This main handler is SysTick_Handler() in main.c. In this handler:

The elec-rec firmware supports four different instrument banks, which can be selected via a configuration button mechanism described in the usage manual below. The four status LEDs reflect the currently selected instrument bank.

Multi-note is a feature that allows for multiple sustained notes to be played concurrently alongside the active note. The instrument’s volume is split halfway between the background multi-notes and the current active note. Since fetching each sample from external memory for all four multi-notes in addition to the active note (up to 5 sample fetches) is too expensive in terms of time for the 36KHz periodic sampling/writing interval, active notes are cached in multi-note waveform buffers in the microcontroller’s on-board RAM. A configuration button mechanism can then enable the active note as a multi-note, or reset and disable all multi-notes.

In controller and data modes, the periodic sampling / writing handler is suspended and instead Controller_loop() or Data_loop() are run, respectively. The controller mode of the elec-rec simply prints all inputs continuously in an easily parsable ASCII format to the serial port. The data mode of the elec-rec accepts instructions over the serial port to rewrite the non-volatile memory to update the instrument bank waveforms. See the usage manual below for more information on controller and data modes.

The microphone is digitally rectified and filtered aggressively to yield an amplitude peak detector that can be used as a reliable breath input. Currently, the raw microphone data is passed through a 4th-order EWMA filter, then passed through a bounder / limiter and scaled by the microphone calibration variable, then passed through a 3rd-order EWMA filter. I experimented a while with some basic FIR filters, which worked well, but were too computationally expensive to meet the timing on 36KHz periodic sampling / writing handler (leading to audible audio distortion).

Necessary in the elec-rec code base are also SPI-based drivers written for the Atmel AT25DF041A DataFlash, and the Analog Devices AD5061 DAC.

The elec-rec is easily flashed over the same USB serial port that is used in controller and data modes. Installing the bootloader jumper and resetting the elec-rec causes the microcontroller to boot its flashing bootloader ROM, and the microcontroller can then be flashed over the USB serial port with a tool like Flash Magic.

Storage of Waveforms on Non-Volatile Memory

The non-volatile flash memory is programmed in data mode, and later read in instrument mode, with the following layout:

Origin at 0x0

# Bytes |	Description
-------------------------------------------------
4 	|	Sample Rate in Hertz (e.g. 36000)
4 	|	Address of C waveform
2 	|	Length of C waveform
4 	|	Address of B waveform
2 	|	Length of B waveform
4 	|	Address of Bb waveform
2 	|	Length of Bb waveform
...
4 	|	Address of Cl waveform
2 	|	Length of Cl waveform
xxxx 	|	C waveform data
xxxx 	|	B waveform data
xxxx 	|	Bb waveform data
...


The 26 waveform indices are enumerated as follows:
enum { 	FINGER_INDEX_C, FINGER_INDEX_B, FINGER_INDEX_Bb,
	FINGER_INDEX_A, FINGER_INDEX_Ab, FINGER_INDEX_G,
	FINGER_INDEX_Gb, FINGER_INDEX_F, FINGER_INDEX_E,
	FINGER_INDEX_Eb, FINGER_INDEX_D, FINGER_INDEX_Db,
	FINGER_INDEX_Cl,
 	FINGER_INDEX_OCT_C, FINGER_INDEX_OCT_B, FINGER_INDEX_OCT_Bb,
	FINGER_INDEX_OCT_A, FINGER_INDEX_OCT_Ab, FINGER_INDEX_OCT_G,
	FINGER_INDEX_OCT_Gb, FINGER_INDEX_OCT_F, FINGER_INDEX_OCT_E,
	FINGER_INDEX_OCT_Eb, FINGER_INDEX_OCT_D, FINGER_INDEX_OCT_Db,
	FINGER_INDEX_OCT_Cl,
};
at the top of notes.h.

notes.h also specifies the mapping of button fingering with waveform index.

At start-up, the elec-rec reads the addresses and lengths for all 26 supported waveforms from the beginning of the non-volatile memory into a data structure in memory. This data structure also holds the current index (initialized to 0) into the 26 waveforms. Altogether, this allows for constant-time access to the next sample for any selected note (as the exact offset into memory for the next sample for that waveform is always known).

Waveform Generation and Utilities

Complementing the elec-rec firmware is a small set of tools for waveform generation and upload, written in Python[2].

basic-sampleset-gen.py generates trigonometric/geometric sine, square, sawtooth, and triangle waveforms into ASCII-readable CSV files of the raw 16-bit sample values. This script produces sampleset-sine.txt, sampleset-square.txt, sampleset-sawtooth.txt, and sampleset-triangle.txt files, which can be selectively uploaded with elec-rec-upload.py to the desired elec-rec instrument banks.

Usage: python basic-sampleset-gen.py

elec-rec-upload.py facilitates uploading four sampleset files to the respective instrument banks on the elec-rec. It can be used with the elec-rec when the elec-rec is operating in data mode (which implements a protocol that elec-rec-upload.py speaks, as a wrapper to interfacing with the non-volatile memory over SPI). In addition to sending each data block with a checksum, this utility also reads back all of the data written to the elec-rec non-volatile memory and verifies its contents.

Usage: python elec-rec-upload.py <serial port device> <sample set 1 file> <sample set 2 file> <sample set 3 file> <sample set 4 file> [only verify = 1/0]

Lastly, spectrum.py can extract the spectral characteristics of a recording of an instrument playing a single note, and resynthesize this spectrum across all supported 26 notes of the elec-rec to generate a sampleset that can be uploaded to an elec-rec instrument bank with elec-rec-upload.py. This way, the elec-rec can roughly approximate the sound of existing musical instruments. Read more about spectrum.py here: elec-rec Spectrum Resynth

Usage: python spectrum.py <input spectrum> <output sample set file>

Bugs and Limitations

Hardware Bugs

The first revision of the elec-rec board had two bugs.

The first was connecting the TX and RX LEDs in a sourcing rather than sinking configuration to the FT232RL. This means that the transmit / receive LED indicators of the FT232RL are non-functional, but this is not a big deal as they are just for notification/debug purposes.

The second bug was a bit more involved, and it had to do with the SPI bus linking the Cortex M3 microcontroller and the AD5061 DAC. It is rather essential for this bus to be clocked at a high clock speed, to easily meet a decent sampling/writing rate for higher fidelity audio. I was targeting a clock speed of 18MHz (the max of the AD5061 DAC max clock speed and what the Cortex M3 SPI peripheral clock could divide down to), but at first I could not even manage reliable communication at 4MHz. I noticed that observing the SPI SCK signal with an oscilloscope probe would suddenly lead to normal operation, as in, reliable communication. I suspect that the problem had something to do with my less-than-ideal board layout in this area, maybe the ground return path of the AD5061 (I could only really afford a 2-layer board for this prototype, so the best I could do was ground pours, and those also got fragmented by the signal traces). Since the probe’s 10pF or so temporarily fixed the issue, I soldered in 36pF shunted between the MISO data line and ground. This black magic solution which I will reluctantly call “compensation”, actually did precisely the trick, and now the SPI bus can be clocked at 18MHz error-free. I feel that transmission lines are of some relevance here, but I can’t yet speak comfortably about them. Maybe after I take that E&M class.

Firmware Limitations

The particular instrument implemented in the elec-rec firmware does not support attack or decay in played waveforms, it simply loops periodically (36KHz) through the waveforms corresponding to the selected notes.

The aggressive digital filtering of the microphone input limits the dynamic range of the elec-rec instrument. The breath input effectively functions as an on/off input, with maybe one intermediate volume level. This is in part due to the high gain at the analog input stage of the microphone, which causes saturation at the op-amp output when the microphone is directly blown on. This high gain was chosen to suitably amplify speech input (to keep the hardware platform general), and is not ideally selected for capturing blown air of various strength.

elec-rec Usage Manual

Operation: Instrument Mode

The elec-rec has a two octave, specifically 26 note, range with tonal instrument sample sets. However, the elec-rec is agnostic to the contents of the sample sets, the firmware simply provides a mapping between pitch buttons and memory addresses to fetch and play the corresponding waveform.

Combinations of the front buttons select a pitch in recorder/saxophone style fingering, the back bottom left button provides an octave shift in pitch, and the other back buttons allow for configuration and the multi-note feature.

Front Buttons: F1, F2, F3, F4, F5, F6, F7

Note     Front Buttons (F1-F7)
C'         2          
B        1            
Bb       1     4      
A        1 2          
Ab       1 2   4      
G        1 2 3        
Gb       1 2 3   5    
F        1 2 3 4      
E        1 2 3 4 5    
Eb       1 2 3 4   6  
D        1 2 3 4 5 6  
Db       1 2 3 4 5   7
C        1 2 3 4 5 6 7

Back Buttons: Back Top Left, Back Top Right, Back Bottom Left, Back Bottom Right

Function Button
Multi-note Start/Stop Back Top Left
Multi-note Add Back Top Right
Octave Back Bottom Left
Configuration Back Bottom Right

Wheel Pots: Middle Wheel Pot, Bottom Wheel Pot

Function Wheel Pot
Microphone Volume Gain Middle Wheel Pot
Master Volume Bottom Wheel Pot

Instrument Bank Selection

The elec-rec features four sample set or instrument banks that can be selected with the Configuration button and one of the four F1-F4 buttons.

The front button corresponding to the desired instrument must be held alone first, then the Configuration button (Back Bottom Right) must be pressed.

The four LEDs near the bottom of the elec-rec show the current selected instrument. The first LED (closest to the center of the board) corresponds to Instrument 1, the second to Instrument 2, and so on.

Multi-note

The elec-rec can sustain up to four notes, assembled from any of the four instruments, and any notes. The sustained sound is normalized to 1/2 [linear] volume, allowing for the user to play over the sustained sound with the other 1/2 of [linear] volume.

To start the multi-note sustain, finger the first pitch and press the “Multi-note Start/Stop” button to begin the sustain with the first pitch. For all subsequent pitches to add to the multi-note sustain, finger the pitch and and press the “Multi-note Add” button to add it to the sustained set of notes.

To clear the multi-note sustain at any time, press the “Multi-note Start/Stop” button again.

Microphone Gain Adjust

The microphone volume gain can be adjusted for greater or lesser sensitivity based on the requirements of the user’s performance environment.

The middle control wheel selects the microphone volume gain: rotating it all the way clockwise selects the lowest microphone gain (suitable for loud environments, effectively lowering the trigger threshold of the breath input), rotating it all the way counter-clockwise selects the greatest microphone gain.

To cause the new microphone volume gain to take effect, hold the F5 button alone, and then press the Configuration button.

This procedure is implemented to prevent accidental modification of the microphone volume gain while playing the instrument, since the control is near the playing interface of the elec-rec.

Operation: Controller Mode

The elec-rec can operate in controller mode, a mode where all inputs are continuously written to the USB serial port in ASCII-readable format at a 115,200 baud rate.

To enter controller mode, hold the F6 button alone, and then press the Configuration button.

The elec-rec will then continuously stream input data to the USB serial port in the following format:

00000000000_201_2D7_170_15E_0F2

which encodes the following information:

(Back Bottom Right)(Back Bottom Left)(Back Top Right)(Back Top Left)(F7)(F6)(F5)(F4)(F3)(F2)(F1)_(Microphone ADC Value)_(Microphone Volume Gain Wheel)_(Accelerometer X)_(Accelerometer Y)_(Accelerometer Z)

where (object) corresponds to either an ASCII-encoded bit (1 or 0) or ASCII-encoded hex value (ranging from 000 to 3FF).

The accelerometer is not mounted in this version of the elec-rec.

To leave controller mode, press the reset button at the top of the elec-rec board on the back, to reset the elec-rec back into instrument mode.

Operation: Data Mode

The data mode of the elec-rec allows you to upload new sample sets to the non-volatile memory of the elec-rec and consequently redefine the four instrument / sample set banks that can selected in instrument mode.

To enter data mode, hold the F7 button alone, and then press the Configuration button.

The elec-rec can then be interfaced with the elec-rec upload program to upload a new set of sample sets / instruments to the non-volatile memory of the elec-rec.

For example:

$ python elec-rec-upload.py /dev/ttyUSB0 sampleset-square.txt sampleset-sine.txt sampleset-recorder.txt sampleset-sax.txt
Writing sample byte stream...
Progress: 2048 / 16180 = 12.657602
Progress: 4096 / 16180 = 25.315204
Progress: 6144 / 16180 = 37.972806
Progress: 8192 / 16180 = 50.630408
Progress: 10240 / 16180 = 63.288010
Progress: 12288 / 16180 = 75.945612
Progress: 14336 / 16180 = 88.603214
Progress: 16180 / 16180 = 100.000000

Verifying sample byte stream...
Progress: 2048 / 16180 = 12.657602
Progress: 4096 / 16180 = 25.315204
Progress: 6144 / 16180 = 37.972806
Progress: 8192 / 16180 = 50.630408
Progress: 10240 / 16180 = 63.288010
Progress: 12288 / 16180 = 75.945612
Progress: 14336 / 16180 = 88.603214
Progress: 16180 / 16180 = 100.000000
Verification succeeded!
$

The first argument is the path to the serial port device (e.g. “COM1” for Windows). The second through fifth arguments specify the elec-rec sample set file for the four sample set / instrument banks of the instrument.

To leave data mode, hit the reset button at the top of the elec-rec board, on the back, to reset the system back into instrument mode.

Comments

Creative Commons License