Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
No results found
Show changes
Showing
with 1009 additions and 535 deletions
#include "maximilian.h"
maxiOsc myCounter,mySwitchableOsc;//these oscillators will help us count and make sound.
int CurrentCount;//we're going to put the current count in this variable so that we can use it more easily.
double myOscOutput;//we're going to stick the output here to make it easier to mess with stuff.
void setup() {//some inits
//nothing to go here this time
}
void play(double *output) {
CurrentCount=myCounter.phasor(1, 1, 9);//phasor can take three arguments; frequency, start value and end value.
if (CurrentCount<5)//simple if statement
myOscOutput=mySwitchableOsc.square(CurrentCount*100);
else if (CurrentCount>=5)//and the 'else' bit.
myOscOutput=mySwitchableOsc.sinewave(CurrentCount*50);//one osc object can produce whichever waveform you want.
*output=myOscOutput;//point me at your speakers and fire.
}
#include "maximilian.h"
maxiOsc myCounter,mySwitchableOsc;//
int CurrentCount;//
double myOscOutput,myCurrentVolume;//
double myEnvelopeData[4] = {1,0,0,500};//this data will be used to make an envelope. Value and time to value in ms.
maxiEnvelope myEnvelope;
void setup() {//some inits
myEnvelope.amplitude=myEnvelopeData[0]; //initialise the envelope
}
void play(double *output) {
myCurrentVolume=myEnvelope.line(4,myEnvelopeData);
CurrentCount=myCounter.phasor(1, 1, 9);//phasor can take three arguments; frequency, start value and end value.
if (CurrentCount<5)//simple if statement
myOscOutput=mySwitchableOsc.square(CurrentCount*100);
else if (CurrentCount>=5)//and the 'else' bit.
myOscOutput=mySwitchableOsc.sinewave(CurrentCount*50);//one osc object can produce whichever waveform you want.
if (CurrentCount==1)
myEnvelope.trigger(0,myEnvelopeData[0]); //trigger the envelope
*output=myOscOutput*myCurrentVolume;//point me at your speakers and fire.
}
// quick_example.cpp
#include <emscripten/bind.h>
#include "math.h"
#include "mylib-2.h"
#define TWOPI 6.283185307179586476925286766559
using namespace emscripten;
// This is a transition table that helps with bandlimited oscs.
double transition[1001]={-0.500003,-0.500003,-0.500023,-0.500063,-0.500121,-0.500179,-0.500259,
-0.50036,-0.500476,-0.500591,-0.500732,-0.500893,-0.501066,-0.501239,
-0.50144,-0.501661,-0.501891,-0.502123,-0.502382,-0.502662,-0.502949,
-0.50324,-0.503555,-0.503895,-0.504238,-0.504587,-0.504958,-0.505356,
-0.505754,-0.506162,-0.506589,-0.507042,-0.507495,-0.50796,-0.508444,
-0.508951,-0.509458,-0.509979,-0.510518,-0.511079,-0.511638,-0.512213,
-0.512808,-0.51342,-0.51403,-0.514659,-0.515307,-0.51597,-0.51663,-0.517312,
-0.518012,-0.518724,-0.519433,-0.520166,-0.520916,-0.521675,-0.522432,
-0.523214,-0.524013,-0.524819,-0.525624,-0.526451,-0.527298,-0.528147,
-0.528999,-0.52987,-0.530762,-0.531654,-0.532551,-0.533464,-0.534399,
-0.535332,-0.536271,-0.537226,-0.538202,-0.539172,-0.540152,-0.541148,
-0.542161,-0.543168,-0.544187,-0.54522,-0.546269,-0.54731,-0.548365,
-0.549434,-0.550516,-0.55159,-0.552679,-0.553781,-0.554893,-0.555997,
-0.557118,-0.558252,-0.559391,-0.560524,-0.561674,-0.562836,-0.564001,
-0.565161,-0.566336,-0.567524,-0.568712,-0.569896,-0.571095,-0.572306,
-0.573514,-0.574721,-0.575939,-0.577171,-0.578396,-0.579622,-0.580858,
-0.582108,-0.583348,-0.58459,-0.585842,-0.587106,-0.588358,-0.589614,
-0.590879,-0.592154,-0.593415,-0.594682,-0.595957,-0.59724,-0.598507,
-0.599782,-0.601064,-0.602351,-0.603623,-0.604902,-0.606189,-0.607476,
-0.60875,-0.610032,-0.611319,-0.612605,-0.613877,-0.615157,-0.616443,
-0.617723,-0.618992,-0.620268,-0.621548,-0.62282,-0.624083,-0.62535,
-0.626622,-0.627882,-0.629135,-0.630391,-0.631652,-0.632898,-0.634138,
-0.63538,-0.636626,-0.637854,-0.639078,-0.640304,-0.641531,-0.642739,
-0.643943,-0.645149,-0.646355,-0.647538,-0.64872,-0.649903,-0.651084,
-0.652241,-0.653397,-0.654553,-0.655705,-0.656834,-0.657961,-0.659087,
-0.660206,-0.661304,-0.662399,-0.663492,-0.664575,-0.665639,-0.666699,
-0.667756,-0.6688,-0.669827,-0.670849,-0.671866,-0.672868,-0.673854,
-0.674835,-0.675811,-0.676767,-0.677709,-0.678646,-0.679576,-0.680484,
-0.68138,-0.682269,-0.683151,-0.684008,-0.684854,-0.685693,-0.686524,
-0.687327,-0.688119,-0.688905,-0.689682,-0.690428,-0.691164,-0.691893,
-0.692613,-0.6933,-0.693978,-0.694647,-0.695305,-0.695932,-0.696549,
-0.697156,-0.697748,-0.698313,-0.698865,-0.699407,-0.699932,-0.700431,
-0.700917,-0.701391,-0.701845,-0.702276,-0.702693,-0.703097,-0.703478,
-0.703837,-0.704183,-0.704514,-0.704819,-0.705105,-0.705378,-0.705633,
-0.70586,-0.706069,-0.706265,-0.706444,-0.706591,-0.706721,-0.706837,
-0.706938,-0.707003,-0.707051,-0.707086,-0.707106,-0.707086,-0.707051,
-0.707001,-0.706935,-0.706832,-0.706711,-0.706576,-0.706421,-0.706233,
-0.706025,-0.705802,-0.705557,-0.705282,-0.704984,-0.704671,-0.704334,
-0.703969,-0.703582,-0.703176,-0.702746,-0.702288,-0.70181,-0.701312,
-0.700785,-0.700234,-0.699664,-0.69907,-0.698447,-0.6978,-0.697135,
-0.696446,-0.695725,-0.694981,-0.694219,-0.693435,-0.692613,-0.691771,
-0.690911,-0.69003,-0.689108,-0.688166,-0.687206,-0.686227,-0.685204,
-0.684162,-0.683101,-0.682019,-0.680898,-0.679755,-0.678592,-0.677407,
-0.676187,-0.674941,-0.673676,-0.672386,-0.671066,-0.669718,-0.66835,
-0.666955,-0.665532,-0.664083,-0.662611,-0.661112,-0.659585,-0.658035,
-0.656459,-0.654854,-0.653223,-0.651572,-0.649892,-0.648181,-0.646446,
-0.644691,-0.642909,-0.641093,-0.639253,-0.637393,-0.63551,-0.633588,
-0.631644,-0.62968,-0.627695,-0.625668,-0.623621,-0.621553,-0.619464,
-0.617334,-0.615183,-0.613011,-0.610817,-0.608587,-0.606333,-0.604058,
-0.60176,-0.599429,-0.597072,-0.594695,-0.592293,-0.589862,-0.587404,
-0.584925,-0.58242,-0.579888,-0.577331,-0.574751,-0.572145,-0.569512,
-0.566858,-0.564178,-0.561471,-0.558739,-0.555988,-0.553209,-0.550402,
-0.547572,-0.544723,-0.54185,-0.538944,-0.536018,-0.533072,-0.530105,
-0.527103,-0.524081,-0.52104,-0.51798,-0.514883,-0.511767,-0.508633,
-0.505479,-0.502291,-0.499083,-0.495857,-0.492611,-0.489335,-0.486037,
-0.48272,-0.479384,-0.476021,-0.472634,-0.46923,-0.465805,-0.462356,
-0.458884,-0.455394,-0.451882,-0.448348,-0.444795,-0.44122,-0.437624,
-0.434008,-0.430374,-0.426718,-0.423041,-0.419344,-0.415631,-0.411897,
-0.40814,-0.404365,-0.400575,-0.396766,-0.392933,-0.389082,-0.385217,
-0.381336,-0.377428,-0.373505,-0.369568,-0.365616,-0.361638,-0.357645,
-0.353638,-0.349617,-0.345572,-0.341512,-0.337438,-0.33335,-0.329242,
-0.325118,-0.32098,-0.316829,-0.31266,-0.308474,-0.304276,-0.300063,
-0.295836,-0.291593,-0.287337,-0.283067,-0.278783,-0.274487,-0.270176,
-0.265852,-0.261515,-0.257168,-0.252806,-0.248431,-0.244045,-0.239649,
-0.23524,-0.230817,-0.226385,-0.221943,-0.21749,-0.213024,-0.208548,
-0.204064,-0.199571,-0.195064,-0.190549,-0.186026,-0.181495,-0.176952,
-0.1724,-0.167842,-0.163277,-0.1587,-0.154117,-0.149527,-0.14493,-0.140325,
-0.135712,-0.131094,-0.12647,-0.121839,-0.117201,-0.112559,-0.10791,
-0.103257,-0.0985979,-0.0939343,-0.0892662,-0.0845935,-0.079917,-0.0752362,
-0.0705516,-0.0658635,-0.0611729,-0.0564786,-0.0517814,-0.0470818,-0.0423802,
-0.0376765,-0.0329703,-0.0282629,-0.0235542,-0.0188445,-0.0141335,-0.00942183,
-0.00470983,2.41979e-06,0.00471481,0.00942681,0.0141384,0.0188494,0.023559,
0.028268,0.0329754,0.0376813,0.0423851,0.0470868,0.0517863,0.0564836,
0.0611777,0.0658683,0.0705566,0.0752412,0.0799218,0.0845982,0.0892712,
0.0939393,0.0986028,0.103262,0.107915,0.112563,0.117206,0.121844,0.126475,
0.131099,0.135717,0.14033,0.144935,0.149531,0.154122,0.158705,0.163281,
0.167847,0.172405,0.176956,0.1815,0.18603,0.190553,0.195069,0.199576,
0.204068,0.208552,0.213028,0.217495,0.221947,0.226389,0.230822,0.235245,
0.239653,0.244049,0.248436,0.252811,0.257173,0.26152,0.265857,0.270181,
0.274491,0.278788,0.283071,0.287341,0.291597,0.29584,0.300068,0.30428,
0.308478,0.312664,0.316833,0.320984,0.325122,0.329246,0.333354,0.337442,
0.341516,0.345576,0.34962,0.353642,0.357649,0.361642,0.36562,0.369572,
0.373509,0.377432,0.38134,0.385221,0.389086,0.392936,0.39677,0.400579,
0.404369,0.408143,0.4119,0.415634,0.419347,0.423044,0.426721,0.430377,
0.434011,0.437627,0.441223,0.444798,0.448351,0.451885,0.455397,0.458887,
0.462359,0.465807,0.469232,0.472637,0.476024,0.479386,0.482723,0.486039,
0.489338,0.492613,0.49586,0.499086,0.502294,0.505481,0.508635,0.511769,
0.514885,0.517982,0.521042,0.524083,0.527105,0.530107,0.533074,0.53602,
0.538946,0.541851,0.544725,0.547574,0.550404,0.553211,0.555989,0.55874,
0.561472,0.564179,0.566859,0.569514,0.572146,0.574753,0.577332,0.579889,
0.582421,0.584926,0.587405,0.589863,0.592294,0.594696,0.597073,0.59943,
0.60176,0.604059,0.606333,0.608588,0.610818,0.613012,0.615183,0.617335,
0.619464,0.621553,0.623621,0.625669,0.627696,0.629681,0.631645,0.633588,
0.63551,0.637393,0.639253,0.641093,0.642909,0.644691,0.646446,0.648181,
0.649892,0.651572,0.653223,0.654854,0.656459,0.658035,0.659585,0.661112,
0.662611,0.664083,0.665532,0.666955,0.66835,0.669718,0.671066,0.672386,
0.673676,0.674941,0.676187,0.677407,0.678592,0.679755,0.680898,0.682019,
0.683101,0.684162,0.685204,0.686227,0.687206,0.688166,0.689108,0.69003,
0.690911,0.691771,0.692613,0.693435,0.694219,0.694981,0.695725,0.696447,
0.697135,0.6978,0.698447,0.69907,0.699664,0.700234,0.700786,0.701312,
0.70181,0.702288,0.702746,0.703177,0.703582,0.703969,0.704334,0.704671,
0.704984,0.705282,0.705557,0.705802,0.706025,0.706233,0.706422,0.706576,
0.706712,0.706832,0.706936,0.707002,0.707051,0.707086,0.707106,0.707086,
0.707051,0.707003,0.706939,0.706838,0.706721,0.706592,0.706445,0.706265,
0.70607,0.705861,0.705634,0.705378,0.705105,0.70482,0.704515,0.704184,
0.703837,0.703478,0.703097,0.702694,0.702276,0.701846,0.701392,0.700917,
0.700432,0.699932,0.699408,0.698866,0.698314,0.697749,0.697156,0.696549,
0.695933,0.695305,0.694648,0.693979,0.693301,0.692613,0.691894,0.691165,
0.690428,0.689683,0.688905,0.68812,0.687327,0.686525,0.685693,0.684854,
0.684009,0.683152,0.68227,0.68138,0.680485,0.679577,0.678647,0.67771,
0.676768,0.675811,0.674836,0.673855,0.672869,0.671867,0.670849,0.669827,
0.668801,0.667757,0.6667,0.66564,0.664576,0.663493,0.6624,0.661305,
0.660207,0.659088,0.657962,0.656834,0.655705,0.654553,0.653398,0.652241,
0.651085,0.649903,0.648721,0.647539,0.646356,0.645149,0.643944,0.642739,
0.641532,0.640304,0.639079,0.637855,0.636626,0.635381,0.634139,0.632899,
0.631652,0.630392,0.629136,0.627883,0.626622,0.62535,0.624083,0.62282,
0.621548,0.620268,0.618993,0.617724,0.616443,0.615158,0.613878,0.612605,
0.61132,0.610032,0.608751,0.607477,0.606189,0.604903,0.603623,0.602351,
0.601065,0.599782,0.598508,0.59724,0.595957,0.594682,0.593415,0.592154,
0.59088,0.589615,0.588359,0.587106,0.585843,0.584591,0.583349,0.582108,
0.580859,0.579623,0.578397,0.577172,0.575939,0.574721,0.573515,0.572307,
0.571095,0.569897,0.568713,0.567525,0.566337,0.565161,0.564002,0.562837,
0.561674,0.560525,0.559392,0.558252,0.557119,0.555998,0.554893,0.553782,
0.552679,0.55159,0.550516,0.549434,0.548365,0.54731,0.546269,0.54522,
0.544187,0.543168,0.542161,0.541148,0.540153,0.539173,0.538202,0.537226,
0.536271,0.535332,0.5344,0.533464,0.532551,0.531654,0.530762,0.52987,
0.528999,0.528147,0.527298,0.526451,0.525624,0.524819,0.524014,0.523214,
0.522432,0.521675,0.520916,0.520166,0.519433,0.518724,0.518012,0.517312,
0.51663,0.51597,0.515307,0.51466,0.51403,0.51342,0.512808,0.512213,
0.511638,0.511079,0.510518,0.509979,0.509458,0.508951,0.508444,0.50796,
0.507495,0.507042,0.506589,0.506162,0.505754,0.505356,0.504958,0.504587,
0.504237,0.503895,0.503555,0.50324,0.502949,0.502662,0.502382,0.502123,
0.501891,0.501661,0.50144,0.501239,0.501066,0.500893,0.500732,0.500591,
0.500476,0.50036,0.500259,0.500179,0.500121,0.500063,0.500023,0.500003,0.500003};
int maxiSettings::sampleRate = 44100;
int maxiSettings::channels = 2;
int maxiSettings::bufferSize = 1024;
maxiOsc::maxiOsc() {
phase = 0.0;
}
double maxiOsc::sawn(double frequency) {
if ( phase >= 0.5 ) phase -= 1.0;
// phase += (1./(44100.0/(frequency)));
phase += (1./(maxiSettings::sampleRate/(frequency)));
double temp=(8820.22/frequency)*phase;
if (temp<-0.5) {
temp=-0.5;
}
if (temp>0.5) {
temp=0.5;
}
temp*=1000.0f;
temp+=500.0f;
double remainder = temp - floor(temp);
output = (double) ((1.0f-remainder) * transition[(long)temp] + remainder * transition[1+(long)temp]) - phase;
return(output);
}
double maxiOsc::noise() {
//White Noise
//always the same unless you seed it.
float r = rand()/(float)RAND_MAX;
output=r*2-1;
return(output);
}
// void maxiOsc::phaseReset(double phaseIn) {
// //This allows you to set the phase of the oscillator to anything you like.
// phase=phaseIn;
// }
double maxiOsc::sinewave(double frequency) {
//This is a sinewave oscillator
output=sin (phase*(TWOPI));
if ( phase >= 1.0 ) phase -= 1.0;
phase += (1./(maxiSettings::sampleRate/(frequency)));
return(output);
}
double maxiFilter::lopass(double input, double cutoff) {
output=outputs[0] + cutoff*(input-outputs[0]);
outputs[0]=output;
return(output);
}
//awesome. cuttof is freq in hz. res is between 1 and whatever. Watch out!
double maxiFilter::lores(double input,double cutoff1, double resonance) {
cutoff=cutoff1*0.5;
if (cutoff<10) cutoff=10;
if (cutoff>(maxiSettings::sampleRate*0.5)) cutoff=(maxiSettings::sampleRate*0.5);
if (resonance<1.) resonance = 1.;
z=cos(TWOPI*cutoff/maxiSettings::sampleRate);
c=2-2*z;
double r=(sqrt(2.0)*sqrt(-pow((z-1.0),3.0))+resonance*(z-1))/(resonance*(z-1));
x=x+(input-y)*c;
y=y+x;
x=x*r;
output=y;
return(output);
}
//working hires filter
double maxiFilter::hires(double input,double cutoff1, double resonance) {
cutoff=cutoff1*0.5;
if (cutoff<10) cutoff=10;
if (cutoff>(maxiSettings::sampleRate*0.5)) cutoff=(maxiSettings::sampleRate*0.5);
if (resonance<1.) resonance = 1.;
z=cos(TWOPI*cutoff/maxiSettings::sampleRate);
c=2-2*z;
double r=(sqrt(2.0)*sqrt(-pow((z-1.0),3.0))+resonance*(z-1))/(resonance*(z-1));
x=x+(input-y)*c;
y=y+x;
x=x*r;
output=input-y;
return(output);
}
EMSCRIPTEN_BINDINGS(my_module) {
class_<maxiSettings>("maxiSettings")
.constructor<>()
.class_function("settup", &maxiSettings::setup)
;
class_<maxiOsc>("maxiOsc")
.constructor<>()
.function("sinewave", &maxiOsc::sinewave)
.function("sawn", &maxiOsc::sawn)
.function("noise", &maxiOsc::noise)
;
class_<maxiFilter>("maxiFilter")
.constructor<>()
.function("lopass", &maxiFilter::lopass)
.function("lores", &maxiFilter::lores)
.function("hires", &maxiFilter::hires)
;
}
//
// mylib-2.h
//
//
// Created by D J Clarke on 08/10/2015.
//
//
#ifndef _mylib_2_h
#define _mylib_2_h
class maxiSettings {
public:
static int sampleRate;
static int channels;
static int bufferSize;
static void setup(int initSampleRate, int initChannels, int initBufferSize) {
maxiSettings::sampleRate = initSampleRate;
maxiSettings::channels = initChannels;
maxiSettings::bufferSize = initBufferSize;
}
};
class maxiOsc {
double frequency;
double phase;
double startphase;
double endphase;
double output;
double tri;
public:
maxiOsc();
double sinewave(double frequency);
double coswave(double frequency);
double phasor(double frequency);
double phasor(double frequency, double startphase, double endphase);
double saw(double frequency);
double triangle(double frequency);
double square(double frequency);
double pulse(double frequency, double duty);
double noise();
double sinebuf(double frequency);
double sinebuf4(double frequency);
double sawn(double frequency);
double rect(double frequency, double duty=0.5);
void phaseReset(double phaseIn);
};
class maxiFilter {
double gain;
double input;
double output;
double inputs[10];
double outputs[10];
double cutoff1;
double x;//speed
double y;//pos
double z;//pole
double c;//filter coefficient
public:
maxiFilter():x(0.0), y(0.0), z(0.0), c(0.0){};
double cutoff;
double resonance;
double lores(double input,double cutoff1, double resonance);
double hires(double input,double cutoff1, double resonance);
double bandpass(double input,double cutoff1, double resonance);
double lopass(double input,double cutoff);
double hipass(double input,double cutoff);
};
#endif
......@@ -418,7 +418,7 @@ fft::fft(int fftSize) {
in_img = (float *) malloc(n * sizeof(float));
out_real = (float *) malloc(n * sizeof(float));
out_img = (float *) malloc(n * sizeof(float));
#ifdef __APPLE_CC__
log2n = log2(n);
A.realp = (float *) malloc(half * sizeof(float));
......@@ -532,6 +532,7 @@ void fft::convToDB_vdsp(float *in, float *out) {
#endif
void fft::inversePowerSpectrum(int start, float *finalOut, float *window, float *magnitude,float *phase) {
// void fft::inversePowerSpectrum(int start, float *finalOut, float *window, vector<float>& magnitude,vector<float>& phase) {
int i;
/* get real and imag part */
......@@ -559,6 +560,7 @@ void fft::inversePowerSpectrum(int start, float *finalOut, float *window, float
#ifdef __APPLE_CC__
void fft::inversePowerSpectrum_vdsp(int start, float *finalOut, float *window, float *magnitude,float *phase) {
//void fft::inversePowerSpectrum_vdsp(int start, float *finalOut, float *window, vector<float>& magnitude, std::vector<float>& phase) {
uint32_t i;
for (i = 0; i < half; i++) {
......
......@@ -41,7 +41,7 @@
#include <Accelerate/Accelerate.h>
#endif
#include <vector>
class fft {
......@@ -60,15 +60,20 @@ public:
FFTSetup setupReal;
COMPLEX_SPLIT A;
float *polar;
void powerSpectrum_vdsp(int start, float *data, float *window, float *magnitude,float *phase);
void inversePowerSpectrum_vdsp(int start, float *finalOut, float *window, float *magnitude,float *phase);
void powerSpectrum_vdsp(int start, float *data, float *window, float *magnitude,float *phase);
void inversePowerSpectrum_vdsp(int start, float *finalOut, float *window, float *magnitude,float *phase);
// void inversePowerSpectrum_vdsp(int start, float *finalOut, float *window, std::vector<float>& magnitude, std::vector<float>& phase);
void convToDB_vdsp(float *in, float *out);
#endif
/* Calculate the power spectrum */
void powerSpectrum(int start, float *data, float *window, float *magnitude, float *phase);
/* ... the inverse */
void inversePowerSpectrum(int start, float *finalOut, float *window, float *magnitude,float *phase);
void inversePowerSpectrum(int start, float *finalOut, float *window, float *magnitude,float *phase);
// void inversePowerSpectrum(int start, float *finalOut, float *window, std::vector<float>& magnitude,std::vector<float>& phase);
void convToDB(float *in, float *out);
static void genWindow(int whichFunction, int NumSamples, float *window);
......
......@@ -30,6 +30,7 @@ inline double binToHz(unsigned int bin, unsigned int sR, unsigned int bS) {
return bin*sR/bS;
}
// is T used anywhere?
template <class T>
class maxiBarkScaleAnalyser {
......
......@@ -50,14 +50,16 @@ void maxiFFT::setup(int _fftSize, int _windowSize, int _hopSize) {
bins = fftSize / 2;
hopSize = _hopSize;
buffer = (float *) malloc(fftSize * sizeof(float));
magnitudes = (float *) malloc(bins * sizeof(float));
// magnitudes = (float *) malloc(bins * sizeof(float));
magnitudes.resize(bins);
magnitudesDB = (float *) malloc(bins * sizeof(float));
phases = (float *) malloc(bins * sizeof(float));
// phases = (float *) malloc(bins * sizeof(float));
phases.resize(bins);
avgPower = new float;
memset(buffer, 0, fftSize * sizeof(float));
memset(magnitudes, 0, bins * sizeof(float));
// memset(magnitudes, 0, bins * sizeof(float));
memset(magnitudesDB, 0, bins * sizeof(float));
memset(phases, 0, bins * sizeof(float));
// memset(phases, 0, bins * sizeof(float));
*avgPower = 0;
pos =windowSize - hopSize;
newFFT = 0;
......@@ -73,9 +75,9 @@ bool maxiFFT::process(float value) {
newFFT = pos == windowSize;
if (newFFT) {
#if defined(__APPLE_CC__) && !defined(_NO_VDSP)
_fft->powerSpectrum_vdsp(0, buffer, window, magnitudes, phases);
_fft->powerSpectrum_vdsp(0, buffer, window, magnitudes.data(), phases.data());
#else
_fft->powerSpectrum(0, buffer, window, magnitudes, phases);
_fft->powerSpectrum(0, buffer, window, magnitudes.data(), phases.data());
#endif
//shift buffer back by one hop size
memcpy(buffer, buffer + hopSize, (windowSize - hopSize) * sizeof(float));
......@@ -89,9 +91,9 @@ bool maxiFFT::process(float value) {
float maxiFFT::magsToDB() {
#if defined(__APPLE_CC__) && !defined(_NO_VDSP)
_fft->convToDB_vdsp(magnitudes, magnitudesDB);
_fft->convToDB_vdsp(magnitudes.data(), magnitudesDB);
#else
_fft->convToDB(magnitudes, magnitudesDB);
_fft->convToDB(magnitudes.data(), magnitudesDB);
#endif
return *magnitudesDB;
}
......@@ -122,7 +124,7 @@ float maxiFFT::spectralCentroid() {
maxiFFT::~maxiFFT() {
delete _fft;
if (buffer)
delete[] buffer,magnitudes,phases,window, avgPower, magnitudesDB;
delete[] buffer,/*magnitudes,phases,*/window, avgPower, magnitudesDB;
}
......@@ -147,14 +149,17 @@ void maxiIFFT::setup(int _fftSize, int _windowSize, int _hopSize) {
fft::genWindow(3, windowSize, window);
}
float maxiIFFT::process(float *magnitudes, float *phases) {
//float maxiIFFT::process(float *magnitudes, float *phases) {
float maxiIFFT::process(std::vector<float>& magnitudes, std::vector<float>& phases) {
if (0==pos) {
//do ifft
memset(ifftOut, 0, fftSize * sizeof(float));
// use data() to pass first adrress of vectors
#if defined(__APPLE_CC__) && !defined(_NO_VDSP)
_fft->inversePowerSpectrum_vdsp(0, ifftOut, window, magnitudes, phases);
_fft->inversePowerSpectrum_vdsp(0, ifftOut, window, magnitudes.data(), phases.data());
#else
_fft->inversePowerSpectrum(0, ifftOut, window, magnitudes, phases);
_fft->inversePowerSpectrum(0, ifftOut, window, magnitudes.data(), phases.data());
#endif
//add to output
//shift back by one hop
......@@ -249,8 +254,8 @@ void maxiFFTOctaveAnalyzer::setup(float samplingRate, int nBandsInTheFFT, int nA
linearEQSlope = 0.0f; // unity -- no eq by default
}
void maxiFFTOctaveAnalyzer::calculate(float * fftData){
//void maxiFFTOctaveAnalyzer::calculate(float * fftData){
void maxiFFTOctaveAnalyzer::calculate(vector<float>& fftData){
int last_avgidx = 0; // tracks when we've crossed into a new averaging bin, so store current average
float sum = 0.0f; // running total of spectrum data
int count = 0; // count of spectrums accumulated (for averaging)
......
......@@ -6,7 +6,7 @@
* Copyright 2009 Mick Grierson & Strangeloop Limited. All rights reserved.
* Thanks to the Goldsmiths Creative Computing Team.
* Special thanks to Arturo Castro for the PortAudio implementation.
*
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
......@@ -15,11 +15,11 @@
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
......@@ -39,32 +39,84 @@
#include "fft.h"
#include "stddef.h"
#include "../maxi_emscr_new.h"
#include <vector>
class maxiFFT {
public:
maxiFFT(){
_fft = NULL;
buffer = magnitudes = phases = window = avgPower = NULL;
_fft = NULL;
buffer = /* magnitudes = phases = */window = avgPower = NULL;
};
~maxiFFT();
void setup(int fftSize, int windowSize, int hopSize);
bool process(float value);
float magsToDB();
float *magnitudes, *phases, *magnitudesDB;
float /* *magnitudes, *phases, */ *magnitudesDB;
vector<float> magnitudes, phases;
float *avgPower;
int windowSize;
int hopSize;
int bins;
vector<float> getMagnitudes() const{
return magnitudes;
}
vector<float> getPhases() const{
return phases;
}
// properties (emscr)
float getMagnitude(int n){
return magnitudes[n];
}
float getMagnitudeDB(int n){
return magnitudesDB[n];
}
float getPhase(int n){
return phases[n];
}
int getWindowSize() const{
return windowSize;
}
void setWindowSize(int size){
this->windowSize = size;
}
int getHopSize() const{
return hopSize;
}
void setHopSize(int size){
this->hopSize = size;
}
int getNumBins() const{
return hopSize;
}
void setNumBins(int n){
this->bins = n;
}
void setMagnitudes(vector<float> magnitudes_){
magnitudes = magnitudes_;
}
void setPhases(vector<float> phases_){
phases = phases_;
}
//features
float spectralFlatness();
float spectralCentroid();
private:
float *buffer, *window;
int pos;
......@@ -72,7 +124,7 @@ private:
int fftSize;
fft *_fft;
bool newFFT;
};
class maxiIFFT {
......@@ -83,8 +135,8 @@ public:
};
~maxiIFFT();
void setup(int fftSize, int windowSize, int hopSize);
float process(float *magnitudes, float *phases);
// float process(float *magnitudes, float *phases);
float process(std::vector<float>& magnitudes, std::vector<float>& phases);
private:
float *ifftOut, *buffer, *window;
int windowSize;
......@@ -98,8 +150,8 @@ private:
class maxiFFTOctaveAnalyzer {
/*based on code by David Bollinger, http://www.davebollinger.com/
*/
/*based on code by David Bollinger, http://www.davebollinger.com/
*/
public:
float samplingRate; // sampling rate in Hz (needed to calculate frequency spans)
......@@ -115,18 +167,132 @@ public:
int peakHoldTime; // how long do we hold peaks? (in fft frames)
float peakDecayRate; // how quickly the peaks decay: 0f=instantly .. 1f=not at all
int * spe2avg; // the mapping between spectrum[] indices and averages[] indices
// the fft's log equalizer() is no longer of any use (it would be nonsense to log scale
// the spectrum values into log-sized average bins) so here's a quick-and-dirty linear
// equalizer instead:
// the fft's log equalizer() is no longer of any use (it would be nonsense to log scale
// the spectrum values into log-sized average bins) so here's a quick-and-dirty linear
// equalizer instead:
float linearEQSlope; // the rate of linear eq
float linearEQIntercept; // the base linear scaling used at the first averaging bin
// the formula is: spectrum[i] * (linearEQIntercept + i * linearEQSlope)
// so.. note that clever use of it can also provide a "gain" control of sorts
// (fe: set intercept to 2f and slope to 0f to double gain)
// the formula is: spectrum[i] * (linearEQIntercept + i * linearEQSlope)
// so.. note that clever use of it can also provide a "gain" control of sorts
// (fe: set intercept to 2f and slope to 0f to double gain)
void setup(float samplingRate, int nBandsInTheFFT, int nAveragesPerOctave);
void calculate(float * fftData);
// void calculate(float * fftData);
void calculate(vector<float>& fftData);
// -------------------------------------------
// Property functions (emscr)
int getSamplingRate() const{
return samplingRate;
}
void setSamplingRate(int rate){
this->samplingRate = rate;
}
int getNSpectrum() const{
return nSpectrum;
}
void setNSpectrum(int nSpectrum){
this->nSpectrum = nSpectrum;
}
int getNAverages() const{
return nAverages;
}
void setNAverages(int nAverages){
this->nAverages = nAverages;
}
int getNAveragesPerOct() const{
return nAveragesPerOctave;
}
void setNAveragesPerOct(int nAverages){
this->nAveragesPerOctave = nAverages;
}
float getSpecFreqSpan() const{
return spectrumFrequencySpan;
}
void setSpecFreqSpan(float span){
this->spectrumFrequencySpan = span;
}
float getFirstOctFreq()const{
return firstOctaveFrequency;
}
void setFirstOctFreq(float freq) {
this->firstOctaveFrequency = freq;
}
float getAvgFreqIncr() const{
return averageFrequencyIncrement;
}
void setAvgFreqIncr(float incr) {
this->averageFrequencyIncrement = incr;
}
float getAverage(int n) const{
return averages[n];
}
float getPeak(int n) const{
return peaks[n];
}
int getPeakHoldTime(int n) const{
return peakHoldTimes[n];
}
int getPeakHoldTimeTotal() const{
return peakHoldTime;
}
void setPeakHoldTimeTotal(int tm){
this->peakHoldTime = tm;
}
float getPeakDecayRate() const{
return peakDecayRate;
}
void setPeakDecayRate(float rate){
this->peakDecayRate = rate;
}
int getSpe2Avg(int n) const{
return spe2avg[n];
}
float getLinEQSlope() const{
return linearEQSlope;
}
void setLinEQSlope(float slope){
this->linearEQSlope = slope;
}
float getLinEQIntercept() const{
return linearEQIntercept;
}
void setLinEQIntercept(float n){
this->linearEQIntercept = n;
}
};
......
......@@ -16,24 +16,71 @@ EMSCRIPTEN_BINDINGS(my_module_maxiFFT) {
// LIBS
// MAXI MAXI CLOCK
// MAXI FFT
class_<maxiFFT>("maxiFFT")
// .constructor<>()
// .constructor<int>()
// .constructor<>()
// .constructor<int>()
.smart_ptr_constructor("shared_ptr<maxiFFT>",&std::make_shared<maxiFFT>)
.smart_ptr_constructor("shared_ptr<maxiFFT>",&std::make_shared<maxiFFT>)
.function("setup", &maxiFFT::setup)
.function("process", &maxiFFT::process)
.function("magsToDB", &maxiFFT::magsToDB)
.function("spectralFlatness", &maxiFFT::spectralFlatness)
.function("spectralCentroid", &maxiFFT::spectralCentroid)
.function("getMagnitude", &maxiFFT::getMagnitude)
// .function("setTempo", &maxiClock::setTempo)
// .function("setTicksPerBeat", &maxiClock::setTicksPerBeat)
// .function("isTick", &maxiClock::isTick)
.function("getMagnitudeDB", &maxiFFT::getMagnitudeDB)
.function("getPhase", &maxiFFT::getPhase)
// .property("tick", &maxiClock::getTick, &maxiClock::setTick)
.property("windowSize", &maxiFFT::getWindowSize, &maxiFFT::setWindowSize)
.property("hopSize", &maxiFFT::getHopSize, &maxiFFT::setHopSize)
.property("bins", &maxiFFT::getNumBins, &maxiFFT::setNumBins)
.property("magnitudes", &maxiFFT::getMagnitudes, &maxiFFT::setMagnitudes)
.property("phases", &maxiFFT::getPhases, &maxiFFT::setPhases)
;
// MAXI IFFT
class_<maxiIFFT>("maxiIFFT")
// .constructor<>()
// .constructor<int>()
.smart_ptr_constructor("shared_ptr<maxiIFFT>",&std::make_shared<maxiIFFT>)
.function("setup", &maxiIFFT::setup)
.function("process", &maxiIFFT::process)
;
// MAXI IFFT
class_<maxiFFTOctaveAnalyzer>("maxiFFTOctaveAnalyzer")
// .constructor<>()
// .constructor<int>()
.smart_ptr_constructor("shared_ptr<maxiFFTOctaveAnalyzer>",&std::make_shared<maxiFFTOctaveAnalyzer>)
.function("setup", &maxiFFTOctaveAnalyzer::setup)
.function("calculate", &maxiFFTOctaveAnalyzer::calculate)
//properties
.property("samplingRate", &maxiFFTOctaveAnalyzer::getSamplingRate, &maxiFFTOctaveAnalyzer::setSamplingRate)
.property("nSpectrum", &maxiFFTOctaveAnalyzer::getNSpectrum, &maxiFFTOctaveAnalyzer::setNSpectrum)
.property("nAverages", &maxiFFTOctaveAnalyzer::getNAverages, &maxiFFTOctaveAnalyzer::setNAverages)
.property("nAveragesPerOctave", &maxiFFTOctaveAnalyzer::getNAveragesPerOct, &maxiFFTOctaveAnalyzer::setNAveragesPerOct)
.property("spectrumFrequencySpan", &maxiFFTOctaveAnalyzer::getSpecFreqSpan, &maxiFFTOctaveAnalyzer::setSpecFreqSpan)
.property("firstOctaveFrequency", &maxiFFTOctaveAnalyzer::getFirstOctFreq, &maxiFFTOctaveAnalyzer::setFirstOctFreq)
.property("averageFrequencyIncrement", &maxiFFTOctaveAnalyzer::getAvgFreqIncr, &maxiFFTOctaveAnalyzer::setAvgFreqIncr)
.function("getAverage", &maxiFFTOctaveAnalyzer::getAverage)
.function("getPeak", &maxiFFTOctaveAnalyzer::getPeak)
.function("getPeakHoldTime", &maxiFFTOctaveAnalyzer::getPeakHoldTime)
.property("peakHoldTime", &maxiFFTOctaveAnalyzer::getPeakHoldTimeTotal, &maxiFFTOctaveAnalyzer::setPeakHoldTimeTotal)
.property("peakDecayRate", &maxiFFTOctaveAnalyzer::getPeakDecayRate, &maxiFFTOctaveAnalyzer::setPeakDecayRate)
.function("getSpe2Avg", &maxiFFTOctaveAnalyzer::getSpe2Avg)
.property("linearEQSlope", &maxiFFTOctaveAnalyzer::getLinEQSlope, &maxiFFTOctaveAnalyzer::setLinEQSlope)
.property("linearEQIntercept", &maxiFFTOctaveAnalyzer::getLinEQIntercept, &maxiFFTOctaveAnalyzer::setLinEQIntercept)
;
};
......
#include "maxiGrains.h"
#include "maxiGrains_embind.h"
......
......@@ -2,8 +2,7 @@
#ifndef _MAXI_GRAINS_H
#define _MAXI_GRAINS_H
#include "maximilian.h"
#include "../maxi_emscr_new.h"
#if defined(__APPLE_CC__)
#include "accelerate/accelerate.h"
//Mac users can uncommment the line below to use Apple's accelerate framework for calculating grains. This gives ~300% speed improvement and better sound quality, but doesn't work well on all machines.
......@@ -160,7 +159,8 @@ public:
*/
maxiGrain(maxiSample *sample, const double position, const double duration, const double speed, maxiGrainWindowCache<F> *windowCache) :sample(sample), pos(position), dur(duration), speed(speed)
{
buffer = sample->temp;
buffer = sample->temp.data();
// buffer = sample->temp;
sampleStartPos = sample->length * pos;
sampleDur = dur * (double)sample->mySampleRate;
sampleDurMinusOne = sampleDur - 1;
......@@ -183,7 +183,7 @@ public:
#if defined(__APPLE_CC__) && defined(MAXIGRAINFAST)
//premake the grain using fast vector functions, and quadratic interpolation
double *sourceData = (double*)malloc(sampleDur * sizeof(double));
short* buffer = (short *)sample->temp;
short* buffer = (short *)sample->temp.data();
//convert sample to double data
vDSP_vflt16D(buffer + sampleStartPos, 1, sourceData, 1, min(sampleDur, sample->length - sampleStartPos));
//todo: wraping code
......@@ -258,6 +258,8 @@ public:
grainList grains;
maxiSample *sample;
// maxiGrainPlayer(){}
maxiGrainPlayer(maxiSample *sample) : sample(sample) {
}
......@@ -292,7 +294,12 @@ public:
double randomOffset;
double looper;
maxiTimestretch(){
position=0;
looper = 0;
// grainPlayer = new maxiGrainPlayer(sample);
randomOffset=0;
}
maxiTimestretch(maxiSample *sample) : sample(sample) {
position=0;
......@@ -304,7 +311,26 @@ public:
~maxiTimestretch() {
delete grainPlayer;
}
void setSample(maxiSample* sampleIn){
// could just erase the sample in player
// and replace?
if(grainPlayer){
delete grainPlayer;
grainPlayer = NULL;
}
sample = sampleIn;
grainPlayer = new maxiGrainPlayer(sample);
}
//
// void setSampleVec(vector<double> sampleIn){
// delete sample;
// sample = new maxiSample();
// sample->setSample(sampleIn);
//// sample = sampleIn;
// }
double getNormalisedPosition() {
return position / (double) sample->length;
}
......@@ -315,12 +341,12 @@ public:
void setPosition(double pos) {
position = pos * sample->length;
position = maxiMap::clamp(position, 0, sample->length-1);
position = maxiMap::clamp<double>(position, 0, sample->length-1);
}
//play at a speed
inline double play(double speed, double grainLength, int overlaps, double posMod=0.0) {
inline double play(double speed, double grainLength, int overlaps, double posMod) {
position = position + speed;
looper++;
if (position > sample->length) position-= sample->length;
......@@ -363,6 +389,13 @@ public:
maxiGrainWindowCache<F> windowCache;
double randomOffset;
maxiPitchShift(){
position=0;
cycles=0;
// grainPlayer = new maxiGrainPlayer(sample);
randomOffset=0;
}
maxiPitchShift(maxiSample *sample) : sample(sample) {
position=0;
cycles=0;
......@@ -374,6 +407,16 @@ public:
delete grainPlayer;
}
void setSample(maxiSample* sampleIn){
if(grainPlayer){
delete grainPlayer;
grainPlayer = NULL;
}
sample = sampleIn;
grainPlayer = new maxiGrainPlayer(sample);
}
double play(double speed, double grainLength, int overlaps, double posMod=0.0) {
position = position + 1;
cycles++;
......@@ -410,6 +453,16 @@ public:
long loopStart, loopEnd, loopLength;
double looper;
maxiPitchStretch(){
// grainPlayer = new maxiGrainPlayer(sample);
randomOffset=0;
loopStart = 0.0;
// loopEnd = sample->length;
// loopLength =sample->length;
position=0;
looper = 0;
}
maxiPitchStretch(maxiSample *sample) : sample(sample) {
grainPlayer = new maxiGrainPlayer(sample);
randomOffset=0;
......@@ -419,7 +472,20 @@ public:
position=0;
looper = 0;
}
void setSample(maxiSample* sampleIn){
if(grainPlayer){
delete grainPlayer;
grainPlayer = NULL;
}
sample = sampleIn;
grainPlayer = new maxiGrainPlayer(sample);
loopEnd = sample->length;
loopLength =sample->length;
}
double getNormalisedPosition() {
return position / (double) sample->length;
}
......@@ -430,9 +496,9 @@ public:
void setPosition(double pos) {
position = pos * sample->length;
position = maxiMap::clamp(position, 0, sample->length-1);
position = maxiMap::clamp<double>(position, 0, sample->length-1);
}
void setLoopStart(double val) {
loopStart = val * sample->length;
loopLength = loopEnd - loopStart;
......
/*
contains all bindings for use with emscripten
*/
#ifndef Maxi_Emscripten_maxiFFT_embind_h
#define Maxi_Emscripten_maxiFFT_embind_h
#include <emscripten.h>
#include <emscripten/bind.h>
//#include "fft.cpp"
using namespace emscripten;
EMSCRIPTEN_BINDINGS(my_module_maxiGrains) {
// -------------------------------------------------------------------------------------------
// LIBS
// MAXI TIMESTRETCH
class_<maxiTimestretch<hannWinFunctor> >("maxiTimestretch")
.smart_ptr_constructor("shared_ptr<maxiTimestretch<hannWinFunctor> >",&std::make_shared<maxiTimestretch<hannWinFunctor> >)
// .smart_ptr_constructor<maxiSample*>("shared_ptr<maxiTimestretch<hannWinFunctor> >",&std::make_shared<maxiTimestretch<hannWinFunctor> >)
.function("setSample", &maxiTimestretch<hannWinFunctor>::setSample, allow_raw_pointers())
.function("getNormalisedPosition", &maxiTimestretch<hannWinFunctor>::getNormalisedPosition)
.function("getPosition", &maxiTimestretch<hannWinFunctor>::getPosition)
.function("setPosition", &maxiTimestretch<hannWinFunctor>::setPosition)
.function("play", &maxiTimestretch<hannWinFunctor>::play)
.function("play2", &maxiTimestretch<hannWinFunctor>::play2)
;
// MAXI PITCHSHIFT
class_<maxiPitchShift<hannWinFunctor> >("maxiPitchShift")
.smart_ptr_constructor("shared_ptr<maxiPitchShift<hannWinFunctor> >",&std::make_shared<maxiPitchShift<hannWinFunctor> >)
.function("setSample", &maxiPitchShift<hannWinFunctor>::setSample, allow_raw_pointers())
.function("play", &maxiPitchShift<hannWinFunctor>::play)
;
// MAXI PITCHSTRETCH
class_<maxiPitchStretch<hannWinFunctor> >("maxiPitchStretch")
.smart_ptr_constructor("shared_ptr<maxiTimestretch<hannWinFunctor> >",&std::make_shared<maxiPitchStretch<hannWinFunctor> >)
// .smart_ptr_constructor<maxiSample*>("shared_ptr<maxiTimestretch<hannWinFunctor> >",&std::make_shared<maxiTimestretch<hannWinFunctor> >)
.function("setSample", &maxiPitchStretch<hannWinFunctor>::setSample, allow_raw_pointers())
.function("getNormalisedPosition", &maxiPitchStretch<hannWinFunctor>::getNormalisedPosition)
.function("getPosition", &maxiPitchStretch<hannWinFunctor>::getPosition)
.function("setPosition", &maxiPitchStretch<hannWinFunctor>::setPosition)
.function("setLoopStart", &maxiPitchStretch<hannWinFunctor>::setLoopStart)
.function("setLoopEnd", &maxiPitchStretch<hannWinFunctor>::setLoopEnd)
.function("play", &maxiPitchStretch<hannWinFunctor>::play)
;
};
#endif
......@@ -8,7 +8,7 @@
*/
#include "maxiMFCC.h"
#include "maxiMFCC_embind.h"
#ifdef __APPLE_CC__
template <>
......
......@@ -12,10 +12,12 @@
#pragma once
#pragma pack(16)
#include "maxiFFT.h"
//#include "../maxi_emscr_new.h"
//#include "maxiFFT.h"
#include <math.h>
#include <iostream>
#include <cstdlib>
#include <vector>
#ifdef __APPLE_CC__
#include <Accelerate/Accelerate.h>
#endif
......@@ -69,9 +71,10 @@ public:
calcMelFilterBank(sampleRate, numBins);
createDCTCoeffs();
}
void mfcc(float* powerSpectrum, T *mfccs) {
melFilterAndLogSquare(powerSpectrum);
dct(mfccs);
// void mfcc(float* powerSpectrum, T *mfccs) {
void mfcc(vector<float>& powerSpectrum, vector<T>& mfccs) {
melFilterAndLogSquare(powerSpectrum.data());
dct(mfccs.data());
}
private:
......
/*
contains all bindings for use with emscripten
*/
#ifndef Maxi_Emscripten_maxiMFCC_embind_h
#define Maxi_Emscripten_maxiMFCC_embind_h
#include <emscripten.h>
#include <emscripten/bind.h>
using namespace emscripten;
EMSCRIPTEN_BINDINGS(my_module_maxiMFCC) {
// -------------------------------------------------------------------------------------------
// LIBS
// MAXI MFCC
class_<maxiMFCC>("maxiMFCC")
// .constructor<>()
// .constructor<int>()
.smart_ptr_constructor("shared_ptr<maxiMFCC>",&std::make_shared<maxiMFCC>)
.function("setup", &maxiMFCC::setup)
.function("mfcc", &maxiMFCC::mfcc, allow_raw_pointers())
;
};
#endif
......@@ -33,6 +33,15 @@ public:
static void clearVectorDbl(vector<double>& vecIn) {
vecIn.clear();
}
static void clearVectorFloat(vector<float>& vecIn) {
vecIn.clear();
}
// static void pr(){
// EM_ASM_({
// Module.print('I received: ' + $0);
// }, 100);
// }
};
using namespace emscripten;
......@@ -40,11 +49,15 @@ using namespace emscripten;
EMSCRIPTEN_BINDINGS(my_module) {
register_vector<int>("VectorInt");
register_vector<double>("VectorDouble");
// register_vector<float>("VectorFloat");
register_vector<char>("VectorChar");
register_vector<float>("VectorFloat");
class_<vectorTools>("vectorTools")
.constructor<>()
.class_function("clearVectorDbl", &vectorTools::clearVectorDbl)
.class_function("clearVectorFloat", &vectorTools::clearVectorFloat)
// .class_function("print", &vectorTools::pr)
;
// class_<testVectorHolder>("testVectorHolder")
......@@ -74,6 +87,9 @@ EMSCRIPTEN_BINDINGS(my_module) {
class_<maxiSettings>("maxiSettings")
.constructor<>()
.class_function("setup", &maxiSettings::setup)
.property("sampleRate", &maxiSettings::getSampleRate, &maxiSettings::setSampleRate)
.property("channels", &maxiSettings::getNumChannels, &maxiSettings::setNumChannels)
.property("bufferSize", &maxiSettings::getBufferSize, &maxiSettings::setBufferSize)
;
......@@ -157,11 +173,14 @@ EMSCRIPTEN_BINDINGS(my_module) {
// .constructor<>()
// .constructor<double, double>()
.smart_ptr_constructor("shared_ptr<maxiLagExp<double>>",&std::make_shared<maxiLagExp<double>>, allow_raw_pointers()) // not sure how to override constructors with smart_ptr
// .smart_ptr_constructor("shared_ptr<maxiLagExp<double>>",&std::make_shared<maxiLagExp<double>>)
// .smart_ptr_constructor("shared_ptr<maxiLagExp<double>>",&std::make_shared<maxiLagExp<double>>)
.function("init", &maxiLagExp<double>::init)
.function("addSample", &maxiLagExp<double>::addSample)
.function("value", &maxiLagExp<double>::value)
.property("alpha", &maxiLagExp<double>::getAlpha, &maxiLagExp<double>::setAlpha)
.property("alphaReciprocal", &maxiLagExp<double>::getAlphaReciprocal, &maxiLagExp<double>::setAlphaReciprocal)
.property("val", &maxiLagExp<double>::value, &maxiLagExp<double>::setVal)
;
......@@ -171,7 +190,10 @@ EMSCRIPTEN_BINDINGS(my_module) {
.smart_ptr_constructor("shared_ptr<maxiSample>",&std::make_shared<maxiSample>)
// .property("length", &maxiSample::getLength, &maxiSample::setLength) // no work???
.function("getLength", &maxiSample::getLength)
.function("setSample", &maxiSample::setSample)
// .function("setSample", &maxiSample::setSample)
.function("setSample", select_overload<void(vector<double>&)>(&maxiSample::setSample))
.function("setSample", select_overload<void(vector<double>&, int)>(&maxiSample::setSample))
// .function("getSummary", &maxiSample::getSummary)
.function("isReady", &maxiSample::isReady)
......@@ -181,13 +203,14 @@ EMSCRIPTEN_BINDINGS(my_module) {
.function("play", select_overload<double()>(&maxiSample::play))
.function("play", select_overload<double(double)>(&maxiSample::play))
.function("play", select_overload<double(double, double, double)>(&maxiSample::play))
.function("play4", &maxiSample::play4)
.function("trigger", &maxiSample::trigger)
.function("clear", &maxiSample::clear)
// .function("normalise", &maxiSample::normalise)
// .function("autoTrim", &maxiSample::autoTrim)
// .function("load", &maxiSample::load)
// .function("read", &maxiSample::read, allow_raw_pointers())
;
......@@ -229,7 +252,7 @@ EMSCRIPTEN_BINDINGS(my_module) {
.function("setSustain", &maxiEnv::setSustain)
.property("trigger", &maxiEnv::getTrigger, &maxiEnv::setTrigger)
;
// CONVERT
......@@ -329,24 +352,15 @@ EMSCRIPTEN_BINDINGS(my_module) {
.function("setTicksPerBeat", &maxiClock::setTicksPerBeat)
.function("isTick", &maxiClock::isTick)
.property("currentCount", &maxiClock::getCurrentCount, &maxiClock::setCurrentCount)
.property("currentCount", &maxiClock::getLastCount, &maxiClock::setLastCount)
.property("playHead", &maxiClock::getPlayHead, &maxiClock::setPlayHead)
.property("bps", &maxiClock::getBps, &maxiClock::setBps)
.property("bpm", &maxiClock::getBpm, &maxiClock::setBpm)
.property("tick", &maxiClock::getTick, &maxiClock::setTick)
.property("ticks", &maxiClock::getTicks, &maxiClock::setTicks)
;
// class_<maxiFFT>("maxiFFT")
// // .constructor<>()
// // .constructor<int>()
// .smart_ptr_constructor("shared_ptr<maxiFFT>",&std::make_shared<maxiFFT>)
// .function("setup", &maxiFFT::setup, allow_raw_pointers())
// .function("process", &maxiFFT::process, allow_raw_pointers())
// .function("magsToDB", &maxiFFT::magsToDB, allow_raw_pointers())
// .function("spectralFlatness", &maxiFFT::spectralFlatness, allow_raw_pointers())
// .function("spectralCentroid", &maxiFFT::spectralCentroid, allow_raw_pointers())
// // .function("setTempo", &maxiClock::setTempo)
// // .function("setTicksPerBeat", &maxiClock::setTicksPerBeat)
// // .function("isTick", &maxiClock::isTick)
//
// // .property("tick", &maxiClock::getTick, &maxiClock::setTick)
// ;
};
#endif
......@@ -493,16 +493,16 @@ double maxiFilter::bandpass(double input,double cutoff1, double resonance) {
}
//stereo bus
std::vector<double>& maxiMix::stereo(double input,std::vector<double>&two,double x) {
void maxiMix::stereo(double input,std::vector<double>&two,double x) {
if (x>1) x=1;
if (x<0) x=0;
two[0]=input*sqrt(1.0-x);
two[1]=input*sqrt(x);
return two;
// return two;
}
//quad bus
std::vector<double>& maxiMix::quad(double input,std::vector<double>& four,double x,double y) {
void maxiMix::quad(double input,std::vector<double>& four,double x,double y) {
if (x>1) x=1;
if (x<0) x=0;
if (y>1) y=1;
......@@ -511,11 +511,11 @@ std::vector<double>& maxiMix::quad(double input,std::vector<double>& four,double
four[1]=input*sqrt((1.0-x)*(1.0-y));
four[2]=input*sqrt(x*y);
four[3]=input*sqrt(x*(1.0-y));
return(four);
// return(four);
}
//ambisonic bus
std::vector<double>& maxiMix::ambisonic(double input,std::vector<double>&eight,double x,double y,double z) {
void maxiMix::ambisonic(double input,std::vector<double>&eight,double x,double y,double z) {
if (x>1) x=1;
if (x<0) x=0;
if (y>1) y=1;
......@@ -530,9 +530,11 @@ std::vector<double>& maxiMix::ambisonic(double input,std::vector<double>&eight,d
eight[5]=input*(sqrt((1.0-x)*(1.0-y))*z);
eight[6]=input*sqrt((x*y)*z);
eight[7]=input*sqrt((x*(1.0-y))*z);
return(eight);
// return(eight);
}
// --------------------------------------------------------------------------------
// MAXI_SAMPLE
/*
//This is the maxiSample load function. It just calls read.
bool maxiSample::load(string fileName, int channel) {
myPath = fileName;
......@@ -568,7 +570,7 @@ bool maxiSample::loadOgg(string fileName, int channel) {
#endif
return 0;
}
*/
// -------------------------
// js bits
bool maxiSample::isReady(){
......@@ -579,10 +581,32 @@ bool maxiSample::isReady(){
}
void maxiSample::setSample(vector<double>& temp){
tempVec = temp;
// tempVec = temp;
length = temp.size();
for(int i = 0; i < length; i++){
this->temp.push_back(temp[i]*32767.0);
}
mySampleRate = 44100;
}
void maxiSample::setSample(vector<double>& temp, int sampleRate){
// tempVec = temp;
length = temp.size();
for(int i = 0; i < length; i++){
this->temp.push_back(temp[i]*32767.0);
}
mySampleRate = sampleRate;
}
//void maxiSample::setSampleChar(vector<char>& temp){
// this->temp = temp.data();
// length = temp.size();
//}
// -------------------------
//This sets the playback position to the start of a sample
......@@ -590,6 +614,89 @@ void maxiSample::trigger() {
position = 0;
recordPosition = 0;
}
/*
// attempt at using read with characters input from js
bool maxiSample::read(vector<char>& fileChars)
{
bool result;
ifstream inFile( myPath.c_str(), ios::in | ios::binary);
result = inFile.is_open();
if (result) {
bool datafound = false;
inFile.seekg(4, ios::beg);
inFile.read( (char*) &myChunkSize, 4 ); // read the ChunkSize
inFile.seekg(16, ios::beg);
inFile.read( (char*) &mySubChunk1Size, 4 ); // read the SubChunk1Size
//inFile.seekg(20, ios::beg);
inFile.read( (char*) &myFormat, sizeof(short) ); // read the file format. This should be 1 for PCM
//inFile.seekg(22, ios::beg);
inFile.read( (char*) &myChannels, sizeof(short) ); // read the # of channels (1 or 2)
//inFile.seekg(24, ios::beg);
inFile.read( (char*) &mySampleRate, sizeof(int) ); // read the samplerate
//inFile.seekg(28, ios::beg);
inFile.read( (char*) &myByteRate, sizeof(int) ); // read the byterate
//inFile.seekg(32, ios::beg);
inFile.read( (char*) &myBlockAlign, sizeof(short) ); // read the blockalign
//inFile.seekg(34, ios::beg);
inFile.read( (char*) &myBitsPerSample, sizeof(short) ); // read the bitspersample
//ignore any extra chunks
char chunkID[5]="";
chunkID[4] = 0;
int filePos = 20 + mySubChunk1Size;
while(!datafound && !inFile.eof()) {
inFile.seekg(filePos, ios::beg);
inFile.read((char*) &chunkID, sizeof(char) * 4);
inFile.seekg(filePos + 4, ios::beg);
inFile.read( (char*) &myDataSize, sizeof(int) ); // read the size of the data
filePos += 8;
if (strcmp(chunkID,"data") == 0) {
datafound = true;
}else{
filePos += myDataSize;
}
}
// read the data chunk
char * myData = (char*) malloc(myDataSize * sizeof(char));
inFile.seekg(filePos, ios::beg);
inFile.read(myData, myDataSize);
length=myDataSize*(0.5/myChannels);
inFile.close(); // close the input file
cout << "Ch: " << myChannels << ", len: " << length << endl;
if (myChannels>1) {
int position=0;
int channel=readChannel*2;
for (int i=channel;i<myDataSize+6;i+=(myChannels*2)) {
myData[position]=myData[i];
myData[position+1]=myData[i+1];
position+=2;
}
}
free(temp);
temp = (short*) malloc(myDataSize * sizeof(char));
memcpy(temp, myData, myDataSize * sizeof(char));
free(myData);
}else {
// cout << "ERROR: Could not load sample: " <<myPath << endl; //This line seems to be hated by windows
printf("ERROR: Could not load sample.");
}
return result; // this should probably be something more descriptive
}
//This is the main read function.
bool maxiSample::read()
......@@ -672,7 +779,252 @@ bool maxiSample::read()
return result; // this should probably be something more descriptive
}
*/
// -----------------
//This plays back at the correct speed. Always loops.
double maxiSample::play() {
position++;
if ((long) position >= length) position=0;
output = (double) temp[(long)position]/32767.0;
return output;
}
void maxiSample::setPosition(double newPos) {
position = maxiMap::clamp<double>(newPos, 0.0, 1.0) * length;
}
//start end and points are between 0 and 1
double maxiSample::playLoop(double start, double end) {
position++;
if (position < length * start) position = length * start;
if ((long) position >= length * end) position = length * start;
output = (double) temp[(long)position]/32767.0;
return output;
}
double maxiSample::playUntil(double end) {
position++;
if ((long) position<length * end)
output = (double) temp[(long)position]/32767.0;
else {
output=0;
}
return output;
}
//This plays back at the correct speed. Only plays once. To retrigger, you have to manually reset the position
double maxiSample::playOnce() {
position++;
if ((long) position<length)
output = (double) temp[(long)position]/32767.0;
else {
output=0;
}
return output;
}
//Same as above but takes a speed value specified as a ratio, with 1.0 as original speed
double maxiSample::playOnce(double speed) {
position=position+((speed*chandiv)/(maxiSettings::sampleRate/mySampleRate));
double remainder = position - (long) position;
if ((long) position<length)
output = (double) ((1-remainder) * temp[1+ (long) position] + remainder * temp[2+(long) position])/32767;//linear interpolation
else
output=0;
return(output);
}
//As above but looping
double maxiSample::play(double speed) {
double remainder;
long a,b;
position=position+((speed*chandiv)/(maxiSettings::sampleRate/mySampleRate));
if (speed >=0) {
if ((long) position>=length-1) position=1;
remainder = position - floor(position);
if (position+1<length) {
a=position+1;
}
else {
a=length-1;
}
if (position+2<length)
{
b=position+2;
}
else {
b=length-1;
}
output = (double) ((1-remainder) * temp[a] + remainder * temp[b])/32767;//linear interpolation
} else {
if ((long) position<0) position=length;
remainder = position - floor(position);
if (position-1>=0) {
a=position-1;
}
else {
a=0;
}
if (position-2>=0) {
b=position-2;
}
else {
b=0;
}
output = (double) ((-1-remainder) * temp[a] + remainder * temp[b])/32767;//linear interpolation
}
return(output);
}
//placeholder
double maxiSample::play(double frequency, double start, double end) {
return play(frequency, start, end, position);
}
//This allows you to say how often a second you want a specific chunk of audio to play
double maxiSample::play(double frequency, double start, double end, double &pos) {
double remainder;
if (end>=length) end=length-1;
long a,b;
if (frequency >0.) {
if (pos<start) {
pos=start;
}
if ( pos >= end ) pos = start;
pos += ((end-start)/((maxiSettings::sampleRate)/(frequency*chandiv)));
remainder = pos - floor(pos);
long posl = floor(pos);
if (posl+1<length) {
a=posl+1;
}
else {
a=posl-1;
}
if (posl+2<length) {
b=posl+2;
}
else {
b=length-1;
}
output = (double) ((1-remainder) * temp[a] +
remainder * temp[b])/32767;//linear interpolation
} else {
frequency*=-1.;
if ( pos <= start ) pos = end;
pos -= ((end-start)/(maxiSettings::sampleRate/(frequency*chandiv)));
remainder = pos - floor(pos);
long posl = floor(pos);
if (posl-1>=0) {
a=posl-1;
}
else {
a=0;
}
if (posl-2>=0) {
b=posl-2;
}
else {
b=0;
}
output = (double) ((-1-remainder) * temp[a] +
remainder * temp[b])/32767;//linear interpolation
}
return(output);
}
//Same as above. better cubic inerpolation. Cobbled together from various (pd externals, yehar, other places).
double maxiSample::play4(double frequency, double start, double end) {
double remainder;
double a,b,c,d,a1,a2,a3;
if (frequency >0.) {
if (position<start) {
position=start;
}
if ( position >= end ) position = start;
position += ((end-start)/(maxiSettings::sampleRate/(frequency*chandiv)));
remainder = position - floor(position);
if (position>0) {
a=temp[(int)(floor(position))-1];
} else {
a=temp[0];
}
b=temp[(long) position];
if (position<end-2) {
c=temp[(long) position+1];
} else {
c=temp[0];
}
if (position<end-3) {
d=temp[(long) position+2];
} else {
d=temp[0];
}
a1 = 0.5f * (c - a);
a2 = a - 2.5 * b + 2.f * c - 0.5f * d;
a3 = 0.5f * (d - a) + 1.5f * (b - c);
output = (double) (((a3 * remainder + a2) * remainder + a1) * remainder + b) / 32767;
} else {
frequency*=-1.;
if ( position <= start ) position = end;
position -= ((end-start)/(maxiSettings::sampleRate/(frequency*chandiv)));
remainder = position - floor(position);
if (position>start && position < end-1) {
a=temp[(long) position+1];
} else {
a=temp[0];
}
b=temp[(long) position];
if (position>start) {
c=temp[(long) position-1];
} else {
c=temp[0];
}
if (position>start+1) {
d=temp[(long) position-2];
} else {
d=temp[0];
}
a1 = 0.5f * (c - a);
a2 = a - 2.5 * b + 2.f * c - 0.5f * d;
a3 = 0.5f * (d - a) + 1.5f * (b - c);
output = (double) (((a3 * remainder + a2) * -remainder + a1) * -remainder + b) / 32767;
}
return(output);
}
// -----------------
/*
//This plays back at the correct speed. Always loops.
double maxiSample::play() {
position++;
......@@ -911,6 +1263,8 @@ double maxiSample::play4(double frequency, double start, double end) {
return(output);
}
*/
/*
//You don't need to worry about this stuff.
......@@ -1108,7 +1462,7 @@ double maxiSample::bufferPlay4(unsigned char &bufferin,double frequency, double
void maxiSample::getLength() {
length=myDataSize*0.5;
}
/*
void maxiSample::setLength(unsigned long numSamples) {
cout << "Length: " << numSamples << endl;
short *newData = (short*) malloc(sizeof(short) * numSamples);
......@@ -1122,6 +1476,7 @@ void maxiSample::setLength(unsigned long numSamples) {
position=0;
recordPosition=0;
}
*/
//void maxiSample::clear() {
// memset(temp, 0, myDataSize);
......@@ -1140,12 +1495,12 @@ void maxiSample::normalise(float maxLevel) {
}
// if vector, need to do *32767.0 ??
float scale = 32767.0 * maxLevel / (float) maxValue;
float scale = /*32767.0 * */maxLevel / (float) maxValue;
for(int i=0; i < length; i++) {
temp[i] = round(scale * (float) temp[i]);
}
}
/*
void maxiSample::autoTrim(float alpha, float threshold, bool trimStart, bool trimEnd) {
int startMarker=0;
......@@ -1195,7 +1550,7 @@ void maxiSample::autoTrim(float alpha, float threshold, bool trimStart, bool tri
}
}
}
*/
......@@ -1304,6 +1659,21 @@ double maxiDyn::compress(double input) {
return output*(1+log(ratio));
}
void maxiDyn::setAttack(double attackMS) {
attack = pow( 0.01, 1.0 / ( attackMS * maxiSettings::sampleRate * 0.001 ) );
}
void maxiDyn::setRelease(double releaseMS) {
release = pow( 0.01, 1.0 / ( releaseMS * maxiSettings::sampleRate * 0.001 ) );
}
void maxiDyn::setThreshold(double thresholdI) {
threshold = thresholdI;
}
void maxiDyn::setRatio(double ratioF) {
ratio = ratioF;
}
/* Lots of people struggle with the envelope generators so here's a new easy one.
It takes mental numbers for attack and release tho. Basically, they're exponentials.
......@@ -1475,21 +1845,7 @@ void maxiEnv::setDecay(double decayMS) {
}
void maxiDyn::setAttack(double attackMS) {
attack = pow( 0.01, 1.0 / ( attackMS * maxiSettings::sampleRate * 0.001 ) );
}
void maxiDyn::setRelease(double releaseMS) {
release = pow( 0.01, 1.0 / ( releaseMS * maxiSettings::sampleRate * 0.001 ) );
}
void maxiDyn::setThreshold(double thresholdI) {
threshold = thresholdI;
}
void maxiDyn::setRatio(double ratioF) {
ratio = ratioF;
}
double convert::mtof(int midinote) {
......
......@@ -63,6 +63,30 @@ public:
maxiSettings::channels = initChannels;
maxiSettings::bufferSize = initBufferSize;
}
void setSampleRate(int sampleRate_){
sampleRate = sampleRate_;
}
void setNumChannels(int channels_){
channels = channels_;
}
void setBufferSize(int bufferSize_){
bufferSize = bufferSize_;
}
int getSampleRate() const{
return sampleRate;
}
int getNumChannels() const{
return channels;
}
int getBufferSize() const{
return bufferSize;
}
};
......@@ -119,14 +143,14 @@ public:
valindex = index;
}
int getValindex() const{
return valindex;
}
void setAmplitude(double amp){
amplitude = amp;
}
int getValindex() const{
return valindex;
}
double getAmplitude() const{
return amplitude;
}
......@@ -178,15 +202,15 @@ public:
void setCutoff(double cut){
cutoff = cut;
}
void setResonance(double res){
resonance = res;
}
double getCutoff() const{
return cutoff;
}
void setResonance(double res){
resonance = res;
}
double getResonance() const{
return resonance;
}
......@@ -199,9 +223,9 @@ class maxiMix {
double four[4];
double eight[8];
public:
double x;
double y;
double z;
// double x;
// double y;
// double z;
// ------------------------------------------------
// getters/setters
......@@ -213,9 +237,9 @@ public:
// double *ambisonic(double input,double eight[8],double x,double y, double z);
// should return or just be void function
std::vector<double>& stereo(double input,std::vector<double>& two,double x);
std::vector<double>& quad(double input,std::vector<double>& four, double x,double y);
std::vector<double>& ambisonic(double input,std::vector<double>& eight, double x,double y, double z);
void stereo(double input,std::vector<double>& two,double x);
void quad(double input,std::vector<double>& four, double x,double y);
void ambisonic(double input,std::vector<double>& eight, double x,double y, double z);
};
//lagging with an exponential moving average
......@@ -244,9 +268,33 @@ public:
val = (alpha * newVal) + (alphaReciprocal * val);
}
inline T value() {
// getters/setters
void setAlpha(T alpha_){
alpha = alpha_;
}
void setAlphaReciprocal(T alphaReciprocal_){
alphaReciprocal = alphaReciprocal_;
}
void setVal(T val_){
val = val_;
}
T getAlpha() const{
return alpha;
}
T getAlphaReciprocal() const{
return alphaReciprocal;
}
inline T value() const{
return val;
}
};
......@@ -275,16 +323,17 @@ public:
short myBitsPerSample;
vector<double> tempVec;
vector<short> temp;
// char* myData;
short* temp;
// short* temp;
// get/set for the Path property
~maxiSample()
{
// if (myData) free(myData);
if (temp) free(temp);
// if (temp) free(temp);
temp.clear();
tempVec.clear();
printf("freeing SampleData");
......@@ -299,10 +348,12 @@ public:
recordPosition = 0;
myChannels = source.myChannels;
mySampleRate = maxiSettings::sampleRate;
free(temp);
// free(temp);
temp.clear();
myDataSize = source.myDataSize;
temp = (short*) malloc(myDataSize * sizeof(char));
memcpy(temp, source.temp, myDataSize * sizeof(char));
// temp = (short*) malloc(myDataSize * sizeof(char));
temp = source.temp;
// memcpy(temp, source.temp, myDataSize * sizeof(char));
length = source.length;
return *this;
}
......@@ -317,14 +368,18 @@ public:
bool isReady();
void setSample(vector<double>& temp);
void clear(){tempVec.clear();}
void setSample(vector<double>& temp, int sampleRate);
// void setSampleChar(vector<char>& temp);
void clear(){temp.clear();}
// -------------------------
void trigger();
// read a wav file into this class
bool read();
// bool read(vector<char>& fileChars);
//read an ogg file into this class using stb_vorbis
bool readOgg();
......@@ -398,8 +453,8 @@ public:
myFile.write ((char*) &myBitsPerSample, 2);
myFile.write ("data", 4);
myFile.write ((char*) &myDataSize, 4);
myFile.write ((char*) temp, myDataSize);
// myFile.write ((char*) temp, myDataSize);
myFile.write ((char*) temp.data(), myDataSize);
return true;
}
......@@ -479,6 +534,13 @@ public:
// ------------------------------------------------
// getters/setters
// int getTrigger() const{
// return trigger;
// }
// void setTrigger(int trigger){
// this->trigger = trigger;
// }
// ------------------------------------------------
};
......@@ -871,14 +933,6 @@ public:
void setTicksPerBeat(int ticksPerBeat);
bool isTick();
void setTick(int tick){
this->tick = tick;
}
int getTick() const{
return tick;
}
maxiOsc timer;
int currentCount;
int lastCount;
......@@ -887,7 +941,65 @@ public:
double bpm;
int ticks;
bool tick;
// SETTERS
void setCurrentCount(int n){
this->currentCount = n;
}
void setLastCount(int n){
this->lastCount = n;
}
void setPlayHead(int n){
this->playHead = n;
}
void setBps(int bps_){
this->bps = bps_;
}
void setBpm(int bpm_){
this->bpm = bpm_;
}
void setTick(int tick_){
this->tick = tick_;
}
void setTicks(int ticks_){
this->ticks = ticks_;
}
// GETTERS
int getCurrentCount() const{
return currentCount;
}
int getLastCount() const{
return lastCount;
}
int getPlayHead() const{
return playHead;
}
double getBps() const{
return bps;
}
double getBpm() const{
return bpm;
}
bool getTick() const{
return tick;
}
int getTicks() const{
return ticks;
}
};
......
......@@ -308,7 +308,7 @@ public:
char* myData;
tempVec
//tempVec
// different vars for use with js
vector<double> tempVec;
......