aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVitaly Novichkov <Wohlstand@users.noreply.github.com>2018-09-03 13:15:04 +0300
committerGitHub <noreply@github.com>2018-09-03 13:15:04 +0300
commit5c9eb9c4fb736a004af31874d457a183d7a3cbe5 (patch)
tree6e1ef697e208386e2eabab75699c19c138ffe893
parentce26aee47eba23d1b55a5840f79772c78fd69595 (diff)
parent273841b7b2442d1909ae8d0233b7097426a1d16c (diff)
downloadlibADLMIDI-5c9eb9c4fb736a004af31874d457a183d7a3cbe5.tar.gz
libADLMIDI-5c9eb9c4fb736a004af31874d457a183d7a3cbe5.tar.bz2
libADLMIDI-5c9eb9c4fb736a004af31874d457a183d7a3cbe5.zip
Merge pull request #170 from jpcima/wopl-file
wopl: bug fix and test
-rw-r--r--src/wopl/wopl_file.c10
-rw-r--r--test/CMakeLists.txt1
-rw-r--r--test/wopl-file/CMakeLists.txt15
-rw-r--r--test/wopl-file/wopl_file.cpp116
4 files changed, 139 insertions, 3 deletions
diff --git a/src/wopl/wopl_file.c b/src/wopl/wopl_file.c
index 25b75be..f018cbc 100644
--- a/src/wopl/wopl_file.c
+++ b/src/wopl/wopl_file.c
@@ -353,6 +353,8 @@ int WOPL_LoadInstFromMem(WOPIFile *file, void *mem, size_t length)
GO_FORWARD(2);
}
+ file->version = version;
+
{/* is drum flag */
if(length < 1)
return WOPL_ERR_UNEXPECTED_ENDING;
@@ -434,11 +436,13 @@ size_t WOPL_CalculateInstFileSize(WOPIFile *file, uint16_t version)
* is percussive instrument
*/
- if(version >= 3)
- ins_size = WOPL_INST_SIZE_V3;
+ if(version > 2)
+ /* Skip sounding delays are not part of single-instrument file
+ * two sizes of uint16_t will be subtracted */
+ ins_size = WOPL_INST_SIZE_V3 - (sizeof(uint16_t) * 2);
else
ins_size = WOPL_INST_SIZE_V2;
- final_size += ins_size * 128;
+ final_size += ins_size;
return final_size;
}
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index ee02087..9e6b247 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -3,6 +3,7 @@ set(CMAKE_CXX_STANDARD 11)
add_subdirectory(bankmap)
add_subdirectory(conversion)
+add_subdirectory(wopl-file)
add_library(Catch-objects OBJECT "common/catch_main.cpp")
target_include_directories(Catch-objects PRIVATE "common")
diff --git a/test/wopl-file/CMakeLists.txt b/test/wopl-file/CMakeLists.txt
new file mode 100644
index 0000000..082f1fe
--- /dev/null
+++ b/test/wopl-file/CMakeLists.txt
@@ -0,0 +1,15 @@
+
+set(CMAKE_CXX_STANDARD 11)
+
+include_directories (${CMAKE_CURRENT_SOURCE_DIR}/../common
+ ${CMAKE_SOURCE_DIR}/include
+ ${CMAKE_SOURCE_DIR}/src)
+
+add_executable(WoplFile
+ wopl_file.cpp
+ ${libADLMIDI_SOURCE_DIR}/src/wopl/wopl_file.c
+ $<TARGET_OBJECTS:Catch-objects>)
+
+set_target_properties(WoplFile PROPERTIES COMPILE_DEFINITIONS "GSL_THROW_ON_CONTRACT_VIOLATION")
+add_test(NAME WoplFileTest COMMAND WoplFile)
+
diff --git a/test/wopl-file/wopl_file.cpp b/test/wopl-file/wopl_file.cpp
new file mode 100644
index 0000000..04913dd
--- /dev/null
+++ b/test/wopl-file/wopl_file.cpp
@@ -0,0 +1,116 @@
+#include <catch.hpp>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include "wopl/wopl_file.h"
+
+static const char *test_files[] = {
+ "fm_banks/wopl_files/Apogee-IMF-90.wopl",
+ "fm_banks/wopl_files/DMXOPL3-by-sneakernets-GS.wopl",
+ "fm_banks/wopl_files/GM-By-J.A.Nguyen-and-Wohlstand.wopl",
+ "fm_banks/wopl_files/lostvik.wopl",
+ "fm_banks/wopl_files/Wohlstand's-modded-FatMan.wopl"
+};
+
+static WOPLFile *LoadBankFromFile(const char *path);
+
+TEST_CASE("[WOPLFile] Load, Save, Load")
+{
+ for (int version : {1, 2}) {
+ for (const char *test_file : test_files) {
+ fprintf(stderr, "--- Test '%s' with version %d\n", test_file, version);
+
+ WOPLFile *wopl = LoadBankFromFile(test_file);
+ REQUIRE(wopl != nullptr);
+
+ size_t size = WOPL_CalculateBankFileSize(wopl, version);
+ char *mem = new char[size];
+
+ REQUIRE(WOPL_SaveBankToMem(wopl, mem, size, version, 0) == 0);
+
+ {
+ int error;
+ WOPLFile *wopl2 = WOPL_LoadBankFromMem(mem, size, &error);
+ if(!wopl2)
+ fprintf(stderr, "--- Loading error %d\n", error);
+ REQUIRE(wopl2);
+
+ if(wopl->version == version)
+ REQUIRE(WOPL_BanksCmp(wopl, wopl2) == 1);
+ else {
+ REQUIRE(wopl->banks_count_melodic == wopl2->banks_count_melodic);
+ REQUIRE(wopl->banks_count_percussion == wopl2->banks_count_percussion);
+ REQUIRE(wopl->opl_flags == wopl2->opl_flags);
+ REQUIRE(wopl->volume_model == wopl2->volume_model);
+ }
+
+ WOPL_Free(wopl2);
+ }
+
+ delete[] mem;
+
+ {
+ unsigned melo_banks = wopl->banks_count_melodic;
+ unsigned drum_banks = wopl->banks_count_percussion;
+
+ for(unsigned Bi = 0; Bi < melo_banks + drum_banks; ++Bi)
+ {
+ const WOPLBank &bank = (Bi < melo_banks) ?
+ wopl->banks_melodic[Bi] : wopl->banks_percussive[Bi - melo_banks];
+
+ for(unsigned Pi = 0; Pi < 128; ++Pi)
+ {
+ WOPIFile opli = {};
+ opli.version = version;
+ opli.is_drum = Bi >= melo_banks;
+ opli.inst = bank.ins[Pi];
+
+ size = WOPL_CalculateInstFileSize(&opli, version);
+ mem = new char[size];
+
+ REQUIRE(WOPL_SaveInstToMem(&opli, mem, size, version) == 0);
+
+ WOPIFile opli2 = {};
+ int error = WOPL_LoadInstFromMem(&opli2, mem, size);
+ if(error != 0)
+ fprintf(stderr, "--- Loading error %d\n", error);
+ REQUIRE(error == 0);
+
+ size_t compare_size = sizeof(WOPIFile) - 2 * sizeof(uint16_t);
+ REQUIRE(memcmp(&opli, &opli2, compare_size) == 0);
+
+ delete[] mem;
+ }
+ }
+ }
+
+ WOPL_Free(wopl);
+ }
+ }
+}
+
+static WOPLFile *LoadBankFromFile(const char *path)
+{
+ WOPLFile *file = nullptr;
+ FILE *fh;
+ struct stat st;
+ char *mem = nullptr;
+
+ if(!(fh = fopen(path, "rb")) || fstat(fileno(fh), &st) != 0)
+ goto fail;
+
+ mem = new char[st.st_size];
+ if(fread(mem, st.st_size, 1, fh) != 1)
+ goto fail;
+
+ int error;
+ file = WOPL_LoadBankFromMem(mem, st.st_size, &error);
+ if(!file)
+ fprintf(stderr, "--- Loading error %d\n", error);
+
+fail:
+ delete[] mem;
+ if (fh) fclose(fh);
+ return file;
+}