mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 10:38:11 +00:00
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
This commit is contained in:
parent
ddefb95b21
commit
4a36a51618
17 changed files with 1647 additions and 762 deletions
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* Copyright (c) 2019-2020, William McPherson <willmcpherson2@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -24,8 +25,8 @@
|
|||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "Music.h"
|
||||
#include "PianoWidget.h"
|
||||
#include "AudioEngine.h"
|
||||
#include "MainWidget.h"
|
||||
#include <LibAudio/AClientConnection.h>
|
||||
#include <LibCore/CFile.h>
|
||||
#include <LibDraw/PNGLoader.h>
|
||||
|
@ -39,34 +40,36 @@
|
|||
int main(int argc, char** argv)
|
||||
{
|
||||
GApplication app(argc, argv);
|
||||
|
||||
auto audio_client = AClientConnection::construct();
|
||||
audio_client->handshake();
|
||||
|
||||
AudioEngine audio_engine;
|
||||
|
||||
auto window = GWindow::construct();
|
||||
auto main_widget = MainWidget::construct(audio_engine);
|
||||
window->set_main_widget(main_widget);
|
||||
window->set_title("Piano");
|
||||
window->set_rect(100, 100, 512, 512);
|
||||
|
||||
auto piano_widget = PianoWidget::construct();
|
||||
window->set_main_widget(piano_widget);
|
||||
window->show();
|
||||
window->set_rect(90, 90, 840, 600);
|
||||
window->set_icon(load_png("/res/icons/16x16/app-piano.png"));
|
||||
window->show();
|
||||
|
||||
LibThread::Thread sound_thread([piano_widget = piano_widget.ptr()] {
|
||||
LibThread::Thread audio_thread([&] {
|
||||
auto audio = CFile::construct("/dev/audio");
|
||||
if (!audio->open(CIODevice::WriteOnly)) {
|
||||
dbgprintf("Can't open audio device: %s", audio->error_string());
|
||||
return 1;
|
||||
}
|
||||
|
||||
FixedArray<Sample> buffer(sample_count);
|
||||
for (;;) {
|
||||
u8 buffer[4096];
|
||||
piano_widget->fill_audio_buffer(buffer, sizeof(buffer));
|
||||
audio->write(buffer, sizeof(buffer));
|
||||
CEventLoop::current().post_event(*piano_widget, make<CCustomEvent>(0));
|
||||
audio_engine.fill_buffer(buffer);
|
||||
audio->write(reinterpret_cast<u8*>(buffer.data()), buffer_size);
|
||||
CEventLoop::current().post_event(*main_widget, make<CCustomEvent>(0));
|
||||
CEventLoop::wake();
|
||||
}
|
||||
});
|
||||
sound_thread.start();
|
||||
audio_thread.start();
|
||||
|
||||
auto menubar = make<GMenuBar>();
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue