Skip to content

Commit

Permalink
Update Soundmodels
Browse files Browse the repository at this point in the history
Updated soundmodel, soundmodelPoly and soundmodelMono to have ADSR and filter capabilities
  • Loading branch information
AaronCollins1999 committed Mar 21, 2022
1 parent a1ba7e3 commit 22ea2f3
Show file tree
Hide file tree
Showing 5 changed files with 156 additions and 29 deletions.
14 changes: 13 additions & 1 deletion src/SoundModel.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#define SOUNDMODEL_H

#include <vector>
#include "defs.hpp"
#include <defs.hpp>

namespace SYNTHPI {
namespace audio {
Expand Down Expand Up @@ -48,6 +48,18 @@ class SoundModel {

virtual void updateBank(unsigned int parameter)= 0;

virtual void updateAttack(unsigned int parameter)= 0;

virtual void updateDecay(unsigned int parameter)= 0;

virtual void updateSustain(unsigned int parameter)= 0;

virtual void updateRelease(unsigned int parameter)= 0;

virtual void updateCutoff(unsigned int parameter) =0;

virtual void updateRes(unsigned int parameter) =0;


};

Expand Down
49 changes: 43 additions & 6 deletions src/SoundModelMono.cpp
Original file line number Diff line number Diff line change
@@ -1,35 +1,38 @@
//SoundModelMono.cpp

#include "SoundModelMono.h"
#include "Lock.h"
#include <string>
#include <iostream>

using namespace SYNTHPI;
using namespace audio;

#define RELEASE_INIT (1024*1600) //? maybe just put that to 0.
//#define RELEASE_INIT (1024*1600) //? maybe just put that to 0.

SoundModelMono::SoundModelMono() {
this-> sampleratef=static_cast<float>(samplerate);
this-> waveosc.loadBank(1, SOURCE_PREGENERATED);
this->noteOn = false;
this->currentNote = -1;
this->release = 0; //replace by waveosc.getRelease();
myadsr.reset();
}

std::vector<sample_t> SoundModelMono::getSamples(int nSamples) {

std::vector<sample_t> buffer(nSamples);
std::vector<sample_t> adsrbuffer(nSamples);
std::vector<sample_t> OSCbuffer(nSamples);
lock.acquire();

release=myadsr.inRelease();

/* Allows us to render sound when in release or on state */
if(noteOn==true || release>0) {
if(noteOn==true || release>true) {
OSCbuffer= waveosc.getSamples(nSamples);

adsrbuffer=myadsr.getSamples(nSamples);

for (unsigned int i =0;i<nSamples;i++){
buffer[i]=OSCbuffer[i] //add ADSR mult here
buffer[i]=OSCbuffer[i]*adsrbuffer[i];
}
}else{
for (unsigned int i = 0; i<nSamples; i++){
Expand Down Expand Up @@ -63,6 +66,7 @@ void SoundModelMono::setNoteOn(int midinote) {
waveosc.setSemitone(midinote); //get the frequency to play at
noteOn = true;
currentNote = midinote;
myadsr.gate(true);

}
lock.release();
Expand All @@ -75,6 +79,7 @@ void SoundModelMono::setNoteOff(int midinote) {
/* Only turn of if we're actually playing that note */
if(currentNote == midinote) {
try{
myadsr.gate(false);
noteOn = false;
//currentNote = -1;
//release = waveosc.getRelease(); //return release time as a number of samples it will take for the ADSR to get back to 0 based on sampling rate
Expand Down Expand Up @@ -106,8 +111,40 @@ void SoundModelMono::updateBank(unsigned int parameter) {
}
}

void SoundModelMono::updateAttack(unsigned int parameter){
float paramf=log10(1.002+99.0*(static_cast<float>(parameter)/127.0));
float rate=2.0*paramf*sampleratef; //0 to 10s with log response
//std::cout<<2.0*paramf<<std::endl;
myadsr.setAttackRate(rate);
}

void SoundModelMono::updateDecay(unsigned int parameter){
float paramf=log10(1.0+99.0*(static_cast<float>(parameter)/127.0));
float rate=2.0*paramf*sampleratef; //0 to 10s with log response std::cout<<rate<<std::endl;
//std::cout<<paramf*2.0<<std::endl;
myadsr.setDecayRate(rate);
}

void SoundModelMono::updateSustain(unsigned int parameter){
float paramf=log10(1.001+99.0*static_cast<float>(parameter)/127.0);
float level=paramf/2.0; //0 to 10s with log response level=logf(static_cast<float>(parameter+1)/128.0); //0. to 1. with log response
//std::cout<<level<<std::endl;
myadsr.setSustainLevel(level);
}

void SoundModelMono::updateRelease(unsigned int parameter){
float paramf=log10(1.001+99.0*(static_cast<float>(parameter)/127.0));
float rate=2.0*paramf*sampleratef; //0 to 10s with log response std::cout<<rate<<std::endl;
//std::cout<<2.0*paramf<<std::endl;
myadsr.setReleaseRate(rate);
}



//next functions are unused

void SoundModelMono::updateVolume(unsigned int parameter) {}

void SoundModelMono::updateCutoff(unsigned int parameter) {}

void SoundModelMono::updateRes(unsigned int parameter) {}
28 changes: 20 additions & 8 deletions src/SoundModelMono.h
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
#include "Thread.h"
#include "waveosc.hpp"
#include <Thread.h>
#include <waveosc.hpp>
#include "SoundModel.h"
#include "defs.hpp"
#include "Lock.h"
#include <defs.hpp>
#include <Lock.h>
#include <string>
#include <math.h>
#include <ADSR.h>

#ifndef SOUND_MODEL_MONO_H
#define SOUND_MODEL_MONO_H
Expand All @@ -21,16 +22,15 @@ namespace audio {
class SoundModelMono : public SoundModel {

protected:

ADSR myadsr;
WaveOSC waveosc; /* instance of a wave oscillator */
bool noteOn; /* True if a note is currently playing (not counting release) */
int currentNote; /* Current note being played */
int release; /* Countdown for how long isPlaying should return true after note released (number of samples it'll take the adsr to get back to 0 based on sampling rate) */


bool release=false; /* bool to check if isPlaying should return true even if the note is off */
int safeBank=1;
float sampleratef;
Lock lock; /* Main lock for all methods */
float sampleratef;

public:

Expand Down Expand Up @@ -77,6 +77,18 @@ class SoundModelMono : public SoundModel {

virtual void updateBank(unsigned int parameter) override;

virtual void updateAttack(unsigned int parameter) override;

virtual void updateDecay(unsigned int parameter) override;

virtual void updateSustain(unsigned int parameter) override;

virtual void updateRelease(unsigned int parameter) override;

virtual void updateCutoff(unsigned int parameter) override;

virtual void updateRes(unsigned int parameter) override;

};

} // namespace audio
Expand Down
53 changes: 47 additions & 6 deletions src/SoundModelPoly.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,11 @@ using namespace SYNTHPI;
using namespace audio;

SoundModelPoly::SoundModelPoly(const int poly, const int samplerate) {
VoiceNo=poly;
for (int i = 0; i < VoiceNo; i++) {
for (int i = 0; i < poly; i++) {
soundModelList.push_back(new SoundModelMono);

}
//std::cout << "SMP created" << std::endl;
VoiceNo=poly;
}

std::vector<sample_t> SoundModelPoly::getSamples(int nSamples){
Expand All @@ -34,15 +33,24 @@ std::vector<sample_t> SoundModelPoly::getSamples(int nSamples){
}

// Dezipper the audio output by changing the output gain progressively along the outbut buffer length,
// does the same for the filter cutoff and Q factor
float gain_step = (target_vol-master_vol)/nSamples;

float Fc_step = (target_Fc-Fc)/nSamples;
float Q_step = (target_Q-Q)/nSamples;
for(unsigned int i = 0; i < nSamples; i++) {

polybuffer[i] = polybuffer[i] * master_vol;
auto coeffs12=filter12.calculate_coeffs(Q,Fc,samplerate);
auto coeffs24=filter24.calculate_coeffs(Q,Fc,samplerate);

polybuffer[i] = filter24.process(filter12.process(polybuffer[i])) * master_vol;

master_vol += gain_step;
Fc+=Fc_step;
Q+=Q_step;
}
master_vol = target_vol;
Fc=target_Fc;
Q=target_Q;
return polybuffer;
}

Expand Down Expand Up @@ -111,4 +119,37 @@ void SoundModelPoly::updateBank(unsigned int parameter) {
for (unsigned int i=0; i<soundModelList.size();i++){
soundModelList[i]->updateBank(parameter);
}
}
}

void SoundModelPoly::updateAttack(unsigned int parameter) {
for (unsigned int i=0; i<soundModelList.size();i++){
soundModelList[i]->updateAttack(parameter);
}
}

void SoundModelPoly::updateDecay(unsigned int parameter) {
for (unsigned int i=0; i<soundModelList.size();i++){
soundModelList[i]->updateDecay(parameter);
}
}

void SoundModelPoly::updateSustain(unsigned int parameter) {
for (unsigned int i=0; i<soundModelList.size();i++){
soundModelList[i]->updateSustain(parameter);
}
}

void SoundModelPoly::updateRelease(unsigned int parameter) {
for (unsigned int i=0; i<soundModelList.size();i++){
soundModelList[i]->updateRelease(parameter);
}
}


void SoundModelPoly::updateCutoff(unsigned int parameter){
target_Fc=80.0+powf(18000.0,(static_cast<float>(parameter)/127.0));
}

void SoundModelPoly::updateRes(unsigned int parameter){
target_Q=0.707+10.0*(static_cast<float>(parameter)/127.0);
}
41 changes: 33 additions & 8 deletions src/SoundModelPoly.h
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
#include "SoundModel.h"
#include "defs.hpp"
#include <defs.hpp>
#include <string>
#include <vector>
#include <list>
#include <queue>

#include <filter_includes.h>
#include <filter_common.h>

#ifndef SOUND_MODEL_POLY_H
#define SOUND_MODEL_POLY_H
Expand All @@ -19,17 +21,29 @@ namespace audio {
class SoundModelPoly : public SoundModel {

private:

SO_LPF filter12;
SO_LPF filter24;
//float filtered_sample;
float Q=0.707;
float Fc=20000;

float target_Q=0.707;
float target_Fc=1500;
/*! a vector of soundmodelmono, ie a vector of the voices in synthpi */
std::vector<SoundModel*> soundModelList;

/*! */
int soundModelNo;

int lastSoundModel;
/*! a vector of int which keeps track of the order the voices are being turned on*/
//std::vector<int> lastSoundModel;

/*! same as std::vector<int> lastSoundModel but keeps track of the midinotes */
std::vector<int> midiNoteList;

/*! */
int soundModelNo;

int lastSoundModel;

/*! */
int VoiceNo;

Expand All @@ -44,14 +58,13 @@ class SoundModelPoly : public SoundModel {
/*! a buffer to return the sum of voices to playback engine*/
std::vector<sample_t> polybuffer;

int midinoteoffbuffer =-1;

public:
/**
* Create a SoundModelPoly with a given number of SoundModelMonos
* @param poly The numer of monophonic sound models to create
* @param samplerate Operating sample rate
* @param gain
* (optional) Multiply model outputs by this to yield the
* final result
*/
SoundModelPoly(const int poly, const int samplerate);

Expand Down Expand Up @@ -102,6 +115,18 @@ class SoundModelPoly : public SoundModel {

virtual void updateBank(unsigned int parameter) override;

virtual void updateAttack(unsigned int parameter) override;

virtual void updateDecay(unsigned int parameter) override;

virtual void updateSustain(unsigned int parameter) override;

virtual void updateRelease(unsigned int parameter) override;

virtual void updateCutoff(unsigned int parameter) override;

virtual void updateRes(unsigned int parameter) override;


};

Expand Down

0 comments on commit 22ea2f3

Please sign in to comment.