Lucidbeaming

Berghain Box

Fabrication

Text and long form content.

image details
image details
image details

Code

#include <MozziGuts.h>
#include <IntMap.h>
#include <Oscil.h>
#include <Metronome.h>
#include <Sample.h>
#include <RollingAverage.h>
#include <DCfilter.h>
#include <ArduinoTapTempo.h>
#include <Ead.h>
#include <tables/sin2048_int8.h>
#include <tables/saw2048_int8.h>
#include <samples/bkick.h>

#define CONTROL_RATE 128
ArduinoTapTempo tapTempo;

Metronome kMetro(600);
Oscil <SIN2048_NUM_CELLS, AUDIO_RATE> aSin(SIN2048_DATA);
Oscil <SAW2048_NUM_CELLS, AUDIO_RATE> aSaw(SAW2048_DATA);
Ead envelope(CONTROL_RATE);
Sample <bkick_NUM_CELLS, AUDIO_RATE>aSample(bkick_DATA);
RollingAverage <int, 8> avgA;
DCfilter dcB(0.9);
RollingAverage <int, 8> avgC;
RollingAverage <int, 8> avgD;
DCfilter dcBTN(0.9);

const IntMap fMap(0,1023,30,300);
const IntMap decayMap(0,1023,100,2000);
const IntMap bpm(0,1023,10,400);
int knobVal, rate, knFreq, knobA, knobB, knobC, knobD, envGain;
bool buttonPress, kMetrun, tapActive;

void setup() {
  startMozzi(CONTROL_RATE);
  Serial.begin(115200);
  aSin.setFreq(75);
  aSaw.setFreq(75);
  pinMode(7, INPUT_PULLUP);
  kMetro.setBPM(120);
  kMetro.start();
  aSample.setFreq(15.66328f);
}

void updateControl(){
  readControls();

  if (kMetro.ready()) {
    aSample.start();
    unsigned int decayVal = decayMap(knobC);
    unsigned int attackVal = 20;
    envelope.start(attackVal,decayVal);
  }
  envGain = (int) envelope.next();

  tapTempo.update(buttonPress);

  float pitch = (knobA / 1024.0) * 10.3333f;
  aSample.setFreq(pitch);
  int waveFreq = fMap(knobA);
  aSin.setFreq(waveFreq);
  aSaw.setFreq(waveFreq);

  if (tapActive) {
    rate = tapTempo.getBPM();
  } else {
    rate = bpm(knobB);
  }
  kMetro.setBPM(rate);

  Serial.print(" A: ");Serial.print(knobA);
  Serial.print(" B: ");Serial.print(knobB);
  Serial.print(" C: ");Serial.print(knobC);
  Serial.print(" D: ");Serial.print(knobD);
  Serial.print(" Btn: ");Serial.print(buttonPress);
  Serial.print(" freq: ");Serial.print(pitch);
  Serial.print(" bpm: ");Serial.print(tapTempo.getBPM());
  Serial.print("\n");
}

AudioOutput_t updateAudio(){
  //int asig = (int) aSample.next();
  
  if (knobD > 512) {
    int asig = (int) aSample.next();
    return MonoOutput::from8Bit(asig);
  } else {
    int apig = (int) aSin.next();
    return MonoOutput::from16Bit(apig*envGain);
  }
  //return MonoOutput::fromAlmostNBit(7, asig);
  //return MonoOutput::fromAlmostNBit(5, asig).clip();
}

void loop() {
audioHook();
}

void readControls() {
  int potA = mozziAnalogRead(A0);
  knobA = 1023 - avgA.next(potA);
  int potB = mozziAnalogRead(A1);
  int senVal = dcB.next(potB);
  if (senVal < -2 || senVal > 2) {
    tapActive = LOW;
    knobB = 1023 - potB;
  }
  int potC = mozziAnalogRead(A2);
  knobC = 1023 - avgC.next(potC);
  int potD = mozziAnalogRead(A3);
  knobD = 1023 - avgD.next(potD);

  bool butA = digitalRead(7);
  buttonPress = butA == HIGH;
  if (buttonPress) {
    tapActive = HIGH;
  }
}