Upload files to 'Software'

This commit is contained in:
Simon 2021-03-13 11:10:56 +01:00
parent a088f50d07
commit 566bacc562
5 changed files with 639 additions and 0 deletions

View File

@ -0,0 +1,135 @@
#include <Synth-Clatter.h>
#include <Synth-Decay.h>
#include <Synth-DrumHeart.h>
#include <synth_simple_drum.h>
#include <TeensyBoomVoiceLibrary.h>
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
#include "panel-scanner.h"
#include "editor.h"
#include "pattern.h"
#include "player.h"
#include "voice.h"
#include "teensy_midi.h"
const int channel = 1;
// Appp construct singletons
PanelScanner theScanner;
Editor theEditor;
Pattern thePattern; // TBD: multidimensional...
Player thePlayer;
Teensy_Midi theMidi;
void setup() {
// put your setup code here, to run once:
Serial.begin(57600);
delay(1500);
Serial.println("Setup");
pinMode(15, INPUT); // Volume pot pin?
// SD CARD & general SPI inits
// Initialize the SD card
SPI.setMOSI(7);
SPI.setSCK(14);
// This sets the chip selects for the panel
// to OFF. Gotta do it before SD init, else the panels contend!
theScanner.initScanning();
if (!(SD.begin(10)))
{
Serial.println("Unable to access the SD card");
}
else
{
Serial.println("SD card begin worked");
}
if (SD.exists("test.txt"))
{
Serial.println("found test.txt file");
}
else
{
Serial.println("Didn't find test file?");
}
theMidi.init(); //Midi Initialisieren
theEditor.setMode(Editor::eMODE_PATT_SEL);
// audio library init
AudioMemory(20);
//next = millis() + 1000;
// read panel before we start to run
//paramUpdate();
voiceInit();
delay(500);
Serial.println("Setup Complete");
}
void loop()
{
uint32_t now = millis();
static uint32_t then;
#if 1
// put your main code here, to run repeatedly:
paramUpdate1();// kik,snr,hat
paramUpdate2();// toms, shaker
paramUpdate3();// master volume & tempo
if (now > then)
{
thePlayer.tick();
}
if (now % 5 == 0)
{
theScanner.tick();
}
if (now % 5000 == 0)
{
//theScanner.dumpLEDs();
Serial.print("Diagnostics: ");
Serial.print(" max, buffs: ");
Serial.print(AudioProcessorUsageMax());
Serial.print(" ");
Serial.println(AudioMemoryUsageMax());
AudioProcessorUsageMaxReset();
//Test:
// triggerKick(true);
// int note = 40;
// for (note=10; note <= 127; note++) {
// MIDI.sendNoteOn(note, 100, channel);
// delay(200);
// MIDI.sendNoteOff(note, 100, channel);
// setBlinkingLED(22, true);
//setLEDs(true);
// }
}
then = now;
#endif
}

379
Software/player.cpp Normal file
View File

@ -0,0 +1,379 @@
#include <Arduino.h>
#include "player.h"
#include "pattern.h"
#include "editor.h"
#include "voice.h"
#include "teensy_midi.h"
// Similar, for the pattern...
extern Pattern thePattern;
extern PanelScanner theScanner;
extern Editor theEditor;
extern Teensy_Midi theMidi;
// constructor...
Player::Player()
{
playing = false;
swing = false;
current_step = 0;
active_mutes = 0;
pending_mutes = 0;
active_pattern = 0;
pending_pattern = -1;
pause_len = 125;// milliseconds, 125 mS = 120 bpm
}
void Player::start()
{
playing = true;
current_step = 0;
if(chain_active)
{
chain_play_idx = 0;
active_pattern = chain_array[0];
thePattern.setCurrentPattern(active_pattern);
}
//theScanner.setOverlayLED(0x17);
theEditor.forceLEDs();
theMidi.start();
}
void Player::stop()
{
playing = false;
theEditor.forceLEDs();
theMidi.stop();
}
bool Player::isPlaying()
{
return playing;
}
void Player::setPause(uint32_t millisec)
{
pause_len = millisec;
}
bool Player::toggleSwing()
{
swing = !swing;
Serial.print("Swing is now: ");
Serial.println(swing);
return swing;
}
bool Player::getSwing()
{
return swing;
}
bool Player::toggleMuteBit(uint32_t bit)
{
if(bit > 12)
return false;
if(playing)
{
pending_mutes ^= (1 << bit);
return (pending_mutes & (1 << bit));
}
else
{
active_mutes ^= (1 << bit);
return (active_mutes & (1 << bit));
}
}
bool Player::getMuteBit(uint32_t bit)
{
if(bit > 12)
return false;
return (active_mutes & (1 << bit));
}
bool Player::getPendingMuteBit(uint32_t bit)
{
if(bit > 12)
return false;
return (pending_mutes & (1 << bit));
}
bool Player::setNextPattern(int32_t next)
{
if((uint32_t) next > Pattern::NUM_PATTERNS)
return false;
if(next == active_pattern)
{
return false;
}
if(playing)
{
pending_pattern = next;
return true;// (pending_pattern);
}
else
{
active_pattern = next;
thePattern.setCurrentPattern(active_pattern);
return true; //(active_mutes & (1 << bit));
}
}
int32_t Player::getActivePattern()
{
return active_pattern;
}
int32_t Player::getPendingPattern()
{
return pending_pattern;
}
int32_t Player::getCurrentStep()
{
return current_step;
}
bool Player::getBlinkPhase()
{
int32_t now = millis();
if(now < (next_time - (pause_len>>1)))
{
return true;
}
return false;
}
////////////////////////////////////////////////////////////////
// chain stuff
////////////////////////////////////////////////////////////////
bool Player::chainIsActive()
{
return chain_active;
}
void Player::initChain()
{
chain_active = false;
chain_insert_idx = 0;
chain_play_idx = 0;
}
void Player::addToChain(int32_t patt_num)
{
if((uint32_t) patt_num >= Pattern::NUM_PATTERNS)
{
Serial.println("addToChain patt_num out of bounds!");
return;
}
Serial.print("Adding patt ");
Serial.print(patt_num);
Serial.print("to chain at idx ");
Serial.println(chain_insert_idx);
if(!chain_active)
{
// the first piece added to chain
chain_active = true;
chain_array[0] = patt_num;
chain_insert_idx = 1;
chain_play_idx = -1;// one before the first step - it'll increment and be at beginning
theEditor.forceLEDs();
return;
}
if(chain_insert_idx < (int32_t)CHAIN_LEN)
{
chain_array[chain_insert_idx] = patt_num;
chain_insert_idx++;
theEditor.forceLEDs();
}
}
int32_t Player::getNextChainVal()
{
chain_play_idx++;
if(chain_play_idx >= chain_insert_idx)
{
chain_play_idx = 0;
}
#if 0
Serial.print("Getting next chain pattern, (idx, val):");
Serial.print(chain_play_idx);
Serial.print(" ");
Serial.println(chain_array[chain_play_idx]);
#endif
return chain_array[chain_play_idx];
}
bool Player::checkChainMembership(int32_t patt)
{
// is patt # active within chain?
for(int32_t i = 0; i < chain_insert_idx; i++)
{
if(patt == chain_array[i])
{
//Serial.println("found chain member");
return true;
}
}
return false;
}
void Player::tick()
{
int32_t now = millis();
if(now < next_time)
{
return;
}
if(!swing)
{
next_time = now + pause_len;
}
else
{
if(!(current_step & 0x01))
{
next_time = now + pause_len + (pause_len/3);
}
else
{
next_time = now + ((2*pause_len)/3);
}
}
if(playing)
{
uint32_t trigdata = thePattern.getStepData(current_step);
// Apply mutes
trigdata &= (~active_mutes);
theEditor.forceLEDs();
#if 0
Serial.print("Trigger: step#");
Serial.print(current_step);
Serial.print(" bitmap:");
Serial.println(trigdata, HEX);
#endif
theMidi.clock();
AudioNoInterrupts();
if (trigdata & 0x01)
{
triggerKick(trigdata & 0x010000);
}
if (trigdata & 0x02)
{
triggerSnare(trigdata & 0x020000);
}
if (trigdata & 0x04)
{
// closed hat trumps open hat.
triggerHat(false, trigdata & 0x040000);
}
else if (trigdata & 0x08)
{
triggerHat(true, trigdata & 0x080000);
}
if (trigdata & 0x10)
{
triggerTom(1, trigdata & 0x100000);
}
else if (trigdata & 0x20)
{
triggerTom(2, trigdata & 0x200000);
}
else if (trigdata & 0x40)
{
triggerTom(3, trigdata & 0x400000);
}
if (trigdata & 0x80)
{
triggerBell(trigdata & 0x800000);
}
if (trigdata & 0x100)
{
triggerShaker(trigdata & 0x1000000);
}
if (trigdata & 0x200)
{
triggerCymbal(trigdata & 0x2000000);
}
if (trigdata & 0x400)
{
triggerClap(trigdata & 0x4000000);
}
AudioInterrupts();
}
current_step++;
if(current_step >= 0x10)
{
// this block of code is setting up the NEXT invocation, so we can change
// patterns without overhead before the next set of triggers.
// It means that come instenal state is ahead of the actual playback state -
// the takeaway: don't call theEditor.forceLEDs(), or the display gets out of sync
current_step = 0;
if(pending_mutes)
{
active_mutes ^= pending_mutes;
pending_mutes = 0;
}
if(!chain_active)
{
if(pending_pattern != -1)
{
active_pattern = pending_pattern;
thePattern.setCurrentPattern(pending_pattern);
pending_pattern = -1;
}
//else, just keep current pattern...
}
else//chain_active
{
active_pattern = getNextChainVal();
thePattern.setCurrentPattern(active_pattern);
}
// do this after the LED updates, or they get the wrong current step!
current_step = 0;
}
}

68
Software/player.h Normal file
View File

@ -0,0 +1,68 @@
#ifndef _PLAYER_H_
#define _PLAYER_H_
#pragma once
class Player
{
public:
Player();
void start();
void stop();
bool isPlaying();
void setPause(uint32_t millisec);
bool toggleSwing();
bool getSwing();
bool toggleMuteBit(uint32_t bit);
bool getMuteBit(uint32_t bit);
bool getPendingMuteBit(uint32_t bit);
bool setNextPattern(int32_t next);
int32_t getActivePattern();
int32_t getPendingPattern();
int32_t getCurrentStep();
bool getBlinkPhase();
void tick();
static const uint32_t CHAIN_LEN = 32;
// Chain Stuff
bool chainIsActive();
void initChain();
void addToChain(int32_t patt_num);
int32_t getNextChainVal();
bool checkChainMembership(int32_t patt);
private:
bool playing;
bool swing;
int32_t current_step;
int32_t prev_step;
int32_t pause_len;
int32_t next_time;
int32_t active_mutes;
int32_t pending_mutes;
int32_t active_pattern;
int32_t pending_pattern;
bool chain_active;
int32_t chain_len;
int32_t chain_insert_idx;
int32_t chain_play_idx;
int8_t chain_array[CHAIN_LEN];
};
#endif // keepout

40
Software/teensy_midi.cpp Normal file
View File

@ -0,0 +1,40 @@
#include <MIDI.h>
#include "teensy_midi.h"
MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, MIDI);
int MIDI_Clock = 1;
int MIDI_Clock_Master = 1;
// constructor...
Teensy_Midi::Teensy_Midi()
{
}
void Teensy_Midi::init()
{
MIDI.begin();
Serial.print("Midi Begin: ");
}
void Teensy_Midi::start()
{
if (MIDI_Clock == 1 && MIDI_Clock_Master == 1) {
MIDI.send((midi::MidiType)0xFA, 0, 0, 1);
}
}
void Teensy_Midi::stop()
{
if (MIDI_Clock == 1 && MIDI_Clock_Master == 1) {
MIDI.send((midi::MidiType)0xFC, 0, 0, 1);
}
}
void Teensy_Midi::clock()
{
//Send midi-CLock
if (MIDI_Clock == 1 && MIDI_Clock_Master == 1) {
MIDI.send((midi::MidiType)0xF8, 0, 0, 1);
}
}

17
Software/teensy_midi.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef _TEENSY_MIDI_H_
#define _TEENSY_MIDI_H_
class Teensy_Midi
{
public:
Teensy_Midi();
void init();
void start();
void stop();
void clock();
};
#endif