Skip to content

Commit

Permalink
MIDI inputs working again. Highlight keys when not on message arrives…
Browse files Browse the repository at this point in the history
… at MIDI input. Version 0.9.8.
  • Loading branch information
hsstraub committed Dec 18, 2020
1 parent bc4423f commit ade0191
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 18 deletions.
31 changes: 27 additions & 4 deletions Source/AllKeysOverview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,25 +42,34 @@ KeyMiniDisplayInsideAllKeysOverview::KeyMiniDisplayInsideAllKeysOverview(int new
boardIndex = newBoardIndex;
keyIndex = newKeyIndex;

TerpstraSysExApplication::getApp().getMidiDriver().addListener(this);
}

KeyMiniDisplayInsideAllKeysOverview::~KeyMiniDisplayInsideAllKeysOverview()
{
TerpstraSysExApplication::getApp().getMidiDriver().removeListener(this);
}

void KeyMiniDisplayInsideAllKeysOverview::paint(Graphics& g)
{
jassert(getParentComponent() != nullptr);
bool boardIsSelected = boardIndex == dynamic_cast<AllKeysOverview*>(getParentComponent())->getCurrentSetSelection();

Colour hexagonColour = findColour(TerpstraKeyEdit::backgroundColourId).overlaidWith(getKeyColour()
.withAlpha(boardIsSelected ? TERPSTRASINGLEKEYCOLOURALPHA : TERPSTRASINGLEKEYCOLOURUNSELECTEDMINIALPHA));
// ToDo if highlighted: even different alpha?
float hexagonInteriorAlpha;
if (isHighlighted)
hexagonInteriorAlpha = TERPSTRASINGLEKEYCOLOURHIGHLIGHTEDALPHA;
else if (boardIsSelected)
hexagonInteriorAlpha = TERPSTRASINGLEKEYCOLOURALPHA;
else
hexagonInteriorAlpha = TERPSTRASINGLEKEYCOLOURUNSELECTEDMINIALPHA;

Colour hexagonColour = findColour(TerpstraKeyEdit::backgroundColourId).overlaidWith(
getKeyColour().withAlpha(hexagonInteriorAlpha));
g.setColour(hexagonColour);
g.fillPath(hexPath);

// Key highlighted or not: color and thickness of the line
float lineWidth = isHighlighted ? 1.5 : 1;
float lineWidth = isHighlighted ? 2 : 1;
Colour lineColour = findColour(isHighlighted ? TerpstraKeyEdit::selectedKeyOutlineId : TerpstraKeyEdit::outlineColourId);
g.setColour(lineColour);
g.strokePath(hexPath, PathStrokeType(1));
Expand Down Expand Up @@ -137,6 +146,20 @@ void KeyMiniDisplayInsideAllKeysOverview::mouseUp(const MouseEvent& e)
}
}

void KeyMiniDisplayInsideAllKeysOverview::midiMessageReceived(const MidiMessage& midiMessage)
{
// ToDo If key is parametrized as controller?
if (midiMessage.isNoteOnOrOff())
{
auto keyData = getKeyData();
if (keyData != nullptr && midiMessage.getChannel() == keyData->channelNumber && midiMessage.getNoteNumber() == keyData->noteNumber)
{
isHighlighted = midiMessage.isNoteOn();
repaint();
}
}
}

const TerpstraKey* KeyMiniDisplayInsideAllKeysOverview::getKeyData() const
{
if (boardIndex >= 0 && boardIndex < NUMBEROFBOARDS && keyIndex >= 0 && keyIndex < TERPSTRABOARDSIZE)
Expand Down
9 changes: 8 additions & 1 deletion Source/AllKeysOverview.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,11 @@
#include <JuceHeader.h>

#include "KeyboardDataStructure.h"
#include "TerpstraMidiDriver.h"


// Representation of a key inside the overview
class KeyMiniDisplayInsideAllKeysOverview : public Component
class KeyMiniDisplayInsideAllKeysOverview : public Component, public TerpstraMidiDriver::Listener
{
public:
KeyMiniDisplayInsideAllKeysOverview(int newBoardIndex, int newKeyIndex);
Expand All @@ -37,6 +38,12 @@ class KeyMiniDisplayInsideAllKeysOverview : public Component
void mouseDown(const MouseEvent& e) override;
void mouseUp(const juce::MouseEvent& e) override;

// Implementation of TerpstraNidiDriver::Listener
void midiMessageReceived(const MidiMessage& midiMessage) override;
void midiMessageSent(const MidiMessage& midiMessage) override {}
void midiSendQueueSize(int queueSize) override {}
void generalLogMessage(String textMessage, HajuErrorVisualizer::ErrorLevel errorLevel) override {}

private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(KeyMiniDisplayInsideAllKeysOverview)

Expand Down
2 changes: 1 addition & 1 deletion Source/MidiEditArea.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ void MidiEditArea::comboBoxChanged (juce::ComboBox* comboBoxThatHasChanged)
{
//[UserComboBoxCode_cbMidiInput] -- add your combo box handling code here..
if (cbMidiInput->getSelectedItemIndex() >= 0)
TerpstraSysExApplication::getApp().getMidiDriver().setMidiInput(cbMidiInput->getSelectedItemIndex()+1);
TerpstraSysExApplication::getApp().getMidiDriver().setMidiInput(cbMidiInput->getSelectedItemIndex());

if (cbMidiInput->getSelectedItemIndex() < 0 || cbMidiOutput->getSelectedItemIndex() < 0)
{
Expand Down
32 changes: 21 additions & 11 deletions Source/TerpstraMidiDriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -423,9 +423,11 @@ void TerpstraMidiDriver::sendMessageWithAcknowledge(const MidiMessage& message)
else
{
// Add message to queue first. The oldest message in queue will be sent.
messageBuffer.add(message);
const MessageManagerLock mmLock;
this->listeners.call(&Listener::midiSendQueueSize, messageBuffer.size());
{
messageBuffer.add(message);
const MessageManagerLock mmLock;
this->listeners.call(&Listener::midiSendQueueSize, messageBuffer.size());
}

// If there is no message waiting for acknowledge: send oldest message of queue
if (!isTimerRunning())
Expand All @@ -445,8 +447,10 @@ void TerpstraMidiDriver::sendOldestMessageInQueue()
currentMsgWaitingForAck = messageBuffer[0]; // oldest element in buffer
hasMsgWaitingForAck = true;
messageBuffer.remove(0); // remove from buffer
const MessageManagerLock mmLock;
this->listeners.call(&Listener::midiSendQueueSize, messageBuffer.size());
{
const MessageManagerLock mmLock;
this->listeners.call(&Listener::midiSendQueueSize, messageBuffer.size());
}

sendCurrentMessage();
}
Expand All @@ -460,8 +464,10 @@ void TerpstraMidiDriver::sendCurrentMessage()
sendMessageNow(currentMsgWaitingForAck); // send it

// Notify listeners
const MessageManagerLock mmLock;
this->listeners.call(&Listener::midiMessageSent, currentMsgWaitingForAck);
{
const MessageManagerLock mmLock;
this->listeners.call(&Listener::midiMessageSent, currentMsgWaitingForAck);
}

timerType = waitForAnswer;
startTimer(receiveTimeoutInMilliseconds); // Start waiting for answer
Expand All @@ -470,8 +476,10 @@ void TerpstraMidiDriver::sendCurrentMessage()
void TerpstraMidiDriver::handleIncomingMidiMessage(MidiInput* source, const MidiMessage& message)
{
// Notify listeners
const MessageManagerLock mmLock;
this->listeners.call(&Listener::midiMessageReceived, message);
{
const MessageManagerLock mmLock;
this->listeners.call(&Listener::midiMessageReceived, message);
}

// Check whether received message is an answer to the previously sent one
if (hasMsgWaitingForAck && messageIsResponseToMessage(message, currentMsgWaitingForAck))
Expand Down Expand Up @@ -511,8 +519,10 @@ void TerpstraMidiDriver::timerCallback()
if (timerType == waitForAnswer)
{
// No answer came from MIDI input
const MessageManagerLock mmLock;
this->listeners.call(&Listener::generalLogMessage, "No answer from device", HajuErrorVisualizer::ErrorLevel::error);
{
const MessageManagerLock mmLock;
this->listeners.call(&Listener::generalLogMessage, "No answer from device", HajuErrorVisualizer::ErrorLevel::error);
}

// For now: Remove from buffer, try to send next one
hasMsgWaitingForAck = false;
Expand Down
1 change: 1 addition & 0 deletions Source/ViewConstants.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#define TERPSTRASELECTEDKEYFLDLINEWIDTH 3.0f
#define TERPSTRASINGLEKEYFLDMARGIN 1.5f
#define TERPSTRASINGLEKEYROTATIONANGLE -0.25f
#define TERPSTRASINGLEKEYCOLOURHIGHLIGHTEDALPHA 0.9f
#define TERPSTRASINGLEKEYCOLOURALPHA 0.8f
#define TERPSTRASINGLEKEYCOLOURUNSELECTEDMINIALPHA 0.6f

Expand Down
2 changes: 1 addition & 1 deletion TerpstraSysEx.jucer
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>

<JUCERPROJECT id="oPBJmN" name="LumatoneSetup" projectType="guiapp" version="0.9.7"
<JUCERPROJECT id="oPBJmN" name="LumatoneSetup" projectType="guiapp" version="0.9.8"
bundleIdentifier="HansStraub.Lumatone.LumatoneSetup" includeBinaryInAppConfig="1"
companyName="Hans Straub" headerPath="../../../JUCE/modules"
jucerFormatVersion="1">
Expand Down

0 comments on commit ade0191

Please sign in to comment.