-
Notifications
You must be signed in to change notification settings - Fork 1
/
PyTschirpAttribute.cpp
120 lines (106 loc) · 3.49 KB
/
PyTschirpAttribute.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/*
Copyright (c) 2020 Christof Ruch. All rights reserved.
Dual licensed: Distributed under Affero GPL license by default, an MIT license is available for purchase
*/
#include "PyTschirpAttribute.h"
#include "Capability.h"
#include "SynthParameterDefinition.h"
#include "DetailedParametersCapability.h"
namespace py = pybind11;
PyTschirpAttribute::PyTschirpAttribute(std::shared_ptr<midikraft::Patch> patch, std::string const ¶m) : patch_(patch)
{
def_ = defByName(param);
}
PyTschirpAttribute::PyTschirpAttribute(std::shared_ptr<midikraft::Patch> patch, std::string const ¶m, int targetLayerNo) : patch_(patch)
{
def_ = defByName(param);
auto layerAccess = midikraft::Capability::hasCapability<midikraft::SynthMultiLayerParameterCapability>(def_);
if (!layerAccess) {
throw std::runtime_error("PyTschirp: Program Error: Parameter set does not support multi layers");
}
// This parameter definition targets a specific layer. This is used e.g. to access either Layer A or Layer B of a Prophet Rev2
layerAccess->setSourceLayer(targetLayerNo);
layerAccess->setTargetLayer(targetLayerNo);
}
void PyTschirpAttribute::set(int value)
{
auto intParam = midikraft::Capability::hasCapability<midikraft::SynthIntParameterCapability>(def_);
if (intParam) {
intParam->setInPatch(*patch_, value);
}
else {
throw std::runtime_error("PyTschirp: Illegal operation, can't set int type");
}
}
void PyTschirpAttribute::set(std::vector<int> data)
{
auto vectorParam = midikraft::Capability::hasCapability<midikraft::SynthVectorParameterCapability>(def_);
if (vectorParam) {
vectorParam->setInPatch(*patch_, data);
}
else {
throw std::runtime_error("PyTschirp: Illegal operation, can't set vector type");
}
}
py::object PyTschirpAttribute::get() const
{
if (!def_) {
return py::none();
}
if ((def_->type() == midikraft::SynthParameterDefinition::ParamType::INT_ARRAY)
|| (def_->type() == midikraft::SynthParameterDefinition::ParamType::LOOKUP_ARRAY))
{
auto vectorParam = midikraft::Capability::hasCapability<midikraft::SynthVectorParameterCapability>(def_);
if (vectorParam) {
std::vector<int> value;
if (!vectorParam->valueInPatch(*patch_, value)) {
throw std::runtime_error("PyTschirp: Internal error getting array from patch data!");
}
py::list result;
for (auto val : value) result.append(val);
return result;
}
else {
throw std::runtime_error("PyTschirp: Invalid type int array but no SynthVectorParameterCapability implemented");
}
}
else {
auto intParam = midikraft::Capability::hasCapability<midikraft::SynthIntParameterCapability>(def_);
if (intParam) {
int value;
if (intParam->valueInPatch(*patch_, value)) {
return py::int_(value);
}
}
else {
throw std::runtime_error("PyTschirp: Invalid type int but no SynthIntParameterCapability implemented");
}
}
// Invalid
throw std::runtime_error("PyTschirp: Invalid attribute index in patch");
}
std::string PyTschirpAttribute::asText() const
{
if (def_) {
return def_->valueInPatchToText(*patch_);
}
else {
return "unknown attribute";
}
}
std::shared_ptr <midikraft::SynthParameterDefinition> PyTschirpAttribute::def()
{
return def_;
}
std::shared_ptr<midikraft::SynthParameterDefinition> PyTschirpAttribute::defByName(std::string const &name) const
{
auto params = midikraft::Capability::hasCapability<midikraft::DetailedParametersCapability>(patch_);
if (params) {
for (auto param : params->allParameterDefinitions()) {
if (param->name() == name) {
return param;
}
}
}
return {};
}