aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/opcodes.cpp153
1 files changed, 153 insertions, 0 deletions
diff --git a/src/opcodes.cpp b/src/opcodes.cpp
new file mode 100644
index 0000000..bcfb014
--- /dev/null
+++ b/src/opcodes.cpp
@@ -0,0 +1,153 @@
+#include "guttersynth.h"
+#include "plugin.h"
+#include "handling.h"
+
+static const char* badHandle = "guttersynth handle is not valid";
+static csnd::Csound* cs = NULL;
+
+void* allocate(size_t size) {
+ return cs->malloc(size);
+}
+
+void deallocate(void* item) {
+ cs->free(item);
+}
+
+
+/*
+ from max patch
+
+ sliders:
+ * singlegain = gain
+ * c = damp + (matrix out) , clipped
+ * dt = rate
+ * gamma = q
+ */
+
+class GutterSynth {
+ gutter_state* g;
+ csnd::Table* tGain;
+ csnd::Table* tFreq;
+ csnd::Table* tQ;
+ int dataSize;
+
+ void update_tables() {
+ int changed = 0;
+ for (int b = 0; b < g->bankCount; b++) {
+ if (memcmp(g->gains+(g->filterCount*b), tGain[b].data(), dataSize) != 0) {
+ memcpy(g->gains+(g->filterCount*b), tGain[b].data(), dataSize);
+ changed = 1;
+ }
+ if (memcmp(g->filterFreqs+(g->filterCount*b), tFreq[b].data(), dataSize) != 0) {
+ memcpy(g->filterFreqs+(g->filterCount*b), tFreq[b].data(), dataSize);
+ changed = 1;
+ }
+ if (memcmp(g->Q+(g->filterCount*b), tQ[b].data(), dataSize) != 0) {
+ memcpy(g->Q+(g->filterCount*b), tQ[b].data(), dataSize);
+ changed = 1;
+ }
+ }
+ if (changed) {
+ gutter_calccoeffs(g);
+ }
+ }
+};
+
+
+
+// ibankcount, ifiltercount, igaintbls[], ifreqtbls[], iqtables[], kgamma, komega, kc, kdt, ksinglegain, kfiltersOn, ksmoothing, kdistmethod
+struct gutter : csnd::Plugin<1, 13> {
+ static constexpr char const *otypes = "a";
+ static constexpr char const *itypes = "iii[]i[]i[]kkkkkkkk";
+
+ gutter_state* g;
+ csnd::Table* tGain;
+ csnd::Table* tFreq;
+ csnd::Table* tQ;
+ int dataSize;
+
+ int init() {
+ if (cs == NULL) cs = csound;
+ csound->plugin_deinit(this);
+
+ g = gutter_init_ca(
+ (int)inargs[0], (int)inargs[1], csound->sr(),
+ &allocate,
+ &deallocate
+ );
+
+ csnd::Vector<MYFLT> &ftsGain = inargs.vector_data<MYFLT>(2);
+ csnd::Vector<MYFLT> &ftsFreq = inargs.vector_data<MYFLT>(3);
+ csnd::Vector<MYFLT> &ftsQ = inargs.vector_data<MYFLT>(4);
+
+ if (ftsGain.len() != g->bankCount) return csound->init_error("Gain tables do not match bank count");
+ if (ftsFreq.len() != g->bankCount) return csound->init_error("Frequency tables do not match bank count");
+ if (ftsQ.len() != g->bankCount) return csound->init_error("Q tables do not match bank count");
+
+ tGain = (csnd::Table*) csound->malloc(sizeof(csnd::Table) * g->bankCount);
+ tFreq = (csnd::Table*) csound->malloc(sizeof(csnd::Table) * g->bankCount);
+ tQ = (csnd::Table*) csound->malloc(sizeof(csnd::Table) * g->bankCount);
+
+ for (int b = 0; b < g->bankCount; b++) {
+ tGain[b].init(csound, &ftsGain[b]);
+ tFreq[b].init(csound, &ftsFreq[b]);
+ tQ[b].init(csound, &ftsQ[b]);
+ }
+
+ update_tables();
+ g->enableAudioInput = 0;
+ dataSize = sizeof(MYFLT) * g->filterCount;
+
+ return OK;
+ }
+
+ void update_tables() {
+ int changed = 0;
+ for (int b = 0; b < g->bankCount; b++) {
+ if (memcmp(g->gains+(g->filterCount*b), tGain[b].data(), dataSize) != 0) {
+ memcpy(g->gains+(g->filterCount*b), tGain[b].data(), dataSize);
+ changed = 1;
+ }
+ if (memcmp(g->filterFreqs+(g->filterCount*b), tFreq[b].data(), dataSize) != 0) {
+ memcpy(g->filterFreqs+(g->filterCount*b), tFreq[b].data(), dataSize);
+ changed = 1;
+ }
+ if (memcmp(g->Q+(g->filterCount*b), tQ[b].data(), dataSize) != 0) {
+ memcpy(g->Q+(g->filterCount*b), tQ[b].data(), dataSize);
+ changed = 1;
+ }
+ }
+ if (changed) {
+ gutter_calccoeffs(g);
+ }
+ }
+
+ int deinit() {
+ csound->free(tGain);
+ csound->free(tFreq);
+ csound->free(tQ);
+ gutter_cleanup(g);
+ return OK;
+ }
+
+ int aperf() {
+ update_tables(); // on trig?
+ g->gamma = inargs[5];
+ g->omega = inargs[6];
+ g->c = inargs[7];
+ g->dt = inargs[8];
+ g->singleGain = inargs[9];
+ g->filtersOn = (int) inargs[10];
+ g->smoothing = inargs[11];
+ g->distortionMethod = inargs[12];
+
+ gutter_process_samples(g, outargs(0), nsmps);
+
+ return OK;
+ }
+};
+
+#include <modload.h>
+void csnd::on_load(csnd::Csound *csound) {
+ csnd::plugin<gutter>(csound, "gutter", csnd::thread::ia);
+}