Skip to content

Commit

Permalink
Misc pull requests from Chysn and Logarhythm1
Browse files Browse the repository at this point in the history
Adding BigScope App – Changes from pull request Chysn#76
Changes from pull request Chysn#51
Changes from pull request Chysn#105
Changes from pull request Logarhythm1#2
  • Loading branch information
suit4 committed Jun 17, 2022
1 parent 7a5c0da commit b4ea46d
Show file tree
Hide file tree
Showing 7 changed files with 288 additions and 3 deletions.
225 changes: 225 additions & 0 deletions software/o_c_REV/APP_BIGSCOPE.ino.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
#include "HSApplication.h"
#include "HSMIDI.h"

#define HEMISPHERE_MAX_CV 7680
#define HEMISPHERE_CENTER_CV 0
#define SCOPE_WIDTH 128

class BigScope : public HSApplication, public SystemExclusiveHandler {
public:
void Start() {
last_bpm_tick = OC::CORE::ticks;
bpm = 0;
sample_ticks = 320;
freeze = 0;
last_scope_tick = 0;
}

void Resume() {
}

void Controller() {
if (Clock(0)) {
int this_tick = OC::CORE::ticks;
int time = this_tick - last_bpm_tick;
last_bpm_tick = this_tick;
bpm = 1000000 / time;
if (bpm > 9999) bpm = 9999;

if (last_scope_tick) {
int cycle_ticks = OC::CORE::ticks - last_scope_tick;
sample_ticks = cycle_ticks / 64;
sample_ticks = constrain(sample_ticks, 2, 64000);
}
last_scope_tick = OC::CORE::ticks;
}

if (!freeze) {
last_cv = In(0);

if (--sample_countdown < 1) {
sample_countdown = sample_ticks;
if (++sample_num > 127) sample_num = 0;
int sample = Proportion(In(0), HEMISPHERE_MAX_CV, 128);
sample = constrain(sample, -128, 127) + 127;
snapshot[sample_num] = (uint8_t) sample;
}

Out(0, In(0));
}
}

void View() {
gfxHeader("Scope");
//gfxPrint(1, 2, "Scope");
//DrawTicks();
DrawVoltage();
DrawBPM();
DrawInput1();
if (freeze) {
gfxInvert(0, 24, 128, 40);
}
}

void OnSendSysEx() {
}

void OnReceiveSysEx() {
}

/////////////////////////////////////////////////////////////////
// Control handlers
/////////////////////////////////////////////////////////////////
void OnLeftButtonPress() {
freeze = 1 - freeze;
}

void OnLeftButtonLongPress() {

}

void OnRightButtonPress() {
}

void OnUpButtonPress() {
}

void OnDownButtonPress() {
}

void OnDownButtonLongPress() {
}

void OnLeftEncoderMove(int direction) {
if (sample_ticks < 32) sample_ticks += direction;
else sample_ticks += direction * 10;
sample_ticks = constrain(sample_ticks, 2, 64000);
last_encoder_move = OC::CORE::ticks;
}

void OnRightEncoderMove(int direction) {
}

private:
// BPM Calcultion
int last_bpm_tick;
int bpm;

// CV monitor
int last_cv;
bool freeze;

// Scope
uint8_t snapshot[128];
int sample_ticks; // Ticks between samples
int sample_countdown; // Last time a sample was taken
int sample_num; // Current sample number at the start
int last_encoder_move; // The last the the sample_ticks value was changed
int last_scope_tick; // Used to auto-calculate sample countdown

void DrawBPM() {
gfxPrint(110, 1, bpm / 4);
gfxBitmap(102, 1, 8, CLOCK_ICON);
}

// void DrawTicks() {
// gfxPrint(40, 1, sample_ticks);
// }


void gfxPrintVoltage(int cv) {
int v = (cv * 100) / (12 << 7);
bool neg = v < 0 ? 1 : 0;
if (v < 0) v = -v;
int wv = v / 100; // whole volts
int dv = v - (wv * 100); // decimal
gfxPrint(neg ? "-" : "+");
gfxPrint(wv);
gfxPrint(".");
if (dv < 10) gfxPrint("0");
gfxPrint(dv);
gfxPrint("V");
}

void DrawVoltage() {
gfxBitmap(45, 3, 8, CV_ICON);
gfxPos(55, 1);
gfxPrintVoltage(last_cv);
}

void DrawInput1() {
for (int s = 0; s < 128; s++)
{
int x = s + sample_num;
if (x > 127) x -= 128;
int l = Proportion(snapshot[x], 255, 48);
gfxPixel(x, (48 - l) + 14);
}

}

};

BigScope BigScope_instance;

// App stubs
void BigScope_init() {
BigScope_instance.BaseStart();
}

// Not using O_C Storage
size_t BigScope_storageSize() { return 0; }

size_t BigScope_save(void *storage) { return 0; }

size_t BigScope_restore(const void *storage) { return 0; }

void BigScope_isr() {
return BigScope_instance.BaseController();
}

void BigScope_handleAppEvent(OC::AppEvent event) {
if (event == OC::APP_EVENT_RESUME) {
BigScope_instance.Resume();
}
if (event == OC::APP_EVENT_SUSPEND) {
BigScope_instance.OnSendSysEx();
}
}

void BigScope_loop() {} // Deprecated

void BigScope_menu() {
BigScope_instance.BaseView();
}

void BigScope_screensaver() {} // Deprecated

void BigScope_handleButtonEvent(const UI::Event &event) {
// For left encoder, handle press and long press
if (event.control == OC::CONTROL_BUTTON_L) {
if (event.type == UI::EVENT_BUTTON_LONG_PRESS) BigScope_instance.OnLeftButtonLongPress();
else BigScope_instance.OnLeftButtonPress();
}

// For right encoder, only handle press (long press is reserved)
if (event.control == OC::CONTROL_BUTTON_R && event.type == UI::EVENT_BUTTON_PRESS)
BigScope_instance.OnRightButtonPress();

// For up button, handle only press (long press is reserved)
if (event.control == OC::CONTROL_BUTTON_UP) BigScope_instance.OnUpButtonPress();

// For down button, handle press and long press
if (event.control == OC::CONTROL_BUTTON_DOWN) {
if (event.type == UI::EVENT_BUTTON_PRESS) BigScope_instance.OnDownButtonPress();
if (event.type == UI::EVENT_BUTTON_LONG_PRESS) BigScope_instance.OnDownButtonLongPress();
}
}

void BigScope_handleEncoderEvent(const UI::Event &event) {
// Left encoder turned
if (event.control == OC::CONTROL_ENCODER_L) BigScope_instance.OnLeftEncoderMove(event.value);

// Right encoder turned
if (event.control == OC::CONTROL_ENCODER_R) BigScope_instance.OnRightEncoderMove(event.value);
}
2 changes: 2 additions & 0 deletions software/o_c_REV/APP_HEMISPHERE.ino
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ public:
help_hemisphere = -1;
clock_setup = 0;

OC::DAC::set_all_octave(0);

SetApplet(0, get_applet_index_by_id(8)); // ADSR
SetApplet(1, get_applet_index_by_id(26)); // Scale Duet
}
Expand Down
8 changes: 8 additions & 0 deletions software/o_c_REV/HEM_ADSREG.ino
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,15 @@ public:
}

void View() {
int adsr[4] = {attack, decay, sustain, release};
const char *labels[] = {"Attack","Decay","Sustain","Release"};

gfxHeader(applet_name());
gfxPos(1, 15);
gfxPrint(labels[edit_stage]);
gfxPrint(45 + 18 - digitCount(adsr[edit_stage]) * 6, 15, adsr[edit_stage]);
gfxCursor(46, 23, 17);

DrawIndicator();
DrawADSR();
}
Expand Down
41 changes: 38 additions & 3 deletions software/o_c_REV/HEM_Carpeggio.ino
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public:
replay = 0;
transpose = 0;
ImprintChord(2);
pitch_out_for_step();
}

void Controller() {
Expand All @@ -53,8 +54,8 @@ public:
step = (y * 4) + x;
pitch_out_for_step();
} else {
pitch_out_for_step();
if (++step > 15) step = 0;
pitch_out_for_step();
}
replay = 0;
} else if (replay) {
Expand Down Expand Up @@ -85,14 +86,25 @@ public:
cursor = 0; // Don't advance cursor when chord is changed
ImprintChord(chord);
}
if (++cursor > 2) cursor = 0;
if (++cursor > 3) cursor = 0;
ResetCursor();
}

void OnEncoderMove(int direction) {
if (cursor == 0) sequence[step] = constrain(sequence[step] += direction, -24, 60);
if (cursor == 1) chord = constrain(chord += direction, 0, Nr_of_arp_chords - 1);
if (cursor == 2) transpose = constrain(transpose += direction, -24, 24);
if (cursor == 3) {
// only imprint cord when turning left from shuffle
if (shuffle && direction < 0) {
ImprintChord(sel_chord);
}
// shuffle chord every time we turn right
if (direction > 0) {
ShuffleChord();
}

}
if (cursor != 1) replay = 1;
}

Expand Down Expand Up @@ -130,6 +142,7 @@ private:
int chord; // Selected chord
int sel_chord; // Most recently-imprinted chord
int transpose; // Transposition setting (-24 ~ +24)
bool shuffle = false;

// Variables to handle imprint confirmation animation
int confirm_animation_countdown;
Expand All @@ -149,6 +162,12 @@ private:
gfxPrint(transpose);
if (cursor == 2) gfxCursor(32, 33, 30);

// Shuffle selector
gfxBitmap(37, 36, 8, PLAY_ICON);
gfxBitmap(49, 36, 8, LOOP_ICON);
gfxInvert(36 + (shuffle ? 12 : 0), 35, 10, 10);
if (cursor == 3) gfxCursor(37, 46, 20);

// Note name editor
uint8_t midi_note = constrain(sequence[step] + 36 + transpose, 0, 127);
gfxPrint(38, 50, midi_note_numbers[midi_note]);
Expand Down Expand Up @@ -188,6 +207,22 @@ private:
chord = new_chord;
confirm_animation_position = 16;
confirm_animation_countdown = HEM_CARPEGGIO_ANIMATION_SPEED;
shuffle = false;
}

void ShuffleChord() {
int16_t old; // temp var for note being swapped
int16_t rnd; // temp var for index of note swapping in
for (int i = 0; i < 16; i++) {
// set old to current step value
old = sequence[i];
rnd = random(0, 16);
sequence[i] = sequence[rnd];
sequence[rnd] = old;
}
confirm_animation_position = 16;
confirm_animation_countdown = HEM_CARPEGGIO_ANIMATION_SPEED;
shuffle = true;
}

void pitch_out_for_step() {
Expand Down Expand Up @@ -237,4 +272,4 @@ uint32_t Carpeggio_OnDataRequest(bool hemisphere) {

void Carpeggio_OnDataReceive(bool hemisphere, uint32_t data) {
Carpeggio_instance[hemisphere].OnDataReceive(data);
}
}
9 changes: 9 additions & 0 deletions software/o_c_REV/HemisphereApplet.h
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,15 @@ class HemisphereApplet {
return padding;
}

int digitCount(int n) {
int count = 0;
while (n != 0) {
n /= 10; // n = n/10
++count;
}
return count;
}

//////////////// Hemisphere-specific graphics methods
////////////////////////////////////////////////////////////////////////////////

Expand Down
3 changes: 3 additions & 0 deletions software/o_c_REV/OC_apps.ino
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ OC::App available_apps[] = {
#ifdef ENABLE_APP_DARKEST_TIMELINE
DECLARE_APP('D','2', "Darkest Timeline", TheDarkestTimeline),
#endif
#ifdef ENABLE_APP_BIG_SCOPE
DECLARE_APP('B','S', "Scope", BigScope),
#endif
DECLARE_APP('E','N', "Enigma", EnigmaTMWS),
DECLARE_APP('N','N', "Neural Net", NeuralNetwork),
DECLARE_APP('S','C', "Scale Editor", SCALEEDITOR),
Expand Down
3 changes: 3 additions & 0 deletions software/o_c_REV/OC_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,8 @@
// This uses approximately 640 additional bytes of program storage space
#define HEM_LOGARHYTHM_MOD_SCALES

// Define this to enable the BigScope App
#define ENABLE_APP_BIG_SCOPE

#endif

0 comments on commit b4ea46d

Please sign in to comment.