Skip to content

Commit f44db72

Browse files
committed
DRAFT support for maximilian
1 parent 692302c commit f44db72

File tree

26 files changed

+1251
-1
lines changed

26 files changed

+1251
-1
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ Dependent on the example you might need to install some of the following librari
120120
- [TTS](https://github.com/pschatzmann/TTS) A Text to Speach Engine
121121
- [flite](https://github.com/pschatzmann/arduino-flite) A Text to Speach Engine
122122
- [arduino-stk](https://github.com/pschatzmann/Arduino-STK) Synthesis ToolKit in C++ (STK)
123+
- [Maximilian](https://github.com/pschatzmann/Maximilian) cross-platform and multi-target audio synthesis and signal processing library
123124
- [Mozzi](https://github.com/pschatzmann/Mozzi) A sound synthesis library for Arduino
124125
- [ESP8266Audio](https://github.com/earlephilhower/ESP8266Audio) to play different audio Formats
125126

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#include "AudioTools.h"
2+
#include "AudioLibs/MaximilianDSP.h"
3+
4+
// Define output
5+
I2SStream out;
6+
Maximilian maximilian(out);
7+
8+
//This shows how the fundamental building block of digital audio - the sine wave.
9+
maxiOsc mySine;//One oscillator - can be called anything. Can be any of the available waveforms.
10+
11+
void setup() {//some inits
12+
// setup logging
13+
Serial.begin(115200);
14+
AudioLogger::instance().begin(Serial, AudioLogger::Info);
15+
// setup Aduio output
16+
auto cfg = out.defaultConfig(TX_MODE);
17+
out.begin(cfg);
18+
maxiSettings::setup(cfg.sample_rate, cfg.channels, 512);
19+
}
20+
21+
void play(double *output) {
22+
output[0]=mySine.sinewave(440);
23+
output[1]=output[0];
24+
}
25+
26+
// Arduino loop
27+
void loop() {
28+
maximilian.loop();
29+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//This examples shows another fundamental building block of digital audio - adding two sine waves together. When you add waves together they create a new wave whose amplitude at any time is computed by adding the current amplitudes of each wave together. So, if one wave has an amplitude of 1, and the other has an amplitude of 1, the new wave will be equal to 2 at that point in time. Whereas, later, if one wave has an amplitude of -1, and the other has an amplitude of 1, the new wave - the one you hear - will equal 0. This can create some interesting effects, including 'beating', when the waves interact to create a single wave that fades up and down based on the frequencies of the two interacting waves. The frequency of the 'beating' i.e. the fading in and out, is equal to the difference in frequency between the two waves.
2+
3+
#include "MaximilianDSP.h"
4+
5+
// Define output
6+
I2SStream out;
7+
Maximilian maximilian(out);
8+
9+
maxiOsc mySine,myOtherSine;//Two oscillators with names.
10+
11+
void setup() {//some inits
12+
// setup logging
13+
Serial.begin(115200);
14+
AudioLogger::instance().begin(Serial, AudioLogger::Info);
15+
16+
// setup Aduio output
17+
auto cfg = out.defaultConfig(TX_MODE);
18+
out.begin(cfg);
19+
maxiSettings::setup(cfg.sample_rate, cfg.channels, 512);
20+
}
21+
22+
void play(double *output) {//this is where the magic happens. Very slow magic.
23+
//output[0] is the left output. output[1] is the right output
24+
output[0]=mySine.sinewave(440)+myOtherSine.sinewave(441);//these two sines will beat together. They're now a bit too loud though..
25+
output[1]=output[0];
26+
}
27+
28+
29+
// Arduino loop
30+
void loop() {
31+
maximilian.loop();
32+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#include "MaximilianDSP.h"
2+
3+
// Define Arduino output
4+
I2SStream out;
5+
Maximilian maximilian(out);
6+
7+
//This shows how to use maximilian to do basic amplitude modulation. Amplitude modulation is when you multiply waves together. In maximilian you just use the * inbetween the two waveforms.
8+
9+
maxiOsc mySine,myOtherSine;//Two oscillators. They can be called anything. They can be any of the available waveforms. These ones will be sinewaves
10+
11+
void setup() {//some inits
12+
// setup logging
13+
Serial.begin(115200);
14+
AudioLogger::instance().begin(Serial, AudioLogger::Info);
15+
16+
// setup Aduio output
17+
auto cfg = out.defaultConfig(TX_MODE);
18+
out.begin(cfg);
19+
maxiSettings::setup(cfg.sample_rate, cfg.channels, 512);
20+
}
21+
22+
void play(double *output) {
23+
24+
// This form of amplitude modulation is straightforward multiplication of two waveforms.
25+
// Notice that the maths is different to when you add waves.
26+
// The waves aren't 'beating'. Instead, the amplitude of one is modulating the amplitude of the other
27+
// Remember that the sine wave has positive and negative sections as it oscillates.
28+
// When you multiply something by -1, its phase is inverted but it retains its amplitude.
29+
// So you hear 2 waves per second, not 1, even though the frequency is 1.
30+
output[0]=mySine.sinewave(440)*myOtherSine.sinewave(1);
31+
output[1]=output[0];
32+
}
33+
34+
// Arduino loop
35+
void loop() {
36+
maximilian.loop();
37+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#include "MaximilianDSP.h"
2+
3+
// Define Arduino output
4+
I2SStream out;
5+
Maximilian maximilian(out);
6+
7+
//This shows how to use maximilian to do basic amplitude modulation.
8+
//It also shows what happens when you modulate waves with waves that have frequencies over 20 hz.
9+
//You start to get interesting effects.
10+
11+
maxiOsc mySine,myOtherSine,myPhasor;//Three oscillators. They can be called anything. They can be any of the available waveforms.
12+
13+
14+
void setup() {//some inits
15+
// setup logging
16+
Serial.begin(115200);
17+
AudioLogger::instance().begin(Serial, AudioLogger::Info);
18+
19+
// setup Aduio output
20+
auto cfg = out.defaultConfig(TX_MODE);
21+
out.begin(cfg);
22+
maxiSettings::setup(cfg.sample_rate, cfg.channels, 512);
23+
}
24+
25+
void play(double *output) {
26+
27+
//Using the phasor we can create a ramp, and use this ramp to set the frequency of one of the waves.
28+
//When the frequency of the lower waveform passes over the threshold of 20hz, we start to hear two new waveforms.
29+
//The frequency of the first new wave is the sum of the two original waves.
30+
//The frequency of the second new wave is the difference of the two original waves.
31+
//So you hear two new waves, one going up, one going down.
32+
33+
output[0]=mySine.sinewave(440)*myOtherSine.sinewave(myPhasor.phasor(0.01,0,440));
34+
output[1]=output[0];
35+
36+
}
37+
38+
// Arduino loop
39+
void loop() {
40+
maximilian.loop();
41+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// One way of thinking about FM synthesis is to see it as vibrato.
2+
// You make a pitch, then vary it up and down at some rate.
3+
// You can change the speed of the pitch variation (modulation frequency), and also the amount of variation (modulation index).
4+
// In FM, usually only one of the waveforms - the carrier that provides the initial pitch - is sent to the output.
5+
// The frequency of the the carrier wave is continually adjusted at a rate equal to the frequency of the second wave (the modulator).
6+
// So at any given point in time, the frequency of the carrier can increase by an amount equal to the current amp of the modulator.
7+
// This has some interesting effects.
8+
9+
#include "MaximilianDSP.h"
10+
11+
// Define Arduino output
12+
I2SStream out;
13+
Maximilian maximilian(out);
14+
// Maximilian
15+
maxiOsc mySine,myOtherSine;//Two oscillators
16+
17+
18+
void setup() {//some inits
19+
// setup logging
20+
Serial.begin(115200);
21+
AudioLogger::instance().begin(Serial, AudioLogger::Info);
22+
23+
// setup Aduio output
24+
auto cfg = out.defaultConfig(TX_MODE);
25+
out.begin(cfg);
26+
maxiSettings::setup(cfg.sample_rate, cfg.channels, 512);
27+
}
28+
29+
void play(double *output) {
30+
31+
// In this example, the 'myOtherSine.sinewave' is at an amplitude of 1, it's original amplitude.
32+
// This is pretty simple and not too useful.
33+
//output[0]=mySine.sinewave(440*myOtherSine.sinewave(1));
34+
35+
// Perhaps you should comment out the above line and uncomment the below one instead
36+
// It shows how the frequency of the carrier is altered by ADDING a second waveform to its frequency value.
37+
// The carrier frequency is 440, and the modulation frequency is 1.
38+
// It also shows how the modulation index works. In this case the modulation index is 100
39+
// Try adjusting the modolation index. Also, try altering the modulation frequency.
40+
output[0]=mySine.sinewave(440+(myOtherSine.sinewave(1)*100));
41+
output[1]=output[0];
42+
43+
}
44+
45+
// In complex FM systems you can have lots of modulators stacked together in interesting ways, and theoretically this can make any sound.
46+
// John Chowning is the guy you probably want to talk to about that.
47+
48+
// Arduino loop
49+
void loop() {
50+
maximilian.loop();
51+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Nothing much to say about this other than I like it.
2+
3+
#include "MaximilianDSP.h"
4+
5+
// Define Arduino output
6+
I2SStream out;
7+
Maximilian maximilian(out);
8+
// Maximilian
9+
maxiOsc mySine,myOtherSine,myLastSine,myPhasor;//Three oscillators
10+
11+
12+
void setup() {//some inits
13+
// setup logging
14+
Serial.begin(115200);
15+
AudioLogger::instance().begin(Serial, AudioLogger::Info);
16+
17+
// setup Aduio output
18+
auto cfg = out.defaultConfig(TX_MODE);
19+
out.begin(cfg);
20+
maxiSettings::setup(cfg.sample_rate, cfg.channels, 512);
21+
}
22+
23+
void play(double *output) {
24+
output[0]=mySine.sinewave(myOtherSine.sinewave(myLastSine.sinewave(0.1)*30)*440);//awesome bassline
25+
output[1]=output[0];
26+
}
27+
28+
// Arduino loop
29+
void loop() {
30+
maximilian.loop();
31+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
2+
#include "MaximilianDSP.h"
3+
4+
// Define Arduino output
5+
I2SStream out;
6+
Maximilian maximilian(out);
7+
8+
// Maximilian
9+
maxiOsc mySine; // This is the oscillator we will use to generate the test tone
10+
maxiClock myClock; // This will allow us to generate a clock signal and do things at specific times
11+
double freq; // This is a variable that we will use to hold and set the current frequency of the oscillator
12+
13+
void setup() {
14+
// setup logging
15+
Serial.begin(115200);
16+
AudioLogger::instance().begin(Serial, AudioLogger::Info);
17+
18+
// setup audio output
19+
auto cfg = out.defaultConfig(TX_MODE);
20+
out.begin(cfg);
21+
maxiSettings::setup(cfg.sample_rate, cfg.channels, 512);
22+
23+
// setup maximilian
24+
myClock.setTicksPerBeat(1);//This sets the number of ticks per beat
25+
myClock.setTempo(120);// This sets the tempo in Beats Per Minute
26+
freq=20; // Here we initialise the variable
27+
}
28+
29+
void play(double *output) {
30+
31+
myClock.ticker(); // This makes the clock object count at the current samplerate
32+
33+
//This is a 'conditional'. It does a test and then does something if the test is true
34+
35+
if (myClock.tick) { // If there is an actual tick at this time, this will be true.
36+
37+
freq+=100; // DO SOMETHING
38+
39+
} // The curly braces close the conditional
40+
41+
//output[0] is the left output. output[1] is the right output
42+
43+
output[0]=mySine.sinewave(freq);//simple as that!
44+
output[1]=output[0];
45+
46+
}
47+
48+
// Arduino loop
49+
void loop() {
50+
maximilian.loop();
51+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// This example shows how you can create a basic counter with a phasor.
2+
// A phasor oscillator can create a ramp between any two values.
3+
// It takes three inputs - frequency, start value and stop value.
4+
// These are all double precision floats, so it's a continuous slide.
5+
// If you write it into an integer, it will round it off for you.
6+
// This creates a bunch of steps.
7+
8+
#include "MaximilianDSP.h"
9+
10+
// Define Arduino output
11+
I2SStream out;
12+
Maximilian maximilian(out);
13+
14+
// Maximilian
15+
maxiOsc myCounter,mySquare;//these oscillators will help us count and play sound
16+
int CurrentCount;//we're going to put the current count in this variable so that we can use it more easily.
17+
18+
19+
void setup() {//some inits
20+
// setup logging
21+
Serial.begin(115200);
22+
AudioLogger::instance().begin(Serial, AudioLogger::Info);
23+
24+
// setup audio output
25+
auto cfg = out.defaultConfig(TX_MODE);
26+
out.begin(cfg);
27+
maxiSettings::setup(cfg.sample_rate, cfg.channels, 512);
28+
}
29+
30+
void play(double *output) {
31+
32+
// Here you can see that CurrentCount is an int. It's taking the continuous output of the phasor and convering it.
33+
// You don't need to explicityly 'cast' (i.e. change) the value from a float to an int.
34+
// It happens automagically in these cases.
35+
36+
// Once every second, CurrentCount counts from 1 until it gets to 9, then resets itself.
37+
// When it reaches 9 it resets, so the values you get are 1-8.
38+
39+
CurrentCount=myCounter.phasor(1, 1, 9);//phasor can take three arguments; frequency, start value and end value.
40+
41+
// If we multiply the output of CurrentCount by 100, we get 100,200,300,400,500,600,700,800 in that order.
42+
// These become the frequency of the oscillator.
43+
// In this case, the oscillator is an antialiased sawtooth wave. Yum.
44+
output[0]=mySquare.sawn(CurrentCount*100);
45+
output[1]=output[0];
46+
47+
}
48+
49+
// Arduino loop
50+
void loop() {
51+
maximilian.loop();
52+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#include "MaximilianDSP.h"
2+
3+
// Define Arduino output
4+
I2SStream out;
5+
Maximilian maximilian(out);
6+
7+
// Maximilian
8+
maxiOsc myCounter,mySwitchableOsc;//these oscillators will help us count and make sound.
9+
int CurrentCount;//we're going to put the current count in this variable so that we can use it more easily.
10+
double myOscOutput;//we're going to stick the output here to make it easier to mess with stuff.
11+
12+
void setup() {//some inits
13+
// setup logging
14+
Serial.begin(115200);
15+
AudioLogger::instance().begin(Serial, AudioLogger::Info);
16+
17+
// setup audio output
18+
auto cfg = out.defaultConfig(TX_MODE);
19+
out.begin(cfg);
20+
maxiSettings::setup(cfg.sample_rate, cfg.channels, 512);
21+
}
22+
23+
void play(double *output) {
24+
25+
CurrentCount=myCounter.phasor(1, 1, 9);//phasor can take three arguments; frequency, start value and end value.
26+
27+
// here we use a conditional to make something happen at a specific time.
28+
29+
if (CurrentCount<5)//simple if statement
30+
31+
myOscOutput=mySwitchableOsc.square(CurrentCount*100);
32+
33+
else if (CurrentCount>=5)//and the 'else' bit.
34+
35+
myOscOutput=mySwitchableOsc.sinewave(CurrentCount*50);//one osc object can produce whichever waveform you want.
36+
37+
output[0]=myOscOutput;
38+
output[1]=output[0];
39+
40+
}
41+
42+
// Arduino loop
43+
void loop() {
44+
maximilian.loop();
45+
}

0 commit comments

Comments
 (0)