From 2d3937e7919bc59c6dcbc61d10ce7b5c5c0506dd Mon Sep 17 00:00:00 2001 From: scawful Date: Sun, 1 Jan 2023 16:11:44 -0600 Subject: [PATCH] added snes_spc library --- .gitmodules | 6 ++-- CMakeLists.txt | 16 +++++++++ src/CMakeLists.txt | 3 ++ src/app/editor/music_editor.cc | 63 +++++++++++++++++++++++++++++++++- src/app/editor/music_editor.h | 3 ++ src/app/rom.cc | 1 + src/app/spc700/spc700.def | 26 ++++++++++++++ src/lib/snes-spc-arm | 1 - 8 files changed, 114 insertions(+), 5 deletions(-) create mode 100644 src/app/spc700/spc700.def delete mode 160000 src/lib/snes-spc-arm diff --git a/.gitmodules b/.gitmodules index 13b54df6..2cc439c6 100644 --- a/.gitmodules +++ b/.gitmodules @@ -22,6 +22,6 @@ [submodule "src/lib/asar"] path = src/lib/asar url = https://github.com/RPGHacker/asar.git -[submodule "src/lib/snes-spc-arm"] - path = src/lib/snes-spc-arm - url = https://github.com/nathancassano/snes-spc-arm.git +[submodule "src/lib/snes_spc"] + path = src/lib/snes_spc + url = https://github.com/blarggs-audio-libraries/snes_spc.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 47398dda..3a12639b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -45,6 +45,22 @@ endif() add_subdirectory(src/lib/asar/src) include(cmake/asar.cmake) +# snes-spc -------------------------------------------------------------------- +ADD_DEFINITIONS(-DSNES_SPC_EXPORTS) +set(SNES_SPC_SOURCES + "../src/lib/snes_spc/snes_spc/spc.cpp" + "../src/lib/snes_spc/snes_spc/SNES_SPC.cpp" + "../src/lib/snes_spc/snes_spc/SNES_SPC_misc.cpp" + "../src/lib/snes_spc/snes_spc/SNES_SPC_state.cpp" + "../src/lib/snes_spc/snes_spc/SPC_DSP.cpp" + "../src/lib/snes_spc/snes_spc/dsp.cpp" + "../src/lib/snes_spc/snes_spc/SPC_Filter.cpp" + "../src/lib/snes_spc/demo/wave_writer.c" + "../src/lib/snes_spc/demo/demo_util.c" +) +include_directories(src/lib/snes_spc/snes_spc) +ADD_LIBRARY(snes_spc STATIC ${SNES_SPC_SOURCES} src/app/spc700/spc700.def) + # ImGui ----------------------------------------------------------------------- include(cmake/imgui.cmake) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index dbc43580..5624947c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -53,6 +53,7 @@ add_executable( ${YAZE_APP_ZELDA3_SRC} ${YAZE_GUI_SRC} ${ASAR_STATIC_SRC} + ${SNES_SPC_SOURCES} ${IMGUI_SRC} ) @@ -67,6 +68,7 @@ target_include_directories( ${SDL2_INCLUDE_DIR} ${GLEW_INCLUDE_DIRS} lib/asar/src/asar/ + lib/snes_spc/snes_spc/ ) set(SDL_TARGETS SDL2::SDL2) @@ -87,6 +89,7 @@ target_link_libraries( ${OPENGL_LIBRARIES} ${CMAKE_DL_LIBS} asar-static + snes_spc ImGui ) diff --git a/src/app/editor/music_editor.cc b/src/app/editor/music_editor.cc index 78689ff9..7918c87c 100644 --- a/src/app/editor/music_editor.cc +++ b/src/app/editor/music_editor.cc @@ -1,13 +1,68 @@ #include "music_editor.h" +#include + +#include "absl/strings/str_format.h" +#include "app/editor/assembly_editor.h" +#include "gui/canvas.h" #include "gui/icons.h" #include "gui/input.h" -#include "imgui.h" +#include "snes_spc/demo/demo_util.h" +#include "snes_spc/demo/wave_writer.h" +#include "snes_spc/snes_spc/spc.h" namespace yaze { namespace app { namespace editor { +namespace { + +void PlaySPC() { + /* Create emulator and filter */ + SNES_SPC* snes_spc = spc_new(); + SPC_Filter* filter = spc_filter_new(); + if (!snes_spc || !filter) error("Out of memory"); + + /* Load SPC */ + { + /* Load file into memory */ + long spc_size; + void* spc = load_file("assets/music/hyrule_field.spc", &spc_size); + + /* Load SPC data into emulator */ + error(spc_load_spc(snes_spc, spc, spc_size)); + free(spc); /* emulator makes copy of data */ + + /* Most SPC files have garbage data in the echo buffer, so clear that */ + spc_clear_echo(snes_spc); + + /* Clear filter before playing */ + spc_filter_clear(filter); + } + + /* Record 20 seconds to wave file */ + wave_open(spc_sample_rate, "out.wav"); + wave_enable_stereo(); + while (wave_sample_count() < 20 * spc_sample_rate * 2) { +/* Play into buffer */ +#define BUF_SIZE 2048 + short buf[BUF_SIZE]; + error(spc_play(snes_spc, BUF_SIZE, buf)); + + /* Filter samples */ + spc_filter_run(filter, buf, BUF_SIZE); + + wave_write(buf, BUF_SIZE); + } + + /* Cleanup */ + spc_filter_delete(filter); + spc_delete(snes_spc); + wave_close(); +} + +} // namespace + void MusicEditor::Update() { if (ImGui::BeginTable("MusicEditorColumns", 2, music_editor_flags_, ImVec2(0, 0))) { @@ -162,6 +217,12 @@ void MusicEditor::DrawToolset() { static int selected_option = 0; static int current_volume = 0; const int MAX_VOLUME = 100; + + + if (is_playing) { + PlaySPC(); + } + gui::ItemLabel("Select a song to edit: ", gui::ItemLabelFlags::Left); ImGui::Combo("#songs_in_game", &selected_option, kGameSongs, 30); diff --git a/src/app/editor/music_editor.h b/src/app/editor/music_editor.h index 8fd7e4a9..a5433c39 100644 --- a/src/app/editor/music_editor.h +++ b/src/app/editor/music_editor.h @@ -8,6 +8,9 @@ #include "gui/canvas.h" #include "gui/icons.h" #include "gui/input.h" +#include "snes_spc/demo/demo_util.h" +#include "snes_spc/demo/wave_writer.h" +#include "snes_spc/snes_spc/spc.h" namespace yaze { namespace app { diff --git a/src/app/rom.cc b/src/app/rom.cc index 30b7e998..8c6f6310 100644 --- a/src/app/rom.cc +++ b/src/app/rom.cc @@ -479,6 +479,7 @@ absl::StatusOr ROM::Compress(const int start, const int length, int mode, absl::StatusOr ROM::CompressGraphics(const int pos, const int length) { return Compress(pos, length, kNintendoMode2); } + absl::StatusOr ROM::CompressOverworld(const int pos, const int length) { return Compress(pos, length, kNintendoMode1); } diff --git a/src/app/spc700/spc700.def b/src/app/spc700/spc700.def new file mode 100644 index 00000000..4781c5ef --- /dev/null +++ b/src/app/spc700/spc700.def @@ -0,0 +1,26 @@ +LIBRARY snes_spc +DESCRIPTION "snes_spc 0.9.0" +EXPORTS + spc_new @1 + spc_delete @2 + spc_init_rom @3 + spc_set_output @4 + spc_sample_count @5 + spc_reset @6 + spc_soft_reset @7 + spc_read_port @8 + spc_write_port @9 + spc_end_frame @10 + spc_mute_voices @11 + spc_disable_surround @12 + spc_set_tempo @13 + spc_load_spc @14 + spc_clear_echo @15 + spc_play @16 + spc_skip @17 + spc_filter_new @18 + spc_filter_delete @19 + spc_filter_run @20 + spc_filter_clear @21 + spc_filter_set_gain @22 + spc_filter_set_bass @23 \ No newline at end of file diff --git a/src/lib/snes-spc-arm b/src/lib/snes-spc-arm deleted file mode 160000 index 609c02b0..00000000 --- a/src/lib/snes-spc-arm +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 609c02b00851bddc6adeda90c073fcccb784c346