Commit 11af293a authored by jhammen's avatar jhammen
Browse files

implement state save method

parent e26cbe97
......@@ -22,21 +22,26 @@
namespace handrumr {
class Instrument {
string mName;
int mKey;
Layer *mLayers;
int layerCount;
int mLayerCount;
public:
Instrument() {}
string &name() { return mName; }
void name(const string &n) { mName = n; }
int key() { return mKey; }
void key(int key) { mKey = key; }
void layers(Layer *layers, int count) {
mLayers = layers;
layerCount = count;
mLayerCount = count;
}
Layer *layers() { return mLayers; }
int layerCount() { return mLayerCount; }
Sample *sample(int velocity) {
int index = 0;
while(mLayers[index].min() < velocity
&& index < layerCount) { index++; }
&& index < mLayerCount) { index++; }
return mLayers[index-1].sample();
}
};
......
......@@ -23,7 +23,7 @@ class Layer
{
int mMin;
Sample *mSamples;
int sampleCount;
int mSampleCount;
float totalWeight;
public:
Layer() : totalWeight(0.0) {}
......@@ -31,18 +31,20 @@ public:
int min() { return mMin; }
void samples(Sample *samples, int count) {
mSamples = samples;
sampleCount = count;
for(int i = 0; i < sampleCount; i++) {
mSampleCount = count;
for(int i = 0; i < mSampleCount; i++) {
totalWeight += mSamples[i].weight();
mSamples[i].weight(totalWeight);
mSamples[i].totalWeight(totalWeight);
}
}
Sample *samples() { return mSamples; }
int sampleCount() { return mSampleCount; }
Sample *sample() {
float roll = static_cast <float> (rand())
/ (static_cast <float> (RAND_MAX/totalWeight));
int index = 0;
while(mSamples[index].weight() < roll
&& index < sampleCount - 1) { index++; }
while(mSamples[index].totalWeight() < roll
&& index < mSampleCount - 1) { index++; }
return &mSamples[index];
}
};
......
......@@ -64,18 +64,8 @@ void Plugin::connectPort(uint32_t port, void *data)
LV2_State_Status Plugin::restore(LV2_State_Retrieve_Function retrieve, LV2_State_Handle handle,
uint32_t flags, const LV2_Feature* const* features)
{
// Get host features
LV2_State_Map_Path* paths = NULL;
const char* missing = lv2_features_query(features,
LV2_STATE__mapPath, &paths, true, NULL);
if (missing) {
printf("Missing feature <%s>\n", missing);
return LV2_STATE_ERR_NO_FEATURE;
}
size_t size;
uint32_t type;
uint32_t valflags;
uint32_t type, valflags;
const void* value = retrieve(handle, uris.hd_config, &size, &type, &valflags);
if (!value) {
printf("Missing config\n");
......@@ -93,11 +83,12 @@ LV2_State_Status Plugin::restore(LV2_State_Retrieve_Function retrieve, LV2_State
}
Json::Value jsonInstrs = root["instruments"];
string base = root["folder"].asString();
sampleBase = root["folder"].asString();
instruments = new handrumr::Instrument[jsonInstrs.size()];
instrumentCount = jsonInstrs.size();
for(int i = 0; i < instrumentCount; i++) {
instruments[i].key(jsonInstrs[i]["key"].asInt());
instruments[i].name(jsonInstrs[i]["name"].asString());
// layers
Json::Value jsonLayers = jsonInstrs[i]["layers"];
int layerCount = jsonLayers.size();
......@@ -112,7 +103,7 @@ LV2_State_Status Plugin::restore(LV2_State_Retrieve_Function retrieve, LV2_State
if(jsonSamples[j].isMember("weight")) {
samples[j].weight(jsonSamples[j]["weight"].asFloat());
}
samples[j].load(base + '/' + jsonSamples[j]["file"].asString());
samples[j].load(sampleBase, jsonSamples[j]["file"].asString());
}
layers[l].samples(samples, sampleCount);
}
......@@ -124,7 +115,41 @@ LV2_State_Status Plugin::restore(LV2_State_Retrieve_Function retrieve, LV2_State
LV2_State_Status Plugin::save(LV2_State_Store_Function store, LV2_State_Handle handle,
uint32_t flags, const LV2_Feature* const* features)
{
// TODO: implement
// create json config
Json::Value root;
root["folder"] = sampleBase;
Json::Value jsonInstruments(Json::arrayValue);
for(int i = 0; i < instrumentCount; i++) {
Json::Value jsonInstrument;
jsonInstrument["name"] = instruments[i].name();
jsonInstrument["key"] = instruments[i].key();
Json::Value jsonLayers(Json::arrayValue);
Layer *layers = instruments[i].layers();
for(int l = 0; l < instruments[i].layerCount(); l++) {
Json::Value jsonLayer;
jsonLayer["min"] = layers[l].min();
Json::Value jsonSamples(Json::arrayValue);
Sample *samples = layers[l].samples();
for(int s = 0; s < layers[l].sampleCount(); s++) {
Json::Value jsonSample;
jsonSample["file"] = samples[s].file();
if(samples[s].weight() != 1.0) {
jsonSample["weight"] = samples[s].weight();
}
jsonSamples.append(jsonSample);
}
jsonLayer["samples"] = jsonSamples;
jsonLayers.append(jsonLayer);
}
jsonInstrument["layers"] = jsonLayers;
jsonInstruments.append(jsonInstrument);
}
root["instruments"] = jsonInstruments;
string configString = root.toStyledString();
// call host-provided store method
store(handle, uris.hd_config, configString.c_str(), configString.length() + 1,
uris.atom_string, LV2_STATE_IS_POD);
return LV2_STATE_SUCCESS;
}
......
......@@ -88,6 +88,7 @@ class Plugin
// config
Instrument *instruments;
int instrumentCount;
string sampleBase;
public:
Plugin(const LV2_Feature* const*);
void activated(bool state) { mActivated = state; }
......
......@@ -18,14 +18,20 @@
#include <stdexcept>
void Sample::load(const string &path)
void Sample::load(const string &base, const string &path)
{
string fullPath;
if(base.length() > 0) {
fullPath.append(base);
fullPath.append("/");
}
fullPath.append(path);
SF_INFO info;
SNDFILE* const sndfile = sf_open(path.c_str(), SFM_READ, &info);
SNDFILE* const sndfile = sf_open(fullPath.c_str(), SFM_READ, &info);
if (!sndfile || !info.frames) {
std::string mesg("failed to load sample ");
mesg.append(path);
mesg.append(fullPath);
throw std::logic_error(mesg);
}
if(info.channels != 1) {
......@@ -33,6 +39,7 @@ void Sample::load(const string &path)
}
// Read data
mFile = path;
mSize = info.frames;
mData = new float[mSize];
sf_seek(sndfile, 0ul, SEEK_SET);
......
......@@ -25,15 +25,20 @@ using std::string;
class Sample
{
string mFile;
float *mData;
float mWeight;
float mTotalWeight;
sf_count_t mSize;
public:
Sample() : mSize(0), mWeight(1.0) {}
void load(const string &path);
void load(const string &base, const string &path);
sf_count_t size() { return mSize; }
string const &file() { return mFile; }
void weight(float w) { mWeight = w; }
float weight() { return mWeight; }
void totalWeight(float w) { mTotalWeight = w; }
float totalWeight() { return mTotalWeight; }
float *data() { return mData; }
};
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment