Files
hot-step-cpp-ROCm/engine/vendor/vst3sdk/public.sdk/source/vst/interappaudio/PresetManager.mm
T
2026-08-16 18:24:52 +07:00

282 lines
8.4 KiB
Plaintext

//-----------------------------------------------------------------------------
// Project : VST SDK
//
// Category : Helpers
// Filename : public.sdk/source/vst/interappaudio/PresetManager.mm
// Created by : Steinberg, 10/2013
// Description : VST 3 InterAppAudio
// Flags : clang-format SMTGSequencer
//
//-----------------------------------------------------------------------------
// This file is part of a Steinberg SDK. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this distribution
// and at www.steinberg.net/sdklicenses.
// No part of the SDK, including this file, may be copied, modified, propagated,
// or distributed except according to the terms contained in the LICENSE file.
//-----------------------------------------------------------------------------
#import "PresetManager.h"
#import "PresetBrowserViewController.h"
#import "PresetSaveViewController.h"
#import "public.sdk/source/vst/vstpresetfile.h"
#import "pluginterfaces/vst/ivstattributes.h"
namespace Steinberg {
namespace Vst {
namespace InterAppAudio {
//-----------------------------------------------------------------------------
class PresetStream : public ReadOnlyBStream, public IStreamAttributes
{
public:
PresetStream (IBStream* sourceStream, TSize sourceOffset, TSize sectionSize,
const char* utf8Path)
: ReadOnlyBStream (sourceStream, sourceOffset, sectionSize), fileName (utf8Path)
{
fileName.toWideString (kCP_Utf8);
}
virtual tresult PLUGIN_API getFileName (String128 name) override
{
if (fileName.length () > 0)
{
fileName.copyTo (name, 0, 128);
return kResultTrue;
}
return kResultFalse;
}
virtual IAttributeList* PLUGIN_API getAttributes () override { return nullptr; }
DEF_INTERFACES_1 (IStreamAttributes, ReadOnlyBStream)
REFCOUNT_METHODS (ReadOnlyBStream)
protected:
String fileName;
};
//-----------------------------------------------------------------------------
PresetManager::PresetManager (VST3Plugin* plugin, const TUID& cid)
: plugin (plugin)
, visiblePresetBrowserViewController (nil)
, visibleSavePresetViewController (nil)
, cid (cid)
{
id obj = [[NSUserDefaults standardUserDefaults] objectForKey:@"PresetManager|lastPreset"];
if (obj && [obj isKindOfClass:[NSString class]])
{
lastPreset = [obj UTF8String];
}
}
//-----------------------------------------------------------------------------
NSArray* PresetManager::getPresetPaths (PresetPathType type)
{
if (type == kFactory)
{
return [[NSBundle mainBundle] URLsForResourcesWithExtension:@"vstpreset"
subdirectory:@"Presets"];
}
NSFileManager* fs = [NSFileManager defaultManager];
NSURL* documentsUrl = [fs URLForDirectory:NSDocumentDirectory
inDomain:NSUserDomainMask
appropriateForURL:Nil
create:YES
error:NULL];
if (documentsUrl)
{
NSMutableArray* userUrls = [NSMutableArray new];
NSDirectoryEnumerator* enumerator =
[fs enumeratorAtURL:documentsUrl
includingPropertiesForKeys:nil
options:NSDirectoryEnumerationSkipsSubdirectoryDescendants
errorHandler:nil];
for (NSURL* url in enumerator.allObjects)
{
if ([[url pathExtension] isEqualToString:@"vstpreset"])
{
[userUrls addObject:url];
}
}
return [userUrls sortedArrayUsingComparator:^NSComparisonResult (NSURL* obj1, NSURL* obj2) {
return [[obj1 lastPathComponent] caseInsensitiveCompare:[obj2 lastPathComponent]];
}];
}
return nil;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API PresetManager::runLoadPresetBrowser ()
{
if (visiblePresetBrowserViewController != nil)
return kResultFalse;
addRef ();
visiblePresetBrowserViewController =
[[PresetBrowserViewController alloc] initWithCallback:[this] (const char* path) {
loadPreset (path);
visiblePresetBrowserViewController = nil;
release ();
}];
addRef ();
dispatch_async (dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
if (visiblePresetBrowserViewController)
{
[visiblePresetBrowserViewController setFactoryPresets:getPresetPaths (kFactory)
userPresets:getPresetPaths (kUser)];
}
release ();
});
return kResultTrue;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API PresetManager::runSavePresetBrowser ()
{
if (visibleSavePresetViewController != nil)
return kResultFalse;
addRef ();
visibleSavePresetViewController =
[[PresetSaveViewController alloc] initWithCallback:[this] (const char* path) {
savePreset (path);
visibleSavePresetViewController = nil;
release ();
}];
return kResultTrue;
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API PresetManager::loadNextPreset ()
{
return loadPreset (true);
}
//-----------------------------------------------------------------------------
tresult PLUGIN_API PresetManager::loadPreviousPreset ()
{
return loadPreset (false);
}
//-----------------------------------------------------------------------------
tresult PresetManager::loadPreset (bool next)
{
NSArray* presets =
[[getPresetPaths (kFactory) arrayByAddingObjectsFromArray:getPresetPaths (kUser)]
sortedArrayUsingComparator:^NSComparisonResult (NSURL* obj1, NSURL* obj2) {
return [[obj1 lastPathComponent] caseInsensitiveCompare:[obj2 lastPathComponent]];
}];
__block NSUInteger index = NSNotFound;
if (lastPreset.isEmpty () == false)
{
NSURL* lastUrl =
[[NSURL fileURLWithPath:[NSString stringWithUTF8String:lastPreset]] fileReferenceURL];
if (lastUrl)
{
[presets enumerateObjectsUsingBlock:^(NSURL* obj, NSUInteger idx, BOOL* stop) {
if ([[obj fileReferenceURL] isEqual:lastUrl])
{
index = idx;
*stop = YES;
}
}];
}
}
if (index == NSNotFound)
{
if (next)
index = [presets count] - 1;
else
index = 1;
}
if (index != NSNotFound)
{
if (next)
{
if (index >= [presets count] - 1)
index = 0;
else
index++;
}
else
{
if (index == 0)
index = [presets count] - 1;
else
index--;
}
return loadPreset ([[[presets objectAtIndex:index] path] UTF8String]);
}
return kResultFalse;
}
//-----------------------------------------------------------------------------
tresult PresetManager::loadPreset (const char* path)
{
if (path)
{
IPtr<IBStream> stream = owned (FileStream::open (path, "r"));
if (stream)
{
[[NSUserDefaults standardUserDefaults] setObject:[NSString stringWithUTF8String:path]
forKey:@"PresetManager|lastPreset"];
lastPreset = path;
auto component = U::cast<IComponent> (plugin->getAudioProcessor ());
IEditController* controller = plugin->getEditController ();
if (component)
{
PresetFile pf (stream);
if (!pf.readChunkList ())
return kResultFalse;
if (pf.getClassID () != cid)
return kResultFalse;
const PresetFile::Entry* e = pf.getEntry (kComponentState);
if (e == nullptr)
return kResultFalse;
auto filename = strrchr (path, '/');
if (filename)
filename++;
IPtr<PresetStream> readOnlyBStream =
owned (new PresetStream (stream, e->offset, e->size, filename));
tresult result = component->setState (readOnlyBStream);
if ((result == kResultTrue || result == kNotImplemented) && controller)
{
readOnlyBStream->seek (0, IBStream::kIBSeekSet);
controller->setComponentState (readOnlyBStream);
if (pf.contains (kControllerState))
{
e = pf.getEntry (kControllerState);
if (e)
{
readOnlyBStream =
owned (new PresetStream (stream, e->offset, e->size, filename));
controller->setState (readOnlyBStream);
}
}
}
return result;
}
}
}
return kResultFalse;
}
//-----------------------------------------------------------------------------
void PresetManager::savePreset (const char* path)
{
IBStream* stream = FileStream::open (path, "w");
if (stream)
{
auto component = U::cast<IComponent> (plugin->getAudioProcessor ());
IEditController* controller = plugin->getEditController ();
if (component)
{
PresetFile::savePreset (stream, cid, component, controller);
}
stream->release ();
loadPreset (path);
}
}
}
}
} // namespaces