Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: FastPWM mbed-dsp
Revision 1:db0c24aebb8a, committed 2017-07-03
- Comitter:
- kkado
- Date:
- Mon Jul 03 08:35:31 2017 +0000
- Parent:
- 0:c5ca205c0a80
- Commit message:
- Corrected documentation placement.
Changed in this revision
| STMstation_synth.cpp | Show annotated file Show diff for this revision Revisions of this file |
| STMstation_synth.h | Show annotated file Show diff for this revision Revisions of this file |
--- a/STMstation_synth.cpp Mon Jul 03 08:16:42 2017 +0000
+++ b/STMstation_synth.cpp Mon Jul 03 08:35:31 2017 +0000
@@ -7,18 +7,29 @@
const uint8_t freqLength = sizeof(freqs)/sizeof(freqs[0]);
const float pi = 3.14159265359;
+//Sampling rate, uncomment one line only!
+//const uint16_t FSAMP = 44100; const float period = 0.000023;
+//const uint16_t FSAMP = 22050; const float period = 0.000045;
+const uint16_t FSAMP = 11025; const float period = 0.000091;
+
//Constructor
-STMstation_synth::STMstation_synth():
- //FSAMP(44100), period(0.000023), //<<Only uncomment one of these lines!
- //FSAMP(22050), period(0.000045), //<<
- FSAMP(11025), period(0.000091), //<<
- tone(AUDIO_PIN,1)
+STMstation_synth::STMstation_synth():tone(AUDIO_PIN,1)
{
- tone.pulsewidth_ticks(1);
- tone.period_ticks(256);
- sample.attach(this,&STMstation_synth::note2,period);
+ begin();
}
+//Constructor
+STMstation_synth::STMstation_synth(PinName audio_pin):tone(audio_pin,1)
+{
+ begin();
+}
+
+//Set up PWM and timer interrupt
+void STMstation_synth::begin(){
+ tone.pulsewidth_ticks(128);
+ tone.period_ticks(256);
+ sample.attach(this,&STMstation_synth::note,period);
+}
//Calculate the coefficients
void STMstation_synth::calc_coefs(int i){
@@ -46,7 +57,7 @@
}
//Calculate vSum
-void STMstation_synth::calc_vSum2(){
+void STMstation_synth::calc_vSum(){
uint8_t active = 0; //Number of active channels
uint16_t accum = 0; //Sum of volume channel values
bool over = 0; //Is any value over 127?
@@ -131,7 +142,7 @@
}
//Calculate values
-void STMstation_synth::calc_val2(){
+void STMstation_synth::calc_val(){
Master.val = 128;
for(int i=0; i<CHANNELS; i++){
if(Master.notes[i] != NULL){
@@ -216,17 +227,17 @@
void STMstation_synth::check_start(){
for(int i=0; i<CHANNELS; i++){
if(Master.counter[i] == 0){
- calc_vSum2();
+ calc_vSum();
calc_coefs(i);
}
}
}
//Play dat funky music
-void STMstation_synth::note2(){
+void STMstation_synth::note(){
check_start();
calc_env();
- calc_val2();
+ calc_val();
tone.pulsewidth_ticks(Master.val);
check_end();
}
@@ -275,7 +286,7 @@
}
}
}
- calc_vSum2();
+ calc_vSum();
for(uint16_t i=0; i<CHANNELS; i++){
if(Master.notes[i]!=NULL){
calc_coefs(i);
--- a/STMstation_synth.h Mon Jul 03 08:16:42 2017 +0000
+++ b/STMstation_synth.h Mon Jul 03 08:35:31 2017 +0000
@@ -5,6 +5,70 @@
#include "arm_math.h"
#include "FastPWM.h"
+#define AUDIO_PIN PB_0
+#define CHANNELS 5
+
+/** Stores data for a song or sound effect
+ * @param notes Note frequency and timbre
+ * @param durations Duration (from 1/64th to 4 counts)
+ * @param AR Attack/Release (bits 7:4 - attack, 3:0 - release)
+ * @param vol Volume (0 - muted, 127 - 1x volume, 255 - 2x volume
+ * @param max Max index of each channel
+ * @param ended Has the channel completed playing?
+ * @param repeat Should the channel repeat or stop?
+ * @param bpm Tempo, in 1/4th counts per minute
+ */
+struct melody{
+ const uint8_t * notes[CHANNELS];
+ const uint8_t * durations[CHANNELS];
+ const uint8_t * AR[CHANNELS];
+ const uint8_t * vol[CHANNELS];
+ uint16_t max[CHANNELS];
+ bool ended[CHANNELS], repeat[CHANNELS];
+ uint8_t bpm;
+};
+
+/** Stores data that is currently being played. So many members! A lot of these are just coefficients for waveform synthesis.
+ * @param notes (LOADED FROM MELODY) Note frequency and timbre
+ * @param durations (LOADED FROM MELODY) Duration (from 1/64th to 4 counts)
+ * @param AR (LOADED FROM MELODY) Attack/Release (bits 7:4 - attack, 3:0 - release)
+ * @param vol (LOADED FROM MELODY) Volume (0 - muted, 127 - 1x volume, 255 - 2x volume
+ * @param index Note currently being played
+ * @param max (LOADED FROM MELODY) Max index of each channel
+ * @param env (FOR SYNTHEESIS) Envelope value (between 0~1)
+ * @param sineCoef (FOR SYNTHEESIS) Coefficient for sine wave synthesis
+ * @param vSum (FOR SYNTHEESIS) Divider to prevent clipping
+ * @param atkSlope (FOR SYNTHEESIS) Attack slope for envelope
+ * @param relSlope (FOR SYNTHEESIS) Release slope for envelope
+ * @param relOffset (FOR SYNTHEESIS) Release offset for envelope
+ * @param volCoef (FOR SYNTHEESIS) Volume coefficient to control volume, prevent clipping
+ * @param halfPeriod (FOR SYNTHEESIS) Half period for square, triangle functions
+ * @param triSlope (FOR SYNTHEESIS) Triangle wave slope
+ * @param noiseVal (FOR SYNTHEESIS) Value returned from random noise generation
+ * @param triVal (FOR SYNTHEESIS) Value returned from triangle wave calculation
+ * @param counter Current sample value
+ * @param envAtkEnd (FOR SYNTHEESIS) Counter value at which attack ramp ends
+ * @param envRelStart (FOR SYNTHEESIS) Counter value at which release ramp starts
+ * @param val 8-bit sample value
+ * @timbre (FOR SYNTHEESIS) What kind of waveform is playing? 0 - sine, 1 - sq, 2 - tri, 3 - noise
+ * @freqIndex (FOR SYNTHEESIS) What frequency is playing? 0 - rest, 1~freqLength frequencies in ascending order
+ * @param bpm (LOADED FROM MELODY) Tempo, in 1/4th counts per minute
+ * @param repeat (LOADED FROM MELODY) Channel repeat
+ * @param endptr (LOADED FROM MELODY) Points to melody end value
+ */
+struct master{
+ const uint8_t * notes[CHANNELS];
+ const uint8_t * durations[CHANNELS];
+ const uint8_t * AR[CHANNELS];
+ const uint8_t * vol[CHANNELS];
+ uint16_t index[CHANNELS], max[CHANNELS];
+ float env[CHANNELS], sineCoef[CHANNELS], vSum, atkSlope[CHANNELS], relSlope[CHANNELS], relOffset[CHANNELS], volCoef[CHANNELS], halfPeriod[CHANNELS], triSlope[CHANNELS], noiseVal[CHANNELS], triVal[CHANNELS];
+ uint32_t counter[CHANNELS], envAtkEnd[CHANNELS], envRelStart[CHANNELS];
+ uint8_t val, timbre[CHANNELS], freqIndex[CHANNELS], bpm[CHANNELS];
+ bool repeat[CHANNELS];
+ bool* endptr[CHANNELS];
+};
+
/** Basic synthesizer library for STM32F401RE Nucleo or STMstation P.1 development boards - may work with
* other targets, but not tested yet.
*
@@ -25,58 +89,49 @@
* R1 = 150 Ohms, C1 = 47nF, C2 = 1uF, Speaker = 0.25W, 8 Ohms
* @endcode
*/
-
-#define AUDIO_PIN PB_0
-#define CHANNELS 5
-
-//Audio melody struct
-struct melody{
- const uint8_t * notes[CHANNELS];
- const uint8_t * durations[CHANNELS];
- const uint8_t * AR[CHANNELS];
- const uint8_t * vol[CHANNELS];
- uint16_t max[CHANNELS];
- bool ended[CHANNELS], repeat[CHANNELS];
- uint8_t bpm;
-};
-
-//Audio master struct
-struct master{
- const uint8_t * notes[CHANNELS];
- const uint8_t * durations[CHANNELS];
- const uint8_t * AR[CHANNELS];
- const uint8_t * vol[CHANNELS];
- uint16_t index[CHANNELS], max[CHANNELS];
- float env[CHANNELS], sineCoef[CHANNELS], vSum, atkSlope[CHANNELS], relSlope[CHANNELS], relOffset[CHANNELS], volCoef[CHANNELS], halfPeriod[CHANNELS], triSlope[CHANNELS], noiseVal[CHANNELS], triVal[CHANNELS];
- uint32_t counter[CHANNELS], envAtkEnd[CHANNELS], envRelStart[CHANNELS];
- uint8_t val, timbre[CHANNELS], freqIndex[CHANNELS], bpm[CHANNELS];
- bool repeat[CHANNELS];
- bool* endptr[CHANNELS];
-};
-
class STMstation_synth{
public:
+ /** Create an instance of STMstation_synth
+ * @param audio_pin PWM output
+ */
+ STMstation_synth(PinName audio_pin);
+ /** Create an instance of STMstation_synth
+ * Use default output for STMstation P.1, PB_0
+ */
STMstation_synth();
-
+ /** Play a track
+ * @param newMelody Melody to play
+ * @param refChannel If starting from nonzero index, specify reference channel
+ * @param newIndex Start index
+ */
+ void play(melody &newMelody, uint8_t refChannel = 0, uint16_t newIndex = 0);
+ /** Clear all data from a selected channel
+ * @param channel Channel to clear
+ */
+ void clear_channel(uint8_t _channel);
+ /** Stop playing a track
+ * @param newMelody Melody to stop
+ */
+ void stop_track(melody &newMelody);
+ /** Check if a track is still playing
+ * @param newMelody Melody to check
+ */
+ bool check_track(melody &newMelody);
+
+ struct master Master;
+ private:
+ void begin();
void calc_coefs(int i);
- void calc_vSum2();
+ void calc_vSum();
void calc_env();
int8_t square(float _halfperiod, uint16_t _counter);
void calc_triangle(uint8_t _channel, float _halfperiod, float _trislope, uint32_t _counter);
void calc_noise(uint8_t _channel, uint8_t _freq, uint32_t _counter);
- void calc_val2();
- void clear_channel(uint8_t _channel);
- void stop_track(melody &newMelody);
- bool check_track(melody &newMelody);
+ void calc_val();
void check_end();
void check_start();
- void note2();
- void play(melody &newMelody, uint8_t refChannel = 0, uint16_t newIndex = 0);
+ void note();
- const uint16_t FSAMP;
- const float period;
- struct master Master;
- private:
Ticker sample;
FastPWM tone;
};