]> git.quilime.com - iosynth.git/commitdiff
Compiling
authorGabriel Dunne <gdunne@quilime.com>
Mon, 9 Dec 2013 02:32:19 +0000 (18:32 -0800)
committerGabriel Dunne <gdunne@quilime.com>
Mon, 9 Dec 2013 02:32:19 +0000 (18:32 -0800)
239 files changed:
.gitignore [new file with mode: 0644]
lib/Maximilian/maximilian.cpp [new file with mode: 0644]
lib/Maximilian/maximilian.h [new file with mode: 0755]
lib/MoMu-STK-1.0.0/AUTHORS [new file with mode: 0644]
lib/MoMu-STK-1.0.0/COPYING [new file with mode: 0644]
lib/MoMu-STK-1.0.0/DEVELOPER [new file with mode: 0644]
lib/MoMu-STK-1.0.0/INSTALL [new file with mode: 0644]
lib/MoMu-STK-1.0.0/README [new file with mode: 0644]
lib/MoMu-STK-1.0.0/TODO [new file with mode: 0644]
lib/MoMu-STK-1.0.0/VERSIONS [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/ADSR.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/Asymp.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/BandedWG.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/BeeThree.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/BiQuad.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/Blit.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/BlitSaw.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/BlitSquare.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/BlowBotl.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/BlowHole.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/BowTable.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/Bowed.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/Brass.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/Chorus.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/Clarinet.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/Delay.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/DelayA.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/DelayL.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/Drummer.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/Echo.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/Effect.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/Envelope.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/FM.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/FMVoices.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/FileLoop.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/FileRead.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/FileWrite.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/FileWvIn.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/FileWvOut.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/Filter.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/Fir.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/Flute.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/FormSwep.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/Function.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/Generator.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/Granulate.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/HevyMetl.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/Iir.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/InetWvIn.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/InetWvOut.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/Instrmnt.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/JCRev.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/JetTable.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/LentPitShift.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/Mandolin.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/Mesh2D.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/Messager.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/MidiFileIn.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/Modal.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/ModalBar.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/Modulate.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/Moog.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/Mutex.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/NRev.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/Noise.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/OnePole.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/OneZero.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/PRCRev.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/PercFlut.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/Phonemes.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/PitShift.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/PluckTwo.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/Plucked.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/PoleZero.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/ReedTable.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/Resonate.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/Rhodey.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/Sampler.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/Saxofony.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/Shakers.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/Simple.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/SineWave.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/SingWave.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/Sitar.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/Skini.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/Skini_msg.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/Skini_tbl.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/Socket.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/Sphere.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/StifKarp.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/Stk.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/StkUdpSocket.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/TapDelay.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/TcpClient.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/TcpServer.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/Thread.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/TubeBell.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/TwoPole.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/TwoZero.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/Vector3D.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/VoicForm.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/Voicer.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/Whistle.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/Wurley.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/WvIn.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/include/WvOut.h [new file with mode: 0644]
lib/MoMu-STK-1.0.0/rawwaves/ahh.raw [new file with mode: 0644]
lib/MoMu-STK-1.0.0/rawwaves/bassdrum.raw [new file with mode: 0644]
lib/MoMu-STK-1.0.0/rawwaves/britestk.raw [new file with mode: 0644]
lib/MoMu-STK-1.0.0/rawwaves/cowbell1.raw [new file with mode: 0644]
lib/MoMu-STK-1.0.0/rawwaves/crashcym.raw [new file with mode: 0644]
lib/MoMu-STK-1.0.0/rawwaves/dope.raw [new file with mode: 0644]
lib/MoMu-STK-1.0.0/rawwaves/eee.raw [new file with mode: 0644]
lib/MoMu-STK-1.0.0/rawwaves/fwavblnk.raw [new file with mode: 0644]
lib/MoMu-STK-1.0.0/rawwaves/halfwave.raw [new file with mode: 0644]
lib/MoMu-STK-1.0.0/rawwaves/hihatcym.raw [new file with mode: 0644]
lib/MoMu-STK-1.0.0/rawwaves/impuls10.raw [new file with mode: 0644]
lib/MoMu-STK-1.0.0/rawwaves/impuls20.raw [new file with mode: 0644]
lib/MoMu-STK-1.0.0/rawwaves/impuls40.raw [new file with mode: 0644]
lib/MoMu-STK-1.0.0/rawwaves/makefunc.c [new file with mode: 0644]
lib/MoMu-STK-1.0.0/rawwaves/makemidi.c [new file with mode: 0644]
lib/MoMu-STK-1.0.0/rawwaves/makewavs.c [new file with mode: 0644]
lib/MoMu-STK-1.0.0/rawwaves/mand1.raw [new file with mode: 0644]
lib/MoMu-STK-1.0.0/rawwaves/mand10.raw [new file with mode: 0644]
lib/MoMu-STK-1.0.0/rawwaves/mand11.raw [new file with mode: 0644]
lib/MoMu-STK-1.0.0/rawwaves/mand12.raw [new file with mode: 0644]
lib/MoMu-STK-1.0.0/rawwaves/mand2.raw [new file with mode: 0644]
lib/MoMu-STK-1.0.0/rawwaves/mand3.raw [new file with mode: 0644]
lib/MoMu-STK-1.0.0/rawwaves/mand4.raw [new file with mode: 0644]
lib/MoMu-STK-1.0.0/rawwaves/mand5.raw [new file with mode: 0644]
lib/MoMu-STK-1.0.0/rawwaves/mand6.raw [new file with mode: 0644]
lib/MoMu-STK-1.0.0/rawwaves/mand7.raw [new file with mode: 0644]
lib/MoMu-STK-1.0.0/rawwaves/mand8.raw [new file with mode: 0644]
lib/MoMu-STK-1.0.0/rawwaves/mand9.raw [new file with mode: 0644]
lib/MoMu-STK-1.0.0/rawwaves/mandpluk.raw [new file with mode: 0644]
lib/MoMu-STK-1.0.0/rawwaves/marmstk1.raw [new file with mode: 0644]
lib/MoMu-STK-1.0.0/rawwaves/ooo.raw [new file with mode: 0644]
lib/MoMu-STK-1.0.0/rawwaves/peksblnk.raw [new file with mode: 0644]
lib/MoMu-STK-1.0.0/rawwaves/ppksblnk.raw [new file with mode: 0644]
lib/MoMu-STK-1.0.0/rawwaves/ridecymb.raw [new file with mode: 0644]
lib/MoMu-STK-1.0.0/rawwaves/silence.raw [new file with mode: 0644]
lib/MoMu-STK-1.0.0/rawwaves/sine.c [new file with mode: 0644]
lib/MoMu-STK-1.0.0/rawwaves/sineblnk.raw [new file with mode: 0644]
lib/MoMu-STK-1.0.0/rawwaves/sinewave.raw [new file with mode: 0644]
lib/MoMu-STK-1.0.0/rawwaves/snardrum.raw [new file with mode: 0644]
lib/MoMu-STK-1.0.0/rawwaves/snglpeak.raw [new file with mode: 0644]
lib/MoMu-STK-1.0.0/rawwaves/tambourn.raw [new file with mode: 0644]
lib/MoMu-STK-1.0.0/rawwaves/tomhidrm.raw [new file with mode: 0644]
lib/MoMu-STK-1.0.0/rawwaves/tomlowdr.raw [new file with mode: 0644]
lib/MoMu-STK-1.0.0/rawwaves/tommiddr.raw [new file with mode: 0644]
lib/MoMu-STK-1.0.0/rawwaves/twopeaks.raw [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/ADSR.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/Asymp.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/BandedWG.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/BeeThree.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/BiQuad.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/Blit.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/BlitSaw.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/BlitSquare.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/BlowBotl.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/BlowHole.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/Bowed.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/Brass.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/Chorus.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/Clarinet.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/Delay.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/DelayA.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/DelayL.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/Drummer.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/Echo.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/Envelope.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/FM.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/FMVoices.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/FileLoop.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/FileRead.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/FileWrite.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/FileWvIn.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/FileWvOut.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/Fir.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/Flute.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/FormSwep.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/Granulate.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/HevyMetl.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/Iir.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/InetWvIn.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/InetWvOut.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/JCRev.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/LentPitShift.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/Mandolin.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/Mesh2D.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/Messager.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/MidiFileIn.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/Modal.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/ModalBar.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/Modulate.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/Moog.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/Mutex.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/NRev.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/Noise.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/OnePole.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/OneZero.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/PRCRev.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/PercFlut.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/Phonemes.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/PitShift.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/PluckTwo.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/Plucked.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/PoleZero.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/Resonate.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/Rhodey.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/Sampler.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/Saxofony.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/Shakers.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/Simple.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/SineWave.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/SingWave.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/Sitar.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/Skini.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/Socket.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/Sphere.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/StifKarp.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/Stk.mm [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/StkUdpSocket.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/TapDelay.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/TcpClient.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/TcpServer.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/Thread.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/TubeBell.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/TwoPole.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/TwoZero.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/VoicForm.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/Voicer.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/Whistle.cpp [new file with mode: 0644]
lib/MoMu-STK-1.0.0/src/Wurley.cpp [new file with mode: 0644]
src/Voice.cpp [new file with mode: 0644]
src/Voice.h [new file with mode: 0644]
src/iosynthApp.cpp
src/iosynthApp.h [new file with mode: 0644]
xcode_ios/iosynth.xcodeproj/project.pbxproj

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..e43b0f9
--- /dev/null
@@ -0,0 +1 @@
+.DS_Store
diff --git a/lib/Maximilian/maximilian.cpp b/lib/Maximilian/maximilian.cpp
new file mode 100644 (file)
index 0000000..9537096
--- /dev/null
@@ -0,0 +1,1270 @@
+
+/*
+ *  maximilian.cpp
+ *  platform independent synthesis library using portaudio or rtaudio
+ *
+ *  Created by Mick Grierson on 29/12/2009.
+ *  Copyright 2009 Mick Grierson & Strangeloop Limited. All rights reserved.
+ *     Thanks to the Goldsmiths Creative Computing Team.
+ *     Special thanks to Arturo Castro for the PortAudio implementation.
+ *
+ *     Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or sell
+ *     copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *     
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "maximilian.h"
+#include "math.h"
+
+/*  Maximilian can be configured to load ogg vorbis format files using the 
+*   loadOgg() method.
+*   Uncomment the following to include Sean Barrett's Ogg Vorbis decoder.
+*   If you're on windows, make sure to add the files std_vorbis.c and std_vorbis.h to your project*/
+
+//#define VORBIS
+
+#ifdef VORBIS
+extern "C" {
+    #include "stb_vorbis.h"
+}
+#endif
+
+//This used to be important for dealing with multichannel playback
+float chandiv= 1;
+
+int maxiSettings::sampleRate = 44100;
+int maxiSettings::channels = 2;
+int maxiSettings::bufferSize = 1024;
+
+
+//this is a 514-point sinewave table that has many uses. 
+double sineBuffer[514]={0,0.012268,0.024536,0.036804,0.049042,0.06131,0.073547,0.085785,0.097992,0.1102,0.12241,0.13455,0.1467,0.15884,0.17093,0.18301,0.19507,0.20709,0.21909,0.23105,0.24295,0.25485,0.26669,0.2785,0.29025,0.30197,0.31366,0.32529,0.33685,0.34839,0.35986,0.37128,0.38266,0.39395,0.40521,0.41641,0.42752,0.4386,0.44958,0.46051,0.47137,0.48215,0.49286,0.50351,0.51407,0.52457,0.53497,0.54529,0.55554,0.5657,0.57578,0.58575,0.59567,0.60547,0.6152,0.62482,0.63437,0.6438,0.65314,0.66238,0.67151,0.68057,0.68951,0.69833,0.70706,0.7157,0.72421,0.7326,0.74091,0.74908,0.75717,0.76514,0.77298,0.7807,0.7883,0.79581,0.80316,0.81042,0.81754,0.82455,0.83142,0.8382,0.84482,0.85132,0.8577,0.86392,0.87006,0.87604,0.88187,0.8876,0.89319,0.89862,0.90396,0.90912,0.91415,0.91907,0.92383,0.92847,0.93295,0.93729,0.9415,0.94556,0.94949,0.95325,0.95691,0.96039,0.96375,0.96692,0.97,0.9729,0.97565,0.97827,0.98074,0.98306,0.98523,0.98724,0.98914,0.99084,0.99243,0.99387,0.99515,0.99628,0.99725,0.99808,0.99875,0.99927,0.99966,0.99988,0.99997,0.99988,0.99966,0.99927,0.99875,0.99808,0.99725,0.99628,0.99515,0.99387,0.99243,0.99084,0.98914,0.98724,0.98523,0.98306,0.98074,0.97827,0.97565,0.9729,0.97,0.96692,0.96375,0.96039,0.95691,0.95325,0.94949,0.94556,0.9415,0.93729,0.93295,0.92847,0.92383,0.91907,0.91415,0.90912,0.90396,0.89862,0.89319,0.8876,0.88187,0.87604,0.87006,0.86392,0.8577,0.85132,0.84482,0.8382,0.83142,0.82455,0.81754,0.81042,0.80316,0.79581,0.7883,0.7807,0.77298,0.76514,0.75717,0.74908,0.74091,0.7326,0.72421,0.7157,0.70706,0.69833,0.68951,0.68057,0.67151,0.66238,0.65314,0.6438,0.63437,0.62482,0.6152,0.60547,0.59567,0.58575,0.57578,0.5657,0.55554,0.54529,0.53497,0.52457,0.51407,0.50351,0.49286,0.48215,0.47137,0.46051,0.44958,0.4386,0.42752,0.41641,0.40521,0.39395,0.38266,0.37128,0.35986,0.34839,0.33685,0.32529,0.31366,0.30197,0.29025,0.2785,0.26669,0.25485,0.24295,0.23105,0.21909,0.20709,0.19507,0.18301,0.17093,0.15884,0.1467,0.13455,0.12241,0.1102,0.097992,0.085785,0.073547,0.06131,0.049042,0.036804,0.024536,0.012268,0,-0.012268,-0.024536,-0.036804,-0.049042,-0.06131,-0.073547,-0.085785,-0.097992,-0.1102,-0.12241,-0.13455,-0.1467,-0.15884,-0.17093,-0.18301,-0.19507,-0.20709,-0.21909,-0.23105,-0.24295,-0.25485,-0.26669,-0.2785,-0.29025,-0.30197,-0.31366,-0.32529,-0.33685,-0.34839,-0.35986,-0.37128,-0.38266,-0.39395,-0.40521,-0.41641,-0.42752,-0.4386,-0.44958,-0.46051,-0.47137,-0.48215,-0.49286,-0.50351,-0.51407,-0.52457,-0.53497,-0.54529,-0.55554,-0.5657,-0.57578,-0.58575,-0.59567,-0.60547,-0.6152,-0.62482,-0.63437,-0.6438,-0.65314,-0.66238,-0.67151,-0.68057,-0.68951,-0.69833,-0.70706,-0.7157,-0.72421,-0.7326,-0.74091,-0.74908,-0.75717,-0.76514,-0.77298,-0.7807,-0.7883,-0.79581,-0.80316,-0.81042,-0.81754,-0.82455,-0.83142,-0.8382,-0.84482,-0.85132,-0.8577,-0.86392,-0.87006,-0.87604,-0.88187,-0.8876,-0.89319,-0.89862,-0.90396,-0.90912,-0.91415,-0.91907,-0.92383,-0.92847,-0.93295,-0.93729,-0.9415,-0.94556,-0.94949,-0.95325,-0.95691,-0.96039,-0.96375,-0.96692,-0.97,-0.9729,-0.97565,-0.97827,-0.98074,-0.98306,-0.98523,-0.98724,-0.98914,-0.99084,-0.99243,-0.99387,-0.99515,-0.99628,-0.99725,-0.99808,-0.99875,-0.99927,-0.99966,-0.99988,-0.99997,-0.99988,-0.99966,-0.99927,-0.99875,-0.99808,-0.99725,-0.99628,-0.99515,-0.99387,-0.99243,-0.99084,-0.98914,-0.98724,-0.98523,-0.98306,-0.98074,-0.97827,-0.97565,-0.9729,-0.97,-0.96692,-0.96375,-0.96039,-0.95691,-0.95325,-0.94949,-0.94556,-0.9415,-0.93729,-0.93295,-0.92847,-0.92383,-0.91907,-0.91415,-0.90912,-0.90396,-0.89862,-0.89319,-0.8876,-0.88187,-0.87604,-0.87006,-0.86392,-0.8577,-0.85132,-0.84482,-0.8382,-0.83142,-0.82455,-0.81754,-0.81042,-0.80316,-0.79581,-0.7883,-0.7807,-0.77298,-0.76514,-0.75717,-0.74908,-0.74091,-0.7326,-0.72421,-0.7157,-0.70706,-0.69833,-0.68951,-0.68057,-0.67151,-0.66238,-0.65314,-0.6438,-0.63437,-0.62482,-0.6152,-0.60547,-0.59567,-0.58575,-0.57578,-0.5657,-0.55554,-0.54529,-0.53497,-0.52457,-0.51407,-0.50351,-0.49286,-0.48215,-0.47137,-0.46051,-0.44958,-0.4386,-0.42752,-0.41641,-0.40521,-0.39395,-0.38266,-0.37128,-0.35986,-0.34839,-0.33685,-0.32529,-0.31366,-0.30197,-0.29025,-0.2785,-0.26669,-0.25485,-0.24295,-0.23105,-0.21909,-0.20709,-0.19507,-0.18301,-0.17093,-0.15884,-0.1467,-0.13455,-0.12241,-0.1102,-0.097992,-0.085785,-0.073547,-0.06131,-0.049042,-0.036804,-0.024536,-0.012268,0,0.012268
+};
+
+// This is a transition table that helps with bandlimited oscs.
+double transition[1001]={-0.500003,-0.500003,-0.500023,-0.500063,-0.500121,-0.500179,-0.500259,
+    -0.50036,-0.500476,-0.500591,-0.500732,-0.500893,-0.501066,-0.501239,
+    -0.50144,-0.501661,-0.501891,-0.502123,-0.502382,-0.502662,-0.502949,
+    -0.50324,-0.503555,-0.503895,-0.504238,-0.504587,-0.504958,-0.505356,
+    -0.505754,-0.506162,-0.506589,-0.507042,-0.507495,-0.50796,-0.508444,
+    -0.508951,-0.509458,-0.509979,-0.510518,-0.511079,-0.511638,-0.512213,
+    -0.512808,-0.51342,-0.51403,-0.514659,-0.515307,-0.51597,-0.51663,-0.517312,
+    -0.518012,-0.518724,-0.519433,-0.520166,-0.520916,-0.521675,-0.522432,
+    -0.523214,-0.524013,-0.524819,-0.525624,-0.526451,-0.527298,-0.528147,
+    -0.528999,-0.52987,-0.530762,-0.531654,-0.532551,-0.533464,-0.534399,
+    -0.535332,-0.536271,-0.537226,-0.538202,-0.539172,-0.540152,-0.541148,
+    -0.542161,-0.543168,-0.544187,-0.54522,-0.546269,-0.54731,-0.548365,
+    -0.549434,-0.550516,-0.55159, -0.552679,-0.553781,-0.554893,-0.555997,
+    -0.557118,-0.558252,-0.559391,-0.560524,-0.561674,-0.562836,-0.564001,
+    -0.565161,-0.566336,-0.567524,-0.568712,-0.569896,-0.571095,-0.572306,
+    -0.573514,-0.574721,-0.575939,-0.577171,-0.578396,-0.579622,-0.580858,
+    -0.582108,-0.583348,-0.58459, -0.585842,-0.587106,-0.588358,-0.589614,
+    -0.590879,-0.592154,-0.593415,-0.594682,-0.595957,-0.59724,-0.598507,
+    -0.599782,-0.601064,-0.602351,-0.603623,-0.604902,-0.606189,-0.607476,
+    -0.60875,-0.610032,-0.611319, -0.612605,-0.613877,-0.615157,-0.616443,
+    -0.617723,-0.618992,-0.620268,-0.621548,-0.62282,-0.624083,-0.62535,
+    -0.626622,-0.627882,-0.629135,-0.630391,-0.631652,-0.632898,-0.634138,
+    -0.63538,-0.636626,-0.637854, -0.639078,-0.640304,-0.641531,-0.642739,
+    -0.643943,-0.645149,-0.646355,-0.647538,-0.64872,-0.649903,-0.651084,
+    -0.652241,-0.653397,-0.654553,-0.655705,-0.656834,-0.657961,-0.659087,
+    -0.660206,-0.661304,-0.662399,-0.663492,-0.664575,-0.665639,-0.666699,
+    -0.667756,-0.6688,-0.669827,  -0.670849,-0.671866,-0.672868,-0.673854,
+    -0.674835,-0.675811,-0.676767,-0.677709,-0.678646,-0.679576,-0.680484,
+    -0.68138,-0.682269,-0.683151, -0.684008,-0.684854,-0.685693,-0.686524,
+    -0.687327,-0.688119,-0.688905,-0.689682,-0.690428,-0.691164,-0.691893,
+    -0.692613,-0.6933,-0.693978,  -0.694647,-0.695305,-0.695932,-0.696549,
+    -0.697156,-0.697748,-0.698313,-0.698865,-0.699407,-0.699932,-0.700431,
+    -0.700917,-0.701391,-0.701845,-0.702276,-0.702693,-0.703097,-0.703478,
+    -0.703837,-0.704183,-0.704514,-0.704819,-0.705105,-0.705378,-0.705633,
+    -0.70586,-0.706069,-0.706265, -0.706444,-0.706591,-0.706721,-0.706837,
+    -0.706938,-0.707003,-0.707051,-0.707086,-0.707106,-0.707086,-0.707051,
+    -0.707001,-0.706935,-0.706832,-0.706711,-0.706576,-0.706421,-0.706233,
+    -0.706025,-0.705802,-0.705557,-0.705282,-0.704984,-0.704671,-0.704334,
+    -0.703969,-0.703582,-0.703176,-0.702746,-0.702288,-0.70181,-0.701312,
+    -0.700785,-0.700234,-0.699664,-0.69907,-0.698447,-0.6978,-0.697135,
+    -0.696446,-0.695725,-0.694981,-0.694219,-0.693435,-0.692613,-0.691771,
+    -0.690911,-0.69003,-0.689108, -0.688166,-0.687206,-0.686227,-0.685204,
+    -0.684162,-0.683101,-0.682019,-0.680898,-0.679755,-0.678592,-0.677407,
+    -0.676187,-0.674941,-0.673676,-0.672386,-0.671066,-0.669718,-0.66835,
+    -0.666955,-0.665532,-0.664083,-0.662611,-0.661112,-0.659585,-0.658035,
+    -0.656459,-0.654854,-0.653223,-0.651572,-0.649892,-0.648181,-0.646446,
+    -0.644691,-0.642909,-0.641093,-0.639253,-0.637393,-0.63551,-0.633588,
+    -0.631644,-0.62968,-0.627695,-0.625668,-0.623621,-0.621553,-0.619464,
+    -0.617334,-0.615183,-0.613011,-0.610817,-0.608587,-0.606333,-0.604058,
+    -0.60176,-0.599429,-0.597072,-0.594695,-0.592293,-0.589862,-0.587404,
+    -0.584925,-0.58242,-0.579888,-0.577331,-0.574751,-0.572145,-0.569512,
+    -0.566858,-0.564178,-0.561471,-0.558739,-0.555988,-0.553209,-0.550402,
+    -0.547572,-0.544723,-0.54185,-0.538944,-0.536018,-0.533072,-0.530105,
+    -0.527103,-0.524081,-0.52104,-0.51798,-0.514883,-0.511767,-0.508633,
+    -0.505479,-0.502291,-0.499083,-0.495857,-0.492611,-0.489335,-0.486037,
+    -0.48272,-0.479384,-0.476021,-0.472634,-0.46923,-0.465805,-0.462356,
+    -0.458884,-0.455394,-0.451882,-0.448348,-0.444795,-0.44122,-0.437624,
+    -0.434008,-0.430374,-0.426718,-0.423041,-0.419344,-0.415631,-0.411897,
+    -0.40814,-0.404365,-0.400575,-0.396766,-0.392933,-0.389082,-0.385217,
+    -0.381336,-0.377428,-0.373505,-0.369568,-0.365616,-0.361638,-0.357645,
+    -0.353638,-0.349617,-0.345572,-0.341512,-0.337438,-0.33335,-0.329242,
+    -0.325118,-0.32098,-0.316829,-0.31266,-0.308474,-0.304276,-0.300063,
+    -0.295836,-0.291593,-0.287337,-0.283067,-0.278783,-0.274487,-0.270176,
+    -0.265852,-0.261515,-0.257168,-0.252806,-0.248431,-0.244045,-0.239649,
+    -0.23524,-0.230817,-0.226385,-0.221943,-0.21749,-0.213024,-0.208548,
+    -0.204064,-0.199571,-0.195064,-0.190549,-0.186026,-0.181495,-0.176952,
+    -0.1724,-0.167842,-0.163277,-0.1587,-0.154117,-0.149527,-0.14493,-0.140325,
+    -0.135712,-0.131094,-0.12647,-0.121839,-0.117201,-0.112559,-0.10791,
+    -0.103257,-0.0985979,-0.0939343,-0.0892662,-0.0845935,-0.079917,-0.0752362,
+    -0.0705516,-0.0658635,-0.0611729,-0.0564786,-0.0517814,-0.0470818,-0.0423802,
+    -0.0376765,-0.0329703,-0.0282629,-0.0235542,-0.0188445,-0.0141335,-0.00942183,
+    -0.00470983,2.41979e-06,0.00471481,0.00942681,0.0141384,0.0188494,0.023559,
+    0.028268,0.0329754,0.0376813,0.0423851,0.0470868,0.0517863,0.0564836,
+    0.0611777,0.0658683,0.0705566,0.0752412,0.0799218,0.0845982,0.0892712,
+    0.0939393,0.0986028,0.103262,0.107915,0.112563,0.117206,0.121844,0.126475,
+    0.131099,0.135717,0.14033,0.144935,0.149531,0.154122,0.158705,0.163281,
+    0.167847,0.172405,0.176956,0.1815,0.18603,0.190553,0.195069,0.199576,
+    0.204068,0.208552,0.213028,0.217495,0.221947,0.226389,0.230822,0.235245,
+    0.239653,0.244049,0.248436,0.252811,0.257173,0.26152,0.265857,0.270181,
+    0.274491,0.278788,0.283071,0.287341,0.291597,0.29584,0.300068,0.30428,
+    0.308478,0.312664,0.316833,0.320984,0.325122,0.329246,0.333354,0.337442,
+    0.341516,0.345576,0.34962,0.353642,0.357649,0.361642,0.36562,0.369572,
+    0.373509,0.377432,0.38134,0.385221,0.389086,0.392936,0.39677,0.400579,
+    0.404369,0.408143,0.4119,0.415634,0.419347,0.423044,0.426721,0.430377,
+    0.434011,0.437627,0.441223,0.444798,0.448351,0.451885,0.455397,0.458887,
+    0.462359,0.465807,0.469232,0.472637,0.476024,0.479386,0.482723,0.486039,
+    0.489338,0.492613,0.49586,0.499086,0.502294,0.505481,0.508635,0.511769,
+    0.514885,0.517982,0.521042,0.524083,0.527105,0.530107,0.533074,0.53602,
+    0.538946,0.541851,0.544725,0.547574,0.550404,0.553211,0.555989,0.55874,
+    0.561472,0.564179,0.566859,0.569514,0.572146,0.574753,0.577332,0.579889,
+    0.582421,0.584926,0.587405,0.589863,0.592294,0.594696,0.597073,0.59943,
+    0.60176,0.604059,0.606333,0.608588,0.610818,0.613012,0.615183,0.617335,
+    0.619464,0.621553,0.623621,0.625669,0.627696,0.629681,0.631645,0.633588,
+    0.63551,0.637393,0.639253,0.641093,0.642909,0.644691,0.646446,0.648181,
+    0.649892,0.651572,0.653223,0.654854,0.656459,0.658035,0.659585,0.661112,
+    0.662611,0.664083,0.665532,0.666955,0.66835,0.669718,0.671066,0.672386,
+    0.673676,0.674941,0.676187,0.677407,0.678592,0.679755,0.680898,0.682019,
+    0.683101,0.684162,0.685204,0.686227,0.687206,0.688166,0.689108,0.69003,
+    0.690911,0.691771,0.692613,0.693435,0.694219,0.694981,0.695725,0.696447,
+    0.697135,0.6978,0.698447,0.69907,0.699664,0.700234,0.700786,0.701312,
+    0.70181,0.702288,0.702746,0.703177,0.703582,0.703969,0.704334,0.704671,
+    0.704984,0.705282,0.705557,0.705802,0.706025,0.706233,0.706422,0.706576,
+    0.706712,0.706832,0.706936,0.707002,0.707051,0.707086,0.707106,0.707086,
+    0.707051,0.707003,0.706939,0.706838,0.706721,0.706592,0.706445,0.706265,
+    0.70607,0.705861,0.705634,0.705378,0.705105,0.70482,0.704515,0.704184,
+    0.703837,0.703478,0.703097,0.702694,0.702276,0.701846,0.701392,0.700917,
+    0.700432,0.699932,0.699408,0.698866,0.698314,0.697749,0.697156,0.696549,
+    0.695933,0.695305,0.694648,0.693979,0.693301,0.692613,0.691894,0.691165,
+    0.690428,0.689683,0.688905,0.68812,0.687327,0.686525,0.685693,0.684854,
+    0.684009,0.683152,0.68227,0.68138,0.680485,0.679577,0.678647,0.67771,
+    0.676768,0.675811,0.674836,0.673855,0.672869,0.671867,0.670849,0.669827,
+    0.668801,0.667757,0.6667,0.66564,0.664576,0.663493,0.6624,0.661305,
+    0.660207,0.659088,0.657962,0.656834,0.655705,0.654553,0.653398,0.652241,
+    0.651085,0.649903,0.648721,0.647539,0.646356,0.645149,0.643944,0.642739,
+    0.641532,0.640304,0.639079,0.637855,0.636626,0.635381,0.634139,0.632899,
+    0.631652,0.630392,0.629136,0.627883,0.626622,0.62535,0.624083,0.62282,
+    0.621548,0.620268,0.618993,0.617724,0.616443,0.615158,0.613878,0.612605,
+    0.61132,0.610032,0.608751,0.607477,0.606189,0.604903,0.603623,0.602351,
+    0.601065,0.599782,0.598508,0.59724,0.595957,0.594682,0.593415,0.592154,
+    0.59088,0.589615,0.588359,0.587106,0.585843,0.584591,0.583349,0.582108,
+    0.580859,0.579623,0.578397,0.577172,0.575939,0.574721,0.573515,0.572307,
+    0.571095,0.569897,0.568713,0.567525,0.566337,0.565161,0.564002,0.562837,
+    0.561674,0.560525,0.559392,0.558252,0.557119,0.555998,0.554893,0.553782,
+    0.552679,0.55159,0.550516,0.549434,0.548365,0.54731,0.546269,0.54522,
+    0.544187,0.543168,0.542161,0.541148,0.540153,0.539173,0.538202,0.537226,
+    0.536271,0.535332,0.5344,0.533464,0.532551,0.531654,0.530762,0.52987,
+    0.528999,0.528147,0.527298,0.526451,0.525624,0.524819,0.524014,0.523214,
+    0.522432,0.521675,0.520916,0.520166,0.519433,0.518724,0.518012,0.517312,
+    0.51663,0.51597,0.515307,0.51466,0.51403,0.51342,0.512808,0.512213,
+    0.511638,0.511079,0.510518,0.509979,0.509458,0.508951,0.508444,0.50796,
+    0.507495,0.507042,0.506589,0.506162,0.505754,0.505356,0.504958,0.504587,
+    0.504237,0.503895,0.503555,0.50324,0.502949,0.502662,0.502382,0.502123,
+    0.501891,0.501661,0.50144,0.501239,0.501066,0.500893,0.500732,0.500591,
+    0.500476,0.50036,0.500259,0.500179,0.500121,0.500063,0.500023,0.500003,0.500003};
+
+//This is a lookup table for converting midi to frequency
+double mtofarray[129]={0, 8.661957, 9.177024, 9.722718, 10.3, 10.913383, 11.562325, 12.25, 12.978271, 13.75, 14.567617, 15.433853, 16.351599, 17.323914, 18.354048, 19.445436, 20.601723, 21.826765, 23.124651, 24.5, 25.956543, 27.5, 29.135235, 30.867706, 32.703197, 34.647827, 36.708096, 38.890873, 41.203445, 43.65353, 46.249302, 49., 51.913086, 55., 58.27047, 61.735413, 65.406395, 69.295654, 73.416191, 77.781746, 82.406891, 87.30706, 92.498604, 97.998856, 103.826172, 110., 116.540939, 123.470825, 130.81279, 138.591309, 146.832382, 155.563492, 164.813782, 174.61412, 184.997208, 195.997711, 207.652344, 220., 233.081879, 246.94165, 261.62558, 277.182617,293.664764, 311.126984, 329.627563, 349.228241, 369.994415, 391.995422, 415.304688, 440., 466.163757, 493.883301, 523.25116, 554.365234, 587.329529, 622.253967, 659.255127, 698.456482, 739.988831, 783.990845, 830.609375, 880., 932.327515, 987.766602, 1046.502319, 1108.730469, 1174.659058, 1244.507935, 1318.510254, 1396.912964, 1479.977661, 1567.981689, 1661.21875, 1760., 1864.655029, 1975.533203, 2093.004639, 2217.460938, 2349.318115, 2489.015869, 2637.020508, 2793.825928, 2959.955322, 3135.963379, 3322.4375, 3520., 3729.31, 3951.066406, 4186.009277, 4434.921875, 4698.63623, 4978.031738, 5274.041016, 5587.651855, 5919.910645, 6271.926758, 6644.875, 7040., 7458.620117, 7902.132812, 8372.018555, 8869.84375, 9397.272461, 9956.063477, 10548.082031, 11175.303711, 11839.821289, 12543.853516, 13289.75};
+
+void setup();//use this to do any initialisation if you want.
+
+void play(double *channels);//run dac! 
+
+maxiOsc::maxiOsc(){
+    //When you create an oscillator, the constructor sets the phase of the oscillator to 0.
+       phase = 0.0;
+}
+
+double maxiOsc::noise() {
+    //White Noise
+       //always the same unless you seed it.
+       float r = rand()/(float)RAND_MAX;
+       output=r*2-1;
+       return(output);
+}
+
+void maxiOsc::phaseReset(double phaseIn) {
+    //This allows you to set the phase of the oscillator to anything you like.
+       phase=phaseIn;
+       
+}
+
+double maxiOsc::sinewave(double frequency) {
+    //This is a sinewave oscillator
+       output=sin (phase*(TWOPI));
+       if ( phase >= 1.0 ) phase -= 1.0;
+       phase += (1./(maxiSettings::sampleRate/(frequency)));
+       return(output);
+       
+}
+
+double maxiOsc::sinebuf4(double frequency) {
+    //This is a sinewave oscillator that uses 4 point interpolation on a 514 point buffer
+       double remainder;
+       double a,b,c,d,a1,a2,a3;
+       phase += 512./(maxiSettings::sampleRate/(frequency));
+       if ( phase >= 511 ) phase -=512;
+       remainder = phase - floor(phase);
+       
+       if (phase==0) {
+               a=sineBuffer[(long) 512];
+               b=sineBuffer[(long) phase];
+               c=sineBuffer[(long) phase+1];
+               d=sineBuffer[(long) phase+2];
+               
+       } else {
+               a=sineBuffer[(long) phase-1];
+               b=sineBuffer[(long) phase];
+               c=sineBuffer[(long) phase+1];
+               d=sineBuffer[(long) phase+2];
+               
+       }
+       
+       a1 = 0.5f * (c - a);
+       a2 = a - 2.5 * b + 2.f * c - 0.5f * d;
+       a3 = 0.5f * (d - a) + 1.5f * (b - c);
+       output = double (((a3 * remainder + a2) * remainder + a1) * remainder + b);
+       return(output);
+}
+
+double maxiOsc::sinebuf(double frequency) { //specify the frequency of the oscillator in Hz / cps etc.
+    //This is a sinewave oscillator that uses linear interpolation on a 514 point buffer
+       double remainder;
+       phase += 512./(maxiSettings::sampleRate/(frequency*chandiv));
+       if ( phase >= 511 ) phase -=512;
+       remainder = phase - floor(phase);
+       output = (double) ((1-remainder) * sineBuffer[1+ (long) phase] + remainder * sineBuffer[2+(long) phase]);
+       return(output);
+}
+
+double maxiOsc::coswave(double frequency) {
+    //This is a cosine oscillator
+       output=cos (phase*(TWOPI));
+       if ( phase >= 1.0 ) phase -= 1.0;
+       phase += (1./(maxiSettings::sampleRate/(frequency)));
+       return(output);
+       
+}
+
+double maxiOsc::phasor(double frequency) {
+    //This produces a floating point linear ramp between 0 and 1 at the desired frequency 
+       output = phase;
+       if ( phase >= 1.0 ) phase -= 1.0;
+       phase += (1. / (maxiSettings::sampleRate/(frequency)));
+       return(output);
+} 
+
+double maxiOsc::square(double frequency) {
+    //This is a square wave
+       if (phase<0.5) output=-1;
+       if (phase>0.5) output=1;
+       if ( phase >= 1.0 ) phase -= 1.0;
+       phase += (1./(maxiSettings::sampleRate/(frequency)));
+       return(output);
+}
+
+double maxiOsc::pulse(double frequency, double duty) {
+    //This is a pulse generator that creates a signal between -1 and 1.
+       if (duty<0.) duty=0;
+       if (duty>1.) duty=1;
+       if ( phase >= 1.0 ) phase -= 1.0;
+       phase += (1./(maxiSettings::sampleRate/(frequency)));
+       if (phase<duty) output=-1.;
+       if (phase>duty) output=1.;
+       return(output);
+}
+
+double maxiOsc::phasor(double frequency, double startphase, double endphase) {
+    //This is a phasor that takes a value for the start and end of the ramp. 
+       output=phase;
+       if (phase<startphase) {
+               phase=startphase;
+       }
+       if ( phase >= endphase ) phase = startphase;
+       phase += ((endphase-startphase)/(maxiSettings::sampleRate/(frequency)));
+       return(output);
+}
+
+
+double maxiOsc::saw(double frequency) {
+       //Sawtooth generator. This is like a phasor but goes between -1 and 1
+       output=phase;
+       if ( phase >= 1.0 ) phase -= 2.0;
+       phase += (1./(maxiSettings::sampleRate/(frequency)));
+       return(output);
+       
+}
+
+double maxiOsc::sawn(double frequency) {
+       //Bandlimited sawtooth generator. Woohoo.
+    if ( phase >= 0.5 ) phase -= 1.0;
+    phase += (1./(maxiSettings::sampleRate/(frequency)));
+       double temp=(8820.22/frequency)*phase;
+    if (temp<-0.5) {
+        temp=-0.5;
+    }
+    if (temp>0.5) {
+        temp=0.5;
+    }
+    temp*=1000.0f;
+    temp+=500.0f;
+    double remainder = temp - floor(temp);
+    output = (double) ((1.0f-remainder) * transition[(long)temp] + remainder * transition[1+(long)temp]) - phase;
+       return(output);
+       
+}
+
+double maxiOsc::rect(double frequency, double duty) {
+
+    return (output);
+}
+
+double maxiOsc::triangle(double frequency) {
+    //This is a triangle wave.
+       if ( phase >= 1.0 ) phase -= 1.0;
+       phase += (1./(maxiSettings::sampleRate/(frequency)));
+       if (phase <= 0.5 ) {
+               output =(phase - 0.25) * 4;
+       } else {
+               output =((1.0-phase) - 0.25) * 4;
+       }
+       return(output);
+       
+} 
+
+double maxiEnvelope::line(int numberofsegments,double segments[1000]) {
+       //This is a basic multi-segment ramp generator that you can use for more or less anything.
+    //However, it's not that intuitive.
+    if (isPlaying==1) {//only make a sound once you've been triggered
+       period=2./(segments[valindex+1]*0.004);
+       nextval=segments[valindex+2];
+       currentval=segments[valindex];
+       if (currentval-amplitude > 0.0000001 && valindex < numberofsegments) {
+               amplitude += ((currentval-startval)/(maxiSettings::sampleRate/period));
+       } else if (currentval-amplitude < -0.0000001 && valindex < numberofsegments) {
+               amplitude -= (((currentval-startval)*(-1))/(maxiSettings::sampleRate/period));
+       } else if (valindex >numberofsegments-1) {
+               valindex=numberofsegments-2;
+       } else {
+               valindex=valindex+2;
+               startval=currentval;
+       }
+       output=amplitude;
+               
+       }
+       else {
+               output=0;
+               
+       }
+       return(output);
+}
+
+//and this
+void maxiEnvelope::trigger(int index, double amp) {
+       isPlaying=1;//ok the envelope is being used now.
+       valindex=index;
+       amplitude=amp;
+       
+}
+
+//Delay with feedback
+maxiDelayline::maxiDelayline() {
+       memset( memory, 0, 88200*sizeof (double) );     
+}
+
+
+double maxiDelayline::dl(double input, int size, double feedback)  {
+       if ( phase >=size ) {
+               phase = 0;
+       }
+       output = memory[phase];
+       memory[phase] = (memory[phase] * feedback) + (input * feedback) * 0.5;
+       phase += 1;
+       return(output);
+}
+
+double maxiDelayline::dl(double input, int size, double feedback, int position)  {
+       if ( phase >=size ) phase = 0;
+       if ( position >=size ) position = 0;
+       output=memory[position];
+       memory[phase]=(memory[phase]*feedback)+(input*feedback)*chandiv;
+       phase+=1;
+       return(output);
+       
+}
+
+//I particularly like these. cutoff between 0 and 1
+double maxiFilter::lopass(double input, double cutoff) {
+       output=outputs[0] + cutoff*(input-outputs[0]);
+       outputs[0]=output;
+       return(output);
+}
+//as above
+double maxiFilter::hipass(double input, double cutoff) {
+       output=input-(outputs[0] + cutoff*(input-outputs[0]));
+       outputs[0]=output;
+       return(output);
+}
+//awesome. cuttof is freq in hz. res is between 1 and whatever. Watch out!
+double maxiFilter::lores(double input,double cutoff1, double resonance) {
+       cutoff=cutoff1*0.5;
+       if (cutoff<10) cutoff=10;
+       if (cutoff>(maxiSettings::sampleRate*0.5)) cutoff=(maxiSettings::sampleRate*0.5);
+       if (resonance<1.) resonance = 1.;
+       z=cos(TWOPI*cutoff/maxiSettings::sampleRate);
+       c=2-2*z;
+       double r=(sqrt(2.0)*sqrt(-pow((z-1.0),3.0))+resonance*(z-1))/(resonance*(z-1));
+       x=x+(input-y)*c;
+       y=y+x;
+       x=x*r;
+       output=y;
+       return(output);
+}
+
+//working hires filter
+double maxiFilter::hires(double input,double cutoff1, double resonance) {
+       cutoff=cutoff1*0.5;
+       if (cutoff<10) cutoff=10;
+       if (cutoff>(maxiSettings::sampleRate*0.5)) cutoff=(maxiSettings::sampleRate*0.5);
+       if (resonance<1.) resonance = 1.;
+       z=cos(TWOPI*cutoff/maxiSettings::sampleRate);
+       c=2-2*z;
+       double r=(sqrt(2.0)*sqrt(-pow((z-1.0),3.0))+resonance*(z-1))/(resonance*(z-1));
+       x=x+(input-y)*c;
+       y=y+x;
+       x=x*r;
+       output=input-y;
+       return(output);
+}
+
+//This works a bit. Needs attention.
+double maxiFilter::bandpass(double input,double cutoff1, double resonance) {
+       cutoff=cutoff1;
+       if (cutoff>(maxiSettings::sampleRate*0.5)) cutoff=(maxiSettings::sampleRate*0.5);
+       if (resonance>=1.) resonance=0.999999;
+       z=cos(TWOPI*cutoff/maxiSettings::sampleRate);
+       inputs[0] = (1-resonance)*(sqrt(resonance*(resonance-4.0*pow(z,2.0)+2.0)+1));
+       inputs[1] = 2*z*resonance;
+       inputs[2] = pow((resonance*-1),2);
+       
+       output=inputs[0]*input+inputs[1]*outputs[1]+inputs[2]*outputs[2];
+       outputs[2]=outputs[1];
+       outputs[1]=output;
+       return(output);
+}
+
+//stereo bus
+double *maxiMix::stereo(double input,double two[2],double x) {
+       if (x>1) x=1;
+       if (x<0) x=0;
+       two[0]=input*sqrt(1.0-x);
+       two[1]=input*sqrt(x);
+       return(two);
+} 
+
+//quad bus
+double *maxiMix::quad(double input,double four[4],double x,double y) {
+       if (x>1) x=1;
+       if (x<0) x=0;
+       if (y>1) y=1;
+       if (y<0) y=0;
+       four[0]=input*sqrt((1.0-x)*y);
+       four[1]=input*sqrt((1.0-x)*(1.0-y));
+       four[2]=input*sqrt(x*y);
+       four[3]=input*sqrt(x*(1.0-y));
+       return(four);
+}
+
+//ambisonic bus
+double *maxiMix::ambisonic(double input,double eight[8],double x,double y,double z) {
+       if (x>1) x=1;
+       if (x<0) x=0;
+       if (y>1) y=1;
+       if (y<0) y=0;
+       if (z>1) y=1;
+       if (z<0) y=0;
+       eight[0]=input*(sqrt((1.0-x)*y)*1.0-z);
+       eight[1]=input*(sqrt((1.0-x)*(1.0-y))*1.0-z);
+       eight[2]=input*(sqrt(x*y)*1.0-z);
+       eight[3]=input*(sqrt(x*(1.0-y))*1.0-z);
+       eight[4]=input*(sqrt((1.0-x)*y)*z);
+       eight[5]=input*(sqrt((1.0-x)*(1.0-y))*z);
+       eight[6]=input*sqrt((x*y)*z);
+       eight[7]=input*sqrt((x*(1.0-y))*z);
+       return(eight);
+}
+
+//This is the maxiSample load function. It just calls read.
+bool maxiSample::load(string fileName, int channel) {
+       myPath = fileName;
+       readChannel=channel;
+       return read();
+}
+
+// This is for OGG loading
+bool maxiSample::loadOgg(string fileName, int channel) {
+#ifdef VORBIS
+    bool result;
+       readChannel=channel;
+    int channelx;
+//    cout << fileName << endl;
+    myDataSize = stb_vorbis_decode_filename(const_cast<char*>(fileName.c_str()), &channelx, &temp);
+    result = myDataSize > 0;
+    printf("\nchannels = %d\nlength = %d",channelx,myDataSize);
+    printf("\n");
+    myChannels=(short)channelx;
+    length=myDataSize;
+    mySampleRate=44100;
+    
+    if (myChannels>1) {
+        int position=0;
+        int channel=readChannel;
+        for (int i=channel;i<myDataSize*2;i+=myChannels) {
+            temp[position]=temp[i];
+            position++;
+        }
+    }
+       return result; // this should probably be something more descriptive
+#endif
+    return 0;
+}
+
+//This sets the playback position to the start of a sample
+void maxiSample::trigger() {
+       position = 0;
+}
+
+//This is the main read function.
+bool maxiSample::read()
+{
+       bool result;
+       ifstream inFile( myPath.c_str(), ios::in | ios::binary);
+       result = (bool) inFile;
+       if (inFile) {
+               bool datafound = false;
+               inFile.seekg(4, ios::beg);
+               inFile.read( (char*) &myChunkSize, 4 ); // read the ChunkSize
+               
+               inFile.seekg(16, ios::beg);
+               inFile.read( (char*) &mySubChunk1Size, 4 ); // read the SubChunk1Size
+               
+               //inFile.seekg(20, ios::beg);
+               inFile.read( (char*) &myFormat, sizeof(short) ); // read the file format.  This should be 1 for PCM
+               
+               //inFile.seekg(22, ios::beg);
+               inFile.read( (char*) &myChannels, sizeof(short) ); // read the # of channels (1 or 2)
+               
+               //inFile.seekg(24, ios::beg);
+               inFile.read( (char*) &mySampleRate, sizeof(int) ); // read the samplerate
+               
+               //inFile.seekg(28, ios::beg);
+               inFile.read( (char*) &myByteRate, sizeof(int) ); // read the byterate
+               
+               //inFile.seekg(32, ios::beg);
+               inFile.read( (char*) &myBlockAlign, sizeof(short) ); // read the blockalign
+               
+               //inFile.seekg(34, ios::beg);
+               inFile.read( (char*) &myBitsPerSample, sizeof(short) ); // read the bitspersample
+               
+               //ignore any extra chunks
+               char chunkID[5]="";
+               chunkID[4] = 0;
+               int filePos = 36;
+               while(!datafound && !inFile.eof()) {
+                       inFile.seekg(filePos, ios::beg);
+                       inFile.read((char*) &chunkID, sizeof(char) * 4);
+                       inFile.seekg(filePos + 4, ios::beg);
+                       inFile.read( (char*) &myDataSize, sizeof(int) ); // read the size of the data
+                       filePos += 8;
+                       if (strcmp(chunkID,"data") == 0) {
+                               datafound = true;
+                       }else{
+                               filePos += myDataSize;
+                       }
+               }
+               
+               // read the data chunk
+               myData = (char*) malloc(myDataSize * sizeof(char));
+               inFile.seekg(filePos, ios::beg);
+               inFile.read(myData, myDataSize);
+               length=myDataSize*(0.5/myChannels);
+               inFile.close(); // close the input file
+               
+        cout << "Ch: " << myChannels << ", len: " << length << endl;
+               if (myChannels>1) {
+                       int position=0;
+                       int channel=readChannel*2;
+                       for (int i=channel;i<myDataSize+6;i+=(myChannels*2)) {
+                               myData[position]=myData[i];
+                               myData[position+1]=myData[i+1];
+                               position+=2;
+                       }
+               }
+        temp = (short*) malloc(myDataSize * sizeof(char));
+        memcpy(temp, myData, myDataSize * sizeof(char));
+        
+        free(myData);
+               
+       }else {
+//             cout << "ERROR: Could not load sample: " <<myPath << endl; //This line seems to be hated by windows 
+        printf("ERROR: Could not load sample.");
+
+       }
+       
+       
+       return result; // this should probably be something more descriptive
+}
+
+//This plays back at the correct speed. Always loops.
+double maxiSample::play() {
+       position++;
+       if ((long) position == length) position=0;
+       output = (double) temp[(long)position]/32767.0;
+       return output;
+}
+
+//This plays back at the correct speed. Only plays once. To retrigger, you have to manually reset the position
+double maxiSample::playOnce() {
+       position++;
+       if ((long) position<length)
+        output = (double) temp[(long)position]/32767.0;
+    else {
+        output=0;
+    }
+       return output;
+
+}
+
+//Same as above but takes a speed value specified as a ratio, with 1.0 as original speed
+double maxiSample::playOnce(double speed) {
+       position=position+((speed*chandiv)/(maxiSettings::sampleRate/mySampleRate));
+       double remainder = position - (long) position;
+       if ((long) position<length)
+               output = (double) ((1-remainder) * temp[1+ (long) position] + remainder * temp[2+(long) position])/32767;//linear interpolation
+       else 
+               output=0;
+       return(output);
+}
+
+//As above but looping
+double maxiSample::play(double speed) {
+       double remainder;
+       long a,b;
+       position=position+((speed*chandiv)/(maxiSettings::sampleRate/mySampleRate));
+       if (speed >=0) {
+               
+               if ((long) position>=length-1) position=1;
+               remainder = position - floor(position);
+               if (position+1<length) {
+                       a=position+1;
+                       
+               }
+               else {
+                       a=length-1;
+               }
+               if (position+2<length)
+               {
+               b=position+2;
+               }
+               else {
+               b=length-1;
+               }
+               
+               output = (double) ((1-remainder) * temp[a] + remainder * temp[b])/32767;//linear interpolation
+} else {
+               if ((long) position<0) position=length;
+               remainder = position - floor(position);
+               if (position-1>=0) {
+                       a=position-1;
+                               
+                       }
+                       else {
+                               a=0;
+                       }
+       if (position-2>=0) {
+               b=position-2;
+                       }
+                       else {
+                               b=0;
+                       }
+               output = (double) ((-1-remainder) * temp[a] + remainder * temp[b])/32767;//linear interpolation
+       }       
+       return(output);
+}
+
+//placeholder
+double maxiSample::play(double frequency, double start, double end) {
+       return play(frequency, start, end, position);
+}
+
+//This allows you to say how often a second you want a specific chunk of audio to play
+double maxiSample::play(double frequency, double start, double end, double &pos) {
+       double remainder;
+       if (end>=length) end=length-1;
+       long a,b;
+
+       if (frequency >0.) {
+               if (pos<start) {
+                       pos=start;
+               }
+               
+               if ( pos >= end ) pos = start;
+               pos += ((end-start)/(maxiSettings::sampleRate/(frequency*chandiv)));
+               remainder = pos - floor(pos);
+               long posl = floor(pos);
+               if (posl+1<length) {
+                       a=posl+1;
+                       
+               }
+               else {
+                       a=posl-1;
+               }
+               if (posl+2<length) {
+                       b=posl+2;
+               }
+               else {
+                       b=length-1;
+               }
+
+               output = (double) ((1-remainder) * temp[a] +
+                                                  remainder * temp[b])/32767;//linear interpolation
+       } else {
+               frequency=frequency-(frequency+frequency);
+               if ( pos <= start ) pos = end;
+               pos -= ((end-start)/(maxiSettings::sampleRate/(frequency*chandiv)));
+               remainder = pos - floor(pos);
+               long posl = floor(pos);
+               if (posl-1>=0) {
+                       a=posl-1;
+               }
+               else {
+                       a=0;
+               }
+               if (posl-2>=0) {
+                       b=posl-2;
+               }
+               else {
+                       b=0;
+               }               
+               output = (double) ((-1-remainder) * temp[a] +
+                                                  remainder * temp[b])/32767;//linear interpolation
+               
+       }
+       
+       return(output);
+}
+
+
+//Same as above. better cubic inerpolation. Cobbled together from various (pd externals, yehar, other places).
+double maxiSample::play4(double frequency, double start, double end) {
+       double remainder;
+       double a,b,c,d,a1,a2,a3;
+       if (frequency >0.) {
+               if (position<start) {
+                       position=start;
+               }
+               if ( position >= end ) position = start;
+               position += ((end-start)/(maxiSettings::sampleRate/(frequency*chandiv)));
+               remainder = position - floor(position);
+               if (position>0) {
+                       a=temp[(int)(floor(position))-1];
+
+               } else {
+                       a=temp[0];
+                       
+               }
+               
+               b=temp[(long) position];
+               if (position<end-2) {
+                       c=temp[(long) position+1];
+
+               } else {
+                       c=temp[0];
+
+               }
+               if (position<end-3) {
+                       d=temp[(long) position+2];
+
+               } else {
+                       d=temp[0];
+               }
+               a1 = 0.5f * (c - a);
+               a2 = a - 2.5 * b + 2.f * c - 0.5f * d;
+               a3 = 0.5f * (d - a) + 1.5f * (b - c);
+               output = (double) (((a3 * remainder + a2) * remainder + a1) * remainder + b) / 32767;
+               
+       } else {
+               frequency=frequency-(frequency+frequency);
+               if ( position <= start ) position = end;
+               position -= ((end-start)/(maxiSettings::sampleRate/(frequency*chandiv)));
+               remainder = position - floor(position);
+               if (position>start && position < end-1) {
+                       a=temp[(long) position+1];
+                       
+               } else {
+                       a=temp[0];
+                       
+               }
+               
+               b=temp[(long) position];
+               if (position>start) {
+                       c=temp[(long) position-1];
+                       
+               } else {
+                       c=temp[0];
+                       
+               }
+               if (position>start+1) {
+                       d=temp[(long) position-2];
+                       
+               } else {
+                       d=temp[0];
+               }
+               a1 = 0.5f * (c - a);
+               a2 = a - 2.5 * b + 2.f * c - 0.5f * d;
+               a3 = 0.5f * (d - a) + 1.5f * (b - c);
+               output = (double) (((a3 * remainder + a2) * -remainder + a1) * -remainder + b) / 32767;
+               
+       }
+       
+       return(output);
+}
+
+
+//You don't need to worry about this stuff.
+double maxiSample::bufferPlay(unsigned char &bufferin,long length) {
+       double remainder;
+       short* buffer = (short *)&bufferin;
+       position=(position+1);
+       remainder = position - (long) position;
+       if ((long) position>length) position=0;
+       output = (double) ((1-remainder) * buffer[1+ (long) position] + remainder * buffer[2+(long) position])/32767;//linear interpolation
+       return(output);
+}
+
+double maxiSample::bufferPlay(unsigned char &bufferin,double speed,long length) {
+       double remainder;
+       long a,b;
+       short* buffer = (short *)&bufferin;
+       position=position+((speed*chandiv)/(maxiSettings::sampleRate/mySampleRate));
+       if (speed >=0) {
+               
+               if ((long) position>=length-1) position=1;
+               remainder = position - floor(position);
+               if (position+1<length) {
+                       a=position+1;
+                       
+               }
+               else {
+                       a=length-1;
+               }
+               if (position+2<length)
+               {
+                       b=position+2;
+               }
+               else {
+                       b=length-1;
+               }
+               
+               output = (double) ((1-remainder) * buffer[a] + remainder * buffer[b])/32767;//linear interpolation
+       } else {
+               if ((long) position<0) position=length;
+               remainder = position - floor(position);
+               if (position-1>=0) {
+                       a=position-1;
+                       
+               }
+               else {
+                       a=0;
+               }
+               if (position-2>=0) {
+                       b=position-2;
+               }
+               else {
+                       b=0;
+               }
+               output = (double) ((-1-remainder) * buffer[a] + remainder * buffer[b])/32767;//linear interpolation
+       }       
+       return(output);
+}
+
+double maxiSample::bufferPlay(unsigned char &bufferin,double frequency, double start, double end) {
+       double remainder;
+       length=end;
+       long a,b;
+       short* buffer = (short *)&bufferin;
+       if (frequency >0.) {
+               if (position<start) {
+                       position=start;
+               }
+               
+               if ( position >= end ) position = start;
+               position += ((end-start)/(maxiSettings::sampleRate/(frequency*chandiv)));
+               remainder = position - floor(position);
+               long pos = floor(position);
+               if (pos+1<length) {
+                       a=pos+1;
+                       
+               }
+               else {
+                       a=pos-1;
+               }
+               if (pos+2<length) {
+                       b=pos+2;
+               }
+               else {
+                       b=length-1;
+               }
+               
+               output = (double) ((1-remainder) * buffer[a] +
+                                                  remainder * buffer[b])/32767;//linear interpolation
+       } else {
+               frequency=frequency-(frequency+frequency);
+               if ( position <= start ) position = end;
+               position -= ((end-start)/(maxiSettings::sampleRate/(frequency*chandiv)));
+               remainder = position - floor(position);
+               long pos = floor(position);
+               if (pos-1>=0) {
+                       a=pos-1;
+               }
+               else {
+                       a=0;
+               }
+               if (pos-2>=0) {
+                       b=pos-2;
+               }
+               else {
+                       b=0;
+               }               
+               output = (double) ((-1-remainder) * buffer[a] +
+                                                  remainder * buffer[b])/32767;//linear interpolation
+               
+       }
+       
+       return(output);
+}
+
+//better cubic inerpolation. Cobbled together from various (pd externals, yehar, other places).
+double maxiSample::bufferPlay4(unsigned char &bufferin,double frequency, double start, double end) {
+       double remainder;
+       double a,b,c,d,a1,a2,a3;
+       short* buffer = (short*)&bufferin;
+       if (frequency >0.) {
+               if (position<start) {
+                       position=start;
+               }
+               if ( position >= end ) position = start;
+               position += ((end-start)/(maxiSettings::sampleRate/(frequency*chandiv)));
+               remainder = position - floor(position);
+               if (position>0) {
+                       a=buffer[(int)(floor(position))-1];
+                       
+               } else {
+                       a=buffer[0];
+                       
+               }
+               
+               b=buffer[(long) position];
+               if (position<end-2) {
+                       c=buffer[(long) position+1];
+                       
+               } else {
+                       c=buffer[0];
+                       
+               }
+               if (position<end-3) {
+                       d=buffer[(long) position+2];
+                       
+               } else {
+                       d=buffer[0];
+               }
+               a1 = 0.5f * (c - a);
+               a2 = a - 2.5 * b + 2.f * c - 0.5f * d;
+               a3 = 0.5f * (d - a) + 1.5f * (b - c);
+               output = (double) (((a3 * remainder + a2) * remainder + a1) * remainder + b) / 32767;
+               
+       } else {
+               frequency=frequency-(frequency+frequency);
+               if ( position <= start ) position = end;
+               position -= ((end-start)/(maxiSettings::sampleRate/(frequency*chandiv)));
+               remainder = position - floor(position);
+               if (position>start && position < end-1) {
+                       a=buffer[(long) position+1];
+                       
+               } else {
+                       a=buffer[0];
+                       
+               }
+               
+               b=buffer[(long) position];
+               if (position>start) {
+                       c=buffer[(long) position-1];
+                       
+               } else {
+                       c=buffer[0];
+                       
+               }
+               if (position>start+1) {
+                       d=buffer[(long) position-2];
+                       
+               } else {
+                       d=buffer[0];
+               }
+               a1 = 0.5f * (c - a);
+               a2 = a - 2.5 * b + 2.f * c - 0.5f * d;
+               a3 = 0.5f * (d - a) + 1.5f * (b - c);
+               output = (double) (((a3 * remainder + a2) * -remainder + a1) * -remainder + b) / 32767;
+               
+       }
+       
+       return(output);
+}
+
+
+void maxiSample::getLength() {
+       length=myDataSize*0.5;  
+}
+
+void maxiSample::setLength(unsigned long numSamples) {
+    cout << "Length: " << numSamples << endl;
+    short *newData = (short*) malloc(sizeof(short) * numSamples);
+    if (NULL!=temp) {
+        unsigned long copyLength = min((unsigned long)length, numSamples);
+        memcpy(newData, temp, sizeof(short) * copyLength);
+    }
+    temp = newData;
+    myDataSize = numSamples * 2;
+    length=numSamples;
+    position=0;
+    recordPosition=0;
+}
+
+void maxiSample::clear() {
+    memset(myData, 0, myDataSize);
+}
+
+void maxiSample::reset() {
+    position=0;
+}
+
+
+
+
+
+/* OK this compressor and gate are now ready to use. The envelopes, like all the envelopes in this recent update, use stupid algorithms for 
+ incrementing - consequently a long attack is something like 0.0001 and a long release is like 0.9999.
+ Annoyingly, a short attack is 0.1, and a short release is 0.99. I'll sort this out laters */
+
+double maxiDyn::gate(double input, double threshold, long holdtime, double attack, double release) {
+       
+       if (fabs(input)>threshold && attackphase!=1){ 
+               holdcount=0;
+               releasephase=0;
+               attackphase=1;
+               if(amplitude==0) amplitude=0.01;
+       }
+       
+       if (attackphase==1 && amplitude<1) {
+               amplitude*=(1+attack);
+               output=input*amplitude;
+       }
+       
+       if (amplitude>=1) {
+               attackphase=0;
+               holdphase=1;
+       }
+       
+       if (holdcount<holdtime && holdphase==1) {
+               output=input;
+               holdcount++;
+       }
+       
+       if (holdcount==holdtime) {
+               holdphase=0;
+               releasephase=1;
+       }
+       
+       if (releasephase==1 && amplitude>0.) {
+               output=input*(amplitude*=release);
+               
+       }
+       
+       return output;
+}
+
+
+double maxiDyn::compressor(double input, double ratio, double threshold, double attack, double release) {
+       
+       if (fabs(input)>threshold && attackphase!=1){ 
+               holdcount=0;
+               releasephase=0;
+               attackphase=1;
+               if(currentRatio==0) currentRatio=ratio;
+       }
+       
+       if (attackphase==1 && currentRatio<ratio-1) {
+               currentRatio*=(1+attack);
+       }
+       
+       if (currentRatio>=ratio-1) {
+               attackphase=0;
+               releasephase=1;
+       }
+       
+       if (releasephase==1 && currentRatio>0.) {
+               currentRatio*=release;          
+       }
+       
+       if (input>0.) {
+               output = input/(1.+currentRatio);
+       } else {
+               output = input/(1.+currentRatio);
+       }
+       
+       return output*(1+log(ratio));
+}
+
+
+/* Lots of people struggle with the envelope generators so here's a new easy one.
+ It takes mental numbers for attack and release tho. Basically, they're exponentials.
+ I'll map them out later so that it's a bit more intuitive */
+double maxiEnv::ar(double input, double attack, double release, long holdtime, int trigger) {
+       
+       if (trigger==1 && attackphase!=1 && holdphase!=1){ 
+               holdcount=0;
+               releasephase=0;
+               attackphase=1;
+       }
+       
+       if (attackphase==1) {
+               amplitude+=(1*attack);
+               output=input*amplitude;
+       }
+       
+       if (amplitude>=1) {
+               amplitude=1;
+               attackphase=0;
+               holdphase=1;
+       }
+       
+       if (holdcount<holdtime && holdphase==1) {
+               output=input;
+               holdcount++;
+       }
+       
+       if (holdcount==holdtime && trigger==1) {
+               output=input;
+       }
+       
+       if (holdcount==holdtime && trigger!=1) {
+               holdphase=0;
+               releasephase=1;
+       }
+       
+       if (releasephase==1 && amplitude>0.) {
+               output=input*(amplitude*=release);
+               
+       }
+       
+       return output;
+}
+
+/* and here's a new adsr. It's not bad, very simple to use*/
+
+double maxiEnv::adsr(double input, double attack, double decay, double sustain, double release, long holdtime, int trigger) {
+       
+       if (trigger==1 && attackphase!=1 && holdphase!=1 && decayphase!=1){ 
+               holdcount=0;
+               decayphase=0;
+               sustainphase=0;
+               releasephase=0;
+               attackphase=1;
+       }
+       
+       if (attackphase==1) {
+               amplitude+=(1*attack);
+               output=input*amplitude;
+       }
+       
+       if (amplitude>=1) {
+               amplitude=1;
+               attackphase=0;
+               decayphase=1;
+       }
+       
+       if (decayphase==1) {
+               output=input*(amplitude*=decay);        
+               if (amplitude<=sustain) {
+                       decayphase=0;
+                       holdphase=1;
+               }
+       }
+       
+       if (holdcount<holdtime && holdphase==1) {
+               output=input*amplitude;
+               holdcount++;
+       }
+       
+       if (holdcount==holdtime && trigger==1) {
+               output=input*amplitude;
+       }
+       
+       if (holdcount==holdtime && trigger!=1) {
+               holdphase=0;
+               releasephase=1;
+       }
+       
+       if (releasephase==1 && amplitude>0.) {
+               output=input*(amplitude*=release);
+               
+       }
+       
+       return output;
+}
+
+double convert::mtof(int midinote) {
+       
+       return mtofarray[midinote];
+}
+
+
+void maxiEnvelopeFollower::setAttack(double attackMS) {
+    attack = pow( 0.01, 1.0 / ( attackMS * maxiSettings::sampleRate * 0.001 ) );
+}
+
+void maxiEnvelopeFollower::setRelease(double releaseMS) {
+    release = pow( 0.01, 1.0 / ( releaseMS * maxiSettings::sampleRate * 0.001 ) );    
+}
+
diff --git a/lib/Maximilian/maximilian.h b/lib/Maximilian/maximilian.h
new file mode 100755 (executable)
index 0000000..0cac59d
--- /dev/null
@@ -0,0 +1,501 @@
+/*
+ *  maximilian.h
+ *  platform independent synthesis library using portaudio or rtaudio
+ *
+ *  Created by Mick Grierson on 29/12/2009.
+ *  Copyright 2009 Mick Grierson & Strangeloop Limited. All rights reserved.
+ *     Thanks to the Goldsmiths Creative Computing Team.
+ *     Special thanks to Arturo Castro for the PortAudio implementation.
+ * 
+ *     Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or sell
+ *     copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *     
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef MAXIMILIAN_H
+#define MAXIMILIAN_H
+
+//#define MAXIMILIAN_PORTAUDIO
+#define MAXIMILIAN_RT_AUDIO
+
+
+#include <iostream>
+#include <fstream>
+#include <string.h>
+#include <cstdlib>
+#include "math.h"
+
+using namespace std;
+#ifndef PI
+#define PI  3.1415926535897932384626433832795
+#endif
+#define TWOPI 6.283185307179586476925286766559
+
+class maxiSettings {
+public:
+       static int sampleRate;
+       static int channels;
+       static int bufferSize;
+       static void setup(int initSampleRate, int initChannels, int initBufferSize) {
+               maxiSettings::sampleRate = initSampleRate;
+               maxiSettings::channels = initChannels;
+               maxiSettings::bufferSize = initBufferSize;
+       }
+};
+
+
+class maxiOsc {
+       
+       double frequency;
+       double phase;
+       double startphase;
+       double endphase;
+       double output;
+       double tri;
+       
+       
+public:
+       maxiOsc();
+       double sinewave(double frequency);
+       double coswave(double frequency);
+       double phasor(double frequency);
+       double phasor(double frequency, double startphase, double endphase);
+       double saw(double frequency);
+       double triangle(double frequency);
+       double square(double frequency);
+       double pulse(double frequency, double duty);
+       double noise();
+       double sinebuf(double frequency);
+       double sinebuf4(double frequency);
+    double sawn(double frequency);
+    double rect(double frequency, double duty=0.5);
+       void phaseReset(double phaseIn);
+       
+};
+
+
+class maxiEnvelope {
+       
+       double period;
+       double output;
+       double startval;
+       double currentval;
+       double nextval;
+       int isPlaying;
+
+public:        
+       double line(int numberofsegments,double segments[100]);
+       void trigger(int index,double amp);
+       int valindex;
+       double amplitude;
+       
+};
+
+
+class maxiDelayline {
+       double frequency;
+       int phase;
+       double startphase;
+       double endphase;
+       double output;
+       double memory[88200];
+       
+public:
+       maxiDelayline();
+       double dl(double input, int size, double feedback);
+       double dl(double input, int size, double feedback, int position);
+       
+       
+};
+
+
+class maxiFilter {     
+       double gain;
+       double input;
+       double output;
+       double inputs[10];
+       double outputs[10];
+       double cutoff1;
+       double x;//speed
+       double y;//pos
+       double z;//pole
+       double c;//filter coefficient
+    
+public:
+       maxiFilter():x(0.0), y(0.0), z(0.0), c(0.0){};
+       double cutoff;
+       double resonance;
+       double lores(double input,double cutoff1, double resonance);
+       double hires(double input,double cutoff1, double resonance);
+       double bandpass(double input,double cutoff1, double resonance);
+       double lopass(double input,double cutoff);
+       double hipass(double input,double cutoff);
+       
+};
+
+class maxiMix  {
+       double input;
+       double two[2];
+       double four[4];
+       double eight[8];
+public:
+       double x;
+       double y;
+       double z;
+       double *stereo(double input,double two[2],double x);
+       double *quad(double input,double four[4], double x,double y);
+       double *ambisonic(double input,double eight[8],double x,double y, double z);
+       
+};
+
+//lagging with an exponential moving average
+//a lower alpha value gives a slower lag
+template <class T> 
+class maxiLagExp {
+public:
+       T alpha, alphaReciprocal;
+       T val;
+       
+       maxiLagExp() {
+               init(0.5, 0.0);
+       };
+       
+       maxiLagExp(T initAlpha, T initVal) {
+               init(initAlpha, initVal);
+       }
+       
+       void init(T initAlpha, T initVal) {
+               alpha = initAlpha;
+               alphaReciprocal = 1.0 - alpha;
+               val = initVal;
+       }
+       
+       inline void addSample(T newVal) {
+               val = (alpha * newVal) + (alphaReciprocal * val);
+       }
+       
+       inline T value() {
+               return val;
+       }
+};
+
+
+class maxiSample  {
+       
+private:
+       string  myPath;
+       int     myChunkSize;
+       int     mySubChunk1Size;
+       int             readChannel;
+       short   myFormat;
+       int     myByteRate;
+       short   myBlockAlign;
+       short   myBitsPerSample;
+       double position, recordPosition;
+       double speed;
+       double output;
+    maxiLagExp<double> loopRecordLag;
+       
+public:
+       int     myDataSize;
+       short   myChannels;
+       int     mySampleRate;
+       long length;
+       void getLength();
+    void setLength(unsigned long numSamples);  
+       
+       
+       char*   myData;
+    short* temp;
+       
+       // get/set for the Path property
+       
+       ~maxiSample()
+       {
+               if (myData) free(myData);
+        if (temp) free(temp);
+        printf("freeing SampleData");
+
+       }
+       
+       maxiSample():myData(NULL),temp(NULL),position(0), recordPosition(0), myChannels(1), mySampleRate(maxiSettings::sampleRate) {};
+       
+       bool load(string fileName, int channel=0);
+    
+    bool loadOgg(string filename,int channel=0);
+       
+       void trigger();
+       
+       // read a wav file into this class
+       bool read();
+       
+       //read an ogg file into this class using stb_vorbis
+    bool readOgg();
+    
+    void loopRecord(double newSample, const bool recordEnabled, const double recordMix) {
+        loopRecordLag.addSample(recordEnabled);
+        if(recordEnabled) {
+            double currentSample = ((short*)myData)[(unsigned long)recordPosition] / 32767.0;
+            newSample = (recordMix * currentSample) + ((1.0 - recordMix) * newSample);
+            newSample *= loopRecordLag.value();
+            ((short*)myData)[(unsigned long)recordPosition] = newSample * 32767;
+        }
+        ++recordPosition;
+        if (recordPosition == length)
+            recordPosition=0;
+    }
+    
+    void clear();
+    
+    void reset();
+       
+       double play();
+       
+       double playOnce();
+       
+       double playOnce(double speed);
+       
+       double play(double speed);
+       
+       double play(double frequency, double start, double end, double &pos);
+       
+       double play(double frequency, double start, double end);
+       
+       double play4(double frequency, double start, double end);
+       
+       double bufferPlay(unsigned char &bufferin,long length);
+       
+       double bufferPlay(unsigned char &bufferin,double speed,long length);
+       
+       double bufferPlay(unsigned char &bufferin,double frequency, double start, double end);
+       
+       double bufferPlay4(unsigned char &bufferin,double frequency, double start, double end);
+    bool save() {
+        save(myPath);
+    }
+    
+       bool save(string filename)
+       {
+               fstream myFile (filename.c_str(), ios::out | ios::binary);
+               
+               // write the wav file per the wav file format
+               myFile.seekp (0, ios::beg); 
+               myFile.write ("RIFF", 4);
+               myFile.write ((char*) &myChunkSize, 4);
+               myFile.write ("WAVE", 4);
+               myFile.write ("fmt ", 4);
+               myFile.write ((char*) &mySubChunk1Size, 4);
+               myFile.write ((char*) &myFormat, 2);
+               myFile.write ((char*) &myChannels, 2);
+               myFile.write ((char*) &mySampleRate, 4);
+               myFile.write ((char*) &myByteRate, 4);
+               myFile.write ((char*) &myBlockAlign, 2);
+               myFile.write ((char*) &myBitsPerSample, 2);
+               myFile.write ("data", 4);
+               myFile.write ((char*) &myDataSize, 4);
+               myFile.write (myData, myDataSize);
+               
+               return true;
+       }
+       
+       // return a printable summary of the wav file
+       char *getSummary()
+       {
+               char *summary = new char[250];
+               sprintf(summary, " Format: %d\n Channels: %d\n SampleRate: %d\n ByteRate: %d\n BlockAlign: %d\n BitsPerSample: %d\n DataSize: %d\n", myFormat, myChannels, mySampleRate, myByteRate, myBlockAlign, myBitsPerSample, myDataSize);
+               std::cout << myDataSize;
+               return summary;
+       }
+};
+
+
+class maxiMap {
+public:
+       static double inline linlin(double val, double inMin, double inMax, double outMin, double outMax) {
+               return ((val - inMin) / (inMax - inMin) * (outMax - outMin)) + outMin;
+       }
+       
+       static double inline linexp(double val, double inMin, double inMax, double outMin, double outMax) {
+               //clipping
+               val = max(min(val, inMax), inMin);
+               return pow((outMax / outMin), (val - inMin) / (inMax - inMin)) * outMin;
+       }
+       
+       static double inline explin(double val, double inMin, double inMax, double outMin, double outMax) {
+               //clipping
+               val = max(min(val, inMax), inMin);
+               return (log(val/inMin) / log(inMax/inMin) * (outMax - outMin)) + outMin;
+       }
+       
+       static int inline clamp(int v, const int low, const int high) {
+               v = min(high, v);
+               v = max(low, v);
+               return v;
+       }
+       
+};
+
+
+class maxiDyn {
+       
+       
+public:
+       double gate(double input, double threshold=0.9, long holdtime=1, double attack=1, double release=0.9995);
+       double compressor(double input, double ratio, double threshold=0.9, double attack=1, double release=0.9995);
+       double input;
+       double ratio;
+       double currentRatio;
+       double threshold;
+       double output;
+       double attack;
+       double release;
+       double amplitude;
+       long holdtime;
+       long holdcount;
+       int attackphase,holdphase,releasephase;
+};
+
+class maxiEnv {
+       
+       
+public:
+       double ar(double input, double attack=1, double release=0.9, long holdtime=1, int trigger=0);
+       double adsr(double input, double attack=1, double decay=0.99, double sustain=0.125, double release=0.9, long holdtime=1, int trigger=0);
+       double input;
+       double output;
+       double attack;
+       double decay;
+       double sustain;
+       double release;
+       double amplitude;
+       int trigger;
+       long holdtime;
+       long holdcount;
+       int attackphase,decayphase,sustainphase,holdphase,releasephase;
+};
+
+class convert {
+public:
+       double mtof(int midinote);
+};
+
+
+
+class maxiDistortion {
+public:
+    /*atan distortion, see http://www.musicdsp.org/showArchiveComment.php?ArchiveID=104*/
+    /*shape from 1 (soft clipping) to infinity (hard clipping)*/
+    double atanDist(const double in, const double shape);
+    double fastAtanDist(const double in, const double shape);
+    double fastatan( double x );
+};
+
+inline double maxiDistortion::fastatan(double x)
+{
+    return (x / (1.0 + 0.28 * (x * x)));
+}
+
+inline double maxiDistortion::atanDist(const double in, const double shape) {
+    double out;
+    out = (1.0 / atan(shape)) * atan(in * shape);
+    return out;
+}
+
+inline double maxiDistortion::fastAtanDist(const double in, const double shape) {
+    double out;
+    out = (1.0 / fastatan(shape)) * fastatan(in * shape);
+    return out;
+}
+
+
+class maxiFlanger {
+public:
+    //delay = delay time - ~800 sounds good
+    //feedback = 0 - 1
+    //speed = lfo speed in Hz, 0.0001 - 10 sounds good
+    //depth = 0 - 1
+    double flange(const double input, const unsigned int delay, const double feedback, const double speed, const double depth);
+    maxiDelayline dl;
+    maxiOsc lfo;
+
+};
+
+inline double maxiFlanger::flange(const double input, const unsigned int delay, const double feedback, const double speed, const double depth)
+{
+    //todo: needs fixing
+    double output;
+    double lfoVal = lfo.triangle(speed);
+    output = dl.dl(input, delay + (lfoVal * depth * delay) + 1, feedback) ;    
+    double normalise = (1 - fabs(output));
+    output *= normalise;
+    return (output + input) / 2.0;
+}
+
+class maxiChorus {
+public:
+    //delay = delay time - ~800 sounds good
+    //feedback = 0 - 1
+    //speed = lfo speed in Hz, 0.0001 - 10 sounds good
+    //depth = 0 - 1
+    double chorus(const double input, const unsigned int delay, const double feedback, const double speed, const double depth);
+    maxiDelayline dl, dl2;
+    maxiOsc lfo;
+    maxiFilter lopass;
+    
+};
+
+inline double maxiChorus::chorus(const double input, const unsigned int delay, const double feedback, const double speed, const double depth)
+{
+    //this needs fixing
+    double output1, output2;
+    double lfoVal = lfo.noise();
+    lfoVal = lopass.lores(lfoVal, speed, 1.0) * 2.0;
+    output1 = dl.dl(input, delay + (lfoVal * depth * delay) + 1, feedback) ;    
+    output2 = dl2.dl(input, (delay + (lfoVal * depth * delay * 1.02) + 1) * 0.98, feedback * 0.99) ;    
+    output1 *= (1.0 - fabs(output1));
+    output2 *= (1.0 - fabs(output2));
+    return (output1 + output2 + input) / 3.0;
+}
+
+class maxiEnvelopeFollower {
+public:
+    maxiEnvelopeFollower() {
+        setAttack(100);
+        setRelease(100);
+        env = 0;
+    }
+    void setAttack(double attackMS);
+    void setRelease(double releaseMS);
+    inline double play(double input) {
+        input = fabs(input);
+        if (input>env)
+            env = attack * (env - input) + input;
+        else
+            env = release * (env - input) + input;        
+        return env;
+    }
+       void reset() {env=0;}
+private:
+    double attack, release, env;
+};
+
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/AUTHORS b/lib/MoMu-STK-1.0.0/AUTHORS
new file mode 100644 (file)
index 0000000..8a9da28
--- /dev/null
@@ -0,0 +1,32 @@
+---
+The Synthesis ToolKit in C++ (STK)
+http://ccrma.stanford.edu/software/stk/
+
+By Perry R. Cook and Gary P. Scavone, 1995-2010.
+
+See README (contains original README from STK).
+
+---
+MoMu-STK (for iPhone, iPad, iPod Touch)
+
+authors:
+    Nicholas J. Bryan (njb@ccrma.stanford.edu)
+
+as part of the MoMu toolkit, co-created by:
+    Jorge Herrera (jorgeh@ccrma.stanford.edu)
+    Jieun Oh (jieun5@ccrma.stanford.edu)
+    Ge Wang (ge@ccrma.stanford.edu)
+
+    date: October 2009
+    version: 1.0.0
+---
+  MoMu STK:
+    http://momu.stanford.edu/stk/
+
+  Mobile Music Research at CCRMA:
+    http://momu.stanford.edu/
+
+  Music, Computing, and Design Research Group:
+    http://ccrma.stanford.edu/groups/mcd/
+
diff --git a/lib/MoMu-STK-1.0.0/COPYING b/lib/MoMu-STK-1.0.0/COPYING
new file mode 100644 (file)
index 0000000..f066b0f
--- /dev/null
@@ -0,0 +1 @@
+See README
\ No newline at end of file
diff --git a/lib/MoMu-STK-1.0.0/DEVELOPER b/lib/MoMu-STK-1.0.0/DEVELOPER
new file mode 100644 (file)
index 0000000..22e5ce6
--- /dev/null
@@ -0,0 +1,6 @@
+---
+Please check out the MoMu STK and toolkit page:
+
+    http://momu.stanford.edu/stk/
+    http://momu.stanford.edu/toolkit/
+---
diff --git a/lib/MoMu-STK-1.0.0/INSTALL b/lib/MoMu-STK-1.0.0/INSTALL
new file mode 100644 (file)
index 0000000..66f7a13
--- /dev/null
@@ -0,0 +1,11 @@
+As this current release of MoMu STK targets the iPhone platform, 
+and the spirit of this toolkit to enable developers to rapidly 
+develop sweet interactive audio applications, we'll leave the 
+installation up to you.  In some cases, you might simply want 
+include a particular module, in which you only need to bring 
+in or reference the associated files.
+
+We hope you find this useful!  Have fun with it!
+
+All the best,
+Nick
diff --git a/lib/MoMu-STK-1.0.0/README b/lib/MoMu-STK-1.0.0/README
new file mode 100644 (file)
index 0000000..ff3432e
--- /dev/null
@@ -0,0 +1,232 @@
+-----------------------------------------------------------------------
+The STK (MoMu release) is a slightly modified version of The Synthesis 
+ToolKit in C++ (STK) by Perry R. Cook and Gary P. Scavone, 1995-2010.
+Slight modifications for iPhone OS by Nicholas J. Bryan (October 2009) 
+as part of the MoMu project with Jorge Herrera, Jieun Oh, and Ge Wang 
+(see http://momu.stanford.edu/).  See VERSIONS and AUTHORS for more
+information.  The original STK README (license, etc.) can be found below.
+All licensing or similar issues follow from the original license as 
+specified by Perry R. Cook and Gary P. Scavone.
+-----------------------------------------------------------------------
+
+The Synthesis ToolKit in C++ (STK)
+
+By Perry R. Cook and Gary P. Scavone, 1995-2010.
+
+---
+This distribution of the Synthesis ToolKit in C++ (STK) contains the following:
+
+include:  STK class header files
+src:      STK class source files
+rawwaves: STK audio files (1-channel, 16-bit, big-endian)
+doc:      STK documentation
+projects: example STK projects and programs
+
+Please read the Legal and Ethical notes near the bottom of this document.
+
+For compiling and installing STK, see the INSTALL file in this directory.
+
+OVERVIEW:
+
+The Synthesis ToolKit in C++ (STK) is a set of open source audio
+signal processing and algorithmic synthesis classes written in the C++
+programming language.  STK was designed to facilitate rapid
+development of music synthesis and audio processing software, with an
+emphasis on cross-platform functionality, realtime control, ease of
+use, and educational example code.  The Synthesis ToolKit is extremely
+portable (it's mostly platform-independent C and C++ code), and it's
+completely user-extensible (all source included, no unusual libraries,
+and no hidden drivers).  We like to think that this increases the
+chances that our programs will still work in another 5-10 years.  In
+fact, the ToolKit has been working continuously for nearly 15 years
+now.  STK currently runs with "realtime" support (audio and MIDI) on
+Linux, Macintosh OS X, and Windows computer platforms.  Generic,
+non-realtime support has been tested under NeXTStep, Sun, and other
+platforms and should work with any standard C++ compiler.
+
+The Synthesis ToolKit is free for non-commercial use.  The only parts
+of the Synthesis ToolKit that are platform-dependent concern real-time
+audio and MIDI input and output, and that is taken care of with a few
+special classes.  The interface for MIDI input and the simple Tcl/Tk
+graphical user interfaces (GUIs) provided is the same, so it's easy to
+experiment in real time using either the GUIs or MIDI.  The Synthesis
+ToolKit can generate simultaneous SND (AU), WAV, AIFF, and MAT-file
+output soundfile formats (as well as realtime sound output), so you
+can view your results using one of a large variety of sound/signal
+analysis tools already available (e.g. Snd, Cool Edit, Matlab).
+
+The Synthesis Toolkit is not one particular program.  Rather, it is a
+set of C++ classes that you can use to create your own programs.  A
+few example applications are provided to demonstrate some of the ways
+to use the classes.  If you have specific needs, you will probably
+have to either modify the example programs or write a new program
+altogether. Further, the example programs don't have a fancy GUI
+wrapper. If you feel the need to have a "drag and drop" graphical
+patching GUI, you probably don't want to use the ToolKit. Spending
+hundreds of hours making platform-dependent graphics code would go
+against one of the fundamental design goals of the ToolKit - platform
+independence.
+
+For those instances where a simple GUI with sliders and buttons is
+helpful, we use Tcl/Tk (http://dev.scriptics.com) which is freely
+distributed for all the supported ToolKit platforms. A number of
+Tcl/Tk GUI scripts are distributed with the ToolKit release.  For
+control, the Synthesis Toolkit uses raw MIDI (on supported platforms),
+and SKINI (Synthesis ToolKit Instrument Network Interface, a MIDI-like
+text message synthesis control format).
+
+
+SYSTEM REQUIREMENTS:
+
+See the individual README's (eg. README-linux) in the /doc directory
+for platform specific information and system requirements.  In
+general, you will use the configure script to create Makefiles on unix
+platforms (and MinGW) or the VC++ workspace files to compile the
+example programs.  To use the Tcl/Tk GUIs, you will need Tcl/Tk
+version 8.0 or higher.
+
+
+WHAT'S NEW (AND NOT SO NEW):
+
+Despite being available in one form or another since 1996, we still
+consider STK to be alpha software.  We attempt to maintain backward
+compatability but changes are sometimes made in an effort to improve
+the overall design or performance of the software.  Please read the
+Release Notes to see what has changed since the last release.
+
+A new StkFrames class has been created to facilitate the handling and
+passing of multichannel, vectorized audio data.  All STK classes have
+been updated to include tick() functions that accept StkFrames
+arguments.
+
+The control message handling scheme has been simplified greatly
+through the use of the Messager class.  It is now possible to have
+access to simultaneous piped, socketed, and/or MIDI input control
+messages.  In most cases, this should eliminate the use of the
+Md2Skini program.
+
+Realtime audio input capabilities were added to STK with release 3.0,
+though the behavior of such is very hardware dependent.  Under Linux,
+Macintosh OS-X, and Irix, audio input and output are possible with
+very low latency.  Using the Windoze DirectSound API, minimum
+dependable output sound latency seems to be around 20 milliseconds or
+so, while input sound latency is on the order of a hundred
+milliseconds or more!
+
+As mentioned above, it is possible to record the audio ouput of an STK
+program to .snd, .wav, .raw, .aif, and .mat (Matlab MAT-file) output
+file types.  Though somewhat obsolete, the program Md2Skini can be
+used to write SKINI scorefiles from realtime MIDI input.  Finally, STK
+should compile with non-realtime functionality on any platform with a
+generic C++ compiler.
+
+For those who wish to make a library from the core STK classes, the
+configure script generates a Makefile in the src directory that will
+accomplish that (Linux, SGI, and Macintosh OS X only).
+
+
+DISCLAIMER:
+
+You probably already guessed this, but just to be sure, we don't
+guarantee anything works.  :-) It's free ... what do you expect?  If
+you find a bug, please let us know and we'll try to correct it.  You
+can also make suggestions, but again, no guarantees.  Send email to
+the mail list.
+
+
+LEGAL AND ETHICAL:
+
+This software was designed and created to be made publicly available
+for free, primarily for academic purposes, so if you use it, pass it
+on with this documentation, and for free.
+
+If you make a million dollars with it, it would be nice if you would
+share.  If you make compositions with it, put us in the program notes.
+
+Some of the concepts are covered by various patents, some known to us
+and likely others which are unknown.  Many of the ones known to us are
+administered by the Stanford Office of Technology and Licensing.
+
+The good news is that large hunks of the techniques used here are
+public domain.  To avoid subtle legal issues, we'll not state what's
+freely useable here, but we'll try to note within the various classes
+where certain things are likely to be protected by patents.
+
+LICENSE:
+
+STK WWW site: http://ccrma.stanford.edu/software/stk/
+
+The Synthesis ToolKit in C++ (STK)
+Copyright (c) 1995-2010 Perry R. Cook and Gary P. Scavone
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+Any person wishing to distribute modifications to the Software is
+asked to send the modifications to the original developer so that they
+can be incorporated into the canonical version.  This is, however, not
+a binding provision of this license.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+FURTHER READING:
+
+For complete documentation on this ToolKit, the classes, etc., see the
+doc directory of the distribution or surf to
+http://ccrma.stanford.edu/software/stk/.  Also check the platform
+specific README's for specific system requirements.
+
+
+PERRY'S NOTES FROM THE ORIGINAL DISTRIBUTION:
+
+This whole world was created with no particular hardware in mind.
+These examples are intended to be tutorial in nature, as a platform
+for the continuation of my research, and as a possible starting point
+for a software synthesis system.  The basic motivation was to create
+the necessary unit generators to do the synthesis, processing, and
+control that I want to do and teach about.  Little thought for
+optimization was given and therefore improvements, especially speed
+enhancements, should be possible with these classes.  It was written
+with some basic concepts in mind about how to let compilers optimize.
+
+Your question at this point might be, "But Perry, with CMix, CMusic,
+CSound, CShells, CMonkeys, etc. already cluttering the landscape, why
+a new set of stupid C functions for music synthesis and processing?"
+The answers lie below.
+
+1) I needed to port many of the things I've done into something which is generic enough to port further to different machines.
+
+2) I really plan to document this stuff, so that you don't have to be me to figure out what's going on. (I'll probably be sorry I said this in a couple of years, when even I can't figure out what I was thinking.)
+
+3) The classic difficulties most people have in trying to implement physical models are:
+
+   A) They have trouble understanding the papers, and/or in turning the theory into practice.
+
+   B) The Physical Model instruments are a pain to get to oscillate, and coming up with stable and meaningful parameter values is required to get the models to work at all.
+
+   This set of C++ unit generators and instruments might help to diminish the scores of emails I get asking what to do with those block diagrams I put in my papers.
+
+4) I wanted to try some new stuff with modal synthesis, and implement some classic FM patches as well.
+
+5) I wanted to reimplement, and newly implement more of the intelligent and physical performer models I've talked about in some of my papers. But I wanted to do it in a portable way, and in such a way that I can hook up modules quickly.  I also wanted to make these instruments connectable to such player objects, so folks like Brad Garton who really think a lot about the players can connect them to my instruments, a lot about which I think.
+
+6) More rationalizations to follow . . .
+
+
+
+
diff --git a/lib/MoMu-STK-1.0.0/TODO b/lib/MoMu-STK-1.0.0/TODO
new file mode 100644 (file)
index 0000000..4825436
--- /dev/null
@@ -0,0 +1 @@
+- Connect MoAudio (from MoMu) to RtWvIn.h/cpp and RtWvOut.h/cpp
\ No newline at end of file
diff --git a/lib/MoMu-STK-1.0.0/VERSIONS b/lib/MoMu-STK-1.0.0/VERSIONS
new file mode 100644 (file)
index 0000000..4428418
--- /dev/null
@@ -0,0 +1,18 @@
+---
+MoMu STK-1.0.0
+  - initial release based on STK 4.4.2!
+  - includes everything in STK 4.4.2 except:
+       -RtAudio.h/cpp
+       -RtError.h
+       -RtMidi.h/cpp
+       -RtWvIn.h/cpp
+       -RtWvOut.h/cpp
+  - slight modifications were made to:
+       -Stk.h
+       -Stk.cpp -> Stk.mm
+       -UdpSocket.h/cpp -> StkUdpSocket.h/cpp
+       -makefunc.c
+       -makemidi.c
+       -makewavs.c
+       -sine.c
+
diff --git a/lib/MoMu-STK-1.0.0/include/ADSR.h b/lib/MoMu-STK-1.0.0/include/ADSR.h
new file mode 100644 (file)
index 0000000..de6cb02
--- /dev/null
@@ -0,0 +1,163 @@
+#ifndef STK_ADSR_H
+#define STK_ADSR_H
+
+#include "Generator.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class ADSR
+    \brief STK ADSR envelope class.
+
+    This class implements a traditional ADSR (Attack, Decay, Sustain,
+    Release) envelope.  It responds to simple keyOn and keyOff
+    messages, keeping track of its state.  The \e state = ADSR::DONE
+    after the envelope value reaches 0.0 in the ADSR::RELEASE state.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class ADSR : public Generator
+{
+ public:
+
+  //! ADSR envelope states.
+  enum {
+    ATTACK,   /*!< Attack */
+    DECAY,    /*!< Decay */
+    SUSTAIN,  /*!< Sustain */
+    RELEASE,  /*!< Release */
+    DONE      /*!< End of release */
+  };
+
+  //! Default constructor.
+  ADSR( void );
+
+  //! Class destructor.
+  ~ADSR( void );
+
+  //! Set target = 1, state = \e ADSR::ATTACK.
+  void keyOn( void );
+
+  //! Set target = 0, state = \e ADSR::RELEASE.
+  void keyOff( void );
+
+  //! Set the attack rate.
+  void setAttackRate( StkFloat rate );
+
+  //! Set the decay rate.
+  void setDecayRate( StkFloat rate );
+
+  //! Set the sustain level.
+  void setSustainLevel( StkFloat level );
+
+  //! Set the release rate.
+  void setReleaseRate( StkFloat rate );
+
+  //! Set the attack rate based on a time duration.
+  void setAttackTime( StkFloat time );
+
+  //! Set the decay rate based on a time duration.
+  void setDecayTime( StkFloat time );
+
+  //! Set the release rate based on a time duration.
+  void setReleaseTime( StkFloat time );
+
+  //! Set sustain level and attack, decay, and release time durations.
+  void setAllTimes( StkFloat aTime, StkFloat dTime, StkFloat sLevel, StkFloat rTime );
+
+  //! Set the target value.
+  void setTarget( StkFloat target );
+
+  //! Return the current envelope \e state (ATTACK, DECAY, SUSTAIN, RELEASE, DONE).
+  int getState( void ) const { return state_; };
+
+  //! Set to state = ADSR::SUSTAIN with current and target values of \e value.
+  void setValue( StkFloat value );
+
+  //! Return the last computed output value.
+  StkFloat lastOut( void ) const { return lastFrame_[0]; };
+
+  //! Compute and return one output sample.
+  StkFloat tick( void );
+
+  //! Fill a channel of the StkFrames object with computed outputs.
+  /*!
+    The \c channel argument must be less than the number of
+    channels in the StkFrames argument (the first channel is specified
+    by 0).  However, range checking is only performed if _STK_DEBUG_
+    is defined during compilation, in which case an out-of-range value
+    will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
+
+ protected:  
+
+  void sampleRateChanged( StkFloat newRate, StkFloat oldRate );
+
+  int state_;
+  StkFloat value_;
+  StkFloat target_;
+  StkFloat attackRate_;
+  StkFloat decayRate_;
+  StkFloat releaseRate_;
+  StkFloat sustainLevel_;
+};
+
+inline StkFloat ADSR :: tick( void )
+{
+  switch ( state_ ) {
+
+  case ATTACK:
+    value_ += attackRate_;
+    if ( value_ >= target_ ) {
+      value_ = target_;
+      target_ = sustainLevel_;
+           state_ = DECAY;
+    }
+    lastFrame_[0] = value_;
+    break;
+
+  case DECAY:
+    value_ -= decayRate_;
+    if ( value_ <= sustainLevel_ ) {
+      value_ = sustainLevel_;
+      state_ = SUSTAIN;
+    }
+    lastFrame_[0] = value_;
+    break;
+
+  case RELEASE:
+    value_ -= releaseRate_;
+    if ( value_ <= 0.0 ) {
+      value_ = (StkFloat) 0.0;
+      state_ = DONE;
+    }
+    lastFrame_[0] = value_;
+
+  }
+
+  return value_;
+}
+
+inline StkFrames& ADSR :: tick( StkFrames& frames, unsigned int channel )
+{
+#if defined(_STK_DEBUG_)
+  if ( channel >= frames.channels() ) {
+    errorString_ << "ADSR::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *samples = &frames[channel];
+  unsigned int hop = frames.channels();
+  for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
+    *samples = ADSR::tick();
+
+  return frames;
+}
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/Asymp.h b/lib/MoMu-STK-1.0.0/include/Asymp.h
new file mode 100644 (file)
index 0000000..648f2b6
--- /dev/null
@@ -0,0 +1,143 @@
+#ifndef STK_ASYMP_H
+#define STK_ASYMP_H
+
+#include "Generator.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class Asymp
+    \brief STK asymptotic curve envelope class
+
+    This class implements a simple envelope generator
+    which asymptotically approaches a target value.
+    The algorithm used is of the form:
+
+    y[n] = a y[n-1] + (1-a) target,
+
+    where a = exp(-T/tau), T is the sample period, and
+    tau is a time constant.  The user can set the time
+    constant (default value = 0.3) and target value.
+    Theoretically, this recursion never reaches its
+    target, though the calculations in this class are
+    stopped when the current value gets within a small
+    threshold value of the target (at which time the
+    current value is set to the target).  It responds
+    to \e keyOn and \e keyOff messages by ramping to
+    1.0 on keyOn and to 0.0 on keyOff.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+const StkFloat TARGET_THRESHOLD = 0.000001;
+
+class Asymp : public Generator
+{
+ public:
+
+  //! Default constructor.
+  Asymp( void );
+
+  //! Class destructor.
+  ~Asymp( void );
+
+  //! Set target = 1.
+  void keyOn( void );
+
+  //! Set target = 0.
+  void keyOff( void );
+
+  //! Set the asymptotic rate via the time factor \e tau (must be > 0).
+  /*!
+    The rate is computed as described above.  The value of \e tau
+    must be greater than zero.  Values of \e tau close to zero produce
+    fast approach rates, while values greater than 1.0 produce rather
+    slow rates.
+  */
+  void setTau( StkFloat tau );
+
+  //! Set the asymptotic rate based on a time duration (must be > 0).
+  void setTime( StkFloat time );
+
+  //! Set the target value.
+  void setTarget( StkFloat target );
+
+  //! Set current and target values to \e value.
+  void setValue( StkFloat value );
+
+  //! Return the current envelope \e state (0 = at target, 1 otherwise).
+  int getState( void ) const { return state_; };
+
+  //! Return the last computed output value.
+  StkFloat lastOut( void ) const { return lastFrame_[0]; };
+
+  //! Compute and return one output sample.
+  StkFloat tick( void );
+
+  //! Fill a channel of the StkFrames object with computed outputs.
+  /*!
+    The \c channel argument must be less than the number of
+    channels in the StkFrames argument (the first channel is specified
+    by 0).  However, range checking is only performed if _STK_DEBUG_
+    is defined during compilation, in which case an out-of-range value
+    will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
+
+ protected:
+
+  void sampleRateChanged( StkFloat newRate, StkFloat oldRate );
+
+  StkFloat value_;
+  StkFloat target_;
+  StkFloat factor_;
+  StkFloat constant_;
+  int state_;
+};
+
+inline StkFloat Asymp :: tick( void )
+{
+  if ( state_ ) {
+
+    value_ = factor_ * value_ + constant_;
+
+    // Check threshold.
+    if ( target_ > value_ ) {
+      if ( target_ - value_ <= TARGET_THRESHOLD ) {
+        value_ = target_;
+        state_ = 0;
+      }
+    }
+    else {
+      if ( value_ - target_ <= TARGET_THRESHOLD ) {
+        value_ = target_;
+        state_ = 0;
+      }
+    }
+    lastFrame_[0] = value_;
+  }
+
+  return value_;
+}
+
+inline StkFrames& Asymp :: tick( StkFrames& frames, unsigned int channel )
+{
+#if defined(_STK_DEBUG_)
+  if ( channel >= frames.channels() ) {
+    errorString_ << "Asymp::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *samples = &frames[channel];
+  unsigned int hop = frames.channels();
+  for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
+    *samples = Asymp::tick();
+
+  return frames;
+}
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/BandedWG.h b/lib/MoMu-STK-1.0.0/include/BandedWG.h
new file mode 100644 (file)
index 0000000..503863d
--- /dev/null
@@ -0,0 +1,116 @@
+#ifndef STK_BANDEDWG_H
+#define STK_BANDEDWG_H
+
+#include "Instrmnt.h"
+#include "DelayL.h"
+#include "BowTable.h"
+#include "ADSR.h"
+#include "BiQuad.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class BandedWG
+    \brief Banded waveguide modeling class.
+
+    This class uses banded waveguide techniques to
+    model a variety of sounds, including bowed
+    bars, glasses, and bowls.  For more
+    information, see Essl, G. and Cook, P. "Banded
+    Waveguides: Towards Physical Modelling of Bar
+    Percussion Instruments", Proceedings of the
+    1999 International Computer Music Conference.
+
+    Control Change Numbers: 
+       - Bow Pressure = 2
+       - Bow Motion = 4
+       - Strike Position = 8 (not implemented)
+       - Vibrato Frequency = 11
+       - Gain = 1
+       - Bow Velocity = 128
+       - Set Striking = 64
+       - Instrument Presets = 16
+         - Uniform Bar = 0
+         - Tuned Bar = 1
+         - Glass Harmonica = 2
+         - Tibetan Bowl = 3
+
+    by Georg Essl, 1999 - 2004.
+    Modified for STK 4.0 by Gary Scavone.
+*/
+/***************************************************/
+
+const int MAX_BANDED_MODES = 20;
+
+class BandedWG : public Instrmnt
+{
+ public:
+  //! Class constructor.
+  BandedWG( void );
+
+  //! Class destructor.
+  ~BandedWG( void );
+
+  //! Reset and clear all internal state.
+  void clear( void );
+
+  //! Set strike position (0.0 - 1.0).
+  void setStrikePosition( StkFloat position );
+
+  //! Select a preset.
+  void setPreset( int preset );
+
+  //! Set instrument parameters for a particular frequency.
+  void setFrequency( StkFloat frequency );
+
+  //! Apply bow velocity/pressure to instrument with given amplitude and rate of increase.
+  void startBowing( StkFloat amplitude, StkFloat rate );
+
+  //! Decrease bow velocity/breath pressure with given rate of decrease.
+  void stopBowing( StkFloat rate );
+
+  //! Pluck the instrument with given amplitude.
+  void pluck( StkFloat amp );
+
+  //! Start a note with the given frequency and amplitude.
+  void noteOn( StkFloat frequency, StkFloat amplitude );
+
+  //! Stop a note with the given amplitude (speed of decay).
+  void noteOff( StkFloat amplitude );
+
+  //! Perform the control change specified by \e number and \e value (0.0 - 128.0).
+  void controlChange( int number, StkFloat value );
+
+  //! Compute and return one output sample.
+  StkFloat tick( unsigned int channel = 0 );
+
+ protected:
+
+  bool doPluck_;
+  bool trackVelocity_;
+  int nModes_;
+  int presetModes_;
+  BowTable bowTable_;
+  ADSR     adsr_;
+  BiQuad   bandpass_[MAX_BANDED_MODES];
+  DelayL   delay_[MAX_BANDED_MODES];
+  StkFloat maxVelocity_;
+  StkFloat modes_[MAX_BANDED_MODES];
+  StkFloat frequency_;
+  StkFloat baseGain_;
+  StkFloat gains_[MAX_BANDED_MODES];
+  StkFloat basegains_[MAX_BANDED_MODES];
+  StkFloat excitation_[MAX_BANDED_MODES];
+  StkFloat integrationConstant_;
+  StkFloat velocityInput_;
+  StkFloat bowVelocity_;
+  StkFloat bowTarget_;
+  StkFloat bowPosition_;
+  StkFloat strikeAmp_;
+  int strikePosition_;
+
+};
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/BeeThree.h b/lib/MoMu-STK-1.0.0/include/BeeThree.h
new file mode 100644 (file)
index 0000000..8fa9e37
--- /dev/null
@@ -0,0 +1,90 @@
+#ifndef STK_BEETHREE_H
+#define STK_BEETHREE_H
+
+#include "FM.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class BeeThree
+    \brief STK Hammond-oid organ FM synthesis instrument.
+
+    This class implements a simple 4 operator
+    topology, also referred to as algorithm 8 of
+    the TX81Z.
+
+    \code
+    Algorithm 8 is :
+                     1 --.
+                     2 -\|
+                         +-> Out
+                     3 -/|
+                     4 --
+    \endcode
+
+    Control Change Numbers: 
+       - Operator 4 (feedback) Gain = 2
+       - Operator 3 Gain = 4
+       - LFO Speed = 11
+       - LFO Depth = 1
+       - ADSR 2 & 4 Target = 128
+
+    The basic Chowning/Stanford FM patent expired
+    in 1995, but there exist follow-on patents,
+    mostly assigned to Yamaha.  If you are of the
+    type who should worry about this (making
+    money) worry away.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class BeeThree : public FM
+{
+ public:
+  //! Class constructor.
+  /*!
+    An StkError will be thrown if the rawwave path is incorrectly set.
+  */
+  BeeThree( void );
+
+  //! Class destructor.
+  ~BeeThree( void );
+
+  //! Start a note with the given frequency and amplitude.
+  void noteOn( StkFloat frequency, StkFloat amplitude );
+
+  //! Compute and return one output sample.
+  StkFloat tick( unsigned int channel = 0 );
+
+ protected:
+
+};
+
+inline StkFloat BeeThree :: tick( unsigned int )
+{
+  register StkFloat temp;
+
+  if ( modDepth_ > 0.0 )       {
+    temp = 1.0 + ( modDepth_ * vibrato_.tick() * 0.1 );
+    waves_[0]->setFrequency( baseFrequency_ * temp * ratios_[0] );
+    waves_[1]->setFrequency( baseFrequency_ * temp * ratios_[1] );
+    waves_[2]->setFrequency( baseFrequency_ * temp * ratios_[2] );
+    waves_[3]->setFrequency( baseFrequency_ * temp * ratios_[3] );
+  }
+
+  waves_[3]->addPhaseOffset( twozero_.lastOut() );
+  temp = control1_ * 2.0 * gains_[3] * adsr_[3]->tick() * waves_[3]->tick();
+  twozero_.tick( temp );
+
+  temp += control2_ * 2.0 * gains_[2] * adsr_[2]->tick() * waves_[2]->tick();
+  temp += gains_[1] * adsr_[1]->tick() * waves_[1]->tick();
+  temp += gains_[0] * adsr_[0]->tick() * waves_[0]->tick();
+
+  lastFrame_[0] = temp * 0.125;
+  return lastFrame_[0];
+}
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/BiQuad.h b/lib/MoMu-STK-1.0.0/include/BiQuad.h
new file mode 100644 (file)
index 0000000..19cf61c
--- /dev/null
@@ -0,0 +1,183 @@
+#ifndef STK_BIQUAD_H
+#define STK_BIQUAD_H
+
+#include "Filter.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class BiQuad
+    \brief STK biquad (two-pole, two-zero) filter class.
+
+    This class implements a two-pole, two-zero digital filter.
+    Methods are provided for creating a resonance or notch in the
+    frequency response while maintaining a constant filter gain.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class BiQuad : public Filter
+{
+public:
+
+  //! Default constructor creates a second-order pass-through filter.
+  BiQuad();
+
+  //! Class destructor.
+  ~BiQuad();
+
+  //! A function to enable/disable the automatic updating of class data when the STK sample rate changes.
+  void ignoreSampleRateChange( bool ignore = true ) { ignoreSampleRateChange_ = ignore; };
+
+  //! Set all filter coefficients.
+  void setCoefficients( StkFloat b0, StkFloat b1, StkFloat b2, StkFloat a1, StkFloat a2, bool clearState = false );
+
+  //! Set the b[0] coefficient value.
+  void setB0( StkFloat b0 ) { b_[0] = b0; };
+
+  //! Set the b[1] coefficient value.
+  void setB1( StkFloat b1 ) { b_[1] = b1; };
+
+  //! Set the b[2] coefficient value.
+  void setB2( StkFloat b2 ) { b_[2] = b2; };
+
+  //! Set the a[1] coefficient value.
+  void setA1( StkFloat a1 ) { a_[1] = a1; };
+
+  //! Set the a[2] coefficient value.
+  void setA2( StkFloat a2 ) { a_[2] = a2; };
+
+  //! Sets the filter coefficients for a resonance at \e frequency (in Hz).
+  /*!
+    This method determines the filter coefficients corresponding to
+    two complex-conjugate poles with the given \e frequency (in Hz)
+    and \e radius from the z-plane origin.  If \e normalize is true,
+    the filter zeros are placed at z = 1, z = -1, and the coefficients
+    are then normalized to produce a constant unity peak gain
+    (independent of the filter \e gain parameter).  The resulting
+    filter frequency response has a resonance at the given \e
+    frequency.  The closer the poles are to the unit-circle (\e radius
+    close to one), the narrower the resulting resonance width.
+  */
+  void setResonance( StkFloat frequency, StkFloat radius, bool normalize = false );
+
+  //! Set the filter coefficients for a notch at \e frequency (in Hz).
+  /*!
+    This method determines the filter coefficients corresponding to
+    two complex-conjugate zeros with the given \e frequency (in Hz)
+    and \e radius from the z-plane origin.  No filter normalization
+    is attempted.
+  */
+  void setNotch( StkFloat frequency, StkFloat radius );
+
+  //! Sets the filter zeroes for equal resonance gain.
+  /*!
+    When using the filter as a resonator, zeroes places at z = 1, z
+    = -1 will result in a constant gain at resonance of 1 / (1 - R),
+    where R is the pole radius setting.
+
+  */
+  void setEqualGainZeroes( void );
+
+  //! Return the last computed output value.
+  StkFloat lastOut( void ) const { return lastFrame_[0]; };
+
+  //! Input one sample to the filter and return a reference to one output.
+  StkFloat tick( StkFloat input );
+
+  //! Take a channel of the StkFrames object as inputs to the filter and replace with corresponding outputs.
+  /*!
+    The StkFrames argument reference is returned.  The \c channel
+    argument must be less than the number of channels in the
+    StkFrames argument (the first channel is specified by 0).
+    However, range checking is only performed if _STK_DEBUG_ is
+    defined during compilation, in which case an out-of-range value
+    will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
+
+  //! Take a channel of the \c iFrames object as inputs to the filter and write outputs to the \c oFrames object.
+  /*!
+    The \c iFrames object reference is returned.  Each channel
+    argument must be less than the number of channels in the
+    corresponding StkFrames argument (the first channel is specified
+    by 0).  However, range checking is only performed if _STK_DEBUG_
+    is defined during compilation, in which case an out-of-range value
+    will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0, unsigned int oChannel = 0 );
+
+ protected:
+
+  virtual void sampleRateChanged( StkFloat newRate, StkFloat oldRate );
+};
+
+inline StkFloat BiQuad :: tick( StkFloat input )
+{
+  inputs_[0] = gain_ * input;
+  lastFrame_[0] = b_[0] * inputs_[0] + b_[1] * inputs_[1] + b_[2] * inputs_[2];
+  lastFrame_[0] -= a_[2] * outputs_[2] + a_[1] * outputs_[1];
+  inputs_[2] = inputs_[1];
+  inputs_[1] = inputs_[0];
+  outputs_[2] = outputs_[1];
+  outputs_[1] = lastFrame_[0];
+
+  return lastFrame_[0];
+}
+
+inline StkFrames& BiQuad :: tick( StkFrames& frames, unsigned int channel )
+{
+#if defined(_STK_DEBUG_)
+  if ( channel >= frames.channels() ) {
+    errorString_ << "BiQuad::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *samples = &frames[channel];
+  unsigned int hop = frames.channels();
+  for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
+    inputs_[0] = gain_ * *samples;
+    *samples = b_[0] * inputs_[0] + b_[1] * inputs_[1] + b_[2] * inputs_[2];
+    *samples -= a_[2] * outputs_[2] + a_[1] * outputs_[1];
+    inputs_[2] = inputs_[1];
+    inputs_[1] = inputs_[0];
+    outputs_[2] = outputs_[1];
+    outputs_[1] = *samples;
+  }
+
+  lastFrame_[0] = outputs_[1];
+  return frames;
+}
+
+inline StkFrames& BiQuad :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iChannel, unsigned int oChannel )
+{
+#if defined(_STK_DEBUG_)
+  if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
+    errorString_ << "BiQuad::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *iSamples = &iFrames[iChannel];
+  StkFloat *oSamples = &oFrames[oChannel];
+  unsigned int iHop = iFrames.channels(), oHop = oFrames.channels();
+  for ( unsigned int i=0; i<iFrames.frames(); i++, iSamples += iHop, oSamples += oHop ) {
+    inputs_[0] = gain_ * *iSamples;
+    *oSamples = b_[0] * inputs_[0] + b_[1] * inputs_[1] + b_[2] * inputs_[2];
+    *oSamples -= a_[2] * outputs_[2] + a_[1] * outputs_[1];
+    inputs_[2] = inputs_[1];
+    inputs_[1] = inputs_[0];
+    outputs_[2] = outputs_[1];
+    outputs_[1] = *oSamples;
+  }
+
+  lastFrame_[0] = outputs_[1];
+  return iFrames;
+}
+
+} // stk namespace
+
+#endif
+
diff --git a/lib/MoMu-STK-1.0.0/include/Blit.h b/lib/MoMu-STK-1.0.0/include/Blit.h
new file mode 100644 (file)
index 0000000..ab9ac96
--- /dev/null
@@ -0,0 +1,151 @@
+#ifndef STK_BLIT_H
+#define STK_BLIT_H
+
+#include "Generator.h"
+#include <cmath>
+#include <limits>
+
+namespace stk {
+
+/***************************************************/
+/*! \class Blit
+    \brief STK band-limited impulse train class.
+
+    This class generates a band-limited impulse train using a
+    closed-form algorithm reported by Stilson and Smith in "Alias-Free
+    Digital Synthesis of Classic Analog Waveforms", 1996.  The user
+    can specify both the fundamental frequency of the impulse train
+    and the number of harmonics contained in the resulting signal.
+
+    The signal is normalized so that the peak value is +/-1.0.
+
+    If nHarmonics is 0, then the signal will contain all harmonics up
+    to half the sample rate.  Note, however, that this setting may
+    produce aliasing in the signal when the frequency is changing (no
+    automatic modification of the number of harmonics is performed by
+    the setFrequency() function).
+
+    Original code by Robin Davies, 2005.
+    Revisions by Gary Scavone for STK, 2005.
+*/
+/***************************************************/
+
+class Blit: public Generator
+{
+ public:
+  //! Default constructor that initializes BLIT frequency to 220 Hz.
+  Blit( StkFloat frequency = 220.0 );
+
+  //! Class destructor.
+  ~Blit();
+
+  //! Resets the oscillator state and phase to 0.
+  void reset();
+
+  //! Set the phase of the signal.
+  /*!
+    Set the phase of the signal, in the range 0 to 1.
+  */
+  void setPhase( StkFloat phase ) { phase_ = PI * phase; };
+
+  //! Get the current phase of the signal.
+  /*!
+    Get the phase of the signal, in the range [0 to 1.0).
+  */
+  StkFloat getPhase() const { return phase_ / PI; };
+
+  //! Set the impulse train rate in terms of a frequency in Hz.
+  void setFrequency( StkFloat frequency );
+
+  //! Set the number of harmonics generated in the signal.
+  /*!
+    This function sets the number of harmonics contained in the
+    resulting signal.  It is equivalent to (2 * M) + 1 in the BLIT
+    algorithm.  The default value of 0 sets the algorithm for maximum
+    harmonic content (harmonics up to half the sample rate).  This
+    parameter is not checked against the current sample rate and
+    fundamental frequency.  Thus, aliasing can result if one or more
+    harmonics for a given fundamental frequency exceeds fs / 2.  This
+    behavior was chosen over the potentially more problematic solution
+    of automatically modifying the M parameter, which can produce
+    audible clicks in the signal.
+  */
+  void setHarmonics( unsigned int nHarmonics = 0 );
+
+  //! Return the last computed output value.
+  StkFloat lastOut( void ) const { return lastFrame_[0]; };
+
+  //! Compute and return one output sample.
+  StkFloat tick( void );
+
+  //! Fill a channel of the StkFrames object with computed outputs.
+  /*!
+    The \c channel argument must be less than the number of
+    channels in the StkFrames argument (the first channel is specified
+    by 0).  However, range checking is only performed if _STK_DEBUG_
+    is defined during compilation, in which case an out-of-range value
+    will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
+
+ protected:
+
+  void updateHarmonics( void );
+
+  unsigned int nHarmonics_;
+  unsigned int m_;
+  StkFloat rate_;
+  StkFloat phase_;
+  StkFloat p_;
+
+};
+
+inline StkFloat Blit :: tick( void )
+{
+  // The code below implements the SincM algorithm of Stilson and
+  // Smith with an additional scale factor of P / M applied to
+  // normalize the output.
+
+  // A fully optimized version of this code would replace the two sin
+  // calls with a pair of fast sin oscillators, for which stable fast
+  // two-multiply algorithms are well known. In the spirit of STK,
+  // which favors clarity over performance, the optimization has not
+  // been made here.
+
+  // Avoid a divide by zero at the sinc peak, which has a limiting
+  // value of 1.0.
+  StkFloat tmp, denominator = sin( phase_ );
+  if ( denominator <= std::numeric_limits<StkFloat>::epsilon() )
+    tmp = 1.0;
+  else {
+    tmp =  sin( m_ * phase_ );
+    tmp /= m_ * denominator;
+  }
+
+  phase_ += rate_;
+  if ( phase_ >= PI ) phase_ -= PI;
+
+  lastFrame_[0] = tmp;
+       return lastFrame_[0];
+}
+
+inline StkFrames& Blit :: tick( StkFrames& frames, unsigned int channel )
+{
+#if defined(_STK_DEBUG_)
+  if ( channel >= frames.channels() ) {
+    errorString_ << "Blit::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *samples = &frames[channel];
+  unsigned int hop = frames.channels();
+  for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
+    *samples = Blit::tick();
+
+  return frames;
+}
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/BlitSaw.h b/lib/MoMu-STK-1.0.0/include/BlitSaw.h
new file mode 100644 (file)
index 0000000..26a1582
--- /dev/null
@@ -0,0 +1,148 @@
+#ifndef STK_BLITSAW_H
+#define STK_BLITSAW_H
+
+#include "Generator.h"
+#include <cmath>
+#include <limits>
+
+namespace stk {
+
+/***************************************************/
+/*! \class BlitSaw
+    \brief STK band-limited sawtooth wave class.
+
+    This class generates a band-limited sawtooth waveform using a
+    closed-form algorithm reported by Stilson and Smith in "Alias-Free
+    Digital Synthesis of Classic Analog Waveforms", 1996.  The user
+    can specify both the fundamental frequency of the sawtooth and the
+    number of harmonics contained in the resulting signal.
+
+    If nHarmonics is 0, then the signal will contain all harmonics up
+    to half the sample rate.  Note, however, that this setting may
+    produce aliasing in the signal when the frequency is changing (no
+    automatic modification of the number of harmonics is performed by
+    the setFrequency() function).
+
+    Based on initial code of Robin Davies, 2005.
+    Modified algorithm code by Gary Scavone, 2005.
+*/
+/***************************************************/
+
+class BlitSaw: public Generator
+{
+ public:
+  //! Class constructor.
+  BlitSaw( StkFloat frequency = 220.0 );
+
+  //! Class destructor.
+  ~BlitSaw();
+
+  //! Resets the oscillator state and phase to 0.
+  void reset();
+
+  //! Set the sawtooth oscillator rate in terms of a frequency in Hz.
+  void setFrequency( StkFloat frequency );
+
+  //! Set the number of harmonics generated in the signal.
+  /*!
+    This function sets the number of harmonics contained in the
+    resulting signal.  It is equivalent to (2 * M) + 1 in the BLIT
+    algorithm.  The default value of 0 sets the algorithm for maximum
+    harmonic content (harmonics up to half the sample rate).  This
+    parameter is not checked against the current sample rate and
+    fundamental frequency.  Thus, aliasing can result if one or more
+    harmonics for a given fundamental frequency exceeds fs / 2.  This
+    behavior was chosen over the potentially more problematic solution
+    of automatically modifying the M parameter, which can produce
+    audible clicks in the signal.
+  */
+  void setHarmonics( unsigned int nHarmonics = 0 );
+
+  //! Return the last computed output value.
+  StkFloat lastOut( void ) const { return lastFrame_[0]; };
+
+  //! Compute and return one output sample.
+  StkFloat tick( void );
+
+  //! Fill a channel of the StkFrames object with computed outputs.
+  /*!
+    The \c channel argument must be less than the number of
+    channels in the StkFrames argument (the first channel is specified
+    by 0).  However, range checking is only performed if _STK_DEBUG_
+    is defined during compilation, in which case an out-of-range value
+    will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
+
+ protected:
+
+  void updateHarmonics( void );
+
+  unsigned int nHarmonics_;
+  unsigned int m_;
+  StkFloat rate_;
+  StkFloat phase_;
+  StkFloat p_;
+  StkFloat C2_;
+  StkFloat a_;
+  StkFloat state_;
+
+};
+
+inline StkFloat BlitSaw :: tick( void )
+{
+  // The code below implements the BLIT algorithm of Stilson and
+  // Smith, followed by a summation and filtering operation to produce
+  // a sawtooth waveform.  After experimenting with various approaches
+  // to calculate the average value of the BLIT over one period, I
+  // found that an estimate of C2_ = 1.0 / period (in samples) worked
+  // most consistently.  A "leaky integrator" is then applied to the
+  // difference of the BLIT output and C2_. (GPS - 1 October 2005)
+
+  // A fully  optimized version of this code would replace the two sin 
+  // calls with a pair of fast sin oscillators, for which stable fast 
+  // two-multiply algorithms are well known. In the spirit of STK,
+  // which favors clarity over performance, the optimization has 
+  // not been made here.
+
+  // Avoid a divide by zero, or use of a denormalized divisor 
+  // at the sinc peak, which has a limiting value of m_ / p_.
+  StkFloat tmp, denominator = sin( phase_ );
+  if ( fabs(denominator) <= std::numeric_limits<StkFloat>::epsilon() )
+    tmp = a_;
+  else {
+    tmp =  sin( m_ * phase_ );
+    tmp /= p_ * denominator;
+  }
+
+  tmp += state_ - C2_;
+  state_ = tmp * 0.995;
+
+  phase_ += rate_;
+  if ( phase_ >= PI ) phase_ -= PI;
+    
+  lastFrame_[0] = tmp;
+       return lastFrame_[0];
+}
+
+inline StkFrames& BlitSaw :: tick( StkFrames& frames, unsigned int channel )
+{
+#if defined(_STK_DEBUG_)
+  if ( channel >= frames.channels() ) {
+    errorString_ << "BlitSaw::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+
+  StkFloat *samples = &frames[channel];
+  unsigned int hop = frames.channels();
+  for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
+    *samples = BlitSaw::tick();
+
+  return frames;
+}
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/BlitSquare.h b/lib/MoMu-STK-1.0.0/include/BlitSquare.h
new file mode 100644 (file)
index 0000000..ab21de1
--- /dev/null
@@ -0,0 +1,170 @@
+#ifndef STK_BLITSQUARE_H
+#define STK_BLITSQUARE_H
+
+#include "Generator.h"
+#include <cmath>
+#include <limits>
+
+namespace stk {
+
+/***************************************************/
+/*! \class BlitSquare
+    \brief STK band-limited square wave class.
+
+    This class generates a band-limited square wave signal.  It is
+    derived in part from the approach reported by Stilson and Smith in
+    "Alias-Free Digital Synthesis of Classic Analog Waveforms", 1996.
+    The algorithm implemented in this class uses a SincM function with
+    an even M value to achieve a bipolar bandlimited impulse train.
+    This signal is then integrated to achieve a square waveform.  The
+    integration process has an associated DC offset so a DC blocking
+    filter is applied at the output.
+
+    The user can specify both the fundamental frequency of the
+    waveform and the number of harmonics contained in the resulting
+    signal.
+
+    If nHarmonics is 0, then the signal will contain all harmonics up
+    to half the sample rate.  Note, however, that this setting may
+    produce aliasing in the signal when the frequency is changing (no
+    automatic modification of the number of harmonics is performed by
+    the setFrequency() function).  Also note that the harmonics of a
+    square wave fall at odd integer multiples of the fundamental, so
+    aliasing will happen with a lower fundamental than with the other
+    Blit waveforms.  This class is not guaranteed to be well behaved
+    in the presence of significant aliasing.
+
+    Based on initial code of Robin Davies, 2005.
+    Modified algorithm code by Gary Scavone, 2005 - 2006.
+*/
+/***************************************************/
+
+class BlitSquare: public Generator
+{
+ public:
+  //! Default constructor that initializes BLIT frequency to 220 Hz.
+  BlitSquare( StkFloat frequency = 220.0 );
+
+  //! Class destructor.
+  ~BlitSquare();
+
+  //! Resets the oscillator state and phase to 0.
+  void reset();
+
+  //! Set the phase of the signal.
+  /*!
+    Set the phase of the signal, in the range 0 to 1.
+  */
+  void setPhase( StkFloat phase ) { phase_ = PI * phase; };
+
+  //! Get the current phase of the signal.
+  /*!
+    Get the phase of the signal, in the range [0 to 1.0).
+  */
+  StkFloat getPhase() const { return phase_ / PI; };
+
+  //! Set the impulse train rate in terms of a frequency in Hz.
+  void setFrequency( StkFloat frequency );
+
+  //! Set the number of harmonics generated in the signal.
+  /*!
+    This function sets the number of harmonics contained in the
+    resulting signal.  It is equivalent to (2 * M) + 1 in the BLIT
+    algorithm.  The default value of 0 sets the algorithm for maximum
+    harmonic content (harmonics up to half the sample rate).  This
+    parameter is not checked against the current sample rate and
+    fundamental frequency.  Thus, aliasing can result if one or more
+    harmonics for a given fundamental frequency exceeds fs / 2.  This
+    behavior was chosen over the potentially more problematic solution
+    of automatically modifying the M parameter, which can produce
+    audible clicks in the signal.
+  */
+  void setHarmonics( unsigned int nHarmonics = 0 );
+
+  //! Return the last computed output value.
+  StkFloat lastOut( void ) const { return lastFrame_[0]; };
+
+  //! Compute and return one output sample.
+  StkFloat tick( void );
+
+  //! Fill a channel of the StkFrames object with computed outputs.
+  /*!
+    The \c channel argument must be less than the number of
+    channels in the StkFrames argument (the first channel is specified
+    by 0).  However, range checking is only performed if _STK_DEBUG_
+    is defined during compilation, in which case an out-of-range value
+    will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
+
+ protected:
+
+  void updateHarmonics( void );
+
+  unsigned int nHarmonics_;
+  unsigned int m_;
+  StkFloat rate_;
+  StkFloat phase_;
+  StkFloat p_;
+  StkFloat a_;
+  StkFloat lastBlitOutput_;
+  StkFloat dcbState_;
+};
+
+inline StkFloat BlitSquare :: tick( void )
+{
+  StkFloat temp = lastBlitOutput_;
+
+  // A fully  optimized version of this would replace the two sin calls
+  // with a pair of fast sin oscillators, for which stable fast 
+  // two-multiply algorithms are well known. In the spirit of STK,
+  // which favors clarity over performance, the optimization has 
+  // not been made here.
+
+  // Avoid a divide by zero, or use of a denomralized divisor
+  // at the sinc peak, which has a limiting value of 1.0.
+  StkFloat denominator = sin( phase_ );
+  if ( fabs( denominator )  < std::numeric_limits<StkFloat>::epsilon() ) {
+    // Inexact comparison safely distinguishes betwen *close to zero*, and *close to PI*.
+    if ( phase_ < 0.1f || phase_ > TWO_PI - 0.1f )
+      lastBlitOutput_ = a_;
+    else
+      lastBlitOutput_ = -a_;
+  }
+  else {
+    lastBlitOutput_ =  sin( m_ * phase_ );
+    lastBlitOutput_ /= p_ * denominator;
+  }
+
+  lastBlitOutput_ += temp;
+
+  // Now apply DC blocker.
+  lastFrame_[0] = lastBlitOutput_ - dcbState_ + 0.999 * lastFrame_[0];
+  dcbState_ = lastBlitOutput_;
+
+  phase_ += rate_;
+  if ( phase_ >= TWO_PI ) phase_ -= TWO_PI;
+
+       return lastFrame_[0];
+}
+
+inline StkFrames& BlitSquare :: tick( StkFrames& frames, unsigned int channel )
+{
+#if defined(_STK_DEBUG_)
+  if ( channel >= frames.channels() ) {
+    errorString_ << "BlitSquare::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *samples = &frames[channel];
+  unsigned int hop = frames.channels();
+  for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
+    *samples = BlitSquare::tick();
+
+  return frames;
+}
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/BlowBotl.h b/lib/MoMu-STK-1.0.0/include/BlowBotl.h
new file mode 100644 (file)
index 0000000..237a695
--- /dev/null
@@ -0,0 +1,107 @@
+#ifndef STK_BLOWBOTL_H
+#define STK_BLOWBOTL_H
+
+#include "Instrmnt.h"
+#include "JetTable.h"
+#include "BiQuad.h"
+#include "PoleZero.h"
+#include "Noise.h"
+#include "ADSR.h"
+#include "SineWave.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class BlowBotl
+    \brief STK blown bottle instrument class.
+
+    This class implements a helmholtz resonator
+    (biquad filter) with a polynomial jet
+    excitation (a la Cook).
+
+    Control Change Numbers: 
+       - Noise Gain = 4
+       - Vibrato Frequency = 11
+       - Vibrato Gain = 1
+       - Volume = 128
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class BlowBotl : public Instrmnt
+{
+ public:
+  //! Class constructor.
+  /*!
+    An StkError will be thrown if the rawwave path is incorrectly set.
+  */
+  BlowBotl( void );
+
+  //! Class destructor.
+  ~BlowBotl( void );
+
+  //! Reset and clear all internal state.
+  void clear( void );
+
+  //! Set instrument parameters for a particular frequency.
+  void setFrequency( StkFloat frequency );
+
+  //! Apply breath velocity to instrument with given amplitude and rate of increase.
+  void startBlowing( StkFloat amplitude, StkFloat rate );
+
+  //! Decrease breath velocity with given rate of decrease.
+  void stopBlowing( StkFloat rate );
+
+  //! Start a note with the given frequency and amplitude.
+  void noteOn( StkFloat frequency, StkFloat amplitude );
+
+  //! Stop a note with the given amplitude (speed of decay).
+  void noteOff( StkFloat amplitude );
+
+  //! Perform the control change specified by \e number and \e value (0.0 - 128.0).
+  void controlChange( int number, StkFloat value );
+
+  //! Compute and return one output sample.
+  StkFloat tick( unsigned int channel = 0 );
+
+ protected:
+
+  JetTable jetTable_;
+  BiQuad resonator_;
+  PoleZero dcBlock_;
+  Noise noise_;
+  ADSR adsr_;
+  SineWave vibrato_;
+  StkFloat maxPressure_;
+  StkFloat noiseGain_;
+  StkFloat vibratoGain_;
+  StkFloat outputGain_;
+
+};
+
+inline StkFloat BlowBotl :: tick( unsigned int )
+{
+  StkFloat breathPressure;
+  StkFloat randPressure;
+  StkFloat pressureDiff;
+
+  // Calculate the breath pressure (envelope + vibrato)
+  breathPressure = maxPressure_ * adsr_.tick();
+  breathPressure += vibratoGain_ * vibrato_.tick();
+
+  pressureDiff = breathPressure - resonator_.lastOut();
+
+  randPressure = noiseGain_ * noise_.tick();
+  randPressure *= breathPressure;
+  randPressure *= (1.0 + pressureDiff);
+
+  resonator_.tick( breathPressure + randPressure - ( jetTable_.tick( pressureDiff ) * pressureDiff ) );
+  lastFrame_[0] = 0.2 * outputGain_ * dcBlock_.tick( pressureDiff );
+
+  return lastFrame_[0];
+}
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/BlowHole.h b/lib/MoMu-STK-1.0.0/include/BlowHole.h
new file mode 100644 (file)
index 0000000..53ac9be
--- /dev/null
@@ -0,0 +1,149 @@
+#ifndef STK_BLOWHOLE_H
+#define STK_BLOWHOLE_H
+
+#include "Instrmnt.h"
+#include "DelayL.h"
+#include "ReedTable.h"
+#include "OneZero.h"
+#include "PoleZero.h"
+#include "Envelope.h"
+#include "Noise.h"
+#include "SineWave.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class BlowHole
+    \brief STK clarinet physical model with one
+           register hole and one tonehole.
+
+    This class is based on the clarinet model,
+    with the addition of a two-port register hole
+    and a three-port dynamic tonehole
+    implementation, as discussed by Scavone and
+    Cook (1998).
+
+    In this implementation, the distances between
+    the reed/register hole and tonehole/bell are
+    fixed.  As a result, both the tonehole and
+    register hole will have variable influence on
+    the playing frequency, which is dependent on
+    the length of the air column.  In addition,
+    the highest playing freqeuency is limited by
+    these fixed lengths.
+
+    This is a digital waveguide model, making its
+    use possibly subject to patents held by Stanford
+    University, Yamaha, and others.
+
+    Control Change Numbers: 
+       - Reed Stiffness = 2
+       - Noise Gain = 4
+       - Tonehole State = 11
+       - Register State = 1
+       - Breath Pressure = 128
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class BlowHole : public Instrmnt
+{
+ public:
+  //! Class constructor.
+  /*!
+    An StkError will be thrown if the rawwave path is incorrectly set.
+  */
+  BlowHole( StkFloat lowestFrequency );
+
+  //! Class destructor.
+  ~BlowHole( void );
+
+  //! Reset and clear all internal state.
+  void clear( void );
+
+  //! Set instrument parameters for a particular frequency.
+  void setFrequency( StkFloat frequency );
+
+  //! Set the tonehole state (0.0 = closed, 1.0 = fully open).
+  void setTonehole( StkFloat newValue );
+
+  //! Set the register hole state (0.0 = closed, 1.0 = fully open).
+  void setVent( StkFloat newValue );
+
+  //! Apply breath pressure to instrument with given amplitude and rate of increase.
+  void startBlowing( StkFloat amplitude, StkFloat rate );
+
+  //! Decrease breath pressure with given rate of decrease.
+  void stopBlowing( StkFloat rate );
+
+  //! Start a note with the given frequency and amplitude.
+  void noteOn( StkFloat frequency, StkFloat amplitude );
+
+  //! Stop a note with the given amplitude (speed of decay).
+  void noteOff( StkFloat amplitude );
+
+  //! Perform the control change specified by \e number and \e value (0.0 - 128.0).
+  void controlChange( int number, StkFloat value );
+
+  //! Compute and return one output sample.
+  StkFloat tick( unsigned int channel = 0 );
+
+ protected:
+
+  DelayL    delays_[3];
+  ReedTable reedTable_;
+  OneZero   filter_;
+  PoleZero  tonehole_;
+  PoleZero  vent_;
+  Envelope  envelope_;
+  Noise     noise_;
+  SineWave vibrato_;
+  unsigned long length_;
+  StkFloat scatter_;
+  StkFloat thCoeff_;
+  StkFloat rhGain_;
+  StkFloat outputGain_;
+  StkFloat noiseGain_;
+  StkFloat vibratoGain_;
+
+};
+
+  inline StkFloat BlowHole :: tick( unsigned int )
+{
+  StkFloat pressureDiff;
+  StkFloat breathPressure;
+  StkFloat temp;
+
+  // Calculate the breath pressure (envelope + noise + vibrato)
+  breathPressure = envelope_.tick(); 
+  breathPressure += breathPressure * noiseGain_ * noise_.tick();
+  breathPressure += breathPressure * vibratoGain_ * vibrato_.tick();
+
+  // Calculate the differential pressure = reflected - mouthpiece pressures
+  pressureDiff = delays_[0].lastOut() - breathPressure;
+
+  // Do two-port junction scattering for register vent
+  StkFloat pa = breathPressure + pressureDiff * reedTable_.tick( pressureDiff );
+  StkFloat pb = delays_[1].lastOut();
+  vent_.tick( pa+pb );
+
+  lastFrame_[0] = delays_[0].tick( vent_.lastOut()+pb );
+  lastFrame_[0] *= outputGain_;
+
+  // Do three-port junction scattering (under tonehole)
+  pa += vent_.lastOut();
+  pb = delays_[2].lastOut();
+  StkFloat pth = tonehole_.lastOut();
+  temp = scatter_ * (pa + pb - 2 * pth);
+
+  delays_[2].tick( filter_.tick(pa + temp) * -0.95 );
+  delays_[1].tick( pb + temp );
+  tonehole_.tick( pa + pb - pth + temp );
+
+  return lastFrame_[0];
+}
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/BowTable.h b/lib/MoMu-STK-1.0.0/include/BowTable.h
new file mode 100644 (file)
index 0000000..316bfa7
--- /dev/null
@@ -0,0 +1,140 @@
+#ifndef STK_BOWTABL_H
+#define STK_BOWTABL_H
+
+#include "Function.h"
+#include <cmath>
+
+namespace stk {
+
+/***************************************************/
+/*! \class BowTable
+    \brief STK bowed string table class.
+
+    This class implements a simple bowed string
+    non-linear function, as described by Smith (1986).
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class BowTable : public Function
+{
+public:
+  //! Default constructor.
+  BowTable( void ) : offset_(0.0), slope_(0.1) {};
+
+  //! Set the table offset value.
+  /*!
+    The table offset is a bias which controls the
+    symmetry of the friction.  If you want the
+    friction to vary with direction, use a non-zero
+    value for the offset.  The default value is zero.
+  */
+  void setOffset( StkFloat offset ) { offset_ = offset; };
+
+  //! Set the table slope value.
+  /*!
+   The table slope controls the width of the friction
+   pulse, which is related to bow force.
+  */
+  void setSlope( StkFloat slope ) { slope_ = slope; };
+
+  //! Take one sample input and map to one sample of output.
+  StkFloat tick( StkFloat input );
+
+  //! Take a channel of the StkFrames object as inputs to the table and replace with corresponding outputs.
+  /*!
+    The StkFrames argument reference is returned.  The \c channel
+    argument must be less than the number of channels in the
+    StkFrames argument (the first channel is specified by 0).
+    However, range checking is only performed if _STK_DEBUG_ is
+    defined during compilation, in which case an out-of-range value
+    will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
+
+  //! Take a channel of the \c iFrames object as inputs to the table and write outputs to the \c oFrames object.
+  /*!
+    The \c iFrames object reference is returned.  Each channel
+    argument must be less than the number of channels in the
+    corresponding StkFrames argument (the first channel is specified
+    by 0).  However, range checking is only performed if _STK_DEBUG_
+    is defined during compilation, in which case an out-of-range value
+    will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0, unsigned int oChannel = 0 );
+
+protected:
+
+  StkFloat offset_;
+  StkFloat slope_;
+
+};
+
+inline StkFloat BowTable :: tick( StkFloat input )
+{
+  // The input represents differential string vs. bow velocity.
+  StkFloat sample  = input + offset_;  // add bias to input
+  sample *= slope_;          // then scale it
+  lastFrame_[0] = (StkFloat) fabs( (double) sample ) + (StkFloat) 0.75;
+  lastFrame_[0] = (StkFloat) pow( lastFrame_[0], (StkFloat) -4.0 );
+
+  // Set minimum friction to 0.0
+  // if ( lastFrame_[0] < 0.0 ) lastFrame_[0] = 0.0;
+
+  // Set maximum friction to 1.0.
+  if ( lastFrame_[0] > 1.0 ) lastFrame_[0] = (StkFloat) 1.0;
+
+  return lastFrame_[0];
+}
+
+inline StkFrames& BowTable :: tick( StkFrames& frames, unsigned int channel )
+{
+#if defined(_STK_DEBUG_)
+  if ( channel >= frames.channels() ) {
+    errorString_ << "BowTable::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *samples = &frames[channel];
+  unsigned int hop = frames.channels();
+  for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
+    *samples = *samples + offset_;
+    *samples *= slope_;
+    *samples = (StkFloat) fabs( (double) *samples ) + 0.75;
+    *samples = (StkFloat) pow( *samples, (StkFloat) -4.0 );
+    if ( *samples > 1.0) *samples = 1.0;
+  }
+
+  lastFrame_[0] = *(samples-hop);
+  return frames;
+}
+
+inline StkFrames& BowTable :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iChannel, unsigned int oChannel )
+{
+#if defined(_STK_DEBUG_)
+  if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
+    errorString_ << "BowTable::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *iSamples = &iFrames[iChannel];
+  StkFloat *oSamples = &oFrames[oChannel];
+  unsigned int iHop = iFrames.channels(), oHop = oFrames.channels();
+  for ( unsigned int i=0; i<iFrames.frames(); i++, iSamples += iHop, oSamples += oHop ) {
+    *oSamples = *iSamples + offset_;
+    *oSamples *= slope_;
+    *oSamples = (StkFloat) fabs( (double) *oSamples ) + 0.75;
+    *oSamples = (StkFloat) pow( *oSamples, (StkFloat) -4.0 );
+    if ( *oSamples > 1.0) *oSamples = 1.0;
+  }
+
+  lastFrame_[0] = *(oSamples-oHop);
+  return iFrames;
+}
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/Bowed.h b/lib/MoMu-STK-1.0.0/include/Bowed.h
new file mode 100644 (file)
index 0000000..4d36967
--- /dev/null
@@ -0,0 +1,112 @@
+#ifndef STK_BOWED_H
+#define STK_BOWED_H
+
+#include "Instrmnt.h"
+#include "DelayL.h"
+#include "BowTable.h"
+#include "OnePole.h"
+#include "BiQuad.h"
+#include "SineWave.h"
+#include "ADSR.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class Bowed
+    \brief STK bowed string instrument class.
+
+    This class implements a bowed string model, a
+    la Smith (1986), after McIntyre, Schumacher,
+    Woodhouse (1983).
+
+    This is a digital waveguide model, making its
+    use possibly subject to patents held by
+    Stanford University, Yamaha, and others.
+
+    Control Change Numbers: 
+       - Bow Pressure = 2
+       - Bow Position = 4
+       - Vibrato Frequency = 11
+       - Vibrato Gain = 1
+       - Volume = 128
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class Bowed : public Instrmnt
+{
+ public:
+  //! Class constructor, taking the lowest desired playing frequency.
+  Bowed( StkFloat lowestFrequency );
+
+  //! Class destructor.
+  ~Bowed( void );
+
+  //! Reset and clear all internal state.
+  void clear( void );
+
+  //! Set instrument parameters for a particular frequency.
+  void setFrequency( StkFloat frequency );
+
+  //! Set vibrato gain.
+  void setVibrato( StkFloat gain );
+
+  //! Apply breath pressure to instrument with given amplitude and rate of increase.
+  void startBowing( StkFloat amplitude, StkFloat rate );
+
+  //! Decrease breath pressure with given rate of decrease.
+  void stopBowing( StkFloat rate );
+
+  //! Start a note with the given frequency and amplitude.
+  void noteOn( StkFloat frequency, StkFloat amplitude );
+
+  //! Stop a note with the given amplitude (speed of decay).
+  void noteOff( StkFloat amplitude );
+
+  //! Perform the control change specified by \e number and \e value (0.0 - 128.0).
+  void controlChange( int number, StkFloat value );
+
+  //! Compute and return one output sample.
+  StkFloat tick( unsigned int channel = 0 );
+
+ protected:
+
+  DelayL   neckDelay_;
+  DelayL   bridgeDelay_;
+  BowTable bowTable_;
+  OnePole  stringFilter_;
+  BiQuad   bodyFilter_;
+  SineWave vibrato_;
+  ADSR     adsr_;
+  StkFloat maxVelocity_;
+  StkFloat baseDelay_;
+  StkFloat vibratoGain_;
+  StkFloat betaRatio_;
+
+};
+
+inline StkFloat Bowed :: tick( unsigned int )
+{
+  StkFloat bowVelocity = maxVelocity_ * adsr_.tick();
+  StkFloat bridgeRefl = -stringFilter_.tick( bridgeDelay_.lastOut() );
+  StkFloat nutRefl = -neckDelay_.lastOut();
+  StkFloat stringVel = bridgeRefl + nutRefl;               // Sum is string velocity
+  StkFloat velDiff = bowVelocity - stringVel;              // Differential velocity
+  StkFloat newVel = velDiff * bowTable_.tick( velDiff );   // Non-Linear bow function
+  neckDelay_.tick(bridgeRefl + newVel);                    // Do string propagations
+  bridgeDelay_.tick(nutRefl + newVel);
+    
+  if ( vibratoGain_ > 0.0 )  {
+    neckDelay_.setDelay( (baseDelay_ * (1.0 - betaRatio_) ) + 
+                         (baseDelay_ * vibratoGain_ * vibrato_.tick()) );
+  }
+
+  lastFrame_[0] = bodyFilter_.tick( bridgeDelay_.lastOut() );
+
+  return lastFrame_[0];
+}
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/Brass.h b/lib/MoMu-STK-1.0.0/include/Brass.h
new file mode 100644 (file)
index 0000000..1892c73
--- /dev/null
@@ -0,0 +1,110 @@
+#ifndef STK_BRASS_H
+#define STK_BRASS_H
+
+#include "Instrmnt.h"
+#include "DelayA.h"
+#include "BiQuad.h"
+#include "PoleZero.h"
+#include "ADSR.h"
+#include "SineWave.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class Brass
+    \brief STK simple brass instrument class.
+
+    This class implements a simple brass instrument
+    waveguide model, a la Cook (TBone, HosePlayer).
+
+    This is a digital waveguide model, making its
+    use possibly subject to patents held by
+    Stanford University, Yamaha, and others.
+
+    Control Change Numbers: 
+       - Lip Tension = 2
+       - Slide Length = 4
+       - Vibrato Frequency = 11
+       - Vibrato Gain = 1
+       - Volume = 128
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class Brass: public Instrmnt
+{
+ public:
+  //! Class constructor, taking the lowest desired playing frequency.
+  /*!
+    An StkError will be thrown if the rawwave path is incorrectly set.
+  */
+  Brass( StkFloat lowestFrequency );
+
+  //! Class destructor.
+  ~Brass(  );
+
+  //! Reset and clear all internal state.
+  void clear(  );
+
+  //! Set instrument parameters for a particular frequency.
+  void setFrequency( StkFloat frequency );
+
+  //! Set the lips frequency.
+  void setLip( StkFloat frequency );
+
+  //! Apply breath pressure to instrument with given amplitude and rate of increase.
+  void startBlowing( StkFloat amplitude, StkFloat rate );
+
+  //! Decrease breath pressure with given rate of decrease.
+  void stopBlowing( StkFloat rate );
+
+  //! Start a note with the given frequency and amplitude.
+  void noteOn( StkFloat frequency, StkFloat amplitude );
+
+  //! Stop a note with the given amplitude (speed of decay).
+  void noteOff( StkFloat amplitude );
+
+  //! Perform the control change specified by \e number and \e value (0.0 - 128.0).
+  void controlChange( int number, StkFloat value );
+
+  //! Compute and return one output sample.
+  StkFloat tick( unsigned int channel = 0 );
+
+ protected:
+
+  DelayA   delayLine_;
+  BiQuad   lipFilter_;
+  PoleZero dcBlock_;
+  ADSR     adsr_;
+  SineWave vibrato_;
+  unsigned long length_;
+  StkFloat lipTarget_;
+  StkFloat slideTarget_;
+  StkFloat vibratoGain_;
+  StkFloat maxPressure_;
+
+};
+
+inline StkFloat Brass :: tick( unsigned int )
+{
+  StkFloat breathPressure = maxPressure_ * adsr_.tick();
+  breathPressure += vibratoGain_ * vibrato_.tick();
+
+  StkFloat mouthPressure = 0.3 * breathPressure;
+  StkFloat borePressure = 0.85 * delayLine_.lastOut();
+  StkFloat deltaPressure = mouthPressure - borePressure; // Differential pressure.
+  deltaPressure = lipFilter_.tick( deltaPressure );      // Force - > position.
+  deltaPressure *= deltaPressure;                        // Basic position to area mapping.
+  if ( deltaPressure > 1.0 ) deltaPressure = 1.0;        // Non-linear saturation.
+
+  // The following input scattering assumes the mouthPressure = area.
+  lastFrame_[0] = deltaPressure * mouthPressure + ( 1.0 - deltaPressure) * borePressure;
+  lastFrame_[0] = delayLine_.tick( dcBlock_.tick( lastFrame_[0] ) );
+
+  return lastFrame_[0];
+}
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/Chorus.h b/lib/MoMu-STK-1.0.0/include/Chorus.h
new file mode 100644 (file)
index 0000000..5258cca
--- /dev/null
@@ -0,0 +1,168 @@
+#ifndef STK_CHORUS_H
+#define STK_CHORUS_H
+
+#include "Effect.h"
+#include "DelayL.h"
+#include "SineWave.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class Chorus
+    \brief STK chorus effect class.
+
+    This class implements a chorus effect.  It takes a monophonic
+    input signal and produces a stereo output signal.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class Chorus : public Effect
+{
+ public:
+  //! Class constructor, taking the median desired delay length.
+  /*!
+    An StkError can be thrown if the rawwave path is incorrect.
+  */
+  Chorus( StkFloat baseDelay = 6000 );
+
+  //! Reset and clear all internal state.
+  void clear( void );
+
+  //! Set modulation depth.
+  void setModDepth( StkFloat depth ) { modDepth_ = depth; };
+
+  //! Set modulation frequency.
+  void setModFrequency( StkFloat frequency );
+
+  //! Return the specified channel value of the last computed stereo frame.
+  /*!
+    Use the lastFrame() function to get both values of the last
+    computed stereo frame.  The \c channel argument must be 0 or 1
+    (the first channel is specified by 0).  However, range checking is
+    only performed if _STK_DEBUG_ is defined during compilation, in
+    which case an out-of-range value will trigger an StkError
+    exception.
+  */
+  StkFloat lastOut( unsigned int channel = 0 );
+
+  //! Input one sample to the effect and return the specified \c channel value of the computed stereo frame.
+  /*!
+    Use the lastFrame() function to get both values of the computed
+    stereo output frame. The \c channel argument must be 0 or 1 (the
+    first channel is specified by 0).  However, range checking is only
+    performed if _STK_DEBUG_ is defined during compilation, in which
+    case an out-of-range value will trigger an StkError exception.
+  */
+  StkFloat tick( StkFloat input, unsigned int channel = 0 );
+
+  //! Take a channel of the StkFrames object as inputs to the effect and replace with stereo outputs.
+  /*!
+    The StkFrames argument reference is returned.  The stereo
+    outputs are written to the StkFrames argument starting at the
+    specified \c channel.  Therefore, the \c channel argument must be
+    less than ( channels() - 1 ) of the StkFrames argument (the first
+    channel is specified by 0).  However, range checking is only
+    performed if _STK_DEBUG_ is defined during compilation, in which
+    case an out-of-range value will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
+
+  //! Take a channel of the \c iFrames object as inputs to the effect and write stereo outputs to the \c oFrames object.
+  /*!
+    The \c iFrames object reference is returned.  The \c iChannel
+    argument must be less than the number of channels in the \c
+    iFrames argument (the first channel is specified by 0).  The \c
+    oChannel argument must be less than ( channels() - 1 ) of the \c
+    oFrames argument.  However, range checking is only performed if
+    _STK_DEBUG_ is defined during compilation, in which case an
+    out-of-range value will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0, unsigned int oChannel = 0 );
+
+ protected:
+
+  DelayL delayLine_[2];
+  SineWave mods_[2];
+  StkFloat baseLength_;
+  StkFloat modDepth_;
+
+};
+
+inline StkFloat Chorus :: lastOut( unsigned int channel )
+{
+#if defined(_STK_DEBUG_)
+  if ( channel > 1 ) {
+    errorString_ << "Chorus::lastOut(): channel argument must be less than 2!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  return lastFrame_[channel];
+}
+
+inline StkFloat Chorus :: tick( StkFloat input, unsigned int channel )
+{
+#if defined(_STK_DEBUG_)
+  if ( channel > 1 ) {
+    errorString_ << "Chorus::tick(): channel argument must be less than 2!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  delayLine_[0].setDelay( baseLength_ * 0.707 * ( 1.0 + modDepth_ * mods_[0].tick() ) );
+  delayLine_[1].setDelay( baseLength_  * 0.5 *  ( 1.0 - modDepth_ * mods_[1].tick() ) );
+  lastFrame_[0] = effectMix_ * ( delayLine_[0].tick( input ) - input ) + input;
+  lastFrame_[1] = effectMix_ * ( delayLine_[1].tick( input ) - input ) + input;
+  return lastFrame_[channel];
+}
+
+inline StkFrames& Chorus :: tick( StkFrames& frames, unsigned int channel )
+{
+#if defined(_STK_DEBUG_)
+  if ( channel >= frames.channels() - 1 ) {
+    errorString_ << "Chorus::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *samples = &frames[channel];
+  unsigned int hop = frames.channels() - 1;
+  for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
+    *samples = effectMix_ * ( delayLine_[0].tick( *samples ) - *samples ) + *samples;
+    samples++;
+    *samples = effectMix_ * ( delayLine_[1].tick( *samples ) - *samples ) + *samples;
+  }
+
+  lastFrame_[0] = *(samples-hop);
+  lastFrame_[1] = *(samples-hop+1);
+  return frames;
+}
+
+inline StkFrames& Chorus :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iChannel, unsigned int oChannel )
+{
+#if defined(_STK_DEBUG_)
+  if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() - 1 ) {
+    errorString_ << "Chorus::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *iSamples = &iFrames[iChannel];
+  StkFloat *oSamples = &oFrames[oChannel];
+  unsigned int iHop = iFrames.channels(), oHop = oFrames.channels();
+  for ( unsigned int i=0; i<iFrames.frames(); i++, iSamples += iHop, oSamples += oHop ) {
+    *oSamples++ = effectMix_ * ( delayLine_[0].tick( *iSamples ) - *iSamples ) + *iSamples;
+    *oSamples = effectMix_ * ( delayLine_[1].tick( *iSamples ) - *iSamples ) + *iSamples;
+  }
+
+  lastFrame_[0] = *(oSamples-oHop);
+  lastFrame_[1] = *(oSamples-oHop+1);
+  return iFrames;
+}
+
+} // stk namespace
+
+#endif
+
diff --git a/lib/MoMu-STK-1.0.0/include/Clarinet.h b/lib/MoMu-STK-1.0.0/include/Clarinet.h
new file mode 100644 (file)
index 0000000..899055d
--- /dev/null
@@ -0,0 +1,116 @@
+#ifndef STK_CLARINET_H
+#define STK_CLARINET_H
+
+#include "Instrmnt.h"
+#include "DelayL.h"
+#include "ReedTable.h"
+#include "OneZero.h"
+#include "Envelope.h"
+#include "Noise.h"
+#include "SineWave.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class Clarinet
+    \brief STK clarinet physical model class.
+
+    This class implements a simple clarinet
+    physical model, as discussed by Smith (1986),
+    McIntyre, Schumacher, Woodhouse (1983), and
+    others.
+
+    This is a digital waveguide model, making its
+    use possibly subject to patents held by Stanford
+    University, Yamaha, and others.
+
+    Control Change Numbers: 
+       - Reed Stiffness = 2
+       - Noise Gain = 4
+       - Vibrato Frequency = 11
+       - Vibrato Gain = 1
+       - Breath Pressure = 128
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class Clarinet : public Instrmnt
+{
+ public:
+  //! Class constructor, taking the lowest desired playing frequency.
+  /*!
+    An StkError will be thrown if the rawwave path is incorrectly set.
+  */
+  Clarinet( StkFloat lowestFrequency );
+
+  //! Class destructor.
+  ~Clarinet( void );
+
+  //! Reset and clear all internal state.
+  void clear( void );
+
+  //! Set instrument parameters for a particular frequency.
+  void setFrequency( StkFloat frequency );
+
+  //! Apply breath pressure to instrument with given amplitude and rate of increase.
+  void startBlowing( StkFloat amplitude, StkFloat rate );
+
+  //! Decrease breath pressure with given rate of decrease.
+  void stopBlowing( StkFloat rate );
+
+  //! Start a note with the given frequency and amplitude.
+  void noteOn( StkFloat frequency, StkFloat amplitude );
+
+  //! Stop a note with the given amplitude (speed of decay).
+  void noteOff( StkFloat amplitude );
+
+  //! Perform the control change specified by \e number and \e value (0.0 - 128.0).
+  void controlChange( int number, StkFloat value );
+
+  //! Compute and return one output sample.
+  StkFloat tick( unsigned int channel = 0 );
+
+ protected:
+
+  DelayL delayLine_;
+  ReedTable reedTable_;
+  OneZero filter_;
+  Envelope envelope_;
+  Noise noise_;
+  SineWave vibrato_;
+  long length_;
+  StkFloat outputGain_;
+  StkFloat noiseGain_;
+  StkFloat vibratoGain_;
+
+};
+
+inline StkFloat Clarinet :: tick( unsigned int )
+{
+  StkFloat pressureDiff;
+  StkFloat breathPressure;
+
+  // Calculate the breath pressure (envelope + noise + vibrato)
+  breathPressure = envelope_.tick(); 
+  breathPressure += breathPressure * noiseGain_ * noise_.tick();
+  breathPressure += breathPressure * vibratoGain_ * vibrato_.tick();
+
+  // Perform commuted loss filtering.
+  pressureDiff = -0.95 * filter_.tick( delayLine_.lastOut() );
+
+  // Calculate pressure difference of reflected and mouthpiece pressures.
+  pressureDiff = pressureDiff - breathPressure;
+
+  // Perform non-linear scattering using pressure difference in reed function.
+  lastFrame_[0] = delayLine_.tick(breathPressure + pressureDiff * reedTable_.tick(pressureDiff));
+
+  // Apply output gain.
+  lastFrame_[0] *= outputGain_;
+
+  return lastFrame_[0];
+}
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/Delay.h b/lib/MoMu-STK-1.0.0/include/Delay.h
new file mode 100644 (file)
index 0000000..33f4644
--- /dev/null
@@ -0,0 +1,182 @@
+#ifndef STK_DELAY_H
+#define STK_DELAY_H
+
+#include "Filter.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class Delay
+    \brief STK non-interpolating delay line class.
+
+    This class implements a non-interpolating digital delay-line.  If
+    the delay and maximum length are not specified during
+    instantiation, a fixed maximum length of 4095 and a delay of zero
+    is set.
+    
+    A non-interpolating delay line is typically used in fixed
+    delay-length applications, such as for reverberation.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class Delay : public Filter
+{
+public:
+
+  //! The default constructor creates a delay-line with maximum length of 4095 samples and zero delay.
+  /*!
+    An StkError will be thrown if the delay parameter is less than
+    zero, the maximum delay parameter is less than one, or the delay
+    parameter is greater than the maxDelay value.
+   */
+  Delay( unsigned long delay = 0, unsigned long maxDelay = 4095 );
+
+  //! Class destructor.
+  ~Delay();
+
+  //! Set the maximum delay-line length.
+  /*!
+    This method should generally only be used during initial setup
+    of the delay line.  If it is used between calls to the tick()
+    function, without a call to clear(), a signal discontinuity will
+    likely occur.  If the current maximum length is greater than the
+    new length, no change will be made.
+  */
+  void setMaximumDelay( unsigned long delay );
+
+  //! Set the delay-line length.
+  /*!
+    The valid range for \e delay is from 0 to the maximum delay-line length.
+  */
+  void setDelay( unsigned long delay );
+
+  //! Return the current delay-line length.
+  unsigned long getDelay( void ) const { return delay_; };
+
+  //! Return the value at \e tapDelay samples from the delay-line input.
+  /*!
+    The tap point is determined modulo the delay-line length and is
+    relative to the last input value (i.e., a tapDelay of zero returns
+    the last input value).
+  */
+  StkFloat contentsAt( unsigned long tapDelay );
+
+  //! Sum the provided value into the delay line at \e tapDelay samples from the input.
+  /*!
+    The new value is returned.  The tap point is determined modulo
+    the delay-line length and is relative to the last input value
+    (i.e., a tapDelay of zero sums into the last input value).
+  */
+  StkFloat addTo( unsigned long tapDelay, StkFloat value );
+
+  //! Return the last computed output value.
+  StkFloat lastOut( void ) const { return lastFrame_[0]; };
+
+  //! Return the value that will be output by the next call to tick().
+  /*!
+    This method is valid only for delay settings greater than zero!
+   */
+  StkFloat nextOut( void ) { return inputs_[outPoint_]; };
+
+  //! Calculate and return the signal energy in the delay-line.
+  StkFloat energy( void ) const;
+
+  //! Input one sample to the filter and return one output.
+  StkFloat tick( StkFloat input );
+
+  //! Take a channel of the StkFrames object as inputs to the filter and replace with corresponding outputs.
+  /*!
+    The StkFrames argument reference is returned.  The \c channel
+    argument must be less than the number of channels in the
+    StkFrames argument (the first channel is specified by 0).
+    However, range checking is only performed if _STK_DEBUG_ is
+    defined during compilation, in which case an out-of-range value
+    will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
+
+  //! Take a channel of the \c iFrames object as inputs to the filter and write outputs to the \c oFrames object.
+  /*!
+    The \c iFrames object reference is returned.  Each channel
+    argument must be less than the number of channels in the
+    corresponding StkFrames argument (the first channel is specified
+    by 0).  However, range checking is only performed if _STK_DEBUG_
+    is defined during compilation, in which case an out-of-range value
+    will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0, unsigned int oChannel = 0 );
+
+protected:
+
+  unsigned long inPoint_;
+  unsigned long outPoint_;
+  unsigned long delay_;
+};
+
+inline StkFloat Delay :: tick( StkFloat input )
+{
+  inputs_[inPoint_++] = input * gain_;
+
+  // Check for end condition
+  if ( inPoint_ == inputs_.size() )
+    inPoint_ = 0;
+
+  // Read out next value
+  lastFrame_[0] = inputs_[outPoint_++];
+
+  if ( outPoint_ == inputs_.size() )
+    outPoint_ = 0;
+
+  return lastFrame_[0];
+}
+
+inline StkFrames& Delay :: tick( StkFrames& frames, unsigned int channel )
+{
+#if defined(_STK_DEBUG_)
+  if ( channel >= frames.channels() ) {
+    errorString_ << "Delay::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *samples = &frames[channel];
+  unsigned int hop = frames.channels();
+  for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
+    inputs_[inPoint_++] = *samples * gain_;
+    if ( inPoint_ == inputs_.size() ) inPoint_ = 0;
+    *samples = inputs_[outPoint_++];
+    if ( outPoint_ == inputs_.size() ) outPoint_ = 0;
+  }
+
+  lastFrame_[0] = *(samples-hop);
+  return frames;
+}
+
+inline StkFrames& Delay :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iChannel, unsigned int oChannel )
+{
+#if defined(_STK_DEBUG_)
+  if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
+    errorString_ << "Delay::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *iSamples = &iFrames[iChannel];
+  StkFloat *oSamples = &oFrames[oChannel];
+  unsigned int iHop = iFrames.channels(), oHop = oFrames.channels();
+  for ( unsigned int i=0; i<iFrames.frames(); i++, iSamples += iHop, oSamples += oHop ) {
+    inputs_[inPoint_++] = *iSamples * gain_;
+    if ( inPoint_ == inputs_.size() ) inPoint_ = 0;
+    *oSamples = inputs_[outPoint_++];
+    if ( outPoint_ == inputs_.size() ) outPoint_ = 0;
+  }
+
+  lastFrame_[0] = *(oSamples-oHop);
+  return iFrames;
+}
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/DelayA.h b/lib/MoMu-STK-1.0.0/include/DelayA.h
new file mode 100644 (file)
index 0000000..f092152
--- /dev/null
@@ -0,0 +1,201 @@
+#ifndef STK_DELAYA_H
+#define STK_DELAYA_H
+
+#include "Filter.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class DelayA
+    \brief STK allpass interpolating delay line class.
+
+    This class implements a fractional-length digital delay-line using
+    a first-order allpass filter.  If the delay and maximum length are
+    not specified during instantiation, a fixed maximum length of 4095
+    and a delay of 0.5 is set.
+
+    An allpass filter has unity magnitude gain but variable phase
+    delay properties, making it useful in achieving fractional delays
+    without affecting a signal's frequency magnitude response.  In
+    order to achieve a maximally flat phase delay response, the
+    minimum delay possible in this implementation is limited to a
+    value of 0.5.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class DelayA : public Filter
+{
+public:
+
+  //! Default constructor creates a delay-line with maximum length of 4095 samples and delay = 0.5.
+  /*!
+    An StkError will be thrown if the delay parameter is less than
+    zero, the maximum delay parameter is less than one, or the delay
+    parameter is greater than the maxDelay value.
+   */  
+  DelayA( StkFloat delay = 0.5, unsigned long maxDelay = 4095 );
+
+  //! Class destructor.
+  ~DelayA();
+
+  //! Clears all internal states of the delay line.
+  void clear( void );
+  
+  //! Set the maximum delay-line length.
+  /*!
+    This method should generally only be used during initial setup
+    of the delay line.  If it is used between calls to the tick()
+    function, without a call to clear(), a signal discontinuity will
+    likely occur.  If the current maximum length is greater than the
+    new length, no change will be made.
+  */
+  void setMaximumDelay( unsigned long delay );
+
+  //! Set the delay-line length
+  /*!
+    The valid range for \e delay is from 0.5 to the maximum delay-line length.
+  */
+  void setDelay( StkFloat delay );
+
+  //! Return the current delay-line length.
+  StkFloat getDelay( void ) const { return delay_; };
+
+  //! Return the value at \e tapDelay samples from the delay-line input.
+  /*!
+    The tap point is determined modulo the delay-line length and is
+    relative to the last input value (i.e., a tapDelay of zero returns
+    the last input value).
+  */
+  StkFloat contentsAt( unsigned long tapDelay );
+
+  //! Return the last computed output value.
+  StkFloat lastOut( void ) const { return lastFrame_[0]; };
+
+  //! Return the value which will be output by the next call to tick().
+  /*!
+    This method is valid only for delay settings greater than zero!
+   */
+  StkFloat nextOut( void );
+
+  //! Input one sample to the filter and return one output.
+  StkFloat tick( StkFloat input );
+
+  //! Take a channel of the StkFrames object as inputs to the filter and replace with corresponding outputs.
+  /*!
+    The StkFrames argument reference is returned.  The \c channel
+    argument must be less than the number of channels in the
+    StkFrames argument (the first channel is specified by 0).
+    However, range checking is only performed if _STK_DEBUG_ is
+    defined during compilation, in which case an out-of-range value
+    will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
+
+  //! Take a channel of the \c iFrames object as inputs to the filter and write outputs to the \c oFrames object.
+  /*!
+    The \c iFrames object reference is returned.  Each channel
+    argument must be less than the number of channels in the
+    corresponding StkFrames argument (the first channel is specified
+    by 0).  However, range checking is only performed if _STK_DEBUG_
+    is defined during compilation, in which case an out-of-range value
+    will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0, unsigned int oChannel = 0 );
+
+protected:  
+
+  unsigned long inPoint_;
+  unsigned long outPoint_;
+  StkFloat delay_;
+  StkFloat alpha_;
+  StkFloat coeff_;
+  StkFloat apInput_;
+  StkFloat nextOutput_;
+  bool doNextOut_;
+};
+
+inline StkFloat DelayA :: nextOut( void )
+{
+  if ( doNextOut_ ) {
+    // Do allpass interpolation delay.
+    nextOutput_ = -coeff_ * lastFrame_[0];
+    nextOutput_ += apInput_ + ( coeff_ * inputs_[outPoint_] );
+    doNextOut_ = false;
+  }
+
+  return nextOutput_;
+}
+
+inline StkFloat DelayA :: tick( StkFloat input )
+{
+  inputs_[inPoint_++] = input * gain_;
+
+  // Increment input pointer modulo length.
+  if ( inPoint_ == inputs_.size() )
+    inPoint_ = 0;
+
+  lastFrame_[0] = nextOut();
+  doNextOut_ = true;
+
+  // Save the allpass input and increment modulo length.
+  apInput_ = inputs_[outPoint_++];
+  if ( outPoint_ == inputs_.size() )
+    outPoint_ = 0;
+
+  return lastFrame_[0];
+}
+
+inline StkFrames& DelayA :: tick( StkFrames& frames, unsigned int channel )
+{
+#if defined(_STK_DEBUG_)
+  if ( channel >= frames.channels() ) {
+    errorString_ << "DelayA::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *samples = &frames[channel];
+  unsigned int hop = frames.channels();
+  for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
+    inputs_[inPoint_++] = *samples * gain_;
+    if ( inPoint_ == inputs_.size() ) inPoint_ = 0;
+    *samples = nextOut();
+    lastFrame_[0] = *samples;
+    doNextOut_ = true;
+    apInput_ = inputs_[outPoint_++];
+    if ( outPoint_ == inputs_.size() ) outPoint_ = 0;
+  }
+
+  return frames;
+}
+
+inline StkFrames& DelayA :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iChannel, unsigned int oChannel )
+{
+#if defined(_STK_DEBUG_)
+  if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
+    errorString_ << "DelayA::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *iSamples = &iFrames[iChannel];
+  StkFloat *oSamples = &oFrames[oChannel];
+  unsigned int iHop = iFrames.channels(), oHop = oFrames.channels();
+  for ( unsigned int i=0; i<iFrames.frames(); i++, iSamples += iHop, oSamples += oHop ) {
+    inputs_[inPoint_++] = *iSamples * gain_;
+    if ( inPoint_ == inputs_.size() ) inPoint_ = 0;
+    *oSamples = nextOut();
+    lastFrame_[0] = *oSamples;
+    doNextOut_ = true;
+    apInput_ = inputs_[outPoint_++];
+    if ( outPoint_ == inputs_.size() ) outPoint_ = 0;
+  }
+
+  return iFrames;
+}
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/DelayL.h b/lib/MoMu-STK-1.0.0/include/DelayL.h
new file mode 100644 (file)
index 0000000..e7d45d4
--- /dev/null
@@ -0,0 +1,197 @@
+#ifndef STK_DELAYL_H
+#define STK_DELAYL_H
+
+#include "Delay.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class DelayL
+    \brief STK linear interpolating delay line class.
+
+    This class implements a fractional-length digital delay-line using
+    first-order linear interpolation.  If the delay and maximum length
+    are not specified during instantiation, a fixed maximum length of
+    4095 and a delay of zero is set.
+
+    Linear interpolation is an efficient technique for achieving
+    fractional delay lengths, though it does introduce high-frequency
+    signal attenuation to varying degrees depending on the fractional
+    delay setting.  The use of higher order Lagrange interpolators can
+    typically improve (minimize) this attenuation characteristic.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class DelayL : public Filter
+{
+public:
+
+  //! Default constructor creates a delay-line with maximum length of 4095 samples and zero delay.
+  /*!
+    An StkError will be thrown if the delay parameter is less than
+    zero, the maximum delay parameter is less than one, or the delay
+    parameter is greater than the maxDelay value.
+   */  
+  DelayL( StkFloat delay = 0.0, unsigned long maxDelay = 4095 );
+
+  //! Class destructor.
+  ~DelayL();
+
+  //! Set the maximum delay-line length.
+  /*!
+    This method should generally only be used during initial setup
+    of the delay line.  If it is used between calls to the tick()
+    function, without a call to clear(), a signal discontinuity will
+    likely occur.  If the current maximum length is greater than the
+    new length, no change will be made.
+  */
+  void setMaximumDelay( unsigned long delay );
+
+  //! Set the delay-line length.
+  /*!
+    The valid range for \e delay is from 0 to the maximum delay-line length.
+  */
+  void setDelay( StkFloat delay );
+
+  //! Return the current delay-line length.
+  StkFloat getDelay( void ) const { return delay_; };
+
+  //! Return the value at \e tapDelay samples from the delay-line input.
+  /*!
+    The tap point is determined modulo the delay-line length and is
+    relative to the last input value (i.e., a tapDelay of zero returns
+    the last input value).
+  */
+  StkFloat contentsAt( unsigned long tapDelay );
+
+  //! Return the last computed output value.
+  StkFloat lastOut( void ) const { return lastFrame_[0]; };
+
+  //! Return the value which will be output by the next call to tick().
+  /*!
+    This method is valid only for delay settings greater than zero!
+   */
+  StkFloat nextOut( void );
+
+  //! Input one sample to the filter and return one output.
+  StkFloat tick( StkFloat input );
+
+  //! Take a channel of the StkFrames object as inputs to the filter and replace with corresponding outputs.
+  /*!
+    The StkFrames argument reference is returned.  The \c channel
+    argument must be less than the number of channels in the
+    StkFrames argument (the first channel is specified by 0).
+    However, range checking is only performed if _STK_DEBUG_ is
+    defined during compilation, in which case an out-of-range value
+    will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
+
+  //! Take a channel of the \c iFrames object as inputs to the filter and write outputs to the \c oFrames object.
+  /*!
+    The \c iFrames object reference is returned.  Each channel
+    argument must be less than the number of channels in the
+    corresponding StkFrames argument (the first channel is specified
+    by 0).  However, range checking is only performed if _STK_DEBUG_
+    is defined during compilation, in which case an out-of-range value
+    will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0, unsigned int oChannel = 0 );
+
+ protected:
+
+  unsigned long inPoint_;
+  unsigned long outPoint_;
+  StkFloat delay_;
+  StkFloat alpha_;
+  StkFloat omAlpha_;
+  StkFloat nextOutput_;
+  bool doNextOut_;
+};
+
+inline StkFloat DelayL :: nextOut( void )
+{
+  if ( doNextOut_ ) {
+    // First 1/2 of interpolation
+    nextOutput_ = inputs_[outPoint_] * omAlpha_;
+    // Second 1/2 of interpolation
+    if (outPoint_+1 < inputs_.size())
+      nextOutput_ += inputs_[outPoint_+1] * alpha_;
+    else
+      nextOutput_ += inputs_[0] * alpha_;
+    doNextOut_ = false;
+  }
+
+  return nextOutput_;
+}
+
+inline StkFloat DelayL :: tick( StkFloat input )
+{
+  inputs_[inPoint_++] = input * gain_;
+
+  // Increment input pointer modulo length.
+  if ( inPoint_ == inputs_.size() )
+    inPoint_ = 0;
+
+  lastFrame_[0] = nextOut();
+  doNextOut_ = true;
+
+  // Increment output pointer modulo length.
+  if ( ++outPoint_ == inputs_.size() )
+    outPoint_ = 0;
+
+  return lastFrame_[0];
+}
+
+inline StkFrames& DelayL :: tick( StkFrames& frames, unsigned int channel )
+{
+#if defined(_STK_DEBUG_)
+  if ( channel >= frames.channels() ) {
+    errorString_ << "DelayL::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *samples = &frames[channel];
+  unsigned int hop = frames.channels();
+  for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
+    inputs_[inPoint_++] = *samples * gain_;
+    if ( inPoint_ == inputs_.size() ) inPoint_ = 0;
+    *samples = nextOut();
+    doNextOut_ = true;
+    if ( ++outPoint_ == inputs_.size() ) outPoint_ = 0;
+  }
+
+  lastFrame_[0] = *(samples-hop);
+  return frames;
+}
+
+inline StkFrames& DelayL :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iChannel, unsigned int oChannel )
+{
+#if defined(_STK_DEBUG_)
+  if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
+    errorString_ << "DelayL::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *iSamples = &iFrames[iChannel];
+  StkFloat *oSamples = &oFrames[oChannel];
+  unsigned int iHop = iFrames.channels(), oHop = oFrames.channels();
+  for ( unsigned int i=0; i<iFrames.frames(); i++, iSamples += iHop, oSamples += oHop ) {
+    inputs_[inPoint_++] = *iSamples * gain_;
+    if ( inPoint_ == inputs_.size() ) inPoint_ = 0;
+    *oSamples = nextOut();
+    doNextOut_ = true;
+    if ( ++outPoint_ == inputs_.size() ) outPoint_ = 0;
+  }
+
+  lastFrame_[0] = *(oSamples-oHop);
+  return iFrames;
+}
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/Drummer.h b/lib/MoMu-STK-1.0.0/include/Drummer.h
new file mode 100644 (file)
index 0000000..4ea2688
--- /dev/null
@@ -0,0 +1,92 @@
+#ifndef STK_DRUMMER_H
+#define STK_DRUMMER_H
+
+#include "Instrmnt.h"
+#include "FileWvIn.h"
+#include "OnePole.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class Drummer
+    \brief STK drum sample player class.
+
+    This class implements a drum sampling
+    synthesizer using WvIn objects and one-pole
+    filters.  The drum rawwave files are sampled
+    at 22050 Hz, but will be appropriately
+    interpolated for other sample rates.  You can
+    specify the maximum polyphony (maximum number
+    of simultaneous voices) via a #define in the
+    Drummer.h.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+const int DRUM_NUMWAVES = 11;
+const int DRUM_POLYPHONY = 4;
+
+class Drummer : public Instrmnt
+{
+ public:
+  //! Class constructor.
+  /*!
+    An StkError will be thrown if the rawwave path is incorrectly set.
+  */
+  Drummer( void );
+
+  //! Class destructor.
+  ~Drummer( void );
+
+  //! Start a note with the given drum type and amplitude.
+  /*!
+    Use general MIDI drum instrument numbers, converted to
+    frequency values as if MIDI note numbers, to select a particular
+    instrument.  An StkError will be thrown if the rawwave path is
+    incorrectly set.
+  */
+  void noteOn( StkFloat instrument, StkFloat amplitude );
+
+  //! Stop a note with the given amplitude (speed of decay).
+  void noteOff( StkFloat amplitude );
+
+  //! Compute and return one output sample.
+  StkFloat tick( unsigned int channel = 0 );
+
+ protected:
+
+  FileWvIn waves_[DRUM_POLYPHONY];
+  OnePole  filters_[DRUM_POLYPHONY];
+  std::vector<int> soundOrder_;
+  std::vector<int> soundNumber_;
+  int      nSounding_;
+};
+
+inline StkFloat Drummer :: tick( unsigned int )
+{
+  lastFrame_[0] = 0.0;
+  if ( nSounding_ == 0 ) return lastFrame_[0];
+
+  for ( int i=0; i<DRUM_POLYPHONY; i++ ) {
+    if ( soundOrder_[i] >= 0 ) {
+      if ( waves_[i].isFinished() ) {
+        // Re-order the list.
+        for ( int j=0; j<DRUM_POLYPHONY; j++ ) {
+          if ( soundOrder_[j] > soundOrder_[i] )
+            soundOrder_[j] -= 1;
+        }
+        soundOrder_[i] = -1;
+        nSounding_--;
+      }
+      else
+        lastFrame_[0] += filters_[i].tick( waves_[i].tick() );
+    }
+  }
+
+  return lastFrame_[0];
+}
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/Echo.h b/lib/MoMu-STK-1.0.0/include/Echo.h
new file mode 100644 (file)
index 0000000..473bd40
--- /dev/null
@@ -0,0 +1,120 @@
+#ifndef STK_ECHO_H
+#define STK_ECHO_H
+
+#include "Effect.h" 
+#include "Delay.h" 
+
+namespace stk {
+
+/***************************************************/
+/*! \class Echo
+    \brief STK echo effect class.
+
+    This class implements an echo effect.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class Echo : public Effect
+{
+ public:
+  //! Class constructor, taking the longest desired delay length (one second default value).
+  /*!
+    The default delay value is set to 1/2 the maximum delay length.
+  */
+  Echo( unsigned long maximumDelay = (unsigned long) Stk::sampleRate() );
+
+  //! Reset and clear all internal state.
+  void clear();
+
+  //! Set the maximum delay line length in samples.
+  void setMaximumDelay( unsigned long delay );
+
+  //! Set the delay line length in samples.
+  void setDelay( unsigned long delay );
+
+  //! Return the last computed output value.
+  StkFloat lastOut( void ) const { return lastFrame_[0]; };
+
+  //! Input one sample to the effect and return one output.
+  StkFloat tick( StkFloat input );
+
+  //! Take a channel of the StkFrames object as inputs to the effect and replace with corresponding outputs.
+  /*!
+    The StkFrames argument reference is returned.  The \c channel
+    argument must be less than the number of channels in the
+    StkFrames argument (the first channel is specified by 0).
+    However, range checking is only performed if _STK_DEBUG_ is
+    defined during compilation, in which case an out-of-range value
+    will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
+
+  //! Take a channel of the \c iFrames object as inputs to the effect and write outputs to the \c oFrames object.
+  /*!
+    The \c iFrames object reference is returned.  Each channel
+    argument must be less than the number of channels in the
+    corresponding StkFrames argument (the first channel is specified
+    by 0).  However, range checking is only performed if _STK_DEBUG_
+    is defined during compilation, in which case an out-of-range value
+    will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0, unsigned int oChannel = 0 );
+
+ protected:
+
+  Delay delayLine_;
+  unsigned long length_;
+
+};
+
+inline StkFloat Echo :: tick( StkFloat input )
+{
+  lastFrame_[0] = effectMix_ * ( delayLine_.tick( input ) - input ) + input;
+  return lastFrame_[0];
+}
+
+inline StkFrames& Echo :: tick( StkFrames& frames, unsigned int channel )
+{
+#if defined(_STK_DEBUG_)
+  if ( channel >= frames.channels() ) {
+    errorString_ << "Echo::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *samples = &frames[channel];
+  unsigned int hop = frames.channels();
+  for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
+    *samples = effectMix_ * ( delayLine_.tick( *samples ) - *samples ) + *samples;
+  }
+
+  lastFrame_[0] = *(samples-hop);
+  return frames;
+}
+
+inline StkFrames& Echo :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iChannel, unsigned int oChannel )
+{
+#if defined(_STK_DEBUG_)
+  if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
+    errorString_ << "Echo::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *iSamples = &iFrames[iChannel];
+  StkFloat *oSamples = &oFrames[oChannel];
+  unsigned int iHop = iFrames.channels(), oHop = oFrames.channels();
+  for ( unsigned int i=0; i<iFrames.frames(); i++, iSamples += iHop, oSamples += oHop ) {
+    *oSamples = effectMix_ * ( delayLine_.tick( *iSamples ) - *iSamples ) + *iSamples;
+  }
+
+  lastFrame_[0] = *(oSamples-oHop);
+  return iFrames;
+}
+
+} // stk namespace
+
+#endif
+
diff --git a/lib/MoMu-STK-1.0.0/include/Effect.h b/lib/MoMu-STK-1.0.0/include/Effect.h
new file mode 100644 (file)
index 0000000..acae6a9
--- /dev/null
@@ -0,0 +1,79 @@
+#ifndef STK_EFFECT_H
+#define STK_EFFECT_H
+
+#include "Stk.h"
+#include <cmath>
+
+namespace stk {
+
+/***************************************************/
+/*! \class Effect
+    \brief STK abstract effects parent class.
+
+    This class provides common functionality for STK effects
+    subclasses.  It is general enough to support both monophonic and
+    polyphonic input/output classes.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class Effect : public Stk
+{
+ public:
+  //! Class constructor.
+  Effect( void ) { lastFrame_.resize( 1, 1, 0.0 ); };
+
+  //! Return the number of output channels for the class.
+  unsigned int channelsOut( void ) const { return lastFrame_.channels(); };
+
+  //! Return an StkFrames reference to the last output sample frame.
+  const StkFrames& lastFrame( void ) const { return lastFrame_; };
+
+  //! Reset and clear all internal state.
+  virtual void clear() = 0;
+
+  //! Set the mixture of input and "effected" levels in the output (0.0 = input only, 1.0 = effect only). 
+  void setEffectMix( StkFloat mix );
+
+ protected:
+
+  // Returns true if argument value is prime.
+  bool isPrime( unsigned int number );
+
+  StkFrames lastFrame_;
+  StkFloat effectMix_;
+
+};
+
+inline void Effect :: setEffectMix( StkFloat mix )
+{
+  if ( mix < 0.0 ) {
+    errorString_ << "Effect::setEffectMix: mix parameter is less than zero ... setting to zero!";
+    handleError( StkError::WARNING );
+    effectMix_ = 0.0;
+  }
+  else if ( mix > 1.0 ) {
+    errorString_ << "Effect::setEffectMix: mix parameter is greater than 1.0 ... setting to one!";
+    handleError( StkError::WARNING );
+    effectMix_ = 1.0;
+  }
+  else
+    effectMix_ = mix;
+}
+
+inline bool Effect :: isPrime( unsigned int number )
+{
+  if ( number == 2 ) return true;
+  if ( number & 1 ) {
+         for ( int i=3; i<(int)sqrt((double)number)+1; i+=2 )
+                 if ( (number % i) == 0 ) return false;
+         return true; // prime
+       }
+  else return false; // even
+}
+
+} // stk namespace
+
+#endif
+
diff --git a/lib/MoMu-STK-1.0.0/include/Envelope.h b/lib/MoMu-STK-1.0.0/include/Envelope.h
new file mode 100644 (file)
index 0000000..358a7e8
--- /dev/null
@@ -0,0 +1,162 @@
+#ifndef STK_ENVELOPE_H
+#define STK_ENVELOPE_H
+
+#include "Generator.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class Envelope
+    \brief STK linear line envelope class.
+
+    This class implements a simple linear line envelope generator
+    which is capable of ramping to an arbitrary target value by a
+    specified \e rate.  It also responds to simple \e keyOn and \e
+    keyOff messages, ramping to 1.0 on keyOn and to 0.0 on keyOff.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class Envelope : public Generator
+{
+ public:
+
+  //! Default constructor.
+  Envelope( void );
+
+  //! Class destructor.
+  ~Envelope( void );
+
+  //! Assignment operator.
+  Envelope& operator= ( const Envelope& e );
+
+  //! Set target = 1.
+  void keyOn( void ) { this->setTarget( 1.0 ); };
+
+  //! Set target = 0.
+  void keyOff( void ) { this->setTarget( 0.0 ); };
+
+  //! Set the \e rate.
+  void setRate( StkFloat rate );
+
+  //! Set the \e rate based on a time duration.
+  void setTime( StkFloat time );
+
+  //! Set the target value.
+  void setTarget( StkFloat target );
+
+  //! Set current and target values to \e value.
+  void setValue( StkFloat value );
+
+  //! Return the current envelope \e state (0 = at target, 1 otherwise).
+  int getState( void ) const { return state_; };
+
+  //! Return the last computed output value.
+  StkFloat lastOut( void ) const { return lastFrame_[0]; };
+
+  //! Compute and return one output sample.
+  StkFloat tick( void );
+
+  //! Fill a channel of the StkFrames object with computed outputs.
+  /*!
+    The \c channel argument must be less than the number of
+    channels in the StkFrames argument (the first channel is specified
+    by 0).  However, range checking is only performed if _STK_DEBUG_
+    is defined during compilation, in which case an out-of-range value
+    will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
+
+ protected:
+
+  void sampleRateChanged( StkFloat newRate, StkFloat oldRate );
+
+  StkFloat value_;
+  StkFloat target_;
+  StkFloat rate_;
+  int state_;
+};
+
+inline void Envelope :: setRate( StkFloat rate )
+{
+#if defined(_STK_DEBUG_)
+  if ( rate < 0.0 ) {
+    errorString_ << "Envelope::setRate: negative rates not allowed ... correcting!";
+    handleError( StkError::WARNING );
+    rate_ = -rate;
+  }
+  else
+#endif
+    rate_ = rate;
+}
+
+inline void Envelope :: setTime( StkFloat time )
+{
+#if defined(_STK_DEBUG_)
+  if ( time < 0.0 ) {
+    errorString_ << "Envelope::setTime: negative times not allowed ... correcting!";
+    handleError( StkError::WARNING );
+    rate_ = 1.0 / ( -time * Stk::sampleRate() );
+  }
+  else
+#endif
+    rate_ = 1.0 / ( time * Stk::sampleRate() );
+}
+
+inline void Envelope :: setTarget( StkFloat target )
+{
+  target_ = target;
+  if ( value_ != target_ ) state_ = 1;
+}
+
+inline void Envelope :: setValue( StkFloat value )
+{
+  state_ = 0;
+  target_ = value;
+  value_ = value;
+}
+
+inline StkFloat Envelope :: tick( void )
+{
+  if ( state_ ) {
+    if ( target_ > value_ ) {
+      value_ += rate_;
+      if ( value_ >= target_ ) {
+        value_ = target_;
+        state_ = 0;
+      }
+    }
+    else {
+      value_ -= rate_;
+      if ( value_ <= target_ ) {
+        value_ = target_;
+        state_ = 0;
+      }
+    }
+    lastFrame_[0] = value_;
+  }
+
+  return value_;
+}
+
+inline StkFrames& Envelope :: tick( StkFrames& frames, unsigned int channel )
+{
+#if defined(_STK_DEBUG_)
+  if ( channel >= frames.channels() ) {
+    errorString_ << "Envelope::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *samples = &frames[channel];
+  unsigned int hop = frames.channels();
+  for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
+    *samples = tick();
+
+  return frames;
+}
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/FM.h b/lib/MoMu-STK-1.0.0/include/FM.h
new file mode 100644 (file)
index 0000000..eb2e156
--- /dev/null
@@ -0,0 +1,112 @@
+#ifndef STK_FM_H
+#define STK_FM_H
+
+#include "Instrmnt.h"
+#include "ADSR.h"
+#include "FileLoop.h"
+#include "SineWave.h"
+#include "TwoZero.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class FM
+    \brief STK abstract FM synthesis base class.
+
+    This class controls an arbitrary number of
+    waves and envelopes, determined via a
+    constructor argument.
+
+    Control Change Numbers: 
+       - Control One = 2
+       - Control Two = 4
+       - LFO Speed = 11
+       - LFO Depth = 1
+       - ADSR 2 & 4 Target = 128
+
+    The basic Chowning/Stanford FM patent expired
+    in 1995, but there exist follow-on patents,
+    mostly assigned to Yamaha.  If you are of the
+    type who should worry about this (making
+    money) worry away.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class FM : public Instrmnt
+{
+ public:
+  //! Class constructor, taking the number of wave/envelope operators to control.
+  /*!
+    An StkError will be thrown if the rawwave path is incorrectly set.
+  */
+  FM( unsigned int operators = 4 );
+
+  //! Class destructor.
+  virtual ~FM( void );
+
+  //! Reset and clear all wave and envelope states.
+  void clear( void );
+
+  //! Load the rawwave filenames in waves.
+  void loadWaves( const char **filenames );
+
+  //! Set instrument parameters for a particular frequency.
+  virtual void setFrequency( StkFloat frequency );
+
+  //! Set the frequency ratio for the specified wave.
+  void setRatio( unsigned int waveIndex, StkFloat ratio );
+
+  //! Set the gain for the specified wave.
+  void setGain( unsigned int waveIndex, StkFloat gain );
+
+  //! Set the modulation speed in Hz.
+  void setModulationSpeed( StkFloat mSpeed ) { vibrato_.setFrequency( mSpeed ); };
+
+  //! Set the modulation depth.
+  void setModulationDepth( StkFloat mDepth ) { modDepth_ = mDepth; };
+
+  //! Set the value of control1.
+  void setControl1( StkFloat cVal ) { control1_ = cVal * 2.0; };
+
+  //! Set the value of control1.
+  void setControl2( StkFloat cVal ) { control2_ = cVal * 2.0; };
+
+  //! Start envelopes toward "on" targets.
+  void keyOn( void );
+
+  //! Start envelopes toward "off" targets.
+  void keyOff( void );
+
+  //! Stop a note with the given amplitude (speed of decay).
+  void noteOff( StkFloat amplitude );
+
+  //! Perform the control change specified by \e number and \e value (0.0 - 128.0).
+  virtual void controlChange( int number, StkFloat value );
+
+  //! Compute and return one output sample.
+  virtual StkFloat tick( unsigned int ) = 0;
+
+ protected:
+
+  std::vector<ADSR *> adsr_; 
+  std::vector<FileLoop *> waves_;
+  SineWave vibrato_;
+  TwoZero  twozero_;
+  unsigned int nOperators_;
+  StkFloat baseFrequency_;
+  std::vector<StkFloat> ratios_;
+  std::vector<StkFloat> gains_;
+  StkFloat modDepth_;
+  StkFloat control1_;
+  StkFloat control2_;
+  StkFloat fmGains_[100];
+  StkFloat fmSusLevels_[16];
+  StkFloat fmAttTimes_[32];
+
+};
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/FMVoices.h b/lib/MoMu-STK-1.0.0/include/FMVoices.h
new file mode 100644 (file)
index 0000000..5f5416e
--- /dev/null
@@ -0,0 +1,98 @@
+#ifndef STK_FMVOICES_H
+#define STK_FMVOICES_H
+
+#include "FM.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class FMVoices
+    \brief STK singing FM synthesis instrument.
+
+    This class implements 3 carriers and a common
+    modulator, also referred to as algorithm 6 of
+    the TX81Z.
+
+    \code
+    Algorithm 6 is :
+                        /->1 -\
+                     4-|-->2 - +-> Out
+                        \->3 -/
+    \endcode
+
+    Control Change Numbers: 
+       - Vowel = 2
+       - Spectral Tilt = 4
+       - LFO Speed = 11
+       - LFO Depth = 1
+       - ADSR 2 & 4 Target = 128
+
+    The basic Chowning/Stanford FM patent expired
+    in 1995, but there exist follow-on patents,
+    mostly assigned to Yamaha.  If you are of the
+    type who should worry about this (making
+    money) worry away.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class FMVoices : public FM
+{
+ public:
+  //! Class constructor.
+  /*!
+    An StkError will be thrown if the rawwave path is incorrectly set.
+  */
+  FMVoices( void );
+
+  //! Class destructor.
+  ~FMVoices( void );
+
+  //! Set instrument parameters for a particular frequency.
+  void setFrequency( StkFloat frequency );
+
+  //! Start a note with the given frequency and amplitude.
+  void noteOn( StkFloat frequency, StkFloat amplitude );
+
+  //! Perform the control change specified by \e number and \e value (0.0 - 128.0).
+  void controlChange( int number, StkFloat value );
+
+  //! Compute and return one output sample.
+  StkFloat tick( unsigned int channel = 0 );
+
+ protected:
+
+  int currentVowel_;
+  StkFloat tilt_[3];
+  StkFloat mods_[3];
+};
+
+inline StkFloat FMVoices :: tick( unsigned int )
+{
+  register StkFloat temp, temp2;
+
+  temp = gains_[3] * adsr_[3]->tick() * waves_[3]->tick();
+  temp2 = vibrato_.tick() * modDepth_ * 0.1;
+
+  waves_[0]->setFrequency(baseFrequency_ * (1.0 + temp2) * ratios_[0]);
+  waves_[1]->setFrequency(baseFrequency_ * (1.0 + temp2) * ratios_[1]);
+  waves_[2]->setFrequency(baseFrequency_ * (1.0 + temp2) * ratios_[2]);
+  waves_[3]->setFrequency(baseFrequency_ * (1.0 + temp2) * ratios_[3]);
+
+  waves_[0]->addPhaseOffset(temp * mods_[0]);
+  waves_[1]->addPhaseOffset(temp * mods_[1]);
+  waves_[2]->addPhaseOffset(temp * mods_[2]);
+  waves_[3]->addPhaseOffset( twozero_.lastOut() );
+  twozero_.tick( temp );
+  temp =  gains_[0] * tilt_[0] * adsr_[0]->tick() * waves_[0]->tick();
+  temp += gains_[1] * tilt_[1] * adsr_[1]->tick() * waves_[1]->tick();
+  temp += gains_[2] * tilt_[2] * adsr_[2]->tick() * waves_[2]->tick();
+
+  lastFrame_[0] = temp * 0.33;
+  return lastFrame_[0];
+}
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/FileLoop.h b/lib/MoMu-STK-1.0.0/include/FileLoop.h
new file mode 100644 (file)
index 0000000..e93011a
--- /dev/null
@@ -0,0 +1,161 @@
+#ifndef STK_FILELOOP_H
+#define STK_FILELOOP_H
+
+#include "FileWvIn.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class FileLoop
+    \brief STK file looping / oscillator class.
+
+    This class provides audio file looping functionality.  Any audio
+    file that can be loaded by FileRead can be looped using this
+    class.
+
+    FileLoop supports multi-channel data.  It is important to
+    distinguish the tick() method that computes a single frame (and
+    returns only the specified sample of a multi-channel frame) from
+    the overloaded one that takes an StkFrames object for
+    multi-channel and/or multi-frame data.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class FileLoop : protected FileWvIn
+{
+ public:
+  //! Default constructor.
+  FileLoop( unsigned long chunkThreshold = 1000000, unsigned long chunkSize = 1024 );
+
+  //! Class constructor that opens a specified file.
+  FileLoop( std::string fileName, bool raw = false, bool doNormalize = true,
+            unsigned long chunkThreshold = 1000000, unsigned long chunkSize = 1024 );
+
+  //! Class destructor.
+  ~FileLoop( void );
+
+  //! Open the specified file and load its data.
+  /*!
+    Data from a previously opened file will be overwritten by this
+    function.  An StkError will be thrown if the file is not found,
+    its format is unknown, or a read error occurs.  If the file data
+    is to be loaded incrementally from disk and normalization is
+    specified, a scaling will be applied with respect to fixed-point
+    limits.  If the data format is floating-point, no scaling is
+    performed.
+  */
+  void openFile( std::string fileName, bool raw = false, bool doNormalize = true );
+
+  //! Close a file if one is open.
+  void closeFile( void ) { FileWvIn::closeFile(); };
+
+  //! Clear outputs and reset time (file) pointer to zero.
+  void reset( void ) { FileWvIn::reset(); };
+
+  //! Normalize data to a maximum of +-1.0.
+  /*!
+    This function has no effect when data is incrementally loaded
+    from disk.
+  */
+  void normalize( void ) { FileWvIn::normalize( 1.0 ); };
+
+  //! Normalize data to a maximum of \e +-peak.
+  /*!
+    This function has no effect when data is incrementally loaded
+    from disk.
+  */
+  void normalize( StkFloat peak ) { FileWvIn::normalize( peak ); };
+
+  //! Return the file size in sample frames.
+  unsigned long getSize( void ) const { return data_.frames(); };
+
+  //! Return the input file sample rate in Hz (not the data read rate).
+  /*!
+    WAV, SND, and AIF formatted files specify a sample rate in
+    their headers.  STK RAW files have a sample rate of 22050 Hz
+    by definition.  MAT-files are assumed to have a rate of 44100 Hz.
+  */
+  StkFloat getFileRate( void ) const { return data_.dataRate(); };
+
+  //! Set the data read rate in samples.  The rate can be negative.
+  /*!
+    If the rate value is negative, the data is read in reverse order.
+  */
+  void setRate( StkFloat rate );
+
+  //! Set the data interpolation rate based on a looping frequency.
+  /*!
+    This function determines the interpolation rate based on the file
+    size and the current Stk::sampleRate.  The \e frequency value
+    corresponds to file cycles per second.  The frequency can be
+    negative, in which case the loop is read in reverse order.
+  */
+  void setFrequency( StkFloat frequency ) { this->setRate( file_.fileSize() * frequency / Stk::sampleRate() ); };
+
+  //! Increment the read pointer by \e time samples, modulo file size.
+  void addTime( StkFloat time );
+
+  //! Increment current read pointer by \e angle, relative to a looping frequency.
+  /*!
+    This function increments the read pointer based on the file
+    size and the current Stk::sampleRate.  The \e anAngle value
+    is a multiple of file size.
+  */
+  void addPhase( StkFloat angle );
+
+  //! Add a phase offset to the current read pointer.
+  /*!
+    This function determines a time offset based on the file
+    size and the current Stk::sampleRate.  The \e angle value
+    is a multiple of file size.
+  */
+  void addPhaseOffset( StkFloat angle );
+
+  //! Return the specified channel value of the last computed frame.
+  /*!
+    For multi-channel files, use the lastFrame() function to get
+    all values from the last computed frame.  If no file data is
+    loaded, the returned value is 0.0.  The \c channel argument must
+    be less than the number of channels in the file data (the first
+    channel is specified by 0).  However, range checking is only
+    performed if _STK_DEBUG_ is defined during compilation, in which
+    case an out-of-range value will trigger an StkError exception.
+  */
+  StkFloat lastOut( unsigned int channel = 0 ) { return FileWvIn::lastOut( channel ); };
+
+  //! Compute a sample frame and return the specified \c channel value.
+  /*!
+    For multi-channel files, use the lastFrame() function to get
+    all values from the computed frame.  If no file data is loaded,
+    the returned value is 0.0.  The \c channel argument must be less
+    than the number of channels in the file data (the first channel is
+    specified by 0).  However, range checking is only performed if
+    _STK_DEBUG_ is defined during compilation, in which case an
+    out-of-range value will trigger an StkError exception.
+  */
+  StkFloat tick( unsigned int channel = 0 );
+
+  //! Fill the StkFrames argument with computed frames and return the same reference.
+  /*!
+    The number of channels in the StkFrames argument should equal
+    the number of channels in the file data.  However, this is only
+    checked if _STK_DEBUG_ is defined during compilation, in which
+    case an incompatibility will trigger an StkError exception.  If no
+    file data is loaded, the function does nothing (a warning will be
+    issued if _STK_DEBUG_ is defined during compilation and
+    Stk::showWarnings() has been set to \e true).
+  */
+  StkFrames& tick( StkFrames& frames );
+
+ protected:
+
+  StkFrames firstFrame_;
+  StkFloat phaseOffset_;
+
+};
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/FileRead.h b/lib/MoMu-STK-1.0.0/include/FileRead.h
new file mode 100644 (file)
index 0000000..967572d
--- /dev/null
@@ -0,0 +1,133 @@
+#ifndef STK_FILEREAD_H
+#define STK_FILEREAD_H
+
+#include "Stk.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class FileRead
+    \brief STK audio file input class.
+
+    This class provides input support for various
+    audio file formats.  Multi-channel (>2)
+    soundfiles are supported.  The file data is
+    returned via an external StkFrames object
+    passed to the read() function.  This class
+    does not store its own copy of the file data,
+    rather the data is read directly from disk.
+
+    FileRead currently supports uncompressed WAV,
+    AIFF/AIFC, SND (AU), MAT-file (Matlab), and
+    STK RAW file formats.  Signed integer (8-,
+    16-, and 32-bit) and floating-point (32- and
+    64-bit) data types are supported.  Compressed
+    data types are not supported.
+
+    STK RAW files have no header and are assumed
+    to contain a monophonic stream of 16-bit
+    signed integers in big-endian byte order at a
+    sample rate of 22050 Hz.  MAT-file data should
+    be saved in an array with each data channel
+    filling a matrix row.  The sample rate for
+    MAT-files is assumed to be 44100 Hz.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class FileRead : public Stk
+{
+public:
+  //! Default constructor.
+  FileRead( void );
+
+  //! Overloaded constructor that opens a file during instantiation.
+  /*!
+    An StkError will be thrown if the file is not found or its
+    format is unknown or unsupported.  The optional arguments allow a
+    headerless file type to be supported.  If \c typeRaw is false (the
+    default), the subsequent parameters are ignored.
+  */
+  FileRead( std::string fileName, bool typeRaw = false, unsigned int nChannels = 1,
+            StkFormat format = STK_SINT16, StkFloat rate = 22050.0 );
+
+  //! Class destructor.
+  ~FileRead( void );
+
+  //! Open the specified file and determine its formatting.
+  /*!
+    An StkError will be thrown if the file is not found or its
+    format is unknown or unsupported.  The optional arguments allow a
+    headerless file type to be supported.  If \c typeRaw is false (the
+    default), the subsequent parameters are ignored.
+  */
+  void open( std::string fileName, bool typeRaw = false, unsigned int nChannels = 1,
+             StkFormat format = STK_SINT16, StkFloat rate = 22050.0 );
+
+  //! If a file is open, close it.
+  void close( void );
+
+  //! Returns \e true if a file is currently open.
+  bool isOpen( void );
+
+  //! Return the file size in sample frames.
+  unsigned long fileSize( void ) const { return fileSize_; };
+
+  //! Return the number of audio channels in the file.
+  unsigned int channels( void ) const { return channels_; };
+
+  //! Return the file sample rate in Hz.
+  /*!
+    WAV, SND, and AIF formatted files specify a sample rate in
+    their headers.  By definition, STK RAW files have a sample rate of
+    22050 Hz.  MAT-files are assumed to have a rate of 44100 Hz.
+  */
+  StkFloat fileRate( void ) const { return fileRate_; };
+
+  //! Read sample frames from the file into an StkFrames object.
+  /*!
+    The number of sample frames to read will be determined from the
+    number of frames of the StkFrames argument.  If this size is
+    larger than the available data in the file (given the file size
+    and starting frame index), the extra frames will be unaffected
+    (the StkFrames object will not be resized).  Optional parameters
+    are provided to specify the starting sample frame within the file
+    (default = 0) and whether to normalize the data with respect to
+    fixed-point limits (default = true).  An StkError will be thrown
+    if a file error occurs or if the number of channels in the
+    StkFrames argument is not equal to that in the file.
+   */
+  void read( StkFrames& buffer, unsigned long startFrame = 0, bool doNormalize = true );
+
+protected:
+
+  // Get STK RAW file information.
+  bool getRawInfo( const char *fileName, unsigned int nChannels,
+                   StkFormat format, StkFloat rate );
+
+  // Get WAV file header information.
+  bool getWavInfo( const char *fileName );
+
+  // Get SND (AU) file header information.
+  bool getSndInfo( const char *fileName );
+
+  // Get AIFF file header information.
+  bool getAifInfo( const char *fileName );
+
+  // Get MAT-file header information.
+  bool getMatInfo( const char *fileName );
+
+  FILE *fd_;
+  bool byteswap_;
+  bool wavFile_;
+  unsigned long fileSize_;
+  unsigned long dataOffset_;
+  unsigned int channels_;
+  StkFormat dataType_;
+  StkFloat fileRate_;
+};
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/FileWrite.h b/lib/MoMu-STK-1.0.0/include/FileWrite.h
new file mode 100644 (file)
index 0000000..1692216
--- /dev/null
@@ -0,0 +1,116 @@
+#ifndef STK_FILEWRITE_H
+#define STK_FILEWRITE_H
+
+#include "Stk.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class FileWrite
+    \brief STK audio file output class.
+
+    This class provides output support for various
+    audio file formats.
+
+    FileWrite writes samples to an audio file.  It supports
+    multi-channel data.
+
+    FileWrite currently supports uncompressed WAV, AIFF, AIFC, SND
+    (AU), MAT-file (Matlab), and STK RAW file formats.  Signed integer
+    (8-, 16-, and 32-bit) and floating- point (32- and 64-bit) data
+    types are supported.  STK RAW files use 16-bit integers by
+    definition.  MAT-files will always be written as 64-bit floats.
+    If a data type specification does not match the specified file
+    type, the data type will automatically be modified.  Compressed
+    data types are not supported.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class FileWrite : public Stk
+{
+ public:
+
+  typedef unsigned long FILE_TYPE;
+
+  static const FILE_TYPE FILE_RAW; /*!< STK RAW file type. */
+  static const FILE_TYPE FILE_WAV; /*!< WAV file type. */
+  static const FILE_TYPE FILE_SND; /*!< SND (AU) file type. */
+  static const FILE_TYPE FILE_AIF; /*!< AIFF file type. */
+  static const FILE_TYPE FILE_MAT; /*!< Matlab MAT-file type. */
+
+  //! Default constructor.
+  FileWrite( void );
+
+  //! Overloaded constructor used to specify a file name, type, and data format with this object.
+  /*!
+    An StkError is thrown for invalid argument values or if an error occurs when initializing the output file.
+  */
+  FileWrite( std::string fileName, unsigned int nChannels = 1, FILE_TYPE type = FILE_WAV, Stk::StkFormat format = STK_SINT16 );
+
+  //! Class destructor.
+  virtual ~FileWrite();
+
+  //! Create a file of the specified type and name and output samples to it in the given data format.
+  /*!
+    An StkError is thrown for invalid argument values or if an error occurs when initializing the output file.
+  */
+  void open( std::string fileName, unsigned int nChannels = 1,
+             FileWrite::FILE_TYPE type = FILE_WAV, Stk::StkFormat format = STK_SINT16 );
+
+  //! If a file is open, write out samples in the queue and then close it.
+  void close( void );
+
+  //! Returns \e true if a file is currently open.
+  bool isOpen( void );
+
+  //! Write sample frames from the StkFrames object to the file.
+  /*!
+    An StkError will be thrown if the number of channels in the
+    StkFrames argument does not agree with the number of channels
+    specified when opening the file.
+   */
+  void write( StkFrames& buffer );
+
+ protected:
+
+  // Write STK RAW file header.
+  bool setRawFile( const char *fileName );
+
+  // Write WAV file header.
+  bool setWavFile( const char *fileName );
+
+  // Close WAV file, updating the header.
+  void closeWavFile( void );
+
+  // Write SND (AU) file header.
+  bool setSndFile( const char *fileName );
+
+  // Close SND file, updating the header.
+  void closeSndFile( void );
+
+  // Write AIFF file header.
+  bool setAifFile( const char *fileName );
+
+  // Close AIFF file, updating the header.
+  void closeAifFile( void );
+
+  // Write MAT-file header.
+  bool setMatFile( const char *fileName );
+
+  // Close MAT-file, updating the header.
+  void closeMatFile( void );
+
+  FILE *fd_;
+  FILE_TYPE fileType_;
+  StkFormat dataType_;
+  unsigned int channels_;
+  unsigned long frameCounter_;
+  bool byteswap_;
+
+};
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/FileWvIn.h b/lib/MoMu-STK-1.0.0/include/FileWvIn.h
new file mode 100644 (file)
index 0000000..64b782b
--- /dev/null
@@ -0,0 +1,193 @@
+#ifndef STK_FILEWVIN_H
+#define STK_FILEWVIN_H
+
+#include "WvIn.h"
+#include "FileRead.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class FileWvIn
+    \brief STK audio file input class.
+
+    This class inherits from WvIn.  It provides a "tick-level"
+    interface to the FileRead class.  It also provides variable-rate
+    playback functionality.  Audio file support is provided by the
+    FileRead class.  Linear interpolation is used for fractional read
+    rates.
+
+    FileWvIn supports multi-channel data.  It is important to
+    distinguish the tick() method that computes a single frame (and
+    returns only the specified sample of a multi-channel frame) from
+    the overloaded one that takes an StkFrames object for
+    multi-channel and/or multi-frame data.
+
+    FileWvIn will either load the entire content of an audio file into
+    local memory or incrementally read file data from disk in chunks.
+    This behavior is controlled by the optional constructor arguments
+    \e chunkThreshold and \e chunkSize.  File sizes greater than \e
+    chunkThreshold (in sample frames) will be read incrementally in
+    chunks of \e chunkSize each (also in sample frames).
+
+    When the file end is reached, subsequent calls to the tick()
+    functions return zeros and isFinished() returns \e true.
+
+    See the FileRead class for a description of the supported audio
+    file formats.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class FileWvIn : public WvIn
+{
+public:
+  //! Default constructor.
+  FileWvIn( unsigned long chunkThreshold = 1000000, unsigned long chunkSize = 1024 );
+
+  //! Overloaded constructor for file input.
+  /*!
+    An StkError will be thrown if the file is not found, its format is
+    unknown, or a read error occurs.
+  */
+  FileWvIn( std::string fileName, bool raw = false, bool doNormalize = true,
+            unsigned long chunkThreshold = 1000000, unsigned long chunkSize = 1024 );
+
+  //! Class destructor.
+  ~FileWvIn( void );
+
+  //! Open the specified file and load its data.
+  /*!
+    Data from a previously opened file will be overwritten by this
+    function.  An StkError will be thrown if the file is not found,
+    its format is unknown, or a read error occurs.  If the file data
+    is to be loaded incrementally from disk and normalization is
+    specified, a scaling will be applied with respect to fixed-point
+    limits.  If the data format is floating-point, no scaling is
+    performed.
+  */
+  virtual void openFile( std::string fileName, bool raw = false, bool doNormalize = true );
+
+  //! Close a file if one is open.
+  virtual void closeFile( void );
+
+  //! Clear outputs and reset time (file) pointer to zero.
+  virtual void reset( void );
+
+  //! Normalize data to a maximum of +-1.0.
+  /*!
+    This function has no effect when data is incrementally loaded
+    from disk.
+  */
+  virtual void normalize( void );
+
+  //! Normalize data to a maximum of \e +-peak.
+  /*!
+    This function has no effect when data is incrementally loaded
+    from disk.
+  */
+  virtual void normalize( StkFloat peak );
+
+  //! Return the file size in sample frames.
+  virtual unsigned long getSize( void ) const { return data_.frames(); };
+
+  //! Return the input file sample rate in Hz (not the data read rate).
+  /*!
+    WAV, SND, and AIF formatted files specify a sample rate in
+    their headers.  STK RAW files have a sample rate of 22050 Hz
+    by definition.  MAT-files are assumed to have a rate of 44100 Hz.
+  */
+  virtual StkFloat getFileRate( void ) const { return data_.dataRate(); };
+
+  //! Query whether reading is complete.
+  bool isFinished( void ) const { return finished_; };
+
+  //! Set the data read rate in samples.  The rate can be negative.
+  /*!
+    If the rate value is negative, the data is read in reverse order.
+  */
+  virtual void setRate( StkFloat rate );
+
+  //! Increment the read pointer by \e time samples.
+  /*!
+    Note that this function will not modify the interpolation flag status.
+   */
+  virtual void addTime( StkFloat time );
+
+  //! Turn linear interpolation on/off.
+  /*!
+    Interpolation is automatically off when the read rate is
+    an integer value.  If interpolation is turned off for a
+    fractional rate, the time index is truncated to an integer
+    value.
+  */
+  void setInterpolate( bool doInterpolate ) { interpolate_ = doInterpolate; };
+
+  //! Return the specified channel value of the last computed frame.
+  /*!
+    If no file is loaded, the returned value is 0.0.  The \c
+    channel argument must be less than the number of output channels,
+    which can be determined with the channelsOut() function (the first
+    channel is specified by 0).  However, range checking is only
+    performed if _STK_DEBUG_ is defined during compilation, in which
+    case an out-of-range value will trigger an StkError exception. \sa
+    lastFrame()
+  */
+  StkFloat lastOut( unsigned int channel = 0 );
+
+  //! Compute a sample frame and return the specified \c channel value.
+  /*!
+    For multi-channel files, use the lastFrame() function to get
+    all values from the computed frame.  If no file data is loaded,
+    the returned value is 0.0.  The \c channel argument must be less
+    than the number of channels in the file data (the first channel is
+    specified by 0).  However, range checking is only performed if
+    _STK_DEBUG_ is defined during compilation, in which case an
+    out-of-range value will trigger an StkError exception.
+  */
+  virtual StkFloat tick( unsigned int channel = 0 );
+
+  //! Fill the StkFrames argument with computed frames and return the same reference.
+  /*!
+    The number of channels in the StkFrames argument must equal
+    the number of channels in the file data.  However, this is only
+    checked if _STK_DEBUG_ is defined during compilation, in which
+    case an incompatibility will trigger an StkError exception.  If no
+    file data is loaded, the function does nothing (a warning will be
+    issued if _STK_DEBUG_ is defined during compilation).
+  */
+  virtual StkFrames& tick( StkFrames& frames );
+
+protected:
+
+  void sampleRateChanged( StkFloat newRate, StkFloat oldRate );
+
+  FileRead file_;
+  bool finished_;
+  bool interpolate_;
+  bool normalizing_;
+  bool chunking_;
+  StkFloat time_;
+  StkFloat rate_;
+  unsigned long chunkThreshold_;
+  unsigned long chunkSize_;
+  long chunkPointer_;
+
+};
+
+inline StkFloat FileWvIn :: lastOut( unsigned int channel )
+{
+#if defined(_STK_DEBUG_)
+  if ( channel >= data_.channels() ) {
+    errorString_ << "FileWvIn::lastOut(): channel argument and soundfile data are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  if ( finished_ ) return 0.0;
+  return lastFrame_[channel];
+}
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/FileWvOut.h b/lib/MoMu-STK-1.0.0/include/FileWvOut.h
new file mode 100644 (file)
index 0000000..e6bf5ae
--- /dev/null
@@ -0,0 +1,102 @@
+#ifndef STK_FILEWVOUT_H
+#define STK_FILEWVOUT_H
+
+#include "WvOut.h"
+#include "FileWrite.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class FileWvOut
+    \brief STK audio file output class.
+
+    This class inherits from WvOut.  It provides a "tick-level"
+    interface to the FileWrite class.
+
+    FileWvOut writes samples to an audio file and supports
+    multi-channel data.  It is important to distinguish the tick()
+    method that outputs a single sample to all channels in a sample
+    frame from the overloaded one that takes a reference to an
+    StkFrames object for multi-channel and/or multi-frame data.
+
+    See the FileWrite class for a description of the supported audio
+    file formats.
+
+    Currently, FileWvOut is non-interpolating and the output rate is
+    always Stk::sampleRate().
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class FileWvOut : public WvOut
+{
+ public:
+
+  //! Default constructor with optional output buffer size argument.
+  /*!
+    The output buffer size defines the number of frames that are
+    accumulated between writes to disk.
+  */
+  FileWvOut( unsigned int bufferFrames = 1024 );
+
+  //! Overloaded constructor used to specify a file name, type, and data format with this object.
+  /*!
+    An StkError is thrown for invalid argument values or if an error occurs when initializing the output file.
+  */
+  FileWvOut( std::string fileName,
+             unsigned int nChannels = 1,
+             FileWrite::FILE_TYPE type = FileWrite::FILE_WAV,
+             Stk::StkFormat format = STK_SINT16,
+             unsigned int bufferFrames = 1024 );
+
+  //! Class destructor.
+  virtual ~FileWvOut();
+
+  //! Open a new file with the specified parameters.
+  /*!
+    If a file was previously open, it will be closed.  An StkError
+    will be thrown if any of the specified arguments are invalid or a
+    file error occurs during opening.
+  */
+  void openFile( std::string fileName,
+                 unsigned int nChannels,
+                 FileWrite::FILE_TYPE type,
+                 Stk::StkFormat format );
+
+  //! Close a file if one is open.
+  /*!
+    Any data remaining in the internal buffer will be written to
+    the file before closing.
+  */
+  void closeFile( void );
+
+  //! Output a single sample to all channels in a sample frame.
+  /*!
+    An StkError is thrown if an output error occurs.
+  */
+  void tick( const StkFloat sample );
+
+  //! Output the StkFrames data.
+  /*!
+    An StkError will be thrown if an output error occurs.  An
+    StkError will also be thrown if _STK_DEBUG_ is defined during
+    compilation and there is an incompatability between the number of
+    channels in the FileWvOut object and that in the StkFrames object.
+  */
+  void tick( const StkFrames& frames );
+
+ protected:
+
+  void incrementFrame( void );
+
+  FileWrite file_;
+  unsigned int bufferFrames_;
+  unsigned int bufferIndex_;
+  unsigned int iData_;
+
+};
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/Filter.h b/lib/MoMu-STK-1.0.0/include/Filter.h
new file mode 100644 (file)
index 0000000..79963de
--- /dev/null
@@ -0,0 +1,86 @@
+#ifndef STK_FILTER_H
+#define STK_FILTER_H
+
+#include "Stk.h"
+#include <vector>
+
+namespace stk {
+
+/***************************************************/
+/*! \class Filter
+    \brief STK abstract filter class.
+
+    This class provides limited common functionality for STK digital
+    filter subclasses.  It is general enough to support both
+    monophonic and polyphonic input/output classes.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class Filter : public Stk
+{
+public:
+  //! Class constructor.
+  Filter( void ) { gain_ = 1.0; channelsIn_ = 1; lastFrame_.resize( 1, 1, 0.0 ); };
+
+  //! Return the number of input channels for the class.
+  unsigned int channelsIn( void ) const { return channelsIn_; };
+
+  //! Return the number of output channels for the class.
+  unsigned int channelsOut( void ) const { return lastFrame_.channels(); };
+
+  //! Clears all internal states of the filter.
+  virtual void clear( void );
+
+  //! Set the filter gain.
+  /*!
+    The gain is applied at the filter input and does not affect the
+    coefficient values.  The default gain value is 1.0.
+   */
+  void setGain( StkFloat gain ) { gain_ = gain; };
+
+  //! Return the current filter gain.
+  StkFloat getGain( void ) const { return gain_; };
+
+  //! Return an StkFrames reference to the last output sample frame.
+  const StkFrames& lastFrame( void ) const { return lastFrame_; };
+
+  //! Take a channel of the StkFrames object as inputs to the filter and replace with corresponding outputs.
+  /*!
+    The StkFrames argument reference is returned.  The \c channel
+    argument must be less than the number of channels in the
+    StkFrames argument (the first channel is specified by 0).
+    However, range checking is only performed if _STK_DEBUG_ is
+    defined during compilation, in which case an out-of-range value
+    will trigger an StkError exception.
+  */
+  virtual StkFrames& tick( StkFrames& frames, unsigned int channel = 0 ) = 0;
+
+protected:
+
+  unsigned int channelsIn_;
+  StkFrames lastFrame_;
+
+  StkFloat gain_;
+  std::vector<StkFloat> b_;
+  std::vector<StkFloat> a_;
+  StkFrames outputs_;
+  StkFrames inputs_;
+
+};
+
+inline void Filter :: clear( void )
+{
+  unsigned int i;
+  for ( i=0; i<inputs_.size(); i++ )
+    inputs_[i] = 0.0;
+  for ( i=0; i<outputs_.size(); i++ )
+    outputs_[i] = 0.0;
+  for ( i=0; i<lastFrame_.size(); i++ )
+    lastFrame_[i] = 0.0;  
+}
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/Fir.h b/lib/MoMu-STK-1.0.0/include/Fir.h
new file mode 100644 (file)
index 0000000..c68dde4
--- /dev/null
@@ -0,0 +1,155 @@
+#ifndef STK_FIR_H
+#define STK_FIR_H
+
+#include "Filter.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class Fir
+    \brief STK general finite impulse response filter class.
+
+    This class provides a generic digital filter structure that can be
+    used to implement FIR filters.  For filters with feedback terms,
+    the Iir class should be used.
+
+    In particular, this class implements the standard difference
+    equation:
+
+    y[n] = b[0]*x[n] + ... + b[nb]*x[n-nb]
+
+    The \e gain parameter is applied at the filter input and does not
+    affect the coefficient values.  The default gain value is 1.0.
+    This structure results in one extra multiply per computed sample,
+    but allows easy control of the overall filter gain.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class Fir : public Filter
+{
+public:
+  //! Default constructor creates a zero-order pass-through "filter".
+  Fir( void );
+
+  //! Overloaded constructor which takes filter coefficients.
+  /*!
+    An StkError can be thrown if the coefficient vector size is
+    zero.
+  */
+  Fir( std::vector<StkFloat> &coefficients );
+
+  //! Class destructor.
+  ~Fir( void );
+
+  //! Set filter coefficients.
+  /*!
+    An StkError can be thrown if the coefficient vector size is
+    zero.  The internal state of the filter is not cleared unless the
+    \e clearState flag is \c true.
+  */
+  void setCoefficients( std::vector<StkFloat> &coefficients, bool clearState = false );
+
+  //! Return the last computed output value.
+  StkFloat lastOut( void ) const { return lastFrame_[0]; };
+
+  //! Input one sample to the filter and return one output.
+  StkFloat tick( StkFloat input );
+
+  //! Take a channel of the StkFrames object as inputs to the filter and replace with corresponding outputs.
+  /*!
+    The StkFrames argument reference is returned.  The \c channel
+    argument must be less than the number of channels in the
+    StkFrames argument (the first channel is specified by 0).
+    However, range checking is only performed if _STK_DEBUG_ is
+    defined during compilation, in which case an out-of-range value
+    will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
+
+  //! Take a channel of the \c iFrames object as inputs to the filter and write outputs to the \c oFrames object.
+  /*!
+    The \c iFrames object reference is returned.  Each channel
+    argument must be less than the number of channels in the
+    corresponding StkFrames argument (the first channel is specified
+    by 0).  However, range checking is only performed if _STK_DEBUG_
+    is defined during compilation, in which case an out-of-range value
+    will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0, unsigned int oChannel = 0 );
+
+protected:
+
+};
+
+inline StkFloat Fir :: tick( StkFloat input )
+{
+  lastFrame_[0] = 0.0;
+  inputs_[0] = gain_ * input;
+
+  for ( unsigned int i=b_.size()-1; i>0; i-- ) {
+    lastFrame_[0] += b_[i] * inputs_[i];
+    inputs_[i] = inputs_[i-1];
+  }
+  lastFrame_[0] += b_[0] * inputs_[0];
+
+  return lastFrame_[0];
+}
+
+inline StkFrames& Fir :: tick( StkFrames& frames, unsigned int channel )
+{
+#if defined(_STK_DEBUG_)
+  if ( channel >= frames.channels() ) {
+    errorString_ << "Fir::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *samples = &frames[channel];
+  unsigned int i, hop = frames.channels();
+  for ( unsigned int j=0; j<frames.frames(); j++, samples += hop ) {
+    inputs_[0] = gain_ * *samples;
+    *samples = 0.0;
+
+    for ( i=b_.size()-1; i>0; i-- ) {
+      *samples += b_[i] * inputs_[i];
+      inputs_[i] = inputs_[i-1];
+    }
+    *samples += b_[0] * inputs_[0];
+  }
+
+  lastFrame_[0] = *(samples-hop);
+  return frames;
+}
+
+inline StkFrames& Fir :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iChannel, unsigned int oChannel )
+{
+#if defined(_STK_DEBUG_)
+  if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
+    errorString_ << "Fir::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *iSamples = &iFrames[iChannel];
+  StkFloat *oSamples = &oFrames[oChannel];
+  unsigned int i, iHop = iFrames.channels(), oHop = oFrames.channels();
+  for ( unsigned int j=0; j<iFrames.frames(); j++, iSamples += iHop, oSamples += oHop ) {
+    inputs_[0] = gain_ * *iSamples;
+    *oSamples = 0.0;
+
+    for ( i=b_.size()-1; i>0; i-- ) {
+      *oSamples += b_[i] * inputs_[i];
+      inputs_[i] = inputs_[i-1];
+    }
+    *oSamples += b_[0] * inputs_[0];
+  }
+
+  lastFrame_[0] = *(oSamples-oHop);
+  return iFrames;
+}
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/Flute.h b/lib/MoMu-STK-1.0.0/include/Flute.h
new file mode 100644 (file)
index 0000000..ca7549d
--- /dev/null
@@ -0,0 +1,129 @@
+#ifndef STK_FLUTE_H
+#define STK_FLUTE_H
+
+#include "Instrmnt.h"
+#include "JetTable.h"
+#include "DelayL.h"
+#include "OnePole.h"
+#include "PoleZero.h"
+#include "Noise.h"
+#include "ADSR.h"
+#include "SineWave.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class Flute
+    \brief STK flute physical model class.
+
+    This class implements a simple flute
+    physical model, as discussed by Karjalainen,
+    Smith, Waryznyk, etc.  The jet model uses
+    a polynomial, a la Cook.
+
+    This is a digital waveguide model, making its
+    use possibly subject to patents held by Stanford
+    University, Yamaha, and others.
+
+    Control Change Numbers: 
+       - Jet Delay = 2
+       - Noise Gain = 4
+       - Vibrato Frequency = 11
+       - Vibrato Gain = 1
+       - Breath Pressure = 128
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class Flute : public Instrmnt
+{
+ public:
+  //! Class constructor, taking the lowest desired playing frequency.
+  /*!
+    An StkError will be thrown if the rawwave path is incorrectly set.
+  */
+  Flute( StkFloat lowestFrequency );
+
+  //! Class destructor.
+  ~Flute( void );
+
+  //! Reset and clear all internal state.
+  void clear( void );
+
+  //! Set instrument parameters for a particular frequency.
+  void setFrequency( StkFloat frequency );
+
+  //! Set the reflection coefficient for the jet delay (-1.0 - 1.0).
+  void setJetReflection( StkFloat coefficient );
+
+  //! Set the reflection coefficient for the air column delay (-1.0 - 1.0).
+  void setEndReflection( StkFloat coefficient );
+
+  //! Set the length of the jet delay in terms of a ratio of jet delay to air column delay lengths.
+  void setJetDelay( StkFloat aRatio );
+
+  //! Apply breath velocity to instrument with given amplitude and rate of increase.
+  void startBlowing( StkFloat amplitude, StkFloat rate );
+
+  //! Decrease breath velocity with given rate of decrease.
+  void stopBlowing( StkFloat rate );
+
+  //! Start a note with the given frequency and amplitude.
+  void noteOn( StkFloat frequency, StkFloat amplitude );
+
+  //! Stop a note with the given amplitude (speed of decay).
+  void noteOff( StkFloat amplitude );
+
+  //! Perform the control change specified by \e number and \e value (0.0 - 128.0).
+  void controlChange( int number, StkFloat value );
+
+  //! Compute and return one output sample.
+  StkFloat tick( unsigned int channel = 0 );
+
+ protected:
+
+  DelayL   jetDelay_;
+  DelayL   boreDelay_;
+  JetTable jetTable_;
+  OnePole  filter_;
+  PoleZero dcBlock_;
+  Noise    noise_;
+  ADSR     adsr_;
+  SineWave vibrato_;
+  unsigned long length_;
+  StkFloat lastFrequency_;
+  StkFloat maxPressure_;
+  StkFloat jetReflection_;
+  StkFloat endReflection_;
+  StkFloat noiseGain_;
+  StkFloat vibratoGain_;
+  StkFloat outputGain_;
+  StkFloat jetRatio_;
+
+};
+
+inline StkFloat Flute :: tick( unsigned int )
+{
+  StkFloat pressureDiff;
+  StkFloat breathPressure;
+
+  // Calculate the breath pressure (envelope + noise + vibrato)
+  breathPressure = maxPressure_ * adsr_.tick();
+  breathPressure += breathPressure * ( noiseGain_ * noise_.tick() + vibratoGain_ * vibrato_.tick() );
+
+  StkFloat temp = filter_.tick( boreDelay_.lastOut() );
+  temp = dcBlock_.tick( temp ); // Block DC on reflection.
+
+  pressureDiff = breathPressure - (jetReflection_ * temp);
+  pressureDiff = jetDelay_.tick( pressureDiff );
+  pressureDiff = jetTable_.tick( pressureDiff ) + (endReflection_ * temp);
+  lastFrame_[0] = (StkFloat) 0.3 * boreDelay_.tick( pressureDiff );
+
+  lastFrame_[0] *= outputGain_;
+  return lastFrame_[0];
+}
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/FormSwep.h b/lib/MoMu-STK-1.0.0/include/FormSwep.h
new file mode 100644 (file)
index 0000000..6155425
--- /dev/null
@@ -0,0 +1,188 @@
+#ifndef STK_FORMSWEP_H
+#define STK_FORMSWEP_H
+
+#include "Filter.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class FormSwep
+    \brief STK sweepable formant filter class.
+
+    This class implements a formant (resonance) which can be "swept"
+    over time from one frequency setting to another.  It provides
+    methods for controlling the sweep rate and target frequency.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class FormSwep : public Filter
+{
+ public:
+
+  //! Default constructor creates a second-order pass-through filter.
+  FormSwep( void );
+
+  //! Class destructor.
+  ~FormSwep();
+
+  //! A function to enable/disable the automatic updating of class data when the STK sample rate changes.
+  void ignoreSampleRateChange( bool ignore = true ) { ignoreSampleRateChange_ = ignore; };
+
+  //! Sets the filter coefficients for a resonance at \e frequency (in Hz).
+  /*!
+    This method determines the filter coefficients corresponding to
+    two complex-conjugate poles with the given \e frequency (in Hz)
+    and \e radius from the z-plane origin.  The filter zeros are
+    placed at z = 1, z = -1, and the coefficients are then normalized to
+    produce a constant unity gain (independent of the filter \e gain
+    parameter).  The resulting filter frequency response has a
+    resonance at the given \e frequency.  The closer the poles are to
+    the unit-circle (\e radius close to one), the narrower the
+    resulting resonance width.
+  */
+  void setResonance( StkFloat frequency, StkFloat radius );
+
+  //! Set both the current and target resonance parameters.
+  void setStates( StkFloat frequency, StkFloat radius, StkFloat gain = 1.0 );
+
+  //! Set target resonance parameters.
+  void setTargets( StkFloat frequency, StkFloat radius, StkFloat gain = 1.0 );
+
+  //! Set the sweep rate (between 0.0 - 1.0).
+  /*!
+    The formant parameters are varied in increments of the
+    sweep rate between their current and target values.
+    A sweep rate of 1.0 will produce an immediate change in
+    resonance parameters from their current values to the
+    target values.  A sweep rate of 0.0 will produce no
+    change in resonance parameters.  
+  */
+  void setSweepRate( StkFloat rate );
+
+  //! Set the sweep rate in terms of a time value in seconds.
+  /*!
+    This method adjusts the sweep rate based on a
+    given time for the formant parameters to reach
+    their target values.
+  */
+  void setSweepTime( StkFloat time );
+
+  //! Return the last computed output value.
+  StkFloat lastOut( void ) const { return lastFrame_[0]; };
+
+  //! Input one sample to the filter and return a reference to one output.
+  StkFloat tick( StkFloat input );
+
+  //! Take a channel of the StkFrames object as inputs to the filter and replace with corresponding outputs.
+  /*!
+    The StkFrames argument reference is returned.  The \c channel
+    argument must be less than the number of channels in the
+    StkFrames argument (the first channel is specified by 0).
+    However, range checking is only performed if _STK_DEBUG_ is
+    defined during compilation, in which case an out-of-range value
+    will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
+
+  //! Take a channel of the \c iFrames object as inputs to the filter and write outputs to the \c oFrames object.
+  /*!
+    The \c iFrames object reference is returned.  Each channel
+    argument must be less than the number of channels in the
+    corresponding StkFrames argument (the first channel is specified
+    by 0).  However, range checking is only performed if _STK_DEBUG_
+    is defined during compilation, in which case an out-of-range value
+    will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0, unsigned int oChannel = 0 );
+
+ protected:
+
+  virtual void sampleRateChanged( StkFloat newRate, StkFloat oldRate );
+
+  bool dirty_;
+  StkFloat frequency_;
+  StkFloat radius_;
+  StkFloat startFrequency_;
+  StkFloat startRadius_;
+  StkFloat startGain_;
+  StkFloat targetFrequency_;
+  StkFloat targetRadius_;
+  StkFloat targetGain_;
+  StkFloat deltaFrequency_;
+  StkFloat deltaRadius_;
+  StkFloat deltaGain_;
+  StkFloat sweepState_;
+  StkFloat sweepRate_;
+
+};
+
+inline StkFloat FormSwep :: tick( StkFloat input )
+{                                     
+  if ( dirty_ )  {
+    sweepState_ += sweepRate_;
+    if ( sweepState_ >= 1.0 )   {
+      sweepState_ = 1.0;
+      dirty_ = false;
+      radius_ = targetRadius_;
+      frequency_ = targetFrequency_;
+      gain_ = targetGain_;
+    }
+    else {
+      radius_ = startRadius_ + (deltaRadius_ * sweepState_);
+      frequency_ = startFrequency_ + (deltaFrequency_ * sweepState_);
+      gain_ = startGain_ + (deltaGain_ * sweepState_);
+    }
+    this->setResonance( frequency_, radius_ );
+  }
+
+  inputs_[0] = gain_ * input;
+  lastFrame_[0] = b_[0] * inputs_[0] + b_[1] * inputs_[1] + b_[2] * inputs_[2];
+  lastFrame_[0] -= a_[2] * outputs_[2] + a_[1] * outputs_[1];
+  inputs_[2] = inputs_[1];
+  inputs_[1] = inputs_[0];
+  outputs_[2] = outputs_[1];
+  outputs_[1] = lastFrame_[0];
+
+  return lastFrame_[0];
+}
+
+inline StkFrames& FormSwep :: tick( StkFrames& frames, unsigned int channel )
+{
+#if defined(_STK_DEBUG_)
+  if ( channel >= frames.channels() ) {
+    errorString_ << "FormSwep::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *samples = &frames[channel];
+  unsigned int hop = frames.channels();
+  for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
+    *samples = tick( *samples );
+
+  return frames;
+}
+
+inline StkFrames& FormSwep :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iChannel, unsigned int oChannel )
+{
+#if defined(_STK_DEBUG_)
+  if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
+    errorString_ << "FormSwep::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *iSamples = &iFrames[iChannel];
+  StkFloat *oSamples = &oFrames[oChannel];
+  unsigned int iHop = iFrames.channels(), oHop = oFrames.channels();
+  for ( unsigned int i=0; i<iFrames.frames(); i++, iSamples += iHop, oSamples += oHop )
+    *oSamples = tick( *iSamples );
+
+  return iFrames;
+}
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/Function.h b/lib/MoMu-STK-1.0.0/include/Function.h
new file mode 100644 (file)
index 0000000..6ee2ebc
--- /dev/null
@@ -0,0 +1,41 @@
+#ifndef STK_FUNCTION_H
+#define STK_FUNCTION_H
+
+#include "Stk.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class Function
+    \brief STK abstract function parent class.
+
+    This class provides common functionality for STK classes that
+    implement tables or other types of input to output function
+    mappings.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class Function : public Stk
+{
+ public:
+  //! Class constructor.
+  Function( void ) { lastFrame_.resize( 1, 1, 0.0 ); };
+
+  //! Return the last computed output sample.
+  StkFloat lastOut( void ) const { return lastFrame_[0]; };
+
+  //! Take one sample input and compute one sample of output.
+  virtual StkFloat tick( StkFloat input ) = 0;
+
+ protected:
+
+  StkFrames lastFrame_;
+
+};
+
+} // stk namespace
+
+#endif
+
diff --git a/lib/MoMu-STK-1.0.0/include/Generator.h b/lib/MoMu-STK-1.0.0/include/Generator.h
new file mode 100644 (file)
index 0000000..0256ede
--- /dev/null
@@ -0,0 +1,50 @@
+#ifndef STK_GENERATOR_H
+#define STK_GENERATOR_H
+
+#include "Stk.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class Generator
+    \brief STK abstract unit generator parent class.
+
+    This class provides limited common functionality for STK unit
+    generator sample-source subclasses.  It is general enough to
+    support both monophonic and polyphonic output classes.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class Generator : public Stk
+{
+ public:
+
+  //! Class constructor.
+  Generator( void ) { lastFrame_.resize( 1, 1, 0.0 ); };
+
+  //! Return the number of output channels for the class.
+  unsigned int channelsOut( void ) const { return lastFrame_.channels(); };
+
+  //! Return an StkFrames reference to the last output sample frame.
+  const StkFrames& lastFrame( void ) const { return lastFrame_; };
+
+  //! Fill the StkFrames object with computed sample frames, starting at the specified channel.
+  /*!
+    The \c channel argument plus the number of output channels must
+    be less than the number of channels in the StkFrames argument (the
+    first channel is specified by 0).  However, range checking is only
+    performed if _STK_DEBUG_ is defined during compilation, in which
+    case an out-of-range value will trigger an StkError exception.
+  */
+  virtual StkFrames& tick( StkFrames& frames, unsigned int channel = 0 ) = 0;
+
+  protected:
+
+  StkFrames lastFrame_;
+};
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/Granulate.h b/lib/MoMu-STK-1.0.0/include/Granulate.h
new file mode 100644 (file)
index 0000000..afbb701
--- /dev/null
@@ -0,0 +1,209 @@
+#ifndef STK_GRANULATE_H
+#define STK_GRANULATE_H
+
+#include <vector>
+#include "Generator.h"
+#include "Envelope.h"
+#include "Noise.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class Granulate
+    \brief STK granular synthesis class.
+
+    This class implements a real-time granular synthesis algorithm
+    that operates on an input soundfile.  Multi-channel files are
+    supported.  Various functions are provided to allow control over
+    voice and grain parameters.
+
+    The functionality of this class is based on the program MacPod by
+    Chris Rolfe and Damian Keller, though there are likely to be a
+    number of differences in the actual implementation.
+
+    by Gary Scavone, 2005 - 2010.
+*/
+/***************************************************/
+
+class Granulate: public Generator
+{
+ public:
+  //! Default constructor.
+  Granulate( void );
+
+  //! Constructor taking input audio file and number of voices arguments.
+  Granulate( unsigned int nVoices, std::string fileName, bool typeRaw = false );
+
+  //! Class destructor.
+  ~Granulate( void );
+
+  //! Load a monophonic soundfile to be "granulated".
+  /*!
+    An StkError will be thrown if the file is not found, its format
+    is unknown or unsupported, or the file has more than one channel.
+  */
+  void openFile( std::string fileName, bool typeRaw = false );
+
+  //! Reset the file pointer and all existing grains to the file start.
+  /*!
+    Multiple grains are offset from one another in time by grain
+    duration / nVoices.
+  */
+  void reset( void );
+
+  //! Set the number of simultaneous grain "voices" to use.
+  /*!
+    Multiple grains are offset from one another in time by grain
+    duration / nVoices.  For this reason, it is best to set the grain
+    parameters before calling this function (during initialization).
+  */
+  void setVoices( unsigned int nVoices = 1 );
+
+  //! Set the stretch factor used for grain playback (1 - 1000).
+  /*!
+    Granular synthesis allows for time-stetching without affecting
+    the original pitch of a sound.  A stretch factor of 4 will produce
+    a resulting sound of length 4 times the orignal sound.  The
+    default parameter of 1 produces no stretching.
+  */
+  void setStretch( unsigned int stretchFactor = 1 );
+
+  //! Set global grain parameters used to determine individual grain settings.
+  /*!
+    Each grain is defined as having a length of \e duration
+    milliseconds which must be greater than zero.  For values of \e
+    rampPercent (0 - 100) greater than zero, a linear envelope will be
+    applied to each grain.  If \e rampPercent = 100, the resultant
+    grain "window" is triangular while \e rampPercent = 50 produces a
+    trapezoidal window.  In addition, each grain can have a time delay
+    of length \e delay and a grain pointer increment of length \e
+    offset, which can be negative, before the next ramp onset (in
+    milliseconds).  The \e offset parameter controls grain pointer
+    jumps between enveloped grain segments, while the \e delay
+    parameter causes grain calculations to pause between grains.  The
+    actual values calculated for each grain will be randomized by a
+    factor set using the setRandomFactor() function.
+  */
+  void setGrainParameters( unsigned int duration = 30, unsigned int rampPercent = 50,
+                           int offset = 0, unsigned int delay = 0 );
+
+  //! This factor is used when setting individual grain parameters (0.0 - 1.0).
+  /*!
+    This random factor is applied when all grain state durations
+    are calculated.  If set to 0.0, no randomness occurs.  When
+    randomness = 1.0, a grain segment of length \e duration will be
+    randomly augmented by up to +- \e duration seconds (i.e., a 30
+    millisecond length will be augmented by an extra length of up to
+    +30 or -30 milliseconds).
+   */
+  void setRandomFactor( StkFloat randomness = 0.1 );
+
+  //! Return the specified channel value of the last computed frame.
+  /*!
+    The \c channel argument must be less than the number of output
+    channels, which can be determined with the channelsOut() function
+    (the first channel is specified by 0).  However, range checking is
+    only performed if _STK_DEBUG_ is defined during compilation, in
+    which case an out-of-range value will trigger an StkError
+    exception. \sa lastFrame()
+  */
+  StkFloat lastOut( unsigned int channel = 0 );
+
+  //! Compute one sample frame and return the specified \c channel value.
+  StkFloat tick( unsigned int channel = 0 );
+
+  //! Fill the StkFrames object with computed sample frames, starting at the specified channel.
+  /*!
+    The \c channel argument plus the number of output channels must
+    be less than the number of channels in the StkFrames argument (the
+    first channel is specified by 0).  However, range checking is only
+    performed if _STK_DEBUG_ is defined during compilation, in which
+    case an out-of-range value will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
+
+  enum GrainState {
+    GRAIN_STOPPED,
+    GRAIN_FADEIN,
+    GRAIN_SUSTAIN,
+    GRAIN_FADEOUT
+  };
+
+ protected:
+
+  struct Grain {
+    StkFloat eScaler;
+    StkFloat eRate;
+    unsigned long attackCount;
+    unsigned long sustainCount;
+    unsigned long decayCount;
+    unsigned long delayCount;
+    unsigned long counter;
+    //unsigned long pointer;
+    StkFloat pointer;
+    unsigned long startPointer;
+    unsigned int repeats;
+    GrainState state;
+
+    // Default constructor.
+    Grain()
+      :eScaler(0.0), eRate(0.0), attackCount(0), sustainCount(0), decayCount(0),
+       delayCount(0), counter(0), pointer(0), startPointer(0), repeats(0), state(GRAIN_STOPPED) {}
+  };
+
+  void calculateGrain( Granulate::Grain& grain );
+
+  StkFrames data_;
+  std::vector<Grain> grains_;
+  Noise noise;
+  //long gPointer_;
+  StkFloat gPointer_;
+
+  // Global grain parameters.
+  unsigned int gDuration_;
+  unsigned int gRampPercent_;
+  unsigned int gDelay_;
+  unsigned int gStretch_;
+  unsigned int stretchCounter_;
+  int gOffset_;
+  StkFloat gRandomFactor_;
+  StkFloat gain_;
+
+};
+
+inline StkFloat Granulate :: lastOut( unsigned int channel )
+{
+#if defined(_STK_DEBUG_)
+  if ( channel >= lastFrame_.channels() ) {
+    errorString_ << "Granulate::lastOut(): channel argument is invalid!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  return lastFrame_[channel];
+}
+
+inline StkFrames& Granulate :: tick( StkFrames& frames, unsigned int channel )
+{
+  unsigned int nChannels = lastFrame_.channels();
+#if defined(_STK_DEBUG_)
+  if ( channel > frames.channels() - nChannels ) {
+    errorString_ << "Granulate::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *samples = &frames[channel];
+  unsigned int j, hop = frames.channels() - nChannels;
+  for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
+    *samples++ = tick();
+    for ( j=1; j<nChannels; j++ )
+      *samples++ = lastFrame_[j];
+  }
+
+  return frames;
+}
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/HevyMetl.h b/lib/MoMu-STK-1.0.0/include/HevyMetl.h
new file mode 100644 (file)
index 0000000..b16a9d6
--- /dev/null
@@ -0,0 +1,89 @@
+#ifndef STK_HEVYMETL_H
+#define STK_HEVYMETL_H
+
+#include "FM.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class HevyMetl
+    \brief STK heavy metal FM synthesis instrument.
+
+    This class implements 3 cascade operators with
+    feedback modulation, also referred to as
+    algorithm 3 of the TX81Z.
+
+    \code
+    Algorithm 3 is :    4--\
+                    3-->2-- + -->1-->Out
+    \endcode
+
+    Control Change Numbers: 
+       - Total Modulator Index = 2
+       - Modulator Crossfade = 4
+       - LFO Speed = 11
+       - LFO Depth = 1
+       - ADSR 2 & 4 Target = 128
+
+    The basic Chowning/Stanford FM patent expired
+    in 1995, but there exist follow-on patents,
+    mostly assigned to Yamaha.  If you are of the
+    type who should worry about this (making
+    money) worry away.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class HevyMetl : public FM
+{
+ public:
+  //! Class constructor.
+  /*!
+    An StkError will be thrown if the rawwave path is incorrectly set.
+  */
+  HevyMetl( void );
+
+  //! Class destructor.
+  ~HevyMetl( void );
+
+  //! Start a note with the given frequency and amplitude.
+  void noteOn( StkFloat frequency, StkFloat amplitude );
+
+  //! Compute and return one output sample.
+  StkFloat tick( unsigned int channel = 0 );
+
+ protected:
+
+};
+
+inline StkFloat HevyMetl :: tick( unsigned int )
+{
+  register StkFloat temp;
+
+  temp = vibrato_.tick() * modDepth_ * 0.2;    
+  waves_[0]->setFrequency(baseFrequency_ * (1.0 + temp) * ratios_[0]);
+  waves_[1]->setFrequency(baseFrequency_ * (1.0 + temp) * ratios_[1]);
+  waves_[2]->setFrequency(baseFrequency_ * (1.0 + temp) * ratios_[2]);
+  waves_[3]->setFrequency(baseFrequency_ * (1.0 + temp) * ratios_[3]);
+    
+  temp = gains_[2] * adsr_[2]->tick() * waves_[2]->tick();
+  waves_[1]->addPhaseOffset( temp );
+    
+  waves_[3]->addPhaseOffset( twozero_.lastOut() );
+  temp = (1.0 - (control2_ * 0.5)) * gains_[3] * adsr_[3]->tick() * waves_[3]->tick();
+  twozero_.tick(temp);
+    
+  temp += control2_ * 0.5 * gains_[1] * adsr_[1]->tick() * waves_[1]->tick();
+  temp = temp * control1_;
+    
+  waves_[0]->addPhaseOffset( temp );
+  temp = gains_[0] * adsr_[0]->tick() * waves_[0]->tick();
+    
+  lastFrame_[0] = temp * 0.5;
+  return lastFrame_[0];
+}
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/Iir.h b/lib/MoMu-STK-1.0.0/include/Iir.h
new file mode 100644 (file)
index 0000000..28f9b47
--- /dev/null
@@ -0,0 +1,202 @@
+#ifndef STK_IIR_H
+#define STK_IIR_H
+
+#include "Filter.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class Iir
+    \brief STK general infinite impulse response filter class.
+
+    This class provides a generic digital filter structure that can be
+    used to implement IIR filters.  For filters containing only
+    feedforward terms, the Fir class is slightly more efficient.
+
+    In particular, this class implements the standard difference
+    equation:
+
+    a[0]*y[n] = b[0]*x[n] + ... + b[nb]*x[n-nb] -
+                a[1]*y[n-1] - ... - a[na]*y[n-na]
+
+    If a[0] is not equal to 1, the filter coeffcients are normalized
+    by a[0].
+
+    The \e gain parameter is applied at the filter input and does not
+    affect the coefficient values.  The default gain value is 1.0.
+    This structure results in one extra multiply per computed sample,
+    but allows easy control of the overall filter gain.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class Iir : public Filter
+{
+public:
+  //! Default constructor creates a zero-order pass-through "filter".
+  Iir( void );
+
+  //! Overloaded constructor which takes filter coefficients.
+  /*!
+    An StkError can be thrown if either of the coefficient vector
+    sizes is zero, or if the a[0] coefficient is equal to zero.
+  */
+  Iir( std::vector<StkFloat> &bCoefficients, std::vector<StkFloat> &aCoefficients );
+
+  //! Class destructor.
+  ~Iir( void );
+
+  //! Set filter coefficients.
+  /*!
+    An StkError can be thrown if either of the coefficient vector
+    sizes is zero, or if the a[0] coefficient is equal to zero.  If
+    a[0] is not equal to 1, the filter coeffcients are normalized by
+    a[0].  The internal state of the filter is not cleared unless the
+    \e clearState flag is \c true.
+  */
+  void setCoefficients( std::vector<StkFloat> &bCoefficients, std::vector<StkFloat> &aCoefficients, bool clearState = false );
+
+  //! Set numerator coefficients.
+  /*!
+    An StkError can be thrown if coefficient vector is empty.  Any
+    previously set denominator coefficients are left unaffected.  Note
+    that the default constructor sets the single denominator
+    coefficient a[0] to 1.0.  The internal state of the filter is not
+    cleared unless the \e clearState flag is \c true.
+  */
+  void setNumerator( std::vector<StkFloat> &bCoefficients, bool clearState = false );
+
+  //! Set denominator coefficients.
+  /*!
+    An StkError can be thrown if the coefficient vector is empty or
+    if the a[0] coefficient is equal to zero.  Previously set
+    numerator coefficients are unaffected unless a[0] is not equal to
+    1, in which case all coeffcients are normalized by a[0].  Note
+    that the default constructor sets the single numerator coefficient
+    b[0] to 1.0.  The internal state of the filter is not cleared
+    unless the \e clearState flag is \c true.
+  */
+  void setDenominator( std::vector<StkFloat> &aCoefficients, bool clearState = false );
+
+  //! Return the last computed output value.
+  StkFloat lastOut( void ) const { return lastFrame_[0]; };
+
+  //! Input one sample to the filter and return one output.
+  StkFloat tick( StkFloat input );
+
+  //! Take a channel of the StkFrames object as inputs to the filter and replace with corresponding outputs.
+  /*!
+    The StkFrames argument reference is returned.  The \c channel
+    argument must be less than the number of channels in the
+    StkFrames argument (the first channel is specified by 0).
+    However, range checking is only performed if _STK_DEBUG_ is
+    defined during compilation, in which case an out-of-range value
+    will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
+
+  //! Take a channel of the \c iFrames object as inputs to the filter and write outputs to the \c oFrames object.
+  /*!
+    The \c iFrames object reference is returned.  Each channel
+    argument must be less than the number of channels in the
+    corresponding StkFrames argument (the first channel is specified
+    by 0).  However, range checking is only performed if _STK_DEBUG_
+    is defined during compilation, in which case an out-of-range value
+    will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0, unsigned int oChannel = 0 );
+
+protected:
+
+};
+
+inline StkFloat Iir :: tick( StkFloat input )
+{
+  unsigned int i;
+
+  outputs_[0] = 0.0;
+  inputs_[0] = gain_ * input;
+  for ( i=b_.size()-1; i>0; i-- ) {
+    outputs_[0] += b_[i] * inputs_[i];
+    inputs_[i] = inputs_[i-1];
+  }
+  outputs_[0] += b_[0] * inputs_[0];
+
+  for ( i=a_.size()-1; i>0; i-- ) {
+    outputs_[0] += -a_[i] * outputs_[i];
+    outputs_[i] = outputs_[i-1];
+  }
+
+  lastFrame_[0] = outputs_[0];
+  return lastFrame_[0];
+}
+
+inline StkFrames& Iir :: tick( StkFrames& frames, unsigned int channel )
+{
+#if defined(_STK_DEBUG_)
+  if ( channel >= frames.channels() ) {
+    errorString_ << "Iir::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *samples = &frames[channel];
+  unsigned int i, hop = frames.channels();
+  for ( unsigned int j=0; j<frames.frames(); j++, samples += hop ) {
+    outputs_[0] = 0.0;
+    inputs_[0] = gain_ * *samples;
+    for ( i=b_.size()-1; i>0; i-- ) {
+      outputs_[0] += b_[i] * inputs_[i];
+      inputs_[i] = inputs_[i-1];
+    }
+    outputs_[0] += b_[0] * inputs_[0];
+
+    for ( i=a_.size()-1; i>0; i-- ) {
+      outputs_[0] += -a_[i] * outputs_[i];
+      outputs_[i] = outputs_[i-1];
+    }
+
+    *samples = outputs_[0];
+  }
+
+  lastFrame_[0] = *(samples-hop);
+  return frames;
+}
+
+inline StkFrames& Iir :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iChannel, unsigned int oChannel )
+{
+#if defined(_STK_DEBUG_)
+  if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
+    errorString_ << "Iir::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *iSamples = &iFrames[iChannel];
+  StkFloat *oSamples = &oFrames[oChannel];
+  unsigned int i, iHop = iFrames.channels(), oHop = oFrames.channels();
+  for ( unsigned int j=0; j<iFrames.frames(); j++, iSamples += iHop, oSamples += oHop ) {
+    outputs_[0] = 0.0;
+    inputs_[0] = gain_ * *iSamples;
+    for ( i=b_.size()-1; i>0; i-- ) {
+      outputs_[0] += b_[i] * inputs_[i];
+      inputs_[i] = inputs_[i-1];
+    }
+    outputs_[0] += b_[0] * inputs_[0];
+
+    for ( i=a_.size()-1; i>0; i-- ) {
+      outputs_[0] += -a_[i] * outputs_[i];
+      outputs_[i] = outputs_[i-1];
+    }
+
+    *oSamples = outputs_[0];
+  }
+
+  lastFrame_[0] = *(oSamples-oHop);
+  return iFrames;
+}
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/InetWvIn.h b/lib/MoMu-STK-1.0.0/include/InetWvIn.h
new file mode 100644 (file)
index 0000000..911c056
--- /dev/null
@@ -0,0 +1,157 @@
+#ifndef STK_INETWVIN_H
+#define STK_INETWVIN_H
+
+#include "WvIn.h"
+#include "TcpServer.h"
+#include "StkUdpSocket.h"
+#include "Thread.h"
+#include "Mutex.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class InetWvIn
+    \brief STK internet streaming input class.
+
+    This Wvin subclass reads streamed audio data over a network via a
+    TCP or UDP socket connection.  The data is assumed in big-endian,
+    or network, byte order.  Only a single socket connection is
+    supported.
+
+    InetWvIn supports multi-channel data.  It is important to
+    distinguish the tick() method that computes a single frame (and
+    returns only the specified sample of a multi-channel frame) from
+    the overloaded one that takes an StkFrames object for
+    multi-channel and/or multi-frame data.
+
+    This class implements a socket server.  When using the TCP
+    protocol, the server "listens" for a single remote connection
+    within the InetWvIn::start() function.  For the UDP protocol, no
+    attempt is made to verify packet delivery or order.  The default
+    data type for the incoming stream is signed 16-bit integers,
+    though any of the defined StkFormats are permissible.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+typedef struct {
+  bool finished;
+  void *object;
+} ThreadInfo;
+
+class InetWvIn : public WvIn
+{
+public:
+  //! Default constructor.
+  /*!
+    An StkError will be thrown if an error occurs while initializing the input thread.
+  */
+  InetWvIn( unsigned long bufferFrames = 1024, unsigned int nBuffers = 8 );
+
+  //! Class destructor.
+  ~InetWvIn();
+
+  //! Wait for a (new) socket connection with specified protocol, port, data channels and format.
+  /*!
+    For the UDP protocol, this function will create a socket
+    instance and return.  For the TCP protocol, this function will
+    block until a connection is established.  An StkError will be
+    thrown if a socket error occurs or an invalid function argument is
+    provided.
+  */
+  void listen( int port = 2006, unsigned int nChannels = 1,
+               Stk::StkFormat format = STK_SINT16,
+               Socket::ProtocolType protocol = Socket::PROTO_TCP );
+
+  //! Returns true is an input connection exists or input data remains in the queue.
+  /*!
+    This method will not return false after an input connection has been closed until
+    all buffered input data has been read out.
+  */
+  bool isConnected( void );
+
+  //! Return the specified channel value of the last computed frame.
+  /*!
+    For multi-channel files, use the lastFrame() function to get
+    all values from the last computed frame.  If no connection exists,
+    the returned value is 0.0.  The \c channel argument must be less
+    than the number of channels in the data stream (the first channel
+    is specified by 0).  However, range checking is only performed if
+    _STK_DEBUG_ is defined during compilation, in which case an
+    out-of-range value will trigger an StkError exception.
+  */
+  StkFloat lastOut( unsigned int channel = 0 );
+
+  //! Compute a sample frame and return the specified \c channel value.
+  /*!
+    For multi-channel files, use the lastFrame() function to get
+    all values from the computed frame.  If no connection exists, the
+    returned value is 0.0 (and a warning will be issued if _STK_DEBUG_
+    is defined during compilation).  The \c channel argument must be
+    less than the number of channels in the data stream (the first
+    channel is specified by 0).  However, range checking is only
+    performed if _STK_DEBUG_ is defined during compilation, in which
+    case an out-of-range value will trigger an StkError exception.
+  */
+  StkFloat tick( unsigned int channel = 0 );
+
+  //! Fill the StkFrames argument with computed frames and return the same reference.
+  /*!
+    The number of channels in the StkFrames argument must equal the
+    number of channels specified in the listen() function.  However,
+    this is only checked if _STK_DEBUG_ is defined during compilation,
+    in which case an incompatibility will trigger an StkError
+    exception.  If no connection exists, the function does
+    nothing (a warning will be issued if _STK_DEBUG_ is defined during
+    compilation).
+  */
+  StkFrames& tick( StkFrames& frames );
+
+  // Called by the thread routine to receive data via the socket connection
+  // and fill the socket buffer.  This is not intended for general use but
+  // must be public for access from the thread.
+  void receive( void );
+
+protected:
+
+  // Read buffered socket data into the data buffer ... will block if none available.
+  int readData( void );
+
+  Socket *soket_;
+  Thread thread_;
+  Mutex mutex_;
+  char *buffer_;
+  unsigned long bufferFrames_;
+  unsigned long bufferBytes_;
+  unsigned long bytesFilled_;
+  unsigned int nBuffers_;
+  unsigned long writePoint_;
+  unsigned long readPoint_;
+  long bufferCounter_;
+  int dataBytes_;
+  bool connected_;
+  int fd_;
+  ThreadInfo threadInfo_;
+  Stk::StkFormat dataType_;
+
+};
+
+inline StkFloat InetWvIn :: lastOut( unsigned int channel )
+{
+#if defined(_STK_DEBUG_)
+  if ( channel >= data_.channels() ) {
+    errorString_ << "InetWvIn::lastOut(): channel argument and data stream are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  // If no connection and we've output all samples in the queue, return.
+  if ( !connected_ && bytesFilled_ == 0 && bufferCounter_ == 0 ) return 0.0;
+
+  return lastFrame_[channel];
+}
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/InetWvOut.h b/lib/MoMu-STK-1.0.0/include/InetWvOut.h
new file mode 100644 (file)
index 0000000..cf10786
--- /dev/null
@@ -0,0 +1,98 @@
+#ifndef STK_INETWVOUT_H
+#define STK_INETWVOUT_H
+
+#include "WvOut.h"
+#include "Socket.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class InetWvOut
+    \brief STK internet streaming output class.
+
+    This WvOut subclass can stream data over a network via a TCP or
+    UDP socket connection.  The data is converted to big-endian byte
+    order, if necessary, before being transmitted.
+
+    InetWvOut supports multi-channel data.  It is important to
+    distinguish the tick() method that outputs a single sample to all
+    channels in a sample frame from the overloaded one that takes a
+    reference to an StkFrames object for multi-channel and/or
+    multi-frame data.
+
+    This class connects to a socket server, the port and IP address of
+    which must be specified as constructor arguments.  The default
+    data type is signed 16-bit integers but any of the defined
+    StkFormats are permissible.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class InetWvOut : public WvOut
+{
+ public:
+  //! Default constructor ... the socket is not instantiated.
+  InetWvOut( unsigned long packetFrames = 1024 );
+
+  //! Overloaded constructor which opens a network connection during instantiation.
+  /*!
+    An StkError is thrown if a socket error occurs or an invalid argument is specified.
+  */
+  InetWvOut( int port, Socket::ProtocolType protocol = Socket::PROTO_TCP,
+             std::string hostname = "localhost", unsigned int nChannels = 1, Stk::StkFormat format = STK_SINT16,
+             unsigned long packetFrames = 1024 );
+
+  //! Class destructor.
+  ~InetWvOut();
+
+  //! Connect to the specified host and port and prepare to stream \e nChannels of data in the given data format.
+  /*!
+    An StkError is thrown if a socket error occurs or an invalid argument is specified.
+  */
+  void connect( int port, Socket::ProtocolType protocol = Socket::PROTO_TCP,
+                std::string hostname = "localhost", unsigned int nChannels = 1, Stk::StkFormat format = STK_SINT16 );
+
+  //! If a connection is open, write out remaining samples in the queue and then disconnect.
+  void disconnect( void );
+
+  //! Output a single sample to all channels in a sample frame.
+  /*!
+    An StkError is thrown if an output error occurs.  If a socket
+    connection does not exist, the function does nothing (a warning
+    will be issued if _STK_DEBUG_ is defined during compilation).
+  */
+  void tick( const StkFloat sample );
+
+  //! Output the StkFrames data.
+  /*!
+    An StkError will be thrown if an output error occurs.  An
+    StkError will also be thrown if _STK_DEBUG_ is defined during
+    compilation and there is an incompatability between the number of
+    channels in the FileWvOut object and that in the StkFrames object.
+    If a socket connection does not exist, the function does nothing
+    (a warning will be issued if _STK_DEBUG_ is defined during
+    compilation).
+  */
+  void tick( const StkFrames& frames );
+
+ protected:
+
+  void incrementFrame( void );
+
+  // Write a buffer of length frames via the socket connection.
+  void writeData( unsigned long frames );
+
+  char *buffer_;
+  Socket *soket_;
+  unsigned long bufferFrames_;
+  unsigned long bufferBytes_;
+  unsigned long bufferIndex_;
+  unsigned long iData_;
+  unsigned int dataBytes_;
+  Stk::StkFormat dataType_;
+};
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/Instrmnt.h b/lib/MoMu-STK-1.0.0/include/Instrmnt.h
new file mode 100644 (file)
index 0000000..6887b60
--- /dev/null
@@ -0,0 +1,129 @@
+#ifndef STK_INSTRMNT_H
+#define STK_INSTRMNT_H
+
+#include "Stk.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class Instrmnt
+  \brief STK instrument abstract base class.
+
+  This class provides a common interface for
+  all STK instruments.
+
+  by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class Instrmnt : public Stk
+{
+ public:
+  //! Class constructor.
+  Instrmnt( void ) { lastFrame_.resize( 1, 1, 0.0 ); };
+
+  //! Start a note with the given frequency and amplitude.
+  virtual void noteOn( StkFloat frequency, StkFloat amplitude ) = 0;
+
+  //! Stop a note with the given amplitude (speed of decay).
+  virtual void noteOff( StkFloat amplitude ) = 0;
+
+  //! Set instrument parameters for a particular frequency.
+  virtual void setFrequency( StkFloat frequency );
+
+  //! Perform the control change specified by \e number and \e value (0.0 - 128.0).
+  virtual void controlChange(int number, StkFloat value);
+
+  //! Return the number of output channels for the class.
+  unsigned int channelsOut( void ) const { return lastFrame_.channels(); };
+
+  //! Return an StkFrames reference to the last output sample frame.
+  const StkFrames& lastFrame( void ) const { return lastFrame_; };
+
+  //! Return the specified channel value of the last computed frame.
+  /*!
+    The \c channel argument must be less than the number of output
+    channels, which can be determined with the channelsOut() function
+    (the first channel is specified by 0).  However, range checking is
+    only performed if _STK_DEBUG_ is defined during compilation, in
+    which case an out-of-range value will trigger an StkError
+    exception. \sa lastFrame()
+  */
+  StkFloat lastOut( unsigned int channel = 0 );
+
+  //! Compute one sample frame and return the specified \c channel value.
+  /*!
+    For monophonic instruments, the \c channel argument is ignored.
+  */
+  virtual StkFloat tick( unsigned int channel = 0 ) = 0;
+
+  //! Fill the StkFrames object with computed sample frames, starting at the specified channel.
+  /*!
+    The \c channel argument plus the number of output channels must
+    be less than the number of channels in the StkFrames argument (the
+    first channel is specified by 0).  However, range checking is only
+    performed if _STK_DEBUG_ is defined during compilation, in which
+    case an out-of-range value will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
+
+ protected:
+
+  StkFrames lastFrame_;
+
+};
+
+inline void Instrmnt :: setFrequency(StkFloat frequency)
+{
+  errorString_ << "Instrmnt::setFrequency: virtual setFrequency function call!";
+  handleError( StkError::WARNING );
+}
+
+inline StkFloat Instrmnt :: lastOut( unsigned int channel )
+{
+#if defined(_STK_DEBUG_)
+  if ( channel >= lastFrame_.channels() ) {
+    errorString_ << "Instrmnt::lastOut(): channel argument is invalid!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  return lastFrame_[channel];
+}
+
+inline StkFrames& Instrmnt :: tick( StkFrames& frames, unsigned int channel )
+{
+  unsigned int nChannels = lastFrame_.channels();
+#if defined(_STK_DEBUG_)
+  if ( channel > frames.channels() - nChannels ) {
+    errorString_ << "Instrmnt::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *samples = &frames[channel];
+  unsigned int j, hop = frames.channels() - nChannels;
+  if ( nChannels == 1 ) {
+    for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
+      *samples++ = tick();
+  }
+  else {
+    for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
+      *samples++ = tick();
+      for ( j=1; j<nChannels; j++ )
+        *samples++ = lastFrame_[j];
+    }
+  }
+
+  return frames;
+}
+
+inline void Instrmnt :: controlChange( int number, StkFloat value )
+{
+  errorString_ << "Instrmnt::controlChange: virtual function call!";
+  handleError( StkError::WARNING );
+}
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/JCRev.h b/lib/MoMu-STK-1.0.0/include/JCRev.h
new file mode 100644 (file)
index 0000000..659e6e8
--- /dev/null
@@ -0,0 +1,158 @@
+#ifndef STK_JCREV_H
+#define STK_JCREV_H
+
+#include "Effect.h"
+#include "Delay.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class JCRev
+    \brief John Chowning's reverberator class.
+
+    This class takes a monophonic input signal and produces a stereo
+    output signal.  It is derived from the CLM JCRev function, which
+    is based on the use of networks of simple allpass and comb delay
+    filters.  This class implements three series allpass units,
+    followed by four parallel comb filters, and two decorrelation
+    delay lines in parallel at the output.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class JCRev : public Effect
+{
+ public:
+  //! Class constructor taking a T60 decay time argument (one second default value).
+  JCRev( StkFloat T60 = 1.0 );
+
+  //! Reset and clear all internal state.
+  void clear( void );
+
+  //! Set the reverberation T60 decay time.
+  void setT60( StkFloat T60 );
+
+  //! Return the specified channel value of the last computed stereo frame.
+  /*!
+    Use the lastFrame() function to get both values of the last
+    computed stereo frame.  The \c channel argument must be 0 or 1
+    (the first channel is specified by 0).  However, range checking is
+    only performed if _STK_DEBUG_ is defined during compilation, in
+    which case an out-of-range value will trigger an StkError
+    exception.
+  */
+  StkFloat lastOut( unsigned int channel = 0 );
+
+  //! Input one sample to the effect and return the specified \c channel value of the computed stereo frame.
+  /*!
+    Use the lastFrame() function to get both values of the computed
+    stereo output frame. The \c channel argument must be 0 or 1 (the
+    first channel is specified by 0).  However, range checking is only
+    performed if _STK_DEBUG_ is defined during compilation, in which
+    case an out-of-range value will trigger an StkError exception.
+  */
+  StkFloat tick( StkFloat input, unsigned int channel = 0 );
+
+  //! Take a channel of the StkFrames object as inputs to the effect and replace with stereo outputs.
+  /*!
+    The StkFrames argument reference is returned.  The stereo
+    outputs are written to the StkFrames argument starting at the
+    specified \c channel.  Therefore, the \c channel argument must be
+    less than ( channels() - 1 ) of the StkFrames argument (the first
+    channel is specified by 0).  However, range checking is only
+    performed if _STK_DEBUG_ is defined during compilation, in which
+    case an out-of-range value will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
+
+  //! Take a channel of the \c iFrames object as inputs to the effect and write stereo outputs to the \c oFrames object.
+  /*!
+    The \c iFrames object reference is returned.  The \c iChannel
+    argument must be less than the number of channels in the \c
+    iFrames argument (the first channel is specified by 0).  The \c
+    oChannel argument must be less than ( channels() - 1 ) of the \c
+    oFrames argument.  However, range checking is only performed if
+    _STK_DEBUG_ is defined during compilation, in which case an
+    out-of-range value will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0, unsigned int oChannel = 0 );
+
+ protected:
+
+  Delay allpassDelays_[3];
+  Delay combDelays_[4];
+  Delay outLeftDelay_;
+  Delay outRightDelay_;
+  StkFloat allpassCoefficient_;
+  StkFloat combCoefficient_[4];
+
+};
+
+inline StkFloat JCRev :: lastOut( unsigned int channel )
+{
+#if defined(_STK_DEBUG_)
+  if ( channel > 1 ) {
+    errorString_ << "JCRev::lastOut(): channel argument must be less than 2!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  return lastFrame_[channel];
+}
+
+inline StkFloat JCRev :: tick( StkFloat input, unsigned int channel )
+{
+#if defined(_STK_DEBUG_)
+  if ( channel > 1 ) {
+    errorString_ << "JCRev::tick(): channel argument must be less than 2!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat temp, temp0, temp1, temp2, temp3, temp4, temp5, temp6;
+  StkFloat filtout;
+
+  temp = allpassDelays_[0].lastOut();
+  temp0 = allpassCoefficient_ * temp;
+  temp0 += input;
+  allpassDelays_[0].tick(temp0);
+  temp0 = -(allpassCoefficient_ * temp0) + temp;
+    
+  temp = allpassDelays_[1].lastOut();
+  temp1 = allpassCoefficient_ * temp;
+  temp1 += temp0;
+  allpassDelays_[1].tick(temp1);
+  temp1 = -(allpassCoefficient_ * temp1) + temp;
+    
+  temp = allpassDelays_[2].lastOut();
+  temp2 = allpassCoefficient_ * temp;
+  temp2 += temp1;
+  allpassDelays_[2].tick(temp2);
+  temp2 = -(allpassCoefficient_ * temp2) + temp;
+    
+  temp3 = temp2 + (combCoefficient_[0] * combDelays_[0].lastOut());
+  temp4 = temp2 + (combCoefficient_[1] * combDelays_[1].lastOut());
+  temp5 = temp2 + (combCoefficient_[2] * combDelays_[2].lastOut());
+  temp6 = temp2 + (combCoefficient_[3] * combDelays_[3].lastOut());
+
+  combDelays_[0].tick(temp3);
+  combDelays_[1].tick(temp4);
+  combDelays_[2].tick(temp5);
+  combDelays_[3].tick(temp6);
+
+  filtout = temp3 + temp4 + temp5 + temp6;
+
+  lastFrame_[0] = effectMix_ * (outLeftDelay_.tick(filtout));
+  lastFrame_[1] = effectMix_ * (outRightDelay_.tick(filtout));
+  temp = (1.0 - effectMix_) * input;
+  lastFrame_[0] += temp;
+  lastFrame_[1] += temp;
+    
+  return lastFrame_[channel];
+}
+
+} // stk namespace
+
+#endif
+
diff --git a/lib/MoMu-STK-1.0.0/include/JetTable.h b/lib/MoMu-STK-1.0.0/include/JetTable.h
new file mode 100644 (file)
index 0000000..73acc57
--- /dev/null
@@ -0,0 +1,112 @@
+#ifndef STK_JETTABL_H
+#define STK_JETTABL_H
+
+#include "Function.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class JetTable
+    \brief STK jet table class.
+
+    This class implements a flue jet non-linear
+    function, computed by a polynomial calculation.
+    Contrary to the name, this is not a "table".
+
+    Consult Fletcher and Rossing, Karjalainen,
+    Cook, and others for more information.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class JetTable : public Function
+{
+public:
+
+  //! Take one sample input and map to one sample of output.
+  StkFloat tick( StkFloat input );
+
+  //! Take a channel of the StkFrames object as inputs to the table and replace with corresponding outputs.
+  /*!
+    The StkFrames argument reference is returned.  The \c channel
+    argument must be less than the number of channels in the
+    StkFrames argument (the first channel is specified by 0).
+    However, range checking is only performed if _STK_DEBUG_ is
+    defined during compilation, in which case an out-of-range value
+    will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
+
+  //! Take a channel of the \c iFrames object as inputs to the table and write outputs to the \c oFrames object.
+  /*!
+    The \c iFrames object reference is returned.  Each channel
+    argument must be less than the number of channels in the
+    corresponding StkFrames argument (the first channel is specified
+    by 0).  However, range checking is only performed if _STK_DEBUG_
+    is defined during compilation, in which case an out-of-range value
+    will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0, unsigned int oChannel = 0 );
+
+};
+
+inline StkFloat JetTable :: tick( StkFloat input )
+{
+  // Perform "table lookup" using a polynomial
+  // calculation (x^3 - x), which approximates
+  // the jet sigmoid behavior.
+  lastFrame_[0] = input * (input * input - 1.0);
+
+  // Saturate at +/- 1.0.
+  if ( lastFrame_[0] > 1.0 ) lastFrame_[0] = 1.0;
+  if ( lastFrame_[0] < -1.0 ) lastFrame_[0] = -1.0; 
+  return lastFrame_[0];
+}
+
+inline StkFrames& JetTable :: tick( StkFrames& frames, unsigned int channel )
+{
+#if defined(_STK_DEBUG_)
+  if ( channel >= frames.channels() ) {
+    errorString_ << "JetTable::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *samples = &frames[channel];
+  unsigned int hop = frames.channels();
+  for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
+    *samples = *samples * (*samples * *samples - 1.0);
+    if ( *samples > 1.0) *samples = 1.0;
+    if ( *samples < -1.0) *samples = -1.0;
+  }
+
+  lastFrame_[0] = *(samples-hop);
+  return frames;
+}
+
+inline StkFrames& JetTable :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iChannel, unsigned int oChannel )
+{
+#if defined(_STK_DEBUG_)
+  if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
+    errorString_ << "JetTable::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *iSamples = &iFrames[iChannel];
+  StkFloat *oSamples = &oFrames[oChannel];
+  unsigned int iHop = iFrames.channels(), oHop = oFrames.channels();
+  for ( unsigned int i=0; i<iFrames.frames(); i++, iSamples += iHop, oSamples += oHop ) {
+    *oSamples = *oSamples * (*oSamples * *oSamples - 1.0);
+    if ( *oSamples > 1.0) *oSamples = 1.0;
+    if ( *oSamples < -1.0) *oSamples = -1.0;
+  }
+
+  lastFrame_[0] = *(oSamples-oHop);
+  return iFrames;
+}
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/LentPitShift.h b/lib/MoMu-STK-1.0.0/include/LentPitShift.h
new file mode 100644 (file)
index 0000000..f2a535f
--- /dev/null
@@ -0,0 +1,267 @@
+#ifndef STK_LENLentPitShift_H
+#define STK_LENLentPitShift_H
+
+#include "Effect.h"
+#include "Delay.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class LentPitShift
+    \brief Pitch shifter effect class based on the Lent algorithm.
+
+    This class implements a pitch shifter using pitch 
+    tracking and sample windowing and shifting.
+
+    by Francois Germain, 2009.
+*/
+/***************************************************/
+
+class LentPitShift : public Effect
+{
+ public:
+  //! Class constructor.
+  LentPitShift( StkFloat periodRatio = 1.0, int tMax = RT_BUFFER_SIZE );
+
+  ~LentPitShift( void ) {
+    delete window;
+    window = NULL;
+    delete dt;
+    dt = NULL;
+    delete dpt;
+    dpt = NULL;
+    delete cumDt;
+    cumDt = NULL;
+  }
+
+  //! Reset and clear all internal state.
+  void clear( void );
+
+  //! Set the pitch shift factor (1.0 produces no shift).
+  void setShift( StkFloat shift );
+
+  //! Input one sample to the filter and return one output.
+  StkFloat tick( StkFloat input );
+
+  //! Take a channel of the StkFrames object as inputs to the filter and replace with corresponding outputs.
+  /*!
+    The StkFrames argument reference is returned.  The \c channel
+    argument must be less than the number of channels in the
+    StkFrames argument (the first channel is specified by 0).
+    However, range checking is only performed if _STK_DEBUG_ is
+    defined during compilation, in which case an out-of-range value
+    will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
+
+  //! Take a channel of the \c iFrames object as inputs to the filter and write outputs to the \c oFrames object.
+  /*!
+    The \c iFrames object reference is returned.  Each channel
+    argument must be less than the number of channels in the
+    corresponding StkFrames argument (the first channel is specified
+    by 0).  However, range checking is only performed if _STK_DEBUG_
+    is defined during compilation, in which case an out-of-range value
+    will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0, unsigned int oChannel = 0 );
+
+ protected:
+
+  //! Apply the effect on the input samples and store it.
+  /*!
+    The samples stored in the input frame vector are processed
+    and the delayed result are stored in the output frame vector
+  */
+  void process( );
+
+  // Frame storage vectors for process function
+  StkFrames inputFrames;
+  StkFrames outputFrames;
+  int ptrFrames;          // writing pointer
+
+  // Input delay line
+  Delay inputLine_;
+  int inputPtr;
+
+  // Output delay line
+  Delay outputLine_;
+  double outputPtr;
+
+  // Pitch tracker variables
+  unsigned long tMax_;    // Maximal period measurable by the pitch tracker.
+  // It is also the size of the window used by the pitch tracker and
+  // the size of the frames that can be computed by the tick function
+
+  StkFloat threshold_; // Threshold of detection for the pitch tracker
+  unsigned long lastPeriod_;    // Result of the last pitch tracking loop
+  StkFloat* dt;        // Array containing the euclidian distance coefficients
+  StkFloat* cumDt;     // Array containing the cumulative sum of the coefficients in dt
+  StkFloat* dpt;       // Array containing the pitch tracking function coefficients
+
+  // Pitch shifter variables
+  StkFloat env[2];     // Coefficients for the linear interpolation when modifying the output samples
+  StkFloat* window;    // Hamming window used for the input portion extraction
+  double periodRatio_; // Ratio of modification of the signal period
+  StkFrames zeroFrame; // Frame of tMax_ zero samples
+
+
+  // Coefficient delay line that could be used for a dynamic calculation of the pitch
+  //Delay* coeffLine_;
+
+};
+
+inline void LentPitShift::process()
+{
+  StkFloat x_t;    // input coefficient
+  StkFloat x_t_T;  // previous input coefficient at T samples
+  StkFloat coeff;  // new coefficient for the difference function
+
+  int alternativePitch = tMax_;  // Global minimum storage
+  lastPeriod_ = tMax_+1;         // Storage of the lowest local minimum under the threshold
+
+  // Loop variables
+  unsigned long delay_;
+  unsigned int n;
+
+  // Initialization of the dt coefficients.  Since the
+  // frames are of tMax_ length, there is no overlapping
+  // between the successive windows where pitch tracking
+  // is performed.
+  for ( delay_=1; delay_<=tMax_; delay_++ )
+    dt[delay_] = 0.;
+
+  // Calculation of the dt coefficients and update of the input delay line.
+  for ( n=0; n<inputFrames.size(); n++ ) {
+    x_t = inputLine_.tick( inputFrames[ n ] );
+    for ( delay_=1; delay_<= tMax_; delay_++ ) {
+      x_t_T = inputLine_.contentsAt( delay_ );
+      coeff = x_t - x_t_T;
+      dt[delay_] += coeff * coeff;
+    }
+  }
+
+  // Calculation of the pitch tracking function and test for the minima.
+  for ( delay_=1; delay_<=tMax_; delay_++ ) {
+    cumDt[delay_] = dt[delay_] + cumDt[delay_-1];
+    dpt[delay_] = dt[delay_] * delay_ / cumDt[delay_];
+
+    // Look for a minimum
+    if ( dpt[delay_-1]-dpt[delay_-2] < 0 && dpt[delay_]-dpt[delay_-1] > 0 ) {
+      // Check if the minimum is under the threshold
+      if ( dpt[delay_-1] < threshold_ ){
+        lastPeriod_ = delay_-1;
+        // If a minimum is found, we can stop the loop
+        break;
+      }
+      else if ( dpt[alternativePitch] > dpt[delay_-1] )
+        // Otherwise we store it if it is the current global minimum
+        alternativePitch = delay_-1;
+    }
+  }
+
+  // Test for the last period length.
+  if ( dpt[delay_]-dpt[delay_-1] < 0 ) {
+    if ( dpt[delay_] < threshold_ )
+      lastPeriod_ = delay_;
+    else if ( dpt[alternativePitch] > dpt[delay_] )
+      alternativePitch = delay_;
+  }
+
+  if ( lastPeriod_ == tMax_+1 )
+    // No period has been under the threshold so we used the global minimum
+    lastPeriod_ = alternativePitch;
+
+  // We put the new zero output coefficients in the output delay line and 
+  // we get the previous calculated coefficients
+  outputLine_.tick( zeroFrame, outputFrames );
+
+  // Initialization of the Hamming window used in the algorithm
+  for ( int n=-(int)lastPeriod_; n<(int)lastPeriod_; n++ )
+    window[n+lastPeriod_] = (1 + cos(PI*n/lastPeriod_)) / 2    ;
+
+  int M;  // Index of reading in the input delay line
+  int N;  // Index of writing in the output delay line
+  double sample;  // Temporary storage for the new coefficient
+
+  // We loop for all the frames of length lastPeriod_ presents between inputPtr and tMax_
+  for ( ; inputPtr<(int)(tMax_-lastPeriod_); inputPtr+=lastPeriod_ ) {
+    // Test for the decision of compression/expansion
+    while ( outputPtr < inputPtr ) {
+      // Coefficients for the linear interpolation
+      env[1] = fmod( outputPtr + tMax_, 1.0 );
+      env[0] = 1.0 - env[1];
+      M = tMax_ - inputPtr + lastPeriod_ - 1; // New reading pointer
+      N = 2*tMax_ - (unsigned long)floor(outputPtr + tMax_) + lastPeriod_ - 1; // New writing pointer
+      for ( unsigned int j=0; j<2*lastPeriod_; j++,M--,N-- ) {
+        sample = inputLine_.contentsAt(M) * window[j] / 2.;
+        // Linear interpolation
+        outputLine_.addTo(N, env[0] * sample);
+        outputLine_.addTo(N-1, env[1] * sample);
+      }
+      outputPtr = outputPtr + lastPeriod_ * periodRatio_; // new output pointer
+    }
+  }
+  // Shifting of the pointers waiting for the new frame of length tMax_.
+  outputPtr -= tMax_;
+  inputPtr  -= tMax_;
+}
+
+
+inline StkFloat LentPitShift :: tick( StkFloat input )
+{
+  StkFloat sample;
+
+  inputFrames[ptrFrames] = input;
+
+  sample = outputFrames[ptrFrames++];
+
+  // Check for end condition
+  if ( ptrFrames == (int) inputFrames.size() ){
+    ptrFrames = 0;
+    process( );
+  }
+
+  return sample;
+}
+
+inline StkFrames& LentPitShift :: tick( StkFrames& frames, unsigned int channel )
+{
+#if defined(_STK_DEBUG_)
+  if ( channel >= frames.channels() ) {
+    errorString_ << "LentPitShift::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *samples = &frames[channel];
+  unsigned int hop = frames.channels();
+  for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
+    *samples = tick( *samples );
+  }
+
+  return frames;
+}
+
+inline StkFrames& LentPitShift :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iChannel, unsigned int oChannel )
+{
+#if defined(_STK_DEBUG_)
+  if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
+    errorString_ << "LentPitShift::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *iSamples = &iFrames[iChannel];
+  StkFloat *oSamples = &oFrames[oChannel];
+  unsigned int iHop = iFrames.channels(), oHop = oFrames.channels();
+  for ( unsigned int i=0; i<iFrames.frames(); i++, iSamples += iHop, oSamples += oHop ) {
+    *oSamples = tick( *iSamples );
+  }
+
+  return iFrames;
+}
+
+} // stk namespace
+
+#endif
+
diff --git a/lib/MoMu-STK-1.0.0/include/Mandolin.h b/lib/MoMu-STK-1.0.0/include/Mandolin.h
new file mode 100644 (file)
index 0000000..9a0af95
--- /dev/null
@@ -0,0 +1,105 @@
+#ifndef STK_MANDOLIN_H
+#define STK_MANDOLIN_H
+
+#include "PluckTwo.h"
+#include "FileWvIn.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class Mandolin
+    \brief STK mandolin instrument model class.
+
+    This class inherits from PluckTwo and uses
+    "commuted synthesis" techniques to model a
+    mandolin instrument.
+
+    This is a digital waveguide model, making its
+    use possibly subject to patents held by
+    Stanford University, Yamaha, and others.
+    Commuted Synthesis, in particular, is covered
+    by patents, granted, pending, and/or
+    applied-for.  All are assigned to the Board of
+    Trustees, Stanford University.  For
+    information, contact the Office of Technology
+    Licensing, Stanford University.
+
+    Control Change Numbers: 
+       - Body Size = 2
+       - Pluck Position = 4
+       - String Sustain = 11
+       - String Detuning = 1
+       - Microphone Position = 128
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class Mandolin : public PluckTwo
+{
+ public:
+  //! Class constructor, taking the lowest desired playing frequency.
+  Mandolin( StkFloat lowestFrequency );
+
+  //! Class destructor.
+  ~Mandolin( void );
+
+  //! Pluck the strings with the given amplitude (0.0 - 1.0) using the current frequency.
+  void pluck( StkFloat amplitude );
+
+  //! Pluck the strings with the given amplitude (0.0 - 1.0) and position (0.0 - 1.0).
+  void pluck( StkFloat amplitude,StkFloat position );
+
+  //! Start a note with the given frequency and amplitude (0.0 - 1.0).
+  void noteOn( StkFloat frequency, StkFloat amplitude );
+
+  //! Set the body size (a value of 1.0 produces the "default" size).
+  void setBodySize( StkFloat size );
+
+  //! Perform the control change specified by \e number and \e value (0.0 - 128.0).
+  void controlChange( int number, StkFloat value );
+
+  //! Compute and return one output sample.
+  StkFloat tick( unsigned int channel = 0 );
+
+  protected:
+
+  FileWvIn *soundfile_[12];
+  int mic_;
+  long dampTime_;
+  bool waveDone_;
+};
+
+inline StkFloat Mandolin :: tick( unsigned int )
+{
+  StkFloat temp = 0.0;
+  if ( !waveDone_ ) {
+    // Scale the pluck excitation with comb
+    // filtering for the duration of the file.
+    temp = soundfile_[mic_]->tick() * pluckAmplitude_;
+    temp = temp - combDelay_.tick(temp);
+    waveDone_ = soundfile_[mic_]->isFinished();
+  }
+
+  // Damping hack to help avoid overflow on re-plucking.
+  if ( dampTime_ >=0 ) {
+    dampTime_ -= 1;
+    // Calculate 1st delay filtered reflection plus pluck excitation.
+    lastFrame_[0] = delayLine_.tick( filter_.tick( temp + (delayLine_.lastOut() * 0.7) ) );
+    // Calculate 2nd delay just like the 1st.
+    lastFrame_[0] += delayLine2_.tick( filter2_.tick( temp + (delayLine2_.lastOut() * 0.7) ) );
+  }
+  else { // No damping hack after 1 period.
+    // Calculate 1st delay filtered reflection plus pluck excitation.
+    lastFrame_[0] = delayLine_.tick( filter_.tick( temp + (delayLine_.lastOut() * loopGain_) ) );
+    // Calculate 2nd delay just like the 1st.
+    lastFrame_[0] += delayLine2_.tick( filter2_.tick( temp + (delayLine2_.lastOut() * loopGain_) ) );
+  }
+
+  lastFrame_[0] *= 0.3;
+  return lastFrame_[0];
+}
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/Mesh2D.h b/lib/MoMu-STK-1.0.0/include/Mesh2D.h
new file mode 100644 (file)
index 0000000..91b83e4
--- /dev/null
@@ -0,0 +1,107 @@
+#ifndef STK_MESH2D_H
+#define STK_MESH2D_H
+
+#include "Instrmnt.h"
+#include "OnePole.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class Mesh2D
+    \brief Two-dimensional rectilinear waveguide mesh class.
+
+    This class implements a rectilinear,
+    two-dimensional digital waveguide mesh
+    structure.  For details, see Van Duyne and
+    Smith, "Physical Modeling with the 2-D Digital
+    Waveguide Mesh", Proceedings of the 1993
+    International Computer Music Conference.
+
+    This is a digital waveguide model, making its
+    use possibly subject to patents held by Stanford
+    University, Yamaha, and others.
+
+    Control Change Numbers: 
+       - X Dimension = 2
+       - Y Dimension = 4
+       - Mesh Decay = 11
+       - X-Y Input Position = 1
+
+    by Julius Smith, 2000 - 2002.
+    Revised by Gary Scavone for STK, 2002.
+*/
+/***************************************************/
+
+const short NXMAX = 12;
+const short NYMAX = 12;
+
+class Mesh2D : public Instrmnt
+{
+ public:
+  //! Class constructor, taking the x and y dimensions in samples.
+  Mesh2D( short nX, short nY );
+
+  //! Class destructor.
+  ~Mesh2D( void );
+
+  //! Reset and clear all internal state.
+  void clear( void );
+
+  //! Set the x dimension size in samples.
+  void setNX( short lenX );
+
+  //! Set the y dimension size in samples.
+  void setNY( short lenY );
+
+  //! Set the x, y input position on a 0.0 - 1.0 scale.
+  void setInputPosition( StkFloat xFactor, StkFloat yFactor );
+
+  //! Set the loss filters gains (0.0 - 1.0).
+  void setDecay( StkFloat decayFactor );
+
+  //! Impulse the mesh with the given amplitude (frequency ignored).
+  void noteOn( StkFloat frequency, StkFloat amplitude );
+
+  //! Stop a note with the given amplitude (speed of decay) ... currently ignored.
+  void noteOff( StkFloat amplitude );
+
+  //! Calculate and return the signal energy stored in the mesh.
+  StkFloat energy( void );
+
+  //! Input a sample to the mesh and compute one output sample.
+  StkFloat inputTick( StkFloat input );
+
+  //! Perform the control change specified by \e number and \e value (0.0 - 128.0).
+  void controlChange( int number, StkFloat value );
+
+  //! Compute and return one output sample.
+  StkFloat tick( unsigned int channel = 0 );
+
+ protected:
+
+  StkFloat tick0();
+  StkFloat tick1();
+  void clearMesh();
+
+  short NX_, NY_;
+  short xInput_, yInput_;
+  OnePole  filterX_[NXMAX];
+  OnePole  filterY_[NYMAX];
+  StkFloat v_[NXMAX-1][NYMAX-1]; // junction velocities
+  StkFloat vxp_[NXMAX][NYMAX];   // positive-x velocity wave
+  StkFloat vxm_[NXMAX][NYMAX];   // negative-x velocity wave
+  StkFloat vyp_[NXMAX][NYMAX];   // positive-y velocity wave
+  StkFloat vym_[NXMAX][NYMAX];   // negative-y velocity wave
+
+  // Alternate buffers
+  StkFloat vxp1_[NXMAX][NYMAX];  // positive-x velocity wave
+  StkFloat vxm1_[NXMAX][NYMAX];  // negative-x velocity wave
+  StkFloat vyp1_[NXMAX][NYMAX];  // positive-y velocity wave
+  StkFloat vym1_[NXMAX][NYMAX];  // negative-y velocity wave
+
+  int counter_; // time in samples
+};
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/Messager.h b/lib/MoMu-STK-1.0.0/include/Messager.h
new file mode 100644 (file)
index 0000000..a6fa0e4
--- /dev/null
@@ -0,0 +1,166 @@
+#ifndef STK_MESSAGER_H
+#define STK_MESSAGER_H
+
+#include "Stk.h"
+#include "Skini.h"
+#include <queue>
+
+#if defined(__STK_REALTIME__)
+
+#include "Mutex.h"
+#include "Thread.h"
+#include "TcpServer.h"
+#include "RtMidi.h"
+
+#endif // __STK_REALTIME__
+
+namespace stk {
+
+/***************************************************/
+/*! \class Messager
+    \brief STK input control message parser.
+
+    This class reads and parses control messages from a variety of
+    sources, such as a scorefile, MIDI port, socket connection, or
+    stdin.  MIDI messages are retrieved using the RtMidi class.  All
+    other input sources (scorefile, socket, or stdin) are assumed to
+    provide SKINI formatted messages.  This class can be compiled with
+    generic, non-realtime support, in which case only scorefile
+    reading is possible.
+
+    The various \e realtime message acquisition mechanisms (from MIDI,
+    socket, or stdin) take place asynchronously, filling the message
+    queue.  A call to popMessage() will pop the next available control
+    message from the queue and return it via the referenced Message
+    structure.  When a \e non-realtime scorefile is set, it is not
+    possible to start reading realtime input messages (from MIDI,
+    socket, or stdin).  Likewise, it is not possible to read from a
+    scorefile when a realtime input mechanism is running.
+
+    When MIDI input is started, input is also automatically read from
+    stdin.  This allows for program termination via the terminal
+    window.  An __SK_Exit_ message is pushed onto the stack whenever
+    an "exit" or "Exit" message is received from stdin or when all
+    socket connections close and no stdin thread is running.
+
+    This class is primarily for use in STK example programs but it is
+    generic enough to work in many other contexts.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+const int DEFAULT_QUEUE_LIMIT = 200;
+
+class Messager : public Stk
+{
+ public:
+
+  // This structure is used to share data among the various realtime
+  // messager threads.  It must be public.
+  struct MessagerData {
+    Skini skini;
+    std::queue<Skini::Message> queue;
+    unsigned int queueLimit;
+    int sources;
+
+#if defined(__STK_REALTIME__)
+    Mutex mutex;
+    RtMidiIn *midi;
+    TcpServer *socket;
+    std::vector<int> fd;
+    fd_set mask;
+#endif
+
+    // Default constructor.
+    MessagerData()
+      :queueLimit(0), sources(0) {}
+  };
+
+  //! Default constructor.
+  Messager();
+
+  //! Class destructor.
+  ~Messager();
+
+  //! Pop the next message from the queue and write it to the referenced message structure.
+  /*!
+    Invalid messages (or an empty queue) are indicated by type
+    values of zero, in which case all other message structure values
+    are undefined.  The user MUST verify the returned message type is
+    valid before reading other message values.
+  */
+  void popMessage( Skini::Message& message );
+
+  //! Push the referenced message onto the message stack.
+  void pushMessage( Skini::Message& message );
+
+  //! Specify a SKINI formatted scorefile from which messages should be read.
+  /*!
+    A return value of \c true indicates the call was successful.  A
+    return value of \c false can occur if the file is not found,
+    cannot be opened, another file is currently still open, or if a
+    realtime input mechanism is running.  Scorefile input is
+    considered to be a non-realtime control mechanism that cannot run
+    concurrently with realtime input.
+  */
+  bool setScoreFile( const char* filename );
+
+#if defined(__STK_REALTIME__)
+  //! Initiate the "realtime" retreival from stdin of control messages into the queue.
+  /*!
+    This function initiates a thread for asynchronous retrieval of
+    SKINI formatted messages from stdin.  A return value of \c true
+    indicates the call was successful.  A return value of \c false can
+    occur if a scorefile is being read, a stdin thread is already
+    running, or a thread error occurs during startup.  Stdin input is
+    considered to be a realtime control mechanism that cannot run
+    concurrently with non-realtime scorefile input.
+  */
+  bool startStdInput();
+
+  //! Start a socket server, accept connections, and read "realtime" control messages into the message queue.
+  /*!
+    This function creates a socket server on the optional port
+    (default = 2001) and starts a thread for asynchronous retrieval of
+    SKINI formatted messages from socket connections.  A return value
+    of \c true indicates the call was successful.  A return value of
+    \c false can occur if a scorefile is being read, a socket thread
+    is already running, or an error occurs during the socket server
+    or thread initialization stages.  Socket input is considered to be
+    a realtime control mechanism that cannot run concurrently with
+    non-realtime scorefile input.
+  */
+  bool startSocketInput( int port=2001 );
+
+  //! Start MIDI input, with optional device and port identifiers.
+  /*!
+    This function creates an RtMidiIn instance for MIDI input.  The
+    RtMidiIn class invokes a local callback function to read incoming
+    messages into the queue.  If \c port = -1, RtMidiIn will open a
+    virtual port to which other software applications can connect (OS
+    X and Linux only).  A return value of \c true indicates the call
+    was successful.  A return value of \c false can occur if a
+    scorefile is being read, MIDI input is already running, or an
+    error occurs during RtMidiIn construction.  Midi input is
+    considered to be a realtime control mechanism that cannot run
+    concurrently with non-realtime scorefile input.
+  */
+  bool startMidiInput( int port=0 );
+
+#endif
+
+ protected:
+
+  MessagerData data_;
+
+#if defined(__STK_REALTIME__)
+  Thread stdinThread_;
+  Thread socketThread_;
+#endif
+
+};
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/MidiFileIn.h b/lib/MoMu-STK-1.0.0/include/MidiFileIn.h
new file mode 100644 (file)
index 0000000..9758a12
--- /dev/null
@@ -0,0 +1,135 @@
+#ifndef STK_MIDIFILEIN_H
+#define STK_MIDIFILEIN_H
+
+#include "Stk.h"
+#include <string>
+#include <vector>
+#include <fstream>
+#include <sstream>
+
+namespace stk {
+
+/**********************************************************************/
+/*! \class MidiFileIn
+    \brief A standard MIDI file reading/parsing class.
+
+    This class can be used to read events from a standard MIDI file.
+    Event bytes are copied to a C++ vector and must be subsequently
+    interpreted by the user.  The function getNextMidiEvent() skips
+    meta and sysex events, returning only MIDI channel messages.
+    Event delta-times are returned in the form of "ticks" and a
+    function is provided to determine the current "seconds per tick".
+    Tempo changes are internally tracked by the class and reflected in
+    the values returned by the function getTickSeconds().
+
+    by Gary P. Scavone, 2003 - 2010.
+*/
+/**********************************************************************/
+
+class MidiFileIn : public Stk
+{
+ public:
+  //! Default constructor.
+  /*!
+      If an error occurs while opening or parsing the file header, an
+      StkError exception will be thrown.
+  */
+  MidiFileIn( std::string fileName );
+
+  //! Class destructor.
+  ~MidiFileIn();
+
+  //! Return the MIDI file format (0, 1, or 2).
+  int getFileFormat() const;
+
+  //! Return the number of tracks in the MIDI file.
+  unsigned int getNumberOfTracks() const;
+
+  //! Return the MIDI file division value from the file header.
+  /*!
+      Note that this value must be "parsed" in accordance with the
+      MIDI File Specification.  In particular, if the MSB is set, the
+      file uses time-code representations for delta-time values.
+  */
+  int getDivision() const;
+
+  //! Move the specified track event reader to the beginning of its track.
+  /*!
+      The relevant track tempo value is reset as well.  If an invalid
+      track number is specified, an StkError exception will be thrown.
+  */
+  void rewindTrack( unsigned int track = 0 );
+
+  //! Get the current value, in seconds, of delta-time ticks for the specified track.
+  /*!
+      This value can change as events are read (via "Set Tempo"
+      Meta-Events).  Therefore, one should call this function after
+      every call to getNextEvent() or getNextMidiEvent().  If an
+      invalid track number is specified, an StkError exception will be
+      thrown.
+  */   
+  double getTickSeconds( unsigned int track = 0 );
+
+  //! Fill the user-provided vector with the next event in the specified track and return the event delta-time in ticks.
+  /*!
+      MIDI File events consist of a delta time and a sequence of event
+      bytes.  This function returns the delta-time value and writes
+      the subsequent event bytes directly to the event vector.  The
+      user must parse the event bytes in accordance with the MIDI File
+      Specification.  All returned MIDI channel events are complete
+      ... a status byte is provided even when running status is used
+      in the file.  If the track has reached its end, no bytes will be
+      written and the event vector size will be zero.  If an invalid
+      track number is specified or an error occurs while reading the
+      file, an StkError exception will be thrown.
+  */
+  unsigned long getNextEvent( std::vector<unsigned char> *event, unsigned int track = 0 );
+
+  //! Fill the user-provided vector with the next MIDI channel event in the specified track and return the event delta time in ticks.
+  /*!
+      All returned MIDI events are complete ... a status byte is
+      provided even when running status is used in the file.  Meta and
+      sysex events in the track are skipped though "Set Tempo" events
+      are properly parsed for use by the getTickSeconds() function.
+      If the track has reached its end, no bytes will be written and
+      the event vector size will be zero.  If an invalid track number
+      is specified or an error occurs while reading the file, an
+      StkError exception will be thrown.
+  */
+  unsigned long getNextMidiEvent( std::vector<unsigned char> *midiEvent, unsigned int track = 0 );
+
+ protected:
+
+  // This protected class function is used for reading variable-length
+  // MIDI file values. It is assumed that this function is called with
+  // the file read pointer positioned at the start of a
+  // variable-length value.  The function returns true if the value is
+  // successfully parsed.  Otherwise, it returns false.
+  bool readVariableLength( unsigned long *value );
+
+  std::ifstream file_;
+  unsigned int nTracks_;
+  int format_;
+  int division_;
+  bool usingTimeCode_;
+  std::vector<double> tickSeconds_;
+  std::vector<long> trackPointers_;
+  std::vector<long> trackOffsets_;
+  std::vector<long> trackLengths_;
+  std::vector<char> trackStatus_;
+
+  // This structure and the following variables are used to save and
+  // keep track of a format 1 tempo map (and the initial tickSeconds
+  // parameter for formats 0 and 2).
+  struct TempoChange { 
+    unsigned long count;
+    double tickSeconds;
+  };
+  std::vector<TempoChange> tempoEvents_;
+  std::vector<unsigned long> trackCounters_;
+  std::vector<unsigned int> trackTempoIndex_;
+};
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/Modal.h b/lib/MoMu-STK-1.0.0/include/Modal.h
new file mode 100644 (file)
index 0000000..eba0008
--- /dev/null
@@ -0,0 +1,117 @@
+#ifndef STK_MODAL_H
+#define STK_MODAL_H
+
+#include "Instrmnt.h"
+#include "Envelope.h"
+#include "FileLoop.h"
+#include "SineWave.h"
+#include "BiQuad.h"
+#include "OnePole.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class Modal
+    \brief STK resonance model abstract base class.
+
+    This class contains an excitation wavetable,
+    an envelope, an oscillator, and N resonances
+    (non-sweeping BiQuad filters), where N is set
+    during instantiation.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class Modal : public Instrmnt
+{
+public:
+  //! Class constructor, taking the desired number of modes to create.
+  /*!
+    An StkError will be thrown if the rawwave path is incorrectly set.
+  */
+  Modal( unsigned int modes = 4 );
+
+  //! Class destructor.
+  virtual ~Modal( void );
+
+  //! Reset and clear all internal state.
+  void clear( void );
+
+  //! Set instrument parameters for a particular frequency.
+  virtual void setFrequency( StkFloat frequency );
+
+  //! Set the ratio and radius for a specified mode filter.
+  void setRatioAndRadius( unsigned int modeIndex, StkFloat ratio, StkFloat radius );
+
+  //! Set the master gain.
+  void setMasterGain( StkFloat aGain ) { masterGain_ = aGain; };
+
+  //! Set the direct gain.
+  void setDirectGain( StkFloat aGain ) { directGain_ = aGain; };
+
+  //! Set the gain for a specified mode filter.
+  void setModeGain( unsigned int modeIndex, StkFloat gain );
+
+  //! Initiate a strike with the given amplitude (0.0 - 1.0).
+  virtual void strike( StkFloat amplitude );
+
+  //! Damp modes with a given decay factor (0.0 - 1.0).
+  void damp( StkFloat amplitude );
+
+  //! Start a note with the given frequency and amplitude.
+  void noteOn( StkFloat frequency, StkFloat amplitude );
+
+  //! Stop a note with the given amplitude (speed of decay).
+  void noteOff( StkFloat amplitude );
+
+  //! Perform the control change specified by \e number and \e value (0.0 - 128.0).
+  virtual void controlChange( int number, StkFloat value ) = 0;
+
+  //! Compute and return one output sample.
+  StkFloat tick( unsigned int channel = 0 );
+
+protected:
+
+  Envelope envelope_; 
+  FileWvIn *wave_;
+  BiQuad **filters_;
+  OnePole  onepole_;
+  SineWave vibrato_;
+
+  unsigned int nModes_;
+  std::vector<StkFloat> ratios_;
+  std::vector<StkFloat> radii_;
+
+  StkFloat vibratoGain_;
+  StkFloat masterGain_;
+  StkFloat directGain_;
+  StkFloat stickHardness_;
+  StkFloat strikePosition_;
+  StkFloat baseFrequency_;
+};
+
+inline StkFloat Modal :: tick( unsigned int )
+{
+  StkFloat temp = masterGain_ * onepole_.tick( wave_->tick() * envelope_.tick() );
+
+  StkFloat temp2 = 0.0;
+  for ( unsigned int i=0; i<nModes_; i++ )
+    temp2 += filters_[i]->tick(temp);
+
+  temp2  -= temp2 * directGain_;
+  temp2 += directGain_ * temp;
+
+  if ( vibratoGain_ != 0.0 ) {
+    // Calculate AM and apply to master out
+    temp = 1.0 + ( vibrato_.tick() * vibratoGain_ );
+    temp2 = temp * temp2;
+  }
+    
+  lastFrame_[0] = temp2;
+  return lastFrame_[0];
+}
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/ModalBar.h b/lib/MoMu-STK-1.0.0/include/ModalBar.h
new file mode 100644 (file)
index 0000000..a61cee8
--- /dev/null
@@ -0,0 +1,65 @@
+#ifndef STK_MODALBAR_H
+#define STK_MODALBAR_H
+
+#include "Modal.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class ModalBar
+    \brief STK resonant bar instrument class.
+
+    This class implements a number of different
+    struck bar instruments.  It inherits from the
+    Modal class.
+
+    Control Change Numbers: 
+       - Stick Hardness = 2
+       - Stick Position = 4
+       - Vibrato Gain = 1
+       - Vibrato Frequency = 11
+       - Direct Stick Mix = 8
+       - Volume = 128
+       - Modal Presets = 16
+         - Marimba = 0
+         - Vibraphone = 1
+         - Agogo = 2
+         - Wood1 = 3
+         - Reso = 4
+         - Wood2 = 5
+         - Beats = 6
+         - Two Fixed = 7
+         - Clump = 8
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class ModalBar : public Modal
+{
+public:
+  //! Class constructor.
+  ModalBar( void );
+
+  //! Class destructor.
+  ~ModalBar( void );
+
+  //! Set stick hardness (0.0 - 1.0).
+  void setStickHardness( StkFloat hardness );
+
+  //! Set stick position (0.0 - 1.0).
+  void setStrikePosition( StkFloat position );
+
+  //! Select a bar preset (currently modulo 9).
+  void setPreset( int preset );
+
+  //! Set the modulation (vibrato) depth.
+  void setModulationDepth( StkFloat mDepth );
+
+  //! Perform the control change specified by \e number and \e value (0.0 - 128.0).
+  void controlChange( int number, StkFloat value );
+};
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/Modulate.h b/lib/MoMu-STK-1.0.0/include/Modulate.h
new file mode 100644 (file)
index 0000000..1b77c9c
--- /dev/null
@@ -0,0 +1,108 @@
+#ifndef STK_MODULATE_H
+#define STK_MODULATE_H
+
+#include "Generator.h"
+#include "SineWave.h"
+#include "Noise.h"
+#include "OnePole.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class Modulate
+    \brief STK periodic/random modulator.
+
+    This class combines random and periodic
+    modulations to give a nice, natural human
+    modulation function.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class Modulate : public Generator
+{
+ public:
+  //! Class constructor.
+  /*!
+    An StkError can be thrown if the rawwave path is incorrect.
+   */
+  Modulate( void );
+
+  //! Class destructor.
+  ~Modulate( void );
+
+  //! Reset internal state.
+  void reset( void ) { lastFrame_[0] = 0.0; };
+
+  //! Set the periodic (vibrato) rate or frequency in Hz.
+  void setVibratoRate( StkFloat rate ) { vibrato_.setFrequency( rate ); };
+
+  //! Set the periodic (vibrato) gain.
+  void setVibratoGain( StkFloat gain ) { vibratoGain_ = gain; };
+
+  //! Set the random modulation gain.
+  void setRandomGain( StkFloat gain );
+
+  //! Return the last computed output value.
+  StkFloat lastOut( void ) const { return lastFrame_[0]; };
+
+  //! Compute and return one output sample.
+  StkFloat tick( void );
+
+  //! Fill a channel of the StkFrames object with computed outputs.
+  /*!
+    The \c channel argument must be less than the number of
+    channels in the StkFrames argument (the first channel is specified
+    by 0).  However, range checking is only performed if _STK_DEBUG_
+    is defined during compilation, in which case an out-of-range value
+    will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
+
+ protected:
+
+  void sampleRateChanged( StkFloat newRate, StkFloat oldRate );
+
+  SineWave vibrato_;
+  Noise noise_;
+  OnePole  filter_;
+  StkFloat vibratoGain_;
+  StkFloat randomGain_;
+  unsigned int noiseRate_;
+  unsigned int noiseCounter_;
+
+};
+
+inline StkFloat Modulate :: tick( void )
+{
+  // Compute periodic and random modulations.
+  lastFrame_[0] = vibratoGain_ * vibrato_.tick();
+  if ( noiseCounter_++ >= noiseRate_ ) {
+    noise_.tick();
+    noiseCounter_ = 0;
+  }
+  lastFrame_[0] += filter_.tick( noise_.lastOut() );
+  return lastFrame_[0];
+}
+
+inline StkFrames& Modulate :: tick( StkFrames& frames, unsigned int channel )
+{
+#if defined(_STK_DEBUG_)
+  if ( channel >= frames.channels() ) {
+    errorString_ << "Modulate::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *samples = &frames[channel];
+  unsigned int hop = frames.channels();
+  for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
+    *samples = Modulate::tick();
+
+  return frames;
+}
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/Moog.h b/lib/MoMu-STK-1.0.0/include/Moog.h
new file mode 100644 (file)
index 0000000..6f6053a
--- /dev/null
@@ -0,0 +1,88 @@
+#ifndef STK_MOOG_H
+#define STK_MOOG_H
+
+#include "Sampler.h"
+#include "FormSwep.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class Moog
+    \brief STK moog-like swept filter sampling synthesis class.
+
+    This instrument uses one attack wave, one
+    looped wave, and an ADSR envelope (inherited
+    from the Sampler class) and adds two sweepable
+    formant (FormSwep) filters.
+
+    Control Change Numbers: 
+       - Filter Q = 2
+       - Filter Sweep Rate = 4
+       - Vibrato Frequency = 11
+       - Vibrato Gain = 1
+       - Gain = 128
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class Moog : public Sampler
+{
+ public:
+  //! Class constructor.
+  /*!
+    An StkError will be thrown if the rawwave path is incorrectly set.
+  */
+  Moog( void );
+
+  //! Class destructor.
+  ~Moog( void );
+
+  //! Set instrument parameters for a particular frequency.
+  void setFrequency( StkFloat frequency );
+
+  //! Start a note with the given frequency and amplitude.
+  void noteOn( StkFloat frequency, StkFloat amplitude );
+
+  //! Set the modulation (vibrato) speed in Hz.
+  void setModulationSpeed( StkFloat mSpeed ) { loops_[1]->setFrequency( mSpeed ); };
+
+  //! Set the modulation (vibrato) depth.
+  void setModulationDepth( StkFloat mDepth ) { modDepth_ = mDepth * 0.5; };
+
+  //! Perform the control change specified by \e number and \e value (0.0 - 128.0).
+  void controlChange( int number, StkFloat value );
+
+  //! Compute and return one output sample.
+  StkFloat tick( unsigned int channel = 0 );
+
+ protected:
+
+  FormSwep filters_[2];
+  StkFloat modDepth_;
+  StkFloat filterQ_;
+  StkFloat filterRate_;
+
+};
+
+inline StkFloat Moog :: tick( unsigned int )
+{
+  StkFloat temp;
+
+  if ( modDepth_ != 0.0 ) {
+    temp = loops_[1]->tick() * modDepth_;    
+    loops_[0]->setFrequency( baseFrequency_ * (1.0 + temp) );
+  }
+
+  temp = attackGain_ * attacks_[0]->tick();
+  temp += loopGain_ * loops_[0]->tick();
+  temp = filter_.tick( temp );
+  temp *= adsr_.tick();
+  temp = filters_[0].tick( temp );
+  lastFrame_[0] = filters_[1].tick( temp );
+  return lastFrame_[0] * 6.0;
+}
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/Mutex.h b/lib/MoMu-STK-1.0.0/include/Mutex.h
new file mode 100644 (file)
index 0000000..57ec712
--- /dev/null
@@ -0,0 +1,74 @@
+#ifndef STK_MUTEX_H
+#define STK_MUTEX_H
+
+#include "Stk.h"
+
+#if (defined(__OS_IRIX__) || defined(__OS_LINUX__) || defined(__OS_MACOSX__))
+
+  #include <pthread.h>
+  typedef pthread_mutex_t MUTEX;
+  typedef pthread_cond_t CONDITION;
+
+#elif defined(__OS_WINDOWS__)
+
+  #include <windows.h>
+  #include <process.h>
+  typedef CRITICAL_SECTION MUTEX;
+  typedef HANDLE CONDITION;
+
+#endif
+
+namespace stk {
+
+/***************************************************/
+/*! \class Mutex
+    \brief STK mutex class.
+
+    This class provides a uniform interface for
+    cross-platform mutex use.  On Linux and IRIX
+    systems, the pthread library is used. Under
+    Windows, critical sections are used.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class Mutex : public Stk
+{
+ public:
+  //! Default constructor.
+  Mutex();
+
+  //! Class destructor.
+  ~Mutex();
+
+  //! Lock the mutex.
+  void lock(void);
+
+  //! Unlock the mutex.
+  void unlock(void);
+
+  //! Wait indefinitely on the mutex condition variable.
+  /*!
+    The mutex must be locked before calling this function, and then
+    subsequently unlocked after this function returns.
+   */
+  void wait(void);
+
+  //! Signal the condition variable.
+  /*!
+    The mutex must be locked before calling this function, and then
+    subsequently unlocked after this function returns.
+   */
+  void signal(void);
+
+ protected:
+
+  MUTEX mutex_;
+  CONDITION condition_;
+
+};
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/NRev.h b/lib/MoMu-STK-1.0.0/include/NRev.h
new file mode 100644 (file)
index 0000000..43933d1
--- /dev/null
@@ -0,0 +1,160 @@
+#ifndef STK_NREV_H
+#define STK_NREV_H
+
+#include "Effect.h"
+#include "Delay.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class NRev
+    \brief CCRMA's NRev reverberator class.
+
+    This class takes a monophonic input signal and produces a stereo
+    output signal.  It is derived from the CLM NRev function, which is
+    based on the use of networks of simple allpass and comb delay
+    filters.  This particular arrangement consists of 6 comb filters
+    in parallel, followed by 3 allpass filters, a lowpass filter, and
+    another allpass in series, followed by two allpass filters in
+    parallel with corresponding right and left outputs.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class NRev : public Effect
+{
+ public:
+  //! Class constructor taking a T60 decay time argument (one second default value).
+  NRev( StkFloat T60 = 1.0 );
+
+  //! Reset and clear all internal state.
+  void clear( void );
+
+  //! Set the reverberation T60 decay time.
+  void setT60( StkFloat T60 );
+
+  //! Return the specified channel value of the last computed stereo frame.
+  /*!
+    Use the lastFrame() function to get both values of the last
+    computed stereo frame.  The \c channel argument must be 0 or 1
+    (the first channel is specified by 0).  However, range checking is
+    only performed if _STK_DEBUG_ is defined during compilation, in
+    which case an out-of-range value will trigger an StkError
+    exception.
+  */
+  StkFloat lastOut( unsigned int channel = 0 );
+
+  //! Input one sample to the effect and return the specified \c channel value of the computed stereo frame.
+  /*!
+    Use the lastFrame() function to get both values of the computed
+    stereo output frame. The \c channel argument must be 0 or 1 (the
+    first channel is specified by 0).  However, range checking is only
+    performed if _STK_DEBUG_ is defined during compilation, in which
+    case an out-of-range value will trigger an StkError exception.
+  */
+  StkFloat tick( StkFloat input, unsigned int channel = 0 );
+
+  //! Take a channel of the StkFrames object as inputs to the effect and replace with stereo outputs.
+  /*!
+    The StkFrames argument reference is returned.  The stereo
+    outputs are written to the StkFrames argument starting at the
+    specified \c channel.  Therefore, the \c channel argument must be
+    less than ( channels() - 1 ) of the StkFrames argument (the first
+    channel is specified by 0).  However, range checking is only
+    performed if _STK_DEBUG_ is defined during compilation, in which
+    case an out-of-range value will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
+
+  //! Take a channel of the \c iFrames object as inputs to the effect and write stereo outputs to the \c oFrames object.
+  /*!
+    The \c iFrames object reference is returned.  The \c iChannel
+    argument must be less than the number of channels in the \c
+    iFrames argument (the first channel is specified by 0).  The \c
+    oChannel argument must be less than ( channels() - 1 ) of the \c
+    oFrames argument.  However, range checking is only performed if
+    _STK_DEBUG_ is defined during compilation, in which case an
+    out-of-range value will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0, unsigned int oChannel = 0 );
+
+ protected:
+
+  Delay allpassDelays_[8];
+  Delay combDelays_[6];
+  StkFloat allpassCoefficient_;
+  StkFloat combCoefficient_[6];
+       StkFloat lowpassState_;
+
+};
+
+inline StkFloat NRev :: lastOut( unsigned int channel )
+{
+#if defined(_STK_DEBUG_)
+  if ( channel > 1 ) {
+    errorString_ << "NRev::lastOut(): channel argument must be less than 2!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  return lastFrame_[channel];
+}
+
+inline StkFloat NRev :: tick( StkFloat input, unsigned int channel )
+{
+#if defined(_STK_DEBUG_)
+  if ( channel > 1 ) {
+    errorString_ << "NRev::tick(): channel argument must be less than 2!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat temp, temp0, temp1, temp2, temp3;
+  int i;
+
+  temp0 = 0.0;
+  for ( i=0; i<6; i++ ) {
+    temp = input + (combCoefficient_[i] * combDelays_[i].lastOut());
+    temp0 += combDelays_[i].tick(temp);
+  }
+
+  for ( i=0; i<3; i++ )        {
+    temp = allpassDelays_[i].lastOut();
+    temp1 = allpassCoefficient_ * temp;
+    temp1 += temp0;
+    allpassDelays_[i].tick(temp1);
+    temp0 = -(allpassCoefficient_ * temp1) + temp;
+  }
+
+       // One-pole lowpass filter.
+  lowpassState_ = 0.7 * lowpassState_ + 0.3 * temp0;
+  temp = allpassDelays_[3].lastOut();
+  temp1 = allpassCoefficient_ * temp;
+  temp1 += lowpassState_;
+  allpassDelays_[3].tick( temp1 );
+  temp1 = -( allpassCoefficient_ * temp1 ) + temp;
+    
+  temp = allpassDelays_[4].lastOut();
+  temp2 = allpassCoefficient_ * temp;
+  temp2 += temp1;
+  allpassDelays_[4].tick( temp2 );
+  lastFrame_[0] = effectMix_*( -( allpassCoefficient_ * temp2 ) + temp );
+    
+  temp = allpassDelays_[5].lastOut();
+  temp3 = allpassCoefficient_ * temp;
+  temp3 += temp1;
+  allpassDelays_[5].tick( temp3 );
+  lastFrame_[1] = effectMix_*( - ( allpassCoefficient_ * temp3 ) + temp );
+
+  temp = ( 1.0 - effectMix_ ) * input;
+  lastFrame_[0] += temp;
+  lastFrame_[1] += temp;
+    
+  return lastFrame_[channel];
+}
+
+} // stk namespace
+
+#endif
+
diff --git a/lib/MoMu-STK-1.0.0/include/Noise.h b/lib/MoMu-STK-1.0.0/include/Noise.h
new file mode 100644 (file)
index 0000000..12ecc18
--- /dev/null
@@ -0,0 +1,83 @@
+#ifndef STK_NOISE_H
+#define STK_NOISE_H
+
+#include "Generator.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class Noise
+    \brief STK noise generator.
+
+    Generic random number generation using the
+    C rand() function.  The quality of the rand()
+    function varies from one OS to another.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class Noise : public Generator
+{
+public:
+
+  //! Default constructor that can also take a specific seed value.
+  /*!
+    If the seed value is zero (the default value), the random number generator is
+    seeded with the system time.
+  */
+  Noise( unsigned int seed = 0 );
+
+  //! Seed the random number generator with a specific seed value.
+  /*!
+    If no seed is provided or the seed value is zero, the random
+    number generator is seeded with the current system time.
+  */
+  void setSeed( unsigned int seed = 0 );
+
+  //! Return the last computed output value.
+  StkFloat lastOut( void ) const { return lastFrame_[0]; };
+
+  //! Compute and return one output sample.
+  StkFloat tick( void );
+
+  //! Fill a channel of the StkFrames object with computed outputs.
+  /*!
+    The \c channel argument must be less than the number of
+    channels in the StkFrames argument (the first channel is specified
+    by 0).  However, range checking is only performed if _STK_DEBUG_
+    is defined during compilation, in which case an out-of-range value
+    will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
+
+protected:
+
+};
+
+inline StkFloat Noise :: tick( void )
+{
+  return lastFrame_[0] = (StkFloat) ( 2.0 * rand() / (RAND_MAX + 1.0) - 1.0 );
+}
+
+inline StkFrames& Noise :: tick( StkFrames& frames, unsigned int channel )
+{
+#if defined(_STK_DEBUG_)
+  if ( channel >= frames.channels() ) {
+    errorString_ << "Noise::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *samples = &frames[channel];
+  unsigned int hop = frames.channels();
+  for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
+    *samples = (StkFloat) ( 2.0 * rand() / (RAND_MAX + 1.0) - 1.0 );
+
+  lastFrame_[0] = *(samples-hop);
+  return frames;
+}
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/OnePole.h b/lib/MoMu-STK-1.0.0/include/OnePole.h
new file mode 100644 (file)
index 0000000..3ca838f
--- /dev/null
@@ -0,0 +1,133 @@
+#ifndef STK_ONEPOLE_H
+#define STK_ONEPOLE_H
+
+#include "Filter.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class OnePole
+    \brief STK one-pole filter class.
+
+    This class implements a one-pole digital filter.  A method is
+    provided for setting the pole position along the real axis of the
+    z-plane while maintaining a constant peak filter gain.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class OnePole : public Filter
+{
+public:
+
+  //! The default constructor creates a low-pass filter (pole at z = 0.9).
+  OnePole( StkFloat thePole = 0.9 );
+
+  //! Class destructor.
+  ~OnePole();
+
+  //! Set the b[0] coefficient value.
+  void setB0( StkFloat b0 ) { b_[0] = b0; };
+
+  //! Set the a[1] coefficient value.
+  void setA1( StkFloat a1 ) { a_[1] = a1; };
+
+  //! Set all filter coefficients.
+  void setCoefficients( StkFloat b0, StkFloat a1, bool clearState = false );
+
+  //! Set the pole position in the z-plane.
+  /*!
+    This method sets the pole position along the real-axis of the
+    z-plane and normalizes the coefficients for a maximum gain of one.
+    A positive pole value produces a low-pass filter, while a negative
+    pole value produces a high-pass filter.  This method does not
+    affect the filter \e gain value.
+  */
+  void setPole( StkFloat thePole );
+
+  //! Return the last computed output value.
+  StkFloat lastOut( void ) const { return lastFrame_[0]; };
+
+  //! Input one sample to the filter and return one output.
+  StkFloat tick( StkFloat input );
+
+  //! Take a channel of the StkFrames object as inputs to the filter and replace with corresponding outputs.
+  /*!
+    The StkFrames argument reference is returned.  The \c channel
+    argument must be less than the number of channels in the
+    StkFrames argument (the first channel is specified by 0).
+    However, range checking is only performed if _STK_DEBUG_ is
+    defined during compilation, in which case an out-of-range value
+    will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
+
+  //! Take a channel of the \c iFrames object as inputs to the filter and write outputs to the \c oFrames object.
+  /*!
+    The \c iFrames object reference is returned.  Each channel
+    argument must be less than the number of channels in the
+    corresponding StkFrames argument (the first channel is specified
+    by 0).  However, range checking is only performed if _STK_DEBUG_
+    is defined during compilation, in which case an out-of-range value
+    will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0, unsigned int oChannel = 0 );
+
+};
+
+inline StkFloat OnePole :: tick( StkFloat input )
+{
+  inputs_[0] = gain_ * input;
+  lastFrame_[0] = b_[0] * inputs_[0] - a_[1] * outputs_[1];
+  outputs_[1] = lastFrame_[0];
+
+  return lastFrame_[0];
+}
+
+inline StkFrames& OnePole :: tick( StkFrames& frames, unsigned int channel )
+{
+#if defined(_STK_DEBUG_)
+  if ( channel >= frames.channels() ) {
+    errorString_ << "OnePole::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *samples = &frames[channel];
+  unsigned int hop = frames.channels();
+  for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
+    inputs_[0] = gain_ * *samples;
+    *samples = b_[0] * inputs_[0] - a_[1] * outputs_[1];
+    outputs_[1] = *samples;
+  }
+
+  lastFrame_[0] = outputs_[1];
+  return frames;
+}
+
+inline StkFrames& OnePole :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iChannel, unsigned int oChannel )
+{
+#if defined(_STK_DEBUG_)
+  if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
+    errorString_ << "OnePole::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *iSamples = &iFrames[iChannel];
+  StkFloat *oSamples = &oFrames[oChannel];
+  unsigned int iHop = iFrames.channels(), oHop = oFrames.channels();
+  for ( unsigned int i=0; i<iFrames.frames(); i++, iSamples += iHop, oSamples += oHop ) {
+    inputs_[0] = gain_ * *iSamples;
+    *oSamples = b_[0] * inputs_[0] - a_[1] * outputs_[1];
+    outputs_[1] = *oSamples;
+  }
+
+  lastFrame_[0] = outputs_[1];
+  return iFrames;
+}
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/OneZero.h b/lib/MoMu-STK-1.0.0/include/OneZero.h
new file mode 100644 (file)
index 0000000..b3d0aaf
--- /dev/null
@@ -0,0 +1,134 @@
+#ifndef STK_ONEZERO_H
+#define STK_ONEZERO_H
+
+#include "Filter.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class OneZero
+  \brief STK one-zero filter class.
+
+  This class implements a one-zero digital filter.  A method is
+  provided for setting the zero position along the real axis of the
+  z-plane while maintaining a constant filter gain.
+
+  by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class OneZero : public Filter
+{
+ public:
+
+  //! The default constructor creates a low-pass filter (zero at z = -1.0).
+  OneZero( StkFloat theZero = -1.0 );
+
+  //! Class destructor.
+  ~OneZero();
+
+  //! Set the b[0] coefficient value.
+  void setB0( StkFloat b0 ) { b_[0] = b0; };
+
+  //! Set the b[1] coefficient value.
+  void setB1( StkFloat b1 ) { b_[1] = b1; };
+
+  //! Set all filter coefficients.
+  void setCoefficients( StkFloat b0, StkFloat b1, bool clearState = false );
+
+  //! Set the zero position in the z-plane.
+  /*!
+    This method sets the zero position along the real-axis of the
+    z-plane and normalizes the coefficients for a maximum gain of one.
+    A positive zero value produces a high-pass filter, while a
+    negative zero value produces a low-pass filter.  This method does
+    not affect the filter \e gain value.
+  */
+  void setZero( StkFloat theZero );
+
+  //! Return the last computed output value.
+  StkFloat lastOut( void ) const { return lastFrame_[0]; };
+
+  //! Input one sample to the filter and return one output.
+  StkFloat tick( StkFloat input );
+
+  //! Take a channel of the StkFrames object as inputs to the filter and replace with corresponding outputs.
+  /*!
+    The StkFrames argument reference is returned.  The \c channel
+    argument must be less than the number of channels in the
+    StkFrames argument (the first channel is specified by 0).
+    However, range checking is only performed if _STK_DEBUG_ is
+    defined during compilation, in which case an out-of-range value
+    will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
+
+  //! Take a channel of the \c iFrames object as inputs to the filter and write outputs to the \c oFrames object.
+  /*!
+    The \c iFrames object reference is returned.  Each channel
+    argument must be less than the number of channels in the
+    corresponding StkFrames argument (the first channel is specified
+    by 0).  However, range checking is only performed if _STK_DEBUG_
+    is defined during compilation, in which case an out-of-range value
+    will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0, unsigned int oChannel = 0 );
+
+};
+
+inline StkFloat OneZero :: tick( StkFloat input )
+{
+  inputs_[0] = gain_ * input;
+  lastFrame_[0] = b_[1] * inputs_[1] + b_[0] * inputs_[0];
+  inputs_[1] = inputs_[0];
+
+  return lastFrame_[0];
+}
+
+inline StkFrames& OneZero :: tick( StkFrames& frames, unsigned int channel )
+{
+#if defined(_STK_DEBUG_)
+  if ( channel >= frames.channels() ) {
+    errorString_ << "OneZero::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *samples = &frames[channel];
+  unsigned int hop = frames.channels();
+  for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
+    inputs_[0] = gain_ * *samples;
+    *samples = b_[1] * inputs_[1] + b_[0] * inputs_[0];
+    inputs_[1] = inputs_[0];
+  }
+
+  lastFrame_[0] = *(samples-hop);
+  return frames;
+}
+
+inline StkFrames& OneZero :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iChannel, unsigned int oChannel )
+{
+#if defined(_STK_DEBUG_)
+  if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
+    errorString_ << "OneZero::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *iSamples = &iFrames[iChannel];
+  StkFloat *oSamples = &oFrames[oChannel];
+  unsigned int iHop = iFrames.channels(), oHop = oFrames.channels();
+  for ( unsigned int i=0; i<iFrames.frames(); i++, iSamples += iHop, oSamples += oHop ) {
+    inputs_[0] = gain_ * *iSamples;
+    *oSamples = b_[1] * inputs_[1] + b_[0] * inputs_[0];
+    inputs_[1] = inputs_[0];
+  }
+
+  lastFrame_[0] = *(oSamples-oHop);
+  return iFrames;
+}
+
+} // stk namespace
+
+#endif
+
diff --git a/lib/MoMu-STK-1.0.0/include/PRCRev.h b/lib/MoMu-STK-1.0.0/include/PRCRev.h
new file mode 100644 (file)
index 0000000..3a0324a
--- /dev/null
@@ -0,0 +1,140 @@
+#ifndef STK_PRCREV_H
+#define STK_PRCREV_H
+
+#include "Effect.h"
+#include "Delay.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class PRCRev
+    \brief Perry's simple reverberator class.
+
+    This class takes a monophonic input signal and produces a stereo
+    output signal.  It is based on some of the famous Stanford/CCRMA
+    reverbs (NRev, KipRev), which were based on the
+    Chowning/Moorer/Schroeder reverberators using networks of simple
+    allpass and comb delay filters.  This class implements two series
+    allpass units and two parallel comb filters.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class PRCRev : public Effect
+{
+public:
+  //! Class constructor taking a T60 decay time argument (one second default value).
+  PRCRev( StkFloat T60 = 1.0 );
+
+  //! Reset and clear all internal state.
+  void clear( void );
+
+  //! Set the reverberation T60 decay time.
+  void setT60( StkFloat T60 );
+
+  //! Return the specified channel value of the last computed stereo frame.
+  /*!
+    Use the lastFrame() function to get both values of the last
+    computed stereo frame.  The \c channel argument must be 0 or 1
+    (the first channel is specified by 0).  However, range checking is
+    only performed if _STK_DEBUG_ is defined during compilation, in
+    which case an out-of-range value will trigger an StkError
+    exception.
+  */
+  StkFloat lastOut( unsigned int channel = 0 );
+
+  //! Input one sample to the effect and return the specified \c channel value of the computed stereo frame.
+  /*!
+    Use the lastFrame() function to get both values of the computed
+    stereo output frame. The \c channel argument must be 0 or 1 (the
+    first channel is specified by 0).  However, range checking is only
+    performed if _STK_DEBUG_ is defined during compilation, in which
+    case an out-of-range value will trigger an StkError exception.
+  */
+  StkFloat tick( StkFloat input, unsigned int channel = 0 );
+
+  //! Take a channel of the StkFrames object as inputs to the effect and replace with stereo outputs.
+  /*!
+    The StkFrames argument reference is returned.  The stereo
+    outputs are written to the StkFrames argument starting at the
+    specified \c channel.  Therefore, the \c channel argument must be
+    less than ( channels() - 1 ) of the StkFrames argument (the first
+    channel is specified by 0).  However, range checking is only
+    performed if _STK_DEBUG_ is defined during compilation, in which
+    case an out-of-range value will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
+
+  //! Take a channel of the \c iFrames object as inputs to the effect and write stereo outputs to the \c oFrames object.
+  /*!
+    The \c iFrames object reference is returned.  The \c iChannel
+    argument must be less than the number of channels in the \c
+    iFrames argument (the first channel is specified by 0).  The \c
+    oChannel argument must be less than ( channels() - 1 ) of the \c
+    oFrames argument.  However, range checking is only performed if
+    _STK_DEBUG_ is defined during compilation, in which case an
+    out-of-range value will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0, unsigned int oChannel = 0 );
+
+protected:
+
+  Delay allpassDelays_[2];
+  Delay combDelays_[2];
+  StkFloat allpassCoefficient_;
+  StkFloat combCoefficient_[2];
+
+};
+
+inline StkFloat PRCRev :: lastOut( unsigned int channel )
+{
+#if defined(_STK_DEBUG_)
+  if ( channel > 1 ) {
+    errorString_ << "PRCRev::lastOut(): channel argument must be less than 2!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  return lastFrame_[channel];
+}
+
+ inline StkFloat PRCRev :: tick( StkFloat input, unsigned int channel )
+{
+#if defined(_STK_DEBUG_)
+  if ( channel > 1 ) {
+    errorString_ << "PRCRev::tick(): channel argument must be less than 2!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat temp, temp0, temp1, temp2, temp3;
+
+  temp = allpassDelays_[0].lastOut();
+  temp0 = allpassCoefficient_ * temp;
+  temp0 += input;
+  allpassDelays_[0].tick(temp0);
+  temp0 = -(allpassCoefficient_ * temp0) + temp;
+    
+  temp = allpassDelays_[1].lastOut();
+  temp1 = allpassCoefficient_ * temp;
+  temp1 += temp0;
+  allpassDelays_[1].tick(temp1);
+  temp1 = -(allpassCoefficient_ * temp1) + temp;
+    
+  temp2 = temp1 + (combCoefficient_[0] * combDelays_[0].lastOut());
+  temp3 = temp1 + (combCoefficient_[1] * combDelays_[1].lastOut());
+
+  lastFrame_[0] = effectMix_ * (combDelays_[0].tick(temp2));
+  lastFrame_[1] = effectMix_ * (combDelays_[1].tick(temp3));
+  temp = (1.0 - effectMix_) * input;
+  lastFrame_[0] += temp;
+  lastFrame_[1] += temp;
+
+  return lastFrame_[channel];
+}
+
+} // stk namespace
+
+#endif
+
diff --git a/lib/MoMu-STK-1.0.0/include/PercFlut.h b/lib/MoMu-STK-1.0.0/include/PercFlut.h
new file mode 100644 (file)
index 0000000..326d55c
--- /dev/null
@@ -0,0 +1,90 @@
+#ifndef STK_PERCFLUT_H
+#define STK_PERCFLUT_H
+
+#include "FM.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class PercFlut
+    \brief STK percussive flute FM synthesis instrument.
+
+    This class implements algorithm 4 of the TX81Z.
+
+    \code
+    Algorithm 4 is :   4->3--\
+                          2-- + -->1-->Out
+    \endcode
+
+    Control Change Numbers: 
+       - Total Modulator Index = 2
+       - Modulator Crossfade = 4
+       - LFO Speed = 11
+       - LFO Depth = 1
+       - ADSR 2 & 4 Target = 128
+
+    The basic Chowning/Stanford FM patent expired
+    in 1995, but there exist follow-on patents,
+    mostly assigned to Yamaha.  If you are of the
+    type who should worry about this (making
+    money) worry away.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class PercFlut : public FM
+{
+ public:
+  //! Class constructor.
+  /*!
+    An StkError will be thrown if the rawwave path is incorrectly set.
+  */
+  PercFlut( void );
+
+  //! Class destructor.
+  ~PercFlut( void );
+
+  //! Set instrument parameters for a particular frequency.
+  void setFrequency( StkFloat frequency );
+
+  //! Start a note with the given frequency and amplitude.
+  void noteOn( StkFloat frequency, StkFloat amplitude );
+
+  //! Compute and return one output sample.
+  StkFloat tick( unsigned int channel = 0 );
+
+ protected:
+
+};
+
+inline StkFloat PercFlut :: tick( unsigned int )
+{
+  register StkFloat temp;
+
+  temp = vibrato_.tick() * modDepth_ * 0.2;    
+  waves_[0]->setFrequency(baseFrequency_ * (1.0 + temp) * ratios_[0]);
+  waves_[1]->setFrequency(baseFrequency_ * (1.0 + temp) * ratios_[1]);
+  waves_[2]->setFrequency(baseFrequency_ * (1.0 + temp) * ratios_[2]);
+  waves_[3]->setFrequency(baseFrequency_ * (1.0 + temp) * ratios_[3]);
+    
+  waves_[3]->addPhaseOffset( twozero_.lastOut() );
+  temp = gains_[3] * adsr_[3]->tick() * waves_[3]->tick();
+
+  twozero_.tick(temp);
+  waves_[2]->addPhaseOffset( temp );
+  temp = (1.0 - (control2_ * 0.5)) * gains_[2] * adsr_[2]->tick() * waves_[2]->tick();
+
+  temp += control2_ * 0.5 * gains_[1] * adsr_[1]->tick() * waves_[1]->tick();
+  temp = temp * control1_;
+
+  waves_[0]->addPhaseOffset(temp);
+  temp = gains_[0] * adsr_[0]->tick() * waves_[0]->tick();
+    
+  lastFrame_[0] = temp * 0.5;
+  return lastFrame_[0];
+}
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/Phonemes.h b/lib/MoMu-STK-1.0.0/include/Phonemes.h
new file mode 100644 (file)
index 0000000..9b7a084
--- /dev/null
@@ -0,0 +1,54 @@
+#ifndef STK_PHONEMES_H
+#define STK_PHONEMES_H
+
+#include "Stk.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class Phonemes
+    \brief STK phonemes table.
+
+    This class does nothing other than declare a
+    set of 32 static phoneme formant parameters
+    and provide access to those values.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class Phonemes : public Stk
+{
+public:
+
+  Phonemes(void);
+  ~Phonemes(void);
+
+  //! Returns the phoneme name for the given index (0-31).
+  static const char *name( unsigned int index );
+
+  //! Returns the voiced component gain for the given phoneme index (0-31).
+  static StkFloat voiceGain( unsigned int index );
+
+  //! Returns the unvoiced component gain for the given phoneme index (0-31).
+  static StkFloat noiseGain( unsigned int index );
+
+  //! Returns the formant frequency for the given phoneme index (0-31) and partial (0-3).
+  static StkFloat formantFrequency( unsigned int index, unsigned int partial );
+
+  //! Returns the formant radius for the given phoneme index (0-31) and partial (0-3).
+  static StkFloat formantRadius( unsigned int index, unsigned int partial );
+
+  //! Returns the formant gain for the given phoneme index (0-31) and partial (0-3).
+  static StkFloat formantGain( unsigned int index, unsigned int partial );
+
+private:
+
+  static const char phonemeNames[][4];
+  static const StkFloat phonemeGains[][2];
+  static const StkFloat phonemeParameters[][4][3];
+};
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/PitShift.h b/lib/MoMu-STK-1.0.0/include/PitShift.h
new file mode 100644 (file)
index 0000000..a1551a2
--- /dev/null
@@ -0,0 +1,107 @@
+#ifndef STK_PITSHIFT_H
+#define STK_PITSHIFT_H
+
+#include "Effect.h"
+#include "DelayL.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class PitShift
+    \brief STK simple pitch shifter effect class.
+
+    This class implements a simple pitch shifter
+    using delay lines.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+const int maxDelay = 5024;
+
+class PitShift : public Effect
+{
+ public:
+  //! Class constructor.
+  PitShift( void );
+
+  //! Reset and clear all internal state.
+  void clear( void );
+
+  //! Set the pitch shift factor (1.0 produces no shift).
+  void setShift( StkFloat shift );
+
+  //! Return the last computed output value.
+  StkFloat lastOut( void ) const { return lastFrame_[0]; };
+
+  //! Input one sample to the effect and return one output.
+  StkFloat tick( StkFloat input );
+
+  //! Take a channel of the StkFrames object as inputs to the effect and replace with corresponding outputs.
+  /*!
+    The StkFrames argument reference is returned.  The \c channel
+    argument must be less than the number of channels in the
+    StkFrames argument (the first channel is specified by 0).
+    However, range checking is only performed if _STK_DEBUG_ is
+    defined during compilation, in which case an out-of-range value
+    will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
+
+  //! Take a channel of the \c iFrames object as inputs to the effect and write outputs to the \c oFrames object.
+  /*!
+    The \c iFrames object reference is returned.  Each channel
+    argument must be less than the number of channels in the
+    corresponding StkFrames argument (the first channel is specified
+    by 0).  However, range checking is only performed if _STK_DEBUG_
+    is defined during compilation, in which case an out-of-range value
+    will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0, unsigned int oChannel = 0 );
+
+ protected:
+
+  DelayL delayLine_[2];
+  StkFloat delay_[2];
+  StkFloat env_[2];
+  StkFloat rate_;
+  unsigned long delayLength_;
+  unsigned long halfLength_;
+
+};
+
+inline StkFloat PitShift :: tick( StkFloat input )
+{
+  // Calculate the two delay length values, keeping them within the
+  // range 12 to maxDelay-12.
+  delay_[0] += rate_;
+  while ( delay_[0] > maxDelay-12 ) delay_[0] -= delayLength_;
+  while ( delay_[0] < 12 ) delay_[0] += delayLength_;
+
+  delay_[1] = delay_[0] + halfLength_;
+  while ( delay_[1] > maxDelay-12 ) delay_[1] -= delayLength_;
+  while ( delay_[1] < 12 ) delay_[1] += delayLength_;
+
+  // Set the new delay line lengths.
+  delayLine_[0].setDelay( delay_[0] );
+  delayLine_[1].setDelay( delay_[1] );
+
+  // Calculate a triangular envelope.
+  env_[1] = fabs( ( delay_[0] - halfLength_ + 12 ) * ( 1.0 / (halfLength_ + 12 ) ) );
+  env_[0] = 1.0 - env_[1];
+
+  // Delay input and apply envelope.
+  lastFrame_[0] =  env_[0] * delayLine_[0].tick( input );
+  lastFrame_[0] += env_[1] * delayLine_[1].tick( input );
+
+  // Compute effect mix and output.
+  lastFrame_[0] *= effectMix_;
+  lastFrame_[0] += ( 1.0 - effectMix_ ) * input;
+
+  return lastFrame_[0];
+}
+
+} // stk namespace
+
+#endif
+
diff --git a/lib/MoMu-STK-1.0.0/include/PluckTwo.h b/lib/MoMu-STK-1.0.0/include/PluckTwo.h
new file mode 100644 (file)
index 0000000..d39fe6a
--- /dev/null
@@ -0,0 +1,89 @@
+#ifndef STK_PLUCKTWO_H
+#define STK_PLUCKTWO_H
+
+#include "Instrmnt.h"
+#include "DelayL.h"
+#include "DelayA.h"
+#include "OneZero.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class PluckTwo
+    \brief STK enhanced plucked string model class.
+
+    This class implements an enhanced two-string,
+    plucked physical model, a la Jaffe-Smith,
+    Smith, and others.
+
+    PluckTwo is an abstract class, with no excitation
+    specified.  Therefore, it can't be directly
+    instantiated.
+
+    This is a digital waveguide model, making its
+    use possibly subject to patents held by
+    Stanford University, Yamaha, and others.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class PluckTwo : public Instrmnt
+{
+ public:
+  //! Class constructor, taking the lowest desired playing frequency.
+  PluckTwo( StkFloat lowestFrequency );
+
+  //! Class destructor.
+  virtual ~PluckTwo( void );
+
+  //! Reset and clear all internal state.
+  void clear( void );
+
+  //! Set instrument parameters for a particular frequency.
+  virtual void setFrequency( StkFloat frequency );
+
+  //! Detune the two strings by the given factor.  A value of 1.0 produces unison strings.
+  void setDetune( StkFloat detune );
+
+  //! Efficient combined setting of frequency and detuning.
+  void setFreqAndDetune( StkFloat frequency, StkFloat detune );
+
+  //! Set the pluck or "excitation" position along the string (0.0 - 1.0).
+  void setPluckPosition( StkFloat position );
+
+  //! Set the base loop gain.
+  /*!
+    The actual loop gain is set according to the frequency.
+    Because of high-frequency loop filter roll-off, higher
+    frequency settings have greater loop gains.
+  */
+  void setBaseLoopGain( StkFloat aGain );
+
+  //! Stop a note with the given amplitude (speed of decay).
+  virtual void noteOff( StkFloat amplitude );
+
+  virtual StkFloat tick( unsigned int channel = 0 ) = 0;
+
+ protected:
+
+  DelayA  delayLine_;
+  DelayA  delayLine2_;
+  DelayL  combDelay_;
+  OneZero filter_;
+  OneZero filter2_;
+
+  unsigned long length_;
+  StkFloat loopGain_;
+  StkFloat baseLoopGain_;
+  StkFloat lastFrequency_;
+  StkFloat lastLength_;
+  StkFloat detuning_;
+  StkFloat pluckAmplitude_;
+  StkFloat pluckPosition_;
+
+};
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/Plucked.h b/lib/MoMu-STK-1.0.0/include/Plucked.h
new file mode 100644 (file)
index 0000000..ec3860b
--- /dev/null
@@ -0,0 +1,78 @@
+#ifndef STK_PLUCKED_H
+#define STK_PLUCKED_H
+
+#include "Instrmnt.h"
+#include "DelayA.h"
+#include "OneZero.h"
+#include "OnePole.h"
+#include "Noise.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class Plucked
+    \brief STK plucked string model class.
+
+    This class implements a simple plucked string
+    physical model based on the Karplus-Strong
+    algorithm.
+
+    This is a digital waveguide model, making its
+    use possibly subject to patents held by
+    Stanford University, Yamaha, and others.
+    There exist at least two patents, assigned to
+    Stanford, bearing the names of Karplus and/or
+    Strong.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class Plucked : public Instrmnt
+{
+ public:
+  //! Class constructor, taking the lowest desired playing frequency.
+  Plucked( StkFloat lowestFrequency );
+
+  //! Class destructor.
+  ~Plucked( void );
+
+  //! Reset and clear all internal state.
+  void clear( void );
+
+  //! Set instrument parameters for a particular frequency.
+  void setFrequency( StkFloat frequency );
+
+  //! Pluck the string with the given amplitude using the current frequency.
+  void pluck( StkFloat amplitude );
+
+  //! Start a note with the given frequency and amplitude.
+  void noteOn( StkFloat frequency, StkFloat amplitude );
+
+  //! Stop a note with the given amplitude (speed of decay).
+  void noteOff( StkFloat amplitude );
+
+  //! Compute and return one output sample.
+  StkFloat tick( unsigned int channel = 0 );
+
+ protected:  
+
+  DelayA   delayLine_;
+  OneZero  loopFilter_;
+  OnePole  pickFilter_;
+  Noise    noise_;
+  StkFloat loopGain_;
+  unsigned long length_;
+
+};
+
+inline StkFloat Plucked :: tick( unsigned int )
+{
+  // Here's the whole inner loop of the instrument!!
+  return lastFrame_[0] = 3.0 * delayLine_.tick( loopFilter_.tick( delayLine_.lastOut() * loopGain_ ) ); 
+}
+
+} // stk namespace
+
+#endif
+
diff --git a/lib/MoMu-STK-1.0.0/include/PoleZero.h b/lib/MoMu-STK-1.0.0/include/PoleZero.h
new file mode 100644 (file)
index 0000000..b0299b1
--- /dev/null
@@ -0,0 +1,112 @@
+#ifndef STK_POLEZERO_H\r
+#define STK_POLEZERO_H\r
+\r
+#include "Filter.h"\r
+\r
+namespace stk {\r
+\r
+/***************************************************/\r
+/*! \class PoleZero\r
+    \brief STK one-pole, one-zero filter class.\r
+\r
+    This class implements a one-pole, one-zero digital filter.  A\r
+    method is provided for creating an allpass filter with a given\r
+    coefficient.  Another method is provided to create a DC blocking\r
+    filter.\r
+\r
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.\r
+*/\r
+/***************************************************/\r
+\r
+class PoleZero : public Filter\r
+{\r
+ public:\r
+\r
+  //! Default constructor creates a first-order pass-through filter.\r
+  PoleZero();\r
+\r
+  //! Class destructor.\r
+  ~PoleZero();\r
+\r
+  //! Set the b[0] coefficient value.\r
+  void setB0( StkFloat b0 ) { b_[0] = b0; };\r
+\r
+  //! Set the b[1] coefficient value.\r
+  void setB1( StkFloat b1 ) { b_[1] = b1; };\r
+\r
+  //! Set the a[1] coefficient value.\r
+  void setA1( StkFloat a1 ) { a_[1] = a1; };\r
+\r
+  //! Set all filter coefficients.\r
+  void setCoefficients( StkFloat b0, StkFloat b1, StkFloat a1, bool clearState = false );\r
+\r
+  //! Set the filter for allpass behavior using \e coefficient.\r
+  /*!\r
+    This method uses \e coefficient to create an allpass filter,\r
+    which has unity gain at all frequencies.  Note that the \e\r
+    coefficient magnitude must be less than one to maintain stability.\r
+  */\r
+  void setAllpass( StkFloat coefficient );\r
+\r
+  //! Create a DC blocking filter with the given pole position in the z-plane.\r
+  /*!\r
+    This method sets the given pole position, together with a zero\r
+    at z=1, to create a DC blocking filter.  \e thePole should be\r
+    close to one to minimize low-frequency attenuation.\r
+\r
+  */\r
+  void setBlockZero( StkFloat thePole = 0.99 );\r
+\r
+  //! Return the last computed output value.\r
+  StkFloat lastOut( void ) const { return lastFrame_[0]; };\r
+\r
+  //! Input one sample to the filter and return one output.\r
+  StkFloat tick( StkFloat input );\r
+\r
+  //! Take a channel of the StkFrames object as inputs to the filter and replace with corresponding outputs.\r
+  /*!\r
+    The \c channel argument must be less than the number of\r
+    channels in the StkFrames argument (the first channel is specified\r
+    by 0).  However, range checking is only performed if _STK_DEBUG_\r
+    is defined during compilation, in which case an out-of-range value\r
+    will trigger an StkError exception.\r
+  */\r
+  StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );\r
+\r
+};\r
+\r
+inline StkFloat PoleZero :: tick( StkFloat input )\r
+{\r
+  inputs_[0] = gain_ * input;\r
+  lastFrame_[0] = b_[0] * inputs_[0] + b_[1] * inputs_[1] - a_[1] * outputs_[1];\r
+  inputs_[1] = inputs_[0];\r
+  outputs_[1] = lastFrame_[0];\r
+\r
+  return lastFrame_[0];\r
+}\r
+\r
+inline StkFrames& PoleZero :: tick( StkFrames& frames, unsigned int channel )\r
+{\r
+#if defined(_STK_DEBUG_)\r
+  if ( channel >= frames.channels() ) {\r
+    errorString_ << "PoleZero::tick(): channel and StkFrames arguments are incompatible!";\r
+    handleError( StkError::FUNCTION_ARGUMENT );\r
+  }\r
+#endif\r
+\r
+  StkFloat *samples = &frames[channel];\r
+  unsigned int hop = frames.channels();\r
+  for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {\r
+    inputs_[0] = gain_ * *samples;\r
+    *samples = b_[0] * inputs_[0] + b_[1] * inputs_[1] - a_[1] * outputs_[1];\r
+    inputs_[1] = inputs_[0];\r
+    outputs_[1] = *samples;\r
+  }\r
+\r
+  lastFrame_[0] = outputs_[1];\r
+  return frames;\r
+}\r
+\r
+} // stk namespace\r
+\r
+#endif\r
diff --git a/lib/MoMu-STK-1.0.0/include/ReedTable.h b/lib/MoMu-STK-1.0.0/include/ReedTable.h
new file mode 100644 (file)
index 0000000..c4bdaef
--- /dev/null
@@ -0,0 +1,143 @@
+#ifndef STK_REEDTABLE_H
+#define STK_REEDTABLE_H
+
+#include "Function.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class ReedTable
+    \brief STK reed table class.
+
+    This class implements a simple one breakpoint,
+    non-linear reed function, as described by
+    Smith (1986).  This function is based on a
+    memoryless non-linear spring model of the reed
+    (the reed mass is ignored) which saturates when
+    the reed collides with the mouthpiece facing.
+
+    See McIntyre, Schumacher, & Woodhouse (1983),
+    Smith (1986), Hirschman, Cook, Scavone, and
+    others for more information.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class ReedTable : public Function
+{
+public:
+  //! Default constructor.
+  ReedTable( void ) : offset_(0.6), slope_(-0.8) {};
+
+  //! Set the table offset value.
+  /*!
+    The table offset roughly corresponds to the size
+    of the initial reed tip opening (a greater offset
+    represents a smaller opening).
+  */
+  void setOffset( StkFloat offset ) { offset_ = offset; };
+
+  //! Set the table slope value.
+  /*!
+   The table slope roughly corresponds to the reed
+   stiffness (a greater slope represents a harder
+   reed).
+  */
+  void setSlope( StkFloat slope ) { slope_ = slope; };
+
+  //! Take one sample input and map to one sample of output.
+  StkFloat tick( StkFloat input );
+
+  //! Take a channel of the StkFrames object as inputs to the table and replace with corresponding outputs.
+  /*!
+    The StkFrames argument reference is returned.  The \c channel
+    argument must be less than the number of channels in the
+    StkFrames argument (the first channel is specified by 0).
+    However, range checking is only performed if _STK_DEBUG_ is
+    defined during compilation, in which case an out-of-range value
+    will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
+
+  //! Take a channel of the \c iFrames object as inputs to the table and write outputs to the \c oFrames object.
+  /*!
+    The \c iFrames object reference is returned.  Each channel
+    argument must be less than the number of channels in the
+    corresponding StkFrames argument (the first channel is specified
+    by 0).  However, range checking is only performed if _STK_DEBUG_
+    is defined during compilation, in which case an out-of-range value
+    will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0, unsigned int oChannel = 0 );
+
+protected:
+
+  StkFloat offset_;
+  StkFloat slope_;
+
+};
+
+inline StkFloat ReedTable :: tick( StkFloat input )    
+{
+  // The input is differential pressure across the reed.
+  lastFrame_[0] = offset_ + (slope_ * input);
+
+  // If output is > 1, the reed has slammed shut and the
+  // reflection function value saturates at 1.0.
+  if ( lastFrame_[0] > 1.0) lastFrame_[0] = (StkFloat) 1.0;
+
+  // This is nearly impossible in a physical system, but
+  // a reflection function value of -1.0 corresponds to
+  // an open end (and no discontinuity in bore profile).
+  if ( lastFrame_[0] < -1.0) lastFrame_[0] = (StkFloat) -1.0;
+
+  return lastFrame_[0];
+}
+
+inline StkFrames& ReedTable :: tick( StkFrames& frames, unsigned int channel )
+{
+#if defined(_STK_DEBUG_)
+  if ( channel >= frames.channels() ) {
+    errorString_ << "ReedTable::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *samples = &frames[channel];
+  unsigned int hop = frames.channels();
+  for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
+    *samples = offset_ + (slope_ * *samples);
+    if ( *samples > 1.0) *samples = 1.0;
+    if ( *samples < -1.0) *samples = -1.0;
+  }
+
+  lastFrame_[0] = *(samples-hop);
+  return frames;
+}
+
+inline StkFrames& ReedTable :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iChannel, unsigned int oChannel )
+{
+#if defined(_STK_DEBUG_)
+  if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
+    errorString_ << "ReedTable::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *iSamples = &iFrames[iChannel];
+  StkFloat *oSamples = &oFrames[oChannel];
+  unsigned int iHop = iFrames.channels(), oHop = oFrames.channels();
+  for ( unsigned int i=0; i<iFrames.frames(); i++, iSamples += iHop, oSamples += oHop ) {
+    *oSamples = offset_ + (slope_ * *iSamples);
+    if ( *oSamples > 1.0) *oSamples = 1.0;
+    if ( *oSamples < -1.0) *oSamples = -1.0;
+  }
+
+  lastFrame_[0] = *(oSamples-oHop);
+  return iFrames;
+}
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/Resonate.h b/lib/MoMu-STK-1.0.0/include/Resonate.h
new file mode 100644 (file)
index 0000000..0627eb1
--- /dev/null
@@ -0,0 +1,90 @@
+#ifndef STK_RESONATE_H
+#define STK_RESONATE_H
+
+#include "Instrmnt.h"
+#include "ADSR.h"
+#include "BiQuad.h"
+#include "Noise.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class Resonate
+    \brief STK noise driven formant filter.
+
+    This instrument contains a noise source, which
+    excites a biquad resonance filter, with volume
+    controlled by an ADSR.
+
+    Control Change Numbers:
+       - Resonance Frequency (0-Nyquist) = 2
+       - Pole Radii = 4
+       - Notch Frequency (0-Nyquist) = 11
+       - Zero Radii = 1
+       - Envelope Gain = 128
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class Resonate : public Instrmnt
+{
+ public:
+  //! Class constructor.
+  Resonate( void );
+
+  //! Class destructor.
+  ~Resonate( void );
+
+  //! Reset and clear all internal state.
+  void clear( void );
+
+  //! Set the filter for a resonance at the given frequency (Hz) and radius.
+  void setResonance( StkFloat frequency, StkFloat radius );
+
+  //! Set the filter for a notch at the given frequency (Hz) and radius.
+  void setNotch( StkFloat frequency, StkFloat radius );
+
+  //! Set the filter zero coefficients for contant resonance gain.
+  void setEqualGainZeroes( void ) { filter_.setEqualGainZeroes(); };
+
+  //! Initiate the envelope with a key-on event.
+  void keyOn( void ) { adsr_.keyOn(); };
+
+  //! Signal a key-off event to the envelope.
+  void keyOff( void ) { adsr_.keyOff(); };
+
+  //! Start a note with the given frequency and amplitude.
+  void noteOn( StkFloat frequency, StkFloat amplitude );
+
+  //! Stop a note with the given amplitude (speed of decay).
+  void noteOff( StkFloat amplitude );
+
+  //! Perform the control change specified by \e number and \e value (0.0 - 128.0).
+  void controlChange( int number, StkFloat value );
+
+  //! Compute and return one output sample.
+  StkFloat tick( unsigned int channel = 0 );
+
+ protected:
+
+  ADSR     adsr_;
+  BiQuad   filter_;
+  Noise    noise_;
+  StkFloat poleFrequency_;
+  StkFloat poleRadius_;
+  StkFloat zeroFrequency_;
+  StkFloat zeroRadius_;
+
+};
+
+inline StkFloat Resonate :: tick( unsigned int )
+{
+  lastFrame_[0] = filter_.tick( noise_.tick() );
+  lastFrame_[0] *= adsr_.tick();
+  return lastFrame_[0];
+}
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/Rhodey.h b/lib/MoMu-STK-1.0.0/include/Rhodey.h
new file mode 100644 (file)
index 0000000..dce9f8e
--- /dev/null
@@ -0,0 +1,91 @@
+#ifndef STK_RHODEY_H
+#define STK_RHODEY_H
+
+#include "FM.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class Rhodey
+    \brief STK Fender Rhodes electric piano FM
+           synthesis instrument.
+
+    This class implements two simple FM Pairs
+    summed together, also referred to as algorithm
+    5 of the TX81Z.
+
+    \code
+    Algorithm 5 is :  4->3--\
+                             + --> Out
+                      2->1--/
+    \endcode
+
+    Control Change Numbers: 
+       - Modulator Index One = 2
+       - Crossfade of Outputs = 4
+       - LFO Speed = 11
+       - LFO Depth = 1
+       - ADSR 2 & 4 Target = 128
+
+    The basic Chowning/Stanford FM patent expired
+    in 1995, but there exist follow-on patents,
+    mostly assigned to Yamaha.  If you are of the
+    type who should worry about this (making
+    money) worry away.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class Rhodey : public FM
+{
+ public:
+  //! Class constructor.
+  /*!
+    An StkError will be thrown if the rawwave path is incorrectly set.
+  */
+  Rhodey( void );
+
+  //! Class destructor.
+  ~Rhodey( void );
+
+  //! Set instrument parameters for a particular frequency.
+  void setFrequency( StkFloat frequency );
+
+  //! Start a note with the given frequency and amplitude.
+  void noteOn( StkFloat frequency, StkFloat amplitude );
+
+  //! Compute and return one output sample.
+  StkFloat tick( unsigned int channel = 0 );
+
+ protected:
+
+};
+
+inline StkFloat Rhodey :: tick( unsigned int )
+{
+  StkFloat temp, temp2;
+
+  temp = gains_[1] * adsr_[1]->tick() * waves_[1]->tick();
+  temp = temp * control1_;
+
+  waves_[0]->addPhaseOffset( temp );
+  waves_[3]->addPhaseOffset( twozero_.lastOut() );
+  temp = gains_[3] * adsr_[3]->tick() * waves_[3]->tick();
+  twozero_.tick(temp);
+
+  waves_[2]->addPhaseOffset( temp );
+  temp = ( 1.0 - (control2_ * 0.5)) * gains_[0] * adsr_[0]->tick() * waves_[0]->tick();
+  temp += control2_ * 0.5 * gains_[2] * adsr_[2]->tick() * waves_[2]->tick();
+
+  // Calculate amplitude modulation and apply it to output.
+  temp2 = vibrato_.tick() * modDepth_;
+  temp = temp * (1.0 + temp2);
+    
+  lastFrame_[0] = temp * 0.5;
+  return lastFrame_[0];
+}
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/Sampler.h b/lib/MoMu-STK-1.0.0/include/Sampler.h
new file mode 100644 (file)
index 0000000..be6d2d8
--- /dev/null
@@ -0,0 +1,68 @@
+#ifndef STK_SAMPLER_H
+#define STK_SAMPLER_H
+
+#include "Instrmnt.h"
+#include "ADSR.h"
+#include "FileLoop.h"
+#include "OnePole.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class Sampler
+    \brief STK sampling synthesis abstract base class.
+
+    This instrument provides an ADSR envelope, a one-pole filter, and
+    structures for an arbitrary number of attack and looped files.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class Sampler : public Instrmnt
+{
+ public:
+  //! Default constructor.
+  Sampler( void );
+
+  //! Class destructor.
+  virtual ~Sampler( void );
+
+  //! Reset and clear all internal state.
+  void clear( void );
+
+  //! Set instrument parameters for a particular frequency.
+  virtual void setFrequency( StkFloat frequency ) = 0;
+
+  //! Initiate the envelopes with a key-on event and reset the attack waves.
+  void keyOn( void );
+
+  //! Signal a key-off event to the envelopes.
+  void keyOff( void );
+
+  //! Stop a note with the given amplitude (speed of decay).
+  virtual void noteOff( StkFloat amplitude );
+
+  //! Perform the control change specified by \e number and \e value (0.0 - 128.0).
+  virtual void controlChange( int number, StkFloat value ) = 0;
+
+  //! Compute and return one output sample.
+  virtual StkFloat tick( unsigned int channel = 0 ) = 0;
+
+ protected:
+
+  ADSR adsr_;
+  std::vector<FileWvIn *> attacks_;
+  std::vector<FileLoop *> loops_;
+  OnePole filter_;
+  StkFloat baseFrequency_;
+  std::vector<StkFloat> attackRatios_;
+  std::vector<StkFloat> loopRatios_;
+  StkFloat attackGain_;
+  StkFloat loopGain_;
+
+};
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/Saxofony.h b/lib/MoMu-STK-1.0.0/include/Saxofony.h
new file mode 100644 (file)
index 0000000..45f33b8
--- /dev/null
@@ -0,0 +1,129 @@
+#ifndef STK_SAXOFONY_H
+#define STK_SAXOFONY_H
+
+#include "Instrmnt.h"
+#include "DelayL.h"
+#include "ReedTable.h"
+#include "OneZero.h"
+#include "Envelope.h"
+#include "Noise.h"
+#include "SineWave.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class Saxofony
+    \brief STK faux conical bore reed instrument class.
+
+    This class implements a "hybrid" digital
+    waveguide instrument that can generate a
+    variety of wind-like sounds.  It has also been
+    referred to as the "blowed string" model.  The
+    waveguide section is essentially that of a
+    string, with one rigid and one lossy
+    termination.  The non-linear function is a
+    reed table.  The string can be "blown" at any
+    point between the terminations, though just as
+    with strings, it is impossible to excite the
+    system at either end.  If the excitation is
+    placed at the string mid-point, the sound is
+    that of a clarinet.  At points closer to the
+    "bridge", the sound is closer to that of a
+    saxophone.  See Scavone (2002) for more details.
+
+    This is a digital waveguide model, making its
+    use possibly subject to patents held by Stanford
+    University, Yamaha, and others.
+
+    Control Change Numbers: 
+       - Reed Stiffness = 2
+       - Reed Aperture = 26
+       - Noise Gain = 4
+       - Blow Position = 11
+       - Vibrato Frequency = 29
+       - Vibrato Gain = 1
+       - Breath Pressure = 128
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class Saxofony : public Instrmnt
+{
+ public:
+  //! Class constructor, taking the lowest desired playing frequency.
+  /*!
+    An StkError will be thrown if the rawwave path is incorrectly set.
+  */
+  Saxofony( StkFloat lowestFrequency );
+
+  //! Class destructor.
+  ~Saxofony( void );
+
+  //! Reset and clear all internal state.
+  void clear( void );
+
+  //! Set instrument parameters for a particular frequency.
+  void setFrequency( StkFloat frequency );
+
+  //! Set the "blowing" position between the air column terminations (0.0 - 1.0).
+  void setBlowPosition( StkFloat aPosition );
+
+  //! Apply breath pressure to instrument with given amplitude and rate of increase.
+  void startBlowing( StkFloat amplitude, StkFloat rate );
+
+  //! Decrease breath pressure with given rate of decrease.
+  void stopBlowing( StkFloat rate );
+
+  //! Start a note with the given frequency and amplitude.
+  void noteOn( StkFloat frequency, StkFloat amplitude );
+
+  //! Stop a note with the given amplitude (speed of decay).
+  void noteOff( StkFloat amplitude );
+
+  //! Perform the control change specified by \e number and \e value (0.0 - 128.0).
+  void controlChange( int number, StkFloat value );
+
+  //! Compute and return one output sample.
+  StkFloat tick( unsigned int channel = 0 );
+
+ protected:
+
+  DelayL    delays_[2];
+  ReedTable reedTable_;
+  OneZero   filter_;
+  Envelope  envelope_;
+  Noise     noise_;
+  SineWave vibrato_;
+  unsigned long length_;
+  StkFloat outputGain_;
+  StkFloat noiseGain_;
+  StkFloat vibratoGain_;
+  StkFloat position_;
+
+};
+
+inline StkFloat Saxofony :: tick( unsigned int )
+{
+  StkFloat pressureDiff;
+  StkFloat breathPressure;
+  StkFloat temp;
+
+  // Calculate the breath pressure (envelope + noise + vibrato)
+  breathPressure = envelope_.tick(); 
+  breathPressure += breathPressure * noiseGain_ * noise_.tick();
+  breathPressure += breathPressure * vibratoGain_ * vibrato_.tick();
+
+  temp = -0.95 * filter_.tick( delays_[0].lastOut() );
+  lastFrame_[0] = temp - delays_[1].lastOut();
+  pressureDiff = breathPressure - lastFrame_[0];
+  delays_[1].tick( temp );
+  delays_[0].tick( breathPressure - (pressureDiff * reedTable_.tick(pressureDiff)) - temp );
+
+  lastFrame_[0] *= outputGain_;
+  return lastFrame_[0];
+}
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/Shakers.h b/lib/MoMu-STK-1.0.0/include/Shakers.h
new file mode 100644 (file)
index 0000000..dcad1eb
--- /dev/null
@@ -0,0 +1,131 @@
+#ifndef STK_SHAKERS_H
+#define STK_SHAKERS_H
+
+#include "Instrmnt.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class Shakers
+    \brief PhISEM and PhOLIES class.
+
+    PhISEM (Physically Informed Stochastic Event
+    Modeling) is an algorithmic approach for
+    simulating collisions of multiple independent
+    sound producing objects.  This class is a
+    meta-model that can simulate a Maraca, Sekere,
+    Cabasa, Bamboo Wind Chimes, Water Drops,
+    Tambourine, Sleighbells, and a Guiro.
+
+    PhOLIES (Physically-Oriented Library of
+    Imitated Environmental Sounds) is a similar
+    approach for the synthesis of environmental
+    sounds.  This class implements simulations of
+    breaking sticks, crunchy snow (or not), a
+    wrench, sandpaper, and more.
+
+    Control Change Numbers: 
+      - Shake Energy = 2
+      - System Decay = 4
+      - Number Of Objects = 11
+      - Resonance Frequency = 1
+      - Shake Energy = 128
+      - Instrument Selection = 1071
+        - Maraca = 0
+        - Cabasa = 1
+        - Sekere = 2
+        - Guiro = 3
+        - Water Drops = 4
+        - Bamboo Chimes = 5
+        - Tambourine = 6
+        - Sleigh Bells = 7
+        - Sticks = 8
+        - Crunch = 9
+        - Wrench = 10
+        - Sand Paper = 11
+        - Coke Can = 12
+        - Next Mug = 13
+        - Penny + Mug = 14
+        - Nickle + Mug = 15
+        - Dime + Mug = 16
+        - Quarter + Mug = 17
+        - Franc + Mug = 18
+        - Peso + Mug = 19
+        - Big Rocks = 20
+        - Little Rocks = 21
+        - Tuned Bamboo Chimes = 22
+
+    by Perry R. Cook, 1996 - 2010.
+*/
+/***************************************************/
+
+const int MAX_FREQS = 8;
+const int NUM_INSTR = 24;
+
+class Shakers : public Instrmnt
+{
+ public:
+  //! Class constructor.
+  Shakers( void );
+
+  //! Class destructor.
+  ~Shakers( void );
+
+  //! Start a note with the given instrument and amplitude.
+  /*!
+    Use the instrument numbers above, converted to frequency values
+    as if MIDI note numbers, to select a particular instrument.
+  */
+  void noteOn( StkFloat instrument, StkFloat amplitude );
+
+  //! Stop a note with the given amplitude (speed of decay).
+  void noteOff( StkFloat amplitude );
+
+  //! Perform the control change specified by \e number and \e value (0.0 - 128.0).
+  void controlChange( int number, StkFloat value );
+
+  //! Compute and return one output sample.
+  StkFloat tick( unsigned int channel = 0 );
+
+ protected:
+
+  int setupName( char* instr );
+  int setupNum( int inst );
+  int setFreqAndReson( int which, StkFloat freq, StkFloat reson );
+  void setDecays( StkFloat sndDecay, StkFloat sysDecay );
+  void setFinalZs( StkFloat z0, StkFloat z1, StkFloat z2 );
+  StkFloat wuter_tick( void );
+  StkFloat tbamb_tick( void );
+  StkFloat ratchet_tick( void );
+
+  int instType_;
+  int ratchetPos_, lastRatchetPos_;
+  StkFloat shakeEnergy_;
+  StkFloat inputs_[MAX_FREQS];
+  StkFloat outputs_[MAX_FREQS][2];
+  StkFloat coeffs_[MAX_FREQS][2];
+  StkFloat sndLevel_;
+  StkFloat baseGain_;
+  StkFloat gains_[MAX_FREQS];
+  int nFreqs_;
+  StkFloat t_center_freqs_[MAX_FREQS];
+  StkFloat center_freqs_[MAX_FREQS];
+  StkFloat resons_[MAX_FREQS];
+  StkFloat freq_rand_[MAX_FREQS];
+  int freqalloc_[MAX_FREQS];
+  StkFloat soundDecay_;
+  StkFloat systemDecay_;
+  StkFloat nObjects_;
+  StkFloat totalEnergy_;
+  StkFloat ratchet_, ratchetDelta_;
+  StkFloat finalZ_[3];
+  StkFloat finalZCoeffs_[3];
+  StkFloat defObjs_[NUM_INSTR];
+  StkFloat defDecays_[NUM_INSTR];
+  StkFloat decayScale_[NUM_INSTR];
+
+};
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/Simple.h b/lib/MoMu-STK-1.0.0/include/Simple.h
new file mode 100644 (file)
index 0000000..b2aeea7
--- /dev/null
@@ -0,0 +1,92 @@
+#ifndef STK_SIMPLE_H
+#define STK_SIMPLE_H
+
+#include "Instrmnt.h"
+#include "ADSR.h"
+#include "FileLoop.h"
+#include "OnePole.h"
+#include "BiQuad.h"
+#include "Noise.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class Simple
+    \brief STK wavetable/noise instrument.
+
+    This class combines a looped wave, a
+    noise source, a biquad resonance filter,
+    a one-pole filter, and an ADSR envelope
+    to create some interesting sounds.
+
+    Control Change Numbers: 
+       - Filter Pole Position = 2
+       - Noise/Pitched Cross-Fade = 4
+       - Envelope Rate = 11
+       - Gain = 128
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class Simple : public Instrmnt
+{
+ public:
+  //! Class constructor.
+  /*!
+    An StkError will be thrown if the rawwave path is incorrectly set.
+  */
+  Simple( void );
+
+  //! Class destructor.
+  ~Simple( void );
+
+  //! Clear internal states.
+  void clear( void );
+
+  //! Set instrument parameters for a particular frequency.
+  void setFrequency( StkFloat frequency );
+
+  //! Start envelope toward "on" target.
+  void keyOn( void );
+
+  //! Start envelope toward "off" target.
+  void keyOff( void );
+
+  //! Start a note with the given frequency and amplitude.
+  void noteOn( StkFloat frequency, StkFloat amplitude );
+
+  //! Stop a note with the given amplitude (speed of decay).
+  void noteOff( StkFloat amplitude );
+
+  //! Perform the control change specified by \e number and \e value (0.0 - 128.0).
+  void controlChange( int number, StkFloat value );
+
+  //! Compute and return one output sample.
+  StkFloat tick( unsigned int channel = 0 );
+
+ protected:
+
+  ADSR      adsr_; 
+  FileLoop *loop_;
+  OnePole   filter_;
+  BiQuad    biquad_;
+  Noise     noise_;
+  StkFloat  baseFrequency_;
+  StkFloat  loopGain_;
+
+};
+
+inline StkFloat Simple :: tick( unsigned int )
+{
+  lastFrame_[0] = loopGain_ * loop_->tick();
+  biquad_.tick( noise_.tick() );
+  lastFrame_[0] += (1.0 - loopGain_) * biquad_.lastOut();
+  lastFrame_[0] = filter_.tick( lastFrame_[0] );
+  lastFrame_[0] *= adsr_.tick();
+  return lastFrame_[0];
+}
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/SineWave.h b/lib/MoMu-STK-1.0.0/include/SineWave.h
new file mode 100644 (file)
index 0000000..cb7785f
--- /dev/null
@@ -0,0 +1,159 @@
+#ifndef STK_SINEWAVE_H
+#define STK_SINEWAVE_H
+
+const unsigned long TABLE_SIZE = 2048;
+
+#include "Generator.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class SineWave
+    \brief STK sinusoid oscillator class.
+
+    This class computes and saves a static sine "table" that can be
+    shared by multiple instances.  It has an interface similar to the
+    WaveLoop class but inherits from the Generator class.  Output
+    values are computed using linear interpolation.
+
+    The "table" length, set in SineWave.h, is 2048 samples by default.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
+*/
+/***************************************************/
+
+class SineWave : public Generator
+{
+public:
+  //! Default constructor.
+  SineWave( void );
+
+  //! Class destructor.
+  ~SineWave( void );
+
+  //! Clear output and reset time pointer to zero.
+  void reset( void );
+
+  //! Set the data read rate in samples.  The rate can be negative.
+  /*!
+    If the rate value is negative, the data is read in reverse order.
+  */
+  void setRate( StkFloat rate ) { rate_ = rate; };
+
+  //! Set the data interpolation rate based on a looping frequency.
+  /*!
+    This function determines the interpolation rate based on the file
+    size and the current Stk::sampleRate.  The \e frequency value
+    corresponds to file cycles per second.  The frequency can be
+    negative, in which case the loop is read in reverse order.
+   */
+  void setFrequency( StkFloat frequency );
+
+  //! Increment the read pointer by \e time in samples, modulo the table size.
+  void addTime( StkFloat time );
+
+  //! Increment the read pointer by a normalized \e phase value.
+  /*!
+    This function increments the read pointer by a normalized phase
+    value, such that \e phase = 1.0 corresponds to a 360 degree phase
+    shift.  Positive or negative values are possible.
+   */
+  void addPhase( StkFloat phase );
+
+  //! Add a normalized phase offset to the read pointer.
+  /*!
+    A \e phaseOffset = 1.0 corresponds to a 360 degree phase
+    offset.  Positive or negative values are possible.
+   */
+  void addPhaseOffset( StkFloat phaseOffset );
+
+  //! Return the last computed output value.
+  StkFloat lastOut( void ) const { return lastFrame_[0]; };
+
+  //! Compute and return one output sample.
+  StkFloat tick( void );
+
+  //! Fill a channel of the StkFrames object with computed outputs.
+  /*!
+    The \c channel argument must be less than the number of
+    channels in the StkFrames argument (the first channel is specified
+    by 0).  However, range checking is only performed if _STK_DEBUG_
+    is defined during compilation, in which case an out-of-range value
+    will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
+
+protected:
+
+  void sampleRateChanged( StkFloat newRate, StkFloat oldRate );
+
+  static StkFrames table_;
+  StkFloat time_;
+  StkFloat rate_;
+  StkFloat phaseOffset_;
+  unsigned int iIndex_;
+  StkFloat alpha_;
+
+};
+
+inline StkFloat SineWave :: tick( void )
+{
+  // Check limits of time address ... if necessary, recalculate modulo
+  // TABLE_SIZE.
+  while ( time_ < 0.0 )
+    time_ += TABLE_SIZE;
+  while ( time_ >= TABLE_SIZE )
+    time_ -= TABLE_SIZE;
+
+  iIndex_ = (unsigned int) time_;
+  alpha_ = time_ - iIndex_;
+  StkFloat tmp = table_[ iIndex_ ];
+  tmp += ( alpha_ * ( table_[ iIndex_ + 1 ] - tmp ) );
+
+  // Increment time, which can be negative.
+  time_ += rate_;
+
+  lastFrame_[0] = tmp;
+  return lastFrame_[0];
+}
+
+inline StkFrames& SineWave :: tick( StkFrames& frames, unsigned int channel )
+{
+#if defined(_STK_DEBUG_)
+  if ( channel >= frames.channels() ) {
+    errorString_ << "SineWave::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *samples = &frames[channel];
+  StkFloat tmp = 0.0;
+
+  unsigned int hop = frames.channels();
+  for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
+
+    // Check limits of time address ... if necessary, recalculate modulo
+    // TABLE_SIZE.
+    while ( time_ < 0.0 )
+      time_ += TABLE_SIZE;
+    while ( time_ >= TABLE_SIZE )
+      time_ -= TABLE_SIZE;
+
+    iIndex_ = (unsigned int) time_;
+    alpha_ = time_ - iIndex_;
+    tmp = table_[ iIndex_ ];
+    tmp += ( alpha_ * ( table_[ iIndex_ + 1 ] - tmp ) );
+    *samples = tmp;
+
+    // Increment time, which can be negative.
+    time_ += rate_;
+  }
+
+  lastFrame_[0] = tmp;
+  return frames;
+}
+
+} // stk namespace
+
+#endif
+
diff --git a/lib/MoMu-STK-1.0.0/include/SingWave.h b/lib/MoMu-STK-1.0.0/include/SingWave.h
new file mode 100644 (file)
index 0000000..fcc3343
--- /dev/null
@@ -0,0 +1,136 @@
+#ifndef STK_SINGWAVE_H
+#define STK_SINGWAVE_H
+
+#include "FileLoop.h"
+#include "Modulate.h"
+#include "Envelope.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class SingWave
+    \brief STK "singing" looped soundfile class.
+
+    This class loops a specified soundfile and modulates it both
+    periodically and randomly to produce a pitched musical sound, like
+    a simple voice or violin.  In general, it is not be used alone
+    because of "munchkinification" effects from pitch shifting.
+    Within STK, it is used as an excitation source for other
+    instruments.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class SingWave : public Generator
+{
+ public:
+  //! Class constructor taking filename argument.
+  /*!
+    An StkError will be thrown if the file is not found, its format
+    is unknown, or a read error occurs.  If the soundfile has no
+    header, the second argument should be \e true and the file data
+    will be assumed to consist of 16-bit signed integers in big-endian
+    byte order at a sample rate of 22050 Hz.
+  */
+  SingWave( std::string fileName, bool raw = false );
+
+  //! Class destructor.
+  ~SingWave( void );
+
+  //! Reset file to beginning.
+  void reset( void ) { wave_.reset(); lastFrame_[0] = 0.0; };
+
+  //! Normalize the file to a maximum of +-1.0.
+  void normalize( void ) { wave_.normalize(); };
+
+  //! Normalize the file to a maximum of \e +- peak.
+  void normalize( StkFloat peak ) { wave_.normalize( peak ); };
+
+  //! Set looping parameters for a particular frequency.
+  void setFrequency( StkFloat frequency );
+
+  //! Set the vibrato frequency in Hz.
+  void setVibratoRate( StkFloat rate ) { modulator_.setVibratoRate( rate ); };
+
+  //! Set the vibrato gain.
+  void setVibratoGain( StkFloat gain ) { modulator_.setVibratoGain( gain ); };
+
+  //! Set the random-ness amount.
+  void setRandomGain( StkFloat gain ) { modulator_.setRandomGain( gain ); };
+
+  //! Set the sweep rate.
+  void setSweepRate( StkFloat rate ) { sweepRate_ = rate; };
+
+  //! Set the gain rate.
+  void setGainRate( StkFloat rate ) { envelope_.setRate( rate ); };
+
+  //! Set the gain target value.
+  void setGainTarget( StkFloat target ) { envelope_.setTarget( target ); };
+
+  //! Start a note.
+  void noteOn( void ) { envelope_.keyOn(); };
+
+  //! Stop a note.
+  void noteOff( void ) { envelope_.keyOff(); };
+
+  //! Return the last computed output value.
+  StkFloat lastOut( void ) const { return lastFrame_[0]; };
+
+  //! Compute and return one output sample.
+  StkFloat tick( void );
+
+  //! Fill a channel of the StkFrames object with computed outputs.
+  /*!
+    The \c channel argument must be less than the number of
+    channels in the StkFrames argument (the first channel is specified
+    by 0).  However, range checking is only performed if _STK_DEBUG_
+    is defined during compilation, in which case an out-of-range value
+    will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
+
+ protected:
+
+  FileLoop wave_;
+  Modulate modulator_;
+  Envelope envelope_;
+  Envelope pitchEnvelope_;
+  StkFloat rate_;
+  StkFloat sweepRate_;
+
+};
+
+inline StkFloat SingWave :: tick( void )
+{
+  // Set the wave rate.
+  StkFloat newRate = pitchEnvelope_.tick();
+  newRate += newRate * modulator_.tick();
+  wave_.setRate( newRate );
+
+  lastFrame_[0] = wave_.tick();
+  lastFrame_[0] *= envelope_.tick();
+
+  return lastFrame_[0];
+}
+
+inline StkFrames& SingWave :: tick( StkFrames& frames, unsigned int channel )
+{
+#if defined(_STK_DEBUG_)
+  if ( channel >= frames.channels() ) {
+    errorString_ << "SingWave::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *samples = &frames[channel];
+  unsigned int hop = frames.channels();
+  for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
+    *samples = SingWave::tick();
+
+  return frames;
+}
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/Sitar.h b/lib/MoMu-STK-1.0.0/include/Sitar.h
new file mode 100644 (file)
index 0000000..8419afa
--- /dev/null
@@ -0,0 +1,92 @@
+#ifndef STK_SITAR_H
+#define STK_SITAR_H
+
+#include "Instrmnt.h"
+#include "DelayA.h"
+#include "OneZero.h"
+#include "Noise.h"
+#include "ADSR.h"
+#include <cmath>
+
+namespace stk {
+
+/***************************************************/
+/*! \class Sitar
+    \brief STK sitar string model class.
+
+    This class implements a sitar plucked string
+    physical model based on the Karplus-Strong
+    algorithm.
+
+    This is a digital waveguide model, making its
+    use possibly subject to patents held by
+    Stanford University, Yamaha, and others.
+    There exist at least two patents, assigned to
+    Stanford, bearing the names of Karplus and/or
+    Strong.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class Sitar : public Instrmnt
+{
+ public:
+  //! Class constructor, taking the lowest desired playing frequency.
+  Sitar( StkFloat lowestFrequency = 20 );
+
+  //! Class destructor.
+  ~Sitar( void );
+
+  //! Reset and clear all internal state.
+  void clear( void );
+
+  //! Set instrument parameters for a particular frequency.
+  void setFrequency( StkFloat frequency );
+
+  //! Pluck the string with the given amplitude using the current frequency.
+  void pluck( StkFloat amplitude );
+
+  //! Start a note with the given frequency and amplitude.
+  void noteOn( StkFloat frequency, StkFloat amplitude );
+
+  //! Stop a note with the given amplitude (speed of decay).
+  void noteOff( StkFloat amplitude );
+
+  //! Compute and return one output sample.
+  StkFloat tick( unsigned int channel = 0 );
+
+ protected:
+
+  DelayA  delayLine_;
+  OneZero loopFilter_;
+  Noise   noise_;
+  ADSR    envelope_;
+
+  StkFloat loopGain_;
+  StkFloat amGain_;
+  StkFloat delay_;
+  StkFloat targetDelay_;
+
+};
+
+inline StkFloat Sitar :: tick( unsigned int )
+{
+  if ( fabs(targetDelay_ - delay_) > 0.001 ) {
+    if ( targetDelay_ < delay_ )
+      delay_ *= 0.99999;
+    else
+      delay_ *= 1.00001;
+    delayLine_.setDelay( delay_ );
+  }
+
+  lastFrame_[0] = delayLine_.tick( loopFilter_.tick( delayLine_.lastOut() * loopGain_ ) + 
+                                (amGain_ * envelope_.tick() * noise_.tick()));
+  
+  return lastFrame_[0];
+}
+
+} // stk namespace
+
+#endif
+
diff --git a/lib/MoMu-STK-1.0.0/include/Skini.h b/lib/MoMu-STK-1.0.0/include/Skini.h
new file mode 100644 (file)
index 0000000..6e25b96
--- /dev/null
@@ -0,0 +1,121 @@
+#ifndef STK_SKINI_H
+#define STK_SKINI_H
+
+#include "Stk.h"
+#include <vector>
+#include <string>
+#include <fstream>
+
+namespace stk {
+
+/***************************************************/
+/*! \class Skini
+    \brief STK SKINI parsing class
+
+    This class parses SKINI formatted text
+    messages.  It can be used to parse individual
+    messages or it can be passed an entire file.
+    The SKINI specification is Perry's and his
+    alone, but it's all text so it shouldn't be too
+    hard to figure out.
+
+    SKINI (Synthesis toolKit Instrument Network
+    Interface) is like MIDI, but allows for
+    floating-point control changes, note numbers,
+    etc.  The following example causes a sharp
+    middle C to be played with a velocity of 111.132:
+
+    \code
+    noteOn  60.01  111.132
+    \endcode
+
+    \sa \ref skini
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class Skini : public Stk
+{
+ public:
+
+  //! A message structure to store and pass parsed SKINI messages.
+  struct Message { 
+    long type;                         /*!< The message type, as defined in SKINI.msg. */
+    long channel;                      /*!< The message channel (not limited to 16!). */
+    StkFloat time;                     /*!< The message time stamp in seconds (delta or absolute). */
+    std::vector<StkFloat> floatValues; /*!< The message values read as floats (values are type-specific). */
+    std::vector<long> intValues;       /*!< The message values read as ints (number and values are type-specific). */
+    std::string remainder;             /*!< Any remaining message data, read as ascii text. */
+
+    // Default constructor.
+    Message()
+      :type(0), channel(0), time(0.0), floatValues(2), intValues(2) {}
+  };
+
+  //! Default constructor.
+  Skini();
+
+  //! Class destructor
+  ~Skini();
+
+  //! Set a SKINI formatted file for reading.
+  /*!
+    If the file is successfully opened, this function returns \e
+    true.  Otherwise, \e false is returned.
+   */
+  bool setFile( std::string fileName );
+
+  //! Parse the next file message (if a file is loaded) and return the message type.
+  /*!
+    This function skips over lines in a file which cannot be
+    parsed.  A type value equal to zero in the referenced message
+    structure (and the returned value) indicates the file end is
+    reached or no file is open for reading.
+  */
+  long nextMessage( Skini::Message& message );
+
+  //! Attempt to parse the given string and returning the message type.
+  /*!
+    A type value equal to zero in the referenced message structure
+    indicates an invalid message.
+  */
+  long parseString( std::string& line, Skini::Message& message );
+
+  //! Return the SKINI type string for the given type value.
+  static std::string whatsThisType(long type);
+
+  //! Return the SKINI controller string for the given controller number.
+  static std::string whatsThisController(long number);
+
+ protected:
+
+  void tokenize( const std::string& str, std::vector<std::string>& tokens, const std::string& delimiters );
+
+  std::ifstream file_;
+};
+
+static const double Midi2Pitch[129] = {
+8.18,8.66,9.18,9.72,10.30,10.91,11.56,12.25,
+12.98,13.75,14.57,15.43,16.35,17.32,18.35,19.45,
+20.60,21.83,23.12,24.50,25.96,27.50,29.14,30.87,
+32.70,34.65,36.71,38.89,41.20,43.65,46.25,49.00,
+51.91,55.00,58.27,61.74,65.41,69.30,73.42,77.78,
+82.41,87.31,92.50,98.00,103.83,110.00,116.54,123.47,
+130.81,138.59,146.83,155.56,164.81,174.61,185.00,196.00,
+207.65,220.00,233.08,246.94,261.63,277.18,293.66,311.13,
+329.63,349.23,369.99,392.00,415.30,440.00,466.16,493.88,
+523.25,554.37,587.33,622.25,659.26,698.46,739.99,783.99,
+830.61,880.00,932.33,987.77,1046.50,1108.73,1174.66,1244.51,
+1318.51,1396.91,1479.98,1567.98,1661.22,1760.00,1864.66,1975.53,
+2093.00,2217.46,2349.32,2489.02,2637.02,2793.83,2959.96,3135.96,
+3322.44,3520.00,3729.31,3951.07,4186.01,4434.92,4698.64,4978.03,
+5274.04,5587.65,5919.91,6271.93,6644.88,7040.00,7458.62,7902.13,
+8372.02,8869.84,9397.27,9956.06,10548.08,11175.30,11839.82,12543.85,
+13289.75};
+
+} // stk namespace
+
+#endif
+
+
diff --git a/lib/MoMu-STK-1.0.0/include/Skini_msg.h b/lib/MoMu-STK-1.0.0/include/Skini_msg.h
new file mode 100644 (file)
index 0000000..432f2cb
--- /dev/null
@@ -0,0 +1,137 @@
+#ifndef STK_SKINI_MSG_H
+#define STK_SKINI_MSG_H
+
+// MoMu Modified
+
+/*********************************************************/
+/*
+  Definition of SKINI Message Types and Special Symbols
+     Synthesis toolKit Instrument Network Interface
+
+  These symbols should have the form:
+
+   \c __SK_<name>_
+
+  where <name> is the string used in the SKINI stream.
+
+  by Perry R. Cook, 1995 - 2009.
+*/
+/*********************************************************/
+
+namespace stk {
+
+#define NOPE        -32767
+#define YEP         1
+#define SK_DBL      -32766
+#define SK_INT      -32765
+#define SK_STR      -32764
+#define __SK_Exit_  999
+
+/***** MIDI COMPATIBLE MESSAGES *****/
+/*** (Status bytes for channel=0) ***/
+
+#define __SK_NoteOff_                128
+#define __SK_NoteOn_                 144
+#define __SK_PolyPressure_           160
+#define __SK_ControlChange_          176
+#define __SK_ProgramChange_          192
+#define __SK_AfterTouch_             208
+#define __SK_ChannelPressure_        __SK_AfterTouch_
+#define __SK_PitchWheel_             224
+#define __SK_PitchBend_              __SK_PitchWheel_
+#define __SK_PitchChange_            49
+
+#define __SK_Clock_                  248
+#define __SK_SongStart_              250
+#define __SK_Continue_               251
+#define __SK_SongStop_               252
+#define __SK_ActiveSensing_          254
+#define __SK_SystemReset_            255
+
+#define __SK_Volume_                 7
+#define __SK_ModWheel_               1
+#define __SK_Modulation_             __SK_ModWheel_
+#define __SK_Breath_                 2
+#define __SK_FootControl_            4
+#define __SK_Portamento_             65
+#define __SK_Balance_                8
+#define __SK_Pan_                    10
+#define __SK_Sustain_                64
+#define __SK_Damper_                 __SK_Sustain_
+#define __SK_Expression_             11 
+
+#define __SK_AfterTouch_Cont_        128
+#define __SK_ModFrequency_           __SK_Expression_
+
+#define __SK_ProphesyRibbon_         16
+#define __SK_ProphesyWheelUp_        2
+#define __SK_ProphesyWheelDown_      3
+#define __SK_ProphesyPedal_          18
+#define __SK_ProphesyKnob1_          21
+#define __SK_ProphesyKnob2_          22
+
+/***  Instrument Family Specific ***/
+
+#define __SK_NoiseLevel_             __SK_FootControl_
+
+#define __SK_PickPosition_           __SK_FootControl_
+#define __SK_StringDamping_          __SK_Expression_
+#define __SK_StringDetune_           __SK_ModWheel_
+#define __SK_BodySize_               __SK_Breath_
+#define __SK_BowPressure_            __SK_Breath_
+#define __SK_BowPosition_            __SK_PickPosition_
+#define __SK_BowBeta_                __SK_BowPosition_
+
+#define __SK_ReedStiffness_          __SK_Breath_
+#define __SK_ReedRestPos_            __SK_FootControl_
+
+#define __SK_FluteEmbouchure_        __SK_Breath_
+#define __SK_JetDelay_               __SK_FluteEmbouchure_
+
+#define __SK_LipTension_             __SK_Breath_
+#define __SK_SlideLength_            __SK_FootControl_
+
+#define __SK_StrikePosition_         __SK_PickPosition_
+#define __SK_StickHardness_          __SK_Breath_
+
+#define __SK_TrillDepth_             1051
+#define __SK_TrillSpeed_             1052
+#define __SK_StrumSpeed_             __SK_TrillSpeed_
+#define __SK_RollSpeed_              __SK_TrillSpeed_
+
+#define __SK_FilterQ_                __SK_Breath_
+#define __SK_FilterFreq_             1062
+#define __SK_FilterSweepRate_        __SK_FootControl_
+
+#define __SK_ShakerInst_             1071 
+#define __SK_ShakerEnergy_           __SK_Breath_
+#define __SK_ShakerDamping_          __SK_ModFrequency_
+#define __SK_ShakerNumObjects_       __SK_FootControl_
+
+#define __SK_Strumming_              1090
+#define __SK_NotStrumming_           1091
+#define __SK_Trilling_               1092
+#define __SK_NotTrilling_            1093
+#define __SK_Rolling_                __SK_Strumming_
+#define __SK_NotRolling_             __SK_NotStrumming_
+
+#define __SK_PlayerSkill_            2001
+#define __SK_Chord_                  2002
+#define __SK_ChordOff_               2003
+
+#define __SK_SINGER_FilePath_        3000
+#define __SK_SINGER_Frequency_       3001
+#define __SK_SINGER_NoteName_        3002
+#define __SK_SINGER_Shape_           3003
+#define __SK_SINGER_Glot_            3004
+#define __SK_SINGER_VoicedUnVoiced_  3005
+#define __SK_SINGER_Synthesize_      3006
+#define __SK_SINGER_Silence_         3007
+#define __SK_SINGER_VibratoAmt_      __SK_ModWheel_
+#define __SK_SINGER_RndVibAmt_       3008
+#define __SK_SINGER_VibFreq_         __SK_Expression_
+
+} // stk namespace
+
+
+#endif
\ No newline at end of file
diff --git a/lib/MoMu-STK-1.0.0/include/Skini_tbl.h b/lib/MoMu-STK-1.0.0/include/Skini_tbl.h
new file mode 100644 (file)
index 0000000..63936dc
--- /dev/null
@@ -0,0 +1,136 @@
+#include "Skini_msg.h"
+
+// MoMu Modified
+
+namespace stk {
+
+#define __SK_MaxMsgTypes_ 80
+
+struct SkiniSpec { char messageString[32];
+                   long  type;
+                   long data2;
+                   long data3;
+                 };
+
+/* SEE COMMENT BLOCK AT BOTTOM FOR FIELDS AND USES   */
+/* MessageString     , type,     data2,     data3    */ 
+
+struct SkiniSpec skini_msgs[__SK_MaxMsgTypes_] = 
+{
+ {"NoteOff"          ,        __SK_NoteOff_,                   SK_DBL,  SK_DBL},
+ {"NoteOn"           ,         __SK_NoteOn_,                   SK_DBL,  SK_DBL},
+ {"PolyPressure"     ,   __SK_PolyPressure_,                   SK_DBL,  SK_DBL},
+ {"ControlChange"    ,  __SK_ControlChange_,                   SK_INT,  SK_DBL},
+ {"ProgramChange"    ,  __SK_ProgramChange_,                   SK_DBL,    NOPE},
+ {"AfterTouch"       ,     __SK_AfterTouch_,                   SK_DBL,    NOPE},
+ {"ChannelPressure"  ,__SK_ChannelPressure_,                   SK_DBL,    NOPE},
+ {"PitchWheel"       ,     __SK_PitchWheel_,                   SK_DBL,    NOPE},
+ {"PitchBend"        ,      __SK_PitchBend_,                   SK_DBL,    NOPE},
+ {"PitchChange"      ,    __SK_PitchChange_,                   SK_DBL,    NOPE},
+
+ {"Clock"            ,          __SK_Clock_,                     NOPE,    NOPE},
+ {"Undefined"        ,                  249,                     NOPE,    NOPE},
+ {"SongStart"        ,      __SK_SongStart_,                     NOPE,    NOPE},
+ {"Continue"         ,       __SK_Continue_,                     NOPE,    NOPE},
+ {"SongStop"         ,       __SK_SongStop_,                     NOPE,    NOPE},
+ {"Undefined"        ,                  253,                     NOPE,    NOPE},
+ {"ActiveSensing"    ,  __SK_ActiveSensing_,                     NOPE,    NOPE},
+ {"SystemReset"      ,    __SK_SystemReset_,                     NOPE,    NOPE},
+
+ {"Volume"           ,  __SK_ControlChange_, __SK_Volume_            ,  SK_DBL},
+ {"ModWheel"         ,  __SK_ControlChange_, __SK_ModWheel_          ,  SK_DBL},
+ {"Modulation"       ,  __SK_ControlChange_, __SK_Modulation_        ,  SK_DBL},
+ {"Breath"           ,  __SK_ControlChange_, __SK_Breath_            ,  SK_DBL},
+ {"FootControl"      ,  __SK_ControlChange_, __SK_FootControl_       ,  SK_DBL},
+ {"Portamento"       ,  __SK_ControlChange_, __SK_Portamento_        ,  SK_DBL},
+ {"Balance"          ,  __SK_ControlChange_, __SK_Balance_           ,  SK_DBL},
+ {"Pan"              ,  __SK_ControlChange_, __SK_Pan_               ,  SK_DBL},
+ {"Sustain"          ,  __SK_ControlChange_, __SK_Sustain_           ,  SK_DBL},
+ {"Damper"           ,  __SK_ControlChange_, __SK_Damper_            ,  SK_DBL},
+ {"Expression"       ,  __SK_ControlChange_, __SK_Expression_        ,  SK_DBL},
+
+ {"NoiseLevel"       ,  __SK_ControlChange_, __SK_NoiseLevel_        ,  SK_DBL},
+ {"PickPosition"     ,  __SK_ControlChange_, __SK_PickPosition_      ,  SK_DBL},
+ {"StringDamping"    ,  __SK_ControlChange_, __SK_StringDamping_     ,  SK_DBL},
+ {"StringDetune"     ,  __SK_ControlChange_, __SK_StringDetune_      ,  SK_DBL},
+ {"BodySize"         ,  __SK_ControlChange_, __SK_BodySize_          ,  SK_DBL},
+ {"BowPressure"      ,  __SK_ControlChange_, __SK_BowPressure_       ,  SK_DBL},
+ {"BowPosition"      ,  __SK_ControlChange_, __SK_BowPosition_       ,  SK_DBL},
+ {"BowBeta"          ,  __SK_ControlChange_, __SK_BowBeta_           ,  SK_DBL},
+ {"ReedStiffness"    ,  __SK_ControlChange_, __SK_ReedStiffness_     ,  SK_DBL},
+ {"ReedRestPos"      ,  __SK_ControlChange_, __SK_ReedRestPos_       ,  SK_DBL},
+ {"FluteEmbouchure"  ,  __SK_ControlChange_, __SK_FluteEmbouchure_   ,  SK_DBL},
+ {"LipTension"       ,  __SK_ControlChange_, __SK_LipTension_        ,  SK_DBL},
+ {"StrikePosition"   ,  __SK_ControlChange_, __SK_StrikePosition_    ,  SK_DBL},
+ {"StickHardness"    ,  __SK_ControlChange_, __SK_StickHardness_     ,  SK_DBL},
+
+ {"TrillDepth"       ,  __SK_ControlChange_, __SK_TrillDepth_        ,  SK_DBL}, 
+ {"TrillSpeed"       ,  __SK_ControlChange_, __SK_TrillSpeed_        ,  SK_DBL},
+                                             
+ {"Strumming"        ,  __SK_ControlChange_, __SK_Strumming_         ,  127   }, 
+ {"NotStrumming"     ,  __SK_ControlChange_, __SK_Strumming_         ,  0     },
+                                             
+ {"PlayerSkill"      ,  __SK_ControlChange_, __SK_PlayerSkill_       ,  SK_DBL}, 
+
+ {"Chord"            ,  __SK_Chord_           ,                   SK_DBL,  SK_STR}, 
+ {"ChordOff"         ,  __SK_ChordOff_     ,                   SK_DBL,    NOPE}, 
+
+ {"ShakerInst"       ,  __SK_ControlChange_, __SK_ShakerInst_        ,  SK_DBL},
+ {"Maraca"           ,  __SK_ControlChange_, __SK_ShakerInst_         ,   0    },
+ {"Sekere"           ,  __SK_ControlChange_, __SK_ShakerInst_         ,   1    },
+ {"Cabasa"           ,  __SK_ControlChange_, __SK_ShakerInst_        ,   2    },
+ {"Bamboo"           ,  __SK_ControlChange_, __SK_ShakerInst_        ,   3    },
+ {"Waterdrp"         ,  __SK_ControlChange_, __SK_ShakerInst_        ,   4    },
+ {"Tambourn"         ,  __SK_ControlChange_, __SK_ShakerInst_        ,   5    },
+ {"Sleighbl"         ,  __SK_ControlChange_, __SK_ShakerInst_        ,   6    },
+ {"Guiro"            ,  __SK_ControlChange_, __SK_ShakerInst_        ,   7    },       
+
+ {"OpenFile"         ,                  256,                   SK_STR,    NOPE},
+ {"SetPath"          ,                  257,                   SK_STR,    NOPE},
+
+ {"FilePath"         ,  __SK_SINGER_FilePath_      ,           SK_STR,    NOPE},
+ {"Frequency"        ,  __SK_SINGER_Frequency_     ,           SK_STR,    NOPE},
+ {"NoteName"         ,  __SK_SINGER_NoteName_      ,           SK_STR,    NOPE},
+ {"VocalShape"       ,  __SK_SINGER_Shape_         ,           SK_STR,    NOPE},
+ {"Glottis"          ,  __SK_SINGER_Glot_          ,           SK_STR,    NOPE},
+ {"VoicedUnVoiced"   ,  __SK_SINGER_VoicedUnVoiced_,           SK_DBL,  SK_STR},
+ {"Synthesize"       ,  __SK_SINGER_Synthesize_    ,           SK_STR,    NOPE},
+ {"Silence"          ,  __SK_SINGER_Silence_       ,           SK_STR,    NOPE},
+ {"RndVibAmt"        ,  __SK_SINGER_RndVibAmt_     ,           SK_STR,    NOPE},
+ {"VibratoAmt"       ,  __SK_ControlChange_        ,__SK_SINGER_VibratoAmt_,SK_DBL},
+ {"VibFreq"          ,  __SK_ControlChange_        ,__SK_SINGER_VibFreq_   ,SK_DBL}
+};
+
+
+/**  FORMAT: *************************************************************/
+/*                                                                       */
+/* MessageStr$      , type, data2, data3,                                */
+/*                                                                       */
+/*     type is the message type sent back from the SKINI line parser.    */
+/*     data<n> is either                                                 */
+/*          NOPE    : field not used, specifically, there aren't going   */                                           
+/*                    to be any more fields on this line.  So if there   */
+/*                    is NOPE in data2, data3 won't even be checked      */
+/*          SK_INT  : byte (actually scanned as 32 bit signed integer)   */
+/*                    If it's a MIDI data field which is required to     */
+/*                    be an integer, like a controller number, it's      */
+/*                    0-127.  Otherwise, get creative with SK_INTs.      */
+/*          SK_DBL  : double precision floating point.  SKINI uses these */
+/*                    in the MIDI context for note numbers with micro    */
+/*                    tuning, velocities, controller values, etc.        */
+/*          SK_STR  : only valid in final field.  This allows (nearly)   */
+/*                    arbitrary message types to be supported by simply  */
+/*                    scanning the string to EndOfLine and then passing  */
+/*                    it to a more intelligent handler.  For example,    */
+/*                    MIDI SYSEX (system exclusive) messages of up to    */
+/*                    256 bytes can be read as space-delimited integers  */
+/*                    into the SK_STR buffer.  Longer bulk dumps,        */
+/*                    soundfiles, etc. should be handled as a new        */
+/*                    message type pointing to a FileName stored in the  */
+/*                    SK_STR field, or as a new type of multi-line       */                                      
+/*                    message.                                           */
+/*                                                                       */
+/*************************************************************************/
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/include/Socket.h b/lib/MoMu-STK-1.0.0/include/Socket.h
new file mode 100644 (file)
index 0000000..a153845
--- /dev/null
@@ -0,0 +1,89 @@
+#ifndef STK_SOCKET_H
+#define STK_SOCKET_H
+
+#include "Stk.h"
+
+#if (defined(__OS_IRIX__) || defined(__OS_LINUX__) || defined(__OS_MACOSX__))
+
+  #include <sys/socket.h>
+  #include <sys/types.h>
+  #include <arpa/inet.h>
+  #include <netdb.h>
+  #include <unistd.h>
+  #include <fcntl.h>
+  #include <netinet/in.h>
+  #include <netinet/tcp.h>
+
+#elif defined(__OS_WINDOWS__)
+
+  #include <winsock.h>
+
+#endif
+
+namespace stk {
+
+/***************************************************/
+/*! \class Socket
+    \brief STK internet socket abstract base class.
+
+    This class provides common functionality for TCP and UDP internet
+    socket server and client subclasses.  This class also provides a
+    number of static functions for use with external socket
+    descriptors.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class Socket : public Stk
+{
+ public:
+
+  enum ProtocolType {
+    PROTO_TCP,
+    PROTO_UDP
+  };
+
+  //! Class constructor
+  Socket();
+
+  //! Class destructor.
+  virtual ~Socket();
+
+  //! Close the socket.
+  static void close( int socket );
+
+  //! Return the socket descriptor.
+  int id( void ) const { return soket_; };
+
+  //! Return the socket port number.
+  int port( void ) const { return port_; };
+
+  //! Returns true if the socket descriptor is valid.
+  static bool isValid( int socket ) { return socket != -1; };
+
+  //! If enable = false, the socket is set to non-blocking mode.  When first created, sockets are by default in blocking mode.
+  static void setBlocking( int socket, bool enable );
+
+  //! Write a buffer over the socket connection.  Returns the number of bytes written or -1 if an error occurs.
+  virtual int writeBuffer(const void *buffer, long bufferSize, int flags = 0) = 0;
+
+  //! Read an input buffer, up to length \e bufferSize.  Returns the number of bytes read or -1 if an error occurs.
+  virtual int readBuffer(void *buffer, long bufferSize, int flags = 0) = 0;
+
+  //! Write a buffer via the specified socket.  Returns the number of bytes written or -1 if an error occurs.
+  static int writeBuffer(int socket, const void *buffer, long bufferSize, int flags );
+
+  //! Read a buffer via the specified socket.  Returns the number of bytes read or -1 if an error occurs.
+  static int readBuffer(int socket, void *buffer, long bufferSize, int flags );
+
+ protected:
+
+  int soket_;
+  int port_;
+
+};
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/Sphere.h b/lib/MoMu-STK-1.0.0/include/Sphere.h
new file mode 100644 (file)
index 0000000..48a6d76
--- /dev/null
@@ -0,0 +1,79 @@
+#ifndef STK_SPHERE_H
+#define STK_SPHERE_H
+
+#include "Stk.h"
+#include "Vector3D.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class Sphere
+    \brief STK sphere class.
+
+    This class implements a spherical ball with
+    radius, mass, position, and velocity parameters.
+
+    by Perry R. Cook, 1995 - 2010.
+*/
+/***************************************************/
+
+class Sphere : public Stk
+{
+public:
+  //! Constructor taking an initial radius value.
+  Sphere( StkFloat radius = 1.0 ) { radius_ = radius; mass_ = 1.0; };
+
+  //! Set the 3D center position of the sphere.
+  void setPosition( StkFloat x, StkFloat y, StkFloat z ) { position_.setXYZ(x, y, z); };
+
+  //! Set the 3D velocity of the sphere.
+  void setVelocity( StkFloat x, StkFloat y, StkFloat z ) { velocity_.setXYZ(x, y, z); };
+
+  //! Set the radius of the sphere.
+  void setRadius( StkFloat radius ) { radius_ = radius; };
+
+  //! Set the mass of the sphere.
+  void setMass( StkFloat mass ) { mass_ = mass; };
+
+  //! Get the current position of the sphere as a 3D vector.
+  Vector3D* getPosition( void ) { return &position_; };
+
+  //! Get the relative position of the given point to the sphere as a 3D vector.
+  Vector3D* getRelativePosition( Vector3D *position );
+
+  //! Set the velcoity of the sphere as a 3D vector.
+  StkFloat getVelocity( Vector3D* velocity );
+
+  //! Returns the distance from the sphere boundary to the given position (< 0 if inside).
+  StkFloat isInside( Vector3D *position );
+
+  //! Get the current sphere radius.
+  StkFloat getRadius( void ) { return radius_; };
+
+  //! Get the current sphere mass.
+  StkFloat getMass( void ) { return mass_; };
+
+  //! Increase the current sphere velocity by the given 3D components.
+  void addVelocity( StkFloat x, StkFloat y, StkFloat z );
+
+  //! Move the sphere for the given time increment.
+  void tick( StkFloat timeIncrement );
+   
+private:
+  Vector3D position_;
+  Vector3D velocity_;
+  Vector3D workingVector_;
+  StkFloat radius_;
+  StkFloat mass_;
+};
+
+inline void Sphere::tick( StkFloat timeIncrement )
+{
+  position_.setX(position_.getX() + (timeIncrement * velocity_.getX()));
+  position_.setY(position_.getY() + (timeIncrement * velocity_.getY()));
+  position_.setZ(position_.getZ() + (timeIncrement * velocity_.getZ()));
+};
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/StifKarp.h b/lib/MoMu-STK-1.0.0/include/StifKarp.h
new file mode 100644 (file)
index 0000000..002e31f
--- /dev/null
@@ -0,0 +1,117 @@
+#ifndef STK_STIFKARP_H
+#define STK_STIFKARP_H
+
+#include "Instrmnt.h"
+#include "DelayL.h"
+#include "DelayA.h"
+#include "OneZero.h"
+#include "Noise.h"
+#include "BiQuad.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class StifKarp
+    \brief STK plucked stiff string instrument.
+
+    This class implements a simple plucked string
+    algorithm (Karplus Strong) with enhancements
+    (Jaffe-Smith, Smith, and others), including
+    string stiffness and pluck position controls.
+    The stiffness is modeled with allpass filters.
+
+    This is a digital waveguide model, making its
+    use possibly subject to patents held by
+    Stanford University, Yamaha, and others.
+
+    Control Change Numbers:
+       - Pickup Position = 4
+       - String Sustain = 11
+       - String Stretch = 1
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class StifKarp : public Instrmnt
+{
+ public:
+  //! Class constructor, taking the lowest desired playing frequency.
+  StifKarp( StkFloat lowestFrequency );
+
+  //! Class destructor.
+  ~StifKarp( void );
+
+  //! Reset and clear all internal state.
+  void clear( void );
+
+  //! Set instrument parameters for a particular frequency.
+  void setFrequency( StkFloat frequency );
+
+  //! Set the stretch "factor" of the string (0.0 - 1.0).
+  void setStretch( StkFloat stretch );
+
+  //! Set the pluck or "excitation" position along the string (0.0 - 1.0).
+  void setPickupPosition( StkFloat position );
+
+  //! Set the base loop gain.
+  /*!
+    The actual loop gain is set according to the frequency.
+    Because of high-frequency loop filter roll-off, higher
+    frequency settings have greater loop gains.
+  */
+  void setBaseLoopGain( StkFloat aGain );
+
+  //! Pluck the string with the given amplitude using the current frequency.
+  void pluck( StkFloat amplitude );
+
+  //! Start a note with the given frequency and amplitude.
+  void noteOn( StkFloat frequency, StkFloat amplitude );
+
+  //! Stop a note with the given amplitude (speed of decay).
+  void noteOff( StkFloat amplitude );
+
+  //! Perform the control change specified by \e number and \e value (0.0 - 128.0).
+  void controlChange( int number, StkFloat value );
+
+  //! Compute and return one output sample.
+  StkFloat tick( unsigned int channel = 0 );
+
+ protected:
+
+  DelayA  delayLine_;
+  DelayL  combDelay_;
+  OneZero filter_;
+  Noise   noise_;
+  BiQuad  biquad_[4];
+
+  unsigned long length_;
+  StkFloat loopGain_;
+  StkFloat baseLoopGain_;
+  StkFloat lastFrequency_;
+  StkFloat lastLength_;
+  StkFloat stretching_;
+  StkFloat pluckAmplitude_;
+  StkFloat pickupPosition_;
+
+};
+
+inline StkFloat StifKarp :: tick( unsigned int )
+{
+  StkFloat temp = delayLine_.lastOut() * loopGain_;
+
+  // Calculate allpass stretching.
+  for (int i=0; i<4; i++)
+    temp = biquad_[i].tick(temp);
+
+  // Moving average filter.
+  temp = filter_.tick(temp);
+
+  lastFrame_[0] = delayLine_.tick(temp);
+  lastFrame_[0] = lastFrame_[0] - combDelay_.tick( lastFrame_[0] );
+  return lastFrame_[0];
+}
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/Stk.h b/lib/MoMu-STK-1.0.0/include/Stk.h
new file mode 100644 (file)
index 0000000..f9a34c2
--- /dev/null
@@ -0,0 +1,541 @@
+#ifndef STK_STK_H
+#define STK_STK_H
+
+#include <string>
+#include <iostream>
+#include <sstream>
+#include <vector>
+#include <cstdlib>
+
+/*! \namespace stk
+    \brief The STK namespace.
+
+    Most Stk classes are defined within the STK namespace.  Exceptions
+    to this include the classes RtAudio, RtMidi, and RtError.
+*/
+namespace stk {
+
+/***************************************************/
+/*! \class Stk
+    \brief STK base class
+
+    Nearly all STK classes inherit from this class.
+    The global sample rate and rawwave path variables
+    can be queried and modified via Stk.  In addition,
+    this class provides error handling and
+    byte-swapping functions.
+
+    The Synthesis ToolKit in C++ (STK) is a set of open source audio
+    signal processing and algorithmic synthesis classes written in the
+    C++ programming language. STK was designed to facilitate rapid
+    development of music synthesis and audio processing software, with
+    an emphasis on cross-platform functionality, realtime control,
+    ease of use, and educational example code.  STK currently runs
+    with realtime support (audio and MIDI) on Linux, Macintosh OS X,
+    and Windows computer platforms. Generic, non-realtime support has
+    been tested under NeXTStep, Sun, and other platforms and should
+    work with any standard C++ compiler.
+
+    STK WWW site: http://ccrma.stanford.edu/software/stk/
+
+    The Synthesis ToolKit in C++ (STK)
+    Copyright (c) 1995-2010 Perry R. Cook and Gary P. Scavone
+
+    Permission is hereby granted, free of charge, to any person
+    obtaining a copy of this software and associated documentation files
+    (the "Software"), to deal in the Software without restriction,
+    including without limitation the rights to use, copy, modify, merge,
+    publish, distribute, sublicense, and/or sell copies of the Software,
+    and to permit persons to whom the Software is furnished to do so,
+    subject to the following conditions:
+
+    The above copyright notice and this permission notice shall be
+    included in all copies or substantial portions of the Software.
+
+    Any person wishing to distribute modifications to the Software is
+    asked to send the modifications to the original developer so that
+    they can be incorporated into the canonical version.  This is,
+    however, not a binding provision of this license.
+
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+    IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+    ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+    CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+    WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+/***************************************************/
+
+//#define _STK_DEBUG_
+#define __OS_MACOSX__ // MoMu Modified
+       
+#ifndef __APPLE__
+       #define __APPLE__
+#endif
+       
+// Most data in STK is passed and calculated with the
+// following user-definable floating-point type.  You
+// can change this to "float" if you prefer or perhaps
+// a "long double" in the future.
+typedef double StkFloat;
+
+//! STK error handling class.
+/*!
+  This is a fairly abstract exception handling class.  There could
+  be sub-classes to take care of more specific error conditions ... or
+  not.
+*/
+class StkError
+{
+public:
+  enum Type {
+    STATUS,
+    WARNING,
+    DEBUG_WARNING,
+    MEMORY_ALLOCATION,
+    MEMORY_ACCESS,
+    FUNCTION_ARGUMENT,
+    FILE_NOT_FOUND,
+    FILE_UNKNOWN_FORMAT,
+    FILE_ERROR,
+    PROCESS_THREAD,
+    PROCESS_SOCKET,
+    PROCESS_SOCKET_IPADDR,
+    AUDIO_SYSTEM,
+    MIDI_SYSTEM,
+    UNSPECIFIED
+  };
+
+protected:
+  std::string message_;
+  Type type_;
+
+public:
+  //! The constructor.
+  StkError(const std::string& message, Type type = StkError::UNSPECIFIED)
+    : message_(message), type_(type) {}
+
+  //! The destructor.
+  virtual ~StkError(void) {};
+
+  //! Prints thrown error message to stderr.
+  virtual void printMessage(void) { std::cerr << '\n' << message_ << "\n\n"; }
+
+  //! Returns the thrown error message type.
+  virtual const Type& getType(void) { return type_; }
+
+  //! Returns the thrown error message string.
+  virtual const std::string& getMessage(void) { return message_; }
+
+  //! Returns the thrown error message as a C string.
+  virtual const char *getMessageCString(void) { return message_.c_str(); }
+};
+
+
+class Stk
+{
+public:
+
+  typedef unsigned long StkFormat;
+  static const StkFormat STK_SINT8;   /*!< -128 to +127 */
+  static const StkFormat STK_SINT16;  /*!< -32768 to +32767 */
+  static const StkFormat STK_SINT24;  /*!< Upper 3 bytes of 32-bit signed integer. */
+  static const StkFormat STK_SINT32;  /*!< -2147483648 to +2147483647. */
+  static const StkFormat STK_FLOAT32; /*!< Normalized between plus/minus 1.0. */
+  static const StkFormat STK_FLOAT64; /*!< Normalized between plus/minus 1.0. */
+
+  //! Static method that returns the current STK sample rate.
+  static StkFloat sampleRate( void ) { return srate_; }
+
+  //! Static method that sets the STK sample rate.
+  /*!
+    The sample rate set using this method is queried by all STK
+    classes that depend on its value.  It is initialized to the
+    default SRATE set in Stk.h.  Many STK classes use the sample rate
+    during instantiation.  Therefore, if you wish to use a rate that
+    is different from the default rate, it is imperative that it be
+    set \e BEFORE STK objects are instantiated.  A few classes that
+    make use of the global STK sample rate are automatically notified
+    when the rate changes so that internal class data can be
+    appropriately updated.  However, this has not been fully
+    implemented.  Specifically, classes that appropriately update
+    their own data when either a setFrequency() or noteOn() function
+    is called do not currently receive the automatic notification of
+    rate change.  If the user wants a specific class instance to
+    ignore such notifications, perhaps in a multi-rate context, the
+    function Stk::ignoreSampleRateChange() should be called.
+  */
+  static void setSampleRate( StkFloat rate );
+
+  //! A function to enable/disable the automatic updating of class data when the STK sample rate changes.
+  /*!
+    This function allows the user to enable or disable class data
+    updates in response to global sample rate changes on a class by
+    class basis.
+  */
+  void ignoreSampleRateChange( bool ignore = true ) { ignoreSampleRateChange_ = ignore; };
+
+  //! Static method that returns the current rawwave path.
+  static std::string rawwavePath(void) { return rawwavepath_; }
+
+  //! Static method that sets the STK rawwave path.
+  static void setRawwavePath( std::string path );
+
+  //! Static method that byte-swaps a 16-bit data type.
+  static void swap16( unsigned char *ptr );
+
+  //! Static method that byte-swaps a 32-bit data type.
+  static void swap32( unsigned char *ptr );
+
+  //! Static method that byte-swaps a 64-bit data type.
+  static void swap64( unsigned char *ptr );
+
+  //! Static cross-platform method to sleep for a number of milliseconds.
+  static void sleep( unsigned long milliseconds );
+
+  //! Static function for error reporting and handling using c-strings.
+  static void handleError( const char *message, StkError::Type type );
+
+  //! Static function for error reporting and handling using c++ strings.
+  static void handleError( std::string message, StkError::Type type );
+
+  //! Toggle display of WARNING and STATUS messages.
+  static void showWarnings( bool status ) { showWarnings_ = status; }
+
+  //! Toggle display of error messages before throwing exceptions.
+  static void printErrors( bool status ) { printErrors_ = status; }
+
+private:
+  static StkFloat srate_;
+  static std::string rawwavepath_;
+  static bool showWarnings_;
+  static bool printErrors_;
+  static std::vector<Stk *> alertList_;
+
+protected:
+
+  std::ostringstream errorString_;
+  bool ignoreSampleRateChange_;
+
+  //! Default constructor.
+  Stk( void );
+
+  //! Class destructor.
+  virtual ~Stk( void );
+
+  //! This function should be implemented in subclasses that depend on the sample rate.
+  virtual void sampleRateChanged( StkFloat newRate, StkFloat oldRate );
+
+  //! Add class pointer to list for sample rate change notification.
+  void addSampleRateAlert( Stk *ptr );
+
+  //! Remove class pointer from list for sample rate change notification.
+  void removeSampleRateAlert( Stk *ptr );
+
+  //! Internal function for error reporting that assumes message in \c errorString_ variable.
+  void handleError( StkError::Type type );
+};
+
+
+/***************************************************/
+/*! \class StkFrames
+    \brief An STK class to handle vectorized audio data.
+
+    This class can hold single- or multi-channel audio data.  The data
+    type is always StkFloat and the channel format is always
+    interleaved.  In an effort to maintain efficiency, no
+    out-of-bounds checks are performed in this class unless
+    _STK_DEBUG_ is defined.
+
+    Internally, the data is stored in a one-dimensional C array.  An
+    indexing operator is available to set and retrieve data values.
+    Alternately, one can use pointers to access the data, using the
+    index operator to get an address for a particular location in the
+    data:
+
+      StkFloat* ptr = &myStkFrames[0];
+
+    Possible future improvements in this class could include functions
+    to convert to and return other data types.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class StkFrames
+{
+public:
+
+  //! The default constructor initializes the frame data structure to size zero.
+  StkFrames( unsigned int nFrames = 0, unsigned int nChannels = 0 );
+
+  //! Overloaded constructor that initializes the frame data to the specified size with \c value.
+  StkFrames( const StkFloat& value, unsigned int nFrames, unsigned int nChannels );
+
+  //! The destructor.
+  ~StkFrames();
+
+  // A copy constructor.
+  StkFrames( const StkFrames& f );
+
+  // Assignment operator that returns a reference to self.
+  StkFrames& operator= ( const StkFrames& f );
+
+  //! Subscript operator that returns a reference to element \c n of self.
+  /*!
+    The result can be used as an lvalue. This reference is valid
+    until the resize function is called or the array is destroyed. The
+    index \c n must be between 0 and size less one.  No range checking
+    is performed unless _STK_DEBUG_ is defined.
+  */
+  StkFloat& operator[] ( size_t n );
+
+  //! Subscript operator that returns the value at element \c n of self.
+  /*!
+    The index \c n must be between 0 and size less one.  No range
+    checking is performed unless _STK_DEBUG_ is defined.
+  */
+  StkFloat operator[] ( size_t n ) const;
+
+  //! Assignment by sum operator into self.
+  /*!
+    The dimensions of the argument are expected to be the same as
+    self.  No range checking is performed unless _STK_DEBUG_ is
+    defined.
+  */
+  void operator+= ( StkFrames& f );
+
+  //! Assignment by product operator into self.
+  /*!
+    The dimensions of the argument are expected to be the same as
+    self.  No range checking is performed unless _STK_DEBUG_ is
+    defined.
+  */
+  void operator*= ( StkFrames& f );
+
+  //! Channel / frame subscript operator that returns a reference.
+  /*!
+    The result can be used as an lvalue. This reference is valid
+    until the resize function is called or the array is destroyed. The
+    \c frame index must be between 0 and frames() - 1.  The \c channel
+    index must be between 0 and channels() - 1.  No range checking is
+    performed unless _STK_DEBUG_ is defined.
+  */
+  StkFloat& operator() ( size_t frame, unsigned int channel );
+
+  //! Channel / frame subscript operator that returns a value.
+  /*!
+    The \c frame index must be between 0 and frames() - 1.  The \c
+    channel index must be between 0 and channels() - 1.  No range checking
+    is performed unless _STK_DEBUG_ is defined.
+  */
+  StkFloat operator() ( size_t frame, unsigned int channel ) const;
+
+  //! Return an interpolated value at the fractional frame index and channel.
+  /*!
+    This function performs linear interpolation.  The \c frame
+    index must be between 0.0 and frames() - 1.  The \c channel index
+    must be between 0 and channels() - 1.  No range checking is
+    performed unless _STK_DEBUG_ is defined.
+  */
+  StkFloat interpolate( StkFloat frame, unsigned int channel = 0 ) const;
+
+  //! Returns the total number of audio samples represented by the object.
+  size_t size() const { return size_; }; 
+
+  //! Returns \e true if the object size is zero and \e false otherwise.
+  bool empty() const;
+
+  //! Resize self to represent the specified number of channels and frames.
+  /*!
+    Changes the size of self based on the number of frames and
+    channels.  No element assignment is performed.  No memory
+    deallocation occurs if the new size is smaller than the previous
+    size.  Further, no new memory is allocated when the new size is
+    smaller or equal to a previously allocated size.
+  */
+  void resize( size_t nFrames, unsigned int nChannels = 1 );
+
+  //! Resize self to represent the specified number of channels and frames and perform element initialization.
+  /*!
+    Changes the size of self based on the number of frames and
+    channels, and assigns \c value to every element.  No memory
+    deallocation occurs if the new size is smaller than the previous
+    size.  Further, no new memory is allocated when the new size is
+    smaller or equal to a previously allocated size.
+  */
+  void resize( size_t nFrames, unsigned int nChannels, StkFloat value );
+
+  //! Return the number of channels represented by the data.
+  unsigned int channels( void ) const { return nChannels_; };
+
+  //! Return the number of sample frames represented by the data.
+  unsigned int frames( void ) const { return nFrames_; };
+
+  //! Set the sample rate associated with the StkFrames data.
+  /*!
+    By default, this value is set equal to the current STK sample
+    rate at the time of instantiation.
+   */
+  void setDataRate( StkFloat rate ) { dataRate_ = rate; };
+
+  //! Return the sample rate associated with the StkFrames data.
+  /*!
+    By default, this value is set equal to the current STK sample
+    rate at the time of instantiation.
+   */
+  StkFloat dataRate( void ) const { return dataRate_; };
+
+private:
+
+  StkFloat *data_;
+  StkFloat dataRate_;
+  size_t nFrames_;
+  unsigned int nChannels_;
+  size_t size_;
+  size_t bufferSize_;
+
+};
+
+inline bool StkFrames :: empty() const
+{
+  if ( size_ > 0 ) return false;
+  else return true;
+}
+
+inline StkFloat& StkFrames :: operator[] ( size_t n )
+{
+#if defined(_STK_DEBUG_)
+  if ( n >= size_ ) {
+    std::ostringstream error;
+    error << "StkFrames::operator[]: invalid index (" << n << ") value!";
+    Stk::handleError( error.str(), StkError::MEMORY_ACCESS );
+  }
+#endif
+
+  return data_[n];
+}
+
+inline StkFloat StkFrames :: operator[] ( size_t n ) const
+{
+#if defined(_STK_DEBUG_)
+  if ( n >= size_ ) {
+    std::ostringstream error;
+    error << "StkFrames::operator[]: invalid index (" << n << ") value!";
+    Stk::handleError( error.str(), StkError::MEMORY_ACCESS );
+  }
+#endif
+
+  return data_[n];
+}
+
+inline StkFloat& StkFrames :: operator() ( size_t frame, unsigned int channel )
+{
+#if defined(_STK_DEBUG_)
+  if ( frame >= nFrames_ || channel >= nChannels_ ) {
+    std::ostringstream error;
+    error << "StkFrames::operator(): invalid frame (" << frame << ") or channel (" << channel << ") value!";
+    Stk::handleError( error.str(), StkError::MEMORY_ACCESS );
+  }
+#endif
+
+  return data_[ frame * nChannels_ + channel ];
+}
+
+inline StkFloat StkFrames :: operator() ( size_t frame, unsigned int channel ) const
+{
+#if defined(_STK_DEBUG_)
+  if ( frame >= nFrames_ || channel >= nChannels_ ) {
+    std::ostringstream error;
+    error << "StkFrames::operator(): invalid frame (" << frame << ") or channel (" << channel << ") value!";
+    Stk::handleError( error.str(), StkError::MEMORY_ACCESS );
+  }
+#endif
+
+  return data_[ frame * nChannels_ + channel ];
+}
+
+inline void StkFrames :: operator+= ( StkFrames& f )
+{
+#if defined(_STK_DEBUG_)
+  if ( f.frames() != nFrames_ || f.channels() != nChannels_ ) {
+    std::ostringstream error;
+    error << "StkFrames::operator+=: frames argument must be of equal dimensions!";
+    Stk::handleError( error.str(), StkError::MEMORY_ACCESS );
+  }
+#endif
+
+  StkFloat *fptr = &f[0];
+  StkFloat *dptr = data_;
+  for ( unsigned int i=0; i<size_; i++ )
+    *dptr++ += *fptr++;
+}
+
+inline void StkFrames :: operator*= ( StkFrames& f )
+{
+#if defined(_STK_DEBUG_)
+  if ( f.frames() != nFrames_ || f.channels() != nChannels_ ) {
+    std::ostringstream error;
+    error << "StkFrames::operator*=: frames argument must be of equal dimensions!";
+    Stk::handleError( error.str(), StkError::MEMORY_ACCESS );
+  }
+#endif
+
+  StkFloat *fptr = &f[0];
+  StkFloat *dptr = data_;
+  for ( unsigned int i=0; i<size_; i++ )
+    *dptr++ *= *fptr++;
+}
+
+// Here are a few other useful typedefs.
+typedef unsigned short UINT16;
+typedef unsigned int UINT32;
+typedef signed short SINT16;
+typedef signed int SINT32;
+typedef float FLOAT32;
+typedef double FLOAT64;
+
+// The default sampling rate.
+const StkFloat SRATE = 44100.0;
+
+// The default real-time audio input and output buffer size.  If
+// clicks are occuring in the input and/or output sound stream, a
+// larger buffer size may help.  Larger buffer sizes, however, produce
+// more latency.
+const unsigned int RT_BUFFER_SIZE = 512;
+
+// The default rawwave path value is set with the preprocessor
+// definition RAWWAVE_PATH.  This can be specified as an argument to
+// the configure script, in an integrated development environment, or
+// below.  The global STK rawwave path variable can be dynamically set
+// with the Stk::setRawwavePath() function.  This value is
+// concatenated to the beginning of all references to rawwave files in
+// the various STK core classes (ex. Clarinet.cpp).  If you wish to
+// move the rawwaves directory to a different location in your file
+// system, you will need to set this path definition appropriately.
+
+//#if !defined(RAWWAVE_PATH)
+//  #define RAWWAVE_PATH ""            //MoMu Modified
+//#endif
+
+const StkFloat PI           = 3.14159265358979;
+const StkFloat TWO_PI       = 2 * PI;
+const StkFloat ONE_OVER_128 = 0.0078125;
+
+#if defined(__WINDOWS_DS__) || defined(__WINDOWS_ASIO__) || defined(__WINDOWS_MM__)
+  #define __OS_WINDOWS__
+  #define __STK_REALTIME__
+#elif defined(__LINUX_OSS__) || defined(__LINUX_ALSA__) || defined(__UNIX_JACK__)
+  #define __OS_LINUX__
+  #define __STK_REALTIME__
+#elif defined(__IRIX_AL__)
+  #define __OS_IRIX__
+#elif defined(__MACOSX_CORE__) || defined(__UNIX_JACK__)
+  #define __OS_MACOSX__
+  #define __STK_REALTIME__
+#endif
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/StkUdpSocket.h b/lib/MoMu-STK-1.0.0/include/StkUdpSocket.h
new file mode 100644 (file)
index 0000000..749c88d
--- /dev/null
@@ -0,0 +1,76 @@
+#ifndef STK_UDPSOCKET_H
+#define STK_UDPSOCKET_H
+
+#include "Socket.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class UdpSocket
+    \brief STK UDP socket server/client class.
+
+    This class provides a uniform cross-platform UDP socket
+    server/client interface.  Methods are provided for reading or
+    writing data buffers.  The constructor creates a UDP socket and
+    binds it to the specified port.  Note that only one socket can be
+    bound to a given port on the same machine.
+
+    UDP sockets provide unreliable, connection-less service.  Messages
+    can be lost, duplicated, or received out of order.  That said,
+    data transmission tends to be faster than with TCP connections and
+    datagrams are not potentially combined by the underlying system.
+
+    The user is responsible for checking the values returned by the
+    read/write methods.  Values less than or equal to zero indicate
+    the occurence of an error.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class StkUdpSocket : public Socket
+{
+ public:
+  //! Default constructor creates a local UDP socket on port 2006 (or the specified port number).
+  /*!
+    An StkError will be thrown if a socket error occurs during instantiation.
+  */
+  StkUdpSocket( int port = 2006 );
+
+  //! The class destructor closes the socket instance.
+  ~StkUdpSocket();
+
+  //! Set the address for subsequent outgoing data sent via the \e writeBuffer() function.
+  /*!
+    An StkError will be thrown if the host is unknown.
+  */
+  void setDestination( int port = 2006, std::string hostname = "localhost" );
+
+  //! Send a buffer to the address specified with the \e setDestination() function.  Returns the number of bytes written or -1 if an error occurs.
+  /*!
+    This function will fail if the default address (set with \e setDestination()) is invalid or has not been specified.
+   */
+  int writeBuffer(const void *buffer, long bufferSize, int flags = 0);
+
+  //! Read an input buffer, up to length \e bufferSize.  Returns the number of bytes read or -1 if an error occurs.
+  int readBuffer(void *buffer, long bufferSize, int flags = 0);
+
+  //! Write a buffer to the specified socket.  Returns the number of bytes written or -1 if an error occurs.
+  int writeBufferTo(const void *buffer, long bufferSize, int port, std::string hostname = "localhost", int flags = 0 );
+
+ protected:
+
+  //! A protected function for use in writing a socket address structure.
+  /*!
+    An StkError will be thrown if the host is unknown.
+  */
+  void setAddress( struct sockaddr_in *address, int port = 2006, std::string hostname = "localhost" );
+
+  struct sockaddr_in address_;
+  bool validAddress_;
+
+};
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/TapDelay.h b/lib/MoMu-STK-1.0.0/include/TapDelay.h
new file mode 100644 (file)
index 0000000..f807092
--- /dev/null
@@ -0,0 +1,216 @@
+#ifndef STK_TAPDELAY_H
+#define STK_TAPDELAY_H
+
+#include "Filter.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class TapDelay
+    \brief STK non-interpolating tapped delay line class.
+
+    This class implements a non-interpolating digital delay-line with
+    an arbitrary number of output "taps".  If the maximum length and
+    tap delays are not specified during instantiation, a fixed maximum
+    length of 4095 and a single tap delay of zero is set.
+    
+    A non-interpolating delay line is typically used in fixed
+    delay-length applications, such as for reverberation.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class TapDelay : public Filter
+{
+ public:
+
+  //! The default constructor creates a delay-line with maximum length of 4095 samples and a single tap at delay = 0.
+  /*!
+    An StkError will be thrown if any tap delay parameter is less
+    than zero, the maximum delay parameter is less than one, or any
+    tap delay parameter is greater than the maxDelay value.
+   */
+  TapDelay( std::vector<unsigned long> taps = std::vector<unsigned long>( 1, 0 ), unsigned long maxDelay = 4095 );
+
+  //! Class destructor.
+  ~TapDelay();
+
+  //! Set the maximum delay-line length.
+  /*!
+    This method should generally only be used during initial setup
+    of the delay line.  If it is used between calls to the tick()
+    function, without a call to clear(), a signal discontinuity will
+    likely occur.  If the current maximum length is greater than the
+    new length, no change will be made.
+  */
+  void setMaximumDelay( unsigned long delay );
+
+  //! Set the delay-line tap lengths.
+  /*!
+    The valid range for each tap length is from 0 to the maximum delay-line length.
+  */
+  void setTapDelays( std::vector<unsigned long> taps );
+
+  //! Return the current delay-line length.
+  std::vector<unsigned long> getTapDelays( void ) const { return delays_; };
+
+  //! Return the specified tap value of the last computed frame.
+  /*!
+    Use the lastFrame() function to get all tap values from the
+    last computed frame.  The \c tap argument must be less than the
+    number of delayline taps (the first tap is specified by 0).
+    However, range checking is only performed if _STK_DEBUG_ is
+    defined during compilation, in which case an out-of-range value
+    will trigger an StkError exception.
+  */
+  StkFloat lastOut( unsigned int tap = 0 ) const;
+
+  //! Input one sample to the delayline and return outputs at all tap positions.
+  /*!
+    The StkFrames argument reference is returned.  The output
+    values are ordered according to the tap positions set using the
+    setTapDelays() function (no sorting is performed).  The StkFrames
+    argument must contain at least as many channels as the number of
+    taps.  However, range checking is only performed if _STK_DEBUG_ is
+    defined during compilation, in which case an out-of-range value
+    will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFloat input, StkFrames& outputs );
+
+  //! Take a channel of the StkFrames object as inputs to the filter and write outputs back to the same object.
+  /*!
+    The StkFrames argument reference is returned.  The output
+    values are ordered according to the tap positions set using the
+    setTapDelays() function (no sorting is performed).  The StkFrames
+    argument must contain at least as many channels as the number of
+    taps.  However, range checking is only performed if _STK_DEBUG_ is
+    defined during compilation, in which case an out-of-range value
+    will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
+
+  //! Take a channel of the \c iFrames object as inputs to the filter and write outputs to the \c oFrames object.
+  /*!
+    The \c iFrames object reference is returned.  The output values
+    are ordered according to the tap positions set using the
+    setTapDelays() function (no sorting is performed).  The \c
+    iChannel argument must be less than the number of channels in
+    the \c iFrames argument (the first channel is specified by 0).
+    The \c oFrames argument must contain at least as many channels as
+    the number of taps.  However, range checking is only performed if
+    _STK_DEBUG_ is defined during compilation, in which case an
+    out-of-range value will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0 );
+
+ protected:
+
+  unsigned long inPoint_;
+  std::vector<unsigned long> outPoint_;
+  std::vector<unsigned long> delays_;
+
+};
+
+inline StkFloat TapDelay :: lastOut( unsigned int tap ) const
+{
+#if defined(_STK_DEBUG_)
+  if ( tap >= lastFrame_.size() ) ) {
+    errorString_ << "TapDelay::lastOut(): tap argument and number of taps are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  return lastFrame_[tap];
+}
+
+inline StkFrames& TapDelay :: tick( StkFloat input, StkFrames& outputs )
+{
+#if defined(_STK_DEBUG_)
+  if ( outputs.channels() < outPoint_.size() ) {
+    errorString_ << "TapDelay::tick(): number of taps > channels in StkFrames argument!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  inputs_[inPoint_++] = input * gain_;
+
+  // Check for end condition
+  if ( inPoint_ == inputs_.size() )
+    inPoint_ = 0;
+
+  // Read out next values
+  StkFloat *outs = &outputs[0];
+  for ( unsigned int i=0; i<outPoint_.size(); i++ ) {
+    *outs++ = inputs_[outPoint_[i]];
+    lastFrame_[i] = *outs;
+    if ( ++outPoint_[i] == inputs_.size() )
+      outPoint_[i] = 0;
+  }
+
+  return outputs;
+}
+
+inline StkFrames& TapDelay :: tick( StkFrames& frames, unsigned int channel )
+{
+#if defined(_STK_DEBUG_)
+  if ( channel >= frames.channels() ) {
+    errorString_ << "TapDelay::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+  if ( frames.channels() < outPoint_.size() ) {
+    errorString_ << "TapDelay::tick(): number of taps > channels in StkFrames argument!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *iSamples = &frames[channel];
+  StkFloat *oSamples = &frames[0];
+  unsigned int j, iHop = frames.channels(), oHop = frames.channels() - outPoint_.size();
+  for ( unsigned int i=0; i<frames.frames(); i++, iSamples += iHop, oSamples += oHop ) {
+    inputs_[inPoint_++] = *iSamples * gain_;
+    if ( inPoint_ == inputs_.size() ) inPoint_ = 0;
+    for ( j=0; j<outPoint_.size(); j++ ) {
+      *oSamples++ = inputs_[outPoint_[j]];
+      if ( ++outPoint_[j] == inputs_.size() ) outPoint_[j] = 0;
+    }
+  }
+
+  oSamples -= frames.channels();
+  for ( j=0; j<outPoint_.size(); j++ ) lastFrame_[j] = *oSamples++;
+  return frames;
+}
+
+inline StkFrames& TapDelay :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iChannel )
+{
+#if defined(_STK_DEBUG_)
+  if ( iChannel >= iFrames.channels() ) {
+    errorString_ << "TapDelay::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+  if ( oFrames.channels() < outPoint_.size() ) {
+    errorString_ << "TapDelay::tick(): number of taps > channels in output StkFrames argument!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *iSamples = &iFrames[iChannel];
+  StkFloat *oSamples = &oFrames[0];
+  unsigned int j, iHop = iFrames.channels(), oHop = oFrames.channels() - outPoint_.size();
+  for ( unsigned int i=0; i<iFrames.frames(); i++, iSamples += iHop, oSamples += oHop ) {
+    inputs_[inPoint_++] = *iSamples * gain_;
+    if ( inPoint_ == inputs_.size() ) inPoint_ = 0;
+    for ( j=0; j<outPoint_.size(); j++ ) {
+      *oSamples++ = inputs_[outPoint_[j]];
+      if ( ++outPoint_[j] == inputs_.size() ) outPoint_[j] = 0;
+    }
+  }
+
+  oSamples -= oFrames.channels();
+  for ( j=0; j<outPoint_.size(); j++ ) lastFrame_[j] = *oSamples++;
+  return iFrames;
+}
+
+#endif
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/include/TcpClient.h b/lib/MoMu-STK-1.0.0/include/TcpClient.h
new file mode 100644 (file)
index 0000000..5bbc24d
--- /dev/null
@@ -0,0 +1,65 @@
+#ifndef STK_TCPCLIENT_H
+#define STK_TCPCLIENT_H
+
+#include "Socket.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class TcpClient
+    \brief STK TCP socket client class.
+
+    This class provides a uniform cross-platform TCP socket client
+    interface.  Methods are provided for reading or writing data
+    buffers to/from connections.
+
+    TCP sockets are reliable and connection-oriented.  A TCP socket
+    client must be connected to a TCP server before data can be sent
+    or received.  Data delivery is guaranteed in order, without loss,
+    error, or duplication.  That said, TCP transmissions tend to be
+    slower than those using the UDP protocol and data sent with
+    multiple \e write() calls can be arbitrarily combined by the
+    underlying system.
+
+    The user is responsible for checking the values
+    returned by the read/write methods.  Values
+    less than or equal to zero indicate a closed
+    or lost connection or the occurence of an error.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class TcpClient : public Socket
+{
+ public:
+  //! Default class constructor creates a socket client connection to the specified host and port.
+  /*!
+    An StkError will be thrown if a socket error occurs during instantiation.
+  */
+  TcpClient( int port, std::string hostname = "localhost" );
+
+  //! The class destructor closes the socket instance, breaking any existing connections.
+  ~TcpClient();
+
+  //! Connect the socket client to the specified host and port and returns the resulting socket descriptor.
+  /*!
+    If the socket client is already connected, that connection is
+    terminated and a new connection is attempted.  An StkError will be
+    thrown if a socket error occurs.
+  */
+  int connect( int port, std::string hostname = "localhost" );
+
+  //! Write a buffer over the socket connection.  Returns the number of bytes written or -1 if an error occurs.
+  int writeBuffer(const void *buffer, long bufferSize, int flags = 0);
+
+  //! Read a buffer from the socket connection, up to length \e bufferSize.  Returns the number of bytes read or -1 if an error occurs.
+  int readBuffer(void *buffer, long bufferSize, int flags = 0);
+
+ protected:
+
+};
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/TcpServer.h b/lib/MoMu-STK-1.0.0/include/TcpServer.h
new file mode 100644 (file)
index 0000000..dddc69c
--- /dev/null
@@ -0,0 +1,65 @@
+#ifndef STK_TCPSERVER_H
+#define STK_TCPSERVER_H
+
+#include "Socket.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class TcpServer
+    \brief STK TCP socket server class.
+
+    This class provides a uniform cross-platform TCP socket server
+    interface.  Methods are provided for reading or writing data
+    buffers to/from connections.
+
+    TCP sockets are reliable and connection-oriented.  A TCP socket
+    server must accept a connection from a TCP client before data can
+    be sent or received.  Data delivery is guaranteed in order,
+    without loss, error, or duplication.  That said, TCP transmissions
+    tend to be slower than those using the UDP protocol and data sent
+    with multiple \e write() calls can be arbitrarily combined by the
+    underlying system.
+
+    The user is responsible for checking the values
+    returned by the read/write methods.  Values
+    less than or equal to zero indicate a closed
+    or lost connection or the occurence of an error.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class TcpServer : public Socket
+{
+ public:
+  //! Default constructor creates a local socket server on port 2006 (or the specified port number).
+  /*!
+    An StkError will be thrown if a socket error occurs during instantiation.
+  */
+  TcpServer( int port = 2006 );
+
+  //! The class destructor closes the socket instance, breaking any existing connections.
+  ~TcpServer();
+
+  //! Extract the first pending connection request from the queue and create a new connection, returning the descriptor for the accepted socket.
+  /*!
+    If no connection requests are pending and the socket has not
+    been set non-blocking, this function will block until a connection
+    is present.  If an error occurs, -1 is returned.
+  */
+  int accept( void );
+
+  //! Write a buffer over the socket connection.  Returns the number of bytes written or -1 if an error occurs.
+  int writeBuffer(const void *buffer, long bufferSize, int flags = 0);
+
+  //! Read a buffer from the socket connection, up to length \e bufferSize.  Returns the number of bytes read or -1 if an error occurs.
+  int readBuffer(void *buffer, long bufferSize, int flags = 0);
+
+ protected:
+
+};
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/Thread.h b/lib/MoMu-STK-1.0.0/include/Thread.h
new file mode 100644 (file)
index 0000000..079fc80
--- /dev/null
@@ -0,0 +1,98 @@
+#ifndef STK_THREAD_H
+#define STK_THREAD_H
+
+#include "Stk.h"
+
+#if (defined(__OS_IRIX__) || defined(__OS_LINUX__) || defined(__OS_MACOSX__))
+
+  #include <pthread.h>
+  #define THREAD_TYPE
+  typedef pthread_t THREAD_HANDLE;
+  typedef void * THREAD_RETURN;
+  typedef void * (*THREAD_FUNCTION)(void *);
+
+#elif defined(__OS_WINDOWS__)
+
+  #include <windows.h>
+  #include <process.h>
+  #define THREAD_TYPE __stdcall
+  typedef unsigned long THREAD_HANDLE;
+  typedef unsigned THREAD_RETURN;
+  typedef unsigned (__stdcall *THREAD_FUNCTION)(void *);
+
+#endif
+
+namespace stk {
+
+/***************************************************/
+/*! \class Thread
+    \brief STK thread class.
+
+    This class provides a uniform interface for cross-platform
+    threads.  On unix systems, the pthread library is used.  Under
+    Windows, the C runtime threadex functions are used.
+
+    Each instance of the Thread class can be used to control a single
+    thread process.  Routines are provided to signal cancelation
+    and/or joining with a thread, though it is not possible for this
+    class to know the running status of a thread once it is started.
+
+    For cross-platform compatability, thread functions should be
+    declared as follows:
+
+    THREAD_RETURN THREAD_TYPE thread_function(void *ptr)
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class Thread : public Stk
+{
+ public:
+  //! Default constructor.
+  Thread();
+
+  //! The class destructor does not attempt to cancel or join a thread.
+  ~Thread();
+
+  //! Begin execution of the thread \e routine.  Upon success, true is returned.
+  /*!
+    A data pointer can be supplied to the thread routine via the
+    optional \e ptr argument.  If the thread cannot be created, the
+    return value is false.
+  */
+  bool start( THREAD_FUNCTION routine, void * ptr = NULL );
+
+  //! Signal cancellation of a thread routine, returning \e true on success.
+  /*!
+    This function only signals thread cancellation.  It does not
+    wait to verify actual routine termination.  A \e true return value
+    only signifies that the cancellation signal was properly executed,
+    not thread cancellation.  A thread routine may need to make use of
+    the testCancel() function to specify a cancellation point.
+  */
+  bool cancel(void);
+
+  //! Block the calling routine indefinitely until the thread terminates.
+  /*!
+    This function suspends execution of the calling routine until the thread has terminated.  It will return immediately if the thread was already terminated.  A \e true return value signifies successful termination.  A \e false return value indicates a problem with the wait call.
+  */
+  bool wait(void);
+
+  //! Create a cancellation point within a thread routine.
+  /*!
+    This function call checks for thread cancellation, allowing the
+    thread to be terminated if a cancellation request was previously
+    signaled.
+  */
+  void testCancel(void);
+
+ protected:
+
+  THREAD_HANDLE thread_;
+
+};
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/TubeBell.h b/lib/MoMu-STK-1.0.0/include/TubeBell.h
new file mode 100644 (file)
index 0000000..6b4d2a7
--- /dev/null
@@ -0,0 +1,88 @@
+#ifndef STK_TUBEBELL_H
+#define STK_TUBEBELL_H
+
+#include "FM.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class TubeBell
+    \brief STK tubular bell (orchestral chime) FM
+           synthesis instrument.
+
+    This class implements two simple FM Pairs
+    summed together, also referred to as algorithm
+    5 of the TX81Z.
+
+    \code
+    Algorithm 5 is :  4->3--\
+                             + --> Out
+                      2->1--/
+    \endcode
+
+    Control Change Numbers: 
+       - Modulator Index One = 2
+       - Crossfade of Outputs = 4
+       - LFO Speed = 11
+       - LFO Depth = 1
+       - ADSR 2 & 4 Target = 128
+
+    The basic Chowning/Stanford FM patent expired
+    in 1995, but there exist follow-on patents,
+    mostly assigned to Yamaha.  If you are of the
+    type who should worry about this (making
+    money) worry away.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class TubeBell : public FM
+{
+ public:
+  //! Class constructor.
+  /*!
+    An StkError will be thrown if the rawwave path is incorrectly set.
+  */
+  TubeBell( void );
+
+  //! Class destructor.
+  ~TubeBell( void );
+
+  //! Start a note with the given frequency and amplitude.
+  void noteOn( StkFloat frequency, StkFloat amplitude );
+
+  //! Compute and return one output sample.
+  StkFloat tick( unsigned int channel = 0 );
+
+ protected:
+
+};
+
+inline StkFloat TubeBell :: tick( unsigned int )
+{
+  StkFloat temp, temp2;
+
+  temp = gains_[1] * adsr_[1]->tick() * waves_[1]->tick();
+  temp = temp * control1_;
+
+  waves_[0]->addPhaseOffset( temp );
+  waves_[3]->addPhaseOffset( twozero_.lastOut() );
+  temp = gains_[3] * adsr_[3]->tick() * waves_[3]->tick();
+  twozero_.tick( temp );
+
+  waves_[2]->addPhaseOffset( temp );
+  temp = ( 1.0 - (control2_ * 0.5)) * gains_[0] * adsr_[0]->tick() * waves_[0]->tick();
+  temp += control2_ * 0.5 * gains_[2] * adsr_[2]->tick() * waves_[2]->tick();
+
+  // Calculate amplitude modulation and apply it to output.
+  temp2 = vibrato_.tick() * modDepth_;
+  temp = temp * (1.0 + temp2);
+    
+  lastFrame_[0] = temp * 0.5;
+  return lastFrame_[0];
+}
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/TwoPole.h b/lib/MoMu-STK-1.0.0/include/TwoPole.h
new file mode 100644 (file)
index 0000000..adb4789
--- /dev/null
@@ -0,0 +1,151 @@
+#ifndef STK_TWOPOLE_H
+#define STK_TWOPOLE_H
+
+#include "Filter.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class TwoPole
+    \brief STK two-pole filter class.
+
+    This class implements a two-pole digital filter.  A method is
+    provided for creating a resonance in the frequency response while
+    maintaining a nearly constant filter gain.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class TwoPole : public Filter
+{
+ public:
+
+  //! Default constructor creates a second-order pass-through filter.
+  TwoPole( void );
+
+  //! Class destructor.
+  ~TwoPole();
+
+  //! A function to enable/disable the automatic updating of class data when the STK sample rate changes.
+  void ignoreSampleRateChange( bool ignore = true ) { ignoreSampleRateChange_ = ignore; };
+
+  //! Set the b[0] coefficient value.
+  void setB0( StkFloat b0 ) { b_[0] = b0; };
+
+  //! Set the a[1] coefficient value.
+  void setA1( StkFloat a1 ) { a_[1] = a1; };
+
+  //! Set the a[2] coefficient value.
+  void setA2( StkFloat a2 ) { a_[2] = a2; };
+
+  //! Set all filter coefficients.
+  void setCoefficients( StkFloat b0, StkFloat a1, StkFloat a2, bool clearState = false );
+
+  //! Sets the filter coefficients for a resonance at \e frequency (in Hz).
+  /*!
+    This method determines the filter coefficients corresponding to
+    two complex-conjugate poles with the given \e frequency (in Hz)
+    and \e radius from the z-plane origin.  If \e normalize is true,
+    the coefficients are then normalized to produce unity gain at \e
+    frequency (the actual maximum filter gain tends to be slightly
+    greater than unity when \e radius is not close to one).  The
+    resulting filter frequency response has a resonance at the given
+    \e frequency.  The closer the poles are to the unit-circle (\e
+    radius close to one), the narrower the resulting resonance width.
+    An unstable filter will result for \e radius >= 1.0.  For a better
+    resonance filter, use a BiQuad filter. \sa BiQuad filter class
+  */
+  void setResonance(StkFloat frequency, StkFloat radius, bool normalize = false);
+
+  //! Return the last computed output value.
+  StkFloat lastOut( void ) const { return lastFrame_[0]; };
+
+  //! Input one sample to the filter and return one output.
+  StkFloat tick( StkFloat input );
+
+  //! Take a channel of the StkFrames object as inputs to the filter and replace with corresponding outputs.
+  /*!
+    The StkFrames argument reference is returned.  The \c channel
+    argument must be less than the number of channels in the
+    StkFrames argument (the first channel is specified by 0).
+    However, range checking is only performed if _STK_DEBUG_ is
+    defined during compilation, in which case an out-of-range value
+    will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
+
+  //! Take a channel of the \c iFrames object as inputs to the filter and write outputs to the \c oFrames object.
+  /*!
+    The \c iFrames object reference is returned.  Each channel
+    argument must be less than the number of channels in the
+    corresponding StkFrames argument (the first channel is specified
+    by 0).  However, range checking is only performed if _STK_DEBUG_
+    is defined during compilation, in which case an out-of-range value
+    will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0, unsigned int oChannel = 0 );
+
+ protected:
+
+  virtual void sampleRateChanged( StkFloat newRate, StkFloat oldRate );
+};
+
+inline StkFloat TwoPole :: tick( StkFloat input )
+{
+  inputs_[0] = gain_ * input;
+  lastFrame_[0] = b_[0] * inputs_[0] - a_[1] * outputs_[1] - a_[2] * outputs_[2];
+  outputs_[2] = outputs_[1];
+  outputs_[1] = lastFrame_[0];
+
+  return lastFrame_[0];
+}
+
+inline StkFrames& TwoPole :: tick( StkFrames& frames, unsigned int channel )
+{
+#if defined(_STK_DEBUG_)
+  if ( channel >= frames.channels() ) {
+    errorString_ << "TwoPole::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *samples = &frames[channel];
+  unsigned int hop = frames.channels();
+  for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
+    inputs_[0] = gain_ * *samples;
+    *samples = b_[0] * inputs_[0] - a_[1] * outputs_[1] - a_[2] * outputs_[2];
+    outputs_[2] = outputs_[1];
+    outputs_[1] = *samples;
+  }
+
+  lastFrame_[0] = outputs_[1];
+  return frames;
+}
+
+inline StkFrames& TwoPole :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iChannel, unsigned int oChannel )
+{
+#if defined(_STK_DEBUG_)
+  if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
+    errorString_ << "TwoPole::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *iSamples = &iFrames[iChannel];
+  StkFloat *oSamples = &oFrames[oChannel];
+  unsigned int iHop = iFrames.channels(), oHop = oFrames.channels();
+  for ( unsigned int i=0; i<iFrames.frames(); i++, iSamples += iHop, oSamples += oHop ) {
+    inputs_[0] = gain_ * *iSamples;
+    *oSamples = b_[0] * inputs_[0] - a_[1] * outputs_[1] - a_[2] * outputs_[2];
+    outputs_[2] = outputs_[1];
+    outputs_[1] = *oSamples;
+  }
+
+  lastFrame_[0] = outputs_[1];
+  return iFrames;
+}
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/TwoZero.h b/lib/MoMu-STK-1.0.0/include/TwoZero.h
new file mode 100644 (file)
index 0000000..443fb85
--- /dev/null
@@ -0,0 +1,147 @@
+#ifndef STK_TWOZERO_H
+#define STK_TWOZERO_H
+
+#include "Filter.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class TwoZero
+    \brief STK two-zero filter class.
+
+    This class implements a two-zero digital filter.  A method is
+    provided for creating a "notch" in the frequency response while
+    maintaining a constant filter gain.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class TwoZero : public Filter
+{
+ public:
+  //! Default constructor creates a second-order pass-through filter.
+  TwoZero();
+
+  //! Class destructor.
+  ~TwoZero();
+
+  //! A function to enable/disable the automatic updating of class data when the STK sample rate changes.
+  void ignoreSampleRateChange( bool ignore = true ) { ignoreSampleRateChange_ = ignore; };
+
+  //! Set the b[0] coefficient value.
+  void setB0( StkFloat b0 ) { b_[0] = b0; };
+
+  //! Set the b[1] coefficient value.
+  void setB1( StkFloat b1 ) { b_[1] = b1; };
+
+  //! Set the b[2] coefficient value.
+  void setB2( StkFloat b2 ) { b_[2] = b2; };
+
+  //! Set all filter coefficients.
+  void setCoefficients( StkFloat b0, StkFloat b1, StkFloat b2, bool clearState = false );
+
+  //! Sets the filter coefficients for a "notch" at \e frequency (in Hz).
+  /*!
+    This method determines the filter coefficients corresponding to
+    two complex-conjugate zeros with the given \e frequency (in Hz)
+    and \e radius from the z-plane origin.  The coefficients are then
+    normalized to produce a maximum filter gain of one (independent of
+    the filter \e gain parameter).  The resulting filter frequency
+    response has a "notch" or anti-resonance at the given \e
+    frequency.  The closer the zeros are to the unit-circle (\e radius
+    close to or equal to one), the narrower the resulting notch width.
+  */
+  void setNotch( StkFloat frequency, StkFloat radius );
+
+  //! Return the last computed output value.
+  StkFloat lastOut( void ) const { return lastFrame_[0]; };
+
+  //! Input one sample to the filter and return one output.
+  StkFloat tick( StkFloat input );
+
+  //! Take a channel of the StkFrames object as inputs to the filter and replace with corresponding outputs.
+  /*!
+    The StkFrames argument reference is returned.  The \c channel
+    argument must be less than the number of channels in the
+    StkFrames argument (the first channel is specified by 0).
+    However, range checking is only performed if _STK_DEBUG_ is
+    defined during compilation, in which case an out-of-range value
+    will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
+
+  //! Take a channel of the \c iFrames object as inputs to the filter and write outputs to the \c oFrames object.
+  /*!
+    The \c iFrames object reference is returned.  Each channel
+    argument must be less than the number of channels in the
+    corresponding StkFrames argument (the first channel is specified
+    by 0).  However, range checking is only performed if _STK_DEBUG_
+    is defined during compilation, in which case an out-of-range value
+    will trigger an StkError exception.
+  */
+  StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0, unsigned int oChannel = 0 );
+
+ protected:
+
+  void sampleRateChanged( StkFloat newRate, StkFloat oldRate );
+};
+
+inline StkFloat TwoZero :: tick( StkFloat input )
+{
+  inputs_[0] = gain_ * input;
+  lastFrame_[0] = b_[2] * inputs_[2] + b_[1] * inputs_[1] + b_[0] * inputs_[0];
+  inputs_[2] = inputs_[1];
+  inputs_[1] = inputs_[0];
+
+  return lastFrame_[0];
+}
+
+inline StkFrames& TwoZero :: tick( StkFrames& frames, unsigned int channel )
+{
+#if defined(_STK_DEBUG_)
+  if ( channel >= frames.channels() ) {
+    errorString_ << "TwoZero::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *samples = &frames[channel];
+  unsigned int hop = frames.channels();
+  for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
+    inputs_[0] = gain_ * *samples;
+    *samples = b_[2] * inputs_[2] + b_[1] * inputs_[1] + b_[0] * inputs_[0];
+    inputs_[2] = inputs_[1];
+    inputs_[1] = inputs_[0];
+  }
+
+  lastFrame_[0] = *(samples-hop);
+  return frames;
+}
+
+inline StkFrames& TwoZero :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iChannel, unsigned int oChannel )
+{
+#if defined(_STK_DEBUG_)
+  if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
+    errorString_ << "TwoZero::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *iSamples = &iFrames[iChannel];
+  StkFloat *oSamples = &oFrames[oChannel];
+  unsigned int iHop = iFrames.channels(), oHop = oFrames.channels();
+  for ( unsigned int i=0; i<iFrames.frames(); i++, iSamples += iHop, oSamples += oHop ) {
+    inputs_[0] = gain_ * *iSamples;
+    *oSamples = b_[2] * inputs_[2] + b_[1] * inputs_[1] + b_[0] * inputs_[0];
+    inputs_[2] = inputs_[1];
+    inputs_[1] = inputs_[0];
+  }
+
+  lastFrame_[0] = *(oSamples-oHop);
+  return iFrames;
+}
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/Vector3D.h b/lib/MoMu-STK-1.0.0/include/Vector3D.h
new file mode 100644 (file)
index 0000000..574cc2a
--- /dev/null
@@ -0,0 +1,68 @@
+#ifndef STK_VECTOR3D_H
+#define STK_VECTOR3D_H
+
+#include "Stk.h"
+#include <cmath>
+
+namespace stk {
+
+/***************************************************/
+/*! \class Vector3D
+    \brief STK 3D vector class.
+
+    This class implements a three-dimensional vector.
+
+    by Perry R. Cook, 1995 - 2010.
+*/
+/***************************************************/
+
+class Vector3D : public Stk
+{
+
+public:
+  //! Default constructor taking optional initial X, Y, and Z values.
+  Vector3D( StkFloat x = 0.0, StkFloat y = 0.0, StkFloat z = 0.0 ) { setXYZ( x, y, z ); };
+
+  //! Get the current X value.
+  StkFloat getX( void ) { return X_; };
+
+  //! Get the current Y value.
+  StkFloat getY( void ) { return Y_; };
+
+  //! Get the current Z value.
+  StkFloat getZ( void ) { return Z_; };
+
+  //! Calculate the vector length.
+  StkFloat getLength( void );
+
+  //! Set the X, Y, and Z values simultaniously.
+  void setXYZ( StkFloat x, StkFloat y, StkFloat z ) { X_ = x; Y_ = y; Z_ = z; };
+
+  //! Set the X value.
+  void setX( StkFloat x ) { X_ = x; };
+
+  //! Set the Y value.
+  void setY( StkFloat y ) { Y_ = y; };
+
+  //! Set the Z value.
+  void setZ( StkFloat z ) { Z_ = z; };
+
+protected:
+  StkFloat X_;
+  StkFloat Y_;
+  StkFloat Z_;
+};
+
+inline StkFloat Vector3D :: getLength( void )
+{
+  StkFloat temp;
+  temp = X_ * X_;
+  temp += Y_ * Y_;
+  temp += Z_ * Z_;
+  temp = sqrt( temp );
+  return temp;
+}
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/VoicForm.h b/lib/MoMu-STK-1.0.0/include/VoicForm.h
new file mode 100644 (file)
index 0000000..3617c71
--- /dev/null
@@ -0,0 +1,124 @@
+#ifndef STK_VOICFORM_H
+#define STK_VOICFORM_H
+
+#include "Instrmnt.h"
+#include "Envelope.h"
+#include "Noise.h"
+#include "SingWave.h"
+#include "FormSwep.h"
+#include "OnePole.h"
+#include "OneZero.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class VoicForm
+    \brief Four formant synthesis instrument.
+
+    This instrument contains an excitation singing
+    wavetable (looping wave with random and
+    periodic vibrato, smoothing on frequency,
+    etc.), excitation noise, and four sweepable
+    complex resonances.
+
+    Measured formant data is included, and enough
+    data is there to support either parallel or
+    cascade synthesis.  In the floating point case
+    cascade synthesis is the most natural so
+    that's what you'll find here.
+
+    Control Change Numbers: 
+       - Voiced/Unvoiced Mix = 2
+       - Vowel/Phoneme Selection = 4
+       - Vibrato Frequency = 11
+       - Vibrato Gain = 1
+       - Loudness (Spectral Tilt) = 128
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class VoicForm : public Instrmnt
+{
+  public:
+  //! Class constructor.
+  /*!
+    An StkError will be thrown if the rawwave path is incorrectly set.
+  */
+  VoicForm( void );
+
+  //! Class destructor.
+  ~VoicForm( void );
+
+  //! Reset and clear all internal state.
+  void clear( void );
+
+  //! Set instrument parameters for a particular frequency.
+  void setFrequency( StkFloat frequency );
+
+  //! Set instrument parameters for the given phoneme.  Returns false if phoneme not found.
+  bool setPhoneme( const char* phoneme );
+
+  //! Set the voiced component gain.
+  void setVoiced( StkFloat vGain ) { voiced_->setGainTarget(vGain); };
+
+  //! Set the unvoiced component gain.
+  void setUnVoiced( StkFloat nGain ) { noiseEnv_.setTarget(nGain); };
+
+  //! Set the sweep rate for a particular formant filter (0-3).
+  void setFilterSweepRate( unsigned int whichOne, StkFloat rate );
+
+  //! Set voiced component pitch sweep rate.
+  void setPitchSweepRate( StkFloat rate ) { voiced_->setSweepRate(rate); };
+
+  //! Start the voice.
+  void speak( void ) { voiced_->noteOn(); };
+
+  //! Stop the voice.
+  void quiet( void );
+
+  //! Start a note with the given frequency and amplitude.
+  void noteOn( StkFloat frequency, StkFloat amplitude );
+
+  //! Stop a note with the given amplitude (speed of decay).
+  void noteOff( StkFloat amplitude ) { this->quiet(); };
+
+  //! Perform the control change specified by \e number and \e value (0.0 - 128.0).
+  void controlChange( int number, StkFloat value );
+
+  //! Compute and return one output sample.
+  StkFloat tick( unsigned int channel = 0 );
+
+protected:
+
+  SingWave *voiced_;
+  Noise    noise_;
+  Envelope noiseEnv_;
+  FormSwep filters_[4];
+  OnePole  onepole_;
+  OneZero  onezero_;
+
+};
+
+inline StkFloat VoicForm :: tick( unsigned int )
+{
+  StkFloat temp;
+  temp = onepole_.tick( onezero_.tick( voiced_->tick() ) );
+  temp += noiseEnv_.tick() * noise_.tick();
+  lastFrame_[0] = filters_[0].tick(temp);
+  lastFrame_[0] += filters_[1].tick(temp);
+  lastFrame_[0] += filters_[2].tick(temp);
+  lastFrame_[0] += filters_[3].tick(temp);
+  /*
+    temp  += noiseEnv_.tick() * noise_.tick();
+    lastFrame_[0]  = filters_[0].tick(temp);
+    lastFrame_[0]  = filters_[1].tick(lastFrame_[0]);
+    lastFrame_[0]  = filters_[2].tick(lastFrame_[0]);
+    lastFrame_[0]  = filters_[3].tick(lastFrame_[0]);
+  */
+  return lastFrame_[0];
+}
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/Voicer.h b/lib/MoMu-STK-1.0.0/include/Voicer.h
new file mode 100644 (file)
index 0000000..267b18b
--- /dev/null
@@ -0,0 +1,219 @@
+#ifndef STK_VOICER_H
+#define STK_VOICER_H
+
+#include "Instrmnt.h"
+#include <vector>
+
+namespace stk {
+
+/***************************************************/
+/*! \class Voicer
+    \brief STK voice manager class.
+
+    This class can be used to manage a group of STK instrument
+    classes.  Individual voices can be controlled via unique note
+    tags.  Instrument groups can be controlled by group number.
+
+    A previously constructed STK instrument class is linked with a
+    voice manager using the addInstrument() function.  An optional
+    group number argument can be specified to the addInstrument()
+    function as well (default group = 0).  The voice manager does not
+    delete any instrument instances ... it is the responsibility of
+    the user to allocate and deallocate all instruments.
+
+    The tick() function returns the mix of all sounding voices.  Each
+    noteOn returns a unique tag (credits to the NeXT MusicKit), so you
+    can send control changes to specific voices within an ensemble.
+    Alternately, control changes can be sent to all voices in a given
+    group.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class Voicer : public Stk
+{
+ public:
+  //! Class constructor taking an optional note decay time (in seconds).
+  Voicer( StkFloat decayTime = 0.2 );
+
+  //! Add an instrument with an optional group number to the voice manager.
+  /*!
+    A set of instruments can be grouped by group number and
+    controlled via the functions that take a group number argument.
+  */
+  void addInstrument( Instrmnt *instrument, int group=0 );
+
+  //! Remove the given instrument pointer from the voice manager's control.
+  /*!
+    It is important that any instruments which are to be deleted by
+    the user while the voice manager is running be first removed from
+    the manager's control via this function!!
+  */
+  void removeInstrument( Instrmnt *instrument );
+
+  //! Initiate a noteOn event with the given note number and amplitude and return a unique note tag.
+  /*!
+    Send the noteOn message to the first available unused voice.
+    If all voices are sounding, the oldest voice is interrupted and
+    sent the noteOn message.  If the optional group argument is
+    non-zero, only voices in that group are used.  If no voices are
+    found for a specified non-zero group value, the function returns
+    -1.  The amplitude value should be in the range 0.0 - 128.0.
+  */
+  long noteOn( StkFloat noteNumber, StkFloat amplitude, int group=0 );
+
+  //! Send a noteOff to all voices having the given noteNumber and optional group (default group = 0).
+  /*!
+    The amplitude value should be in the range 0.0 - 128.0.
+  */
+  void noteOff( StkFloat noteNumber, StkFloat amplitude, int group=0 );
+
+  //! Send a noteOff to the voice with the given note tag.
+  /*!
+    The amplitude value should be in the range 0.0 - 128.0.
+  */
+  void noteOff( long tag, StkFloat amplitude );
+
+  //! Send a frequency update message to all voices assigned to the optional group argument (default group = 0).
+  /*!
+    The \e noteNumber argument corresponds to a MIDI note number, though it is a floating-point value and can range beyond the normal 0-127 range.
+  */
+  void setFrequency( StkFloat noteNumber, int group=0 );
+
+  //! Send a frequency update message to the voice with the given note tag.
+  /*!
+    The \e noteNumber argument corresponds to a MIDI note number, though it is a floating-point value and can range beyond the normal 0-127 range.
+  */
+  void setFrequency( long tag, StkFloat noteNumber );
+
+  //! Send a pitchBend message to all voices assigned to the optional group argument (default group = 0).
+  void pitchBend( StkFloat value, int group=0 );
+
+  //! Send a pitchBend message to the voice with the given note tag.
+  void pitchBend( long tag, StkFloat value );
+
+  //! Send a controlChange to all instruments assigned to the optional group argument (default group = 0).
+  void controlChange( int number, StkFloat value, int group=0 );
+
+  //! Send a controlChange to the voice with the given note tag.
+  void controlChange( long tag, int number, StkFloat value );
+
+  //! Send a noteOff message to all existing voices.
+  void silence( void );
+
+  //! Return the current number of output channels.
+  unsigned int channelsOut( void ) const { return lastFrame_.channels(); };
+
+  //! Return an StkFrames reference to the last output sample frame.
+  const StkFrames& lastFrame( void ) const { return lastFrame_; };
+
+  //! Return the specified channel value of the last computed frame.
+  /*!
+    The \c channel argument must be less than the number of output
+    channels, which can be determined with the channelsOut() function
+    (the first channel is specified by 0).  However, range checking is
+    only performed if _STK_DEBUG_ is defined during compilation, in
+    which case an out-of-range value will trigger an StkError
+    exception. \sa lastFrame()
+  */
+  StkFloat lastOut( unsigned int channel = 0 );
+
+  //! Mix one sample frame of all sounding voices and return the specified \c channel value.
+  /*!
+    The \c channel argument must be less than the number of output
+    channels, which can be determined with the channelsOut() function
+    (the first channel is specified by 0).  However, range checking is
+    only performed if _STK_DEBUG_ is defined during compilation, in
+    which case an out-of-range value will trigger an StkError
+    exception.
+  */
+  StkFloat tick( unsigned int channel = 0 );
+
+  //! Fill the StkFrames argument with computed frames and return the same reference.
+  /*!
+    The number of channels in the StkFrames argument must equal
+    the number of channels in the file data.  However, this is only
+    checked if _STK_DEBUG_ is defined during compilation, in which
+    case an incompatibility will trigger an StkError exception.  If no
+    file data is loaded, the function does nothing (a warning will be
+    issued if _STK_DEBUG_ is defined during compilation).
+  */
+  StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
+
+ protected:
+
+  struct Voice {
+    Instrmnt *instrument;
+    long tag;
+    StkFloat noteNumber;
+    StkFloat frequency;
+    int sounding;
+    int group;
+
+    // Default constructor.
+    Voice()
+      :instrument(0), tag(0), noteNumber(-1.0), frequency(0.0), sounding(0), group(0) {}
+  };
+
+  std::vector<Voice> voices_;
+  long tags_;
+  int muteTime_;
+  StkFrames lastFrame_;
+};
+
+inline StkFloat Voicer :: lastOut( unsigned int channel )
+{
+#if defined(_STK_DEBUG_)
+  if ( channel >= lastFrame_.channels() ) {
+    errorString_ << "Voicer::lastOut(): channel argument is invalid!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  return lastFrame_[channel];
+}
+
+
+inline StkFloat Voicer :: tick( unsigned int channel )
+{
+  unsigned int j;
+  for ( j=0; j<lastFrame_.channels(); j++ ) lastFrame_[j] = 0.0;
+  for ( unsigned int i=0; i<voices_.size(); i++ ) {
+    if ( voices_[i].sounding != 0 ) {
+      voices_[i].instrument->tick();
+      for ( j=0; j<voices_[i].instrument->channelsOut(); j++ ) lastFrame_[j] += voices_[i].instrument->lastOut( j );
+    }
+    if ( voices_[i].sounding < 0 )
+      voices_[i].sounding++;
+    if ( voices_[i].sounding == 0 )
+      voices_[i].noteNumber = -1;
+  }
+
+  return lastFrame_[channel];
+}
+
+inline StkFrames& Voicer :: tick( StkFrames& frames, unsigned int channel )
+{
+  unsigned int nChannels = lastFrame_.channels();
+#if defined(_STK_DEBUG_)
+  if ( channel > frames.channels() - nChannels ) {
+    errorString_ << "Voicer::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *samples = &frames[channel];
+  unsigned int j, hop = frames.channels() - nChannels;
+  for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
+    tick();
+    for ( j=0; j<nChannels; j++ )
+      *samples++ = lastFrame_[j];
+  }
+
+  return frames;
+}
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/Whistle.h b/lib/MoMu-STK-1.0.0/include/Whistle.h
new file mode 100644 (file)
index 0000000..965eaa7
--- /dev/null
@@ -0,0 +1,91 @@
+#ifndef STK_WHISTLE_H
+#define STK_WHISTLE_H
+
+#include "Instrmnt.h"
+#include "Sphere.h"
+#include "Vector3D.h"
+#include "Noise.h"
+#include "SineWave.h"
+#include "OnePole.h"
+#include "Envelope.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class Whistle
+    \brief STK police/referee whistle instrument class.
+
+    This class implements a hybrid physical/spectral
+    model of a police whistle (a la Cook).
+
+    Control Change Numbers: 
+       - Noise Gain = 4
+       - Fipple Modulation Frequency = 11
+       - Fipple Modulation Gain = 1
+       - Blowing Frequency Modulation = 2
+       - Volume = 128
+
+    by Perry R. Cook  1996 - 2010.
+*/
+/***************************************************/
+
+class Whistle : public Instrmnt
+{
+public:
+  //! Class constructor.
+  /*!
+    An StkError will be thrown if the rawwave path is incorrectly set.
+  */
+  Whistle( void );
+
+  //! Class destructor.
+  ~Whistle( void );
+
+  //! Reset and clear all internal state.
+  void clear( void );
+
+  //! Set instrument parameters for a particular frequency.
+  void setFrequency( StkFloat frequency );
+
+  //! Apply breath velocity to instrument with given amplitude and rate of increase.
+  void startBlowing( StkFloat amplitude, StkFloat rate );
+
+  //! Decrease breath velocity with given rate of decrease.
+  void stopBlowing( StkFloat rate );
+
+  //! Start a note with the given frequency and amplitude.
+  void noteOn( StkFloat frequency, StkFloat amplitude );
+
+  //! Stop a note with the given amplitude (speed of decay).
+  void noteOff( StkFloat amplitude );
+
+  //! Perform the control change specified by \e number and \e value (0.0 - 128.0).
+  void controlChange( int number, StkFloat value );
+
+  //! Compute and return one output sample.
+  StkFloat tick( unsigned int channel = 0 );
+
+protected:
+
+       Vector3D *tempVectorP_;
+  Vector3D tempVector_;
+  OnePole onepole_;
+  Noise noise_;
+       Envelope envelope_;
+  Sphere can_;           // Declare a Spherical "can".
+  Sphere pea_, bumper_;  // One spherical "pea", and a spherical "bumper".
+
+  SineWave sine_;
+
+  StkFloat baseFrequency_;
+  StkFloat noiseGain_;
+  StkFloat fippleFreqMod_;
+       StkFloat fippleGainMod_;
+       StkFloat blowFreqMod_;
+       StkFloat tickSize_;
+       StkFloat canLoss_;
+       int subSample_, subSampCount_;
+};
+
+} // stk namespace
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/Wurley.h b/lib/MoMu-STK-1.0.0/include/Wurley.h
new file mode 100644 (file)
index 0000000..dead6d7
--- /dev/null
@@ -0,0 +1,91 @@
+#ifndef STK_WURLEY_H
+#define STK_WURLEY_H
+
+#include "FM.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class Wurley
+    \brief STK Wurlitzer electric piano FM
+           synthesis instrument.
+
+    This class implements two simple FM Pairs
+    summed together, also referred to as algorithm
+    5 of the TX81Z.
+
+    \code
+    Algorithm 5 is :  4->3--\
+                             + --> Out
+                      2->1--/
+    \endcode
+
+    Control Change Numbers: 
+       - Modulator Index One = 2
+       - Crossfade of Outputs = 4
+       - LFO Speed = 11
+       - LFO Depth = 1
+       - ADSR 2 & 4 Target = 128
+
+    The basic Chowning/Stanford FM patent expired
+    in 1995, but there exist follow-on patents,
+    mostly assigned to Yamaha.  If you are of the
+    type who should worry about this (making
+    money) worry away.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class Wurley : public FM
+{
+ public:
+  //! Class constructor.
+  /*!
+    An StkError will be thrown if the rawwave path is incorrectly set.
+  */
+  Wurley( void );
+
+  //! Class destructor.
+  ~Wurley( void );
+
+  //! Set instrument parameters for a particular frequency.
+  void setFrequency( StkFloat frequency );
+
+  //! Start a note with the given frequency and amplitude.
+  void noteOn( StkFloat frequency, StkFloat amplitude );
+
+  //! Compute and return one output sample.
+  StkFloat tick( unsigned int channel = 0 );
+
+ protected:
+
+};
+
+inline StkFloat Wurley :: tick( unsigned int )
+{
+  StkFloat temp, temp2;
+
+  temp = gains_[1] * adsr_[1]->tick() * waves_[1]->tick();
+  temp = temp * control1_;
+
+  waves_[0]->addPhaseOffset( temp );
+  waves_[3]->addPhaseOffset( twozero_.lastOut() );
+  temp = gains_[3] * adsr_[3]->tick() * waves_[3]->tick();
+  twozero_.tick(temp);
+
+  waves_[2]->addPhaseOffset( temp );
+  temp = ( 1.0 - (control2_ * 0.5)) * gains_[0] * adsr_[0]->tick() * waves_[0]->tick();
+  temp += control2_ * 0.5 * gains_[2] * adsr_[2]->tick() * waves_[2]->tick();
+
+  // Calculate amplitude modulation and apply it to output.
+  temp2 = vibrato_.tick() * modDepth_;
+  temp = temp * (1.0 + temp2);
+    
+  lastFrame_[0] = temp * 0.5;
+  return lastFrame_[0];
+}
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/WvIn.h b/lib/MoMu-STK-1.0.0/include/WvIn.h
new file mode 100644 (file)
index 0000000..7baab99
--- /dev/null
@@ -0,0 +1,46 @@
+#ifndef STK_WVIN_H
+#define STK_WVIN_H
+
+#include "Stk.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class WvIn
+    \brief STK audio input abstract base class.
+
+    This class provides common functionality for a variety of audio
+    data input subclasses.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class WvIn : public Stk
+{
+public:
+  //! Return the number of audio channels in the data or stream.
+  unsigned int channelsOut( void ) const { return data_.channels(); };
+
+  //! Return an StkFrames reference to the last computed sample frame.
+  /*!
+    If no file data is loaded, an empty container is returned.
+   */
+  const StkFrames& lastFrame( void ) const { return lastFrame_; };
+
+  //! Compute one sample frame and return the specified \c channel value.
+  virtual StkFloat tick( unsigned int channel = 0 ) = 0;
+
+  //! Fill the StkFrames argument with computed frames and return the same reference.
+  virtual StkFrames& tick( StkFrames& frames ) = 0;
+
+protected:
+
+  StkFrames data_;
+  StkFrames lastFrame_;
+
+};
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/include/WvOut.h b/lib/MoMu-STK-1.0.0/include/WvOut.h
new file mode 100644 (file)
index 0000000..f779308
--- /dev/null
@@ -0,0 +1,85 @@
+#ifndef STK_WVOUT_H
+#define STK_WVOUT_H
+
+#include "Stk.h"
+
+namespace stk {
+
+/***************************************************/
+/*! \class WvOut
+    \brief STK audio output abstract base class.
+
+    This class provides common functionality for a variety of audio
+    data output subclasses.
+
+    Currently, WvOut is non-interpolating and the output rate is
+    always Stk::sampleRate().
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+class WvOut : public Stk
+{
+ public:
+
+  //! Default constructor.
+  WvOut( void ) : frameCounter_(0), clipping_(false) {};
+
+  //! Return the number of sample frames output.
+  unsigned long getFrameCount( void ) const { return frameCounter_; };
+
+  //! Return the number of seconds of data output.
+  StkFloat getTime( void ) const { return (StkFloat) frameCounter_ / Stk::sampleRate(); };
+
+  //! Returns \c true if clipping has been detected during output since instantiation or the last reset.
+  bool clipStatus( void ) { return clipping_; };
+
+  //! Reset the clipping status to \c false.
+  void resetClipStatus( void ) { clipping_ = false; };
+
+  //! Output a single sample to all channels in a sample frame.
+  /*!
+    An StkError is thrown if an output error occurs.
+  */
+  virtual void tick( const StkFloat sample ) = 0;
+
+  //! Output the StkFrames data.
+  virtual void tick( const StkFrames& frames ) = 0;
+
+ protected:
+
+  // Check for sample clipping and clamp.
+  StkFloat& clipTest( StkFloat& sample );
+
+  StkFrames data_;
+  unsigned long frameCounter_;
+  bool clipping_;
+
+};
+
+inline StkFloat& WvOut :: clipTest( StkFloat& sample )
+{
+  bool clip = false;
+  if ( sample > 1.0 ) {
+    sample = 1.0;
+    clip = true;
+  }
+  else if ( sample < -1.0 ) {
+    sample = -1.0;
+    clip = true;
+  }
+
+  if ( clip == true && clipping_ == false ) {
+    // First occurrence of clipping since instantiation or reset.
+    clipping_ = true;
+    errorString_ << "WvOut: data value(s) outside +-1.0 detected ... clamping at outer bound!";
+    handleError( StkError::WARNING );
+  }
+
+  return sample;
+}
+
+} // stk namespace
+
+#endif
diff --git a/lib/MoMu-STK-1.0.0/rawwaves/ahh.raw b/lib/MoMu-STK-1.0.0/rawwaves/ahh.raw
new file mode 100644 (file)
index 0000000..dda5f55
Binary files /dev/null and b/lib/MoMu-STK-1.0.0/rawwaves/ahh.raw differ
diff --git a/lib/MoMu-STK-1.0.0/rawwaves/bassdrum.raw b/lib/MoMu-STK-1.0.0/rawwaves/bassdrum.raw
new file mode 100644 (file)
index 0000000..16b1ece
Binary files /dev/null and b/lib/MoMu-STK-1.0.0/rawwaves/bassdrum.raw differ
diff --git a/lib/MoMu-STK-1.0.0/rawwaves/britestk.raw b/lib/MoMu-STK-1.0.0/rawwaves/britestk.raw
new file mode 100644 (file)
index 0000000..4bf9ba6
Binary files /dev/null and b/lib/MoMu-STK-1.0.0/rawwaves/britestk.raw differ
diff --git a/lib/MoMu-STK-1.0.0/rawwaves/cowbell1.raw b/lib/MoMu-STK-1.0.0/rawwaves/cowbell1.raw
new file mode 100644 (file)
index 0000000..4cd641f
Binary files /dev/null and b/lib/MoMu-STK-1.0.0/rawwaves/cowbell1.raw differ
diff --git a/lib/MoMu-STK-1.0.0/rawwaves/crashcym.raw b/lib/MoMu-STK-1.0.0/rawwaves/crashcym.raw
new file mode 100644 (file)
index 0000000..21318b2
Binary files /dev/null and b/lib/MoMu-STK-1.0.0/rawwaves/crashcym.raw differ
diff --git a/lib/MoMu-STK-1.0.0/rawwaves/dope.raw b/lib/MoMu-STK-1.0.0/rawwaves/dope.raw
new file mode 100644 (file)
index 0000000..6a7a1ff
Binary files /dev/null and b/lib/MoMu-STK-1.0.0/rawwaves/dope.raw differ
diff --git a/lib/MoMu-STK-1.0.0/rawwaves/eee.raw b/lib/MoMu-STK-1.0.0/rawwaves/eee.raw
new file mode 100644 (file)
index 0000000..d3888db
Binary files /dev/null and b/lib/MoMu-STK-1.0.0/rawwaves/eee.raw differ
diff --git a/lib/MoMu-STK-1.0.0/rawwaves/fwavblnk.raw b/lib/MoMu-STK-1.0.0/rawwaves/fwavblnk.raw
new file mode 100644 (file)
index 0000000..14da074
Binary files /dev/null and b/lib/MoMu-STK-1.0.0/rawwaves/fwavblnk.raw differ
diff --git a/lib/MoMu-STK-1.0.0/rawwaves/halfwave.raw b/lib/MoMu-STK-1.0.0/rawwaves/halfwave.raw
new file mode 100644 (file)
index 0000000..b34639b
Binary files /dev/null and b/lib/MoMu-STK-1.0.0/rawwaves/halfwave.raw differ
diff --git a/lib/MoMu-STK-1.0.0/rawwaves/hihatcym.raw b/lib/MoMu-STK-1.0.0/rawwaves/hihatcym.raw
new file mode 100644 (file)
index 0000000..f61389e
Binary files /dev/null and b/lib/MoMu-STK-1.0.0/rawwaves/hihatcym.raw differ
diff --git a/lib/MoMu-STK-1.0.0/rawwaves/impuls10.raw b/lib/MoMu-STK-1.0.0/rawwaves/impuls10.raw
new file mode 100644 (file)
index 0000000..e18689d
Binary files /dev/null and b/lib/MoMu-STK-1.0.0/rawwaves/impuls10.raw differ
diff --git a/lib/MoMu-STK-1.0.0/rawwaves/impuls20.raw b/lib/MoMu-STK-1.0.0/rawwaves/impuls20.raw
new file mode 100644 (file)
index 0000000..9d89aec
Binary files /dev/null and b/lib/MoMu-STK-1.0.0/rawwaves/impuls20.raw differ
diff --git a/lib/MoMu-STK-1.0.0/rawwaves/impuls40.raw b/lib/MoMu-STK-1.0.0/rawwaves/impuls40.raw
new file mode 100644 (file)
index 0000000..9a3619b
Binary files /dev/null and b/lib/MoMu-STK-1.0.0/rawwaves/impuls40.raw differ
diff --git a/lib/MoMu-STK-1.0.0/rawwaves/makefunc.c b/lib/MoMu-STK-1.0.0/rawwaves/makefunc.c
new file mode 100644 (file)
index 0000000..0068dce
--- /dev/null
@@ -0,0 +1,54 @@
+/**********************************************/
+/**  Utility to make various functions       **/
+/**  like exponential and log gain curves.   **/
+/**                                          **/
+/**  Included here:                          **/
+/**  Yamaha TX81Z curves for master gain,    **/
+/**  Envelope Rates (in normalized units),   **/
+/**  envelope sustain level, and more....    **/
+/**********************************************/
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+void main1() //MoMu modified
+{
+  int i;
+  double data[128];
+
+  /*************** TX81Z Master Gain *************/    
+  for (i=0;i<100;i++)   {
+    data[i] = pow(2.0,-(99-i)/10.0);
+  }
+  data[0] = 0.0;
+  printf("double __FM4Op_gains[99] = {");
+  for (i=0;i<100;i++)  {
+    if (i%8 == 0) printf("\n");
+    printf("%lf,",data[i]);
+  }
+  printf("};\n");
+  /*************** TX81Z Sustain Level ***********/    
+  for (i=0;i<16;i++)   {
+    data[i] = pow(2.0,-(15-i)/2.0);
+  }
+  data[0] = 0.0;
+  printf("double __FM4Op_susLevels[16] = {");
+  for (i=0;i<16;i++)  {
+    if (i%8 == 0) printf("\n");
+    printf("%lf,",data[i]);
+  }
+  printf("};\n");
+  /******************  Attack Rate ***************/    
+  for (i=0;i<32;i++)   {
+    data[i] = 6.0 * pow(5.7,-(i-1)/5.0);
+  }
+  printf("double __FM4Op_attTimes[16] = {");
+  for (i=0;i<32;i++)  {
+    if (i%8 == 0) printf("\n");
+    printf("%lf,",data[i]);
+  }
+  printf("};\n");
+  exit(1);
+}
+
diff --git a/lib/MoMu-STK-1.0.0/rawwaves/makemidi.c b/lib/MoMu-STK-1.0.0/rawwaves/makemidi.c
new file mode 100644 (file)
index 0000000..cf82b7d
--- /dev/null
@@ -0,0 +1,33 @@
+/**********************************************/
+/**  Utility to make various functions       **/
+/**  like exponential and log gain curves.   **/
+/**  Specifically for direct MIDI parameter  **/           
+/**  conversions.                            **/
+/**  Included here:                          **/
+/**  A440 Referenced Equal Tempered Pitches  **/
+/**  as a function of MIDI note number.      **/
+/**                                          **/
+/**********************************************/
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+void main2() //MoMu modified
+{
+  int i;
+  double temp;
+  //double data[128];
+
+  /********* Pitch as fn. of MIDI Note **********/    
+    
+  printf("double __MIDI_To_Pitch[128] = {");
+  for (i=0;i<128;i++)  {
+    if (i%8 == 0) printf("\n");
+    temp = 220.0 * pow(2.0,((double) i - 57) / 12.0);
+    printf("%.2lf,",temp);
+  }
+  printf("};\n");
+  exit(1);
+}
+
diff --git a/lib/MoMu-STK-1.0.0/rawwaves/makewavs.c b/lib/MoMu-STK-1.0.0/rawwaves/makewavs.c
new file mode 100644 (file)
index 0000000..71863d0
--- /dev/null
@@ -0,0 +1,116 @@
+/**********************************************/
+/**    Utility to make various flavors of    **/
+/**    sine wave (rectified, etc), and       **/
+/**    other commonly needed waveforms, like **/
+/**    triangles, ramps, etc.                **/
+/**    The files generated are all 16 bit    **/
+/**    linear signed integer, of length      **/
+/**    as defined by LENGTH below            **/
+/**********************************************/
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define LENGTH 256
+#define PI 3.14159265358979323846
+
+void main3() //MoMu modified
+{
+  int i,j;
+  double temp;
+  short data[LENGTH + 2];
+  FILE *fd;
+
+  ///////////  Yer Basic TX81Z Waves, Including Sine ///////////  
+  fd = fopen("halfwave.raw","wb");
+  for (i=0;i<LENGTH/2;i++)
+    data[i] = 32767 * sin(i * 2 * PI / (double) LENGTH);
+  for (i=LENGTH/2;i<LENGTH;i++) 
+    data[i] = 0;
+  fwrite(&data,2,LENGTH,fd);
+  fclose(fd);
+    
+  fd = fopen("sinewave.raw","wb");
+  for (i=LENGTH/2;i<LENGTH;i++)
+    data[i] = 32767 * sin(i * 2 * PI / (double) LENGTH);
+  fwrite(&data,2,LENGTH,fd);
+  fclose(fd);
+    
+  fd = fopen("sineblnk.raw","wb");
+  for (i=0;i<LENGTH/2;i++)
+    data[i] = data[2*i];
+  for (i=LENGTH/2;i<LENGTH;i++) 
+    data[i] = 0;
+  fwrite(&data,2,LENGTH,fd);
+  fclose(fd);
+    
+  fd = fopen("fwavblnk.raw","wb");
+  for (i=0;i<LENGTH/4;i++)
+    data[i+LENGTH/4] = data[i];
+  fwrite(&data,2,LENGTH,fd);
+  fclose(fd);
+    
+  fd = fopen("snglpeak.raw","wb");
+  for (i=0;i<=LENGTH/4;i++)
+    data[i] = 32767 * (1.0 - cos(i * 2 * PI / (double) LENGTH));
+  for (i=0;i<=LENGTH/4;i++)
+    data[LENGTH/2-i] = data[i];
+  for (i=LENGTH/2;i<LENGTH;i++) 
+    data[i] = 0;
+  fwrite(&data,2,LENGTH,fd);
+  fclose(fd);
+    
+  fd = fopen("twopeaks.raw","wb");
+  for (i=0;i<=LENGTH/2;i++)    {
+    data[LENGTH/2+i] = -data[i];
+  }
+  fwrite(&data,2,LENGTH,fd);
+  fclose(fd);
+    
+  fd = fopen("peksblnk.raw","wb");
+  for (i=0;i<=LENGTH/2;i++)
+    data[i] = data[i*2];
+  for (i=LENGTH/2;i<LENGTH;i++) 
+    data[i] = 0;
+  fwrite(&data,2,LENGTH,fd);
+  fclose(fd);
+    
+  fd = fopen("ppksblnk.raw","wb");
+  for (i=0;i<=LENGTH/4;i++)
+    data[i+LENGTH/4] = data[i]; 
+  fwrite(&data,2,LENGTH,fd);
+  fclose(fd);
+
+  ///////////  Impulses of various bandwidth  ///////////  
+  fd = fopen("impuls10.raw","wb");
+  for (i=0;i<LENGTH;i++)      {
+    temp = 0.0;
+    for (j=1;j<=10;j++)
+      temp += cos(i * j * 2 * PI / (double) LENGTH);
+    data[i] = 32767 / 10.0 * temp;
+  }
+  fwrite(&data,2,LENGTH,fd);
+  fclose(fd);
+    
+  fd = fopen("impuls20.raw","wb");
+  for (i=0;i<LENGTH;i++)      {
+    temp = 0.0;
+    for (j=1;j<=20;j++)
+      temp += cos(i * j * 2 * PI / (double) LENGTH);
+    data[i] = 32767 / 20.0 * temp;
+  }
+  fwrite(&data,2,LENGTH,fd);
+  fclose(fd);
+    
+  fd = fopen("impuls40.raw","wb");
+  for (i=0;i<LENGTH;i++)      {
+    temp = 0.0;
+    for (j=1;j<=40;j++)
+      temp += cos(i * j * 2 * PI / (double) LENGTH);
+    data[i] = 32767 / 40.0 * temp;
+  }
+  fwrite(&data,2,LENGTH,fd);
+  fclose(fd);
+
+}
diff --git a/lib/MoMu-STK-1.0.0/rawwaves/mand1.raw b/lib/MoMu-STK-1.0.0/rawwaves/mand1.raw
new file mode 100644 (file)
index 0000000..bc04a05
Binary files /dev/null and b/lib/MoMu-STK-1.0.0/rawwaves/mand1.raw differ
diff --git a/lib/MoMu-STK-1.0.0/rawwaves/mand10.raw b/lib/MoMu-STK-1.0.0/rawwaves/mand10.raw
new file mode 100644 (file)
index 0000000..4b35376
Binary files /dev/null and b/lib/MoMu-STK-1.0.0/rawwaves/mand10.raw differ
diff --git a/lib/MoMu-STK-1.0.0/rawwaves/mand11.raw b/lib/MoMu-STK-1.0.0/rawwaves/mand11.raw
new file mode 100644 (file)
index 0000000..94889be
Binary files /dev/null and b/lib/MoMu-STK-1.0.0/rawwaves/mand11.raw differ
diff --git a/lib/MoMu-STK-1.0.0/rawwaves/mand12.raw b/lib/MoMu-STK-1.0.0/rawwaves/mand12.raw
new file mode 100644 (file)
index 0000000..a128642
Binary files /dev/null and b/lib/MoMu-STK-1.0.0/rawwaves/mand12.raw differ
diff --git a/lib/MoMu-STK-1.0.0/rawwaves/mand2.raw b/lib/MoMu-STK-1.0.0/rawwaves/mand2.raw
new file mode 100644 (file)
index 0000000..6208008
Binary files /dev/null and b/lib/MoMu-STK-1.0.0/rawwaves/mand2.raw differ
diff --git a/lib/MoMu-STK-1.0.0/rawwaves/mand3.raw b/lib/MoMu-STK-1.0.0/rawwaves/mand3.raw
new file mode 100644 (file)
index 0000000..8857f86
Binary files /dev/null and b/lib/MoMu-STK-1.0.0/rawwaves/mand3.raw differ
diff --git a/lib/MoMu-STK-1.0.0/rawwaves/mand4.raw b/lib/MoMu-STK-1.0.0/rawwaves/mand4.raw
new file mode 100644 (file)
index 0000000..6058eb1
Binary files /dev/null and b/lib/MoMu-STK-1.0.0/rawwaves/mand4.raw differ
diff --git a/lib/MoMu-STK-1.0.0/rawwaves/mand5.raw b/lib/MoMu-STK-1.0.0/rawwaves/mand5.raw
new file mode 100644 (file)
index 0000000..9b308a8
Binary files /dev/null and b/lib/MoMu-STK-1.0.0/rawwaves/mand5.raw differ
diff --git a/lib/MoMu-STK-1.0.0/rawwaves/mand6.raw b/lib/MoMu-STK-1.0.0/rawwaves/mand6.raw
new file mode 100644 (file)
index 0000000..05f083d
Binary files /dev/null and b/lib/MoMu-STK-1.0.0/rawwaves/mand6.raw differ
diff --git a/lib/MoMu-STK-1.0.0/rawwaves/mand7.raw b/lib/MoMu-STK-1.0.0/rawwaves/mand7.raw
new file mode 100644 (file)
index 0000000..64941e9
Binary files /dev/null and b/lib/MoMu-STK-1.0.0/rawwaves/mand7.raw differ
diff --git a/lib/MoMu-STK-1.0.0/rawwaves/mand8.raw b/lib/MoMu-STK-1.0.0/rawwaves/mand8.raw
new file mode 100644 (file)
index 0000000..52027bf
Binary files /dev/null and b/lib/MoMu-STK-1.0.0/rawwaves/mand8.raw differ
diff --git a/lib/MoMu-STK-1.0.0/rawwaves/mand9.raw b/lib/MoMu-STK-1.0.0/rawwaves/mand9.raw
new file mode 100644 (file)
index 0000000..9e88a0c
Binary files /dev/null and b/lib/MoMu-STK-1.0.0/rawwaves/mand9.raw differ
diff --git a/lib/MoMu-STK-1.0.0/rawwaves/mandpluk.raw b/lib/MoMu-STK-1.0.0/rawwaves/mandpluk.raw
new file mode 100644 (file)
index 0000000..162a0da
Binary files /dev/null and b/lib/MoMu-STK-1.0.0/rawwaves/mandpluk.raw differ
diff --git a/lib/MoMu-STK-1.0.0/rawwaves/marmstk1.raw b/lib/MoMu-STK-1.0.0/rawwaves/marmstk1.raw
new file mode 100644 (file)
index 0000000..185b445
Binary files /dev/null and b/lib/MoMu-STK-1.0.0/rawwaves/marmstk1.raw differ
diff --git a/lib/MoMu-STK-1.0.0/rawwaves/ooo.raw b/lib/MoMu-STK-1.0.0/rawwaves/ooo.raw
new file mode 100644 (file)
index 0000000..1b8331e
Binary files /dev/null and b/lib/MoMu-STK-1.0.0/rawwaves/ooo.raw differ
diff --git a/lib/MoMu-STK-1.0.0/rawwaves/peksblnk.raw b/lib/MoMu-STK-1.0.0/rawwaves/peksblnk.raw
new file mode 100644 (file)
index 0000000..9c40517
Binary files /dev/null and b/lib/MoMu-STK-1.0.0/rawwaves/peksblnk.raw differ
diff --git a/lib/MoMu-STK-1.0.0/rawwaves/ppksblnk.raw b/lib/MoMu-STK-1.0.0/rawwaves/ppksblnk.raw
new file mode 100644 (file)
index 0000000..95a4446
Binary files /dev/null and b/lib/MoMu-STK-1.0.0/rawwaves/ppksblnk.raw differ
diff --git a/lib/MoMu-STK-1.0.0/rawwaves/ridecymb.raw b/lib/MoMu-STK-1.0.0/rawwaves/ridecymb.raw
new file mode 100644 (file)
index 0000000..722fa5a
Binary files /dev/null and b/lib/MoMu-STK-1.0.0/rawwaves/ridecymb.raw differ
diff --git a/lib/MoMu-STK-1.0.0/rawwaves/silence.raw b/lib/MoMu-STK-1.0.0/rawwaves/silence.raw
new file mode 100644 (file)
index 0000000..4b8a1b3
Binary files /dev/null and b/lib/MoMu-STK-1.0.0/rawwaves/silence.raw differ
diff --git a/lib/MoMu-STK-1.0.0/rawwaves/sine.c b/lib/MoMu-STK-1.0.0/rawwaves/sine.c
new file mode 100644 (file)
index 0000000..d10c103
--- /dev/null
@@ -0,0 +1,22 @@
+//    Utility to make a rawwave sine table (assumes big-endian machine).
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define LENGTH 1024
+#define PI 3.14159265358979323846
+
+void main4() //MoMu modified
+{
+  int i;
+  //double temp;
+  short data[LENGTH + 2];
+  FILE *fd;
+
+  fd = fopen("sinewave.raw","wb");
+  for (i=0; i<LENGTH; i++)
+    data[i] = 32767 * sin(i * 2 * PI / (double) LENGTH);
+  fwrite(&data,2,LENGTH,fd);
+  fclose(fd);
+}
diff --git a/lib/MoMu-STK-1.0.0/rawwaves/sineblnk.raw b/lib/MoMu-STK-1.0.0/rawwaves/sineblnk.raw
new file mode 100644 (file)
index 0000000..78e0a11
Binary files /dev/null and b/lib/MoMu-STK-1.0.0/rawwaves/sineblnk.raw differ
diff --git a/lib/MoMu-STK-1.0.0/rawwaves/sinewave.raw b/lib/MoMu-STK-1.0.0/rawwaves/sinewave.raw
new file mode 100644 (file)
index 0000000..a5cb349
Binary files /dev/null and b/lib/MoMu-STK-1.0.0/rawwaves/sinewave.raw differ
diff --git a/lib/MoMu-STK-1.0.0/rawwaves/snardrum.raw b/lib/MoMu-STK-1.0.0/rawwaves/snardrum.raw
new file mode 100644 (file)
index 0000000..93005ad
Binary files /dev/null and b/lib/MoMu-STK-1.0.0/rawwaves/snardrum.raw differ
diff --git a/lib/MoMu-STK-1.0.0/rawwaves/snglpeak.raw b/lib/MoMu-STK-1.0.0/rawwaves/snglpeak.raw
new file mode 100644 (file)
index 0000000..898e095
Binary files /dev/null and b/lib/MoMu-STK-1.0.0/rawwaves/snglpeak.raw differ
diff --git a/lib/MoMu-STK-1.0.0/rawwaves/tambourn.raw b/lib/MoMu-STK-1.0.0/rawwaves/tambourn.raw
new file mode 100644 (file)
index 0000000..fa81252
Binary files /dev/null and b/lib/MoMu-STK-1.0.0/rawwaves/tambourn.raw differ
diff --git a/lib/MoMu-STK-1.0.0/rawwaves/tomhidrm.raw b/lib/MoMu-STK-1.0.0/rawwaves/tomhidrm.raw
new file mode 100644 (file)
index 0000000..0cf482b
Binary files /dev/null and b/lib/MoMu-STK-1.0.0/rawwaves/tomhidrm.raw differ
diff --git a/lib/MoMu-STK-1.0.0/rawwaves/tomlowdr.raw b/lib/MoMu-STK-1.0.0/rawwaves/tomlowdr.raw
new file mode 100644 (file)
index 0000000..9813513
Binary files /dev/null and b/lib/MoMu-STK-1.0.0/rawwaves/tomlowdr.raw differ
diff --git a/lib/MoMu-STK-1.0.0/rawwaves/tommiddr.raw b/lib/MoMu-STK-1.0.0/rawwaves/tommiddr.raw
new file mode 100644 (file)
index 0000000..4d04257
Binary files /dev/null and b/lib/MoMu-STK-1.0.0/rawwaves/tommiddr.raw differ
diff --git a/lib/MoMu-STK-1.0.0/rawwaves/twopeaks.raw b/lib/MoMu-STK-1.0.0/rawwaves/twopeaks.raw
new file mode 100644 (file)
index 0000000..d383a24
Binary files /dev/null and b/lib/MoMu-STK-1.0.0/rawwaves/twopeaks.raw differ
diff --git a/lib/MoMu-STK-1.0.0/src/ADSR.cpp b/lib/MoMu-STK-1.0.0/src/ADSR.cpp
new file mode 100644 (file)
index 0000000..958ab13
--- /dev/null
@@ -0,0 +1,155 @@
+/***************************************************/
+/*! \class ADSR
+    \brief STK ADSR envelope class.
+
+    This class implements a traditional ADSR (Attack, Decay, Sustain,
+    Release) envelope.  It responds to simple keyOn and keyOff
+    messages, keeping track of its state.  The \e state = ADSR::DONE
+    after the envelope value reaches 0.0 in the ADSR::RELEASE state.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "ADSR.h"
+
+namespace stk {
+
+ADSR :: ADSR( void )
+{
+  target_ = 0.0;
+  value_ = 0.0;
+  attackRate_ = 0.001;
+  decayRate_ = 0.001;
+  releaseRate_ = 0.005;
+  sustainLevel_ = 0.5;
+  state_ = ATTACK;
+  Stk::addSampleRateAlert( this );
+}
+
+ADSR :: ~ADSR( void )
+{
+}
+
+void ADSR :: sampleRateChanged( StkFloat newRate, StkFloat oldRate )
+{
+  if ( !ignoreSampleRateChange_ ) {
+    attackRate_ = oldRate * attackRate_ / newRate;
+    decayRate_ = oldRate * decayRate_ / newRate;
+    releaseRate_ = oldRate * releaseRate_ / newRate;
+  }
+}
+
+void ADSR :: keyOn()
+{
+  target_ = 1.0;
+  state_ = ATTACK;
+}
+
+void ADSR :: keyOff()
+{
+  target_ = 0.0;
+  state_ = RELEASE;
+}
+
+void ADSR :: setAttackRate( StkFloat rate )
+{
+  if ( rate < 0.0 ) {
+    errorString_ << "ADSR::setAttackRate: negative rates not allowed ... correcting!";
+    handleError( StkError::WARNING );
+    attackRate_ = -rate;
+  }
+  else attackRate_ = rate;
+}
+
+void ADSR :: setDecayRate( StkFloat rate )
+{
+  if ( rate < 0.0 ) {
+    errorString_ << "ADSR::setDecayRate: negative rates not allowed ... correcting!";
+    handleError( StkError::WARNING );
+    decayRate_ = -rate;
+  }
+  else decayRate_ = rate;
+}
+
+void ADSR :: setSustainLevel( StkFloat level )
+{
+  if ( level < 0.0 ) {
+    errorString_ << "ADSR::setSustainLevel: level out of range ... correcting!";
+    handleError( StkError::WARNING );
+    sustainLevel_ = 0.0;
+  }
+  else sustainLevel_ = level;
+}
+
+void ADSR :: setReleaseRate( StkFloat rate )
+{
+  if ( rate < 0.0 ) {
+    errorString_ << "ADSR::setReleaseRate: negative rates not allowed ... correcting!";
+    handleError( StkError::WARNING );
+    releaseRate_ = -rate;
+  }
+  else releaseRate_ = rate;
+}
+
+void ADSR :: setAttackTime( StkFloat time )
+{
+  if ( time < 0.0 ) {
+    errorString_ << "ADSR::setAttackTime: negative times not allowed ... correcting!";
+    handleError( StkError::WARNING );
+    attackRate_ = 1.0 / ( -time * Stk::sampleRate() );
+  }
+  else attackRate_ = 1.0 / ( time * Stk::sampleRate() );
+}
+
+void ADSR :: setDecayTime( StkFloat time )
+{
+  if ( time < 0.0 ) {
+    errorString_ << "ADSR::setDecayTime: negative times not allowed ... correcting!";
+    handleError( StkError::WARNING );
+    decayRate_ = 1.0 / ( -time * Stk::sampleRate() );
+  }
+  else decayRate_ = 1.0 / ( time * Stk::sampleRate() );
+}
+
+void ADSR :: setReleaseTime( StkFloat time )
+{
+  if ( time < 0.0 ) {
+    errorString_ << "ADSR::setReleaseTime: negative times not allowed ... correcting!";
+    handleError( StkError::WARNING );
+    releaseRate_ = sustainLevel_ / ( -time * Stk::sampleRate() );
+  }
+  else releaseRate_ = sustainLevel_ / ( time * Stk::sampleRate() );
+}
+
+void ADSR :: setAllTimes( StkFloat aTime, StkFloat dTime, StkFloat sLevel, StkFloat rTime )
+{
+  this->setAttackTime( aTime );
+  this->setDecayTime( dTime );
+  this->setSustainLevel( sLevel );
+  this->setReleaseTime( rTime );
+}
+
+void ADSR :: setTarget( StkFloat target )
+{
+  target_ = target;
+  if ( value_ < target_ ) {
+    state_ = ATTACK;
+    this->setSustainLevel( target_ );
+  }
+  if ( value_ > target_ ) {
+    this->setSustainLevel( target_ );
+    state_ = DECAY;
+  }
+}
+
+void ADSR :: setValue( StkFloat value )
+{
+  state_ = SUSTAIN;
+  target_ = value;
+  value_ = value;
+  this->setSustainLevel( value );
+  lastFrame_[0] = value;
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/Asymp.cpp b/lib/MoMu-STK-1.0.0/src/Asymp.cpp
new file mode 100644 (file)
index 0000000..c379b24
--- /dev/null
@@ -0,0 +1,103 @@
+/***************************************************/
+/*! \class Asymp
+    \brief STK asymptotic curve envelope class
+
+    This class implements a simple envelope generator
+    which asymptotically approaches a target value.
+    The algorithm used is of the form:
+
+    y[n] = a y[n-1] + (1-a) target,
+
+    where a = exp(-T/tau), T is the sample period, and
+    tau is a time constant.  The user can set the time
+    constant (default value = 0.3) and target value.
+    Theoretically, this recursion never reaches its
+    target, though the calculations in this class are
+    stopped when the current value gets within a small
+    threshold value of the target (at which time the
+    current value is set to the target).  It responds
+    to \e keyOn and \e keyOff messages by ramping to
+    1.0 on keyOn and to 0.0 on keyOff.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "Asymp.h"
+#include <cmath>
+
+namespace stk {
+
+Asymp :: Asymp( void )
+{
+  value_ = 0.0;
+  target_ = 0.0;
+  state_ = 0;
+  factor_ = exp( -1.0 / ( 0.3 * Stk::sampleRate() ) );
+  constant_ = 0.0;
+  Stk::addSampleRateAlert( this );
+}
+
+Asymp :: ~Asymp( void )
+{    
+}
+
+void Asymp :: sampleRateChanged( StkFloat newRate, StkFloat oldRate )
+{
+  if ( !ignoreSampleRateChange_ ) {
+    StkFloat tau = -1.0 / ( std::log( factor_ ) * oldRate );
+    factor_ = std::exp( -1.0 / ( tau * newRate ) );
+  }
+}
+
+void Asymp :: keyOn( void )
+{
+  this->setTarget( 1.0 );
+}
+
+void Asymp :: keyOff( void )
+{
+  this->setTarget( 0.0 );
+}
+
+void Asymp :: setTau( StkFloat tau )
+{
+  if ( tau <= 0.0 ) {
+    errorString_ << "Asymp::setTau: negative or zero tau not allowed ... ignoring!";
+    handleError( StkError::WARNING );
+    return;
+  }
+
+  factor_ = std::exp( -1.0 / ( tau * Stk::sampleRate() ) );
+  constant_ = ( 1.0 - factor_ ) * target_;
+}
+
+void Asymp :: setTime( StkFloat time )
+{
+  if ( time <= 0.0 ) {
+    errorString_ << "Asymp::setTime: negative or zero times not allowed ... ignoring!";
+    handleError( StkError::WARNING );
+    return;
+  }
+
+  StkFloat tau = -time / std::log( TARGET_THRESHOLD );
+  factor_ = std::exp( -1.0 / ( tau * Stk::sampleRate() ) );
+  constant_ = ( 1.0 - factor_ ) * target_;
+}
+
+void Asymp :: setTarget( StkFloat target )
+{
+  target_ = target;
+  if ( value_ != target_ ) state_ = 1;
+  constant_ = ( 1.0 - factor_ ) * target_;
+}
+
+void Asymp :: setValue( StkFloat value )
+{
+  state_ = 0;
+  target_ = value;
+  value_ = value;
+}
+
+} // stk namespace
+
diff --git a/lib/MoMu-STK-1.0.0/src/BandedWG.cpp b/lib/MoMu-STK-1.0.0/src/BandedWG.cpp
new file mode 100644 (file)
index 0000000..1d102c1
--- /dev/null
@@ -0,0 +1,380 @@
+/***************************************************/
+/*! \class BandedWG
+    \brief Banded waveguide modeling class.
+
+    This class uses banded waveguide techniques to
+    model a variety of sounds, including bowed
+    bars, glasses, and bowls.  For more
+    information, see Essl, G. and Cook, P. "Banded
+    Waveguides: Towards Physical Modelling of Bar
+    Percussion Instruments", Proceedings of the
+    1999 International Computer Music Conference.
+
+    Control Change Numbers: 
+       - Bow Pressure = 2
+       - Bow Motion = 4
+       - Strike Position = 8 (not implemented)
+       - Vibrato Frequency = 11
+       - Gain = 1
+       - Bow Velocity = 128
+       - Set Striking = 64
+       - Instrument Presets = 16
+         - Uniform Bar = 0
+         - Tuned Bar = 1
+         - Glass Harmonica = 2
+         - Tibetan Bowl = 3
+
+    by Georg Essl, 1999 - 2004.
+    Modified for STK 4.0 by Gary Scavone.
+*/
+/***************************************************/
+
+#include "BandedWG.h"
+#include "Skini_msg.h"
+#include <cmath>
+
+namespace stk {
+
+BandedWG :: BandedWG( void )
+{
+  doPluck_ = true;
+
+  bowTable_.setSlope( 3.0 );
+  adsr_.setAllTimes( 0.02, 0.005, 0.9, 0.01);
+
+  frequency_ = 220.0;
+  this->setPreset(0);
+
+  bowPosition_ = 0;
+  baseGain_ = (StkFloat) 0.999;
+  
+  integrationConstant_ = 0.0;
+  trackVelocity_ = false;
+
+  bowVelocity_ = 0.0;
+  bowTarget_ = 0.0;
+
+  strikeAmp_ = 0.0;
+}
+
+BandedWG :: ~BandedWG( void )
+{
+}
+
+void BandedWG :: clear( void )
+{
+  for ( int i=0; i<nModes_; i++ ) {
+    delay_[i].clear();
+    bandpass_[i].clear();
+  }
+}
+
+void BandedWG :: setPreset( int preset )
+{
+  int i;
+  switch ( preset ) {
+
+  case 1: // Tuned Bar
+    presetModes_ = 4;
+    modes_[0] = (StkFloat) 1.0;
+    modes_[1] = (StkFloat) 4.0198391420;
+    modes_[2] = (StkFloat) 10.7184986595;
+    modes_[3] = (StkFloat) 18.0697050938;
+
+    for (i=0; i<presetModes_; i++) {
+      basegains_[i] = (StkFloat) pow(0.999,(double) i+1);
+      excitation_[i] = 1.0;
+    }
+
+    break;
+
+  case 2: // Glass Harmonica
+    presetModes_ = 5;
+    modes_[0] = (StkFloat) 1.0;
+    modes_[1] = (StkFloat) 2.32;
+    modes_[2] = (StkFloat) 4.25;
+    modes_[3] = (StkFloat) 6.63;
+    modes_[4] = (StkFloat) 9.38;
+    // modes_[5] = (StkFloat) 12.22;
+
+    for (i=0; i<presetModes_; i++) {
+      basegains_[i] = (StkFloat) pow(0.999,(double) i+1);
+      excitation_[i] = 1.0;
+    }
+    /*
+      baseGain_ = (StkFloat) 0.99999;
+      for (i=0; i<presetModes_; i++) 
+      gains_[i]= (StkFloat) pow(baseGain_, delay_[i].getDelay()+i);
+    */
+
+    break;
+   
+  case 3: // Tibetan Prayer Bowl (ICMC'02)
+    presetModes_ = 12;
+    modes_[0]=0.996108344;
+    basegains_[0]=0.999925960128219;
+    excitation_[0]=11.900357/10.0;
+    modes_[1]=1.0038916562;
+    basegains_[1]=0.999925960128219;
+    excitation_[1]=11.900357/10.;
+    modes_[2]=2.979178;
+    basegains_[2]=0.999982774366897;
+    excitation_[2]=10.914886/10.;
+    modes_[3]=2.99329767;
+    basegains_[3]=0.999982774366897;
+    excitation_[3]=10.914886/10.;
+    modes_[4]=5.704452;
+    basegains_[4]=1.0; //0.999999999999999999987356406352;
+    excitation_[4]=42.995041/10.;
+    modes_[5]=5.704452;
+    basegains_[5]=1.0; //0.999999999999999999987356406352;
+    excitation_[5]=42.995041/10.;
+    modes_[6]=8.9982;
+    basegains_[6]=1.0; //0.999999999999999999996995497558225;
+    excitation_[6]=40.063034/10.;
+    modes_[7]=9.01549726;
+    basegains_[7]=1.0; //0.999999999999999999996995497558225;
+    excitation_[7]=40.063034/10.;
+    modes_[8]=12.83303;
+    basegains_[8]=0.999965497558225;
+    excitation_[8]=7.063034/10.;
+    modes_[9]=12.807382;
+    basegains_[9]=0.999965497558225;
+    excitation_[9]=7.063034/10.;
+    modes_[10]=17.2808219;
+    basegains_[10]=0.9999999999999999999965497558225;
+    excitation_[10]=57.063034/10.;
+    modes_[11]=21.97602739726;
+    basegains_[11]=0.999999999999999965497558225;
+    excitation_[11]=57.063034/10.;
+
+    break;     
+
+  default: // Uniform Bar
+    presetModes_ = 4;
+    modes_[0] = (StkFloat) 1.0;
+    modes_[1] = (StkFloat) 2.756;
+    modes_[2] = (StkFloat) 5.404;
+    modes_[3] = (StkFloat) 8.933;
+
+    for (i=0; i<presetModes_; i++) {
+      basegains_[i] = (StkFloat) pow(0.9,(double) i+1);
+      excitation_[i] = 1.0;
+    }
+
+    break;
+  }
+
+  nModes_ = presetModes_;
+  setFrequency( frequency_ );
+}
+
+void BandedWG :: setFrequency( StkFloat frequency )
+{
+  frequency_ = frequency;
+  if ( frequency <= 0.0 ) {
+    errorString_ << "BandedWG::setFrequency: parameter is less than or equal to zero!";
+    handleError( StkError::WARNING );
+    frequency_ = 220.0;
+  }
+  if (frequency_ > 1568.0) frequency_ = 1568.0;
+
+  StkFloat radius;
+  StkFloat base = Stk::sampleRate() / frequency_;
+  StkFloat length;
+  for (int i=0; i<presetModes_; i++) {
+    // Calculate the delay line lengths for each mode.
+    length = (int)(base / modes_[i]);
+    if ( length > 2.0) {
+      delay_[i].setDelay( length );
+      gains_[i]=basegains_[i];
+      //         gains_[i]=(StkFloat) pow(basegains_[i], 1/((StkFloat)delay_[i].getDelay()));
+      //         std::cerr << gains_[i];
+    }
+    else       {
+      nModes_ = i;
+      break;
+    }
+    // std::cerr << std::endl;
+
+    // Set the bandpass filter resonances
+    radius = 1.0 - PI * 32 / Stk::sampleRate(); //frequency_ * modes_[i] / Stk::sampleRate()/32;
+    if ( radius < 0.0 ) radius = 0.0;
+    bandpass_[i].setResonance(frequency_ * modes_[i], radius, true);
+
+    delay_[i].clear();
+    bandpass_[i].clear();
+  }
+
+  //int olen = (int)(delay_[0].getDelay());
+  //strikePosition_ = (int)(strikePosition_*(length/modes_[0])/olen);
+}
+
+void BandedWG :: setStrikePosition( StkFloat position )
+{
+  strikePosition_ = (int)(delay_[0].getDelay() * position / 2.0);
+}
+
+void BandedWG :: startBowing( StkFloat amplitude, StkFloat rate )
+{
+  adsr_.setAttackRate(rate);
+  adsr_.keyOn();
+  maxVelocity_ = 0.03 + (0.1 * amplitude); 
+}
+
+void BandedWG :: stopBowing( StkFloat rate )
+{
+  adsr_.setReleaseRate(rate);
+  adsr_.keyOff();
+}
+
+void BandedWG :: pluck( StkFloat amplitude )
+{
+  int j;
+  StkFloat min_len = delay_[nModes_-1].getDelay();
+  for (int i=0; i<nModes_; i++)
+    for(j=0; j<(int)(delay_[i].getDelay()/min_len); j++)
+      delay_[i].tick( excitation_[i]*amplitude / nModes_ );
+
+  //   strikeAmp_ += amplitude;
+}
+
+void BandedWG :: noteOn( StkFloat frequency, StkFloat amplitude )
+{
+  this->setFrequency(frequency);
+
+  if ( doPluck_ )
+    this->pluck(amplitude);
+  else
+    this->startBowing(amplitude, amplitude * 0.001);
+
+#if defined(_STK_DEBUG_)
+  errorString_ << "BandedWG::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << ".";
+  handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+void BandedWG :: noteOff( StkFloat amplitude )
+{
+  if ( !doPluck_ )
+    this->stopBowing((1.0 - amplitude) * 0.005);
+
+#if defined(_STK_DEBUG_)
+  errorString_ << "BandedWG::NoteOff: amplitude = " << amplitude << ".";
+  handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+StkFloat BandedWG :: tick( unsigned int )
+{
+  int k;
+
+  StkFloat input = 0.0;
+  if ( doPluck_ ) {
+    input = 0.0;
+    //  input = strikeAmp_/nModes_;
+    //  strikeAmp_ = 0.0;
+  }
+  else {
+    if ( integrationConstant_ == 0.0 )
+      velocityInput_ = 0.0;
+    else
+      velocityInput_ = integrationConstant_ * velocityInput_;
+
+    for ( k=0; k<nModes_; k++ )
+      velocityInput_ += baseGain_ * delay_[k].lastOut();
+      
+    if ( trackVelocity_ )  {
+      bowVelocity_ *= 0.9995;
+      bowVelocity_ += bowTarget_;
+      bowTarget_ *= 0.995;
+    }
+    else
+      bowVelocity_ = adsr_.tick() * maxVelocity_;
+
+    input = bowVelocity_ - velocityInput_;
+    input = input * bowTable_.tick(input);
+    input = input/(StkFloat)nModes_;
+  }
+
+  StkFloat data = 0.0;  
+  for ( k=0; k<nModes_; k++ ) {
+    bandpass_[k].tick(input + gains_[k] * delay_[k].lastOut());
+    delay_[k].tick(bandpass_[k].lastOut());
+    data += bandpass_[k].lastOut();
+  }
+  
+  //lastFrame_[0] = data * nModes_;
+  lastFrame_[0] = data * 4;
+  return lastFrame_[0];
+}
+
+void BandedWG :: controlChange( int number, StkFloat value )
+{
+  StkFloat norm = value * ONE_OVER_128;
+  if ( norm < 0 ) {
+    norm = 0.0;
+    errorString_ << "BandedWG::controlChange: control value less than zero ... setting to zero!";
+    handleError( StkError::WARNING );
+  }
+  else if ( norm > 1.0 ) {
+    norm = 1.0;
+    errorString_ << "BandedWG::controlChange: control value greater than 128.0 ... setting to 128.0!";
+    handleError( StkError::WARNING );
+  }
+
+  if (number == __SK_BowPressure_) { // 2
+    if ( norm == 0.0 )
+      doPluck_ = true;
+    else {
+      doPluck_ = false;
+      bowTable_.setSlope( 10.0 - (9.0 * norm));
+    }
+  }
+  else if (number == 4)        { // 4
+    if ( !trackVelocity_ ) trackVelocity_ = true;
+    bowTarget_ += 0.005 * (norm - bowPosition_);
+    bowPosition_ = norm;
+    //adsr_.setTarget(bowPosition_);
+  }
+  else if (number == 8) // 8
+    this->setStrikePosition( norm );
+  else if (number == __SK_AfterTouch_Cont_) { // 128
+    //bowTarget_ += 0.02 * (norm - bowPosition_);
+    //bowPosition_ = norm;
+    if ( trackVelocity_ ) trackVelocity_ = false;
+    maxVelocity_ = 0.13 * norm; 
+    adsr_.setTarget(norm);
+  }      
+  else if (number == __SK_ModWheel_) { // 1
+    //    baseGain_ = 0.9989999999 + (0.001 * norm );
+         baseGain_ = 0.8999999999999999 + (0.1 * norm);
+    // std::cerr << "Yuck!" << std::endl;
+    for (int i=0; i<nModes_; i++)
+      gains_[i]=(StkFloat) basegains_[i]*baseGain_;
+    //      gains_[i]=(StkFloat) pow(baseGain_, (int)((StkFloat)delay_[i].getDelay()+i));
+  }
+  else if (number == __SK_ModFrequency_) // 11
+    integrationConstant_ = norm;
+  else if (number == __SK_Sustain_)    { // 64
+    if (value < 65) doPluck_ = true;
+    else doPluck_ = false;
+  }
+  else if (number == __SK_Portamento_) { // 65
+    if (value < 65) trackVelocity_ = false;
+    else trackVelocity_ = true;
+  }
+  else if (number == __SK_ProphesyRibbon_) // 16
+    this->setPreset((int) value);  
+  else {
+    errorString_ << "BandedWG::controlChange: undefined control number (" << number << ")!";
+    handleError( StkError::WARNING );
+  }
+
+#if defined(_STK_DEBUG_)
+    errorString_ << "BandedWG::controlChange: number = " << number << ", value = " << value << ".";
+    handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/BeeThree.cpp b/lib/MoMu-STK-1.0.0/src/BeeThree.cpp
new file mode 100644 (file)
index 0000000..9272b3b
--- /dev/null
@@ -0,0 +1,84 @@
+/***************************************************/
+/*! \class BeeThree
+    \brief STK Hammond-oid organ FM synthesis instrument.
+
+    This class implements a simple 4 operator
+    topology, also referred to as algorithm 8 of
+    the TX81Z.
+
+    \code
+    Algorithm 8 is :
+                     1 --.
+                     2 -\|
+                         +-> Out
+                     3 -/|
+                     4 --
+    \endcode
+
+    Control Change Numbers: 
+       - Operator 4 (feedback) Gain = 2
+       - Operator 3 Gain = 4
+       - LFO Speed = 11
+       - LFO Depth = 1
+       - ADSR 2 & 4 Target = 128
+
+    The basic Chowning/Stanford FM patent expired
+    in 1995, but there exist follow-on patents,
+    mostly assigned to Yamaha.  If you are of the
+    type who should worry about this (making
+    money) worry away.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "BeeThree.h"
+
+namespace stk {
+
+BeeThree :: BeeThree( void )
+  : FM()
+{
+  // Concatenate the STK rawwave path to the rawwave files
+  for ( unsigned int i=0; i<3; i++ )
+    waves_[i] = new FileLoop( (Stk::rawwavePath() + "sinewave.raw").c_str(), true );
+  waves_[3] = new FileLoop( (Stk::rawwavePath() + "fwavblnk.raw").c_str(), true );
+
+  this->setRatio( 0, 0.999 );
+  this->setRatio( 1, 1.997 );
+  this->setRatio( 2, 3.006 );
+  this->setRatio( 3, 6.009 );
+
+  gains_[0] = fmGains_[95];
+  gains_[1] = fmGains_[95];
+  gains_[2] = fmGains_[99];
+  gains_[3] = fmGains_[95];
+
+  adsr_[0]->setAllTimes( 0.005, 0.003, 1.0, 0.01 );
+  adsr_[1]->setAllTimes( 0.005, 0.003, 1.0, 0.01 );
+  adsr_[2]->setAllTimes( 0.005, 0.003, 1.0, 0.01 );
+  adsr_[3]->setAllTimes( 0.005, 0.001, 0.4, 0.03 );
+
+  twozero_.setGain( 0.1 );
+}  
+
+BeeThree :: ~BeeThree( void )
+{
+}
+
+void BeeThree :: noteOn( StkFloat frequency, StkFloat amplitude )
+{
+  gains_[0] = amplitude * fmGains_[95];
+  gains_[1] = amplitude * fmGains_[95];
+  gains_[2] = amplitude * fmGains_[99];
+  gains_[3] = amplitude * fmGains_[95];
+  this->setFrequency( frequency );
+  this->keyOn();
+
+#if defined(_STK_DEBUG_)
+  errorString_ << "BeeThree::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << '.';
+  handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/BiQuad.cpp b/lib/MoMu-STK-1.0.0/src/BiQuad.cpp
new file mode 100644 (file)
index 0000000..b9de9a5
--- /dev/null
@@ -0,0 +1,81 @@
+/***************************************************/
+/*! \class BiQuad
+    \brief STK biquad (two-pole, two-zero) filter class.
+
+    This class implements a two-pole, two-zero digital filter.
+    Methods are provided for creating a resonance or notch in the
+    frequency response while maintaining a constant filter gain.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "BiQuad.h"
+#include <cmath>
+
+namespace stk {
+
+BiQuad :: BiQuad() : Filter()
+{
+  b_.resize( 3, 0.0 );
+  a_.resize( 3, 0.0 );
+  b_[0] = 1.0;
+  a_[0] = 1.0;
+  inputs_.resize( 3, 1, 0.0 );
+  outputs_.resize( 3, 1, 0.0 );
+
+  Stk::addSampleRateAlert( this );
+}
+
+BiQuad :: ~BiQuad()
+{
+  Stk::removeSampleRateAlert( this );
+}
+
+void BiQuad :: setCoefficients( StkFloat b0, StkFloat b1, StkFloat b2, StkFloat a1, StkFloat a2, bool clearState )
+{
+  b_[0] = b0;
+  b_[1] = b1;
+  b_[2] = b2;
+  a_[1] = a1;
+  a_[2] = a2;
+
+  if ( clearState ) this->clear();
+}
+
+void BiQuad :: sampleRateChanged( StkFloat newRate, StkFloat oldRate )
+{
+  if ( !ignoreSampleRateChange_ ) {
+    errorString_ << "BiQuad::sampleRateChanged: you may need to recompute filter coefficients!";
+    handleError( StkError::WARNING );
+  }
+}
+
+void BiQuad :: setResonance(StkFloat frequency, StkFloat radius, bool normalize)
+{
+  a_[2] = radius * radius;
+  a_[1] = -2.0 * radius * cos( TWO_PI * frequency / Stk::sampleRate() );
+
+  if ( normalize ) {
+    // Use zeros at +- 1 and normalize the filter peak gain.
+    b_[0] = 0.5 - 0.5 * a_[2];
+    b_[1] = 0.0;
+    b_[2] = -b_[0];
+  }
+}
+
+void BiQuad :: setNotch(StkFloat frequency, StkFloat radius)
+{
+  // This method does not attempt to normalize the filter gain.
+  b_[2] = radius * radius;
+  b_[1] = (StkFloat) -2.0 * radius * cos( TWO_PI * (double) frequency / Stk::sampleRate() );
+}
+
+void BiQuad :: setEqualGainZeroes()
+{
+  b_[0] = 1.0;
+  b_[1] = 0.0;
+  b_[2] = -1.0;
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/Blit.cpp b/lib/MoMu-STK-1.0.0/src/Blit.cpp
new file mode 100644 (file)
index 0000000..f6a5cad
--- /dev/null
@@ -0,0 +1,78 @@
+/***************************************************/\r
+/*! \class Blit\r
+    \brief STK band-limited impulse train class.\r
+\r
+    This class generates a band-limited impulse train using a\r
+    closed-form algorithm reported by Stilson and Smith in "Alias-Free\r
+    Digital Synthesis of Classic Analog Waveforms", 1996.  The user\r
+    can specify both the fundamental frequency of the impulse train\r
+    and the number of harmonics contained in the resulting signal.\r
+\r
+    The signal is normalized so that the peak value is +/-1.0.\r
+\r
+    If nHarmonics is 0, then the signal will contain all harmonics up\r
+    to half the sample rate.  Note, however, that this setting may\r
+    produce aliasing in the signal when the frequency is changing (no\r
+    automatic modification of the number of harmonics is performed by\r
+    the setFrequency() function).\r
+\r
+    Original code by Robin Davies, 2005.\r
+    Revisions by Gary Scavone for STK, 2005.\r
+*/\r
+/***************************************************/\r
+\r
+#include "Blit.h"\r
+\r
+namespace stk {\r
\r
+Blit:: Blit( StkFloat frequency )\r
+{\r
+  nHarmonics_ = 0;\r
+  this->setFrequency( frequency );\r
+  this->reset();\r
+}\r
+\r
+Blit :: ~Blit()\r
+{\r
+}\r
+\r
+void Blit :: reset()\r
+{\r
+  phase_ = 0.0;\r
+  lastFrame_[0] = 0.0;\r
+}\r
+\r
+void Blit :: setFrequency( StkFloat frequency )\r
+{\r
+#if defined(_STK_DEBUG_)\r
+  errorString_ << "Blit::setFrequency: frequency = " << frequency << '.';\r
+  handleError( StkError::DEBUG_WARNING );\r
+#endif\r
+\r
+  p_ = Stk::sampleRate() / frequency;\r
+  rate_ = PI / p_;\r
+  this->updateHarmonics();\r
+}\r
+\r
+void Blit :: setHarmonics( unsigned int nHarmonics )\r
+{\r
+  nHarmonics_ = nHarmonics;\r
+  this->updateHarmonics();\r
+}\r
+\r
+void Blit :: updateHarmonics( void )\r
+{\r
+  if ( nHarmonics_ <= 0 ) {\r
+    unsigned int maxHarmonics = (unsigned int) floor( 0.5 * p_ );\r
+    m_ = 2 * maxHarmonics + 1;\r
+  }\r
+  else\r
+    m_ = 2 * nHarmonics_ + 1;\r
+\r
+#if defined(_STK_DEBUG_)\r
+  errorString_ << "Blit::updateHarmonics: nHarmonics_ = " << nHarmonics_ << ", m_ = " << m_ << '.';\r
+  handleError( StkError::DEBUG_WARNING );\r
+#endif\r
+}\r
+\r
+} // stk namespace\r
diff --git a/lib/MoMu-STK-1.0.0/src/BlitSaw.cpp b/lib/MoMu-STK-1.0.0/src/BlitSaw.cpp
new file mode 100644 (file)
index 0000000..abde294
--- /dev/null
@@ -0,0 +1,91 @@
+/***************************************************/\r
+/*! \class BlitSaw\r
+    \brief STK band-limited sawtooth wave class.\r
+\r
+    This class generates a band-limited sawtooth waveform using a\r
+    closed-form algorithm reported by Stilson and Smith in "Alias-Free\r
+    Digital Synthesis of Classic Analog Waveforms", 1996.  The user\r
+    can specify both the fundamental frequency of the sawtooth and the\r
+    number of harmonics contained in the resulting signal.\r
+\r
+    If nHarmonics is 0, then the signal will contain all harmonics up\r
+    to half the sample rate.  Note, however, that this setting may\r
+    produce aliasing in the signal when the frequency is changing (no\r
+    automatic modification of the number of harmonics is performed by\r
+    the setFrequency() function).\r
+\r
+    Based on initial code of Robin Davies, 2005.\r
+    Modified algorithm code by Gary Scavone, 2005.\r
+*/\r
+/***************************************************/\r
+\r
+#include "BlitSaw.h"\r
+\r
+namespace stk {\r
\r
+BlitSaw:: BlitSaw( StkFloat frequency )\r
+{\r
+  nHarmonics_ = 0;\r
+  this->reset();\r
+  this->setFrequency( frequency );\r
+}\r
+\r
+BlitSaw :: ~BlitSaw()\r
+{\r
+}\r
+\r
+void BlitSaw :: reset()\r
+{\r
+  phase_ = 0.0f;\r
+  state_ = 0.0;\r
+  lastFrame_[0] = 0.0;\r
+}\r
+\r
+void BlitSaw :: setFrequency( StkFloat frequency )\r
+{\r
+#if defined(_STK_DEBUG_)\r
+  errorString_ << "BlitSaw::setFrequency: frequency = " << frequency << '.';\r
+  handleError( StkError::DEBUG_WARNING );\r
+#endif\r
+\r
+  p_ = Stk::sampleRate() / frequency;\r
+  C2_ = 1 / p_;\r
+  rate_ = PI * C2_;\r
+  this->updateHarmonics();\r
+}\r
+\r
+void BlitSaw :: setHarmonics( unsigned int nHarmonics )\r
+{\r
+  nHarmonics_ = nHarmonics;\r
+  this->updateHarmonics();\r
+\r
+  // I found that the initial DC offset could be minimized with an\r
+  // initial state setting as given below.  This initialization should\r
+  // only happen before starting the oscillator for the first time\r
+  // (but after setting the frequency and number of harmonics).  I\r
+  // struggled a bit to decide where best to put this and finally\r
+  // settled on here.  In general, the user shouldn't be messing with\r
+  // the number of harmonics once the oscillator is running because\r
+  // this is automatically taken care of in the setFrequency()\r
+  // function.  (GPS - 1 October 2005)\r
+  state_ = -0.5 * a_;\r
+}\r
+\r
+void BlitSaw :: updateHarmonics( void )\r
+{\r
+  if ( nHarmonics_ <= 0 ) {\r
+    unsigned int maxHarmonics = (unsigned int) floor( 0.5 * p_ );\r
+    m_ = 2 * maxHarmonics + 1;\r
+  }\r
+  else\r
+    m_ = 2 * nHarmonics_ + 1;\r
+\r
+  a_ = m_ / p_;\r
+\r
+#if defined(_STK_DEBUG_)\r
+  errorString_ << "BlitSaw::updateHarmonics: nHarmonics_ = " << nHarmonics_ << ", m_ = " << m_ << '.';\r
+  handleError( StkError::DEBUG_WARNING );\r
+#endif\r
+}\r
+\r
+} // stk namespace\r
diff --git a/lib/MoMu-STK-1.0.0/src/BlitSquare.cpp b/lib/MoMu-STK-1.0.0/src/BlitSquare.cpp
new file mode 100644 (file)
index 0000000..6d7e44a
--- /dev/null
@@ -0,0 +1,95 @@
+/***************************************************/\r
+/*! \class BlitSquare\r
+    \brief STK band-limited square wave class.\r
+\r
+    This class generates a band-limited square wave signal.  It is\r
+    derived in part from the approach reported by Stilson and Smith in\r
+    "Alias-Free Digital Synthesis of Classic Analog Waveforms", 1996.\r
+    The algorithm implemented in this class uses a SincM function with\r
+    an even M value to achieve a bipolar bandlimited impulse train.\r
+    This signal is then integrated to achieve a square waveform.  The\r
+    integration process has an associated DC offset so a DC blocking\r
+    filter is applied at the output.\r
+\r
+    The user can specify both the fundamental frequency of the\r
+    waveform and the number of harmonics contained in the resulting\r
+    signal.\r
+\r
+    If nHarmonics is 0, then the signal will contain all harmonics up\r
+    to half the sample rate.  Note, however, that this setting may\r
+    produce aliasing in the signal when the frequency is changing (no\r
+    automatic modification of the number of harmonics is performed by\r
+    the setFrequency() function).  Also note that the harmonics of a\r
+    square wave fall at odd integer multiples of the fundamental, so\r
+    aliasing will happen with a lower fundamental than with the other\r
+    Blit waveforms.  This class is not guaranteed to be well behaved\r
+    in the presence of significant aliasing.\r
+\r
+    Based on initial code of Robin Davies, 2005\r
+    Modified algorithm code by Gary Scavone, 2005 - 2010.\r
+*/\r
+/***************************************************/\r
+\r
+#include "BlitSquare.h"\r
+\r
+namespace stk {\r
+\r
+BlitSquare:: BlitSquare( StkFloat frequency )\r
+{\r
+  nHarmonics_ = 0;\r
+  this->setFrequency( frequency );\r
+  this->reset();\r
+}\r
+\r
+BlitSquare :: ~BlitSquare()\r
+{\r
+}\r
+\r
+void BlitSquare :: reset()\r
+{\r
+  phase_ = 0.0;\r
+  lastFrame_[0] = 0.0;\r
+  dcbState_ = 0.0;\r
+  lastBlitOutput_ = 0;\r
+}\r
+\r
+void BlitSquare :: setFrequency( StkFloat frequency )\r
+{\r
+#if defined(_STK_DEBUG_)\r
+  errorString_ << "BlitSquare::setFrequency: frequency = " << frequency << '.';\r
+  handleError( StkError::DEBUG_WARNING );\r
+#endif\r
+\r
+  // By using an even value of the parameter M, we get a bipolar blit\r
+  // waveform at half the blit frequency.  Thus, we need to scale the\r
+  // frequency value here by 0.5. (GPS, 2006).\r
+  p_ = 0.5 * Stk::sampleRate() / frequency;\r
+  rate_ = PI / p_;\r
+  this->updateHarmonics();\r
+}\r
+\r
+void BlitSquare :: setHarmonics( unsigned int nHarmonics )\r
+{\r
+  nHarmonics_ = nHarmonics;\r
+  this->updateHarmonics();\r
+}\r
+\r
+void BlitSquare :: updateHarmonics( void )\r
+{\r
+  // Make sure we end up with an even value of the parameter M here.\r
+  if ( nHarmonics_ <= 0 ) {\r
+    unsigned int maxHarmonics = (unsigned int) floor( 0.5 * p_ );\r
+    m_ = 2 * (maxHarmonics + 1);\r
+  }\r
+  else\r
+    m_ = 2 * (nHarmonics_ + 1);\r
+\r
+  a_ = m_ / p_;\r
+\r
+#if defined(_STK_DEBUG_)\r
+  errorString_ << "BlitSquare::updateHarmonics: nHarmonics_ = " << nHarmonics_ << ", m_ = " << m_ << '.';\r
+  handleError( StkError::DEBUG_WARNING );\r
+#endif\r
+}\r
+\r
+} // stk namespace\r
diff --git a/lib/MoMu-STK-1.0.0/src/BlowBotl.cpp b/lib/MoMu-STK-1.0.0/src/BlowBotl.cpp
new file mode 100644 (file)
index 0000000..dd60593
--- /dev/null
@@ -0,0 +1,129 @@
+/***************************************************/
+/*! \class BlowBotl
+    \brief STK blown bottle instrument class.
+
+    This class implements a helmholtz resonator
+    (biquad filter) with a polynomial jet
+    excitation (a la Cook).
+
+    Control Change Numbers: 
+       - Noise Gain = 4
+       - Vibrato Frequency = 11
+       - Vibrato Gain = 1
+       - Volume = 128
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "BlowBotl.h"
+#include "Skini_msg.h"
+
+namespace stk {
+
+#define __BOTTLE_RADIUS_ 0.999
+
+BlowBotl :: BlowBotl( void )
+{
+  dcBlock_.setBlockZero();
+
+  vibrato_.setFrequency( 5.925 );
+  vibratoGain_ = 0.0;
+
+  resonator_.setResonance(500.0, __BOTTLE_RADIUS_, true);
+  adsr_.setAllTimes( 0.005, 0.01, 0.8, 0.010);
+
+  noiseGain_ = 20.0;
+       maxPressure_ = (StkFloat) 0.0;
+}
+
+BlowBotl :: ~BlowBotl( void )
+{
+}
+
+void BlowBotl :: clear( void )
+{
+  resonator_.clear();
+}
+
+void BlowBotl :: setFrequency( StkFloat frequency )
+{
+  StkFloat freakency = frequency;
+  if ( frequency <= 0.0 ) {
+    errorString_ << "BlowBotl::setFrequency: parameter is less than or equal to zero!";
+    handleError( StkError::WARNING );
+    freakency = 220.0;
+  }
+
+  resonator_.setResonance( freakency, __BOTTLE_RADIUS_, true );
+}
+
+void BlowBotl :: startBlowing( StkFloat amplitude, StkFloat rate )
+{
+  adsr_.setAttackRate(rate);
+  maxPressure_ = amplitude;
+  adsr_.keyOn();
+}
+
+void BlowBotl :: stopBlowing( StkFloat rate )
+{
+  adsr_.setReleaseRate(rate);
+  adsr_.keyOff();
+}
+
+void BlowBotl :: noteOn( StkFloat frequency, StkFloat amplitude )
+{
+  this->setFrequency(frequency);
+  startBlowing( 1.1 + (amplitude * 0.20), amplitude * 0.02);
+  outputGain_ = amplitude + 0.001;
+
+#if defined(_STK_DEBUG_)
+  errorString_ << "BlowBotl::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << ".";
+  handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+void BlowBotl :: noteOff( StkFloat amplitude )
+{
+  this->stopBlowing(amplitude * 0.02);
+
+#if defined(_STK_DEBUG_)
+  errorString_ << "BlowBotl::NoteOff: amplitude = " << amplitude << ".";
+  handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+void BlowBotl :: controlChange( int number, StkFloat value )
+{
+  StkFloat norm = value * ONE_OVER_128;
+  if ( norm < 0 ) {
+    norm = 0.0;
+    errorString_ << "BlowBotl::controlChange: control value less than zero ... setting to zero!";
+    handleError( StkError::WARNING );
+  }
+  else if ( norm > 1.0 ) {
+    norm = 1.0;
+    errorString_ << "BlowBotl::controlChange: control value greater than 128.0 ... setting to 128.0!";
+    handleError( StkError::WARNING );
+  }
+
+  if (number == __SK_NoiseLevel_) // 4
+    noiseGain_ = norm * 30.0;
+  else if (number == __SK_ModFrequency_) // 11
+    vibrato_.setFrequency( norm * 12.0 );
+  else if (number == __SK_ModWheel_) // 1
+    vibratoGain_ = norm * 0.4;
+  else if (number == __SK_AfterTouch_Cont_) // 128
+    adsr_.setTarget( norm );
+  else {
+    errorString_ << "BlowBotl::controlChange: undefined control number (" << number << ")!";
+    handleError( StkError::WARNING );
+  }
+
+#if defined(_STK_DEBUG_)
+    errorString_ << "BlowBotl::controlChange: number = " << number << ", value = " << value << ".";
+    handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/BlowHole.cpp b/lib/MoMu-STK-1.0.0/src/BlowHole.cpp
new file mode 100644 (file)
index 0000000..6934f85
--- /dev/null
@@ -0,0 +1,224 @@
+/***************************************************/
+/*! \class BlowHole
+    \brief STK clarinet physical model with one
+           register hole and one tonehole.
+
+    This class is based on the clarinet model,
+    with the addition of a two-port register hole
+    and a three-port dynamic tonehole
+    implementation, as discussed by Scavone and
+    Cook (1998).
+
+    In this implementation, the distances between
+    the reed/register hole and tonehole/bell are
+    fixed.  As a result, both the tonehole and
+    register hole will have variable influence on
+    the playing frequency, which is dependent on
+    the length of the air column.  In addition,
+    the highest playing freqeuency is limited by
+    these fixed lengths.
+
+    This is a digital waveguide model, making its
+    use possibly subject to patents held by Stanford
+    University, Yamaha, and others.
+
+    Control Change Numbers: 
+       - Reed Stiffness = 2
+       - Noise Gain = 4
+       - Tonehole State = 11
+       - Register State = 1
+       - Breath Pressure = 128
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "BlowHole.h"
+#include "Skini_msg.h"
+#include <cmath>
+
+namespace stk {
+
+BlowHole :: BlowHole( StkFloat lowestFrequency )
+{
+  length_ = (unsigned long) ( Stk::sampleRate() / lowestFrequency + 1 );
+  // delays[0] is the delay line between the reed and the register vent.
+  delays_[0].setDelay( 5.0 * Stk::sampleRate() / 22050.0 );
+  // delays[1] is the delay line between the register vent and the tonehole.
+  delays_[1].setMaximumDelay( length_ );
+  delays_[1].setDelay( length_ >> 1 );
+  // delays[2] is the delay line between the tonehole and the end of the bore.
+  delays_[2].setDelay( 4.0 * Stk::sampleRate() / 22050.0 );
+
+  reedTable_.setOffset( 0.7 );
+  reedTable_.setSlope( -0.3 );
+
+  // Calculate the initial tonehole three-port scattering coefficient
+  StkFloat rb = 0.0075;    // main bore radius
+  StkFloat rth = 0.003;    // tonehole radius
+  scatter_ = -pow(rth,2) / ( pow(rth,2) + 2*pow(rb,2) );
+
+  // Calculate tonehole coefficients and set for initially open.
+  StkFloat te = 1.4 * rth;    // effective length of the open hole
+  thCoeff_ = (te*2*Stk::sampleRate() - 347.23) / (te*2*Stk::sampleRate() + 347.23);
+  tonehole_.setA1(-thCoeff_);
+  tonehole_.setB0(thCoeff_);
+  tonehole_.setB1(-1.0);
+
+  // Calculate register hole filter coefficients
+  double r_rh = 0.0015;    // register vent radius
+  te = 1.4 * r_rh;         // effective length of the open hole
+  double xi = 0.0;         // series resistance term
+  double zeta = 347.23 + 2*PI*pow(rb,2)*xi/1.1769;
+  double psi = 2*PI*pow(rb,2)*te / (PI*pow(r_rh,2));
+  StkFloat rhCoeff = (zeta - 2 * Stk::sampleRate() * psi) / (zeta + 2 * Stk::sampleRate() * psi);
+  rhGain_ = -347.23 / (zeta + 2 * Stk::sampleRate() * psi);
+  vent_.setA1( rhCoeff );
+  vent_.setB0(1.0);
+  vent_.setB1(1.0);
+  // Start with register vent closed
+  vent_.setGain(0.0);
+
+  vibrato_.setFrequency((StkFloat) 5.735);
+  outputGain_ = 1.0;
+  noiseGain_ = 0.2;
+  vibratoGain_ = 0.01;
+}
+
+BlowHole :: ~BlowHole( void )
+{
+}
+
+void BlowHole :: clear( void )
+{
+  delays_[0].clear();
+  delays_[1].clear();
+  delays_[2].clear();
+  filter_.tick( 0.0 );
+  tonehole_.tick( 0.0 );
+  vent_.tick( 0.0 );
+}
+
+void BlowHole :: setFrequency( StkFloat frequency )
+{
+  StkFloat freakency = frequency;
+  if ( frequency <= 0.0 ) {
+    std::cerr << "BlowHole: setFrequency parameter is less than or equal to zero!" << std::endl;
+    freakency = 220.0;
+  }
+
+  // Delay = length - approximate filter delay.
+  StkFloat delay = (Stk::sampleRate() / freakency) * 0.5 - 3.5;
+  delay -= delays_[0].getDelay() + delays_[2].getDelay();
+
+  if (delay <= 0.0) delay = 0.3;
+  else if (delay > length_) delay = length_;
+  delays_[1].setDelay(delay);
+}
+
+void BlowHole :: setVent( StkFloat newValue )
+{
+  // This method allows setting of the register vent "open-ness" at
+  // any point between "Open" (newValue = 1) and "Closed"
+  // (newValue = 0).
+
+  StkFloat gain;
+
+  if (newValue <= 0.0)
+    gain = 0.0;
+  else if (newValue >= 1.0)
+    gain = rhGain_;
+  else
+    gain = newValue * rhGain_;
+
+  vent_.setGain( gain );
+}
+
+void BlowHole :: setTonehole( StkFloat newValue )
+{
+  // This method allows setting of the tonehole "open-ness" at
+  // any point between "Open" (newValue = 1) and "Closed"
+  // (newValue = 0).
+  StkFloat new_coeff;
+
+  if ( newValue <= 0.0 )
+    new_coeff = 0.9995;
+  else if ( newValue >= 1.0 )
+    new_coeff = thCoeff_;
+  else
+    new_coeff = (newValue * (thCoeff_ - 0.9995)) + 0.9995;
+
+  tonehole_.setA1( -new_coeff );
+  tonehole_.setB0( new_coeff );
+}
+
+void BlowHole :: startBlowing( StkFloat amplitude, StkFloat rate )
+{
+  envelope_.setRate( rate );
+  envelope_.setTarget( amplitude );
+}
+
+void BlowHole :: stopBlowing( StkFloat rate )
+{
+  envelope_.setRate( rate );
+  envelope_.setTarget( 0.0 ); 
+}
+
+void BlowHole :: noteOn( StkFloat frequency, StkFloat amplitude )
+{
+  this->setFrequency( frequency );
+  this->startBlowing( 0.55 + (amplitude * 0.30), amplitude * 0.005 );
+  outputGain_ = amplitude + 0.001;
+
+#if defined(_STK_DEBUG_)
+  errorString_ << "BlowHole::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << ".";
+  handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+void BlowHole :: noteOff( StkFloat amplitude )
+{
+  this->stopBlowing( amplitude * 0.01 );
+
+#if defined(_STK_DEBUG_)
+  errorString_ << "BlowHole::NoteOff: amplitude = " << amplitude << ".";
+  handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+void BlowHole :: controlChange( int number, StkFloat value )
+{
+  StkFloat norm = value * ONE_OVER_128;
+  if ( norm < 0 ) {
+    norm = 0.0;
+    errorString_ << "BlowHole::controlChange: control value less than zero ... setting to zero!";
+    handleError( StkError::WARNING );
+  }
+  else if ( norm > 1.0 ) {
+    norm = 1.0;
+    errorString_ << "BlowHole::controlChange: control value greater than 128.0 ... setting to 128.0!";
+    handleError( StkError::WARNING );
+  }
+
+  if (number == __SK_ReedStiffness_) // 2
+    reedTable_.setSlope( -0.44 + (0.26 * norm) );
+  else if (number == __SK_NoiseLevel_) // 4
+    noiseGain_ = ( norm * 0.4);
+  else if (number == __SK_ModFrequency_) // 11
+    this->setTonehole( norm );
+  else if (number == __SK_ModWheel_) // 1
+    this->setVent( norm );
+  else if (number == __SK_AfterTouch_Cont_) // 128
+    envelope_.setValue( norm );
+  else {
+    errorString_ << "BlowHole::controlChange: undefined control number (" << number << ")!";
+    handleError( StkError::WARNING );
+  }
+
+#if defined(_STK_DEBUG_)
+    errorString_ << "BlowHole::controlChange: number = " << number << ", value = " << value << ".";
+    handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/Bowed.cpp b/lib/MoMu-STK-1.0.0/src/Bowed.cpp
new file mode 100644 (file)
index 0000000..09272a4
--- /dev/null
@@ -0,0 +1,162 @@
+/***************************************************/
+/*! \class Bowed
+    \brief STK bowed string instrument class.
+
+    This class implements a bowed string model, a
+    la Smith (1986), after McIntyre, Schumacher,
+    Woodhouse (1983).
+
+    This is a digital waveguide model, making its
+    use possibly subject to patents held by
+    Stanford University, Yamaha, and others.
+
+    Control Change Numbers: 
+       - Bow Pressure = 2
+       - Bow Position = 4
+       - Vibrato Frequency = 11
+       - Vibrato Gain = 1
+       - Volume = 128
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "Bowed.h"
+#include "Skini_msg.h"
+
+namespace stk {
+
+Bowed :: Bowed( StkFloat lowestFrequency )
+{
+  unsigned long length;
+  length = (long) ( Stk::sampleRate() / lowestFrequency + 1 );
+  neckDelay_.setMaximumDelay( length );
+  neckDelay_.setDelay( 100.0 );
+
+  length >>= 1;
+  bridgeDelay_.setMaximumDelay( length );
+  bridgeDelay_.setDelay( 29.0 );
+
+  bowTable_.setSlope(3.0 );
+
+  vibrato_.setFrequency( 6.12723 );
+  vibratoGain_ = 0.0;
+
+  stringFilter_.setPole( 0.6 - (0.1 * 22050.0 / Stk::sampleRate()) );
+  stringFilter_.setGain( 0.95 );
+
+  bodyFilter_.setResonance( 500.0, 0.85, true );
+  bodyFilter_.setGain( 0.2 );
+
+  adsr_.setAllTimes( 0.02, 0.005, 0.9, 0.01 );
+    
+  betaRatio_ = 0.127236;
+
+  // Necessary to initialize internal variables.
+  this->setFrequency( 220.0 );
+}
+
+Bowed :: ~Bowed( void )
+{
+}
+
+void Bowed :: clear( void )
+{
+  neckDelay_.clear();
+  bridgeDelay_.clear();
+}
+
+void Bowed :: setFrequency( StkFloat frequency )
+{
+  StkFloat freakency = frequency;
+  if ( frequency <= 0.0 ) {
+    errorString_ << "Bowed::setFrequency: parameter is less than or equal to zero!";
+    handleError( StkError::WARNING );
+    freakency = 220.0;
+  }
+
+  // Delay = length - approximate filter delay.
+  baseDelay_ = Stk::sampleRate() / freakency - 4.0;
+  if ( baseDelay_ <= 0.0 ) baseDelay_ = 0.3;
+  bridgeDelay_.setDelay( baseDelay_ * betaRatio_ );         // bow to bridge length
+  neckDelay_.setDelay( baseDelay_ * (1.0 - betaRatio_) );  // bow to nut (finger) length
+}
+
+void Bowed :: startBowing( StkFloat amplitude, StkFloat rate )
+{
+  adsr_.setAttackRate( rate );
+  adsr_.keyOn();
+  maxVelocity_ = 0.03 + ( 0.2 * amplitude ); 
+}
+
+void Bowed :: stopBowing( StkFloat rate )
+{
+  adsr_.setReleaseRate( rate );
+  adsr_.keyOff();
+}
+
+void Bowed :: noteOn( StkFloat frequency, StkFloat amplitude )
+{
+  this->startBowing( amplitude, amplitude * 0.001 );
+  this->setFrequency( frequency );
+
+#if defined(_STK_DEBUG_)
+  errorString_ << "Bowed::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << ".";
+  handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+void Bowed :: noteOff( StkFloat amplitude )
+{
+  this->stopBowing( (1.0 - amplitude) * 0.005 );
+
+#if defined(_STK_DEBUG_)
+  errorString_ << "Bowed::NoteOff: amplitude = " << amplitude << ".";
+  handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+void Bowed :: setVibrato( StkFloat gain )
+{
+  vibratoGain_ = gain;
+}
+
+void Bowed :: controlChange( int number, StkFloat value )
+{
+  StkFloat norm = value * ONE_OVER_128;
+  if ( norm < 0 ) {
+    norm = 0.0;
+    errorString_ << "Bowed::controlChange: control value less than zero ... setting to zero!";
+    handleError( StkError::WARNING );
+  }
+  else if ( norm > 1.0 ) {
+    norm = 1.0;
+    errorString_ << "Bowed::controlChange: control value greater than 128.0 ... setting to 128.0!";
+    handleError( StkError::WARNING );
+  }
+
+  if (number == __SK_BowPressure_) // 2
+               bowTable_.setSlope( 5.0 - (4.0 * norm) );
+  else if (number == __SK_BowPosition_) { // 4
+               betaRatio_ = 0.027236 + (0.2 * norm);
+    bridgeDelay_.setDelay( baseDelay_ * betaRatio_ );
+    neckDelay_.setDelay( baseDelay_ * (1.0 - betaRatio_) );
+  }
+  else if (number == __SK_ModFrequency_) // 11
+    vibrato_.setFrequency( norm * 12.0 );
+  else if (number == __SK_ModWheel_) // 1
+    vibratoGain_ = ( norm * 0.4 );
+  else if (number == __SK_AfterTouch_Cont_) // 128
+    adsr_.setTarget(norm);
+  else {
+    errorString_ << "Bowed::controlChange: undefined control number (" << number << ")!";
+    handleError( StkError::WARNING );
+  }
+
+#if defined(_STK_DEBUG_)
+    errorString_ << "Bowed::controlChange: number = " << number << ", value = " << value << ".";
+    handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/Brass.cpp b/lib/MoMu-STK-1.0.0/src/Brass.cpp
new file mode 100644 (file)
index 0000000..295660f
--- /dev/null
@@ -0,0 +1,162 @@
+/***************************************************/
+/*! \class Brass
+    \brief STK simple brass instrument class.
+
+    This class implements a simple brass instrument
+    waveguide model, a la Cook (TBone, HosePlayer).
+
+    This is a digital waveguide model, making its
+    use possibly subject to patents held by
+    Stanford University, Yamaha, and others.
+
+    Control Change Numbers: 
+       - Lip Tension = 2
+       - Slide Length = 4
+       - Vibrato Frequency = 11
+       - Vibrato Gain = 1
+       - Volume = 128
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "Brass.h"
+#include "Skini_msg.h"
+#include <cmath>
+
+namespace stk {
+
+Brass :: Brass( StkFloat lowestFrequency )
+{
+  length_ = (unsigned long) ( Stk::sampleRate() / lowestFrequency + 1 );
+  delayLine_.setMaximumDelay( length_ );
+  delayLine_.setDelay( 0.5 * length_ );
+
+  lipFilter_.setGain( 0.03 );
+  dcBlock_.setBlockZero();
+
+  adsr_.setAllTimes( 0.005, 0.001, 1.0, 0.010 );
+
+  vibrato_.setFrequency( 6.137 );
+  vibratoGain_ = 0.0;
+
+  this->clear();
+       maxPressure_ = 0.0;
+  lipTarget_ = 0.0;
+
+  // This is necessary to initialize variables.
+  this->setFrequency( 220.0 );
+}
+
+Brass :: ~Brass( void )
+{
+}
+
+void Brass :: clear( void )
+{
+  delayLine_.clear();
+  lipFilter_.clear();
+  dcBlock_.clear();
+}
+
+void Brass :: setFrequency( StkFloat frequency )
+{
+  StkFloat freakency = frequency;
+  if ( frequency <= 0.0 ) {
+    errorString_ << "Brass::setFrequency: parameter is less than or equal to zero!";
+    handleError( StkError::WARNING );
+    freakency = 220.0;
+  }
+
+  // Fudge correction for filter delays.
+  slideTarget_ = (Stk::sampleRate() / freakency * 2.0) + 3.0;
+  delayLine_.setDelay( slideTarget_ ); // play a harmonic
+
+  lipTarget_ = freakency;
+  lipFilter_.setResonance( freakency, 0.997 );
+}
+
+void Brass :: setLip( StkFloat frequency )
+{
+  StkFloat freakency = frequency;
+  if ( frequency <= 0.0 ) {
+    errorString_ << "Brass::setLip: parameter is less than or equal to zero!";
+    handleError( StkError::WARNING );
+    freakency = 220.0;
+  }
+
+  lipFilter_.setResonance( freakency, 0.997 );
+}
+
+void Brass :: startBlowing( StkFloat amplitude, StkFloat rate )
+{
+  adsr_.setAttackRate( rate );
+  maxPressure_ = amplitude;
+  adsr_.keyOn();
+}
+
+void Brass :: stopBlowing( StkFloat rate )
+{
+  adsr_.setReleaseRate( rate );
+  adsr_.keyOff();
+}
+
+void Brass :: noteOn( StkFloat frequency, StkFloat amplitude )
+{
+  this->setFrequency( frequency );
+  this->startBlowing( amplitude, amplitude * 0.001 );
+
+#if defined(_STK_DEBUG_)
+  errorString_ << "Brass::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << ".";
+  handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+void Brass :: noteOff( StkFloat amplitude )
+{
+  this->stopBlowing( amplitude * 0.005 );
+
+#if defined(_STK_DEBUG_)
+  errorString_ << "Brass::NoteOff: amplitude = " << amplitude << ".";
+  handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+void Brass :: controlChange( int number, StkFloat value )
+{
+  StkFloat norm = value * ONE_OVER_128;
+  if ( norm < 0 ) {
+    norm = 0.0;
+    errorString_ << "Brass::controlChange: control value less than zero ... setting to zero!";
+    handleError( StkError::WARNING );
+  }
+  else if ( norm > 1.0 ) {
+    norm = 1.0;
+    errorString_ << "Brass::controlChange: control value greater than 128.0 ... setting to 128.0!";
+    handleError( StkError::WARNING );
+  }
+
+  if (number == __SK_LipTension_)      { // 2
+    StkFloat temp = lipTarget_ * pow( 4.0, (2.0 * norm) - 1.0 );
+    this->setLip(temp);
+  }
+  else if (number == __SK_SlideLength_) // 4
+    delayLine_.setDelay( slideTarget_ * (0.5 + norm) );
+  else if (number == __SK_ModFrequency_) // 11
+    vibrato_.setFrequency( norm * 12.0 );
+  else if (number == __SK_ModWheel_ ) // 1
+    vibratoGain_ = norm * 0.4;
+  else if (number == __SK_AfterTouch_Cont_) // 128
+    adsr_.setTarget( norm );
+  else {
+    errorString_ << "Brass::controlChange: undefined control number (" << number << ")!";
+    handleError( StkError::WARNING );
+  }
+
+#if defined(_STK_DEBUG_)
+    errorString_ << "Brass::controlChange: number = " << number << ", value = " << value << ".";
+    handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/Chorus.cpp b/lib/MoMu-STK-1.0.0/src/Chorus.cpp
new file mode 100644 (file)
index 0000000..7e968ba
--- /dev/null
@@ -0,0 +1,46 @@
+/***************************************************/
+/*! \class Chorus
+    \brief STK chorus effect class.
+
+    This class implements a chorus effect.  It takes a monophonic
+    input signal and produces a stereo output signal.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "Chorus.h"
+
+namespace stk {
+
+Chorus :: Chorus( StkFloat baseDelay )
+{
+  lastFrame_.resize( 1, 2, 0.0 ); // resize lastFrame_ for stereo output
+  delayLine_[0].setMaximumDelay( (unsigned long) (baseDelay * 1.414) + 2);
+  delayLine_[0].setDelay( baseDelay );
+  delayLine_[1].setMaximumDelay( (unsigned long) (baseDelay * 1.414) + 2);
+  delayLine_[1].setDelay( baseDelay );
+  baseLength_ = baseDelay;
+
+  mods_[0].setFrequency( 0.2 );
+  mods_[1].setFrequency( 0.222222 );
+  modDepth_ = 0.05;
+  effectMix_ = 0.5;
+  this->clear();
+}
+
+void Chorus :: clear( void )
+{
+  delayLine_[0].clear();
+  delayLine_[1].clear();
+  lastFrame_[0] = 0.0;
+  lastFrame_[1] = 0.0;
+}
+
+void Chorus :: setModFrequency( StkFloat frequency )
+{
+  mods_[0].setFrequency( frequency );
+  mods_[1].setFrequency( frequency * 1.1111 );
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/Clarinet.cpp b/lib/MoMu-STK-1.0.0/src/Clarinet.cpp
new file mode 100644 (file)
index 0000000..ed38a8e
--- /dev/null
@@ -0,0 +1,139 @@
+/***************************************************/
+/*! \class Clarinet
+    \brief STK clarinet physical model class.
+
+    This class implements a simple clarinet
+    physical model, as discussed by Smith (1986),
+    McIntyre, Schumacher, Woodhouse (1983), and
+    others.
+
+    This is a digital waveguide model, making its
+    use possibly subject to patents held by Stanford
+    University, Yamaha, and others.
+
+    Control Change Numbers: 
+       - Reed Stiffness = 2
+       - Noise Gain = 4
+       - Vibrato Frequency = 11
+       - Vibrato Gain = 1
+       - Breath Pressure = 128
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "Clarinet.h"
+#include "Skini_msg.h"
+
+namespace stk {
+
+Clarinet :: Clarinet( StkFloat lowestFrequency )
+{
+  length_ = (long) (Stk::sampleRate() / lowestFrequency + 1);
+  delayLine_.setMaximumDelay( length_ );
+  delayLine_.setDelay( length_ / 2.0 );
+  reedTable_.setOffset((StkFloat) 0.7);
+  reedTable_.setSlope((StkFloat) -0.3);
+
+  vibrato_.setFrequency((StkFloat) 5.735);
+  outputGain_ = (StkFloat) 1.0;
+  noiseGain_ = (StkFloat) 0.2;
+  vibratoGain_ = (StkFloat) 0.1;
+}
+
+Clarinet :: ~Clarinet( void )
+{
+}
+
+void Clarinet :: clear( void )
+{
+  delayLine_.clear();
+  filter_.tick( 0.0 );
+}
+
+void Clarinet :: setFrequency( StkFloat frequency )
+{
+  StkFloat freakency = frequency;
+  if ( frequency <= 0.0 ) {
+    errorString_ << "Clarinet::setFrequency: parameter is less than or equal to zero!";
+    handleError( StkError::WARNING );
+    freakency = 220.0;
+  }
+
+  // Delay = length - approximate filter delay.
+  StkFloat delay = (Stk::sampleRate() / freakency) * 0.5 - 1.5;
+  if (delay <= 0.0) delay = 0.3;
+  else if (delay > length_) delay = length_;
+  delayLine_.setDelay(delay);
+}
+
+void Clarinet :: startBlowing( StkFloat amplitude, StkFloat rate )
+{
+  envelope_.setRate(rate);
+  envelope_.setTarget(amplitude); 
+}
+
+void Clarinet :: stopBlowing( StkFloat rate )
+{
+  envelope_.setRate(rate);
+  envelope_.setTarget((StkFloat) 0.0); 
+}
+
+void Clarinet :: noteOn( StkFloat frequency, StkFloat amplitude )
+{
+  this->setFrequency(frequency);
+  this->startBlowing((StkFloat) 0.55 + (amplitude * (StkFloat) 0.30), amplitude * (StkFloat) 0.005);
+  outputGain_ = amplitude + (StkFloat) 0.001;
+
+#if defined(_STK_DEBUG_)
+  errorString_ << "Clarinet::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << '.';
+  handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+void Clarinet :: noteOff( StkFloat amplitude )
+{
+  this->stopBlowing( amplitude * 0.01 );
+
+#if defined(_STK_DEBUG_)
+  errorString_ << "Clarinet::NoteOff: amplitude = " << amplitude << '.';
+  handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+void Clarinet :: controlChange( int number, StkFloat value )
+{
+  StkFloat norm = value * ONE_OVER_128;
+  if ( norm < 0 ) {
+    norm = 0.0;
+    errorString_ << "Clarinet::controlChange: control value less than zero ... setting to zero!";
+    handleError( StkError::WARNING );
+  }
+  else if ( norm > 1.0 ) {
+    norm = 1.0;
+    errorString_ << "Clarinet::controlChange: control value greater than 128.0 ... setting to 128.0!";
+    handleError( StkError::WARNING );
+  }
+
+  if (number == __SK_ReedStiffness_) // 2
+    reedTable_.setSlope((StkFloat) -0.44 + ( (StkFloat) 0.26 * norm ));
+  else if (number == __SK_NoiseLevel_) // 4
+    noiseGain_ = (norm * (StkFloat) 0.4);
+  else if (number == __SK_ModFrequency_) // 11
+    vibrato_.setFrequency((norm * (StkFloat) 12.0));
+  else if (number == __SK_ModWheel_) // 1
+    vibratoGain_ = (norm * (StkFloat) 0.5);
+  else if (number == __SK_AfterTouch_Cont_) // 128
+    envelope_.setValue(norm);
+  else {
+    errorString_ << "Clarinet::controlChange: undefined control number (" << number << ")!";
+    handleError( StkError::WARNING );
+  }
+
+#if defined(_STK_DEBUG_)
+    errorString_ << "Clarinet::controlChange: number = " << number << ", value = " << value << '.';
+    handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/Delay.cpp b/lib/MoMu-STK-1.0.0/src/Delay.cpp
new file mode 100644 (file)
index 0000000..fd3efb4
--- /dev/null
@@ -0,0 +1,130 @@
+/***************************************************/
+/*! \class Delay
+    \brief STK non-interpolating delay line class.
+
+    This class implements a non-interpolating digital delay-line.  If
+    the delay and maximum length are not specified during
+    instantiation, a fixed maximum length of 4095 and a delay of zero
+    is set.
+    
+    A non-interpolating delay line is typically used in fixed
+    delay-length applications, such as for reverberation.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "Delay.h"
+
+namespace stk {
+
+Delay :: Delay( unsigned long delay, unsigned long maxDelay )
+{
+  // Writing before reading allows delays from 0 to length-1. 
+  // If we want to allow a delay of maxDelay, we need a
+  // delay-line of length = maxDelay+1.
+  if ( maxDelay < 1 ) {
+    errorString_ << "Delay::Delay: maxDelay must be > 0!\n";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+
+  if ( delay > maxDelay ) {
+    errorString_ << "Delay::Delay: maxDelay must be > than delay argument!\n";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+
+  if ( ( maxDelay + 1 ) > inputs_.size() )
+    inputs_.resize( maxDelay + 1, 1, 0.0 );
+
+  inPoint_ = 0;
+  this->setDelay( delay );
+}
+
+Delay :: ~Delay()
+{
+}
+
+void Delay :: setMaximumDelay( unsigned long delay )
+{
+  if ( delay < inputs_.size() ) return;
+
+  if ( delay < 0 ) {
+    errorString_ << "Delay::setMaximumDelay: argument (" << delay << ") less than zero!\n";
+    handleError( StkError::WARNING );
+    return;
+  }
+  else if ( delay < delay_ ) {
+    errorString_ << "Delay::setMaximumDelay: argument (" << delay << ") less than current delay setting (" << delay_ << ")!\n";
+    handleError( StkError::WARNING );
+    return;
+  }
+
+  inputs_.resize( delay + 1 );
+}
+
+void Delay :: setDelay( unsigned long delay )
+{
+  if ( delay > inputs_.size() - 1 ) { // The value is too big.
+    errorString_ << "Delay::setDelay: argument (" << delay << ") too big ... setting to maximum!\n";
+    handleError( StkError::WARNING );
+
+    // Force delay to maximum length.
+    outPoint_ = inPoint_ + 1;
+    if ( outPoint_ == inputs_.size() ) outPoint_ = 0;
+    delay_ = inputs_.size() - 1;
+  }
+  else if ( delay < 0 ) {
+    errorString_ << "Delay::setDelay: argument (" << delay << ") less than zero ... setting to zero!\n";
+    handleError( StkError::WARNING );
+
+    outPoint_ = inPoint_;
+    delay_ = 0;
+  }
+  else { // read chases write
+    if ( inPoint_ >= delay ) outPoint_ = inPoint_ - delay;
+    else outPoint_ = inputs_.size() + inPoint_ - delay;
+    delay_ = delay;
+  }
+}
+
+StkFloat Delay :: energy( void ) const
+{
+  unsigned long i;
+  register StkFloat e = 0;
+  if ( inPoint_ >= outPoint_ ) {
+    for ( i=outPoint_; i<inPoint_; i++ ) {
+      register StkFloat t = inputs_[i];
+      e += t*t;
+    }
+  } else {
+    for ( i=outPoint_; i<inputs_.size(); i++ ) {
+      register StkFloat t = inputs_[i];
+      e += t*t;
+    }
+    for ( i=0; i<inPoint_; i++ ) {
+      register StkFloat t = inputs_[i];
+      e += t*t;
+    }
+  }
+  return e;
+}
+
+StkFloat Delay :: contentsAt( unsigned long tapDelay )
+{
+  long tap = inPoint_ - tapDelay - 1;
+  while ( tap < 0 ) // Check for wraparound.
+    tap += inputs_.size();
+
+  return inputs_[tap];
+}
+
+StkFloat Delay :: addTo( unsigned long tapDelay, StkFloat value )
+{
+  long tap = inPoint_ - tapDelay - 1;
+  while ( tap < 0 ) // Check for wraparound.
+    tap += inputs_.size();
+
+  return inputs_[tap]+= value;
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/DelayA.cpp b/lib/MoMu-STK-1.0.0/src/DelayA.cpp
new file mode 100644 (file)
index 0000000..c5d320c
--- /dev/null
@@ -0,0 +1,130 @@
+/***************************************************/
+/*! \class DelayA
+    \brief STK allpass interpolating delay line class.
+
+    This class implements a fractional-length digital delay-line using
+    a first-order allpass filter.  If the delay and maximum length are
+    not specified during instantiation, a fixed maximum length of 4095
+    and a delay of zero is set.
+
+    An allpass filter has unity magnitude gain but variable phase
+    delay properties, making it useful in achieving fractional delays
+    without affecting a signal's frequency magnitude response.  In
+    order to achieve a maximally flat phase delay response, the
+    minimum delay possible in this implementation is limited to a
+    value of 0.5.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "DelayA.h"
+
+namespace stk {
+
+DelayA :: DelayA( StkFloat delay, unsigned long maxDelay )
+{
+  if ( delay < 0.5 || maxDelay < 1 ) {
+    errorString_ << "DelayA::DelayA: delay must be >= 0.5, maxDelay must be > 0!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+
+  if ( delay > (StkFloat) maxDelay ) {
+    errorString_ << "DelayA::DelayA: maxDelay must be > than delay argument!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+
+  // Writing before reading allows delays from 0 to length-1. 
+  if ( maxDelay + 1 > inputs_.size() )
+    inputs_.resize( maxDelay + 1, 1, 0.0 );
+
+  inPoint_ = 0;
+  this->setDelay( delay );
+  apInput_ = 0.0;
+  doNextOut_ = true;
+}
+
+DelayA :: ~DelayA()
+{
+}
+
+void DelayA :: clear()
+{
+  for ( unsigned int i=0; i<inputs_.size(); i++ )
+    inputs_[i] = 0.0;
+  lastFrame_[0] = 0.0;
+  apInput_ = 0.0;
+}
+
+void DelayA :: setMaximumDelay( unsigned long delay )
+{
+  if ( delay < inputs_.size() ) return;
+
+  if ( delay < 0 ) {
+    errorString_ << "DelayA::setMaximumDelay: argument (" << delay << ") less than zero!\n";
+    handleError( StkError::WARNING );
+    return;
+  }
+  else if ( delay < delay_ ) {
+    errorString_ << "DelayA::setMaximumDelay: argument (" << delay << ") less than current delay setting (" << delay_ << ")!\n";
+    handleError( StkError::WARNING );
+    return;
+  }
+
+  inputs_.resize( delay + 1 );
+}
+
+void DelayA :: setDelay( StkFloat delay )
+{
+  StkFloat outPointer;
+  unsigned long length = inputs_.size();
+
+  if ( delay + 1 > length ) { // The value is too big.
+    errorString_ << "DelayA::setDelay: argument (" << delay << ") too big ... setting to maximum!";
+    handleError( StkError::WARNING );
+
+    // Force delay to maxLength
+    outPointer = inPoint_ + 1.0;
+    delay_ = length - 1;
+  }
+  else if ( delay < 0.5 ) {
+    errorString_ << "DelayA::setDelay: argument (" << delay << ") less than 0.5 not possible!";
+    handleError( StkError::WARNING );
+
+    outPointer = inPoint_ + 0.4999999999;
+    delay_ = 0.5;
+  }
+  else {
+    outPointer = inPoint_ - delay + 1.0;     // outPoint chases inpoint
+    delay_ = delay;
+  }
+
+  while ( outPointer < 0 )
+    outPointer += length;  // modulo maximum length
+
+  outPoint_ = (long) outPointer;         // integer part
+  if ( outPoint_ == length ) outPoint_ = 0;
+  alpha_ = 1.0 + outPoint_ - outPointer; // fractional part
+
+  if ( alpha_ < 0.5 ) {
+    // The optimal range for alpha is about 0.5 - 1.5 in order to
+    // achieve the flattest phase delay response.
+    outPoint_ += 1;
+    if (outPoint_ >= length) outPoint_ -= length;
+    alpha_ += (StkFloat) 1.0;
+  }
+
+  coeff_ = ((StkFloat) 1.0 - alpha_) / 
+    ((StkFloat) 1.0 + alpha_);         // coefficient for all pass
+}
+
+StkFloat DelayA :: contentsAt( unsigned long tapDelay )
+{
+  long tap = inPoint_ - tapDelay - 1;
+  while ( tap < 0 ) // Check for wraparound.
+    tap += inputs_.size();
+
+  return inputs_[tap];
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/DelayL.cpp b/lib/MoMu-STK-1.0.0/src/DelayL.cpp
new file mode 100644 (file)
index 0000000..02e3fbb
--- /dev/null
@@ -0,0 +1,109 @@
+/***************************************************/
+/*! \class DelayL
+    \brief STK linear interpolating delay line class.
+
+    This class implements a fractional-length digital delay-line using
+    first-order linear interpolation.  If the delay and maximum length
+    are not specified during instantiation, a fixed maximum length of
+    4095 and a delay of zero is set.
+
+    Linear interpolation is an efficient technique for achieving
+    fractional delay lengths, though it does introduce high-frequency
+    signal attenuation to varying degrees depending on the fractional
+    delay setting.  The use of higher order Lagrange interpolators can
+    typically improve (minimize) this attenuation characteristic.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "DelayL.h"
+
+namespace stk {
+
+DelayL :: DelayL( StkFloat delay, unsigned long maxDelay )
+{
+  if ( delay < 0.0 || maxDelay < 1 ) {
+    errorString_ << "DelayL::DelayL: delay must be >= 0.0, maxDelay must be > 0!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+
+  if ( delay > (StkFloat) maxDelay ) {
+    errorString_ << "DelayL::DelayL: maxDelay must be > than delay argument!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+
+  // Writing before reading allows delays from 0 to length-1. 
+  if ( maxDelay + 1 > inputs_.size() )
+    inputs_.resize( maxDelay + 1, 1, 0.0 );
+
+  inPoint_ = 0;
+  this->setDelay( delay );
+  doNextOut_ = true;
+}
+
+DelayL :: ~DelayL()
+{
+}
+
+void DelayL :: setMaximumDelay( unsigned long delay )
+{
+  if ( delay < inputs_.size() ) return;
+
+  if ( delay < 0 ) {
+    errorString_ << "DelayL::setMaximumDelay: argument (" << delay << ") less than zero!\n";
+    handleError( StkError::WARNING );
+    return;
+  }
+  else if ( delay < delay_ ) {
+    errorString_ << "DelayL::setMaximumDelay: argument (" << delay << ") less than current delay setting (" << delay_ << ")!\n";
+    handleError( StkError::WARNING );
+    return;
+  }
+
+  inputs_.resize( delay + 1 );
+}
+
+void DelayL :: setDelay( StkFloat delay )
+{
+  StkFloat outPointer;
+
+  if ( delay + 1 > inputs_.size() ) { // The value is too big.
+    errorString_ << "DelayL::setDelay: argument (" << delay << ") too big ... setting to maximum!";
+    handleError( StkError::WARNING );
+
+    // Force delay to maxLength
+    outPointer = inPoint_ + 1.0;
+    delay_ = inputs_.size() - 1;
+  }
+  else if (delay < 0 ) {
+    errorString_ << "DelayL::setDelay: argument (" << delay << ") less than zero ... setting to zero!";
+    handleError( StkError::WARNING );
+
+    outPointer = inPoint_;
+    delay_ = 0;
+  }
+  else {
+    outPointer = inPoint_ - delay;  // read chases write
+    delay_ = delay;
+  }
+
+  while (outPointer < 0)
+    outPointer += inputs_.size(); // modulo maximum length
+
+  outPoint_ = (long) outPointer;   // integer part
+  if ( outPoint_ == inputs_.size() ) outPoint_ = 0;
+  alpha_ = outPointer - outPoint_; // fractional part
+  omAlpha_ = (StkFloat) 1.0 - alpha_;
+}
+
+StkFloat DelayL :: contentsAt( unsigned long tapDelay )
+{
+  long tap = inPoint_ - tapDelay - 1;
+  while ( tap < 0 ) // Check for wraparound.
+    tap += inputs_.size();
+
+  return inputs_[tap];
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/Drummer.cpp b/lib/MoMu-STK-1.0.0/src/Drummer.cpp
new file mode 100644 (file)
index 0000000..24d5ebe
--- /dev/null
@@ -0,0 +1,160 @@
+/***************************************************/
+/*! \class Drummer
+    \brief STK drum sample player class.
+
+    This class implements a drum sampling
+    synthesizer using FileWvIn objects and one-pole
+    filters.  The drum rawwave files are sampled
+    at 22050 Hz, but will be appropriately
+    interpolated for other sample rates.  You can
+    specify the maximum polyphony (maximum number
+    of simultaneous voices) via a #define in the
+    Drummer.h.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "Drummer.h"
+#include <cmath>
+
+namespace stk {
+
+// Not really General MIDI yet.
+unsigned char genMIDIMap[128] =
+  { 0,0,0,0,0,0,0,0,           // 0-7
+    0,0,0,0,0,0,0,0,           // 8-15
+    0,0,0,0,0,0,0,0,           // 16-23
+    0,0,0,0,0,0,0,0,           // 24-31
+    0,0,0,0,1,0,2,0,           // 32-39
+    2,3,6,3,6,4,7,4,           // 40-47
+    5,8,5,0,0,0,10,0,          // 48-55
+    9,0,0,0,0,0,0,0,           // 56-63
+    0,0,0,0,0,0,0,0,           // 64-71
+    0,0,0,0,0,0,0,0,           // 72-79
+    0,0,0,0,0,0,0,0,           // 80-87
+    0,0,0,0,0,0,0,0,           // 88-95
+    0,0,0,0,0,0,0,0,           // 96-103
+    0,0,0,0,0,0,0,0,           // 104-111
+    0,0,0,0,0,0,0,0,           // 112-119
+    0,0,0,0,0,0,0,0     // 120-127
+  };
+                                 
+char waveNames[DRUM_NUMWAVES][16] =
+  { 
+    "dope.raw",
+    "bassdrum.raw",
+    "snardrum.raw",
+    "tomlowdr.raw",
+    "tommiddr.raw",
+    "tomhidrm.raw",
+    "hihatcym.raw",
+    "ridecymb.raw",
+    "crashcym.raw", 
+    "cowbell1.raw", 
+    "tambourn.raw"
+  };
+
+Drummer :: Drummer( void ) : Instrmnt()
+{
+  // This counts the number of sounding voices.
+  nSounding_ = 0;
+  soundOrder_ = std::vector<int> (DRUM_POLYPHONY, -1);
+  soundNumber_ = std::vector<int> (DRUM_POLYPHONY, -1);
+}
+
+Drummer :: ~Drummer( void )
+{
+}
+
+void Drummer :: noteOn( StkFloat instrument, StkFloat amplitude )
+{
+#if defined(_STK_DEBUG_)
+  errorString_ << "Drummer::NoteOn: instrument = " << instrument << ", amplitude = " << amplitude << '.';
+  handleError( StkError::DEBUG_WARNING );
+#endif
+
+  StkFloat gain = amplitude;
+  if ( amplitude > 1.0 ) {
+    errorString_ << "Drummer::noteOn: amplitude parameter is greater than 1.0 ... setting to 1.0!";
+    handleError( StkError::WARNING );
+    gain = 1.0;
+  }
+  else if ( amplitude < 0.0 ) {
+    errorString_ << "Drummer::noteOn: amplitude parameter is less than 0.0 ... doing nothing!";
+    handleError( StkError::WARNING );
+    return;
+  }
+
+  // Yes, this is tres kludgey.
+  //int noteNumber = (int) ( ( 12 * log( instrument / 220.0 ) / log( 2.0 ) ) + 57.01 );
+       
+       int noteNumber = (int) ( instrument + .1 );
+       
+       if( (noteNumber < 0) || (noteNumber >= DRUM_NUMWAVES) )  // MoMu Modified
+               noteNumber = 0;
+
+  // If we already have a wave of this note number loaded, just reset
+  // it.  Otherwise, look first for an unused wave or preempt the
+  // oldest if already at maximum polyphony.
+  int iWave;
+  for ( iWave=0; iWave<DRUM_POLYPHONY; iWave++ ) {
+    if ( soundNumber_[iWave] == noteNumber ) {
+      if ( waves_[iWave].isFinished() ) {
+        soundOrder_[iWave] = nSounding_;
+        nSounding_++;
+      }
+      waves_[iWave].reset();
+      filters_[iWave].setPole( 0.999 - (gain * 0.6) );
+      filters_[iWave].setGain( gain );
+      break;
+    }
+  }
+
+  if ( iWave == DRUM_POLYPHONY ) { // This note number is not currently loaded.
+    if ( nSounding_ < DRUM_POLYPHONY ) {
+      for ( iWave=0; iWave<DRUM_POLYPHONY; iWave++ )
+        if ( soundOrder_[iWave] < 0 ) break;
+      nSounding_ += 1;
+    }
+    else { // interrupt oldest voice
+      for ( iWave=0; iWave<DRUM_POLYPHONY; iWave++ )
+        if ( soundOrder_[iWave] == 0 ) break;
+      // Re-order the list.
+      for ( int j=0; j<DRUM_POLYPHONY; j++ ) {
+        if ( soundOrder_[j] > soundOrder_[iWave] )
+          soundOrder_[j] -= 1;
+      }
+    }
+    soundOrder_[iWave] = nSounding_ - 1;
+    soundNumber_[iWave] = noteNumber;
+    std::cout << "iWave = " << iWave << ", nSounding = " << nSounding_ << ", soundOrder[] = " << soundOrder_[iWave] << std::endl;
+
+    // Concatenate the STK rawwave path to the rawwave file
+         
+         std::cout<<Stk::rawwavePath()<<std::endl;  
+         std::cout<<(Stk::rawwavePath() + waveNames[ noteNumber ]).c_str()<<std::endl; 
+         
+    waves_[iWave].openFile( (Stk::rawwavePath() + waveNames[ noteNumber ]).c_str(), true );
+    if ( Stk::sampleRate() != 22050.0 )
+      waves_[iWave].setRate( 22050.0 / Stk::sampleRate() );
+    filters_[iWave].setPole( 0.999 - (gain * 0.6) );
+    filters_[iWave].setGain( gain );
+  }
+
+#if defined(_STK_DEBUG_)
+  errorString_ << "Drummer::noteOn: number sounding = " << nSounding_ << ", notes: ";
+  for ( int i=0; i<nSounding_; i++ ) errorString_ << soundNumber_[i] << "  ";
+  errorString_ << '\n';
+  handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+void Drummer :: noteOff( StkFloat amplitude )
+{
+  // Set all sounding wave filter gains low.
+  int i = 0;
+  while ( i < nSounding_ ) filters_[i++].setGain( amplitude * 0.01 );
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/Echo.cpp b/lib/MoMu-STK-1.0.0/src/Echo.cpp
new file mode 100644 (file)
index 0000000..5d75790
--- /dev/null
@@ -0,0 +1,54 @@
+/***************************************************/
+/*! \class Echo
+    \brief STK echo effect class.
+
+    This class implements an echo effect.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "Echo.h"
+#include <iostream>
+
+namespace stk {
+
+Echo :: Echo( unsigned long maximumDelay ) : Effect()
+{
+  this->setMaximumDelay( maximumDelay );
+  delayLine_.setDelay( length_ >> 1 );
+  effectMix_ = 0.5;
+  this->clear();
+}
+
+void Echo :: clear( void )
+{
+  delayLine_.clear();
+  lastFrame_[0] = 0.0;
+}
+
+void Echo :: setMaximumDelay( unsigned long delay )
+{
+  length_ = delay;
+  if ( delay == 0 ) {
+    errorString_ << "Echo::setMaximumDelay: parameter cannot be zero ... setting to 10!";
+    handleError( StkError::WARNING );
+    length_ = 10;
+  }
+
+  delayLine_.setMaximumDelay( length_ );
+}
+
+void Echo :: setDelay( unsigned long delay )
+{
+  unsigned long size = delay;
+  if ( delay > length_ ) {
+    errorString_ << "Echo::setDelay: parameter is greater than maximum delay length ... setting to max!";
+    handleError( StkError::WARNING );
+    size = length_;
+  }
+
+  delayLine_.setDelay( size );
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/Envelope.cpp b/lib/MoMu-STK-1.0.0/src/Envelope.cpp
new file mode 100644 (file)
index 0000000..2d33fe1
--- /dev/null
@@ -0,0 +1,50 @@
+/***************************************************/
+/*! \class Envelope
+    \brief STK linear line envelope class.
+
+    This class implements a simple linear line envelope generator
+    which is capable of ramping to an arbitrary target value by a
+    specified \e rate.  It also responds to simple \e keyOn and \e
+    keyOff messages, ramping to 1.0 on keyOn and to 0.0 on keyOff.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "Envelope.h"
+
+namespace stk {
+
+Envelope :: Envelope( void ) : Generator()
+{    
+  target_ = 0.0;
+  value_ = 0.0;
+  rate_ = 0.001;
+  state_ = 0;
+  Stk::addSampleRateAlert( this );
+}
+
+Envelope :: ~Envelope( void )
+{
+  Stk::removeSampleRateAlert( this );
+}
+
+Envelope& Envelope :: operator= ( const Envelope& e )
+{
+  if ( this != &e ) {
+    target_ = e.target_;
+    value_ = e.value_;
+    rate_ = e.rate_;
+    state_ = e.state_;
+  }
+
+  return *this;
+}
+
+void Envelope :: sampleRateChanged( StkFloat newRate, StkFloat oldRate )
+{
+  if ( !ignoreSampleRateChange_ )
+    rate_ = oldRate * rate_ / newRate;
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/FM.cpp b/lib/MoMu-STK-1.0.0/src/FM.cpp
new file mode 100644 (file)
index 0000000..71e7ecd
--- /dev/null
@@ -0,0 +1,197 @@
+/***************************************************/
+/*! \class FM
+    \brief STK abstract FM synthesis base class.
+
+    This class controls an arbitrary number of
+    waves and envelopes, determined via a
+    constructor argument.
+
+    Control Change Numbers: 
+       - Control One = 2
+       - Control Two = 4
+       - LFO Speed = 11
+       - LFO Depth = 1
+       - ADSR 2 & 4 Target = 128
+
+    The basic Chowning/Stanford FM patent expired
+    in 1995, but there exist follow-on patents,
+    mostly assigned to Yamaha.  If you are of the
+    type who should worry about this (making
+    money) worry away.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "FM.h"
+#include "Skini_msg.h"
+
+namespace stk {
+
+FM :: FM( unsigned int operators )
+  : nOperators_(operators)
+{
+  if ( nOperators_ == 0 ) {
+    errorString_ << "FM: Invalid number of operators (" << operators << ") argument to constructor!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+
+  twozero_.setB2( -1.0 );
+  twozero_.setGain( 0.0 );
+
+  vibrato_.setFrequency( 6.0 );
+
+  unsigned int j;
+  adsr_.resize( nOperators_ );
+  waves_.resize( nOperators_ );
+  for (j=0; j<nOperators_; j++ ) {
+    ratios_.push_back( 1.0 );
+    gains_.push_back( 1.0 );
+    adsr_[j] = new ADSR();
+  }
+
+  modDepth_ = 0.0;
+  control1_ = 1.0;
+  control2_ = 1.0;
+  baseFrequency_ = 440.0;
+
+  int i;
+  StkFloat temp = 1.0;
+  for (i=99; i>=0; i--) {
+    fmGains_[i] = temp;
+    temp *= 0.933033;
+  }
+
+  temp = 1.0;
+  for (i=15; i>=0; i--) {
+    fmSusLevels_[i] = temp;
+    temp *= 0.707101;
+  }
+
+  temp = 8.498186;
+  for (i=0; i<32; i++) {
+    fmAttTimes_[i] = temp;
+    temp *= 0.707101;
+  }
+}
+
+FM :: ~FM( void )
+{
+  for (unsigned int i=0; i<nOperators_; i++ ) {
+    delete waves_[i];
+    delete adsr_[i];
+  }
+}
+
+void FM :: loadWaves( const char **filenames )
+{
+  for (unsigned int i=0; i<nOperators_; i++ )
+    waves_[i] = new FileLoop( filenames[i], true );
+}
+
+void FM :: setFrequency( StkFloat frequency )
+{    
+  baseFrequency_ = frequency;
+
+  for ( unsigned int i=0; i<nOperators_; i++ )
+    waves_[i]->setFrequency( baseFrequency_ * ratios_[i] );
+}
+
+void FM :: setRatio( unsigned int waveIndex, StkFloat ratio )
+{
+  if ( waveIndex < 0 ) {
+    errorString_ << "FM::setRatio: waveIndex parameter is less than zero!";
+    handleError( StkError::WARNING );
+    return;
+  }
+  else if ( waveIndex >= nOperators_ ) {
+    errorString_ << "FM:setRatio: waveIndex parameter is greater than the number of operators!";
+    handleError( StkError::WARNING );
+    return;
+  }
+
+  ratios_[waveIndex] = ratio;
+  if (ratio > 0.0) 
+    waves_[waveIndex]->setFrequency( baseFrequency_ * ratio );
+  else
+    waves_[waveIndex]->setFrequency( ratio );
+}
+
+void FM :: setGain( unsigned int waveIndex, StkFloat gain )
+{
+  if ( waveIndex < 0 ) {
+    errorString_ << "FM::setGain: waveIndex parameter is less than zero!";
+    handleError( StkError::WARNING );
+    return;
+  }
+  else if ( waveIndex >= nOperators_ ) {
+    errorString_ << "FM::setGain: waveIndex parameter is greater than the number of operators!";
+    handleError( StkError::WARNING );
+    return;
+  }
+
+  gains_[waveIndex] = gain;
+}
+
+void FM :: keyOn( void )
+{
+  for ( unsigned int i=0; i<nOperators_; i++ )
+    adsr_[i]->keyOn();
+}
+
+void FM :: keyOff( void )
+{
+  for ( unsigned int i=0; i<nOperators_; i++ )
+    adsr_[i]->keyOff();
+}
+
+void FM :: noteOff( StkFloat amplitude )
+{
+  this->keyOff();
+
+#if defined(_STK_DEBUG_)
+  errorString_ << "FM::NoteOff: amplitude = " << amplitude << ".";
+  handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+void FM :: controlChange( int number, StkFloat value )
+{
+  StkFloat norm = value * ONE_OVER_128;
+  if ( norm < 0 ) {
+    norm = 0.0;
+    errorString_ << "FM::controlChange: control value less than zero ... setting to zero!";
+    handleError( StkError::WARNING );
+  }
+  else if ( norm > 1.0 ) {
+    norm = 1.0;
+    errorString_ << "FM::controlChange: control value greater than 128.0 ... setting to 128.0!";
+    handleError( StkError::WARNING );
+  }
+
+  if (number == __SK_Breath_) // 2
+    this->setControl1( norm );
+  else if (number == __SK_FootControl_) // 4
+    this->setControl2( norm );
+  else if (number == __SK_ModFrequency_) // 11
+    this->setModulationSpeed( norm * 12.0);
+  else if (number == __SK_ModWheel_) // 1
+    this->setModulationDepth( norm );
+  else if (number == __SK_AfterTouch_Cont_)    { // 128
+    //adsr_[0]->setTarget( norm );
+    adsr_[1]->setTarget( norm );
+    //adsr_[2]->setTarget( norm );
+    adsr_[3]->setTarget( norm );
+  }
+  else {
+    errorString_ << "FM::controlChange: undefined control number (" << number << ")!";
+    handleError( StkError::WARNING );
+  }
+
+#if defined(_STK_DEBUG_)
+    errorString_ << "FM::controlChange: number = " << number << ", value = " << value << '.';
+    handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/FMVoices.cpp b/lib/MoMu-STK-1.0.0/src/FMVoices.cpp
new file mode 100644 (file)
index 0000000..040c2e0
--- /dev/null
@@ -0,0 +1,169 @@
+/***************************************************/
+/*! \class FMVoices
+    \brief STK singing FM synthesis instrument.
+
+    This class implements 3 carriers and a common
+    modulator, also referred to as algorithm 6 of
+    the TX81Z.
+
+    \code
+    Algorithm 6 is :
+                        /->1 -\
+                     4-|-->2 - +-> Out
+                        \->3 -/
+    \endcode
+
+    Control Change Numbers: 
+       - Vowel = 2
+       - Spectral Tilt = 4
+       - LFO Speed = 11
+       - LFO Depth = 1
+       - ADSR 2 & 4 Target = 128
+
+    The basic Chowning/Stanford FM patent expired
+    in 1995, but there exist follow-on patents,
+    mostly assigned to Yamaha.  If you are of the
+    type who should worry about this (making
+    money) worry away.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "FMVoices.h"
+#include "Skini_msg.h"
+#include "Phonemes.h"
+
+namespace stk {
+
+FMVoices :: FMVoices( void )
+  : FM()
+{
+  // Concatenate the STK rawwave path to the rawwave files
+  for ( unsigned int i=0; i<3; i++ )
+    waves_[i] = new FileLoop( (Stk::rawwavePath() + "sinewave.raw").c_str(), true );
+  waves_[3] = new FileLoop( (Stk::rawwavePath() + "fwavblnk.raw").c_str(), true );
+
+  this->setRatio(0, 2.00);
+  this->setRatio(1, 4.00);
+  this->setRatio(2, 12.0);
+  this->setRatio(3, 1.00);
+
+  gains_[3] = fmGains_[80];
+
+  adsr_[0]->setAllTimes( 0.05, 0.05, fmSusLevels_[15], 0.05);
+  adsr_[1]->setAllTimes( 0.05, 0.05, fmSusLevels_[15], 0.05);
+  adsr_[2]->setAllTimes( 0.05, 0.05, fmSusLevels_[15], 0.05);
+  adsr_[3]->setAllTimes( 0.01, 0.01, fmSusLevels_[15], 0.5);
+
+  twozero_.setGain( 0.0 );
+  modDepth_ = (StkFloat) 0.005;
+  currentVowel_ = 0;
+  tilt_[0] = 1.0;
+  tilt_[1] = 0.5;
+  tilt_[2] = 0.2;    
+  mods_[0] = 1.0;
+  mods_[1] = 1.1;
+  mods_[2] = 1.1;
+  baseFrequency_ = 110.0;
+  this->setFrequency( 110.0 );    
+}  
+
+FMVoices :: ~FMVoices( void )
+{
+}
+
+void FMVoices :: setFrequency( StkFloat frequency )
+{
+  StkFloat temp, temp2 = 0.0;
+  int tempi = 0;
+  unsigned int i = 0;
+
+  if (currentVowel_ < 32)      {
+    i = currentVowel_;
+    temp2 = 0.9;
+  }
+  else if (currentVowel_ < 64) {
+    i = currentVowel_ - 32;
+    temp2 = 1.0;
+  }
+  else if (currentVowel_ < 96) {
+    i = currentVowel_ - 64;
+    temp2 = 1.1;
+  }
+  else if (currentVowel_ <= 128)       {
+    i = currentVowel_ - 96;
+    temp2 = 1.2;
+  }
+
+  baseFrequency_ = frequency;
+  temp = (temp2 * Phonemes::formantFrequency(i, 0) / baseFrequency_) + 0.5;
+  tempi = (int) temp;
+  this->setRatio( 0, (StkFloat) tempi );
+  temp = (temp2 * Phonemes::formantFrequency(i, 1) / baseFrequency_) + 0.5;
+  tempi = (int) temp;
+  this->setRatio( 1, (StkFloat) tempi );
+  temp = (temp2 * Phonemes::formantFrequency(i, 2) / baseFrequency_) + 0.5;
+  tempi = (int) temp;
+  this->setRatio( 2, (StkFloat) tempi );    
+  gains_[0] = 1.0;
+  gains_[1] = 1.0;
+  gains_[2] = 1.0;
+}
+
+void FMVoices :: noteOn( StkFloat frequency, StkFloat amplitude )
+{
+  this->setFrequency( frequency );
+  tilt_[0] = amplitude;
+  tilt_[1] = amplitude * amplitude;
+  tilt_[2] = tilt_[1] * amplitude;
+  this->keyOn();
+
+#if defined(_STK_DEBUG_)
+  errorString_ << "FMVoices::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << '.';
+  handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+void FMVoices :: controlChange( int number, StkFloat value )
+{
+  StkFloat norm = value * ONE_OVER_128;
+  if ( norm < 0 ) {
+    norm = 0.0;
+    errorString_ << "FMVoices::controlChange: control value less than zero ... setting to zero!";
+    handleError( StkError::WARNING );
+  }
+  else if ( norm > 1.0 ) {
+    norm = 1.0;
+    errorString_ << "FMVoices::controlChange: control value greater than 128.0 ... setting to 128.0!";
+    handleError( StkError::WARNING );
+  }
+
+
+  if (number == __SK_Breath_) // 2
+    gains_[3] = fmGains_[(int) ( norm * 99.9 )];
+  else if (number == __SK_FootControl_)        { // 4
+    currentVowel_ = (int) (norm * 128.0);
+    this->setFrequency(baseFrequency_);
+  }
+  else if (number == __SK_ModFrequency_) // 11
+    this->setModulationSpeed( norm * 12.0);
+  else if (number == __SK_ModWheel_) // 1
+    this->setModulationDepth( norm );
+  else if (number == __SK_AfterTouch_Cont_)    { // 128
+    tilt_[0] = norm;
+    tilt_[1] = norm * norm;
+    tilt_[2] = tilt_[1] * norm;
+  }
+  else {
+    errorString_ << "FMVoices::controlChange: undefined control number (" << number << ")!";
+    handleError( StkError::WARNING );
+  }
+
+#if defined(_STK_DEBUG_)
+    errorString_ << "FMVoices::controlChange: number = " << number << ", value = " << value << '.';
+    handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/FileLoop.cpp b/lib/MoMu-STK-1.0.0/src/FileLoop.cpp
new file mode 100644 (file)
index 0000000..528d057
--- /dev/null
@@ -0,0 +1,224 @@
+/***************************************************/
+/*! \class FileLoop
+    \brief STK file looping / oscillator class.
+
+    This class provides audio file looping functionality.  Any audio
+    file that can be loaded by FileRead can be looped using this
+    class.
+
+    FileLoop supports multi-channel data.  It is important to
+    distinguish the tick() method that computes a single frame (and
+    returns only the specified sample of a multi-channel frame) from
+    the overloaded one that takes an StkFrames object for
+    multi-channel and/or multi-frame data.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "FileLoop.h"
+#include <cmath>
+
+namespace stk {
+
+FileLoop :: FileLoop( unsigned long chunkThreshold, unsigned long chunkSize )
+  : FileWvIn( chunkThreshold, chunkSize ), phaseOffset_(0.0)
+{
+  Stk::addSampleRateAlert( this );
+}
+
+FileLoop :: FileLoop( std::string fileName, bool raw, bool doNormalize,
+                      unsigned long chunkThreshold, unsigned long chunkSize )
+  : FileWvIn( chunkThreshold, chunkSize ), phaseOffset_(0.0)
+{
+  this->openFile( fileName, raw, doNormalize );
+  Stk::addSampleRateAlert( this );
+}
+
+FileLoop :: ~FileLoop( void )
+{
+  Stk::removeSampleRateAlert( this );
+}
+
+void FileLoop :: openFile( std::string fileName, bool raw, bool doNormalize )
+{
+  // Call close() in case another file is already open.
+  this->closeFile();
+
+  // Attempt to open the file ... an error might be thrown here.
+  file_.open( fileName, raw );
+
+  // Determine whether chunking or not.
+  if ( file_.fileSize() > chunkThreshold_ ) {
+    chunking_ = true;
+    chunkPointer_ = 0;
+    data_.resize( chunkSize_ + 1, file_.channels() );
+    if ( doNormalize ) normalizing_ = true;
+    else normalizing_ = false;
+  }
+  else {
+    chunking_ = false;
+    data_.resize( file_.fileSize() + 1, file_.channels() );
+  }
+
+  // Load all or part of the data.
+  file_.read( data_, 0, doNormalize );
+
+  if ( chunking_ ) { // If chunking, save the first sample frame for later.
+    firstFrame_.resize( 1, data_.channels() );
+    for ( unsigned int i=0; i<data_.channels(); i++ )
+      firstFrame_[i] = data_[i];
+  }
+  else {  // If not chunking, copy the first sample frame to the last.
+    for ( unsigned int i=0; i<data_.channels(); i++ )
+      data_( data_.frames() - 1, i ) = data_[i];
+  }
+
+  // Resize our lastOutputs container.
+  lastFrame_.resize( 1, file_.channels() );
+
+  // Set default rate based on file sampling rate.
+  this->setRate( data_.dataRate() / Stk::sampleRate() );
+
+  if ( doNormalize & !chunking_ ) this->normalize();
+
+  this->reset();
+}
+
+void FileLoop :: setRate( StkFloat rate )
+{
+  rate_ = rate;
+
+  if ( fmod( rate_, 1.0 ) != 0.0 ) interpolate_ = true;
+  else interpolate_ = false;
+}
+
+void FileLoop :: addTime( StkFloat time )
+{
+  // Add an absolute time in samples.
+  time_ += time;
+
+  StkFloat fileSize = file_.fileSize();
+  while ( time_ < 0.0 )
+    time_ += fileSize;
+  while ( time_ >= fileSize )
+    time_ -= fileSize;
+}
+
+void FileLoop :: addPhase( StkFloat angle )
+{
+  // Add a time in cycles (one cycle = fileSize).
+  StkFloat fileSize = file_.fileSize();
+  time_ += fileSize * angle;
+
+  while ( time_ < 0.0 )
+    time_ += fileSize;
+  while ( time_ >= fileSize )
+    time_ -= fileSize;
+}
+
+void FileLoop :: addPhaseOffset( StkFloat angle )
+{
+  // Add a phase offset in cycles, where 1.0 = fileSize.
+  phaseOffset_ = file_.fileSize() * angle;
+}
+
+StkFloat FileLoop :: tick( unsigned int channel )
+{
+#if defined(_STK_DEBUG_)
+  if ( channel >= data_.channels() ) {
+    errorString_ << "FileLoop::tick(): channel argument and soundfile data are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  // Check limits of time address ... if necessary, recalculate modulo
+  // fileSize.
+  StkFloat fileSize = file_.fileSize();
+
+  while ( time_ < 0.0 )
+    time_ += fileSize;
+  while ( time_ >= fileSize )
+    time_ -= fileSize;
+
+  StkFloat tyme = time_;
+  if ( phaseOffset_ ) {
+    tyme += phaseOffset_;
+    while ( tyme < 0.0 )
+      tyme += fileSize;
+    while ( tyme >= fileSize )
+      tyme -= fileSize;
+  }
+
+  if ( chunking_ ) {
+
+    // Check the time address vs. our current buffer limits.
+    if ( ( time_ < (StkFloat) chunkPointer_ ) ||
+         ( time_ > (StkFloat) ( chunkPointer_ + chunkSize_ - 1 ) ) ) {
+
+      while ( time_ < (StkFloat) chunkPointer_ ) { // negative rate
+        chunkPointer_ -= chunkSize_ - 1; // overlap chunks by one frame
+        if ( chunkPointer_ < 0 ) chunkPointer_ = 0;
+      }
+      while ( time_ > (StkFloat) ( chunkPointer_ + chunkSize_ - 1 ) ) { // positive rate
+        chunkPointer_ += chunkSize_ - 1; // overlap chunks by one frame
+        if ( chunkPointer_ + chunkSize_ > file_.fileSize() ) { // at end of file
+          chunkPointer_ = file_.fileSize() - chunkSize_ + 1; // leave extra frame at end of buffer
+          // Now fill extra frame with first frame data.
+          for ( unsigned int j=0; j<firstFrame_.channels(); j++ )
+            data_( data_.frames() - 1, j ) = firstFrame_[j];
+        }
+      }
+
+      // Load more data.
+      file_.read( data_, chunkPointer_, normalizing_ );
+    }
+
+    // Adjust index for the current buffer.
+    tyme -= chunkPointer_;
+  }
+
+  if ( interpolate_ ) {
+    for ( unsigned int i=0; i<lastFrame_.size(); i++ )
+      lastFrame_[i] = data_.interpolate( tyme, i );
+  }
+  else {
+    for ( unsigned int i=0; i<lastFrame_.size(); i++ )
+      lastFrame_[i] = data_( (size_t) tyme, i );
+  }
+
+  // Increment time, which can be negative.
+  time_ += rate_;
+
+  return lastFrame_[channel];
+}
+
+StkFrames& FileLoop :: tick( StkFrames& frames )
+{
+  if ( !file_.isOpen() ) {
+#if defined(_STK_DEBUG_)
+    errorString_ << "FileLoop::tick(): no file data is loaded!";
+    handleError( StkError::WARNING );
+#endif
+    return frames;
+  }
+
+  unsigned int nChannels = lastFrame_.channels();
+#if defined(_STK_DEBUG_)
+  if ( nChannels != frames.channels() ) {
+    errorString_ << "FileLoop::tick(): StkFrames argument is incompatible with file data!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  unsigned int j, counter = 0;
+  for ( unsigned int i=0; i<frames.frames(); i++ ) {
+    this->tick();
+    for ( j=0; j<nChannels; j++ )
+      frames[counter++] = lastFrame_[j];
+  }
+
+  return frames;
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/FileRead.cpp b/lib/MoMu-STK-1.0.0/src/FileRead.cpp
new file mode 100644 (file)
index 0000000..774f417
--- /dev/null
@@ -0,0 +1,737 @@
+/***************************************************/
+/*! \class FileRead
+    \brief STK audio file input class.
+
+    This class provides input support for various
+    audio file formats.  Multi-channel (>2)
+    soundfiles are supported.  The file data is
+    returned via an external StkFrames object
+    passed to the read() function.  This class
+    does not store its own copy of the file data,
+    rather the data is read directly from disk.
+
+    FileRead currently supports uncompressed WAV,
+    AIFF/AIFC, SND (AU), MAT-file (Matlab), and
+    STK RAW file formats.  Signed integer (8-,
+    16-, and 32-bit) and floating-point (32- and
+    64-bit) data types are supported.  Compressed
+    data types are not supported.
+
+    STK RAW files have no header and are assumed
+    to contain a monophonic stream of 16-bit
+    signed integers in big-endian byte order at a
+    sample rate of 22050 Hz.  MAT-file data should
+    be saved in an array with each data channel
+    filling a matrix row.  The sample rate for
+    MAT-files is assumed to be 44100 Hz.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
+*/
+/***************************************************/
+
+#include "FileRead.h"
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <cstring>
+#include <cmath>
+#include <cstdio>
+
+namespace stk {
+
+FileRead :: FileRead()
+  : fd_(0)
+{
+}
+
+FileRead :: FileRead( std::string fileName, bool typeRaw, unsigned int nChannels,
+                      StkFormat format, StkFloat rate )
+  : fd_(0)
+{
+  open( fileName, typeRaw, nChannels, format, rate );
+}
+
+FileRead :: ~FileRead()
+{
+  if ( fd_ )
+    fclose( fd_ );
+}
+
+void FileRead :: close( void )
+{
+  if ( fd_ ) fclose( fd_ );
+  fd_ = 0;
+  wavFile_ = false;
+}
+
+bool FileRead :: isOpen( void )
+{
+  if ( fd_ ) return true;
+  else return false;
+}
+
+void FileRead :: open( std::string fileName, bool typeRaw, unsigned int nChannels,
+                       StkFormat format, StkFloat rate )
+{
+  // If another file is open, close it.
+  close();
+
+  // Try to open the file.
+  fd_ = fopen( fileName.c_str(), "rb" );
+  if ( !fd_ ) {
+    errorString_ << "FileRead::open: could not open or find file (" << fileName << ")!";
+    handleError( StkError::FILE_NOT_FOUND );
+  }
+
+  // Attempt to determine file type from header (unless RAW).
+  bool result = false;
+  if ( typeRaw )
+    result = getRawInfo( fileName.c_str(), nChannels, format, rate );
+  else {
+    char header[12];
+    if ( fread( &header, 4, 3, fd_ ) != 3 ) goto error;
+    if ( !strncmp( header, "RIFF", 4 ) &&
+         !strncmp( &header[8], "WAVE", 4 ) )
+      result = getWavInfo( fileName.c_str() );
+    else if ( !strncmp( header, ".snd", 4 ) )
+      result = getSndInfo( fileName.c_str() );
+    else if ( !strncmp( header, "FORM", 4 ) &&
+              ( !strncmp( &header[8], "AIFF", 4 ) || !strncmp(&header[8], "AIFC", 4) ) )
+      result = getAifInfo( fileName.c_str() );
+    else {
+      if ( fseek( fd_, 126, SEEK_SET ) == -1 ) goto error;
+      if ( fread( &header, 2, 1, fd_ ) != 1 ) goto error;
+      if ( !strncmp( header, "MI", 2 ) ||
+           !strncmp( header, "IM", 2 ) )
+        result = getMatInfo( fileName.c_str() );
+      else {
+        errorString_ << "FileRead::open: file (" << fileName << ") format unknown.";
+        handleError( StkError::FILE_UNKNOWN_FORMAT );
+      }
+    }
+  }
+
+  // If here, we had a file type candidate but something else went wrong.
+  if ( result == false )
+    handleError( StkError::FILE_ERROR );
+
+  // Check for empty files.
+  if ( fileSize_ == 0 ) {
+    errorString_ << "FileRead::open: file (" << fileName << ") data size is zero!";
+    handleError( StkError::FILE_ERROR );
+  }
+
+  return;
+
+ error:
+  errorString_ << "FileRead::open: error reading file (" << fileName << ")!";
+  handleError( StkError::FILE_ERROR );
+}
+
+bool FileRead :: getRawInfo( const char *fileName, unsigned int nChannels, StkFormat format, StkFloat rate )
+{
+  // Use the system call "stat" to determine the file length.
+  struct stat filestat;
+  if ( stat(fileName, &filestat) == -1 ) {
+    errorString_ << "FileRead: Could not stat RAW file (" << fileName << ").";
+    return false;
+  }
+
+  // Rawwave files have no header and by default, are assumed to
+  // contain a monophonic stream of 16-bit signed integers in
+  // big-endian byte order at a sample rate of 22050 Hz.  However,
+  // different parameters can be specified if desired.
+  dataOffset_ = 0;
+  channels_ = nChannels;
+  dataType_ = format;
+  fileRate_ = rate;
+  int sampleBytes = 0;
+  if ( format == STK_SINT8 ) sampleBytes = 1;
+  else if ( format == STK_SINT16 ) sampleBytes = 2;
+  else if ( format == STK_SINT32 || format == STK_FLOAT32 ) sampleBytes = 4;
+  else if ( format == STK_FLOAT64 ) sampleBytes = 8;
+
+  fileSize_ = (long) filestat.st_size / sampleBytes / channels_;  // length in frames
+
+  byteswap_ = false;
+#ifdef __LITTLE_ENDIAN__
+  byteswap_ = true;
+#endif
+
+  return true;
+}
+
+bool FileRead :: getWavInfo( const char *fileName )
+{
+  // Find "format" chunk ... it must come before the "data" chunk.
+  char id[4];
+  SINT32 chunkSize;
+  if ( fread(&id, 4, 1, fd_) != 1 ) goto error;
+  while ( strncmp(id, "fmt ", 4) ) {
+    if ( fread(&chunkSize, 4, 1, fd_) != 1 ) goto error;
+#ifndef __LITTLE_ENDIAN__
+    swap32((unsigned char *)&chunkSize);
+#endif
+    if ( fseek(fd_, chunkSize, SEEK_CUR) == -1 ) goto error;
+    if ( fread(&id, 4, 1, fd_) != 1 ) goto error;
+  }
+
+  // Check that the data is not compressed.
+  unsigned short format_tag;
+  if ( fread(&chunkSize, 4, 1, fd_) != 1 ) goto error; // Read fmt chunk size.
+  if ( fread(&format_tag, 2, 1, fd_) != 1 ) goto error;
+#ifndef __LITTLE_ENDIAN__
+  swap16((unsigned char *)&format_tag);
+  swap32((unsigned char *)&chunkSize);
+#endif
+  if ( format_tag == 0xFFFE ) { // WAVE_FORMAT_EXTENSIBLE
+    dataOffset_ = ftell(fd_);
+    if ( fseek(fd_, 14, SEEK_CUR) == -1 ) goto error;
+    unsigned short extSize;
+    if ( fread(&extSize, 2, 1, fd_) != 1 ) goto error;
+#ifndef __LITTLE_ENDIAN__
+    swap16((unsigned char *)&extSize);
+#endif
+    if ( extSize == 0 ) goto error;
+    if ( fseek(fd_, 6, SEEK_CUR) == -1 ) goto error;
+    if ( fread(&format_tag, 2, 1, fd_) != 1 ) goto error;
+#ifndef __LITTLE_ENDIAN__
+    swap16((unsigned char *)&format_tag);
+#endif
+    if ( fseek(fd_, dataOffset_, SEEK_SET) == -1 ) goto error;
+  }
+  if (format_tag != 1 && format_tag != 3 ) { // PCM = 1, FLOAT = 3
+    errorString_ << "FileRead: "<< fileName << " contains an unsupported data format type (" << format_tag << ").";
+    return false;
+  }
+
+  // Get number of channels from the header.
+  SINT16 temp;
+  if ( fread(&temp, 2, 1, fd_) != 1 ) goto error;
+#ifndef __LITTLE_ENDIAN__
+  swap16((unsigned char *)&temp);
+#endif
+  channels_ = (unsigned int ) temp;
+
+  // Get file sample rate from the header.
+  SINT32 srate;
+  if ( fread(&srate, 4, 1, fd_) != 1 ) goto error;
+#ifndef __LITTLE_ENDIAN__
+  swap32((unsigned char *)&srate);
+#endif
+  fileRate_ = (StkFloat) srate;
+
+  // Determine the data type.
+  dataType_ = 0;
+  if ( fseek(fd_, 6, SEEK_CUR) == -1 ) goto error;   // Locate bits_per_sample info.
+  if ( fread(&temp, 2, 1, fd_) != 1 ) goto error;
+#ifndef __LITTLE_ENDIAN__
+  swap16((unsigned char *)&temp);
+#endif
+  if ( format_tag == 1 ) {
+    if (temp == 8)
+      dataType_ = STK_SINT8;
+    else if (temp == 16)
+      dataType_ = STK_SINT16;
+    else if (temp == 32)
+      dataType_ = STK_SINT32;
+  }
+  else if ( format_tag == 3 ) {
+    if (temp == 32)
+      dataType_ = STK_FLOAT32;
+    else if (temp == 64)
+      dataType_ = STK_FLOAT64;
+  }
+  if ( dataType_ == 0 ) {
+    errorString_ << "FileRead: " << temp << " bits per sample with data format " << format_tag << " are not supported (" << fileName << ").";
+    return false;
+  }
+
+  // Jump over any remaining part of the "fmt" chunk.
+  if ( fseek(fd_, chunkSize-16, SEEK_CUR) == -1 ) goto error;
+
+  // Find "data" chunk ... it must come after the "fmt" chunk.
+  if ( fread(&id, 4, 1, fd_) != 1 ) goto error;
+
+  while ( strncmp(id, "data", 4) ) {
+    if ( fread(&chunkSize, 4, 1, fd_) != 1 ) goto error;
+#ifndef __LITTLE_ENDIAN__
+    swap32((unsigned char *)&chunkSize);
+#endif
+    chunkSize += chunkSize % 2; // chunk sizes must be even
+    if ( fseek(fd_, chunkSize, SEEK_CUR) == -1 ) goto error;
+    if ( fread(&id, 4, 1, fd_) != 1 ) goto error;
+  }
+
+  // Get length of data from the header.
+  SINT32 bytes;
+  if ( fread(&bytes, 4, 1, fd_) != 1 ) goto error;
+#ifndef __LITTLE_ENDIAN__
+  swap32((unsigned char *)&bytes);
+#endif
+  fileSize_ = 8 * bytes / temp / channels_;  // sample frames
+
+  dataOffset_ = ftell(fd_);
+  byteswap_ = false;
+#ifndef __LITTLE_ENDIAN__
+  byteswap_ = true;
+#endif
+
+  wavFile_ = true;
+  return true;
+
+ error:
+  errorString_ << "FileRead: error reading WAV file (" << fileName << ").";
+  return false;
+}
+
+bool FileRead :: getSndInfo( const char *fileName )
+{
+  // Determine the data type.
+  UINT32 format;
+  if ( fseek(fd_, 12, SEEK_SET) == -1 ) goto error;   // Locate format
+  if ( fread(&format, 4, 1, fd_) != 1 ) goto error;
+#ifdef __LITTLE_ENDIAN__
+    swap32((unsigned char *)&format);
+#endif
+  if (format == 2) dataType_ = STK_SINT8;
+  else if (format == 3) dataType_ = STK_SINT16;
+  else if (format == 4) dataType_ = STK_SINT24;
+  else if (format == 5) dataType_ = STK_SINT32;
+  else if (format == 6) dataType_ = STK_FLOAT32;
+  else if (format == 7) dataType_ = STK_FLOAT64;
+  else {
+    errorString_ << "FileRead: data format in file " << fileName << " is not supported.";
+    return false;
+  }
+
+  // Get file sample rate from the header.
+  UINT32 srate;
+  if ( fread(&srate, 4, 1, fd_) != 1 ) goto error;
+#ifdef __LITTLE_ENDIAN__
+  swap32((unsigned char *)&srate);
+#endif
+  fileRate_ = (StkFloat) srate;
+
+  // Get number of channels from the header.
+  UINT32 chans;
+  if ( fread(&chans, 4, 1, fd_) != 1 ) goto error;
+#ifdef __LITTLE_ENDIAN__
+  swap32((unsigned char *)&chans);
+#endif
+  channels_ = chans;
+
+  if ( fseek(fd_, 4, SEEK_SET) == -1 ) goto error;
+  if ( fread(&dataOffset_, 4, 1, fd_) != 1 ) goto error;
+#ifdef __LITTLE_ENDIAN__
+  swap32((unsigned char *)&dataOffset_);
+#endif
+
+  // Get length of data from the header.
+  if ( fread(&fileSize_, 4, 1, fd_) != 1 ) goto error;
+#ifdef __LITTLE_ENDIAN__
+  swap32((unsigned char *)&fileSize_);
+#endif
+  // Convert to sample frames.
+  if ( dataType_ == STK_SINT8 )
+    fileSize_ /= channels_;
+  if ( dataType_ == STK_SINT16 )
+    fileSize_ /= 2 * channels_;
+  else if ( dataType_ == STK_SINT24 )
+    fileSize_ /= 3 * channels_;
+  else if ( dataType_ == STK_SINT32 || dataType_ == STK_FLOAT32 )
+    fileSize_ /= 4 * channels_;
+  else if ( dataType_ == STK_FLOAT64 )
+    fileSize_ /= 8 * channels_;
+
+  byteswap_ = false;
+#ifdef __LITTLE_ENDIAN__
+  byteswap_ = true;
+#endif
+
+  return true;
+
+ error:
+  errorString_ << "FileRead: Error reading SND file (" << fileName << ").";
+  return false;
+}
+
+bool FileRead :: getAifInfo( const char *fileName )
+{
+  bool aifc = false;
+  char id[4];
+
+  // Determine whether this is AIFF or AIFC.
+  if ( fseek(fd_, 8, SEEK_SET) == -1 ) goto error;
+  if ( fread(&id, 4, 1, fd_) != 1 ) goto error;
+  if ( !strncmp(id, "AIFC", 4) ) aifc = true;
+
+  // Find "common" chunk
+  SINT32 chunkSize;
+  if ( fread(&id, 4, 1, fd_) != 1) goto error;
+  while ( strncmp(id, "COMM", 4) ) {
+    if ( fread(&chunkSize, 4, 1, fd_) != 1 ) goto error;
+#ifdef __LITTLE_ENDIAN__
+    swap32((unsigned char *)&chunkSize);
+#endif
+    chunkSize += chunkSize % 2; // chunk sizes must be even
+    if ( fseek(fd_, chunkSize, SEEK_CUR) == -1 ) goto error;
+    if ( fread(&id, 4, 1, fd_) != 1 ) goto error;
+  }
+
+  // Get number of channels from the header.
+  SINT16 temp;
+  if ( fseek(fd_, 4, SEEK_CUR) == -1 ) goto error; // Jump over chunk size
+  if ( fread(&temp, 2, 1, fd_) != 1 ) goto error;
+#ifdef __LITTLE_ENDIAN__
+  swap16((unsigned char *)&temp);
+#endif
+  channels_ = temp;
+
+  // Get length of data from the header.
+  SINT32 frames;
+  if ( fread(&frames, 4, 1, fd_) != 1 ) goto error;
+#ifdef __LITTLE_ENDIAN__
+  swap32((unsigned char *)&frames);
+#endif
+  fileSize_ = frames; // sample frames
+
+  // Read the number of bits per sample.
+  if ( fread(&temp, 2, 1, fd_) != 1 ) goto error;
+#ifdef __LITTLE_ENDIAN__
+  swap16((unsigned char *)&temp);
+#endif
+
+  // Get file sample rate from the header.  For AIFF files, this value
+  // is stored in a 10-byte, IEEE Standard 754 floating point number,
+  // so we need to convert it first.
+  unsigned char srate[10];
+  unsigned char exp;
+  unsigned long mantissa;
+  unsigned long last;
+  if ( fread(&srate, 10, 1, fd_) != 1 ) goto error;
+  mantissa = (unsigned long) *(unsigned long *)(srate+2);
+#ifdef __LITTLE_ENDIAN__
+  swap32((unsigned char *)&mantissa);
+#endif
+  exp = 30 - *(srate+1);
+  last = 0;
+  while (exp--) {
+    last = mantissa;
+    mantissa >>= 1;
+  }
+  if (last & 0x00000001) mantissa++;
+  fileRate_ = (StkFloat) mantissa;
+
+  // Determine the data format.
+  dataType_ = 0;
+  if ( aifc == false ) {
+    if ( temp <= 8 ) dataType_ = STK_SINT8;
+    else if ( temp <= 16 ) dataType_ = STK_SINT16;
+    else if ( temp <= 24 ) dataType_ = STK_SINT24;
+    else if ( temp <= 32 ) dataType_ = STK_SINT32;
+  }
+  else {
+    if ( fread(&id, 4, 1, fd_) != 1 ) goto error;
+    if ( !strncmp(id, "NONE", 4) ) {
+      if ( temp <= 8 ) dataType_ = STK_SINT8;
+      else if ( temp <= 16 ) dataType_ = STK_SINT16;
+      else if ( temp <= 24 ) dataType_ = STK_SINT24;
+      else if ( temp <= 32 ) dataType_ = STK_SINT32;
+    }
+    else if ( (!strncmp(id, "fl32", 4) || !strncmp(id, "FL32", 4)) && temp == 32 ) dataType_ = STK_FLOAT32;
+    else if ( (!strncmp(id, "fl64", 4) || !strncmp(id, "FL64", 4)) && temp == 64 ) dataType_ = STK_FLOAT64;
+  }
+  if ( dataType_ == 0 ) {
+    errorString_ << "FileRead: AIFF/AIFC file (" << fileName << ") has unsupported data type (" << id << ").";
+    return false;
+  }
+
+  // Start at top to find data (SSND) chunk ... chunk order is undefined.
+  if ( fseek(fd_, 12, SEEK_SET) == -1 ) goto error;
+
+  // Find data (SSND) chunk
+  if ( fread(&id, 4, 1, fd_) != 1 ) goto error;
+  while ( strncmp(id, "SSND", 4) ) {
+    if ( fread(&chunkSize, 4, 1, fd_) != 1 ) goto error;
+#ifdef __LITTLE_ENDIAN__
+    swap32((unsigned char *)&chunkSize);
+#endif
+    chunkSize += chunkSize % 2; // chunk sizes must be even
+    if ( fseek(fd_, chunkSize, SEEK_CUR) == -1 ) goto error;
+    if ( fread(&id, 4, 1, fd_) != 1 ) goto error;
+  }
+
+  // Skip over chunk size, offset, and blocksize fields
+  if ( fseek(fd_, 12, SEEK_CUR) == -1 ) goto error;
+
+  dataOffset_ = ftell(fd_);
+  byteswap_ = false;
+#ifdef __LITTLE_ENDIAN__
+  byteswap_ = true;
+#endif
+
+  return true;
+
+ error:
+  errorString_ << "FileRead: Error reading AIFF file (" << fileName << ").";
+  return false;
+}
+
+bool FileRead :: getMatInfo( const char *fileName )
+{
+  // MAT-file formatting information is available at:
+  // http://www.mathworks.com/access/helpdesk/help/pdf_doc/matlab/matfile_format.pdf
+
+  // Verify this is a version 5 MAT-file format.
+  char head[5];
+  if ( fseek(fd_, 0, SEEK_SET) == -1 ) goto error;
+  if ( fread(&head, 4, 1, fd_) != 1 ) goto error;
+  // If any of the first 4 characters of the header = 0, then this is
+  // a Version 4 MAT-file.
+  head[4] = '\0';
+  if ( strstr(head, "0") ) {
+    errorString_ << "FileRead: " << fileName << " appears to be a Version 4 MAT-file, which is not currently supported.";
+    return false;
+  }
+
+  // Determine the endian-ness of the file.
+  char mi[2];
+  byteswap_ = false;
+  // Locate "M" and "I" characters in header.
+  if ( fseek(fd_, 126, SEEK_SET) == -1 ) goto error;
+  if ( fread(&mi, 2, 1, fd_) != 1) goto error;
+#ifdef __LITTLE_ENDIAN__
+  if ( !strncmp(mi, "MI", 2) )
+    byteswap_ = true;
+  else if ( strncmp(mi, "IM", 2) ) goto error;
+#else
+  if ( !strncmp(mi, "IM", 2))
+    byteswap_ = true;
+  else if ( strncmp(mi, "MI", 2) ) goto error;
+#endif
+
+  // Check the data element type
+  SINT32 datatype;
+  if ( fread(&datatype, 4, 1, fd_) != 1 ) goto error;
+  if ( byteswap_ ) swap32((unsigned char *)&datatype);
+  if (datatype != 14) {
+    errorString_ << "FileRead: The file does not contain a single Matlab array (or matrix) data element.";
+    return false;
+  }
+
+  // Determine the array data type.
+  SINT32 tmp;
+  SINT32 size;
+  if ( fseek(fd_, 168, SEEK_SET) == -1 ) goto error;
+  if ( fread(&tmp, 4, 1, fd_) != 1 ) goto error;
+  if (byteswap_) swap32((unsigned char *)&tmp);
+  if (tmp == 1) {  // array name > 4 characters
+    if ( fread(&tmp, 4, 1, fd_) != 1 ) goto error;  // get array name length
+    if (byteswap_) swap32((unsigned char *)&tmp);
+    size = (SINT32) ceil((float)tmp / 8);
+    if ( fseek(fd_, size*8, SEEK_CUR) == -1 ) goto error;  // jump over array name
+  }
+  else { // array name <= 4 characters, compressed data element
+    if ( fseek(fd_, 4, SEEK_CUR) == -1 ) goto error;
+  }
+  if ( fread(&tmp, 4, 1, fd_) != 1 ) goto error;
+  if (byteswap_) swap32((unsigned char *)&tmp);
+  if ( tmp == 1 ) dataType_ = STK_SINT8;
+  else if ( tmp == 3 ) dataType_ = STK_SINT16;
+  else if ( tmp == 5 ) dataType_ = STK_SINT32;
+  else if ( tmp == 7 ) dataType_ = STK_FLOAT32;
+  else if ( tmp == 9 ) dataType_ = STK_FLOAT64;
+  else {
+    errorString_ << "FileRead: The MAT-file array data format (" << tmp << ") is not supported.";
+    return false;
+  }
+
+  // Get number of rows from the header.
+  SINT32 rows;
+  if ( fseek(fd_, 160, SEEK_SET) == -1 ) goto error;
+  if ( fread(&rows, 4, 1, fd_) != 1 ) goto error;
+  if (byteswap_) swap32((unsigned char *)&rows);
+
+  // Get number of columns from the header.
+  SINT32 columns;
+  if ( fread(&columns, 4, 1, fd_) != 1 ) goto error;
+  if (byteswap_) swap32((unsigned char *)&columns);
+
+  // Assume channels = smaller of rows or columns.
+  if (rows < columns) {
+    channels_ = rows;
+    fileSize_ = columns;
+  }
+  else {
+    errorString_ << "FileRead: Transpose the MAT-file array so that audio channels fill matrix rows (not columns).";
+    return false;
+  }
+
+  // Move read pointer to the data in the file.
+  SINT32 headsize;
+  if ( fseek(fd_, 132, SEEK_SET) == -1 ) goto error;
+  if ( fread(&headsize, 4, 1, fd_) != 1 ) goto error; // file size from 132nd byte
+  if (byteswap_) swap32((unsigned char *)&headsize);
+  headsize -= fileSize_ * 8 * channels_;
+  if ( fseek(fd_, headsize, SEEK_CUR) == -1 ) goto error;
+  dataOffset_ = ftell(fd_);
+
+  // Assume MAT-files have 44100 Hz sample rate.
+  fileRate_ = 44100.0;
+
+  return true;
+
+ error:
+  errorString_ << "FileRead: Error reading MAT-file (" << fileName << ").";
+  return false;
+}
+
+void FileRead :: read( StkFrames& buffer, unsigned long startFrame, bool doNormalize )
+{
+  // Make sure we have an open file.
+  if ( fd_ == 0 ) {
+    errorString_ << "FileRead::read: a file is not open!";
+    Stk::handleError( StkError::WARNING );
+    return;
+  }
+
+  // Check the buffer size.
+  unsigned int nFrames = buffer.frames();
+  if ( nFrames == 0 ) {
+    errorString_ << "FileRead::read: StkFrames buffer size is zero ... no data read!";
+    Stk::handleError( StkError::WARNING );
+    return;
+  }
+
+  if ( buffer.channels() != channels_ ) {
+    errorString_ << "FileRead::read: StkFrames argument has incompatible number of channels!";
+    Stk::handleError( StkError::FUNCTION_ARGUMENT );
+  }
+
+  // Check for file end.
+  if ( startFrame + nFrames >= fileSize_ )
+    nFrames = fileSize_ - startFrame;
+
+  long i, nSamples = (long) ( nFrames * channels_ );
+  unsigned long offset = startFrame * channels_;
+
+  // Read samples into StkFrames data buffer.
+  if ( dataType_ == STK_SINT16 ) {
+    SINT16 *buf = (SINT16 *) &buffer[0];
+    if ( fseek( fd_, dataOffset_+(offset*2), SEEK_SET ) == -1 ) goto error;
+    if ( fread( buf, nSamples * 2, 1, fd_ ) != 1 ) goto error;
+    if ( byteswap_ ) {
+      SINT16 *ptr = buf;
+      for ( i=nSamples-1; i>=0; i-- )
+        swap16( (unsigned char *) ptr++ );
+    }
+    if ( doNormalize ) {
+      StkFloat gain = 1.0 / 32768.0;
+      for ( i=nSamples-1; i>=0; i-- )
+        buffer[i] = buf[i] * gain;
+    }
+    else {
+      for ( i=nSamples-1; i>=0; i-- )
+        buffer[i] = buf[i];
+    }
+  }
+  else if ( dataType_ == STK_SINT32 ) {
+    SINT32 *buf = (SINT32 *) &buffer[0];
+    if ( fseek( fd_, dataOffset_+(offset*4 ), SEEK_SET ) == -1 ) goto error;
+    if ( fread( buf, nSamples * 4, 1, fd_ ) != 1 ) goto error;
+    if ( byteswap_ ) {
+      SINT32 *ptr = buf;
+      for ( i=nSamples-1; i>=0; i-- )
+        swap32( (unsigned char *) ptr++ );
+    }
+    if ( doNormalize ) {
+      StkFloat gain = 1.0 / 2147483648.0;
+      for ( i=nSamples-1; i>=0; i-- )
+        buffer[i] = buf[i] * gain;
+    }
+    else {
+      for ( i=nSamples-1; i>=0; i-- )
+        buffer[i] = buf[i];
+    }
+  }
+  else if ( dataType_ == STK_FLOAT32 ) {
+    FLOAT32 *buf = (FLOAT32 *) &buffer[0];
+    if ( fseek( fd_, dataOffset_+(offset*4), SEEK_SET ) == -1 ) goto error;
+    if ( fread( buf, nSamples * 4, 1, fd_ ) != 1 ) goto error;
+    if ( byteswap_ ) {
+      FLOAT32 *ptr = buf;
+      for ( i=nSamples-1; i>=0; i-- )
+        swap32( (unsigned char *) ptr++ );
+    }
+    for ( i=nSamples-1; i>=0; i-- )
+      buffer[i] = buf[i];
+  }
+  else if ( dataType_ == STK_FLOAT64 ) {
+    FLOAT64 *buf = (FLOAT64 *) &buffer[0];
+    if ( fseek( fd_, dataOffset_+(offset*8), SEEK_SET ) == -1 ) goto error;
+    if ( fread( buf, nSamples * 8, 1, fd_ ) != 1 ) goto error;
+    if ( byteswap_ ) {
+      FLOAT64 *ptr = buf;
+      for ( i=nSamples-1; i>=0; i-- )
+        swap64( (unsigned char *) ptr++ );
+    }
+    for ( i=nSamples-1; i>=0; i-- )
+      buffer[i] = buf[i];
+  }
+  else if ( dataType_ == STK_SINT8 && wavFile_ ) { // 8-bit WAV data is unsigned!
+    unsigned char *buf = (unsigned char *) &buffer[0];
+    if ( fseek( fd_, dataOffset_+offset, SEEK_SET ) == -1 ) goto error;
+    if ( fread( buf, nSamples, 1, fd_) != 1 ) goto error;
+    if ( doNormalize ) {
+      StkFloat gain = 1.0 / 128.0;
+      for ( i=nSamples-1; i>=0; i-- )
+        buffer[i] = ( buf[i] - 128 ) * gain;
+    }
+    else {
+      for ( i=nSamples-1; i>=0; i-- )
+        buffer[i] = buf[i] - 128.0;
+    }
+  }
+  else if ( dataType_ == STK_SINT8 ) { // signed 8-bit data
+    char *buf = (char *) &buffer[0];
+    if ( fseek( fd_, dataOffset_+offset, SEEK_SET ) == -1 ) goto error;
+    if ( fread( buf, nSamples, 1, fd_ ) != 1 ) goto error;
+    if ( doNormalize ) {
+      StkFloat gain = 1.0 / 128.0;
+      for ( i=nSamples-1; i>=0; i-- )
+        buffer[i] = buf[i] * gain;
+    }
+    else {
+      for ( i=nSamples-1; i>=0; i-- )
+        buffer[i] = buf[i];
+    }
+  }
+  else if ( dataType_ == STK_SINT24 ) {
+    // 24-bit values are harder to import efficiently since there is
+    // no native 24-bit type.  The following routine works but is much
+    // less efficient that that used for the other data types.
+    SINT32 buf;
+    StkFloat gain = 1.0 / 8388608.0;
+    if ( fseek(fd_, dataOffset_+(offset*3), SEEK_SET ) == -1 ) goto error;
+    for ( i=0; i<nSamples; i++ ) {
+      if ( fread( &buf, 3, 1, fd_ ) != 1 ) goto error;
+      buf >>= 8;
+      if ( byteswap_ )
+        swap32( (unsigned char *) &buf );
+      if ( doNormalize )
+        buffer[i] = buf * gain;
+      else
+        buffer[i] = buf;
+    }
+  }
+
+  buffer.setDataRate( fileRate_ );
+
+  return;
+
+ error:
+  errorString_ << "FileRead: Error reading file data.";
+  handleError( StkError::FILE_ERROR);
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/FileWrite.cpp b/lib/MoMu-STK-1.0.0/src/FileWrite.cpp
new file mode 100644 (file)
index 0000000..d50e73a
--- /dev/null
@@ -0,0 +1,707 @@
+/***************************************************/
+/*! \class FileWrite
+    \brief STK audio file output class.
+
+    This class provides output support for various
+    audio file formats.
+
+    FileWrite writes samples to an audio file.  It supports
+    multi-channel data.
+
+    FileWrite currently supports uncompressed WAV, AIFF, AIFC, SND
+    (AU), MAT-file (Matlab), and STK RAW file formats.  Signed integer
+    (8-, 16-, and 32-bit) and floating- point (32- and 64-bit) data
+    types are supported.  STK RAW files use 16-bit integers by
+    definition.  MAT-files will always be written as 64-bit floats.
+    If a data type specification does not match the specified file
+    type, the data type will automatically be modified.  Compressed
+    data types are not supported.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "FileWrite.h"
+#include <cstring>
+#include <cstdio>
+#include <cmath>
+
+namespace stk {
+
+const FileWrite::FILE_TYPE FileWrite :: FILE_RAW = 1;
+const FileWrite::FILE_TYPE FileWrite :: FILE_WAV = 2;
+const FileWrite::FILE_TYPE FileWrite :: FILE_SND = 3;
+const FileWrite::FILE_TYPE FileWrite :: FILE_AIF = 4;
+const FileWrite::FILE_TYPE FileWrite :: FILE_MAT = 5;
+
+// WAV header structure. See ftp://ftp.isi.edu/in-notes/rfc2361.txt
+// for information regarding format codes.
+struct wavhdr {
+  char riff[4];           // "RIFF"
+  SINT32 file_size;       // in bytes
+  char wave[4];           // "WAVE"
+  char fmt[4];            // "fmt "
+  SINT32 chunk_size;      // in bytes (16 for PCM)
+  SINT16 format_tag;      // 1=PCM, 2=ADPCM, 3=IEEE float, 6=A-Law, 7=Mu-Law
+  SINT16 num_chans;       // 1=mono, 2=stereo
+  SINT32 sample_rate;
+  SINT32 bytes_per_sec;
+  SINT16 bytes_per_samp;  // 2=16-bit mono, 4=16-bit stereo
+  SINT16 bits_per_samp;
+  char data[4];           // "data"
+  SINT32 data_length;     // in bytes
+};
+
+// SND (AU) header structure (NeXT and Sun).
+struct sndhdr {
+  char pref[4];
+  SINT32 hdr_length;
+  SINT32 data_length;
+  SINT32 format;
+  SINT32 sample_rate;
+  SINT32 num_channels;
+  char comment[16];
+};
+
+// AIFF/AIFC header structure ... only the part common to both
+// formats.
+struct aifhdr {
+  char form[4];                // "FORM"
+  SINT32 form_size;            // in bytes
+  char aiff[4];                // "AIFF" or "AIFC"
+  char comm[4];                // "COMM"
+  SINT32 comm_size;            // "COMM" chunk size (18 for AIFF, 24 for AIFC)
+  SINT16 num_chans;            // number of channels
+  unsigned long sample_frames; // sample frames of audio data
+  SINT16 sample_size;          // in bits
+  unsigned char srate[10];     // IEEE 754 floating point format
+};
+
+struct aifssnd {
+  char ssnd[4];               // "SSND"
+  SINT32 ssnd_size;           // "SSND" chunk size
+  unsigned long offset;       // data offset in data block (should be 0)
+  unsigned long block_size;   // not used by STK (should be 0)
+};
+
+// MAT-file 5 header structure.
+struct mathdr {
+  char heading[124];   // Header text field
+  SINT16 hff[2];       // Header flag fields
+  SINT32 adf[11];      // Array data format fields
+  // There's more, but it's of variable length
+};
+
+FileWrite :: FileWrite()
+  : fd_( 0 )
+{
+}
+
+FileWrite::FileWrite( std::string fileName, unsigned int nChannels, FILE_TYPE type, Stk::StkFormat format )
+  : fd_( 0 )
+{
+  this->open( fileName, nChannels, type, format );
+}
+
+FileWrite :: ~FileWrite()
+{
+  this->close();
+}
+
+void FileWrite :: close( void )
+{
+  if ( fd_ == 0 ) return;
+
+  if ( fileType_ == FILE_RAW )
+    fclose( fd_ );
+  else if ( fileType_ == FILE_WAV )
+    this->closeWavFile();
+  else if ( fileType_ == FILE_SND )
+    this->closeSndFile();
+  else if ( fileType_ == FILE_AIF )
+    this->closeAifFile();
+  else if ( fileType_ == FILE_MAT )
+    this->closeMatFile();
+
+  fd_ = 0;
+}
+
+bool FileWrite :: isOpen( void )
+{
+  if ( fd_ ) return true;
+  else return false;
+}
+
+void FileWrite :: open( std::string fileName, unsigned int nChannels, FileWrite::FILE_TYPE type, Stk::StkFormat format )
+{
+  // Call close() in case another file is already open.
+  this->close();
+
+  if ( nChannels < 1 ) {
+    errorString_ << "FileWrite::open: then channels argument must be greater than zero!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+
+  channels_ = nChannels;
+  fileType_ = type;
+
+  if ( format != STK_SINT8 && format != STK_SINT16 &&
+       format != STK_SINT32 && format != STK_FLOAT32 && 
+       format != STK_FLOAT64 ) {
+    errorString_ << "FileWrite::open: unknown data type (" << format << ") specified!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  } 
+  dataType_ = format;
+
+  bool result = false;
+  if ( fileType_ == FILE_RAW ) {
+    if ( channels_ != 1 ) {
+      errorString_ << "FileWrite::open: STK RAW files are, by definition, always monaural (channels = " << nChannels << " not supported)!";
+      handleError( StkError::FUNCTION_ARGUMENT );
+    }
+    result = setRawFile( fileName.c_str() );
+  }
+  else if ( fileType_ == FILE_WAV )
+    result = setWavFile( fileName.c_str() );
+  else if ( fileType_ == FILE_SND )
+    result = setSndFile( fileName.c_str() );
+  else if ( fileType_ == FILE_AIF )
+    result = setAifFile( fileName.c_str() );
+  else if ( fileType_ == FILE_MAT )
+    result = setMatFile( fileName.c_str() );
+  else {
+    errorString_ << "FileWrite::open: unknown file type (" << fileType_ << ") specified!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+
+  if ( result == false )
+    handleError( StkError::FILE_ERROR );
+
+  frameCounter_ = 0;
+}
+
+bool FileWrite :: setRawFile( const char *fileName )
+{
+  char name[8192];
+  strncpy(name, fileName, 8192);
+  if ( strstr(name, ".raw") == NULL) strcat(name, ".raw");
+  fd_ = fopen(name, "wb");
+  if ( !fd_ ) {
+    errorString_ << "FileWrite: could not create RAW file: " << name << '.';
+    return false;
+  }
+
+  if ( dataType_ != STK_SINT16 ) {
+    dataType_ = STK_SINT16;
+    errorString_ << "FileWrite: using 16-bit signed integer data format for file " << name << '.';
+    handleError( StkError::DEBUG_WARNING );
+  }
+
+  byteswap_ = false;
+#ifdef __LITTLE_ENDIAN__
+  byteswap_ = true;
+#endif
+
+  errorString_ << "FileWrite: creating RAW file: " << name;
+  handleError( StkError::STATUS );
+  return true;
+}
+
+bool FileWrite :: setWavFile( const char *fileName )
+{
+  char name[8192];
+  strncpy(name, fileName, 8192);
+  if ( strstr(name, ".wav") == NULL) strcat(name, ".wav");
+  fd_ = fopen(name, "wb");
+  if ( !fd_ ) {
+    errorString_ << "FileWrite: could not create WAV file: " << name;
+    return false;
+  }
+
+  struct wavhdr hdr = {"RIF", 44, "WAV", "fmt", 16, 1, 1,
+                        (SINT32) Stk::sampleRate(), 0, 2, 16, "dat", 0};
+  hdr.riff[3] = 'F';
+  hdr.wave[3] = 'E';
+  hdr.fmt[3]  = ' ';
+  hdr.data[3] = 'a';
+  hdr.num_chans = (SINT16) channels_;
+  if ( dataType_ == STK_SINT8 )
+    hdr.bits_per_samp = 8;
+  else if ( dataType_ == STK_SINT16 )
+    hdr.bits_per_samp = 16;
+  else if ( dataType_ == STK_SINT32 )
+    hdr.bits_per_samp = 32;
+  else if ( dataType_ == STK_FLOAT32 ) {
+    hdr.format_tag = 3;
+    hdr.bits_per_samp = 32;
+  }
+  else if ( dataType_ == STK_FLOAT64 ) {
+    hdr.format_tag = 3;
+    hdr.bits_per_samp = 64;
+  }
+  hdr.bytes_per_samp = (SINT16) (channels_ * hdr.bits_per_samp / 8);
+  hdr.bytes_per_sec = (SINT32) (hdr.sample_rate * hdr.bytes_per_samp);
+
+  byteswap_ = false;
+#ifndef __LITTLE_ENDIAN__
+  byteswap_ = true;
+  swap32((unsigned char *)&hdr.file_size);
+  swap32((unsigned char *)&hdr.chunk_size);
+  swap16((unsigned char *)&hdr.format_tag);
+  swap16((unsigned char *)&hdr.num_chans);
+  swap32((unsigned char *)&hdr.sample_rate);
+  swap32((unsigned char *)&hdr.bytes_per_sec);
+  swap16((unsigned char *)&hdr.bytes_per_samp);
+  swap16((unsigned char *)&hdr.bits_per_samp);
+#endif
+
+  if ( fwrite(&hdr, 4, 11, fd_) != 11 ) {
+    errorString_ << "FileWrite: could not write WAV header for file " << name << '.';
+    return false;
+  }
+
+  errorString_ << "FileWrite: creating WAV file: " << name;
+  handleError( StkError::STATUS );
+  return true;
+}
+
+void FileWrite :: closeWavFile( void )
+{
+  int bytes_per_sample = 1;
+  if ( dataType_ == STK_SINT16 )
+    bytes_per_sample = 2;
+  else if ( dataType_ == STK_SINT32 || dataType_ == STK_FLOAT32 )
+    bytes_per_sample = 4;
+  else if ( dataType_ == STK_FLOAT64 )
+    bytes_per_sample = 8;
+
+  SINT32 bytes = frameCounter_ * channels_ * bytes_per_sample;
+#ifndef __LITTLE_ENDIAN__
+  swap32((unsigned char *)&bytes);
+#endif
+  fseek(fd_, 40, SEEK_SET); // jump to data length
+  fwrite(&bytes, 4, 1, fd_);
+
+  bytes = frameCounter_ * channels_ * bytes_per_sample + 44;
+#ifndef __LITTLE_ENDIAN__
+  swap32((unsigned char *)&bytes);
+#endif
+  fseek(fd_, 4, SEEK_SET); // jump to file size
+  fwrite(&bytes, 4, 1, fd_);
+  fclose( fd_ );
+}
+
+bool FileWrite :: setSndFile( const char *fileName )
+{
+  char name[8192];
+  strncpy(name, fileName, 8192);
+  if ( strstr(name, ".snd") == NULL) strcat(name, ".snd");
+  fd_ = fopen(name, "wb");
+  if ( !fd_ ) {
+    errorString_ << "FileWrite: could not create SND file: " << name;
+    return false;
+  }
+
+  struct sndhdr hdr = {".sn", 40, 0, 3, (SINT32) Stk::sampleRate(), 1, "Created by STK"};
+  hdr.pref[3] = 'd';
+  hdr.num_channels = channels_;
+  if ( dataType_ == STK_SINT8 )
+    hdr.format = 2;
+  else if ( dataType_ == STK_SINT16 )
+    hdr.format = 3;
+  else if ( dataType_ == STK_SINT32 )
+    hdr.format = 5;
+  else if ( dataType_ == STK_FLOAT32 )
+    hdr.format = 6;
+  else if ( dataType_ == STK_FLOAT64 )
+    hdr.format = 7;
+
+  byteswap_ = false;
+#ifdef __LITTLE_ENDIAN__
+  byteswap_ = true;
+  swap32 ((unsigned char *)&hdr.hdr_length);
+  swap32 ((unsigned char *)&hdr.format);
+  swap32 ((unsigned char *)&hdr.sample_rate);
+  swap32 ((unsigned char *)&hdr.num_channels);
+#endif
+
+  if ( fwrite(&hdr, 4, 10, fd_) != 10 ) {
+    errorString_ << "FileWrite: Could not write SND header for file " << name << '.';
+    return false;
+  }
+
+  errorString_ << "FileWrite: creating SND file: " << name;
+  handleError( StkError::STATUS );
+  return true;
+}
+
+void FileWrite :: closeSndFile( void )
+{
+  int bytes_per_sample = 1;
+  if ( dataType_ == STK_SINT16 )
+    bytes_per_sample = 2;
+  else if ( dataType_ == STK_SINT32 )
+    bytes_per_sample = 4;
+  else if ( dataType_ == STK_FLOAT32 )
+    bytes_per_sample = 4;
+  else if ( dataType_ == STK_FLOAT64 )
+    bytes_per_sample = 8;
+
+  SINT32 bytes = frameCounter_ * bytes_per_sample * channels_;
+#ifdef __LITTLE_ENDIAN__
+  swap32 ((unsigned char *)&bytes);
+#endif
+  fseek(fd_, 8, SEEK_SET); // jump to data size
+  fwrite(&bytes, 4, 1, fd_);
+  fclose(fd_);
+}
+
+bool FileWrite :: setAifFile( const char *fileName )
+{
+  char name[8192];
+  strncpy(name, fileName, 8192);
+  if ( strstr(name, ".aif") == NULL) strcat(name, ".aif");
+  fd_ = fopen(name, "wb");
+  if ( !fd_ ) {
+    errorString_ << "FileWrite: could not create AIF file: " << name;
+    return false;
+  }
+
+  // Common parts of AIFF/AIFC header.
+  struct aifhdr hdr = {"FOR", 46, "AIF", "COM", 18, 0, 0, 16, "0"};
+  struct aifssnd ssnd = {"SSN", 8, 0, 0};
+  hdr.form[3] = 'M';
+  hdr.aiff[3] = 'F';
+  hdr.comm[3] = 'M';
+  ssnd.ssnd[3] = 'D';
+  hdr.num_chans = channels_;
+  if ( dataType_ == STK_SINT8 )
+    hdr.sample_size = 8;
+  else if ( dataType_ == STK_SINT16 )
+    hdr.sample_size = 16;
+  else if ( dataType_ == STK_SINT32 )
+    hdr.sample_size = 32;
+  else if ( dataType_ == STK_FLOAT32 ) {
+    hdr.aiff[3] = 'C';
+    hdr.sample_size = 32;
+    hdr.comm_size = 24;
+  }
+  else if ( dataType_ == STK_FLOAT64 ) {
+    hdr.aiff[3] = 'C';
+    hdr.sample_size = 64;
+    hdr.comm_size = 24;
+  }
+
+  // For AIFF files, the sample rate is stored in a 10-byte,
+  // IEEE Standard 754 floating point number, so we need to
+  // convert to that.
+  SINT16 i;
+  unsigned long exp;
+  unsigned long rate = (unsigned long) Stk::sampleRate();
+  memset(hdr.srate, 0, 10);
+  exp = rate;
+  for (i=0; i<32; i++) {
+    exp >>= 1;
+    if (!exp) break;
+  }
+  i += 16383;
+#ifdef __LITTLE_ENDIAN__
+  swap16((unsigned char *)&i);
+#endif
+  *(SINT16 *)(hdr.srate) = (SINT16) i;
+
+  for (i=32; i; i--) {
+    if (rate & 0x80000000) break;
+    rate <<= 1;
+  }
+
+#ifdef __LITTLE_ENDIAN__
+  swap32((unsigned char *)&rate);
+#endif
+  *(unsigned long *)(hdr.srate+2) = (unsigned long) rate;
+
+  byteswap_ = false;  
+#ifdef __LITTLE_ENDIAN__
+  byteswap_ = true;
+  swap32((unsigned char *)&hdr.form_size);
+  swap32((unsigned char *)&hdr.comm_size);
+  swap16((unsigned char *)&hdr.num_chans);
+  swap16((unsigned char *)&hdr.sample_size);
+  swap32((unsigned char *)&ssnd.ssnd_size);
+  swap32((unsigned char *)&ssnd.offset);
+  swap32((unsigned char *)&ssnd.block_size);
+#endif
+
+  // The structure boundaries don't allow a single write of 54 bytes.
+  if ( fwrite(&hdr, 4, 5, fd_) != 5 ) goto error;
+  if ( fwrite(&hdr.num_chans, 2, 1, fd_) != 1 ) goto error;
+  if ( fwrite(&hdr.sample_frames, 4, 1, fd_) != 1 ) goto error;
+  if ( fwrite(&hdr.sample_size, 2, 1, fd_) != 1 ) goto error;
+  if ( fwrite(&hdr.srate, 10, 1, fd_) != 1 ) goto error;
+
+  if ( dataType_ == STK_FLOAT32 ) {
+    char type[4] = {'f','l','3','2'};
+    char zeroes[2] = { 0, 0 };
+    if ( fwrite(&type, 4, 1, fd_) != 1 ) goto error;
+    if ( fwrite(&zeroes, 2, 1, fd_) != 1 ) goto error;
+  }
+  else if ( dataType_ == STK_FLOAT64 ) {
+    char type[4] = {'f','l','6','4'};
+    char zeroes[2] = { 0, 0 };
+    if ( fwrite(&type, 4, 1, fd_) != 1 ) goto error;
+    if ( fwrite(&zeroes, 2, 1, fd_) != 1 ) goto error;
+  }
+  
+  if ( fwrite(&ssnd, 4, 4, fd_) != 4 ) goto error;
+
+  errorString_ << "FileWrite: creating AIF file: " << name;
+  handleError( StkError::STATUS );
+  return true;
+
+ error:
+  errorString_ << "FileWrite: could not write AIF header for file: " << name;
+  return false;
+}
+
+void FileWrite :: closeAifFile( void )
+{
+  unsigned long frames = (unsigned long) frameCounter_;
+#ifdef __LITTLE_ENDIAN__
+  swap32((unsigned char *)&frames);
+#endif
+  fseek(fd_, 22, SEEK_SET); // jump to "COMM" sample_frames
+  fwrite(&frames, 4, 1, fd_);
+
+  int bytes_per_sample = 1;
+  if ( dataType_ == STK_SINT16 )
+    bytes_per_sample = 2;
+  else if ( dataType_ == STK_SINT32 || dataType_ == STK_FLOAT32 )
+    bytes_per_sample = 4;
+  else if ( dataType_ == STK_FLOAT64 )
+    bytes_per_sample = 8;
+
+  unsigned long bytes = frameCounter_ * bytes_per_sample * channels_ + 46;
+  if ( dataType_ == STK_FLOAT32 || dataType_ == STK_FLOAT64 ) bytes += 6;
+#ifdef __LITTLE_ENDIAN__
+  swap32((unsigned char *)&bytes);
+#endif
+  fseek(fd_, 4, SEEK_SET); // jump to file size
+  fwrite(&bytes, 4, 1, fd_);
+
+  bytes = frameCounter_ * bytes_per_sample * channels_ + 8;
+  if ( dataType_ == STK_FLOAT32 || dataType_ == STK_FLOAT64 ) bytes += 6;
+#ifdef __LITTLE_ENDIAN__
+  swap32((unsigned char *)&bytes);
+#endif
+  if ( dataType_ == STK_FLOAT32 || dataType_ == STK_FLOAT64 )
+    fseek(fd_, 48, SEEK_SET); // jump to "SSND" chunk size
+  else
+    fseek(fd_, 42, SEEK_SET); // jump to "SSND" chunk size
+  fwrite(&bytes, 4, 1, fd_);
+
+  fclose( fd_ );
+}
+
+bool FileWrite :: setMatFile( const char *fileName )
+{
+  char name[8192];
+  strncpy(name, fileName, 8192);
+  if ( strstr(name, ".mat") == NULL) strcat(name, ".mat");
+  fd_ = fopen(name, "w+b");
+  if ( !fd_ ) {
+    errorString_ << "FileWrite: could not create MAT file: " << name;
+    return false;
+  }
+
+  if ( dataType_ != STK_FLOAT64 ) {
+    dataType_ = STK_FLOAT64;
+    errorString_ << "FileWrite: using 64-bit floating-point data format for file " << name << '.';
+    handleError( StkError::DEBUG_WARNING );
+  }
+
+  struct mathdr hdr;
+  strcpy(hdr.heading,"MATLAB 5.0 MAT-file, Generated using the Synthesis ToolKit in C++ (STK). By Perry R. Cook and Gary P. Scavone.");
+
+  int i;
+  for (i=strlen(hdr.heading);i<124;i++) hdr.heading[i] = ' ';
+
+  // Header Flag Fields
+  hdr.hff[0] = (SINT16) 0x0100;   // Version field
+  hdr.hff[1] = (SINT16) 'M';      // Endian indicator field ("MI")
+  hdr.hff[1] <<= 8;
+  hdr.hff[1] += 'I';
+
+  hdr.adf[0] = (SINT32) 14;       // Matlab array data type value
+  hdr.adf[1] = (SINT32) 0;        // Size of file after this point to end (in bytes)
+                                 // Don't know size yet.
+
+  // Numeric Array Subelements (4):
+  // 1. Array Flags
+  hdr.adf[2] = (SINT32) 6;        // Matlab 32-bit unsigned integer data type value
+  hdr.adf[3] = (SINT32) 8;        // 8 bytes of data to follow
+  hdr.adf[4] = (SINT32) 6;        // Double-precision array, no array flags set
+  hdr.adf[5] = (SINT32) 0;        // 4 bytes undefined
+  // 2. Array Dimensions
+  hdr.adf[6] = (SINT32) 5;        // Matlab 32-bit signed integer data type value
+  hdr.adf[7] = (SINT32) 8;        // 8 bytes of data to follow (2D array)
+  hdr.adf[8] = (SINT32) channels_; // This is the number of rows
+  hdr.adf[9] = (SINT32) 0;        // This is the number of columns
+
+  // 3. Array Name
+  // We'll use fileName for the matlab array name (as well as the file name).
+  // If fileName is 4 characters or less, we have to use a compressed data element
+  // format for the array name data element.  Otherwise, the array name must
+  // be formatted in 8-byte increments (up to 31 characters + NULL).
+  SINT32 namelength = (SINT32) strlen(fileName);
+  if (strstr(fileName, ".mat")) namelength -= 4;
+  if (namelength > 31) namelength = 31; // Truncate name to 31 characters.
+  char arrayName[64];
+  strncpy(arrayName, fileName, namelength);
+  arrayName[namelength] = '\0';
+  if (namelength > 4) {
+    hdr.adf[10] = (SINT32) 1;        // Matlab 8-bit signed integer data type value
+  }
+  else { // Compressed data element format
+    hdr.adf[10] = namelength;
+    hdr.adf[10] <<= 16;
+    hdr.adf[10] += 1;
+  }
+  SINT32 headsize = 40;        // Number of bytes in data element so far.
+
+  // Write the fixed portion of the header
+  if ( fwrite(&hdr, 172, 1, fd_) != 1 ) goto error;
+
+  // Write MATLAB array name
+  SINT32 tmp;
+  if (namelength > 4) {
+    if ( fwrite(&namelength, 4, 1, fd_) != 1) goto error;
+    if ( fwrite(arrayName, namelength, 1, fd_) != 1 ) goto error;
+    tmp = (SINT32) ceil((float)namelength / 8);
+    if ( fseek(fd_, tmp*8-namelength, SEEK_CUR) == -1 ) goto error;
+    headsize += tmp * 8;
+  }
+  else { // Compressed data element format
+    if ( fwrite(arrayName, namelength, 1, fd_) != 1 ) goto error;
+    tmp = 4 - namelength;
+    if ( fseek(fd_, tmp, SEEK_CUR) == -1 ) goto error;
+  }
+
+  // Finish writing known header information
+  tmp = 9;        // Matlab IEEE 754 double data type
+  if ( fwrite(&tmp, 4, 1, fd_) != 1 ) goto error;
+  tmp = 0;        // Size of real part subelement in bytes (8 per sample)
+  if ( fwrite(&tmp, 4, 1, fd_) != 1 ) goto error;
+  headsize += 8;  // Total number of bytes in data element so far
+
+  if ( fseek(fd_, 132, SEEK_SET) == -1 ) goto error;
+  if ( fwrite(&headsize, 4, 1, fd_) != 1 ) goto error; // Write header size ... will update at end
+  if ( fseek(fd_, 0, SEEK_END) == -1 ) goto error;
+
+  byteswap_ = false;
+  errorString_ << "FileWrite: creating MAT-file (" << name << ") containing MATLAB array: " << arrayName;
+  handleError( StkError::STATUS );
+
+  return true;
+
+ error:
+  errorString_ << "FileWrite: could not write MAT-file header for file " << name << '.';
+  return false;
+}
+
+void FileWrite :: closeMatFile( void )
+{
+  fseek(fd_, 164, SEEK_SET); // jump to number of columns
+  fwrite(&frameCounter_, 4, 1, fd_);
+
+  SINT32 headsize, temp;
+  fseek(fd_, 132, SEEK_SET);  // jump to header size
+  fread(&headsize, 4, 1, fd_);
+  temp = headsize;
+  headsize += (SINT32) (frameCounter_ * 8 * channels_);
+  fseek(fd_, 132, SEEK_SET);
+  // Write file size (minus some header info)
+  fwrite(&headsize, 4, 1, fd_);
+
+  fseek(fd_, temp+132, SEEK_SET); // jumpt to data size (in bytes)
+  temp = frameCounter_ * 8 * channels_;
+  fwrite(&temp, 4, 1, fd_);
+
+  fclose(fd_);
+}
+
+void FileWrite :: write( StkFrames& buffer )
+{
+  if ( fd_ == 0 ) {
+    errorString_ << "FileWrite::write(): a file has not yet been opened!";
+    handleError( StkError::WARNING );
+    return;
+  }
+
+  if ( buffer.channels() != channels_ ) {
+    errorString_ << "FileWrite::write(): number of channels in the StkFrames argument does not match that specified to open() function!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+    return;
+  }
+
+  unsigned long nSamples = buffer.size();
+  if ( dataType_ == STK_SINT16 ) {
+    SINT16 sample;
+    for ( unsigned long k=0; k<nSamples; k++ ) {
+      sample = (SINT16) (buffer[k] * 32767.0);
+      //sample = ((SINT16) (( buffer[k] + 1.0 ) * 32767.5 + 0.5)) - 32768;
+      if ( byteswap_ ) swap16( (unsigned char *)&sample );
+      if ( fwrite(&sample, 2, 1, fd_) != 1 ) goto error;
+    }
+  }
+  else if ( dataType_ == STK_SINT8 ) {
+    if ( fileType_ == FILE_WAV ) { // 8-bit WAV data is unsigned!
+      unsigned char sample;
+      for ( unsigned long k=0; k<nSamples; k++ ) {
+        sample = (unsigned char) (buffer[k] * 127.0 + 128.0);
+        if ( fwrite(&sample, 1, 1, fd_) != 1 ) goto error;
+      }
+    }
+    else {
+      signed char sample;
+      for ( unsigned long k=0; k<nSamples; k++ ) {
+        sample = (signed char) (buffer[k] * 127.0);
+        //sample = ((signed char) (( buffer[k] + 1.0 ) * 127.5 + 0.5)) - 128;
+        if ( fwrite(&sample, 1, 1, fd_) != 1 ) goto error;
+      }
+    }
+  }
+  else if ( dataType_ == STK_SINT32 ) {
+    SINT32 sample;
+    for ( unsigned long k=0; k<nSamples; k++ ) {
+      sample = (SINT32) (buffer[k] * 2147483647.0);
+      //sample = ((SINT32) (( buffer[k] + 1.0 ) * 2147483647.5 + 0.5)) - 2147483648;
+      if ( byteswap_ ) swap32( (unsigned char *)&sample );
+      if ( fwrite(&sample, 4, 1, fd_) != 1 ) goto error;
+    }
+  }
+  else if ( dataType_ == STK_FLOAT32 ) {
+    FLOAT32 sample;
+    for ( unsigned long k=0; k<nSamples; k++ ) {
+      sample = (FLOAT32) (buffer[k]);
+      if ( byteswap_ ) swap32( (unsigned char *)&sample );
+      if ( fwrite(&sample, 4, 1, fd_) != 1 ) goto error;
+    }
+  }
+  else if ( dataType_ == STK_FLOAT64 ) {
+    FLOAT64 sample;
+    for ( unsigned long k=0; k<nSamples; k++ ) {
+      sample = (FLOAT64) (buffer[k]);
+      if ( byteswap_ ) swap64( (unsigned char *)&sample );
+      if ( fwrite(&sample, 8, 1, fd_) != 1 ) goto error;
+    }
+  }
+
+  frameCounter_ += buffer.frames();
+  return;
+
+ error:
+  errorString_ << "FileWrite::write(): error writing data to file!";
+  handleError( StkError::FILE_ERROR );
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/FileWvIn.cpp b/lib/MoMu-STK-1.0.0/src/FileWvIn.cpp
new file mode 100644 (file)
index 0000000..f3c38b5
--- /dev/null
@@ -0,0 +1,258 @@
+/***************************************************/
+/*! \class FileWvIn
+    \brief STK audio file input class.
+
+    This class inherits from WvIn.  It provides a "tick-level"
+    interface to the FileRead class.  It also provides variable-rate
+    playback functionality.  Audio file support is provided by the
+    FileRead class.  Linear interpolation is used for fractional read
+    rates.
+
+    FileWvIn supports multi-channel data.  It is important to
+    distinguish the tick() method that computes a single frame (and
+    returns only the specified sample of a multi-channel frame) from
+    the overloaded one that takes an StkFrames object for
+    multi-channel and/or multi-frame data.
+
+    FileWvIn will either load the entire content of an audio file into
+    local memory or incrementally read file data from disk in chunks.
+    This behavior is controlled by the optional constructor arguments
+    \e chunkThreshold and \e chunkSize.  File sizes greater than \e
+    chunkThreshold (in sample frames) will be read incrementally in
+    chunks of \e chunkSize each (also in sample frames).
+
+    When the file end is reached, subsequent calls to the tick()
+    functions return zeros and isFinished() returns \e true.
+
+    See the FileRead class for a description of the supported audio
+    file formats.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "FileWvIn.h"
+#include <cmath>
+
+namespace stk {
+
+FileWvIn :: FileWvIn( unsigned long chunkThreshold, unsigned long chunkSize )
+  : finished_(true), interpolate_(false), time_(0.0),
+    chunkThreshold_(chunkThreshold), chunkSize_(chunkSize)
+{
+  Stk::addSampleRateAlert( this );
+}
+
+FileWvIn :: FileWvIn( std::string fileName, bool raw, bool doNormalize,
+                      unsigned long chunkThreshold, unsigned long chunkSize )
+  : finished_(true), interpolate_(false), time_(0.0),
+    chunkThreshold_(chunkThreshold), chunkSize_(chunkSize)
+{
+  openFile( fileName, raw, doNormalize );
+  Stk::addSampleRateAlert( this );
+}
+
+FileWvIn :: ~FileWvIn()
+{
+  this->closeFile();
+  Stk::removeSampleRateAlert( this );
+}
+
+void FileWvIn :: sampleRateChanged( StkFloat newRate, StkFloat oldRate )
+{
+  if ( !ignoreSampleRateChange_ )
+    this->setRate( oldRate * rate_ / newRate );
+}
+
+void FileWvIn :: closeFile( void )
+{
+  if ( file_.isOpen() ) file_.close();
+  finished_ = true;
+  lastFrame_.resize( 0, 0 );
+}
+
+void FileWvIn :: openFile( std::string fileName, bool raw, bool doNormalize )
+{
+  // Call close() in case another file is already open.
+  this->closeFile();
+
+  // Attempt to open the file ... an error might be thrown here.
+  file_.open( fileName, raw );
+
+  // Determine whether chunking or not.
+  if ( file_.fileSize() > chunkThreshold_ ) {
+    chunking_ = true;
+    chunkPointer_ = 0;
+    data_.resize( chunkSize_, file_.channels() );
+    if ( doNormalize ) normalizing_ = true;
+    else normalizing_ = false;
+  }
+  else {
+    chunking_ = false;
+    data_.resize( (size_t) file_.fileSize(), file_.channels() );
+  }
+
+  // Load all or part of the data.
+  file_.read( data_, 0, doNormalize );
+
+  // Resize our lastFrame container.
+  lastFrame_.resize( 1, file_.channels() );
+
+  // Set default rate based on file sampling rate.
+  this->setRate( data_.dataRate() / Stk::sampleRate() );
+
+  if ( doNormalize & !chunking_ ) this->normalize();
+
+  this->reset();
+}
+
+void FileWvIn :: reset(void)
+{
+  time_ = (StkFloat) 0.0;
+  for ( unsigned int i=0; i<lastFrame_.size(); i++ ) lastFrame_[i] = 0.0;
+  finished_ = false;
+}
+
+void FileWvIn :: normalize(void)
+{
+  this->normalize( 1.0 );
+}
+
+// Normalize all channels equally by the greatest magnitude in all of the data.
+void FileWvIn :: normalize( StkFloat peak )
+{
+  // When chunking, the "normalization" scaling is performed by FileRead.
+  if ( chunking_ ) return;
+
+  size_t i;
+  StkFloat max = 0.0;
+
+  for ( i=0; i<data_.size(); i++ ) {
+    if ( fabs( data_[i] ) > max )
+      max = (StkFloat) fabs((double) data_[i]);
+  }
+
+  if ( max > 0.0 ) {
+    max = 1.0 / max;
+    max *= peak;
+    for ( i=0; i<data_.size(); i++ )
+      data_[i] *= max;
+  }
+}
+
+void FileWvIn :: setRate( StkFloat rate )
+{
+#if defined(_STK_DEBUG_)
+  errorString_ << "FileWvIn::setRate: changing file read rate from " << rate_ << " to " << rate << '.';
+  handleError( StkError::DEBUG_WARNING );
+#endif
+
+  rate_ = rate;
+
+  // If negative rate and at beginning of sound, move pointer to end
+  // of sound.
+  if ( (rate_ < 0) && (time_ == 0.0) ) time_ = file_.fileSize() - 1.0;
+
+  if ( fmod( rate_, 1.0 ) != 0.0 ) interpolate_ = true;
+  else interpolate_ = false;
+}
+
+void FileWvIn :: addTime( StkFloat time )   
+{
+  // Add an absolute time in samples 
+  time_ += time;
+
+  if ( time_ < 0.0 ) time_ = 0.0;
+  if ( time_ > file_.fileSize() - 1.0 ) {
+    time_ = file_.fileSize() - 1.0;
+    for ( unsigned int i=0; i<lastFrame_.size(); i++ ) lastFrame_[i] = 0.0;
+    finished_ = true;
+  }
+}
+
+StkFloat FileWvIn :: tick( unsigned int channel )
+{
+#if defined(_STK_DEBUG_)
+  if ( channel >= data_.channels() ) {
+    errorString_ << "FileWvIn::tick(): channel argument and soundfile data are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  if ( finished_ ) return 0.0;
+
+  if ( time_ < 0.0 || time_ > (StkFloat) ( file_.fileSize() - 1.0 ) ) {
+    for ( unsigned int i=0; i<lastFrame_.size(); i++ ) lastFrame_[i] = 0.0;
+    finished_ = true;
+    return 0.0;
+  }
+
+  StkFloat tyme = time_;
+  if ( chunking_ ) {
+
+    // Check the time address vs. our current buffer limits.
+    if ( ( time_ < (StkFloat) chunkPointer_ ) ||
+         ( time_ > (StkFloat) ( chunkPointer_ + chunkSize_ - 1 ) ) ) {
+
+      while ( time_ < (StkFloat) chunkPointer_ ) { // negative rate
+        chunkPointer_ -= chunkSize_ - 1; // overlap chunks by one frame
+        if ( chunkPointer_ < 0 ) chunkPointer_ = 0;
+      }
+      while ( time_ > (StkFloat) ( chunkPointer_ + chunkSize_ - 1 ) ) { // positive rate
+        chunkPointer_ += chunkSize_ - 1; // overlap chunks by one frame
+        if ( chunkPointer_ + chunkSize_ > file_.fileSize() ) // at end of file
+          chunkPointer_ = file_.fileSize() - chunkSize_;
+      }
+
+      // Load more data.
+      file_.read( data_, chunkPointer_, normalizing_ );
+    }
+
+    // Adjust index for the current buffer.
+    tyme -= chunkPointer_;
+  }
+
+  if ( interpolate_ ) {
+    for ( unsigned int i=0; i<lastFrame_.size(); i++ )
+      lastFrame_[i] = data_.interpolate( tyme, i );
+  }
+  else {
+    for ( unsigned int i=0; i<lastFrame_.size(); i++ )
+      lastFrame_[i] = data_( (size_t) tyme, i );
+  }
+
+  // Increment time, which can be negative.
+  time_ += rate_;
+
+  return lastFrame_[channel];
+}
+
+StkFrames& FileWvIn :: tick( StkFrames& frames )
+{
+  if ( !file_.isOpen() ) {
+#if defined(_STK_DEBUG_)
+    errorString_ << "FileWvIn::tick(): no file data is loaded!";
+    handleError( StkError::DEBUG_WARNING );
+#endif
+    return frames;
+  }
+
+  unsigned int nChannels = lastFrame_.channels();
+#if defined(_STK_DEBUG_)
+  if ( nChannels != frames.channels() ) {
+    errorString_ << "FileWvIn::tick(): StkFrames argument is incompatible with file data!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  unsigned int j, counter = 0;
+  for ( unsigned int i=0; i<frames.frames(); i++ ) {
+    this->tick();
+    for ( j=0; j<nChannels; j++ )
+      frames[counter++] = lastFrame_[j];
+  }
+
+  return frames;
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/FileWvOut.cpp b/lib/MoMu-STK-1.0.0/src/FileWvOut.cpp
new file mode 100644 (file)
index 0000000..04ee5c5
--- /dev/null
@@ -0,0 +1,140 @@
+/***************************************************/
+/*! \class FileWvOut
+    \brief STK audio file output class.
+
+    This class inherits from WvOut.  It provides a "tick-level"
+    interface to the FileWrite class.
+
+    FileWvOut writes samples to an audio file and supports
+    multi-channel data.  It is important to distinguish the tick()
+    method that outputs a single sample to all channels in a sample
+    frame from the overloaded one that takes a reference to an
+    StkFrames object for multi-channel and/or multi-frame data.
+
+    See the FileWrite class for a description of the supported audio
+    file formats.
+
+    Currently, FileWvOut is non-interpolating and the output rate is
+    always Stk::sampleRate().
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "FileWvOut.h"
+
+namespace stk {
+
+FileWvOut :: FileWvOut( unsigned int bufferFrames )
+  :bufferFrames_( bufferFrames )
+{
+}
+
+FileWvOut::FileWvOut( std::string fileName, unsigned int nChannels, FileWrite::FILE_TYPE type, Stk::StkFormat format, unsigned int bufferFrames )
+  :bufferFrames_( bufferFrames )
+{
+  this->openFile( fileName, nChannels, type, format );
+}
+
+FileWvOut :: ~FileWvOut()
+{
+  this->closeFile();
+}
+
+void FileWvOut :: closeFile( void )
+{
+  if ( file_.isOpen() ) {
+
+    // Output any remaining samples in the buffer before closing.
+    if ( bufferIndex_ > 0 ) {
+      data_.resize( bufferIndex_, data_.channels() );
+      file_.write( data_ );
+    }
+
+    file_.close();
+    frameCounter_ = 0;
+  }
+}
+
+void FileWvOut :: openFile( std::string fileName,
+                            unsigned int nChannels,
+                            FileWrite::FILE_TYPE type,
+                            Stk::StkFormat format )
+{
+  closeFile();
+
+  if ( nChannels < 1 ) {
+    errorString_ << "FileWvOut::openFile: the channels argument must be greater than zero!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+
+  // An StkError can be thrown by the FileWrite class here.
+  file_.open( fileName, nChannels, type, format );
+
+  // Allocate new memory if necessary.
+  data_.resize( bufferFrames_, nChannels );
+
+  bufferIndex_ = 0;
+  iData_ = 0;
+}
+
+void FileWvOut :: incrementFrame( void )
+{
+  frameCounter_++;
+  bufferIndex_++;
+
+  if ( bufferIndex_ == bufferFrames_ ) {
+    file_.write( data_ );
+    bufferIndex_ = 0;
+    iData_ = 0;
+  }
+}
+
+void FileWvOut :: tick( const StkFloat sample )
+{
+#if defined(_STK_DEBUG_)
+  if ( !file_.isOpen() ) {
+    errorString_ << "FileWvOut::tick(): no file open!";
+    handleError( StkError::WARNING );
+    return;
+  }
+#endif
+
+  unsigned int nChannels = data_.channels();
+  StkFloat input = sample;
+  clipTest( input );
+  for ( unsigned int j=0; j<nChannels; j++ )
+    data_[iData_++] = input;
+
+  this->incrementFrame();
+}
+
+void FileWvOut :: tick( const StkFrames& frames )
+{
+#if defined(_STK_DEBUG_)
+  if ( !file_.isOpen() ) {
+    errorString_ << "FileWvOut::tick(): no file open!";
+    handleError( StkError::WARNING );
+    return;
+  }
+
+  if ( data_.channels() != frames.channels() ) {
+    errorString_ << "FileWvOut::tick(): incompatible channel value in StkFrames argument!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  unsigned int iFrames = 0;
+  unsigned int j, nChannels = data_.channels();
+  for ( unsigned int i=0; i<frames.frames(); i++ ) {
+
+    for ( j=0; j<nChannels; j++ ) {
+      data_[iData_] = frames[iFrames++];
+      clipTest( data_[iData_++] );
+    }
+
+    this->incrementFrame();
+  }
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/Fir.cpp b/lib/MoMu-STK-1.0.0/src/Fir.cpp
new file mode 100644 (file)
index 0000000..2465009
--- /dev/null
@@ -0,0 +1,73 @@
+/***************************************************/
+/*! \class Fir
+    \brief STK general finite impulse response filter class.
+
+    This class provides a generic digital filter structure that can be
+    used to implement FIR filters.  For filters with feedback terms,
+    the Iir class should be used.
+
+    In particular, this class implements the standard difference
+    equation:
+
+    y[n] = b[0]*x[n] + ... + b[nb]*x[n-nb]
+
+    The \e gain parameter is applied at the filter input and does not
+    affect the coefficient values.  The default gain value is 1.0.
+    This structure results in one extra multiply per computed sample,
+    but allows easy control of the overall filter gain.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "Fir.h"
+
+namespace stk {
+
+Fir :: Fir()
+{
+  // The default constructor should setup for pass-through.
+  b_.push_back( 1.0 );
+
+  inputs_.resize( 1, 1, 0.0 );
+}
+
+Fir :: Fir( std::vector<StkFloat> &coefficients )
+{
+  // Check the arguments.
+  if ( coefficients.size() == 0 ) {
+    errorString_ << "Fir: coefficient vector must have size > 0!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+
+  gain_ = 1.0;
+  b_ = coefficients;
+
+  inputs_.resize( b_.size(), 1, 0.0 );
+  this->clear();
+}
+
+Fir :: ~Fir()
+{
+}
+
+void Fir :: setCoefficients( std::vector<StkFloat> &coefficients, bool clearState )
+{
+  // Check the argument.
+  if ( coefficients.size() == 0 ) {
+    errorString_ << "Fir::setCoefficients: coefficient vector must have size > 0!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+
+  if ( b_.size() != coefficients.size() ) {
+    b_ = coefficients;
+    inputs_.resize( b_.size(), 1, 0.0 );
+  }
+  else {
+    for ( unsigned int i=0; i<b_.size(); i++ ) b_[i] = coefficients[i];
+  }
+
+  if ( clearState ) this->clear();
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/Flute.cpp b/lib/MoMu-STK-1.0.0/src/Flute.cpp
new file mode 100644 (file)
index 0000000..2cf6e58
--- /dev/null
@@ -0,0 +1,180 @@
+/***************************************************/
+/*! \class Flute
+    \brief STK flute physical model class.
+
+    This class implements a simple flute
+    physical model, as discussed by Karjalainen,
+    Smith, Waryznyk, etc.  The jet model uses
+    a polynomial, a la Cook.
+
+    This is a digital waveguide model, making its
+    use possibly subject to patents held by Stanford
+    University, Yamaha, and others.
+
+    Control Change Numbers: 
+       - Jet Delay = 2
+       - Noise Gain = 4
+       - Vibrato Frequency = 11
+       - Vibrato Gain = 1
+       - Breath Pressure = 128
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "Flute.h"
+#include "Skini_msg.h"
+
+namespace stk {
+
+Flute :: Flute( StkFloat lowestFrequency )
+{
+  length_ = (unsigned long) ( Stk::sampleRate() / lowestFrequency + 1 );
+  boreDelay_.setMaximumDelay( length_ );
+  boreDelay_.setDelay( 100.0 );
+
+  jetDelay_.setMaximumDelay( length_ );
+  jetDelay_.setDelay( 49.0 );
+
+  vibrato_.setFrequency( 5.925 );
+
+  this->clear();
+
+  filter_.setPole( 0.7 - ((StkFloat) 0.1 * 22050.0 / Stk::sampleRate() ) );
+  filter_.setGain( -1.0 );
+
+  dcBlock_.setBlockZero();
+
+  adsr_.setAllTimes( 0.005, 0.01, 0.8, 0.010);
+  endReflection_ = 0.5;
+  jetReflection_ = 0.5;
+  noiseGain_     = 0.15;    // Breath pressure random component.
+  vibratoGain_   = 0.05;    // Breath periodic vibrato component.
+  jetRatio_      = 0.32;
+
+       maxPressure_ = 0.0;
+  lastFrequency_ = 220.0;
+}
+
+Flute :: ~Flute( void )
+{
+}
+
+void Flute :: clear( void )
+{
+  jetDelay_.clear();
+  boreDelay_.clear();
+  filter_.clear();
+  dcBlock_.clear();
+}
+
+void Flute :: setFrequency( StkFloat frequency )
+{
+  lastFrequency_ = frequency;
+  if ( frequency <= 0.0 ) {
+    errorString_ << "Flute::setFrequency: parameter is less than or equal to zero!";
+    handleError( StkError::WARNING );
+    lastFrequency_ = 220.0;
+  }
+
+  // We're overblowing here.
+  lastFrequency_ *= 0.66666;
+
+  // delay = length - approximate filter delay.
+  StkFloat delay = Stk::sampleRate() / lastFrequency_ - (StkFloat) 2.0;
+  if ( delay <= 0.0 ) delay = 0.3;
+  else if ( delay > length_ ) delay = length_;
+
+  boreDelay_.setDelay(delay);
+  jetDelay_.setDelay(delay * jetRatio_);
+}
+
+void Flute :: startBlowing( StkFloat amplitude, StkFloat rate )
+{
+  adsr_.setAttackRate( rate );
+  maxPressure_ = amplitude / (StkFloat) 0.8;
+  adsr_.keyOn();
+}
+
+void Flute :: stopBlowing( StkFloat rate )
+{
+  adsr_.setReleaseRate( rate );
+  adsr_.keyOff();
+}
+
+void Flute :: noteOn( StkFloat frequency, StkFloat amplitude )
+{
+  this->setFrequency( frequency );
+  this->startBlowing( 1.1 + (amplitude * 0.20), amplitude * 0.02 );
+  outputGain_ = amplitude + 0.001;
+
+#if defined(_STK_DEBUG_)
+  errorString_ << "Flute::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << ".";
+  handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+void Flute :: noteOff( StkFloat amplitude )
+{
+  this->stopBlowing( amplitude * 0.02 );
+
+#if defined(_STK_DEBUG_)
+  errorString_ << "Flute::NoteOff: amplitude = " << amplitude << ".";
+  handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+void Flute :: setJetReflection( StkFloat coefficient )
+{
+  jetReflection_ = coefficient;
+}
+
+void Flute :: setEndReflection( StkFloat coefficient )
+{         
+  endReflection_ = coefficient;
+}               
+
+void Flute :: setJetDelay( StkFloat aRatio )
+{
+  // Delay = length - approximate filter delay.
+  StkFloat temp = Stk::sampleRate() / lastFrequency_ - (StkFloat) 2.0;
+  jetRatio_ = aRatio;
+  jetDelay_.setDelay(temp * aRatio); // Scaled by ratio.
+}
+
+void Flute :: controlChange( int number, StkFloat value )
+{
+  StkFloat norm = value * ONE_OVER_128;
+  if ( norm < 0 ) {
+    norm = 0.0;
+    errorString_ << "Flute::controlChange: control value less than zero ... setting to zero!";
+    handleError( StkError::WARNING );
+  }
+  else if ( norm > 1.0 ) {
+    norm = 1.0;
+    errorString_ << "Flute::controlChange: control value greater than 128.0 ... setting to 128.0!";
+    handleError( StkError::WARNING );
+  }
+
+  if (number == __SK_JetDelay_) // 2
+    this->setJetDelay( (StkFloat) (0.08 + (0.48 * norm)) );
+  else if (number == __SK_NoiseLevel_) // 4
+    noiseGain_ = ( norm * 0.4);
+  else if (number == __SK_ModFrequency_) // 11
+    vibrato_.setFrequency( norm * 12.0);
+  else if (number == __SK_ModWheel_) // 1
+    vibratoGain_ = ( norm * 0.4 );
+  else if (number == __SK_AfterTouch_Cont_) // 128
+    adsr_.setTarget( norm );
+  else {
+    errorString_ << "Flute::controlChange: undefined control number (" << number << ")!";
+    handleError( StkError::WARNING );
+  }
+
+#if defined(_STK_DEBUG_)
+    errorString_ << "Flute::controlChange: number = " << number << ", value = " << value << ".";
+    handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/FormSwep.cpp b/lib/MoMu-STK-1.0.0/src/FormSwep.cpp
new file mode 100644 (file)
index 0000000..b47d75d
--- /dev/null
@@ -0,0 +1,110 @@
+/***************************************************/
+/*! \class FormSwep
+    \brief STK sweepable formant filter class.
+
+    This class implements a formant (resonance) which can be "swept"
+    over time from one frequency setting to another.  It provides
+    methods for controlling the sweep rate and target frequency.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "FormSwep.h"
+#include <cmath>
+
+namespace stk {
+
+FormSwep :: FormSwep( void )
+{
+  frequency_ = 0.0;
+  radius_ = 0.0;
+  targetGain_ = 1.0;
+  targetFrequency_ = 0.0;
+  targetRadius_ = 0.0;
+  deltaGain_ = 0.0;
+  deltaFrequency_ = 0.0;
+  deltaRadius_ = 0.0;
+  sweepState_ = 0.0;
+  sweepRate_ = 0.002;
+  dirty_ = false;
+
+  b_.resize( 3, 0.0 );
+  a_.resize( 3, 0.0 );
+  a_[0] = 1.0;
+  inputs_.resize( 3, 1, 0.0 );
+  outputs_.resize( 3, 1, 0.0 );
+
+  Stk::addSampleRateAlert( this );
+}
+
+FormSwep :: ~FormSwep()
+{
+  Stk::removeSampleRateAlert( this );
+}
+
+void FormSwep :: sampleRateChanged( StkFloat newRate, StkFloat oldRate )
+{
+  if ( !ignoreSampleRateChange_ ) {
+    errorString_ << "FormSwep::sampleRateChanged: you may need to recompute filter coefficients!";
+    handleError( StkError::WARNING );
+  }
+}
+
+void FormSwep :: setResonance( StkFloat frequency, StkFloat radius )
+{
+  radius_ = radius;
+  frequency_ = frequency;
+
+  a_[2] = radius * radius;
+  a_[1] = -2.0 * radius * cos( TWO_PI * frequency / Stk::sampleRate() );
+
+  // Use zeros at +- 1 and normalize the filter peak gain.
+  b_[0] = 0.5 - 0.5 * a_[2];
+  b_[1] = 0.0;
+  b_[2] = -b_[0];
+}
+
+void FormSwep :: setStates( StkFloat frequency, StkFloat radius, StkFloat gain )
+{
+  dirty_ = false;
+
+  if ( frequency_ != frequency || radius_ != radius )
+    this->setResonance( frequency, radius );
+
+  gain_ = gain;
+  targetFrequency_ = frequency;
+  targetRadius_ = radius;
+  targetGain_ = gain;
+}
+
+void FormSwep :: setTargets( StkFloat frequency, StkFloat radius, StkFloat gain )
+{
+  dirty_ = true;
+  startFrequency_ = frequency_;
+  startRadius_ = radius_;
+  startGain_ = gain_;
+  targetFrequency_ = frequency;
+  targetRadius_ = radius;
+  targetGain_ = gain;
+  deltaFrequency_ = frequency - frequency_;
+  deltaRadius_ = radius - radius_;
+  deltaGain_ = gain - gain_;
+  sweepState_ = 0.0;
+}
+
+void FormSwep :: setSweepRate( StkFloat rate )
+{
+  sweepRate_ = rate;
+  if ( sweepRate_ > 1.0 ) sweepRate_ = 1.0;
+  if ( sweepRate_ < 0.0 ) sweepRate_ = 0.0;
+}
+
+void FormSwep :: setSweepTime( StkFloat time )
+{
+  sweepRate_ = 1.0 / ( time * Stk::sampleRate() );
+  if ( sweepRate_ > 1.0 ) sweepRate_ = 1.0;
+  if ( sweepRate_ < 0.0 ) sweepRate_ = 0.0;
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/Granulate.cpp b/lib/MoMu-STK-1.0.0/src/Granulate.cpp
new file mode 100644 (file)
index 0000000..7d3ef83
--- /dev/null
@@ -0,0 +1,294 @@
+/***************************************************/
+/*! \class Granulate
+    \brief STK granular synthesis class.
+
+    This class implements a real-time granular synthesis algorithm
+    that operates on an input soundfile.  Multi-channel files are
+    supported.  Various functions are provided to allow control over
+    voice and grain parameters.
+
+    The functionality of this class is based on the program MacPod by
+    Chris Rolfe and Damian Keller, though there are likely to be a
+    number of differences in the actual implementation.
+
+    by Gary Scavone, 2005 - 2010.
+*/
+/***************************************************/
+
+#include "Granulate.h"
+#include "FileRead.h"
+#include <cmath>
+
+namespace stk {
+
+Granulate :: Granulate( void )
+{
+  this->setGrainParameters(); // use default values
+  this->setRandomFactor();
+  gStretch_ = 0;
+  stretchCounter_ = 0;
+  gain_ = 1.0;
+}
+
+Granulate :: Granulate( unsigned int nVoices, std::string fileName, bool typeRaw )
+{
+  this->setGrainParameters(); // use default values
+  this->setRandomFactor();
+  gStretch_ = 0;
+  stretchCounter_ = 0;
+  this->openFile( fileName, typeRaw );
+  this->setVoices( nVoices );
+}
+
+Granulate :: ~Granulate( void )
+{
+}
+
+void Granulate :: setStretch( unsigned int stretchFactor )
+{
+  if ( stretchFactor <= 1 )
+    gStretch_ = 0;
+  else if ( gStretch_ >= 1000 )
+    gStretch_ = 1000;
+  else
+    gStretch_ = stretchFactor - 1;
+}
+
+void Granulate :: setGrainParameters( unsigned int duration, unsigned int rampPercent,
+                                      int offset, unsigned int delay )
+{
+  gDuration_ = duration;
+  if ( gDuration_ == 0 ) {
+    gDuration_ = 1;
+    errorString_ << "Granulate::setGrainParameters: duration argument cannot be zero ... setting to 1 millisecond.";
+    handleError( StkError::WARNING );
+  }
+
+  gRampPercent_ = rampPercent;
+  if ( gRampPercent_ > 100 ) {
+    gRampPercent_ = 100;
+    errorString_ << "Granulate::setGrainParameters: rampPercent argument cannot be greater than 100 ... setting to 100.";
+    handleError( StkError::WARNING );
+  }
+
+  gOffset_ = offset;
+  gDelay_ = delay;
+}
+
+void Granulate :: setRandomFactor( StkFloat randomness )
+{
+  if ( randomness < 0.0 ) gRandomFactor_ = 0.0;
+  else if ( randomness > 1.0 ) gRandomFactor_ = 0.97;
+
+  gRandomFactor_ = 0.97 * randomness;
+};
+
+void Granulate :: openFile( std::string fileName, bool typeRaw )
+{
+  // Attempt to load the soundfile data.
+  FileRead file( fileName, typeRaw );
+  data_.resize( file.fileSize(), file.channels() );
+  file.read( data_ );
+  lastFrame_.resize( 1, file.channels(), 0.0 );
+
+  this->reset();
+
+#if defined(_STK_DEBUG_)
+  errorString_ << "Granulate::openFile: file = " << fileName << ", file frames = " << file.fileSize() << '.';
+  handleError( StkError::DEBUG_WARNING );
+#endif
+
+}
+
+void Granulate :: reset( void )
+{
+  gPointer_ = 0;
+
+  // Reset grain parameters.
+  unsigned int count, nVoices = grains_.size();
+  for ( unsigned int i=0; i<grains_.size(); i++ ) {
+    grains_[i].repeats = 0;
+    count = (unsigned int ) ( i * gDuration_ * 0.001 * Stk::sampleRate() / nVoices );
+    grains_[i].counter = count;
+    grains_[i].state = GRAIN_STOPPED;
+  }
+
+  for ( unsigned int i=0; i<lastFrame_.channels(); i++ )
+    lastFrame_[i] = 0.0;
+}
+
+void Granulate :: setVoices( unsigned int nVoices )
+{
+#if defined(_STK_DEBUG_)
+  errorString_ << "Granulate::setVoices: nVoices = " << nVoices << ", existing voices = " << grains_.size() << '.';
+  handleError( StkError::DEBUG_WARNING );
+#endif
+
+  unsigned int oldSize = grains_.size();
+  grains_.resize( nVoices );
+
+  // Initialize new grain voices.
+  unsigned int count;
+  for ( unsigned int i=oldSize; i<nVoices; i++ ) {
+    grains_[i].repeats = 0;
+    count = (unsigned int ) ( i * gDuration_ * 0.001 * Stk::sampleRate() / nVoices );
+    grains_[i].counter = count;
+    grains_[i].pointer = gPointer_;
+    grains_[i].state = GRAIN_STOPPED;
+  }
+
+  gain_ = 1.0 / grains_.size();
+}
+
+void Granulate :: calculateGrain( Granulate::Grain& grain )
+{
+  if ( grain.repeats > 0 ) {
+    grain.repeats--;
+    grain.pointer = grain.startPointer;
+    if ( grain.attackCount > 0 ) {
+      grain.eScaler = 0.0;
+      grain.eRate = -grain.eRate;
+      grain.counter = grain.attackCount;
+      grain.state = GRAIN_FADEIN;
+    }
+    else {
+      grain.counter = grain.sustainCount;
+      grain.state = GRAIN_SUSTAIN;
+    }
+    return;
+  }
+
+  // Calculate duration and envelope parameters.
+  StkFloat seconds = gDuration_ * 0.001;
+  seconds += ( seconds * gRandomFactor_ * noise.tick() );
+  unsigned int count = (unsigned long) ( seconds * Stk::sampleRate() );
+  grain.attackCount = (unsigned int) ( gRampPercent_ * 0.005 * count );
+  grain.decayCount = grain.attackCount;
+  grain.sustainCount = count - 2 * grain.attackCount;
+  grain.eScaler = 0.0;
+  if ( grain.attackCount > 0 ) {
+    grain.eRate = 1.0 / grain.attackCount;
+    grain.counter = grain.attackCount;
+    grain.state = GRAIN_FADEIN;
+  }
+  else {
+    grain.counter = grain.sustainCount;
+    grain.state = GRAIN_SUSTAIN;
+  }
+
+  // Calculate delay parameter.
+  seconds = gDelay_ * 0.001;
+  seconds += ( seconds * gRandomFactor_ * noise.tick() );
+  count = (unsigned long) ( seconds * Stk::sampleRate() );
+  grain.delayCount = count;
+
+  // Save stretch parameter.
+  grain.repeats = gStretch_;
+
+  // Calculate offset parameter.
+  seconds = gOffset_ * 0.001;
+  seconds += ( seconds * gRandomFactor_ * std::abs( noise.tick() ) );
+  int offset = (int) ( seconds * Stk::sampleRate() );
+
+  // Add some randomization to the pointer start position.
+  seconds = gDuration_ * 0.001 * gRandomFactor_ * noise.tick();
+  offset += (int) ( seconds * Stk::sampleRate() );
+  grain.pointer += offset;
+  while ( grain.pointer >= data_.frames() ) grain.pointer -= data_.frames();
+  if ( grain.pointer <  0 ) grain.pointer = 0;
+  grain.startPointer = grain.pointer;
+}
+
+StkFloat Granulate :: tick( unsigned int channel )
+{
+#if defined(_STK_DEBUG_)
+  if ( channel >= data_.channels() ) {
+    errorString_ << "Granulate::tick(): channel argument and soundfile data are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  unsigned int i, j, nChannels = lastFrame_.channels();
+  for ( j=0; j<nChannels; j++ ) lastFrame_[j] = 0.0;
+
+  if ( data_.size() == 0 ) return 0.0;
+
+  StkFloat sample;
+  for ( i=0; i<grains_.size(); i++ ) {
+
+    if ( grains_[i].counter == 0 ) { // Update the grain state.
+
+      switch ( grains_[i].state ) {
+
+      case GRAIN_STOPPED:
+        // We're done waiting between grains ... setup for new grain
+        this->calculateGrain( grains_[i] );
+        break;
+
+      case GRAIN_FADEIN:
+        // We're done ramping up the envelope
+        if ( grains_[i].sustainCount > 0 ) {
+          grains_[i].counter = grains_[i].sustainCount;
+          grains_[i].state = GRAIN_SUSTAIN;
+          break;
+        }
+        // else no sustain state (i.e. perfect triangle window)
+
+      case GRAIN_SUSTAIN:
+        // We're done with flat part of envelope ... setup to ramp down
+        if ( grains_[i].decayCount > 0 ) {
+          grains_[i].counter = grains_[i].decayCount;
+          grains_[i].eRate = -grains_[i].eRate;
+          grains_[i].state = GRAIN_FADEOUT;
+          break;
+        }
+        // else no fade out state (gRampPercent = 0)
+
+      case GRAIN_FADEOUT:
+        // We're done ramping down ... setup for wait between grains
+        if ( grains_[i].delayCount > 0 ) {
+          grains_[i].counter = grains_[i].delayCount;
+          grains_[i].state = GRAIN_STOPPED;
+          break;
+        }
+        // else no delay (gDelay = 0)
+
+        this->calculateGrain( grains_[i] );
+      }
+    }
+
+    // Accumulate the grain outputs.
+    if ( grains_[i].state > 0 ) {
+      for ( j=0; j<nChannels; j++ ) {
+        sample = data_[ nChannels * grains_[i].pointer + j ];
+
+        if ( grains_[i].state == GRAIN_FADEIN || grains_[i].state == GRAIN_FADEOUT ) {
+          sample *= grains_[i].eScaler;
+          grains_[i].eScaler += grains_[i].eRate;
+        }
+
+        lastFrame_[j] += sample;
+      }
+
+
+      // Increment and check pointer limits.
+      grains_[i].pointer++;
+      if ( grains_[i].pointer >= data_.frames() )
+        grains_[i].pointer = 0;
+    }
+
+    // Decrement counter for all states.
+    grains_[i].counter--;
+  }
+
+  // Increment our global file pointer at the stretch rate.
+  if ( stretchCounter_++ == gStretch_ ) {
+    gPointer_++;
+    if ( (unsigned long) gPointer_ >= data_.frames() ) gPointer_ = 0;
+    stretchCounter_ = 0;
+  }
+
+  return lastFrame_[channel];
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/HevyMetl.cpp b/lib/MoMu-STK-1.0.0/src/HevyMetl.cpp
new file mode 100644 (file)
index 0000000..1ff75a6
--- /dev/null
@@ -0,0 +1,80 @@
+/***************************************************/
+/*! \class HevyMetl
+    \brief STK heavy metal FM synthesis instrument.
+
+    This class implements 3 cascade operators with
+    feedback modulation, also referred to as
+    algorithm 3 of the TX81Z.
+
+    Algorithm 3 is :     4--\
+                    3-->2-- + -->1-->Out
+
+    Control Change Numbers: 
+       - Total Modulator Index = 2
+       - Modulator Crossfade = 4
+       - LFO Speed = 11
+       - LFO Depth = 1
+       - ADSR 2 & 4 Target = 128
+
+    The basic Chowning/Stanford FM patent expired
+    in 1995, but there exist follow-on patents,
+    mostly assigned to Yamaha.  If you are of the
+    type who should worry about this (making
+    money) worry away.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "HevyMetl.h"
+
+namespace stk {
+
+HevyMetl :: HevyMetl( void )
+  : FM()
+{
+  // Concatenate the STK rawwave path to the rawwave files
+  for ( unsigned int i=0; i<3; i++ )
+    waves_[i] = new FileLoop( (Stk::rawwavePath() + "sinewave.raw").c_str(), true );
+  waves_[3] = new FileLoop( (Stk::rawwavePath() + "fwavblnk.raw").c_str(), true );
+
+  this->setRatio(0, 1.0 * 1.000);
+  this->setRatio(1, 4.0 * 0.999);
+  this->setRatio(2, 3.0 * 1.001);
+  this->setRatio(3, 0.5 * 1.002);
+
+  gains_[0] = fmGains_[92];
+  gains_[1] = fmGains_[76];
+  gains_[2] = fmGains_[91];
+  gains_[3] = fmGains_[68];
+
+  adsr_[0]->setAllTimes( 0.001, 0.001, 1.0, 0.01);
+  adsr_[1]->setAllTimes( 0.001, 0.010, 1.0, 0.50);
+  adsr_[2]->setAllTimes( 0.010, 0.005, 1.0, 0.20);
+  adsr_[3]->setAllTimes( 0.030, 0.010, 0.2, 0.20);
+
+  twozero_.setGain( 2.0 );
+  vibrato_.setFrequency( 5.5 );
+  modDepth_ = 0.0;
+}  
+
+HevyMetl :: ~HevyMetl( void )
+{
+}
+
+void HevyMetl :: noteOn( StkFloat frequency, StkFloat amplitude )
+{
+  gains_[0] = amplitude * fmGains_[92];
+  gains_[1] = amplitude * fmGains_[76];
+  gains_[2] = amplitude * fmGains_[91];
+  gains_[3] = amplitude * fmGains_[68];
+  this->setFrequency( frequency );
+  this->keyOn();
+
+#if defined(_STK_DEBUG_)
+  errorString_ << "HevyMetl::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << '.';
+  handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/Iir.cpp b/lib/MoMu-STK-1.0.0/src/Iir.cpp
new file mode 100644 (file)
index 0000000..e1224fa
--- /dev/null
@@ -0,0 +1,125 @@
+/***************************************************/
+/*! \class Iir
+    \brief STK general infinite impulse response filter class.
+
+    This class provides a generic digital filter structure that can be
+    used to implement IIR filters.  For filters containing only
+    feedforward terms, the Fir class is slightly more efficient.
+
+    In particular, this class implements the standard difference
+    equation:
+
+    a[0]*y[n] = b[0]*x[n] + ... + b[nb]*x[n-nb] -
+                a[1]*y[n-1] - ... - a[na]*y[n-na]
+
+    If a[0] is not equal to 1, the filter coeffcients are normalized
+    by a[0].
+
+    The \e gain parameter is applied at the filter input and does not
+    affect the coefficient values.  The default gain value is 1.0.
+    This structure results in one extra multiply per computed sample,
+    but allows easy control of the overall filter gain.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "Iir.h"
+
+namespace stk {
+
+Iir :: Iir()
+{
+  // The default constructor should setup for pass-through.
+  b_.push_back( 1.0 );
+  a_.push_back( 1.0 );
+
+  inputs_.resize( 1, 1, 0.0 );
+  outputs_.resize( 1, 1, 0.0 );
+}
+
+Iir :: Iir( std::vector<StkFloat> &bCoefficients, std::vector<StkFloat> &aCoefficients )
+{
+  // Check the arguments.
+  if ( bCoefficients.size() == 0 || aCoefficients.size() == 0 ) {
+    errorString_ << "Iir: a and b coefficient vectors must both have size > 0!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+
+  if ( aCoefficients[0] == 0.0 ) {
+    errorString_ << "Iir: a[0] coefficient cannot == 0!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+
+  gain_ = 1.0;
+  b_ = bCoefficients;
+  a_ = aCoefficients;
+
+  inputs_.resize( b_.size(), 1, 0.0 );
+  outputs_.resize( a_.size(), 1, 0.0 );
+  this->clear();
+}
+
+Iir :: ~Iir()
+{
+}
+
+void Iir :: setCoefficients( std::vector<StkFloat> &bCoefficients, std::vector<StkFloat> &aCoefficients, bool clearState )
+{
+  this->setNumerator( bCoefficients, false );
+  this->setDenominator( aCoefficients, false );
+
+  if ( clearState ) this->clear();
+}
+
+void Iir :: setNumerator( std::vector<StkFloat> &bCoefficients, bool clearState )
+{
+  // Check the argument.
+  if ( bCoefficients.size() == 0 ) {
+    errorString_ << "Iir::setNumerator: coefficient vector must have size > 0!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+
+  if ( b_.size() != bCoefficients.size() ) {
+    b_ = bCoefficients;
+    inputs_.resize( b_.size(), 1, 0.0 );
+  }
+  else {
+    for ( unsigned int i=0; i<b_.size(); i++ ) b_[i] = bCoefficients[i];
+  }
+
+  if ( clearState ) this->clear();
+}
+
+void Iir :: setDenominator( std::vector<StkFloat> &aCoefficients, bool clearState )
+{
+  // Check the argument.
+  if ( aCoefficients.size() == 0 ) {
+    errorString_ << "Iir::setDenominator: coefficient vector must have size > 0!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+
+  if ( aCoefficients[0] == 0.0 ) {
+    errorString_ << "Iir::setDenominator: a[0] coefficient cannot == 0!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+
+  if ( a_.size() != aCoefficients.size() ) {
+    a_ = aCoefficients;
+    outputs_.resize( a_.size(), 1, 0.0 );
+  }
+  else {
+    for ( unsigned int i=0; i<a_.size(); i++ ) a_[i] = aCoefficients[i];
+  }
+
+  if ( clearState ) this->clear();
+
+  // Scale coefficients by a[0] if necessary
+  if ( a_[0] != 1.0 ) {
+    unsigned int i;
+    for ( i=0; i<b_.size(); i++ ) b_[i] /= a_[0];
+    for ( i=1; i<a_.size(); i++ )  a_[i] /= a_[0];
+  }
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/InetWvIn.cpp b/lib/MoMu-STK-1.0.0/src/InetWvIn.cpp
new file mode 100644 (file)
index 0000000..03edbe4
--- /dev/null
@@ -0,0 +1,320 @@
+/***************************************************/
+/*! \class InetWvIn
+    \brief STK internet streaming input class.
+
+    This Wvin subclass reads streamed audio data over a network via a
+    TCP or UDP socket connection.  The data is assumed in big-endian,
+    or network, byte order.  Only a single socket connection is
+    supported.
+
+    InetWvIn supports multi-channel data.  It is important to
+    distinguish the tick() method that computes a single frame (and
+    returns only the specified sample of a multi-channel frame) from
+    the overloaded one that takes an StkFrames object for
+    multi-channel and/or multi-frame data.
+
+    This class implements a socket server.  When using the TCP
+    protocol, the server "listens" for a single remote connection
+    within the InetWvIn::start() function.  For the UDP protocol, no
+    attempt is made to verify packet delivery or order.  The default
+    data type for the incoming stream is signed 16-bit integers,
+    though any of the defined StkFormats are permissible.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "InetWvIn.h"
+
+namespace stk {
+
+extern "C" THREAD_RETURN THREAD_TYPE inputThread( void * ptr )
+{
+  ThreadInfo *info = (ThreadInfo *)ptr;
+
+  while ( !info->finished ) {
+    ((InetWvIn *) info->object)->receive();
+  }
+
+  return 0;
+}
+
+InetWvIn :: InetWvIn( unsigned long bufferFrames, unsigned int nBuffers )
+  :soket_(0), buffer_(0), bufferFrames_(bufferFrames), bufferBytes_(0), nBuffers_(nBuffers), connected_(false)
+{
+  threadInfo_.finished = false;
+  threadInfo_.object = (void *) this;
+
+  // Start the input thread.
+  if ( !thread_.start( &inputThread, &threadInfo_ ) ) {
+    errorString_ << "InetWvIn(): unable to start input thread in constructor!";
+    handleError( StkError::PROCESS_THREAD );
+  }
+}
+
+InetWvIn :: ~InetWvIn()
+{
+  // Close down the thread.
+  connected_ = false;
+  threadInfo_.finished = true;
+
+  if ( soket_ ) delete soket_;
+  if ( buffer_ ) delete [] buffer_;
+}
+
+void InetWvIn :: listen( int port, unsigned int nChannels,
+                         Stk::StkFormat format, Socket::ProtocolType protocol )
+{
+  mutex_.lock();
+
+  if ( connected_ ) delete soket_;
+
+  if ( nChannels < 1 ) {
+    errorString_ << "InetWvIn()::listen(): the channel argument (" << nChannels << ") must be greater than zero.";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+
+  if ( format == STK_SINT16 ) dataBytes_ = 2;
+  else if ( format == STK_SINT32 || format == STK_FLOAT32 ) dataBytes_ = 4;
+  else if ( format == STK_FLOAT64 ) dataBytes_ = 8;
+  else if ( format == STK_SINT8 ) dataBytes_ = 1;
+  else {
+    errorString_ << "InetWvIn(): unknown data type specified (" << format << ").";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  } 
+  dataType_ = format;
+
+  unsigned long bufferBytes = bufferFrames_ * nBuffers_ * nChannels * dataBytes_;
+  if ( bufferBytes > bufferBytes_ ) {
+    if ( buffer_) delete [] buffer_;
+    buffer_ = (char *) new char[ bufferBytes ];
+    bufferBytes_ = bufferBytes;
+  }
+
+  data_.resize( bufferFrames_, nChannels );
+  lastFrame_.resize( 1, nChannels, 0.0 );
+
+  bufferCounter_ = 0;
+  writePoint_ = 0;
+  readPoint_ = 0;
+  bytesFilled_ = 0;
+
+  if ( protocol == Socket::PROTO_TCP ) {
+    TcpServer *socket = new TcpServer( port );
+    errorString_ << "InetWvIn:listen(): waiting for TCP connection on port " << socket->port() << " ... ";
+    handleError( StkError::STATUS );
+    fd_ = socket->accept();
+    if ( fd_ < 0) {
+      errorString_ << "InetWvIn::listen(): Error accepting TCP connection request!";
+      handleError( StkError::PROCESS_SOCKET );
+    }
+    errorString_ << "InetWvIn::listen(): TCP socket connection made!";
+    handleError( StkError::STATUS );
+    soket_ = (Socket *) socket;
+  }
+  else {
+    soket_ = new StkUdpSocket( port );
+    fd_ = soket_->id();
+  }
+
+  connected_ = true;
+
+  mutex_.unlock();
+}
+
+void InetWvIn :: receive( void )
+{
+  if ( !connected_ ) {
+    Stk::sleep(100);
+    return;
+  }
+
+  fd_set mask;
+  FD_ZERO( &mask );
+  FD_SET( fd_, &mask );
+
+  // The select function will block until data is available for reading.
+  select( fd_+1, &mask, (fd_set *)0, (fd_set *)0, NULL );
+
+  if ( FD_ISSET( fd_, &mask ) ) {
+    mutex_.lock();
+    unsigned long unfilled = bufferBytes_ - bytesFilled_;
+    if ( unfilled > 0 ) {
+      // There's room in our buffer for more data.
+      unsigned long endPoint = writePoint_ + unfilled;
+      if ( endPoint > bufferBytes_ ) unfilled -= endPoint - bufferBytes_;
+      int i = soket_->readBuffer( fd_, (void *)&buffer_[writePoint_], unfilled, 0 );
+      //int i = Socket::readBuffer( fd_, (void *)&buffer_[writePoint_], unfilled, 0 );
+      if ( i <= 0 ) {
+        errorString_ << "InetWvIn::receive(): the remote InetWvIn socket has closed.";
+        handleError( StkError::STATUS );
+        connected_ = false;
+        mutex_.unlock();
+        return;
+      }
+      bytesFilled_ += i;
+      writePoint_ += i;
+      if ( writePoint_ == bufferBytes_ )
+        writePoint_ = 0;
+      mutex_.unlock();
+    }
+    else {
+      // Sleep 10 milliseconds AFTER unlocking mutex.
+      mutex_.unlock();
+      Stk::sleep( 10 );
+    }
+  }
+}
+
+int InetWvIn :: readData( void )
+{
+  // We have two potential courses of action should this method
+  // be called and the input buffer isn't sufficiently filled.
+  // One solution is to fill the data buffer with zeros and return.
+  // The other solution is to wait until the necessary data exists.
+  // I chose the latter, as it works for both streamed files
+  // (non-realtime data transport) and realtime playback (given
+  // adequate network bandwidth and speed).
+
+  // Wait until data is ready.
+  unsigned long bytes = data_.size() * dataBytes_;
+  while ( connected_ && bytesFilled_ < bytes )
+    Stk::sleep( 10 );
+
+  if ( !connected_ && bytesFilled_ == 0 ) return 0;
+  bytes = ( bytesFilled_ < bytes ) ? bytesFilled_ : bytes;
+
+  // Copy samples from buffer to data.
+  StkFloat gain;
+  long samples = bytes / dataBytes_;
+  mutex_.lock();
+  if ( dataType_ == STK_SINT16 ) {
+    gain = 1.0 / 32767.0;
+    SINT16 *buf = (SINT16 *) (buffer_+readPoint_);
+    for (int i=0; i<samples; i++ ) {
+#ifdef __LITTLE_ENDIAN__
+      swap16((unsigned char *) buf);
+#endif
+      data_[i] = (StkFloat) *buf++;
+      data_[i] *= gain;
+    }
+  }
+  else if ( dataType_ == STK_SINT32 ) {
+    gain = 1.0 / 2147483647.0;
+    SINT32 *buf = (SINT32 *) (buffer_+readPoint_);
+    for (int i=0; i<samples; i++ ) {
+#ifdef __LITTLE_ENDIAN__
+      swap32((unsigned char *) buf);
+#endif
+      data_[i] = (StkFloat) *buf++;
+      data_[i] *= gain;
+    }
+  }
+  else if ( dataType_ == STK_FLOAT32 ) {
+    FLOAT32 *buf = (FLOAT32 *) (buffer_+readPoint_);
+    for (int i=0; i<samples; i++ ) {
+#ifdef __LITTLE_ENDIAN__
+      swap32((unsigned char *) buf);
+#endif
+      data_[i] = (StkFloat) *buf++;
+    }
+  }
+  else if ( dataType_ == STK_FLOAT64 ) {
+    FLOAT64 *buf = (FLOAT64 *) (buffer_+readPoint_);
+    for (int i=0; i<samples; i++ ) {
+#ifdef __LITTLE_ENDIAN__
+      swap64((unsigned char *) buf);
+#endif
+      data_[i] = (StkFloat) *buf++;
+    }
+  }
+  else if ( dataType_ == STK_SINT8 ) {
+    gain = 1.0 / 127.0;
+    signed char *buf = (signed char *) (buffer_+readPoint_);
+    for (int i=0; i<samples; i++ ) {
+      data_[i] = (StkFloat) *buf++;
+      data_[i] *= gain;
+    }
+  }
+
+  readPoint_ += bytes;
+  if ( readPoint_ == bufferBytes_ )
+    readPoint_ = 0;
+  bytesFilled_ -= bytes;
+  if ( bytesFilled_ < 0 )
+    bytesFilled_ = 0;
+
+  mutex_.unlock();
+  return samples / data_.channels();
+}
+
+bool InetWvIn :: isConnected( void )
+{
+  if ( bytesFilled_ > 0 || bufferCounter_ > 0 )
+    return true;
+  else
+    return connected_;
+}
+
+StkFloat InetWvIn :: tick( unsigned int channel )
+{
+  // If no connection and we've output all samples in the queue, return 0.0.
+  if ( !connected_ && bytesFilled_ == 0 && bufferCounter_ == 0 ) {
+#if defined(_STK_DEBUG_)
+    errorString_ << "InetWvIn::tick(): a valid socket connection does not exist!";
+    handleError( StkError::DEBUG_WARNING );
+#endif
+    return 0.0;
+  }
+
+#if defined(_STK_DEBUG_)
+  if ( channel >= data_.channels() ) {
+    errorString_ << "InetWvIn::tick(): channel argument is incompatible with data stream!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  if ( bufferCounter_ == 0 )
+    bufferCounter_ = readData();
+
+  unsigned int nChannels = lastFrame_.channels();
+  long index = ( bufferFrames_ - bufferCounter_ ) * nChannels;
+  for ( unsigned int i=0; i<nChannels; i++ )
+    lastFrame_[i] = data_[index++];
+
+  bufferCounter_--;
+  if ( bufferCounter_ < 0 )
+    bufferCounter_ = 0;
+
+  return lastFrame_[channel];
+}
+
+StkFrames& InetWvIn :: tick( StkFrames& frames )
+{
+#if defined(_STK_DEBUG_)
+  if ( data_.channels() != frames.channels() ) {
+    errorString_ << "InetWvIn::tick(): StkFrames argument is incompatible with streamed channels!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  // If no connection and we've output all samples in the queue, return.
+  if ( !connected_ && bytesFilled_ == 0 && bufferCounter_ == 0 ) {
+#if defined(_STK_DEBUG_)
+    errorString_ << "InetWvIn::tick(): a valid socket connection does not exist!";
+    handleError( StkError::DEBUG_WARNING );
+#endif
+    return frames;
+  }
+
+  unsigned int j, counter = 0;
+  for ( unsigned int i=0; i<frames.frames(); i++ ) {
+    this->tick();
+    for ( j=0; j<lastFrame_.channels(); j++ )
+      frames[counter++] = lastFrame_[j];
+  }
+
+  return frames;
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/InetWvOut.cpp b/lib/MoMu-STK-1.0.0/src/InetWvOut.cpp
new file mode 100644 (file)
index 0000000..88ec285
--- /dev/null
@@ -0,0 +1,230 @@
+/***************************************************/
+/*! \class InetWvOut
+    \brief STK internet streaming output class.
+
+    This WvOut subclass can stream data over a network via a TCP or
+    UDP socket connection.  The data is converted to big-endian byte
+    order, if necessary, before being transmitted.
+
+    InetWvOut supports multi-channel data.  It is important to
+    distinguish the tick() method that outputs a single sample to all
+    channels in a sample frame from the overloaded one that takes a
+    reference to an StkFrames object for multi-channel and/or
+    multi-frame data.
+
+    This class connects to a socket server, the port and IP address of
+    which must be specified as constructor arguments.  The default
+    data type is signed 16-bit integers but any of the defined
+    StkFormats are permissible.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "InetWvOut.h"
+#include "TcpClient.h"
+#include "StkUdpSocket.h"
+
+namespace stk {
+
+InetWvOut :: InetWvOut( unsigned long packetFrames )
+  : buffer_(0), soket_(0), bufferFrames_(packetFrames), bufferBytes_(0)
+{
+}
+
+InetWvOut :: InetWvOut( int port, Socket::ProtocolType protocol, std::string hostname,
+                        unsigned int nChannels, Stk::StkFormat format, unsigned long packetFrames )
+  : buffer_(0), soket_(0), bufferFrames_(packetFrames), bufferBytes_(0)
+{
+  connect( port, protocol, hostname, nChannels, format );
+}
+
+InetWvOut :: ~InetWvOut()
+{
+  disconnect();
+  if ( soket_ ) delete soket_;
+  if ( buffer_ ) delete [] buffer_;
+}
+
+void InetWvOut :: connect( int port, Socket::ProtocolType protocol, std::string hostname,
+                           unsigned int nChannels, Stk::StkFormat format )
+{
+  if ( soket_ && soket_->isValid( soket_->id() ) )
+    disconnect();
+
+  if ( nChannels == 0 ) {
+    errorString_ << "InetWvOut::connect: the channel argument (" << nChannels << ") must be greater than zero!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+
+  if ( format == STK_SINT8 ) dataBytes_ = 1;
+  else if ( format == STK_SINT16 ) dataBytes_ = 2;
+  else if ( format == STK_SINT32 || format == STK_FLOAT32 ) dataBytes_ = 4;
+  else if ( format == STK_FLOAT64 ) dataBytes_ = 8;
+  else {
+    errorString_ << "InetWvOut::connect: unknown data type specified (" << format << ").";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  } 
+  dataType_ = format;
+
+  if ( protocol == Socket::PROTO_TCP ) {
+    soket_ = new TcpClient( port, hostname );
+  }
+  else {
+    // For UDP sockets, the sending and receiving sockets cannot have
+    // the same port number.  Since the port argument corresponds to
+    // the destination port, we will associate this socket instance
+    // with a different port number (arbitrarily determined as port -
+    // 1).
+    StkUdpSocket *socket = new StkUdpSocket( port - 1 );
+    socket->setDestination( port, hostname );
+    soket_ = (Socket *) socket;
+  }
+
+  // Allocate new memory if necessary.
+  data_.resize( bufferFrames_, nChannels );
+  unsigned long bufferBytes = dataBytes_ * bufferFrames_ * nChannels;
+  if ( bufferBytes > bufferBytes_ ) {
+    if ( buffer_) delete [] buffer_;
+    buffer_ = (char *) new char[ bufferBytes ];
+    bufferBytes_ = bufferBytes;
+  }
+  frameCounter_ = 0;
+  bufferIndex_ = 0;
+  iData_ = 0;
+}
+
+void InetWvOut :: disconnect(void)
+{
+  if ( soket_ ) {
+    writeData( bufferIndex_ );
+    soket_->close( soket_->id() );
+    delete soket_;
+    soket_ = 0;
+  }
+}
+
+void InetWvOut :: writeData( unsigned long frames )
+{
+  unsigned long samples = frames * data_.channels();
+  if ( dataType_ == STK_SINT8 ) {
+    signed char *ptr = (signed char *) buffer_;
+    for ( unsigned long k=0; k<samples; k++ ) {
+      this->clipTest( data_[k] );
+      *ptr++ = (signed char) (data_[k] * 127.0);
+    }
+  }
+  else if ( dataType_ == STK_SINT16 ) {
+    SINT16 *ptr = (SINT16 *) buffer_;
+    for ( unsigned long k=0; k<samples; k++ ) {
+      this->clipTest( data_[k] );
+      *ptr = (SINT16) (data_[k] * 32767.0);
+#ifdef __LITTLE_ENDIAN__
+      swap16 ((unsigned char *)ptr);
+#endif
+      ptr++;
+    }
+  }
+  else if ( dataType_ == STK_SINT32 ) {
+    SINT32 *ptr = (SINT32 *) buffer_;
+    for ( unsigned long k=0; k<samples; k++ ) {
+      this->clipTest( data_[k] );
+      *ptr = (SINT32) (data_[k] * 2147483647.0);
+#ifdef __LITTLE_ENDIAN__
+      swap32 ((unsigned char *)ptr);
+#endif
+      ptr++;
+    }
+  }
+  else if ( dataType_ == STK_FLOAT32 ) {
+    FLOAT32 *ptr = (FLOAT32 *) buffer_;
+    for ( unsigned long k=0; k<samples; k++ ) {
+      this->clipTest( data_[k] );
+      *ptr = (FLOAT32) data_[k];
+#ifdef __LITTLE_ENDIAN__
+      swap32 ((unsigned char *)ptr);
+#endif
+      ptr++;
+    }
+  }
+  else if ( dataType_ == STK_FLOAT64 ) {
+    FLOAT64 *ptr = (FLOAT64 *) buffer_;
+    for ( unsigned long k=0; k<samples; k++ ) {
+      this->clipTest( data_[k] );
+      *ptr = (FLOAT64) data_[k];
+#ifdef __LITTLE_ENDIAN__
+      swap64 ((unsigned char *)ptr);
+#endif
+      ptr++;
+    }
+  }
+
+  long bytes = dataBytes_ * samples;
+  if ( soket_->writeBuffer( (const void *)buffer_, bytes, 0 ) < 0 ) {
+    errorString_ << "InetWvOut: connection to socket server failed!";
+    handleError( StkError::PROCESS_SOCKET );
+  }
+}
+
+void InetWvOut :: incrementFrame( void )
+{
+  frameCounter_++;
+  bufferIndex_++;
+
+  if ( bufferIndex_ == bufferFrames_ ) {
+    writeData( bufferFrames_ );
+    bufferIndex_ = 0;
+    iData_ = 0;
+  }
+}
+
+void InetWvOut :: tick( const StkFloat sample )
+{
+  if ( !soket_ || !soket_->isValid( soket_->id() ) ) {
+#if defined(_STK_DEBUG_)
+    errorString_ << "InetWvOut::tick(): a valid socket connection does not exist!";
+    handleError( StkError::DEBUG_WARNING );
+#endif
+    return;
+  }
+
+  unsigned int nChannels = data_.channels();
+  StkFloat input = sample;
+  clipTest( input );
+  for ( unsigned int j=0; j<nChannels; j++ )
+    data_[iData_++] = input;
+
+  this->incrementFrame();
+}
+
+void InetWvOut :: tick( const StkFrames& frames )
+{
+  if ( !soket_ || !soket_->isValid( soket_->id() ) ) {
+#if defined(_STK_DEBUG_)
+    errorString_ << "InetWvOut::tick(): a valid socket connection does not exist!";
+    handleError( StkError::DEBUG_WARNING );
+#endif
+    return;
+  }
+
+#if defined(_STK_DEBUG_)
+  if ( data_.channels() != frames.channels() ) {
+    errorString_ << "InetWvOut::tick(): incompatible channel value in StkFrames argument!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  unsigned int j, nChannels = data_.channels();
+  unsigned int iFrames = 0;
+  for ( unsigned int i=0; i<frames.frames(); i++ ) {
+
+    for ( j=0; j<nChannels; j++ ) {
+      data_[iData_] = frames[iFrames++];
+      clipTest( data_[iData_++] );
+    }
+
+    this->incrementFrame();
+  }
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/JCRev.cpp b/lib/MoMu-STK-1.0.0/src/JCRev.cpp
new file mode 100644 (file)
index 0000000..763b49b
--- /dev/null
@@ -0,0 +1,120 @@
+/***************************************************/
+/*! \class JCRev
+    \brief John Chowning's reverberator class.
+
+    This class takes a monophonic input signal and produces a stereo
+    output signal.  It is derived from the CLM JCRev function, which
+    is based on the use of networks of simple allpass and comb delay
+    filters.  This class implements three series allpass units,
+    followed by four parallel comb filters, and two decorrelation
+    delay lines in parallel at the output.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "JCRev.h"
+#include <cmath>
+
+namespace stk {
+
+JCRev :: JCRev( StkFloat T60 )
+{
+  lastFrame_.resize( 1, 2, 0.0 ); // resize lastFrame_ for stereo output
+
+  // Delay lengths for 44100 Hz sample rate.
+  int lengths[9] = {1777, 1847, 1993, 2137, 389, 127, 43, 211, 179};
+  double scaler = Stk::sampleRate() / 44100.0;
+
+  int delay, i;
+  if ( scaler != 1.0 ) {
+    for ( i=0; i<9; i++ ) {
+      delay = (int) floor( scaler * lengths[i] );
+      if ( (delay & 1) == 0) delay++;
+      while ( !this->isPrime(delay) ) delay += 2;
+      lengths[i] = delay;
+    }
+  }
+
+  for ( i=0; i<3; i++ ) {
+         allpassDelays_[i].setMaximumDelay( lengths[i+4] );
+         allpassDelays_[i].setDelay( lengths[i+4] );
+  }
+
+  for ( i=0; i<4; i++ ) {
+    combDelays_[i].setMaximumDelay( lengths[i] );
+    combDelays_[i].setDelay( lengths[i] );
+  }
+
+  this->setT60( T60 );
+  outLeftDelay_.setMaximumDelay( lengths[7] );
+  outLeftDelay_.setDelay( lengths[7] );
+  outRightDelay_.setMaximumDelay( lengths[8] );
+  outRightDelay_.setDelay( lengths[8] );
+  allpassCoefficient_ = 0.7;
+  effectMix_ = 0.3;
+  this->clear();
+}
+
+void JCRev :: clear()
+{
+  allpassDelays_[0].clear();
+  allpassDelays_[1].clear();
+  allpassDelays_[2].clear();
+  combDelays_[0].clear();
+  combDelays_[1].clear();
+  combDelays_[2].clear();
+  combDelays_[3].clear();
+  outRightDelay_.clear();
+  outLeftDelay_.clear();
+  lastFrame_[0] = 0.0;
+  lastFrame_[1] = 0.0;
+}
+
+void JCRev :: setT60( StkFloat T60 )
+{
+  for ( int i=0; i<4; i++ )
+    combCoefficient_[i] = pow(10.0, (-3.0 * combDelays_[i].getDelay() / (T60 * Stk::sampleRate())));
+}
+
+StkFrames& JCRev :: tick( StkFrames& frames, unsigned int channel )
+{
+#if defined(_STK_DEBUG_)
+  if ( channel >= frames.channels() - 1 ) {
+    errorString_ << "JCRev::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *samples = &frames[channel];
+  unsigned int hop = frames.channels();
+  for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
+    *samples = tick( *samples );
+    *samples++;
+    *samples = lastFrame_[1];
+  }
+
+  return frames;
+}
+
+StkFrames& JCRev :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iChannel, unsigned int oChannel )
+{
+#if defined(_STK_DEBUG_)
+  if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() - 1 ) {
+    errorString_ << "JCRev::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *iSamples = &iFrames[iChannel];
+  StkFloat *oSamples = &oFrames[oChannel];
+  unsigned int iHop = iFrames.channels(), oHop = oFrames.channels();
+  for ( unsigned int i=0; i<iFrames.frames(); i++, iSamples += iHop, oSamples += oHop ) {
+    *oSamples++ = tick( *iSamples );
+    *oSamples = lastFrame_[1];
+  }
+
+  return iFrames;
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/LentPitShift.cpp b/lib/MoMu-STK-1.0.0/src/LentPitShift.cpp
new file mode 100644 (file)
index 0000000..7dfe23a
--- /dev/null
@@ -0,0 +1,52 @@
+/***************************************************/\r
+/*! \class LentPitShift\r
+    \brief Pitch shifter effect class based on the Lent algorithm.\r
+\r
+    This class implements a pitch shifter using pitch \r
+    tracking and sample windowing and shifting.\r
+\r
+    by Francois Germain, 2009.\r
+*/\r
+/***************************************************/\r
+\r
+#include "LentPitShift.h"\r
+\r
+namespace stk {\r
+\r
+LentPitShift::LentPitShift( StkFloat periodRatio, int tMax )\r
+  : inputFrames(0.,tMax,1), outputFrames(0.,tMax,1), ptrFrames(0), inputPtr(0), outputPtr(0.), tMax_(tMax), periodRatio_(periodRatio), zeroFrame(0., tMax, 1)\r
+{\r
+       window = new StkFloat[2*tMax_]; // Allocation of the array for the hamming window\r
+       threshold_ = 0.1;               // Default threshold for pitch tracking\r
+\r
+       dt = new StkFloat[tMax+1]; // Allocation of the euclidian distance coefficient array.  The first one is never used.\r
+       cumDt = new StkFloat[tMax+1];  // Allocation of the cumulative sum array\r
+       cumDt[0] = 0.;                 // Initialization of the first coefficient of the cumulative sum\r
+       dpt = new StkFloat[tMax+1];    // Allocation of the pitch tracking function coefficient array\r
+       dpt[0]   = 1.;                 // Initialization of the first coefficient of dpt which is always the same\r
+\r
+       // Initialisation of the input and output delay lines\r
+       inputLine_.setMaximumDelay( 3 * tMax_ );\r
+       // The delay is choosed such as the coefficients are not read before being finalised.\r
+       outputLine_.setMaximumDelay( 3 * tMax_ );\r
+       outputLine_.setDelay( 3 * tMax_ );\r
+\r
+       //Initialization of the delay line of pitch tracking coefficients\r
+       //coeffLine_ = new Delay[512];\r
+       //for(int i=0;i<tMax_;i++)\r
+       //      coeffLine_[i] = new Delay( tMax_, tMax_ );\r
+}\r
+\r
+void LentPitShift :: clear()\r
+{\r
+       inputLine_.clear();\r
+       outputLine_.clear();\r
+}\r
+\r
+void LentPitShift :: setShift( StkFloat shift )\r
+{\r
+  if ( shift <= 0.0 ) periodRatio_ = 1.0;\r
+  periodRatio_ = 1.0 / shift; \r
+}\r
+\r
+} // stk namespace\r
diff --git a/lib/MoMu-STK-1.0.0/src/Mandolin.cpp b/lib/MoMu-STK-1.0.0/src/Mandolin.cpp
new file mode 100644 (file)
index 0000000..7646133
--- /dev/null
@@ -0,0 +1,160 @@
+/***************************************************/
+/*! \class Mandolin
+    \brief STK mandolin instrument model class.
+
+    This class inherits from PluckTwo and uses
+    "commuted synthesis" techniques to model a
+    mandolin instrument.
+
+    This is a digital waveguide model, making its
+    use possibly subject to patents held by
+    Stanford University, Yamaha, and others.
+    Commuted Synthesis, in particular, is covered
+    by patents, granted, pending, and/or
+    applied-for.  All are assigned to the Board of
+    Trustees, Stanford University.  For
+    information, contact the Office of Technology
+    Licensing, Stanford University.
+
+    Control Change Numbers: 
+       - Body Size = 2
+       - Pluck Position = 4
+       - String Sustain = 11
+       - String Detuning = 1
+       - Microphone Position = 128
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "Mandolin.h"
+#include "Skini_msg.h"
+
+namespace stk {
+
+Mandolin :: Mandolin( StkFloat lowestFrequency )
+  : PluckTwo( lowestFrequency )
+{
+  // Concatenate the STK rawwave path to the rawwave files
+  soundfile_[0] = new FileWvIn( (Stk::rawwavePath() + "mand1.raw").c_str(), true );
+  soundfile_[1] = new FileWvIn( (Stk::rawwavePath() + "mand2.raw").c_str(), true );
+  soundfile_[2] = new FileWvIn( (Stk::rawwavePath() + "mand3.raw").c_str(), true );
+  soundfile_[3] = new FileWvIn( (Stk::rawwavePath() + "mand4.raw").c_str(), true );
+  soundfile_[4] = new FileWvIn( (Stk::rawwavePath() + "mand5.raw").c_str(), true );
+  soundfile_[5] = new FileWvIn( (Stk::rawwavePath() + "mand6.raw").c_str(), true );
+  soundfile_[6] = new FileWvIn( (Stk::rawwavePath() + "mand7.raw").c_str(), true );
+  soundfile_[7] = new FileWvIn( (Stk::rawwavePath() + "mand8.raw").c_str(), true );
+  soundfile_[8] = new FileWvIn( (Stk::rawwavePath() + "mand9.raw").c_str(), true );
+  soundfile_[9] = new FileWvIn( (Stk::rawwavePath() + "mand10.raw").c_str(), true );
+  soundfile_[10] = new FileWvIn( (Stk::rawwavePath() + "mand11.raw").c_str(), true );
+  soundfile_[11] = new FileWvIn( (Stk::rawwavePath() + "mand12.raw").c_str(), true );
+
+  mic_ = 0;
+  dampTime_ = 0;
+  waveDone_ = soundfile_[mic_]->isFinished();
+}
+
+Mandolin :: ~Mandolin( void )
+{
+  for ( int i=0; i<12; i++ )
+    delete soundfile_[i];
+}
+
+void Mandolin :: pluck( StkFloat amplitude )
+{
+  // This function gets interesting, because pluck
+  // may be longer than string length, so we just
+  // reset the soundfile and add in the pluck in
+  // the tick method.
+  soundfile_[mic_]->reset();
+  waveDone_ = false;
+  pluckAmplitude_ = amplitude;
+  if ( amplitude < 0.0 ) {
+    errorString_ << "Mandolin::pluck: amplitude parameter less than zero ... setting to 0.0!";
+    handleError( StkError::WARNING );
+    pluckAmplitude_ = 0.0;
+  }
+  else if ( amplitude > 1.0 ) {
+    errorString_ << "Mandolin::pluck: amplitude parameter greater than one ... setting to 1.0!";
+    handleError( StkError::WARNING );
+    pluckAmplitude_ = 1.0;
+  }
+
+  // Set the pick position, which puts zeroes at position * length.
+  combDelay_.setDelay( 0.5 * pluckPosition_ * lastLength_ ); 
+  dampTime_ = (long) lastLength_;   // See tick method below.
+}
+
+void Mandolin :: pluck( StkFloat amplitude, StkFloat position )
+{
+  // Pluck position puts zeroes at position * length.
+  pluckPosition_ = position;
+  if ( position < 0.0 ) {
+    std::cerr << "Mandolin::pluck: position parameter less than zero ... setting to 0.0!";
+    handleError( StkError::WARNING );
+    pluckPosition_ = 0.0;
+  }
+  else if ( position > 1.0 ) {
+    errorString_ << "Mandolin::pluck: amplitude parameter greater than one ... setting to 1.0!";
+    handleError( StkError::WARNING );
+    pluckPosition_ = 1.0;
+  }
+
+  this->pluck( amplitude );
+}
+
+void Mandolin :: noteOn( StkFloat frequency, StkFloat amplitude )
+{
+  this->setFrequency( frequency );
+  this->pluck( amplitude );
+
+#if defined(_STK_DEBUG_)
+  errorString_ << "Mandolin::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << ".";
+  handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+void Mandolin :: setBodySize( StkFloat size )
+{
+  // Scale the commuted body response by its sample rate (22050).
+  StkFloat rate = size * 22050.0 / Stk::sampleRate();
+  for ( int i=0; i<12; i++ )
+    soundfile_[i]->setRate( rate );
+}
+
+void Mandolin :: controlChange( int number, StkFloat value )
+{
+  StkFloat norm = value * ONE_OVER_128;
+  if ( norm < 0 ) {
+    norm = 0.0;
+    errorString_ << "Mandolin::controlChange: control value less than zero ... setting to zero!";
+    handleError( StkError::WARNING );
+  }
+  else if ( norm > 1.0 ) {
+    norm = 1.0;
+    errorString_ << "Mandolin::controlChange: control value greater than 128.0 ... setting to 128.0!";
+    handleError( StkError::WARNING );
+  }
+
+  if (number == __SK_BodySize_) // 2
+    this->setBodySize( norm * 2.0 );
+  else if (number == __SK_PickPosition_) // 4
+    this->setPluckPosition( norm );
+  else if (number == __SK_StringDamping_) // 11
+    this->setBaseLoopGain( 0.97 + (norm * 0.03));
+  else if (number == __SK_StringDetune_) // 1
+    this->setDetune( 1.0 - (norm * 0.1) );
+  else if (number == __SK_AfterTouch_Cont_) // 128
+    mic_ = (int) (norm * 11.0);
+  else {
+    errorString_ << "Mandolin::controlChange: undefined control number (" << number << ")!";
+    handleError( StkError::WARNING );
+  }
+
+#if defined(_STK_DEBUG_)
+    errorString_ << "Mandolin::controlChange: number = " << number << ", value = " << value << ".";
+    handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/Mesh2D.cpp b/lib/MoMu-STK-1.0.0/src/Mesh2D.cpp
new file mode 100644 (file)
index 0000000..c324569
--- /dev/null
@@ -0,0 +1,400 @@
+/***************************************************/
+/*! \class Mesh2D
+    \brief Two-dimensional rectilinear waveguide mesh class.
+
+    This class implements a rectilinear,
+    two-dimensional digital waveguide mesh
+    structure.  For details, see Van Duyne and
+    Smith, "Physical Modeling with the 2-D Digital
+    Waveguide Mesh", Proceedings of the 1993
+    International Computer Music Conference.
+
+    This is a digital waveguide model, making its
+    use possibly subject to patents held by Stanford
+    University, Yamaha, and others.
+
+    Control Change Numbers: 
+       - X Dimension = 2
+       - Y Dimension = 4
+       - Mesh Decay = 11
+       - X-Y Input Position = 1
+
+    by Julius Smith, 2000 - 2002.
+    Revised by Gary Scavone for STK, 2002.
+*/
+/***************************************************/
+
+#include "Mesh2D.h"
+#include "Skini_msg.h"
+
+namespace stk {
+
+Mesh2D :: Mesh2D( short nX, short nY )
+{
+  this->setNX(nX);
+  this->setNY(nY);
+
+  StkFloat pole = 0.05;
+
+  short i;
+  for (i=0; i<NYMAX; i++) {
+    filterY_[i].setPole( pole );
+    filterY_[i].setGain( 0.99 );
+  }
+
+  for (i=0; i<NXMAX; i++) {
+    filterX_[i].setPole( pole );
+    filterX_[i].setGain( 0.99 );
+  }
+
+  this->clearMesh();
+
+  counter_=0;
+  xInput_ = 0;
+  yInput_ = 0;
+}
+
+Mesh2D :: ~Mesh2D( void )
+{
+}
+
+void Mesh2D :: clear( void )
+{
+  this->clearMesh();
+
+  short i;
+  for (i=0; i<NY_; i++)
+    filterY_[i].clear();
+
+  for (i=0; i<NX_; i++)
+    filterX_[i].clear();
+
+  counter_=0;
+}
+
+void Mesh2D :: clearMesh( void )
+{
+  int x, y;
+  for (x=0; x<NXMAX-1; x++) {
+    for (y=0; y<NYMAX-1; y++) {
+      v_[x][y] = 0;
+    }
+  }
+  for (x=0; x<NXMAX; x++) {
+    for (y=0; y<NYMAX; y++) {
+
+      vxp_[x][y] = 0;
+      vxm_[x][y] = 0;
+      vyp_[x][y] = 0;
+      vym_[x][y] = 0;
+
+      vxp1_[x][y] = 0;
+      vxm1_[x][y] = 0;
+      vyp1_[x][y] = 0;
+      vym1_[x][y] = 0;
+    }
+  }
+}
+
+StkFloat Mesh2D :: energy( void )
+{
+  // Return total energy contained in wave variables Note that some
+  // energy is also contained in any filter delay elements.
+
+  int x, y;
+  StkFloat t;
+  StkFloat e = 0;
+  if ( counter_ & 1 ) { // Ready for Mesh2D::tick1() to be called.
+    for (x=0; x<NX_; x++) {
+      for (y=0; y<NY_; y++) {
+        t = vxp1_[x][y];
+        e += t*t;
+        t = vxm1_[x][y];
+        e += t*t;
+        t = vyp1_[x][y];
+        e += t*t;
+        t = vym1_[x][y];
+        e += t*t;
+      }
+    }
+  }
+  else { // Ready for Mesh2D::tick0() to be called.
+    for (x=0; x<NX_; x++) {
+      for (y=0; y<NY_; y++) {
+        t = vxp_[x][y];
+        e += t*t;
+        t = vxm_[x][y];
+        e += t*t;
+        t = vyp_[x][y];
+        e += t*t;
+        t = vym_[x][y];
+        e += t*t;
+      }
+    }
+  }
+
+  return(e);
+}
+
+void Mesh2D :: setNX( short lenX )
+{
+  NX_ = lenX;
+  if ( lenX < 2 ) {
+    errorString_ << "Mesh2D::setNX(" << lenX << "): Minimum length is 2!";
+    handleError( StkError::WARNING );
+    NX_ = 2;
+  }
+  else if ( lenX > NXMAX ) {
+    errorString_ << "Mesh2D::setNX(" << lenX << "): Maximum length is " << NXMAX << '!';;
+    handleError( StkError::WARNING );
+    NX_ = NXMAX;
+  }
+}
+
+void Mesh2D :: setNY( short lenY )
+{
+  NY_ = lenY;
+  if ( lenY < 2 ) {
+    errorString_ << "Mesh2D::setNY(" << lenY << "): Minimum length is 2!";
+    handleError( StkError::WARNING );
+    NY_ = 2;
+  }
+  else if ( lenY > NYMAX ) {
+    errorString_ << "Mesh2D::setNY(" << lenY << "): Maximum length is " << NXMAX << '!';;
+    handleError( StkError::WARNING );
+    NY_ = NYMAX;
+  }
+}
+
+void Mesh2D :: setDecay( StkFloat decayFactor )
+{
+  StkFloat gain = decayFactor;
+  if ( decayFactor < 0.0 ) {
+    errorString_ << "Mesh2D::setDecay: decayFactor value is less than 0.0!";
+    handleError( StkError::WARNING );
+    gain = 0.0;
+  }
+  else if ( decayFactor > 1.0 ) {
+    errorString_ << "Mesh2D::setDecay decayFactor value is greater than 1.0!";
+    handleError( StkError::WARNING );
+    gain = 1.0;
+  }
+
+  int i;
+  for (i=0; i<NYMAX; i++)
+    filterY_[i].setGain( gain );
+
+  for (i=0; i<NXMAX; i++)
+    filterX_[i].setGain( gain );
+}
+
+void Mesh2D :: setInputPosition( StkFloat xFactor, StkFloat yFactor )
+{
+  if ( xFactor < 0.0 ) {
+    errorString_ << "Mesh2D::setInputPosition xFactor value is less than 0.0!";
+    handleError( StkError::WARNING );
+    xInput_ = 0;
+  }
+  else if ( xFactor > 1.0 ) {
+    errorString_ << "Mesh2D::setInputPosition xFactor value is greater than 1.0!";
+    handleError( StkError::WARNING );
+    xInput_ = NX_ - 1;
+  }
+  else
+    xInput_ = (short) (xFactor * (NX_ - 1));
+
+  if ( yFactor < 0.0 ) {
+    errorString_ << "Mesh2D::setInputPosition yFactor value is less than 0.0!";
+    handleError( StkError::WARNING );
+    yInput_ = 0;
+  }
+  else if ( yFactor > 1.0 ) {
+    errorString_ << "Mesh2D::setInputPosition yFactor value is greater than 1.0!";
+    handleError( StkError::WARNING );
+    yInput_ = NY_ - 1;
+  }
+  else
+    yInput_ = (short) (yFactor * (NY_ - 1));
+}
+
+void Mesh2D :: noteOn( StkFloat frequency, StkFloat amplitude )
+{
+  // Input at corner.
+  if ( counter_ & 1 ) {
+    vxp1_[xInput_][yInput_] += amplitude;
+    vyp1_[xInput_][yInput_] += amplitude;
+  }
+  else {
+    vxp_[xInput_][yInput_] += amplitude;
+    vyp_[xInput_][yInput_] += amplitude;
+  }
+
+#if defined(_STK_DEBUG_)
+  errorString_ << "Mesh2D::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << ".";
+  handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+void Mesh2D :: noteOff( StkFloat amplitude )
+{
+#if defined(_STK_DEBUG_)
+  errorString_ << "Mesh2D::NoteOff: amplitude = " << amplitude << ".";
+  handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+StkFloat Mesh2D :: inputTick( StkFloat input )
+{
+  if ( counter_ & 1 ) {
+    vxp1_[xInput_][yInput_] += input;
+    vyp1_[xInput_][yInput_] += input;
+    lastFrame_[0] = tick1();
+  }
+  else {
+    vxp_[xInput_][yInput_] += input;
+    vyp_[xInput_][yInput_] += input;
+    lastFrame_[0] = tick0();
+  }
+
+  counter_++;
+  return lastFrame_[0];
+}
+
+StkFloat Mesh2D :: tick( unsigned int )
+{
+  lastFrame_[0] = ((counter_ & 1) ? this->tick1() : this->tick0());
+  counter_++;
+  return lastFrame_[0];
+}
+
+const StkFloat VSCALE = 0.5;
+
+StkFloat Mesh2D :: tick0( void )
+{
+  int x, y;
+  StkFloat outsamp = 0;
+
+  // Update junction velocities.
+  for (x=0; x<NX_-1; x++) {
+    for (y=0; y<NY_-1; y++) {
+      v_[x][y] = ( vxp_[x][y] + vxm_[x+1][y] + 
+                 vyp_[x][y] + vym_[x][y+1] ) * VSCALE;
+    }
+  }    
+
+  // Update junction outgoing waves, using alternate wave-variable buffers.
+  for (x=0; x<NX_-1; x++) {
+    for (y=0; y<NY_-1; y++) {
+      StkFloat vxy = v_[x][y];
+      // Update positive-going waves.
+      vxp1_[x+1][y] = vxy - vxm_[x+1][y];
+      vyp1_[x][y+1] = vxy - vym_[x][y+1];
+      // Update minus-going waves.
+      vxm1_[x][y] = vxy - vxp_[x][y];
+      vym1_[x][y] = vxy - vyp_[x][y];
+    }
+  }    
+
+  // Loop over velocity-junction boundary faces, update edge
+  // reflections, with filtering.  We're only filtering on one x and y
+  // edge here and even this could be made much sparser.
+  for (y=0; y<NY_-1; y++) {
+    vxp1_[0][y] = filterY_[y].tick(vxm_[0][y]);
+    vxm1_[NX_-1][y] = vxp_[NX_-1][y];
+  }
+  for (x=0; x<NX_-1; x++) {
+    vyp1_[x][0] = filterX_[x].tick(vym_[x][0]);
+    vym1_[x][NY_-1] = vyp_[x][NY_-1];
+  }
+
+  // Output = sum of outgoing waves at far corner.  Note that the last
+  // index in each coordinate direction is used only with the other
+  // coordinate indices at their next-to-last values.  This is because
+  // the "unit strings" attached to each velocity node to terminate
+  // the mesh are not themselves connected together.
+  outsamp = vxp_[NX_-1][NY_-2] + vyp_[NX_-2][NY_-1];
+
+  return outsamp;
+}
+
+StkFloat Mesh2D :: tick1( void )
+{
+  int x, y;
+  StkFloat outsamp = 0;
+
+  // Update junction velocities.
+  for (x=0; x<NX_-1; x++) {
+    for (y=0; y<NY_-1; y++) {
+      v_[x][y] = ( vxp1_[x][y] + vxm1_[x+1][y] + 
+                 vyp1_[x][y] + vym1_[x][y+1] ) * VSCALE;
+    }
+  }
+
+  // Update junction outgoing waves, 
+  // using alternate wave-variable buffers.
+  for (x=0; x<NX_-1; x++) {
+    for (y=0; y<NY_-1; y++) {
+      StkFloat vxy = v_[x][y];
+
+      // Update positive-going waves.
+      vxp_[x+1][y] = vxy - vxm1_[x+1][y];
+      vyp_[x][y+1] = vxy - vym1_[x][y+1];
+
+      // Update minus-going waves.
+      vxm_[x][y] = vxy - vxp1_[x][y];
+      vym_[x][y] = vxy - vyp1_[x][y];
+    }
+  }
+
+  // Loop over velocity-junction boundary faces, update edge
+  // reflections, with filtering.  We're only filtering on one x and y
+  // edge here and even this could be made much sparser.
+  for (y=0; y<NY_-1; y++) {
+    vxp_[0][y] = filterY_[y].tick(vxm1_[0][y]);
+    vxm_[NX_-1][y] = vxp1_[NX_-1][y];
+  }
+  for (x=0; x<NX_-1; x++) {
+    vyp_[x][0] = filterX_[x].tick(vym1_[x][0]);
+    vym_[x][NY_-1] = vyp1_[x][NY_-1];
+  }
+
+  // Output = sum of outgoing waves at far corner.
+  outsamp = vxp1_[NX_-1][NY_-2] + vyp1_[NX_-2][NY_-1];
+
+  return outsamp;
+}
+
+void Mesh2D :: controlChange( int number, StkFloat value )
+{
+  StkFloat norm = value * ONE_OVER_128;
+  if ( norm < 0 ) {
+    norm = 0.0;
+    errorString_ << "Mesh2D::controlChange: control value less than zero ... setting to zero!";
+    handleError( StkError::WARNING );
+  }
+  else if ( norm > 1.0 ) {
+    norm = 1.0;
+    errorString_ << "Mesh2D::controlChange: control value greater than 128.0 ... setting to 128.0!";
+    handleError( StkError::WARNING );
+  }
+
+  if (number == 2) // 2
+    this->setNX( (short) (norm * (NXMAX-2) + 2) );
+  else if (number == 4) // 4
+    this->setNY( (short) (norm * (NYMAX-2) + 2) );
+  else if (number == 11) // 11
+    this->setDecay( 0.9 + (norm * 0.1) );
+  else if (number == __SK_ModWheel_) // 1
+    this->setInputPosition( norm, norm );
+  else {
+    errorString_ << "Mesh2D::controlChange: undefined control number (" << number << ")!";
+    handleError( StkError::WARNING );
+  }
+
+#if defined(_STK_DEBUG_)
+    errorString_ << "Mesh2D::controlChange: number = " << number << ", value = " << value << ".";
+    handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/Messager.cpp b/lib/MoMu-STK-1.0.0/src/Messager.cpp
new file mode 100644 (file)
index 0000000..ac08cdc
--- /dev/null
@@ -0,0 +1,428 @@
+/***************************************************/
+/*! \class Messager
+    \brief STK input control message parser.
+
+    This class reads and parses control messages from a variety of
+    sources, such as a scorefile, MIDI port, socket connection, or
+    stdin.  MIDI messages are retrieved using the RtMidi class.  All
+    other input sources (scorefile, socket, or stdin) are assumed to
+    provide SKINI formatted messages.  This class can be compiled with
+    generic, non-realtime support, in which case only scorefile
+    reading is possible.
+
+    The various \e realtime message acquisition mechanisms (from MIDI,
+    socket, or stdin) take place asynchronously, filling the message
+    queue.  A call to popMessage() will pop the next available control
+    message from the queue and return it via the referenced Message
+    structure.  When a \e non-realtime scorefile is set, it is not
+    possible to start reading realtime input messages (from MIDI,
+    socket, or stdin).  Likewise, it is not possible to read from a
+    scorefile when a realtime input mechanism is running.
+
+    When MIDI input is started, input is also automatically read from
+    stdin.  This allows for program termination via the terminal
+    window.  An __SK_Exit_ message is pushed onto the stack whenever
+    an "exit" or "Exit" message is received from stdin or when all
+    socket connections close and no stdin thread is running.
+
+    This class is primarily for use in STK example programs but it is
+    generic enough to work in many other contexts.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "Messager.h"
+#include <iostream>
+#include <algorithm>
+#include "Skini_msg.h"
+
+namespace stk {
+
+#if defined(__STK_REALTIME__)
+
+extern "C" THREAD_RETURN THREAD_TYPE stdinHandler(void * ptr);
+extern "C" THREAD_RETURN THREAD_TYPE socketHandler(void * ptr);
+
+#endif // __STK_REALTIME__
+
+static const int STK_FILE   = 0x1;
+static const int STK_MIDI   = 0x2;
+static const int STK_STDIN   = 0x4;
+static const int STK_SOCKET = 0x8;
+
+Messager :: Messager()
+{
+  data_.sources = 0;
+  data_.queueLimit = DEFAULT_QUEUE_LIMIT;
+#if defined(__STK_REALTIME__)
+  data_.socket = 0;
+  data_.midi = 0;
+#endif
+}
+
+Messager :: ~Messager()
+{
+  // Clear the queue in case any thread is waiting on its limit.
+#if defined(__STK_REALTIME__)
+  data_.mutex.lock();
+#endif
+  while ( data_.queue.size() ) data_.queue.pop();
+  data_.sources = 0;
+
+#if defined(__STK_REALTIME__)
+  data_.mutex.unlock();
+  if ( data_.socket ) {
+    socketThread_.wait();
+    delete data_.socket;
+  }
+
+  if ( data_.midi ) delete data_.midi;
+#endif
+}
+
+bool Messager :: setScoreFile( const char* filename )
+{
+  if ( data_.sources ) {
+    if ( data_.sources == STK_FILE ) {
+      errorString_ << "Messager::setScoreFile: already reading a scorefile!";
+      handleError( StkError::WARNING );
+    }
+    else {
+      errorString_ << "Messager::setScoreFile: already reading realtime control input ... cannot do scorefile input too!";
+      handleError( StkError::WARNING );
+    }
+    return false;
+  }
+
+  if ( !data_.skini.setFile( filename ) ) return false;
+  data_.sources = STK_FILE;
+  return true;
+}
+
+void Messager :: popMessage( Skini::Message& message )
+{
+  if ( data_.sources == STK_FILE ) { // scorefile input
+    if ( !data_.skini.nextMessage( message ) )
+      message.type = __SK_Exit_;
+    return;
+  }
+
+  if ( data_.queue.size() == 0 ) {
+    // An empty (or invalid) message is indicated by a type = 0.
+    message.type = 0;
+    return;
+  }
+
+  // Copy queued message to the message pointer structure and then "pop" it.
+#if defined(__STK_REALTIME__)
+  data_.mutex.lock();
+#endif
+  message = data_.queue.front();
+  data_.queue.pop();
+#if defined(__STK_REALTIME__)
+  data_.mutex.unlock();
+#endif
+}
+
+void Messager :: pushMessage( Skini::Message& message )
+{
+#if defined(__STK_REALTIME__)
+  data_.mutex.lock();
+#endif
+  data_.queue.push( message );
+#if defined(__STK_REALTIME__)
+  data_.mutex.unlock();
+#endif
+}
+
+#if defined(__STK_REALTIME__)
+
+bool Messager :: startStdInput()
+{
+  if ( data_.sources == STK_FILE ) {
+    errorString_ << "Messager::startStdInput: already reading a scorefile ... cannot do realtime control input too!";
+    handleError( StkError::WARNING );
+    return false;
+  }
+
+  if ( data_.sources & STK_STDIN ) {
+    errorString_ << "Messager::startStdInput: stdin input thread already started.";
+    handleError( StkError::WARNING );
+    return false;
+  }
+
+  // Start the stdin input thread.
+  if ( !stdinThread_.start( (THREAD_FUNCTION)&stdinHandler, &data_ ) ) {
+    errorString_ << "Messager::startStdInput: unable to start stdin input thread!";
+    handleError( StkError::WARNING );
+    return false;
+  }
+  data_.sources |= STK_STDIN;
+  return true;
+}
+
+THREAD_RETURN THREAD_TYPE stdinHandler(void *ptr)
+{
+  Messager::MessagerData *data = (Messager::MessagerData *) ptr;
+  Skini::Message message;
+
+  std::string line;
+  while ( !std::getline( std::cin, line).eof() ) {
+    if ( line.empty() ) continue;
+    if ( line.compare(0, 4, "Exit") == 0 || line.compare(0, 4, "exit") == 0 )
+      break;
+
+    data->mutex.lock();
+    if ( data->skini.parseString( line, message ) )
+      data->queue.push( message );
+    data->mutex.unlock();
+
+    while ( data->queue.size() >= data->queueLimit ) Stk::sleep( 50 );
+  }
+
+  // We assume here that if someone types an "exit" message in the
+  // terminal window, all processing should stop.
+  message.type = __SK_Exit_;
+  data->queue.push( message );
+  data->sources &= ~STK_STDIN;
+
+  return NULL;
+}
+
+void midiHandler( double timeStamp, std::vector<unsigned char> *bytes, void *ptr )
+{
+  if ( bytes->size() < 2 ) return;
+
+  // Parse the MIDI bytes ... only keep MIDI channel messages.
+  if ( bytes->at(0) > 239 ) return;
+
+  Messager::MessagerData *data = (Messager::MessagerData *) ptr;
+  Skini::Message message;
+
+  message.type = bytes->at(0) & 0xF0;
+  message.channel = bytes->at(0) & 0x0F;
+  message.time = 0.0; // realtime messages should have delta time = 0.0
+  message.intValues[0] = bytes->at(1);
+  message.floatValues[0] = (StkFloat) message.intValues[0];
+  if ( ( message.type != 0xC0 ) && ( message.type != 0xD0 ) ) {
+    if ( bytes->size() < 3 ) return;
+    message.intValues[1] = bytes->at(2);
+    message.floatValues[1] = (StkFloat) message.intValues[1];
+  }
+
+  while ( data->queue.size() >= data->queueLimit ) Stk::sleep( 50 );
+
+  data->mutex.lock();
+  data->queue.push( message );
+  data->mutex.unlock();
+}
+
+bool Messager :: startMidiInput( int port )
+{
+  if ( data_.sources == STK_FILE ) {
+    errorString_ << "Messager::startMidiInput: already reading a scorefile ... cannot do realtime control input too!";
+    handleError( StkError::WARNING );
+    return false;
+  }
+
+  if ( data_.sources & STK_MIDI ) {
+    errorString_ << "Messager::startMidiInput: MIDI input already started.";
+    handleError( StkError::WARNING );
+    return false;
+  }
+
+  // First start the stdin input thread if it isn't already running
+  // (to allow the user to exit).
+  if ( !( data_.sources & STK_STDIN ) ) {
+    if ( this->startStdInput() == false ) {
+      errorString_ << "Messager::startMidiInput: unable to start input from stdin.";
+      handleError( StkError::WARNING );
+      return false;
+    }
+  }
+
+  try {
+    data_.midi = new RtMidiIn();
+    data_.midi->setCallback( &midiHandler, (void *) &data_ );
+    if ( port == -1 ) data_.midi->openVirtualPort();
+    else data_.midi->openPort( (unsigned int)port );
+  }
+  catch ( RtError &error ) {
+    errorString_ << "Messager::startMidiInput: error creating RtMidiIn instance (" << error.getMessage() << ").";
+    handleError( StkError::WARNING );
+    return false;
+  }
+
+  data_.sources |= STK_MIDI;
+  return true;
+}
+
+bool Messager :: startSocketInput( int port )
+{
+  if ( data_.sources == STK_FILE ) {
+    errorString_ << "Messager::startSocketInput: already reading a scorefile ... cannot do realtime control input too!";
+    handleError( StkError::WARNING );
+    return false;
+  }
+
+  if ( data_.sources & STK_SOCKET ) {
+    errorString_ << "Messager::startSocketInput: socket input thread already started.";
+    handleError( StkError::WARNING );
+    return false;
+  }
+
+  // Create the socket server.
+  try {
+    data_.socket = new TcpServer( port );
+  }
+  catch ( StkError& ) {
+    return false;
+  }
+
+  errorString_ << "Socket server listening for connection(s) on port " << port << "...";
+  handleError( StkError::STATUS );
+
+  // Initialize socket descriptor information.
+  FD_ZERO(&data_.mask);
+  int fd = data_.socket->id();
+  FD_SET( fd, &data_.mask );
+  data_.fd.push_back( fd );
+
+  // Start the socket thread.
+  if ( !socketThread_.start( (THREAD_FUNCTION)&socketHandler, &data_ ) ) {
+    errorString_ << "Messager::startSocketInput: unable to start socket input thread!";
+    handleError( StkError::WARNING );
+    return false;
+  }
+
+  data_.sources |= STK_SOCKET;
+  return true;
+}
+
+#if (defined(__OS_IRIX__) || defined(__OS_LINUX__) || defined(__OS_MACOSX__))
+  #include <sys/time.h>
+  #include <errno.h>
+#endif
+
+THREAD_RETURN THREAD_TYPE socketHandler(void *ptr)
+{
+  Messager::MessagerData *data = (Messager::MessagerData *) ptr;
+  Skini::Message message;
+  std::vector<int>& fd = data->fd;
+
+  struct timeval timeout;
+  fd_set rmask;
+  int newfd;
+  unsigned int i;
+  const int bufferSize = 1024;
+  char buffer[bufferSize];
+  int index = 0, bytesRead = 0;
+  std::string line;
+  std::vector<int> fdclose;
+
+  while ( data->sources & STK_SOCKET ) {
+
+    // Use select function to periodically poll socket desriptors.
+    rmask = data->mask;
+    timeout.tv_sec = 0; timeout.tv_usec = 50000; // 50 milliseconds
+    if ( select( fd.back()+1, &rmask, (fd_set *)0, (fd_set *)0, &timeout ) <= 0 ) continue;
+
+    // A file descriptor is set.  Check if there's a new socket connection available.
+    if ( FD_ISSET( data->socket->id(), &rmask ) ) {
+
+      // Accept and service new connection.
+      newfd = data->socket->accept();
+      if ( newfd >= 0 ) {
+        std::cout << "New socket connection made.\n" << std::endl;
+
+        // Set the socket to non-blocking mode.
+        Socket::setBlocking( newfd, false );
+
+        // Save the descriptor and update the masks.
+        fd.push_back( newfd );
+        std::sort( fd.begin(), data->fd.end() );
+        FD_SET( newfd, &data->mask );
+        FD_CLR( data->socket->id(), &rmask );
+      }
+      else
+        std::cerr << "Messager: Couldn't accept connection request!\n";
+    }
+
+    // Check the other descriptors.
+    for ( i=0; i<fd.size(); i++ ) {
+
+      if ( !FD_ISSET( fd[i], &rmask ) ) continue;
+
+      // This connection has data.  Read and parse it.
+      bytesRead = 0;
+      index = 0;
+#if ( defined(__OS_IRIX__) || defined(__OS_LINUX__) || defined(__OS_MACOSX__) )
+      errno = 0;
+      while (bytesRead != -1 && errno != EAGAIN) {
+#elif defined(__OS_WINDOWS__)
+      while (bytesRead != SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK) {
+#endif
+
+        while ( index < bytesRead ) {
+          line += buffer[index];
+          if ( buffer[index++] == '\n' ) {
+            data->mutex.lock();
+            if ( line.compare(0, 4, "Exit") == 0 || line.compare(0, 4, "exit") == 0 ) {
+              // Ignore this line and assume the connection will be
+              // closed on a subsequent read call.
+              ;
+            }
+            else if ( data->skini.parseString( line, message ) )
+              data->queue.push( message );
+            data->mutex.unlock();
+            line.erase();
+          }
+        }
+        index = 0;
+
+        bytesRead = Socket::readBuffer(fd[i], buffer, bufferSize, 0);
+        if (bytesRead == 0) {
+          // This socket connection closed.
+          FD_CLR( fd[i], &data->mask );
+          Socket::close( fd[i] );
+          fdclose.push_back( fd[i] );
+        }
+      }
+    }
+
+    // Now remove descriptors for closed connections.
+    for ( i=0; i<fdclose.size(); i++ ) {
+      for ( unsigned int j=0; j<fd.size(); j++ ) {
+        if ( fd[j] == fdclose[i] ) {
+          fd.erase( fd.begin() + j );
+          break;
+        }
+      }
+
+      // Check to see whether all connections are closed.  Note that
+      // the server descriptor will always remain.
+      if ( fd.size() == 1 ) {
+        data->sources &= ~STK_SOCKET;
+        if ( data->sources & STK_MIDI )
+          std::cout << "MIDI input still running ... type 'exit<cr>' to quit.\n" << std::endl;
+        else if ( !(data->sources & STK_STDIN) ) {
+          // No stdin thread running, so quit now.
+          message.type = __SK_Exit_;
+          data->queue.push( message );
+        }
+      }
+      fdclose.clear();
+    }
+
+    // Wait until we're below the queue limit.
+    while ( data->queue.size() >= data->queueLimit ) Stk::sleep( 50 );
+  }
+
+  return NULL;
+}
+
+#endif
+
+} // stk namespace
+
diff --git a/lib/MoMu-STK-1.0.0/src/MidiFileIn.cpp b/lib/MoMu-STK-1.0.0/src/MidiFileIn.cpp
new file mode 100644 (file)
index 0000000..17fce6f
--- /dev/null
@@ -0,0 +1,367 @@
+/**********************************************************************/
+/*! \class MidiFileIn
+    \brief A standard MIDI file reading/parsing class.
+
+    This class can be used to read events from a standard MIDI file.
+    Event bytes are copied to a C++ vector and must be subsequently
+    interpreted by the user.  The function getNextMidiEvent() skips
+    meta and sysex events, returning only MIDI channel messages.
+    Event delta-times are returned in the form of "ticks" and a
+    function is provided to determine the current "seconds per tick".
+    Tempo changes are internally tracked by the class and reflected in
+    the values returned by the function getTickSeconds().
+
+    by Gary P. Scavone, 2003 - 2010.
+*/
+/**********************************************************************/
+
+#include "MidiFileIn.h"
+#include <cstring>
+#include <iostream>
+
+namespace stk {
+
+MidiFileIn :: MidiFileIn( std::string fileName )
+{
+  // Attempt to open the file.
+  file_.open( fileName.c_str(), std::ios::in | std::ios::binary );
+  if ( !file_ ) {
+    errorString_ << "MidiFileIn: error opening or finding file (" <<  fileName << ").";
+    handleError( StkError::FILE_NOT_FOUND );
+  }
+
+  // Parse header info.
+  char chunkType[4];
+  char buffer[4];
+  SINT32 *length;
+  if ( !file_.read( chunkType, 4 ) ) goto error;
+  if ( !file_.read( buffer, 4 ) ) goto error;
+#ifdef __LITTLE_ENDIAN__
+  swap32((unsigned char *)&buffer);
+#endif
+  length = (SINT32 *) &buffer;
+  if ( strncmp( chunkType, "MThd", 4 ) || ( *length != 6 ) ) {
+    errorString_ << "MidiFileIn: file (" <<  fileName << ") does not appear to be a MIDI file!";
+    handleError( StkError::FILE_UNKNOWN_FORMAT );
+  }
+
+  // Read the MIDI file format.
+  SINT16 *data;
+  if ( !file_.read( buffer, 2 ) ) goto error;
+#ifdef __LITTLE_ENDIAN__
+  swap16((unsigned char *)&buffer);
+#endif
+  data = (SINT16 *) &buffer;
+  if ( *data < 0 || *data > 2 ) {
+    errorString_ << "MidiFileIn: the file (" <<  fileName << ") format is invalid!";
+    handleError( StkError::FILE_ERROR );
+  }
+  format_ = *data;
+
+  // Read the number of tracks.
+  if ( !file_.read( buffer, 2 ) ) goto error;
+#ifdef __LITTLE_ENDIAN__
+  swap16((unsigned char *)&buffer);
+#endif
+  if ( format_ == 0 && *data != 1 ) {
+    errorString_ << "MidiFileIn: invalid number of tracks (>1) for a file format = 0!";
+    handleError( StkError::FILE_ERROR );
+  }
+  nTracks_ = *data;
+
+  // Read the beat division.
+  if ( !file_.read( buffer, 2 ) ) goto error;
+#ifdef __LITTLE_ENDIAN__
+  swap16((unsigned char *)&buffer);
+#endif
+  division_ = (int) *data;
+  double tickrate;
+  usingTimeCode_ = false;
+  if ( *data & 0x8000 ) {
+    // Determine ticks per second from time-code formats.
+    tickrate = (double) -(*data & 0x7F00);
+    // If frames per second value is 29, it really should be 29.97.
+    if ( tickrate == 29.0 ) tickrate = 29.97;
+    tickrate *= (*data & 0x00FF);
+    usingTimeCode_ = true;
+  }
+  else {
+    tickrate = (double) (*data & 0x7FFF); // ticks per quarter note
+  }
+
+  // Now locate the track offsets and lengths.  If not using time
+  // code, we can initialize the "tick time" using a default tempo of
+  // 120 beats per minute.  We will then check for tempo meta-events
+  // afterward.
+  unsigned int i;
+  for ( i=0; i<nTracks_; i++ ) {
+    if ( !file_.read( chunkType, 4 ) ) goto error;
+    if ( strncmp( chunkType, "MTrk", 4 ) ) goto error;
+    if ( !file_.read( buffer, 4 ) ) goto error;
+#ifdef __LITTLE_ENDIAN__
+  swap32((unsigned char *)&buffer);
+#endif
+    length = (SINT32 *) &buffer;
+    trackLengths_.push_back( *length );
+    trackOffsets_.push_back( (long) file_.tellg() );
+    trackPointers_.push_back( (long) file_.tellg() );
+    trackStatus_.push_back( 0 );
+    file_.seekg( *length, std::ios_base::cur );
+    if ( usingTimeCode_ ) tickSeconds_.push_back( (double) (1.0 / tickrate) );
+    else tickSeconds_.push_back( (double) (0.5 / tickrate) );
+  }
+
+  // Save the initial tickSeconds parameter.
+  TempoChange tempoEvent;
+  tempoEvent.count = 0;
+  tempoEvent.tickSeconds = tickSeconds_[0];
+  tempoEvents_.push_back( tempoEvent );
+
+  // If format 1 and not using time code, parse and save the tempo map
+  // on track 0.
+  if ( format_ == 1 && !usingTimeCode_ ) {
+    std::vector<unsigned char> event;
+    unsigned long value, count;
+
+    // We need to temporarily change the usingTimeCode_ value here so
+    // that the getNextEvent() function doesn't try to check the tempo
+    // map (which we're creating here).
+    usingTimeCode_ = true;
+    count = getNextEvent( &event, 0 );
+    while ( event.size() ) {
+      if ( ( event.size() == 6 ) && ( event[0] == 0xff ) &&
+           ( event[1] == 0x51 ) && ( event[2] == 0x03 ) ) {
+        tempoEvent.count = count;
+        value = ( event[3] << 16 ) + ( event[4] << 8 ) + event[5];
+        tempoEvent.tickSeconds = (double) (0.000001 * value / tickrate);
+        if ( count > tempoEvents_.back().count )
+          tempoEvents_.push_back( tempoEvent );
+        else
+          tempoEvents_.back() = tempoEvent;
+      }
+      count += getNextEvent( &event, 0 );
+    }
+    rewindTrack( 0 );
+    for ( unsigned int i=0; i<nTracks_; i++ ) {
+      trackCounters_.push_back( 0 );
+      trackTempoIndex_.push_back( 0 );
+    }
+    // Change the time code flag back!
+    usingTimeCode_ = false;
+  }
+
+  return;
+
+ error:
+  errorString_ << "MidiFileIn: error reading from file (" <<  fileName << ").";
+  handleError( StkError::FILE_ERROR );
+}
+
+MidiFileIn :: ~MidiFileIn()
+{
+  // An ifstream object implicitly closes itself during destruction
+  // but we'll make an explicit call to "close" anyway.
+  file_.close(); 
+}
+
+int MidiFileIn :: getFileFormat() const
+{
+  return format_;
+}
+
+unsigned int MidiFileIn :: getNumberOfTracks() const
+{
+  return nTracks_;
+}
+
+int MidiFileIn :: getDivision() const
+{
+  return division_;
+}
+
+void MidiFileIn :: rewindTrack( unsigned int track )
+{
+  if ( track >= nTracks_ ) {
+    errorString_ << "MidiFileIn::getNextEvent: invalid track argument (" <<  track << ").";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+
+  trackPointers_[track] = trackOffsets_[track];
+  trackStatus_[track] = 0;
+  tickSeconds_[track] = tempoEvents_[0].tickSeconds;
+}
+
+double MidiFileIn :: getTickSeconds( unsigned int track )
+{
+  // Return the current tick value in seconds for the given track.
+  if ( track >= nTracks_ ) {
+    errorString_ << "MidiFileIn::getTickSeconds: invalid track argument (" <<  track << ").";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+
+  return tickSeconds_[track];
+}
+
+unsigned long MidiFileIn :: getNextEvent( std::vector<unsigned char> *event, unsigned int track )
+{
+  // Fill the user-provided vector with the next event in the
+  // specified track (default = 0) and return the event delta time in
+  // ticks.  This function assumes that the stored track pointer is
+  // positioned at the start of a track event.  If the track has
+  // reached its end, the event vector size will be zero.
+  //
+  // If we have a format 0 or 2 file and we're not using timecode, we
+  // should check every meta-event for tempo changes and make
+  // appropriate updates to the tickSeconds_ parameter if so.
+  //
+  // If we have a format 1 file and we're not using timecode, keep a
+  // running sum of ticks for each track and update the tickSeconds_
+  // parameter as needed based on the stored tempo map.
+
+  if ( track >= nTracks_ ) {
+    errorString_ << "MidiFileIn::getNextEvent: invalid track argument (" <<  track << ").";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+
+  event->clear();
+  // Check for the end of the track.
+  if ( (trackPointers_[track] - trackOffsets_[track]) >= trackLengths_[track] )
+    return 0;
+
+  unsigned long ticks = 0, bytes = 0;
+  bool isTempoEvent = false;
+
+  // Read the event delta time.
+  file_.seekg( trackPointers_[track], std::ios_base::beg );
+  if ( !readVariableLength( &ticks ) ) goto error;
+
+  // Parse the event stream to determine the event length.
+  unsigned char c;
+  if ( !file_.read( (char *)&c, 1 ) ) goto error;
+  switch ( c ) {
+
+  case 0xFF: // A Meta-Event
+    unsigned long position;
+    trackStatus_[track] = 0;
+    event->push_back( c );
+    if ( !file_.read( (char *)&c, 1 ) ) goto error;
+    event->push_back( c );
+    if ( format_ != 1 && ( c == 0x51 ) ) isTempoEvent = true;
+    position = file_.tellg();
+    if ( !readVariableLength( &bytes ) ) goto error;
+    bytes += ( (unsigned long)file_.tellg() - position );
+    file_.seekg( position, std::ios_base::beg );
+    break;
+
+  case 0xF0:
+  case 0xF7: // The start or continuation of a Sysex event
+    trackStatus_[track] = 0;
+    event->push_back( c );
+    position = file_.tellg();
+    if ( !readVariableLength( &bytes ) ) goto error;
+    bytes += ( (unsigned long)file_.tellg() - position );
+    file_.seekg( position, std::ios_base::beg );
+    break;
+
+  default: // Should be a MIDI channel event
+    if ( c & 0x80 ) { // MIDI status byte
+      if ( c > 0xF0 ) goto error;
+      trackStatus_[track] = c;
+      event->push_back( c );
+      c &= 0xF0;
+      if ( (c == 0xC0) || (c == 0xD0) ) bytes = 1;
+      else bytes = 2;
+    }
+    else if ( trackStatus_[track] & 0x80 ) { // Running status
+      event->push_back( trackStatus_[track] );
+      event->push_back( c );
+      c = trackStatus_[track] & 0xF0;
+      if ( (c != 0xC0) && (c != 0xD0) ) bytes = 1;
+    }
+    else goto error;
+
+  }
+
+  // Read the rest of the event into the event vector.
+  unsigned long i;
+  for ( i=0; i<bytes; i++ ) {
+    if ( !file_.read( (char *)&c, 1 ) ) goto error;
+    event->push_back( c );
+  }
+
+  if ( !usingTimeCode_ ) {
+    if ( isTempoEvent ) {
+      // Parse the tempo event and update tickSeconds_[track].
+      double tickrate = (double) (division_ & 0x7FFF);
+      unsigned long value = ( event->at(3) << 16 ) + ( event->at(4) << 8 ) + event->at(5);
+      tickSeconds_[track] = (double) (0.000001 * value / tickrate);
+    }
+
+    if ( format_ == 1 ) {
+      // Update track counter and check the tempo map.
+      trackCounters_[track] += ticks;
+      TempoChange tempoEvent = tempoEvents_[ trackTempoIndex_[track] ];
+      if ( trackCounters_[track] >= tempoEvent.count && trackTempoIndex_[track] < tempoEvents_.size() - 1 ) {
+        trackTempoIndex_[track]++;
+        tickSeconds_[track] = tempoEvent.tickSeconds;
+      }
+    }
+  }
+
+  // Save the current track pointer value.
+  trackPointers_[track] = file_.tellg();
+
+  return ticks;
+
+ error:
+  errorString_ << "MidiFileIn::getNextEvent: file read error!";
+  handleError( StkError::FILE_ERROR );
+  return 0;
+}
+
+unsigned long MidiFileIn :: getNextMidiEvent( std::vector<unsigned char> *midiEvent, unsigned int track )
+{
+  // Fill the user-provided vector with the next MIDI event in the
+  // specified track (default = 0) and return the event delta time in
+  // ticks.  Meta-Events preceeding this event are skipped and ignored.
+  if ( track >= nTracks_ ) {
+    errorString_ << "MidiFileIn::getNextMidiEvent: invalid track argument (" <<  track << ").";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+
+  unsigned long ticks = getNextEvent( midiEvent, track );
+  while ( midiEvent->size() && ( midiEvent->at(0) >= 0xF0 ) ) {
+    //for ( unsigned int i=0; i<midiEvent->size(); i++ )
+      //std::cout << "event byte = " << i << ", value = " << (int)midiEvent->at(i) << std::endl;
+    ticks = getNextEvent( midiEvent, track );
+  }
+
+  //for ( unsigned int i=0; i<midiEvent->size(); i++ )
+    //std::cout << "event byte = " << i << ", value = " << (int)midiEvent->at(i) << std::endl;
+
+  return ticks;
+}
+
+bool MidiFileIn :: readVariableLength( unsigned long *value )
+{
+  // It is assumed that this function is called with the file read
+  // pointer positioned at the start of a variable-length value.  The
+  // function returns "true" if the value is successfully parsed and
+  // "false" otherwise.
+  *value = 0;
+  char c;
+
+  if ( !file_.read( &c, 1 ) ) return false;
+  *value = (unsigned long) c;
+  if ( *value & 0x80 ) {
+    *value &= 0x7f;
+    do {
+      if ( !file_.read( &c, 1 ) ) return false;
+      *value = ( *value << 7 ) + ( c & 0x7f );
+    } while ( c & 0x80 );
+  }
+
+  return true;
+} 
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/Modal.cpp b/lib/MoMu-STK-1.0.0/src/Modal.cpp
new file mode 100644 (file)
index 0000000..7f2dadc
--- /dev/null
@@ -0,0 +1,181 @@
+/***************************************************/
+/*! \class Modal
+    \brief STK resonance model abstract base class.
+
+    This class contains an excitation wavetable,
+    an envelope, an oscillator, and N resonances
+    (non-sweeping BiQuad filters), where N is set
+    during instantiation.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "Modal.h"
+#include <cstdlib>
+
+namespace stk {
+
+Modal :: Modal( unsigned int modes )
+  : nModes_(modes)
+{
+  if ( nModes_ == 0 ) {
+    errorString_ << "Modal: 'modes' argument to constructor is zero!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+
+  // We don't make the excitation wave here yet, because we don't know
+  // what it's going to be.
+
+  ratios_.resize( nModes_ );
+  radii_.resize( nModes_ );
+  filters_ = (BiQuad **) calloc( nModes_, sizeof(BiQuad *) );
+  for (unsigned int i=0; i<nModes_; i++ ) {
+    filters_[i] = new BiQuad;
+    filters_[i]->setEqualGainZeroes();
+  }
+
+  // Set some default values.
+  vibrato_.setFrequency( 6.0 );
+  vibratoGain_ = 0.0;
+  directGain_ = 0.0;
+  masterGain_ = 1.0;
+  baseFrequency_ = 440.0;
+
+  this->clear();
+
+  stickHardness_ =  0.5;
+  strikePosition_ = 0.561;
+}  
+
+Modal :: ~Modal( void )
+{
+  for ( unsigned int i=0; i<nModes_; i++ ) {
+    delete filters_[i];
+  }
+  free( filters_ );
+}
+
+void Modal :: clear( void )
+{    
+  onepole_.clear();
+  for ( unsigned int i=0; i<nModes_; i++ )
+    filters_[i]->clear();
+}
+
+void Modal :: setFrequency( StkFloat frequency )
+{
+  baseFrequency_ = frequency;
+  for ( unsigned int i=0; i<nModes_; i++ )
+    this->setRatioAndRadius( i, ratios_[i], radii_[i] );
+}
+
+void Modal :: setRatioAndRadius( unsigned int modeIndex, StkFloat ratio, StkFloat radius )
+{
+  if ( modeIndex >= nModes_ ) {
+    errorString_ << "Modal::setRatioAndRadius: modeIndex parameter is greater than number of modes!";
+    handleError( StkError::WARNING );
+    return;
+  }
+
+  StkFloat nyquist = Stk::sampleRate() / 2.0;
+  StkFloat temp;
+
+  if ( ratio * baseFrequency_ < nyquist ) {
+    ratios_[modeIndex] = ratio;
+  }
+  else {
+    temp = ratio;
+    while (temp * baseFrequency_ > nyquist) temp *= 0.5;
+    ratios_[modeIndex] = temp;
+#if defined(_STK_DEBUG_)
+    errorString_ << "Modal::setRatioAndRadius: aliasing would occur here ... correcting.";
+    handleError( StkError::DEBUG_WARNING );
+#endif
+  }
+  radii_[modeIndex] = radius;
+  if (ratio < 0) 
+    temp = -ratio;
+  else
+    temp = ratio * baseFrequency_;
+
+  filters_[modeIndex]->setResonance(temp, radius);
+}
+
+void Modal :: setModeGain( unsigned int modeIndex, StkFloat gain )
+{
+  if ( modeIndex >= nModes_ ) {
+    errorString_ << "Modal::setModeGain: modeIndex parameter is greater than number of modes!";
+    handleError( StkError::WARNING );
+    return;
+  }
+
+  filters_[modeIndex]->setGain( gain );
+}
+
+void Modal :: strike( StkFloat amplitude )
+{
+  StkFloat gain = amplitude;
+  if ( amplitude < 0.0 ) {
+    errorString_ << "Modal::strike: amplitude is less than zero ... setting to zero!";
+    handleError( StkError::WARNING );
+    gain = 0.0;
+  }
+  else if ( amplitude > 1.0 ) {
+    errorString_ << "Modal::strike: amplitude is greater than one ... setting to 1.0!";
+    handleError( StkError::WARNING );
+    gain = 1.0;
+  }
+
+  envelope_.setRate( 1.0 );
+  envelope_.setTarget( gain );
+  onepole_.setPole( 1.0 - gain );
+  envelope_.tick();
+  wave_->reset();
+
+  StkFloat temp;
+  for ( unsigned int i=0; i<nModes_; i++ ) {
+    if (ratios_[i] < 0)
+      temp = -ratios_[i];
+    else
+      temp = ratios_[i] * baseFrequency_;
+    filters_[i]->setResonance(temp, radii_[i]);
+  }
+}
+
+void Modal :: noteOn( StkFloat frequency, StkFloat amplitude )
+{
+  this->strike(amplitude);
+  this->setFrequency(frequency);
+
+#if defined(_STK_DEBUG_)
+  errorString_ << "Modal::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << '.';
+  handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+void Modal :: noteOff( StkFloat amplitude )
+{
+  // This calls damp, but inverts the meaning of amplitude (high
+  // amplitude means fast damping).
+  this->damp( 1.0 - (amplitude * 0.03) );
+
+#if defined(_STK_DEBUG_)
+  errorString_ << "Modal::NoteOff: amplitude = " << amplitude << '.';
+  handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+void Modal :: damp( StkFloat amplitude )
+{
+  StkFloat temp;
+  for ( unsigned int i=0; i<nModes_; i++ ) {
+    if ( ratios_[i] < 0 )
+      temp = -ratios_[i];
+    else
+      temp = ratios_[i] * baseFrequency_;
+    filters_[i]->setResonance( temp, radii_[i]*amplitude );
+  }
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/ModalBar.cpp b/lib/MoMu-STK-1.0.0/src/ModalBar.cpp
new file mode 100644 (file)
index 0000000..9a6c1a6
--- /dev/null
@@ -0,0 +1,200 @@
+/***************************************************/
+/*! \class ModalBar
+    \brief STK resonant bar instrument class.
+
+    This class implements a number of different
+    struck bar instruments.  It inherits from the
+    Modal class.
+
+    Control Change Numbers: 
+       - Stick Hardness = 2
+       - Stick Position = 4
+       - Vibrato Gain = 8
+       - Vibrato Frequency = 11
+       - Direct Stick Mix = 1
+       - Volume = 128
+       - Modal Presets = 16
+         - Marimba = 0
+         - Vibraphone = 1
+         - Agogo = 2
+         - Wood1 = 3
+         - Reso = 4
+         - Wood2 = 5
+         - Beats = 6
+         - Two Fixed = 7
+         - Clump = 8
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "ModalBar.h"
+#include "Skini_msg.h"
+#include <cmath>
+
+namespace stk {
+
+ModalBar :: ModalBar( void )
+  : Modal()
+{
+  // Concatenate the STK rawwave path to the rawwave file
+  wave_ = new FileWvIn( (Stk::rawwavePath() + "marmstk1.raw").c_str(), true );
+  wave_->setRate( 0.5 * 22050.0 / Stk::sampleRate() );
+
+  // Set the resonances for preset 0 (marimba).
+  this->setPreset( 0 );
+}
+
+ModalBar :: ~ModalBar( void )
+{
+  delete wave_;
+}
+
+void ModalBar :: setStickHardness( StkFloat hardness )
+{
+  stickHardness_ = hardness;
+  if ( hardness < 0.0 ) {
+    errorString_ << "ModalBar::setStickHardness: parameter is less than zero ... setting to 0.0!";
+    handleError( StkError::WARNING );
+    stickHardness_ = 0.0;
+  }
+  else if ( hardness > 1.0 ) {
+    errorString_ << "ModalBar::setStickHarness: parameter is greater than one ... setting to 1.0!";
+    handleError( StkError::WARNING );
+    stickHardness_ = 1.0;
+  }
+
+  wave_->setRate( (0.25 * pow(4.0, stickHardness_) ) );
+  masterGain_ = 0.1 + (1.8 * stickHardness_);
+}
+
+void ModalBar :: setStrikePosition( StkFloat position )
+{
+  strikePosition_ = position;
+  if ( position < 0.0 ) {
+    errorString_ << "ModalBar::setStrikePosition: parameter is less than zero ... setting to 0.0!";
+    handleError( StkError::WARNING );
+    strikePosition_ = 0.0;
+  }
+  else if ( position > 1.0 ) {
+    errorString_ << "ModalBar::setStrikePosition: parameter is greater than one ... setting to 1.0!";
+    handleError( StkError::WARNING );
+    strikePosition_ = 1.0;
+  }
+
+  // Hack only first three modes.
+  StkFloat temp2 = position * PI;
+  StkFloat temp = sin(temp2);                                       
+  this->setModeGain(0, 0.12 * temp);
+
+  temp = sin(0.05 + (3.9 * temp2));
+  this->setModeGain(1, -0.03 * temp);
+
+  temp = sin(-0.05 + (11 * temp2));
+  this->setModeGain(2, 0.11 * temp);
+}
+
+void ModalBar :: setPreset( int preset )
+{
+  // Presets:
+  //     First line:  relative modal frequencies (negative number is
+  //                  a fixed mode that doesn't scale with frequency
+  //     Second line: resonances of the modes
+  //     Third line:  mode volumes
+  //     Fourth line: stickHardness, strikePosition, and direct stick
+  //                  gain (mixed directly into the output
+  static StkFloat presets[9][4][4] = { 
+    {{1.0, 3.99, 10.65, -2443},                // Marimba
+     {0.9996, 0.9994, 0.9994, 0.999},
+     {0.04, 0.01, 0.01, 0.008},
+     {0.429688, 0.445312, 0.093750}},
+    {{1.0, 2.01, 3.9, 14.37},          // Vibraphone
+     {0.99995, 0.99991, 0.99992, 0.9999},      
+     {0.025, 0.015, 0.015, 0.015 },
+     {0.390625,0.570312,0.078125}},
+    {{1.0, 4.08, 6.669, -3725.0},              // Agogo 
+     {0.999, 0.999, 0.999, 0.999},     
+     {0.06, 0.05, 0.03, 0.02},
+     {0.609375,0.359375,0.140625}},
+    {{1.0, 2.777, 7.378, 15.377},              // Wood1
+     {0.996, 0.994, 0.994, 0.99},      
+     {0.04, 0.01, 0.01, 0.008},
+     {0.460938,0.375000,0.046875}},
+    {{1.0, 2.777, 7.378, 15.377},              // Reso
+     {0.99996, 0.99994, 0.99994, 0.9999},      
+     {0.02, 0.005, 0.005, 0.004},
+     {0.453125,0.250000,0.101562}},
+    {{1.0, 1.777, 2.378, 3.377},               // Wood2
+     {0.996, 0.994, 0.994, 0.99},      
+     {0.04, 0.01, 0.01, 0.008},
+     {0.312500,0.445312,0.109375}},
+    {{1.0, 1.004, 1.013, 2.377},               // Beats
+     {0.9999, 0.9999, 0.9999, 0.999},  
+     {0.02, 0.005, 0.005, 0.004},
+     {0.398438,0.296875,0.070312}},
+    {{1.0, 4.0, -1320.0, -3960.0},             // 2Fix
+     {0.9996, 0.999, 0.9994, 0.999},   
+     {0.04, 0.01, 0.01, 0.008},
+     {0.453125,0.453125,0.070312}},
+    {{1.0, 1.217, 1.475, 1.729},               // Clump
+     {0.999, 0.999, 0.999, 0.999},     
+     {0.03, 0.03, 0.03, 0.03 },
+     {0.390625,0.570312,0.078125}},
+  };
+
+  int temp = (preset % 9);
+  for (unsigned int i=0; i<nModes_; i++) {
+    this->setRatioAndRadius(i, presets[temp][0][i], presets[temp][1][i]);
+    this->setModeGain(i, presets[temp][2][i]);
+  }
+
+  this->setStickHardness(presets[temp][3][0]);
+  this->setStrikePosition(presets[temp][3][1]);
+  directGain_ = presets[temp][3][2];
+
+  if (temp == 1) // vibraphone
+    vibratoGain_ = 0.2;
+  else
+    vibratoGain_ = 0.0;
+}
+
+void ModalBar :: controlChange( int number, StkFloat value )
+{
+  StkFloat norm = value * ONE_OVER_128;
+  if ( norm < 0 ) {
+    norm = 0.0;
+    errorString_ << "ModalBar::controlChange: control value less than zero ... setting to zero!";
+    handleError( StkError::WARNING );
+  }
+  else if ( norm > 1.0 ) {
+    norm = 1.0;
+    errorString_ << "ModalBar::controlChange: control value greater than 128.0 ... setting to 128.0!";
+    handleError( StkError::WARNING );
+  }
+
+  if (number == __SK_StickHardness_) // 2
+    this->setStickHardness( norm );
+  else if (number == __SK_StrikePosition_) // 4
+    this->setStrikePosition( norm );
+  else if (number == __SK_ProphesyRibbon_) // 16
+               this->setPreset((int) value);
+  else if (number == __SK_Balance_) // 8
+    vibratoGain_ = norm * 0.3;
+  else if (number == __SK_ModWheel_) // 1
+    directGain_ = norm;
+  else if (number == __SK_ModFrequency_) // 11
+    vibrato_.setFrequency( norm * 12.0 );
+  else if (number == __SK_AfterTouch_Cont_)    // 128
+    envelope_.setTarget( norm );
+  else {
+    errorString_ << "ModalBar::controlChange: undefined control number (" << number << ")!";
+    handleError( StkError::WARNING );
+  }
+
+#if defined(_STK_DEBUG_)
+    errorString_ << "ModalBar::controlChange: number = " << number << ", value = " << value << '.';
+    handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/Modulate.cpp b/lib/MoMu-STK-1.0.0/src/Modulate.cpp
new file mode 100644 (file)
index 0000000..39743ca
--- /dev/null
@@ -0,0 +1,49 @@
+/***************************************************/
+/*! \class Modulate
+    \brief STK periodic/random modulator.
+
+    This class combines random and periodic
+    modulations to give a nice, natural human
+    modulation function.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "Modulate.h"
+
+namespace stk {
+
+Modulate :: Modulate( void )
+{
+  vibrato_.setFrequency( 6.0 );
+  vibratoGain_ = 0.04;
+
+  noiseRate_ = (unsigned int) ( 330.0 * Stk::sampleRate() / 22050.0 );
+  noiseCounter_ = noiseRate_;
+
+  randomGain_ = 0.05;
+  filter_.setPole( 0.999 );
+  filter_.setGain( randomGain_ );
+
+  Stk::addSampleRateAlert( this );
+}
+
+Modulate :: ~Modulate( void )
+{
+  Stk::removeSampleRateAlert( this );
+}
+
+void Modulate :: sampleRateChanged( StkFloat newRate, StkFloat oldRate )
+{
+  if ( !ignoreSampleRateChange_ )
+    noiseRate_ = (unsigned int ) ( newRate * noiseRate_ / oldRate );
+}
+
+void Modulate :: setRandomGain( StkFloat gain )
+{
+  randomGain_ = gain;
+  filter_.setGain( randomGain_ );
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/Moog.cpp b/lib/MoMu-STK-1.0.0/src/Moog.cpp
new file mode 100644 (file)
index 0000000..35aa3c8
--- /dev/null
@@ -0,0 +1,122 @@
+/***************************************************/
+/*! \class Moog
+    \brief STK moog-like swept filter sampling synthesis class.
+
+    This instrument uses one attack wave, one
+    looped wave, and an ADSR envelope (inherited
+    from the Sampler class) and adds two sweepable
+    formant (FormSwep) filters.
+
+    Control Change Numbers: 
+       - Filter Q = 2
+       - Filter Sweep Rate = 4
+       - Vibrato Frequency = 11
+       - Vibrato Gain = 1
+       - Gain = 128
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "Moog.h"
+#include "Skini_msg.h"
+
+namespace stk {
+
+Moog :: Moog( void )
+{
+  // Concatenate the STK rawwave path to the rawwave file
+  attacks_.push_back( new FileWvIn( (Stk::rawwavePath() + "mandpluk.raw").c_str(), true ) );
+  loops_.push_back ( new FileLoop( (Stk::rawwavePath() + "impuls20.raw").c_str(), true ) );
+  loops_.push_back ( new FileLoop( (Stk::rawwavePath() + "sinewave.raw").c_str(), true ) ); // vibrato
+  loops_[1]->setFrequency( 6.122 );
+
+  filters_[0].setTargets( 0.0, 0.7 );
+  filters_[1].setTargets( 0.0, 0.7 );
+
+  adsr_.setAllTimes( 0.001, 1.5, 0.6, 0.250 );
+  filterQ_ = 0.85;
+  filterRate_ = 0.0001;
+  modDepth_ = 0.0;
+}  
+
+Moog :: ~Moog( void )
+{
+}
+
+void Moog :: setFrequency( StkFloat frequency )
+{
+  baseFrequency_ = frequency;
+  if ( frequency <= 0.0 ) {
+    errorString_ << "Moog::setFrequency: parameter is less than or equal to zero!";
+    handleError( StkError::WARNING );
+    baseFrequency_ = 220.0;
+  }
+
+  StkFloat rate = attacks_[0]->getSize() * 0.01 * baseFrequency_ / Stk::sampleRate();
+  attacks_[0]->setRate( rate );
+  loops_[0]->setFrequency( baseFrequency_ );
+}
+
+void Moog :: noteOn( StkFloat frequency, StkFloat amplitude )
+{
+  StkFloat temp;
+    
+  this->setFrequency( frequency );
+  this->keyOn();
+  attackGain_ = amplitude * 0.5;
+  loopGain_ = amplitude;
+
+  temp = filterQ_ + 0.05;
+  filters_[0].setStates( 2000.0, temp );
+  filters_[1].setStates( 2000.0, temp );
+
+  temp = filterQ_ + 0.099;
+  filters_[0].setTargets( frequency, temp );
+  filters_[1].setTargets( frequency, temp );
+
+  filters_[0].setSweepRate( filterRate_ * 22050.0 / Stk::sampleRate() );
+  filters_[1].setSweepRate( filterRate_ * 22050.0 / Stk::sampleRate() );
+
+#if defined(_STK_DEBUG_)
+  errorString_ << "Moog::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << '.';
+  handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+void Moog :: controlChange( int number, StkFloat value )
+{
+  StkFloat norm = value * ONE_OVER_128;
+  if ( norm < 0 ) {
+    norm = 0.0;
+    errorString_ << "Moog::controlChange: control value less than zero ... setting to zero!";
+    handleError( StkError::WARNING );
+  }
+  else if ( norm > 1.0 ) {
+    norm = 1.0;
+    errorString_ << "Moog::controlChange: control value greater than 128.0 ... setting to 128.0!";
+    handleError( StkError::WARNING );
+  }
+
+  if (number == __SK_FilterQ_) // 2
+    filterQ_ = 0.80 + ( 0.1 * norm );
+  else if (number == __SK_FilterSweepRate_) // 4
+    filterRate_ = norm * 0.0002;
+  else if (number == __SK_ModFrequency_) // 11
+    this->setModulationSpeed( norm * 12.0 );
+  else if (number == __SK_ModWheel_)  // 1
+    this->setModulationDepth( norm );
+  else if (number == __SK_AfterTouch_Cont_) // 128
+    adsr_.setTarget( norm );
+  else {
+    errorString_ << "Moog::controlChange: undefined control number (" << number << ")!";
+    handleError( StkError::WARNING );
+  }
+
+#if defined(_STK_DEBUG_)
+    errorString_ << "Moog::controlChange: number = " << number << ", value = " << value << '.';
+    handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/Mutex.cpp b/lib/MoMu-STK-1.0.0/src/Mutex.cpp
new file mode 100644 (file)
index 0000000..896decf
--- /dev/null
@@ -0,0 +1,104 @@
+/***************************************************/
+/*! \class Mutex
+    \brief STK mutex class.
+
+    This class provides a uniform interface for
+    cross-platform mutex use.  On Linux and IRIX
+    systems, the pthread library is used. Under
+    Windows, critical sections are used.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "Mutex.h"
+
+namespace stk {
+
+Mutex :: Mutex()
+{
+
+#if (defined(__OS_IRIX__) || defined(__OS_LINUX__) || defined(__OS_MACOSX__))
+
+  pthread_mutex_init(&mutex_, NULL);
+  pthread_cond_init(&condition_, NULL);
+
+#elif defined(__OS_WINDOWS__)
+
+  InitializeCriticalSection(&mutex_);
+  condition_ = CreateEvent(NULL,  // no security
+                           true,  // manual-reset
+                           false, // non-signaled initially
+                           NULL); // unnamed
+
+#endif 
+}
+
+Mutex :: ~Mutex()
+{
+#if (defined(__OS_IRIX__) || defined(__OS_LINUX__) || defined(__OS_MACOSX__))
+
+  pthread_mutex_destroy(&mutex_);
+  pthread_cond_destroy(&condition_);
+
+#elif defined(__OS_WINDOWS__)
+
+  DeleteCriticalSection(&mutex_);
+  CloseHandle( condition_ );
+
+#endif 
+}
+
+void Mutex :: lock()
+{
+#if (defined(__OS_IRIX__) || defined(__OS_LINUX__) || defined(__OS_MACOSX__))
+
+  pthread_mutex_lock(&mutex_);
+
+#elif defined(__OS_WINDOWS__)
+
+  EnterCriticalSection(&mutex_);
+
+#endif 
+}
+
+void Mutex :: unlock()
+{
+#if (defined(__OS_IRIX__) || defined(__OS_LINUX__) || defined(__OS_MACOSX__))
+
+  pthread_mutex_unlock(&mutex_);
+
+#elif defined(__OS_WINDOWS__)
+
+  LeaveCriticalSection(&mutex_);
+
+#endif 
+}
+
+void Mutex :: wait()
+{
+#if (defined(__OS_IRIX__) || defined(__OS_LINUX__) || defined(__OS_MACOSX__))
+
+  pthread_cond_wait(&condition_, &mutex_);
+
+#elif defined(__OS_WINDOWS__)
+
+  WaitForMultipleObjects(1, &condition_, false, INFINITE);
+
+#endif 
+}
+
+void Mutex :: signal()
+{
+#if (defined(__OS_IRIX__) || defined(__OS_LINUX__) || defined(__OS_MACOSX__))
+
+  pthread_cond_signal(&condition_);
+
+#elif defined(__OS_WINDOWS__)
+
+  SetEvent( condition_ );
+
+#endif 
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/NRev.cpp b/lib/MoMu-STK-1.0.0/src/NRev.cpp
new file mode 100644 (file)
index 0000000..3c81f81
--- /dev/null
@@ -0,0 +1,110 @@
+/***************************************************/
+/*! \class NRev
+    \brief CCRMA's NRev reverberator class.
+
+    This class takes a monophonic input signal and produces a stereo
+    output signal.  It is derived from the CLM NRev function, which is
+    based on the use of networks of simple allpass and comb delay
+    filters.  This particular arrangement consists of 6 comb filters
+    in parallel, followed by 3 allpass filters, a lowpass filter, and
+    another allpass in series, followed by two allpass filters in
+    parallel with corresponding right and left outputs.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "NRev.h"
+#include <cmath>
+
+namespace stk {
+
+NRev :: NRev( StkFloat T60 )
+{
+  lastFrame_.resize( 1, 2, 0.0 ); // resize lastFrame_ for stereo output
+
+  int lengths[15] = {1433, 1601, 1867, 2053, 2251, 2399, 347, 113, 37, 59, 53, 43, 37, 29, 19};
+  double scaler = Stk::sampleRate() / 25641.0;
+
+  int delay, i;
+  for ( i=0; i<15; i++ ) {
+    delay = (int) floor(scaler * lengths[i]);
+    if ( (delay & 1) == 0) delay++;
+    while ( !this->isPrime(delay) ) delay += 2;
+    lengths[i] = delay;
+  }
+
+  for ( i=0; i<6; i++ ) {
+    combDelays_[i].setMaximumDelay( lengths[i] );
+    combDelays_[i].setDelay( lengths[i] );
+    combCoefficient_[i] = pow(10.0, (-3 * lengths[i] / (T60 * Stk::sampleRate())));
+  }
+
+  for ( i=0; i<8; i++ ) {
+         allpassDelays_[i].setMaximumDelay( lengths[i+6] );
+         allpassDelays_[i].setDelay( lengths[i+6] );
+  }
+
+  this->setT60( T60 );
+  allpassCoefficient_ = 0.7;
+  effectMix_ = 0.3;
+  this->clear();
+}
+
+void NRev :: clear()
+{
+  int i;
+  for (i=0; i<6; i++) combDelays_[i].clear();
+  for (i=0; i<8; i++) allpassDelays_[i].clear();
+  lastFrame_[0] = 0.0;
+  lastFrame_[1] = 0.0;
+  lowpassState_ = 0.0;
+}
+
+void NRev :: setT60( StkFloat T60 )
+{
+  for ( int i=0; i<6; i++ )
+    combCoefficient_[i] = pow(10.0, (-3.0 * combDelays_[i].getDelay() / (T60 * Stk::sampleRate())));
+}
+
+StkFrames& NRev :: tick( StkFrames& frames, unsigned int channel )
+{
+#if defined(_STK_DEBUG_)
+  if ( channel >= frames.channels() - 1 ) {
+    errorString_ << "NRev::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *samples = &frames[channel];
+  unsigned int hop = frames.channels();
+  for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
+    *samples = tick( *samples );
+    samples++;
+    *samples = lastFrame_[1];
+  }
+
+  return frames;
+}
+
+StkFrames& NRev :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iChannel, unsigned int oChannel )
+{
+#if defined(_STK_DEBUG_)
+  if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() - 1 ) {
+    errorString_ << "NRev::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *iSamples = &iFrames[iChannel];
+  StkFloat *oSamples = &oFrames[oChannel];
+  unsigned int iHop = iFrames.channels(), oHop = oFrames.channels();
+  for ( unsigned int i=0; i<iFrames.frames(); i++, iSamples += iHop, oSamples += oHop ) {
+    *oSamples++ = tick( *iSamples );
+    *oSamples = lastFrame_[1];
+  }
+
+  return iFrames;
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/Noise.cpp b/lib/MoMu-STK-1.0.0/src/Noise.cpp
new file mode 100644 (file)
index 0000000..063487e
--- /dev/null
@@ -0,0 +1,34 @@
+/***************************************************/
+/*! \class Noise
+    \brief STK noise generator.
+
+    Generic random number generation using the
+    C rand() function.  The quality of the rand()
+    function varies from one OS to another.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "Noise.h"
+#include <time.h>
+
+namespace stk {
+
+Noise :: Noise( unsigned int seed )
+{
+  // Seed the random number generator
+  this->setSeed( seed );
+}
+
+void Noise :: setSeed( unsigned int seed )
+{
+  if ( seed == 0 )
+    srand( (unsigned int) time( NULL ) );
+  else
+    srand( seed );
+}
+
+} // stk namespace
+
+
diff --git a/lib/MoMu-STK-1.0.0/src/OnePole.cpp b/lib/MoMu-STK-1.0.0/src/OnePole.cpp
new file mode 100644 (file)
index 0000000..0c33b4d
--- /dev/null
@@ -0,0 +1,50 @@
+/***************************************************/
+/*! \class OnePole
+    \brief STK one-pole filter class.
+
+    This class implements a one-pole digital filter.  A method is
+    provided for setting the pole position along the real axis of the
+    z-plane while maintaining a constant peak filter gain.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "OnePole.h"
+
+namespace stk {
+
+OnePole :: OnePole( StkFloat thePole )
+{
+  b_.resize( 1 );
+  a_.resize( 2 );
+  inputs_.resize( 1, 1, 0.0 );
+  outputs_.resize( 2, 1, 0.0 );
+
+  this->setPole( thePole );
+}
+
+OnePole :: ~OnePole()    
+{
+}
+
+void OnePole :: setPole( StkFloat thePole )
+{
+  // Normalize coefficients for peak unity gain.
+  if ( thePole > 0.0 )
+    b_[0] = (StkFloat) (1.0 - thePole);
+  else
+    b_[0] = (StkFloat) (1.0 + thePole);
+
+  a_[1] = -thePole;
+}
+
+void OnePole :: setCoefficients( StkFloat b0, StkFloat a1, bool clearState )
+{
+  b_[0] = b0;
+  a_[1] = a1;
+
+  if ( clearState ) this->clear();
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/OneZero.cpp b/lib/MoMu-STK-1.0.0/src/OneZero.cpp
new file mode 100644 (file)
index 0000000..7d7fcac
--- /dev/null
@@ -0,0 +1,48 @@
+/***************************************************/
+/*! \class OneZero
+    \brief STK one-zero filter class.
+
+    This class implements a one-zero digital filter.  A method is
+    provided for setting the zero position along the real axis of the
+    z-plane while maintaining a constant filter gain.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "OneZero.h"
+
+namespace stk {
+
+OneZero :: OneZero( StkFloat theZero )
+{
+  b_.resize( 2 );
+  inputs_.resize( 2, 1, 0.0 );
+
+  this->setZero( theZero );
+}
+
+OneZero :: ~OneZero( void )
+{
+}
+
+void OneZero :: setZero( StkFloat theZero )
+{
+  // Normalize coefficients for unity gain.
+  if ( theZero > 0.0 )
+    b_[0] = 1.0 / ((StkFloat) 1.0 + theZero);
+  else
+    b_[0] = 1.0 / ((StkFloat) 1.0 - theZero);
+
+  b_[1] = -theZero * b_[0];
+}
+
+void OneZero :: setCoefficients( StkFloat b0, StkFloat b1, bool clearState )
+{
+  b_[0] = b0;
+  b_[1] = b1;
+
+  if ( clearState ) this->clear();
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/PRCRev.cpp b/lib/MoMu-STK-1.0.0/src/PRCRev.cpp
new file mode 100644 (file)
index 0000000..7fd4cb2
--- /dev/null
@@ -0,0 +1,111 @@
+/***************************************************/
+/*! \class PRCRev
+    \brief Perry's simple reverberator class.
+
+    This class is based on some of the famous
+    Stanford/CCRMA reverbs (NRev, KipRev), which
+    were based on the Chowning/Moorer/Schroeder
+    reverberators using networks of simple allpass
+    and comb delay filters.  This class implements
+    two series allpass units and two parallel comb
+    filters.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "PRCRev.h"
+#include <cmath>
+
+namespace stk {
+
+PRCRev :: PRCRev( StkFloat T60 )
+{
+  lastFrame_.resize( 1, 2, 0.0 ); // resize lastFrame_ for stereo output
+
+  // Delay lengths for 44100 Hz sample rate.
+  int lengths[4]= {353, 1097, 1777, 2137};
+  double scaler = Stk::sampleRate() / 44100.0;
+
+  // Scale the delay lengths if necessary.
+  int delay, i;
+  if ( scaler != 1.0 ) {
+    for (i=0; i<4; i++)        {
+      delay = (int) floor(scaler * lengths[i]);
+      if ( (delay & 1) == 0) delay++;
+      while ( !this->isPrime(delay) ) delay += 2;
+      lengths[i] = delay;
+    }
+  }
+
+  for ( i=0; i<2; i++ )        {
+         allpassDelays_[i].setMaximumDelay( lengths[i] );
+         allpassDelays_[i].setDelay( lengths[i] );
+
+    combDelays_[i].setMaximumDelay( lengths[i+2] );
+    combDelays_[i].setDelay( lengths[i+2] );
+  }
+
+  this->setT60( T60 );
+  allpassCoefficient_ = 0.7;
+  effectMix_ = 0.5;
+  this->clear();
+}
+
+void PRCRev :: clear( void )
+{
+  allpassDelays_[0].clear();
+  allpassDelays_[1].clear();
+  combDelays_[0].clear();
+  combDelays_[1].clear();
+  lastFrame_[0] = 0.0;
+  lastFrame_[1] = 0.0;
+}
+
+void PRCRev :: setT60( StkFloat T60 )
+{
+  combCoefficient_[0] = pow(10.0, (-3.0 * combDelays_[0].getDelay() / (T60 * Stk::sampleRate())));
+  combCoefficient_[1] = pow(10.0, (-3.0 * combDelays_[1].getDelay() / (T60 * Stk::sampleRate())));
+}
+
+StkFrames& PRCRev :: tick( StkFrames& frames, unsigned int channel )
+{
+#if defined(_STK_DEBUG_)
+  if ( channel >= frames.channels() - 1 ) {
+    errorString_ << "PRCRev::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *samples = &frames[channel];
+  unsigned int hop = frames.channels();
+  for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
+    *samples = tick( *samples );
+    *samples++;
+    *samples = lastFrame_[1];
+  }
+
+  return frames;
+}
+
+StkFrames& PRCRev :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iChannel, unsigned int oChannel )
+{
+#if defined(_STK_DEBUG_)
+  if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() - 1 ) {
+    errorString_ << "PRCRev::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *iSamples = &iFrames[iChannel];
+  StkFloat *oSamples = &oFrames[oChannel];
+  unsigned int iHop = iFrames.channels(), oHop = oFrames.channels();
+  for ( unsigned int i=0; i<iFrames.frames(); i++, iSamples += iHop, oSamples += oHop ) {
+    *oSamples++ = tick( *iSamples );
+    *oSamples = lastFrame_[1];
+  }
+
+  return iFrames;
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/PercFlut.cpp b/lib/MoMu-STK-1.0.0/src/PercFlut.cpp
new file mode 100644 (file)
index 0000000..5ca3dd8
--- /dev/null
@@ -0,0 +1,83 @@
+/***************************************************/
+/*! \class PercFlut
+    \brief STK percussive flute FM synthesis instrument.
+
+    This class implements algorithm 4 of the TX81Z.
+
+    \code
+    Algorithm 4 is :   4->3--\
+                          2-- + -->1-->Out
+    \endcode
+
+    Control Change Numbers: 
+       - Total Modulator Index = 2
+       - Modulator Crossfade = 4
+       - LFO Speed = 11
+       - LFO Depth = 1
+       - ADSR 2 & 4 Target = 128
+
+    The basic Chowning/Stanford FM patent expired
+    in 1995, but there exist follow-on patents,
+    mostly assigned to Yamaha.  If you are of the
+    type who should worry about this (making
+    money) worry away.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "PercFlut.h"
+
+namespace stk {
+
+PercFlut :: PercFlut( void )
+  : FM()
+{
+  // Concatenate the STK rawwave path to the rawwave files
+  for ( unsigned int i=0; i<3; i++ )
+    waves_[i] = new FileLoop( (Stk::rawwavePath() + "sinewave.raw").c_str(), true );
+  waves_[3] = new FileLoop( (Stk::rawwavePath() + "fwavblnk.raw").c_str(), true );
+
+  this->setRatio(0, 1.50 * 1.000);
+  this->setRatio(1, 3.00 * 0.995);
+  this->setRatio(2, 2.99 * 1.005);
+  this->setRatio(3, 6.00 * 0.997);
+  gains_[0] = fmGains_[99];
+  gains_[1] = fmGains_[71];
+  gains_[2] = fmGains_[93];
+  gains_[3] = fmGains_[85];
+
+  adsr_[0]->setAllTimes( 0.05, 0.05, fmSusLevels_[14], 0.05);
+  adsr_[1]->setAllTimes( 0.02, 0.50, fmSusLevels_[13], 0.5);
+  adsr_[2]->setAllTimes( 0.02, 0.30, fmSusLevels_[11], 0.05);
+  adsr_[3]->setAllTimes( 0.02, 0.05, fmSusLevels_[13], 0.01);
+
+  twozero_.setGain( 0.0 );
+  modDepth_ = 0.005;
+}  
+
+PercFlut :: ~PercFlut( void )
+{
+}
+
+void PercFlut :: setFrequency( StkFloat frequency )
+{    
+  baseFrequency_ = frequency;
+}
+
+void PercFlut :: noteOn( StkFloat frequency, StkFloat amplitude )
+{
+  gains_[0] = amplitude * fmGains_[99] * 0.5;
+  gains_[1] = amplitude * fmGains_[71] * 0.5;
+  gains_[2] = amplitude * fmGains_[93] * 0.5;
+  gains_[3] = amplitude * fmGains_[85] * 0.5;
+  this->setFrequency( frequency );
+  this->keyOn();
+
+#if defined(_STK_DEBUG_)
+  errorString_ << "PercFlut::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << '.';
+  handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/Phonemes.cpp b/lib/MoMu-STK-1.0.0/src/Phonemes.cpp
new file mode 100644 (file)
index 0000000..da7d52d
--- /dev/null
@@ -0,0 +1,298 @@
+/***************************************************/
+/*! \class Phonemes
+    \brief STK phonemes table.
+
+    This class does nothing other than declare a
+    set of 32 static phoneme formant parameters
+    and provide access to those values.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "Phonemes.h"
+#include <iostream>
+
+namespace stk {
+
+const char Phonemes :: phonemeNames[32][4] = 
+  {"eee", "ihh", "ehh", "aaa",
+   "ahh", "aww", "ohh", "uhh",
+   "uuu", "ooo", "rrr", "lll",
+   "mmm", "nnn", "nng", "ngg",
+   "fff", "sss", "thh", "shh",
+   "xxx", "hee", "hoo", "hah",
+   "bbb", "ddd", "jjj", "ggg",
+   "vvv", "zzz", "thz", "zhh"
+  };
+
+const StkFloat Phonemes :: phonemeGains[32][2] =
+  {{1.0, 0.0},    // eee
+   {1.0, 0.0},    // ihh
+   {1.0, 0.0},    // ehh
+   {1.0, 0.0},    // aaa
+
+   {1.0, 0.0},    // ahh
+   {1.0, 0.0},    // aww
+   {1.0, 0.0},    // ohh
+   {1.0, 0.0},    // uhh
+
+   {1.0, 0.0},    // uuu
+   {1.0, 0.0},    // ooo
+   {1.0, 0.0},    // rrr
+   {1.0, 0.0},    // lll
+
+   {1.0, 0.0},    // mmm
+   {1.0, 0.0},    // nnn
+   {1.0, 0.0},    // nng
+   {1.0, 0.0},    // ngg
+
+   {0.0, 0.7},    // fff
+   {0.0, 0.7},    // sss
+   {0.0, 0.7},    // thh
+   {0.0, 0.7},    // shh
+
+   {0.0, 0.7},    // xxx
+   {0.0, 0.1},    // hee
+   {0.0, 0.1},    // hoo
+   {0.0, 0.1},    // hah
+
+   {1.0, 0.1},    // bbb
+   {1.0, 0.1},    // ddd
+   {1.0, 0.1},    // jjj
+   {1.0, 0.1},    // ggg
+
+   {1.0, 1.0},    // vvv
+   {1.0, 1.0},    // zzz
+   {1.0, 1.0},    // thz
+   {1.0, 1.0}     // zhh
+  };
+
+const StkFloat Phonemes :: phonemeParameters[32][4][3] =
+  {{  { 273, 0.996,  10},       // eee (beet)
+      {2086, 0.945, -16}, 
+      {2754, 0.979, -12}, 
+      {3270, 0.440, -17}},
+   {  { 385, 0.987,  10},       // ihh (bit)
+      {2056, 0.930, -20},
+      {2587, 0.890, -20}, 
+      {3150, 0.400, -20}},
+   {  { 515, 0.977,  10},       // ehh (bet)
+      {1805, 0.810, -10}, 
+      {2526, 0.875, -10}, 
+      {3103, 0.400, -13}},
+   {  { 773, 0.950,  10},       // aaa (bat)
+      {1676, 0.830,  -6},
+      {2380, 0.880, -20}, 
+      {3027, 0.600, -20}},
+     
+   {  { 770, 0.950,   0},       // ahh (father)
+      {1153, 0.970,  -9},
+      {2450, 0.780, -29},
+      {3140, 0.800, -39}},
+   {  { 637, 0.910,   0},       // aww (bought)
+      { 895, 0.900,  -3},
+      {2556, 0.950, -17},
+      {3070, 0.910, -20}},
+   {  { 637, 0.910,   0},       // ohh (bone)  NOTE::  same as aww (bought)
+      { 895, 0.900,  -3},
+      {2556, 0.950, -17},
+      {3070, 0.910, -20}},
+   {  { 561, 0.965,   0},       // uhh (but)
+      {1084, 0.930, -10}, 
+      {2541, 0.930, -15}, 
+      {3345, 0.900, -20}},
+    
+   {  { 515, 0.976,   0},       // uuu (foot)
+      {1031, 0.950,  -3},
+      {2572, 0.960, -11},
+      {3345, 0.960, -20}},
+   {  { 349, 0.986, -10},       // ooo (boot)
+      { 918, 0.940, -20},
+      {2350, 0.960, -27},
+      {2731, 0.950, -33}},
+   {  { 394, 0.959, -10},       // rrr (bird)
+      {1297, 0.780, -16},
+      {1441, 0.980, -16},
+      {2754, 0.950, -40}},
+   {  { 462, 0.990,  +5},       // lll (lull)
+      {1200, 0.640, -10},
+      {2500, 0.200, -20},
+      {3000, 0.100, -30}},
+     
+   {  { 265, 0.987, -10},       // mmm (mom)
+      {1176, 0.940, -22},
+      {2352, 0.970, -20},
+      {3277, 0.940, -31}},
+   {  { 204, 0.980, -10},       // nnn (nun)
+      {1570, 0.940, -15},
+      {2481, 0.980, -12},
+      {3133, 0.800, -30}},
+   {  { 204, 0.980, -10},       // nng (sang)    NOTE:: same as nnn
+      {1570, 0.940, -15},
+      {2481, 0.980, -12},
+      {3133, 0.800, -30}},
+   {  { 204, 0.980, -10},       // ngg (bong)    NOTE:: same as nnn
+      {1570, 0.940, -15},
+      {2481, 0.980, -12},
+      {3133, 0.800, -30}},
+     
+   {  {1000, 0.300,   0},       // fff
+      {2800, 0.860, -10},
+      {7425, 0.740,   0},
+      {8140, 0.860,   0}},
+   {  {0,    0.000,   0},       // sss
+      {2000, 0.700, -15},
+      {5257, 0.750,  -3}, 
+      {7171, 0.840,   0}},
+   {  { 100, 0.900,   0},       // thh
+      {4000, 0.500, -20},
+      {5500, 0.500, -15},
+      {8000, 0.400, -20}},
+   {  {2693, 0.940,   0},       // shh
+      {4000, 0.720, -10},
+      {6123, 0.870, -10},
+      {7755, 0.750, -18}},
+
+   {  {1000, 0.300, -10},       // xxx           NOTE:: Not Really Done Yet
+      {2800, 0.860, -10},
+      {7425, 0.740,   0},
+      {8140, 0.860,   0}},
+   {  { 273, 0.996, -40},       // hee (beet)    (noisy eee)
+      {2086, 0.945, -16}, 
+      {2754, 0.979, -12}, 
+      {3270, 0.440, -17}},
+   {  { 349, 0.986, -40},       // hoo (boot)    (noisy ooo)
+      { 918, 0.940, -10},
+      {2350, 0.960, -17},
+      {2731, 0.950, -23}},
+   {  { 770, 0.950, -40},       // hah (father)  (noisy ahh)
+      {1153, 0.970,  -3},
+      {2450, 0.780, -20},
+      {3140, 0.800, -32}},
+     
+   {  {2000, 0.700, -20},       // bbb           NOTE:: Not Really Done Yet
+      {5257, 0.750, -15},
+      {7171, 0.840,  -3}, 
+      {9000, 0.900,   0}},
+   {  { 100, 0.900,   0},       // ddd           NOTE:: Not Really Done Yet
+      {4000, 0.500, -20},
+      {5500, 0.500, -15},
+      {8000, 0.400, -20}},
+   {  {2693, 0.940,   0},       // jjj           NOTE:: Not Really Done Yet
+      {4000, 0.720, -10},
+      {6123, 0.870, -10},
+      {7755, 0.750, -18}},
+   {  {2693, 0.940,   0},       // ggg           NOTE:: Not Really Done Yet
+      {4000, 0.720, -10},
+      {6123, 0.870, -10},
+      {7755, 0.750, -18}},
+     
+   {  {2000, 0.700, -20},       // vvv           NOTE:: Not Really Done Yet
+      {5257, 0.750, -15},
+      {7171, 0.840,  -3}, 
+      {9000, 0.900,   0}},
+   {  { 100, 0.900,   0},       // zzz           NOTE:: Not Really Done Yet
+      {4000, 0.500, -20},
+      {5500, 0.500, -15},
+      {8000, 0.400, -20}},
+   {  {2693, 0.940,   0},       // thz           NOTE:: Not Really Done Yet
+      {4000, 0.720, -10},
+      {6123, 0.870, -10},
+      {7755, 0.750, -18}},
+   {  {2693, 0.940,   0},       // zhh           NOTE:: Not Really Done Yet
+      {4000, 0.720, -10},
+      {6123, 0.870, -10},
+      {7755, 0.750, -18}}
+  };
+
+Phonemes :: Phonemes(void)
+{
+}
+
+Phonemes :: ~Phonemes(void)
+{
+}
+
+const char *Phonemes :: name( unsigned int index )
+{
+  if ( index > 31 ) {
+    std::ostringstream error;
+    error << "Phonemes::name: index is greater than 31!";
+    handleError( error.str(), StkError::WARNING );
+    return 0;
+  }
+  return phonemeNames[index];
+}
+
+StkFloat Phonemes :: voiceGain( unsigned int index )
+{
+  if ( index > 31 ) {
+    std::ostringstream error;
+    error << "Phonemes::voiceGain: index is greater than 31!";
+    handleError( error.str(), StkError::WARNING );
+    return 0.0;
+  }
+  return phonemeGains[index][0];
+}
+
+StkFloat Phonemes :: noiseGain( unsigned int index )
+{
+  if ( index > 31 ) {
+    std::ostringstream error;
+    error << "Phonemes::noiseGain: index is greater than 31!";
+    handleError( error.str(), StkError::WARNING );
+    return 0.0;
+  }
+  return phonemeGains[index][1];
+}
+
+StkFloat Phonemes :: formantFrequency( unsigned int index, unsigned int partial )
+{
+  std::ostringstream error;
+  if ( index > 31 ) {
+    error << "Phonemes::formantFrequency: index is greater than 31!";
+    handleError( error.str(), StkError::WARNING );
+    return 0.0;
+  }
+  if ( partial > 3 ) {
+    error << "Phonemes::formantFrequency: partial is greater than 3!";
+    handleError( error.str(), StkError::WARNING );
+    return 0.0;
+  }
+  return phonemeParameters[index][partial][0];
+}
+
+StkFloat Phonemes :: formantRadius( unsigned int index, unsigned int partial )
+{
+  std::ostringstream error;
+  if ( index > 31 ) {
+    error << "Phonemes::formantRadius: index is greater than 31!";
+    handleError( error.str(), StkError::WARNING );
+    return 0.0;
+  }
+  if ( partial > 3 ) {
+    error << "Phonemes::formantRadius: partial is greater than 3!";
+    handleError( error.str(), StkError::WARNING );
+    return 0.0;
+  }
+  return phonemeParameters[index][partial][1];
+}
+
+StkFloat Phonemes :: formantGain( unsigned int index, unsigned int partial )
+{
+  std::ostringstream error;
+  if ( index > 31 ) {
+    error << "Phonemes::formantGain: index is greater than 31!";
+    handleError( error.str(), StkError::WARNING );
+    return 0.0;
+  }
+  if ( partial > 3 ) {
+    error << "Phonemes::formantGain: partial is greater than 3!";
+    handleError( error.str(), StkError::WARNING );
+    return 0.0;
+  }
+  return phonemeParameters[index][partial][2];
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/PitShift.cpp b/lib/MoMu-STK-1.0.0/src/PitShift.cpp
new file mode 100644 (file)
index 0000000..d2f5212
--- /dev/null
@@ -0,0 +1,88 @@
+/***************************************************/
+/*! \class PitShift
+    \brief STK simple pitch shifter effect class.
+
+    This class implements a simple pitch shifter
+    using delay lines.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "PitShift.h"
+#include <cmath>
+
+namespace stk {
+
+PitShift :: PitShift( void )
+{
+  delayLength_ = maxDelay - 24;
+  halfLength_ = delayLength_ / 2;
+  delay_[0] = 12;
+  delay_[1] = maxDelay / 2;
+
+  delayLine_[0].setMaximumDelay( maxDelay );
+  delayLine_[0].setDelay( delay_[0] );
+  delayLine_[1].setMaximumDelay( maxDelay );
+  delayLine_[1].setDelay( delay_[1] );
+  effectMix_ = 0.5;
+  rate_ = 1.0;
+}
+
+void PitShift :: clear()
+{
+  delayLine_[0].clear();
+  delayLine_[1].clear();
+  lastFrame_[0] = 0.0;
+}
+
+void PitShift :: setShift( StkFloat shift )
+{
+  if ( shift < 1.0 ) {
+    rate_ = 1.0 - shift; 
+  }
+  else if ( shift > 1.0 ) {
+    rate_ = 1.0 - shift;
+  }
+  else {
+    rate_ = 0.0;
+    delay_[0] = halfLength_ + 12;
+  }
+}
+
+StkFrames& PitShift :: tick( StkFrames& frames, unsigned int channel )
+{
+#if defined(_STK_DEBUG_)
+  if ( channel >= frames.channels() ) {
+    errorString_ << "PitShift::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *samples = &frames[channel];
+  unsigned int hop = frames.channels();
+  for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
+    *samples = tick( *samples );
+
+  return frames;
+}
+
+StkFrames& PitShift :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iChannel, unsigned int oChannel )
+{
+#if defined(_STK_DEBUG_)
+  if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
+    errorString_ << "PitShift::tick(): channel and StkFrames arguments are incompatible!";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+#endif
+
+  StkFloat *iSamples = &iFrames[iChannel];
+  StkFloat *oSamples = &oFrames[oChannel];
+  unsigned int iHop = iFrames.channels(), oHop = oFrames.channels();
+  for ( unsigned int i=0; i<iFrames.frames(); i++, iSamples += iHop, oSamples += oHop )
+    *oSamples = tick( *iSamples );
+
+  return iFrames;
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/PluckTwo.cpp b/lib/MoMu-STK-1.0.0/src/PluckTwo.cpp
new file mode 100644 (file)
index 0000000..c5c2740
--- /dev/null
@@ -0,0 +1,132 @@
+/***************************************************/
+/*! \class PluckTwo
+    \brief STK enhanced plucked string model class.
+
+    This class implements an enhanced two-string,
+    plucked physical model, a la Jaffe-Smith,
+    Smith, and others.
+
+    PluckTwo is an abstract class, with no excitation
+    specified.  Therefore, it can't be directly
+    instantiated.
+
+    This is a digital waveguide model, making its
+    use possibly subject to patents held by
+    Stanford University, Yamaha, and others.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "PluckTwo.h"
+
+namespace stk {
+
+PluckTwo :: PluckTwo( StkFloat lowestFrequency )
+{
+  length_ = (unsigned long) ( Stk::sampleRate() / lowestFrequency + 1 );
+  lastLength_ = length_ * 0.5;
+  delayLine_.setMaximumDelay( length_ );
+  delayLine_.setDelay( lastLength_ );
+  delayLine2_.setMaximumDelay( length_ );
+  delayLine2_.setDelay( lastLength_ );
+  combDelay_.setMaximumDelay( length_ );
+  combDelay_.setDelay( lastLength_ );
+
+  baseLoopGain_ = 0.995;
+  loopGain_ = 0.999;
+  pluckAmplitude_ = 0.3;
+  pluckPosition_ = 0.4;
+  detuning_ = 0.995;
+  lastFrequency_ = lowestFrequency * 2.0;
+}
+
+PluckTwo :: ~PluckTwo( void )
+{
+}
+
+void PluckTwo :: clear( void )
+{
+  delayLine_.clear();
+  delayLine2_.clear();
+  combDelay_.clear();
+  filter_.clear();
+  filter2_.clear();
+}
+
+void PluckTwo :: setFrequency( StkFloat frequency )
+{
+  lastFrequency_ = frequency;
+  if ( lastFrequency_ <= 0.0 ) {
+    errorString_ << "Clarinet::setFrequency: parameter is less than or equal to zero!";
+    handleError( StkError::WARNING );
+    lastFrequency_ = 220.0;
+  }
+
+  // Delay = length - approximate filter delay.
+  lastLength_ = Stk::sampleRate() / lastFrequency_;
+  StkFloat delay = (lastLength_ / detuning_) - 0.5;
+  if ( delay <= 0.0 ) delay = 0.3;
+  else if ( delay > length_ ) delay = length_;
+  delayLine_.setDelay( delay );
+
+  delay = (lastLength_ * detuning_) - 0.5;
+  if ( delay <= 0.0 ) delay = 0.3;
+  else if ( delay > length_ ) delay = length_;
+  delayLine2_.setDelay( delay );
+
+  loopGain_ = baseLoopGain_ + (frequency * 0.000005);
+  if ( loopGain_ > 1.0 ) loopGain_ = 0.99999;
+}
+
+void PluckTwo :: setDetune( StkFloat detune )
+{
+  detuning_ = detune;
+  if ( detuning_ <= 0.0 ) {
+    errorString_ << "Clarinet::setDeturn: parameter is less than or equal to zero!";
+    handleError( StkError::WARNING );
+    detuning_ = 0.1;
+  }
+  delayLine_.setDelay(( lastLength_ / detuning_) - 0.5);
+  delayLine2_.setDelay( (lastLength_ * detuning_) - 0.5);
+}
+
+void PluckTwo :: setFreqAndDetune( StkFloat frequency, StkFloat detune )
+{
+  detuning_ = detune;
+  this->setFrequency( frequency );
+}
+
+void PluckTwo :: setPluckPosition( StkFloat position )
+{
+  pluckPosition_ = position;
+  if ( position < 0.0 ) {
+    errorString_ << "PluckTwo::setPluckPosition: parameter is less than zero ... setting to 0.0!";
+    handleError( StkError::WARNING );
+    pluckPosition_ = 0.0;
+  }
+  else if ( position > 1.0 ) {
+    errorString_ << "PluckTwo::setPluckPosition: parameter is greater than one ... setting to 1.0!";
+    handleError( StkError::WARNING );
+    pluckPosition_ = 1.0;
+  }
+}
+
+void PluckTwo :: setBaseLoopGain( StkFloat aGain )
+{
+  baseLoopGain_ = aGain;
+  loopGain_ = baseLoopGain_ + (lastFrequency_ * 0.000005);
+  if ( loopGain_ > 0.99999 ) loopGain_ = 0.99999;
+}
+
+void PluckTwo :: noteOff( StkFloat amplitude )
+{
+  loopGain_ =  (1.0 - amplitude) * 0.5;
+
+#if defined(_STK_DEBUG_)
+  errorString_ << "PluckTwo::NoteOff: amplitude = " << amplitude << ".";
+  handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/Plucked.cpp b/lib/MoMu-STK-1.0.0/src/Plucked.cpp
new file mode 100644 (file)
index 0000000..0cb239a
--- /dev/null
@@ -0,0 +1,117 @@
+/***************************************************/
+/*! \class Plucked
+    \brief STK plucked string model class.
+
+    This class implements a simple plucked string
+    physical model based on the Karplus-Strong
+    algorithm.
+
+    This is a digital waveguide model, making its
+    use possibly subject to patents held by
+    Stanford University, Yamaha, and others.
+    There exist at least two patents, assigned to
+    Stanford, bearing the names of Karplus and/or
+    Strong.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "Plucked.h"
+
+namespace stk {
+
+Plucked :: Plucked( StkFloat lowestFrequency )
+{
+  length_ = (unsigned long) ( Stk::sampleRate() / lowestFrequency + 1 );
+  loopGain_ = 0.999;
+  delayLine_.setMaximumDelay( length_ );
+  delayLine_.setDelay( 0.5 * length_ );
+  this->clear();
+}
+
+Plucked :: ~Plucked( void )
+{
+}
+
+void Plucked :: clear( void )
+{
+  delayLine_.clear();
+  loopFilter_.clear();
+  pickFilter_.clear();
+}
+
+void Plucked :: setFrequency( StkFloat frequency )
+{
+  StkFloat freakency = frequency;
+  if ( frequency <= 0.0 ) {
+    errorString_ << "Plucked::setFrequency: parameter is less than or equal to zero!";
+    handleError( StkError::WARNING );
+    freakency = 220.0;
+  }
+
+  // Delay = length - approximate filter delay.
+  StkFloat delay = (Stk::sampleRate() / freakency) - 0.5;
+  if ( delay <= 0.0 )
+    delay = 0.3;
+  else if ( delay > length_ )
+    delay = length_;
+  delayLine_.setDelay( delay );
+
+  loopGain_ = 0.995 + (freakency * 0.000005);
+  if ( loopGain_ >= 1.0 ) loopGain_ = 0.99999;
+}
+
+void Plucked :: pluck( StkFloat amplitude )
+{
+  StkFloat gain = amplitude;
+  if ( gain > 1.0 ) {
+    errorString_ << "Plucked::pluck: amplitude is greater than 1.0 ... setting to 1.0!";
+    handleError( StkError::WARNING );
+    gain = 1.0;
+  }
+  else if ( gain < 0.0 ) {
+    errorString_ << "Plucked::pluck: amplitude is < 0.0  ... setting to 0.0!";
+    handleError( StkError::WARNING );
+    gain = 0.0;
+  }
+
+  pickFilter_.setPole( 0.999 - (gain * 0.15) );
+  pickFilter_.setGain( gain * 0.5 );
+  for (unsigned long i=0; i<length_; i++)
+    // Fill delay with noise additively with current contents.
+    delayLine_.tick( 0.6 * delayLine_.lastOut() + pickFilter_.tick( noise_.tick() ) );
+}
+
+void Plucked :: noteOn( StkFloat frequency, StkFloat amplitude )
+{
+  this->setFrequency( frequency );
+  this->pluck( amplitude );
+
+#if defined(_STK_DEBUG_)
+  errorString_ << "Plucked::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << ".";
+  handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+void Plucked :: noteOff( StkFloat amplitude )
+{
+  loopGain_ = 1.0 - amplitude;
+  if ( loopGain_ < 0.0 ) {
+    errorString_ << "Plucked::noteOff: amplitude is greater than 1.0 ... setting to 1.0!";
+    handleError( StkError::WARNING );
+    loopGain_ = 0.0;
+  }
+  else if ( loopGain_ > 1.0 ) {
+    errorString_ << "Plucked::noteOff: amplitude is < 0.0  ... setting to 0.0!";
+    handleError( StkError::WARNING );
+    loopGain_ = (StkFloat) 0.99999;
+  }
+
+#if defined(_STK_DEBUG_)
+  errorString_ << "Plucked::NoteOff: amplitude = " << amplitude << ".";
+  handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/PoleZero.cpp b/lib/MoMu-STK-1.0.0/src/PoleZero.cpp
new file mode 100644 (file)
index 0000000..b90d203
--- /dev/null
@@ -0,0 +1,58 @@
+/***************************************************/
+/*! \class PoleZero
+    \brief STK one-pole, one-zero filter class.
+
+    This class implements a one-pole, one-zero digital filter.  A
+    method is provided for creating an allpass filter with a given
+    coefficient.  Another method is provided to create a DC blocking
+    filter.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "PoleZero.h"
+
+namespace stk {
+
+PoleZero :: PoleZero()
+{
+  // Default setting for pass-through.
+  b_.resize( 2, 0.0 );
+  a_.resize( 2, 0.0 );
+  b_[0] = 1.0;
+  a_[0] = 1.0;
+  inputs_.resize( 2, 1, 0.0 );
+  outputs_.resize( 2, 1, 0.0 );
+}
+
+PoleZero :: ~PoleZero()
+{
+}
+
+void PoleZero :: setCoefficients( StkFloat b0, StkFloat b1, StkFloat a1, bool clearState )
+{
+  b_[0] = b0;
+  b_[1] = b1;
+  a_[1] = a1;
+
+  if ( clearState ) this->clear();
+}
+
+void PoleZero :: setAllpass( StkFloat coefficient )
+{
+  b_[0] = coefficient;
+  b_[1] = 1.0;
+  a_[0] = 1.0; // just in case
+  a_[1] = coefficient;
+}
+
+void PoleZero :: setBlockZero( StkFloat thePole )
+{
+  b_[0] = 1.0;
+  b_[1] = -1.0;
+  a_[0] = 1.0; // just in case
+  a_[1] = -thePole;
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/Resonate.cpp b/lib/MoMu-STK-1.0.0/src/Resonate.cpp
new file mode 100644 (file)
index 0000000..dbb4603
--- /dev/null
@@ -0,0 +1,137 @@
+/***************************************************/
+/*! \class Resonate
+    \brief STK noise driven formant filter.
+
+    This instrument contains a noise source, which
+    excites a biquad resonance filter, with volume
+    controlled by an ADSR.
+
+    Control Change Numbers:
+       - Resonance Frequency (0-Nyquist) = 2
+       - Pole Radii = 4
+       - Notch Frequency (0-Nyquist) = 11
+       - Zero Radii = 1
+       - Envelope Gain = 128
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "Resonate.h"
+#include "Skini_msg.h"
+
+namespace stk {
+
+Resonate :: Resonate( void )
+{
+  poleFrequency_ = 4000.0;
+  poleRadius_ = 0.95;
+  // Set the filter parameters.
+  filter_.setResonance( poleFrequency_, poleRadius_, true );
+  zeroFrequency_ = 0.0;
+  zeroRadius_ = 0.0;
+}  
+
+Resonate :: ~Resonate( void )
+{
+}
+
+void Resonate :: noteOn( StkFloat frequency, StkFloat amplitude )
+{
+  adsr_.setTarget( amplitude );
+  this->keyOn();
+  this->setResonance( frequency, poleRadius_ );
+
+#if defined(_STK_DEBUG_)
+  errorString_ << "Resonate::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << '.';
+  handleError( StkError::DEBUG_WARNING );
+#endif
+}
+void Resonate :: noteOff( StkFloat amplitude )
+{
+  this->keyOff();
+
+#if defined(_STK_DEBUG_)
+  errorString_ << "Resonate::NoteOff: amplitude = " << amplitude << '.';
+  handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+void Resonate :: setResonance( StkFloat frequency, StkFloat radius )
+{
+  poleFrequency_ = frequency;
+  if ( frequency < 0.0 ) {
+    errorString_ << "Resonate::setResonance: frequency parameter is less than zero ... setting to 0.0!";
+    handleError( StkError::WARNING );
+    poleFrequency_ = 0.0;
+  }
+
+  poleRadius_ = radius;
+  if ( radius < 0.0 ) {
+    std::cerr << "Resonate::setResonance: radius parameter is less than 0.0 ... setting to 0.0!";
+    handleError( StkError::WARNING );
+    poleRadius_ = 0.0;
+  }
+  else if ( radius >= 1.0 ) {
+    errorString_ << "Resonate::setResonance: radius parameter is greater than or equal to 1.0, which is unstable ... correcting!";
+    handleError( StkError::WARNING );
+    poleRadius_ = 0.9999;
+  }
+  filter_.setResonance( poleFrequency_, poleRadius_, true );
+}
+
+void Resonate :: setNotch( StkFloat frequency, StkFloat radius )
+{
+  zeroFrequency_ = frequency;
+  if ( frequency < 0.0 ) {
+    errorString_ << "Resonate::setNotch: frequency parameter is less than zero ... setting to 0.0!";
+    handleError( StkError::WARNING );
+    zeroFrequency_ = 0.0;
+  }
+
+  zeroRadius_ = radius;
+  if ( radius < 0.0 ) {
+    errorString_ << "Resonate::setNotch: radius parameter is less than 0.0 ... setting to 0.0!";
+    handleError( StkError::WARNING );
+    zeroRadius_ = 0.0;
+  }
+  
+  filter_.setNotch( zeroFrequency_, zeroRadius_ );
+}
+
+void Resonate :: controlChange( int number, StkFloat value )
+{
+  StkFloat norm = value * ONE_OVER_128;
+  if ( norm < 0 ) {
+    norm = 0.0;
+    errorString_ << "Resonate::controlChange: control value less than zero ... setting to zero!";
+    handleError( StkError::WARNING );
+  }
+  else if ( norm > 1.0 ) {
+    norm = 1.0;
+    errorString_ << "Resonate::controlChange: control value greater than 128.0 ... setting to 128.0!";
+    handleError( StkError::WARNING );
+  }
+
+  if (number == 2) // 2
+    setResonance( norm * Stk::sampleRate() * 0.5, poleRadius_ );
+  else if (number == 4) // 4
+    setResonance( poleFrequency_, norm*0.9999 );
+  else if (number == 11) // 11
+    this->setNotch( norm * Stk::sampleRate() * 0.5, zeroRadius_ );
+  else if (number == 1)
+    this->setNotch( zeroFrequency_, norm );
+  else if (number == __SK_AfterTouch_Cont_) // 128
+    adsr_.setTarget( norm );
+  else {
+    errorString_ << "Resonate::controlChange: undefined control number (" << number << ")!";
+    handleError( StkError::WARNING );
+  }
+
+#if defined(_STK_DEBUG_)
+    errorString_ << "Resonate::controlChange: number = " << number << ", value = " << value << '.';
+    handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/Rhodey.cpp b/lib/MoMu-STK-1.0.0/src/Rhodey.cpp
new file mode 100644 (file)
index 0000000..0fa7950
--- /dev/null
@@ -0,0 +1,90 @@
+/***************************************************/
+/*! \class Rhodey
+    \brief STK Fender Rhodes-like electric piano FM
+           synthesis instrument.
+
+    This class implements two simple FM Pairs
+    summed together, also referred to as algorithm
+    5 of the TX81Z.
+
+    \code
+    Algorithm 5 is :  4->3--\
+                             + --> Out
+                      2->1--/
+    \endcode
+
+    Control Change Numbers: 
+       - Modulator Index One = 2
+       - Crossfade of Outputs = 4
+       - LFO Speed = 11
+       - LFO Depth = 1
+       - ADSR 2 & 4 Target = 128
+
+    The basic Chowning/Stanford FM patent expired
+    in 1995, but there exist follow-on patents,
+    mostly assigned to Yamaha.  If you are of the
+    type who should worry about this (making
+    money) worry away.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "Rhodey.h"
+
+namespace stk {
+
+Rhodey :: Rhodey( void )
+  : FM()
+{
+  // Concatenate the STK rawwave path to the rawwave files
+  for ( unsigned int i=0; i<3; i++ )
+    waves_[i] = new FileLoop( (Stk::rawwavePath() + "sinewave.raw").c_str(), true );
+  waves_[3] = new FileLoop( (Stk::rawwavePath() + "fwavblnk.raw").c_str(), true );
+
+  this->setRatio(0, 1.0);
+  this->setRatio(1, 0.5);
+  this->setRatio(2, 1.0);
+  this->setRatio(3, 15.0);
+
+  gains_[0] = fmGains_[99];
+  gains_[1] = fmGains_[90];
+  gains_[2] = fmGains_[99];
+  gains_[3] = fmGains_[67];
+
+  adsr_[0]->setAllTimes( 0.001, 1.50, 0.0, 0.04);
+  adsr_[1]->setAllTimes( 0.001, 1.50, 0.0, 0.04);
+  adsr_[2]->setAllTimes( 0.001, 1.00, 0.0, 0.04);
+  adsr_[3]->setAllTimes( 0.001, 0.25, 0.0, 0.04);
+
+  twozero_.setGain( 1.0 );
+}
+
+Rhodey :: ~Rhodey( void )
+{
+}
+
+void Rhodey :: setFrequency( StkFloat frequency )
+{
+  baseFrequency_ = frequency * 2.0;
+
+  for (unsigned int i=0; i<nOperators_; i++ )
+    waves_[i]->setFrequency( baseFrequency_ * ratios_[i] );
+}
+
+void Rhodey :: noteOn( StkFloat frequency, StkFloat amplitude )
+{
+  gains_[0] = amplitude * fmGains_[99];
+  gains_[1] = amplitude * fmGains_[90];
+  gains_[2] = amplitude * fmGains_[99];
+  gains_[3] = amplitude * fmGains_[67];
+  this->setFrequency( frequency );
+  this->keyOn();
+
+#if defined(_STK_DEBUG_)
+  errorString_ << "Rhodey::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << '.';
+  handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/Sampler.cpp b/lib/MoMu-STK-1.0.0/src/Sampler.cpp
new file mode 100644 (file)
index 0000000..7dd2bfc
--- /dev/null
@@ -0,0 +1,58 @@
+/***************************************************/
+/*! \class Sampler
+    \brief STK sampling synthesis abstract base class.
+
+    This instrument provides an ADSR envelope, a one-pole filter, and
+    structures for an arbitrary number of attack and looped files.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "Sampler.h"
+
+namespace stk {
+
+Sampler :: Sampler( void )
+{
+  // We don't make the waves here yet, because
+  // we don't know what they will be.
+  baseFrequency_ = 440.0;
+  attackGain_ = 0.25;
+  loopGain_ = 0.25;
+}  
+
+Sampler :: ~Sampler( void )
+{
+  unsigned int i;
+  for ( i=0; i<attacks_.size(); i++ ) delete attacks_[i];
+  for ( i=0; i<loops_.size(); i++ ) delete loops_[i];
+}
+
+void Sampler :: keyOn( void )
+{
+  // Reset all attack waves.
+  for ( unsigned int i=0; i<attacks_.size(); i++ )
+    attacks_[i]->reset();
+
+  // Start the envelope.
+  adsr_.keyOn();
+
+}
+
+void Sampler :: keyOff( void )
+{
+  adsr_.keyOff();
+}
+
+void Sampler :: noteOff( StkFloat amplitude )
+{
+  this->keyOff();
+
+#if defined(_STK_DEBUG_)
+  errorString_ << "Sampler::NoteOff: amplitude = " << amplitude << ".";
+  handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/Saxofony.cpp b/lib/MoMu-STK-1.0.0/src/Saxofony.cpp
new file mode 100644 (file)
index 0000000..7d0ecb1
--- /dev/null
@@ -0,0 +1,179 @@
+/***************************************************/
+/*! \class Saxofony
+    \brief STK faux conical bore reed instrument class.
+
+    This class implements a "hybrid" digital
+    waveguide instrument that can generate a
+    variety of wind-like sounds.  It has also been
+    referred to as the "blowed string" model.  The
+    waveguide section is essentially that of a
+    string, with one rigid and one lossy
+    termination.  The non-linear function is a
+    reed table.  The string can be "blown" at any
+    point between the terminations, though just as
+    with strings, it is impossible to excite the
+    system at either end.  If the excitation is
+    placed at the string mid-point, the sound is
+    that of a clarinet.  At points closer to the
+    "bridge", the sound is closer to that of a
+    saxophone.  See Scavone (2002) for more details.
+
+    This is a digital waveguide model, making its
+    use possibly subject to patents held by Stanford
+    University, Yamaha, and others.
+
+    Control Change Numbers: 
+       - Reed Stiffness = 2
+       - Reed Aperture = 26
+       - Noise Gain = 4
+       - Blow Position = 11
+       - Vibrato Frequency = 29
+       - Vibrato Gain = 1
+       - Breath Pressure = 128
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "Saxofony.h"
+#include "Skini_msg.h"
+
+namespace stk {
+
+Saxofony :: Saxofony( StkFloat lowestFrequency )
+{
+  length_ = (unsigned long) (Stk::sampleRate() / lowestFrequency + 1);
+  // Initialize blowing position to 0.2 of length / 2.
+  position_ = 0.2;
+  delays_[0].setMaximumDelay( length_ );
+  delays_[0].setDelay( (1.0-position_) * (length_ >> 1) );
+  delays_[1].setMaximumDelay( length_ );
+  delays_[1].setDelay( (1.0-position_) * (length_ >> 1) );
+
+  reedTable_.setOffset( 0.7 );
+  reedTable_.setSlope( 0.3 );
+
+  vibrato_.setFrequency((StkFloat) 5.735);
+
+  outputGain_ = 0.3;
+  noiseGain_ = 0.2;
+  vibratoGain_ = 0.1;
+}
+
+Saxofony :: ~Saxofony( void )
+{
+}
+
+void Saxofony :: clear( void )
+{
+  delays_[0].clear();
+  delays_[1].clear();
+  filter_.clear();
+}
+
+void Saxofony :: setFrequency( StkFloat frequency )
+{
+  StkFloat freakency = frequency;
+  if ( frequency <= 0.0 ) {
+    errorString_ << "Saxofony::setFrequency: parameter is less than or equal to zero!";
+    handleError( StkError::WARNING );
+    freakency = 220.0;
+  }
+
+  StkFloat delay = (Stk::sampleRate() / freakency) - (StkFloat) 3.0;
+  if (delay <= 0.0) delay = 0.3;
+  else if (delay > length_) delay = length_;
+
+  delays_[0].setDelay( (1.0-position_) * delay );
+  delays_[1].setDelay( position_ * delay );
+}
+
+void Saxofony :: setBlowPosition( StkFloat position )
+{
+  if ( position_ == position ) return;
+
+  if ( position < 0.0 ) position_ = 0.0;
+  else if ( position > 1.0 ) position_ = 1.0;
+  else position_ = position;
+
+  StkFloat totalDelay = delays_[0].getDelay();
+  totalDelay += delays_[1].getDelay();
+
+  delays_[0].setDelay( (1.0-position_) * totalDelay );
+  delays_[1].setDelay( position_ * totalDelay );
+}
+
+void Saxofony :: startBlowing( StkFloat amplitude, StkFloat rate )
+{
+  envelope_.setRate( rate );
+  envelope_.setTarget( amplitude );
+}
+
+void Saxofony :: stopBlowing( StkFloat rate )
+{
+  envelope_.setRate( rate );
+  envelope_.setTarget( 0.0 );
+}
+
+void Saxofony :: noteOn( StkFloat frequency, StkFloat amplitude )
+{
+  this->setFrequency( frequency );
+  this->startBlowing( 0.55 + (amplitude * 0.30), amplitude * 0.005 );
+  outputGain_ = amplitude + 0.001;
+
+#if defined(_STK_DEBUG_)
+  errorString_ << "Saxofony::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << ".";
+  handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+void Saxofony :: noteOff( StkFloat amplitude )
+{
+  this->stopBlowing( amplitude * 0.01 );
+
+#if defined(_STK_DEBUG_)
+  errorString_ << "Saxofony::NoteOff: amplitude = " << amplitude << ".";
+  handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+void Saxofony :: controlChange( int number, StkFloat value )
+{
+  StkFloat norm = value * ONE_OVER_128;
+  if ( norm < 0 ) {
+    norm = 0.0;
+    errorString_ << "Saxofony::controlChange: control value less than zero ... setting to zero!";
+    handleError( StkError::WARNING );
+  }
+  else if ( norm > 1.0 ) {
+    norm = 1.0;
+    errorString_ << "Saxofony::controlChange: control value greater than 128.0 ... setting to 128.0!";
+    handleError( StkError::WARNING );
+  }
+
+  if (number == __SK_ReedStiffness_) // 2
+    reedTable_.setSlope( 0.1 + (0.4 * norm) );
+  else if (number == __SK_NoiseLevel_) // 4
+    noiseGain_ = ( norm * 0.4 );
+  else if (number == 29) // 29
+    vibrato_.setFrequency( norm * 12.0 );
+  else if (number == __SK_ModWheel_) // 1
+    vibratoGain_ = ( norm * 0.5 );
+  else if (number == __SK_AfterTouch_Cont_) // 128
+    envelope_.setValue( norm );
+  else if (number == 11) // 11
+    this->setBlowPosition( norm );
+  else if (number == 26) // reed table offset
+    reedTable_.setOffset(0.4 + ( norm * 0.6));
+  else {
+    errorString_ << "Saxofony::controlChange: undefined control number (" << number << ")!";
+    handleError( StkError::WARNING );
+  }
+
+#if defined(_STK_DEBUG_)
+    errorString_ << "Saxofony::controlChange: number = " << number << ", value = " << value << ".";
+    handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/Shakers.cpp b/lib/MoMu-STK-1.0.0/src/Shakers.cpp
new file mode 100644 (file)
index 0000000..d708d7e
--- /dev/null
@@ -0,0 +1,1135 @@
+/***************************************************/
+/*! \class Shakers
+    \brief PhISEM and PhOLIES class.
+
+    PhISEM (Physically Informed Stochastic Event
+    Modeling) is an algorithmic approach for
+    simulating collisions of multiple independent
+    sound producing objects.  This class is a
+    meta-model that can simulate a Maraca, Sekere,
+    Cabasa, Bamboo Wind Chimes, Water Drops,
+    Tambourine, Sleighbells, and a Guiro.
+
+    PhOLIES (Physically-Oriented Library of
+    Imitated Environmental Sounds) is a similar
+    approach for the synthesis of environmental
+    sounds.  This class implements simulations of
+    breaking sticks, crunchy snow (or not), a
+    wrench, sandpaper, and more.
+
+    Control Change Numbers: 
+       - Shake Energy = 2
+       - System Decay = 4
+       - Number Of Objects = 11
+       - Resonance Frequency = 1
+       - Shake Energy = 128
+       - Instrument Selection = 1071
+        - Maraca = 0
+        - Cabasa = 1
+        - Sekere = 2
+        - Guiro = 3
+        - Water Drops = 4
+        - Bamboo Chimes = 5
+        - Tambourine = 6
+        - Sleigh Bells = 7
+        - Sticks = 8
+        - Crunch = 9
+        - Wrench = 10
+        - Sand Paper = 11
+        - Coke Can = 12
+        - Next Mug = 13
+        - Penny + Mug = 14
+        - Nickle + Mug = 15
+        - Dime + Mug = 16
+        - Quarter + Mug = 17
+        - Franc + Mug = 18
+        - Peso + Mug = 19
+        - Big Rocks = 20
+        - Little Rocks = 21
+        - Tuned Bamboo Chimes = 22
+
+    by Perry R. Cook, 1996 - 2010.
+*/
+/***************************************************/
+
+#include "Shakers.h"
+#include "Skini_msg.h"
+#include <cstring>
+#include <cmath>
+#include <cstdlib>
+
+namespace stk {
+
+int my_random( int max ) //  Return Random Int Between 0 and max
+{
+  int temp = (int) ((float)max * rand() / (RAND_MAX + 1.0) );
+  return temp;
+}
+
+StkFloat float_random( StkFloat max ) // Return random float between 0.0 and max
+{      
+  StkFloat temp = (StkFloat) (max * rand() / (RAND_MAX + 1.0) );
+  return temp;
+}
+
+StkFloat noise_tick( void ) //  Return random StkFloat float between -1.0 and 1.0
+{
+  StkFloat temp = (StkFloat) (2.0 * rand() / (RAND_MAX + 1.0) );
+  temp -= 1.0;
+  return temp;
+}
+
+// Maraca
+const StkFloat MARA_SOUND_DECAY = 0.95;
+const StkFloat MARA_SYSTEM_DECAY = 0.999;
+const StkFloat MARA_GAIN = 20.0;
+const StkFloat MARA_NUM_BEANS = 25;
+const StkFloat MARA_CENTER_FREQ = 3200.0;
+const StkFloat MARA_RESON = 0.96;
+
+// Sekere
+const StkFloat SEKE_SOUND_DECAY = 0.96;
+const StkFloat SEKE_SYSTEM_DECAY = 0.999;
+const StkFloat SEKE_GAIN = 20.0;
+const StkFloat SEKE_NUM_BEANS = 64;
+const StkFloat SEKE_CENTER_FREQ = 5500.0;
+const StkFloat SEKE_RESON = 0.6;
+
+// Sandpaper
+const StkFloat SANDPAPR_SOUND_DECAY = 0.999;
+const StkFloat SANDPAPR_SYSTEM_DECAY = 0.999;
+const StkFloat SANDPAPR_GAIN = 0.5;
+const StkFloat SANDPAPR_NUM_GRAINS = 128;
+const StkFloat SANDPAPR_CENTER_FREQ = 4500.0;
+const StkFloat SANDPAPR_RESON = 0.6;
+
+// Cabasa
+const StkFloat CABA_SOUND_DECAY = 0.96;
+const StkFloat CABA_SYSTEM_DECAY = 0.997;
+const StkFloat CABA_GAIN = 40.0;
+const StkFloat CABA_NUM_BEADS = 512;
+const StkFloat CABA_CENTER_FREQ = 3000.0;
+const StkFloat CABA_RESON = 0.7;
+
+// Bamboo Wind Chimes
+const StkFloat BAMB_SOUND_DECAY = 0.95;
+const StkFloat BAMB_SYSTEM_DECAY = 0.9999;
+const StkFloat BAMB_GAIN = 2.0;
+const StkFloat BAMB_NUM_TUBES = 1.25;
+const StkFloat BAMB_CENTER_FREQ0 = 2800.0;
+const StkFloat BAMB_CENTER_FREQ1 = 0.8 * 2800.0;
+const StkFloat BAMB_CENTER_FREQ2 = 1.2 * 2800.0;
+const StkFloat BAMB_RESON      = 0.995;
+
+// Tuned Bamboo Wind Chimes (Anklung)
+const StkFloat TBAMB_SOUND_DECAY = 0.95;
+const StkFloat TBAMB_SYSTEM_DECAY = 0.9999;
+const StkFloat TBAMB_GAIN = 1.0;
+const StkFloat TBAMB_NUM_TUBES = 1.25;
+const StkFloat TBAMB_CENTER_FREQ0 = 1046.6;
+const StkFloat TBAMB_CENTER_FREQ1 = 1174.8;
+const StkFloat TBAMB_CENTER_FREQ2 = 1397.0;
+const StkFloat TBAMB_CENTER_FREQ3 = 1568.0;
+const StkFloat TBAMB_CENTER_FREQ4 = 1760.0;
+const StkFloat TBAMB_CENTER_FREQ5 = 2093.3;
+const StkFloat TBAMB_CENTER_FREQ6 = 2350.0;
+const StkFloat TBAMB_RESON = 0.996;
+
+// Water Drops
+const StkFloat WUTR_SOUND_DECAY = 0.95;
+const StkFloat WUTR_SYSTEM_DECAY = 0.996;
+const StkFloat WUTR_GAIN = 1.0;
+const StkFloat WUTR_NUM_SOURCES = 10;
+const StkFloat WUTR_CENTER_FREQ0 = 450.0;
+const StkFloat WUTR_CENTER_FREQ1 = 600.0;
+const StkFloat WUTR_CENTER_FREQ2 = 750.0;
+const StkFloat WUTR_RESON = 0.9985;
+const StkFloat WUTR_FREQ_SWEEP = 1.0001;
+
+// Tambourine
+const StkFloat TAMB_SOUND_DECAY = 0.95;
+const StkFloat TAMB_SYSTEM_DECAY = 0.9985;
+const StkFloat TAMB_GAIN = 5.0;
+const StkFloat TAMB_NUM_TIMBRELS = 32;
+const StkFloat TAMB_SHELL_FREQ = 2300;
+const StkFloat TAMB_SHELL_GAIN = 0.1;
+const StkFloat TAMB_SHELL_RESON = 0.96;
+const StkFloat TAMB_CYMB_FREQ1 = 5600;
+const StkFloat TAMB_CYMB_FREQ2 = 8100;
+const StkFloat TAMB_CYMB_RESON = 0.99;
+
+// Sleighbells
+const StkFloat SLEI_SOUND_DECAY = 0.97;
+const StkFloat SLEI_SYSTEM_DECAY = 0.9994;
+const StkFloat SLEI_GAIN = 1.0;
+const StkFloat SLEI_NUM_BELLS = 32;
+const StkFloat SLEI_CYMB_FREQ0 = 2500;
+const StkFloat SLEI_CYMB_FREQ1 = 5300;
+const StkFloat SLEI_CYMB_FREQ2 = 6500;
+const StkFloat SLEI_CYMB_FREQ3 = 8300;
+const StkFloat SLEI_CYMB_FREQ4 = 9800;
+const StkFloat SLEI_CYMB_RESON = 0.99;
+
+// Guiro
+const StkFloat GUIR_SOUND_DECAY = 0.95;
+const StkFloat GUIR_GAIN = 10.0;
+const StkFloat GUIR_NUM_PARTS = 128;
+const StkFloat GUIR_GOURD_FREQ = 2500.0;
+const StkFloat GUIR_GOURD_RESON = 0.97;
+const StkFloat GUIR_GOURD_FREQ2 = 4000.0;
+const StkFloat GUIR_GOURD_RESON2 = 0.97;
+
+// Wrench
+const StkFloat WRENCH_SOUND_DECAY = 0.95;
+const StkFloat WRENCH_GAIN = 5;
+const StkFloat WRENCH_NUM_PARTS = 128;
+const StkFloat WRENCH_FREQ = 3200.0;
+const StkFloat WRENCH_RESON = 0.99;
+const StkFloat WRENCH_FREQ2 = 8000.0;
+const StkFloat WRENCH_RESON2 = 0.992;
+
+// Cokecan
+const StkFloat COKECAN_SOUND_DECAY = 0.97;
+const StkFloat COKECAN_SYSTEM_DECAY = 0.999;
+const StkFloat COKECAN_GAIN = 0.8;
+const StkFloat COKECAN_NUM_PARTS = 48;
+const StkFloat COKECAN_HELMFREQ = 370;
+const StkFloat COKECAN_HELM_RES = 0.99;
+const StkFloat COKECAN_METLFREQ0 = 1025;
+const StkFloat COKECAN_METLFREQ1 = 1424;
+const StkFloat COKECAN_METLFREQ2 = 2149;
+const StkFloat COKECAN_METLFREQ3 = 3596;
+const StkFloat COKECAN_METL_RES = 0.992;
+
+// PhOLIES (Physically-Oriented Library of Imitated Environmental
+// Sounds), Perry Cook, 1997-8
+
+// Stix1
+const StkFloat STIX1_SOUND_DECAY = 0.96;
+const StkFloat STIX1_SYSTEM_DECAY = 0.998;
+const StkFloat STIX1_GAIN = 30.0;
+const StkFloat STIX1_NUM_BEANS = 2;
+const StkFloat STIX1_CENTER_FREQ = 5500.0;
+const StkFloat STIX1_RESON = 0.6;
+
+// Crunch1
+const StkFloat CRUNCH1_SOUND_DECAY = 0.95;
+const StkFloat CRUNCH1_SYSTEM_DECAY = 0.99806;
+const StkFloat CRUNCH1_GAIN = 20.0;
+const StkFloat CRUNCH1_NUM_BEADS = 7;
+const StkFloat CRUNCH1_CENTER_FREQ = 800.0;
+const StkFloat CRUNCH1_RESON = 0.95;
+
+// Nextmug
+const StkFloat NEXTMUG_SOUND_DECAY = 0.97;
+const StkFloat NEXTMUG_SYSTEM_DECAY = 0.9995;
+const StkFloat NEXTMUG_GAIN = 0.8;
+const StkFloat NEXTMUG_NUM_PARTS = 3;
+const StkFloat NEXTMUG_FREQ0 = 2123;
+const StkFloat NEXTMUG_FREQ1 = 4518;
+const StkFloat NEXTMUG_FREQ2 = 8856;
+const StkFloat NEXTMUG_FREQ3 = 10753;
+const StkFloat NEXTMUG_RES = 0.997;
+
+const StkFloat PENNY_FREQ0 = 11000;
+const StkFloat PENNY_FREQ1 = 5200;
+const StkFloat PENNY_FREQ2 = 3835;
+const StkFloat PENNY_RES   = 0.999;
+
+const StkFloat NICKEL_FREQ0 = 5583;
+const StkFloat NICKEL_FREQ1 = 9255;
+const StkFloat NICKEL_FREQ2 = 9805;
+const StkFloat NICKEL_RES = 0.9992;
+
+const StkFloat DIME_FREQ0 = 4450;
+const StkFloat DIME_FREQ1 = 4974;
+const StkFloat DIME_FREQ2 = 9945;
+const StkFloat DIME_RES = 0.9993;
+
+const StkFloat QUARTER_FREQ0 = 1708;
+const StkFloat QUARTER_FREQ1 = 8863;
+const StkFloat QUARTER_FREQ2 = 9045;
+const StkFloat QUARTER_RES = 0.9995;
+
+const StkFloat FRANC_FREQ0 = 5583;
+const StkFloat FRANC_FREQ1 = 11010;
+const StkFloat FRANC_FREQ2 = 1917;
+const StkFloat FRANC_RES = 0.9995;
+
+const StkFloat PESO_FREQ0 = 7250;
+const StkFloat PESO_FREQ1 = 8150;
+const StkFloat PESO_FREQ2 = 10060;
+const StkFloat PESO_RES = 0.9996;
+
+// Big Gravel
+const StkFloat BIGROCKS_SOUND_DECAY = 0.98;
+const StkFloat BIGROCKS_SYSTEM_DECAY = 0.9965;
+const StkFloat BIGROCKS_GAIN = 20.0;
+const StkFloat BIGROCKS_NUM_PARTS = 23;
+const StkFloat BIGROCKS_FREQ = 6460;
+const StkFloat BIGROCKS_RES = 0.932;
+
+// Little Gravel
+const StkFloat LITLROCKS_SOUND_DECAY = 0.98;
+const StkFloat LITLROCKS_SYSTEM_DECAY = 0.99586;
+const StkFloat LITLROCKS_GAIN = 20.0;
+const StkFloat LITLROCKS_NUM_PARTS = 1600;
+const StkFloat LITLROCKS_FREQ = 9000;
+const StkFloat LITLROCKS_RES = 0.843;
+
+// Finally ... the class code!
+
+Shakers :: Shakers( void )
+{
+  int i;
+
+  instType_ = 0;
+  shakeEnergy_ = 0.0;
+  nFreqs_ = 0;
+  sndLevel_ = 0.0;
+
+  for ( i=0; i<MAX_FREQS; i++ )        {
+    inputs_[i] = 0.0;
+    outputs_[i][0] = 0.0;
+    outputs_[i][1] = 0.0;
+    coeffs_[i][0] = 0.0;
+    coeffs_[i][1] = 0.0;
+    gains_[i] = 0.0;
+    center_freqs_[i] = 0.0;
+    resons_[i] =  0.0;
+    freq_rand_[i] = 0.0;
+    freqalloc_[i] = 0;
+  }
+
+  soundDecay_ = 0.0;
+  systemDecay_ = 0.0;
+  nObjects_ = 0.0;
+  totalEnergy_ = 0.0;
+  ratchet_ = 0.0;
+  ratchetDelta_ = 0.0005;
+  lastRatchetPos_ = 0;
+  finalZ_[0] = 0.0;
+  finalZ_[1] = 0.0;
+  finalZ_[2] = 0.0;
+  finalZCoeffs_[0] = 1.0;
+  finalZCoeffs_[1] = 0.0;
+  finalZCoeffs_[2] = 0.0;
+
+  this->setupNum(instType_);
+}
+
+Shakers :: ~Shakers( void )
+{
+}
+
+const StkFloat MAX_SHAKE = 2000.0;
+
+char instrs[NUM_INSTR][10] = {
+  "Maraca", "Cabasa", "Sekere", "Guiro",
+  "Waterdrp", "Bamboo", "Tambourn", "Sleighbl", 
+  "Stix1", "Crunch1", "Wrench", "SandPapr",
+  "CokeCan", "NextMug", "PennyMug", "NicklMug",
+  "DimeMug", "QuartMug", "FrancMug", "PesoMug",
+  "BigRocks", "LitlRoks", "TBamboo"
+};
+
+int Shakers :: setupName( char* instr )
+{
+  int which = 0;
+
+  for (int i=0;i<NUM_INSTR;i++)        {
+    if ( !strcmp(instr,instrs[i]) )
+           which = i;
+  }
+
+#if defined(_STK_DEBUG_)
+  errorString_ << "Shakers::setupName: setting instrument to " << instrs[which] << '.';
+  handleError( StkError::DEBUG_WARNING );
+#endif
+
+  return this->setupNum(which);
+}
+
+void Shakers :: setFinalZs( StkFloat z0, StkFloat z1, StkFloat z2 )
+{
+  finalZCoeffs_[0] = z0;
+  finalZCoeffs_[1] = z1;
+  finalZCoeffs_[2] = z2;
+}
+
+void Shakers :: setDecays( StkFloat sndDecay, StkFloat sysDecay )
+{
+  soundDecay_ = sndDecay;
+  systemDecay_ = sysDecay;
+}
+
+int Shakers :: setFreqAndReson( int which, StkFloat freq, StkFloat reson )
+{
+  if ( which < MAX_FREQS )     {
+    resons_[which] = reson;
+    center_freqs_[which] = freq;
+    t_center_freqs_[which] = freq;
+    coeffs_[which][1] = reson * reson;
+    coeffs_[which][0] = -reson * 2.0 * cos(freq * TWO_PI / Stk::sampleRate());
+    return 1;
+  }
+  else return 0;
+}
+
+int Shakers :: setupNum( int inst )
+{
+  int i, rv = 0;
+  StkFloat temp;
+
+  if (inst == 1) { // Cabasa
+    rv = inst;
+    nObjects_ = CABA_NUM_BEADS;
+    defObjs_[inst] = CABA_NUM_BEADS;
+    setDecays(CABA_SOUND_DECAY, CABA_SYSTEM_DECAY);
+    defDecays_[inst] = CABA_SYSTEM_DECAY;
+    decayScale_[inst] = 0.97;
+    nFreqs_ = 1;
+    baseGain_ = CABA_GAIN;
+    temp = log(nObjects_) * baseGain_ / (StkFloat) nObjects_;
+    gains_[0] = temp;
+    freqalloc_[0] = 0;
+    setFreqAndReson(0,CABA_CENTER_FREQ,CABA_RESON);
+    setFinalZs(1.0,-1.0,0.0);
+  }
+  else if (inst == 2) { // Sekere
+    rv = inst;
+    nObjects_ = SEKE_NUM_BEANS;
+    defObjs_[inst] = SEKE_NUM_BEANS;
+    this->setDecays(SEKE_SOUND_DECAY,SEKE_SYSTEM_DECAY);
+    defDecays_[inst] = SEKE_SYSTEM_DECAY;
+    decayScale_[inst] = 0.94;
+    nFreqs_ = 1;
+    baseGain_ = SEKE_GAIN;
+    temp = log(nObjects_) * baseGain_ / (StkFloat) nObjects_;
+    gains_[0] = temp;
+    freqalloc_[0] = 0;
+    this->setFreqAndReson(0,SEKE_CENTER_FREQ,SEKE_RESON);
+    this->setFinalZs(1.0, 0.0, -1.0);
+  }
+  else if (inst == 3) { //  Guiro
+    rv = inst;
+    nObjects_ = GUIR_NUM_PARTS;
+    defObjs_[inst] = GUIR_NUM_PARTS;
+    setDecays(GUIR_SOUND_DECAY,1.0);
+    defDecays_[inst] = 0.9999;
+    decayScale_[inst] = 1.0;
+    nFreqs_ = 2;
+    baseGain_ = GUIR_GAIN;
+    temp = log(nObjects_) * baseGain_ / (StkFloat) nObjects_;
+    gains_[0]=temp;
+    gains_[1]=temp;
+    freqalloc_[0] = 0;
+    freqalloc_[1] = 0;
+    freq_rand_[0] = 0.0;
+    freq_rand_[1] = 0.0;
+    setFreqAndReson(0,GUIR_GOURD_FREQ,GUIR_GOURD_RESON);
+    setFreqAndReson(1,GUIR_GOURD_FREQ2,GUIR_GOURD_RESON2);
+    ratchet_ = 0;
+    ratchetPos_ = 10;
+  }
+  else if (inst == 4) { //  Water Drops
+    rv = inst;
+    nObjects_ = WUTR_NUM_SOURCES;
+    defObjs_[inst] = WUTR_NUM_SOURCES;
+    setDecays(WUTR_SOUND_DECAY,WUTR_SYSTEM_DECAY);
+    defDecays_[inst] = WUTR_SYSTEM_DECAY;
+    decayScale_[inst] = 0.8;
+    nFreqs_ = 3;
+    baseGain_ = WUTR_GAIN;
+    temp = log(nObjects_) * baseGain_ / (StkFloat) nObjects_;
+    gains_[0]=temp;
+    gains_[1]=temp;
+    gains_[2]=temp;
+    freqalloc_[0] = 1;
+    freqalloc_[1] = 1;
+    freqalloc_[2] = 1;
+    freq_rand_[0] = 0.2;
+    freq_rand_[1] = 0.2;
+    freq_rand_[2] = 0.2;
+    setFreqAndReson(0,WUTR_CENTER_FREQ0,WUTR_RESON);
+    setFreqAndReson(1,WUTR_CENTER_FREQ0,WUTR_RESON);
+    setFreqAndReson(2,WUTR_CENTER_FREQ0,WUTR_RESON);
+    setFinalZs(1.0,0.0,0.0);
+  }
+  else if (inst == 5) { // Bamboo
+    rv = inst;
+    nObjects_ = BAMB_NUM_TUBES;
+    defObjs_[inst] = BAMB_NUM_TUBES;
+    setDecays(BAMB_SOUND_DECAY, BAMB_SYSTEM_DECAY);
+    defDecays_[inst] = BAMB_SYSTEM_DECAY;
+    decayScale_[inst] = 0.7;
+    nFreqs_ = 3;
+    baseGain_ = BAMB_GAIN;
+    temp = log(nObjects_) * baseGain_ / (StkFloat) nObjects_;
+    gains_[0]=temp;
+    gains_[1]=temp;
+    gains_[2]=temp;
+    freqalloc_[0] = 1;
+    freqalloc_[1] = 1;
+    freqalloc_[2] = 1;
+    freq_rand_[0] = 0.2;
+    freq_rand_[1] = 0.2;
+    freq_rand_[2] = 0.2;
+    setFreqAndReson(0,BAMB_CENTER_FREQ0,BAMB_RESON);
+    setFreqAndReson(1,BAMB_CENTER_FREQ1,BAMB_RESON);
+    setFreqAndReson(2,BAMB_CENTER_FREQ2,BAMB_RESON);
+    setFinalZs(1.0,0.0,0.0);
+  }
+  else if (inst == 6) { // Tambourine
+    rv = inst;
+    nObjects_ = TAMB_NUM_TIMBRELS;
+    defObjs_[inst] = TAMB_NUM_TIMBRELS;
+    setDecays(TAMB_SOUND_DECAY,TAMB_SYSTEM_DECAY);
+    defDecays_[inst] = TAMB_SYSTEM_DECAY;
+    decayScale_[inst] = 0.95;
+    nFreqs_ = 3;
+    baseGain_ = TAMB_GAIN;
+    temp = log(nObjects_) * baseGain_ / (StkFloat) nObjects_;
+    gains_[0]=temp*TAMB_SHELL_GAIN;
+    gains_[1]=temp*0.8;
+    gains_[2]=temp;
+    freqalloc_[0] = 0;
+    freqalloc_[1] = 1;
+    freqalloc_[2] = 1;
+    freq_rand_[0] = 0.0;
+    freq_rand_[1] = 0.05;
+    freq_rand_[2] = 0.05;
+    setFreqAndReson(0,TAMB_SHELL_FREQ,TAMB_SHELL_RESON);
+    setFreqAndReson(1,TAMB_CYMB_FREQ1,TAMB_CYMB_RESON);
+    setFreqAndReson(2,TAMB_CYMB_FREQ2,TAMB_CYMB_RESON);
+    setFinalZs(1.0,0.0,-1.0);
+  }
+  else if (inst == 7) { // Sleighbell
+    rv = inst;
+    nObjects_ = SLEI_NUM_BELLS;
+    defObjs_[inst] = SLEI_NUM_BELLS;
+    setDecays(SLEI_SOUND_DECAY,SLEI_SYSTEM_DECAY);
+    defDecays_[inst] = SLEI_SYSTEM_DECAY;
+    decayScale_[inst] = 0.9;
+    nFreqs_ = 5;
+    baseGain_ = SLEI_GAIN;
+    temp = log(nObjects_) * baseGain_ / (StkFloat) nObjects_;
+    gains_[0]=temp;
+    gains_[1]=temp;
+    gains_[2]=temp;
+    gains_[3]=temp*0.5;
+    gains_[4]=temp*0.3;
+    for (i=0;i<nFreqs_;i++)    {
+           freqalloc_[i] = 1;
+           freq_rand_[i] = 0.03;
+    }
+    setFreqAndReson(0,SLEI_CYMB_FREQ0,SLEI_CYMB_RESON);
+    setFreqAndReson(1,SLEI_CYMB_FREQ1,SLEI_CYMB_RESON);
+    setFreqAndReson(2,SLEI_CYMB_FREQ2,SLEI_CYMB_RESON);
+    setFreqAndReson(3,SLEI_CYMB_FREQ3,SLEI_CYMB_RESON);
+    setFreqAndReson(4,SLEI_CYMB_FREQ4,SLEI_CYMB_RESON);
+    setFinalZs(1.0,0.0,-1.0);
+  }
+  else if (inst == 8) { // Stix1
+    rv = inst;
+    nObjects_ = STIX1_NUM_BEANS;
+    defObjs_[inst] = STIX1_NUM_BEANS;
+    setDecays(STIX1_SOUND_DECAY,STIX1_SYSTEM_DECAY);
+    defDecays_[inst] = STIX1_SYSTEM_DECAY;
+
+    decayScale_[inst] = 0.96;
+    nFreqs_ = 1;
+    baseGain_ = STIX1_GAIN;
+    temp = log(nObjects_) * baseGain_ / (StkFloat) nObjects_;
+    gains_[0]=temp;
+    freqalloc_[0] = 0;
+    setFreqAndReson(0,STIX1_CENTER_FREQ,STIX1_RESON);
+    setFinalZs(1.0,0.0,-1.0);
+  }
+  else if (inst == 9) { // Crunch1
+    rv = inst;
+    nObjects_ = CRUNCH1_NUM_BEADS;
+    defObjs_[inst] = CRUNCH1_NUM_BEADS;
+    setDecays(CRUNCH1_SOUND_DECAY,CRUNCH1_SYSTEM_DECAY);
+    defDecays_[inst] = CRUNCH1_SYSTEM_DECAY;
+    decayScale_[inst] = 0.96;
+    nFreqs_ = 1;
+    baseGain_ = CRUNCH1_GAIN;
+    temp = log(nObjects_) * baseGain_ / (StkFloat) nObjects_;
+    gains_[0]=temp;
+    freqalloc_[0] = 0;
+    setFreqAndReson(0,CRUNCH1_CENTER_FREQ,CRUNCH1_RESON);
+    setFinalZs(1.0,-1.0,0.0);
+  }
+  else if (inst == 10) { // Wrench
+    rv = inst;
+    nObjects_ = WRENCH_NUM_PARTS;
+    defObjs_[inst] = WRENCH_NUM_PARTS;
+    setDecays(WRENCH_SOUND_DECAY,1.0);
+    defDecays_[inst] = 0.9999;
+    decayScale_[inst] = 0.98;
+    nFreqs_ = 2;
+    baseGain_ = WRENCH_GAIN;
+    temp = log(nObjects_) * baseGain_ / (StkFloat) nObjects_;
+    gains_[0]=temp;
+    gains_[1]=temp;
+    freqalloc_[0] = 0;
+    freqalloc_[1] = 0;
+    freq_rand_[0] = 0.0;
+    freq_rand_[1] = 0.0;
+    setFreqAndReson(0,WRENCH_FREQ,WRENCH_RESON);
+    setFreqAndReson(1,WRENCH_FREQ2,WRENCH_RESON2);
+    ratchet_ = 0;
+    ratchetPos_ = 10;
+  }
+  else if (inst == 11) { // Sandpapr
+    rv = inst;
+    nObjects_ = SANDPAPR_NUM_GRAINS;
+    defObjs_[inst] = SANDPAPR_NUM_GRAINS;
+    this->setDecays(SANDPAPR_SOUND_DECAY,SANDPAPR_SYSTEM_DECAY);
+    defDecays_[inst] = SANDPAPR_SYSTEM_DECAY;
+    decayScale_[inst] = 0.97;
+    nFreqs_ = 1;
+    baseGain_ = SANDPAPR_GAIN;
+    temp = log(nObjects_) * baseGain_ / (StkFloat) nObjects_;
+    gains_[0] = temp;
+    freqalloc_[0] = 0;
+    this->setFreqAndReson(0,SANDPAPR_CENTER_FREQ,SANDPAPR_RESON);
+    this->setFinalZs(1.0, 0.0, -1.0);
+  }
+  else if (inst == 12) { // Cokecan
+    rv = inst;
+    nObjects_ = COKECAN_NUM_PARTS;
+    defObjs_[inst] = COKECAN_NUM_PARTS;
+    setDecays(COKECAN_SOUND_DECAY,COKECAN_SYSTEM_DECAY);
+    defDecays_[inst] = COKECAN_SYSTEM_DECAY;
+    decayScale_[inst] = 0.95;
+    nFreqs_ = 5;
+    baseGain_ = COKECAN_GAIN;
+    temp = log(nObjects_) * baseGain_ / (StkFloat) nObjects_;
+    gains_[0]=temp;
+    gains_[1]=temp*1.8;
+    gains_[2]=temp*1.8;
+    gains_[3]=temp*1.8;
+    gains_[4]=temp*1.8;
+    freqalloc_[0] = 0;
+    freqalloc_[1] = 0;
+    freqalloc_[2] = 0;
+    freqalloc_[3] = 0;
+    freqalloc_[4] = 0;
+    setFreqAndReson(0,COKECAN_HELMFREQ,COKECAN_HELM_RES);
+    setFreqAndReson(1,COKECAN_METLFREQ0,COKECAN_METL_RES);
+    setFreqAndReson(2,COKECAN_METLFREQ1,COKECAN_METL_RES);
+    setFreqAndReson(3,COKECAN_METLFREQ2,COKECAN_METL_RES);
+    setFreqAndReson(4,COKECAN_METLFREQ3,COKECAN_METL_RES);
+    setFinalZs(1.0,0.0,-1.0);
+  }
+  else if (inst>12 && inst<20) { // Nextmug
+    rv = inst;
+    nObjects_ = NEXTMUG_NUM_PARTS;
+    defObjs_[inst] = NEXTMUG_NUM_PARTS;
+    setDecays(NEXTMUG_SOUND_DECAY,NEXTMUG_SYSTEM_DECAY);
+    defDecays_[inst] = NEXTMUG_SYSTEM_DECAY;
+    decayScale_[inst] = 0.95;
+    nFreqs_ = 4;
+    baseGain_ = NEXTMUG_GAIN;
+    temp = log(nObjects_) * baseGain_ / (StkFloat) nObjects_;
+    gains_[0]=temp;
+    gains_[1]=temp*0.8;
+    gains_[2]=temp*0.6;
+    gains_[3]=temp*0.4;
+    freqalloc_[0] = 0;
+    freqalloc_[1] = 0;
+    freqalloc_[2] = 0;
+    freqalloc_[3] = 0;
+    freqalloc_[4] = 0;
+    freqalloc_[5] = 0;
+    setFreqAndReson(0,NEXTMUG_FREQ0,NEXTMUG_RES);
+    setFreqAndReson(1,NEXTMUG_FREQ1,NEXTMUG_RES);
+    setFreqAndReson(2,NEXTMUG_FREQ2,NEXTMUG_RES);
+    setFreqAndReson(3,NEXTMUG_FREQ3,NEXTMUG_RES);
+    setFinalZs(1.0,0.0,-1.0);
+
+    if (inst == 14) { // Mug + Penny
+      nFreqs_ = 7;
+      gains_[4] = temp;
+      gains_[5] = temp*0.8;
+      gains_[6] = temp*0.5;
+      setFreqAndReson(4,PENNY_FREQ0,PENNY_RES);
+      setFreqAndReson(5,PENNY_FREQ1,PENNY_RES);
+      setFreqAndReson(6,PENNY_FREQ2,PENNY_RES);
+    }
+    else if (inst == 15) { // Mug + Nickel
+      nFreqs_ = 6;
+      gains_[4] = temp;
+      gains_[5] = temp*0.8;
+      gains_[6] = temp*0.5;
+      setFreqAndReson(4,NICKEL_FREQ0,NICKEL_RES);
+      setFreqAndReson(5,NICKEL_FREQ1,NICKEL_RES);
+      setFreqAndReson(6,NICKEL_FREQ2,NICKEL_RES);
+    }
+    else if (inst == 16) { // Mug + Dime
+      nFreqs_ = 6;
+      gains_[4] = temp;
+      gains_[5] = temp*0.8;
+      gains_[6] = temp*0.5;
+      setFreqAndReson(4,DIME_FREQ0,DIME_RES);
+      setFreqAndReson(5,DIME_FREQ1,DIME_RES);
+      setFreqAndReson(6,DIME_FREQ2,DIME_RES);
+    }
+    else if (inst == 17) { // Mug + Quarter
+      nFreqs_ = 6;
+      gains_[4] = temp*1.3;
+      gains_[5] = temp*1.0;
+      gains_[6] = temp*0.8;
+      setFreqAndReson(4,QUARTER_FREQ0,QUARTER_RES);
+      setFreqAndReson(5,QUARTER_FREQ1,QUARTER_RES);
+      setFreqAndReson(6,QUARTER_FREQ2,QUARTER_RES);
+    }
+    else if (inst == 18) { // Mug + Franc
+      nFreqs_ = 6;
+      gains_[4] = temp*0.7;
+      gains_[5] = temp*0.4;
+      gains_[6] = temp*0.3;
+      setFreqAndReson(4,FRANC_FREQ0,FRANC_RES);
+      setFreqAndReson(5,FRANC_FREQ1,FRANC_RES);
+      setFreqAndReson(6,FRANC_FREQ2,FRANC_RES);
+    }
+    else if (inst == 19) { // Mug + Peso
+      nFreqs_ = 6;
+      gains_[4] = temp;
+      gains_[5] = temp*1.2;
+      gains_[6] = temp*0.7;
+      setFreqAndReson(4,PESO_FREQ0,PESO_RES);
+      setFreqAndReson(5,PESO_FREQ1,PESO_RES);
+      setFreqAndReson(6,PESO_FREQ2,PESO_RES);
+    }
+  }
+  else if (inst == 20) { // Big Rocks
+    nFreqs_ = 1;
+    rv = inst;
+    nObjects_ = BIGROCKS_NUM_PARTS;
+    defObjs_[inst] = BIGROCKS_NUM_PARTS;
+    setDecays(BIGROCKS_SOUND_DECAY,BIGROCKS_SYSTEM_DECAY);
+    defDecays_[inst] = BIGROCKS_SYSTEM_DECAY;
+    decayScale_[inst] = 0.95;
+    baseGain_ = BIGROCKS_GAIN;
+    temp = log(nObjects_) * baseGain_ / (StkFloat) nObjects_;
+    gains_[0]=temp;
+    freqalloc_[0] = 1;
+    freq_rand_[0] = 0.11;
+    setFreqAndReson(0,BIGROCKS_FREQ,BIGROCKS_RES);
+    setFinalZs(1.0,0.0,-1.0);
+  }
+  else if (inst == 21) { // Little Rocks
+    nFreqs_ = 1;
+    rv = inst;
+    nObjects_ = LITLROCKS_NUM_PARTS;
+    defObjs_[inst] = LITLROCKS_NUM_PARTS;
+    setDecays(LITLROCKS_SOUND_DECAY,LITLROCKS_SYSTEM_DECAY);
+    defDecays_[inst] = LITLROCKS_SYSTEM_DECAY;
+    decayScale_[inst] = 0.95;
+    baseGain_ = LITLROCKS_GAIN;
+    temp = log(nObjects_) * baseGain_ / (StkFloat) nObjects_;
+    gains_[0]=temp;
+    freqalloc_[0] = 1;
+    freq_rand_[0] = 0.18;
+    setFreqAndReson(0,LITLROCKS_FREQ,LITLROCKS_RES);
+    setFinalZs(1.0,0.0,-1.0);
+  }
+  else if (inst == 22) { // Tuned Bamboo
+    rv = inst;
+    nObjects_ = TBAMB_NUM_TUBES;
+    defObjs_[inst] = TBAMB_NUM_TUBES;
+    setDecays(TBAMB_SOUND_DECAY, TBAMB_SYSTEM_DECAY);
+    defDecays_[inst] = TBAMB_SYSTEM_DECAY;
+    decayScale_[inst] = 0.7;
+    nFreqs_ = 7;
+    baseGain_ = TBAMB_GAIN;
+    temp = log(nObjects_) * baseGain_ / (StkFloat) nObjects_;
+    gains_[0]=temp;
+    gains_[1]=temp;
+    gains_[2]=temp;
+    gains_[3]=temp;
+    gains_[4]=temp;
+    gains_[5]=temp;
+    gains_[6]=temp;
+    freqalloc_[0] = 0;
+    freqalloc_[1] = 0;
+    freqalloc_[2] = 0;
+    freqalloc_[3] = 0;
+    freqalloc_[4] = 0;
+    freqalloc_[5] = 0;
+    freqalloc_[6] = 0;
+    freq_rand_[0] = 0.0;
+    freq_rand_[1] = 0.0;
+    freq_rand_[2] = 0.0;
+    freq_rand_[3] = 0.0;
+    freq_rand_[4] = 0.0;
+    freq_rand_[5] = 0.0;
+    freq_rand_[6] = 0.0;
+    setFreqAndReson(0,TBAMB_CENTER_FREQ0,TBAMB_RESON);
+    setFreqAndReson(1,TBAMB_CENTER_FREQ1,TBAMB_RESON);
+    setFreqAndReson(2,TBAMB_CENTER_FREQ2,TBAMB_RESON);
+    setFreqAndReson(3,TBAMB_CENTER_FREQ3,TBAMB_RESON);
+    setFreqAndReson(4,TBAMB_CENTER_FREQ4,TBAMB_RESON);
+    setFreqAndReson(5,TBAMB_CENTER_FREQ5,TBAMB_RESON);
+    setFreqAndReson(6,TBAMB_CENTER_FREQ6,TBAMB_RESON);
+    setFinalZs(1.0,0.0,-1.0);
+  }
+  else { // Maraca (inst == 0) or default
+    rv = 0;
+    nObjects_ = MARA_NUM_BEANS;
+    defObjs_[0] = MARA_NUM_BEANS;
+    setDecays(MARA_SOUND_DECAY,MARA_SYSTEM_DECAY);
+    defDecays_[0] = MARA_SYSTEM_DECAY;
+    decayScale_[inst] = 0.9;
+    nFreqs_ = 1;
+    baseGain_ = MARA_GAIN;
+    temp = log(nObjects_) * baseGain_ / (StkFloat) nObjects_;
+    gains_[0]=temp;
+    freqalloc_[0] = 0;
+    setFreqAndReson(0,MARA_CENTER_FREQ,MARA_RESON);
+    setFinalZs(1.0,-1.0,0.0);
+  }
+  return rv;
+}
+
+void Shakers :: noteOn( StkFloat frequency, StkFloat amplitude )
+{
+  // Yep ... pretty kludgey, but it works!
+  int noteNum = (int) ((12*log(frequency/220.0)/log(2.0)) + 57.01) % 32;
+  if (instType_ !=  noteNum) instType_ = this->setupNum(noteNum);
+  shakeEnergy_ += amplitude * MAX_SHAKE * 0.1;
+  if (shakeEnergy_ > MAX_SHAKE) shakeEnergy_ = MAX_SHAKE;
+  if (instType_==10 || instType_==3) ratchetPos_ += 1;
+
+#if defined(_STK_DEBUG_)
+  errorString_ << "Shakers::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << '.';
+  handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+void Shakers :: noteOff( StkFloat amplitude )
+{
+  shakeEnergy_ = 0.0;
+  if (instType_==10 || instType_==3) ratchetPos_ = 0;
+}
+
+const StkFloat MIN_ENERGY = 0.3;
+
+StkFloat Shakers :: tick( unsigned int )
+{
+  StkFloat data;
+  StkFloat temp_rand;
+  int i;
+
+  if (instType_ == 4) {
+       if (shakeEnergy_ > MIN_ENERGY)  {
+      lastFrame_[0] = wuter_tick();
+      lastFrame_[0] *= 0.0001;
+    }
+    else {
+      lastFrame_[0] = 0.0;
+    }
+  }
+  else if (instType_ == 22) {
+    lastFrame_[0] = tbamb_tick();
+  }
+  else if (instType_ == 10 || instType_ == 3) {
+    if (ratchetPos_ > 0) {
+      ratchet_ -= (ratchetDelta_ + (0.002*totalEnergy_));
+      if (ratchet_ < 0.0) {
+        ratchet_ = 1.0;
+        ratchetPos_ -= 1;
+           }
+      totalEnergy_ = ratchet_;
+      lastFrame_[0] = ratchet_tick();
+      lastFrame_[0] *= 0.0001;
+    }
+    else lastFrame_[0] = 0.0;
+  }
+  else  { // generic_tick()
+    if (shakeEnergy_ > MIN_ENERGY) {
+      shakeEnergy_ *= systemDecay_;               // Exponential system decay
+      if (float_random(1024.0) < nObjects_) {
+        sndLevel_ += shakeEnergy_;   
+        for (i=0;i<nFreqs_;i++) {
+          if (freqalloc_[i])   {
+            temp_rand = t_center_freqs_[i] * (1.0 + (freq_rand_[i] * noise_tick()));
+            coeffs_[i][0] = -resons_[i] * 2.0 * cos(temp_rand * TWO_PI / Stk::sampleRate());
+          }
+        }
+       }
+      inputs_[0] = sndLevel_ * noise_tick();      // Actual Sound is Random
+      for (i=1; i<nFreqs_; i++)        {
+        inputs_[i] = inputs_[0];
+      }
+      sndLevel_ *= soundDecay_;                   // Exponential Sound decay 
+      finalZ_[2] = finalZ_[1];
+      finalZ_[1] = finalZ_[0];
+      finalZ_[0] = 0;
+      for (i=0;i<nFreqs_;i++)  {
+        inputs_[i] -= outputs_[i][0]*coeffs_[i][0];  // Do
+        inputs_[i] -= outputs_[i][1]*coeffs_[i][1];  // resonant
+        outputs_[i][1] = outputs_[i][0];            // filter
+        outputs_[i][0] = inputs_[i];                // calculations
+        finalZ_[0] += gains_[i] * outputs_[i][1];
+      }
+      data = finalZCoeffs_[0] * finalZ_[0];     // Extra zero(s) for shape
+      data += finalZCoeffs_[1] * finalZ_[1];    // Extra zero(s) for shape
+      data += finalZCoeffs_[2] * finalZ_[2];    // Extra zero(s) for shape
+      if (data > 10000.0)      data = 10000.0;
+      if (data < -10000.0) data = -10000.0;
+      lastFrame_[0] = data * 0.0001;
+    }
+    else lastFrame_[0] = 0.0;
+  }
+
+  return lastFrame_[0];
+}
+
+void Shakers :: controlChange( int number, StkFloat value )
+{
+  StkFloat norm = value * ONE_OVER_128;
+  if ( norm < 0 ) {
+    norm = 0.0;
+    errorString_ << "Shakers::controlChange: control value less than zero ... setting to zero!";
+    handleError( StkError::WARNING );
+  }
+  else if ( norm > 1.0 ) {
+    norm = 1.0;
+    errorString_ << "Shakers::controlChange: control value greater than 128.0 ... setting to 128.0!";
+    handleError( StkError::WARNING );
+  }
+
+  StkFloat temp;
+  int i;
+
+  if (number == __SK_Breath_) { // 2 ... energy
+    shakeEnergy_ += norm * MAX_SHAKE * 0.1;
+    if (shakeEnergy_ > MAX_SHAKE) shakeEnergy_ = MAX_SHAKE;
+    if (instType_==10 || instType_==3) {
+           ratchetPos_ = (int) fabs(value - lastRatchetPos_);
+           ratchetDelta_ = 0.0002 * ratchetPos_;
+           lastRatchetPos_ = (int) value;
+    }
+  }
+  else if (number == __SK_ModFrequency_) { // 4 ... decay
+    if (instType_ != 3 && instType_ != 10) {
+      systemDecay_ = defDecays_[instType_] + ((value - 64.0) *
+                                           decayScale_[instType_] *
+                                           (1.0 - defDecays_[instType_]) / 64.0 );
+      gains_[0] = log(nObjects_) * baseGain_ / (StkFloat) nObjects_;
+      for (i=1;i<nFreqs_;i++) gains_[i] = gains_[0];
+      if (instType_ == 6) { // tambourine
+        gains_[0] *= TAMB_SHELL_GAIN;
+        gains_[1] *= 0.8;
+      }
+      else if (instType_ == 7) { // sleighbell
+        gains_[3] *= 0.5;
+        gains_[4] *= 0.3;
+      }
+      else if (instType_ == 12) { // cokecan
+        for (i=1;i<nFreqs_;i++) gains_[i] *= 1.8;
+      }
+      for (i=0;i<nFreqs_;i++) gains_[i] *= ((128-value)/100.0 + 0.36);
+    }
+  }
+  else if (number == __SK_FootControl_) { // 11 ... number of objects
+    if (instType_ == 5) // bamboo
+      nObjects_ = (StkFloat) (value * defObjs_[instType_] / 64.0) + 0.3;
+    else
+      nObjects_ = (StkFloat) (value * defObjs_[instType_] / 64.0) + 1.1;
+    gains_[0] = log(nObjects_) * baseGain_ / (StkFloat) nObjects_;
+    for (i=1;i<nFreqs_;i++) gains_[i] = gains_[0];
+    if (instType_ == 6) { // tambourine
+      gains_[0] *= TAMB_SHELL_GAIN;
+      gains_[1] *= 0.8;
+    }
+    else if (instType_ == 7) { // sleighbell
+      gains_[3] *= 0.5;
+      gains_[4] *= 0.3;
+    }
+    else if (instType_ == 12) { // cokecan
+      for (i=1;i<nFreqs_;i++) gains_[i] *= 1.8;
+    }
+    if (instType_ != 3 && instType_ != 10) {
+      // reverse calculate decay setting
+      double temp = (double) (64.0 * (systemDecay_-defDecays_[instType_])/(decayScale_[instType_]*(1-defDecays_[instType_])) + 64.0);
+      // scale gains_ by decay setting
+      for (i=0;i<nFreqs_;i++) gains_[i] *= ((128-temp)/100.0 + 0.36);
+    }
+  }
+  else if (number == __SK_ModWheel_) { // 1 ... resonance frequency
+    for (i=0; i<nFreqs_; i++)  {
+      if (instType_ == 6 || instType_ == 2 || instType_ == 7) // limit range a bit for tambourine
+        temp = center_freqs_[i] * pow (1.008,value-64);
+      else
+        temp = center_freqs_[i] * pow (1.015,value-64);
+      t_center_freqs_[i] = temp;
+
+      coeffs_[i][0] = -resons_[i] * 2.0 * cos(temp * TWO_PI / Stk::sampleRate());
+      coeffs_[i][1] = resons_[i]*resons_[i];
+    }
+  }
+  else if (number == __SK_AfterTouch_Cont_) { // 128
+    shakeEnergy_ += norm * MAX_SHAKE * 0.1;
+    if (shakeEnergy_ > MAX_SHAKE) shakeEnergy_ = MAX_SHAKE;
+    if (instType_==10 || instType_==3) {
+           ratchetPos_ = (int) fabs(value - lastRatchetPos_);
+           ratchetDelta_ = 0.0002 * ratchetPos_;
+           lastRatchetPos_ = (int) value;
+    }
+  }
+  else  if (number == __SK_ShakerInst_) { // 1071
+    instType_ = (int) (value + 0.5);   //  Just to be safe
+    this->setupNum(instType_);
+  }                                       
+  else {
+    errorString_ << "Shakers::controlChange: undefined control number (" << number << ")!";
+    handleError( StkError::WARNING );
+  }
+
+#if defined(_STK_DEBUG_)
+    errorString_ << "Shakers::controlChange: number = " << number << ", value = " << value << '.';
+    handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+// KLUDGE-O-MATIC-O-RAMA
+
+StkFloat Shakers :: wuter_tick( void ) {
+  StkFloat data;
+  int j;
+  shakeEnergy_ *= systemDecay_;               // Exponential system decay
+  if (my_random(32767) < nObjects_) {     
+    sndLevel_ = shakeEnergy_;   
+    j = my_random(3);
+         if (j == 0)   {
+      center_freqs_[0] = WUTR_CENTER_FREQ1 * (0.75 + (0.25 * noise_tick()));
+           gains_[0] = fabs(noise_tick());
+         }
+         else if (j == 1)      {
+      center_freqs_[1] = WUTR_CENTER_FREQ1 * (1.0 + (0.25 * noise_tick()));
+           gains_[1] = fabs(noise_tick());
+         }
+         else  {
+      center_freqs_[2] = WUTR_CENTER_FREQ1 * (1.25 + (0.25 * noise_tick()));
+           gains_[2] = fabs(noise_tick());
+         }
+       }
+       
+  gains_[0] *= resons_[0];
+  if (gains_[0] >  0.001) {
+    center_freqs_[0]  *= WUTR_FREQ_SWEEP;
+    coeffs_[0][0] = -resons_[0] * 2.0 * 
+      cos(center_freqs_[0] * TWO_PI / Stk::sampleRate());
+  }
+  gains_[1] *= resons_[1];
+  if (gains_[1] > 0.001) {
+    center_freqs_[1] *= WUTR_FREQ_SWEEP;
+    coeffs_[1][0] = -resons_[1] * 2.0 * 
+      cos(center_freqs_[1] * TWO_PI / Stk::sampleRate());
+  }
+  gains_[2] *= resons_[2];
+  if (gains_[2] > 0.001) {
+    center_freqs_[2] *= WUTR_FREQ_SWEEP;
+    coeffs_[2][0] = -resons_[2] * 2.0 * 
+      cos(center_freqs_[2] * TWO_PI / Stk::sampleRate());
+  }
+       
+  sndLevel_ *= soundDecay_;        // Each (all) event(s) 
+                                   // decay(s) exponentially 
+  inputs_[0] = sndLevel_;
+  inputs_[0] *= noise_tick();     // Actual Sound is Random
+  inputs_[1] = inputs_[0] * gains_[1];
+  inputs_[2] = inputs_[0] * gains_[2];
+  inputs_[0] *= gains_[0];
+  inputs_[0] -= outputs_[0][0]*coeffs_[0][0];
+  inputs_[0] -= outputs_[0][1]*coeffs_[0][1];
+  outputs_[0][1] = outputs_[0][0];
+  outputs_[0][0] = inputs_[0];
+  data = gains_[0]*outputs_[0][0];
+  inputs_[1] -= outputs_[1][0]*coeffs_[1][0];
+  inputs_[1] -= outputs_[1][1]*coeffs_[1][1];
+  outputs_[1][1] = outputs_[1][0];
+  outputs_[1][0] = inputs_[1];
+  data += gains_[1]*outputs_[1][0];
+  inputs_[2] -= outputs_[2][0]*coeffs_[2][0];
+  inputs_[2] -= outputs_[2][1]*coeffs_[2][1];
+  outputs_[2][1] = outputs_[2][0];
+  outputs_[2][0] = inputs_[2];
+  data += gains_[2]*outputs_[2][0];
+  finalZ_[2] = finalZ_[1];
+  finalZ_[1] = finalZ_[0];
+  finalZ_[0] = data * 4;
+
+  data = finalZ_[2] - finalZ_[0];
+  return data;
+}
+
+StkFloat Shakers :: ratchet_tick( void ) {
+  StkFloat data;
+  if (my_random(1024) < nObjects_) {
+    sndLevel_ += 512 * ratchet_ * totalEnergy_;
+  }
+  inputs_[0] = sndLevel_;
+  inputs_[0] *= noise_tick() * ratchet_;
+  sndLevel_ *= soundDecay_;
+                
+  inputs_[1] = inputs_[0];
+  inputs_[0] -= outputs_[0][0]*coeffs_[0][0];
+  inputs_[0] -= outputs_[0][1]*coeffs_[0][1];
+  outputs_[0][1] = outputs_[0][0];
+  outputs_[0][0] = inputs_[0];
+  inputs_[1] -= outputs_[1][0]*coeffs_[1][0];
+  inputs_[1] -= outputs_[1][1]*coeffs_[1][1];
+  outputs_[1][1] = outputs_[1][0];
+  outputs_[1][0] = inputs_[1];
+     
+  finalZ_[2] = finalZ_[1];
+  finalZ_[1] = finalZ_[0];
+  finalZ_[0] = gains_[0]*outputs_[0][1] + gains_[1]*outputs_[1][1];
+  data = finalZ_[0] - finalZ_[2];
+  return data;
+}
+
+StkFloat Shakers :: tbamb_tick( void ) {
+  StkFloat data, temp;
+  static int which = 0;
+  int i;
+
+  if (shakeEnergy_ > MIN_ENERGY)       {
+      shakeEnergy_ *= systemDecay_;    // Exponential system decay
+      if (float_random(1024.0) < nObjects_) {
+           sndLevel_ += shakeEnergy_;
+           which = my_random(7);
+         }  
+      temp = sndLevel_ * noise_tick();      // Actual Sound is Random
+         for (i=0;i<nFreqs_;i++)       inputs_[i] = 0;
+         inputs_[which] = temp;
+      sndLevel_ *= soundDecay_;                   // Exponential Sound decay 
+      finalZ_[2] = finalZ_[1];
+      finalZ_[1] = finalZ_[0];
+      finalZ_[0] = 0;
+      for (i=0;i<nFreqs_;i++)  {
+        inputs_[i] -= outputs_[i][0]*coeffs_[i][0];  // Do
+        inputs_[i] -= outputs_[i][1]*coeffs_[i][1];  // resonant
+        outputs_[i][1] = outputs_[i][0];            // filter
+        outputs_[i][0] = inputs_[i];                // calculations
+        finalZ_[0] += gains_[i] * outputs_[i][1];
+      }
+      data = finalZCoeffs_[0] * finalZ_[0];     // Extra zero(s) for shape
+      data += finalZCoeffs_[1] * finalZ_[1];    // Extra zero(s) for shape
+      data += finalZCoeffs_[2] * finalZ_[2];    // Extra zero(s) for shape
+      if (data > 10000.0)      data = 10000.0;
+      if (data < -10000.0) data = -10000.0;
+      data = data * 0.0001;
+  }
+  else data = 0.0;
+  return data;
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/Simple.cpp b/lib/MoMu-STK-1.0.0/src/Simple.cpp
new file mode 100644 (file)
index 0000000..7b3e724
--- /dev/null
@@ -0,0 +1,115 @@
+/***************************************************/
+/*! \class Simple
+    \brief STK wavetable/noise instrument.
+
+    This class combines a looped wave, a
+    noise source, a biquad resonance filter,
+    a one-pole filter, and an ADSR envelope
+    to create some interesting sounds.
+
+    Control Change Numbers: 
+       - Filter Pole Position = 2
+       - Noise/Pitched Cross-Fade = 4
+       - Envelope Rate = 11
+       - Gain = 128
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "Simple.h"
+#include "Skini_msg.h"
+
+namespace stk {
+
+Simple :: Simple( void )
+{
+  // Concatenate the STK rawwave path to the rawwave file
+  loop_ = new FileLoop( (Stk::rawwavePath() + "impuls10.raw").c_str(), true );
+
+  filter_.setPole( 0.5 );
+  baseFrequency_ = 440.0;
+  setFrequency( baseFrequency_ );
+  loopGain_ = 0.5;
+}  
+
+Simple :: ~Simple( void )
+{
+  delete loop_;
+}
+
+void Simple :: keyOn( void )
+{
+  adsr_.keyOn();
+}
+
+void Simple :: keyOff( void )
+{
+  adsr_.keyOff();
+}
+
+void Simple :: noteOn( StkFloat frequency, StkFloat amplitude )
+{
+  this->keyOn();
+  this->setFrequency( frequency );
+  filter_.setGain( amplitude ); 
+
+#if defined(_STK_DEBUG_)
+  errorString_ << "Simple::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << '.';
+  handleError( StkError::DEBUG_WARNING );
+#endif
+}
+void Simple :: noteOff( StkFloat amplitude )
+{
+  this->keyOff();
+
+#if defined(_STK_DEBUG_)
+  errorString_ << "Simple::NoteOff: amplitude = " << amplitude << ".";
+  handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+void Simple :: setFrequency( StkFloat frequency )
+{
+  biquad_.setResonance( frequency, 0.98, true );
+  loop_->setFrequency( frequency );
+}
+
+void Simple :: controlChange( int number, StkFloat value )
+{
+  StkFloat norm = value * ONE_OVER_128;
+  if ( norm < 0 ) {
+    norm = 0.0;
+    errorString_ << "Simple::controlChange: control value less than zero ... setting to zero!";
+    handleError( StkError::WARNING );
+  }
+  else if ( norm > 1.0 ) {
+    norm = 1.0;
+    errorString_ << "Simple::controlChange: control value greater than 128.0 ... setting to 128.0!";
+    handleError( StkError::WARNING );
+  }
+
+  if (number == __SK_Breath_) // 2
+    filter_.setPole( 0.99 * (1.0 - (norm * 2.0)) );
+  else if (number == __SK_NoiseLevel_) // 4
+    loopGain_ = norm;
+  else if (number == __SK_ModFrequency_) { // 11
+    norm /= 0.2 * Stk::sampleRate();
+    adsr_.setAttackRate( norm );
+    adsr_.setDecayRate( norm );
+    adsr_.setReleaseRate( norm );
+  }
+  else if (number == __SK_AfterTouch_Cont_) // 128
+    adsr_.setTarget( norm );
+  else {
+    errorString_ << "Simple::controlChange: undefined control number (" << number << ")!";
+    handleError( StkError::WARNING );
+  }
+
+#if defined(_STK_DEBUG_)
+    errorString_ << "Simple::controlChange: number = " << number << ", value = " << value << '.';
+    handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/SineWave.cpp b/lib/MoMu-STK-1.0.0/src/SineWave.cpp
new file mode 100644 (file)
index 0000000..3bd8ecf
--- /dev/null
@@ -0,0 +1,78 @@
+/***************************************************/
+/*! \class SineWave
+    \brief STK sinusoid oscillator class.
+
+    This class computes and saves a static sine "table" that can be
+    shared by multiple instances.  It has an interface similar to the
+    WaveLoop class but inherits from the Generator class.  Output
+    values are computed using linear interpolation.
+
+    The "table" length, set in SineWave.h, is 2048 samples by default.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "SineWave.h"
+#include <cmath>
+
+namespace stk {
+
+StkFrames SineWave :: table_;
+
+SineWave :: SineWave( void )
+  : time_(0.0), rate_(1.0), phaseOffset_(0.0)
+{
+  if ( table_.empty() ) {
+    table_.resize( TABLE_SIZE + 1, 1 );
+    StkFloat temp = 1.0 / TABLE_SIZE;
+    for ( unsigned long i=0; i<=TABLE_SIZE; i++ )
+      table_[i] = sin( TWO_PI * i * temp );
+  }
+
+  Stk::addSampleRateAlert( this );
+}
+
+SineWave :: ~SineWave()
+{
+  Stk::removeSampleRateAlert( this );
+}
+
+void SineWave :: sampleRateChanged( StkFloat newRate, StkFloat oldRate )
+{
+  if ( !ignoreSampleRateChange_ )
+    this->setRate( oldRate * rate_ / newRate );
+}
+
+void SineWave :: reset( void )
+{
+  time_ = 0.0;
+  lastFrame_[0] = 0;
+}
+
+void SineWave :: setFrequency( StkFloat frequency )
+{
+  // This is a looping frequency.
+  this->setRate( TABLE_SIZE * frequency / Stk::sampleRate() );
+}
+
+void SineWave :: addTime( StkFloat time )
+{
+  // Add an absolute time in samples.
+  time_ += time;
+}
+
+void SineWave :: addPhase( StkFloat phase )
+{
+  // Add a time in cycles (one cycle = TABLE_SIZE).
+  time_ += TABLE_SIZE * phase;
+}
+
+void SineWave :: addPhaseOffset( StkFloat phaseOffset )
+{
+  // Add a phase offset relative to any previous offset value.
+  time_ += ( phaseOffset - phaseOffset_ ) * TABLE_SIZE;
+  phaseOffset_ = phaseOffset;
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/SingWave.cpp b/lib/MoMu-STK-1.0.0/src/SingWave.cpp
new file mode 100644 (file)
index 0000000..336693b
--- /dev/null
@@ -0,0 +1,53 @@
+/***************************************************/
+/*! \class SingWave
+    \brief STK "singing" looped soundfile class.
+
+    This class loops a specified soundfile and modulates it both
+    periodically and randomly to produce a pitched musical sound, like
+    a simple voice or violin.  In general, it is not be used alone
+    because of "munchkinification" effects from pitch shifting.
+    Within STK, it is used as an excitation source for other
+    instruments.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "SingWave.h"
+
+namespace stk {
+SingWave :: SingWave( std::string fileName, bool raw )
+{
+  // An exception could be thrown here.
+  wave_.openFile( fileName, raw );
+
+       rate_ = 1.0;
+       sweepRate_ = 0.001;
+
+       modulator_.setVibratoRate( 6.0 );
+       modulator_.setVibratoGain( 0.04 );
+       modulator_.setRandomGain( 0.005 );
+
+       this->setFrequency( 75.0 );
+       pitchEnvelope_.setRate( 1.0 );
+       this->tick();
+       this->tick();
+       pitchEnvelope_.setRate( sweepRate_ * rate_ );
+}
+
+SingWave :: ~SingWave()
+{
+}
+
+void SingWave :: setFrequency( StkFloat frequency )
+{
+       StkFloat temp = rate_;
+       rate_ = wave_.getSize() * frequency / Stk::sampleRate();
+       temp -= rate_;
+       if ( temp < 0) temp = -temp;
+       pitchEnvelope_.setTarget( rate_ );
+       pitchEnvelope_.setRate( sweepRate_ * temp );
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/Sitar.cpp b/lib/MoMu-STK-1.0.0/src/Sitar.cpp
new file mode 100644 (file)
index 0000000..14035e7
--- /dev/null
@@ -0,0 +1,102 @@
+/***************************************************/
+/*! \class Sitar
+    \brief STK sitar string model class.
+
+    This class implements a sitar plucked string
+    physical model based on the Karplus-Strong
+    algorithm.
+
+    This is a digital waveguide model, making its
+    use possibly subject to patents held by
+    Stanford University, Yamaha, and others.
+    There exist at least two patents, assigned to
+    Stanford, bearing the names of Karplus and/or
+    Strong.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "Sitar.h"
+
+namespace stk {
+
+Sitar :: Sitar( StkFloat lowestFrequency )
+{
+  unsigned long length = (unsigned long) ( Stk::sampleRate() / lowestFrequency + 1 );
+  delayLine_.setMaximumDelay( length );
+  delay_ = 0.5 * length;
+  delayLine_.setDelay( delay_ );
+  targetDelay_ = delay_;
+
+  loopFilter_.setZero(0.01);
+  loopGain_ = 0.999;
+
+  envelope_.setAllTimes(0.001, 0.04, 0.0, 0.5);
+  this->clear();
+}
+
+Sitar :: ~Sitar( void )
+{
+}
+
+void Sitar :: clear( void )
+{
+  delayLine_.clear();
+  loopFilter_.clear();
+}
+
+void Sitar :: setFrequency( StkFloat frequency )
+{
+  StkFloat freakency = frequency;
+  if ( frequency <= 0.0 ) {
+    errorString_ << "Sitar::setFrequency: parameter is less than or equal to zero!";
+    handleError( StkError::WARNING );
+    freakency = 220.0;
+  }
+
+  targetDelay_ = (Stk::sampleRate() / freakency);
+  delay_ = targetDelay_ * (1.0 + (0.05 * noise_.tick()));
+  delayLine_.setDelay( delay_ );
+  loopGain_ = 0.995 + (freakency * 0.0000005);
+  if ( loopGain_ > 0.9995 ) loopGain_ = 0.9995;
+}
+
+void Sitar :: pluck( StkFloat amplitude )
+{
+  envelope_.keyOn();
+}
+
+void Sitar :: noteOn( StkFloat frequency, StkFloat amplitude )
+{
+  this->setFrequency( frequency );
+  this->pluck( amplitude );
+  amGain_ = 0.1 * amplitude;
+
+#if defined(_STK_DEBUG_)
+  errorString_ << "Sitar::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << ".";
+  handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+void Sitar :: noteOff( StkFloat amplitude )
+{
+  loopGain_ = (StkFloat) 1.0 - amplitude;
+  if ( loopGain_ < 0.0 ) {
+    errorString_ << "Sitar::noteOff: amplitude is greater than 1.0 ... setting to 1.0!";
+    handleError( StkError::WARNING );
+    loopGain_ = 0.0;
+  }
+  else if ( loopGain_ > 1.0 ) {
+    errorString_ << "Sitar::noteOff: amplitude is < 0.0  ... setting to 0.0!";
+    handleError( StkError::WARNING );
+    loopGain_ = 0.99999;
+  }
+
+#if defined(_STK_DEBUG_)
+  errorString_ << "Sitar::NoteOff: amplitude = " << amplitude << ".";
+  handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/Skini.cpp b/lib/MoMu-STK-1.0.0/src/Skini.cpp
new file mode 100644 (file)
index 0000000..69d2b38
--- /dev/null
@@ -0,0 +1,222 @@
+/***************************************************/
+/*! \class Skini
+    \brief STK SKINI parsing class
+
+    This class parses SKINI formatted text
+    messages.  It can be used to parse individual
+    messages or it can be passed an entire file.
+    The SKINI specification is Perry's and his
+    alone, but it's all text so it shouldn't be too
+    hard to figure out.
+
+    SKINI (Synthesis toolKit Instrument Network
+    Interface) is like MIDI, but allows for
+    floating-point control changes, note numbers,
+    etc.  The following example causes a sharp
+    middle C to be played with a velocity of 111.132:
+
+    noteOn  60.01  111.132
+
+    See also SKINI.txt.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "Skini.h"
+#include "Skini_tbl.h"
+#include <cstdlib>
+
+namespace stk {
+
+Skini :: Skini()
+{
+}
+
+Skini :: ~Skini()
+{
+}
+
+bool Skini :: setFile( std::string fileName )
+{
+  if ( file_.is_open() ) {
+    errorString_ << "Skini::setFile: already reaading a file!";
+    handleError( StkError::WARNING );
+    return false;
+  }
+
+  file_.open( fileName.c_str() );
+  if ( !file_ ) {
+    errorString_ << "Skini::setFile: unable to open file (" << fileName << ")";
+    handleError( StkError::WARNING );
+    return false;
+  }
+
+  return true;
+}
+
+long Skini :: nextMessage( Message& message )
+{
+  if ( !file_.is_open() ) return 0;
+
+  std::string line;
+  bool done = false;
+  while ( !done ) {
+
+    // Read a line from the file and skip over invalid messages.
+    if ( std::getline( file_, line ).eof() ) {
+      errorString_ << "// End of Score.  Thanks for using SKINI!!";
+      handleError( StkError::STATUS );
+      file_.close();
+      message.type = 0;
+      done = true;
+    }
+    else if ( parseString( line, message ) > 0 ) done = true;
+  }
+
+  return message.type;  
+}
+
+void Skini :: tokenize( const std::string&        str,
+                        std::vector<std::string>& tokens,
+                        const std::string&        delimiters )
+{
+  // Skip delimiters at beginning.
+  std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
+  // Find first "non-delimiter".
+  std::string::size_type pos     = str.find_first_of(delimiters, lastPos);
+
+  while (std::string::npos != pos || std::string::npos != lastPos) {
+    // Found a token, add it to the vector.
+    tokens.push_back(str.substr(lastPos, pos - lastPos));
+    // Skip delimiters.  Note the "not_of"
+    lastPos = str.find_first_not_of(delimiters, pos);
+    // Find next "non-delimiter"
+    pos = str.find_first_of(delimiters, lastPos);
+  }
+} 
+
+long Skini :: parseString( std::string& line, Message& message )
+{
+  message.type = 0;
+  if ( line.empty() ) return message.type;
+
+  // Check for comment lines.
+  std::string::size_type lastPos = line.find_first_not_of(" ,\t", 0);
+  std::string::size_type pos     = line.find_first_of("/", lastPos);
+  if ( std::string::npos != pos ) {
+    errorString_ << "// Comment Line: " << line;
+    handleError( StkError::STATUS );
+    return message.type;
+  }
+
+  // Tokenize the string.
+  std::vector<std::string> tokens; 
+  this->tokenize( line, tokens, " ,\t");
+
+  // Valid SKINI messages must have at least three fields (type, time,
+  // and channel).
+  if ( tokens.size() < 3 ) return message.type;
+
+  // Determine message type.
+  int iSkini = 0;
+  while ( iSkini < __SK_MaxMsgTypes_ ) {
+    if ( tokens[0] == skini_msgs[iSkini].messageString ) break;
+    iSkini++;
+  }
+
+  if ( iSkini >= __SK_MaxMsgTypes_ )  {
+    errorString_ << "Skini::parseString: couldn't parse this line:\n   " << line;
+    handleError( StkError::WARNING );
+    return message.type;
+  }
+  
+  // Found the type.
+  message.type = skini_msgs[iSkini].type;
+
+  // Parse time field.
+  if ( tokens[1][0] == '=' ) {
+    tokens[1].erase( tokens[1].begin() );
+    if ( tokens[1].empty() ) {
+      errorString_ << "Skini::parseString: couldn't parse time field in line:\n   " << line;
+      handleError( StkError::WARNING );
+      return message.type = 0;
+    }
+    message.time = (StkFloat) -atof( tokens[1].c_str() );
+  }
+  else
+    message.time = (StkFloat) atof( tokens[1].c_str() );
+
+  // Parse the channel field.
+  message.channel = atoi( tokens[2].c_str() );
+
+  // Parse the remaining fields (maximum of 2 more).
+  int iValue = 0;
+  long dataType = skini_msgs[iSkini].data2;
+  while ( dataType != NOPE ) {
+
+    if ( tokens.size() <= (unsigned int) (iValue+3) ) {
+      errorString_ <<  "Skini::parseString: inconsistency between type table and parsed line:\n   " << line;
+      handleError( StkError::WARNING );
+      return message.type = 0;
+    }
+
+    switch ( dataType ) {
+
+    case SK_INT:
+      message.intValues[iValue] = atoi( tokens[iValue+3].c_str() );
+      message.floatValues[iValue] = (StkFloat) message.intValues[iValue];
+      break;
+
+    case SK_DBL:
+      message.floatValues[iValue] = atof( tokens[iValue+3].c_str() );
+      message.intValues[iValue] = (long) message.floatValues[iValue];
+      break;
+
+    case SK_STR: // Must be the last field.
+      message.remainder = tokens[iValue+3];
+      return message.type;
+
+    default: // MIDI extension message
+      message.intValues[iValue] = dataType;
+      message.floatValues[iValue] = (StkFloat) message.intValues[iValue];
+      iValue--;
+    }
+
+    if ( ++iValue == 1 )
+      dataType = skini_msgs[iSkini].data3;
+    else
+      dataType = NOPE;
+  }
+
+  return message.type;
+}
+
+std::string Skini :: whatsThisType(long type)
+{
+  std::string typeString;
+
+  for ( int i=0; i<__SK_MaxMsgTypes_; i++ ) {
+    if ( type == skini_msgs[i].type ) {
+      typeString = skini_msgs[i].messageString;
+      break;
+    }
+  }
+  return typeString;
+}
+
+std::string Skini :: whatsThisController( long number )
+{
+  std::string controller;
+
+  for ( int i=0; i<__SK_MaxMsgTypes_; i++) {
+    if ( skini_msgs[i].type == __SK_ControlChange_ &&
+         number == skini_msgs[i].data2) {
+      controller = skini_msgs[i].messageString;
+      break;
+    }
+  }
+  return controller;
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/Socket.cpp b/lib/MoMu-STK-1.0.0/src/Socket.cpp
new file mode 100644 (file)
index 0000000..ba20ce3
--- /dev/null
@@ -0,0 +1,78 @@
+/***************************************************/
+/*! \class Socket
+    \brief STK internet socket abstract base class.
+
+    This class provides common functionality for TCP and UDP internet
+    socket server and client subclasses.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "Socket.h"
+
+namespace stk {
+
+Socket :: Socket()
+{
+  soket_ = -1;
+  port_ = -1;
+}
+
+Socket :: ~Socket()
+{
+  this->close( soket_ );
+
+#if defined(__OS_WINDOWS__)
+
+  WSACleanup();
+
+#endif
+}
+
+void Socket :: close( int socket )
+{
+  if ( !isValid( socket ) ) return;
+
+#if (defined(__OS_IRIX__) || defined(__OS_LINUX__) || defined(__OS_MACOSX__))
+
+  ::close( socket );
+
+#elif defined(__OS_WINDOWS__)
+
+  ::closesocket( socket );
+
+#endif
+}
+
+void Socket :: setBlocking( int socket, bool enable )
+{
+  if ( !isValid( socket ) ) return;
+
+#if (defined(__OS_IRIX__) || defined(__OS_LINUX__) || defined(__OS_MACOSX__))
+
+  int tmp = ::fcntl( socket, F_GETFL, 0 );
+  if ( tmp >= 0 )
+    tmp = ::fcntl( socket, F_SETFL, enable ? (tmp &~ O_NONBLOCK) : (tmp | O_NONBLOCK) );
+
+#elif defined(__OS_WINDOWS__)
+
+  unsigned long non_block = !enable;
+  ioctlsocket( socket, FIONBIO, &non_block );
+
+#endif
+}
+
+int Socket :: writeBuffer(int socket, const void *buffer, long bufferSize, int flags )
+{
+  if ( !isValid( socket ) ) return -1;
+  return send( socket, (const char *)buffer, bufferSize, flags );
+}
+
+int Socket :: readBuffer(int socket, void *buffer, long bufferSize, int flags )
+{
+  if ( !isValid( socket ) ) return -1;
+  return recv( socket, (char *)buffer, bufferSize, flags );
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/Sphere.cpp b/lib/MoMu-STK-1.0.0/src/Sphere.cpp
new file mode 100644 (file)
index 0000000..707a67f
--- /dev/null
@@ -0,0 +1,50 @@
+/***************************************************/
+/*! \class Sphere
+    \brief STK sphere class.
+
+    This class implements a spherical ball with
+    radius, mass, position, and velocity parameters.
+
+    by Perry R. Cook, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "Sphere.h"
+#include <cmath>
+
+namespace stk {
+
+Vector3D* Sphere::getRelativePosition( Vector3D* position )
+{
+  workingVector_.setXYZ(position->getX() - position_.getX(),
+                        position->getY() - position_.getY(),  
+                        position->getZ() - position_.getZ());
+  return &workingVector_;
+};
+
+StkFloat Sphere::getVelocity( Vector3D* velocity )
+{
+  velocity->setXYZ( velocity_.getX(), velocity_.getY(), velocity_.getZ() );
+  return velocity_.getLength();
+};
+
+StkFloat Sphere::isInside( Vector3D *position )
+{
+  // Return directed distance from aPosition to spherical boundary ( <
+  // 0 if inside).
+  StkFloat distance;
+  Vector3D *tempVector;
+
+  tempVector = this->getRelativePosition( position );
+  distance = tempVector->getLength();
+  return distance - radius_;
+};
+
+void Sphere::addVelocity(StkFloat x, StkFloat y, StkFloat z)
+{
+  velocity_.setX(velocity_.getX() + x);
+  velocity_.setY(velocity_.getY() + y);
+  velocity_.setZ(velocity_.getZ() + z);
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/StifKarp.cpp b/lib/MoMu-STK-1.0.0/src/StifKarp.cpp
new file mode 100644 (file)
index 0000000..6b118ff
--- /dev/null
@@ -0,0 +1,216 @@
+/***************************************************/
+/*! \class StifKarp
+    \brief STK plucked stiff string instrument.
+
+    This class implements a simple plucked string
+    algorithm (Karplus Strong) with enhancements
+    (Jaffe-Smith, Smith, and others), including
+    string stiffness and pluck position controls.
+    The stiffness is modeled with allpass filters.
+
+    This is a digital waveguide model, making its
+    use possibly subject to patents held by
+    Stanford University, Yamaha, and others.
+
+    Control Change Numbers:
+       - Pickup Position = 4
+       - String Sustain = 11
+       - String Stretch = 1
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "StifKarp.h"
+#include "Skini_msg.h"
+#include <cmath>
+
+namespace stk {
+
+StifKarp :: StifKarp( StkFloat lowestFrequency )
+{
+  length_ = (unsigned long) ( Stk::sampleRate() / lowestFrequency + 1 );
+  delayLine_.setMaximumDelay( length_ );
+  delayLine_.setDelay( 0.5 * length_ );
+  combDelay_.setMaximumDelay( length_ );
+  combDelay_.setDelay( 0.2 * length_ );
+
+  pluckAmplitude_ = 0.3;
+  pickupPosition_ = 0.4;
+  lastFrequency_ = lowestFrequency * 2.0;
+  lastLength_ = length_ * 0.5;
+  stretching_ = 0.9999;
+  baseLoopGain_ = 0.995;
+  loopGain_ = 0.999;
+
+  this->clear();
+}
+
+StifKarp :: ~StifKarp( void )
+{
+}
+
+void StifKarp :: clear( void )
+{
+  delayLine_.clear();
+  combDelay_.clear();
+  filter_.clear();
+}
+
+void StifKarp :: setFrequency( StkFloat frequency )
+{
+  lastFrequency_ = frequency; 
+  if ( frequency <= 0.0 ) {
+    errorString_ << "StifKarp::setFrequency: parameter is less than or equal to zero!";
+    handleError( StkError::WARNING );
+    lastFrequency_ = 220.0;
+  }
+
+  lastLength_ = Stk::sampleRate() / lastFrequency_;
+  StkFloat delay = lastLength_ - 0.5;
+  if (delay <= 0.0)
+    delay = 0.3;
+  else if (delay > length_)
+    delay = length_;
+  delayLine_.setDelay( delay );
+
+  loopGain_ = baseLoopGain_ + (frequency * 0.000005);
+  if (loopGain_ >= 1.0) loopGain_ = 0.99999;
+
+  setStretch(stretching_);
+
+  combDelay_.setDelay( 0.5 * pickupPosition_ * lastLength_ ); 
+}
+
+void StifKarp :: setStretch( StkFloat stretch )
+{
+  stretching_ = stretch;
+  StkFloat coefficient;
+  StkFloat freq = lastFrequency_ * 2.0;
+  StkFloat dFreq = ( (0.5 * Stk::sampleRate()) - freq ) * 0.25;
+  StkFloat temp = 0.5 + (stretch * 0.5);
+  if (temp > 0.9999) temp = 0.9999;
+  for (int i=0; i<4; i++)      {
+    coefficient = temp * temp;
+    biquad_[i].setA2( coefficient );
+    biquad_[i].setB0( coefficient );
+    biquad_[i].setB2( 1.0 );
+
+    coefficient = -2.0 * temp * cos(TWO_PI * freq / Stk::sampleRate());
+    biquad_[i].setA1( coefficient );
+    biquad_[i].setB1( coefficient );
+
+    freq += dFreq;
+  }
+}
+
+void StifKarp :: setPickupPosition( StkFloat position ) {
+  pickupPosition_ = position;
+  if ( position < 0.0 ) {
+    errorString_ << "StifKarp::setPickupPosition: parameter is less than zero ... setting to 0.0!";
+    handleError( StkError::WARNING );
+    pickupPosition_ = 0.0;
+  }
+  else if ( position > 1.0 ) {
+    errorString_ << "StifKarp::setPickupPosition: parameter is greater than 1.0 ... setting to 1.0!";
+    handleError( StkError::WARNING );
+    pickupPosition_ = 1.0;
+  }
+
+  // Set the pick position, which puts zeroes at position * length.
+  combDelay_.setDelay( 0.5 * pickupPosition_ * lastLength_ );
+}
+
+void StifKarp :: setBaseLoopGain( StkFloat aGain )
+{
+  baseLoopGain_ = aGain;
+  loopGain_ = baseLoopGain_ + (lastFrequency_ * 0.000005);
+  if ( loopGain_ > 0.99999 ) loopGain_ = (StkFloat) 0.99999;
+}
+
+void StifKarp :: pluck( StkFloat amplitude )
+{
+  StkFloat gain = amplitude;
+  if ( gain > 1.0 ) {
+    errorString_ << "StifKarp::pluck: amplitude is greater than 1.0 ... setting to 1.0!";
+    handleError( StkError::WARNING );
+    gain = 1.0;
+  }
+  else if ( gain < 0.0 ) {
+    errorString_ << "StifKarp::pluck: amplitude is less than zero ... setting to 0.0!";
+    handleError( StkError::WARNING );
+    gain = 0.0;
+  }
+
+  pluckAmplitude_ = amplitude;
+  for (unsigned long i=0; i<length_; i++)  {
+    // Fill delay with noise additively with current contents.
+    delayLine_.tick( (delayLine_.lastOut() * 0.6) + 0.4 * noise_.tick() * pluckAmplitude_ );
+    //delayLine_.tick( combDelay_.tick((delayLine_.lastOut() * 0.6) + 0.4 * noise->tick() * pluckAmplitude_) );
+  }
+}
+
+void StifKarp :: noteOn( StkFloat frequency, StkFloat amplitude )
+{
+  this->setFrequency( frequency );
+  this->pluck( amplitude );
+
+#if defined(_STK_DEBUG_)
+  errorString_ << "StifKarp::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << ".";
+  handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+void StifKarp :: noteOff( StkFloat amplitude )
+{
+  StkFloat gain = amplitude;
+  if ( gain > 1.0 ) {
+    errorString_ << "StifKarp::noteOff: amplitude is greater than 1.0 ... setting to 1.0!";
+    handleError( StkError::WARNING );
+    gain = 1.0;
+  }
+  else if ( gain < 0.0 ) {
+    errorString_ << "StifKarp::noteOff: amplitude is < 0.0  ... setting to 0.0!";
+    handleError( StkError::WARNING );
+    gain = 0.0;
+  }
+  loopGain_ =  (1.0 - gain) * 0.5;
+
+#if defined(_STK_DEBUG_)
+  errorString_ << "StifKarp::NoteOff: amplitude = " << amplitude << ".";
+  handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+void StifKarp :: controlChange( int number, StkFloat value )
+{
+  StkFloat norm = value * ONE_OVER_128;
+  if ( norm < 0 ) {
+    norm = 0.0;
+    errorString_ << "StifKarp::controlChange: control value less than zero ... setting to zero!";
+    handleError( StkError::WARNING );
+  }
+  else if ( norm > 1.0 ) {
+    norm = 1.0;
+    errorString_ << "StifKarp::controlChange: control value greater than 128.0 ... setting to 128.0!";
+    handleError( StkError::WARNING );
+  }
+
+  if (number == __SK_PickPosition_) // 4
+    this->setPickupPosition( norm );
+  else if (number == __SK_StringDamping_) // 11
+    this->setBaseLoopGain( 0.97 + (norm * 0.03) );
+  else if (number == __SK_StringDetune_) // 1
+    this->setStretch( 0.9 + (0.1 * (1.0 - norm)) );
+  else {
+    errorString_ << "StifKarp::controlChange: undefined control number (" << number << ")!";
+    handleError( StkError::WARNING );
+  }
+
+#if defined(_STK_DEBUG_)
+    errorString_ << "StifKarp::controlChange: number = " << number << ", value = " << value << ".";
+    handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/Stk.mm b/lib/MoMu-STK-1.0.0/src/Stk.mm
new file mode 100644 (file)
index 0000000..9af8abd
--- /dev/null
@@ -0,0 +1,345 @@
+/***************************************************/
+/*! \class Stk
+    \brief STK base class
+
+    Nearly all STK classes inherit from this class.
+    The global sample rate can be queried and
+    modified via Stk.  In addition, this class
+    provides error handling and byte-swapping
+    functions.
+
+    The Synthesis ToolKit in C++ (STK) is a set of open source audio
+    signal processing and algorithmic synthesis classes written in the
+    C++ programming language. STK was designed to facilitate rapid
+    development of music synthesis and audio processing software, with
+    an emphasis on cross-platform functionality, realtime control,
+    ease of use, and educational example code.  STK currently runs
+    with realtime support (audio and MIDI) on Linux, Macintosh OS X,
+    and Windows computer platforms. Generic, non-realtime support has
+    been tested under NeXTStep, Sun, and other platforms and should
+    work with any standard C++ compiler.
+
+    STK WWW site: http://ccrma.stanford.edu/software/stk/
+
+    The Synthesis ToolKit in C++ (STK)
+    Copyright (c) 1995-2010 Perry R. Cook and Gary P. Scavone
+
+    Permission is hereby granted, free of charge, to any person
+    obtaining a copy of this software and associated documentation files
+    (the "Software"), to deal in the Software without restriction,
+    including without limitation the rights to use, copy, modify, merge,
+    publish, distribute, sublicense, and/or sell copies of the Software,
+    and to permit persons to whom the Software is furnished to do so,
+    subject to the following conditions:
+
+    The above copyright notice and this permission notice shall be
+    included in all copies or substantial portions of the Software.
+
+    Any person wishing to distribute modifications to the Software is
+    asked to send the modifications to the original developer so that
+    they can be incorporated into the canonical version.  This is,
+    however, not a binding provision of this license.
+
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+    IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+    ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+    CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+    WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+/***************************************************/
+
+#include "Stk.h"
+
+namespace stk {
+
+StkFloat Stk :: srate_ = (StkFloat) SRATE;
+const Stk::StkFormat Stk :: STK_SINT8   = 0x1;
+const Stk::StkFormat Stk :: STK_SINT16  = 0x2;
+const Stk::StkFormat Stk :: STK_SINT24  = 0x4;
+const Stk::StkFormat Stk :: STK_SINT32  = 0x8;
+const Stk::StkFormat Stk :: STK_FLOAT32 = 0x10;
+const Stk::StkFormat Stk :: STK_FLOAT64 = 0x20;
+bool Stk :: showWarnings_ = true;
+bool Stk :: printErrors_ = true;
+std::vector<Stk *> Stk :: alertList_;
+
+std::string Stk::rawwavepath_ = "";
+        
+       
+
+Stk :: Stk( void )
+  : ignoreSampleRateChange_(false)
+{
+       std::string path([[[NSBundle mainBundle] resourcePath] UTF8String]);
+       setRawwavePath( path ); 
+       //std::cout<<(rawwavepath_)<<std::endl;
+}
+
+Stk :: ~Stk( void )
+{
+}
+
+void Stk :: setSampleRate( StkFloat rate )
+{
+  if ( rate > 0.0 && rate != srate_ ) {
+    StkFloat oldRate = srate_;
+    srate_ = rate;
+
+    for ( unsigned int i=0; i<alertList_.size(); i++ )
+      alertList_[i]->sampleRateChanged( srate_, oldRate );
+  }
+}
+
+void Stk :: sampleRateChanged( StkFloat newRate, StkFloat oldRate )
+{
+  // This function should be reimplemented in classes that need to
+  // make internal variable adjustments in response to a global sample
+  // rate change.
+}
+
+void Stk :: addSampleRateAlert( Stk *ptr )
+{
+  for ( unsigned int i=0; i<alertList_.size(); i++ )
+    if ( alertList_[i] == ptr ) return;
+
+  alertList_.push_back( ptr );
+}
+
+void Stk :: removeSampleRateAlert( Stk *ptr )
+{
+  for ( unsigned int i=0; i<alertList_.size(); i++ ) {
+    if ( alertList_[i] == ptr ) {
+      alertList_.erase( alertList_.begin() + i );
+      return;
+    }
+  }
+}
+
+void Stk :: setRawwavePath( std::string path )
+{
+  if ( !path.empty() )
+    rawwavepath_ = path;
+
+  // Make sure the path includes a "/"
+  if ( rawwavepath_[rawwavepath_.length()-1] != '/' )
+    rawwavepath_ += "/";
+}
+
+void Stk :: swap16(unsigned char *ptr)
+{
+  register unsigned char val;
+
+  // Swap 1st and 2nd bytes
+  val = *(ptr);
+  *(ptr) = *(ptr+1);
+  *(ptr+1) = val;
+}
+
+void Stk :: swap32(unsigned char *ptr)
+{
+  register unsigned char val;
+
+  // Swap 1st and 4th bytes
+  val = *(ptr);
+  *(ptr) = *(ptr+3);
+  *(ptr+3) = val;
+
+  //Swap 2nd and 3rd bytes
+  ptr += 1;
+  val = *(ptr);
+  *(ptr) = *(ptr+1);
+  *(ptr+1) = val;
+}
+
+void Stk :: swap64(unsigned char *ptr)
+{
+  register unsigned char val;
+
+  // Swap 1st and 8th bytes
+  val = *(ptr);
+  *(ptr) = *(ptr+7);
+  *(ptr+7) = val;
+
+  // Swap 2nd and 7th bytes
+  ptr += 1;
+  val = *(ptr);
+  *(ptr) = *(ptr+5);
+  *(ptr+5) = val;
+
+  // Swap 3rd and 6th bytes
+  ptr += 1;
+  val = *(ptr);
+  *(ptr) = *(ptr+3);
+  *(ptr+3) = val;
+
+  // Swap 4th and 5th bytes
+  ptr += 1;
+  val = *(ptr);
+  *(ptr) = *(ptr+1);
+  *(ptr+1) = val;
+}
+
+#if (defined(__OS_IRIX__) || defined(__OS_LINUX__) || defined(__OS_MACOSX__))
+  #include <unistd.h>
+#elif defined(__OS_WINDOWS__)
+  #include <windows.h>
+#endif
+
+void Stk :: sleep(unsigned long milliseconds)
+{
+#if defined(__OS_WINDOWS__)
+  Sleep((DWORD) milliseconds);
+#elif (defined(__OS_IRIX__) || defined(__OS_LINUX__) || defined(__OS_MACOSX__))
+  usleep( (unsigned long) (milliseconds * 1000.0) );
+#endif
+}
+
+void Stk :: handleError( StkError::Type type )
+{
+  handleError( errorString_.str(), type );
+  errorString_.str( std::string() ); // reset the ostringstream buffer
+}
+
+void Stk :: handleError( const char *message, StkError::Type type )
+{
+  std::string msg( message );
+  handleError( msg, type );
+}
+
+void Stk :: handleError( std::string message, StkError::Type type )
+{
+  if ( type == StkError::WARNING || type == StkError::STATUS ) {
+    if ( !showWarnings_ ) return;
+    std::cerr << '\n' << message << '\n' << std::endl;
+  }
+  else if (type == StkError::DEBUG_WARNING) {
+#if defined(_STK_DEBUG_)
+    std::cerr << '\n' << message << '\n' << std::endl;
+#endif
+  }
+  else {
+    if ( printErrors_ ) {
+      // Print error message before throwing.
+      std::cerr << '\n' << message << '\n' << std::endl;
+    }
+    throw StkError(message, type);
+  }
+}
+
+//
+// StkFrames definitions
+//
+
+StkFrames :: StkFrames( unsigned int nFrames, unsigned int nChannels )
+  : nFrames_( nFrames ), nChannels_( nChannels )
+{
+  size_ = nFrames_ * nChannels_;
+  bufferSize_ = size_;
+
+  if ( size_ > 0 ) {
+    data_ = (StkFloat *) calloc( size_, sizeof( StkFloat ) );
+#if defined(_STK_DEBUG_)
+    if ( data_ == NULL ) {
+      std::string error = "StkFrames: memory allocation error in constructor!";
+      Stk::handleError( error, StkError::MEMORY_ALLOCATION );
+    }
+#endif
+  }
+  else data_ = 0;
+
+  dataRate_ = Stk::sampleRate();
+}
+
+StkFrames :: StkFrames( const StkFloat& value, unsigned int nFrames, unsigned int nChannels )
+  : nFrames_( nFrames ), nChannels_( nChannels )
+{
+  size_ = nFrames_ * nChannels_;
+  bufferSize_ = size_;
+  if ( size_ > 0 ) {
+    data_ = (StkFloat *) malloc( size_ * sizeof( StkFloat ) );
+#if defined(_STK_DEBUG_)
+    if ( data_ == NULL ) {
+      std::string error = "StkFrames: memory allocation error in constructor!";
+      Stk::handleError( error, StkError::MEMORY_ALLOCATION );
+    }
+#endif
+    for ( long i=0; i<(long)size_; i++ ) data_[i] = value;
+  }
+  else data_ = 0;
+
+  dataRate_ = Stk::sampleRate();
+}
+
+StkFrames :: ~StkFrames()
+{
+  if ( data_ ) free( data_ );
+}
+
+StkFrames :: StkFrames( const StkFrames& f )
+  : size_(0), bufferSize_(0)
+{
+  resize( f.frames(), f.channels() );
+  dataRate_ = Stk::sampleRate();
+  for ( unsigned int i=0; i<size_; i++ ) data_[i] = f[i];
+}
+
+StkFrames& StkFrames :: operator= ( const StkFrames& f )
+{
+  size_ = 0;
+  bufferSize_ = 0;
+  resize( f.frames(), f.channels() );
+  dataRate_ = Stk::sampleRate();
+  for ( unsigned int i=0; i<size_; i++ ) data_[i] = f[i];
+  return *this;
+}
+
+void StkFrames :: resize( size_t nFrames, unsigned int nChannels )
+{
+  nFrames_ = nFrames;
+  nChannels_ = nChannels;
+
+  size_ = nFrames_ * nChannels_;
+  if ( size_ > bufferSize_ ) {
+    if ( data_ ) free( data_ );
+    data_ = (StkFloat *) malloc( size_ * sizeof( StkFloat ) );
+#if defined(_STK_DEBUG_)
+    if ( data_ == NULL ) {
+      std::string error = "StkFrames::resize: memory allocation error!";
+      Stk::handleError( error, StkError::MEMORY_ALLOCATION );
+    }
+#endif
+    bufferSize_ = size_;
+  }
+}
+
+void StkFrames :: resize( size_t nFrames, unsigned int nChannels, StkFloat value )
+{
+  this->resize( nFrames, nChannels );
+
+  for ( size_t i=0; i<size_; i++ ) data_[i] = value;
+}
+
+StkFloat StkFrames :: interpolate( StkFloat frame, unsigned int channel ) const
+{
+#if defined(_STK_DEBUG_)
+  if ( frame < 0.0 || frame > (StkFloat) ( nFrames_ - 1 ) || channel >= nChannels_ ) {
+    std::ostringstream error;
+    error << "StkFrames::interpolate: invalid frame (" << frame << ") or channel (" << channel << ") value!";
+    Stk::handleError( error.str(), StkError::MEMORY_ACCESS );
+  }
+#endif
+
+  size_t iIndex = ( size_t ) frame;                    // integer part of index
+  StkFloat output, alpha = frame - (StkFloat) iIndex;  // fractional part of index
+
+  iIndex = iIndex * nChannels_ + channel;
+  output = data_[ iIndex ];
+  if ( alpha > 0.0 )
+    output += ( alpha * ( data_[ iIndex + nChannels_ ] - output ) );
+
+  return output;
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/StkUdpSocket.cpp b/lib/MoMu-STK-1.0.0/src/StkUdpSocket.cpp
new file mode 100644 (file)
index 0000000..c2d643d
--- /dev/null
@@ -0,0 +1,109 @@
+/***************************************************/
+/*! \class UdpSocket
+    \brief STK UDP socket server/client class.
+
+    This class provides a uniform cross-platform UDP socket
+    server/client interface.  Methods are provided for reading or
+    writing data buffers.  The constructor creates a UDP socket and
+    binds it to the specified port.  Note that only one socket can be
+    bound to a given port on the same machine.
+
+    UDP sockets provide unreliable, connection-less service.  Messages
+    can be lost, duplicated, or received out of order.  That said,
+    data transmission tends to be faster than with TCP connections and
+    datagrams are not potentially combined by the underlying system.
+
+    The user is responsible for checking the values returned by the
+    read/write methods.  Values less than or equal to zero indicate
+    the occurence of an error.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "StkUdpSocket.h"
+#include <cstring>
+
+namespace stk {
+
+StkUdpSocket :: StkUdpSocket(int port )
+{
+  validAddress_ = false;
+
+#if defined(__OS_WINDOWS__)  // windoze-only stuff
+  WSADATA wsaData;
+  WORD wVersionRequested = MAKEWORD(1,1);
+
+  WSAStartup(wVersionRequested, &wsaData);
+  if (wsaData.wVersion != wVersionRequested) {
+    errorString_ << "UdpSocket: Incompatible Windows socket library version!";
+    handleError( StkError::PROCESS_SOCKET );
+  }
+#endif
+
+  // Create the UDP socket
+  soket_ = ::socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
+  if ( soket_ < 0 ) {
+    errorString_ << "UdpSocket: Couldn't create UDP socket!";
+    handleError( StkError::PROCESS_SOCKET );
+  }
+
+  struct sockaddr_in address;
+  address.sin_family = AF_INET;
+  address.sin_addr.s_addr = INADDR_ANY;
+  address.sin_port = htons( port );
+
+  // Bind socket to the appropriate port and interface (INADDR_ANY)
+  if ( bind(soket_, (struct sockaddr *)&address, sizeof(address)) < 0 ) {
+    errorString_ << "UdpSocket: Couldn't bind socket in constructor!";
+    handleError( StkError::PROCESS_SOCKET );
+  }
+
+  port_ = port;
+}
+
+StkUdpSocket :: ~StkUdpSocket()
+{
+}
+
+void StkUdpSocket :: setDestination( int port, std::string hostname )
+{
+  this->setAddress( &address_, port, hostname );
+  validAddress_ = true;
+}
+
+void StkUdpSocket :: setAddress( struct sockaddr_in *address, int port, std::string hostname )
+{
+  struct hostent *hostp;
+  if ( (hostp = gethostbyname( hostname.c_str() )) == 0 ) {
+    errorString_ << "UdpSocket::setAddress: unknown host (" << hostname << ")!";
+    handleError( StkError::PROCESS_SOCKET_IPADDR );
+  }
+
+  // Fill in the address structure
+  address->sin_family = AF_INET;
+  memcpy((void *)&address->sin_addr, hostp->h_addr, hostp->h_length);
+  address->sin_port = htons( port );
+}
+
+int StkUdpSocket :: writeBuffer( const void *buffer, long bufferSize, int flags )
+{
+  if ( !isValid( soket_ ) || !validAddress_ ) return -1;
+  return sendto( soket_, (const char *)buffer, bufferSize, flags, (struct sockaddr *)&address_, sizeof(address_) );
+}
+
+int StkUdpSocket :: readBuffer( void *buffer, long bufferSize, int flags )
+{
+  if ( !isValid( soket_ ) ) return -1;
+  return recvfrom( soket_, (char *)buffer, bufferSize, flags, NULL, NULL );
+}
+
+int StkUdpSocket :: writeBufferTo( const void *buffer, long bufferSize, int port, std::string hostname, int flags )
+{
+  if ( !isValid( soket_ ) ) return -1;
+  struct sockaddr_in address;
+  this->setAddress( &address, port, hostname );
+  return sendto( soket_, (const char *)buffer, bufferSize, flags, (struct sockaddr *)&address, sizeof(address) );
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/TapDelay.cpp b/lib/MoMu-STK-1.0.0/src/TapDelay.cpp
new file mode 100644 (file)
index 0000000..a519d46
--- /dev/null
@@ -0,0 +1,104 @@
+/***************************************************/
+/*! \class TapDelay
+    \brief STK non-interpolating tapped delay line class.
+
+    This class implements a non-interpolating digital delay-line with
+    an arbitrary number of output "taps".  If the maximum length and
+    tap delays are not specified during instantiation, a fixed maximum
+    length of 4095 and a single tap delay of zero is set.
+    
+    A non-interpolating delay line is typically used in fixed
+    delay-length applications, such as for reverberation.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "TapDelay.h"
+
+namespace stk {
+
+TapDelay :: TapDelay( std::vector<unsigned long> taps, unsigned long maxDelay )
+{
+  // Writing before reading allows delays from 0 to length-1. 
+  // If we want to allow a delay of maxDelay, we need a
+  // delayline of length = maxDelay+1.
+  if ( maxDelay < 1 ) {
+    errorString_ << "TapDelay::TapDelay: maxDelay must be > 0!\n";
+    handleError( StkError::FUNCTION_ARGUMENT );
+  }
+
+  for ( unsigned int i=0; i<taps.size(); i++ ) {
+    if ( taps[i] > maxDelay ) {
+      errorString_ << "TapDelay::TapDelay: maxDelay must be > than all tap delay values!\n";
+      handleError( StkError::FUNCTION_ARGUMENT );
+    }
+  }
+
+  if ( ( maxDelay + 1 ) > inputs_.size() )
+    inputs_.resize( maxDelay + 1, 1, 0.0 );
+
+  inPoint_ = 0;
+  this->setTapDelays( taps );
+}
+
+TapDelay :: ~TapDelay()
+{
+}
+
+void TapDelay :: setMaximumDelay( unsigned long delay )
+{
+  if ( delay < inputs_.size() ) return;
+
+  if ( delay < 0 ) {
+    errorString_ << "TapDelay::setMaximumDelay: argument (" << delay << ") less than zero!\n";
+    handleError( StkError::WARNING );
+    return;
+  }
+
+  for ( unsigned int i=0; i<delays_.size(); i++ ) {
+    if ( delay < delays_[i] ) {
+      errorString_ << "TapDelay::setMaximumDelay: argument (" << delay << ") less than a current tap delay setting (" << delays_[i] << ")!\n";
+      handleError( StkError::WARNING );
+      return;
+    }
+  }
+
+  inputs_.resize( delay + 1 );
+}
+
+void TapDelay :: setTapDelays( std::vector<unsigned long> taps )
+{
+  if ( taps.size() != outPoint_.size() ) {
+    outPoint_.resize( taps.size() );
+    delays_.resize( taps.size() );
+    lastFrame_.resize( 1, taps.size(), 0.0 );
+  }
+
+  for ( unsigned int i=0; i<taps.size(); i++ ) {
+    if ( taps[i] > inputs_.size() - 1 ) { // The value is too big.
+      errorString_ << "TapDelay::setTapDelay: argument (" << taps[i] << ") too big ... setting to maximum!\n";
+      handleError( StkError::WARNING );
+
+      // Force delay to maximum length.
+      outPoint_[i] = inPoint_ + 1;
+      if ( outPoint_[i] == inputs_.size() ) outPoint_[i] = 0;
+      delays_[i] = inputs_.size() - 1;
+    }
+    else if ( taps[i] < 0 ) {
+      errorString_ << "TapDelay::setDelay: argument (" << taps[i] << ") less than zero ... setting to zero!\n";
+      handleError( StkError::WARNING );
+
+      outPoint_[i] = inPoint_;
+      delays_[i] = 0;
+    }
+    else { // read chases write
+      if ( inPoint_ >= taps[i] ) outPoint_[i] = inPoint_ - taps[i];
+      else outPoint_[i] = inputs_.size() + inPoint_ - taps[i];
+      delays_[i] = taps[i];
+    }
+  }
+}
+
+} // stk namespace
+
diff --git a/lib/MoMu-STK-1.0.0/src/TcpClient.cpp b/lib/MoMu-STK-1.0.0/src/TcpClient.cpp
new file mode 100644 (file)
index 0000000..44e1999
--- /dev/null
@@ -0,0 +1,104 @@
+/***************************************************/
+/*! \class TcpClient
+    \brief STK TCP socket client class.
+
+    This class provides a uniform cross-platform TCP socket client
+    interface.  Methods are provided for reading or writing data
+    buffers to/from connections.
+
+    TCP sockets are reliable and connection-oriented.  A TCP socket
+    client must be connected to a TCP server before data can be sent
+    or received.  Data delivery is guaranteed in order, without loss,
+    error, or duplication.  That said, TCP transmissions tend to be
+    slower than those using the UDP protocol and data sent with
+    multiple \e write() calls can be arbitrarily combined by the
+    underlying system.
+
+    The user is responsible for checking the values
+    returned by the read/write methods.  Values
+    less than or equal to zero indicate a closed
+    or lost connection or the occurence of an error.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "TcpClient.h"
+#include <cstring>
+
+namespace stk {
+
+TcpClient :: TcpClient( int port, std::string hostname )
+{
+#if defined(__OS_WINDOWS__)  // windoze-only stuff
+  WSADATA wsaData;
+  WORD wVersionRequested = MAKEWORD(1,1);
+
+  WSAStartup( wVersionRequested, &wsaData );
+  if ( wsaData.wVersion != wVersionRequested ) {
+    errorString_ << "TcpClient: Incompatible Windows socket library version!";
+    handleError( StkError::PROCESS_SOCKET );
+  }
+#endif
+
+  // Create a socket client connection.
+  connect( port, hostname );
+}
+
+TcpClient :: ~TcpClient( void )
+{
+}
+
+int TcpClient :: connect( int port, std::string hostname )
+{
+  // Close any existing connections.
+  this->close( soket_ );
+
+  // Create the client-side socket
+  soket_ = ::socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
+  if ( soket_ < 0 ) {
+    errorString_ << "TcpClient: Couldn't create socket client!";
+    handleError( StkError::PROCESS_SOCKET );
+  }
+
+  int flag = 1;
+  int result = setsockopt( soket_, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int) );
+  if ( result < 0 ) {
+    errorString_ << "TcpClient: Error setting socket options!";
+    handleError( StkError::PROCESS_SOCKET );
+  }
+
+  struct hostent *hostp;
+  if ( ( hostp = gethostbyname( hostname.c_str() ) ) == 0 ) {
+    errorString_ << "TcpClient: unknown host (" << hostname << ")!";
+    handleError( StkError::PROCESS_SOCKET_IPADDR );
+  }
+
+  // Fill in the address structure
+  struct sockaddr_in server_address;
+  server_address.sin_family = AF_INET;
+  memcpy( (void *)&server_address.sin_addr, hostp->h_addr, hostp->h_length );
+  server_address.sin_port = htons(port);
+
+  // Connect to the server
+  if ( ::connect( soket_, (struct sockaddr *)&server_address, sizeof(server_address) ) < 0 ) {
+    errorString_ << "TcpClient: Couldn't connect to socket server!";
+    handleError( StkError::PROCESS_SOCKET );
+  }
+
+  return soket_;
+}
+
+int TcpClient :: writeBuffer( const void *buffer, long bufferSize, int flags )
+{
+  if ( !isValid( soket_ ) ) return -1;
+  return send( soket_, (const char *)buffer, bufferSize, flags );
+}
+
+int TcpClient :: readBuffer( void *buffer, long bufferSize, int flags )
+{
+  if ( !isValid( soket_ ) ) return -1;
+  return recv( soket_, (char *)buffer, bufferSize, flags );
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/TcpServer.cpp b/lib/MoMu-STK-1.0.0/src/TcpServer.cpp
new file mode 100644 (file)
index 0000000..7ae930f
--- /dev/null
@@ -0,0 +1,99 @@
+/***************************************************/
+/*! \class TcpServer
+    \brief STK TCP socket server class.
+
+    This class provides a uniform cross-platform TCP socket server
+    interface.  Methods are provided for reading or writing data
+    buffers to/from connections.
+
+    TCP sockets are reliable and connection-oriented.  A TCP socket
+    server must accept a connection from a TCP client before data can
+    be sent or received.  Data delivery is guaranteed in order,
+    without loss, error, or duplication.  That said, TCP transmissions
+    tend to be slower than those using the UDP protocol and data sent
+    with multiple \e write() calls can be arbitrarily combined by the
+    underlying system.
+
+    The user is responsible for checking the values
+    returned by the read/write methods.  Values
+    less than or equal to zero indicate a closed
+    or lost connection or the occurence of an error.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "TcpServer.h"
+
+namespace stk {
+
+TcpServer :: TcpServer( int port )
+{
+  // Create a socket server.
+#if defined(__OS_WINDOWS__)  // windoze-only stuff
+  WSADATA wsaData;
+  WORD wVersionRequested = MAKEWORD(1,1);
+
+  WSAStartup(wVersionRequested, &wsaData);
+  if (wsaData.wVersion != wVersionRequested) {
+    errorString_ << "TcpServer: Incompatible Windows socket library version!";
+    handleError( StkError::PROCESS_SOCKET );
+  }
+#endif
+
+  // Create the server-side socket
+  soket_ = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+  if (soket_ < 0) {
+    errorString_ << "TcpServer: Couldn't create socket server!";
+    handleError( StkError::PROCESS_SOCKET );
+  }
+
+  int flag = 1;
+  int result = setsockopt( soket_, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int) );
+  if (result < 0) {
+    errorString_ << "TcpServer: Error setting socket options!";
+    handleError( StkError::PROCESS_SOCKET );
+  }
+
+  struct sockaddr_in address;
+  address.sin_family = AF_INET;
+  address.sin_addr.s_addr = INADDR_ANY;
+  address.sin_port = htons( port );
+
+  // Bind socket to the appropriate port and interface (INADDR_ANY)
+  if ( bind( soket_, (struct sockaddr *)&address, sizeof(address) ) < 0 ) {
+    errorString_ << "TcpServer: Couldn't bind socket!";
+    handleError( StkError::PROCESS_SOCKET );
+  }
+
+  // Listen for incoming connection(s)
+  if ( listen( soket_, 1 ) < 0 ) {
+    errorString_ << "TcpServer: Couldn't start server listening!";
+    handleError( StkError::PROCESS_SOCKET );
+  }
+
+  port_ = port;
+}
+
+TcpServer :: ~TcpServer()
+{
+}
+
+int TcpServer :: accept( void )
+{
+  return ::accept( soket_, NULL, NULL );
+}
+
+int TcpServer :: writeBuffer(const void *buffer, long bufferSize, int flags )
+{
+  if ( !isValid( soket_ ) ) return -1;
+  return send( soket_, (const char *)buffer, bufferSize, flags );
+}
+
+int TcpServer :: readBuffer(void *buffer, long bufferSize, int flags )
+{
+  if ( !isValid( soket_ ) ) return -1;
+  return recv( soket_, (char *)buffer, bufferSize, flags );
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/Thread.cpp b/lib/MoMu-STK-1.0.0/src/Thread.cpp
new file mode 100644 (file)
index 0000000..dc1a473
--- /dev/null
@@ -0,0 +1,106 @@
+/***************************************************/
+/*! \class Thread
+    \brief STK thread class.
+
+    This class provides a uniform interface for cross-platform
+    threads.  On unix systems, the pthread library is used.  Under
+    Windows, the C runtime threadex functions are used.
+
+    Each instance of the Thread class can be used to control a single
+    thread process.  Routines are provided to signal cancelation
+    and/or joining with a thread, though it is not possible for this
+    class to know the running status of a thread once it is started.
+
+    For cross-platform compatability, thread functions should be
+    declared as follows:
+
+    THREAD_RETURN THREAD_TYPE thread_function(void *ptr)
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "Thread.h"
+
+namespace stk {
+
+Thread :: Thread()
+{
+  thread_ = 0;
+}
+
+Thread :: ~Thread()
+{
+}
+
+bool Thread :: start( THREAD_FUNCTION routine, void * ptr )
+{
+  if ( thread_ ) {
+    errorString_ << "Thread:: a thread is already running!";
+    handleError( StkError::WARNING );
+    return false;
+  }
+
+#if (defined(__OS_IRIX__) || defined(__OS_LINUX__) || defined(__OS_MACOSX__))
+
+  if ( pthread_create(&thread_, NULL, *routine, ptr) == 0 )
+    return true;
+
+#elif defined(__OS_WINDOWS__)
+  unsigned thread_id;
+  thread_ = _beginthreadex(NULL, 0, routine, ptr, 0, &thread_id);
+  if ( thread_ ) return true;
+
+#endif
+  return false;
+}
+
+bool Thread :: cancel()
+{
+#if (defined(__OS_IRIX__) || defined(__OS_LINUX__) || defined(__OS_MACOSX__))
+
+  if ( pthread_cancel(thread_) == 0 ) {
+    return true;
+  }
+
+#elif defined(__OS_WINDOWS__)
+
+  TerminateThread((HANDLE)thread_, 0);
+  return true;
+
+#endif
+  return false;
+}
+
+bool Thread :: wait()
+{
+#if (defined(__OS_IRIX__) || defined(__OS_LINUX__) || defined(__OS_MACOSX__))
+
+  if ( pthread_join(thread_, NULL) == 0 ) {
+    thread_ = 0;
+    return true;
+  }
+
+#elif defined(__OS_WINDOWS__)
+
+  long retval = WaitForSingleObject( (HANDLE)thread_, INFINITE );
+  if ( retval == WAIT_OBJECT_0 ) {
+    CloseHandle( (HANDLE)thread_ );
+    thread_ = 0;
+    return true;
+  }
+
+#endif
+  return false;
+}
+
+void Thread :: testCancel(void)
+{
+#if (defined(__OS_IRIX__) || defined(__OS_LINUX__) || defined(__OS_MACOSX__))
+
+  pthread_testcancel();
+
+#endif
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/TubeBell.cpp b/lib/MoMu-STK-1.0.0/src/TubeBell.cpp
new file mode 100644 (file)
index 0000000..e534574
--- /dev/null
@@ -0,0 +1,83 @@
+/***************************************************/
+/*! \class TubeBell
+    \brief STK tubular bell (orchestral chime) FM
+           synthesis instrument.
+
+    This class implements two simple FM Pairs
+    summed together, also referred to as algorithm
+    5 of the TX81Z.
+
+    \code
+    Algorithm 5 is :  4->3--\
+                             + --> Out
+                      2->1--/
+    \endcode
+
+    Control Change Numbers: 
+       - Modulator Index One = 2
+       - Crossfade of Outputs = 4
+       - LFO Speed = 11
+       - LFO Depth = 1
+       - ADSR 2 & 4 Target = 128
+
+    The basic Chowning/Stanford FM patent expired
+    in 1995, but there exist follow-on patents,
+    mostly assigned to Yamaha.  If you are of the
+    type who should worry about this (making
+    money) worry away.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "TubeBell.h"
+
+namespace stk {
+
+TubeBell :: TubeBell( void )
+  : FM()
+{
+  // Concatenate the STK rawwave path to the rawwave files
+  for ( unsigned int i=0; i<3; i++ )
+    waves_[i] = new FileLoop( (Stk::rawwavePath() + "sinewave.raw").c_str(), true );
+  waves_[3] = new FileLoop( (Stk::rawwavePath() + "fwavblnk.raw").c_str(), true );
+
+  this->setRatio(0, 1.0   * 0.995);
+  this->setRatio(1, 1.414 * 0.995);
+  this->setRatio(2, 1.0   * 1.005);
+  this->setRatio(3, 1.414 * 1.000);
+
+  gains_[0] = fmGains_[94];
+  gains_[1] = fmGains_[76];
+  gains_[2] = fmGains_[99];
+  gains_[3] = fmGains_[71];
+
+  adsr_[0]->setAllTimes( 0.005, 4.0, 0.0, 0.04);
+  adsr_[1]->setAllTimes( 0.005, 4.0, 0.0, 0.04);
+  adsr_[2]->setAllTimes( 0.001, 2.0, 0.0, 0.04);
+  adsr_[3]->setAllTimes( 0.004, 4.0, 0.0, 0.04);
+
+  twozero_.setGain( 0.5 );
+  vibrato_.setFrequency( 2.0 );
+}  
+
+TubeBell :: ~TubeBell( void )
+{
+}
+
+void TubeBell :: noteOn( StkFloat frequency, StkFloat amplitude )
+{
+  gains_[0] = amplitude * fmGains_[94];
+  gains_[1] = amplitude * fmGains_[76];
+  gains_[2] = amplitude * fmGains_[99];
+  gains_[3] = amplitude * fmGains_[71];
+  this->setFrequency( frequency );
+  this->keyOn();
+
+#if defined(_STK_DEBUG_)
+  errorString_ << "TubeBell::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << '.';
+  handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/TwoPole.cpp b/lib/MoMu-STK-1.0.0/src/TwoPole.cpp
new file mode 100644 (file)
index 0000000..b8ab30d
--- /dev/null
@@ -0,0 +1,65 @@
+/***************************************************/
+/*! \class TwoPole
+    \brief STK two-pole filter class.
+
+    This class implements a two-pole digital filter.  A method is
+    provided for creating a resonance in the frequency response while
+    maintaining a nearly constant filter gain.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "TwoPole.h"
+#include <cmath>
+
+namespace stk {
+
+TwoPole :: TwoPole( void )
+{
+  b_.resize( 1 );
+  a_.resize( 3 );
+  inputs_.resize( 1, 1, 0.0 );
+  outputs_.resize( 3, 1, 0.0 );
+  b_[0] = 1.0;
+  a_[0] = 1.0;
+
+  Stk::addSampleRateAlert( this );
+}
+
+TwoPole :: ~TwoPole()
+{
+  Stk::removeSampleRateAlert( this );
+}
+
+void TwoPole :: sampleRateChanged( StkFloat newRate, StkFloat oldRate )
+{
+  if ( !ignoreSampleRateChange_ ) {
+    errorString_ << "TwoPole::sampleRateChanged: you may need to recompute filter coefficients!";
+    handleError( StkError::WARNING );
+  }
+}
+
+void TwoPole :: setResonance( StkFloat frequency, StkFloat radius, bool normalize )
+{
+  a_[2] = radius * radius;
+  a_[1] = (StkFloat) -2.0 * radius * cos(TWO_PI * frequency / Stk::sampleRate());
+
+  if ( normalize ) {
+    // Normalize the filter gain ... not terribly efficient.
+    StkFloat real = 1 - radius + (a_[2] - radius) * cos(TWO_PI * 2 * frequency / Stk::sampleRate());
+    StkFloat imag = (a_[2] - radius) * sin(TWO_PI * 2 * frequency / Stk::sampleRate());
+    b_[0] = sqrt( pow(real, 2) + pow(imag, 2) );
+  }
+}
+
+void TwoPole :: setCoefficients( StkFloat b0, StkFloat a1, StkFloat a2, bool clearState )
+{
+  b_[0] = b0;
+  a_[1] = a1;
+  a_[2] = a2;
+
+  if ( clearState ) this->clear();
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/TwoZero.cpp b/lib/MoMu-STK-1.0.0/src/TwoZero.cpp
new file mode 100644 (file)
index 0000000..e3ed25b
--- /dev/null
@@ -0,0 +1,63 @@
+/***************************************************/
+/*! \class TwoZero
+    \brief STK two-zero filter class.
+
+    This class implements a two-zero digital filter.  A method is
+    provided for creating a "notch" in the frequency response while
+    maintaining a constant filter gain.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "TwoZero.h"
+#include <cmath>
+
+namespace stk {
+
+TwoZero :: TwoZero( void )
+{
+  b_.resize( 3, 0.0 );
+  inputs_.resize( 3, 1, 0.0 );
+  b_[0] = 1.0;
+
+  Stk::addSampleRateAlert( this );
+}
+
+TwoZero :: ~TwoZero()
+{
+  Stk::removeSampleRateAlert( this );
+}
+
+void TwoZero :: sampleRateChanged( StkFloat newRate, StkFloat oldRate )
+{
+  if ( !ignoreSampleRateChange_ ) {
+    errorString_ << "TwoZero::sampleRateChanged: you may need to recompute filter coefficients!";
+    handleError( StkError::WARNING );
+  }
+}
+
+void TwoZero :: setCoefficients( StkFloat b0, StkFloat b1, StkFloat b2, bool clearState )
+{
+  b_[0] = b0;
+  b_[1] = b1;
+  b_[2] = b2;
+
+  if ( clearState ) this->clear();
+}
+
+void TwoZero :: setNotch( StkFloat frequency, StkFloat radius )
+{
+  b_[2] = radius * radius;
+  b_[1] = (StkFloat) -2.0 * radius * cos(TWO_PI * (double) frequency / Stk::sampleRate());
+
+  // Normalize the filter gain.
+  if ( b_[1] > 0.0 ) // Maximum at z = 0.
+    b_[0] = 1.0 / ( 1.0 + b_[1] + b_[2] );
+  else            // Maximum at z = -1.
+    b_[0] = 1.0 / ( 1.0 - b_[1] + b_[2] );
+  b_[1] *= b_[0];
+  b_[2] *= b_[0];
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/VoicForm.cpp b/lib/MoMu-STK-1.0.0/src/VoicForm.cpp
new file mode 100644 (file)
index 0000000..8d40c3d
--- /dev/null
@@ -0,0 +1,201 @@
+/***************************************************/
+/*! \class VoicForm
+    \brief Four formant synthesis instrument.
+
+    This instrument contains an excitation singing
+    wavetable (looping wave with random and
+    periodic vibrato, smoothing on frequency,
+    etc.), excitation noise, and four sweepable
+    complex resonances.
+
+    Measured formant data is included, and enough
+    data is there to support either parallel or
+    cascade synthesis.  In the floating point case
+    cascade synthesis is the most natural so
+    that's what you'll find here.
+
+    Control Change Numbers: 
+       - Voiced/Unvoiced Mix = 2
+       - Vowel/Phoneme Selection = 4
+       - Vibrato Frequency = 11
+       - Vibrato Gain = 1
+       - Loudness (Spectral Tilt) = 128
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "VoicForm.h"
+#include "Phonemes.h"
+#include "Skini_msg.h"
+#include <cstring>
+#include <cmath>
+
+namespace stk {
+
+VoicForm :: VoicForm( void ) : Instrmnt()
+{
+  // Concatenate the STK rawwave path to the rawwave file
+  voiced_ = new SingWave( (Stk::rawwavePath() + "impuls20.raw").c_str(), true );
+  voiced_->setGainRate( 0.001 );
+  voiced_->setGainTarget( 0.0 );
+
+  for ( int i=0; i<4; i++ )
+    filters_[i].setSweepRate( 0.001 );
+    
+  onezero_.setZero( -0.9 );
+  onepole_.setPole( 0.9 );
+    
+  noiseEnv_.setRate( 0.001 );
+  noiseEnv_.setTarget( 0.0 );
+    
+  this->setPhoneme( "eee" );
+  this->clear();
+}  
+
+VoicForm :: ~VoicForm( void )
+{
+  delete voiced_;
+}
+
+void VoicForm :: clear( void )
+{
+  onezero_.clear();
+  onepole_.clear();
+  for ( int i=0; i<4; i++ ) {
+    filters_[i].clear();
+  }
+}
+
+void VoicForm :: setFrequency( StkFloat frequency )
+{
+  StkFloat freakency = frequency;
+  if ( frequency <= 0.0 ) {
+    errorString_ << "VoicForm::setFrequency: parameter is less than or equal to zero!";
+    handleError( StkError::WARNING );
+    freakency = 220.0;
+  }
+
+  voiced_->setFrequency( freakency );
+}
+
+bool VoicForm :: setPhoneme( const char *phoneme )
+{
+  bool found = false;
+  unsigned int i = 0;
+  while( i < 32 && !found ) {
+    if ( !strcmp( Phonemes::name(i), phoneme ) ) {
+      found = true;
+      filters_[0].setTargets( Phonemes::formantFrequency(i, 0), Phonemes::formantRadius(i, 0), pow(10.0, Phonemes::formantGain(i, 0 ) / 20.0) );
+      filters_[1].setTargets( Phonemes::formantFrequency(i, 1), Phonemes::formantRadius(i, 1), pow(10.0, Phonemes::formantGain(i, 1 ) / 20.0) );
+      filters_[2].setTargets( Phonemes::formantFrequency(i, 2), Phonemes::formantRadius(i, 2), pow(10.0, Phonemes::formantGain(i, 2 ) / 20.0) );
+      filters_[3].setTargets( Phonemes::formantFrequency(i, 3), Phonemes::formantRadius(i, 3), pow(10.0, Phonemes::formantGain(i, 3 ) / 20.0) );
+      this->setVoiced( Phonemes::voiceGain( i ) );
+      this->setUnVoiced( Phonemes::noiseGain( i ) );
+#if defined(_STK_DEBUG_)
+      errorString_ << "VoicForm::setPhoneme: found formant " << phoneme << " (number " << i << ").";
+      handleError( StkError::DEBUG_WARNING );
+#endif
+    }
+    i++;
+  }
+
+  if ( !found ) {
+    errorString_ << "VoicForm::setPhoneme: phoneme " << phoneme << " not found!";
+    handleError( StkError::WARNING );
+  }
+
+  return found;
+}
+
+void VoicForm :: setFilterSweepRate( unsigned int whichOne, StkFloat rate )
+{
+  if ( whichOne < 0 || whichOne > 3 ) {
+    errorString_ << "VoicForm::setFilterSweepRate: filter select argument outside range 0-3!";
+    handleError( StkError::WARNING );
+    return;
+  }
+
+  filters_[whichOne].setSweepRate(rate);
+}
+
+void VoicForm :: quiet( void )
+{
+  voiced_->noteOff();
+  noiseEnv_.setTarget( 0.0 );
+}
+
+void VoicForm :: noteOn( StkFloat frequency, StkFloat amplitude )
+{
+  this->setFrequency( frequency );
+  voiced_->setGainTarget( amplitude );
+  onepole_.setPole( 0.97 - (amplitude * 0.2) );
+}
+
+void VoicForm :: controlChange( int number, StkFloat value )
+{
+  StkFloat norm = value * ONE_OVER_128;
+  if ( norm < 0 ) {
+    norm = 0.0;
+    errorString_ << "VoicForm::controlChange: control value less than zero ... setting to zero!";
+    handleError( StkError::WARNING );
+  }
+  else if ( norm > 1.0 ) {
+    norm = 1.0;
+    errorString_ << "VoicForm::controlChange: control value greater than 128.0 ... setting to 128.0!";
+    handleError( StkError::WARNING );
+  }
+
+  if (number == __SK_Breath_)  { // 2
+    this->setVoiced( 1.0 - norm );
+    this->setUnVoiced( 0.01 * norm );
+  }
+  else if (number == __SK_FootControl_)        { // 4
+    StkFloat temp = 0.0;
+    unsigned int i = (int) value;
+    if (i < 32)        {
+      temp = 0.9;
+    }
+    else if (i < 64)   {
+      i -= 32;
+      temp = 1.0;
+    }
+    else if (i < 96)   {
+      i -= 64;
+      temp = 1.1;
+    }
+    else if (i < 128)  {
+      i -= 96;
+      temp = 1.2;
+    }
+    else if (i == 128) {
+      i = 0;
+      temp = 1.4;
+    }
+    filters_[0].setTargets( temp * Phonemes::formantFrequency(i, 0), Phonemes::formantRadius(i, 0), pow(10.0, Phonemes::formantGain(i, 0 ) / 20.0) );
+    filters_[1].setTargets( temp * Phonemes::formantFrequency(i, 1), Phonemes::formantRadius(i, 1), pow(10.0, Phonemes::formantGain(i, 1 ) / 20.0) );
+    filters_[2].setTargets( temp * Phonemes::formantFrequency(i, 2), Phonemes::formantRadius(i, 2), pow(10.0, Phonemes::formantGain(i, 2 ) / 20.0) );
+    filters_[3].setTargets( temp * Phonemes::formantFrequency(i, 3), Phonemes::formantRadius(i, 3), pow(10.0, Phonemes::formantGain(i, 3 ) / 20.0) );
+    this->setVoiced( Phonemes::voiceGain( i ) );
+    this->setUnVoiced( Phonemes::noiseGain( i ) );
+  }
+  else if (number == __SK_ModFrequency_) // 11
+    voiced_->setVibratoRate( norm * 12.0);  // 0 to 12 Hz
+  else if (number == __SK_ModWheel_) // 1
+    voiced_->setVibratoGain( norm * 0.2);
+  else if (number == __SK_AfterTouch_Cont_)    { // 128
+    this->setVoiced( norm );
+    onepole_.setPole( 0.97 - ( norm * 0.2) );
+  }
+  else {
+    errorString_ << "VoicForm::controlChange: undefined control number (" << number << ")!";
+    handleError( StkError::WARNING );
+  }
+
+#if defined(_STK_DEBUG_)
+  errorString_ << "VoicForm::controlChange: number = " << number << ", value = " << value << '.';
+  handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/Voicer.cpp b/lib/MoMu-STK-1.0.0/src/Voicer.cpp
new file mode 100644 (file)
index 0000000..bf8549c
--- /dev/null
@@ -0,0 +1,219 @@
+/***************************************************/
+/*! \class Voicer
+    \brief STK voice manager class.
+
+    This class can be used to manage a group of STK instrument
+    classes.  Individual voices can be controlled via unique note
+    tags.  Instrument groups can be controlled by group number.
+
+    A previously constructed STK instrument class is linked with a
+    voice manager using the addInstrument() function.  An optional
+    group number argument can be specified to the addInstrument()
+    function as well (default group = 0).  The voice manager does not
+    delete any instrument instances ... it is the responsibility of
+    the user to allocate and deallocate all instruments.
+
+    The tick() function returns the mix of all sounding voices.  Each
+    noteOn returns a unique tag (credits to the NeXT MusicKit), so you
+    can send control changes to specific voices within an ensemble.
+    Alternately, control changes can be sent to all voices in a given
+    group.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "Voicer.h"
+#include <cmath>
+
+namespace stk {
+
+Voicer :: Voicer( StkFloat decayTime )
+{
+  tags_ = 23456;
+  muteTime_ = (int) ( decayTime * Stk::sampleRate() );
+  lastFrame_.resize( 1, 1, 0.0 );
+}
+
+void Voicer :: addInstrument( Instrmnt *instrument, int group )
+{
+  Voicer::Voice voice;
+  voice.instrument = instrument;
+  voice.group = group;
+  voice.noteNumber = -1;
+  voices_.push_back( voice );
+
+  // Check output channels and resize lastFrame_ if necessary.
+  if ( instrument->channelsOut() > lastFrame_.channels() ) {
+    unsigned int startChannel = lastFrame_.channels();
+    lastFrame_.resize( 1, instrument->channelsOut() );
+    for ( unsigned int i=startChannel; i<lastFrame_.size(); i++ )
+      lastFrame_[i] = 0.0;
+  }
+}
+
+void Voicer :: removeInstrument( Instrmnt *instrument )
+{
+  bool found = false;
+  std::vector< Voicer::Voice >::iterator i;
+  for ( i=voices_.begin(); i!=voices_.end(); ++i ) {
+    if ( (*i).instrument != instrument ) continue;
+    voices_.erase( i );
+    found = true;
+    break;
+  }
+
+  if ( found ) {
+    // Check output channels and resize lastFrame_ if necessary.
+    unsigned int maxChannels = 1;
+    for ( i=voices_.begin(); i!=voices_.end(); ++i ) {
+      if ( (*i).instrument->channelsOut() > maxChannels ) maxChannels = (*i).instrument->channelsOut();
+    }
+    if ( maxChannels < lastFrame_.channels() )
+      lastFrame_.resize( 1, maxChannels );
+  }
+  else {
+    errorString_ << "Voicer::removeInstrument: instrument pointer not found in current voices!";
+    handleError( StkError::WARNING );
+  }
+}
+
+long Voicer :: noteOn(StkFloat noteNumber, StkFloat amplitude, int group )
+{
+  unsigned int i;
+  StkFloat frequency = (StkFloat) 220.0 * pow( 2.0, (noteNumber - 57.0) / 12.0 );
+  for ( i=0; i<voices_.size(); i++ ) {
+    if (voices_[i].noteNumber < 0 && voices_[i].group == group) {
+      voices_[i].tag = tags_++;
+      voices_[i].group = group;
+      voices_[i].noteNumber = noteNumber;
+      voices_[i].frequency = frequency;
+      voices_[i].instrument->noteOn( frequency, amplitude * ONE_OVER_128 );
+      voices_[i].sounding = 1;
+      return voices_[i].tag;
+    }
+  }
+
+  // All voices are sounding, so interrupt the oldest voice.
+  int voice = -1;
+  for ( i=0; i<voices_.size(); i++ ) {
+    if ( voices_[i].group == group ) {
+      if ( voice == -1 ) voice = i;
+      else if ( voices_[i].tag < voices_[voice].tag ) voice = (int) i;
+    }
+  }
+
+  if ( voice >= 0 ) {
+    voices_[voice].tag = tags_++;
+    voices_[voice].group = group;
+    voices_[voice].noteNumber = noteNumber;
+    voices_[voice].frequency = frequency;
+    voices_[voice].instrument->noteOn( frequency, amplitude * ONE_OVER_128 );
+    voices_[voice].sounding = 1;
+    return voices_[voice].tag;
+  }
+
+  return -1;
+}
+
+void Voicer :: noteOff( StkFloat noteNumber, StkFloat amplitude, int group )
+{
+  for ( unsigned int i=0; i<voices_.size(); i++ ) {
+    if ( voices_[i].noteNumber == noteNumber && voices_[i].group == group ) {
+      voices_[i].instrument->noteOff( amplitude * ONE_OVER_128 );
+      voices_[i].sounding = -muteTime_;
+    }
+  }
+}
+
+void Voicer :: noteOff( long tag, StkFloat amplitude )
+{
+  for ( unsigned int i=0; i<voices_.size(); i++ ) {
+    if ( voices_[i].tag == tag ) {
+      voices_[i].instrument->noteOff( amplitude * ONE_OVER_128 );
+      voices_[i].sounding = -muteTime_;
+      break;
+    }
+  }
+}
+
+void Voicer :: setFrequency( StkFloat noteNumber, int group )
+{
+  StkFloat frequency = (StkFloat) 220.0 * pow( 2.0, (noteNumber - 57.0) / 12.0 );
+  for ( unsigned int i=0; i<voices_.size(); i++ ) {
+    if ( voices_[i].group == group ) {
+      voices_[i].noteNumber = noteNumber;
+      voices_[i].frequency = frequency;
+      voices_[i].instrument->setFrequency( frequency );
+    }
+  }
+}
+
+void Voicer :: setFrequency( long tag, StkFloat noteNumber )
+{
+  StkFloat frequency = (StkFloat) 220.0 * pow( 2.0, (noteNumber - 57.0) / 12.0 );
+  for ( unsigned int i=0; i<voices_.size(); i++ ) {
+    if ( voices_[i].tag == tag ) {
+      voices_[i].noteNumber = noteNumber;
+      voices_[i].frequency = frequency;
+      voices_[i].instrument->setFrequency( frequency );
+      break;
+    }
+  }
+}
+
+void Voicer :: pitchBend( StkFloat value, int group )
+{
+  StkFloat pitchScaler;
+  if ( value < 8192.0 )
+    pitchScaler = pow( 0.5, (8192.0-value) / 8192.0 );
+  else
+    pitchScaler = pow( 2.0, (value-8192.0) / 8192.0 );
+  for ( unsigned int i=0; i<voices_.size(); i++ ) {
+    if ( voices_[i].group == group )
+      voices_[i].instrument->setFrequency( (StkFloat) (voices_[i].frequency * pitchScaler) );
+  }
+}
+
+void Voicer :: pitchBend( long tag, StkFloat value )
+{
+  StkFloat pitchScaler;
+  if ( value < 8192.0 )
+    pitchScaler = pow( 0.5, (8192.0-value) / 8192.0 );
+  else
+    pitchScaler = pow( 2.0, (value-8192.0) / 8192.0 );
+  for ( unsigned int i=0; i<voices_.size(); i++ ) {
+    if ( voices_[i].tag == tag ) {
+      voices_[i].instrument->setFrequency( (StkFloat) (voices_[i].frequency * pitchScaler) );
+      break;
+    }
+  }
+}
+
+void Voicer :: controlChange( int number, StkFloat value, int group )
+{
+  for ( unsigned int i=0; i<voices_.size(); i++ ) {
+    if ( voices_[i].group == group )
+      voices_[i].instrument->controlChange( number, value );
+  }
+}
+
+void Voicer :: controlChange( long tag, int number, StkFloat value )
+{
+  for ( unsigned int i=0; i<voices_.size(); i++ ) {
+    if ( voices_[i].tag == tag ) {
+      voices_[i].instrument->controlChange( number, value );
+      break;
+    }
+  }
+}
+
+void Voicer :: silence( void )
+{
+  for ( unsigned int i=0; i<voices_.size(); i++ ) {
+    if ( voices_[i].sounding > 0 )
+      voices_[i].instrument->noteOff( 0.5 );
+  }
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/Whistle.cpp b/lib/MoMu-STK-1.0.0/src/Whistle.cpp
new file mode 100644 (file)
index 0000000..257f072
--- /dev/null
@@ -0,0 +1,262 @@
+/***************************************************/
+/*! \class Whistle
+    \brief STK police/referee whistle instrument class.
+
+    This class implements a hybrid physical/spectral
+    model of a police whistle (a la Cook).
+
+    Control Change Numbers: 
+       - Noise Gain = 4
+       - Fipple Modulation Frequency = 11
+       - Fipple Modulation Gain = 1
+       - Blowing Frequency Modulation = 2
+       - Volume = 128
+
+    by Perry R. Cook  1996 - 2010.
+*/
+/***************************************************/
+
+#include "Whistle.h"
+#include "Skini_msg.h"
+#include <cmath>
+
+namespace stk {
+
+const int CAN_RADIUS = 100;
+const int PEA_RADIUS = 30;
+const int BUMP_RADIUS = 5;
+
+const StkFloat NORM_CAN_LOSS = 0.97;
+const StkFloat SLOW_CAN_LOSS = 0.90;
+const StkFloat GRAVITY = 20.0;
+
+const StkFloat NORM_TICK_SIZE = 0.004;
+const StkFloat SLOW_TICK_SIZE = 0.0001;
+
+const StkFloat ENV_RATE = 0.001;
+
+Whistle :: Whistle( void )
+{
+  sine_.setFrequency( 2800.0 );
+
+  can_.setRadius( CAN_RADIUS );
+  can_.setPosition(0, 0, 0); // set can location
+  can_.setVelocity(0, 0, 0); // and the velocity
+
+  onepole_.setPole(0.95);  // 0.99
+
+  bumper_.setRadius( BUMP_RADIUS );
+  bumper_.setPosition(0.0, CAN_RADIUS-BUMP_RADIUS, 0);
+  bumper_.setPosition(0.0, CAN_RADIUS-BUMP_RADIUS, 0);
+
+  pea_.setRadius( PEA_RADIUS );
+  pea_.setPosition(0, CAN_RADIUS/2, 0);
+  pea_.setVelocity(35, 15, 0);
+
+  envelope_.setRate( ENV_RATE );
+  envelope_.keyOn();
+
+  fippleFreqMod_ = 0.5;
+  fippleGainMod_ = 0.5;
+  blowFreqMod_ = 0.25;
+  noiseGain_ = 0.125;
+  baseFrequency_ = 2000;
+
+  tickSize_ = NORM_TICK_SIZE;
+  canLoss_ = NORM_CAN_LOSS;
+
+  subSample_ = 1;
+  subSampCount_ = subSample_;
+}
+
+Whistle :: ~Whistle( void )
+{
+#ifdef WHISTLE_ANIMATION
+  printf("Exit, Whistle bye bye!!\n");
+#endif
+}
+
+void Whistle :: clear( void )
+{
+}
+
+void Whistle :: setFrequency( StkFloat frequency )
+{
+  StkFloat freakency = frequency * 4;  // the whistle is a transposing instrument
+  if ( frequency <= 0.0 ) {
+    errorString_ << "Whistle::setFrequency: parameter is less than or equal to zero!";
+    handleError( StkError::WARNING );
+    freakency = 220.0;
+  }
+
+  baseFrequency_ = freakency;
+}
+
+void Whistle :: startBlowing( StkFloat amplitude, StkFloat rate )
+{
+  envelope_.setRate( ENV_RATE );
+  envelope_.setTarget( amplitude );
+}
+
+void Whistle :: stopBlowing( StkFloat rate )
+{
+  envelope_.setRate( rate );
+  envelope_.keyOff();
+}
+
+void Whistle :: noteOn( StkFloat frequency, StkFloat amplitude )
+{
+  this->setFrequency( frequency );
+  this->startBlowing( amplitude*2.0 ,amplitude * 0.2 );
+#if defined(_STK_DEBUG_)
+  errorString_ << "Whistle::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << '.';
+  handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+void Whistle :: noteOff( StkFloat amplitude )
+{
+  this->stopBlowing( amplitude * 0.02 );
+
+#if defined(_STK_DEBUG_)
+  errorString_ << "Whistle::NoteOff: amplitude = " << amplitude << '.';
+  handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+int frameCount = 0;
+
+StkFloat Whistle :: tick( unsigned int )
+{
+  StkFloat soundMix, tempFreq;
+  StkFloat envOut = 0, temp, temp1, temp2, tempX, tempY;
+  double phi, cosphi, sinphi;
+  double gain = 0.5, mod = 0.0;
+
+  if ( --subSampCount_ <= 0 )  {
+    tempVectorP_ = pea_.getPosition();
+    subSampCount_ = subSample_;
+    temp = bumper_.isInside( tempVectorP_ );
+#ifdef WHISTLE_ANIMATION
+    frameCount += 1;
+    if ( frameCount >= (1470 / subSample_) ) {
+      frameCount = 0;
+      printf("%f %f %f\n",tempVectorP_->getX(),tempVectorP_->getY(),envOut);
+      fflush(stdout);
+    }
+#endif
+    envOut = envelope_.tick();
+
+    if (temp < (BUMP_RADIUS + PEA_RADIUS)) {
+      tempX = envOut * tickSize_ * 2000 * noise_.tick();
+      tempY = -envOut * tickSize_ * 1000 * (1.0 + noise_.tick());
+      pea_.addVelocity( tempX, tempY, 0 ); 
+      pea_.tick( tickSize_ );
+    }
+
+    mod  = exp(-temp * 0.01);    // exp. distance falloff of fipple/pea effect
+    temp = onepole_.tick(mod); // smooth it a little
+    gain = (1.0 - (fippleGainMod_*0.5)) + (2.0 * fippleGainMod_ * temp);
+    gain *= gain;                    // squared distance/gain
+    //    tempFreq = 1.0                               //  Normalized Base Freq
+    //                 + (fippleFreqMod_ * 0.25) - (fippleFreqMod_ * temp) // fippleModulation 
+    //                 - (blowFreqMod_) + (blowFreqMod_ * envOut); // blowingModulation
+    // short form of above
+    tempFreq = 1.0 + fippleFreqMod_*(0.25-temp) + blowFreqMod_*(envOut-1.0);
+    tempFreq *= baseFrequency_;
+
+    sine_.setFrequency(tempFreq);
+
+    tempVectorP_ = pea_.getPosition();
+    temp = can_.isInside(tempVectorP_);
+    temp  = -temp;       // We know (hope) it's inside, just how much??
+    if (temp < (PEA_RADIUS * 1.25)) {
+      pea_.getVelocity( &tempVector_ );  // This is the can/pea collision
+      tempX = tempVectorP_->getX();     // calculation.  Could probably
+      tempY = tempVectorP_->getY();     // simplify using tables, etc.
+      phi = -atan2(tempY,tempX);
+
+      cosphi = cos(phi);
+      sinphi = sin(phi);
+      temp1 = (cosphi*tempVector_.getX()) - (sinphi*tempVector_.getY());
+      temp2 = (sinphi*tempVector_.getX()) + (cosphi*tempVector_.getY());
+      temp1 = -temp1;
+      tempX = (cosphi*temp1) + (sinphi*temp2);
+      tempY = (-sinphi*temp1) + (cosphi*temp2);
+      pea_.setVelocity(tempX, tempY, 0);
+      pea_.tick(tickSize_);
+      pea_.setVelocity( tempX*canLoss_, tempY*canLoss_, 0 );
+      pea_.tick(tickSize_);
+    }
+
+    temp = tempVectorP_->getLength();  
+    if (temp > 0.01) {
+      tempX = tempVectorP_->getX();
+      tempY = tempVectorP_->getY();
+      phi = atan2( tempY, tempX );
+      phi += 0.3 * temp / CAN_RADIUS;
+      cosphi = cos(phi);
+      sinphi = sin(phi);
+      tempX = 3.0 * temp * cosphi;
+      tempY = 3.0 * temp * sinphi;
+    }
+    else {
+      tempX = 0.0;
+      tempY = 0.0;
+    }
+
+    temp = (0.9 + 0.1*subSample_*noise_.tick()) * envOut * 0.6 * tickSize_;
+    pea_.addVelocity( temp * tempX, (temp*tempY) - (GRAVITY*tickSize_), 0 );
+    pea_.tick( tickSize_ );
+
+    // bumper_.tick(0.0);
+  }
+
+  temp = envOut * envOut * gain / 2;
+  soundMix = temp * ( sine_.tick() + ( noiseGain_*noise_.tick() ) );
+  lastFrame_[0] = 0.20 * soundMix; // should probably do one-zero filter here
+
+  return lastFrame_[0];
+}
+
+void Whistle :: controlChange( int number, StkFloat value )
+{
+  StkFloat norm = value * ONE_OVER_128;
+  if ( norm < 0 ) {
+    norm = 0.0;
+    errorString_ << "Whistle::controlChange: control value less than zero ... setting to zero!";
+    handleError( StkError::WARNING );
+  }
+  else if ( norm > 1.0 ) {
+    norm = 1.0;
+    errorString_ << "Whistle::controlChange: control value greater than 128.0 ... setting to 128.0!";
+    handleError( StkError::WARNING );
+  }
+
+  if ( number == __SK_NoiseLevel_ ) // 4
+    noiseGain_ = 0.25 * norm;
+  else if ( number == __SK_ModFrequency_ ) // 11
+    fippleFreqMod_ = norm;
+  else if ( number == __SK_ModWheel_ ) // 1
+    fippleGainMod_ = norm;
+  else if ( number == __SK_AfterTouch_Cont_ ) // 128
+    envelope_.setTarget( norm * 2.0 );
+  else if ( number == __SK_Breath_ ) // 2
+    blowFreqMod_ = norm * 0.5;
+  else if ( number == __SK_Sustain_ )  { // 64
+    subSample_ = (int) value;
+    if ( subSample_ < 1.0 ) subSample_ = 1;
+    envelope_.setRate( ENV_RATE / subSample_ );
+  }
+  else {
+    errorString_ << "Whistle::controlChange: undefined control number (" << number << ")!";
+    handleError( StkError::WARNING );
+  }
+
+#if defined(_STK_DEBUG_)
+  errorString_ << "Whistle::controlChange: number = " << number << ", value = " << value << '.';
+  handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+} // stk namespace
diff --git a/lib/MoMu-STK-1.0.0/src/Wurley.cpp b/lib/MoMu-STK-1.0.0/src/Wurley.cpp
new file mode 100644 (file)
index 0000000..88bd9fe
--- /dev/null
@@ -0,0 +1,92 @@
+/***************************************************/
+/*! \class Wurley
+    \brief STK Wurlitzer electric piano FM
+           synthesis instrument.
+
+    This class implements two simple FM Pairs
+    summed together, also referred to as algorithm
+    5 of the TX81Z.
+
+    \code
+    Algorithm 5 is :  4->3--\
+                             + --> Out
+                      2->1--/
+    \endcode
+
+    Control Change Numbers: 
+       - Modulator Index One = 2
+       - Crossfade of Outputs = 4
+       - LFO Speed = 11
+       - LFO Depth = 1
+       - ADSR 2 & 4 Target = 128
+
+    The basic Chowning/Stanford FM patent expired
+    in 1995, but there exist follow-on patents,
+    mostly assigned to Yamaha.  If you are of the
+    type who should worry about this (making
+    money) worry away.
+
+    by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
+*/
+/***************************************************/
+
+#include "Wurley.h"
+
+namespace stk {
+
+Wurley :: Wurley( void )
+  : FM()
+{
+  // Concatenate the STK rawwave path to the rawwave files
+  for ( unsigned int i=0; i<3; i++ )
+    waves_[i] = new FileLoop( (Stk::rawwavePath() + "sinewave.raw").c_str(), true );
+  waves_[3] = new FileLoop( (Stk::rawwavePath() + "fwavblnk.raw").c_str(), true );
+
+  this->setRatio(0, 1.0);
+  this->setRatio(1, 4.0);
+  this->setRatio(2, -510.0);
+  this->setRatio(3, -510.0);
+
+  gains_[0] = fmGains_[99];
+  gains_[1] = fmGains_[82];
+  gains_[2] = fmGains_[92];
+  gains_[3] = fmGains_[68];
+
+  adsr_[0]->setAllTimes( 0.001, 1.50, 0.0, 0.04);
+  adsr_[1]->setAllTimes( 0.001, 1.50, 0.0, 0.04);
+  adsr_[2]->setAllTimes( 0.001, 0.25, 0.0, 0.04);
+  adsr_[3]->setAllTimes( 0.001, 0.15, 0.0, 0.04);
+
+  twozero_.setGain( 2.0 );
+  vibrato_.setFrequency( 8.0 );
+}  
+
+Wurley :: ~Wurley( void )
+{
+}
+
+void Wurley :: setFrequency( StkFloat frequency )
+{    
+  baseFrequency_ = frequency;
+  waves_[0]->setFrequency( baseFrequency_ * ratios_[0]);
+  waves_[1]->setFrequency( baseFrequency_ * ratios_[1]);
+  waves_[2]->setFrequency( ratios_[2] );       // Note here a 'fixed resonance'.
+  waves_[3]->setFrequency( ratios_[3] );
+}
+
+void Wurley :: noteOn( StkFloat frequency, StkFloat amplitude )
+{
+  gains_[0] = amplitude * fmGains_[99];
+  gains_[1] = amplitude * fmGains_[82];
+  gains_[2] = amplitude * fmGains_[82];
+  gains_[3] = amplitude * fmGains_[68];
+  this->setFrequency( frequency );
+  this->keyOn();
+
+#if defined(_STK_DEBUG_)
+  errorString_ << "Wurley::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << '.';
+  handleError( StkError::DEBUG_WARNING );
+#endif
+}
+
+} // stk namespace
diff --git a/src/Voice.cpp b/src/Voice.cpp
new file mode 100644 (file)
index 0000000..36e6c51
--- /dev/null
@@ -0,0 +1,182 @@
+//
+//  Voice.cpp
+//  cinder_ios_stk
+//
+//  Created by Gabriel Dunne on 12/29/12.
+//
+//
+
+#include "Voice.h"
+
+Voice::SoundMode Voice::s_globalMode = SINE_MODE;
+
+Voice::Voice() :
+    m_fs() {
+    m_gain = 0;
+    m_freq = 220;
+    m_mode = s_globalMode;
+}
+
+Voice::~Voice() {
+}
+
+void Voice::init() {
+
+    m_gain = 0;
+    m_freq = 220;
+
+    adsr.setAllTimes( .1, 1.0, 1.0, 0.01 );
+
+    switch(m_mode) {
+
+        case BANDEDWG_MODE:
+            m_wg.setPreset(3);
+            break;
+
+        case SINE_MODE:
+            break;
+
+        case BLIT_MODE:
+            m_blit.setHarmonics(12);
+            break;
+
+        case NOISE_MODE:
+            m_noise.setSeed(time(NULL));
+            m_noiseFilter.setResonance(m_freq, 0.5, true);
+            m_noiseFilter.setEqualGainZeroes();
+            break;
+
+        case WAVFILE_MODE:
+            // std::string filepath = [[[NSBundle mainBundle]
+            // pathForResource:@"spencer-ahh.wav" ofType:@""] UTF8String];
+            // m_wav.openFile(filepath);
+            break;
+        
+        case WURLEY_MODE:
+            break;
+    }
+}
+
+void Voice::keyOn(float a) {
+
+    m_gain = a;
+    adsr.keyOn();
+
+    switch(m_mode) {
+
+        case BANDEDWG_MODE:
+            m_wg.noteOn(m_freq, a);
+            m_wg.pluck(a);
+            break;
+
+        case BLIT_MODE:
+            break;
+
+        case SINE_MODE:
+        case NOISE_MODE:
+            setFrequency(m_freq);
+            break;
+
+        case WAVFILE_MODE:
+            break;
+            
+        case WURLEY_MODE:
+            m_wurley.noteOn(m_freq, m_gain);
+            break;
+    }
+}
+
+void Voice::keyOff(float a) {
+
+    adsr.keyOff();
+
+    switch(m_mode) {
+
+        case BANDEDWG_MODE:
+            m_wg.noteOff(a);
+            break;
+
+        case BLIT_MODE:
+            break;
+
+        case SINE_MODE:
+        case NOISE_MODE:
+            break;
+
+        case WAVFILE_MODE:
+            break;
+        case WURLEY_MODE:
+            m_wurley.noteOff(a);
+            break;
+    }
+}
+
+void Voice::setFrequency(float f) {
+
+    m_freq = f;
+
+    switch(m_mode) {
+
+        case BANDEDWG_MODE:
+            m_wg.noteOn(m_freq, 1.0);
+            break;
+
+        case BLIT_MODE:
+            m_blit.setFrequency(m_freq);
+            break;
+
+        case SINE_MODE:
+            m_sin.setFrequency(m_freq);
+            break;
+
+        case NOISE_MODE:
+            m_noiseFilter.setResonance(m_freq, 0.99999, true);
+            m_noiseFilter.setEqualGainZeroes();
+            break;
+
+        case WAVFILE_MODE:
+            //            float base = mtof(56);
+            //            m_wav.setRate(m_freq/base);
+            break;
+        
+        case WURLEY_MODE:
+            m_wurley.setFrequency(m_freq);
+            break;
+    }
+}
+
+float Voice::tick() {
+
+    float samp = 0;
+
+    switch(m_mode) {
+
+        case BANDEDWG_MODE:
+            samp = m_gain * m_wg.tick();
+            break;
+        case BLIT_MODE:
+            samp = m_gain * m_blit.tick() * adsr.tick() * 0.25 ;
+            break;
+        case SINE_MODE:
+            // samp = m_gain * m_sin.tick() * adsr.tick() * .2;
+            samp = m_gain * maxiOsc.triangle(m_freq) * adsr.tick() * .2;
+            break;
+        case NOISE_MODE:
+            samp = m_gain *
+                   m_noiseFilter.tick(m_noise.tick() * 0.001) *
+                   adsr.tick() * .55;
+            break;
+        case WAVFILE_MODE:
+            samp = m_gain * m_wav.tick() * 0.1;
+            if(m_wav.isFinished()) m_wav.reset();
+            break;
+        
+        case WURLEY_MODE:
+            samp = m_gain * m_wurley.tick() * adsr.tick();
+            break;
+    }
+    return samp;
+}
+
+void Voice::destroy() {
+}
diff --git a/src/Voice.h b/src/Voice.h
new file mode 100644 (file)
index 0000000..0929ec8
--- /dev/null
@@ -0,0 +1,76 @@
+//
+//  Voice.h
+//  cinder_ios_stk
+//
+//  Created by Gabriel Dunne on 12/29/12.
+//
+//
+
+#ifndef cinder_ios_stk_Voice_h
+#define cinder_ios_stk_Voice_h
+
+#include "BandedWG.h"
+#include "Blit.h"
+#include "Noise.h"
+#include "BiQuad.h"
+#include "FileWvIn.h"
+#include "Rhodey.h"
+#include "ADSR.h"
+#include "SineWave.h"
+#include "maximilian.h"
+#include "Wurley.h"
+
+using namespace stk;
+
+class Voice
+{
+public:
+
+    Voice();
+    ~Voice();
+
+    void  init();
+    float tick();
+    void  destroy();
+
+    void setFrequency(float f);
+    void setGain(float g) { m_gain = g; }
+    void keyOn( float amp );
+    void keyOff( float amp );
+
+    enum SoundMode
+    {
+        BLIT_MODE,
+        BANDEDWG_MODE,
+        WAVFILE_MODE,
+        NOISE_MODE,
+        SINE_MODE,
+        WURLEY_MODE        
+    };
+
+    static void setGlobalSoundMode(SoundMode mode) { s_globalMode = mode; }
+    void setSoundMode(SoundMode mode) { m_mode = mode; }
+
+    ADSR adsr;
+
+private:
+    static SoundMode s_globalMode;
+
+    const float m_fs;
+
+    float m_gain;
+    float m_freq;
+
+    SoundMode m_mode;
+    BandedWG m_wg;
+    Blit m_blit;
+    Noise m_noise;
+    BiQuad m_noiseFilter;
+    SineWave m_sin;
+    maxiOsc maxiOsc;
+    Rhodey m_rhodey;
+    FileWvIn m_wav;
+    Wurley m_wurley;
+};
+
+#endif
index 5fee8fb756df197750de6dedb045f8721ebe88f5..a7067b5c9d303097ab59babf4a36475b570f182e 100644 (file)
@@ -1,17 +1,6 @@
-#include "cinder/app/AppNative.h"
-#include "cinder/gl/gl.h"
+#include "iosynthApp.h"
 
-using namespace ci;
-using namespace ci::app;
-using namespace std;
 
-class iosynthApp : public AppNative {
-  public:
-       void setup();
-       void mouseDown( MouseEvent event );     
-       void update();
-       void draw();
-};
 
 void iosynthApp::setup()
 {
@@ -27,8 +16,21 @@ void iosynthApp::update()
 
 void iosynthApp::draw()
 {
-       // clear out the window with black
-       gl::clear( Color( 0, 0, 0 ) ); 
+       gl::clear( Color( 0, 1.0f, 0 ) );
 }
 
+
+void iosynthApp::touchesBegan( TouchEvent t )
+{
+}
+
+void iosynthApp::touchesMoved( TouchEvent t )
+{
+}
+
+void iosynthApp::touchesEnded( TouchEvent t )
+{
+}
+
+
 CINDER_APP_NATIVE( iosynthApp, RendererGl )
diff --git a/src/iosynthApp.h b/src/iosynthApp.h
new file mode 100644 (file)
index 0000000..69cd467
--- /dev/null
@@ -0,0 +1,69 @@
+//
+//  iosynthApp.h
+//  iosynth
+//
+//  Created by Gabriel Dunne on 12/7/13.
+//
+//
+#ifndef iosynth_iosynthApp_h
+#define iosynth_iosynthApp_h
+
+#include "cinder/app/AppNative.h"
+// #include "cinder/app/AppCocoaTouch.h"
+#include "cinder/app/TouchEvent.h"
+#include "cinder/app/Renderer.h"
+#include "cinder/gl/gl.h"
+
+#include "cinder/Rand.h"
+#include "cinder/CinderMath.h"
+#include "cinder/Utilities.h"
+#include "cinder/audio/Output.h"
+#include "cinder/audio/Callback.h"
+
+// STK
+#include "Stk.h"
+#include "NRev.h"
+#include "JCRev.h"
+#include "Sitar.h"
+
+// maximilian
+#include "maximilian.h"
+
+#include "Voice.h"
+
+using namespace ci;
+using namespace ci::app;
+using namespace std;
+
+// num voices = num touchpoints
+#define NUM_VOICES 11
+#define BUFFER_SIZE 1024
+
+class iosynthApp : public AppNative {
+public:
+       void setup();
+       void mouseDown( MouseEvent event );
+       void update();
+       void draw();
+    
+    void processAudio( uint64_t inSampleOffset, uint32_t ioSampleCount,
+                      audio::Buffer32f *ioBuffer );
+    void touchesBegan( TouchEvent event );
+    void touchesMoved( TouchEvent event );
+    void touchesEnded( TouchEvent event );
+    
+    float mMasterGain;
+    float mAudioSamples[2][BUFFER_SIZE];
+    
+    int mAppWidth, mAppHeight;
+    
+    std::vector<Voice *> voices;
+    std::vector<ADSR *> envelopes;
+    
+    JCRev reverb;
+    maxiDelayline maxiDelay;
+    maxiDyn maxiDyn;
+    maxiFilter maxiFilter;
+};
+
+#endif
index bbcacde7c3849423c85ad46c75e79a21b2951eb3..9bd003100ee478967c0735bef4e272388624f662 100644 (file)
        objects = {
 
 /* Begin PBXBuildFile section */
+               00748058165D41390024B57A /* assets in Resources */ = {isa = PBXBuildFile; fileRef = 00748057165D41390024B57A /* assets */; };
                0087D25512CD809F002CD69F /* CoreText.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0087D25412CD809F002CD69F /* CoreText.framework */; };
                00CFDF6B1138442D0091E310 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00CFDF6A1138442D0091E310 /* CoreGraphics.framework */; };
-               C725E001121DAC8FFFFA18FF /* ImageIO.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00CFDF6A1138442D0091FFFF /* ImageIO.framework */; };
-               DDDDE001121DAC8FFFFADDDD /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DDDDDF6A1138442D0091DDDD /* MobileCoreServices.framework */; };
                1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; };
                1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; };
                28FD15000DC6FC520079059D /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 28FD14FF0DC6FC520079059D /* OpenGLES.framework */; };
                28FD15080DC6FC5B0079059D /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 28FD15070DC6FC5B0079059D /* QuartzCore.framework */; };
-               C725DFFE121DAC7F00FA186B /* CoreMedia.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C727C02B121B400300192073 /* CoreMedia.framework */; settings = {
-       ATTRIBUTES = (
-               Weak,
-       );
-}; };
-               C725E001121DAC8F00FA186B /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C725E000121DAC8F00FA186B /* AVFoundation.framework */; settings = {
-       ATTRIBUTES = (
-               Weak,
-       );
-}; };
-               C727C02E121B400300192073 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C727C02D121B400300192073 /* CoreVideo.framework */; settings = {
-       ATTRIBUTES = (
-               Weak,
-       );
-}; };
-               C7FB19D6124BC0D70045AFD2 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C7FB19D5124BC0D70045AFD2 /* AudioToolbox.framework */; };
-               00748058165D41390024B57A /* assets in Resources */ = {isa = PBXBuildFile; fileRef = 00748057165D41390024B57A /* assets */; };
-               D6D8A6B842AA4BF6AD3A0D87 /* iosynth_Prefix.pch in Headers */ = {isa = PBXBuildFile; fileRef = 5F24CD9B8A5949E0B1828046 /* iosynth_Prefix.pch */; };
-               FDB524FC93AD48DE9DEE5102 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 27664426CDC048598E09896C /* Default-568h@2x.png */; };
                31EF3990B82C404DB705930E /* CinderApp_ios.png in Resources */ = {isa = PBXBuildFile; fileRef = C9BCD27FE5CA496094E38DC7 /* CinderApp_ios.png */; };
-               24D3F6D65770461E999C667B /* Resources.h in Headers */ = {isa = PBXBuildFile; fileRef = 359BF798F4294C6BB6836DC9 /* Resources.h */; };
                3280A26996EF49D98A7F86C6 /* iosynthApp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 11CEB50DDC2D442F828EFE49 /* iosynthApp.cpp */; };
+               68CAAF0C1854556E00DB5318 /* Voice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAF0A1854556E00DB5318 /* Voice.cpp */; };
+               68CAAFFC185456F100DB5318 /* maximilian.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAF0F185456F000DB5318 /* maximilian.cpp */; };
+               68CAB02F185456F100DB5318 /* ADSR.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFA7185456F100DB5318 /* ADSR.cpp */; };
+               68CAB030185456F100DB5318 /* Asymp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFA8185456F100DB5318 /* Asymp.cpp */; };
+               68CAB031185456F100DB5318 /* BandedWG.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFA9185456F100DB5318 /* BandedWG.cpp */; };
+               68CAB032185456F100DB5318 /* BeeThree.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFAA185456F100DB5318 /* BeeThree.cpp */; };
+               68CAB033185456F100DB5318 /* BiQuad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFAB185456F100DB5318 /* BiQuad.cpp */; };
+               68CAB034185456F100DB5318 /* Blit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFAC185456F100DB5318 /* Blit.cpp */; };
+               68CAB035185456F100DB5318 /* BlitSaw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFAD185456F100DB5318 /* BlitSaw.cpp */; };
+               68CAB036185456F100DB5318 /* BlitSquare.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFAE185456F100DB5318 /* BlitSquare.cpp */; };
+               68CAB037185456F100DB5318 /* BlowBotl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFAF185456F100DB5318 /* BlowBotl.cpp */; };
+               68CAB038185456F100DB5318 /* BlowHole.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFB0185456F100DB5318 /* BlowHole.cpp */; };
+               68CAB039185456F100DB5318 /* Bowed.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFB1185456F100DB5318 /* Bowed.cpp */; };
+               68CAB03A185456F100DB5318 /* Brass.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFB2185456F100DB5318 /* Brass.cpp */; };
+               68CAB03B185456F100DB5318 /* Chorus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFB3185456F100DB5318 /* Chorus.cpp */; };
+               68CAB03C185456F100DB5318 /* Clarinet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFB4185456F100DB5318 /* Clarinet.cpp */; };
+               68CAB03D185456F100DB5318 /* Delay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFB5185456F100DB5318 /* Delay.cpp */; };
+               68CAB03E185456F100DB5318 /* DelayA.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFB6185456F100DB5318 /* DelayA.cpp */; };
+               68CAB03F185456F100DB5318 /* DelayL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFB7185456F100DB5318 /* DelayL.cpp */; };
+               68CAB040185456F100DB5318 /* Drummer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFB8185456F100DB5318 /* Drummer.cpp */; };
+               68CAB041185456F100DB5318 /* Echo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFB9185456F100DB5318 /* Echo.cpp */; };
+               68CAB042185456F100DB5318 /* Envelope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFBA185456F100DB5318 /* Envelope.cpp */; };
+               68CAB043185456F100DB5318 /* FileLoop.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFBB185456F100DB5318 /* FileLoop.cpp */; };
+               68CAB044185456F100DB5318 /* FileRead.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFBC185456F100DB5318 /* FileRead.cpp */; };
+               68CAB045185456F100DB5318 /* FileWrite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFBD185456F100DB5318 /* FileWrite.cpp */; };
+               68CAB046185456F100DB5318 /* FileWvIn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFBE185456F100DB5318 /* FileWvIn.cpp */; };
+               68CAB047185456F100DB5318 /* FileWvOut.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFBF185456F100DB5318 /* FileWvOut.cpp */; };
+               68CAB048185456F100DB5318 /* Fir.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFC0185456F100DB5318 /* Fir.cpp */; };
+               68CAB049185456F100DB5318 /* Flute.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFC1185456F100DB5318 /* Flute.cpp */; };
+               68CAB04A185456F100DB5318 /* FM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFC2185456F100DB5318 /* FM.cpp */; };
+               68CAB04B185456F100DB5318 /* FMVoices.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFC3185456F100DB5318 /* FMVoices.cpp */; };
+               68CAB04C185456F100DB5318 /* FormSwep.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFC4185456F100DB5318 /* FormSwep.cpp */; };
+               68CAB04D185456F100DB5318 /* Granulate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFC5185456F100DB5318 /* Granulate.cpp */; };
+               68CAB04E185456F100DB5318 /* HevyMetl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFC6185456F100DB5318 /* HevyMetl.cpp */; };
+               68CAB04F185456F100DB5318 /* Iir.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFC7185456F100DB5318 /* Iir.cpp */; };
+               68CAB050185456F100DB5318 /* InetWvIn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFC8185456F100DB5318 /* InetWvIn.cpp */; };
+               68CAB051185456F100DB5318 /* InetWvOut.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFC9185456F100DB5318 /* InetWvOut.cpp */; };
+               68CAB052185456F100DB5318 /* JCRev.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFCA185456F100DB5318 /* JCRev.cpp */; };
+               68CAB053185456F100DB5318 /* LentPitShift.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFCB185456F100DB5318 /* LentPitShift.cpp */; };
+               68CAB054185456F100DB5318 /* Mandolin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFCC185456F100DB5318 /* Mandolin.cpp */; };
+               68CAB055185456F100DB5318 /* Mesh2D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFCD185456F100DB5318 /* Mesh2D.cpp */; };
+               68CAB056185456F100DB5318 /* Messager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFCE185456F100DB5318 /* Messager.cpp */; };
+               68CAB057185456F100DB5318 /* MidiFileIn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFCF185456F100DB5318 /* MidiFileIn.cpp */; };
+               68CAB058185456F100DB5318 /* Modal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFD0185456F100DB5318 /* Modal.cpp */; };
+               68CAB059185456F100DB5318 /* ModalBar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFD1185456F100DB5318 /* ModalBar.cpp */; };
+               68CAB05A185456F100DB5318 /* Modulate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFD2185456F100DB5318 /* Modulate.cpp */; };
+               68CAB05B185456F100DB5318 /* Moog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFD3185456F100DB5318 /* Moog.cpp */; };
+               68CAB05C185456F100DB5318 /* Mutex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFD4185456F100DB5318 /* Mutex.cpp */; };
+               68CAB05D185456F100DB5318 /* Noise.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFD5185456F100DB5318 /* Noise.cpp */; };
+               68CAB05E185456F100DB5318 /* NRev.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFD6185456F100DB5318 /* NRev.cpp */; };
+               68CAB05F185456F100DB5318 /* OnePole.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFD7185456F100DB5318 /* OnePole.cpp */; };
+               68CAB060185456F100DB5318 /* OneZero.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFD8185456F100DB5318 /* OneZero.cpp */; };
+               68CAB061185456F100DB5318 /* PercFlut.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFD9185456F100DB5318 /* PercFlut.cpp */; };
+               68CAB062185456F100DB5318 /* Phonemes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFDA185456F100DB5318 /* Phonemes.cpp */; };
+               68CAB063185456F100DB5318 /* PitShift.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFDB185456F100DB5318 /* PitShift.cpp */; };
+               68CAB064185456F100DB5318 /* Plucked.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFDC185456F100DB5318 /* Plucked.cpp */; };
+               68CAB065185456F100DB5318 /* PluckTwo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFDD185456F100DB5318 /* PluckTwo.cpp */; };
+               68CAB066185456F100DB5318 /* PoleZero.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFDE185456F100DB5318 /* PoleZero.cpp */; };
+               68CAB067185456F100DB5318 /* PRCRev.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFDF185456F100DB5318 /* PRCRev.cpp */; };
+               68CAB068185456F100DB5318 /* Resonate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFE0185456F100DB5318 /* Resonate.cpp */; };
+               68CAB069185456F100DB5318 /* Rhodey.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFE1185456F100DB5318 /* Rhodey.cpp */; };
+               68CAB06A185456F100DB5318 /* Sampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFE2185456F100DB5318 /* Sampler.cpp */; };
+               68CAB06B185456F100DB5318 /* Saxofony.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFE3185456F100DB5318 /* Saxofony.cpp */; };
+               68CAB06C185456F100DB5318 /* Shakers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFE4185456F100DB5318 /* Shakers.cpp */; };
+               68CAB06D185456F100DB5318 /* Simple.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFE5185456F100DB5318 /* Simple.cpp */; };
+               68CAB06E185456F100DB5318 /* SineWave.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFE6185456F100DB5318 /* SineWave.cpp */; };
+               68CAB06F185456F100DB5318 /* SingWave.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFE7185456F100DB5318 /* SingWave.cpp */; };
+               68CAB070185456F100DB5318 /* Sitar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFE8185456F100DB5318 /* Sitar.cpp */; };
+               68CAB071185456F100DB5318 /* Skini.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFE9185456F100DB5318 /* Skini.cpp */; };
+               68CAB072185456F100DB5318 /* Socket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFEA185456F100DB5318 /* Socket.cpp */; };
+               68CAB073185456F100DB5318 /* Sphere.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFEB185456F100DB5318 /* Sphere.cpp */; };
+               68CAB074185456F100DB5318 /* StifKarp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFEC185456F100DB5318 /* StifKarp.cpp */; };
+               68CAB075185456F100DB5318 /* Stk.mm in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFED185456F100DB5318 /* Stk.mm */; };
+               68CAB076185456F100DB5318 /* StkUdpSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFEE185456F100DB5318 /* StkUdpSocket.cpp */; };
+               68CAB077185456F100DB5318 /* TapDelay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFEF185456F100DB5318 /* TapDelay.cpp */; };
+               68CAB078185456F100DB5318 /* TcpClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFF0185456F100DB5318 /* TcpClient.cpp */; };
+               68CAB079185456F100DB5318 /* TcpServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFF1185456F100DB5318 /* TcpServer.cpp */; };
+               68CAB07A185456F100DB5318 /* Thread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFF2185456F100DB5318 /* Thread.cpp */; };
+               68CAB07B185456F100DB5318 /* TubeBell.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFF3185456F100DB5318 /* TubeBell.cpp */; };
+               68CAB07C185456F100DB5318 /* TwoPole.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFF4185456F100DB5318 /* TwoPole.cpp */; };
+               68CAB07D185456F100DB5318 /* TwoZero.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFF5185456F100DB5318 /* TwoZero.cpp */; };
+               68CAB07E185456F100DB5318 /* Voicer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFF6185456F100DB5318 /* Voicer.cpp */; };
+               68CAB07F185456F100DB5318 /* VoicForm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFF7185456F100DB5318 /* VoicForm.cpp */; };
+               68CAB080185456F100DB5318 /* Whistle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFF8185456F100DB5318 /* Whistle.cpp */; };
+               68CAB081185456F100DB5318 /* Wurley.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 68CAAFF9185456F100DB5318 /* Wurley.cpp */; };
+               C725DFFE121DAC7F00FA186B /* CoreMedia.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C727C02B121B400300192073 /* CoreMedia.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
+               C725E001121DAC8F00FA186B /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C725E000121DAC8F00FA186B /* AVFoundation.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
+               C725E001121DAC8FFFFA18FF /* ImageIO.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00CFDF6A1138442D0091FFFF /* ImageIO.framework */; };
+               C727C02E121B400300192073 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C727C02D121B400300192073 /* CoreVideo.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
+               C7FB19D6124BC0D70045AFD2 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C7FB19D5124BC0D70045AFD2 /* AudioToolbox.framework */; };
+               DDDDE001121DAC8FFFFADDDD /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DDDDDF6A1138442D0091DDDD /* MobileCoreServices.framework */; };
+               FDB524FC93AD48DE9DEE5102 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 27664426CDC048598E09896C /* Default-568h@2x.png */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXFileReference section */
                00692BCF14FF149000D0A05E /* iosynth.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iosynth.app; sourceTree = BUILT_PRODUCTS_DIR; };
+               00748057165D41390024B57A /* assets */ = {isa = PBXFileReference; lastKnownFileType = folder; name = assets; path = ../assets; sourceTree = "<group>"; };
                0087D25412CD809F002CD69F /* CoreText.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreText.framework; path = System/Library/Frameworks/CoreText.framework; sourceTree = SDKROOT; };
                00CFDF6A1138442D0091E310 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
                00CFDF6A1138442D0091FFFF /* ImageIO.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ImageIO.framework; path = System/Library/Frameworks/ImageIO.framework; sourceTree = SDKROOT; };
-               DDDDDF6A1138442D0091DDDD /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = System/Library/Frameworks/MobileCoreServices.framework; sourceTree = SDKROOT; };
+               11CEB50DDC2D442F828EFE49 /* iosynthApp.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.cpp; name = iosynthApp.cpp; path = ../src/iosynthApp.cpp; sourceTree = "<group>"; };
                1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
                1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
+               27664426CDC048598E09896C /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = "\"\""; path = "Default-568h@2x.png"; sourceTree = "<group>"; };
                28FD14FF0DC6FC520079059D /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; };
                28FD15070DC6FC5B0079059D /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
+               359BF798F4294C6BB6836DC9 /* Resources.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Resources.h; path = ../include/Resources.h; sourceTree = "<group>"; };
+               3DCA5ADB4E5F41B8BC4AFF40 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+               5F24CD9B8A5949E0B1828046 /* iosynth_Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = "\"\""; path = iosynth_Prefix.pch; sourceTree = "<group>"; };
+               68CAAF0918544B0700DB5318 /* iosynthApp.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = iosynthApp.h; path = ../src/iosynthApp.h; sourceTree = "<group>"; };
+               68CAAF0A1854556E00DB5318 /* Voice.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Voice.cpp; path = ../src/Voice.cpp; sourceTree = "<group>"; };
+               68CAAF0B1854556E00DB5318 /* Voice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Voice.h; path = ../src/Voice.h; sourceTree = "<group>"; };
+               68CAAF0F185456F000DB5318 /* maximilian.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = maximilian.cpp; sourceTree = "<group>"; };
+               68CAAF10185456F000DB5318 /* maximilian.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = maximilian.h; sourceTree = "<group>"; };
+               68CAAF16185456F000DB5318 /* ADSR.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADSR.h; sourceTree = "<group>"; };
+               68CAAF17185456F000DB5318 /* Asymp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Asymp.h; sourceTree = "<group>"; };
+               68CAAF18185456F000DB5318 /* BandedWG.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BandedWG.h; sourceTree = "<group>"; };
+               68CAAF19185456F000DB5318 /* BeeThree.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BeeThree.h; sourceTree = "<group>"; };
+               68CAAF1A185456F000DB5318 /* BiQuad.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BiQuad.h; sourceTree = "<group>"; };
+               68CAAF1B185456F000DB5318 /* Blit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Blit.h; sourceTree = "<group>"; };
+               68CAAF1C185456F000DB5318 /* BlitSaw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BlitSaw.h; sourceTree = "<group>"; };
+               68CAAF1D185456F000DB5318 /* BlitSquare.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BlitSquare.h; sourceTree = "<group>"; };
+               68CAAF1E185456F000DB5318 /* BlowBotl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BlowBotl.h; sourceTree = "<group>"; };
+               68CAAF1F185456F000DB5318 /* BlowHole.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BlowHole.h; sourceTree = "<group>"; };
+               68CAAF20185456F000DB5318 /* Bowed.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Bowed.h; sourceTree = "<group>"; };
+               68CAAF21185456F000DB5318 /* BowTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BowTable.h; sourceTree = "<group>"; };
+               68CAAF22185456F000DB5318 /* Brass.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Brass.h; sourceTree = "<group>"; };
+               68CAAF23185456F000DB5318 /* Chorus.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Chorus.h; sourceTree = "<group>"; };
+               68CAAF24185456F000DB5318 /* Clarinet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Clarinet.h; sourceTree = "<group>"; };
+               68CAAF25185456F000DB5318 /* Delay.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Delay.h; sourceTree = "<group>"; };
+               68CAAF26185456F000DB5318 /* DelayA.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DelayA.h; sourceTree = "<group>"; };
+               68CAAF27185456F000DB5318 /* DelayL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DelayL.h; sourceTree = "<group>"; };
+               68CAAF28185456F000DB5318 /* Drummer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Drummer.h; sourceTree = "<group>"; };
+               68CAAF29185456F000DB5318 /* Echo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Echo.h; sourceTree = "<group>"; };
+               68CAAF2A185456F000DB5318 /* Effect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Effect.h; sourceTree = "<group>"; };
+               68CAAF2B185456F000DB5318 /* Envelope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Envelope.h; sourceTree = "<group>"; };
+               68CAAF2C185456F000DB5318 /* FileLoop.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileLoop.h; sourceTree = "<group>"; };
+               68CAAF2D185456F000DB5318 /* FileRead.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileRead.h; sourceTree = "<group>"; };
+               68CAAF2E185456F000DB5318 /* FileWrite.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileWrite.h; sourceTree = "<group>"; };
+               68CAAF2F185456F000DB5318 /* FileWvIn.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileWvIn.h; sourceTree = "<group>"; };
+               68CAAF30185456F000DB5318 /* FileWvOut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileWvOut.h; sourceTree = "<group>"; };
+               68CAAF31185456F000DB5318 /* Filter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Filter.h; sourceTree = "<group>"; };
+               68CAAF32185456F000DB5318 /* Fir.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Fir.h; sourceTree = "<group>"; };
+               68CAAF33185456F000DB5318 /* Flute.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Flute.h; sourceTree = "<group>"; };
+               68CAAF34185456F000DB5318 /* FM.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FM.h; sourceTree = "<group>"; };
+               68CAAF35185456F000DB5318 /* FMVoices.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FMVoices.h; sourceTree = "<group>"; };
+               68CAAF36185456F000DB5318 /* FormSwep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FormSwep.h; sourceTree = "<group>"; };
+               68CAAF37185456F000DB5318 /* Function.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Function.h; sourceTree = "<group>"; };
+               68CAAF38185456F000DB5318 /* Generator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Generator.h; sourceTree = "<group>"; };
+               68CAAF39185456F000DB5318 /* Granulate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Granulate.h; sourceTree = "<group>"; };
+               68CAAF3A185456F000DB5318 /* HevyMetl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HevyMetl.h; sourceTree = "<group>"; };
+               68CAAF3B185456F000DB5318 /* Iir.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Iir.h; sourceTree = "<group>"; };
+               68CAAF3C185456F000DB5318 /* InetWvIn.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InetWvIn.h; sourceTree = "<group>"; };
+               68CAAF3D185456F000DB5318 /* InetWvOut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InetWvOut.h; sourceTree = "<group>"; };
+               68CAAF3E185456F000DB5318 /* Instrmnt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Instrmnt.h; sourceTree = "<group>"; };
+               68CAAF3F185456F000DB5318 /* JCRev.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JCRev.h; sourceTree = "<group>"; };
+               68CAAF40185456F000DB5318 /* JetTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JetTable.h; sourceTree = "<group>"; };
+               68CAAF41185456F000DB5318 /* LentPitShift.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LentPitShift.h; sourceTree = "<group>"; };
+               68CAAF42185456F000DB5318 /* Mandolin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Mandolin.h; sourceTree = "<group>"; };
+               68CAAF43185456F000DB5318 /* Mesh2D.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Mesh2D.h; sourceTree = "<group>"; };
+               68CAAF44185456F000DB5318 /* Messager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Messager.h; sourceTree = "<group>"; };
+               68CAAF45185456F000DB5318 /* MidiFileIn.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MidiFileIn.h; sourceTree = "<group>"; };
+               68CAAF46185456F000DB5318 /* Modal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Modal.h; sourceTree = "<group>"; };
+               68CAAF47185456F000DB5318 /* ModalBar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ModalBar.h; sourceTree = "<group>"; };
+               68CAAF48185456F000DB5318 /* Modulate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Modulate.h; sourceTree = "<group>"; };
+               68CAAF49185456F000DB5318 /* Moog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Moog.h; sourceTree = "<group>"; };
+               68CAAF4A185456F000DB5318 /* Mutex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Mutex.h; sourceTree = "<group>"; };
+               68CAAF4B185456F000DB5318 /* Noise.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Noise.h; sourceTree = "<group>"; };
+               68CAAF4C185456F000DB5318 /* NRev.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NRev.h; sourceTree = "<group>"; };
+               68CAAF4D185456F000DB5318 /* OnePole.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OnePole.h; sourceTree = "<group>"; };
+               68CAAF4E185456F000DB5318 /* OneZero.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OneZero.h; sourceTree = "<group>"; };
+               68CAAF4F185456F000DB5318 /* PercFlut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PercFlut.h; sourceTree = "<group>"; };
+               68CAAF50185456F000DB5318 /* Phonemes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Phonemes.h; sourceTree = "<group>"; };
+               68CAAF51185456F000DB5318 /* PitShift.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PitShift.h; sourceTree = "<group>"; };
+               68CAAF52185456F000DB5318 /* Plucked.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Plucked.h; sourceTree = "<group>"; };
+               68CAAF53185456F100DB5318 /* PluckTwo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PluckTwo.h; sourceTree = "<group>"; };
+               68CAAF54185456F100DB5318 /* PoleZero.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PoleZero.h; sourceTree = "<group>"; };
+               68CAAF55185456F100DB5318 /* PRCRev.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PRCRev.h; sourceTree = "<group>"; };
+               68CAAF56185456F100DB5318 /* ReedTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReedTable.h; sourceTree = "<group>"; };
+               68CAAF57185456F100DB5318 /* Resonate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Resonate.h; sourceTree = "<group>"; };
+               68CAAF58185456F100DB5318 /* Rhodey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Rhodey.h; sourceTree = "<group>"; };
+               68CAAF59185456F100DB5318 /* Sampler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Sampler.h; sourceTree = "<group>"; };
+               68CAAF5A185456F100DB5318 /* Saxofony.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Saxofony.h; sourceTree = "<group>"; };
+               68CAAF5B185456F100DB5318 /* Shakers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Shakers.h; sourceTree = "<group>"; };
+               68CAAF5C185456F100DB5318 /* Simple.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Simple.h; sourceTree = "<group>"; };
+               68CAAF5D185456F100DB5318 /* SineWave.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SineWave.h; sourceTree = "<group>"; };
+               68CAAF5E185456F100DB5318 /* SingWave.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SingWave.h; sourceTree = "<group>"; };
+               68CAAF5F185456F100DB5318 /* Sitar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Sitar.h; sourceTree = "<group>"; };
+               68CAAF60185456F100DB5318 /* Skini.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Skini.h; sourceTree = "<group>"; };
+               68CAAF61185456F100DB5318 /* Skini_msg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Skini_msg.h; sourceTree = "<group>"; };
+               68CAAF62185456F100DB5318 /* Skini_tbl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Skini_tbl.h; sourceTree = "<group>"; };
+               68CAAF63185456F100DB5318 /* Socket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Socket.h; sourceTree = "<group>"; };
+               68CAAF64185456F100DB5318 /* Sphere.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Sphere.h; sourceTree = "<group>"; };
+               68CAAF65185456F100DB5318 /* StifKarp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StifKarp.h; sourceTree = "<group>"; };
+               68CAAF66185456F100DB5318 /* Stk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Stk.h; sourceTree = "<group>"; };
+               68CAAF67185456F100DB5318 /* StkUdpSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StkUdpSocket.h; sourceTree = "<group>"; };
+               68CAAF68185456F100DB5318 /* TapDelay.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TapDelay.h; sourceTree = "<group>"; };
+               68CAAF69185456F100DB5318 /* TcpClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TcpClient.h; sourceTree = "<group>"; };
+               68CAAF6A185456F100DB5318 /* TcpServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TcpServer.h; sourceTree = "<group>"; };
+               68CAAF6B185456F100DB5318 /* Thread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Thread.h; sourceTree = "<group>"; };
+               68CAAF6C185456F100DB5318 /* TubeBell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TubeBell.h; sourceTree = "<group>"; };
+               68CAAF6D185456F100DB5318 /* TwoPole.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TwoPole.h; sourceTree = "<group>"; };
+               68CAAF6E185456F100DB5318 /* TwoZero.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TwoZero.h; sourceTree = "<group>"; };
+               68CAAF6F185456F100DB5318 /* Vector3D.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Vector3D.h; sourceTree = "<group>"; };
+               68CAAF70185456F100DB5318 /* Voicer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Voicer.h; sourceTree = "<group>"; };
+               68CAAF71185456F100DB5318 /* VoicForm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VoicForm.h; sourceTree = "<group>"; };
+               68CAAF72185456F100DB5318 /* Whistle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Whistle.h; sourceTree = "<group>"; };
+               68CAAF73185456F100DB5318 /* Wurley.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Wurley.h; sourceTree = "<group>"; };
+               68CAAF74185456F100DB5318 /* WvIn.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WvIn.h; sourceTree = "<group>"; };
+               68CAAF75185456F100DB5318 /* WvOut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WvOut.h; sourceTree = "<group>"; };
+               68CAAFA7185456F100DB5318 /* ADSR.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ADSR.cpp; sourceTree = "<group>"; };
+               68CAAFA8185456F100DB5318 /* Asymp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Asymp.cpp; sourceTree = "<group>"; };
+               68CAAFA9185456F100DB5318 /* BandedWG.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BandedWG.cpp; sourceTree = "<group>"; };
+               68CAAFAA185456F100DB5318 /* BeeThree.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BeeThree.cpp; sourceTree = "<group>"; };
+               68CAAFAB185456F100DB5318 /* BiQuad.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BiQuad.cpp; sourceTree = "<group>"; };
+               68CAAFAC185456F100DB5318 /* Blit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Blit.cpp; sourceTree = "<group>"; };
+               68CAAFAD185456F100DB5318 /* BlitSaw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BlitSaw.cpp; sourceTree = "<group>"; };
+               68CAAFAE185456F100DB5318 /* BlitSquare.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BlitSquare.cpp; sourceTree = "<group>"; };
+               68CAAFAF185456F100DB5318 /* BlowBotl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BlowBotl.cpp; sourceTree = "<group>"; };
+               68CAAFB0185456F100DB5318 /* BlowHole.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BlowHole.cpp; sourceTree = "<group>"; };
+               68CAAFB1185456F100DB5318 /* Bowed.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Bowed.cpp; sourceTree = "<group>"; };
+               68CAAFB2185456F100DB5318 /* Brass.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Brass.cpp; sourceTree = "<group>"; };
+               68CAAFB3185456F100DB5318 /* Chorus.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Chorus.cpp; sourceTree = "<group>"; };
+               68CAAFB4185456F100DB5318 /* Clarinet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Clarinet.cpp; sourceTree = "<group>"; };
+               68CAAFB5185456F100DB5318 /* Delay.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Delay.cpp; sourceTree = "<group>"; };
+               68CAAFB6185456F100DB5318 /* DelayA.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DelayA.cpp; sourceTree = "<group>"; };
+               68CAAFB7185456F100DB5318 /* DelayL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DelayL.cpp; sourceTree = "<group>"; };
+               68CAAFB8185456F100DB5318 /* Drummer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Drummer.cpp; sourceTree = "<group>"; };
+               68CAAFB9185456F100DB5318 /* Echo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Echo.cpp; sourceTree = "<group>"; };
+               68CAAFBA185456F100DB5318 /* Envelope.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Envelope.cpp; sourceTree = "<group>"; };
+               68CAAFBB185456F100DB5318 /* FileLoop.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileLoop.cpp; sourceTree = "<group>"; };
+               68CAAFBC185456F100DB5318 /* FileRead.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileRead.cpp; sourceTree = "<group>"; };
+               68CAAFBD185456F100DB5318 /* FileWrite.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileWrite.cpp; sourceTree = "<group>"; };
+               68CAAFBE185456F100DB5318 /* FileWvIn.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileWvIn.cpp; sourceTree = "<group>"; };
+               68CAAFBF185456F100DB5318 /* FileWvOut.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileWvOut.cpp; sourceTree = "<group>"; };
+               68CAAFC0185456F100DB5318 /* Fir.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Fir.cpp; sourceTree = "<group>"; };
+               68CAAFC1185456F100DB5318 /* Flute.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Flute.cpp; sourceTree = "<group>"; };
+               68CAAFC2185456F100DB5318 /* FM.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FM.cpp; sourceTree = "<group>"; };
+               68CAAFC3185456F100DB5318 /* FMVoices.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FMVoices.cpp; sourceTree = "<group>"; };
+               68CAAFC4185456F100DB5318 /* FormSwep.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FormSwep.cpp; sourceTree = "<group>"; };
+               68CAAFC5185456F100DB5318 /* Granulate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Granulate.cpp; sourceTree = "<group>"; };
+               68CAAFC6185456F100DB5318 /* HevyMetl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HevyMetl.cpp; sourceTree = "<group>"; };
+               68CAAFC7185456F100DB5318 /* Iir.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Iir.cpp; sourceTree = "<group>"; };
+               68CAAFC8185456F100DB5318 /* InetWvIn.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InetWvIn.cpp; sourceTree = "<group>"; };
+               68CAAFC9185456F100DB5318 /* InetWvOut.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InetWvOut.cpp; sourceTree = "<group>"; };
+               68CAAFCA185456F100DB5318 /* JCRev.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JCRev.cpp; sourceTree = "<group>"; };
+               68CAAFCB185456F100DB5318 /* LentPitShift.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LentPitShift.cpp; sourceTree = "<group>"; };
+               68CAAFCC185456F100DB5318 /* Mandolin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Mandolin.cpp; sourceTree = "<group>"; };
+               68CAAFCD185456F100DB5318 /* Mesh2D.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Mesh2D.cpp; sourceTree = "<group>"; };
+               68CAAFCE185456F100DB5318 /* Messager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Messager.cpp; sourceTree = "<group>"; };
+               68CAAFCF185456F100DB5318 /* MidiFileIn.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MidiFileIn.cpp; sourceTree = "<group>"; };
+               68CAAFD0185456F100DB5318 /* Modal.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Modal.cpp; sourceTree = "<group>"; };
+               68CAAFD1185456F100DB5318 /* ModalBar.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ModalBar.cpp; sourceTree = "<group>"; };
+               68CAAFD2185456F100DB5318 /* Modulate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Modulate.cpp; sourceTree = "<group>"; };
+               68CAAFD3185456F100DB5318 /* Moog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Moog.cpp; sourceTree = "<group>"; };
+               68CAAFD4185456F100DB5318 /* Mutex.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Mutex.cpp; sourceTree = "<group>"; };
+               68CAAFD5185456F100DB5318 /* Noise.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Noise.cpp; sourceTree = "<group>"; };
+               68CAAFD6185456F100DB5318 /* NRev.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NRev.cpp; sourceTree = "<group>"; };
+               68CAAFD7185456F100DB5318 /* OnePole.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OnePole.cpp; sourceTree = "<group>"; };
+               68CAAFD8185456F100DB5318 /* OneZero.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OneZero.cpp; sourceTree = "<group>"; };
+               68CAAFD9185456F100DB5318 /* PercFlut.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PercFlut.cpp; sourceTree = "<group>"; };
+               68CAAFDA185456F100DB5318 /* Phonemes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Phonemes.cpp; sourceTree = "<group>"; };
+               68CAAFDB185456F100DB5318 /* PitShift.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PitShift.cpp; sourceTree = "<group>"; };
+               68CAAFDC185456F100DB5318 /* Plucked.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Plucked.cpp; sourceTree = "<group>"; };
+               68CAAFDD185456F100DB5318 /* PluckTwo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PluckTwo.cpp; sourceTree = "<group>"; };
+               68CAAFDE185456F100DB5318 /* PoleZero.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PoleZero.cpp; sourceTree = "<group>"; };
+               68CAAFDF185456F100DB5318 /* PRCRev.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PRCRev.cpp; sourceTree = "<group>"; };
+               68CAAFE0185456F100DB5318 /* Resonate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Resonate.cpp; sourceTree = "<group>"; };
+               68CAAFE1185456F100DB5318 /* Rhodey.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Rhodey.cpp; sourceTree = "<group>"; };
+               68CAAFE2185456F100DB5318 /* Sampler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Sampler.cpp; sourceTree = "<group>"; };
+               68CAAFE3185456F100DB5318 /* Saxofony.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Saxofony.cpp; sourceTree = "<group>"; };
+               68CAAFE4185456F100DB5318 /* Shakers.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Shakers.cpp; sourceTree = "<group>"; };
+               68CAAFE5185456F100DB5318 /* Simple.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Simple.cpp; sourceTree = "<group>"; };
+               68CAAFE6185456F100DB5318 /* SineWave.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SineWave.cpp; sourceTree = "<group>"; };
+               68CAAFE7185456F100DB5318 /* SingWave.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SingWave.cpp; sourceTree = "<group>"; };
+               68CAAFE8185456F100DB5318 /* Sitar.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Sitar.cpp; sourceTree = "<group>"; };
+               68CAAFE9185456F100DB5318 /* Skini.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Skini.cpp; sourceTree = "<group>"; };
+               68CAAFEA185456F100DB5318 /* Socket.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Socket.cpp; sourceTree = "<group>"; };
+               68CAAFEB185456F100DB5318 /* Sphere.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Sphere.cpp; sourceTree = "<group>"; };
+               68CAAFEC185456F100DB5318 /* StifKarp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StifKarp.cpp; sourceTree = "<group>"; };
+               68CAAFED185456F100DB5318 /* Stk.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = Stk.mm; sourceTree = "<group>"; };
+               68CAAFEE185456F100DB5318 /* StkUdpSocket.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StkUdpSocket.cpp; sourceTree = "<group>"; };
+               68CAAFEF185456F100DB5318 /* TapDelay.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TapDelay.cpp; sourceTree = "<group>"; };
+               68CAAFF0185456F100DB5318 /* TcpClient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TcpClient.cpp; sourceTree = "<group>"; };
+               68CAAFF1185456F100DB5318 /* TcpServer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TcpServer.cpp; sourceTree = "<group>"; };
+               68CAAFF2185456F100DB5318 /* Thread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Thread.cpp; sourceTree = "<group>"; };
+               68CAAFF3185456F100DB5318 /* TubeBell.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TubeBell.cpp; sourceTree = "<group>"; };
+               68CAAFF4185456F100DB5318 /* TwoPole.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TwoPole.cpp; sourceTree = "<group>"; };
+               68CAAFF5185456F100DB5318 /* TwoZero.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TwoZero.cpp; sourceTree = "<group>"; };
+               68CAAFF6185456F100DB5318 /* Voicer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Voicer.cpp; sourceTree = "<group>"; };
+               68CAAFF7185456F100DB5318 /* VoicForm.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VoicForm.cpp; sourceTree = "<group>"; };
+               68CAAFF8185456F100DB5318 /* Whistle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Whistle.cpp; sourceTree = "<group>"; };
+               68CAAFF9185456F100DB5318 /* Wurley.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Wurley.cpp; sourceTree = "<group>"; };
                C725E000121DAC8F00FA186B /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; };
                C727C02B121B400300192073 /* CoreMedia.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMedia.framework; path = System/Library/Frameworks/CoreMedia.framework; sourceTree = SDKROOT; };
                C727C02D121B400300192073 /* CoreVideo.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreVideo.framework; path = System/Library/Frameworks/CoreVideo.framework; sourceTree = SDKROOT; };
                C7FB19D5124BC0D70045AFD2 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
-               00748057165D41390024B57A /* assets */ = {isa = PBXFileReference; lastKnownFileType = folder; name = assets; path = ../assets; sourceTree = "<group>"; };
-               11CEB50DDC2D442F828EFE49 /* iosynthApp.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.cpp; path = ../src/iosynthApp.cpp; sourceTree = "<group>"; name = iosynthApp.cpp; };
-               359BF798F4294C6BB6836DC9 /* Resources.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ../include/Resources.h; sourceTree = "<group>"; name = Resources.h; };
-               C9BCD27FE5CA496094E38DC7 /* CinderApp_ios.png */ = {isa = PBXFileReference; lastKnownFileType = "\"\""; path = ../resources/CinderApp_ios.png; sourceTree = "<group>"; name = CinderApp_ios.png; };
-               27664426CDC048598E09896C /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = "\"\""; path = "Default-568h@2x.png"; sourceTree = "<group>"; name = "Default-568h@2x.png"; };
-               3DCA5ADB4E5F41B8BC4AFF40 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; name = Info.plist; };
-               5F24CD9B8A5949E0B1828046 /* iosynth_Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = "\"\""; path = iosynth_Prefix.pch; sourceTree = "<group>"; name = iosynth_Prefix.pch; };
+               C9BCD27FE5CA496094E38DC7 /* CinderApp_ios.png */ = {isa = PBXFileReference; lastKnownFileType = "\"\""; name = CinderApp_ios.png; path = ../resources/CinderApp_ios.png; sourceTree = "<group>"; };
+               DDDDDF6A1138442D0091DDDD /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = System/Library/Frameworks/MobileCoreServices.framework; sourceTree = SDKROOT; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
                00692BC414FF149000D0A05E = {
                        isa = PBXGroup;
                        children = (
-                               99692BD914FF149000DFFFFF /* Blocks */,
+                               68CAAF0D185456CC00DB5318 /* lib */,
                                99692BD914FF149000D0A05F /* Headers */,
                                00692BD914FF149000D0A05E /* Source */,
                                00692BD914FF149000D0FFFF /* Resources */,
                        name = Frameworks;
                        sourceTree = "<group>";
                };
-               99692BD914FF149000DFFFFF /* Blocks */ = {
+               00692BD914FF149000D0A05E /* Source */ = {
                        isa = PBXGroup;
                        children = (
+                               11CEB50DDC2D442F828EFE49 /* iosynthApp.cpp */,
+                               68CAAF0918544B0700DB5318 /* iosynthApp.h */,
+                               68CAAF0A1854556E00DB5318 /* Voice.cpp */,
+                               68CAAF0B1854556E00DB5318 /* Voice.h */,
                        );
-                       name = Blocks;
+                       name = Source;
                        sourceTree = "<group>";
                };
-               99692BD914FF149000D0A05F /* Headers */ = {
+               00692BD914FF149000D0FFFF /* Resources */ = {
                        isa = PBXGroup;
                        children = (
-                               359BF798F4294C6BB6836DC9 /* Resources.h */,
-                               5F24CD9B8A5949E0B1828046 /* iosynth_Prefix.pch */,
+                               00748057165D41390024B57A /* assets */,
+                               C9BCD27FE5CA496094E38DC7 /* CinderApp_ios.png */,
+                               27664426CDC048598E09896C /* Default-568h@2x.png */,
+                               3DCA5ADB4E5F41B8BC4AFF40 /* Info.plist */,
                        );
-                       name = Headers;
+                       name = Resources;
                        sourceTree = "<group>";
                };
-               00692BD914FF149000D0A05E /* Source */ = {
+               68CAAF0D185456CC00DB5318 /* lib */ = {
                        isa = PBXGroup;
                        children = (
-                               11CEB50DDC2D442F828EFE49 /* iosynthApp.cpp */,
+                               68CAAF0E185456F000DB5318 /* Maximilian */,
+                               68CAAF11185456F000DB5318 /* MoMu-STK-1.0.0 */,
                        );
-                       name = Source;
+                       name = lib;
                        sourceTree = "<group>";
                };
-               00692BD914FF149000D0FFFF /* Resources */ = {
+               68CAAF0E185456F000DB5318 /* Maximilian */ = {
                        isa = PBXGroup;
                        children = (
-                               00748057165D41390024B57A /* assets */,
-                               C9BCD27FE5CA496094E38DC7 /* CinderApp_ios.png */,
-                               27664426CDC048598E09896C /* Default-568h@2x.png */,
-                               3DCA5ADB4E5F41B8BC4AFF40 /* Info.plist */,
+                               68CAAF0F185456F000DB5318 /* maximilian.cpp */,
+                               68CAAF10185456F000DB5318 /* maximilian.h */,
                        );
-                       name = Resources;
+                       name = Maximilian;
+                       path = ../lib/Maximilian;
+                       sourceTree = "<group>";
+               };
+               68CAAF11185456F000DB5318 /* MoMu-STK-1.0.0 */ = {
+                       isa = PBXGroup;
+                       children = (
+                               68CAAF15185456F000DB5318 /* include */,
+                               68CAAFA6185456F100DB5318 /* src */,
+                       );
+                       name = "MoMu-STK-1.0.0";
+                       path = "../lib/MoMu-STK-1.0.0";
+                       sourceTree = "<group>";
+               };
+               68CAAF15185456F000DB5318 /* include */ = {
+                       isa = PBXGroup;
+                       children = (
+                               68CAAF16185456F000DB5318 /* ADSR.h */,
+                               68CAAF17185456F000DB5318 /* Asymp.h */,
+                               68CAAF18185456F000DB5318 /* BandedWG.h */,
+                               68CAAF19185456F000DB5318 /* BeeThree.h */,
+                               68CAAF1A185456F000DB5318 /* BiQuad.h */,
+                               68CAAF1B185456F000DB5318 /* Blit.h */,
+                               68CAAF1C185456F000DB5318 /* BlitSaw.h */,
+                               68CAAF1D185456F000DB5318 /* BlitSquare.h */,
+                               68CAAF1E185456F000DB5318 /* BlowBotl.h */,
+                               68CAAF1F185456F000DB5318 /* BlowHole.h */,
+                               68CAAF20185456F000DB5318 /* Bowed.h */,
+                               68CAAF21185456F000DB5318 /* BowTable.h */,
+                               68CAAF22185456F000DB5318 /* Brass.h */,
+                               68CAAF23185456F000DB5318 /* Chorus.h */,
+                               68CAAF24185456F000DB5318 /* Clarinet.h */,
+                               68CAAF25185456F000DB5318 /* Delay.h */,
+                               68CAAF26185456F000DB5318 /* DelayA.h */,
+                               68CAAF27185456F000DB5318 /* DelayL.h */,
+                               68CAAF28185456F000DB5318 /* Drummer.h */,
+                               68CAAF29185456F000DB5318 /* Echo.h */,
+                               68CAAF2A185456F000DB5318 /* Effect.h */,
+                               68CAAF2B185456F000DB5318 /* Envelope.h */,
+                               68CAAF2C185456F000DB5318 /* FileLoop.h */,
+                               68CAAF2D185456F000DB5318 /* FileRead.h */,
+                               68CAAF2E185456F000DB5318 /* FileWrite.h */,
+                               68CAAF2F185456F000DB5318 /* FileWvIn.h */,
+                               68CAAF30185456F000DB5318 /* FileWvOut.h */,
+                               68CAAF31185456F000DB5318 /* Filter.h */,
+                               68CAAF32185456F000DB5318 /* Fir.h */,
+                               68CAAF33185456F000DB5318 /* Flute.h */,
+                               68CAAF34185456F000DB5318 /* FM.h */,
+                               68CAAF35185456F000DB5318 /* FMVoices.h */,
+                               68CAAF36185456F000DB5318 /* FormSwep.h */,
+                               68CAAF37185456F000DB5318 /* Function.h */,
+                               68CAAF38185456F000DB5318 /* Generator.h */,
+                               68CAAF39185456F000DB5318 /* Granulate.h */,
+                               68CAAF3A185456F000DB5318 /* HevyMetl.h */,
+                               68CAAF3B185456F000DB5318 /* Iir.h */,
+                               68CAAF3C185456F000DB5318 /* InetWvIn.h */,
+                               68CAAF3D185456F000DB5318 /* InetWvOut.h */,
+                               68CAAF3E185456F000DB5318 /* Instrmnt.h */,
+                               68CAAF3F185456F000DB5318 /* JCRev.h */,
+                               68CAAF40185456F000DB5318 /* JetTable.h */,
+                               68CAAF41185456F000DB5318 /* LentPitShift.h */,
+                               68CAAF42185456F000DB5318 /* Mandolin.h */,
+                               68CAAF43185456F000DB5318 /* Mesh2D.h */,
+                               68CAAF44185456F000DB5318 /* Messager.h */,
+                               68CAAF45185456F000DB5318 /* MidiFileIn.h */,
+                               68CAAF46185456F000DB5318 /* Modal.h */,
+                               68CAAF47185456F000DB5318 /* ModalBar.h */,
+                               68CAAF48185456F000DB5318 /* Modulate.h */,
+                               68CAAF49185456F000DB5318 /* Moog.h */,
+                               68CAAF4A185456F000DB5318 /* Mutex.h */,
+                               68CAAF4B185456F000DB5318 /* Noise.h */,
+                               68CAAF4C185456F000DB5318 /* NRev.h */,
+                               68CAAF4D185456F000DB5318 /* OnePole.h */,
+                               68CAAF4E185456F000DB5318 /* OneZero.h */,
+                               68CAAF4F185456F000DB5318 /* PercFlut.h */,
+                               68CAAF50185456F000DB5318 /* Phonemes.h */,
+                               68CAAF51185456F000DB5318 /* PitShift.h */,
+                               68CAAF52185456F000DB5318 /* Plucked.h */,
+                               68CAAF53185456F100DB5318 /* PluckTwo.h */,
+                               68CAAF54185456F100DB5318 /* PoleZero.h */,
+                               68CAAF55185456F100DB5318 /* PRCRev.h */,
+                               68CAAF56185456F100DB5318 /* ReedTable.h */,
+                               68CAAF57185456F100DB5318 /* Resonate.h */,
+                               68CAAF58185456F100DB5318 /* Rhodey.h */,
+                               68CAAF59185456F100DB5318 /* Sampler.h */,
+                               68CAAF5A185456F100DB5318 /* Saxofony.h */,
+                               68CAAF5B185456F100DB5318 /* Shakers.h */,
+                               68CAAF5C185456F100DB5318 /* Simple.h */,
+                               68CAAF5D185456F100DB5318 /* SineWave.h */,
+                               68CAAF5E185456F100DB5318 /* SingWave.h */,
+                               68CAAF5F185456F100DB5318 /* Sitar.h */,
+                               68CAAF60185456F100DB5318 /* Skini.h */,
+                               68CAAF61185456F100DB5318 /* Skini_msg.h */,
+                               68CAAF62185456F100DB5318 /* Skini_tbl.h */,
+                               68CAAF63185456F100DB5318 /* Socket.h */,
+                               68CAAF64185456F100DB5318 /* Sphere.h */,
+                               68CAAF65185456F100DB5318 /* StifKarp.h */,
+                               68CAAF66185456F100DB5318 /* Stk.h */,
+                               68CAAF67185456F100DB5318 /* StkUdpSocket.h */,
+                               68CAAF68185456F100DB5318 /* TapDelay.h */,
+                               68CAAF69185456F100DB5318 /* TcpClient.h */,
+                               68CAAF6A185456F100DB5318 /* TcpServer.h */,
+                               68CAAF6B185456F100DB5318 /* Thread.h */,
+                               68CAAF6C185456F100DB5318 /* TubeBell.h */,
+                               68CAAF6D185456F100DB5318 /* TwoPole.h */,
+                               68CAAF6E185456F100DB5318 /* TwoZero.h */,
+                               68CAAF6F185456F100DB5318 /* Vector3D.h */,
+                               68CAAF70185456F100DB5318 /* Voicer.h */,
+                               68CAAF71185456F100DB5318 /* VoicForm.h */,
+                               68CAAF72185456F100DB5318 /* Whistle.h */,
+                               68CAAF73185456F100DB5318 /* Wurley.h */,
+                               68CAAF74185456F100DB5318 /* WvIn.h */,
+                               68CAAF75185456F100DB5318 /* WvOut.h */,
+                       );
+                       path = include;
+                       sourceTree = "<group>";
+               };
+               68CAAFA6185456F100DB5318 /* src */ = {
+                       isa = PBXGroup;
+                       children = (
+                               68CAAFA7185456F100DB5318 /* ADSR.cpp */,
+                               68CAAFA8185456F100DB5318 /* Asymp.cpp */,
+                               68CAAFA9185456F100DB5318 /* BandedWG.cpp */,
+                               68CAAFAA185456F100DB5318 /* BeeThree.cpp */,
+                               68CAAFAB185456F100DB5318 /* BiQuad.cpp */,
+                               68CAAFAC185456F100DB5318 /* Blit.cpp */,
+                               68CAAFAD185456F100DB5318 /* BlitSaw.cpp */,
+                               68CAAFAE185456F100DB5318 /* BlitSquare.cpp */,
+                               68CAAFAF185456F100DB5318 /* BlowBotl.cpp */,
+                               68CAAFB0185456F100DB5318 /* BlowHole.cpp */,
+                               68CAAFB1185456F100DB5318 /* Bowed.cpp */,
+                               68CAAFB2185456F100DB5318 /* Brass.cpp */,
+                               68CAAFB3185456F100DB5318 /* Chorus.cpp */,
+                               68CAAFB4185456F100DB5318 /* Clarinet.cpp */,
+                               68CAAFB5185456F100DB5318 /* Delay.cpp */,
+                               68CAAFB6185456F100DB5318 /* DelayA.cpp */,
+                               68CAAFB7185456F100DB5318 /* DelayL.cpp */,
+                               68CAAFB8185456F100DB5318 /* Drummer.cpp */,
+                               68CAAFB9185456F100DB5318 /* Echo.cpp */,
+                               68CAAFBA185456F100DB5318 /* Envelope.cpp */,
+                               68CAAFBB185456F100DB5318 /* FileLoop.cpp */,
+                               68CAAFBC185456F100DB5318 /* FileRead.cpp */,
+                               68CAAFBD185456F100DB5318 /* FileWrite.cpp */,
+                               68CAAFBE185456F100DB5318 /* FileWvIn.cpp */,
+                               68CAAFBF185456F100DB5318 /* FileWvOut.cpp */,
+                               68CAAFC0185456F100DB5318 /* Fir.cpp */,
+                               68CAAFC1185456F100DB5318 /* Flute.cpp */,
+                               68CAAFC2185456F100DB5318 /* FM.cpp */,
+                               68CAAFC3185456F100DB5318 /* FMVoices.cpp */,
+                               68CAAFC4185456F100DB5318 /* FormSwep.cpp */,
+                               68CAAFC5185456F100DB5318 /* Granulate.cpp */,
+                               68CAAFC6185456F100DB5318 /* HevyMetl.cpp */,
+                               68CAAFC7185456F100DB5318 /* Iir.cpp */,
+                               68CAAFC8185456F100DB5318 /* InetWvIn.cpp */,
+                               68CAAFC9185456F100DB5318 /* InetWvOut.cpp */,
+                               68CAAFCA185456F100DB5318 /* JCRev.cpp */,
+                               68CAAFCB185456F100DB5318 /* LentPitShift.cpp */,
+                               68CAAFCC185456F100DB5318 /* Mandolin.cpp */,
+                               68CAAFCD185456F100DB5318 /* Mesh2D.cpp */,
+                               68CAAFCE185456F100DB5318 /* Messager.cpp */,
+                               68CAAFCF185456F100DB5318 /* MidiFileIn.cpp */,
+                               68CAAFD0185456F100DB5318 /* Modal.cpp */,
+                               68CAAFD1185456F100DB5318 /* ModalBar.cpp */,
+                               68CAAFD2185456F100DB5318 /* Modulate.cpp */,
+                               68CAAFD3185456F100DB5318 /* Moog.cpp */,
+                               68CAAFD4185456F100DB5318 /* Mutex.cpp */,
+                               68CAAFD5185456F100DB5318 /* Noise.cpp */,
+                               68CAAFD6185456F100DB5318 /* NRev.cpp */,
+                               68CAAFD7185456F100DB5318 /* OnePole.cpp */,
+                               68CAAFD8185456F100DB5318 /* OneZero.cpp */,
+                               68CAAFD9185456F100DB5318 /* PercFlut.cpp */,
+                               68CAAFDA185456F100DB5318 /* Phonemes.cpp */,
+                               68CAAFDB185456F100DB5318 /* PitShift.cpp */,
+                               68CAAFDC185456F100DB5318 /* Plucked.cpp */,
+                               68CAAFDD185456F100DB5318 /* PluckTwo.cpp */,
+                               68CAAFDE185456F100DB5318 /* PoleZero.cpp */,
+                               68CAAFDF185456F100DB5318 /* PRCRev.cpp */,
+                               68CAAFE0185456F100DB5318 /* Resonate.cpp */,
+                               68CAAFE1185456F100DB5318 /* Rhodey.cpp */,
+                               68CAAFE2185456F100DB5318 /* Sampler.cpp */,
+                               68CAAFE3185456F100DB5318 /* Saxofony.cpp */,
+                               68CAAFE4185456F100DB5318 /* Shakers.cpp */,
+                               68CAAFE5185456F100DB5318 /* Simple.cpp */,
+                               68CAAFE6185456F100DB5318 /* SineWave.cpp */,
+                               68CAAFE7185456F100DB5318 /* SingWave.cpp */,
+                               68CAAFE8185456F100DB5318 /* Sitar.cpp */,
+                               68CAAFE9185456F100DB5318 /* Skini.cpp */,
+                               68CAAFEA185456F100DB5318 /* Socket.cpp */,
+                               68CAAFEB185456F100DB5318 /* Sphere.cpp */,
+                               68CAAFEC185456F100DB5318 /* StifKarp.cpp */,
+                               68CAAFED185456F100DB5318 /* Stk.mm */,
+                               68CAAFEE185456F100DB5318 /* StkUdpSocket.cpp */,
+                               68CAAFEF185456F100DB5318 /* TapDelay.cpp */,
+                               68CAAFF0185456F100DB5318 /* TcpClient.cpp */,
+                               68CAAFF1185456F100DB5318 /* TcpServer.cpp */,
+                               68CAAFF2185456F100DB5318 /* Thread.cpp */,
+                               68CAAFF3185456F100DB5318 /* TubeBell.cpp */,
+                               68CAAFF4185456F100DB5318 /* TwoPole.cpp */,
+                               68CAAFF5185456F100DB5318 /* TwoZero.cpp */,
+                               68CAAFF6185456F100DB5318 /* Voicer.cpp */,
+                               68CAAFF7185456F100DB5318 /* VoicForm.cpp */,
+                               68CAAFF8185456F100DB5318 /* Whistle.cpp */,
+                               68CAAFF9185456F100DB5318 /* Wurley.cpp */,
+                       );
+                       path = src;
+                       sourceTree = "<group>";
+               };
+               99692BD914FF149000D0A05F /* Headers */ = {
+                       isa = PBXGroup;
+                       children = (
+                               359BF798F4294C6BB6836DC9 /* Resources.h */,
+                               5F24CD9B8A5949E0B1828046 /* iosynth_Prefix.pch */,
+                       );
+                       name = Headers;
                        sourceTree = "<group>";
                };
 /* End PBXGroup section */
 /* Begin PBXProject section */
                00692BC614FF149000D0A05E /* Project object */ = {
                        isa = PBXProject;
+                       attributes = {
+                       };
                        buildConfigurationList = 00692BC914FF149000D0A05E /* Build configuration list for PBXProject "iosynth" */;
                        compatibilityVersion = "Xcode 3.2";
                        developmentRegion = English;
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
+                               68CAB035185456F100DB5318 /* BlitSaw.cpp in Sources */,
+                               68CAB062185456F100DB5318 /* Phonemes.cpp in Sources */,
+                               68CAAF0C1854556E00DB5318 /* Voice.cpp in Sources */,
+                               68CAB03A185456F100DB5318 /* Brass.cpp in Sources */,
+                               68CAB048185456F100DB5318 /* Fir.cpp in Sources */,
+                               68CAB04F185456F100DB5318 /* Iir.cpp in Sources */,
+                               68CAB050185456F100DB5318 /* InetWvIn.cpp in Sources */,
+                               68CAB06D185456F100DB5318 /* Simple.cpp in Sources */,
+                               68CAB047185456F100DB5318 /* FileWvOut.cpp in Sources */,
+                               68CAB06F185456F100DB5318 /* SingWave.cpp in Sources */,
+                               68CAB06C185456F100DB5318 /* Shakers.cpp in Sources */,
+                               68CAB065185456F100DB5318 /* PluckTwo.cpp in Sources */,
+                               68CAB053185456F100DB5318 /* LentPitShift.cpp in Sources */,
+                               68CAB037185456F100DB5318 /* BlowBotl.cpp in Sources */,
+                               68CAB073185456F100DB5318 /* Sphere.cpp in Sources */,
+                               68CAB033185456F100DB5318 /* BiQuad.cpp in Sources */,
+                               68CAB05C185456F100DB5318 /* Mutex.cpp in Sources */,
+                               68CAB067185456F100DB5318 /* PRCRev.cpp in Sources */,
+                               68CAB03C185456F100DB5318 /* Clarinet.cpp in Sources */,
+                               68CAB03F185456F100DB5318 /* DelayL.cpp in Sources */,
+                               68CAB072185456F100DB5318 /* Socket.cpp in Sources */,
+                               68CAB070185456F100DB5318 /* Sitar.cpp in Sources */,
+                               68CAB044185456F100DB5318 /* FileRead.cpp in Sources */,
+                               68CAB049185456F100DB5318 /* Flute.cpp in Sources */,
+                               68CAB068185456F100DB5318 /* Resonate.cpp in Sources */,
+                               68CAB04C185456F100DB5318 /* FormSwep.cpp in Sources */,
+                               68CAB07F185456F100DB5318 /* VoicForm.cpp in Sources */,
+                               68CAB05B185456F100DB5318 /* Moog.cpp in Sources */,
+                               68CAB036185456F100DB5318 /* BlitSquare.cpp in Sources */,
+                               68CAB055185456F100DB5318 /* Mesh2D.cpp in Sources */,
+                               68CAB042185456F100DB5318 /* Envelope.cpp in Sources */,
+                               68CAB04B185456F100DB5318 /* FMVoices.cpp in Sources */,
+                               68CAB064185456F100DB5318 /* Plucked.cpp in Sources */,
+                               68CAB03B185456F100DB5318 /* Chorus.cpp in Sources */,
+                               68CAB03E185456F100DB5318 /* DelayA.cpp in Sources */,
+                               68CAB04E185456F100DB5318 /* HevyMetl.cpp in Sources */,
+                               68CAB030185456F100DB5318 /* Asymp.cpp in Sources */,
+                               68CAB032185456F100DB5318 /* BeeThree.cpp in Sources */,
+                               68CAB057185456F100DB5318 /* MidiFileIn.cpp in Sources */,
+                               68CAB051185456F100DB5318 /* InetWvOut.cpp in Sources */,
+                               68CAB054185456F100DB5318 /* Mandolin.cpp in Sources */,
+                               68CAB031185456F100DB5318 /* BandedWG.cpp in Sources */,
+                               68CAB056185456F100DB5318 /* Messager.cpp in Sources */,
+                               68CAB061185456F100DB5318 /* PercFlut.cpp in Sources */,
+                               68CAB039185456F100DB5318 /* Bowed.cpp in Sources */,
+                               68CAB03D185456F100DB5318 /* Delay.cpp in Sources */,
+                               68CAB06B185456F100DB5318 /* Saxofony.cpp in Sources */,
+                               68CAB069185456F100DB5318 /* Rhodey.cpp in Sources */,
+                               68CAB07B185456F100DB5318 /* TubeBell.cpp in Sources */,
+                               68CAB078185456F100DB5318 /* TcpClient.cpp in Sources */,
+                               68CAB05D185456F100DB5318 /* Noise.cpp in Sources */,
+                               68CAB040185456F100DB5318 /* Drummer.cpp in Sources */,
+                               68CAB02F185456F100DB5318 /* ADSR.cpp in Sources */,
+                               68CAB075185456F100DB5318 /* Stk.mm in Sources */,
+                               68CAB058185456F100DB5318 /* Modal.cpp in Sources */,
+                               68CAB07E185456F100DB5318 /* Voicer.cpp in Sources */,
+                               68CAB05A185456F100DB5318 /* Modulate.cpp in Sources */,
+                               68CAB081185456F100DB5318 /* Wurley.cpp in Sources */,
+                               68CAB052185456F100DB5318 /* JCRev.cpp in Sources */,
+                               68CAB066185456F100DB5318 /* PoleZero.cpp in Sources */,
+                               68CAB045185456F100DB5318 /* FileWrite.cpp in Sources */,
+                               68CAB038185456F100DB5318 /* BlowHole.cpp in Sources */,
+                               68CAB071185456F100DB5318 /* Skini.cpp in Sources */,
+                               68CAB080185456F100DB5318 /* Whistle.cpp in Sources */,
+                               68CAB059185456F100DB5318 /* ModalBar.cpp in Sources */,
+                               68CAB076185456F100DB5318 /* StkUdpSocket.cpp in Sources */,
                                3280A26996EF49D98A7F86C6 /* iosynthApp.cpp in Sources */,
+                               68CAB05F185456F100DB5318 /* OnePole.cpp in Sources */,
+                               68CAB07A185456F100DB5318 /* Thread.cpp in Sources */,
+                               68CAB077185456F100DB5318 /* TapDelay.cpp in Sources */,
+                               68CAB06E185456F100DB5318 /* SineWave.cpp in Sources */,
+                               68CAB07D185456F100DB5318 /* TwoZero.cpp in Sources */,
+                               68CAAFFC185456F100DB5318 /* maximilian.cpp in Sources */,
+                               68CAB04D185456F100DB5318 /* Granulate.cpp in Sources */,
+                               68CAB046185456F100DB5318 /* FileWvIn.cpp in Sources */,
+                               68CAB05E185456F100DB5318 /* NRev.cpp in Sources */,
+                               68CAB079185456F100DB5318 /* TcpServer.cpp in Sources */,
+                               68CAB04A185456F100DB5318 /* FM.cpp in Sources */,
+                               68CAB041185456F100DB5318 /* Echo.cpp in Sources */,
+                               68CAB063185456F100DB5318 /* PitShift.cpp in Sources */,
+                               68CAB07C185456F100DB5318 /* TwoPole.cpp in Sources */,
+                               68CAB074185456F100DB5318 /* StifKarp.cpp in Sources */,
+                               68CAB034185456F100DB5318 /* Blit.cpp in Sources */,
+                               68CAB06A185456F100DB5318 /* Sampler.cpp in Sources */,
+                               68CAB060185456F100DB5318 /* OneZero.cpp in Sources */,
+                               68CAB043185456F100DB5318 /* FileLoop.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                00692BF314FF149000D0A05E /* Debug */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
-                               DEAD_CODE_STRIPPING = YES;
+                               ALWAYS_SEARCH_USER_PATHS = NO;
+                               ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+                               CINDER_PATH = ../../../Cinder;
                                CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
                                CLANG_CXX_LIBRARY = "libc++";
-                               ARCHS = "$(ARCHS_STANDARD_32_BIT)";
-                               ALWAYS_SEARCH_USER_PATHS = NO;
                                "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
                                COPY_PHASE_STRIP = NO;
+                               DEAD_CODE_STRIPPING = YES;
                                GCC_C_LANGUAGE_STANDARD = gnu99;
                                GCC_DYNAMIC_NO_PIC = NO;
                                GCC_OPTIMIZATION_LEVEL = 0;
                                GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
+                               HEADER_SEARCH_PATHS = "\"$(CINDER_PATH)/boost\"";
                                IPHONEOS_DEPLOYMENT_TARGET = 5.0;
                                SDKROOT = iphoneos;
                                TARGETED_DEVICE_FAMILY = "1,2";
-                               CINDER_PATH = "../../../Cinder";
-                               HEADER_SEARCH_PATHS = "\"$(CINDER_PATH)/boost\"";
                                USER_HEADER_SEARCH_PATHS = "\"$(CINDER_PATH)/include\" ../include";
                        };
                        name = Debug;
                00692BF414FF149000D0A05E /* Release */ = {
                        isa = XCBuildConfiguration;
                        buildSettings = {
-                               DEAD_CODE_STRIPPING = YES;
-                               CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
-                               CLANG_CXX_LIBRARY = "libc++";
                                ALWAYS_SEARCH_USER_PATHS = NO;
                                ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+                               CINDER_PATH = ../../../Cinder;
+                               CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
+                               CLANG_CXX_LIBRARY = "libc++";
                                "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
                                COPY_PHASE_STRIP = YES;
+                               DEAD_CODE_STRIPPING = YES;
                                GCC_C_LANGUAGE_STANDARD = gnu99;
                                GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
                                GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
+                               HEADER_SEARCH_PATHS = "\"$(CINDER_PATH)/boost\"";
                                IPHONEOS_DEPLOYMENT_TARGET = 5.0;
                                OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1";
                                SDKROOT = iphoneos;
                                TARGETED_DEVICE_FAMILY = "1,2";
-                               VALIDATE_PRODUCT = YES;
-                               CINDER_PATH = "../../../Cinder";
-                               HEADER_SEARCH_PATHS = "\"$(CINDER_PATH)/boost\"";
                                USER_HEADER_SEARCH_PATHS = "\"$(CINDER_PATH)/include\" ../include";
+                               VALIDATE_PRODUCT = YES;
                        };
                        name = Release;
                };
                        isa = XCBuildConfiguration;
                        buildSettings = {
                                GCC_PRECOMPILE_PREFIX_HEADER = YES;
-                               GCC_PREFIX_HEADER = "iosynth_Prefix.pch";
-                               INFOPLIST_FILE = "Info.plist";
-                               PRODUCT_NAME = "$(TARGET_NAME)";
-                               WRAPPER_EXTENSION = app;
+                               GCC_PREFIX_HEADER = iosynth_Prefix.pch;
+                               INFOPLIST_FILE = Info.plist;
                                "OTHER_LDFLAGS[sdk=iphoneos*][arch=*]" = (
                                        "\"$(CINDER_PATH)/lib/libcinder-iphone_d.a\"",
                                        "-lz",
                                        "\"$(CINDER_PATH)/lib/libcinder-iphone-sim_d.a\"",
                                        "-lz",
                                );
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                               WRAPPER_EXTENSION = app;
                        };
                        name = Debug;
                };
                        isa = XCBuildConfiguration;
                        buildSettings = {
                                GCC_PRECOMPILE_PREFIX_HEADER = YES;
-                               GCC_PREFIX_HEADER = "iosynth_Prefix.pch";
-                               INFOPLIST_FILE = "Info.plist";
-                               PRODUCT_NAME = "$(TARGET_NAME)";
-                               WRAPPER_EXTENSION = app;
+                               GCC_PREFIX_HEADER = iosynth_Prefix.pch;
+                               INFOPLIST_FILE = Info.plist;
                                "OTHER_LDFLAGS[sdk=iphoneos*][arch=*]" = (
                                        "\"$(CINDER_PATH)/lib/libcinder-iphone.a\"",
                                        "-lz",
                                        "\"$(CINDER_PATH)/lib/libcinder-iphone-sim.a\"",
                                        "-lz",
                                );
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                               WRAPPER_EXTENSION = app;
                        };
                        name = Release;
                };