Added image opcode
This commit is contained in:
parent
798f501a65
commit
0c4f136874
11 changed files with 7908 additions and 3 deletions
|
|
@ -37,6 +37,7 @@ We invite you to check out the [GOVERNANCE](GOVERNANCE.md) file to see how the o
|
|||
## Dependencies and licenses
|
||||
|
||||
The sfizz library makes primary use of:
|
||||
|
||||
- [libsndfile], licensed under the GNU Lesser General Public License v2.1
|
||||
- [Abseil], licensed under the Apache License 2.0
|
||||
- [atomic_queue] by Maxim Egorushkin, licensed under the MIT license
|
||||
|
|
@ -49,6 +50,7 @@ The sfizz library makes primary use of:
|
|||
- [cpuid] by Steinwurf ApS, licensed under the BSD 3-Clause license
|
||||
|
||||
The sfizz library also uses in some subprojects:
|
||||
|
||||
- [Catch2], licensed under the Boost Software License 1.0
|
||||
- [benchmark], licensed under the Apache License 2.0
|
||||
- [LV2], licensed under the ISC license
|
||||
|
|
@ -57,6 +59,7 @@ The sfizz library also uses in some subprojects:
|
|||
- [fmidi] by Jean Pierre Cimalando, licensed under the Boost Software License 1.0
|
||||
- [libsamplerate], licensed under the BSD 2-Clause license
|
||||
- [GLSL-Color-Spaces] by tobspr, licensed under the MIT license
|
||||
- [stb_image] by Sean Barrett, licensed as public domain or MIT license
|
||||
|
||||
[Abseil]: https://abseil.io/
|
||||
[atomic_queue]: https://github.com/max0x7ba/atomic_queue
|
||||
|
|
@ -76,6 +79,7 @@ The sfizz library also uses in some subprojects:
|
|||
[libsndfile]: http://www.mega-nerd.com/libsndfile/
|
||||
[LV2]: https://lv2plug.in/
|
||||
[GLSL-Color-Spaces]: https://github.com/tobspr/GLSL-Color-Spaces
|
||||
[stb_image]: https://github.com/nothings/stb#stb
|
||||
[our website]: https://sfz.tools/sfizz
|
||||
[releases]: https://github.com/sfztools/sfizz/releases
|
||||
[Carla]: https://kx.studio/Applications:Carla
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ add_library(sfizz_editor STATIC EXCLUDE_FROM_ALL
|
|||
src/editor/EditIds.cpp
|
||||
src/editor/Editor.h
|
||||
src/editor/Editor.cpp
|
||||
src/editor/EditorLibs.cpp
|
||||
src/editor/EditorController.h
|
||||
src/editor/GUIComponents.h
|
||||
src/editor/GUIComponents.cpp
|
||||
|
|
@ -49,7 +50,7 @@ add_library(sfizz_editor STATIC EXCLUDE_FROM_ALL
|
|||
src/editor/utility/vstgui_after.h
|
||||
src/editor/utility/vstgui_before.h)
|
||||
add_library(sfizz::editor ALIAS sfizz_editor)
|
||||
target_include_directories(sfizz_editor PUBLIC "src")
|
||||
target_include_directories(sfizz_editor PUBLIC "src" "external")
|
||||
target_link_libraries(sfizz_editor PUBLIC sfizz::messaging sfizz::plugins-common)
|
||||
target_link_libraries(sfizz_editor PRIVATE sfizz::vstgui)
|
||||
if(APPLE)
|
||||
|
|
|
|||
37
plugins/editor/external/stb_image/LICENSE
vendored
Normal file
37
plugins/editor/external/stb_image/LICENSE
vendored
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
This software is available under 2 licenses -- choose whichever you prefer.
|
||||
------------------------------------------------------------------------------
|
||||
ALTERNATIVE A - MIT License
|
||||
Copyright (c) 2017 Sean Barrett
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
------------------------------------------------------------------------------
|
||||
ALTERNATIVE B - Public Domain (www.unlicense.org)
|
||||
This is free and unencumbered software released into the public domain.
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
|
||||
software, either in source code form or as a compiled binary, for any purpose,
|
||||
commercial or non-commercial, and by any means.
|
||||
In jurisdictions that recognize copyright laws, the author or authors of this
|
||||
software dedicate any and all copyright interest in the software to the public
|
||||
domain. We make this dedication for the benefit of the public at large and to
|
||||
the detriment of our heirs and successors. We intend this dedication to be an
|
||||
overt act of relinquishment in perpetuity of all present and future rights to
|
||||
this software under copyright law.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
7764
plugins/editor/external/stb_image/stb_image.h
vendored
Normal file
7764
plugins/editor/external/stb_image/stb_image.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -6,7 +6,7 @@ widget_class mainView {open
|
|||
xywh {659 319 800 475} type Double
|
||||
class LogicalGroup visible
|
||||
} {
|
||||
Fl_Box {} {
|
||||
Fl_Box imageContainer_ {
|
||||
image {../resources/background.png} xywh {190 110 600 280}
|
||||
class Background
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,9 @@
|
|||
#include <absl/strings/ascii.h>
|
||||
#include <absl/strings/numbers.h>
|
||||
#include <ghc/fs_std.hpp>
|
||||
|
||||
#include <stb_image/stb_image.h>
|
||||
|
||||
#include <array>
|
||||
#include <queue>
|
||||
#include <unordered_map>
|
||||
|
|
@ -39,6 +42,11 @@ using namespace VSTGUI;
|
|||
const int Editor::viewWidth { 800 };
|
||||
const int Editor::viewHeight { 475 };
|
||||
|
||||
struct image_deleter {
|
||||
void operator()(unsigned char* x) const noexcept { stbi_image_free(x); }
|
||||
};
|
||||
typedef std::unique_ptr<unsigned char[], image_deleter> image_u;
|
||||
|
||||
struct Editor::Impl : EditorController::Receiver, IControlListener {
|
||||
EditorController* ctrl_ = nullptr;
|
||||
CFrame* frame_ = nullptr;
|
||||
|
|
@ -122,6 +130,8 @@ struct Editor::Impl : EditorController::Receiver, IControlListener {
|
|||
CTextLabel* infoSamplesLabel_ = nullptr;
|
||||
CTextLabel* infoVoicesLabel_ = nullptr;
|
||||
|
||||
SharedPointer<CViewContainer> imageContainer_;
|
||||
|
||||
CTextLabel* memoryLabel_ = nullptr;
|
||||
|
||||
SActionMenu* fileOperationsMenu_ = nullptr;
|
||||
|
|
@ -204,6 +214,7 @@ struct Editor::Impl : EditorController::Receiver, IControlListener {
|
|||
void updateCCLabel(unsigned cc, const char* label);
|
||||
void updateSWLastCurrent(int sw);
|
||||
void updateSWLastLabel(unsigned sw, const char* label);
|
||||
void updateBackgroundImage(const char* filepath);
|
||||
void updateMemoryUsed(uint64_t mem);
|
||||
|
||||
// edition of CC by UI
|
||||
|
|
@ -233,6 +244,8 @@ struct Editor::Impl : EditorController::Receiver, IControlListener {
|
|||
const char* keyName = keyNames[key % 12];
|
||||
return std::string(keyName) + ' ' + std::to_string(octave);
|
||||
}
|
||||
|
||||
static SharedPointer<CBitmap> loadAnyFormatImage(const fs::path& filePath);
|
||||
};
|
||||
|
||||
Editor::Editor(EditorController& ctrl)
|
||||
|
|
@ -279,6 +292,7 @@ void Editor::open(CFrame& frame)
|
|||
impl.sendQueuedOSC("/key/slots", "", nullptr);
|
||||
impl.sendQueuedOSC("/sw/last/slots", "", nullptr);
|
||||
impl.sendQueuedOSC("/cc/slots", "", nullptr);
|
||||
impl.sendQueuedOSC("/image", "", nullptr);
|
||||
}
|
||||
|
||||
void Editor::close()
|
||||
|
|
@ -311,6 +325,7 @@ void Editor::Impl::uiReceiveValue(EditId id, const EditValue& v)
|
|||
sendQueuedOSC("/key/slots", "", nullptr);
|
||||
sendQueuedOSC("/sw/last/slots", "", nullptr);
|
||||
sendQueuedOSC("/cc/slots", "", nullptr);
|
||||
sendQueuedOSC("/image", "", nullptr);
|
||||
}
|
||||
break;
|
||||
case EditId::Volume:
|
||||
|
|
@ -529,6 +544,9 @@ void Editor::Impl::uiReceiveMessage(const char* path, const char* sig, const sfi
|
|||
else if (Messages::matchOSC("/sw/last/&/label", path, indices) && !strcmp(sig, "s")) {
|
||||
updateSWLastLabel(indices[0], args[0].s);
|
||||
}
|
||||
else if (Messages::matchOSC("/image", path, indices) && !strcmp(sig, "s")) {
|
||||
updateBackgroundImage(args[0].s);
|
||||
}
|
||||
else if (Messages::matchOSC("/mem/buffers", path, indices) && !strcmp(sig, "h")) {
|
||||
updateMemoryUsed(args[0].h);
|
||||
}
|
||||
|
|
@ -579,7 +597,6 @@ void Editor::Impl::createFrameContents()
|
|||
SharedPointer<CBitmap> background = owned(new CBitmap("background.png"));
|
||||
SharedPointer<CBitmap> knob48 = owned(new CBitmap("knob48.png"));
|
||||
SharedPointer<CBitmap> logoText = owned(new CBitmap("logo_text.png"));
|
||||
|
||||
{
|
||||
const CColor frameBackground = { 0xd3, 0xd7, 0xcf };
|
||||
|
||||
|
|
@ -1148,6 +1165,7 @@ void Editor::Impl::changeSfzFile(const std::string& filePath)
|
|||
sendQueuedOSC("/key/slots", "", nullptr);
|
||||
sendQueuedOSC("/sw/last/slots", "", nullptr);
|
||||
sendQueuedOSC("/cc/slots", "", nullptr);
|
||||
sendQueuedOSC("/image", "", nullptr);
|
||||
}
|
||||
|
||||
void Editor::Impl::changeToNextSfzFile(long offset)
|
||||
|
|
@ -1563,6 +1581,75 @@ void Editor::Impl::updateSWLastLabel(unsigned sw, const char* label)
|
|||
updateKeyswitchNameLabel();
|
||||
}
|
||||
|
||||
SharedPointer<CBitmap> Editor::Impl::loadAnyFormatImage(const fs::path& filePath)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
FILE* file { _wfopen(filePath.wstring().c_str(), L"rb") };
|
||||
#else
|
||||
FILE* file { fopen(filePath.c_str(), "rb") };
|
||||
#endif
|
||||
SharedPointer<CBitmap> bitmap;
|
||||
|
||||
if (!file)
|
||||
return bitmap;
|
||||
|
||||
int width, height, channels;
|
||||
image_u image {
|
||||
stbi_load_from_file(file, &width, &height, &channels, STBI_rgb_alpha)
|
||||
};
|
||||
fclose(file);
|
||||
auto imageData = image.get();
|
||||
|
||||
if (imageData) {
|
||||
bitmap = makeOwned<CBitmap>(width, height);
|
||||
SharedPointer<CBitmapPixelAccess> accessor =
|
||||
owned(CBitmapPixelAccess::create(bitmap.get()));
|
||||
|
||||
if (accessor) {
|
||||
do {
|
||||
CColor c(
|
||||
imageData[0],
|
||||
imageData[1],
|
||||
imageData[2],
|
||||
imageData[3]
|
||||
);
|
||||
accessor->setColor(c);
|
||||
imageData += 4;
|
||||
}
|
||||
while (++*accessor);
|
||||
accessor = nullptr;
|
||||
}
|
||||
}
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
void Editor::Impl::updateBackgroundImage(const char* filepath)
|
||||
{
|
||||
const fs::path sfzFilePath = fs::u8path(currentSfzFile_);
|
||||
const fs::path sfzDirPath = sfzFilePath.parent_path();
|
||||
const fs::path imagePath = sfzDirPath / fs::u8path(filepath);
|
||||
SharedPointer<CBitmap> bitmap = loadAnyFormatImage(imagePath);
|
||||
|
||||
if (bitmap) {
|
||||
CCoord containerW = imageContainer_->getWidth();
|
||||
CCoord containerH = imageContainer_->getHeight();
|
||||
CCoord bitmapW = bitmap->getWidth();
|
||||
CCoord bitmapH = bitmap->getHeight();
|
||||
|
||||
if (bitmapW > containerW || bitmapH > containerH) {
|
||||
CCoord xScale = bitmapW / containerW;
|
||||
CCoord yScale = bitmapH / containerH;
|
||||
CCoord scale = (xScale > yScale) ? xScale : yScale;
|
||||
|
||||
PlatformBitmapPtr ptr = bitmap->getPlatformBitmap();
|
||||
ptr->setScaleFactor(scale);
|
||||
}
|
||||
} else {
|
||||
bitmap = owned(new CBitmap("background.png"));
|
||||
}
|
||||
imageContainer_->setBackground(bitmap);
|
||||
}
|
||||
|
||||
void Editor::Impl::updateMemoryUsed(uint64_t mem)
|
||||
{
|
||||
if (CTextLabel* label = memoryLabel_) {
|
||||
|
|
|
|||
2
plugins/editor/src/editor/EditorLibs.cpp
Normal file
2
plugins/editor/src/editor/EditorLibs.cpp
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include <stb_image/stb_image.h>
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
auto* const view__0 = createLogicalGroup(CRect(0, 0, 800, 475), -1, "", kCenterText, 14);
|
||||
mainView = view__0;
|
||||
auto* const view__1 = createBackground(CRect(190, 110, 790, 390), -1, "", kCenterText, 14);
|
||||
imageContainer_ = view__1;
|
||||
view__0->addView(view__1);
|
||||
enterTheme(darkTheme);
|
||||
auto* const view__2 = createLogicalGroup(CRect(0, 0, 800, 110), -1, "", kCenterText, 14);
|
||||
|
|
|
|||
|
|
@ -251,6 +251,7 @@ void Synth::Impl::clear()
|
|||
currentSwitch_ = absl::nullopt;
|
||||
currentSwitchChanged_ = true;
|
||||
defaultPath_ = "";
|
||||
image_ = "";
|
||||
resources_.midiState.reset();
|
||||
resources_.filePool.clear();
|
||||
resources_.filePool.setRamLoading(config::loadInRam);
|
||||
|
|
@ -386,6 +387,9 @@ void Synth::Impl::handleControlOpcodes(const std::vector<Opcode>& members)
|
|||
defaultPath_ = absl::StrReplaceAll(trim(member.value), { { "\\", "/" } });
|
||||
DBG("Changing default sample path to " << defaultPath_);
|
||||
break;
|
||||
case hash("image"):
|
||||
image_ = absl::StrCat(defaultPath_, absl::StrReplaceAll(trim(member.value), { { "\\", "/" } }));
|
||||
break;
|
||||
case hash("note_offset"):
|
||||
noteOffset_ = member.read(Default::noteOffset);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -54,6 +54,10 @@ void sfz::Synth::dispatchMessage(Client& client, int delay, const char* path, co
|
|||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
MATCH("/image", "") {
|
||||
client.receive<'s'>(delay, path, impl.image_.c_str());
|
||||
} break;
|
||||
|
||||
MATCH("/sw/last/slots", "") {
|
||||
const BitArray<128>& switches = impl.swLastSlots_;
|
||||
sfizz_blob_t blob { switches.data(), static_cast<uint32_t>(switches.byte_size()) };
|
||||
|
|
|
|||
|
|
@ -281,6 +281,7 @@ struct Synth::Impl final: public Parser::Listener {
|
|||
|
||||
// Control opcodes
|
||||
std::string defaultPath_ { "" };
|
||||
std::string image_ { "" };
|
||||
int noteOffset_ { Default::noteOffset };
|
||||
int octaveOffset_ { Default::octaveOffset };
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue