diff --git a/README.MD b/README.MD index e930fd2..b512a9a 100644 --- a/README.MD +++ b/README.MD @@ -1,20 +1,22 @@ +6hp multichannel clock utility designed to be low cost and DIY friendly. + +> It is like a "Pamela's 'very light' Workout" ;) +> —u/BBougre + Features: +- 24ppqn internal clock with master BPM - 6 output channels -- Master BPM - Separate divider or multiplier per chennel (from /32 to x24) -- Per-channel random pulse skip chance +- Per-channel random pulse skip probability setting +- Per-channel offset setting - 2 inputs for external modulation (assignable per channel) - All channel settings and bpm are saved on play/pause and recalled on power up +- 2 external clock modes (24ppqn and beat) TODO: -- add offset parameter -- external clock - swing - settings (input mode, pulse length) - expanders with midi/tap tempo etc Timer library available here -https://github.com/PaulStoffregen/FlexiTimer2 - -KiCad SSD1306 display component -https://github.com/pforrmi/KiCad-SSD1306-128x64 \ No newline at end of file +https://github.com/PaulStoffregen/FlexiTimer2 \ No newline at end of file diff --git a/software/GToE/GToE.ino b/software/GToE/GToE.ino index 8a0c80f..5c1372d 100644 --- a/software/GToE/GToE.ino +++ b/software/GToE/GToE.ino @@ -106,6 +106,7 @@ void setup() { saveState(); EEPROM.write(1023, 'K'); } + calculateCycles(); pinMode(ENC_BTN_PIN, INPUT_PULLUP); pinMode(START_STOP_BTN_PIN, INPUT_PULLUP); @@ -117,8 +118,6 @@ void setup() { pinMode(outsPins[i], OUTPUT); } - calculateCycles(); - display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS); //Splash screen @@ -188,12 +187,8 @@ void sendTriggers() { if (pulseCount == 0) { for (int i = 0; i<6; i++) { if (playingModes[i] != clockModes[channels[i].mode]) { - playingModes[i] = clockModes[channels[i].mode]; - if (playingModes[i] > 0) { - channelPulsesPerCycle[i] = (playingModes[i] * PPQN) - 1; - } else { - channelPulsesPerCycle[i] = (PPQN / abs(playingModes[i])) - 1; - } + //playingModes[i] = clockModes[channels[i].mode]; + calculateCycles(); channelPulseCount[i] = 0; } } @@ -216,6 +211,7 @@ void sendTriggers() { void calculateCycles() { for (int i = 0; i<6; i++) { + playingModes[i] = clockModes[channels[i].mode]; if (playingModes[i] > 0) { channelPulsesPerCycle[i] = (playingModes[i] * PPQN) - 1; } else { @@ -302,17 +298,22 @@ void checkInputs() { bpm = MINBPM; } updateTiming(); - } else if (displayTab != 0 && insideTab == 0) { + } else if (displayTab != 0 && insideTab == 0) { //subdivision channels[displayTab-1].mode = channels[displayTab-1].mode - change; if (channels[displayTab-1].mode == 65535) { //65535 is 0-1 for unsigned vars channels[displayTab-1].mode = 0; } else if (channels[displayTab-1].mode > (sizeof(clockModes)/sizeof(int)) - 1) { channels[displayTab-1].mode = (sizeof(clockModes)/sizeof(int)) - 1; - } + } + if (!isPlaying) { + calculateCycles(); + } } else if (displayTab != 0 && insideTab == 1) { //random channels[displayTab-1].random = channels[displayTab-1].random + change; - if (channels[displayTab-1].random > 9 || channels[displayTab-1].random < 0) { + if (channels[displayTab-1].random == 65535) { channels[displayTab-1].random = 0; + } else if (channels[displayTab-1].random > 9) { + channels[displayTab-1].random = 9; } } else if (displayTab != 0 && insideTab == 2) { //modulation channels[displayTab-1].modulationRange = channels[displayTab-1].modulationRange + change; @@ -322,10 +323,10 @@ void checkInputs() { } } else if (displayTab != 0 && insideTab == 3) { //offset channels[displayTab-1].offset = channels[displayTab-1].offset + change; - if (channels[displayTab-1].offset >= channelPulsesPerCycle[displayTab-1]) { - channels[displayTab-1].offset = channelPulsesPerCycle[displayTab-1]; - } else if (channels[displayTab-1].offset <= 0 ) { + if (channels[displayTab-1].offset == 65535) { channels[displayTab-1].offset = 0; + } else if (channels[displayTab-1].offset >= channelPulsesPerCycle[displayTab-1]) { + channels[displayTab-1].offset = channelPulsesPerCycle[displayTab-1]; } } updateScreen(); @@ -461,6 +462,8 @@ void updateScreen() { display.setCursor(58,44); display.print(F(" OFT:")); display.print(channels[displayTab-1].offset); + display.print(F("/")); + display.print(channelPulsesPerCycle[displayTab-1]+1); display.print(F(" ")); }