Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
jmamma committed Nov 11, 2024
2 parents 28e9504 + c20acee commit 53e4278
Show file tree
Hide file tree
Showing 124 changed files with 2,510 additions and 1,726 deletions.
62 changes: 62 additions & 0 deletions Changelog
Original file line number Diff line number Diff line change
@@ -1,3 +1,65 @@
MCL 4.60 21/09/2024

Please upgrade to Machinedrum OS X.11 & Monomachine OS X.01 before using MCL 4.60.

- Sequencer:

The MD's in-built MIDI machines are now supported via the MCL sequencer.
MIDI data is transmitted on MegaCommand's MIDI Port 2.

- Grid Page:

It's now possible to reconfigure the Grid Page Encoders to act as the four
Performance Controllers. Via option: Config -> Page Setup -> Grid Encod

When selecting multiple rows for copy/clear/paste operations the corresponding Bank/Pattern id is now displayed on the left.

- Mixer Page:

Performance States (formerly Mute Sets):

As previously, there are 4 Performance States, each mapped to an individual [Up/Down/Left/Right] key.
Each Performance State contains Mute settings for the MD and External MIDI tracks, and 4 Performance Controller Locks.

Press [Scale] to toggle the Mixer's active device between MD and External MIDI.

The Mutes in a Performance State can be deactivated for the active device by holding an [Up/Down/Left/Right] key and pressing [Mute/BankA]

Apply Performance States:
- To apply a Performance State during a performance, hold down an [Up/Down/Left/Right] Key and press [YES]

Performance State Autoload:
A chosen Performance State can now be made to auto-load when the Perf Slot in Grid Y is loaded:
- From the Mixer Page, Hold an [ Arrow ] key to visually preview the Performance State and then press [Accent/BANKB] to enable auto "LOAD".
- Then save the Perf Slot, in Grid Y.

Performance Controller AutoFill ( Kit Morph ):
- A Perf Controller's assigned left + right scenes can be cleared of paramater locks by holding down the MCL <Encoder Button> and pressing the MC's < Shift > button.
- A Perf Controller's assigned right scenes can be auto-filled altered Kit parameters by holding down the MCL <Encoder Button>
and pressing the MC's <Yes / Load> button.

- Misc:

The Port 1 MIDI driver can now be optionally changed to Generic.

Performance optimizations and improvements.

- Bug Fixes:

Fixed device selection in Chromatic Page

Route and Perf track types would not load correctly during transitions

WavDesigner sample transfer was broken.

GUI fixes for SampleBrowser and text input related pages.

MD's random LFO shape was broken when loading with MCL.

MCL LFO could transmit bogus MIDI data.

MCL would crash when loading tracks at very slow tempo 30BPM.

MCL 4.51a 20/12/2023

Fixed [ Func ] + [ Clear ] regression in PianoRoll.
Expand Down
81 changes: 24 additions & 57 deletions avr/cores/megacommand/A4/A4.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,83 +152,50 @@ void A4Class::requestGlobalX(uint8_t global) {
sendRequest(A4_GLOBALX_REQUEST_ID, global);
}

bool A4Class::getBlockingSound(uint8_t sound, uint16_t timeout) {
SysexCallback cb;
A4SysexListener.addOnSoundMessageCallback(
&cb, (sysex_callback_ptr_t)&SysexCallback::onSysexReceived);
requestSound(sound);
connected = cb.waitBlocking(timeout);
A4SysexListener.removeOnSoundMessageCallback(&cb);
bool A4Class::getBlockingGeneric(uint16_t timeout) {
SysexCallback cb;
A4SysexListener.addOnMessageCallback(&cb, (sysex_callback_ptr_t)&SysexCallback::onSysexReceived);
bool connected = cb.waitBlocking(timeout);
A4SysexListener.removeOnMessageCallback(&cb);
return connected;
}

return connected;
bool A4Class::getBlockingSound(uint8_t sound, uint16_t timeout) {
requestSound(sound);
return getBlockingGeneric(timeout);
}

bool A4Class::getBlockingSettings(uint8_t settings, uint16_t timeout) {
SysexCallback cb;
A4SysexListener.addOnSettingsMessageCallback(
&cb, (sysex_callback_ptr_t)&SysexCallback::onSysexReceived);
requestSettings(settings);
connected = cb.waitBlocking(timeout);
A4SysexListener.removeOnSettingsMessageCallback(&cb);

return connected;
requestSettings(settings);
return getBlockingGeneric(timeout);
}

bool A4Class::getBlockingKitX(uint8_t kit, uint16_t timeout) {
SysexCallback cb;
A4SysexListener.addOnKitMessageCallback(
&cb, (sysex_callback_ptr_t)&SysexCallback::onSysexReceived);
requestKitX(kit);
connected = cb.waitBlocking(timeout);
A4SysexListener.removeOnKitMessageCallback(&cb);

return connected;
requestKitX(kit);
return getBlockingGeneric(timeout);
}

bool A4Class::getBlockingPatternX(uint8_t pattern, uint16_t timeout) {
SysexCallback cb;
A4SysexListener.addOnPatternMessageCallback(
&cb, (sysex_callback_ptr_t)&SysexCallback::onSysexReceived);
requestPatternX(pattern);
connected = cb.waitBlocking(timeout);
A4SysexListener.removeOnPatternMessageCallback(&cb);

return connected;
requestPatternX(pattern);
return getBlockingGeneric(timeout);
}

bool A4Class::getBlockingGlobalX(uint8_t global, uint16_t timeout) {
SysexCallback cb;
A4SysexListener.addOnGlobalMessageCallback(
&cb, (sysex_callback_ptr_t)&SysexCallback::onSysexReceived);
requestGlobalX(global);
connected = cb.waitBlocking(timeout);
A4SysexListener.removeOnGlobalMessageCallback(&cb);

return connected;
requestGlobalX(global);
return getBlockingGeneric(timeout);
}

bool A4Class::getBlockingSoundX(uint8_t sound, uint16_t timeout) {
SysexCallback cb;
A4SysexListener.addOnSoundMessageCallback(
&cb, (sysex_callback_ptr_t)&SysexCallback::onSysexReceived);
requestSoundX(sound);
connected = cb.waitBlocking(timeout);
A4SysexListener.removeOnSoundMessageCallback(&cb);

return connected;
requestSoundX(sound);
return getBlockingGeneric(timeout);
}

bool A4Class::getBlockingSettingsX(uint8_t settings, uint16_t timeout) {
SysexCallback cb;
A4SysexListener.addOnSettingsMessageCallback(
&cb, (sysex_callback_ptr_t)&SysexCallback::onSysexReceived);
requestSettingsX(settings);
connected = cb.waitBlocking(timeout);
A4SysexListener.removeOnSettingsMessageCallback(&cb);

return connected;
requestSettingsX(settings);
return getBlockingGeneric(timeout);
}
void A4Class::muteTrack(uint8_t track, bool mute = true, MidiUartParent *uart_ = nullptr) {

void A4Class::muteTrack(uint8_t track, bool mute, MidiUartParent *uart_) {
if (uart_ == nullptr) { uart_ = uart; }
uart->sendCC(track, 94, mute);
}
Expand Down
2 changes: 1 addition & 1 deletion avr/cores/megacommand/A4/A4.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ class A4Class : public ElektronDevice {
}

virtual uint8_t get_mute_cc() { return 0x5E; }

bool getBlockingGeneric(uint16_t timeout);
/*X denotes get from RAM/unsaved */
bool getBlockingKitX(uint8_t kit, uint16_t timeout = 3000);
bool getBlockingPatternX(uint8_t pattern, uint16_t timeout = 3000);
Expand Down
35 changes: 1 addition & 34 deletions avr/cores/megacommand/A4/A4Sysex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,51 +52,18 @@ void A4SysexListenerClass::end() {
// break;

case A4_GLOBAL_MESSAGE_ID:
onGlobalMessageCallbacks.call();
break;

case A4_GLOBALX_MESSAGE_ID:
onGlobalMessageCallbacks.call();
break;

case A4_KIT_MESSAGE_ID:
onKitMessageCallbacks.call();
break;

case A4_KITX_MESSAGE_ID:
onKitMessageCallbacks.call();
break;

case A4_SOUND_MESSAGE_ID:
onSoundMessageCallbacks.call();
break;

case A4_SOUNDX_MESSAGE_ID:
onSoundMessageCallbacks.call();
break;

case A4_PATTERN_MESSAGE_ID:
onPatternMessageCallbacks.call();
break;

case A4_PATTERNX_MESSAGE_ID:
onPatternMessageCallbacks.call();
break;

case A4_SONG_MESSAGE_ID:
onSongMessageCallbacks.call();
break;

case A4_SONGX_MESSAGE_ID:
onSongMessageCallbacks.call();
break;

case A4_SETTINGS_MESSAGE_ID:
onSettingsMessageCallbacks.call();
break;

case A4_SETTINGSX_MESSAGE_ID:
onSettingsMessageCallbacks.call();
onMessageCallbacks.call();
break;
}

Expand Down
26 changes: 0 additions & 26 deletions avr/cores/megacommand/A4/A4Sysex.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,6 @@ class A4SysexListenerClass : public ElektronSysexListenerClass {
**/

public:
CallbackVector<SysexCallback, 8> onSoundMessageCallbacks;

CallbackVector<SysexCallback, 8> onSettingsMessageCallbacks;

/** Stores if the currently received message is a MachineDrum sysex message.
* **/
bool isA4Message;
Expand All @@ -40,28 +36,6 @@ class A4SysexListenerClass : public ElektronSysexListenerClass {
* automatically by the A4Task subsystem though).
**/
void setup(MidiClass *_midi);

void addOnSoundMessageCallback(SysexCallback *obj, sysex_callback_ptr_t func) {
onSoundMessageCallbacks.add(obj, func);
}
void removeOnSoundMessageCallback(SysexCallback *obj, sysex_callback_ptr_t func) {
onSoundMessageCallbacks.remove(obj, func);
}
void removeOnSoundMessageCallback(SysexCallback *obj) {
onSoundMessageCallbacks.remove(obj);
}

void addOnSettingsMessageCallback(SysexCallback *obj, sysex_callback_ptr_t func) {
onSettingsMessageCallbacks.add(obj, func);
}
void removeOnSettingsMessageCallback(SysexCallback *obj,
sysex_callback_ptr_t func) {
onSettingsMessageCallbacks.remove(obj, func);
}
void removeOnSettingsMessageCallback(SysexCallback *obj) {
onSettingsMessageCallbacks.remove(obj);
}

/* @} */
};

Expand Down
18 changes: 11 additions & 7 deletions avr/cores/megacommand/Adafruit-GFX-Library/Adafruit_GFX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,14 +169,15 @@ void Adafruit_GFX::endWrite() {

// (x,y) is topmost point; if unsure, calling function
// should sort endpoints or call drawLine() instead
void Adafruit_GFX::drawFastVLine(int16_t x, int16_t y, int16_t h,
uint16_t color) {
/*
void Adafruit_GFX::drawFastVLine(uint8_t x, uint8_t y, uint8_t h,
uint8_t color) {
// Update in subclasses if desired!
startWrite();
writeLine(x, y, x, y + h - 1, color);
endWrite();
}

*/
// (x,y) is leftmost point; if unsure, calling function
// should sort endpoints or call drawLine() instead
void Adafruit_GFX::drawFastHLine(int16_t x, int16_t y, int16_t w,
Expand All @@ -187,8 +188,8 @@ void Adafruit_GFX::drawFastHLine(int16_t x, int16_t y, int16_t w,
endWrite();
}

void Adafruit_GFX::fillRect(int16_t x, int16_t y, int16_t w, int16_t h,
uint16_t color) {
void Adafruit_GFX::fillRect(uint8_t x, uint8_t y, uint8_t w, uint8_t h,
uint8_t color) {
// Update in subclasses if desired!
startWrite();
for (int16_t i = x; i < x + w; i++) {
Expand Down Expand Up @@ -829,8 +830,11 @@ void Adafruit_GFX::drawChar(int16_t x, int16_t y, unsigned char c,
((y + 8 * size - 1) < 0)) // Clip top
return;

if (!_cp437 && (c >= 176))
c++; // Handle 'classic' charset behavior

c -= 0x20; //Classic font is reduced in lengthand shifted.
if (c > 126) { c = 0; }
//if (!_cp437 && (c >= 176))
// c++; // Handle 'classic' charset behavior

startWrite();
for (int8_t i = 0; i < 5; i++) { // Char bitmap = 5 columns
Expand Down
22 changes: 11 additions & 11 deletions avr/cores/megacommand/Adafruit-GFX-Library/Adafruit_GFX.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ class Adafruit_GFX : public Print {
// These MAY be overridden by the subclass to provide device-specific
// optimized code. Otherwise 'generic' versions are used.
virtual void startWrite(void);
virtual void writePixel(int16_t x, int16_t y, uint16_t color);
virtual void writeFillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
virtual void writeFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color);
void writePixel(int16_t x, int16_t y, uint16_t color);
void writeFillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
void writeFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color);
virtual void writeFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color);
virtual void writeLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color);
virtual void endWrite(void);
Expand All @@ -39,15 +39,15 @@ class Adafruit_GFX : public Print {
// BASIC DRAW API
// These MAY be overridden by the subclass to provide device-specific
// optimized code. Otherwise 'generic' versions are used.
virtual void
// It's good to implement those, even if using transaction API
drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color),
drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color),
fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color),
fillScreen(uint16_t color),

void fillRect(uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint8_t color);
void fillScreen(uint16_t color);
virtual void drawFastVLine(uint8_t x, uint8_t y, uint8_t h, uint8_t color) = 0;
void drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color);

void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color);
// Optional and probably not necessary to change
drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color),
drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
void drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);

// These exist only with Adafruit_GFX (no subclass overrides)
void
Expand Down
Loading

0 comments on commit 53e4278

Please sign in to comment.