From 5d31136bd3be537866dc867d2c2bc094e3222dde Mon Sep 17 00:00:00 2001 From: Richard Knight Date: Fri, 20 Jun 2025 18:33:18 +0100 Subject: initial --- src/opcodes.cpp | 590 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 590 insertions(+) create mode 100644 src/opcodes.cpp (limited to 'src/opcodes.cpp') diff --git a/src/opcodes.cpp b/src/opcodes.cpp new file mode 100644 index 0000000..a480b4e --- /dev/null +++ b/src/opcodes.cpp @@ -0,0 +1,590 @@ +#include +#include +#include +#include +#include + + +// incorporates samplebummer + +// inputs: kamp, kdensity, krepeattrig, kbufread, kbufmode(0,1,2) [ibufsize] +struct bitchrandom : csnd::Plugin<1, 6> { + static constexpr char const *otypes = "a"; + static constexpr char const *itypes = "kkkkkj"; + MYFLT* buffer; + int bufferSize; + int writePos; + MYFLT last; + + int init() { + bufferSize = (inargs[3] > 0 && inargs[3] < 441000) ? inargs[5] : 4096; + srand(time(NULL)); + buffer = (MYFLT*) csound->malloc(sizeof(MYFLT) * bufferSize); + writePos = 0; + csound->plugin_deinit(this); + return OK; + } + + int deinit() { + csound->free(buffer); + return OK; + } + + int aperf() { + MYFLT aout; + MYFLT doPlay; + int boffs; + + + for (int i = 0; i < nsmps; i++) { + aout = 0; + + doPlay = inargs[1] * ((MYFLT)rand() / RAND_MAX); + + if (doPlay > 0.5) { + aout = ((MYFLT)rand() / RAND_MAX) * inargs[0]; + } + + + buffer[writePos] = aout; + if (writePos + 1 < bufferSize) { + writePos++; + } else { + writePos = 0; + } + if (inargs[3] <= 0) { + boffs = 0; + } else if (inargs[3] >= 1) { + boffs = bufferSize-1; + } else { + boffs = inargs[3] * bufferSize; + } + + + + if (inargs[4] == FL(1)) { + aout -= buffer[boffs]; + } else if (inargs[4] == FL(2)) { + aout += buffer[boffs]; + } + + if (inargs[2] >= 1) { + aout = last; + } else { + last = aout; + } + outargs(0)[i] = aout; + } + return OK; + } +}; + +struct bitchglitch : csnd::Plugin<1, 3> { + static constexpr char const *otypes = "a"; + static constexpr char const *itypes = "akk"; + MYFLT* buffer; + int buffer_size; + int read_position; + int write_position; + int max_read_size; + + int init() { + MYFLT max_seconds = 0.2; + buffer_size = (int) (max_seconds * csound->sr()); + buffer = (MYFLT*) csound->malloc(sizeof(MYFLT) * buffer_size); + read_position = 0; + write_position = 0; + max_read_size = buffer_size; + return OK; + } + + int aperf() { + bool writing = *(inargs(1)) <= 0; + + if (!writing) { + MYFLT relative_max_size = *(inargs(2)); + if (relative_max_size > 1) { + relative_max_size = 1; + } + max_read_size = (int) (relative_max_size * buffer_size); + if (max_read_size < 4) { + max_read_size = 4; + } + } + + for (int i = 0; i < nsmps; i++) { + if (writing) { + outargs(0)[i] = inargs(0)[i]; + if (write_position >= buffer_size) { + write_position = 0; + } + buffer[write_position] = inargs(0)[i]; + write_position++; + } else { + if (read_position >= max_read_size) { + read_position = 0; + } + + outargs(0)[i] = buffer[read_position]; + read_position++; + } + } + return OK; + } +}; + +// aout bitchwreck ain ibuffersize ktrig +struct bitchwreck : csnd::Plugin<1, 3> { + static constexpr char const *otypes = "a"; + static constexpr char const *itypes = "aik"; + csnd::AuxMem buffer1; + csnd::AuxMem buffer2; + int changed; + int read_position; + int write_position; + int buffer_read; + int buffer_write; + + int init() { + buffer1.allocate(csound, csound->sr() * inargs[1]); + buffer2.allocate(csound, csound->sr() * inargs[1]); + buffer_read = 0; + buffer_write = 1; + changed = 1; + write_position = 0; + read_position = 0; + reset(); + return OK; + } + + void reset() { + read_position = buffer1.len() - 1; + } + + int aperf() { + int i = 0; + if (UNLIKELY(inargs[2] >= 1)) { + if (changed) { + reset(); + changed = 0; + } + while (i < nsmps) { + if (buffer_read == 0) { + outargs(0)[i] = buffer1[read_position]; + } else { + outargs(0)[i] = buffer2[read_position]; + } + if (read_position == 0) { + reset(); + } else { + read_position--; + } + i++; + } + } else { + changed = 1; + while (i < nsmps) { + if (buffer_write == 0) { + buffer1[write_position] = inargs(0)[i]; + } else { + buffer2[write_position] = inargs(0)[i]; + } + + if (write_position < buffer1.len()) { + write_position++; + } else { + write_position = 0; + buffer_write = 1 - buffer_write; + buffer_read = 1 - buffer_read; + } + outargs(0)[i] = inargs(0)[i]; + i++; + } + } + return OK; + } +}; + + + +struct bitchpan : csnd::Plugin<2, 2> { + static constexpr char const *otypes = "aa"; + static constexpr char const *itypes = "aP"; + int position; + int panned; + + int init() { + position = 0; + panned = 0; + return OK; + } + + int aperf() { + + for (int i = 0; i < nsmps; i++) { + + if (panned >= inargs[1]) { + panned = 0; + position = 1 - position; + } else { + panned ++; + } + + if (position == 0) { + outargs(0)[i] = inargs(0)[i]; + outargs(1)[i] = 0; + } else { + outargs(0)[i] = 0; + outargs(1)[i] = inargs(0)[i]; + } + } + return OK; + } +}; + + + + +// TODO make it actually do something interesting +struct bitchbuffer1 : csnd::Plugin<1, 4> { + static constexpr char const *otypes = "a"; + static constexpr char const *itypes = "aikk"; + + MYFLT* bufferz; + + csnd::AuxMem buffer1; + int read_position; + int write_position; + int buffer_size; + + + int init() { + read_position = 0; + write_position = 0; + buffer_size = (int) inargs[1]; + + + if (buffer_size < 128) { + //csound->message("Buffer minimum is 128"); // wtf?? causes fuck out. + buffer_size = 128; + } + buffer1.allocate(csound, inargs[1]); + bufferz = (MYFLT*) csound->malloc(sizeof (MYFLT) * buffer_size); + + return OK; + } + + int aperf() { + for (int i = 0; i < nsmps; i++) { + if (UNLIKELY(write_position >= buffer_size)) { + write_position = 0; + } + + bufferz[write_position] = inargs(0)[i]; + write_position++; + + if (UNLIKELY(read_position >= buffer_size)) { + read_position = 0; + } + + if (UNLIKELY(read_position <= 0)) { + read_position = buffer_size - 1; + } + + + } + return OK; + } +}; + + +struct bitchaverage : csnd::Plugin<1, 3> { + static constexpr char const *otypes = "a"; + static constexpr char const *itypes = "aPj"; + MYFLT* buffer; + MYFLT lastval; + int write_position; + int buffer_size; + + int init() { + write_position = 0; + //buffer_size = 150; //(int) csound->get_csound()->GetKsmps(); + buffer_size = (inargs[2] == FL(-1)) ? (int) ksmps() : inargs[2]; + lastval = -1; + buffer = (MYFLT*) csound->malloc(sizeof(MYFLT) * buffer_size); + return OK; + } + + MYFLT get_buffersize() { + MYFLT buffer_ratio = inargs[1]; + if (buffer_ratio > 1) { + buffer_ratio = 1; + } else if (buffer_ratio <= 0) { + buffer_ratio = 0.0001; + } + return buffer_size * buffer_ratio; + } + + MYFLT get_average() { + MYFLT total; + + int len = get_buffersize(); + for (int i = 0; i < len; i++) { + total += buffer[i]; + } + return total / len; + } + + int aperf() { + int len = get_buffersize(); + int i; + for (i = 0; i < nsmps; i++) { + if (UNLIKELY(write_position >= len)) { + write_position = 0; + } + buffer[write_position] = inargs(0)[i]; + + write_position ++; + + } + + MYFLT average = get_average(); + if (lastval == -1) { + for (i = 0; i < nsmps; i++) { + outargs(0)[i] = average; + } + } else { + MYFLT increment; + if (average > lastval) { + increment = (average - lastval)/nsmps; + } else { + increment = (lastval - average)/nsmps; + } + + for (i = 0; i < nsmps; i++) { + outargs(0)[i] = lastval+(increment*(i+1)); + } + } + + lastval = average; + return OK; + } + +}; + + +struct bitchpeaker : csnd::Plugin<1, 4> { + static constexpr char const *otypes = "a"; + static constexpr char const *itypes = "aPJjj"; + MYFLT* buffer; + MYFLT* out_buffer; + MYFLT* consider_buffer; + int* positions_buffer; + int* ends_buffer; + int buffer_size; + int read_position; + int write_position; + int consider_range; + bool reading; + + int init() { + buffer_size = (inargs[4] == FL(-1)) ? (int) ksmps() : inargs[2]; + if (buffer_size < 128) { + //csound->message("Buffer minimum is 128"); + buffer_size = 128; + } + buffer = (MYFLT*) csound->malloc(sizeof(MYFLT) * buffer_size); + out_buffer = (MYFLT*) csound->malloc(sizeof(MYFLT) * buffer_size); + positions_buffer = (int*) csound->malloc(sizeof(int) * buffer_size); + ends_buffer = (int*) csound->malloc(sizeof(int) * buffer_size); + reading = false; + read_position = 0; + write_position = 0; + int buffer_decimation = (int) ((inargs[3] == -1) ? 64 : inargs[3]); + consider_range = (int) buffer_size / buffer_decimation; + consider_buffer = (MYFLT*) csound->malloc(sizeof(MYFLT) * consider_range); + return OK; + } + + MYFLT get_considerationratio() { + MYFLT ratio = inargs[2]; + if (ratio == FL(-1)) { + ratio = 0.3; + } else if (ratio > 1) { + ratio = 1; + } else if (ratio <= 0) { + ratio = 0.0001; + } + return ratio; + } + + MYFLT get_buffersize() { + MYFLT buffer_ratio = inargs[1]; + if (buffer_ratio > 1) { + buffer_ratio = 1; + } else if (buffer_ratio <= 0) { + buffer_ratio = 0.0001; + } + return buffer_size * buffer_ratio; + } + + void shiftInConsidered(MYFLT newVal) { + for (int i = 0; i < consider_range - 1; i++) { + consider_buffer[i] = consider_buffer[i+1]; + } + consider_buffer[consider_range - 1] = newVal; + } + + + + bool eligible() { + MYFLT crphalf = get_considerationratio() * 0.5; + MYFLT cplow = consider_buffer[0] * (1 - crphalf); + MYFLT cphigh = consider_buffer[0] * (1 + crphalf); + for (int i = 1; i < consider_range; i++) { + if (consider_buffer[i] < cplow || consider_buffer[i] > cphigh) { + return false; + } + } + return true; + } + + + int inPositions(int targetIndex) { + int len = get_buffersize(); + for (int i = 0; i < len; i++) { + if (positions_buffer[i] == targetIndex) { + return i; + } + } + return -1; + } + + + void completePositions() { + MYFLT crphalf = get_considerationratio() * 0.5; + MYFLT cplow; + MYFLT cphigh; + int currentIndex = -1; + int len = get_buffersize(); + for (int i = 0; i < len; i++) { + if (currentIndex == -1) { + if (inPositions(i) != -1) { + currentIndex = i; + + cplow = buffer[positions_buffer[currentIndex]] * (1 - crphalf); + cphigh = buffer[positions_buffer[currentIndex]] * (1 + crphalf); + } + } + + if (currentIndex != -1) { + + + if (buffer[i] < cplow || consider_buffer[i] > cphigh) { + ends_buffer[currentIndex] = buffer[i]; + currentIndex = -1; + } + } + } + } + + void sculpt() { + int len = get_buffersize(); + MYFLT total = 0; + int i; + for (i = 0; i < len; i++) { + total += buffer[i]; + } + MYFLT mean = total / len; + + int consider_index = 0; + + int items = 0; + + for (i = 0; i < len; i++) { + shiftInConsidered(buffer[i]); + if (eligible()) { + positions_buffer[items] = i; + items ++; + } + } + + completePositions(); + + bool inSection = false; + int currentStartIndex; + int lpos; + int currentSteps; + MYFLT stepDiv; + MYFLT headroom = 0.1; + for (i = 0; i < len; i++) { + if (items > 0) { + + if (inSection) { + + // roundings... + + out_buffer[i] = buffer[i] + (sin(PI*(lpos*stepDiv)) * headroom); + // ( sine(pi*DISTANCE) *headroom + + lpos++; + if (i >= ends_buffer[currentStartIndex]) { + inSection = false; + } + } else { + int test = inPositions(i); + if (test != -1) { + currentStartIndex = test; + inSection = true; + lpos = 0; + currentSteps = ends_buffer[currentStartIndex] - test; + stepDiv = (MYFLT) FL(1)/currentSteps; + } else { + out_buffer[i] = buffer[i]; + } + } + + } else { + out_buffer[i] = buffer[i]; + } + } + + } + + int aperf() { // some kind of windowed delay thing. + int len = get_buffersize(); + for (int i = 0; i < nsmps; i++) { + if (UNLIKELY(write_position >= len)) { + sculpt(); + write_position = 0; + } + + + if (UNLIKELY(read_position >= len)) { + read_position = 0; + } + + buffer[write_position] = inargs(0)[i]; + outargs(0)[i] = out_buffer[read_position]; + + write_position ++; + read_position ++; + } + return OK; + } +}; + +#include + +void csnd::on_load(csnd::Csound *csound) { + + csnd::plugin(csound, "bitchrandom", csnd::thread::ia); + csnd::plugin(csound, "bitchglitch", csnd::thread::ia); + csnd::plugin(csound, "bitchwreck", csnd::thread::ia); + csnd::plugin(csound, "bitchpan", csnd::thread::ia); + csnd::plugin(csound, "bitchbuffer1", csnd::thread::ia); + csnd::plugin(csound, "bitchpeaker", csnd::thread::ia); + csnd::plugin(csound, "bitchaverage", csnd::thread::ia); + + +} -- cgit v1.2.3