Created
September 17, 2024 17:34
-
-
Save Visuelle-Musik/d842ea44ab7bedf4ddd3f3b313f7d875 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// === AMY-Example: Setting up a patch for addtive synthesis, storing it, assigning it two two different voices and playing one note per voice === | |
#include "AMY-Arduino.h" | |
AMY amy; | |
// --- I2S Driver --- | |
#include <ESP_I2S.h> | |
I2SClass I2S; | |
// --- Initialize everything --- | |
void setup() | |
{ | |
// --- Start up AMY --- | |
amy.begin(1, 0, 0, 0); // Cores==1, Reverb==0, Chorus==0, Echo==0 | |
// --- Serial stuff (Serial Monitor output) --- | |
Serial.begin(115200); | |
// --- Set and start I2S --- | |
I2S.setPins(13, 11, 12, -1, -1); // MB 20240807 | |
I2S.begin(I2S_MODE_STD, AMY_SAMPLE_RATE, I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO); // I2S.begin(I2S_PHILIPS_MODE, AMY_SAMPLE_RATE, BYTES_PER_SAMPLE8); | |
} | |
// --- Main loop function --- | |
void loop() | |
{ | |
// --- Setup variables to generate an additive voice --- | |
char amy_command[MAX_MESSAGE_LEN]; | |
char amy_partial_command[MAX_MESSAGE_LEN]; | |
int num_partials = 6; // use any number, but make sure that patchstring does not exceed bufferlength MAX_MESSAGE_LEN (currently 255) | |
float base_freq = 261.63; | |
int base_osc = 0; | |
struct event e = amy.default_event(); | |
// --- Generate a patch to be stored for our additive voice[s] --- | |
strcpy(amy_command, "1024,"); // Patch-number as a kind of header to our patch-string, numbers 1024-1055 can be used for user-patches | |
for(int i=1; i< num_partials+1; i++) | |
{ | |
// Set up each partial as the corresponding harmonic of the base_freq, with an amplitude of 1/N, 50ms attack, and a decay of 1 sec / N | |
sprintf(amy_partial_command, "v%dw%df%.2fA0,%.2f,%d,0,0,0",base_osc+i,PARTIAL,base_freq*i,1.f/i, 1000/i); | |
strcat(amy_command, amy_partial_command); // Concatinate all partials to one wire-string to set up the patch | |
// Use this command if you want to store only one voice in memory instead: amy_play_message(amy_partial_command); | |
} | |
// --- Actually store the patch-data --- | |
patches_store_patch(amy_command); | |
Serial.printf("%s\n", amy_command); // Print patch, noteted as wire-string to serial for reference | |
// --- Reload the patch to be able to attach it to several voices --- | |
e = amy.default_event(); | |
e.load_patch = 1024; | |
strcpy(e.voices, "0,1"); | |
amy.add_event(e); | |
// --- Note-on events for two notes assigned to one voice each --- | |
e = amy.default_event(); | |
e.time=100; | |
strcpy(e.voices, "0"); | |
e.midi_note=60; | |
e.velocity=0.5f; | |
amy.add_event(e); | |
e = amy.default_event(); | |
e.time=400; | |
strcpy(e.voices, "1"); | |
e.midi_note=67; | |
e.velocity=0.5f; | |
amy.add_event(e); | |
// --- Note-off events for two notes assigned to one voice each --- | |
e = amy.default_event(); | |
e.time=2400; | |
strcpy(e.voices, "0"); | |
e.midi_note=60; | |
e.velocity=0.f; | |
amy.add_event(e); | |
e = amy.default_event(); | |
e.time=2400; | |
strcpy(e.voices, "1"); | |
e.midi_note=67; | |
e.velocity=0.f; | |
amy.add_event(e); | |
// --- Render the amy-events from above as audio --- | |
while(true) | |
{ | |
short* samples = amy.render_to_buffer(); // You should hear two notes played one after the other and then released at the same time... | |
I2S.write((uint8_t*)samples, AMY_BLOCK_SIZE*AMY_NCHANS*BYTES_PER_SAMPLE); | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment