diff options
author | William McPherson <willmcpherson2@gmail.com> | 2020-02-07 00:32:46 +1100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-02-06 19:13:53 +0100 |
commit | b7d190bd108cf9f67abb2181e36ede0a3218c597 (patch) | |
tree | e6fe80a3a23c0d27a15389b30ee4f345f53b299c /Applications | |
parent | 5dc014b26106259a03b16310da5d9f3cdf3a10c3 (diff) | |
download | serenity-b7d190bd108cf9f67abb2181e36ede0a3218c597.zip |
Piano: Add export action
This is a pretty rudimentary WAV export function for Piano.
Diffstat (limited to 'Applications')
-rw-r--r-- | Applications/Piano/AudioEngine.cpp | 18 | ||||
-rw-r--r-- | Applications/Piano/AudioEngine.h | 1 | ||||
-rw-r--r-- | Applications/Piano/main.cpp | 30 |
3 files changed, 49 insertions, 0 deletions
diff --git a/Applications/Piano/AudioEngine.cpp b/Applications/Piano/AudioEngine.cpp index 8eec8938d8..c3ada8eb28 100644 --- a/Applications/Piano/AudioEngine.cpp +++ b/Applications/Piano/AudioEngine.cpp @@ -125,6 +125,24 @@ void AudioEngine::fill_buffer(FixedArray<Sample>& buffer) swap(m_front_buffer_ptr, m_back_buffer_ptr); } +void AudioEngine::reset() +{ + memset(m_front_buffer.data(), 0, buffer_size); + memset(m_back_buffer.data(), 0, buffer_size); + m_front_buffer_ptr = &m_front_buffer; + m_back_buffer_ptr = &m_back_buffer; + + m_delay_buffers.clear(); + + memset(m_note_on, 0, sizeof(m_note_on)); + memset(m_power, 0, sizeof(m_power)); + memset(m_envelope, 0, sizeof(m_envelope)); + + m_time = 0; + m_current_column = 0; + m_previous_column = horizontal_notes - 1; +} + // All of the information for these waves is on Wikipedia. double AudioEngine::sine(size_t note) diff --git a/Applications/Piano/AudioEngine.h b/Applications/Piano/AudioEngine.h index e722e0cfd0..72d3e17a13 100644 --- a/Applications/Piano/AudioEngine.h +++ b/Applications/Piano/AudioEngine.h @@ -40,6 +40,7 @@ public: ~AudioEngine(); const FixedArray<Sample>& buffer() const { return *m_front_buffer_ptr; } + void reset(); Switch roll_note(int y, int x) const { return m_roll_notes[y][x]; } int current_column() const { return m_current_column; } int octave() const { return m_octave; } diff --git a/Applications/Piano/main.cpp b/Applications/Piano/main.cpp index 4be57b21c2..18b0e3d02e 100644 --- a/Applications/Piano/main.cpp +++ b/Applications/Piano/main.cpp @@ -28,11 +28,14 @@ #include "AudioEngine.h" #include "MainWidget.h" #include <LibAudio/ClientConnection.h> +#include <LibAudio/WavWriter.h> #include <LibCore/File.h> #include <LibGUI/GAboutDialog.h> #include <LibGUI/GAction.h> #include <LibGUI/GApplication.h> +#include <LibGUI/GFilePicker.h> #include <LibGUI/GMenuBar.h> +#include <LibGUI/GMessageBox.h> #include <LibGUI/GWindow.h> #include <LibThread/Thread.h> @@ -53,6 +56,10 @@ int main(int argc, char** argv) window->set_icon(Gfx::Bitmap::load_from_file("/res/icons/16x16/app-piano.png")); window->show(); + Audio::WavWriter wav_writer; + Optional<String> save_path; + bool need_to_write_wav = false; + LibThread::Thread audio_thread([&] { auto audio = Core::File::construct("/dev/audio"); if (!audio->open(Core::IODevice::WriteOnly)) { @@ -66,6 +73,17 @@ int main(int argc, char** argv) audio->write(reinterpret_cast<u8*>(buffer.data()), buffer_size); Core::EventLoop::current().post_event(*main_widget, make<Core::CustomEvent>(0)); Core::EventLoop::wake(); + + if (need_to_write_wav) { + need_to_write_wav = false; + audio_engine.reset(); + while (audio_engine.current_column() < horizontal_notes - 1) { + audio_engine.fill_buffer(buffer); + wav_writer.write_samples(reinterpret_cast<u8*>(buffer.data()), buffer_size); + } + audio_engine.reset(); + wav_writer.finalize(); + } } }); audio_thread.start(); @@ -77,6 +95,18 @@ int main(int argc, char** argv) GUI::Application::the().quit(0); return; })); + app_menu->add_action(GUI::Action::create("Export", { Mod_Ctrl, Key_E }, [&](const GUI::Action&) { + save_path = GUI::FilePicker::get_save_filepath("Untitled", "wav"); + if (!save_path.has_value()) + return; + wav_writer.set_file(save_path.value()); + if (wav_writer.has_error()) { + GUI::MessageBox::show(String::format("Failed to export WAV file: %s", wav_writer.error_string()), "Error", GUI::MessageBox::Type::Error); + wav_writer.clear_error(); + return; + } + need_to_write_wav = true; + })); menubar->add_menu(move(app_menu)); auto help_menu = GUI::Menu::construct("Help"); |