shithub: leaf

Download patch

ref: a11130bb24ab844778fc770841e263f5d3aba0c7
parent: 5d657f0156b1e5048ab1887b3e86e4333f463a9d
author: Matthew Wang <mjw7@princeton.edu>
date: Thu May 28 06:44:47 EDT 2020

rename LEAF_JUCEPlugin to TestPlugin

diff: cannot open a/LEAF_JUCEPlugin/Source//null: file does not exist: 'a/LEAF_JUCEPlugin/Source//null' diff: cannot open a/LEAF_JUCEPlugin//null: file does not exist: 'a/LEAF_JUCEPlugin//null' diff: cannot open b/TestPlugin/Source//null: file does not exist: 'b/TestPlugin/Source//null' diff: cannot open b/TestPlugin//null: file does not exist: 'b/TestPlugin//null'
--- a/LEAF_JUCEPlugin/LEAF.jucer
+++ /dev/null
@@ -1,154 +1,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<JUCERPROJECT id="ArQetv" name="LEAF" projectType="audioplug" version="1.0.0"
-              bundleIdentifier="com.pumusic.LEAF" includeBinaryInAppConfig="1"
-              buildVST="0" buildVST3="0" buildAU="1" buildAUv3="0" buildRTAS="0"
-              buildAAX="0" pluginName="LEAF" pluginDesc="LEAF" pluginManufacturer="pumusic"
-              pluginManufacturerCode="Manu" pluginCode="Arqe" pluginChannelConfigs="{2,2}"
-              pluginIsSynth="0" pluginWantsMidiIn="1" pluginProducesMidiOut="0"
-              pluginIsMidiEffectPlugin="0" pluginEditorRequiresKeys="0" pluginAUExportPrefix="LEAFAU"
-              pluginRTASCategory="" aaxIdentifier="com.pumusic.LEAF" pluginAAXCategory="2"
-              jucerVersion="5.4.7" companyName="Princeton University" companyEmail="mrmulshine@gmail.com"
-              displaySplashScreen="1" reportAppUsage="1" splashScreenColour="Dark"
-              buildStandalone="1" enableIAA="0" cppLanguageStandard="11" companyCopyright="Princeton University"
-              pluginFormats="buildAU,buildStandalone" pluginCharacteristicsValue="pluginWantsMidiIn">
-  <MAINGROUP id="F7Bywq" name="LEAF">
-    <GROUP id="{F7096CF4-1A84-4CC8-A236-06FAE894451E}" name="Examples">
-      <FILE id="hMMOsl" name="basic-oscillators.c" compile="0" resource="0"
-            file="../Examples/basic-oscillators.c"/>
-      <FILE id="mVSe2h" name="basic-oscillators.h" compile="0" resource="0"
-            file="../Examples/basic-oscillators.h"/>
-    </GROUP>
-    <GROUP id="{14C5E2CD-5D51-3FD3-5677-28BECA29E95E}" name="Source">
-      <GROUP id="{FFA9F0EC-F45A-74FC-5A10-9B3CAA731E7C}" name="External">
-        <FILE id="ixwZea" name="Yin.h" compile="0" resource="0" file="Source/Yin.h"/>
-        <FILE id="wbnjmF" name="Yin.cpp" compile="1" resource="0" file="Source/Yin.cpp"/>
-      </GROUP>
-      <GROUP id="{5EAA8994-9CCF-AFE1-27F3-6B2132200B97}" name="Test">
-        <FILE id="XkflAI" name="LEAFLink.h" compile="0" resource="0" file="Source/LEAFLink.h"/>
-        <FILE id="O9woHe" name="LEAFLink.cpp" compile="1" resource="0" file="Source/LEAFLink.cpp"/>
-        <FILE id="xGEfAX" name="LEAFTest.h" compile="0" resource="0" file="Source/LEAFTest.h"/>
-        <FILE id="xRGWtb" name="MyTest.h" compile="0" resource="0" file="Source/MyTest.h"/>
-        <FILE id="PGmAOc" name="MyTest.cpp" compile="1" resource="0" file="Source/MyTest.cpp"/>
-      </GROUP>
-      <GROUP id="{A89F40A7-55BD-BADE-F6FC-0813ECB90B8B}" name="Wrapper">
-        <FILE id="R9R9N2" name="Globals.h" compile="0" resource="0" file="Source/Globals.h"/>
-        <FILE id="oQ7Hdj" name="UIComponent.h" compile="0" resource="0" file="Source/UIComponent.h"/>
-        <FILE id="ONd1SP" name="UIComponent.cpp" compile="1" resource="0" file="Source/UIComponent.cpp"/>
-        <FILE id="EnmsIi" name="PluginProcessor.h" compile="0" resource="0"
-              file="Source/PluginProcessor.h"/>
-        <FILE id="xwxe1U" name="PluginProcessor.cpp" compile="1" resource="0"
-              file="Source/PluginProcessor.cpp"/>
-        <FILE id="L2MQTe" name="PluginEditor.h" compile="0" resource="0" file="Source/PluginEditor.h"/>
-        <FILE id="euDngN" name="PluginEditor.cpp" compile="1" resource="0"
-              file="Source/PluginEditor.cpp"/>
-      </GROUP>
-    </GROUP>
-  </MAINGROUP>
-  <EXPORTFORMATS>
-    <XCODE_MAC targetFolder="Builds/MacOSX">
-      <CONFIGURATIONS>
-        <CONFIGURATION name="Debug" isDebug="1" optimisation="1" targetName="OOPS" enablePluginBinaryCopyStep="1"/>
-        <CONFIGURATION name="Release" isDebug="0" optimisation="3" targetName="OOPS"
-                       enablePluginBinaryCopyStep="1"/>
-      </CONFIGURATIONS>
-      <MODULEPATHS>
-        <MODULEPATH id="juce_core" path="../../../../JUCE/modules"/>
-        <MODULEPATH id="juce_events" path="../../../../JUCE/modules"/>
-        <MODULEPATH id="juce_graphics" path="../../../../JUCE/modules"/>
-        <MODULEPATH id="juce_data_structures" path="../../../../JUCE/modules"/>
-        <MODULEPATH id="juce_gui_basics" path="../../../../JUCE/modules"/>
-        <MODULEPATH id="juce_gui_extra" path="../../../../JUCE/modules"/>
-        <MODULEPATH id="juce_cryptography" path="../../../../JUCE/modules"/>
-        <MODULEPATH id="juce_video" path="../../../../JUCE/modules"/>
-        <MODULEPATH id="juce_opengl" path="../../../../JUCE/modules"/>
-        <MODULEPATH id="juce_audio_basics" path="../../../../JUCE/modules"/>
-        <MODULEPATH id="juce_audio_devices" path="../../../../JUCE/modules"/>
-        <MODULEPATH id="juce_audio_formats" path="../../../../JUCE/modules"/>
-        <MODULEPATH id="juce_audio_processors" path="../../../../JUCE/modules"/>
-        <MODULEPATH id="juce_audio_plugin_client" path="../../../../JUCE/modules"/>
-        <MODULEPATH id="juce_audio_utils" path="../../../../JUCE/modules"/>
-        <MODULEPATH id="leaf" path="../../LEAF"/>
-      </MODULEPATHS>
-    </XCODE_MAC>
-    <XCODE_IPHONE targetFolder="Builds/iOS" iosScreenOrientation="portraitlandscape"
-                  iosDevelopmentTeamID="QY96HSP2FJ" microphonePermissionNeeded="1"
-                  iosBackgroundAudio="1" iPadScreenOrientation="portraitlandscape"
-                  iosDeviceFamily="1,2">
-      <CONFIGURATIONS>
-        <CONFIGURATION name="Debug" isDebug="1" optimisation="1" targetName="OOPS" enablePluginBinaryCopyStep="1"/>
-        <CONFIGURATION name="Release" isDebug="0" optimisation="3" targetName="OOPS"
-                       enablePluginBinaryCopyStep="1"/>
-      </CONFIGURATIONS>
-      <MODULEPATHS>
-        <MODULEPATH id="juce_core" path="../../../../JUCE/modules"/>
-        <MODULEPATH id="juce_events" path="../../../../JUCE/modules"/>
-        <MODULEPATH id="juce_graphics" path="../../../../JUCE/modules"/>
-        <MODULEPATH id="juce_data_structures" path="../../../../JUCE/modules"/>
-        <MODULEPATH id="juce_gui_basics" path="../../../../JUCE/modules"/>
-        <MODULEPATH id="juce_gui_extra" path="../../../../JUCE/modules"/>
-        <MODULEPATH id="juce_cryptography" path="../../../../JUCE/modules"/>
-        <MODULEPATH id="juce_video" path="../../../../JUCE/modules"/>
-        <MODULEPATH id="juce_opengl" path="../../../../JUCE/modules"/>
-        <MODULEPATH id="juce_audio_basics" path="../../../../JUCE/modules"/>
-        <MODULEPATH id="juce_audio_devices" path="../../../../JUCE/modules"/>
-        <MODULEPATH id="juce_audio_formats" path="../../../../JUCE/modules"/>
-        <MODULEPATH id="juce_audio_processors" path="../../../../JUCE/modules"/>
-        <MODULEPATH id="juce_audio_plugin_client" path="../../../../JUCE/modules"/>
-        <MODULEPATH id="juce_audio_utils" path="../../../../JUCE/modules"/>
-        <MODULEPATH id="leaf" path="../../LEAF"/>
-      </MODULEPATHS>
-    </XCODE_IPHONE>
-    <VS2017 targetFolder="Builds/VisualStudio2017">
-      <CONFIGURATIONS>
-        <CONFIGURATION name="Debug" winWarningLevel="4" generateManifest="1" winArchitecture="x64"
-                       isDebug="1" optimisation="1" targetName="OOPS" debugInformationFormat="ProgramDatabase"
-                       enablePluginBinaryCopyStep="0"/>
-        <CONFIGURATION name="Release" winWarningLevel="4" generateManifest="1" winArchitecture="x64"
-                       isDebug="0" optimisation="3" targetName="OOPS" debugInformationFormat="ProgramDatabase"
-                       enablePluginBinaryCopyStep="0" linkTimeOptimisation="1"/>
-      </CONFIGURATIONS>
-      <MODULEPATHS>
-        <MODULEPATH id="juce_video" path="..\..\..\JUCE\modules"/>
-        <MODULEPATH id="juce_opengl" path="..\..\..\JUCE\modules"/>
-        <MODULEPATH id="juce_gui_extra" path="..\..\..\JUCE\modules"/>
-        <MODULEPATH id="juce_gui_basics" path="..\..\..\JUCE\modules"/>
-        <MODULEPATH id="juce_graphics" path="..\..\..\JUCE\modules"/>
-        <MODULEPATH id="juce_events" path="..\..\..\JUCE\modules"/>
-        <MODULEPATH id="juce_data_structures" path="..\..\..\JUCE\modules"/>
-        <MODULEPATH id="juce_cryptography" path="..\..\..\JUCE\modules"/>
-        <MODULEPATH id="juce_core" path="..\..\..\JUCE\modules"/>
-        <MODULEPATH id="juce_audio_utils" path="..\..\..\JUCE\modules"/>
-        <MODULEPATH id="juce_audio_processors" path="..\..\..\JUCE\modules"/>
-        <MODULEPATH id="juce_audio_plugin_client" path="..\..\..\JUCE\modules"/>
-        <MODULEPATH id="juce_audio_formats" path="..\..\..\JUCE\modules"/>
-        <MODULEPATH id="juce_audio_devices" path="..\..\..\JUCE\modules"/>
-        <MODULEPATH id="juce_audio_basics" path="..\..\..\JUCE\modules"/>
-        <MODULEPATH id="leaf" path="../../LEAF"/>
-      </MODULEPATHS>
-    </VS2017>
-  </EXPORTFORMATS>
-  <MODULES>
-    <MODULE id="juce_audio_basics" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
-    <MODULE id="juce_audio_devices" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
-    <MODULE id="juce_audio_formats" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
-    <MODULE id="juce_audio_plugin_client" showAllCode="1" useLocalCopy="0"
-            useGlobalPath="1"/>
-    <MODULE id="juce_audio_processors" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
-    <MODULE id="juce_audio_utils" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
-    <MODULE id="juce_core" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
-    <MODULE id="juce_cryptography" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
-    <MODULE id="juce_data_structures" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
-    <MODULE id="juce_events" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
-    <MODULE id="juce_graphics" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
-    <MODULE id="juce_gui_basics" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
-    <MODULE id="juce_gui_extra" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
-    <MODULE id="juce_opengl" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
-    <MODULE id="juce_video" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
-    <MODULE id="leaf" showAllCode="1" useLocalCopy="0" useGlobalPath="0"/>
-  </MODULES>
-  <JUCEOPTIONS JUCE_QUICKTIME="disabled"/>
-  <LIVE_SETTINGS>
-    <OSX/>
-  </LIVE_SETTINGS>
-</JUCERPROJECT>
--- a/LEAF_JUCEPlugin/Source/Globals.h
+++ /dev/null
@@ -1,44 +1,0 @@
-/*
-  ==============================================================================
-
-    Globals.h
-    Created: 17 Jan 2017 12:16:12pm
-    Author:  Michael R Mulshine
-
-  ==============================================================================
-*/
-
-#ifndef GLOBALS_H_INCLUDED
-#define GLOBALS_H_INCLUDED
-
-#include "../JuceLibraryCode/JuceHeader.h"
-
-#define TEST 1
-
-
-String floatArrayToString(Array<float> arr)
-{
-    String s = "";
-    for (auto key : arr)
-    {
-        s.append(String(key), 6);
-        s.append(" ", 1);
-    }
-    return s;
-}
-
-String intArrayToString(Array<int> arr)
-{
-    String s = "";
-    for (auto key : arr)
-    {
-        s.append(String(key), 6);
-        s.append(" ", 1);
-    }
-    return s;
-}
-
-
-
-
-#endif  // GLOBALS_H_INCLUDED
--- a/LEAF_JUCEPlugin/Source/LEAFLink.cpp
+++ /dev/null
@@ -1,144 +1,0 @@
-/*
-  ==============================================================================
-
-    LEAFLink.c
-    Created: 18 Jan 2017 11:25:00am
-    Author:  Michael R Mulshine
-
-  ==============================================================================
-*/
-
-#include "LEAFLink.h"
-
-#define MYTEST 0
-#define FM     1
-
-std::vector<juce::String> cButtonNames =  std::vector<juce::String>
-{
-    
-};
-
-std::vector<juce::String> cSliderNames =  std::vector<juce::String>
-{
-    "on/off",
-    "mod freq",
-    "mod depth"
-};
-
-std::vector<juce::String> cComboBoxNames =  std::vector<juce::String>
-{
-    
-};
-
-std::vector<juce::String> cWaveformTypes =  std::vector<juce::String>
-{
-    
-};
-
-std::vector<float> cSliderModelValues(cSliderNames.size());
-std::vector<float> cSliderValues(cSliderNames.size());
-std::vector<bool> cButtonStates(cButtonNames.size());
-std::vector<int> cComboBoxStates(cComboBoxNames.size());
-
-void setSliderModelValue(String name, float val)
-{
-    for (int i = 0; i < cSliderNames.size(); i++)
-    {
-        if (name == cSliderNames[i])
-        {
-            cSliderModelValues[i] = val;
-            break;
-        }
-    }
-}
-
-void printSliderValues(void)
-{
-    for (int i = 0; i < cSliderNames.size(); i++)
-    {
-        DBG(String(cSliderNames[i]) + ": " + String(cSliderValues[i]));
-    }
-}
-
-bool getButtonState(String name)
-{
-    for (int i = 0; i < cButtonNames.size(); i++)
-    {
-        if (name == cButtonNames[i])
-        {
-            return cButtonStates[i];
-        }
-    }
-    
-    return false;
-}
-
-void setButtonState(String name, bool on)
-{
-    for (int i = 0; i < cButtonNames.size(); i++)
-    {
-        if (name == cButtonNames[i])
-        {
-            cButtonStates[i] = on;
-            break;
-        }
-    }
-}
-
-int getComboBoxState(String name)
-{
-    for (int i = 0; i < cComboBoxNames.size(); i++)
-    {
-        if (name == cComboBoxNames[i])
-        {
-            return cComboBoxStates[i];
-        }
-    }
-    return -1;
-}
-
-void setComboBoxState(String name, int idx)
-{
-    DBG("set state: " + name + " " + String(idx));
-    for (int i = 0; i < cComboBoxNames.size(); i++)
-    {
-        if (name == cComboBoxNames[i])
-        {
-            cComboBoxStates[i] = idx;
-            break;
-        }
-    }
-}
-
-void setSliderValue(String name, float val)
-{
-    for (int i = 0; i < cSliderNames.size(); i++)
-    {
-        if (name == cSliderNames[i])
-        {
-            cSliderValues[i] = val;
-            break;
-        }
-    }
-}
-
-float getSliderValue(String name)
-{
-    float value = 0.0f;
-    
-    for (int i = 0; i < cSliderNames.size(); i++)
-    {
-        if (name == cSliderNames[i])
-        {
-            value = cSliderValues[i];
-            break;
-        }
-    }
-    
-    return value;
-}
-
-float getRandomFloat(void)
-{
-    return ((float)rand()/RAND_MAX);
-}
--- a/LEAF_JUCEPlugin/Source/LEAFLink.h
+++ /dev/null
@@ -1,52 +1,0 @@
-/*
-  ==============================================================================
-
-    Utilities.h
-    Created: 5 Dec 2016 2:37:03pm
-    Author:  Michael R Mulshine
-
-  ==============================================================================
-*/
-
-#ifndef UTILITIES_H_INCLUDED
-#define UTILITIES_H_INCLUDED
-
-#include "../JuceLibraryCode/JuceHeader.h"
-
-#include "stdlib.h"
-
-typedef enum WaveformType {
-    Sine=0,
-    Triangle,
-    Sawtooth,
-    Square,
-    WaveformTypeNil
-}WaveformType;
-
-extern std::vector<juce::String> cSliderNames;
-
-extern std::vector<juce::String> cButtonNames;
-
-extern std::vector<juce::String> cComboBoxNames;
-
-extern std::vector<juce::String> cWaveformTypes;
-
-extern std::vector<float> cSliderValues;
-
-extern std::vector<float> cSliderModelValues;
-
-extern std::vector<bool> cButtonStates;
-
-extern std::vector<int> cComboBoxStates;
-
-void printSliderValues(void);
-bool getButtonState(String name);
-void setButtonState(String name, bool on);
-int getComboBoxState(String name);
-void setComboBoxState(String name, int idx);
-void setSliderModelValue(String name, float val);
-void setSliderValue(String name, float val);
-float getSliderValue(String name);
-float getRandomFloat(void);
-
-#endif  // UTILITIES_H_INCLUDED
--- a/LEAF_JUCEPlugin/Source/LEAFTest.h
+++ /dev/null
@@ -1,29 +1,0 @@
-/*
-  ==============================================================================
-
-    OOPSTest.h
-    Created: 4 Dec 2016 9:14:16pm
-    Author:  Michael R Mulshine
-
-  ==============================================================================
-*/
-
-#ifndef LEAFTEST1_H_INCLUDED
-#define LEAFTEST1_H_INCLUDED
-
-#include "LEAFLink.h"
-
-#include "../../leaf/leaf.h"
-
-#include "Yin.h"
-
-// LEAFTest API
-float   LEAFTest_tick            (float input);
-void    LEAFTest_init            (float sampleRate, int blocksize);
-void    LEAFTest_end             (void);
-void    LEAFTest_block           (void);
-
-void    LEAFTest_noteOn          (int midiNoteNumber, float velocity);
-void    LEAFTest_noteOff         (int midiNoteNumber);
-
-#endif  // LEAFTEST1_H_INCLUDED
--- a/LEAF_JUCEPlugin/Source/MyTest.cpp
+++ /dev/null
@@ -1,222 +1,0 @@
-/*
- ==============================================================================
- FM.c
- Created: 23 Jan 2017 9:39:38am
- Author:  Michael R Mulshine
- ==============================================================================
- */
-
-#include "LEAFTest.h"
-#include "MyTest.h"
-
-
-static void leaf_pool_report(void);
-static void leaf_pool_dump(void);
-static void run_pool_test(void);
-
-tNoise noise;
-tSVF bp1;
-tSVF bp2;
-tFormantShifter fs;
-
-tSampler samp;
-tBuffer buff;
-tEnvelope env;
-
-tAutotune at;
-
-
-tMinBLEP minblep;
-
-tPhasor phasor;
-
-tHighpass hipass;
-
-tMBSaw saw;
-tMBPulse pulse;
-tMBTriangle tri;
-
-float gain;
-float freq;
-float dtime;
-bool buttonState;
-int ratio = 2;
-float x = 0.0f;
-float y = 0.0f;
-float a, b, c, d;
-
-#define MSIZE 500000
-char memory[MSIZE];
-
-void    LEAFTest_init            (float sampleRate, int blockSize)
-{
-    LEAF_init(sampleRate, blockSize, memory, MSIZE, &getRandomFloat);
-    
-    tMBSaw_init(&saw);
-    
-    tMBPulse_init(&pulse);
-    
-    tMBTriangle_init(&tri);
-    
-    tPhasor_init(&phasor);
-    
-    tPhasor_setFreq(&phasor, 200);
-}
-
-inline double getSawFall(double angle) {
-    
-    angle = fmod(angle + double_Pi, 2*double_Pi); // shift x
-    double sample = angle/double_Pi - double(1); // computer as remainder
-    
-    return sample;
-    
-}
-
-float   LEAFTest_tick            (float input)
-{
-    
-    tMBSaw_setFreq(&saw, y);
-    tMBPulse_setWidth(&pulse, x);
-    tMBPulse_setFreq(&pulse, y);
-    tMBTriangle_setSkew(&tri, 0.0);//x*2.0f - 1.0f);
-    tMBTriangle_setFreq(&tri, y);
-    
-    tPhasor_tick(&phasor);
-    
-//    if (phasor->phaseDidReset) tMBSaw_sync(&saw, 0.0f);
-//    if (phasor->phaseDidReset) tMBPulse_sync(&pulse, 0.0f);
-    if (phasor->phaseDidReset) tMBTriangle_sync(&tri, 0.0f);
-    
-//    return tMBSaw_tick(&saw);
-//    return tMBPulse_tick(&pulse);
-    return tMBTriangle_tick(&tri);
-}
-
-int firstFrame = 1;
-bool lastState = false, lastPlayState = false;
-void    LEAFTest_block           (void)
-{
-    //    if (firstFrame == 1)
-    //    {
-    //        tBuffer_record(&buff); // starts recording
-    //        tSampler_play(&samp); // start spitting samples out
-    //        firstFrame = 0;
-    //    }
-    
-    float val = getSliderValue("mod freq");
-    
-    x = val ;
-    
-    //    a = val * tBuffer_getBufferLength(&buff);
-    
-    DBG("start: " + String(a));
-    
-    val = getSliderValue("mod depth");
-    
-    y = val * 5000.0f + 20.0f;
-    
-    DBG(String(y));
-    //    b = val * tBuffer_getBufferLength(&buff);
-    
-    DBG("rate: " + String(b));
-    //
-    //    tSampler_setStart(&samp, a);
-    //    tSampler_setEnd(&samp, b);
-    //    tSampler_setRate(&samp, b);
-    
-    //    tFormantShifter_setShiftFactor(&fs, x);
-    //    tFormantShifter_setIntensity(&fs, y);
-    
-}
-
-void    LEAFTest_controllerInput (int cnum, float cval)
-{
-    
-}
-
-void    LEAFTest_pitchBendInput  (int pitchBend)
-{
-    
-}
-
-int lastNote;
-void    LEAFTest_noteOn          (int note, float velocity)
-{
-}
-
-
-void    LEAFTest_noteOff         (int note)
-{
-}
-
-
-
-void    LEAFTest_end             (void)
-{
-    
-}
-
-// LEAF POOL UTILITIES
-
-void leaf_pool_report(void)
-{
-    DBG(String(leaf_pool_get_used()) + " of  " + String(leaf_pool_get_size()));
-}
-
-void leaf_pool_dump(void)
-{
-    float* buff = (float*)leaf_pool_get_pool();
-    unsigned long siz = leaf_pool_get_size();
-    siz /= sizeof(float);
-    for (int i = 0; i < siz; i++)
-    {
-        DBG(String(buff[i]));
-    }
-}
-
-static void run_pool_test(void)
-{
-    leaf_pool_report();
-    
-    DBG("ALLOC BUFFER 1");
-    int size = 50;
-    float* buffer;
-    buffer = (float*) leaf_alloc(sizeof(float) * size);
-    
-    for (int i = 0; i < size; i++)
-    {
-        buffer[i] = (float)i;
-        
-    }
-    
-    leaf_pool_report();
-    
-    DBG("ALLOC BUFFER 2");
-    size = 25;
-    
-    buffer = (float*) leaf_alloc(sizeof(float) * size);
-    
-    leaf_pool_report();
-    
-    for (int i = 0; i < size; i++)
-    {
-        buffer[i] = (float)(i*2);
-    }
-    leaf_free((char*)buffer);
-    
-    leaf_pool_report();
-    
-    DBG("ALLOC BUFFER 3");
-    size = 15;
-    
-    buffer = (float*) leaf_alloc(sizeof(float) * size);
-    
-    for (int i = 0; i < size; i++)
-    {
-        buffer[i] = (float)(i*3);
-    }
-    
-    leaf_pool_report();
-    
-    leaf_pool_dump();
-}
--- a/LEAF_JUCEPlugin/Source/MyTest.h
+++ /dev/null
@@ -1,16 +1,0 @@
-/*
-  ==============================================================================
-
-    MyTest.h
-    Created: 23 Jan 2017 9:39:38am
-    Author:  Michael R Mulshine
-
-  ==============================================================================
-*/
-
-#ifndef FM_H_INCLUDED
-#define FM_H_INCLUDED
-
-
-
-#endif  // FM_H_INCLUDED
--- a/LEAF_JUCEPlugin/Source/PluginEditor.cpp
+++ /dev/null
@@ -1,13 +1,0 @@
-/*
-  ==============================================================================
-
-    This file was auto-generated!
-
-    It contains the basic framework code for a JUCE plugin editor.
-
-  ==============================================================================
-*/
-
-//#include "PluginEditor.h"
-
-
--- a/LEAF_JUCEPlugin/Source/PluginEditor.h
+++ /dev/null
@@ -1,42 +1,0 @@
-/*
-  ==============================================================================
-
-    This file was auto-generated!
-
-    It contains the basic framework code for a JUCE plugin editor.
-
-  ==============================================================================
-*/
-
-#ifndef PLUGINEDITOR_H_INCLUDED
-#define PLUGINEDITOR_H_INCLUDED
-
-#include "PluginProcessor.h"
-
-#include "UIComponent.h"
-
-//==============================================================================
-/**
-*/
-class OopsAudioProcessorEditor  : public AudioProcessorEditor
-{
-public:
-    OopsAudioProcessorEditor (OopsAudioProcessor&);
-    ~OopsAudioProcessorEditor();
-
-    //==============================================================================
-    void paint (Graphics&) override;
-    void resized() override;
-
-private:
-    // This reference is provided as a quick way for your editor to
-    // access the processor object that created it.
-    
-    UIComponent uicomponent;
-    OopsAudioProcessor& processor;
-
-    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OopsAudioProcessorEditor)
-};
-
-
-#endif  // PLUGINEDITOR_H_INCLUDED
--- a/LEAF_JUCEPlugin/Source/PluginProcessor.cpp
+++ /dev/null
@@ -1,237 +1,0 @@
-/*
-  ==============================================================================
-
-    This file was auto-generated!
-
-    It contains the basic framework code for a JUCE plugin processor.
-
-  ==============================================================================
-*/
-
-#include "PluginProcessor.h"
-#include "PluginEditor.h"
-
-#include "UIComponent.h"
-
-#include "LEAFTest.h"
-
-//==============================================================================
-OopsAudioProcessorEditor::OopsAudioProcessorEditor (OopsAudioProcessor& p)
-: AudioProcessorEditor (&p), processor (p)
-{
-    // Make sure that before the constructor has finished, you've set the
-    // editor's size to whatever you need it to be.
-    setSize (600, 400);
-    
-    addAndMakeVisible(uicomponent);
-}
-
-OopsAudioProcessorEditor::~OopsAudioProcessorEditor()
-{
-}
-
-//==============================================================================
-void OopsAudioProcessorEditor::paint (Graphics& g)
-{
-    g.fillAll (Colours::white);
-}
-
-void OopsAudioProcessorEditor::resized()
-{
-    uicomponent.setBounds(getBounds());
-}
-//==============================================================================
-void OopsAudioProcessor::prepareToPlay (double sampleRate, int samplesPerBlock)
-{
-    gain = 0.0f;
-    timer = 0;
-    start = false;
-    ramp = false;
-    
-    LEAFTest_init(sampleRate, samplesPerBlock);
-}
-
-
-
-//====================================BLOCK=======================================
-
-void OopsAudioProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages)
-{
-   const int totalNumInputChannels  = getTotalNumInputChannels();
-   const int totalNumOutputChannels = getTotalNumOutputChannels();
-    
-    for (int i = totalNumInputChannels; i < totalNumOutputChannels; ++i)
-        buffer.clear (i, 0, buffer.getNumSamples());
-    
-    LEAFTest_block();
-    
-    MidiMessage m;
-    int time;
-    
-    for (MidiBuffer::Iterator i (midiMessages); i.getNextEvent (m, time);)
-    {
-        int noteNumber = m.getNoteNumber();
-        float velocity = m.getFloatVelocity();
-        
-        if (m.isNoteOn())
-        {
-            LEAFTest_noteOn(noteNumber, velocity);
-        }
-        else if (m.isNoteOff())
-        {
-            LEAFTest_noteOff(noteNumber);
-        }
-        else
-        {
-            
-        }
-    }
-    
-
-   const float* inPointerL = buffer.getReadPointer (0);
-   const float* inPointerR = buffer.getReadPointer (1);
-    
-    float* outPointerL = buffer.getWritePointer( 0);
-    float* outPointerR = buffer.getWritePointer( 1);
-    
-    for (int samp = 0; samp < buffer.getNumSamples(); ++samp)
-    {
-        outPointerL[samp] = LEAFTest_tick( (inPointerL[samp] +inPointerR[samp]) * 0.5f);
-        outPointerR[samp] = outPointerL[samp];
-    }
-}
-
-//==============================================================================
-
-OopsAudioProcessor::OopsAudioProcessor()
-#ifndef JucePlugin_PreferredChannelConfigurations
-: AudioProcessor (BusesProperties()
-    #if ! JucePlugin_IsMidiEffect
-        #if ! JucePlugin_IsSynth
-    .withInput  ("Input",  AudioChannelSet::stereo(), true)
-        #endif
-    .withOutput ("Output", AudioChannelSet::stereo(), true)
-    #endif
-                  )
-#endif
-{
-    
-}
-
-OopsAudioProcessor::~OopsAudioProcessor()
-{
-
-}
-
-//==============================================================================
-const String OopsAudioProcessor::getName() const
-{
-    return JucePlugin_Name;
-}
-
-bool OopsAudioProcessor::acceptsMidi() const
-{
-    return true;
-}
-
-bool OopsAudioProcessor::producesMidi() const
-{
-   #if JucePlugin_ProducesMidiOutput
-    return true;
-   #else
-    return false;
-   #endif
-}
-
-double OopsAudioProcessor::getTailLengthSeconds() const
-{
-    return 0.0;
-}
-
-int OopsAudioProcessor::getNumPrograms()
-{
-    return 1;   // NB: some hosts don't cope very well if you tell them there are 0 programs,
-                // so this should be at least 1, even if you're not really implementing programs.
-}
-
-int OopsAudioProcessor::getCurrentProgram()
-{
-    return 0;
-}
-
-void OopsAudioProcessor::setCurrentProgram (int index)
-{
-}
-
-const String OopsAudioProcessor::getProgramName (int index)
-{
-    return String();
-}
-
-void OopsAudioProcessor::changeProgramName (int index, const String& newName)
-{
-}
-
-void OopsAudioProcessor::releaseResources()
-{
-    // When playback stops, you can use this as an opportunity to free up any
-    // spare memory, etc.
-    LEAFTest_end();
-}
-
-#ifndef JucePlugin_PreferredChannelConfigurations
-bool OopsAudioProcessor::isBusesLayoutSupported (const BusesLayout& layouts) const
-{
-  #if JucePlugin_IsMidiEffect
-    ignoreUnused (layouts);
-    return true;
-  #else
-    // This is the place where you check if the layout is supported.
-    // In this template code we only support mono or stereo.
-    if (layouts.getMainOutputChannelSet() != AudioChannelSet::mono()
-     && layouts.getMainOutputChannelSet() != AudioChannelSet::stereo())
-        return false;
-
-    // This checks if the input layout matches the output layout
-   #if ! JucePlugin_IsSynth
-    if (layouts.getMainOutputChannelSet() != layouts.getMainInputChannelSet())
-        return false;
-   #endif
-
-    return true;
-  #endif
-}
-#endif
-
-
-//==============================================================================
-bool OopsAudioProcessor::hasEditor() const
-{
-    return true; // (change this to false if you choose to not supply an editor)
-}
-
-AudioProcessorEditor* OopsAudioProcessor::createEditor()
-{
-    return new OopsAudioProcessorEditor (*this);
-}
-
-//==============================================================================
-void OopsAudioProcessor::getStateInformation (MemoryBlock& destData)
-{
-    // You should use this method to store your parameters in the memory block.
-    // You could do that either as raw data, or use the XML or ValueTree classes
-    // as intermediaries to make it easy to save and load complex data.
-}
-
-void OopsAudioProcessor::setStateInformation (const void* data, int sizeInBytes)
-{
-    // You should use this method to restore your parameters from this memory block,
-    // whose contents will have been created by the getStateInformation() call.
-}
-
-//==============================================================================
-// This creates new instances of the plugin..
-AudioProcessor* JUCE_CALLTYPE createPluginFilter()
-{
-    return new OopsAudioProcessor();
-}
--- a/LEAF_JUCEPlugin/Source/PluginProcessor.h
+++ /dev/null
@@ -1,68 +1,0 @@
-/*
-  ==============================================================================
-
-    This file was auto-generated!
-
-    It contains the basic framework code for a JUCE plugin processor.
-
-  ==============================================================================
-*/
-
-#ifndef PLUGINPROCESSOR_H_INCLUDED
-#define PLUGINPROCESSOR_H_INCLUDED
-
-#include "../JuceLibraryCode/JuceHeader.h"
-
-
-//==============================================================================
-/**
-*/
-class OopsAudioProcessor  : public AudioProcessor
-{
-public:
-    //==============================================================================
-    OopsAudioProcessor();
-    ~OopsAudioProcessor();
-
-    //==============================================================================
-    void prepareToPlay (double sampleRate, int samplesPerBlock) override;
-    void releaseResources() override;
-
-   #ifndef JucePlugin_PreferredChannelConfigurations
-    bool isBusesLayoutSupported (const BusesLayout& layouts) const override;
-   #endif
-
-    void processBlock (AudioSampleBuffer&, MidiBuffer&) override;
-
-    //==============================================================================
-    AudioProcessorEditor* createEditor() override;
-    bool hasEditor() const override;
-
-    //==============================================================================
-   const String getName() const override;
-
-    bool acceptsMidi() const override;
-    bool producesMidi() const override;
-    double getTailLengthSeconds() const override;
-
-    //==============================================================================
-    int getNumPrograms() override;
-    int getCurrentProgram() override;
-    void setCurrentProgram (int index) override;
-   const String getProgramName (int index) override;
-    void changeProgramName (int index, const String& newName) override;
-
-    //==============================================================================
-    void getStateInformation (MemoryBlock& destData) override;
-    void setStateInformation (const void* data, int sizeInBytes) override;
-
-private:
-    uint64 timer;
-    float gain;
-    bool start,ramp;
-    //==============================================================================
-    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OopsAudioProcessor)
-};
-
-
-#endif  // PLUGINPROCESSOR_H_INCLUDED
--- a/LEAF_JUCEPlugin/Source/UIComponent.cpp
+++ /dev/null
@@ -1,155 +1,0 @@
-/*
-  ==============================================================================
-
-    UIComponent.c
-    Created: 18 Jan 2017 11:19:15am
-    Author:  Michael R Mulshine
-
-  ==============================================================================
-*/
-
-#include "UIComponent.h"
-
-#include "LEAFLink.h"
-
-UIComponent::UIComponent()
-
-{
-    for (int i = 0; i < cSliderNames.size(); i++)
-    {
-        
-        sliders.set(i,  new Slider());
-        sliders[i]->setSliderStyle(Slider::SliderStyle::LinearVertical);
-        sliders[i]->setRange(0.0, 1.0, 1.0/50000.0);
-        sliders[i]->setName(cSliderNames[i]);
-        sliders[i]->setComponentID(String(i));
-        sliders[i]->addListener(this);
-        addAndMakeVisible(sliders[i]);
-        
-        sliderLabels.set(i,   new Label());
-        sliderLabels[i]->setName(cSliderNames[i]);
-        sliderLabels[i]->setColour(Label::textColourId, Colours::aliceblue);
-        sliderLabels[i]->setText(cSliderNames[i], NotificationType::dontSendNotification);
-        addAndMakeVisible(sliderLabels[i]);
-        
-        textFields.set(i, new TextEditor());
-        textFields[i]->addListener(this);
-        textFields[i]->setName(cSliderNames[i]);
-        textFields[i]->setEnabled(false);
-        addAndMakeVisible(textFields[i]);
-    }
-    
-    for (int i = 0; i < cButtonNames.size(); i++)
-    {
-        buttons.set(i, new TextButton(cButtonNames[i]));
-        buttons[i]->changeWidthToFitText();
-        buttons[i]->setButtonText(cButtonNames[i]);
-        buttons[i]->addListener(this);
-        addAndMakeVisible(buttons[i]);
-    }
-    
-    for (int i = 0; i < cComboBoxNames.size(); i++)
-    {
-        comboBoxes.set(i, new ComboBox());
-        comboBoxes[i]->setName(cComboBoxNames[i]);
-        comboBoxes[i]->addSeparator();
-        comboBoxes[i]->addListener(this);
-        addAndMakeVisible(comboBoxes[i]);
-        
-    }
-    
-    for (int i = 0; i < cComboBoxNames.size(); i++)
-    {
-        for (int j = 0; j < cWaveformTypes.size(); j++)
-        {
-            comboBoxes[i]->addItem(cWaveformTypes[j], j+1);
-        }
-        comboBoxes[i]->setSelectedItemIndex(0);
-    }
-    
-    
-    startTimerHz(20);
-}
-
-void UIComponent::timerCallback(void)
-{
-    for (int i = 0; i < cSliderNames.size(); i++)
-        textFields[i]->setText(String(cSliderModelValues[i]), false);
-}
-
-void UIComponent::textEditorTextChanged (TextEditor& tf)
-{
-    
-}
-
-UIComponent::~UIComponent()
-{
-}
-
-void UIComponent::paint (Graphics& g)
-{
-    /* This demo code just fills the component's background and
-     draws some placeholder text to get you started.
-     
-     You should replace everything in this method with your own
-     drawing code..
-     */
-    
-    g.fillAll (Colours::slategrey);   // clear the background
-    
-    g.setColour (Colours::aliceblue);
-    g.drawRect (getLocalBounds(), 1);   // draw an outline around the component
-}
-
-void UIComponent::resized()
-{
-    for (int i = 0; i < cSliderNames.size(); i++)
-    {
-        sliders[i]      ->setBounds(cLeftOffset + ((cSliderWidth + cXSpacing) * i),
-                                    cTopOffset,
-                                    cSliderWidth,
-                                    cSliderHeight);
-        
-        textFields[i]   ->setBounds(sliders[i]->getX()  - (cSliderNames[i].length() * 2.0f),
-                                    sliders[i]->getBottom() + cYSpacing,
-                                    75,
-                                    20);
-        
-        sliderLabels[i] ->setBounds(sliders[i]->getX() - (cSliderNames[i].length() * 2.0f),
-                                    textFields[i]->getBottom() + cYSpacing,
-                                    cLabelWidth,
-                                    cLabelHeight);
-    }
-    
-    for (int i = 0; i < cButtonNames.size(); i++)
-    {
-        buttons[i]      ->setBounds(cLeftOffset + ((cButtonWidth + cXSpacing) * i),
-                                    500,
-                                    cButtonWidth,
-                                    cButtonHeight);
-    }
-    
-    for (int i = 0; i < cComboBoxNames.size(); i++)
-    {
-        comboBoxes[i]   ->setBounds(
-                                    cLeftOffset + ((cButtonWidth + cXSpacing) * i),
-                                    cTopOffset + cSliderHeight + cLabelHeight + cButtonHeight + 3 * cYSpacing,
-                                    cBoxWidth,
-                                    cBoxHeight    );
-    }
-}
-
-void UIComponent::sliderValueChanged(Slider* s)
-{
-    setSliderValue(s->getName(), s->getValue());
-}
-
-void UIComponent::buttonStateChanged (Button* b)
-{
-    setButtonState(b->getName(), b->getState());
-}
-
-void UIComponent::comboBoxChanged (ComboBox* cb)
-{
-    setComboBoxState(cb->getName(), cb->getSelectedId() - 1);
-}
--- a/LEAF_JUCEPlugin/Source/UIComponent.h
+++ /dev/null
@@ -1,77 +1,0 @@
-/*
-  ==============================================================================
-
-    UIComponent.h
-    Created: 5 Dec 2016 2:23:38pm
-    Author:  Michael R Mulshine
-
-  ==============================================================================
-*/
-
-#ifndef UICOMPONENT_H_INCLUDED
-#define UICOMPONENT_H_INCLUDED
-
-#include "../JuceLibraryCode/JuceHeader.h"
-
-//==============================================================================
-/*
-*/
-class UIComponent:
-public Component,
-public Slider::Listener,
-public TextButton::Listener,
-public ComboBox::Listener,
-public TextEditor::Listener,
-private Timer
-{
-public:
-    UIComponent();
-
-    ~UIComponent();
-
-    void paint (Graphics& g) override;
-
-    void resized() override;
-    
-    void sliderValueChanged(Slider* s) override;
-    
-    void buttonClicked(Button*b) override {};
-    void buttonStateChanged(Button* b) override;
-    
-    void textEditorTextChanged (TextEditor&) override;
-    
-    void comboBoxChanged (ComboBox* cb) override;
-    
-    void timerCallback() override;
-    
-private:
-    
-    static const int cLeftOffset = 30;
-    static const int cTopOffset = 30;
-    
-    static const int cXSpacing = 60;
-    static const int cYSpacing = 5;
-    
-    static const int cSliderHeight = 200;
-    static const int cSliderWidth = 20;
-    
-    static const int cLabelHeight = 20;
-    static const int cLabelWidth  = cSliderWidth + cXSpacing;
-    
-    static const int cButtonHeight = 30;
-    static const int cButtonWidth  = 60;
-    
-    static const int cBoxHeight = 20;
-    static const int cBoxWidth  =  100;
-    
-    OwnedArray<Slider>      sliders;
-    OwnedArray<Label>       sliderLabels;
-    OwnedArray<TextButton>  buttons;
-    OwnedArray<TextEditor>  textFields;
-    OwnedArray<ComboBox>    comboBoxes;
-    
-    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (UIComponent)
-};
-
-
-#endif  // UICOMPONENT_H_INCLUDED
--- a/LEAF_JUCEPlugin/Source/Yin.cpp
+++ /dev/null
@@ -1,233 +1,0 @@
-/*
-  ==============================================================================
-
-    Yin.c
-    Created: 17 Jan 2017 1:20:23pm
-    Author:  Michael R Mulshine
-
-  ==============================================================================
-*/
-
-#include "Yin.h"
-
-#include <stdint.h> /* For standard interger types (int16_t) */
-#include <stdlib.h> /* For call to malloc */
-
-/* ------------------------------------------------------------------------------------------
---------------------------------------------------------------------------- PRIVATE FUNCTIONS
--------------------------------------------------------------------------------------------*/
-
-/**
- * Step 1: Calculates the squared difference of the signal with a shifted version of itself.
- * @param buffer Buffer of samples to process. 
- *
- * This is the Yin algorithms tweak on autocorellation. Read http://audition.ens.fr/adc/pdf/2002_JASA_YIN.pdf
- * for more details on what is in here and why it's done this way.
- */
-void Yin_difference(Yin *yin, int16_t* buffer){
-	int16_t i;
-	int16_t tau;
-	float delta;
-
-	/* Calculate the difference for difference shift values (tau) for the half of the samples */
-	for(tau = 0 ; tau < yin->halfBufferSize; tau++){
-
-		/* Take the difference of the signal with a shifted version of itself, then square it.
-		 * (This is the Yin algorithm's tweak on autocorellation) */ 
-		for(i = 0; i < yin->halfBufferSize; i++){
-			delta = buffer[i] - buffer[i + tau];
-			yin->yinBuffer[tau] += delta * delta;
-		}
-	}
-}
-
-
-/**
- * Step 2: Calculate the cumulative mean on the normalised difference calculated in step 1
- * @param yin #Yin structure with information about the signal
- *
- * This goes through the Yin autocorellation values and finds out roughly where shift is which 
- * produced the smallest difference
- */
-void Yin_cumulativeMeanNormalizedDifference(Yin *yin){
-	int16_t tau;
-	float runningSum = 0;
-	yin->yinBuffer[0] = 1;
-
-	/* Sum all the values in the autocorellation buffer and nomalise the result, replacing
-	 * the value in the autocorellation buffer with a cumulative mean of the normalised difference */
-	for (tau = 1; tau < yin->halfBufferSize; tau++) {
-		runningSum += yin->yinBuffer[tau];
-		yin->yinBuffer[tau] *= tau / runningSum;
-	}
-}
-
-/**
- * Step 3: Search through the normalised cumulative mean array and find values that are over the threshold
- * @return Shift (tau) which caused the best approximate autocorellation. -1 if no suitable value is found over the threshold.
- */
-int16_t Yin_absoluteThreshold(Yin *yin){
-	int16_t tau;
-
-	/* Search through the array of cumulative mean values, and look for ones that are over the threshold 
-	 * The first two positions in yinBuffer are always so start at the third (index 2) */
-	for (tau = 2; tau < yin->halfBufferSize ; tau++) {
-		if (yin->yinBuffer[tau] < yin->threshold) {
-			while (tau + 1 < yin->halfBufferSize && yin->yinBuffer[tau + 1] < yin->yinBuffer[tau]) {
-				tau++;
-			}
-			/* found tau, exit loop and return
-			 * store the probability
-			 * From the YIN paper: The yin->threshold determines the list of
-			 * candidates admitted to the set, and can be interpreted as the
-			 * proportion of aperiodic power tolerated
-			 * within a periodic signal.
-			 *
-			 * Since we want the periodicity and and not aperiodicity:
-			 * periodicity = 1 - aperiodicity */
-			yin->probability = 1 - yin->yinBuffer[tau];
-			break;
-		}
-	}
-
-	/* if no pitch found, tau => -1 */
-	if (tau == yin->halfBufferSize || yin->yinBuffer[tau] >= yin->threshold) {
-		tau = -1;
-		yin->probability = 0;
-	}
-
-	return tau;
-}
-
-/**
- * Step 5: Interpolate the shift value (tau) to improve the pitch estimate.
- * @param  yin         [description]
- * @param  tauEstimate [description]
- * @return             [description]
- *
- * The 'best' shift value for autocorellation is most likely not an interger shift of the signal.
- * As we only autocorellated using integer shifts we should check that there isn't a better fractional 
- * shift value.
- */
-float Yin_parabolicInterpolation(Yin *yin, int16_t tauEstimate) {
-	float betterTau;
-	int16_t x0;
-	int16_t x2;
-	
-	/* Calculate the first polynomial coeffcient based on the current estimate of tau */
-	if (tauEstimate < 1) {
-		x0 = tauEstimate;
-	} 
-	else {
-		x0 = tauEstimate - 1;
-	}
-
-	/* Calculate the second polynomial coeffcient based on the current estimate of tau */
-	if (tauEstimate + 1 < yin->halfBufferSize) {
-		x2 = tauEstimate + 1;
-	} 
-	else {
-		x2 = tauEstimate;
-	}
-
-	/* Algorithm to parabolically interpolate the shift value tau to find a better estimate */
-	if (x0 == tauEstimate) {
-		if (yin->yinBuffer[tauEstimate] <= yin->yinBuffer[x2]) {
-			betterTau = tauEstimate;
-		} 
-		else {
-			betterTau = x2;
-		}
-	} 
-	else if (x2 == tauEstimate) {
-		if (yin->yinBuffer[tauEstimate] <= yin->yinBuffer[x0]) {
-			betterTau = tauEstimate;
-		} 
-		else {
-			betterTau = x0;
-		}
-	} 
-	else {
-		float s0, s1, s2;
-		s0 = yin->yinBuffer[x0];
-		s1 = yin->yinBuffer[tauEstimate];
-		s2 = yin->yinBuffer[x2];
-		// fixed AUBIO implementation, thanks to Karl Helgason:
-		// (2.0f * s1 - s2 - s0) was incorrectly multiplied with -1
-		betterTau = tauEstimate + (s2 - s0) / (2 * (2 * s1 - s2 - s0));
-	}
-
-
-	return betterTau;
-}
-
-
-
-
-
-/* ------------------------------------------------------------------------------------------
----------------------------------------------------------------------------- PUBLIC FUNCTIONS
--------------------------------------------------------------------------------------------*/
-
-
-
-/**
- * Initialise the Yin pitch detection object
- * @param yin        Yin pitch detection object to initialise
- * @param bufferSize Length of the audio buffer to analyse
- * @param threshold  Allowed uncertainty (e.g 0.05 will return a pitch with ~95% probability)
- */
-void Yin_init(Yin *yin, int16_t bufferSize, float threshold){
-	/* Initialise the fields of the Yin structure passed in */
-	yin->bufferSize = bufferSize;
-	yin->halfBufferSize = bufferSize / 2;
-	yin->probability = 0.0;
-	yin->threshold = threshold;
-
-	/* Allocate the autocorellation buffer and initialise it to zero */
-	yin->yinBuffer = (float *) malloc(sizeof(float)* yin->halfBufferSize);
-
-	int16_t i;
-	for(i = 0; i < yin->halfBufferSize; i++){
-		yin->yinBuffer[i] = 0;
-	}
-}
-
-/**
- * Runs the Yin pitch detection algortihm
- * @param  yin    Initialised Yin object
- * @param  buffer Buffer of samples to analyse
- * @return        Fundamental frequency of the signal in Hz. Returns -1 if pitch can't be found
- */
-float Yin_getPitch(Yin *yin, int16_t* buffer){
-	int16_t tauEstimate = -1;
-	float pitchInHertz = -1;
-	
-	/* Step 1: Calculates the squared difference of the signal with a shifted version of itself. */
-	Yin_difference(yin, buffer);
-	
-	/* Step 2: Calculate the cumulative mean on the normalised difference calculated in step 1 */
-	Yin_cumulativeMeanNormalizedDifference(yin);
-	
-	/* Step 3: Search through the normalised cumulative mean array and find values that are over the threshold */
-	tauEstimate = Yin_absoluteThreshold(yin);
-	
-	/* Step 5: Interpolate the shift value (tau) to improve the pitch estimate. */
-	if(tauEstimate != -1){
-		pitchInHertz = YIN_SAMPLING_RATE / Yin_parabolicInterpolation(yin, tauEstimate);
-	}
-	
-	return pitchInHertz;
-}
-
-/**
- * Certainty of the pitch found 
- * @param  yin Yin object that has been run over a buffer
- * @return     Returns the certainty of the note found as a decimal (i.e 0.3 is 30%)
- */
-float Yin_getProbability(Yin *yin){
-	return yin->probability;
-}
-
-
-
--- a/LEAF_JUCEPlugin/Source/Yin.h
+++ /dev/null
@@ -1,56 +1,0 @@
-/*
-  ==============================================================================
-
-    Yin.h
-    Created: 17 Jan 2017 1:20:23pm
-    Author:  Michael R Mulshine
-
-  ==============================================================================
-*/
-
-#ifndef YIN_H_INCLUDED
-#define YIN_H_INCLUDED
-
-#include <stdint.h>
-
-#define YIN_SAMPLING_RATE 44100
-#define YIN_DEFAULT_THRESHOLD 0.15
-
-/**
- * @struct  Yin
- * @breif	Object to encapsulate the parameters for the Yin pitch detection algorithm 
- */
-typedef struct _Yin {
-	int16_t bufferSize;			/**< Size of the audio buffer to be analysed */
-	int16_t halfBufferSize;		/**< Half the buffer length */
-	float* yinBuffer;		/**< Buffer that stores the results of the intermediate processing steps of the algorithm */
-	float probability;		/**< Probability that the pitch found is correct as a decimal (i.e 0.85 is 85%) */
-	float threshold;		/**< Allowed uncertainty in the result as a decimal (i.e 0.15 is 15%) */
-} Yin;
-
-/**
- * Initialise the Yin pitch detection object
- * @param yin        Yin pitch detection object to initialise
- * @param bufferSize Length of the audio buffer to analyse
- * @param threshold  Allowed uncertainty (e.g 0.05 will return a pitch with ~95% probability)
- */
-void Yin_init(Yin *yin, int16_t bufferSize, float threshold);
-
-/**
- * Runs the Yin pitch detection algortihm
- * @param  yin    Initialised Yin object
- * @param  buffer Buffer of samples to analyse
- * @return        Fundamental frequency of the signal in Hz. Returns -1 if pitch can't be found
- */
-float Yin_getPitch(Yin *yin, int16_t* buffer);
-
-/**
- * Certainty of the pitch found 
- * @param  yin Yin object that has been run over a buffer
- * @return     Returns the certainty of the note found as a decimal (i.e 0.3 is 30%)
- */
-float Yin_getProbability(Yin *yin);
-	
-
-
-#endif  // YIN_H_INCLUDED
--- /dev/null
+++ b/TestPlugin/LEAF.jucer
@@ -1,0 +1,154 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<JUCERPROJECT id="ArQetv" name="LEAF" projectType="audioplug" version="1.0.0"
+              bundleIdentifier="com.pumusic.LEAF" includeBinaryInAppConfig="1"
+              buildVST="0" buildVST3="0" buildAU="1" buildAUv3="0" buildRTAS="0"
+              buildAAX="0" pluginName="LEAF" pluginDesc="LEAF" pluginManufacturer="pumusic"
+              pluginManufacturerCode="Manu" pluginCode="Arqe" pluginChannelConfigs="{2,2}"
+              pluginIsSynth="0" pluginWantsMidiIn="1" pluginProducesMidiOut="0"
+              pluginIsMidiEffectPlugin="0" pluginEditorRequiresKeys="0" pluginAUExportPrefix="LEAFAU"
+              pluginRTASCategory="" aaxIdentifier="com.pumusic.LEAF" pluginAAXCategory="2"
+              jucerVersion="5.4.7" companyName="Princeton University" companyEmail="mrmulshine@gmail.com"
+              displaySplashScreen="1" reportAppUsage="1" splashScreenColour="Dark"
+              buildStandalone="1" enableIAA="0" cppLanguageStandard="11" companyCopyright="Princeton University"
+              pluginFormats="buildAU,buildStandalone" pluginCharacteristicsValue="pluginWantsMidiIn">
+  <MAINGROUP id="F7Bywq" name="LEAF">
+    <GROUP id="{F7096CF4-1A84-4CC8-A236-06FAE894451E}" name="Examples">
+      <FILE id="hMMOsl" name="basic-oscillators.c" compile="0" resource="0"
+            file="../Examples/basic-oscillators.c"/>
+      <FILE id="mVSe2h" name="basic-oscillators.h" compile="0" resource="0"
+            file="../Examples/basic-oscillators.h"/>
+    </GROUP>
+    <GROUP id="{14C5E2CD-5D51-3FD3-5677-28BECA29E95E}" name="Source">
+      <GROUP id="{FFA9F0EC-F45A-74FC-5A10-9B3CAA731E7C}" name="External">
+        <FILE id="ixwZea" name="Yin.h" compile="0" resource="0" file="Source/Yin.h"/>
+        <FILE id="wbnjmF" name="Yin.cpp" compile="1" resource="0" file="Source/Yin.cpp"/>
+      </GROUP>
+      <GROUP id="{5EAA8994-9CCF-AFE1-27F3-6B2132200B97}" name="Test">
+        <FILE id="XkflAI" name="LEAFLink.h" compile="0" resource="0" file="Source/LEAFLink.h"/>
+        <FILE id="O9woHe" name="LEAFLink.cpp" compile="1" resource="0" file="Source/LEAFLink.cpp"/>
+        <FILE id="xGEfAX" name="LEAFTest.h" compile="0" resource="0" file="Source/LEAFTest.h"/>
+        <FILE id="xRGWtb" name="MyTest.h" compile="0" resource="0" file="Source/MyTest.h"/>
+        <FILE id="PGmAOc" name="MyTest.cpp" compile="1" resource="0" file="Source/MyTest.cpp"/>
+      </GROUP>
+      <GROUP id="{A89F40A7-55BD-BADE-F6FC-0813ECB90B8B}" name="Wrapper">
+        <FILE id="R9R9N2" name="Globals.h" compile="0" resource="0" file="Source/Globals.h"/>
+        <FILE id="oQ7Hdj" name="UIComponent.h" compile="0" resource="0" file="Source/UIComponent.h"/>
+        <FILE id="ONd1SP" name="UIComponent.cpp" compile="1" resource="0" file="Source/UIComponent.cpp"/>
+        <FILE id="EnmsIi" name="PluginProcessor.h" compile="0" resource="0"
+              file="Source/PluginProcessor.h"/>
+        <FILE id="xwxe1U" name="PluginProcessor.cpp" compile="1" resource="0"
+              file="Source/PluginProcessor.cpp"/>
+        <FILE id="L2MQTe" name="PluginEditor.h" compile="0" resource="0" file="Source/PluginEditor.h"/>
+        <FILE id="euDngN" name="PluginEditor.cpp" compile="1" resource="0"
+              file="Source/PluginEditor.cpp"/>
+      </GROUP>
+    </GROUP>
+  </MAINGROUP>
+  <EXPORTFORMATS>
+    <XCODE_MAC targetFolder="Builds/MacOSX">
+      <CONFIGURATIONS>
+        <CONFIGURATION name="Debug" isDebug="1" optimisation="1" targetName="OOPS" enablePluginBinaryCopyStep="1"/>
+        <CONFIGURATION name="Release" isDebug="0" optimisation="3" targetName="OOPS"
+                       enablePluginBinaryCopyStep="1"/>
+      </CONFIGURATIONS>
+      <MODULEPATHS>
+        <MODULEPATH id="juce_core" path="../../../../JUCE/modules"/>
+        <MODULEPATH id="juce_events" path="../../../../JUCE/modules"/>
+        <MODULEPATH id="juce_graphics" path="../../../../JUCE/modules"/>
+        <MODULEPATH id="juce_data_structures" path="../../../../JUCE/modules"/>
+        <MODULEPATH id="juce_gui_basics" path="../../../../JUCE/modules"/>
+        <MODULEPATH id="juce_gui_extra" path="../../../../JUCE/modules"/>
+        <MODULEPATH id="juce_cryptography" path="../../../../JUCE/modules"/>
+        <MODULEPATH id="juce_video" path="../../../../JUCE/modules"/>
+        <MODULEPATH id="juce_opengl" path="../../../../JUCE/modules"/>
+        <MODULEPATH id="juce_audio_basics" path="../../../../JUCE/modules"/>
+        <MODULEPATH id="juce_audio_devices" path="../../../../JUCE/modules"/>
+        <MODULEPATH id="juce_audio_formats" path="../../../../JUCE/modules"/>
+        <MODULEPATH id="juce_audio_processors" path="../../../../JUCE/modules"/>
+        <MODULEPATH id="juce_audio_plugin_client" path="../../../../JUCE/modules"/>
+        <MODULEPATH id="juce_audio_utils" path="../../../../JUCE/modules"/>
+        <MODULEPATH id="leaf" path="../../LEAF"/>
+      </MODULEPATHS>
+    </XCODE_MAC>
+    <XCODE_IPHONE targetFolder="Builds/iOS" iosScreenOrientation="portraitlandscape"
+                  iosDevelopmentTeamID="QY96HSP2FJ" microphonePermissionNeeded="1"
+                  iosBackgroundAudio="1" iPadScreenOrientation="portraitlandscape"
+                  iosDeviceFamily="1,2">
+      <CONFIGURATIONS>
+        <CONFIGURATION name="Debug" isDebug="1" optimisation="1" targetName="OOPS" enablePluginBinaryCopyStep="1"/>
+        <CONFIGURATION name="Release" isDebug="0" optimisation="3" targetName="OOPS"
+                       enablePluginBinaryCopyStep="1"/>
+      </CONFIGURATIONS>
+      <MODULEPATHS>
+        <MODULEPATH id="juce_core" path="../../../../JUCE/modules"/>
+        <MODULEPATH id="juce_events" path="../../../../JUCE/modules"/>
+        <MODULEPATH id="juce_graphics" path="../../../../JUCE/modules"/>
+        <MODULEPATH id="juce_data_structures" path="../../../../JUCE/modules"/>
+        <MODULEPATH id="juce_gui_basics" path="../../../../JUCE/modules"/>
+        <MODULEPATH id="juce_gui_extra" path="../../../../JUCE/modules"/>
+        <MODULEPATH id="juce_cryptography" path="../../../../JUCE/modules"/>
+        <MODULEPATH id="juce_video" path="../../../../JUCE/modules"/>
+        <MODULEPATH id="juce_opengl" path="../../../../JUCE/modules"/>
+        <MODULEPATH id="juce_audio_basics" path="../../../../JUCE/modules"/>
+        <MODULEPATH id="juce_audio_devices" path="../../../../JUCE/modules"/>
+        <MODULEPATH id="juce_audio_formats" path="../../../../JUCE/modules"/>
+        <MODULEPATH id="juce_audio_processors" path="../../../../JUCE/modules"/>
+        <MODULEPATH id="juce_audio_plugin_client" path="../../../../JUCE/modules"/>
+        <MODULEPATH id="juce_audio_utils" path="../../../../JUCE/modules"/>
+        <MODULEPATH id="leaf" path="../../LEAF"/>
+      </MODULEPATHS>
+    </XCODE_IPHONE>
+    <VS2017 targetFolder="Builds/VisualStudio2017">
+      <CONFIGURATIONS>
+        <CONFIGURATION name="Debug" winWarningLevel="4" generateManifest="1" winArchitecture="x64"
+                       isDebug="1" optimisation="1" targetName="OOPS" debugInformationFormat="ProgramDatabase"
+                       enablePluginBinaryCopyStep="0"/>
+        <CONFIGURATION name="Release" winWarningLevel="4" generateManifest="1" winArchitecture="x64"
+                       isDebug="0" optimisation="3" targetName="OOPS" debugInformationFormat="ProgramDatabase"
+                       enablePluginBinaryCopyStep="0" linkTimeOptimisation="1"/>
+      </CONFIGURATIONS>
+      <MODULEPATHS>
+        <MODULEPATH id="juce_video" path="..\..\..\JUCE\modules"/>
+        <MODULEPATH id="juce_opengl" path="..\..\..\JUCE\modules"/>
+        <MODULEPATH id="juce_gui_extra" path="..\..\..\JUCE\modules"/>
+        <MODULEPATH id="juce_gui_basics" path="..\..\..\JUCE\modules"/>
+        <MODULEPATH id="juce_graphics" path="..\..\..\JUCE\modules"/>
+        <MODULEPATH id="juce_events" path="..\..\..\JUCE\modules"/>
+        <MODULEPATH id="juce_data_structures" path="..\..\..\JUCE\modules"/>
+        <MODULEPATH id="juce_cryptography" path="..\..\..\JUCE\modules"/>
+        <MODULEPATH id="juce_core" path="..\..\..\JUCE\modules"/>
+        <MODULEPATH id="juce_audio_utils" path="..\..\..\JUCE\modules"/>
+        <MODULEPATH id="juce_audio_processors" path="..\..\..\JUCE\modules"/>
+        <MODULEPATH id="juce_audio_plugin_client" path="..\..\..\JUCE\modules"/>
+        <MODULEPATH id="juce_audio_formats" path="..\..\..\JUCE\modules"/>
+        <MODULEPATH id="juce_audio_devices" path="..\..\..\JUCE\modules"/>
+        <MODULEPATH id="juce_audio_basics" path="..\..\..\JUCE\modules"/>
+        <MODULEPATH id="leaf" path="../../LEAF"/>
+      </MODULEPATHS>
+    </VS2017>
+  </EXPORTFORMATS>
+  <MODULES>
+    <MODULE id="juce_audio_basics" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
+    <MODULE id="juce_audio_devices" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
+    <MODULE id="juce_audio_formats" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
+    <MODULE id="juce_audio_plugin_client" showAllCode="1" useLocalCopy="0"
+            useGlobalPath="1"/>
+    <MODULE id="juce_audio_processors" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
+    <MODULE id="juce_audio_utils" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
+    <MODULE id="juce_core" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
+    <MODULE id="juce_cryptography" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
+    <MODULE id="juce_data_structures" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
+    <MODULE id="juce_events" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
+    <MODULE id="juce_graphics" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
+    <MODULE id="juce_gui_basics" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
+    <MODULE id="juce_gui_extra" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
+    <MODULE id="juce_opengl" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
+    <MODULE id="juce_video" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
+    <MODULE id="leaf" showAllCode="1" useLocalCopy="0" useGlobalPath="0"/>
+  </MODULES>
+  <JUCEOPTIONS JUCE_QUICKTIME="disabled"/>
+  <LIVE_SETTINGS>
+    <OSX/>
+  </LIVE_SETTINGS>
+</JUCERPROJECT>
--- /dev/null
+++ b/TestPlugin/Source/Globals.h
@@ -1,0 +1,44 @@
+/*
+  ==============================================================================
+
+    Globals.h
+    Created: 17 Jan 2017 12:16:12pm
+    Author:  Michael R Mulshine
+
+  ==============================================================================
+*/
+
+#ifndef GLOBALS_H_INCLUDED
+#define GLOBALS_H_INCLUDED
+
+#include "../JuceLibraryCode/JuceHeader.h"
+
+#define TEST 1
+
+
+String floatArrayToString(Array<float> arr)
+{
+    String s = "";
+    for (auto key : arr)
+    {
+        s.append(String(key), 6);
+        s.append(" ", 1);
+    }
+    return s;
+}
+
+String intArrayToString(Array<int> arr)
+{
+    String s = "";
+    for (auto key : arr)
+    {
+        s.append(String(key), 6);
+        s.append(" ", 1);
+    }
+    return s;
+}
+
+
+
+
+#endif  // GLOBALS_H_INCLUDED
--- /dev/null
+++ b/TestPlugin/Source/LEAFLink.cpp
@@ -1,0 +1,144 @@
+/*
+  ==============================================================================
+
+    LEAFLink.c
+    Created: 18 Jan 2017 11:25:00am
+    Author:  Michael R Mulshine
+
+  ==============================================================================
+*/
+
+#include "LEAFLink.h"
+
+#define MYTEST 0
+#define FM     1
+
+std::vector<juce::String> cButtonNames =  std::vector<juce::String>
+{
+    
+};
+
+std::vector<juce::String> cSliderNames =  std::vector<juce::String>
+{
+    "on/off",
+    "mod freq",
+    "mod depth"
+};
+
+std::vector<juce::String> cComboBoxNames =  std::vector<juce::String>
+{
+    
+};
+
+std::vector<juce::String> cWaveformTypes =  std::vector<juce::String>
+{
+    
+};
+
+std::vector<float> cSliderModelValues(cSliderNames.size());
+std::vector<float> cSliderValues(cSliderNames.size());
+std::vector<bool> cButtonStates(cButtonNames.size());
+std::vector<int> cComboBoxStates(cComboBoxNames.size());
+
+void setSliderModelValue(String name, float val)
+{
+    for (int i = 0; i < cSliderNames.size(); i++)
+    {
+        if (name == cSliderNames[i])
+        {
+            cSliderModelValues[i] = val;
+            break;
+        }
+    }
+}
+
+void printSliderValues(void)
+{
+    for (int i = 0; i < cSliderNames.size(); i++)
+    {
+        DBG(String(cSliderNames[i]) + ": " + String(cSliderValues[i]));
+    }
+}
+
+bool getButtonState(String name)
+{
+    for (int i = 0; i < cButtonNames.size(); i++)
+    {
+        if (name == cButtonNames[i])
+        {
+            return cButtonStates[i];
+        }
+    }
+    
+    return false;
+}
+
+void setButtonState(String name, bool on)
+{
+    for (int i = 0; i < cButtonNames.size(); i++)
+    {
+        if (name == cButtonNames[i])
+        {
+            cButtonStates[i] = on;
+            break;
+        }
+    }
+}
+
+int getComboBoxState(String name)
+{
+    for (int i = 0; i < cComboBoxNames.size(); i++)
+    {
+        if (name == cComboBoxNames[i])
+        {
+            return cComboBoxStates[i];
+        }
+    }
+    return -1;
+}
+
+void setComboBoxState(String name, int idx)
+{
+    DBG("set state: " + name + " " + String(idx));
+    for (int i = 0; i < cComboBoxNames.size(); i++)
+    {
+        if (name == cComboBoxNames[i])
+        {
+            cComboBoxStates[i] = idx;
+            break;
+        }
+    }
+}
+
+void setSliderValue(String name, float val)
+{
+    for (int i = 0; i < cSliderNames.size(); i++)
+    {
+        if (name == cSliderNames[i])
+        {
+            cSliderValues[i] = val;
+            break;
+        }
+    }
+}
+
+float getSliderValue(String name)
+{
+    float value = 0.0f;
+    
+    for (int i = 0; i < cSliderNames.size(); i++)
+    {
+        if (name == cSliderNames[i])
+        {
+            value = cSliderValues[i];
+            break;
+        }
+    }
+    
+    return value;
+}
+
+float getRandomFloat(void)
+{
+    return ((float)rand()/RAND_MAX);
+}
--- /dev/null
+++ b/TestPlugin/Source/LEAFLink.h
@@ -1,0 +1,52 @@
+/*
+  ==============================================================================
+
+    Utilities.h
+    Created: 5 Dec 2016 2:37:03pm
+    Author:  Michael R Mulshine
+
+  ==============================================================================
+*/
+
+#ifndef UTILITIES_H_INCLUDED
+#define UTILITIES_H_INCLUDED
+
+#include "../JuceLibraryCode/JuceHeader.h"
+
+#include "stdlib.h"
+
+typedef enum WaveformType {
+    Sine=0,
+    Triangle,
+    Sawtooth,
+    Square,
+    WaveformTypeNil
+}WaveformType;
+
+extern std::vector<juce::String> cSliderNames;
+
+extern std::vector<juce::String> cButtonNames;
+
+extern std::vector<juce::String> cComboBoxNames;
+
+extern std::vector<juce::String> cWaveformTypes;
+
+extern std::vector<float> cSliderValues;
+
+extern std::vector<float> cSliderModelValues;
+
+extern std::vector<bool> cButtonStates;
+
+extern std::vector<int> cComboBoxStates;
+
+void printSliderValues(void);
+bool getButtonState(String name);
+void setButtonState(String name, bool on);
+int getComboBoxState(String name);
+void setComboBoxState(String name, int idx);
+void setSliderModelValue(String name, float val);
+void setSliderValue(String name, float val);
+float getSliderValue(String name);
+float getRandomFloat(void);
+
+#endif  // UTILITIES_H_INCLUDED
--- /dev/null
+++ b/TestPlugin/Source/LEAFTest.h
@@ -1,0 +1,29 @@
+/*
+  ==============================================================================
+
+    OOPSTest.h
+    Created: 4 Dec 2016 9:14:16pm
+    Author:  Michael R Mulshine
+
+  ==============================================================================
+*/
+
+#ifndef LEAFTEST1_H_INCLUDED
+#define LEAFTEST1_H_INCLUDED
+
+#include "LEAFLink.h"
+
+#include "../../leaf/leaf.h"
+
+#include "Yin.h"
+
+// LEAFTest API
+float   LEAFTest_tick            (float input);
+void    LEAFTest_init            (float sampleRate, int blocksize);
+void    LEAFTest_end             (void);
+void    LEAFTest_block           (void);
+
+void    LEAFTest_noteOn          (int midiNoteNumber, float velocity);
+void    LEAFTest_noteOff         (int midiNoteNumber);
+
+#endif  // LEAFTEST1_H_INCLUDED
--- /dev/null
+++ b/TestPlugin/Source/MyTest.cpp
@@ -1,0 +1,222 @@
+/*
+ ==============================================================================
+ FM.c
+ Created: 23 Jan 2017 9:39:38am
+ Author:  Michael R Mulshine
+ ==============================================================================
+ */
+
+#include "LEAFTest.h"
+#include "MyTest.h"
+
+
+static void leaf_pool_report(void);
+static void leaf_pool_dump(void);
+static void run_pool_test(void);
+
+tNoise noise;
+tSVF bp1;
+tSVF bp2;
+tFormantShifter fs;
+
+tSampler samp;
+tBuffer buff;
+tEnvelope env;
+
+tAutotune at;
+
+
+tMinBLEP minblep;
+
+tPhasor phasor;
+
+tHighpass hipass;
+
+tMBSaw saw;
+tMBPulse pulse;
+tMBTriangle tri;
+
+float gain;
+float freq;
+float dtime;
+bool buttonState;
+int ratio = 2;
+float x = 0.0f;
+float y = 0.0f;
+float a, b, c, d;
+
+#define MSIZE 500000
+char memory[MSIZE];
+
+void    LEAFTest_init            (float sampleRate, int blockSize)
+{
+    LEAF_init(sampleRate, blockSize, memory, MSIZE, &getRandomFloat);
+    
+    tMBSaw_init(&saw);
+    
+    tMBPulse_init(&pulse);
+    
+    tMBTriangle_init(&tri);
+    
+    tPhasor_init(&phasor);
+    
+    tPhasor_setFreq(&phasor, 200);
+}
+
+inline double getSawFall(double angle) {
+    
+    angle = fmod(angle + double_Pi, 2*double_Pi); // shift x
+    double sample = angle/double_Pi - double(1); // computer as remainder
+    
+    return sample;
+    
+}
+
+float   LEAFTest_tick            (float input)
+{
+    
+    tMBSaw_setFreq(&saw, y);
+    tMBPulse_setWidth(&pulse, x);
+    tMBPulse_setFreq(&pulse, y);
+    tMBTriangle_setSkew(&tri, 0.0);//x*2.0f - 1.0f);
+    tMBTriangle_setFreq(&tri, y);
+    
+    tPhasor_tick(&phasor);
+    
+//    if (phasor->phaseDidReset) tMBSaw_sync(&saw, 0.0f);
+//    if (phasor->phaseDidReset) tMBPulse_sync(&pulse, 0.0f);
+    if (phasor->phaseDidReset) tMBTriangle_sync(&tri, 0.0f);
+    
+//    return tMBSaw_tick(&saw);
+//    return tMBPulse_tick(&pulse);
+    return tMBTriangle_tick(&tri);
+}
+
+int firstFrame = 1;
+bool lastState = false, lastPlayState = false;
+void    LEAFTest_block           (void)
+{
+    //    if (firstFrame == 1)
+    //    {
+    //        tBuffer_record(&buff); // starts recording
+    //        tSampler_play(&samp); // start spitting samples out
+    //        firstFrame = 0;
+    //    }
+    
+    float val = getSliderValue("mod freq");
+    
+    x = val ;
+    
+    //    a = val * tBuffer_getBufferLength(&buff);
+    
+    DBG("start: " + String(a));
+    
+    val = getSliderValue("mod depth");
+    
+    y = val * 5000.0f + 20.0f;
+    
+    DBG(String(y));
+    //    b = val * tBuffer_getBufferLength(&buff);
+    
+    DBG("rate: " + String(b));
+    //
+    //    tSampler_setStart(&samp, a);
+    //    tSampler_setEnd(&samp, b);
+    //    tSampler_setRate(&samp, b);
+    
+    //    tFormantShifter_setShiftFactor(&fs, x);
+    //    tFormantShifter_setIntensity(&fs, y);
+    
+}
+
+void    LEAFTest_controllerInput (int cnum, float cval)
+{
+    
+}
+
+void    LEAFTest_pitchBendInput  (int pitchBend)
+{
+    
+}
+
+int lastNote;
+void    LEAFTest_noteOn          (int note, float velocity)
+{
+}
+
+
+void    LEAFTest_noteOff         (int note)
+{
+}
+
+
+
+void    LEAFTest_end             (void)
+{
+    
+}
+
+// LEAF POOL UTILITIES
+
+void leaf_pool_report(void)
+{
+    DBG(String(leaf_pool_get_used()) + " of  " + String(leaf_pool_get_size()));
+}
+
+void leaf_pool_dump(void)
+{
+    float* buff = (float*)leaf_pool_get_pool();
+    unsigned long siz = leaf_pool_get_size();
+    siz /= sizeof(float);
+    for (int i = 0; i < siz; i++)
+    {
+        DBG(String(buff[i]));
+    }
+}
+
+static void run_pool_test(void)
+{
+    leaf_pool_report();
+    
+    DBG("ALLOC BUFFER 1");
+    int size = 50;
+    float* buffer;
+    buffer = (float*) leaf_alloc(sizeof(float) * size);
+    
+    for (int i = 0; i < size; i++)
+    {
+        buffer[i] = (float)i;
+        
+    }
+    
+    leaf_pool_report();
+    
+    DBG("ALLOC BUFFER 2");
+    size = 25;
+    
+    buffer = (float*) leaf_alloc(sizeof(float) * size);
+    
+    leaf_pool_report();
+    
+    for (int i = 0; i < size; i++)
+    {
+        buffer[i] = (float)(i*2);
+    }
+    leaf_free((char*)buffer);
+    
+    leaf_pool_report();
+    
+    DBG("ALLOC BUFFER 3");
+    size = 15;
+    
+    buffer = (float*) leaf_alloc(sizeof(float) * size);
+    
+    for (int i = 0; i < size; i++)
+    {
+        buffer[i] = (float)(i*3);
+    }
+    
+    leaf_pool_report();
+    
+    leaf_pool_dump();
+}
--- /dev/null
+++ b/TestPlugin/Source/MyTest.h
@@ -1,0 +1,16 @@
+/*
+  ==============================================================================
+
+    MyTest.h
+    Created: 23 Jan 2017 9:39:38am
+    Author:  Michael R Mulshine
+
+  ==============================================================================
+*/
+
+#ifndef FM_H_INCLUDED
+#define FM_H_INCLUDED
+
+
+
+#endif  // FM_H_INCLUDED
--- /dev/null
+++ b/TestPlugin/Source/PluginEditor.cpp
@@ -1,0 +1,13 @@
+/*
+  ==============================================================================
+
+    This file was auto-generated!
+
+    It contains the basic framework code for a JUCE plugin editor.
+
+  ==============================================================================
+*/
+
+//#include "PluginEditor.h"
+
+
--- /dev/null
+++ b/TestPlugin/Source/PluginEditor.h
@@ -1,0 +1,42 @@
+/*
+  ==============================================================================
+
+    This file was auto-generated!
+
+    It contains the basic framework code for a JUCE plugin editor.
+
+  ==============================================================================
+*/
+
+#ifndef PLUGINEDITOR_H_INCLUDED
+#define PLUGINEDITOR_H_INCLUDED
+
+#include "PluginProcessor.h"
+
+#include "UIComponent.h"
+
+//==============================================================================
+/**
+*/
+class OopsAudioProcessorEditor  : public AudioProcessorEditor
+{
+public:
+    OopsAudioProcessorEditor (OopsAudioProcessor&);
+    ~OopsAudioProcessorEditor();
+
+    //==============================================================================
+    void paint (Graphics&) override;
+    void resized() override;
+
+private:
+    // This reference is provided as a quick way for your editor to
+    // access the processor object that created it.
+    
+    UIComponent uicomponent;
+    OopsAudioProcessor& processor;
+
+    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OopsAudioProcessorEditor)
+};
+
+
+#endif  // PLUGINEDITOR_H_INCLUDED
--- /dev/null
+++ b/TestPlugin/Source/PluginProcessor.cpp
@@ -1,0 +1,237 @@
+/*
+  ==============================================================================
+
+    This file was auto-generated!
+
+    It contains the basic framework code for a JUCE plugin processor.
+
+  ==============================================================================
+*/
+
+#include "PluginProcessor.h"
+#include "PluginEditor.h"
+
+#include "UIComponent.h"
+
+#include "LEAFTest.h"
+
+//==============================================================================
+OopsAudioProcessorEditor::OopsAudioProcessorEditor (OopsAudioProcessor& p)
+: AudioProcessorEditor (&p), processor (p)
+{
+    // Make sure that before the constructor has finished, you've set the
+    // editor's size to whatever you need it to be.
+    setSize (600, 400);
+    
+    addAndMakeVisible(uicomponent);
+}
+
+OopsAudioProcessorEditor::~OopsAudioProcessorEditor()
+{
+}
+
+//==============================================================================
+void OopsAudioProcessorEditor::paint (Graphics& g)
+{
+    g.fillAll (Colours::white);
+}
+
+void OopsAudioProcessorEditor::resized()
+{
+    uicomponent.setBounds(getBounds());
+}
+//==============================================================================
+void OopsAudioProcessor::prepareToPlay (double sampleRate, int samplesPerBlock)
+{
+    gain = 0.0f;
+    timer = 0;
+    start = false;
+    ramp = false;
+    
+    LEAFTest_init(sampleRate, samplesPerBlock);
+}
+
+
+
+//====================================BLOCK=======================================
+
+void OopsAudioProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages)
+{
+   const int totalNumInputChannels  = getTotalNumInputChannels();
+   const int totalNumOutputChannels = getTotalNumOutputChannels();
+    
+    for (int i = totalNumInputChannels; i < totalNumOutputChannels; ++i)
+        buffer.clear (i, 0, buffer.getNumSamples());
+    
+    LEAFTest_block();
+    
+    MidiMessage m;
+    int time;
+    
+    for (MidiBuffer::Iterator i (midiMessages); i.getNextEvent (m, time);)
+    {
+        int noteNumber = m.getNoteNumber();
+        float velocity = m.getFloatVelocity();
+        
+        if (m.isNoteOn())
+        {
+            LEAFTest_noteOn(noteNumber, velocity);
+        }
+        else if (m.isNoteOff())
+        {
+            LEAFTest_noteOff(noteNumber);
+        }
+        else
+        {
+            
+        }
+    }
+    
+
+   const float* inPointerL = buffer.getReadPointer (0);
+   const float* inPointerR = buffer.getReadPointer (1);
+    
+    float* outPointerL = buffer.getWritePointer( 0);
+    float* outPointerR = buffer.getWritePointer( 1);
+    
+    for (int samp = 0; samp < buffer.getNumSamples(); ++samp)
+    {
+        outPointerL[samp] = LEAFTest_tick( (inPointerL[samp] +inPointerR[samp]) * 0.5f);
+        outPointerR[samp] = outPointerL[samp];
+    }
+}
+
+//==============================================================================
+
+OopsAudioProcessor::OopsAudioProcessor()
+#ifndef JucePlugin_PreferredChannelConfigurations
+: AudioProcessor (BusesProperties()
+    #if ! JucePlugin_IsMidiEffect
+        #if ! JucePlugin_IsSynth
+    .withInput  ("Input",  AudioChannelSet::stereo(), true)
+        #endif
+    .withOutput ("Output", AudioChannelSet::stereo(), true)
+    #endif
+                  )
+#endif
+{
+    
+}
+
+OopsAudioProcessor::~OopsAudioProcessor()
+{
+
+}
+
+//==============================================================================
+const String OopsAudioProcessor::getName() const
+{
+    return JucePlugin_Name;
+}
+
+bool OopsAudioProcessor::acceptsMidi() const
+{
+    return true;
+}
+
+bool OopsAudioProcessor::producesMidi() const
+{
+   #if JucePlugin_ProducesMidiOutput
+    return true;
+   #else
+    return false;
+   #endif
+}
+
+double OopsAudioProcessor::getTailLengthSeconds() const
+{
+    return 0.0;
+}
+
+int OopsAudioProcessor::getNumPrograms()
+{
+    return 1;   // NB: some hosts don't cope very well if you tell them there are 0 programs,
+                // so this should be at least 1, even if you're not really implementing programs.
+}
+
+int OopsAudioProcessor::getCurrentProgram()
+{
+    return 0;
+}
+
+void OopsAudioProcessor::setCurrentProgram (int index)
+{
+}
+
+const String OopsAudioProcessor::getProgramName (int index)
+{
+    return String();
+}
+
+void OopsAudioProcessor::changeProgramName (int index, const String& newName)
+{
+}
+
+void OopsAudioProcessor::releaseResources()
+{
+    // When playback stops, you can use this as an opportunity to free up any
+    // spare memory, etc.
+    LEAFTest_end();
+}
+
+#ifndef JucePlugin_PreferredChannelConfigurations
+bool OopsAudioProcessor::isBusesLayoutSupported (const BusesLayout& layouts) const
+{
+  #if JucePlugin_IsMidiEffect
+    ignoreUnused (layouts);
+    return true;
+  #else
+    // This is the place where you check if the layout is supported.
+    // In this template code we only support mono or stereo.
+    if (layouts.getMainOutputChannelSet() != AudioChannelSet::mono()
+     && layouts.getMainOutputChannelSet() != AudioChannelSet::stereo())
+        return false;
+
+    // This checks if the input layout matches the output layout
+   #if ! JucePlugin_IsSynth
+    if (layouts.getMainOutputChannelSet() != layouts.getMainInputChannelSet())
+        return false;
+   #endif
+
+    return true;
+  #endif
+}
+#endif
+
+
+//==============================================================================
+bool OopsAudioProcessor::hasEditor() const
+{
+    return true; // (change this to false if you choose to not supply an editor)
+}
+
+AudioProcessorEditor* OopsAudioProcessor::createEditor()
+{
+    return new OopsAudioProcessorEditor (*this);
+}
+
+//==============================================================================
+void OopsAudioProcessor::getStateInformation (MemoryBlock& destData)
+{
+    // You should use this method to store your parameters in the memory block.
+    // You could do that either as raw data, or use the XML or ValueTree classes
+    // as intermediaries to make it easy to save and load complex data.
+}
+
+void OopsAudioProcessor::setStateInformation (const void* data, int sizeInBytes)
+{
+    // You should use this method to restore your parameters from this memory block,
+    // whose contents will have been created by the getStateInformation() call.
+}
+
+//==============================================================================
+// This creates new instances of the plugin..
+AudioProcessor* JUCE_CALLTYPE createPluginFilter()
+{
+    return new OopsAudioProcessor();
+}
--- /dev/null
+++ b/TestPlugin/Source/PluginProcessor.h
@@ -1,0 +1,68 @@
+/*
+  ==============================================================================
+
+    This file was auto-generated!
+
+    It contains the basic framework code for a JUCE plugin processor.
+
+  ==============================================================================
+*/
+
+#ifndef PLUGINPROCESSOR_H_INCLUDED
+#define PLUGINPROCESSOR_H_INCLUDED
+
+#include "../JuceLibraryCode/JuceHeader.h"
+
+
+//==============================================================================
+/**
+*/
+class OopsAudioProcessor  : public AudioProcessor
+{
+public:
+    //==============================================================================
+    OopsAudioProcessor();
+    ~OopsAudioProcessor();
+
+    //==============================================================================
+    void prepareToPlay (double sampleRate, int samplesPerBlock) override;
+    void releaseResources() override;
+
+   #ifndef JucePlugin_PreferredChannelConfigurations
+    bool isBusesLayoutSupported (const BusesLayout& layouts) const override;
+   #endif
+
+    void processBlock (AudioSampleBuffer&, MidiBuffer&) override;
+
+    //==============================================================================
+    AudioProcessorEditor* createEditor() override;
+    bool hasEditor() const override;
+
+    //==============================================================================
+   const String getName() const override;
+
+    bool acceptsMidi() const override;
+    bool producesMidi() const override;
+    double getTailLengthSeconds() const override;
+
+    //==============================================================================
+    int getNumPrograms() override;
+    int getCurrentProgram() override;
+    void setCurrentProgram (int index) override;
+   const String getProgramName (int index) override;
+    void changeProgramName (int index, const String& newName) override;
+
+    //==============================================================================
+    void getStateInformation (MemoryBlock& destData) override;
+    void setStateInformation (const void* data, int sizeInBytes) override;
+
+private:
+    uint64 timer;
+    float gain;
+    bool start,ramp;
+    //==============================================================================
+    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OopsAudioProcessor)
+};
+
+
+#endif  // PLUGINPROCESSOR_H_INCLUDED
--- /dev/null
+++ b/TestPlugin/Source/UIComponent.cpp
@@ -1,0 +1,155 @@
+/*
+  ==============================================================================
+
+    UIComponent.c
+    Created: 18 Jan 2017 11:19:15am
+    Author:  Michael R Mulshine
+
+  ==============================================================================
+*/
+
+#include "UIComponent.h"
+
+#include "LEAFLink.h"
+
+UIComponent::UIComponent()
+
+{
+    for (int i = 0; i < cSliderNames.size(); i++)
+    {
+        
+        sliders.set(i,  new Slider());
+        sliders[i]->setSliderStyle(Slider::SliderStyle::LinearVertical);
+        sliders[i]->setRange(0.0, 1.0, 1.0/50000.0);
+        sliders[i]->setName(cSliderNames[i]);
+        sliders[i]->setComponentID(String(i));
+        sliders[i]->addListener(this);
+        addAndMakeVisible(sliders[i]);
+        
+        sliderLabels.set(i,   new Label());
+        sliderLabels[i]->setName(cSliderNames[i]);
+        sliderLabels[i]->setColour(Label::textColourId, Colours::aliceblue);
+        sliderLabels[i]->setText(cSliderNames[i], NotificationType::dontSendNotification);
+        addAndMakeVisible(sliderLabels[i]);
+        
+        textFields.set(i, new TextEditor());
+        textFields[i]->addListener(this);
+        textFields[i]->setName(cSliderNames[i]);
+        textFields[i]->setEnabled(false);
+        addAndMakeVisible(textFields[i]);
+    }
+    
+    for (int i = 0; i < cButtonNames.size(); i++)
+    {
+        buttons.set(i, new TextButton(cButtonNames[i]));
+        buttons[i]->changeWidthToFitText();
+        buttons[i]->setButtonText(cButtonNames[i]);
+        buttons[i]->addListener(this);
+        addAndMakeVisible(buttons[i]);
+    }
+    
+    for (int i = 0; i < cComboBoxNames.size(); i++)
+    {
+        comboBoxes.set(i, new ComboBox());
+        comboBoxes[i]->setName(cComboBoxNames[i]);
+        comboBoxes[i]->addSeparator();
+        comboBoxes[i]->addListener(this);
+        addAndMakeVisible(comboBoxes[i]);
+        
+    }
+    
+    for (int i = 0; i < cComboBoxNames.size(); i++)
+    {
+        for (int j = 0; j < cWaveformTypes.size(); j++)
+        {
+            comboBoxes[i]->addItem(cWaveformTypes[j], j+1);
+        }
+        comboBoxes[i]->setSelectedItemIndex(0);
+    }
+    
+    
+    startTimerHz(20);
+}
+
+void UIComponent::timerCallback(void)
+{
+    for (int i = 0; i < cSliderNames.size(); i++)
+        textFields[i]->setText(String(cSliderModelValues[i]), false);
+}
+
+void UIComponent::textEditorTextChanged (TextEditor& tf)
+{
+    
+}
+
+UIComponent::~UIComponent()
+{
+}
+
+void UIComponent::paint (Graphics& g)
+{
+    /* This demo code just fills the component's background and
+     draws some placeholder text to get you started.
+     
+     You should replace everything in this method with your own
+     drawing code..
+     */
+    
+    g.fillAll (Colours::slategrey);   // clear the background
+    
+    g.setColour (Colours::aliceblue);
+    g.drawRect (getLocalBounds(), 1);   // draw an outline around the component
+}
+
+void UIComponent::resized()
+{
+    for (int i = 0; i < cSliderNames.size(); i++)
+    {
+        sliders[i]      ->setBounds(cLeftOffset + ((cSliderWidth + cXSpacing) * i),
+                                    cTopOffset,
+                                    cSliderWidth,
+                                    cSliderHeight);
+        
+        textFields[i]   ->setBounds(sliders[i]->getX()  - (cSliderNames[i].length() * 2.0f),
+                                    sliders[i]->getBottom() + cYSpacing,
+                                    75,
+                                    20);
+        
+        sliderLabels[i] ->setBounds(sliders[i]->getX() - (cSliderNames[i].length() * 2.0f),
+                                    textFields[i]->getBottom() + cYSpacing,
+                                    cLabelWidth,
+                                    cLabelHeight);
+    }
+    
+    for (int i = 0; i < cButtonNames.size(); i++)
+    {
+        buttons[i]      ->setBounds(cLeftOffset + ((cButtonWidth + cXSpacing) * i),
+                                    500,
+                                    cButtonWidth,
+                                    cButtonHeight);
+    }
+    
+    for (int i = 0; i < cComboBoxNames.size(); i++)
+    {
+        comboBoxes[i]   ->setBounds(
+                                    cLeftOffset + ((cButtonWidth + cXSpacing) * i),
+                                    cTopOffset + cSliderHeight + cLabelHeight + cButtonHeight + 3 * cYSpacing,
+                                    cBoxWidth,
+                                    cBoxHeight    );
+    }
+}
+
+void UIComponent::sliderValueChanged(Slider* s)
+{
+    setSliderValue(s->getName(), s->getValue());
+}
+
+void UIComponent::buttonStateChanged (Button* b)
+{
+    setButtonState(b->getName(), b->getState());
+}
+
+void UIComponent::comboBoxChanged (ComboBox* cb)
+{
+    setComboBoxState(cb->getName(), cb->getSelectedId() - 1);
+}
--- /dev/null
+++ b/TestPlugin/Source/UIComponent.h
@@ -1,0 +1,77 @@
+/*
+  ==============================================================================
+
+    UIComponent.h
+    Created: 5 Dec 2016 2:23:38pm
+    Author:  Michael R Mulshine
+
+  ==============================================================================
+*/
+
+#ifndef UICOMPONENT_H_INCLUDED
+#define UICOMPONENT_H_INCLUDED
+
+#include "../JuceLibraryCode/JuceHeader.h"
+
+//==============================================================================
+/*
+*/
+class UIComponent:
+public Component,
+public Slider::Listener,
+public TextButton::Listener,
+public ComboBox::Listener,
+public TextEditor::Listener,
+private Timer
+{
+public:
+    UIComponent();
+
+    ~UIComponent();
+
+    void paint (Graphics& g) override;
+
+    void resized() override;
+    
+    void sliderValueChanged(Slider* s) override;
+    
+    void buttonClicked(Button*b) override {};
+    void buttonStateChanged(Button* b) override;
+    
+    void textEditorTextChanged (TextEditor&) override;
+    
+    void comboBoxChanged (ComboBox* cb) override;
+    
+    void timerCallback() override;
+    
+private:
+    
+    static const int cLeftOffset = 30;
+    static const int cTopOffset = 30;
+    
+    static const int cXSpacing = 60;
+    static const int cYSpacing = 5;
+    
+    static const int cSliderHeight = 200;
+    static const int cSliderWidth = 20;
+    
+    static const int cLabelHeight = 20;
+    static const int cLabelWidth  = cSliderWidth + cXSpacing;
+    
+    static const int cButtonHeight = 30;
+    static const int cButtonWidth  = 60;
+    
+    static const int cBoxHeight = 20;
+    static const int cBoxWidth  =  100;
+    
+    OwnedArray<Slider>      sliders;
+    OwnedArray<Label>       sliderLabels;
+    OwnedArray<TextButton>  buttons;
+    OwnedArray<TextEditor>  textFields;
+    OwnedArray<ComboBox>    comboBoxes;
+    
+    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (UIComponent)
+};
+
+
+#endif  // UICOMPONENT_H_INCLUDED
--- /dev/null
+++ b/TestPlugin/Source/Yin.cpp
@@ -1,0 +1,233 @@
+/*
+  ==============================================================================
+
+    Yin.c
+    Created: 17 Jan 2017 1:20:23pm
+    Author:  Michael R Mulshine
+
+  ==============================================================================
+*/
+
+#include "Yin.h"
+
+#include <stdint.h> /* For standard interger types (int16_t) */
+#include <stdlib.h> /* For call to malloc */
+
+/* ------------------------------------------------------------------------------------------
+--------------------------------------------------------------------------- PRIVATE FUNCTIONS
+-------------------------------------------------------------------------------------------*/
+
+/**
+ * Step 1: Calculates the squared difference of the signal with a shifted version of itself.
+ * @param buffer Buffer of samples to process. 
+ *
+ * This is the Yin algorithms tweak on autocorellation. Read http://audition.ens.fr/adc/pdf/2002_JASA_YIN.pdf
+ * for more details on what is in here and why it's done this way.
+ */
+void Yin_difference(Yin *yin, int16_t* buffer){
+	int16_t i;
+	int16_t tau;
+	float delta;
+
+	/* Calculate the difference for difference shift values (tau) for the half of the samples */
+	for(tau = 0 ; tau < yin->halfBufferSize; tau++){
+
+		/* Take the difference of the signal with a shifted version of itself, then square it.
+		 * (This is the Yin algorithm's tweak on autocorellation) */ 
+		for(i = 0; i < yin->halfBufferSize; i++){
+			delta = buffer[i] - buffer[i + tau];
+			yin->yinBuffer[tau] += delta * delta;
+		}
+	}
+}
+
+
+/**
+ * Step 2: Calculate the cumulative mean on the normalised difference calculated in step 1
+ * @param yin #Yin structure with information about the signal
+ *
+ * This goes through the Yin autocorellation values and finds out roughly where shift is which 
+ * produced the smallest difference
+ */
+void Yin_cumulativeMeanNormalizedDifference(Yin *yin){
+	int16_t tau;
+	float runningSum = 0;
+	yin->yinBuffer[0] = 1;
+
+	/* Sum all the values in the autocorellation buffer and nomalise the result, replacing
+	 * the value in the autocorellation buffer with a cumulative mean of the normalised difference */
+	for (tau = 1; tau < yin->halfBufferSize; tau++) {
+		runningSum += yin->yinBuffer[tau];
+		yin->yinBuffer[tau] *= tau / runningSum;
+	}
+}
+
+/**
+ * Step 3: Search through the normalised cumulative mean array and find values that are over the threshold
+ * @return Shift (tau) which caused the best approximate autocorellation. -1 if no suitable value is found over the threshold.
+ */
+int16_t Yin_absoluteThreshold(Yin *yin){
+	int16_t tau;
+
+	/* Search through the array of cumulative mean values, and look for ones that are over the threshold 
+	 * The first two positions in yinBuffer are always so start at the third (index 2) */
+	for (tau = 2; tau < yin->halfBufferSize ; tau++) {
+		if (yin->yinBuffer[tau] < yin->threshold) {
+			while (tau + 1 < yin->halfBufferSize && yin->yinBuffer[tau + 1] < yin->yinBuffer[tau]) {
+				tau++;
+			}
+			/* found tau, exit loop and return
+			 * store the probability
+			 * From the YIN paper: The yin->threshold determines the list of
+			 * candidates admitted to the set, and can be interpreted as the
+			 * proportion of aperiodic power tolerated
+			 * within a periodic signal.
+			 *
+			 * Since we want the periodicity and and not aperiodicity:
+			 * periodicity = 1 - aperiodicity */
+			yin->probability = 1 - yin->yinBuffer[tau];
+			break;
+		}
+	}
+
+	/* if no pitch found, tau => -1 */
+	if (tau == yin->halfBufferSize || yin->yinBuffer[tau] >= yin->threshold) {
+		tau = -1;
+		yin->probability = 0;
+	}
+
+	return tau;
+}
+
+/**
+ * Step 5: Interpolate the shift value (tau) to improve the pitch estimate.
+ * @param  yin         [description]
+ * @param  tauEstimate [description]
+ * @return             [description]
+ *
+ * The 'best' shift value for autocorellation is most likely not an interger shift of the signal.
+ * As we only autocorellated using integer shifts we should check that there isn't a better fractional 
+ * shift value.
+ */
+float Yin_parabolicInterpolation(Yin *yin, int16_t tauEstimate) {
+	float betterTau;
+	int16_t x0;
+	int16_t x2;
+	
+	/* Calculate the first polynomial coeffcient based on the current estimate of tau */
+	if (tauEstimate < 1) {
+		x0 = tauEstimate;
+	} 
+	else {
+		x0 = tauEstimate - 1;
+	}
+
+	/* Calculate the second polynomial coeffcient based on the current estimate of tau */
+	if (tauEstimate + 1 < yin->halfBufferSize) {
+		x2 = tauEstimate + 1;
+	} 
+	else {
+		x2 = tauEstimate;
+	}
+
+	/* Algorithm to parabolically interpolate the shift value tau to find a better estimate */
+	if (x0 == tauEstimate) {
+		if (yin->yinBuffer[tauEstimate] <= yin->yinBuffer[x2]) {
+			betterTau = tauEstimate;
+		} 
+		else {
+			betterTau = x2;
+		}
+	} 
+	else if (x2 == tauEstimate) {
+		if (yin->yinBuffer[tauEstimate] <= yin->yinBuffer[x0]) {
+			betterTau = tauEstimate;
+		} 
+		else {
+			betterTau = x0;
+		}
+	} 
+	else {
+		float s0, s1, s2;
+		s0 = yin->yinBuffer[x0];
+		s1 = yin->yinBuffer[tauEstimate];
+		s2 = yin->yinBuffer[x2];
+		// fixed AUBIO implementation, thanks to Karl Helgason:
+		// (2.0f * s1 - s2 - s0) was incorrectly multiplied with -1
+		betterTau = tauEstimate + (s2 - s0) / (2 * (2 * s1 - s2 - s0));
+	}
+
+
+	return betterTau;
+}
+
+
+
+
+
+/* ------------------------------------------------------------------------------------------
+---------------------------------------------------------------------------- PUBLIC FUNCTIONS
+-------------------------------------------------------------------------------------------*/
+
+
+
+/**
+ * Initialise the Yin pitch detection object
+ * @param yin        Yin pitch detection object to initialise
+ * @param bufferSize Length of the audio buffer to analyse
+ * @param threshold  Allowed uncertainty (e.g 0.05 will return a pitch with ~95% probability)
+ */
+void Yin_init(Yin *yin, int16_t bufferSize, float threshold){
+	/* Initialise the fields of the Yin structure passed in */
+	yin->bufferSize = bufferSize;
+	yin->halfBufferSize = bufferSize / 2;
+	yin->probability = 0.0;
+	yin->threshold = threshold;
+
+	/* Allocate the autocorellation buffer and initialise it to zero */
+	yin->yinBuffer = (float *) malloc(sizeof(float)* yin->halfBufferSize);
+
+	int16_t i;
+	for(i = 0; i < yin->halfBufferSize; i++){
+		yin->yinBuffer[i] = 0;
+	}
+}
+
+/**
+ * Runs the Yin pitch detection algortihm
+ * @param  yin    Initialised Yin object
+ * @param  buffer Buffer of samples to analyse
+ * @return        Fundamental frequency of the signal in Hz. Returns -1 if pitch can't be found
+ */
+float Yin_getPitch(Yin *yin, int16_t* buffer){
+	int16_t tauEstimate = -1;
+	float pitchInHertz = -1;
+	
+	/* Step 1: Calculates the squared difference of the signal with a shifted version of itself. */
+	Yin_difference(yin, buffer);
+	
+	/* Step 2: Calculate the cumulative mean on the normalised difference calculated in step 1 */
+	Yin_cumulativeMeanNormalizedDifference(yin);
+	
+	/* Step 3: Search through the normalised cumulative mean array and find values that are over the threshold */
+	tauEstimate = Yin_absoluteThreshold(yin);
+	
+	/* Step 5: Interpolate the shift value (tau) to improve the pitch estimate. */
+	if(tauEstimate != -1){
+		pitchInHertz = YIN_SAMPLING_RATE / Yin_parabolicInterpolation(yin, tauEstimate);
+	}
+	
+	return pitchInHertz;
+}
+
+/**
+ * Certainty of the pitch found 
+ * @param  yin Yin object that has been run over a buffer
+ * @return     Returns the certainty of the note found as a decimal (i.e 0.3 is 30%)
+ */
+float Yin_getProbability(Yin *yin){
+	return yin->probability;
+}
+
+
+
--- /dev/null
+++ b/TestPlugin/Source/Yin.h
@@ -1,0 +1,56 @@
+/*
+  ==============================================================================
+
+    Yin.h
+    Created: 17 Jan 2017 1:20:23pm
+    Author:  Michael R Mulshine
+
+  ==============================================================================
+*/
+
+#ifndef YIN_H_INCLUDED
+#define YIN_H_INCLUDED
+
+#include <stdint.h>
+
+#define YIN_SAMPLING_RATE 44100
+#define YIN_DEFAULT_THRESHOLD 0.15
+
+/**
+ * @struct  Yin
+ * @breif	Object to encapsulate the parameters for the Yin pitch detection algorithm 
+ */
+typedef struct _Yin {
+	int16_t bufferSize;			/**< Size of the audio buffer to be analysed */
+	int16_t halfBufferSize;		/**< Half the buffer length */
+	float* yinBuffer;		/**< Buffer that stores the results of the intermediate processing steps of the algorithm */
+	float probability;		/**< Probability that the pitch found is correct as a decimal (i.e 0.85 is 85%) */
+	float threshold;		/**< Allowed uncertainty in the result as a decimal (i.e 0.15 is 15%) */
+} Yin;
+
+/**
+ * Initialise the Yin pitch detection object
+ * @param yin        Yin pitch detection object to initialise
+ * @param bufferSize Length of the audio buffer to analyse
+ * @param threshold  Allowed uncertainty (e.g 0.05 will return a pitch with ~95% probability)
+ */
+void Yin_init(Yin *yin, int16_t bufferSize, float threshold);
+
+/**
+ * Runs the Yin pitch detection algortihm
+ * @param  yin    Initialised Yin object
+ * @param  buffer Buffer of samples to analyse
+ * @return        Fundamental frequency of the signal in Hz. Returns -1 if pitch can't be found
+ */
+float Yin_getPitch(Yin *yin, int16_t* buffer);
+
+/**
+ * Certainty of the pitch found 
+ * @param  yin Yin object that has been run over a buffer
+ * @return     Returns the certainty of the note found as a decimal (i.e 0.3 is 30%)
+ */
+float Yin_getProbability(Yin *yin);
+	
+
+
+#endif  // YIN_H_INCLUDED