4 1.0f - 0.6f * kBlackKeyWidthRatio,
5 2.0f - 0.4f * kBlackKeyWidthRatio,
6 4.0f - 0.7f * kBlackKeyWidthRatio,
7 5.0f - 0.5f * kBlackKeyWidthRatio,
8 6.0f - 0.3f * kBlackKeyWidthRatio,
12 true,
false,
true,
false,
true,
true,
false,
true,
false,
true,
false,
true
16 int getBlackKeyOctaveOffset(
int black_key_index) {
19 if (black_key_index == 0)
28 int getWhiteKeyOctaveOffset(
int white_key_index) {
31 if (white_key_index == 0)
40 int getBlackKeyIndexFromOffset(
int note_offset) {
41 int black_key_index = 0;
42 for (
int i = 0; i < note_offset; ++i) {
46 return black_key_index;
49 int getWhiteKeyIndexFromOffset(
int note_offset) {
50 int white_key_index = 0;
51 for (
int i = 0; i < note_offset; ++i) {
55 return white_key_index;
60 OpenGlComponent(
"keyboard"), state_(state), midi_channel_(1), hover_note_(-1),
61 black_notes_(kNumBlackKeys,
Shaders::kRoundedRectangleFragment),
62 white_pressed_notes_(kNumWhiteKeys,
Shaders::kRoundedRectangleFragment),
63 black_pressed_notes_(kNumBlackKeys,
Shaders::kRoundedRectangleFragment),
64 hover_note_quad_(
Shaders::kRoundedRectangleFragment) {
69 hover_note_quad_.
setQuad(0, -2.0f, -2.0f, 0.0f, 0.0f);
71 int num_children = getNumChildComponents();
73 for (
int i = 0; i < num_children; ++i) {
74 Component* child = getChildComponent(i);
75 child->setWantsKeyboardFocus(
false);
80 float width = getWidth();
81 int height = getHeight();
82 g.setColour(black_key_color_);
85 g.fillRect(x, 0, 1, height);
94 if (findParentComponentOfClass<SynthGuiInterface>() ==
nullptr)
107 float width = getWidth();
108 float height = getHeight();
110 float black_key_y = 1.0f - black_key_height;
112 float black_key_width = (((int)(
kBlackKeyWidthRatio * white_key_width * width / 4.0f)) * 4.0f + 2.0f) / width;
119 float x = -1.0f + octave_width * octave +
kBlackKeyOffsets[index] * white_key_width;
120 x = ((int)((x + 1.0f) * width / 2.0f)) * 2.0f / width - 1.0f;
121 black_notes_.
setQuad(i, x, black_key_y, black_key_width, black_key_height + 0.5f);
131 float white_key_position =
kNumWhiteKeys * position.x / getWidth();
139 if (note_offset <= kBlackKeyWidthRatio && note_offset >= 0.0f) {
155 float velocity = position.y / getHeight();
159 return std::max(kMinVelocity, std::min(1.0f, velocity));
165 hover_note_quad_.
setColor(hover_color_);
166 int hover_note = hover_note_;
169 if (hover_note >= 0) {
174 setWhiteKeyQuad(&hover_note_quad_, 0, index);
175 hover_note_quad_.
render(open_gl, animate);
179 setBlackKeyQuad(&hover_note_quad_, 0, index);
183 white_pressed_notes_.
setColor(key_press_color_);
184 white_pressed_notes_.
render(open_gl, animate);
186 black_notes_.
setColor(black_key_color_);
187 black_notes_.
render(open_gl, animate);
189 if (hover_note >= 0 && !
isWhiteKey(hover_note))
190 hover_note_quad_.
render(open_gl, animate);
192 black_pressed_notes_.
setColor(key_press_color_);
193 black_pressed_notes_.
render(open_gl, animate);
197 int num_pressed_white_keys = 0;
198 int num_pressed_black_keys = 0;
199 int white_key_index = 0;
200 int black_key_index = 0;
203 if (state_.isNoteOnForChannels(0xffff, i)) {
205 setWhiteKeyQuad(&white_pressed_notes_, num_pressed_white_keys, white_key_index);
206 num_pressed_white_keys++;
209 setBlackKeyQuad(&black_pressed_notes_, num_pressed_black_keys, black_key_index);
210 num_pressed_black_keys++;
220 white_pressed_notes_.
setNumQuads(num_pressed_white_keys);
221 black_pressed_notes_.
setNumQuads(num_pressed_black_keys);
224void MidiKeyboard::setWhiteKeyQuad(
OpenGlMultiQuad* quads,
int quad_index,
int white_key_index) {
225 float full_width = getWidth();
226 int start_x = white_key_index * full_width /
kNumWhiteKeys + 1;
227 int end_x = (white_key_index + 1) * full_width /
kNumWhiteKeys;
228 float x = 2.0f * start_x / full_width - 1.0f;
229 float width = 2.0f * (end_x - start_x) / full_width;
231 quads->
setQuad(quad_index, x, -2.0f, width, 4.0f);
234void MidiKeyboard::setBlackKeyQuad(
OpenGlMultiQuad* quads,
int quad_index,
int black_key_index) {
235 float x = black_notes_.
getQuadX(black_key_index);
236 float y = black_notes_.
getQuadY(black_key_index);
237 float width = black_notes_.
getQuadWidth(black_key_index);
239 float border = 2.0f / getWidth();
240 float y_adjust = 2.0f / getHeight();
242 quads->
setQuad(quad_index, x + border, y + y_adjust, width - 2.0f * border, height);
static const float kBlackKeyOffsets[]
Horizontal offsets for black keys relative to white keys, per octave.
Definition midi_keyboard.h:3
void parentHierarchyChanged() override
Called when the parent hierarchy changes.
Definition midi_keyboard.cpp:89
float getVelocityForNote(int midi, Point< float > position)
Calculates the note velocity based on vertical mouse click position.
Definition midi_keyboard.cpp:152
static constexpr int kNumBlackKeysPerOctave
Number of black keys per octave.
Definition midi_keyboard.h:41
static const bool kWhiteKeys[]
Array indicating which notes (semitones) in an octave are white keys.
Definition midi_keyboard.h:11
int getNoteAtPosition(Point< float > position)
Determines the MIDI note at a given mouse position.
Definition midi_keyboard.cpp:130
static force_inline bool isWhiteKey(int midi)
Determines if a given MIDI note number corresponds to a white key.
Definition midi_keyboard.h:53
void paintBackground(Graphics &g) override
Paints any background elements of the keyboard, typically key boundaries.
Definition midi_keyboard.cpp:79
void setPressedKeyPositions()
Updates which keys are displayed as pressed according to the current MidiKeyboardState.
Definition midi_keyboard.cpp:196
static constexpr int kNumWhiteKeys
Total number of white keys across the entire MIDI range.
Definition midi_keyboard.h:35
void setColors()
Updates the color scheme of the keys.
Definition midi_keyboard.cpp:93
void resized() override
Called when the component is resized.
Definition midi_keyboard.cpp:103
static constexpr int kNumWhiteKeysPerOctave
Number of white keys per octave.
Definition midi_keyboard.h:37
bool isBlackKeyHeight(Point< float > position)
Checks if a given position falls within the vertical range of a black key.
Definition midi_keyboard.h:95
void render(OpenGlWrapper &open_gl, bool animate) override
Renders the keyboard and its keys using OpenGL.
Definition midi_keyboard.cpp:162
static constexpr float kBlackKeyWidthRatio
Horizontal ratio of the black key width relative to white keys.
Definition midi_keyboard.h:46
static constexpr float kBlackKeyHeightRatio
Ratio of keyboard height covered by black keys.
Definition midi_keyboard.h:44
static constexpr int kNumBlackKeys
Total number of black keys across the entire MIDI range.
Definition midi_keyboard.h:39
MidiKeyboard(MidiKeyboardState &state)
Constructs the MidiKeyboard component.
Definition midi_keyboard.cpp:59
A base component class that integrates JUCE's Component with OpenGL rendering.
Definition open_gl_component.h:20
virtual void resized() override
Called when the component is resized.
Definition open_gl_component.cpp:121
float findValue(Skin::ValueId value_id)
Finds a float value from the skin associated with this component's parent.
Definition open_gl_component.cpp:173
A component for rendering multiple quads using OpenGL, with customizable colors, rounding,...
Definition open_gl_multi_quad.h:16
void setQuad(int i, float x, float y, float w, float h)
Sets the position and size of a quad in normalized device space.
Definition open_gl_multi_quad.h:313
force_inline float getQuadHeight(int i) const
Gets the height of the specified quad.
Definition open_gl_multi_quad.h:199
void setTargetComponent(Component *target_component)
Sets a target component to help position the quads.
Definition open_gl_multi_quad.h:358
void setNumQuads(int num_quads)
Sets how many quads will actually be drawn (up to max_quads).
Definition open_gl_multi_quad.h:92
virtual void render(OpenGlWrapper &open_gl, bool animate) override
Renders the quads using OpenGL.
Definition open_gl_multi_quad.cpp:92
force_inline void setColor(Colour color)
Sets the base color for the quads.
Definition open_gl_multi_quad.h:102
force_inline float getQuadWidth(int i) const
Gets the width of the specified quad.
Definition open_gl_multi_quad.h:191
void setRounding(float rounding)
Sets the rounding radius of the quads.
Definition open_gl_multi_quad.h:347
force_inline float getQuadY(int i) const
Gets the y-position of a specified quad.
Definition open_gl_multi_quad.h:183
force_inline float getQuadX(int i) const
Gets the x-position of a specified quad.
Definition open_gl_multi_quad.h:175
Manages and provides access to vertex and fragment shaders used by the OpenGL rendering pipeline.
Definition shaders.h:19
@ kWidgetRoundedCorner
Definition skin.h:104
@ kWidgetPrimary1
Definition skin.h:165
@ kWidgetSecondary1
Definition skin.h:168
@ kWidgetSecondary2
Definition skin.h:169
@ kWidgetAccent2
Definition skin.h:172
constexpr int kNotesPerOctave
Number of semitones per octave.
Definition common.h:51
constexpr int kMidiSize
MIDI note count (0-127).
Definition common.h:44
A helper struct containing references to OpenGL context, shaders, and display scale.
Definition shaders.h:174