Piano: Add export action

This is a pretty rudimentary WAV export function for Piano.
This commit is contained in:
William McPherson 2020-02-07 00:32:46 +11:00 committed by Andreas Kling
parent 5dc014b261
commit b7d190bd10
3 changed files with 49 additions and 0 deletions

View file

@ -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)

View file

@ -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; }

View file

@ -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");