SmartGuitarAmp

Guitar plugin made with JUCE that uses neural networks to emulate a tube amplifier
Log | Files | Refs | Submodules | README

ConvolutionStack.cpp (3071B)


      1 /*
      2   ==============================================================================
      3 
      4     ConvolutionStack.cpp
      5     Created: 8 Jan 2019 5:21:49pm
      6     Author:  Damskägg Eero-Pekka
      7 
      8   ==============================================================================
      9 */
     10 
     11 #include "ConvolutionStack.h"
     12 
     13 ConvolutionStack::ConvolutionStack(int numChannels, int filterWidth, std::vector<int> dilations, std::string activation, bool residual) :
     14     dilations(dilations),
     15     residual(residual),
     16     numChannels(numChannels),
     17     filterWidth(filterWidth),
     18     activation(activation)
     19 {
     20     initLayers();
     21 }
     22 
     23 void ConvolutionStack::prepareToPlay(int newNumSamples)
     24 {
     25     samplesPerBlock = newNumSamples;
     26     residualData.setSize(1, samplesPerBlock * numChannels);
     27 }
     28 
     29 void ConvolutionStack::copyResidual(float *data, int numSamples)
     30 {
     31     auto writePtr = residualData.getWritePointer(0);
     32     for (size_t i = 0; i < numSamples * numChannels; ++i)
     33         writePtr[i] = data[i];
     34 }
     35 
     36 void ConvolutionStack::addResidual(float *data, int numSamples)
     37 {
     38     const auto readPtr = residualData.getWritePointer(0);
     39     for (size_t i = 0; i < numSamples * numChannels; ++i)
     40         data[i] = data[i] + readPtr[i];
     41 }
     42 
     43 void ConvolutionStack::process(float *data, float* skipData, int numSamples)
     44 {
     45     if (numSamples > samplesPerBlock)
     46         prepareToPlay(numSamples);
     47     for (int i = 0; i < dilations.size(); ++i)  
     48     {
     49         if (residual)
     50             copyResidual(data, numSamples);
     51         float *skipPtr = getSkipPointer(skipData, i, numSamples);
     52         layers[i].process(data, skipPtr, numSamples);
     53         if (residual)
     54             addResidual(data, numSamples);
     55     }
     56 }
     57 
     58 float* ConvolutionStack::getSkipPointer(float *skipData, int layerIdx, int numSamples)
     59 {
     60     int startCh = numChannels * layerIdx;
     61     int startIdx = idx(startCh, 0, numSamples);
     62     return &skipData[startIdx];
     63 }
     64 
     65 int ConvolutionStack::idx(int ch, int i, int numSamples)
     66 {
     67     return ch * numSamples + i;
     68 }
     69 
     70 void ConvolutionStack::setWeight(std::vector<float> W, int layerIdx, std::string name)
     71 {
     72     layers[layerIdx].setWeight(W, name);
     73 }
     74 
     75 void ConvolutionStack::setParams(int newNumChannels,
     76                                  int newFilterWidth,
     77                                  std::vector<int> newDilations,
     78                                  std::string newActivation,
     79                                  bool newResidual)
     80 {
     81     numChannels = newNumChannels;
     82     filterWidth = newFilterWidth;
     83     dilations = newDilations;
     84     activation = newActivation;
     85     residual = newResidual;
     86     initLayers();
     87     prepareToPlay(samplesPerBlock);
     88 }
     89 
     90 void ConvolutionStack::initLayers()
     91 {
     92     layers.clear();
     93     layers.reserve(dilations.size());
     94     for (size_t i = 0; i < dilations.size(); ++i)
     95         layers.push_back(ConvolutionLayer(numChannels,
     96                                           numChannels,
     97                                           filterWidth,
     98                                           dilations[i],
     99                                           residual,
    100                                           activation));
    101 }