Skip to content

Instantly share code, notes, and snippets.

@jellea
Created June 14, 2013 11:09
Show Gist options
  • Save jellea/5781068 to your computer and use it in GitHub Desktop.
Save jellea/5781068 to your computer and use it in GitHub Desktop.
MuscleSynth is a synthesizer which you control via your muscles.
// Dependencies: eHealth, Mozzi.
#include <eHealth.h>
float ECG = 0;
int ECGfreq = 100;
unsigned long lastsampleECG = 0;
unsigned long time = 0;
#include <MozziGuts.h>
#include <ReverbTank.h>
#include <Oscil.h>
#include <tables/cos8192_int8.h>
#include <tables/envelop2048_uint8.h>
#include <tables/cos512_int8.h> // for filter modulation
#include <Sample.h> // Sample template
#include <samples/TJBAnalogDisk/Acid_mozzi/FMAcidBass4_int8.h> // Bass sample
#include <LowPassFilter.h>
#include <mozzi_rand.h> // for rand()
#define CONTROL_RATE 64 // quite fast, keeps modulation smooth
// Sample
Sample <FMACIDBASS4_NUM_CELLS, AUDIO_RATE> aSample(FMACIDBASS4_DATA);
// Reverb
ReverbTank reverb;
// OSCs
Oscil <COS8192_NUM_CELLS, AUDIO_RATE> aCarrier(COS8192_DATA);
Oscil <COS8192_NUM_CELLS, AUDIO_RATE> aModulator(COS8192_DATA);
Oscil <COS8192_NUM_CELLS, AUDIO_RATE> aModWidth(COS8192_DATA);
Oscil <COS8192_NUM_CELLS, CONTROL_RATE> kModFreq1(COS8192_DATA);
Oscil <COS8192_NUM_CELLS, CONTROL_RATE> kModFreq2(COS8192_DATA);
Oscil <ENVELOP2048_NUM_CELLS, AUDIO_RATE> aEnvelop(ENVELOP2048_DATA);
Oscil <COS512_NUM_CELLS, CONTROL_RATE> kFilterMod1(COS512_DATA);
Oscil <COS512_NUM_CELLS, CONTROL_RATE> kFilterMod2(COS512_DATA);
LowPassFilter lpf1;
LowPassFilter lpf2;
void setup(){
// synth, mods, lpf and sample params
aCarrier.setFreq(40);
kModFreq1.setFreq(3.98f);
kModFreq2.setFreq(3.31757f);
aModWidth.setFreq(2.52434f);
aEnvelop.setFreq(9.0f);
kFilterMod1.setFreq(1.3f);
kFilterMod2.setFreq(0.1f);
lpf1.setResonance(180);
lpf2.setResonance(220);
aSample.setFreq((float) FMACIDBASS4_SAMPLERATE / (float) FMACIDBASS4_NUM_CELLS);
startMozzi();
}
void updateControl(){
ECG = eHealth.getECG();
byte cutoff_freq1 = 50; // desired 150 ± 63, input 4-1
byte cutoff_freq2 = 20; // desired 70 ± 31 , input 4-1
if (ECG < 2.5){
byte cutoff_freq1 = 300; // desired 150 ± 63, input 4-1
byte cutoff_freq2 = 100; // desired 70 ± 31 , input 4-1
}
if (ECG > 2.5){
aSample.start();
}
lpf1.setCutoffFreq(cutoff_freq1);
lpf2.setCutoffFreq(cutoff_freq2);
aModulator.setFreq(260.0f + 0.4313f*kModFreq1.next() + kModFreq2.next());
}
int updateAudio(){
int synth = aCarrier.phMod((int)aModulator.next()*(100u+aModWidth.next()));
synth *= (unsigned char)aEnvelop.next();
synth >>= 8;
// here's the reverb
int arev = reverb.next(synth);
// add the dry and wet signals
return (char)lpf1.next(synth) + (char)lpf2.next((arev>>3)) + (int) aSample.next();
}
void loop(){
audioHook();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment