Simple synthesizer for STM32F401RE/STMstation.

Dependencies:   FastPWM mbed-dsp

This is a basic synthesizer to play music on the STM32F401RE Nucleo/STMstation development board:

/media/uploads/kkado/imgp1229.jpg

Please see the API documentation for further details.

Here's a demo of the synthesizer at work in a music composing program on the STMstation. This one is "Miku" by Anamanaguchi.

Committer:
kkado
Date:
Mon Jul 03 08:16:42 2017 +0000
Revision:
0:c5ca205c0a80
Child:
1:db0c24aebb8a
Last commit before adding documentation

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kkado 0:c5ca205c0a80 1 #ifndef STMstation_synth_h
kkado 0:c5ca205c0a80 2 #define STMstation_synth_h
kkado 0:c5ca205c0a80 3
kkado 0:c5ca205c0a80 4 #include "mbed.h"
kkado 0:c5ca205c0a80 5 #include "arm_math.h"
kkado 0:c5ca205c0a80 6 #include "FastPWM.h"
kkado 0:c5ca205c0a80 7
kkado 0:c5ca205c0a80 8 /** Basic synthesizer library for STM32F401RE Nucleo or STMstation P.1 development boards - may work with
kkado 0:c5ca205c0a80 9 * other targets, but not tested yet.
kkado 0:c5ca205c0a80 10 *
kkado 0:c5ca205c0a80 11 * This is a multi-channel synthesizer, with sine, square, triangle, and noise waveform generation. Music is
kkado 0:c5ca205c0a80 12 * stored as arrays in flash, but it is possible to use editable arrays in RAM. Standard number of channels is
kkado 0:c5ca205c0a80 13 * 5, but additional channels can be added by changing the CHANNELS define.
kkado 0:c5ca205c0a80 14 *
kkado 0:c5ca205c0a80 15 * Audio signal is output as a PWM signal on PB_0, which MUST be fed into a 1-bit DAC to generate sound!
kkado 0:c5ca205c0a80 16 *
kkado 0:c5ca205c0a80 17 * Suggested setup:
kkado 0:c5ca205c0a80 18 * @code
kkado 0:c5ca205c0a80 19 * (PB_0)-----(R1)-----(C2)
kkado 0:c5ca205c0a80 20 * | |
kkado 0:c5ca205c0a80 21 * (C1) (SPEAKER)
kkado 0:c5ca205c0a80 22 * | |
kkado 0:c5ca205c0a80 23 * (GND) (GND)
kkado 0:c5ca205c0a80 24 *
kkado 0:c5ca205c0a80 25 * R1 = 150 Ohms, C1 = 47nF, C2 = 1uF, Speaker = 0.25W, 8 Ohms
kkado 0:c5ca205c0a80 26 * @endcode
kkado 0:c5ca205c0a80 27 */
kkado 0:c5ca205c0a80 28
kkado 0:c5ca205c0a80 29 #define AUDIO_PIN PB_0
kkado 0:c5ca205c0a80 30 #define CHANNELS 5
kkado 0:c5ca205c0a80 31
kkado 0:c5ca205c0a80 32 //Audio melody struct
kkado 0:c5ca205c0a80 33 struct melody{
kkado 0:c5ca205c0a80 34 const uint8_t * notes[CHANNELS];
kkado 0:c5ca205c0a80 35 const uint8_t * durations[CHANNELS];
kkado 0:c5ca205c0a80 36 const uint8_t * AR[CHANNELS];
kkado 0:c5ca205c0a80 37 const uint8_t * vol[CHANNELS];
kkado 0:c5ca205c0a80 38 uint16_t max[CHANNELS];
kkado 0:c5ca205c0a80 39 bool ended[CHANNELS], repeat[CHANNELS];
kkado 0:c5ca205c0a80 40 uint8_t bpm;
kkado 0:c5ca205c0a80 41 };
kkado 0:c5ca205c0a80 42
kkado 0:c5ca205c0a80 43 //Audio master struct
kkado 0:c5ca205c0a80 44 struct master{
kkado 0:c5ca205c0a80 45 const uint8_t * notes[CHANNELS];
kkado 0:c5ca205c0a80 46 const uint8_t * durations[CHANNELS];
kkado 0:c5ca205c0a80 47 const uint8_t * AR[CHANNELS];
kkado 0:c5ca205c0a80 48 const uint8_t * vol[CHANNELS];
kkado 0:c5ca205c0a80 49 uint16_t index[CHANNELS], max[CHANNELS];
kkado 0:c5ca205c0a80 50 float env[CHANNELS], sineCoef[CHANNELS], vSum, atkSlope[CHANNELS], relSlope[CHANNELS], relOffset[CHANNELS], volCoef[CHANNELS], halfPeriod[CHANNELS], triSlope[CHANNELS], noiseVal[CHANNELS], triVal[CHANNELS];
kkado 0:c5ca205c0a80 51 uint32_t counter[CHANNELS], envAtkEnd[CHANNELS], envRelStart[CHANNELS];
kkado 0:c5ca205c0a80 52 uint8_t val, timbre[CHANNELS], freqIndex[CHANNELS], bpm[CHANNELS];
kkado 0:c5ca205c0a80 53 bool repeat[CHANNELS];
kkado 0:c5ca205c0a80 54 bool* endptr[CHANNELS];
kkado 0:c5ca205c0a80 55 };
kkado 0:c5ca205c0a80 56
kkado 0:c5ca205c0a80 57 class STMstation_synth{
kkado 0:c5ca205c0a80 58 public:
kkado 0:c5ca205c0a80 59 STMstation_synth();
kkado 0:c5ca205c0a80 60
kkado 0:c5ca205c0a80 61 void calc_coefs(int i);
kkado 0:c5ca205c0a80 62 void calc_vSum2();
kkado 0:c5ca205c0a80 63 void calc_env();
kkado 0:c5ca205c0a80 64 int8_t square(float _halfperiod, uint16_t _counter);
kkado 0:c5ca205c0a80 65 void calc_triangle(uint8_t _channel, float _halfperiod, float _trislope, uint32_t _counter);
kkado 0:c5ca205c0a80 66 void calc_noise(uint8_t _channel, uint8_t _freq, uint32_t _counter);
kkado 0:c5ca205c0a80 67 void calc_val2();
kkado 0:c5ca205c0a80 68 void clear_channel(uint8_t _channel);
kkado 0:c5ca205c0a80 69 void stop_track(melody &newMelody);
kkado 0:c5ca205c0a80 70 bool check_track(melody &newMelody);
kkado 0:c5ca205c0a80 71 void check_end();
kkado 0:c5ca205c0a80 72 void check_start();
kkado 0:c5ca205c0a80 73 void note2();
kkado 0:c5ca205c0a80 74 void play(melody &newMelody, uint8_t refChannel = 0, uint16_t newIndex = 0);
kkado 0:c5ca205c0a80 75
kkado 0:c5ca205c0a80 76 const uint16_t FSAMP;
kkado 0:c5ca205c0a80 77 const float period;
kkado 0:c5ca205c0a80 78 struct master Master;
kkado 0:c5ca205c0a80 79 private:
kkado 0:c5ca205c0a80 80 Ticker sample;
kkado 0:c5ca205c0a80 81 FastPWM tone;
kkado 0:c5ca205c0a80 82 };
kkado 0:c5ca205c0a80 83
kkado 0:c5ca205c0a80 84 #endif