mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 01:17:34 +00:00
Piano: Add triangle wave and noise
The squad is complete :^) You can find the equation for the triangle wave here: https://en.wikipedia.org/wiki/Triangle_wave We're using this one: |x mod 4 - 2| - 1 Modifications have been made to correct the frequency and phase: |(4x + 1) mod 4 - 2| - 1 The white noise is generated by calling rand() and dividing it by RAND_MAX to get a value from 0 to 1. Then it's adjusted to fit between -1 and 1.
This commit is contained in:
parent
091c783626
commit
69d05fbf44
3 changed files with 38 additions and 1 deletions
|
@ -9,7 +9,7 @@ struct Sample {
|
||||||
i16 right;
|
i16 right;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum WaveType { Sine, Saw, Square, InvalidWave };
|
enum WaveType { Sine, Saw, Square, Triangle, Noise, InvalidWave };
|
||||||
|
|
||||||
enum PianoKey {
|
enum PianoKey {
|
||||||
K_None,
|
K_None,
|
||||||
|
|
|
@ -32,6 +32,10 @@ void PianoWidget::paint_event(GPaintEvent& event)
|
||||||
wave_color = Color(240, 100, 128);
|
wave_color = Color(240, 100, 128);
|
||||||
else if (m_wave_type == WaveType::Square)
|
else if (m_wave_type == WaveType::Square)
|
||||||
wave_color = Color(128, 160, 255);
|
wave_color = Color(128, 160, 255);
|
||||||
|
else if (m_wave_type == WaveType::Triangle)
|
||||||
|
wave_color = Color(35, 171, 35);
|
||||||
|
else if (m_wave_type == WaveType::Noise)
|
||||||
|
wave_color = Color(197, 214, 225);
|
||||||
|
|
||||||
int prev_x = 0;
|
int prev_x = 0;
|
||||||
int prev_y = m_height / 2;
|
int prev_y = m_height / 2;
|
||||||
|
@ -70,6 +74,10 @@ void PianoWidget::fill_audio_buffer(uint8_t* stream, int len)
|
||||||
val = ((volume * m_power[n]) * w_saw(n));
|
val = ((volume * m_power[n]) * w_saw(n));
|
||||||
else if (m_wave_type == WaveType::Square)
|
else if (m_wave_type == WaveType::Square)
|
||||||
val = ((volume * m_power[n]) * w_square(n));
|
val = ((volume * m_power[n]) * w_square(n));
|
||||||
|
else if (m_wave_type == WaveType::Triangle)
|
||||||
|
val = ((volume * m_power[n]) * w_triangle(n));
|
||||||
|
else if (m_wave_type == WaveType::Noise)
|
||||||
|
val = ((volume * m_power[n]) * w_noise());
|
||||||
if (sst[i].left == 0)
|
if (sst[i].left == 0)
|
||||||
sst[i].left = val;
|
sst[i].left = val;
|
||||||
else
|
else
|
||||||
|
@ -147,6 +155,20 @@ double PianoWidget::w_square(size_t n)
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double PianoWidget::w_triangle(size_t n)
|
||||||
|
{
|
||||||
|
double triangle_step = note_frequency[n] / 44100.0;
|
||||||
|
double t = m_triangle_pos[n];
|
||||||
|
double w = fabs(fmod((4 * t) + 1, 4) - 2) - 1;
|
||||||
|
m_triangle_pos[n] += triangle_step;
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
|
||||||
|
double PianoWidget::w_noise()
|
||||||
|
{
|
||||||
|
return (((double)rand() / RAND_MAX) * 2.0) - 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
int PianoWidget::octave_base() const
|
int PianoWidget::octave_base() const
|
||||||
{
|
{
|
||||||
return (m_octave - m_octave_min) * 12;
|
return (m_octave - m_octave_min) * 12;
|
||||||
|
@ -393,6 +415,14 @@ void PianoWidget::render_knobs(GPainter& painter)
|
||||||
r = 128;
|
r = 128;
|
||||||
g = 160;
|
g = 160;
|
||||||
b = 255;
|
b = 255;
|
||||||
|
} else if (m_wave_type == WaveType::Triangle) {
|
||||||
|
r = 35;
|
||||||
|
g = 171;
|
||||||
|
b = 35;
|
||||||
|
} else if (m_wave_type == WaveType::Noise) {
|
||||||
|
r = 197;
|
||||||
|
g = 214;
|
||||||
|
b = 225;
|
||||||
}
|
}
|
||||||
Rect wave_knob_rect(m_width - knob_width - 16 - knob_width - 16, m_height - 30, knob_width, 16);
|
Rect wave_knob_rect(m_width - knob_width - 16 - knob_width - 16, m_height - 30, knob_width, 16);
|
||||||
const char* wave_name = "";
|
const char* wave_name = "";
|
||||||
|
@ -402,6 +432,10 @@ void PianoWidget::render_knobs(GPainter& painter)
|
||||||
wave_name = "C: Sawtooth";
|
wave_name = "C: Sawtooth";
|
||||||
else if (m_wave_type == WaveType::Square)
|
else if (m_wave_type == WaveType::Square)
|
||||||
wave_name = "C: Square ";
|
wave_name = "C: Square ";
|
||||||
|
else if (m_wave_type == WaveType::Triangle)
|
||||||
|
wave_name = "C: Triangle";
|
||||||
|
else if (m_wave_type == WaveType::Noise)
|
||||||
|
wave_name = "C: Noise ";
|
||||||
painter.draw_rect(wave_knob_rect, Color(r, g, b));
|
painter.draw_rect(wave_knob_rect, Color(r, g, b));
|
||||||
painter.draw_text(wave_knob_rect, wave_name, TextAlignment::Center, Color(r, g, b));
|
painter.draw_text(wave_knob_rect, wave_name, TextAlignment::Center, Color(r, g, b));
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,8 @@ private:
|
||||||
double w_sine(size_t);
|
double w_sine(size_t);
|
||||||
double w_saw(size_t);
|
double w_saw(size_t);
|
||||||
double w_square(size_t);
|
double w_square(size_t);
|
||||||
|
double w_triangle(size_t);
|
||||||
|
double w_noise();
|
||||||
|
|
||||||
Rect define_piano_key_rect(int index, PianoKey) const;
|
Rect define_piano_key_rect(int index, PianoKey) const;
|
||||||
PianoKey find_key_for_relative_position(int x, int y) const;
|
PianoKey find_key_for_relative_position(int x, int y) const;
|
||||||
|
@ -49,6 +51,7 @@ private:
|
||||||
double m_sin_pos[note_count];
|
double m_sin_pos[note_count];
|
||||||
double m_square_pos[note_count];
|
double m_square_pos[note_count];
|
||||||
double m_saw_pos[note_count];
|
double m_saw_pos[note_count];
|
||||||
|
double m_triangle_pos[note_count];
|
||||||
|
|
||||||
int m_octave_min { 1 };
|
int m_octave_min { 1 };
|
||||||
int m_octave_max { 6 };
|
int m_octave_max { 6 };
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue