3 #include "AudioTools/CoreAudio/AudioLogger.h"
4 #include "AudioTools/CoreAudio/AudioTypes.h"
5 #include "AudioTools/CoreAudio/AudioBasic/Collections.h"
6 #include "AudioTools/CoreAudio/AudioActions.h"
7 #include "AudioTools/CoreAudio/AudioStreams.h"
8 #include "SoundGenerator.h"
9 #include "AudioEffects.h"
31 virtual void keyOn(
int nte,
float tgt) = 0;
53 setGenerator(generator);
62 result->begin(config);
67 p_generator = &generator;
72 this->config = config;
76 if (p_generator==
nullptr){
80 p_generator->begin(config);
85 p_adsr =
new ADSRGain(0.0001, 0.0001, 0.8, 0.0005);
92 return p_adsr !=
nullptr ? p_adsr->isActive() :
false;
97 if (p_generator!=
nullptr){
100 if (p_adsr!=
nullptr){
108 if (p_adsr!=
nullptr){
111 LOGE(
"p_adsr is null")
116 if (p_generator==
nullptr)
return 0;
118 int size = effects.
size();
119 for (
int j=0; j<size; j++){
120 sample = effects[j]->process(sample);
135 AudioEffectCommon effects;
136 SoundGenerator<int16_t> *p_generator =
nullptr;
137 ADSRGain *p_adsr =
nullptr;
176 for (
int j=0;j<channels.size();j++){
178 channels[j] =
nullptr;
182 delete p_synth_action;
191 defaultChannel->
begin(config);
195 void keyOn(
int note,
float tgt=0){
196 LOGI(
"keyOn: %d", note);
198 if (channel!=
nullptr){
199 channel->
keyOn(note, tgt);
201 LOGW(
"No channel available for %d",note);
205 void keyOff(
int note){
206 LOGI(
"keyOff: %d", note);
208 if (channel!=
nullptr){
218 for (
int j=0;j<channels.size();j++){
221 total += channels[j]->readSample();
227 result = NumberConverter::clipT<int16_t>(total / count);
234 while (p_keys->note > 0){
235 actions.
add(p_keys->pin, callbackKeyOn, callbackKeyOff, activeValue ,
new KeyParameter(
this, p_keys->note));
249 const char* midi_name =
"Synthesizer";
263 class SynthAction :
public MidiAction {
270 void onNoteOn(uint8_t channel, uint8_t note, uint8_t velocity) {
271 int frq = MidiCommon::noteToFrequency(note);
272 float vel = 1.0/127.0 * velocity;
273 synth->keyOn(frq, vel);
275 void onNoteOff(uint8_t channel, uint8_t note, uint8_t velocity) {
276 int frq = MidiCommon::noteToFrequency(note);
279 void onControlChange(uint8_t channel, uint8_t controller, uint8_t value) {}
280 void onPitchBend(uint8_t channel, uint8_t value) {}
283 SynthAction *p_synth_action =
new SynthAction(
this);
285 MidiBleServer ble = MidiBleServer(midi_name, p_synth_action);
290 AbstractSynthesizerChannel *getNoteChannel(
int note){
291 LOGI(
"getNoteChannel: %d", note);
292 for (
int j=0;j<channels.size();j++){
293 if (channels[j]->note() == note){
301 AbstractSynthesizerChannel *getFreeChannel(){
302 LOGI(
"getFreeChannel");
303 for (
int j=0;j<channels.size();j++){
308 LOGI(
"No free channel found: Adding new channel");
309 AbstractSynthesizerChannel* ch = defaultChannel->clone();
310 channels.push_back(ch);
314 static void callbackKeyOn(
bool active,
int pin,
void* ref){
316 KeyParameter* par = (KeyParameter*)ref;
317 if (par !=
nullptr && par->p_synthesizer!=
nullptr){
318 par->p_synthesizer->keyOn(par->note);
320 LOGE(
"callbackKeyOn: unexpected null")
324 static void callbackKeyOff(
bool active,
int pin,
void* ref){
326 KeyParameter* par = (KeyParameter*)ref;
328 if (par->p_synthesizer!=
nullptr){
329 par->p_synthesizer->keyOff(par->note);
331 LOGE(
"callbackKeyOff: p_synthesizer is null");
334 LOGE(
"callbackKeyOff: ref is null");