Skip to content

Instantly share code, notes, and snippets.

@Visuelle-Musik
Created September 17, 2024 17:34
Show Gist options
  • Save Visuelle-Musik/d842ea44ab7bedf4ddd3f3b313f7d875 to your computer and use it in GitHub Desktop.
Save Visuelle-Musik/d842ea44ab7bedf4ddd3f3b313f7d875 to your computer and use it in GitHub Desktop.
// === 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