Commit graph

86 commits

Author SHA1 Message Date
Andreas Kling
0f3e57a6fb LibGUI: Use GUI::Window::set_main_widget<WidgetType>() in clients 2020-03-04 14:26:16 +01:00
Andreas Kling
4697195645 LibGUI: Use set_layout<LayoutType>() in lots of client code 2020-03-04 13:49:48 +01:00
Andreas Kling
a26b63a958 LibGUI: Remove Button& parameter from Button::on_click hook
There was but a single user of this parameter and it's a bit tedious
to write it out every time, so let's get rid of it.
2020-03-03 17:02:38 +01:00
William McPherson
72cbbd5297 Piano: New timing system and zoomable piano roll
This patch allows roll notes to be of different sizes. This necessitates
a new internal representation of time. BPM and time signatures are
mostly implemented but not exposed.

Roll notes are now sample-accurate and the grid is aligned to 60 BPM
4/4. The roll is divided by the time signature raised to some power of
2, giving the musical divisions of (in the case of 4/4) 16, 32, 64 etc.

Before, our timing was derived from the buffer size and we relied on
that to implement delay. Delay has been rewritten to be sample-granular.
It's now exposed as the proper "divisions of a beat".
Something to be wary of is that the last buffer in the loop is also used
for the start of the next loop. In other words, we loop mid-buffer. This
means we write WAVs with a tiny bit of silence due to breaking the loop
after filling half a buffer.

The data structure for the roll is an array of SinglyLinkedLists of
RollNotes. Separating by pitch (via the array layout) makes insertion
much simpler and faster. Using sorted lists (and thus
SinglyLinkedListIterators) to do lookups is very quick as you know the
sample of the next note and can just compare it to the current sample. I
implemented this with HashMaps and the cost of lookups was abysmal. I
also tried a single SinglyLinkedList and the insertion code got even
more complicated than it already is.
2020-02-27 10:21:13 +01:00
Andreas Kling
fbe4081f4b AK: Make Queue use size_t for its size 2020-02-25 14:55:04 +01:00
Andreas Kling
ceec1a7d38 AK: Make Vector use size_t for its size and capacity 2020-02-25 14:52:35 +01:00
Andreas Kling
6c5100b644 LibGUI: Add helper for constructing new TabWidget tabs
This patch adds the following convenience helper:

    auto tab_widget = GUI::TabWidget::construct();
    auto my_widget = tab_widget->add_tab<GUI::Widget>("My tab", ...);

The above is equivalent to:

    auto tab_widget = GUI::TabWidget::construct();
    auto my_widget = GUI::Widget::construct(...);
    tab_widget->add_widget("My tab", my_widget);
2020-02-23 12:27:53 +01:00
Andreas Kling
bfd86c4631 LibGUI: Make GUI::Frame have the 2px sunken container look by default
The overwhelming majority of GUI::Frame users set the same appearance,
so let's just make it the default.
2020-02-23 11:10:52 +01:00
Andreas Kling
3d20da9ee4 Userspace: Use Core::Object::add() when building interfaces 2020-02-23 11:10:52 +01:00
Tibor Nagy
1176167944 Piano: Set step property for ADSR sliders 2020-02-16 21:58:01 +01:00
Andreas Kling
2143da6434 LibGUI: Add forwarding header
This patch adds <LibGUI/Forward.h> and uses it a bunch.
It also dragged various header dependency reduction changes into it.
2020-02-16 09:41:56 +01:00
Andreas Kling
b011ea9962 LibGUI: Reduce menu-related header dependencies 2020-02-15 01:56:30 +01:00
William McPherson
aa149b9330 LibAudio/Piano: Replace floats with doubles
We should default to double-precision so that clients can make the
choice to use float or double.
2020-02-10 14:04:27 +01:00
William McPherson
4ad96df0d4 Piano: Draw stereo waves
Draw two waves in different colors.
2020-02-10 14:04:27 +01:00
William McPherson
93903c8064 Piano: Try to be more stereo-oriented 2020-02-10 14:04:27 +01:00
William McPherson
255edcb525 Piano: Add nice scale factor to WaveWidget 2020-02-10 14:04:27 +01:00
William McPherson
2a66878148 Piano: Ensure WaveWidget paints in-bounds
Letting GUI::Frame::paint_event() cover up your mistakes is tacky :P
2020-02-10 14:04:27 +01:00
William McPherson
60fdc6c9ab Piano: Put reset() with other setters 2020-02-10 14:04:27 +01:00
William McPherson
9997b0dbf5 Piano: Add sampler
This commit adds basic support for importing, viewing and playing WAV
samples at different pitches.

Naming issues:
- We are using the Sample struct from Music.h, but also the Sample
  struct from LibAudio (Audio::Sample). This is a little confusing.

set_recorded_sample() finds the peak sample and then divides all the
samples by that peak to get a guaranteed min/max of -1/1. This is nice
because our other waves are also bound between these values and we can
just do the same stuff. This is why we're using Audio::Sample, because
it uses floats, whereas Music.h's Sample uses i16s. It's a little
annoying that we have to use a mixture of floats and doubles though.

For playback at lower frequencies, we're calculating in-between samples,
rather than just playing samples multiple times. Basically, you get the
current sample and add the difference between the current sample and the
next sample multiplied by the distance from the current sample. This is
like drawing the hypotenuse of a right-angled triangle.
2020-02-10 14:04:27 +01:00
Andreas Kling
6a9cc66b97 LibGUI: Remove leading G from filenames 2020-02-06 20:33:02 +01:00
William McPherson
b7d190bd10 Piano: Add export action
This is a pretty rudimentary WAV export function for Piano.
2020-02-06 19:13:53 +01:00
William McPherson
5dc014b261 Piano: Fix roll playback at startup
This is not a bug currently, since the first column immediately starts
playing at startup and leaves no time for the user to put notes in it.
However, this is needed for exporting.
2020-02-06 19:13:53 +01:00
William McPherson
9a05bbaace Piano: Move piano roll internals to AudioEngine
The piano roll data definitely belongs in AudioEngine along with the
note and time data. Now RollWidget only has GUI information, much like
the other widgets.

Note that this commit exacerbates issue #1158 which is caused by
RollWidget::paint_event().
2020-02-06 19:13:53 +01:00
Andreas Kling
97edc82a26 LibAudio: Remove leading A from filenames 2020-02-06 15:18:03 +01:00
Andreas Kling
d17e23bd27 LibCore: Remove leading C from filenames 2020-02-06 15:04:03 +01:00
Andreas Kling
799b0a4fa8 LibGUI: Rename {H,V}BoxLayout => {Horizontal,Vertical}BoxLayout 2020-02-06 14:44:13 +01:00
Andreas Kling
dccf335d5b LibGUI: Add HorizontalSlider and VerticalSlider convenience classes 2020-02-06 14:43:16 +01:00
Andreas Kling
5c06c32df4 LibGfx: Prefer using Gfx::Bitmap::load_from_file instead of load_png()
Code that just wants to open a Gfx::Bitmap from a file should not be
calling the PNG codec directly.
2020-02-06 13:39:17 +01:00
Andreas Kling
9b87843af1 LibGfx: Unpublish Gfx::Point from global namespace 2020-02-06 13:08:32 +01:00
Andreas Kling
20cfd2a6bf LibGfx: Unpublish Gfx::Rect from global namespace 2020-02-06 13:02:38 +01:00
Andreas Kling
9ac94d393e LibGfx: Rename from LibDraw :^) 2020-02-06 12:04:00 +01:00
Andreas Kling
11580babbf LibDraw: Put all classes in the Gfx namespace
I started adding things to a Draw namespace, but it somehow felt really
wrong seeing Draw::Rect and Draw::Bitmap, etc. So instead, let's rename
the library to LibGfx. :^)
2020-02-06 11:56:38 +01:00
Andreas Kling
92f77864de LibAudio: Put all classes in the Audio namespace and remove leading A 2020-02-06 10:40:02 +01:00
joshua stein
c3a32108b2 Piano: Fix building with clang 2020-02-05 18:39:45 +01:00
William McPherson
1e0d57a13f Piano: Set some nice defaults 2020-02-05 17:52:10 +01:00
William McPherson
59bde64ba6 Piano: Add release
Notice that we are calculating release time according to the level when
the note is turned off rather than the sustain level. Naively using the
sustain level gives very long release times if you turn the note off
during attack, whereas this deterministically gives the same release
time.
2020-02-05 17:52:10 +01:00
William McPherson
ab9475a3f3 Piano: Add attack 2020-02-05 17:52:10 +01:00
William McPherson
5990b3b2e6 Piano: Add sustain 2020-02-05 17:52:10 +01:00
William McPherson
421a340572 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.
2020-02-05 17:52:10 +01:00
William McPherson
44c81ee9db Piano: Remove phony multiple same note playback
I say "phony" because it's not actually playing the same frequency
twice, it's just playing the same frequency at a higher volume. We can
properly implement this later but at the moment it'll get in the way of
our ADSR implementation.
2020-02-05 17:52:10 +01:00
William McPherson
f909095981 Piano: Fix default knob values
Now you can change the defaults in AudioEngine and not be totally
confused.

1. The default for m_octave_knob was actually upside-down.
2. The default for m_decay_knob wasn't respecting AudioEngine.
3. The default for m_delay_knob wasn't respecting AudioEngine.
2020-02-05 17:52:10 +01:00
Andreas Kling
c5bd9d4ed1 LibGUI: Put all classes in the GUI namespace and remove the leading G
This took me a moment. Welcome to the new world of GUI::Widget! :^)
2020-02-02 15:15:33 +01:00
Andreas Kling
2d39da5405 LibCore: Put all classes in the Core namespace and remove the leading C
I've been wanting to do this for a long time. It's time we start being
consistent about how this stuff works.

The new convention is:

- "LibFoo" is a userspace library that provides the "Foo" namespace.

That's it :^) This was pretty tedious to convert and I didn't even
start on LibGUI yet. But it's coming up next.
2020-02-02 15:15:30 +01:00
Andreas Kling
d67da8c101 LibGUI: Add GHBoxLayout and GVBoxLayout convenience classes 2020-02-02 15:09:48 +01:00
William McPherson
4a36a51618 Piano: Rewrite application
Goals:
- Switch to a more typical LibGUI arrangement
- Separate GUI (MainWidget) and audio (AudioEngine)
- Improve on existing features while retaining the same feature set

Improvements:
- Each GUI element is a separate widget
- The wave (WaveWidget) scales with the window
- The piano roll (RollWidget) scales horizontally and scrolls vertically
- The piano (KeysWidget) fits as many notes as possible
- The knobs (KnobsWidget) are now sliders
- All mouse and key events are handled in constant time
- The octave can be changed while playing notes
- The same note can be played with the mouse, keyboard and roll at the
  same time, and the volume of the resulting note is scaled accordingly
- Note frequency constants use the maximum precision available in a
  double
2020-01-31 13:13:04 +01:00
Andreas Kling
94ca55cefd Meta: Add license header to source files
As suggested by Joshua, this commit adds the 2-clause BSD license as a
comment block to the top of every source file.

For the first pass, I've just added myself for simplicity. I encourage
everyone to add themselves as copyright holders of any file they've
added or modified in some significant way. If I've added myself in
error somewhere, feel free to replace it with the appropriate copyright
holder instead.

Going forward, all new source files should include a license header.
2020-01-18 09:45:54 +01:00
Jami Kettunen
74a18c86c9 Applications: Implement some missing MenuBars & AboutDialogs 2019-12-31 01:46:42 +01:00
William McPherson
6cf4468506 Piano: Factor wave rendering to its own function 2019-12-25 16:14:11 +01:00
William McPherson
bc65971df6 Piano: Use switch statements on m_wave_type 2019-12-25 16:14:11 +01:00
William McPherson
e80061c808 Piano: Move m_front_buffer/m_back_buffer off heap 2019-12-25 16:14:11 +01:00