Trying to create a multitrack loopstation
Buttons are working perfectly as they should (encoders arent fully soldered yet and leds arent working)
But the issue is with the audio
Default is output (line out) equals input (line in)
But when a loop (audio buffer) is created, it should play that (after the recording is finished)
What comes out is a loud noise
Disabling the other loops didnt change anything
No clue how to print the audio buffer to console, therefore not able to debug it that way
No clue what the issue is or how to debug it
Any help is greatly appreciated
Here is the code
(loop2 is currently disabled bc of a hardware issue)
#include "daisy_seed.h"
#include "daisysp.h"
// Use the daisy namespace to prevent having to type
// daisy:: before all libdaisy functions
using namespace daisy;
using namespace daisy::seed;
using namespace std;
// Declare a DaisySeed object called hardware
DaisySeed hw;
// PUBLIC Variables
#define MAX_SIZE (48000 * 60 * 1) // 1 minutes of floats at 48 khz
float DSY_SDRAM_BSS buffer1[MAX_SIZE];
float DSY_SDRAM_BSS buffer2[MAX_SIZE];
float DSY_SDRAM_BSS buffer3[MAX_SIZE];
float DSY_SDRAM_BSS buffer4[MAX_SIZE];
float DSY_SDRAM_BSS buffer5[MAX_SIZE];
GPIO buttonFn1, buttonFn2, buttonFn3;
// Classes
class Loop
{
private:
enum buttonFunction {first, second, third, fourth, fifth, sixth, seventh, eight};
enum loopModes {loop, oneshot, replace};
loopModes loopMode = loop;
bool firstLoop = true;
bool recording = false;
bool playing = false;
bool overdubing = false;
int position = 0;
int length = 0;
int loopNumber;
GPIO button;
bool buttonPressed = false;
GPIO led;
GPIO encoder1;
GPIO encoder2;
float *buffer;
public:
// Initialize Hardware for Loop
Loop(Pin buttonPin, Pin encoderPin1, Pin encoderPin2, Pin ledPin, int no, float *buf) {
button.Init(buttonPin, GPIO::Mode::INPUT, GPIO::Pull::PULLUP);
encoder1.Init(encoderPin1, GPIO::Mode::INPUT, GPIO::Pull::PULLUP);
encoder2.Init(encoderPin2, GPIO::Mode::INPUT, GPIO::Pull::PULLUP);
led.Init(ledPin, GPIO::Mode::OUTPUT);
loopNumber = no;
buffer = buf;
}
// ~Loop();
loopModes getLoopMode() {
return loopMode;
}
void setLoopMode(loopModes mode) {
loopMode = mode;
}
void checkButton() {
if (!button.Read() && !buttonPressed)
{
buttonPressed = true;
hw.PrintLine("======");
hw.PrintLine(to_string(loopNumber).data());
ButtonPressed(determineButtonFunction());
} else if (button.Read() && buttonPressed) {
buttonPressed = false;
}
hw.SetLed(buttonPressed);
}
buttonFunction determineButtonFunction() {
if (!buttonFn1.Read() && !buttonFn2.Read() && !buttonFn3.Read())
{ return eight; }
else if (!buttonFn1.Read() && !buttonFn3.Read())
{ return seventh; }
else if (!buttonFn2.Read() && !buttonFn3.Read())
{ return sixth; }
else if (!buttonFn1.Read() && !buttonFn2.Read())
{ return fifth; }
else if (!buttonFn3.Read())
{ return fourth; }
else if (!buttonFn2.Read())
{ return third; }
else if (!buttonFn1.Read())
{ return second; }
else { return first; }
}
void ButtonPressed(buttonFunction funct) {
switch (funct)
{
case first:
hw.PrintLine("first");
// record / play/oneshot/replace / pause
if (firstLoop) {
recording = true;
firstLoop = false;
hw.PrintLine("recording");
// stop recording and play
} else if (recording) {
recording = false;
playing = true;
hw.PrintLine("rec -> play");
// pause
} else if (playing) {
playing = false;
hw.PrintLine("paused");
// play
} else if (!playing) {
playing = true;
hw.PrintLine("playing");
// stop overdubing
} else if (overdubing) {
overdubing = false;
hw.PrintLine("stoped overdub");
}
break;
case second:
hw.PrintLine("second");
// overdub
if (loopMode = loop) {
overdubing = true;
hw.PrintLine("overdub");
}
break;
case third:
hw.PrintLine("third");
break;
case fourth:
hw.PrintLine("fourth");
break;
case fifth:
hw.PrintLine("fifth");
break;
case sixth:
hw.PrintLine("sixth");
break;
case seventh:
hw.PrintLine("seventh");
break;
case eight:
hw.PrintLine("eight");
// delete loop
DeleteLoop();
hw.PrintLine("deleted");
break;
}
}
void DeleteLoop() {
loopMode = loop;
firstLoop = true;
recording = false;
playing = false;
overdubing = false;
position = 0;
length = 0;
for(int i = 0; i < length; i++)
{
buffer[i] = 0;
}
}
void WriteBuffer(AudioHandle::InterleavingInputBuffer in, size_t i) {
if (recording)
{
buffer[position] = in[i];
length++;
} else {
buffer[position] = buffer[position] * 0.5 + in[i] * 0.5;
}
}
void NextSamples(float& output, AudioHandle::InterleavingInputBuffer in, size_t i)
{
if (recording || overdubing)
{
WriteBuffer(in, i);
}
//automatic looptime
if (length >= MAX_SIZE)
{
firstLoop = false;
recording = false;
playing = true;
}
if (playing)
{
position++;
position %= length;
output = buffer[position];
}
}
};
Loop loop1(D27, D26, D2, D1, 1, buffer1),
// loop2(D25, D24, D5, D3, buffer2),
loop3(D23, D22, D8, D6, 3, buffer3),
loop4(D21, D20, D11, D9, 4, buffer4),
loop5(D19, D18, D15, D12, 5, buffer5);
void AudioCallback(AudioHandle::InterleavingInputBuffer in, AudioHandle::InterleavingOutputBuffer out, size_t size) {
float output = 0;
for (size_t i = 0; i < size; i += 2) {
loop1.NextSamples(output, in, i);
// loop2.NextSamples(output, in, i);
loop3.NextSamples(output, in, i);
loop4.NextSamples(output, in, i);
loop5.NextSamples(output, in, i);
out[i] = out[i + 1] = output + in[i] + in[i + 1];
}
}
int main(void)
{
// Configure and Initialize the Daisy Seed
// These are separate to allow reconfiguration of any of the internal
// components before initialization.
hw.Configure();
hw.Init();
hw.SetAudioBlockSize(4);
// Wait for Debugger
hw.StartLog(true);
// Initialize FN Buttons
buttonFn1.Init(D17, GPIO::Mode::INPUT, GPIO::Pull::PULLUP);
buttonFn2.Init(D15, GPIO::Mode::INPUT, GPIO::Pull::PULLUP);
buttonFn3.Init(D16, GPIO::Mode::INPUT, GPIO::Pull::PULLUP);
hw.StartAudio(AudioCallback);
while (1)
{
loop1.checkButton();
// loop2.checkButton();
loop3.checkButton();
loop4.checkButton();
loop5.checkButton();
}
}