summaryrefslogtreecommitdiff
path: root/Applications
diff options
context:
space:
mode:
authorWilliam McPherson <willmcpherson2@gmail.com>2020-02-05 01:36:30 +1100
committerAndreas Kling <kling@serenityos.org>2020-02-05 17:52:10 +0100
commit421a34057296fd268a58c9733dca91c96d39219a (patch)
treedb3099c627f896f20c0a0301ade2c4547cd2e83b /Applications
parent44c81ee9db453c824ed98f697bd67d661b4ee636 (diff)
downloadserenity-421a34057296fd268a58c9733dca91c96d39219a.zip
Piano: Make decay more accurate
1. Make decay sample-granular rather than buffer-granular You only have ~43 buffers per second which can make a jagged signal. 2. Calculate decay in milliseconds Decay is supposed to be a time value.
Diffstat (limited to 'Applications')
-rw-r--r--Applications/Piano/AudioEngine.cpp28
-rw-r--r--Applications/Piano/AudioEngine.h3
-rw-r--r--Applications/Piano/KnobsWidget.cpp2
3 files changed, 21 insertions, 12 deletions
diff --git a/Applications/Piano/AudioEngine.cpp b/Applications/Piano/AudioEngine.cpp
index 15fe0ac609..3378ebaf07 100644
--- a/Applications/Piano/AudioEngine.cpp
+++ b/Applications/Piano/AudioEngine.cpp
@@ -31,6 +31,7 @@
AudioEngine::AudioEngine()
{
+ set_decay(0);
}
AudioEngine::~AudioEngine()
@@ -45,6 +46,11 @@ void AudioEngine::fill_buffer(FixedArray<Sample>& buffer)
for (size_t note = 0; note < note_count; ++note) {
if (!m_note_on[note])
continue;
+
+ m_power[note] -= m_decay_step;
+ if (m_power[note] < 0)
+ m_power[note] = 0;
+
double val = 0;
switch (m_wave) {
case Wave::Sine:
@@ -70,16 +76,6 @@ void AudioEngine::fill_buffer(FixedArray<Sample>& buffer)
buffer[i].right = buffer[i].left;
}
- if (m_decay) {
- for (size_t note = 0; note < note_count; ++note) {
- if (m_note_on[note]) {
- m_power[note] -= m_decay / 100.0;
- if (m_power[note] < 0)
- m_power[note] = 0;
- }
- }
- }
-
if (m_delay) {
if (m_delay_buffers.size() >= m_delay) {
auto to_blend = m_delay_buffers.dequeue();
@@ -201,10 +197,22 @@ void AudioEngine::set_wave(Direction direction)
}
}
+static inline double calculate_step(double distance, int milliseconds)
+{
+ if (milliseconds == 0)
+ return distance;
+
+ constexpr double samples_per_millisecond = sample_rate / 1000.0;
+ double samples = milliseconds * samples_per_millisecond;
+ double step = distance / samples;
+ return step;
+}
+
void AudioEngine::set_decay(int decay)
{
ASSERT(decay >= 0);
m_decay = decay;
+ m_decay_step = calculate_step(1, m_decay);
}
void AudioEngine::set_delay(int delay)
diff --git a/Applications/Piano/AudioEngine.h b/Applications/Piano/AudioEngine.h
index 14280a716f..4f5bdc1585 100644
--- a/Applications/Piano/AudioEngine.h
+++ b/Applications/Piano/AudioEngine.h
@@ -77,7 +77,8 @@ private:
int m_octave { 4 };
int m_wave { first_wave };
- int m_decay { 0 };
+ int m_decay;
+ double m_decay_step;
int m_delay { 0 };
int m_time { 0 };
diff --git a/Applications/Piano/KnobsWidget.cpp b/Applications/Piano/KnobsWidget.cpp
index 4ec786ebad..caa9c40cec 100644
--- a/Applications/Piano/KnobsWidget.cpp
+++ b/Applications/Piano/KnobsWidget.cpp
@@ -91,7 +91,7 @@ KnobsWidget::KnobsWidget(GUI::Widget* parent, AudioEngine& audio_engine, MainWid
m_wave_value->set_text(wave_strings[new_wave]);
};
- constexpr int max_decay = 20;
+ constexpr int max_decay = 1000;
m_decay_knob = GUI::Slider::construct(Orientation::Vertical, m_knobs_container);
m_decay_knob->set_range(0, max_decay);
m_decay_knob->set_value(max_decay - m_audio_engine.decay());