bw_sampler fixes + synth(pp)_sampler examples
This commit is contained in:
parent
2ceca5cc0c
commit
422cdcdb8d
5
examples/synth_sampler/src/android.json
Normal file
5
examples/synth_sampler/src/android.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"android": {
|
||||||
|
"javaPackageName": "com.orastron.bw_example_synth_sampler"
|
||||||
|
}
|
||||||
|
}
|
6
examples/synth_sampler/src/daisy-seed.json
Normal file
6
examples/synth_sampler/src/daisy-seed.json
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"daisy_seed": {
|
||||||
|
"parameterPins": [ -1, -1, 22 ],
|
||||||
|
"midiCCMaps": [ 7, 3, -1 ]
|
||||||
|
}
|
||||||
|
}
|
5
examples/synth_sampler/src/ios.json
Normal file
5
examples/synth_sampler/src/ios.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"ios": {
|
||||||
|
"productBundleIdentifier": "com.orastron.bw_example_synth_sampler"
|
||||||
|
}
|
||||||
|
}
|
10
examples/synth_sampler/src/lv2.json
Normal file
10
examples/synth_sampler/src/lv2.json
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"lv2": {
|
||||||
|
"prefixes": {
|
||||||
|
"bw_examples": "https://www.orastron.com/brickworks/examples/"
|
||||||
|
},
|
||||||
|
"uri": "@bw_examples:synth_sampler",
|
||||||
|
"types": [ "@lv2:InstrumentPlugin" ],
|
||||||
|
"version": "0.0"
|
||||||
|
}
|
||||||
|
}
|
136
examples/synth_sampler/src/plugin.h
Normal file
136
examples/synth_sampler/src/plugin.h
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
/*
|
||||||
|
* Brickworks
|
||||||
|
*
|
||||||
|
* Copyright (C) 2025 Orastron Srl unipersonale
|
||||||
|
*
|
||||||
|
* Brickworks is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, version 3 of the License.
|
||||||
|
*
|
||||||
|
* Brickworks is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Brickworks. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* File author: Stefano D'Angelo
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include <bw_math.h>
|
||||||
|
#include <bw_sampler.h>
|
||||||
|
#include <bw_gain.h>
|
||||||
|
#include <bw_ppm.h>
|
||||||
|
#include <bw_buf.h>
|
||||||
|
|
||||||
|
#define SAMPLE_LENGTH 10 // seconds
|
||||||
|
|
||||||
|
typedef struct plugin {
|
||||||
|
bw_sampler_coeffs sampler_coeffs;
|
||||||
|
bw_sampler_state sampler_state;
|
||||||
|
bw_gain_coeffs gain_coeffs;
|
||||||
|
bw_ppm_coeffs ppm_coeffs;
|
||||||
|
bw_ppm_state ppm_state;
|
||||||
|
|
||||||
|
float fs;
|
||||||
|
float * sample;
|
||||||
|
size_t sample_length;
|
||||||
|
|
||||||
|
float master_tune;
|
||||||
|
int note;
|
||||||
|
} plugin;
|
||||||
|
|
||||||
|
static void plugin_init(plugin *instance, plugin_callbacks *cbs) {
|
||||||
|
(void)cbs;
|
||||||
|
bw_sampler_init(&instance->sampler_coeffs);
|
||||||
|
bw_gain_init(&instance->gain_coeffs);
|
||||||
|
bw_ppm_init(&instance->ppm_coeffs);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void plugin_fini(plugin *instance) {
|
||||||
|
(void)instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void plugin_set_sample_rate(plugin *instance, float sample_rate) {
|
||||||
|
bw_sampler_set_sample_rate(&instance->sampler_coeffs, sample_rate);
|
||||||
|
bw_gain_set_sample_rate(&instance->gain_coeffs, sample_rate);
|
||||||
|
bw_ppm_set_sample_rate(&instance->ppm_coeffs, sample_rate);
|
||||||
|
|
||||||
|
instance->fs = sample_rate;
|
||||||
|
instance->sample_length = (size_t)bw_ceilf(sample_rate * SAMPLE_LENGTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t plugin_mem_req(plugin *instance) {
|
||||||
|
return instance->sample_length * sizeof(float);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void plugin_mem_set(plugin *instance, void *mem) {
|
||||||
|
instance->sample = (float *)mem;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void plugin_reset(plugin *instance) {
|
||||||
|
float p = 0.f;
|
||||||
|
float inc = 440.f / instance->fs;
|
||||||
|
for (size_t i = 0; i < instance->sample_length; i++) {
|
||||||
|
p += inc;
|
||||||
|
p = p - bw_floorf(p);
|
||||||
|
instance->sample[i] = bw_sin2pif(p);
|
||||||
|
}
|
||||||
|
bw_sampler_reset_coeffs(&instance->sampler_coeffs);
|
||||||
|
bw_sampler_reset_state(&instance->sampler_coeffs, &instance->sampler_state, instance->sample, instance->sample_length, 0.f);
|
||||||
|
bw_gain_reset_coeffs(&instance->gain_coeffs);
|
||||||
|
bw_ppm_reset_coeffs(&instance->ppm_coeffs);
|
||||||
|
bw_ppm_reset_state(&instance->ppm_coeffs, &instance->ppm_state, 0.f);
|
||||||
|
instance->note = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void plugin_set_parameter(plugin *instance, size_t index, float value) {
|
||||||
|
switch (index) {
|
||||||
|
case plugin_parameter_volume:
|
||||||
|
{
|
||||||
|
float v = 0.01f * value;
|
||||||
|
bw_gain_set_gain_lin(&instance->gain_coeffs, v * v * v);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case plugin_parameter_master_tune:
|
||||||
|
instance->master_tune = value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static float plugin_get_parameter(plugin *instance, size_t index) {
|
||||||
|
(void)index;
|
||||||
|
return bw_clipf(bw_ppm_get_y_z1(&instance->ppm_state), -60.f, 0.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void plugin_process(plugin *instance, const float **inputs, float **outputs, size_t n_samples) {
|
||||||
|
(void)inputs;
|
||||||
|
|
||||||
|
if (instance->note >= 0) {
|
||||||
|
bw_sampler_set_rate(&instance->sampler_coeffs,
|
||||||
|
(1.f / 440.f) * instance->master_tune * bw_pow2f(8.333333333333333e-2f * (instance->note - 69)));
|
||||||
|
bw_sampler_process(&instance->sampler_coeffs, &instance->sampler_state, instance->sample, instance->sample_length, outputs[0], n_samples);
|
||||||
|
} else
|
||||||
|
bw_sampler_reset_state(&instance->sampler_coeffs, &instance->sampler_state, instance->sample, instance->sample_length, 0.f); // sloppy but simple coding
|
||||||
|
bw_gain_process(&instance->gain_coeffs, outputs[0], outputs[0], n_samples);
|
||||||
|
bw_ppm_process(&instance->ppm_coeffs, &instance->ppm_state, outputs[0], NULL, n_samples);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void plugin_midi_msg_in(plugin *instance, size_t index, const uint8_t * data) {
|
||||||
|
(void)index;
|
||||||
|
switch (data[0] & 0xf0) {
|
||||||
|
case 0x90: // note on
|
||||||
|
if (data[2] == 0) { // no, note off actually
|
||||||
|
if (data[1] == instance->note)
|
||||||
|
instance->note = -1;
|
||||||
|
} else
|
||||||
|
instance->note = data[1];
|
||||||
|
break;
|
||||||
|
case 0x80: // note off
|
||||||
|
if (data[1] == instance->note)
|
||||||
|
instance->note = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
58
examples/synth_sampler/src/product.json
Normal file
58
examples/synth_sampler/src/product.json
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
{
|
||||||
|
"product": {
|
||||||
|
"name": "Brickworks sampler synth example",
|
||||||
|
"bundleName": "bw_example_synth_sampler",
|
||||||
|
"buses": [
|
||||||
|
{
|
||||||
|
"type": "midi",
|
||||||
|
"direction": "input",
|
||||||
|
"name": "MIDI input",
|
||||||
|
"shortName": "MIDI input",
|
||||||
|
"id": "midi_in"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "audio",
|
||||||
|
"direction": "output",
|
||||||
|
"channels": "mono",
|
||||||
|
"name": "Output",
|
||||||
|
"shortName": "Output",
|
||||||
|
"id": "output"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "Volume",
|
||||||
|
"shortName": "Volume",
|
||||||
|
"id": "volume",
|
||||||
|
"direction": "input",
|
||||||
|
"defaultValue": 50.0,
|
||||||
|
"minimum": 0.0,
|
||||||
|
"maximum": 100.0,
|
||||||
|
"unit": "pc",
|
||||||
|
"map": "linear"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Master tune",
|
||||||
|
"shortName": "Master tune",
|
||||||
|
"id": "master_tune",
|
||||||
|
"direction": "input",
|
||||||
|
"defaultValue": 440.0,
|
||||||
|
"minimum": 415.304697579945,
|
||||||
|
"maximum": 466.1637615180899,
|
||||||
|
"unit": "hz",
|
||||||
|
"map": "logarithmic"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Level",
|
||||||
|
"shortName": "Level",
|
||||||
|
"id": "level",
|
||||||
|
"direction": "output",
|
||||||
|
"defaultValue": -60.0,
|
||||||
|
"minimum": -60.0,
|
||||||
|
"maximum": 0.0,
|
||||||
|
"unit": "db",
|
||||||
|
"map": "linear"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
11
examples/synth_sampler/src/vst3.json
Normal file
11
examples/synth_sampler/src/vst3.json
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"vst3": {
|
||||||
|
"plugin": {
|
||||||
|
"cid": "7f8982241131453cbb649f1e09e17ad3"
|
||||||
|
},
|
||||||
|
"controller": {
|
||||||
|
"cid": "5dd7bef0661a4f7583b4260586a5d400"
|
||||||
|
},
|
||||||
|
"subCategory": "Instrument|Synth"
|
||||||
|
}
|
||||||
|
}
|
5
examples/synthpp_sampler/src/android.json
Normal file
5
examples/synthpp_sampler/src/android.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"android": {
|
||||||
|
"javaPackageName": "com.orastron.bw_example_synthpp_sampler"
|
||||||
|
}
|
||||||
|
}
|
6
examples/synthpp_sampler/src/daisy-seed.json
Normal file
6
examples/synthpp_sampler/src/daisy-seed.json
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"daisy_seed": {
|
||||||
|
"parameterPins": [ -1, -1, 22 ],
|
||||||
|
"midiCCMaps": [ 7, 3, -1 ]
|
||||||
|
}
|
||||||
|
}
|
157
examples/synthpp_sampler/src/impl.cpp
Normal file
157
examples/synthpp_sampler/src/impl.cpp
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
/*
|
||||||
|
* Brickworks
|
||||||
|
*
|
||||||
|
* Copyright (C) 2025 Orastron Srl unipersonale
|
||||||
|
*
|
||||||
|
* Brickworks is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, version 3 of the License.
|
||||||
|
*
|
||||||
|
* Brickworks is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Brickworks. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* File author: Stefano D'Angelo
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "impl.h"
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include <bw_math.h>
|
||||||
|
#include <bw_sampler.h>
|
||||||
|
#include <bw_gain.h>
|
||||||
|
#include <bw_ppm.h>
|
||||||
|
#include <bw_buf.h>
|
||||||
|
|
||||||
|
#define SAMPLE_LENGTH 10 // seconds
|
||||||
|
|
||||||
|
using namespace Brickworks;
|
||||||
|
|
||||||
|
class Engine {
|
||||||
|
public:
|
||||||
|
Sampler<1> sampler;
|
||||||
|
Gain<1> gain;
|
||||||
|
PPM<1> ppm;
|
||||||
|
|
||||||
|
float fs;
|
||||||
|
float * sample;
|
||||||
|
size_t sampleLength;
|
||||||
|
|
||||||
|
float masterTune;
|
||||||
|
int note;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
impl impl_new(void) {
|
||||||
|
Engine *instance = new Engine();
|
||||||
|
return reinterpret_cast<impl>(instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
void impl_free(impl handle) {
|
||||||
|
Engine *instance = reinterpret_cast<Engine *>(handle);
|
||||||
|
delete instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
void impl_set_sample_rate(impl handle, float sample_rate) {
|
||||||
|
Engine *instance = reinterpret_cast<Engine *>(handle);
|
||||||
|
instance->sampler.setSampleRate(sample_rate);
|
||||||
|
instance->gain.setSampleRate(sample_rate);
|
||||||
|
instance->ppm.setSampleRate(sample_rate);
|
||||||
|
|
||||||
|
instance->fs = sample_rate;
|
||||||
|
instance->sampleLength = (size_t)bw_ceilf(sample_rate * SAMPLE_LENGTH);
|
||||||
|
|
||||||
|
instance->sample = new float[instance->sampleLength];
|
||||||
|
}
|
||||||
|
|
||||||
|
void impl_reset(impl handle) {
|
||||||
|
Engine *instance = reinterpret_cast<Engine *>(handle);
|
||||||
|
float p = 0.f;
|
||||||
|
float inc = 440.f / instance->fs;
|
||||||
|
for (size_t i = 0; i < instance->sampleLength; i++) {
|
||||||
|
p += inc;
|
||||||
|
p = p - bw_floorf(p);
|
||||||
|
instance->sample[i] = bw_sin2pif(p);
|
||||||
|
}
|
||||||
|
#ifdef WASM
|
||||||
|
const float *sample[1] = {instance->sample};
|
||||||
|
const size_t sampleLength[1] = {instance->sampleLength};
|
||||||
|
instance->sampler.reset(sample, sampleLength);
|
||||||
|
#else
|
||||||
|
instance->sampler.reset({instance->sample}, {instance->sampleLength}, 0.f, {BW_NULL});
|
||||||
|
#endif
|
||||||
|
instance->gain.reset();
|
||||||
|
instance->ppm.reset();
|
||||||
|
instance->note = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void impl_set_parameter(impl handle, size_t index, float value) {
|
||||||
|
Engine *instance = reinterpret_cast<Engine *>(handle);
|
||||||
|
switch (index) {
|
||||||
|
case plugin_parameter_volume:
|
||||||
|
{
|
||||||
|
float v = 0.01f * value;
|
||||||
|
instance->gain.setGainLin(v * v * v);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case plugin_parameter_master_tune:
|
||||||
|
instance->masterTune = value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float impl_get_parameter(impl handle, size_t index) {
|
||||||
|
(void)index;
|
||||||
|
Engine *instance = reinterpret_cast<Engine *>(handle);
|
||||||
|
return bw_clipf(instance->ppm.getYZ1(0), -60.f, 0.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void impl_process(impl handle, const float **inputs, float **outputs, size_t n_samples) {
|
||||||
|
(void)inputs;
|
||||||
|
|
||||||
|
Engine *instance = reinterpret_cast<Engine *>(handle);
|
||||||
|
|
||||||
|
#ifdef WASM
|
||||||
|
const float *sample[1] = {instance->sample};
|
||||||
|
const size_t sampleLength[1] = {instance->sampleLength};
|
||||||
|
float *y[1] = {outputs[0]};
|
||||||
|
if (instance->note >= 0) {
|
||||||
|
instance->sampler.setRate((1.f / 440.f) * instance->masterTune * bw_pow2f(8.333333333333333e-2f * (instance->note - 69)));
|
||||||
|
instance->sampler.process(sample, sampleLength, y, n_samples);
|
||||||
|
} else
|
||||||
|
instance->sampler.reset(sample, sampleLength); // sloppy but simple coding
|
||||||
|
#else
|
||||||
|
if (instance->note >= 0) {
|
||||||
|
instance->sampler.setRate((1.f / 440.f) * instance->masterTune * bw_pow2f(8.333333333333333e-2f * (instance->note - 69)));
|
||||||
|
instance->sampler.process({instance->sample}, {instance->sampleLength}, {outputs[0]}, n_samples);
|
||||||
|
} else
|
||||||
|
instance->sampler.reset({instance->sample}, {instance->sampleLength}, 0.f, {BW_NULL}); // sloppy but simple coding
|
||||||
|
#endif
|
||||||
|
instance->gain.process(outputs, outputs, n_samples);
|
||||||
|
instance->ppm.process(outputs, nullptr, n_samples);
|
||||||
|
}
|
||||||
|
|
||||||
|
void impl_midi_msg_in(impl handle, size_t index, const uint8_t * data) {
|
||||||
|
(void)index;
|
||||||
|
Engine *instance = reinterpret_cast<Engine *>(handle);
|
||||||
|
switch (data[0] & 0xf0) {
|
||||||
|
case 0x90: // note on
|
||||||
|
if (data[2] == 0) { // no, note off actually
|
||||||
|
if (data[1] == instance->note)
|
||||||
|
instance->note = -1;
|
||||||
|
} else
|
||||||
|
instance->note = data[1];
|
||||||
|
break;
|
||||||
|
case 0x80: // note off
|
||||||
|
if (data[1] == instance->note)
|
||||||
|
instance->note = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
5
examples/synthpp_sampler/src/ios.json
Normal file
5
examples/synthpp_sampler/src/ios.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"ios": {
|
||||||
|
"productBundleIdentifier": "com.orastron.bw_example_synthpp_sampler"
|
||||||
|
}
|
||||||
|
}
|
10
examples/synthpp_sampler/src/lv2.json
Normal file
10
examples/synthpp_sampler/src/lv2.json
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"lv2": {
|
||||||
|
"prefixes": {
|
||||||
|
"bw_examples": "https://www.orastron.com/brickworks/examples/"
|
||||||
|
},
|
||||||
|
"uri": "@bw_examples:synthpp_sampler",
|
||||||
|
"types": [ "@lv2:InstrumentPlugin" ],
|
||||||
|
"version": "0.0"
|
||||||
|
}
|
||||||
|
}
|
58
examples/synthpp_sampler/src/product.json
Normal file
58
examples/synthpp_sampler/src/product.json
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
{
|
||||||
|
"product": {
|
||||||
|
"name": "Brickworks sampler synth example (C++)",
|
||||||
|
"bundleName": "bw_example_synthpp_sampler",
|
||||||
|
"buses": [
|
||||||
|
{
|
||||||
|
"type": "midi",
|
||||||
|
"direction": "input",
|
||||||
|
"name": "MIDI input",
|
||||||
|
"shortName": "MIDI input",
|
||||||
|
"id": "midi_in"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "audio",
|
||||||
|
"direction": "output",
|
||||||
|
"channels": "mono",
|
||||||
|
"name": "Output",
|
||||||
|
"shortName": "Output",
|
||||||
|
"id": "output"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "Volume",
|
||||||
|
"shortName": "Volume",
|
||||||
|
"id": "volume",
|
||||||
|
"direction": "input",
|
||||||
|
"defaultValue": 50.0,
|
||||||
|
"minimum": 0.0,
|
||||||
|
"maximum": 100.0,
|
||||||
|
"unit": "pc",
|
||||||
|
"map": "linear"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Master tune",
|
||||||
|
"shortName": "Master tune",
|
||||||
|
"id": "master_tune",
|
||||||
|
"direction": "input",
|
||||||
|
"defaultValue": 440.0,
|
||||||
|
"minimum": 415.304697579945,
|
||||||
|
"maximum": 466.1637615180899,
|
||||||
|
"unit": "hz",
|
||||||
|
"map": "logarithmic"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Level",
|
||||||
|
"shortName": "Level",
|
||||||
|
"id": "level",
|
||||||
|
"direction": "output",
|
||||||
|
"defaultValue": -60.0,
|
||||||
|
"minimum": -60.0,
|
||||||
|
"maximum": 0.0,
|
||||||
|
"unit": "db",
|
||||||
|
"map": "linear"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
11
examples/synthpp_sampler/src/vst3.json
Normal file
11
examples/synthpp_sampler/src/vst3.json
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"vst3": {
|
||||||
|
"plugin": {
|
||||||
|
"cid": "00de68a0424c4b3b9a260cd6e2d01f5c"
|
||||||
|
},
|
||||||
|
"controller": {
|
||||||
|
"cid": "659dbfa4fedb43fb8fcb1b52168dd0b2"
|
||||||
|
},
|
||||||
|
"subCategory": "Instrument|Synth"
|
||||||
|
}
|
||||||
|
}
|
@ -325,12 +325,11 @@ static inline float bw_sampler_interpolate(
|
|||||||
const float * BW_RESTRICT sample,
|
const float * BW_RESTRICT sample,
|
||||||
size_t sample_length,
|
size_t sample_length,
|
||||||
float pos) {
|
float pos) {
|
||||||
{
|
|
||||||
BW_ASSERT(sample_length > 0);
|
BW_ASSERT(sample_length > 0);
|
||||||
|
|
||||||
float xm1, x0, x1, x2, d;
|
float xm1, x0, x1, x2, d;
|
||||||
if (pos >= 1.f) {
|
if (pos >= 1.f) {
|
||||||
const size_t p = static_cast<const size_t>(pos);
|
const size_t p = (size_t)pos;
|
||||||
if (p + 2 < sample_length) {
|
if (p + 2 < sample_length) {
|
||||||
xm1 = sample[p - 1];
|
xm1 = sample[p - 1];
|
||||||
x0 = sample[p];
|
x0 = sample[p];
|
||||||
@ -494,7 +493,7 @@ static inline float bw_sampler_process1(
|
|||||||
BW_ASSERT_DEEP(bw_has_only_finite(sample, sample_length));
|
BW_ASSERT_DEEP(bw_has_only_finite(sample, sample_length));
|
||||||
|
|
||||||
float y;
|
float y;
|
||||||
if (state->pos >= sample_length + 2) {
|
if (state->pos <= sample_length + 2) {
|
||||||
y = bw_sampler_interpolate(sample, sample_length, state->pos);
|
y = bw_sampler_interpolate(sample, sample_length, state->pos);
|
||||||
state->pos += coeffs->rate;
|
state->pos += coeffs->rate;
|
||||||
state->phase = bw_sampler_phase_playing;
|
state->phase = bw_sampler_phase_playing;
|
||||||
|
Loading…
Reference in New Issue
Block a user