Commit 19015c6f authored by Daniel Clarke's avatar Daniel Clarke

all examples done

parent fc26f9bb
......@@ -14,15 +14,13 @@
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "415"
endingLineNumber = "415"
landmarkName = "maxiMix::stereo(double input,vector<double>& two,double x)"
landmarkType = "5">
endingLineNumber = "415">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
shouldBeEnabled = "Yes"
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "Maxi_Emscripten/maxi_embind.h"
......
......@@ -10,7 +10,7 @@
#define Maxi_Emscripten_maxi_embind_h
#include <emscripten.h>
#include <bind.h>
#include <emscripten/bind.h>
class vectorTools {
public:
......@@ -41,6 +41,11 @@ EMSCRIPTEN_BINDINGS(my_module) {
// MAXI OSC
class_<maxiOsc>("maxiOsc")
.constructor<>()
/*
Using a smart_ptr_constructor ensures lifetime management on the js side
by returning a smart_ptr when a constructor is used
*/
// .smart_ptr_constructor("shared_ptr<maxiOsc>",&std::make_shared<maxiOsc>)
.function("sinewave", &maxiOsc::sinewave)
.function("coswave", &maxiOsc::coswave)
.function("phasor", select_overload<double(double)>(&maxiOsc::phasor))
......@@ -60,6 +65,8 @@ EMSCRIPTEN_BINDINGS(my_module) {
// MAXI ENVELOPE
class_<maxiEnvelope>("maxiEnvelope")
.constructor<>()
// .smart_ptr_constructor("shared_ptr<maxiEnvelope>",&std::make_shared<maxiEnvelope>)
.function("line", &maxiEnvelope::line)
// .function("line", &maxiEnvelope::line, allow_raw_pointers()) // if using array version
.function("trigger", &maxiEnvelope::trigger)
......@@ -68,7 +75,8 @@ EMSCRIPTEN_BINDINGS(my_module) {
// MAXI DELAYLINE
class_<maxiDelayline>("maxiDelayline")
.constructor<>()
// .constructor<>()
.smart_ptr_constructor("shared_ptr<maxiDelayline>",&std::make_shared<maxiDelayline>)
.function("dl", select_overload<double(double, int, double)>(&maxiDelayline::dl))
.function("dl", select_overload<double(double, int, double, int)>(&maxiDelayline::dl))
;
......@@ -77,6 +85,7 @@ EMSCRIPTEN_BINDINGS(my_module) {
// MAXI FILTER
class_<maxiFilter>("maxiFilter")
.constructor<>()
// .smart_ptr_constructor("shared_ptr<maxiFilter>",&std::make_shared<maxiFilter>)
.function("lores", &maxiFilter::lores)
.function("hires", &maxiFilter::hires)
.function("bandpass", &maxiFilter::bandpass)
......@@ -87,6 +96,7 @@ EMSCRIPTEN_BINDINGS(my_module) {
// MAXI MIX
class_<maxiMix>("maxiMix")
.constructor<>()
// .smart_ptr_constructor("shared_ptr<maxiMix>",&std::make_shared<maxiMix>)
.function("stereo", &maxiMix::stereo, allow_raw_pointers())
.function("quad", &maxiMix::quad, allow_raw_pointers())
.function("ambisonic", &maxiMix::ambisonic, allow_raw_pointers())
......@@ -95,14 +105,21 @@ EMSCRIPTEN_BINDINGS(my_module) {
// MAXI SAMPLE
class_<maxiSample>("maxiSample")
.constructor<>()
// .property("length", &maxiSample::getLength, &maxiSample::setLength)
// makes some problems in browser?
// .smart_ptr_constructor("shared_ptr<maxiSample>",&std::make_shared<maxiSample>)
.function("getLength", &maxiSample::getLength)
.function("setSample", &maxiSample::setSample)
// .function("getSummary", &maxiSample::getSummary)
.function("playOnce", &maxiSample::playOnce)
.function("isReady", &maxiSample::isReady)
.function("playOnce", select_overload<double()>(&maxiSample::playOnce))
.function("playOnce", select_overload<double(double)>(&maxiSample::playOnce))
.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("play", select_overload<double(double, double, double, double&)>(&maxiSample::play))
.function("play4", &maxiSample::play4)
......
......@@ -34,6 +34,7 @@
#include "maxi_emscr.h"
#include "maxi_embind.h"
#include "big_arrays.h"
#include "emscripten/val.h"
//#include "math.h"
......@@ -111,7 +112,6 @@ double maxiOsc::sinebuf4(double frequency) {
b=sineBuffer[(long) phase];
c=sineBuffer[(long) phase+1];
d=sineBuffer[(long) phase+2];
}
a1 = 0.5f * (c - a);
......@@ -186,7 +186,6 @@ double maxiOsc::saw(double frequency) {
if ( phase >= 1.0 ) phase -= 2.0;
phase += (1./(maxiSettings::sampleRate/(frequency)));
return(output);
}
double maxiOsc::sawn(double frequency) {
......@@ -223,7 +222,6 @@ double maxiOsc::triangle(double frequency) {
output =((1.0-phase) - 0.25) * 4;
}
return(output);
}
// --------------------------------------------------------------------------------
......@@ -255,7 +253,7 @@ double maxiEnvelope::line(int numberofsegments, std::vector<double>& segments)
output=0;
}
return(output);
return output;
}
//and this
......@@ -264,7 +262,6 @@ void maxiEnvelope::trigger(int index, double amp) {
valindex=index;
SetAmplitude(amp);
// amplitude=amp;
}
// --------------------------------------------------------------------------------
......@@ -294,7 +291,6 @@ double maxiDelayline::dl(double input, int size, double feedback, int position)
memory[phase]=(memory[phase]*feedback)+(input*feedback)*chandiv;
phase+=1;
return(output);
}
......@@ -362,10 +358,6 @@ double maxiFilter::bandpass(double input,double cutoff1, double resonance) {
return(output);
}
// --------------------------------------------------------------------------------
// MAXI MIX
/*
......@@ -493,6 +485,7 @@ bool maxiSample::loadOgg(string fileName, int channel) {
return 0;
}
*/
//This sets the playback position to the start of a sample
void maxiSample::trigger() {
position = 0;
......@@ -574,40 +567,46 @@ bool maxiSample::read()
}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
}
bool maxiSample::isReady(){
if(length > 0){
return true;
}
return false;
}
void maxiSample::setSample(vector<double>& temp){
tempVec = temp;
length = temp.size();
}
// my version for easier use with js
double maxiSample::play() {
position++;
if ((int) position == length) position=0;
if ((int) position >= tempVec.size()) position=0;
// if((int)position < tempVec.size()){
output = (double)(tempVec.at((int)position));
// }
return output;
}
void maxiSample::setSample(vector<double>& temp){
tempVec = temp;
length = tempVec.size();
}
//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;
//
//}
double maxiSample::playOnce() {
position++;
if ((long) position<length)
output = (double) tempVec.at((long)position);
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) {
......@@ -744,12 +743,12 @@ double maxiSample::play4(double frequency, double start, double end) {
if ( position >= end ) position = start;
position += ((end-start)/(maxiSettings::sampleRate/(frequency*chandiv)));
remainder = position - floor(position);
if (position>0) {
a=tempVec.at((long)(floor(position))-1);
// if (position>0) { // this may not always work
if (position>=1) {
a=tempVec.at((long)(floor(position))-1); // what if larger than 1 and floor of position is 0?
} else {
a=tempVec.at(0);
}
b=tempVec.at((long) position);
......@@ -758,8 +757,8 @@ double maxiSample::play4(double frequency, double start, double end) {
} else {
c=tempVec.at(0);
}
if (position<end-3) {
d=tempVec.at((long) position+2);
......@@ -779,20 +778,17 @@ double maxiSample::play4(double frequency, double start, double end) {
remainder = position - floor(position);
if (position>start && position < end-1) {
a=tempVec.at((long) position+1);
} else {
a=tempVec.at(0);
}
b=tempVec.at((long) position);
if (position>start) {
c=tempVec.at((long) position-1);
} else {
c=tempVec.at(0);
}
if (position>start+1) {
d=tempVec.at((long) position-2);
......@@ -809,7 +805,7 @@ double maxiSample::play4(double frequency, double start, double end) {
return(output);
}
/*
//You don't need to worry about this stuff.
double maxiSample::bufferPlay(unsigned char &bufferin,long length) {
double remainder;
......@@ -817,10 +813,11 @@ double maxiSample::bufferPlay(unsigned char &bufferin,long length) {
position=(position+1);
remainder = position - (long) position;
if ((long) position>length) position=0;
output = (double) ((1-remainder) * buffer[1+ (long) position] + remainder * buffer[2+(long) position])/32767;//linear interpolation
output = (double) ((1-remainder) * buffer[1+ (long) position] + remainder * buffer[2+(long) position]);//linear interpolation
return(output);
}
/*
double maxiSample::bufferPlay(unsigned char &bufferin,double speed,long length) {
double remainder;
long a,b;
......@@ -999,25 +996,40 @@ double maxiSample::bufferPlay4(unsigned char &bufferin,double frequency, double
return(output);
}
// doesn't return length ???
void maxiSample::getLength() {
length=myDataSize*0.5;
}
void maxiSample::setLength(unsigned long numSamples) {
cout << "Length: " << numSamples << endl;
// cout << "Length: " << numSamples << endl; // why do this ?
short *newData = (short*) malloc(sizeof(short) * numSamples);
if (NULL!=temp) {
unsigned long copyLength = min((unsigned long)length, numSamples);
memcpy(newData, temp, sizeof(short) * copyLength);
}
temp = newData;
myDataSize = numSamples * 2;
myDataSize = (int)numSamples * 2; // added int conversion
length=numSamples;
position=0;
recordPosition=0;
}
*/
long maxiSample::getLength(){
return length;
}
void maxiSample::setLength(unsigned long numSamples){
myDataSize = (int)numSamples * 2; // added int conversion. does this work with vector data size?
tempVec.resize(numSamples); // is this right?
length = numSamples;
position=0;
recordPosition=0;
}
/*
void maxiSample::clear() {
memset(myData, 0, myDataSize);
}
......
......@@ -177,10 +177,7 @@ class maxiMix {
// double two[2];
// double four[4];
// double eight[8];
// vector<double> two;
// vector<double> four[4];
// vector<double> eight[8];
public:
// double x;
// double y;
......@@ -255,7 +252,8 @@ public:
short myChannels;
int mySampleRate;
long length;
void getLength();
// void getLength(); // ???
long getLength();
void setLength(unsigned long numSamples);
......@@ -275,8 +273,12 @@ public:
maxiSample():myData(NULL),temp(NULL),position(0), recordPosition(0), myChannels(1), mySampleRate(maxiSettings::sampleRate) {};
bool load(string fileName, int channel=0);
bool isReady();
// bool loadOgg(string filename,int channel=0);
//
void trigger();
......@@ -314,7 +316,7 @@ public:
double play();
void clear(){tempVec.clear();}
// double playOnce();
double playOnce();
//
double playOnce(double speed);
//
......@@ -329,7 +331,7 @@ public:
//
double play4(double frequency, double start, double end);
//
// double bufferPlay(unsigned char &bufferin,long length);
double bufferPlay(unsigned char &bufferin,long length);
//
// double bufferPlay(unsigned char &bufferin,double speed,long length);
//
......
......@@ -2,5 +2,5 @@
# My example bash script
# echo "Hello World"
../../emcc --bind -o web/maxiLib.js Maxi_Emscripten/Maxi_Emscripten/maxi_emscr.cpp
../../emcc -O1 -std=c++11 -g4 --bind -o web/maxiLib.js Maxi_Emscripten/Maxi_Emscripten/maxi_emscr.cpp
# --preload-file "test.wav"
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
......@@ -23,7 +23,7 @@ window.onload = init;
function setup(){
console.log("non-overrided setup");
// setNumOutputChannels(3);
// setNumChannels(2);
}
// this will be overriden in the users script
......@@ -32,11 +32,20 @@ function play(){
// console.log("non-overrided play happening");
}
// use to set num channels and set output as an array
// not currently working!
function setNumOutputChannels(numChannelsOut_){
function GetArrayAsVectorDbl(arrayIn){
var vecOut = new Module.VectorDouble();
for(var i = 0; i < arrayIn.length; i++){
vecOut.push_back(arrayIn[i]);
}
return vecOut;
}
if(numChannelsOut_ > 1){
// set num channels and set output as an array
// use this if you want to change number of channels
function setNumChannels(isArray, numChannelsOut_){
if(isArray){
OutputIsArray(true, numChannelsOut_);
} else {
OutputIsArray(false, numChannelsOut_);
......@@ -50,6 +59,8 @@ function setNumOutputChannels(numChannelsOut_){
}
// use this if you want to keep num of outputs but change
// method e.g. array or not
function OutputIsArray(isArray, numChannelsOut_){
if(isArray){
output = new Array(numChannelsOut_);
......@@ -68,7 +79,6 @@ var outputErrorLogged = false;
function process(event) {
var numChannels = event.outputBuffer.numberOfChannels;
var outputLength = event.outputBuffer.getChannelData(0).length;
// console.log(numChannels);
for (var i = 0; i < outputLength; ++i) {
play();
......@@ -80,6 +90,7 @@ function process(event) {
}
else
{
for (var channel = 0; channel < numChannels; channel++) {
event.outputBuffer.getChannelData(channel)[i] = output;
}
......
......@@ -58,10 +58,13 @@ loadSample("./beat2.wav", samplePlayer);
}
function play(){
output = samplePlayer.play();//just play the file. Looping is default for all play functions.
// this is necessary as file loading may not complete in setup
if(samplePlayer.isReady()){
// output = samplePlayer.play();//just play the file. Looping is default for all play functions.
// output=samplePlayer.play(0.69)/* * mySine.sinewave(260) * mySine.square(440)*/ ;//play the file with a speed setting. 1. is normal speed.
//output=samplePlayer.play(0.5,0,44100);//linear interpolationplay with a frequency input, start point and end point. Useful for syncing.
//output=samplePlayer.play4(0.5,0,44099);//cubic interpolation play with a frequency input, start point and end point. Useful for syncing.
// output=samplePlayer.play(0.5,0,44100);//linear interpolationplay with a frequency input, start point and end point. Useful for syncing.
output=samplePlayer.play4(0.5,0,44100);//cubic interpolation play with a frequency input, start point and end point. Useful for syncing.
}
}
......
<!--
Copyright 2010, Google Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html><head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>
Javascript Audio Processing
</title>
<!-- <link rel="stylesheet" type="text/css" href="javascript-processing_files/simple.css"> -->
<script src="../maxiLib.js"></script>
<script src="../maxi_webAudio.js"></script>
<!-- Our javascript code -->
<script type="text/javascript">
// var outputs = new Array(2);
// var moreoutputs = new Array(2); //some track outputs
var outputs = new Module.VectorDouble();
var moreoutputs = new Module.VectorDouble();//this data will be used to make an envelope. Value and time to value in ms.
var filtered,patch1,patch2,tune,delayed,mixed,ramp,filtered2,noise,pan,more;//a bunch of patch cables
var beat,lastbeat, morebeats, morebeats2,lastmorebeats;//some rhythmic elemts
// var env = [200,0,0,50];//the kick drum pitch envelope data
var env = GetArrayAsVectorDbl([200,0,0,50]);
// var env2 = [10000,0,9000,5,0,5];//the hi hat pitch envelope dat
var env2 = GetArrayAsVectorDbl([10000,0,9000,5,0,5]);
var melody = [600,0,0,650,0,0,400,0,0,425,0,300,0,315,0,315, 0];//the melody data
var rhythm1 = [1,0,0,1,0,0,1,0,0,1,0,0,1,0,1,0];//another way of doing a rhythm
var a = new Module.maxiOsc();
var c = new Module.maxiOsc();
var d = new Module.maxiOsc();
var e = new Module.maxiOsc();
var g = new Module.maxiOsc();
var h = new Module.maxiOsc();
var i = new Module.maxiOsc();
var j = new Module.maxiOsc();
var squarewave = new Module.maxiOsc();//some oscillators maxiOsc...
var b = new Module.maxiEnvelope();
var f = new Module.maxiEnvelope();//two envelopers
var delay = new Module.maxiDelayline();//a delay line
var myfilter = new Module.maxiFilter();
var antia = new Module.maxiFilter();// a FAT filter
var mymix = new Module.maxiMix();
var bobbins = new Module.maxiMix();//some panning busses
var beats = new Module.maxiSample();
function setup() {//some inits
outputs.push_back(0);
outputs.push_back(0);
moreoutputs.push_back(0);
moreoutputs.push_back(0);
b.amplitude=env.get(0);//starting value for envelope b
f.amplitude=env2.get(0);//same for f
// beats.load("/Users/chris/src/Maximilian/beat2.wav");//put a path to a soundfile here. Wav format only.
loadSample("./beat2.wav", beats);
// printf("Summary:\n%s", beats.getSummary());//get info on samples if you like
OutputIsArray(true, 2);
}
function play() {//this is where the magic happens. Very slow magic.
if(beats.isReady()){
beat = Math.floor(c.phasor(8));//this oscillator is now a counter
morebeats = Math.floor(e.phasor(0.5,0,16));//so is this one
patch1 = b.line(4,env);//here's envelope b
patch2 = f.line(6,env2);//here's envelop f
tune=g.saw(melody[morebeats]*0.25);
if (lastbeat!=beat) {//this is a nice sample and hold routine for the kick drum
f.trigger(0, env2.get(0));//it runs off the hi hat.
if (rhythm1[morebeats]==1) {
b.trigger(0, env.get(0));//and gets played when it's time.
// console.log("B: " + morebeats);
}
}
lastbeat=beat;//let's start again. It's a loop
ramp=i.phasor(0.5,1,2048);//create a basic ramp
pan=j.phasor(0.25);//some panning from a phasor (object is equal power)
delayed=delay.dl(tune, ramp, 0.9)*0.125;//the delay line
//then it all gets mixed.
mixed=((a.sinewave(patch1)*0.5)+((d.saw(patch2))*0.125)+(delayed*0.3)*0.5);
//add some noise
noise=i.noise()*0.25;
filtered2=beats.play(1*(1.0/16.0),0,beats.getLength());
// filtered2=beats.play(-1);
more=squarewave.pulse(melody[morebeats],pan)*0.05;
//filter the noise! this lores takes values between 1 and 100 for res, and freq for cutoff.
filtered=myfilter.lores(filtered2, 1+(pan*10000), 10)*0.4;
//now we send the sounds to some stereo busses.
mymix.stereo(more+mixed+delayed, outputs, 1-pan);
bobbins.stereo(filtered, moreoutputs, pan);//invert the pan
// mixing
output[0]=outputs.get(0)+moreoutputs.get(0);//stick it in the out!!
output[1]=outputs.get(1)+moreoutputs.get(1);
}
}
// window.onbeforeunload = function () {
// alert('unload');
// }
</script>
</head>
<body>
<h1> Sequencing Example </h1>
<p>
</p>
</body></html>
<!--
Copyright 2010, Google Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html><head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>
Javascript Audio Processing
</title>
<!-- <link rel="stylesheet" type="text/css" href="javascript-processing_files/simple.css"> -->
<script src="../maxiLib.js"></script>
<script src="../maxi_webAudio.js"></script>
<!-- Our javascript code -->
<script type="text/javascript">
//This shows how to use maximilian to build a monophonic synth
//These are the synthesiser bits
var VCO1 = new Module.maxiOsc();
var VCO2 = new Module.maxiOsc();
var LFO1 = new Module.maxiOsc();
var LFO2 = new Module.maxiOsc();
var VCF = new Module.maxiFilter();
var ADSR = new Module.maxiEnvelope();
//These are the control values for the envelope
var adsrEnvArray = [1,5,0.125,250,0.125,125,0,500];
var adsrEnv = GetArrayAsVectorDbl(adsrEnvArray);
//This is a bunch of control signals so that we can hear something
var timer = new Module.maxiOsc();//this is the metronome
var currentCount,lastCount;//these values are used to check if we have a new beat this sample