// SPDX-License-Identifier: BSD-2-Clause // This code is part of the sfizz library and is licensed under a BSD 2-clause // license. You should have receive a LICENSE.md file along with the code. // If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz #include "SfizzVstState.h" #include "plugin/NativeHelpers.h" #include #include #include tresult SfizzVstState::load(IBStream* state) { IBStreamer s(state, kLittleEndian); uint64 version = 0; if (!s.readInt64u(version)) return kResultFalse; if (version > currentStateVersion) return kResultFalse; if (const char* str = s.readStr8()) sfzFile = fromPlatformAgnosticPath(str).string(); else return kResultFalse; if (!s.readFloat(volume)) return kResultFalse; if (!s.readInt32(numVoices)) return kResultFalse; if (!s.readInt32(oversamplingLog2)) return kResultFalse; if (!s.readInt32(preloadSize)) return kResultFalse; const SfizzVstState defaults; if (version >= 1) { if (const char* str = s.readStr8()) scalaFile = fromPlatformAgnosticPath(str).string(); else return kResultFalse; if (!s.readInt32(scalaRootKey)) return kResultFalse; if (!s.readFloat(tuningFrequency)) return kResultFalse; if (!s.readFloat(stretchedTuning)) return kResultFalse; } else { scalaFile = defaults.scalaFile; scalaRootKey = defaults.scalaRootKey; tuningFrequency = defaults.tuningFrequency; stretchedTuning = defaults.stretchedTuning; } if (version >= 3) { if (!s.readInt32(sampleQuality)) return kResultFalse; if (!s.readInt32(oscillatorQuality)) return kResultFalse; } else { sampleQuality = defaults.sampleQuality; oscillatorQuality = defaults.oscillatorQuality; } if (version >= 5) { if (!s.readInt32(freewheelingSampleQuality)) return kResultFalse; if (!s.readInt32(freewheelingOscillatorQuality)) return kResultFalse; if (!s.readBool(sustainCancelsRelease)) return kResultFalse; } if (version >= 4) { if (!s.readInt32(lastKeyswitch)) return kResultFalse; } else { lastKeyswitch = -1; } controllers.clear(); if (version >= 2) { uint32 count; if (!s.readInt32u(count)) return kResultFalse; controllers.resize(0x10000); uint32 size = 0; for (uint32 i = 0; i < count; ++i) { uint16 cc; float value; if (!s.readInt16u(cc) || !s.readFloat(value)) return kResultFalse; controllers[cc] = value; size = std::max(size, uint32(cc) + 1); } controllers.resize(size); controllers.shrink_to_fit(); } return kResultTrue; } tresult SfizzVstState::store(IBStream* state) const { IBStreamer s(state, kLittleEndian); if (!s.writeInt64u(currentStateVersion)) return kResultFalse; if (!s.writeStr8(toPlatformAgnosticPath(sfzFile).string().c_str())) return kResultFalse; if (!s.writeFloat(volume)) return kResultFalse; if (!s.writeInt32(numVoices)) return kResultFalse; if (!s.writeInt32(oversamplingLog2)) return kResultFalse; if (!s.writeInt32(preloadSize)) return kResultFalse; if (!s.writeStr8(toPlatformAgnosticPath(scalaFile).string().c_str())) return kResultFalse; if (!s.writeInt32(scalaRootKey)) return kResultFalse; if (!s.writeFloat(tuningFrequency)) return kResultFalse; if (!s.writeFloat(stretchedTuning)) return kResultFalse; if (!s.writeInt32(sampleQuality)) return kResultFalse; if (!s.writeInt32(oscillatorQuality)) return kResultFalse; if (!s.writeInt32(freewheelingSampleQuality)) return kResultFalse; if (!s.writeInt32(freewheelingOscillatorQuality)) return kResultFalse; if (!s.writeBool(sustainCancelsRelease)) return kResultFalse; if (!s.writeInt32(lastKeyswitch)) return kResultFalse; { uint32 ccCount = 0; uint32 ccLimit = uint32(std::min(controllers.size(), size_t(0x10000))); for (uint32_t cc = 0; cc < ccLimit; ++cc) ccCount += controllers[cc] != absl::nullopt; if (!s.writeInt32u(ccCount)) return kResultFalse; for (uint32_t cc = 0; cc < ccLimit; ++cc) { if (absl::optional ccValue = controllers[cc]) { if (!s.writeInt16u(uint16(cc)) || !s.writeFloat(*ccValue)) return kResultFalse; } } } return kResultTrue; } constexpr uint64 SfizzVstState::currentStateVersion;