From 745f0c1f5f565d84bb7bd3f161eeec8ca55b1eeb Mon Sep 17 00:00:00 2001 From: agehama Date: Sun, 31 Jul 2022 20:24:41 +0900 Subject: [PATCH 1/4] =?UTF-8?q?=E3=82=B3=E3=83=A1=E3=83=B3=E3=83=88?= =?UTF-8?q?=E5=89=8A=E9=99=A4=E3=81=AE=E9=96=A2=E6=95=B0=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SFZ_MIDI_Player/source/SFZLoader.cpp | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/SFZ_MIDI_Player/source/SFZLoader.cpp b/SFZ_MIDI_Player/source/SFZLoader.cpp index e58cbc6..8bce21f 100644 --- a/SFZ_MIDI_Player/source/SFZLoader.cpp +++ b/SFZ_MIDI_Player/source/SFZLoader.cpp @@ -103,6 +103,19 @@ void RegionSetting::debugPrint() const Console << U"ampeg: " << Vec4(ampeg_attack, ampeg_decay, ampeg_sustain, ampeg_release); } +String RemoveComment(const String& text) +{ + auto lines = text.split_lines(); + for (auto& line : lines) + { + if (line.starts_with(U'/')) + { + line.clear(); + } + } + return lines.join(U"\n", U"", U""); +} + SfzData LoadSfz(FilePathView sfzPath) { assert(FileSystem::Exists(sfzPath)); @@ -129,11 +142,10 @@ SfzData LoadSfz(FilePathView sfzPath) const String keyAmpegSustain = U"ampeg_sustain="; const String keyAmpegRelease = U"ampeg_release="; const String keyRtDecay = U"rt_decay="; - const String keyComment = U"//"; - const auto text = sfzReader.readAll(); + const auto text = RemoveComment(sfzReader.readAll()); - const auto directory = FileSystem::ParentPath(sfzPath);; + const auto directory = FileSystem::ParentPath(sfzPath); Array settings; RegionSetting group; @@ -147,10 +159,6 @@ SfzData LoadSfz(FilePathView sfzPath) StringView token = text.substrView(pos, nextPos == String::npos ? nextPos : nextPos - pos); if (token.empty()) {} - else if (token.starts_with(keyComment)) - { - nextPos = text.indexOfAny(U"\n", pos); - } else if (token.starts_with(keyRegion)) { if (region) From 3587f74fb17e56e44cad57d2bc75b96c9fb4e015 Mon Sep 17 00:00:00 2001 From: agehama Date: Mon, 1 Aug 2022 21:02:04 +0900 Subject: [PATCH 2/4] =?UTF-8?q?include=E3=82=92=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SFZ_MIDI_Player/source/SFZLoader.cpp | 60 +++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/SFZ_MIDI_Player/source/SFZLoader.cpp b/SFZ_MIDI_Player/source/SFZLoader.cpp index 8bce21f..6e32b1a 100644 --- a/SFZ_MIDI_Player/source/SFZLoader.cpp +++ b/SFZ_MIDI_Player/source/SFZLoader.cpp @@ -106,6 +106,7 @@ void RegionSetting::debugPrint() const String RemoveComment(const String& text) { auto lines = text.split_lines(); + for (auto& line : lines) { if (line.starts_with(U'/')) @@ -113,9 +114,65 @@ String RemoveComment(const String& text) line.clear(); } } + return lines.join(U"\n", U"", U""); } +String Preprocess(const String& text, const String& currentDirectory) +{ + const String keyInclude = U"#include"; + + String result; + + size_t pos = 0; + for (;;) + { + size_t beginPos = text.indexOf(U'#', pos); + + if (beginPos == String::npos) + { + result += text.substrView(pos); + break; + } + + result += text.substrView(pos, beginPos - pos); + pos = beginPos; + + StringView token = text.substrView(beginPos); + + if (token.starts_with(keyInclude)) + { + const size_t pathBegin = token.indexOf(U'\"', keyInclude.length()); + const size_t pathEnd = token.indexOf(U'\"', pathBegin + 1); + + const auto pathStr = token.substr(pathBegin + 1, pathEnd - pathBegin - 1); + + const auto includePath = currentDirectory + pathStr; + Console << U"include \"" << includePath << U"\""; + + assert(FileSystem::Exists(includePath)); + if (!FileSystem::Exists(includePath)) + { + Console << U"error"; + return U""; + } + + TextReader textReader(includePath); + + result += Preprocess(RemoveComment(textReader.readAll()), currentDirectory); + + pos += (pathEnd + 1); + } + else + { + result += U"#"; + ++pos; + } + } + + return result; +} + SfzData LoadSfz(FilePathView sfzPath) { assert(FileSystem::Exists(sfzPath)); @@ -143,9 +200,8 @@ SfzData LoadSfz(FilePathView sfzPath) const String keyAmpegRelease = U"ampeg_release="; const String keyRtDecay = U"rt_decay="; - const auto text = RemoveComment(sfzReader.readAll()); - const auto directory = FileSystem::ParentPath(sfzPath); + const auto text = Preprocess(RemoveComment(sfzReader.readAll()), directory); Array settings; RegionSetting group; From ba75cb9095a6fe3549850916058de050db3ccdb4 Mon Sep 17 00:00:00 2001 From: agehama Date: Mon, 1 Aug 2022 22:43:22 +0900 Subject: [PATCH 3/4] =?UTF-8?q?define=E3=82=92=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SFZ_MIDI_Player/source/SFZLoader.cpp | 98 ++++++++++++++++++++++------ 1 file changed, 77 insertions(+), 21 deletions(-) diff --git a/SFZ_MIDI_Player/source/SFZLoader.cpp b/SFZ_MIDI_Player/source/SFZLoader.cpp index 6e32b1a..6d7a12a 100644 --- a/SFZ_MIDI_Player/source/SFZLoader.cpp +++ b/SFZ_MIDI_Player/source/SFZLoader.cpp @@ -118,16 +118,36 @@ String RemoveComment(const String& text) return lines.join(U"\n", U"", U""); } -String Preprocess(const String& text, const String& currentDirectory) +std::pair splitDefine(StringView defineLine, size_t& endPos) +{ + const String keyDefine = U"#define"; + + const size_t nameBegin = defineLine.indexOf(U'$'); + const size_t nameEnd = defineLine.indexOfAny(U" \t", nameBegin); + const size_t valueBegin = defineLine.indexNotOfAny(U" \t", nameEnd); + const size_t valueEnd = Min(defineLine.indexOfAny(U" \t\n", valueBegin), defineLine.length()); + + const String name(defineLine.substr(nameBegin, nameEnd - nameBegin)); + const String value(defineLine.substr(valueBegin, valueEnd - valueBegin)); + + endPos = valueEnd; + + //Console << U"(" << defineLine << U") => {" << name << U": " << value << U"}"; + + return std::make_pair(name, value.ltrimmed()); +} + +String Preprocess(const String& text, const String& currentDirectory, HashTable& macroDefinitions) { const String keyInclude = U"#include"; + const String keyDefine = U"#define"; String result; size_t pos = 0; for (;;) { - size_t beginPos = text.indexOf(U'#', pos); + size_t beginPos = text.indexOfAny(U"#$", pos); if (beginPos == String::npos) { @@ -140,33 +160,67 @@ String Preprocess(const String& text, const String& currentDirectory) StringView token = text.substrView(beginPos); - if (token.starts_with(keyInclude)) + if (text[beginPos] == U'#') { - const size_t pathBegin = token.indexOf(U'\"', keyInclude.length()); - const size_t pathEnd = token.indexOf(U'\"', pathBegin + 1); + if (token.starts_with(keyInclude)) + { + const size_t pathBegin = token.indexOf(U'\"', keyInclude.length()); + const size_t pathEnd = token.indexOf(U'\"', pathBegin + 1); - const auto pathStr = token.substr(pathBegin + 1, pathEnd - pathBegin - 1); + const auto pathStr = token.substr(pathBegin + 1, pathEnd - pathBegin - 1); - const auto includePath = currentDirectory + pathStr; - Console << U"include \"" << includePath << U"\""; + const auto includePath = currentDirectory + pathStr; + //Console << U"include \"" << includePath << U"\""; - assert(FileSystem::Exists(includePath)); - if (!FileSystem::Exists(includePath)) - { - Console << U"error"; - return U""; - } + assert(FileSystem::Exists(includePath)); + if (!FileSystem::Exists(includePath)) + { + Console << U"error: include file \"" << includePath << U"\" does not exist"; + return U""; + } + + TextReader textReader(includePath); - TextReader textReader(includePath); + result += Preprocess(RemoveComment(textReader.readAll()), currentDirectory, macroDefinitions); - result += Preprocess(RemoveComment(textReader.readAll()), currentDirectory); + pos += (pathEnd + 1); + } + else if (token.starts_with(keyDefine)) + { + size_t endPos = 0; + const auto [name, value] = splitDefine(token, endPos); + pos += endPos; - pos += (pathEnd + 1); + //Console << U"define " << name << U"=>" << value; + macroDefinitions[name] = value; + } + else + { + result += U"#"; + ++pos; + } } - else + else if (text[beginPos] == U'$') { - result += U"#"; - ++pos; + const size_t nameBegin = 1; + const size_t nameEnd = Min(token.indexNotOfAny(U"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_", nameBegin), token.length()); + + StringView varName = token.substr(0, nameEnd); + + if (!macroDefinitions.contains(varName)) + { + Console << U"token: " << token; + Console << U"error: (" << varName << U") not defined "; + return U""; + + result += Format(U"($", varName, U": not defined)"); + } + else + { + result += macroDefinitions[varName]; + } + + pos += nameEnd; } } @@ -201,7 +255,9 @@ SfzData LoadSfz(FilePathView sfzPath) const String keyRtDecay = U"rt_decay="; const auto directory = FileSystem::ParentPath(sfzPath); - const auto text = Preprocess(RemoveComment(sfzReader.readAll()), directory); + + HashTable macroDefinitions; + const auto text = Preprocess(RemoveComment(sfzReader.readAll()), directory, macroDefinitions); Array settings; RegionSetting group; From 50ac4d1752659030ff15938a69c774eb674921c2 Mon Sep 17 00:00:00 2001 From: agehama Date: Tue, 2 Aug 2022 20:17:38 +0900 Subject: [PATCH 4/4] =?UTF-8?q?default=5Fpath=E3=81=AB=E5=AF=BE=E5=BF=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SFZ_MIDI_Player/source/SFZLoader.cpp | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/SFZ_MIDI_Player/source/SFZLoader.cpp b/SFZ_MIDI_Player/source/SFZLoader.cpp index 6d7a12a..af5838b 100644 --- a/SFZ_MIDI_Player/source/SFZLoader.cpp +++ b/SFZ_MIDI_Player/source/SFZLoader.cpp @@ -253,11 +253,13 @@ SfzData LoadSfz(FilePathView sfzPath) const String keyAmpegSustain = U"ampeg_sustain="; const String keyAmpegRelease = U"ampeg_release="; const String keyRtDecay = U"rt_decay="; + const String keyDefaultPath = U"default_path="; - const auto directory = FileSystem::ParentPath(sfzPath); + const auto parentDirectory = FileSystem::ParentPath(sfzPath); + String defaultPath = parentDirectory; HashTable macroDefinitions; - const auto text = Preprocess(RemoveComment(sfzReader.readAll()), directory, macroDefinitions); + const auto text = Preprocess(RemoveComment(sfzReader.readAll()), parentDirectory, macroDefinitions); Array settings; RegionSetting group; @@ -270,7 +272,9 @@ SfzData LoadSfz(FilePathView sfzPath) StringView token = text.substrView(pos, nextPos == String::npos ? nextPos : nextPos - pos); - if (token.empty()) {} + if (token.empty()) + { + } else if (token.starts_with(keyRegion)) { if (region) @@ -283,7 +287,7 @@ SfzData LoadSfz(FilePathView sfzPath) else if (token.starts_with(keySample)) { token = token.substr(keySample.length()); - if (!FileSystem::Exists(directory + token)) + if (!FileSystem::Exists(defaultPath + token)) { pos += keySample.length(); // sampleの場合は空白文字を含める @@ -301,6 +305,10 @@ SfzData LoadSfz(FilePathView sfzPath) { (region ? region.value() : group).hivel = ParseInt(token.substr(keyHivel.length())); } + else if (token.starts_with(keyDefaultPath)) + { + defaultPath = parentDirectory + token.substr(keyDefaultPath.length()); + } else if (token.starts_with(keyKey)) { const auto keyStr = token.substr(keyLokey.length()); @@ -440,7 +448,7 @@ SfzData LoadSfz(FilePathView sfzPath) //} SfzData sfzData; - sfzData.dir = directory; + sfzData.dir = defaultPath; sfzData.data = std::move(settings); return sfzData;