Simple synthesizer for STM32F401RE/STMstation.
Dependencies: FastPWM mbed-dsp
STMstation_synth.h
00001 #ifndef STMstation_synth_h 00002 #define STMstation_synth_h 00003 00004 #include "mbed.h" 00005 #include "arm_math.h" 00006 #include "FastPWM.h" 00007 00008 #define AUDIO_PIN PB_0 00009 #define CHANNELS 5 00010 00011 /** Stores data for a song or sound effect 00012 * @param notes Note frequency and timbre 00013 * @param durations Duration (from 1/64th to 4 counts) 00014 * @param AR Attack/Release (bits 7:4 - attack, 3:0 - release) 00015 * @param vol Volume (0 - muted, 127 - 1x volume, 255 - 2x volume 00016 * @param max Max index of each channel 00017 * @param ended Has the channel completed playing? 00018 * @param repeat Should the channel repeat or stop? 00019 * @param bpm Tempo, in 1/4th counts per minute 00020 */ 00021 struct melody{ 00022 const uint8_t * notes[CHANNELS]; 00023 const uint8_t * durations[CHANNELS]; 00024 const uint8_t * AR[CHANNELS]; 00025 const uint8_t * vol[CHANNELS]; 00026 uint16_t max[CHANNELS]; 00027 bool ended[CHANNELS], repeat[CHANNELS]; 00028 uint8_t bpm; 00029 }; 00030 00031 /** Stores data that is currently being played. So many members! A lot of these are just coefficients for waveform synthesis. 00032 * @param notes (LOADED FROM MELODY) Note frequency and timbre 00033 * @param durations (LOADED FROM MELODY) Duration (from 1/64th to 4 counts) 00034 * @param AR (LOADED FROM MELODY) Attack/Release (bits 7:4 - attack, 3:0 - release) 00035 * @param vol (LOADED FROM MELODY) Volume (0 - muted, 127 - 1x volume, 255 - 2x volume 00036 * @param index Note currently being played 00037 * @param max (LOADED FROM MELODY) Max index of each channel 00038 * @param env (FOR SYNTHEESIS) Envelope value (between 0~1) 00039 * @param sineCoef (FOR SYNTHEESIS) Coefficient for sine wave synthesis 00040 * @param vSum (FOR SYNTHEESIS) Divider to prevent clipping 00041 * @param atkSlope (FOR SYNTHEESIS) Attack slope for envelope 00042 * @param relSlope (FOR SYNTHEESIS) Release slope for envelope 00043 * @param relOffset (FOR SYNTHEESIS) Release offset for envelope 00044 * @param volCoef (FOR SYNTHEESIS) Volume coefficient to control volume, prevent clipping 00045 * @param halfPeriod (FOR SYNTHEESIS) Half period for square, triangle functions 00046 * @param triSlope (FOR SYNTHEESIS) Triangle wave slope 00047 * @param noiseVal (FOR SYNTHEESIS) Value returned from random noise generation 00048 * @param triVal (FOR SYNTHEESIS) Value returned from triangle wave calculation 00049 * @param counter Current sample value 00050 * @param envAtkEnd (FOR SYNTHEESIS) Counter value at which attack ramp ends 00051 * @param envRelStart (FOR SYNTHEESIS) Counter value at which release ramp starts 00052 * @param val 8-bit sample value 00053 * @timbre (FOR SYNTHEESIS) What kind of waveform is playing? 0 - sine, 1 - sq, 2 - tri, 3 - noise 00054 * @freqIndex (FOR SYNTHEESIS) What frequency is playing? 0 - rest, 1~freqLength frequencies in ascending order 00055 * @param bpm (LOADED FROM MELODY) Tempo, in 1/4th counts per minute 00056 * @param repeat (LOADED FROM MELODY) Channel repeat 00057 * @param endptr (LOADED FROM MELODY) Points to melody end value 00058 */ 00059 struct master{ 00060 const uint8_t * notes[CHANNELS]; 00061 const uint8_t * durations[CHANNELS]; 00062 const uint8_t * AR[CHANNELS]; 00063 const uint8_t * vol[CHANNELS]; 00064 uint16_t index[CHANNELS], max[CHANNELS]; 00065 float env[CHANNELS], sineCoef[CHANNELS], vSum, atkSlope[CHANNELS], relSlope[CHANNELS], relOffset[CHANNELS], volCoef[CHANNELS], halfPeriod[CHANNELS], triSlope[CHANNELS], noiseVal[CHANNELS], triVal[CHANNELS]; 00066 uint32_t counter[CHANNELS], envAtkEnd[CHANNELS], envRelStart[CHANNELS]; 00067 uint8_t val, timbre[CHANNELS], freqIndex[CHANNELS], bpm[CHANNELS]; 00068 bool repeat[CHANNELS]; 00069 bool* endptr[CHANNELS]; 00070 }; 00071 00072 /** Basic synthesizer library for STM32F401RE Nucleo or STMstation P.1 development boards - may work with 00073 * other targets, but not tested yet. 00074 * 00075 * This is a multi-channel synthesizer, with sine, square, triangle, and noise waveform generation. Music is 00076 * stored as arrays in flash, but it is possible to use editable arrays in RAM. Standard number of channels is 00077 * 5, but additional channels can be added by changing the CHANNELS define. 00078 * 00079 * Audio signal is output as a PWM signal on PB_0, which MUST be fed into a 1-bit DAC to generate sound! 00080 * 00081 * Suggested setup: 00082 * @code 00083 * (PB_0)-----(R1)-----(C2) 00084 * | | 00085 * (C1) (SPEAKER) 00086 * | | 00087 * (GND) (GND) 00088 * 00089 * R1 = 150 Ohms, C1 = 47nF, C2 = 1uF, Speaker = 0.25W, 8 Ohms 00090 * @endcode 00091 */ 00092 class STMstation_synth{ 00093 public: 00094 /** Create an instance of STMstation_synth 00095 * @param audio_pin PWM output 00096 */ 00097 STMstation_synth(PinName audio_pin); 00098 /** Create an instance of STMstation_synth 00099 * Use default output for STMstation P.1, PB_0 00100 */ 00101 STMstation_synth(); 00102 /** Play a track 00103 * @param newMelody Melody to play 00104 * @param refChannel If starting from nonzero index, specify reference channel 00105 * @param newIndex Start index 00106 */ 00107 void play(melody &newMelody, uint8_t refChannel = 0, uint16_t newIndex = 0); 00108 /** Clear all data from a selected channel 00109 * @param channel Channel to clear 00110 */ 00111 void clear_channel(uint8_t _channel); 00112 /** Stop playing a track 00113 * @param newMelody Melody to stop 00114 */ 00115 void stop_track(melody &newMelody); 00116 /** Check if a track is still playing 00117 * @param newMelody Melody to check 00118 */ 00119 bool check_track(melody &newMelody); 00120 00121 struct master Master; 00122 private: 00123 void begin(); 00124 void calc_coefs(int i); 00125 void calc_vSum(); 00126 void calc_env(); 00127 int8_t square(float _halfperiod, uint16_t _counter); 00128 void calc_triangle(uint8_t _channel, float _halfperiod, float _trislope, uint32_t _counter); 00129 void calc_noise(uint8_t _channel, uint8_t _freq, uint32_t _counter); 00130 void calc_val(); 00131 void check_end(); 00132 void check_start(); 00133 void note(); 00134 00135 Ticker sample; 00136 FastPWM tone; 00137 }; 00138 00139 #endif
Generated on Mon Jul 18 2022 19:42:09 by 1.7.2